@beenotung/tslib
Version:
utils library in Typescript
105 lines • 4.06 kB
JavaScript
"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