Convert Figma logo to code with AI

gruns logoImmortalDB

:nut_and_bolt: A relentless key-value store for the browser.

3,047
61
3,047
39

Top Related Projects

💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.

14,015

Cross-browser storage for all use cases, used across the web.

21,334

Simple and fast JSON database

6,300

IndexedDB, but with promises

11,394

A Minimalistic Wrapper for IndexedDB

Quick Overview

ImmortalDB is a JavaScript library that provides a resilient key-value store for the browser. It utilizes multiple storage mechanisms (localStorage, IndexedDB, and cookies) to ensure data persistence across different scenarios, including private browsing and browser restarts.

Pros

  • Highly resilient storage solution that combines multiple storage mechanisms
  • Automatic fallback to alternative storage methods if one fails
  • Simple API that mimics localStorage for ease of use
  • Supports both synchronous and asynchronous operations

Cons

  • Increased complexity compared to using a single storage method
  • Potential performance overhead due to multiple storage operations
  • Limited to browser environments
  • May not be necessary for applications with simple storage needs

Code Examples

Setting a value:

import { ImmortalDB } from 'immortal-db';

await ImmortalDB.set('key', 'value');

Getting a value:

import { ImmortalDB } from 'immortal-db';

const value = await ImmortalDB.get('key', 'defaultValue');
console.log(value);

Removing a value:

import { ImmortalDB } from 'immortal-db';

await ImmortalDB.remove('key');

Getting Started

To use ImmortalDB in your project, follow these steps:

  1. Install the package:

    npm install immortal-db
    
  2. Import and use ImmortalDB in your JavaScript code:

    import { ImmortalDB } from 'immortal-db';
    
    // Set a value
    await ImmortalDB.set('username', 'JohnDoe');
    
    // Get a value
    const username = await ImmortalDB.get('username');
    console.log(username);
    
    // Remove a value
    await ImmortalDB.remove('username');
    

ImmortalDB provides both synchronous and asynchronous methods. The asynchronous methods (like those shown above) are recommended for better performance and compatibility.

Competitor Comparisons

💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.

Pros of localForage

  • More mature and widely adopted project with a larger community
  • Supports multiple storage backends (IndexedDB, WebSQL, localStorage)
  • Provides a simple key-value API with support for storing complex data types

Cons of localForage

  • Larger file size and potentially more overhead
  • Less focus on data persistence across browser sessions and tab closures

Code Comparison

localForage:

localforage.setItem('key', 'value').then(function () {
  return localforage.getItem('key');
}).then(function (value) {
  console.log(value);
}).catch(function (err) {
  console.log(err);
});

ImmortalDB:

await ImmortalDB.set('key', 'value');
const value = await ImmortalDB.get('key');
console.log(value);

Key Differences

  • ImmortalDB focuses on data persistence across browser sessions and tab closures, while localForage primarily aims to provide a unified API for different storage backends.
  • localForage offers more storage options and a larger feature set, while ImmortalDB prioritizes simplicity and robustness.
  • ImmortalDB uses a Promise-based API by default, whereas localForage supports both callback and Promise-based approaches.

Both libraries serve different use cases and have their own strengths. Choose based on your specific requirements for data persistence, browser support, and storage flexibility.

14,015

Cross-browser storage for all use cases, used across the web.

Pros of store.js

  • Broader browser support, including older versions of IE
  • Fallback mechanisms for various storage types (localStorage, globalStorage, userData)
  • Simpler API with fewer methods, potentially easier for beginners

Cons of store.js

  • Less active development and maintenance
  • Lacks advanced features like encryption and multi-tab synchronization
  • No built-in expiration functionality for stored items

Code Comparison

store.js:

store.set('user', { name: 'Marcus' })
store.get('user')
store.remove('user')
store.clearAll()

ImmortalDB:

await db.set('user', { name: 'Marcus' })
await db.get('user')
await db.remove('user')
await db.clear()

Key Differences

  • ImmortalDB uses Promises and async/await for all operations, while store.js uses synchronous methods
  • ImmortalDB offers built-in encryption and multi-tab synchronization
  • store.js provides a more extensive fallback system for older browsers
  • ImmortalDB has a larger API with additional features like setMany() and getMany()

Use Cases

  • Choose store.js for projects requiring support for very old browsers or a simpler storage API
  • Opt for ImmortalDB when security, multi-tab support, and modern JavaScript features are priorities

Both libraries serve as client-side storage solutions, but ImmortalDB offers more advanced features and security measures, while store.js focuses on broad compatibility and simplicity.

21,334

Simple and fast JSON database

Pros of lowdb

  • Supports Node.js and browser environments
  • Offers a simple API inspired by Lodash
  • Allows for easy data persistence to JSON files

Cons of lowdb

  • Less focus on data durability and persistence across browser sessions
  • May require additional setup for complex data structures
  • Limited built-in support for encryption or data security

Code Comparison

ImmortalDB:

const db = new ImmortalDB();
await db.set('key', 'value');
const value = await db.get('key');

lowdb:

const adapter = new JSONFile('db.json');
const db = new Low(adapter);
await db.read();
db.data ||= { posts: [] };
db.data.posts.push({ id: 1, title: 'lowdb is awesome' });
await db.write();

Key Differences

ImmortalDB focuses on providing a durable key-value store for web browsers, emphasizing data persistence across sessions and tabs. It uses multiple storage mechanisms to ensure data survival.

lowdb, on the other hand, is a lightweight JSON database that can be used in both Node.js and browser environments. It offers a more flexible API for working with JSON data and is better suited for applications that require simple data persistence and manipulation.

While ImmortalDB excels in browser-based durability, lowdb provides a more versatile solution for general-purpose JSON data storage and manipulation across different JavaScript environments.

6,300

IndexedDB, but with promises

Pros of idb

  • Provides a more comprehensive and low-level API for IndexedDB
  • Offers better TypeScript support and type definitions
  • Actively maintained with regular updates and improvements

Cons of idb

  • Requires more setup and configuration compared to ImmortalDB
  • Has a steeper learning curve for developers new to IndexedDB
  • Lacks built-in support for multiple storage mechanisms

Code Comparison

ImmortalDB:

import ImmortalDB from 'immortal-db';

await ImmortalDB.set('key', 'value');
const value = await ImmortalDB.get('key');

idb:

import { openDB } from 'idb';

const db = await openDB('myDatabase', 1, {
  upgrade(db) {
    db.createObjectStore('myStore');
  },
});
await db.put('myStore', 'value', 'key');
const value = await db.get('myStore', 'key');

ImmortalDB provides a simpler API for basic key-value storage, while idb offers more control and flexibility for complex database operations. ImmortalDB abstracts away the underlying storage mechanisms, making it easier to use but less customizable. idb, on the other hand, provides a more direct interface to IndexedDB, allowing for advanced features and better performance optimization at the cost of increased complexity.

11,394

A Minimalistic Wrapper for IndexedDB

Pros of Dexie.js

  • More comprehensive IndexedDB wrapper with advanced querying capabilities
  • Supports complex data structures and relationships
  • Active development and larger community support

Cons of Dexie.js

  • Steeper learning curve due to more complex API
  • Larger file size and potentially higher overhead

Code Comparison

ImmortalDB:

const db = new ImmortalDB();
await db.set('key', 'value');
const value = await db.get('key');

Dexie.js:

const db = new Dexie('MyDatabase');
db.version(1).stores({ items: '++id, name, price' });
await db.items.add({ name: 'apple', price: 1.5 });
const items = await db.items.where('price').above(1).toArray();

Summary

Dexie.js is a more feature-rich IndexedDB wrapper suitable for complex data management in web applications. It offers advanced querying and support for relationships between objects. However, it comes with a steeper learning curve and larger footprint compared to ImmortalDB.

ImmortalDB, on the other hand, provides a simpler key-value storage solution with built-in redundancy across multiple storage mechanisms. It's easier to use for basic storage needs but lacks the advanced features of Dexie.js.

Choose Dexie.js for complex data management requirements, and ImmortalDB for simpler, redundant storage needs in web applications.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

ImmortalDB

ImmortalDB

ImmortalDB is a resilient key-value store for the browser.

ImmortalDB is the best way to store persistent key-value data in the browser. Data saved to ImmortalDB is redundantly stored in Cookies, IndexedDB, and LocalStorage, and relentlessly self heals if any data therein is deleted or corrupted.

For example, clearing cookies is a common user action, even for non-technical users. And browsers unceremoniously delete IndexedDB, LocalStorage, and/or SessionStorage without warning under storage pressure.

ImmortalDB is resilient in the face of such events.

In this way, ImmortalDB is like Evercookie, but

  1. Is actively maintained and well documented.

  2. Provides a simple, modern, Promise-based API.

  3. Strikes an equitable balance between reliability and respect for the user. Data is stored reliably but can also be voluntarily purged if the user designedly clears cookies and application storage.

  4. Doesn't use nefarious exploits nor deprecated third party plugins like Flash, Silverlight, or Java. Only standard, ratified HTML5 APIs are used.

  5. Doesn't vandalize performance or the user experience. For example, Evercookie's CSS History Knocking can beget a deluge of background HTTP requests, and loading Silverlight or Flash can raise unsought permission modals or thrash the user's disk.

How ImmortalDB works.

When you store a key-value pair in ImmortalDB, that key and value are saved redundantly in the browser's cookies, IndexedDB, and LocalStorage data stores.

When a value is retrieved via its key, ImmortalDB

  1. Looks up that key in every data store.
  2. Counts each unique returned value.
  3. Determines the most commonly returned unique value as the 'correct' value.
  4. Returns this correct value.

Then ImmortalDB self-heals: if any data store(s) returned a value different than the determined correct value, or no value at all, the correct value is rewritten to that store. In this way, consensus, reliability, and redundancy is maintained.

API

Set

ImmortalDB's API is simple. To store a value, use set(key, value):

import { ImmortalDB } from 'immortal-db'

await ImmortalDB.set('key', 'value')

key and value must be DOMStrings. ImmortalDB.set(key, value) also always returns value, so it can be chained or embedded, like

const countPlusOne = (await ImmortalDB.set('count', numberOfClowns)) + 1

Get

To retrieve a value, use get(key, default=null):

const value = await ImmortalDB.get('key', default=null)

get() returns the value associated with key, if key exists. If key doesn't exist, default is returned. key must be a DOMString.

Remove

Finally, to remove a key, use remove(key):

ImmortalDB.set('hi', 'bonjour')
console.log(await ImmortalDB.get('hi'))  // Prints 'bonjour'.

await ImmortalDB.remove('hi')

console.log(await ImmortalDB.get('hi'))  // Prints 'null'.

key must be a DOMString.

Data Stores

The data stores that ImmortalDB stores data in can also be configured. For example, this is how to store data reliably in cookies and LocalStorage only:

import { ImmortalStorage, CookieStore, LocalStorageStore } from 'immortal-db'

const stores = [await CookieStore(), await LocalStorageStore()]
const db = new ImmortalStorage(stores)

await db.set(key, JSON.stringify({1:1}))

By default, stores used by ImmortalDB are:

  • CookieStore -> Keys and values are stored in document.cookie.
  • IndexedDbStore -> Keys and values are stored in window.indexedDB.
  • LocalStorageStore -> Keys and values are stored in window.localStorage.

Other, optional stores are:

  • SessionStorageStore -> Keys and values are stored in window.sessionStorage.

New storage implementations can easily be added, too; they need only implement the async methods get(key, default), set(key, value), and remove(key).

Installation

Installing ImmortalDB with npm is easy.

$ npm install immortal-db

Or include dist/immortal-db[.min].js and use window.ImmortalDB directly.

<html>
  <head>
    <script src="immortal-db.min.js"></script>
    <script>
      ;(async () => {
        const db = ImmortalDB.ImmortalDB
        await db.set('hi', 'lolsup')
      })()
    </script>
  </head>

  ...
</html>

Development

To test ImmortalDB, run

npm run start

This starts a webpack dev server and opens ImmortalDB's testing website, http://localhost:9234/.

Once tested, to produce new production-ready files immortal-db.js and immortal-db.min.js in dist/, run

npm run build

NPM DownloadsLast 30 Days