UNPKG

persistent-storage

Version:

Abstracts access to any storage object implementing the webstorage Storage interface, offering optional compression using lz-string and optional encryption using crypto

166 lines 5.46 kB
"use strict"; var crypto = require("./crypto"); var Config = require("./Config"); var lzString = require("lz-string"); var _ = require("lodash"); /** * Constructs a new PersistentStorage instead * @param opts * @param {boolean=false} opts.useCompression * @param {string=} opts.keyPrefix * @param opts.storageBackend * @constructor */ var PersistentStorage = (function () { function PersistentStorage(opts) { if (!opts.storageBackend) { throw new Error("Must provide a storageBackend to wrap"); } this.config = new Config(opts); this.store = opts.storageBackend; this.cache = {}; } PersistentStorage.generateSalt = function (lengthBytes) { return crypto.generateSalt(lengthBytes); }; PersistentStorage.generateIV = function (lengthBytes) { return crypto.generateIV(lengthBytes); }; Object.defineProperty(PersistentStorage.prototype, "length", { get: function () { return this.keys().length; }, enumerable: true, configurable: true }); /** * Sets a value in the persistent storage * @param {string} key - Key to associate this value with * @param {*} value - Value to store, if undefined will delete the given key */ PersistentStorage.prototype.setItem = function (key, value) { key = this.config.keyPrefix + key; if (_.isUndefined(value)) { return this.removeItem(key); } if (this.config.useCache) { this.cache[key] = _.cloneDeep(value); } if (this.config.encryptKeys) { key = crypto.encryptUtf8(key, this.config.encryption); } this.store.setItem(key, convertValueForStorage(value, this.config)); }; /** * Gets a value from the persistant storage, uses in memory cache if possible * @param {string} key - Key to retrieve * @returns {*} */ PersistentStorage.prototype.getItem = function (key) { key = this.config.keyPrefix + key; if (this.config.useCache && this.cache.hasOwnProperty(key)) { return _.cloneDeep(this.cache[key]); } if (this.config.encryptKeys) { key = crypto.encryptUtf8(key, this.config.encryption); } var value = this.store.getItem(key); if (value) { value = inflateValueFromStorage(value, this.config); if (this.config.useCache) { this.cache[key] = value; } return value; } }; /** * Gets the nth key in the store, note that the order of keys is not guaranteed but * will be consistent so long as the key set stays the same. * @param {number} n * @returns {string} */ PersistentStorage.prototype.key = function (n) { return this.keys()[n]; }; /** * Gets an array of the keys in the store * @returns {string[]} */ PersistentStorage.prototype.keys = function () { var _this = this; var prefix = this.config.keyPrefix, keys = _.chain(_.keys(this.store)); if (this.config.encryptKeys) { keys = keys.map(function (key) { try { return crypto.decryptUtf8(key, _this.config.encryption); } catch (err) { return ''; } }); keys = keys.compact(); } if (prefix) { keys = keys.filter(function (key) { return _.startsWith(key, prefix); }) .map(function (key) { return key.substr(prefix.length); }); } return keys.value(); }; /** * Removes an item from the store * @param {string} key */ PersistentStorage.prototype.removeItem = function (key) { key = this.config.keyPrefix + key; delete this.cache[key]; if (this.config.encryptKeys) { key = crypto.encryptUtf8(key, this.config.encryption); } this.store.removeItem(key); }; /** * Clears all items from the store */ PersistentStorage.prototype.clear = function () { var _this = this; this.purgeCache(); if (this.config.keyPrefix) { _.forEach(this.keys(), function (key) { return _this.removeItem(key); }); } else { this.store.clear(); } }; /** * Clears all items from the cache */ PersistentStorage.prototype.purgeCache = function () { this.cache = {}; }; return PersistentStorage; }()); function convertValueForStorage(value, config) { var str = JSON.stringify(value); if (config.useCompression) { str = lzString.compressToUTF16(str); } if (config.useEncryption) { str = crypto.encryptUcs2(str, config.encryption); } return str; } function inflateValueFromStorage(str, config) { if (config.useEncryption) { str = crypto.decryptUcs2(str, config.encryption); } if (config.useCompression) { str = lzString.decompressFromUTF16(str); } return JSON.parse(str); } module.exports = PersistentStorage; //# sourceMappingURL=PersistentStorage.js.map