UNPKG

@beenotung/tslib

Version:
105 lines 4.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CachedObjectStore = void 0; const async_store_1 = require("./async-store"); const compare_1 = require("./compare"); const counted_cache_1 = require("./counted-cache"); const store_1 = require("./store"); Symbol.objectCache = Symbol.for('objectCache'); Symbol.cacheSize = Symbol.for('cacheSize'); Symbol.store = Symbol.for('store'); Symbol.asyncStore = Symbol.for('asyncStore'); Symbol.maxCacheSize = Symbol.for('maxCacheSize'); /** * only cache object * raw string item are not cached * */ class CachedObjectStore { constructor(dirpath, maxCacheSize = Number.MAX_SAFE_INTEGER, maxStorageSize = Number.MAX_SAFE_INTEGER) { this[Symbol.objectCache] = new counted_cache_1.CountedCache(); this[Symbol.cacheSize] = 0; this[Symbol.store] = store_1.Store.create(store_1.getLocalStorage(dirpath, maxStorageSize)); this[Symbol.asyncStore] = async_store_1.AsyncStore.create(dirpath); this[Symbol.maxCacheSize] = maxCacheSize; } get [Symbol.storage]() { return this[Symbol.store][Symbol.storage]; } set storage(storage) { const dirpath = storage._location; if (typeof dirpath !== 'string') { throw new Error('cannot swap storage instance without storage._location'); } this[Symbol.store][Symbol.storage] = storage; this[Symbol.asyncStore][Symbol.dirpath] = dirpath; } // cannot be cached, require too much effort to monitor every setItem and removeItem get length() { return this[Symbol.store].length; } clear() { this[Symbol.asyncStore].clear(); this[Symbol.objectCache].clear(); this[Symbol.cacheSize] = 0; } clearCache() { this[Symbol.objectCache].clear(); this[Symbol.cacheSize] = 0; } // do not cache to reduce memory load getItem(key) { return this[Symbol.store].getItem(key); } getObject(key) { if (this[Symbol.objectCache].has(key)) { const data = this[Symbol.objectCache].get(key); if (data !== null) { return data.value; } } const s = this.getItem(key); if (s === null) { return null; } const value = JSON.parse(s); this[Symbol.objectCache].set(key, { size: s.length, value }); return value; } // cannot be cached, require too much effort to monitor every setItem and removeItem key(index) { return this[Symbol.store].key(index); } // cannot be cached, require too much effort to monitor every setItem and removeItem keys() { return this[Symbol.store].keys(); } removeItem(key) { this[Symbol.objectCache].remove(key); this[Symbol.asyncStore].removeItem(key); } setItem(key, value) { this[Symbol.objectCache].remove(key); this[Symbol.asyncStore].setItem(key, value); } setObject(key, value) { const s = JSON.stringify(value); this[Symbol.cacheSize] += s.length; if (this[Symbol.cacheSize] > this[Symbol.maxCacheSize]) { const caches = this[Symbol.objectCache].getAll(); caches.sort((a, b) => compare_1.compare(a[1].count, b[1].count)); for (; this[Symbol.cacheSize] > this[Symbol.maxCacheSize] && caches.length > 0;) { const [key, cache] = caches.pop(); this[Symbol.cacheSize] -= cache.data.size; this[Symbol.objectCache].remove(key); } } this[Symbol.objectCache].set(key, { size: s.length, value }); this[Symbol.asyncStore].setItem(key, s); } static create(dirpath, maxCacheSize = Number.MAX_SAFE_INTEGER, maxStorageSize = Number.MAX_SAFE_INTEGER) { const store = new CachedObjectStore(dirpath, maxCacheSize, maxStorageSize); return store_1.proxyStore(store); } } exports.CachedObjectStore = CachedObjectStore; //# sourceMappingURL=cached-store.js.map