UNPKG

mastercache

Version:

Multi-tier cache module for Node.js. Redis, Upstash, CloudfareKV, File, in-memory and others drivers

169 lines (167 loc) 4.27 kB
// src/serializers/json.ts var JsonSerializer = class { serialize(value) { return JSON.stringify(value); } deserialize(value) { return JSON.parse(value); } }; // src/cache/cache-entry/cache-entry.ts var CacheEntry = class _CacheEntry { /** * The key of the cache item. */ #key; /** * The value of the item. */ #value; /** * The logical expiration is the time in miliseconds when the item * will be considered expired. But, if grace period is enabled, * the item will still be available for a while. */ #logicalExpiration; #earlyExpiration; static #serializer = new JsonSerializer(); constructor(key, item) { this.#key = key; this.#value = item.value; this.#logicalExpiration = item.logicalExpiration; this.#earlyExpiration = item.earlyExpiration; } getValue() { return this.#value; } getKey() { return this.#key; } getLogicalExpiration() { return this.#logicalExpiration; } getEarlyExpiration() { return this.#earlyExpiration; } isLogicallyExpired() { return Date.now() >= this.#logicalExpiration; } isEarlyExpired() { if (!this.#earlyExpiration) { return false; } if (this.isLogicallyExpired()) { return false; } return Date.now() >= this.#earlyExpiration; } static fromDriver(key, item) { return new _CacheEntry(key, this.#serializer.deserialize(item)); } applyFallbackDuration(duration) { this.#logicalExpiration += duration; this.#earlyExpiration = 0; return this; } expire() { this.#logicalExpiration = Date.now() - 100; this.#earlyExpiration = 0; return this; } serialize() { return _CacheEntry.#serializer.serialize({ value: this.#value, logicalExpiration: this.#logicalExpiration, earlyExpiration: this.#earlyExpiration }); } }; // src/cache/facades/remote-cache.ts var RemoteCache = class { #driver; #logger; constructor(driver, logger) { this.#driver = driver; this.#logger = logger.child({ context: "mastercache.remoteCache" }); } /** * Try to execute a cache operation and fallback to a default value * if the operation fails */ async #tryCacheOperation(operation, options, fallbackValue, fn) { try { return await fn(); } catch (error) { this.#logger.error({ error, opId: options.id }, `(${operation}) failed on remote cache`); if (options.suppressL2Errors === false) throw error; return fallbackValue; } } /** * Get an item from the remote cache */ async get(key, options) { return await this.#tryCacheOperation("get", options, void 0, async () => { const value = await this.#driver.get(key); if (value === void 0) return; return CacheEntry.fromDriver(key, value); }); } /** * Set a new item in the remote cache */ async set(key, value, options) { return await this.#tryCacheOperation("set", options, false, async () => { await this.#driver.set(key, value, options.physicalTtl); return true; }); } /** * Delete an item from the remote cache */ async delete(key, options) { return await this.#tryCacheOperation("delete", options, false, async () => { return await this.#driver.delete(key); }); } /** * Delete multiple items from the remote cache */ async deleteMany(keys, options) { return await this.#tryCacheOperation("deleteMany", options, false, async () => { return await this.#driver.deleteMany(keys); }); } /** * Create a new namespace for the remote cache */ namespace(namespace) { return this.#driver.namespace(namespace); } /** * Check if an item exists in the remote cache */ async has(key, options) { return await this.#tryCacheOperation("has", options, false, async () => { return await this.#driver.has(key); }); } /** * Clear the remote cache */ async clear(options) { return await this.#tryCacheOperation("clear", options, false, async () => { return await this.#driver.clear(); }); } /** * Disconnect from the remote cache */ disconnect() { return this.#driver.disconnect(); } }; export { RemoteCache }; //# sourceMappingURL=remote-cache.js.map