UNPKG

cache2

Version:

一个简单的 JavaScript 缓存管理,支持浏览器端和 node 端。

300 lines (292 loc) 9.79 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tslib = require('tslib'); var Emitter = require('emitter-pro'); var cache = {}; var MemoryStorage = (function () { function MemoryStorage(scope) { if (scope === void 0) { scope = 'default'; } this.scope = scope; if (!cache[this.scope]) { cache[this.scope] = {}; } this.data = cache[this.scope]; } MemoryStorage.prototype.getItem = function (key) { return key in this.data ? this.data[key] : null; }; MemoryStorage.prototype.setItem = function (key, value) { this.data[key] = value; }; MemoryStorage.prototype.removeItem = function (key) { delete this.data[key]; }; MemoryStorage.prototype.clear = function () { cache[this.scope] = {}; this.data = cache[this.scope]; }; return MemoryStorage; }()); function randomString() { return Math.random().toString(16).substring(2, 8); } function isStorageSupported(storage) { try { var isSupport = typeof storage === 'object' && storage !== null && !!storage.setItem && !!storage.getItem && !!storage.removeItem; if (isSupport) { var key = randomString() + new Date().getTime(); var value = '1'; storage.setItem(key, value); if (storage.getItem(key) !== value) { return false; } storage.removeItem(key); } return isSupport; } catch (err) { console.error("[cache2] ".concat(storage, " is not supported. The default memory cache will be used.")); return false; } } function parse(value, reviver) { try { return JSON.parse(value, reviver); } catch (err) { return value; } } function stringify(value, replacer) { return JSON.stringify(value, replacer); } var Storage = (function () { function Storage(storage, options) { if (options === void 0) { options = {}; } var isSupported = storage ? isStorageSupported(storage) : false; this.options = tslib.__assign({ needParsed: isSupported, prefix: '' }, options); this.storage = isSupported ? storage : new MemoryStorage(this.options.memoryScope); } Storage.prototype.getKey = function (key) { return this.options.prefix + key; }; Storage.prototype.get = function (key) { var value = this.storage.getItem(this.getKey(key)); return this.options.needParsed ? parse(value, this.options.reviver) : value; }; Storage.prototype.set = function (key, value) { this.storage.setItem(this.getKey(key), this.options.needParsed ? stringify(value, this.options.replacer) : value); }; Storage.prototype.del = function (key) { this.storage.removeItem(this.getKey(key)); }; Storage.prototype.clear = function () { if (typeof this.storage.clear === 'function') { this.storage.clear(); } }; return Storage; }()); var defaultPrefix = 'cache2_'; var defaultNamespace = 'default'; var Cache = (function (_super) { tslib.__extends(Cache, _super); function Cache(namespace, options) { var _this = _super.call(this) || this; var ns = defaultNamespace, opts; if (typeof namespace === 'string') { ns = namespace || defaultNamespace; } else if (typeof namespace === 'object') { opts = namespace; } if (!opts && typeof options === 'object') { opts = options; } _this.options = tslib.__assign({ max: -1, stdTTL: 0, maxStrategy: 'limited', checkperiod: 0, prefix: defaultPrefix }, opts); _this.storage = new Storage(_this.options.storage, tslib.__assign({ memoryScope: ns }, _this.options)); _this.cacheKey = ns; _this.startCheckperiod(); return _this; } Cache.prototype._check = function (key, data) { var ret = true; if (data.t !== 0 && data.t < Date.now()) { ret = false; this.del(key); this.emit('expired', key, data.v); } return ret; }; Cache.prototype._wrap = function (value, ttl) { var now = Date.now(); var currentTtl = typeof ttl === 'number' ? ttl : this.options.stdTTL; var livetime = currentTtl > 0 ? now + currentTtl : 0; return { v: value, t: livetime, n: now }; }; Cache.prototype._isLimited = function (len) { return this.options.max > -1 && len >= this.options.max; }; Cache.prototype._getReplaceKey = function (keys, cacheValues) { var retkey = keys[0]; keys.forEach(function (key) { if (cacheValues[retkey].n > cacheValues[key].n) { retkey = key; } }); return retkey; }; Object.defineProperty(Cache.prototype, "cacheValues", { get: function () { return this.storage.get(this.cacheKey) || {}; }, enumerable: false, configurable: true }); Cache.prototype.setCacheValues = function (values) { this.storage.set(this.cacheKey, values); }; Cache.prototype._getData = function (key, cacheValues) { var data = cacheValues[key]; if (data && this._check(key, data)) { return data; } return; }; Cache.prototype.get = function (key) { var data = this._getData(key, this.cacheValues); return data === null || data === void 0 ? void 0 : data.v; }; Cache.prototype.mget = function (keys) { var _this = this; var ret = {}; if (!Array.isArray(keys)) { return ret; } var cacheValues = this.cacheValues; keys.forEach(function (key) { var data = _this._getData(key, cacheValues); if (data) { ret[key] = data.v; } }); return ret; }; Cache.prototype.getAll = function () { var keys = Object.keys(this.cacheValues); return this.mget(keys); }; Cache.prototype.set = function (key, value, ttl) { if (this.options.max === 0) { return false; } var cacheValues = this.cacheValues; var keys = Object.keys(cacheValues); if (!cacheValues[key] && this._isLimited(keys.length)) { var validKeys = this.keys(); if (this._isLimited(validKeys.length)) { if (this.options.maxStrategy === 'replaced') { var replaceKey = this._getReplaceKey(validKeys, cacheValues); this.del(replaceKey); } else { return false; } } } cacheValues[key] = this._wrap(value, ttl); this.setCacheValues(cacheValues); this.emit('set', key, cacheValues[key].v); return true; }; Cache.prototype.mset = function (keyValueSet) { var _this = this; var ret = true; keyValueSet.forEach(function (item) { var itemSetResult = _this.set(item.key, item.value, item.ttl); if (ret && !itemSetResult) { ret = false; } }); return ret; }; Cache.prototype.del = function (key) { var _this = this; var cacheValues = this.cacheValues; var count = 0; var keys = Array.isArray(key) ? key : [key]; keys.forEach(function (key) { if (cacheValues[key]) { count++; var oldData = cacheValues[key]; delete cacheValues[key]; _this.emit('del', key, oldData.v); } }); if (count > 0) { this.setCacheValues(cacheValues); } return count; }; Cache.prototype.clear = function () { this.storage.del(this.cacheKey); }; Cache.prototype.keys = function () { var _this = this; var cacheValues = this.cacheValues; var keys = Object.keys(cacheValues); return keys.filter(function (key) { return _this._check(key, cacheValues[key]); }); }; Cache.prototype.has = function (key) { return !!this._getData(key, this.cacheValues); }; Cache.prototype.take = function (key) { var ret; var data = this._getData(key, this.cacheValues); if (data) { ret = data.v; this.del(key); } return ret; }; Cache.prototype.ttl = function (key, ttl) { var data = this._getData(key, this.cacheValues); if (data) { return this.set(key, data.v, ttl); } return false; }; Cache.prototype.getTtl = function (key) { var data = this._getData(key, this.cacheValues); return data === null || data === void 0 ? void 0 : data.t; }; Cache.prototype.getLastModified = function (key) { var data = this._getData(key, this.cacheValues); return data === null || data === void 0 ? void 0 : data.n; }; Cache.prototype.startCheckperiod = function () { var _this = this; this.keys(); if (this.options.checkperiod > 0) { clearTimeout(this._checkTimeout); this._checkTimeout = setTimeout(function () { _this.startCheckperiod(); }, this.options.checkperiod); } }; Cache.prototype.stopCheckperiod = function () { clearTimeout(this._checkTimeout); }; return Cache; }(Emitter)); exports.Cache = Cache; exports.Storage = Storage; exports.default = Cache;