store2

repository·master·Indexed 23 days ago

https://github.com/nbubna/store

A feature-rich wrapper for browser localStorage and sessionStorage (version 2.14.4) that provides support for JSON parsing, namespacing, and atomic transactions. It includes a variety of stable and experimental extensions for data expiration, array functions, event handling, and cookie storage, while offering a fallback to fake in-memory storage to prevent errors when browser storage is unavailable.

Tokens
2.6K
Snippets
7
Records
11
Agent score
34%

What's inside store2

  1. Use custom revivers and replacers for complex types

    master

    To handle rich objects like Date, Map, or Set, you can use reviver and replacer functions.

    • Revivers: Passed as the alt parameter to retrieval functions (get, getAll, remove, transact). They receive each key and value (including nested ones) to parse the string.
    • Replacers: Passed as the overwrite parameter to setter functions (set, setAll, add, transact). They receive each key and value to stringify the data.

    Global Configuration:

    • Set store._.revive to handle all retrieval calls globally.
    • Set store._.replace to handle all setter calls globally.
  2. Write a custom store extension

    master

    You can extend the store interface by using the internal store._ object. The store._.fn(fnName, fn) method automatically adds a new function to every instance of the store interface, including the main store, store.session, and all existing or future namespaces.

    Warning: Using _.fn will override existing methods if the names collide.

    Example: Adding falsy and truthy helpers

    (function(_) {
        _.fn('falsy', function(key) {
            return !this.get(key);
        });
        _.fn('truthy', function(key) {
            return !this.falsy(key);
        });
    })(store._);

    Once registered, these methods are available on all store instances:

    store('foo', 1);
    store.falsy('foo'); // returns false
    
    store.session('bar', 'one');
    store.session.truthy('bar'); // returns true;
    
    const widgetStore = store.namespace('widget');
    widgetStore.falsy('state'); // returns true
    (function(_) {
        _.fn('falsy', function(key) {
            return !this.get(key);
        });
        _.fn('truthy', function(key) {
            return !this.falsy(key);
        });
    })(store._);
  3. Organize data using store.namespace()

    master

    Use store.namespace(prefix) to prevent key collisions by adding a prefix to all keys. The namespaced object provides the exact same API as the main store object.

    var cart = store.namespace('cart');
    cart('total', 23.25); // stores in localStorage as 'cart.total'
    console.log(store('cart.total') == cart('total')); // true
    console.log(store.cart.getAll()); // {total: 23.25}
    cart.session('group', 'toys'); // stores in sessionStorage as 'cart.group'

    Advanced Namespace Options:

    • Create a namespace only in a specific storage area: store.page.namespace("subpage", true, ":") (where true limits it to the current area and ":" sets a custom delimiter).
    • Access namespaces directly via store[namespace] if they don't conflict with the API.
    var cart = store.namespace('cart');
    cart('total', 23.25);// stores in localStorage as 'cart.total'
    console.log(store('cart.total') == cart('total'));// logs true
    console.log(store.cart.getAll());// logs {total: 23.25}
    cart.session('group', 'toys');// stores in sessionStorage as 'cart.group'
  4. Use store extensions for enhanced functionality

    master

    The store library supports various extensions to add specialized behavior. These are categorized by stability:

    Stable Extensions

    • store.cache.js: Enables data expiration. Pass the number of seconds as the third parameter to set() calls.
    • store.array.js: Adds array functions like store.push(key, v1, v2).
    • store.on.js: Provides advanced storage event handling (per key, per namespace, etc.).
    • store.cookie.js: Uses a cookie as a storage area (e.g., store.cookie('num', 1)).
    • store.dom.js: Enables declarative, persistent DOM element content.
    • store.overflow.js: Automatically falls back to fake storage on quota errors.
    • store.old.js: Provides polyfills for ancient browsers.

    Alpha/Experimental Extensions

    • store.async.js: Adds an .async duplicate to stores/namespaces that returns Promises.
    • store.deep.js: Allows retrieving properties from within stored objects using dot notation (e.g., store.get('key.property')).
    • store.dot.js: Creates accessors for keys (e.g., store.foo == store.get('foo')).
    • store.quota.js: Allows registering callbacks to handle or cancel quota errors.
    • store.cookies.js: Manages all cookies as a storage area via the store API.
    • store.onlyreal.js: Silently fails if only fake storage is available.
    • store.measure.js: Experimental tool for measuring used and available space.
  5. Install store2

    master

    You can install store2 using npm or NuGet, or download the minified/development files directly from GitHub.

    NPM:

    npm install store2

    NuGet:

    Install-Package store2
    npm install store2
  6. Iterate through storage with store.each()

    master

    The each method iterates over all key/value pairs. The callback receives key as the first argument and value as the second. You can provide an optional fill argument which will be passed as the third argument to the callback. To stop the loop early, return false from the callback.

    store.each(function(key, value) {
        console.log(key, '->', value);
        if (key === 'stopLoop') {
            return false; // stops the loop
        }
    });
    store.each(function(key, value) {
        console.log(key, '->', value);
        if (key === 'stopLoop') {
            return false;// this will cause each to stop calling this function
        }
    });
  7. Perform atomic updates with store.transact()

    master

    The transact method allows you to modify persistent data safely. The function passed to transact receives the current value as an argument. When the function completes, transact saves the returned value under the specified key. If the function returns undefined, the original value is preserved.

    store.transact(key, function(obj) {
        obj.changed = 'newValue'; // this change will be persisted
    });
    store.transact(key, function(obj) {
        obj.changed = 'newValue';// this change will be persisted
    });
  8. Use fake storage for testing with store.isFake()

    master

    If localStorage or sessionStorage are unavailable, store automatically uses a 'fake' in-memory storage to prevent errors. Data in fake storage will not persist beyond the current page reload.

    You can manually force the use of fake storage (useful for unit testing to avoid polluting actual browser storage) using store.isFake(true|false).

    store.isFake(true); // Force use of temporary, fake storage
  9. Switch between localStorage, sessionStorage, and page memory

    master

    By default, store uses localStorage. You can switch storage areas using the following methods:

    • Session Storage: Use store.session to interact with sessionStorage.
    • Page Memory: Use store.page for non-persistent information that lasts only until page reload.
    • Explicit Local: Use store.local to explicitly target localStorage.

    To switch the main store instance to use sessionStorage, use: store.session("addMeTo", "sessionStorage");.

    All specific methods (get, set, etc.) are available on store.session, store.local, and store.page.

    store.session("addMeTo", "sessionStorage");
    store.local({lots: 'of', data: 'altogether'});// store.local === store :)
    store.page("until","reload");
  10. Use the main store function for basic operations

    master

    The main store function is a versatile entry point that handles several actions based on the arguments provided:

    • Set data: store(key, data) sets stringified data under key.
    • Get data: store(key) gets and parses data stored under key.
    • Transaction: store(key, fn[, alt]) runs a transaction function on/with data stored under key.
    • Set multiple: store({key: data, key2: data2}) sets all key/data pairs in the object.
    • Get all: store() gets all stored key/data pairs as an object.
    • Iterate: store((key, data)=>{ }) calls a function for each key/data in storage. Returning false exits the loop.
    • Clear all: store(false) clears all items from storage.
    store(key, data);                 // sets stringified data under key
    store(key);                       // gets and parses data stored under key
    store(key, fn[, alt]);            // run transaction function on/with data stored under key
    store({key: data, key2: data2});  // sets all key/data pairs in the object
    store();                          // gets all stored key/data pairs as an object
    store((key, data)=>{ });          // calls function for each key/data in storage, return false to exit
    store(false);                     // clears all items from storage
  11. Use explicit store methods for granular control

    master

    For more explicit control, use the following methods on the store object:

    MethodDescription
    store.set(key, data[, overwrite])Sets data. If overwrite is false, skips if key exists. Returns previous value.
    store.setAll(data[, overwrite])Sets multiple key/data pairs.
    store.get(key[, alt])Gets and parses data. alt can be a reviver function.
    store.getAll([fillObj])Gets all pairs. fillObj is an optional object to add results to.
    store.transact(key, fn[, alt])Runs a transaction. The returned value from fn is saved under key.
    store.clear()Clears current storage.
    store.has(key)Returns true or false.
    store.remove(key[, alt])Removes key and returns its data or alt.
    store.each(fn[, fill])Iterates through all items. Returning false stops iteration.
    store.add(key, data[, replacer])Concats, merges, or adds new value into existing one.
    store.keys([fillList])Returns array of keys.
    store.size()Returns number of keys.
    store.clearAll()Clears ALL areas (namespace sensitive).