@wora/cache-persist
Version:
@wora Cache Persist
223 lines • 8.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var jsonSerialize_1 = require("./layers/jsonSerialize");
var prefixLayer_1 = require("./layers/prefixLayer");
var compose_1 = require("./utils/compose");
var createStorage_1 = require("./createStorage");
function promiseResult(execute) {
return Promise.resolve(execute());
}
exports.promiseResult = promiseResult;
function promiseVoid(execute) {
if (execute === void 0) { execute = function () { return undefined; }; }
return promiseResult(execute);
}
exports.promiseVoid = promiseVoid;
var SPLIT = '####';
var NoStorageProxy = {
restore: function () {
return promiseResult(function () {
return undefined;
});
},
push: function (_keys) { return undefined; },
flush: function () { return promiseVoid(); },
getStorage: function () { return undefined; },
};
function StorageProxy(cache, options) {
if (options === void 0) { options = {}; }
var _a = options.prefix, prefix = _a === void 0 ? 'cache' : _a, _b = options.serialize, serialize = _b === void 0 ? true : _b, _c = options.webStorage, webStorage = _c === void 0 ? 'local' : _c, _d = options.mutateKeys, mutateKeys = _d === void 0 ? [] : _d, _e = options.mutateValues, mutateValues = _e === void 0 ? [] : _e, _f = options.errorHandling, errorHandling = _f === void 0 ? function (_cache, _error) { return true; } : _f, _g = options.throttle, throttle = _g === void 0 ? 500 : _g, _h = options.disablePersist, disablePersist = _h === void 0 ? false : _h, _j = options.storage, storage = _j === void 0 ? createStorage_1.createStorage(webStorage) : _j;
var disable = disablePersist || !storage;
if (disable) {
return NoStorageProxy;
}
var restored = false;
var timerId = null;
var inExecution = false;
var resolveFlush;
var rejectFlush;
var promiseFlush;
var queue = [];
if (prefix) {
mutateKeys.unshift(prefixLayer_1.prefixLayer(prefix));
}
if (serialize) {
mutateValues.push(jsonSerialize_1.jsonSerialize);
}
var mutateValue = {
set: compose_1.compose.apply(void 0, mutateValues.map(function (mutate) { return mutate.set; })),
get: compose_1.compose.apply(void 0, mutateValues
.slice()
.reverse()
.map(function (mutate) { return mutate.get; })),
};
var mutateKey = {
set: compose_1.compose.apply(void 0, mutateKeys.map(function (mutate) { return function (key) { return (key != null ? mutate.set(key) : null); }; })),
get: compose_1.compose.apply(void 0, mutateKeys
.slice()
.reverse()
.map(function (mutate) { return function (key) { return (key != null ? mutate.get(key) : null); }; })),
};
if (!storage.multiRemove) {
storage.multiRemove = function (keys) {
var promises = [];
for (var i = 0, l = keys.length; i < l; i++) {
promises.push(storage.removeItem(keys[i]));
}
return Promise.all(promises)
.then(function () { return undefined; })
.catch(function (error) {
throw error;
});
};
storage.multiGet = function (keys) {
var promises = [];
var _loop_1 = function (i, l) {
var key = keys[i];
promises.push(storage
.getItem(key)
.then(function (value) { return [key, value]; })
.catch(function (error) {
throw error;
}));
};
for (var i = 0, l = keys.length; i < l; i++) {
_loop_1(i, l);
}
return Promise.all(promises);
};
storage.multiSet = function (items) {
var promises = [];
for (var i = 0, l = items.length; i < l; i++) {
var _a = items[i], key = _a[0], value = _a[1];
promises.push(storage.setItem(key, value));
}
return Promise.all(promises)
.then(function () { return undefined; })
.catch(function (error) {
throw error;
});
};
}
function restore() {
return storage
.getAllKeys()
.then(function (keys) { return storage.multiGet(keys.filter(function (key) { return !!mutateKey.get(key); })); })
.then(function (data) {
if (data.length === 0) {
restored = true;
return undefined;
}
var result = {};
for (var i = 0, l = data.length; i < l; i++) {
var _a = data[i], key = _a[0], value = _a[1];
var keyMutate = mutateKey.get(key);
var valueMutate = mutateValue.get(value);
result[keyMutate] = valueMutate;
}
restored = true;
return result;
});
}
function push(key) {
var newKey = mutateKey.set(key);
if (newKey && restored) {
queue.push("" + key + SPLIT + newKey);
debounced();
}
}
function flush() {
if (queue.length === 0) {
return Promise.resolve();
}
if (!inExecution) {
cancelTimer();
return execute();
}
if (!promiseFlush) {
promiseFlush = new Promise(function (resolve, reject) {
rejectFlush = reject;
resolveFlush = resolve;
});
debounced();
}
return promiseFlush;
}
function timerExpired() {
if (!inExecution) {
execute();
}
setNextTimer();
}
function cancelTimer() {
if (!timerId)
return;
clearTimeout(timerId);
timerId = null;
}
function setNextTimer() {
cancelTimer();
timerId = setTimeout(timerExpired, throttle);
}
function debounced() {
if (!timerId) {
setNextTimer();
}
}
function execute() {
inExecution = true;
var flushKeys = Array.from(new Set(queue.splice(0)));
var resolve = resolveFlush;
var reject = rejectFlush;
resolveFlush = null;
rejectFlush = null;
promiseFlush = null;
var dispose = function (error) {
if (error) {
if (reject) {
reject();
}
errorHandling(cache, error);
}
else {
if (resolve) {
resolve();
}
}
cancelTimer();
inExecution = false;
if (queue.length > 0) {
debounced();
}
};
var removeKeys = [];
var setValues = [];
for (var i = 0, l = flushKeys.length; i < l; i++) {
var _a = flushKeys[i].split(SPLIT), key = _a[0], newKey = _a[1];
if (cache.has(key)) {
setValues.push([newKey, mutateValue.set(cache.get(key))]);
}
else {
removeKeys.push(newKey);
}
}
var promises = [];
if (removeKeys.length > 0) {
promises.push(storage.multiRemove(removeKeys));
}
if (setValues.length > 0) {
promises.push(storage.multiSet(setValues));
}
return Promise.all(promises)
.then(function () { return dispose(); })
.catch(function (error) { return dispose(error); });
}
return {
push: push,
restore: restore,
flush: flush,
getStorage: function () { return storage; },
};
}
exports.StorageProxy = StorageProxy;
//# sourceMappingURL=StorageProxy.js.map