atom.storage
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -6,2 +6,17 @@ "use strict"; | ||
}); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
var storages = new WeakMap(); | ||
var usedOptions = void 0; | ||
if (process.NODE_ENV !== "production") usedOptions = new WeakMap(); | ||
var getAtoms = function getAtoms(storage) { | ||
var atoms = storages.get(storage); | ||
if (!atoms) storages.set(storage, atoms = {}); | ||
return atoms; | ||
}; | ||
var tryParse = function tryParse(json) { | ||
@@ -31,8 +46,18 @@ try { | ||
var expireNow = exports.expireNow = function expireNow(_ref) { | ||
var unsafeDeleteAtom = exports.unsafeDeleteAtom = function unsafeDeleteAtom(_ref) { | ||
var storage = _ref.storage; | ||
var regex = _ref.regex; | ||
var key = _ref.key; | ||
var atoms = getAtoms(storage); | ||
delete atoms[key]; | ||
}; | ||
var expireNow = exports.expireNow = function expireNow(_ref2) { | ||
var storage = _ref2.storage; | ||
var regex = _ref2.regex; | ||
var unsafeDeleteAtoms = _ref2.unsafeDeleteAtoms; | ||
for (var i = 0; i < storage.length; ++i) { | ||
var key = storage.key(i); | ||
if (!regex.test(key)) continue; | ||
@@ -43,32 +68,62 @@ | ||
if (data.expires <= Date.now()) storage.removeItem(key); | ||
if (data.expires <= Date.now()) { | ||
storage.removeItem(key); | ||
if (unsafeDeleteAtoms) unsafeDeleteAtom({ storage: storage, key: key }); | ||
} | ||
} | ||
}; | ||
exports.default = function (_ref2) { | ||
var key = _ref2.key; | ||
var value = _ref2.value; | ||
var Atom = _ref2.Atom; | ||
var storage = _ref2.storage; | ||
var time = _ref2.time; | ||
var schema = _ref2.schema; | ||
var debounce = _ref2.debounce; | ||
function show(x) { | ||
switch (typeof x === "undefined" ? "undefined" : _typeof(x)) { | ||
case "string": | ||
case "object": | ||
return JSON.stringify(x); | ||
default: | ||
return "" + x; | ||
} | ||
} | ||
var atom = Atom(getValue(storage, key, schema, value)); | ||
exports.default = function (_ref3) { | ||
var key = _ref3.key; | ||
var storage = _ref3.storage; | ||
var changes = atom.changes(); | ||
if (0 <= debounce) changes = changes.debounce(debounce); | ||
var options = _objectWithoutProperties(_ref3, ["key", "storage"]); | ||
changes.onValue(function (value) { | ||
var data = { value: value }; | ||
var value = options.value; | ||
var Atom = options.Atom; | ||
var time = options.time; | ||
var schema = options.schema; | ||
var debounce = options.debounce; | ||
if (schema !== undefined) data.schema = schema; | ||
if (0 <= time) data.expires = time + Date.now(); | ||
var atoms = getAtoms(storage); | ||
storage.setItem(key, JSON.stringify(data)); | ||
}); | ||
var atom = atoms[key]; | ||
if (!atom) { | ||
atoms[key] = atom = Atom(getValue(storage, key, schema, value)); | ||
if (process.NODE_ENV !== "production") usedOptions.set(atom, options); | ||
var changes = atom.changes(); | ||
if (0 <= debounce) changes = changes.debounce(debounce); | ||
changes.onValue(function (value) { | ||
var data = { value: value }; | ||
if (schema !== undefined) data.schema = schema; | ||
if (0 <= time) data.expires = time + Date.now(); | ||
storage.setItem(key, JSON.stringify(data)); | ||
}); | ||
} else if (process.NODE_ENV !== "production") { | ||
var oldOptions = usedOptions.get(atom); | ||
for (var k in options) { | ||
if (options[k] !== oldOptions[k]) throw new Error("atom.storage: Created two atoms with same storage and key " + show(key) + ", but different " + show(k) + ": first " + show(oldOptions[k]) + " and later " + show(options[k]) + "."); | ||
} | ||
} | ||
return atom; | ||
}; | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9hdG9tLnN0b3JhZ2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxJQUFNLFdBQVcsU0FBWCxRQUFXLE9BQVE7QUFDdkIsTUFBSTtBQUNGLFdBQU8sS0FBSyxLQUFMLENBQVcsSUFBWCxDQUFQLENBREU7R0FBSixDQUVFLE9BQU8sS0FBUCxFQUFjO0FBQ2QsV0FBTyxLQUFQLENBRGM7R0FBZDtDQUhhOztBQVFqQixJQUFNLGFBQ0osU0FESSxVQUNKO1NBQVEsUUFBUSxLQUFLLFdBQUwsS0FBcUIsTUFBckIsSUFBK0IsV0FBVyxJQUFYO0NBQS9DOztBQUVGLElBQU0sV0FBVyxTQUFYLFFBQVcsQ0FBQyxPQUFELEVBQVUsR0FBVixFQUFlLE1BQWYsRUFBdUIsS0FBdkIsRUFBaUM7QUFDaEQsTUFBTSxPQUFPLFFBQVEsT0FBUixDQUFnQixHQUFoQixDQUFQLENBRDBDO0FBRWhELE1BQUksQ0FBQyxJQUFELEVBQ0YsT0FBTyxLQUFQLENBREY7O0FBR0EsTUFBTSxPQUFPLFNBQVMsSUFBVCxDQUFQLENBTDBDO0FBTWhELE1BQUksQ0FBQyxXQUFXLElBQVgsQ0FBRCxFQUNGLE9BQU8sS0FBUCxDQURGOztBQUdBLE1BQUksS0FBSyxNQUFMLEtBQWdCLE1BQWhCLEVBQ0YsT0FBTyxLQUFQLENBREY7O0FBR0EsU0FBTyxLQUFLLEtBQUwsQ0FaeUM7Q0FBakM7O0FBZVYsSUFBTSxnQ0FBWSxTQUFaLFNBQVksT0FBc0I7TUFBcEIsdUJBQW9CO01BQVgsbUJBQVc7O0FBQzdDLE9BQUssSUFBSSxJQUFFLENBQUYsRUFBSyxJQUFFLFFBQVEsTUFBUixFQUFnQixFQUFFLENBQUYsRUFBSztBQUNuQyxRQUFNLE1BQU0sUUFBUSxHQUFSLENBQVksQ0FBWixDQUFOLENBRDZCO0FBRW5DLFFBQUksQ0FBQyxNQUFNLElBQU4sQ0FBVyxHQUFYLENBQUQsRUFDRixTQURGOztBQUdBLFFBQU0sT0FBTyxTQUFTLFFBQVEsT0FBUixDQUFnQixHQUFoQixDQUFULENBQVAsQ0FMNkI7QUFNbkMsUUFBSSxDQUFDLFdBQVcsSUFBWCxDQUFELEVBQ0YsU0FERjs7QUFHQSxRQUFJLEtBQUssT0FBTCxJQUFnQixLQUFLLEdBQUwsRUFBaEIsRUFDRixRQUFRLFVBQVIsQ0FBbUIsR0FBbkIsRUFERjtHQVRGO0NBRHVCOztrQkFlVixpQkFNZ0I7TUFOZCxnQkFNYztNQUxkLG9CQUtjO01BSmQsa0JBSWM7TUFIZCx3QkFHYztNQUZkLGtCQUVjO01BRGQsc0JBQ2M7TUFBZCwwQkFBYzs7QUFDN0IsTUFBTSxPQUFPLEtBQUssU0FBUyxPQUFULEVBQWtCLEdBQWxCLEVBQXVCLE1BQXZCLEVBQStCLEtBQS9CLENBQUwsQ0FBUCxDQUR1Qjs7QUFHN0IsTUFBSSxVQUFVLEtBQUssT0FBTCxFQUFWLENBSHlCO0FBSTdCLE1BQUksS0FBSyxRQUFMLEVBQ0YsVUFBVSxRQUFRLFFBQVIsQ0FBaUIsUUFBakIsQ0FBVixDQURGOztBQUdBLFVBQVEsT0FBUixDQUFnQixpQkFBUztBQUN2QixRQUFNLE9BQU8sRUFBQyxZQUFELEVBQVAsQ0FEaUI7O0FBR3ZCLFFBQUksV0FBVyxTQUFYLEVBQ0YsS0FBSyxNQUFMLEdBQWMsTUFBZCxDQURGOztBQUdBLFFBQUksS0FBSyxJQUFMLEVBQ0YsS0FBSyxPQUFMLEdBQWUsT0FBTyxLQUFLLEdBQUwsRUFBUCxDQURqQjs7QUFHQSxZQUFRLE9BQVIsQ0FBZ0IsR0FBaEIsRUFBcUIsS0FBSyxTQUFMLENBQWUsSUFBZixDQUFyQixFQVR1QjtHQUFULENBQWhCLENBUDZCOztBQW1CN0IsU0FBTyxJQUFQLENBbkI2QjtDQU5oQiIsImZpbGUiOiJhdG9tLnN0b3JhZ2UuanMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCB0cnlQYXJzZSA9IGpzb24gPT4ge1xuICB0cnkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGpzb24pXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGVycm9yXG4gIH1cbn1cblxuY29uc3Qgc2VlbXNWYWxpZCA9XG4gIGRhdGEgPT4gZGF0YSAmJiBkYXRhLmNvbnN0cnVjdG9yID09PSBPYmplY3QgJiYgXCJ2YWx1ZVwiIGluIGRhdGFcblxuY29uc3QgZ2V0VmFsdWUgPSAoc3RvcmFnZSwga2V5LCBzY2hlbWEsIHZhbHVlKSA9PiB7XG4gIGNvbnN0IGpzb24gPSBzdG9yYWdlLmdldEl0ZW0oa2V5KVxuICBpZiAoIWpzb24pXG4gICAgcmV0dXJuIHZhbHVlXG5cbiAgY29uc3QgZGF0YSA9IHRyeVBhcnNlKGpzb24pXG4gIGlmICghc2VlbXNWYWxpZChkYXRhKSlcbiAgICByZXR1cm4gdmFsdWVcblxuICBpZiAoZGF0YS5zY2hlbWEgIT09IHNjaGVtYSlcbiAgICByZXR1cm4gdmFsdWVcblxuICByZXR1cm4gZGF0YS52YWx1ZVxufVxuXG5leHBvcnQgY29uc3QgZXhwaXJlTm93ID0gKHtzdG9yYWdlLCByZWdleH0pID0+IHtcbiAgZm9yIChsZXQgaT0wOyBpPHN0b3JhZ2UubGVuZ3RoOyArK2kpIHtcbiAgICBjb25zdCBrZXkgPSBzdG9yYWdlLmtleShpKVxuICAgIGlmICghcmVnZXgudGVzdChrZXkpKVxuICAgICAgY29udGludWVcblxuICAgIGNvbnN0IGRhdGEgPSB0cnlQYXJzZShzdG9yYWdlLmdldEl0ZW0oa2V5KSlcbiAgICBpZiAoIXNlZW1zVmFsaWQoZGF0YSkpXG4gICAgICBjb250aW51ZVxuXG4gICAgaWYgKGRhdGEuZXhwaXJlcyA8PSBEYXRlLm5vdygpKVxuICAgICAgc3RvcmFnZS5yZW1vdmVJdGVtKGtleSlcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCAoe2tleSxcbiAgICAgICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAgICAgIEF0b20sXG4gICAgICAgICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgICAgICAgIHRpbWUsXG4gICAgICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgICAgZGVib3VuY2V9KSA9PiB7XG4gIGNvbnN0IGF0b20gPSBBdG9tKGdldFZhbHVlKHN0b3JhZ2UsIGtleSwgc2NoZW1hLCB2YWx1ZSkpXG5cbiAgbGV0IGNoYW5nZXMgPSBhdG9tLmNoYW5nZXMoKVxuICBpZiAoMCA8PSBkZWJvdW5jZSlcbiAgICBjaGFuZ2VzID0gY2hhbmdlcy5kZWJvdW5jZShkZWJvdW5jZSlcblxuICBjaGFuZ2VzLm9uVmFsdWUodmFsdWUgPT4ge1xuICAgIGNvbnN0IGRhdGEgPSB7dmFsdWV9XG5cbiAgICBpZiAoc2NoZW1hICE9PSB1bmRlZmluZWQpXG4gICAgICBkYXRhLnNjaGVtYSA9IHNjaGVtYVxuXG4gICAgaWYgKDAgPD0gdGltZSlcbiAgICAgIGRhdGEuZXhwaXJlcyA9IHRpbWUgKyBEYXRlLm5vdygpXG5cbiAgICBzdG9yYWdlLnNldEl0ZW0oa2V5LCBKU09OLnN0cmluZ2lmeShkYXRhKSlcbiAgfSlcblxuICByZXR1cm4gYXRvbVxufVxuIl19 | ||
//# sourceMappingURL=data:application/json;base64,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LENBQWYsRUFDRixNQUFNLElBQUksS0FBSixnRUFBdUUsS0FBSyxHQUFMLHlCQUE0QixLQUFLLENBQUwsaUJBQWtCLEtBQUssV0FBVyxDQUFYLENBQUwsb0JBQWlDLEtBQUssUUFBUSxDQUFSLENBQUwsT0FBdEosQ0FBTixDQURGO0tBREY7R0FGSzs7QUFRUCxTQUFPLElBQVAsQ0FuQzZDO0NBQWhDIiwiZmlsZSI6ImF0b20uc3RvcmFnZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHN0b3JhZ2VzID0gbmV3IFdlYWtNYXAoKVxubGV0IHVzZWRPcHRpb25zXG5pZiAocHJvY2Vzcy5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpXG4gIHVzZWRPcHRpb25zID0gbmV3IFdlYWtNYXAoKVxuXG5jb25zdCBnZXRBdG9tcyA9IHN0b3JhZ2UgPT4ge1xuICBsZXQgYXRvbXMgPSBzdG9yYWdlcy5nZXQoc3RvcmFnZSlcbiAgaWYgKCFhdG9tcylcbiAgICBzdG9yYWdlcy5zZXQoc3RvcmFnZSwgYXRvbXMgPSB7fSlcbiAgcmV0dXJuIGF0b21zXG59XG5cbmNvbnN0IHRyeVBhcnNlID0ganNvbiA9PiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoanNvbilcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gZXJyb3JcbiAgfVxufVxuXG5jb25zdCBzZWVtc1ZhbGlkID1cbiAgZGF0YSA9PiBkYXRhICYmIGRhdGEuY29uc3RydWN0b3IgPT09IE9iamVjdCAmJiBcInZhbHVlXCIgaW4gZGF0YVxuXG5jb25zdCBnZXRWYWx1ZSA9IChzdG9yYWdlLCBrZXksIHNjaGVtYSwgdmFsdWUpID0+IHtcbiAgY29uc3QganNvbiA9IHN0b3JhZ2UuZ2V0SXRlbShrZXkpXG4gIGlmICghanNvbilcbiAgICByZXR1cm4gdmFsdWVcblxuICBjb25zdCBkYXRhID0gdHJ5UGFyc2UoanNvbilcbiAgaWYgKCFzZWVtc1ZhbGlkKGRhdGEpKVxuICAgIHJldHVybiB2YWx1ZVxuXG4gIGlmIChkYXRhLnNjaGVtYSAhPT0gc2NoZW1hKVxuICAgIHJldHVybiB2YWx1ZVxuXG4gIHJldHVybiBkYXRhLnZhbHVlXG59XG5cbmV4cG9ydCBjb25zdCB1bnNhZmVEZWxldGVBdG9tID0gKHtzdG9yYWdlLCBrZXl9KSA9PiB7XG4gIGNvbnN0IGF0b21zID0gZ2V0QXRvbXMoc3RvcmFnZSlcbiAgZGVsZXRlIGF0b21zW2tleV1cbn1cblxuZXhwb3J0IGNvbnN0IGV4cGlyZU5vdyA9ICh7c3RvcmFnZSwgcmVnZXgsIHVuc2FmZURlbGV0ZUF0b21zfSkgPT4ge1xuICBmb3IgKGxldCBpPTA7IGk8c3RvcmFnZS5sZW5ndGg7ICsraSkge1xuICAgIGNvbnN0IGtleSA9IHN0b3JhZ2Uua2V5KGkpXG5cbiAgICBpZiAoIXJlZ2V4LnRlc3Qoa2V5KSlcbiAgICAgIGNvbnRpbnVlXG5cbiAgICBjb25zdCBkYXRhID0gdHJ5UGFyc2Uoc3RvcmFnZS5nZXRJdGVtKGtleSkpXG4gICAgaWYgKCFzZWVtc1ZhbGlkKGRhdGEpKVxuICAgICAgY29udGludWVcblxuICAgIGlmIChkYXRhLmV4cGlyZXMgPD0gRGF0ZS5ub3coKSkge1xuICAgICAgc3RvcmFnZS5yZW1vdmVJdGVtKGtleSlcblxuICAgICAgaWYgKHVuc2FmZURlbGV0ZUF0b21zKVxuICAgICAgICB1bnNhZmVEZWxldGVBdG9tKHtzdG9yYWdlLCBrZXl9KVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzaG93KHgpIHtcbiAgc3dpdGNoICh0eXBlb2YgeCkge1xuICBjYXNlIFwic3RyaW5nXCI6XG4gIGNhc2UgXCJvYmplY3RcIjpcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeClcbiAgZGVmYXVsdDpcbiAgICByZXR1cm4gYCR7eH1gXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgKHtrZXksIHN0b3JhZ2UsIC4uLm9wdGlvbnN9KSA9PiB7XG4gIGNvbnN0IHt2YWx1ZSwgQXRvbSwgdGltZSwgc2NoZW1hLCBkZWJvdW5jZX0gPSBvcHRpb25zXG5cbiAgY29uc3QgYXRvbXMgPSBnZXRBdG9tcyhzdG9yYWdlKVxuXG4gIGxldCBhdG9tID0gYXRvbXNba2V5XVxuICBpZiAoIWF0b20pIHtcbiAgICBhdG9tc1trZXldID0gYXRvbSA9IEF0b20oZ2V0VmFsdWUoc3RvcmFnZSwga2V5LCBzY2hlbWEsIHZhbHVlKSlcblxuICAgIGlmIChwcm9jZXNzLk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIilcbiAgICAgIHVzZWRPcHRpb25zLnNldChhdG9tLCBvcHRpb25zKVxuXG4gICAgbGV0IGNoYW5nZXMgPSBhdG9tLmNoYW5nZXMoKVxuICAgIGlmICgwIDw9IGRlYm91bmNlKVxuICAgICAgY2hhbmdlcyA9IGNoYW5nZXMuZGVib3VuY2UoZGVib3VuY2UpXG5cbiAgICBjaGFuZ2VzLm9uVmFsdWUodmFsdWUgPT4ge1xuICAgICAgY29uc3QgZGF0YSA9IHt2YWx1ZX1cblxuICAgICAgaWYgKHNjaGVtYSAhPT0gdW5kZWZpbmVkKVxuICAgICAgICBkYXRhLnNjaGVtYSA9IHNjaGVtYVxuXG4gICAgICBpZiAoMCA8PSB0aW1lKVxuICAgICAgICBkYXRhLmV4cGlyZXMgPSB0aW1lICsgRGF0ZS5ub3coKVxuXG4gICAgICBzdG9yYWdlLnNldEl0ZW0oa2V5LCBKU09OLnN0cmluZ2lmeShkYXRhKSlcbiAgICB9KVxuICB9IGVsc2UgaWYgKHByb2Nlc3MuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgY29uc3Qgb2xkT3B0aW9ucyA9IHVzZWRPcHRpb25zLmdldChhdG9tKVxuICAgIGZvciAoY29uc3QgayBpbiBvcHRpb25zKSB7XG4gICAgICBpZiAob3B0aW9uc1trXSAhPT0gb2xkT3B0aW9uc1trXSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBhdG9tLnN0b3JhZ2U6IENyZWF0ZWQgdHdvIGF0b21zIHdpdGggc2FtZSBzdG9yYWdlIGFuZCBrZXkgJHtzaG93KGtleSl9LCBidXQgZGlmZmVyZW50ICR7c2hvdyhrKX06IGZpcnN0ICR7c2hvdyhvbGRPcHRpb25zW2tdKX0gYW5kIGxhdGVyICR7c2hvdyhvcHRpb25zW2tdKX0uYClcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYXRvbVxufVxuIl19 |
{ | ||
"name": "atom.storage", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Minimalistic storage implementation for Atoms", | ||
@@ -10,3 +10,3 @@ "main": "lib/atom.storage.js", | ||
"prepublish": "npm run lint && npm run test && npm run dist", | ||
"test": "node_modules/mocha/bin/mocha" | ||
"test": "nyc mocha" | ||
}, | ||
@@ -27,14 +27,15 @@ "repository": { | ||
"devDependencies": { | ||
"babel-cli": "^6.6.5", | ||
"babel-eslint": "^6.0.0", | ||
"babel-cli": "^6.7.5", | ||
"babel-eslint": "^6.0.2", | ||
"babel-plugin-transform-es2015-modules-commonjs": "^6.7.4", | ||
"babel-preset-es2015": "^6.6.0", | ||
"babel-preset-stage-2": "^6.5.0", | ||
"eslint": "^2.5.1", | ||
"eslint": "^2.8.0", | ||
"kefir": "^3.2.1", | ||
"kefir.atom": "^2.0.0", | ||
"kefir.atom": "^2.2.1", | ||
"mocha": "^2.4.5", | ||
"node-localstorage": "^1.1.2", | ||
"ramda": "^0.20.0" | ||
"node-localstorage": "^1.3.0", | ||
"nyc": "^6.4.0", | ||
"ramda": "^0.21.0" | ||
} | ||
} |
140
README.md
@@ -1,4 +0,142 @@ | ||
Minimalistic storage (e.g. localStorage) implementation for Atoms. | ||
Minimalistic | ||
[`Storage`](https://developer.mozilla.org/en-US/docs/Web/API/Storage) | ||
(e.g. [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)) | ||
implementation for Atoms. | ||
[![npm version](https://badge.fury.io/js/atom.storage.svg)](http://badge.fury.io/js/atom.storage) [![Build Status](https://travis-ci.org/calmm-js/atom.storage.svg?branch=master)](https://travis-ci.org/calmm-js/atom.storage) [![](https://david-dm.org/calmm-js/atom.storage.svg)](https://david-dm.org/calmm-js/atom.storage) [![](https://david-dm.org/calmm-js/atom.storage/dev-status.svg)](https://david-dm.org/calmm-js/atom.storage#info=devDependencies) [![Gitter](https://img.shields.io/gitter/room/calmm-js/chat.js.svg?style=flat-square)](https://gitter.im/calmm-js/chat) | ||
## Usage | ||
You must first provide an `Atom` implementation. You can use either | ||
```js | ||
import Atom from "bacon.atom" | ||
``` | ||
or | ||
```js | ||
import Atom from "kefir.atom" | ||
``` | ||
for example. See [`bacon.atom`](https://github.com/calmm-js/bacon.atom) and | ||
[`kefir.atom`](https://github.com/calmm-js/kefir.atom) for details. | ||
The default import | ||
```js | ||
import Stored from "atom.storage" | ||
``` | ||
is a function to create an atom whose contents are stored. | ||
### Creating a Stored atom | ||
To create an atom whose contents are stored, you pass a key, a default value, | ||
the desired `Atom` constructor, and the desired | ||
[`Storage`](https://developer.mozilla.org/en-US/docs/Web/API/Storage) object to | ||
the `Stored` constructor. For example: | ||
```js | ||
const stored = Stored({key: "my-stored-model", | ||
value: defaultValue, | ||
Atom, | ||
storage: localStorage}) | ||
``` | ||
The given default value is only used when the given storage does not already | ||
contain a value for the given key. | ||
The value of the atom is converted to a string by calling | ||
[`JSON.stringify`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). | ||
Note that when a stored atom is created, the (default) value is not stored. The | ||
value is stored only after a `modify` method call that actually results in a new | ||
value for the stored atom. | ||
### Sharing | ||
When two (or more) stored atoms are created with the same storage and key, the | ||
implementation only actually creates an atom on the first call. This means that | ||
in | ||
```js | ||
const stored1 = Stored({key: "my-stored-model", | ||
value: defaultValue, | ||
Atom, | ||
storage: localStorage}) | ||
const stored2 = Stored({key: "my-stored-model", | ||
value: defaultValue, | ||
Atom, | ||
storage: localStorage}) | ||
``` | ||
the objects `stored1` and `stored2` are the one and same object and `stored1 === | ||
stored2` is `true`. | ||
### Full options | ||
The full argument object to `Stored` can be described as follows: | ||
```js | ||
{key: String, | ||
value: JSON, | ||
Atom: JSON => AbstractMutable, | ||
storage: Storage, | ||
time: Maybe Milliseconds, | ||
schema: Maybe (Number | Boolean | String | null), | ||
debounce: Maybe Milliseconds} | ||
``` | ||
The `time`, if specified, is the number of milliseconds after which the value is | ||
considered to have expired. If not specified, the value never expires. | ||
The `schema`, if specified, is stored with the value, and checked when a stored | ||
atom is created. If the stored `schema` is not equal, as determined by `===`, | ||
to the given value, then the stored value is ignored and the given default is | ||
used instead. | ||
The `debounce`, if specified, is the debounce period, in milliseconds, to use | ||
for storing values. If not specified, values are stored immediately. Note that | ||
`debounce: 0` is different from no debounce. | ||
### Expiring | ||
The named export | ||
```js | ||
import {expireNow} from "atom.storage" | ||
``` | ||
is a function that takes a `{storage, regex}` argument object. `expireNow` goes | ||
through items in the `storage`, whose keys match the given `regex`, and removes | ||
items that have expired. You typically call `expireNow` once immediately or | ||
shortly after your app starts. For example: | ||
```js | ||
expireNow({storage: localStorage, regex: /^my-unique-app-prefix:/}) | ||
``` | ||
### Combining with Undo | ||
Even though `Stored` [shares atoms with the same storage and key](#sharing), | ||
`Stored` directly returns the shared object it constructs with `Atom`. This | ||
means that you can combine `Stored` with more complex ways to create atoms. In | ||
particular, you can combine `Stored` with `Undo` from | ||
[`atom.undo`](https://github.com/calmm-js/atom.undo). You can decide whether | ||
you create an `Undo` atom with `Stored`: | ||
```js | ||
const storesFullHistory = | ||
Undo({value, Atom: value => Stored({key, value, storage, Atom})}) | ||
``` | ||
Or a stored `Atom` with `Undo`: | ||
```js | ||
const storesLatestValue = | ||
Stored({key, value, storage, Atom: value => Undo({value, Atom})}) | ||
``` | ||
Both of these combinations return an undoable atom and can be useful. |
@@ -0,1 +1,13 @@ | ||
const storages = new WeakMap() | ||
let usedOptions | ||
if (process.NODE_ENV !== "production") | ||
usedOptions = new WeakMap() | ||
const getAtoms = storage => { | ||
let atoms = storages.get(storage) | ||
if (!atoms) | ||
storages.set(storage, atoms = {}) | ||
return atoms | ||
} | ||
const tryParse = json => { | ||
@@ -27,5 +39,11 @@ try { | ||
export const expireNow = ({storage, regex}) => { | ||
export const unsafeDeleteAtom = ({storage, key}) => { | ||
const atoms = getAtoms(storage) | ||
delete atoms[key] | ||
} | ||
export const expireNow = ({storage, regex, unsafeDeleteAtoms}) => { | ||
for (let i=0; i<storage.length; ++i) { | ||
const key = storage.key(i) | ||
if (!regex.test(key)) | ||
@@ -38,33 +56,57 @@ continue | ||
if (data.expires <= Date.now()) | ||
if (data.expires <= Date.now()) { | ||
storage.removeItem(key) | ||
if (unsafeDeleteAtoms) | ||
unsafeDeleteAtom({storage, key}) | ||
} | ||
} | ||
} | ||
export default ({key, | ||
value, | ||
Atom, | ||
storage, | ||
time, | ||
schema, | ||
debounce}) => { | ||
const atom = Atom(getValue(storage, key, schema, value)) | ||
function show(x) { | ||
switch (typeof x) { | ||
case "string": | ||
case "object": | ||
return JSON.stringify(x) | ||
default: | ||
return `${x}` | ||
} | ||
} | ||
let changes = atom.changes() | ||
if (0 <= debounce) | ||
changes = changes.debounce(debounce) | ||
export default ({key, storage, ...options}) => { | ||
const {value, Atom, time, schema, debounce} = options | ||
changes.onValue(value => { | ||
const data = {value} | ||
const atoms = getAtoms(storage) | ||
if (schema !== undefined) | ||
data.schema = schema | ||
let atom = atoms[key] | ||
if (!atom) { | ||
atoms[key] = atom = Atom(getValue(storage, key, schema, value)) | ||
if (0 <= time) | ||
data.expires = time + Date.now() | ||
if (process.NODE_ENV !== "production") | ||
usedOptions.set(atom, options) | ||
storage.setItem(key, JSON.stringify(data)) | ||
}) | ||
let changes = atom.changes() | ||
if (0 <= debounce) | ||
changes = changes.debounce(debounce) | ||
changes.onValue(value => { | ||
const data = {value} | ||
if (schema !== undefined) | ||
data.schema = schema | ||
if (0 <= time) | ||
data.expires = time + Date.now() | ||
storage.setItem(key, JSON.stringify(data)) | ||
}) | ||
} else if (process.NODE_ENV !== "production") { | ||
const oldOptions = usedOptions.get(atom) | ||
for (const k in options) { | ||
if (options[k] !== oldOptions[k]) | ||
throw new Error(`atom.storage: Created two atoms with same storage and key ${show(key)}, but different ${show(k)}: first ${show(oldOptions[k])} and later ${show(options[k])}.`) | ||
} | ||
} | ||
return atom | ||
} |
import Atom from "kefir.atom" | ||
import R from "ramda" | ||
import * as R from "ramda" | ||
import {LocalStorage} from "node-localstorage" | ||
import Kefir from "kefir" | ||
import * as Kefir from "kefir" | ||
@@ -10,3 +10,6 @@ const localStorage = new LocalStorage("./test-storage~") | ||
const expire = () => expireNow({storage: localStorage, regex: /^test:/}) | ||
const expire = () => | ||
expireNow({unsafeDeleteAtoms: true, // NOTE: This option is not used typically. | ||
storage: localStorage, | ||
regex: /^test:/}) | ||
@@ -43,9 +46,9 @@ const Stored = props => AtomStorage({Atom, storage: localStorage, ...props}) | ||
' x1.set(101);' + | ||
' var x2 = Stored({key: "test:x", value: 21});' + | ||
' return x2;}', | ||
101) | ||
' var x2 = Stored({key: "test:x", value: 10});' + | ||
' return Kefir.combine([x1, Kefir.constant(x1 === x2), x2]);}', | ||
[101, true, 101]) | ||
testEq('{var y = Stored({key: "test:y", value: "a", time: 10});' + | ||
' y.set("b");' + | ||
' return Kefir.later(30).flatMap(() => {' + | ||
' return Kefir.later(100).flatMap(() => {' + | ||
' expire();' + | ||
@@ -55,8 +58,8 @@ ' return Stored({key: "test:y", value: "c", time: 10}) })}', | ||
testEq('{var y = Stored({key: "test:y", value: "a", time: 60});' + | ||
' y.set("b");' + | ||
' return Kefir.later(30).flatMap(() => {' + | ||
testEq('{var z = Stored({key: "test:z", value: "a", time: 1000});' + | ||
' z.set("b");' + | ||
' return Kefir.later(10).flatMap(() => {' + | ||
' expire();' + | ||
' return Stored({key: "test:y", value: "c", time: 10}) })}', | ||
' return Stored({key: "test:z", value: "a", time: 1000}) })}', | ||
"b") | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37158
13
230
143
12
2