UNPKG

@melchyore/adonis-cache

Version:
235 lines (234 loc) 8.07 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const utils_1 = require("@poppinss/utils"); const helpers_1 = require("@poppinss/utils/build/helpers"); const CacheEvent_1 = __importDefault(require("./Events/CacheEvent")); const CacheMissed_1 = __importDefault(require("./Events/CacheMissed")); const CacheKeyWritten_1 = __importDefault(require("./Events/CacheKeyWritten")); const CacheKeyForgotten_1 = __importDefault(require("./Events/CacheKeyForgotten")); const CacheHit_1 = __importDefault(require("./Events/CacheHit")); const Utils_1 = __importDefault(require("./Utils")); /** * Repository class that will call the appropriate * store methods. * * @export * @class Repository * @implements {RepositoryContract<CacheStoreContract>} */ class Repository { constructor(_store, prefix) { this._store = _store; this.prefix = prefix; } get config() { return this._config; } get driverConfig() { return this._driverConfig; } get getTTL() { return this._config.ttl || Repository.DEFAULT_TTL; } get store() { return this._store; } setConfig(config, driverConfig) { this._config = config; this._driverConfig = driverConfig; this._store.setPrefix(this.prefix); } setEventDispatcher(_emitter) { this.event = _emitter; this.emitter = new CacheEvent_1.default(this._config, _emitter); } async get(key, fallback) { let value = await this._store.get(await this.itemKey(key)); if (this.isNull(value)) { this.emitter.emit(new CacheMissed_1.default(key)); if (fallback) { value = await this.resolveFallback(fallback); } } else { this.emitter.emit(new CacheHit_1.default(key, value)); } return value; } async many(keys) { const records = await this._store.many(keys); for (const [key, value] of Object.entries(records)) { if (this.isNull(value)) { this.emitter.emit(new CacheMissed_1.default(key)); } else { this.emitter.emit(new CacheHit_1.default(key, value)); } } return records; } async has(key) { return (await this._store.has(await this.itemKey(key))) === true; } async missing(key) { return !(await this.has(key)); } async pull(key) { const value = await this.get(key); if (!this.isNull(value)) { await this.forget(key); } return value; } async put(key, value, ttl) { const expiration = this.calculateTTL(ttl); const result = await this._store.put(await this.itemKey(key), value, expiration); if (result) { this.emitter.emit(new CacheKeyWritten_1.default(key, value, expiration)); } return result; } async add(key, value, ttl) { if (typeof this._store['add'] === 'function') { const expiration = this.calculateTTL(ttl); const result = await this._store.add(await this.itemKey(key), value, expiration); if (result) { this.emitter.emit(new CacheKeyWritten_1.default(key, value, expiration)); } return result; } const cachedValue = await this.get(key); if (this.isNull(cachedValue)) { return await this.put(key, value, ttl); } return false; } async set(key, value, ttl) { return await this.put(key, value, ttl); } async increment(key, value = 1) { return await this._store.increment(await this.itemKey(key), value); } async decrement(key, value = 1) { return await this._store.decrement(await this.itemKey(key), value); } async putMany(list, ttl) { const expiration = this.calculateTTL(ttl); const results = await this._store.putMany(list, expiration); let result = {}; for (let i = 0; i < results.length; ++i) { const key = Object.keys(list)[i]; if (results[i] === true) { result[key] = true; this.emitter.emit(new CacheKeyWritten_1.default(key, Object.values(list)[i], expiration)); } else { result[key] = false; } } return result; } async putManyForever(list) { const results = await this._store.putManyForever(list); let result = {}; for (let i = 0; i < results.length; ++i) { const key = Object.keys(list)[i]; if (results[i] === true) { result[key] = true; this.emitter.emit(new CacheKeyWritten_1.default(key, Object.values(list)[i], 0)); } else { result[key] = false; } } return result; } async forever(key, value) { return await this._store.forever(await this.itemKey(key), value); } async forget(key) { const result = await this._store.forget(await this.itemKey(key)); if (result) { this.emitter.emit(new CacheKeyForgotten_1.default(key)); } return result; } async forgetMultiple(keys) { let result = {}; for (const key of keys) { result[key] = await this.forget(key); } return result; } async remember(key, ttl, closure) { if (this.checkClosure(closure)) { let value = await this.get(key); if (!this.isNull(value)) { return value; } value = await closure(); await this.put(key, value, ttl); return value; } } async sear(key, closure) { return await this.rememberForever(key, closure); } async rememberForever(key, closure) { if (this.checkClosure(closure)) { let value = await this.get(key); if (!this.isNull(value)) { return value; } value = await closure(); await this.forever(key, value); return value; } } async flush() { return await this._store.flush(); } async clear() { return await this.flush(); } tags(names) { if (!('tags' in this._store)) { throw new utils_1.Exception('This cache store does not support tagging'); } const taggedCache = this._store.tags(Array.isArray(names) ? names : [names]); taggedCache.setConfig(this._config, this._driverConfig); taggedCache.setEventDispatcher(this.event); return taggedCache; } async itemKey(key) { return key; } calculateTTL(ttl) { if (ttl && ttl < 0) { throw new utils_1.Exception('Expiration time (TTL) cannot be negative'); } const ttlInMilliseconds = Number(helpers_1.string.toMs(`${ttl ?? this.getTTL}s`)); return this._store.calculateTTL(ttlInMilliseconds); } checkClosure(closure) { if (!Utils_1.default.isFunction(closure)) { throw new utils_1.Exception('Closure must be a function'); } return true; } isNull(value) { return value === null || value === undefined; } async resolveFallback(fallback) { let fallbackValue = Utils_1.default.isFunction(fallback) ? await fallback() : fallback; return fallbackValue; } } exports.default = Repository; /* * Default expiration time `ttl` = 1 hour expressed in seconds. */ Repository.DEFAULT_TTL = 60 * 60;