UNPKG

memorystorage

Version:

Memory-backed implementation of the Web Storage API

83 lines (72 loc) 3.38 kB
/*! memorystorage.js - A memory-backed implementation of the Web Storage API. * * @copyright Copyright 2016 by Stijn de Witt and contributors. Some rights reserved. * @license Licensed under [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/). */ /** * Creates a new MemoryStorage object implementing the <a href="http://www.w3.org/TR/webstorage/">Web Storage API</a> using memory. * * <p>If no arguments are given, the created memory storage object will read from and write to the * <code>global</code> memory storage. If a string argument is given, the new storage object * will read from and write to it's own segment of memory. Any data written to such a memory * storage object will only show up in other memory storage objects that have been created with * the same id. This data will not show up in the <code>global</code> memory space. As such it * is recommended to always construct a memory storage object with a unique string id as argument.</p> * * @param id Optional string argument used to isolate this memory storage object from others. */ function MemoryStorage(id) { // make sure id is assigned id = id || 'global' // try to get existing store var result = storage[id] // return it if found if (result) {return result} // make sure there is no harm in leaving out new in invocations to MemoryStorage if (! (this instanceof MemoryStorage)) {return new MemoryStorage(id);} // create a new store and save a ref to it so we can get it back later result = storage[id] = this; // create a space to store 'cloaked' key/values: items that have a key // that collides with Web Storage API method names. var cloak = {}; // Allow client code to read the id Object.defineProperty(result, 'id', {enumerable:true, configurable:true, value:id}) // Create the length property Object.defineProperty(result, 'length', {enumerable:true, configurable:true, get:function(){ return enumerableKeys().length }}) // Create API methods result.getItem = function MemoryStorage_getItem(key) { return (key in API ? cloak[key] : this[key]) || null } result.setItem = function MemoryStorage_setItem(key, val) { key in API ? cloak[key] = val : this[key] = val } result.removeItem = function MemoryStorage_removeItem(key) { key in API ? delete cloak[key] : delete this[key] } result.key = function MemoryStorage_key(idx) { var keys = enumerableKeys() return idx >= 0 && idx < keys.length ? keys[idx] : null } result.clear = function MemoryStorage_clear() { var keys = uncloakedKeys() for (var i=0,key; key=keys[i]; i++) { delete this[key] } keys = cloakedKeys() for (var i=0,key; key=keys[i]; i++) { delete cloak[key] } } // Wrap in ES6 Proxy if available to support Object.keys() on a MemoryStorage object return typeof Proxy === 'undefined' ? result : new Proxy(result, {ownKeys: function() {return enumerableKeys()}}) // helper functions function uncloakedKeys() {return Object.keys(result).filter(function(x){return !(x in API)})} function cloakedKeys() {return Object.keys(cloak)} function enumerableKeys(){return uncloakedKeys().concat(cloakedKeys())} } // API methods and properties will be cloaked var API = {clear:1, getItem:1, id:1, key:1, length:1, removeItem:1, setItem:1} // Used to store all memorystorage objects var storage = {};