mastercache
Version:
Multi-tier cache module for Node.js. Redis, Upstash, CloudfareKV, File, in-memory and others drivers
1 lines • 18.3 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/cache/factory-runner.ts","../../../../../node_modules/.pnpm/p-timeout@6.1.3/node_modules/p-timeout/index.js","../../../src/libs/exception.ts","../../../src/errors.ts","../../../src/events/cache/cache-hit.ts","../../../src/events/cache/cache-miss.ts","../../../src/events/cache/cache-cleared.ts","../../../src/events/cache/cache-deleted.ts","../../../src/events/cache/cache-written.ts","../../../src/events/bus/bus-message-received.ts","../../../src/events/bus/bus-message-published.ts","../../../src/events/index.ts"],"sourcesContent":["import pTimeout from 'p-timeout';\nimport type { MutexInterface } from 'async-mutex';\n\nimport type { Locks } from './locks';\nimport * as exceptions from '../errors';\nimport { events } from '../events/index';\nimport type { CacheStack } from './stack/cache-stack';\nimport type { GetSetFactory } from '../types/helpers';\nimport type { CacheStackWriter } from './stack/cache-stack-writer';\nimport type { CacheEntryOptions } from './cache-entry/cache-entry-options';\n\n/**\n * Factory Runner is responsible for executing factories\n */\nexport class FactoryRunner {\n #stack: CacheStack;\n #stackWriter: CacheStackWriter;\n #locks: Locks;\n\n constructor(stack: CacheStack, stackWriter: CacheStackWriter, locks: Locks) {\n this.#stack = stack;\n this.#stackWriter = stackWriter;\n this.#locks = locks;\n }\n\n async saveBackgroundFactoryResult(\n key: string,\n factoryResult: unknown,\n options: CacheEntryOptions,\n lockReleaser: MutexInterface.Releaser,\n ) {\n await this.#stackWriter.set(key, factoryResult, options);\n this.#locks.release(key, lockReleaser);\n }\n\n async writeFactoryResult(\n key: string,\n item: unknown,\n options: CacheEntryOptions,\n lockReleaser: MutexInterface.Releaser,\n ) {\n await this.#stackWriter.set(key, item, options);\n\n this.#stack.emit(new events.CacheMiss(key, this.#stack.name));\n this.#stack.logger.trace({ key, cache: this.#stack.name, opId: options.id }, 'cache miss');\n this.#locks.release(key, lockReleaser);\n }\n\n async run(\n key: string,\n factory: GetSetFactory,\n hasFallback: boolean,\n options: CacheEntryOptions,\n lockReleaser: MutexInterface.Releaser,\n ) {\n const timeoutDuration = options.factoryTimeout(hasFallback);\n const timeoutException =\n timeoutDuration === options.timeouts?.hard\n ? exceptions.E_FACTORY_HARD_TIMEOUT\n : exceptions.E_FACTORY_SOFT_TIMEOUT;\n\n const promisifiedFactory = async () => {\n return await factory({ setTtl: (ttl) => options.setLogicalTtl(ttl) });\n };\n\n const factoryPromise = promisifiedFactory();\n\n const factoryResult = await pTimeout(factoryPromise, {\n milliseconds: timeoutDuration ?? Number.POSITIVE_INFINITY,\n fallback: async () => {\n factoryPromise\n .then((result) => this.saveBackgroundFactoryResult(key, result, options, lockReleaser))\n .catch(() => {})\n .finally(() => this.#locks.release(key, lockReleaser));\n\n throw new timeoutException();\n },\n });\n\n await this.writeFactoryResult(key, factoryResult, options, lockReleaser);\n return factoryResult;\n }\n}\n","export class TimeoutError extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = 'TimeoutError';\n\t}\n}\n\n/**\nAn error to be thrown when the request is aborted by AbortController.\nDOMException is thrown instead of this Error when DOMException is available.\n*/\nexport class AbortError extends Error {\n\tconstructor(message) {\n\t\tsuper();\n\t\tthis.name = 'AbortError';\n\t\tthis.message = message;\n\t}\n}\n\n/**\nTODO: Remove AbortError and just throw DOMException when targeting Node 18.\n*/\nconst getDOMException = errorMessage => globalThis.DOMException === undefined\n\t? new AbortError(errorMessage)\n\t: new DOMException(errorMessage);\n\n/**\nTODO: Remove below function and just 'reject(signal.reason)' when targeting Node 18.\n*/\nconst getAbortedReason = signal => {\n\tconst reason = signal.reason === undefined\n\t\t? getDOMException('This operation was aborted.')\n\t\t: signal.reason;\n\n\treturn reason instanceof Error ? reason : getDOMException(reason);\n};\n\nexport default function pTimeout(promise, options) {\n\tconst {\n\t\tmilliseconds,\n\t\tfallback,\n\t\tmessage,\n\t\tcustomTimers = {setTimeout, clearTimeout},\n\t} = options;\n\n\tlet timer;\n\n\tconst wrappedPromise = new Promise((resolve, reject) => {\n\t\tif (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) {\n\t\t\tthrow new TypeError(`Expected \\`milliseconds\\` to be a positive number, got \\`${milliseconds}\\``);\n\t\t}\n\n\t\tif (options.signal) {\n\t\t\tconst {signal} = options;\n\t\t\tif (signal.aborted) {\n\t\t\t\treject(getAbortedReason(signal));\n\t\t\t}\n\n\t\t\tconst abortHandler = () => {\n\t\t\t\treject(getAbortedReason(signal));\n\t\t\t};\n\n\t\t\tsignal.addEventListener('abort', abortHandler, {once: true});\n\n\t\t\tpromise.finally(() => {\n\t\t\t\tsignal.removeEventListener('abort', abortHandler);\n\t\t\t});\n\t\t}\n\n\t\tif (milliseconds === Number.POSITIVE_INFINITY) {\n\t\t\tpromise.then(resolve, reject);\n\t\t\treturn;\n\t\t}\n\n\t\t// We create the error outside of `setTimeout` to preserve the stack trace.\n\t\tconst timeoutError = new TimeoutError();\n\n\t\ttimer = customTimers.setTimeout.call(undefined, () => {\n\t\t\tif (fallback) {\n\t\t\t\ttry {\n\t\t\t\t\tresolve(fallback());\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (typeof promise.cancel === 'function') {\n\t\t\t\tpromise.cancel();\n\t\t\t}\n\n\t\t\tif (message === false) {\n\t\t\t\tresolve();\n\t\t\t} else if (message instanceof Error) {\n\t\t\t\treject(message);\n\t\t\t} else {\n\t\t\t\ttimeoutError.message = message ?? `Promise timed out after ${milliseconds} milliseconds`;\n\t\t\t\treject(timeoutError);\n\t\t\t}\n\t\t}, milliseconds);\n\n\t\t(async () => {\n\t\t\ttry {\n\t\t\t\tresolve(await promise);\n\t\t\t} catch (error) {\n\t\t\t\treject(error);\n\t\t\t}\n\t\t})();\n\t});\n\n\tconst cancelablePromise = wrappedPromise.finally(() => {\n\t\tcancelablePromise.clear();\n\t});\n\n\tcancelablePromise.clear = () => {\n\t\tcustomTimers.clearTimeout.call(undefined, timer);\n\t\ttimer = undefined;\n\t};\n\n\treturn cancelablePromise;\n}\n","/*\n * @poppinss/utils\n *\n * (c) Poppinss\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { format } from 'node:util';\n\n/**\n * Extended Error object with the option to set error `status` and `code`.\n * At AdonisJs, we prefer exceptions with proper error codes to handle\n * them without relying on message pattern matching.\n *\n * ```js\n * new Exception('message', 500, 'E_RUNTIME_EXCEPTION')\n * ```\n */\nexport class Exception extends Error {\n /**\n * Static properties to defined on the exception once\n * and then re-use them\n */\n declare static help?: string;\n declare static code?: string;\n declare static status?: number;\n declare static message?: string;\n\n /**\n * Name of the class that raised the exception.\n */\n name: string;\n\n /**\n * Optional help description for the error. You can use it to define additional\n * human readable information for the error.\n */\n declare help?: string;\n\n /**\n * A machine readable error code. This will allow the error handling logic\n * to narrow down exceptions based upon the error code.\n */\n declare code?: string;\n\n /**\n * A status code for the error. Usually helpful when converting errors\n * to HTTP responses.\n */\n status: number;\n\n constructor(message?: string, options?: ErrorOptions & { code?: string; status?: number }) {\n super(message, options);\n\n const ErrorConstructor = this.constructor as typeof Exception;\n\n this.name = ErrorConstructor.name;\n this.message = message || ErrorConstructor.message || '';\n this.status = options?.status || ErrorConstructor.status || 500;\n\n const code = options?.code || ErrorConstructor.code;\n if (code !== undefined) {\n this.code = code;\n }\n\n const help = ErrorConstructor.help;\n if (help !== undefined) {\n this.help = help;\n }\n\n Error.captureStackTrace(this, ErrorConstructor);\n }\n\n get [Symbol.toStringTag]() {\n return this.constructor.name;\n }\n\n toString() {\n if (this.code) {\n return `${this.name} [${this.code}]: ${this.message}`;\n }\n return `${this.name}: ${this.message}`;\n }\n}\n\n/**\n * Helper to create anonymous error classes\n */\nexport function createError<T extends any[] = never>(\n message: string,\n code: string,\n status?: number\n): typeof Exception & T extends never\n ? { new (args?: any, options?: ErrorOptions): Exception }\n : { new (args: T, options?: ErrorOptions): Exception } {\n return class extends Exception {\n static message = message;\n static code = code;\n static status = status;\n\n constructor(args: T, options?: ErrorOptions) {\n super(format(message, ...(args || [])), options);\n this.name = 'Exception';\n }\n };\n}","import { createError } from './libs/exception';\n\nexport const E_FACTORY_SOFT_TIMEOUT = createError(\n 'Factory has timed out after waiting for soft timeout',\n 'E_FACTORY_SOFT_TIMEOUT',\n);\n\nexport const E_FACTORY_HARD_TIMEOUT = createError(\n 'Factory has timed out after waiting for hard timeout',\n 'E_FACTORY_HARD_TIMEOUT',\n);\n","import type { CacheEvent } from '../../types/main';\n\n/**\n * Event emitted when a cache entry is hit\n */\nexport class CacheHit implements CacheEvent {\n name = 'cache:hit' as const;\n\n constructor(\n readonly key: string,\n readonly value: any,\n readonly store: string,\n readonly graced: boolean = false,\n ) {}\n\n toJSON() {\n return {\n key: this.key,\n value: this.value,\n store: this.store,\n graced: this.graced,\n };\n }\n}\n","import type { CacheEvent } from '../../types/main';\n\n/**\n * Event emitted when a cache entry is missed\n */\nexport class CacheMiss implements CacheEvent {\n name = 'cache:miss' as const;\n\n constructor(\n readonly key: string,\n readonly store: string,\n ) {}\n\n toJSON() {\n return {\n key: this.key,\n store: this.store,\n };\n }\n}\n","import type { CacheEvent } from '../../types/main';\n\n/**\n * Event emitted when a cache store is cleared\n * using `.clear()`\n */\nexport class CacheCleared implements CacheEvent {\n name = 'cache:cleared' as const;\n\n constructor(readonly store: string) {}\n\n toJSON() {\n return {\n store: this.store,\n };\n }\n}\n","import type { CacheEvent } from '../../types/main';\n\n/**\n * Event emitted when a cache entry is deleted\n * using `.delete()` or `.deleteMany()`\n */\nexport class CacheDeleted implements CacheEvent {\n name = 'cache:deleted' as const;\n\n constructor(\n readonly key: string,\n readonly store: string,\n ) {}\n\n toJSON() {\n return {\n key: this.key,\n store: this.store,\n };\n }\n}\n","import type { CacheEvent } from '../../types/main';\n\n/**\n * Event emitted when a cache entry is written\n * using `set`,`getOrSet`\n */\nexport class CacheWritten implements CacheEvent {\n name = 'cache:written' as const;\n\n constructor(\n readonly key: string,\n readonly value: any,\n readonly store: string,\n ) {}\n\n toJSON() {\n return {\n key: this.key,\n store: this.store,\n value: this.value,\n };\n }\n}\n","import type { CacheBusMessage, CacheEvent } from '../../types/main';\n\n/**\n * Event when the bus receives a message\n */\nexport class BusMessageReceived implements CacheEvent {\n name = 'bus:message:received' as const;\n\n constructor(readonly message: CacheBusMessage) {}\n\n toJSON() {\n return {\n keys: this.message.keys,\n type: this.message.type,\n };\n }\n}\n","import type { CacheBusMessage, CacheEvent } from '../../types/main';\n\n/**\n * Event when the bus publishes a message\n */\nexport class BusMessagePublished implements CacheEvent {\n name = 'bus:message:published' as const;\n\n constructor(readonly message: CacheBusMessage) {}\n\n toJSON() {\n return {\n keys: this.message.keys,\n type: this.message.type,\n };\n }\n}\n","import { CacheHit } from './cache/cache-hit';\nimport { CacheMiss } from './cache/cache-miss';\nimport { CacheCleared } from './cache/cache-cleared';\nimport { CacheDeleted } from './cache/cache-deleted';\nimport { CacheWritten } from './cache/cache-written';\nimport { BusMessageReceived } from './bus/bus-message-received';\nimport { BusMessagePublished } from './bus/bus-message-published';\n\nexport const events = {\n BusMessagePublished,\n BusMessageReceived,\n CacheHit,\n CacheMiss,\n CacheCleared,\n CacheDeleted,\n CacheWritten,\n};\n"],"mappings":"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","names":[]}