UNPKG

@beenotung/tslib

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