@warlock.js/cache 5.24.0 → 5.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +616 -616
  3. package/cjs/index.cjs +21 -1
  4. package/cjs/index.cjs.map +1 -1
  5. package/esm/drivers/base-cache-driver.d.mts +12 -0
  6. package/esm/drivers/base-cache-driver.d.mts.map +1 -1
  7. package/esm/drivers/base-cache-driver.mjs +10 -0
  8. package/esm/drivers/base-cache-driver.mjs.map +1 -1
  9. package/esm/drivers/null-cache-driver.mjs.map +1 -1
  10. package/esm/tagged-cache.d.mts.map +1 -1
  11. package/esm/tagged-cache.mjs +11 -1
  12. package/esm/tagged-cache.mjs.map +1 -1
  13. package/esm/types.d.mts +5 -2
  14. package/esm/types.d.mts.map +1 -1
  15. package/esm/types.mjs.map +1 -1
  16. package/esm/utils.mjs.map +1 -1
  17. package/llms-full.txt +1632 -1631
  18. package/llms.txt +1 -1
  19. package/package.json +3 -3
  20. package/skills/apply-cache-patterns/SKILL.md +95 -95
  21. package/skills/configure-set-options/SKILL.md +96 -96
  22. package/skills/handle-cache-errors/SKILL.md +92 -92
  23. package/skills/observe-cache/SKILL.md +104 -103
  24. package/skills/pick-cache-driver/SKILL.md +121 -121
  25. package/skills/test-cache-code/SKILL.md +219 -219
  26. package/skills/use-cache-atomic/SKILL.md +42 -42
  27. package/skills/use-cache-bulk/SKILL.md +57 -57
  28. package/skills/use-cache-list/SKILL.md +85 -85
  29. package/skills/use-cache-lock/SKILL.md +101 -101
  30. package/skills/use-cache-namespace/SKILL.md +88 -88
  31. package/skills/use-cache-similarity/SKILL.md +94 -94
  32. package/skills/use-cache-update-merge/SKILL.md +84 -84
  33. package/skills/use-cache-utils/SKILL.md +89 -89
  34. package/skills/use-cached-hof/SKILL.md +93 -93
  35. package/skills/use-swr/SKILL.md +104 -104
@@ -343,6 +343,18 @@ declare abstract class BaseCacheDriver<ClientType, Options extends Record<string
343
343
  * Create a tagged cache instance for the given tags
344
344
  */
345
345
  tags(tags: string[]): any;
346
+ /**
347
+ * Emit `invalidated` on behalf of a {@link TaggedCache} created by this
348
+ * driver, once per `invalidate()` call. Listeners cannot fail the
349
+ * invalidation: `emit` isolates them.
350
+ *
351
+ * @internal
352
+ */
353
+ emitTagsInvalidated(data: {
354
+ tags: string[];
355
+ keys: string[];
356
+ durationMs: number;
357
+ }): Promise<void>;
346
358
  /**
347
359
  * {@inheritdoc}
348
360
  *
@@ -1 +1 @@
1
- {"version":3,"file":"base-cache-driver.d.mts","names":[],"sources":["../../../../../../../cache/src/drivers/base-cache-driver.ts"],"mappings":"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"}
1
+ {"version":3,"file":"base-cache-driver.d.mts","names":[],"sources":["../../../../../../../cache/src/drivers/base-cache-driver.ts"],"mappings":"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"}
@@ -526,6 +526,16 @@ var BaseCacheDriver = class {
526
526
  return new TaggedCache(tags, this);
527
527
  }
528
528
  /**
529
+ * Emit `invalidated` on behalf of a {@link TaggedCache} created by this
530
+ * driver, once per `invalidate()` call. Listeners cannot fail the
531
+ * invalidation: `emit` isolates them.
532
+ *
533
+ * @internal
534
+ */
535
+ async emitTagsInvalidated(data) {
536
+ await this.emit("invalidated", data);
537
+ }
538
+ /**
529
539
  * {@inheritdoc}
530
540
  *
531
541
  * Default implementation: read → transform → write, serialized per key in
@@ -1 +1 @@
1
- {"version":3,"file":"base-cache-driver.mjs","names":[],"sources":["../../../../../../../cache/src/drivers/base-cache-driver.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { log } from \"@warlock.js/logger\";\nimport { MemoryCacheList } from \"../list/memory-cache-list\";\nimport { TaggedCache } from \"../tagged-cache\";\nimport type {\n CacheConflictPolicy,\n CacheData,\n CacheDriver,\n CacheEventData,\n CacheEventHandler,\n CacheEventType,\n CacheKey,\n CacheListAccessor,\n CacheOperationType,\n CacheSetOptions,\n CacheSetResult,\n CacheSimilarHit,\n CacheSimilarOptions,\n CacheSwrOptions,\n CacheTtl,\n LockOptions,\n LockOutcome,\n RememberOptions,\n} from \"../types\";\nimport { CacheConfigurationError, CacheUnsupportedError } from \"../types\";\nimport {\n normalizeToOptions,\n parseCacheKey,\n parseTtl,\n resolveTtl,\n safeErrorInfo,\n} from \"../utils\";\n\n/**\n * Normalized form of the 3rd `set` argument.\n *\n * All drivers operate on this shape internally regardless of whether the caller\n * passed a positional TTL, a duration string, or a rich options object.\n */\nexport type NormalizedSetOptions = {\n /**\n * Final TTL in seconds — already merged with the driver-level default\n * (`this.options.ttl`). `Infinity` means \"no expiration\".\n *\n * Always populated. Drivers do NOT need to fall back to `this.ttl`\n * themselves — `resolveSetOptions` does the merge centrally so that\n * every driver respects the configured default without ceremony.\n */\n ttl: number;\n /**\n * Inline tag list, or undefined when none were provided.\n */\n tags?: string[];\n /**\n * Conflict policy. Defaults to `\"upsert\"`.\n */\n onConflict: CacheConflictPolicy;\n /**\n * Optional embedding vector for similarity retrieval. Drivers that do not\n * support similarity must throw {@link CacheUnsupportedError} when this is\n * present (rather than silently dropping it).\n */\n vector?: number[];\n /**\n * Optional freshness deadline as a millisecond timestamp. Set by `swr()`\n * to mark when the entry stops being \"fresh\" and becomes\n * \"stale-but-revalidatable.\" Drivers route this through\n * `prepareDataForStorage` so it persists in the wrapper.\n */\n staleAt?: number;\n};\n\nconst messages = {\n clearing: \"Clearing namespace\",\n cleared: \"Namespace cleared\",\n fetching: \"Fetching key\",\n fetched: \"Key fetched\",\n caching: \"Caching key\",\n cached: \"Key cached\",\n flushing: \"Flushing cache\",\n flushed: \"Cache flushed\",\n removing: \"Removing key\",\n removed: \"Key removed\",\n expired: \"Key expired\",\n notFound: \"Key not found\",\n connecting: \"Connecting to the cache engine.\",\n connected: \"Connected to the cache engine.\",\n disconnecting: \"Disconnecting from the cache engine.\",\n disconnected: \"Disconnected from the cache engine.\",\n connectionFailed: \"Failed to connect to the cache engine.\",\n error: \"Error occurred\",\n};\n\nexport abstract class BaseCacheDriver<\n ClientType,\n Options extends Record<string, any>,\n> implements CacheDriver<ClientType, Options> {\n /**\n * CLient driver\n */\n protected clientDriver!: ClientType;\n\n /**\n * Determine whether to log or not\n */\n protected shouldLog: boolean = true;\n\n /**\n * {@inheritdoc}\n */\n public get client() {\n return (this.clientDriver || this) as unknown as ClientType;\n }\n\n /**\n * Set logging state\n */\n public setLoggingState(shouldLog: boolean) {\n this.shouldLog = shouldLog;\n\n return this;\n }\n\n /**\n * Set client driver\n */\n public set client(client: ClientType) {\n this.clientDriver = client;\n }\n\n /**\n * Get the cache driver name\n */\n public abstract name: string;\n\n /**\n * Options list\n */\n public options!: Options;\n\n /**\n * Event listeners storage\n */\n protected eventListeners: Map<CacheEventType, Set<CacheEventHandler>> =\n new Map();\n\n /**\n * {@inheritdoc}\n */\n public parseKey(key: CacheKey) {\n return parseCacheKey(key, this.options);\n }\n\n /**\n * {@inheritdoc}\n */\n public setOptions(options: Options) {\n this.options = options || {};\n return this;\n }\n\n /**\n * Register an event listener\n */\n public on(event: CacheEventType, handler: CacheEventHandler): this {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(handler);\n return this;\n }\n\n /**\n * Remove an event listener\n */\n public off(event: CacheEventType, handler: CacheEventHandler): this {\n const handlers = this.eventListeners.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n return this;\n }\n\n /**\n * Register a one-time event listener\n */\n public once(event: CacheEventType, handler: CacheEventHandler): this {\n const onceHandler: CacheEventHandler = async (data) => {\n await handler(data);\n this.off(event, onceHandler);\n };\n return this.on(event, onceHandler);\n }\n\n /**\n * Emit an event to all registered listeners\n */\n protected async emit(\n event: CacheEventType,\n data: Partial<CacheEventData> = {},\n ): Promise<void> {\n const handlers = this.eventListeners.get(event);\n if (!handlers || handlers.size === 0) return;\n\n const eventData: CacheEventData = {\n driver: this.name,\n ...data,\n };\n\n // Execute all handlers\n const promises: Promise<void>[] = [];\n for (const handler of handlers) {\n try {\n const result = handler(eventData);\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n this.logError(`Error in event handler for '${event}'`, error);\n }\n }\n\n // Wait for all async handlers\n if (promises.length > 0) {\n await Promise.allSettled(promises);\n }\n }\n\n /**\n * {@inheritdoc}\n */\n public abstract removeNamespace(namespace: string): Promise<any>;\n\n /**\n * {@inheritdoc}\n */\n public abstract set(\n key: CacheKey,\n value: any,\n ttlOrOptions?: CacheTtl | CacheSetOptions,\n ): Promise<any>;\n\n /**\n * Normalize the 3rd argument of a `set` call into a single shape every driver\n * can act on. Handles TTL parsing (number | string | Infinity), `expiresAt` →\n * relative TTL conversion, and mutual-exclusion validation.\n *\n * @throws {CacheConfigurationError} when `ttl` and `expiresAt` are passed together\n * or an unparseable duration string is supplied.\n */\n protected resolveSetOptions(\n ttlOrOptions?: CacheTtl | CacheSetOptions,\n ): NormalizedSetOptions {\n const options = normalizeToOptions(ttlOrOptions);\n\n return {\n ttl: resolveTtl(options.ttl, options.expiresAt, this.ttl),\n tags: options.tags,\n onConflict: options.onConflict ?? \"upsert\",\n vector: options.vector,\n staleAt: options.staleAt,\n };\n }\n\n /**\n * Resolve the union of cache keys associated with any of the given tags.\n * Used by `similar()` to narrow the candidate pool before similarity ranking.\n *\n * Returns `null` when no tags are passed (callers should treat that as \"no filter\").\n * Keys come back parsed (prefixed) — the index stores them un-prefixed, but\n * callers match them against their own parsed storage keys.\n */\n protected async getKeysForTags(\n tags: string[] | undefined,\n ): Promise<Set<string> | null> {\n if (!tags || tags.length === 0) {\n return null;\n }\n\n const allKeys = new Set<string>();\n for (const tag of tags) {\n const keys = await this.tagMembers(`cache:tags:${tag}`);\n for (const k of keys) {\n allKeys.add(this.parseKey(k));\n }\n }\n\n return allKeys;\n }\n\n // ============================================================\n // Tag index primitives\n // ============================================================\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: the index is an ordinary entry holding a string\n * array, read-modified-written under {@link runSerialized} — correct within\n * THIS process only. Drivers with a native primitive override it (redis SET,\n * pg atomic upsert, the in-process drivers' {@link InMemoryTagIndex}).\n */\n public async tagAdd(tagKey: CacheKey, members: string[]): Promise<void> {\n if (members.length === 0) {\n return;\n }\n\n await this.runSerialized(this.parseKey(tagKey), async () => {\n const current = await this.readTagArray(tagKey);\n const merged = new Set(current);\n\n for (const member of members) {\n merged.add(member);\n }\n\n if (merged.size !== current.length) {\n await this.set(tagKey, [...merged], Infinity);\n }\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async tagMembers(tagKey: CacheKey): Promise<string[]> {\n return this.readTagArray(tagKey);\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: serialized read-filter-write (process-local); an\n * emptied index is removed.\n */\n public async tagRemove(tagKey: CacheKey, members: string[]): Promise<void> {\n if (members.length === 0) {\n return;\n }\n\n await this.runSerialized(this.parseKey(tagKey), async () => {\n const current = await this.readTagArray(tagKey);\n const dropped = new Set(members);\n const kept = current.filter((member) => !dropped.has(member));\n\n if (kept.length === current.length) {\n return;\n }\n\n if (kept.length === 0) {\n await this.remove(tagKey);\n } else {\n await this.set(tagKey, kept, Infinity);\n }\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async tagDelete(tagKey: CacheKey): Promise<void> {\n await this.runSerialized(this.parseKey(tagKey), () => this.remove(tagKey));\n }\n\n /**\n * The index stored as a plain entry, or `[]`. Non-string members (a corrupted\n * or foreign value) are ignored rather than trusted.\n */\n protected async readTagArray(tagKey: CacheKey): Promise<string[]> {\n const value = await this.get(tagKey);\n\n if (!Array.isArray(value)) {\n return [];\n }\n\n return value.filter((member): member is string => typeof member === \"string\");\n }\n\n /**\n * Apply tag relationships after a successful write. Called by drivers once\n * the value is in storage.\n *\n * Pass the caller's key, not the parsed one: the tag index stores keys\n * un-prefixed so `invalidate()` can delete them through `remove(key)`.\n */\n protected async applyTags(key: CacheKey, tags: string[]): Promise<void> {\n if (tags.length === 0) {\n return;\n }\n\n const tagged = this.tags(tags);\n await (tagged as TaggedCache).storeTagRelationship(key);\n }\n\n /**\n * {@inheritdoc}\n */\n public abstract get(key: CacheKey): Promise<any>;\n\n /**\n * {@inheritdoc}\n */\n public abstract remove(key: CacheKey): Promise<void>;\n\n /**\n * {@inheritdoc}\n */\n public abstract flush(): Promise<void>;\n\n /**\n * {@inheritdoc}\n */\n public async has(key: CacheKey): Promise<boolean> {\n const value = await this.get(key);\n // Event is emitted by get() method\n return value !== null;\n }\n\n /**\n * In-flight `remember()` computations, one per parsed key (stampede guard).\n */\n protected rememberInFlight: Map<string, Promise<any>> = new Map();\n\n /**\n * In-flight `swr()` cold-miss fetches, one per parsed key.\n */\n protected swrFetchInFlight: Map<string, Promise<any>> = new Map();\n\n /**\n * In-flight `swr()` stale-window background refreshes, one per parsed key.\n */\n protected swrRefreshes: Map<string, Promise<void>> = new Map();\n\n /**\n * Per-key serialization chains for the in-process read-modify-write\n * operations (`update`, and the default `increment` / `pull`). Kept apart\n * from the stampede maps so a `remember()` can never break an update chain,\n * and never receives an unrelated promise.\n */\n protected updateChains: Map<string, Promise<any>> = new Map();\n\n /**\n * Run `task` once per key at a time: concurrent callers for the same\n * `parsedKey` share the in-flight promise registered in `inFlight`.\n */\n protected singleFlight<T>(\n inFlight: Map<string, Promise<any>>,\n parsedKey: string,\n task: () => Promise<T>,\n ): Promise<T> {\n const existing = inFlight.get(parsedKey);\n\n if (existing) {\n return existing as Promise<T>;\n }\n\n const promise: Promise<T> = task().finally(() => {\n if (inFlight.get(parsedKey) === promise) {\n inFlight.delete(parsedKey);\n }\n });\n\n inFlight.set(parsedKey, promise);\n\n return promise;\n }\n\n /**\n * Chain `task` after every earlier serialized task for the same key, so\n * read-modify-write callers in THIS process run one at a time. This is\n * process-local: it does not coordinate with other servers.\n */\n protected runSerialized<T>(parsedKey: string, task: () => Promise<T>): Promise<T> {\n const previous = this.updateChains.get(parsedKey) ?? Promise.resolve();\n\n const next = previous.catch(() => undefined).then(task);\n\n this.updateChains.set(parsedKey, next);\n\n // Clean up the slot once this link finishes, but only if nobody chained a\n // follow-up onto it meanwhile. The trailing catch keeps a rejected link\n // from surfacing as an unhandled rejection here (the caller still sees it).\n next\n .finally(() => {\n if (this.updateChains.get(parsedKey) === next) {\n this.updateChains.delete(parsedKey);\n }\n })\n .catch(() => undefined);\n\n return next;\n }\n\n /**\n * {@inheritdoc}\n */\n public async remember(\n key: CacheKey,\n ttlOrOptions: CacheTtl | RememberOptions,\n callback: () => Promise<any>,\n ): Promise<any> {\n const parsedKey = this.parseKey(key);\n\n // The options-form lets callers forward tags / driver-override through to\n // the cache-miss write. Normalize both shapes into a single CacheSetOptions\n // blob so there's one path from here on.\n const setOptions = this.normalizeRememberOptions(ttlOrOptions);\n\n // Only a real miss (`null`) recomputes: cached falsy values such as\n // `0`, `false` and `\"\"` are returned as-is.\n const cachedValue = await this.get(key);\n\n if (cachedValue !== null && cachedValue !== undefined) {\n return cachedValue;\n }\n\n return this.singleFlight(this.rememberInFlight, parsedKey, async () => {\n const result = await callback();\n\n await this.set(key, result, setOptions);\n\n return result;\n });\n }\n\n /**\n * Resolve the TTL-or-options arg of `remember` into a `CacheSetOptions` object\n * that can be passed straight to `set()`. Keeps the implementation unbranched.\n */\n protected normalizeRememberOptions(\n ttlOrOptions: CacheTtl | RememberOptions,\n ): CacheSetOptions {\n if (typeof ttlOrOptions === \"number\" || typeof ttlOrOptions === \"string\") {\n return { ttl: ttlOrOptions };\n }\n\n return {\n ttl: ttlOrOptions.ttl,\n tags: ttlOrOptions.tags,\n };\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: read raw entry, branch on freshness/staleness,\n * trigger background refresh in the stale window, fall through to\n * `callback` on miss/expiry. Concurrent cold-miss callers share one fetch\n * ({@link swrFetchInFlight}); concurrent stale-window callers share one\n * background refresh ({@link swrRefreshes}).\n *\n * Drivers without a real {@link getEntry} override degrade gracefully —\n * the synthetic entry has no `staleAt`, which the freshness check treats\n * as \"always fresh,\" so SWR behaves like a TTL-only cached read on those\n * drivers (no background refresh, but no double-fetch either).\n */\n public async swr<T = any>(\n key: CacheKey,\n options: CacheSwrOptions,\n callback: () => Promise<T>,\n ): Promise<T> {\n const parsedKey = this.parseKey(key);\n const freshSeconds = parseTtl(options.freshTtl);\n const staleSeconds = parseTtl(options.staleTtl);\n\n if (staleSeconds <= freshSeconds) {\n throw new Error(\n `cache.swr: 'staleTtl' (${staleSeconds}s) must be greater than 'freshTtl' (${freshSeconds}s).`,\n );\n }\n\n const entry = await this.getEntry(key);\n const now = Date.now();\n\n const isExpired = entry?.expiresAt !== undefined && entry.expiresAt <= now;\n\n if (!entry || isExpired) {\n return this.singleFlight(this.swrFetchInFlight, parsedKey, () =>\n this.swrFetchAndStore<T>(key, options, callback, freshSeconds, staleSeconds),\n );\n }\n\n const isFresh = entry.staleAt === undefined || entry.staleAt > now;\n\n if (isFresh) {\n return entry.data as T;\n }\n\n this.scheduleSwrRefresh<T>(\n parsedKey,\n key,\n options,\n callback,\n freshSeconds,\n staleSeconds,\n );\n\n return entry.data as T;\n }\n\n /**\n * Read the raw {@link CacheData} wrapper for a key, including any\n * `expiresAt` / `staleAt` metadata. Default implementation falls back to\n * `get()` and synthesizes a metadata-less wrapper — drivers that store\n * the wrapper directly (memory, lru, file, redis, pg, mock) override\n * this to return real metadata so SWR can branch on freshness.\n */\n protected async getEntry(key: CacheKey): Promise<CacheData | null> {\n const value = await this.get(key);\n\n if (value === null) {\n return null;\n }\n\n return { data: value };\n }\n\n /**\n * Remaining lifetime of an existing entry, in seconds — used by TTL-preserving\n * writes such as `update()` / `merge()` when the caller passes no explicit\n * `ttl`.\n *\n * - `Infinity` — the entry exists with no expiry (preserve \"never expires\").\n * - positive number — seconds left before the entry expires.\n * - `undefined` — the key is missing or already past its deadline; the caller\n * should fall back to the driver default TTL.\n *\n * Default reads `expiresAt` from {@link getEntry}, which the metadata-aware\n * drivers (memory, lru, mock, pg) populate. Drivers that track TTL natively\n * and don't carry `expiresAt` in their payload (Redis) override this.\n */\n protected async getRemainingTtl(key: CacheKey): Promise<number | undefined> {\n const entry = await this.getEntry(key);\n\n if (!entry) {\n return undefined;\n }\n\n if (!entry.expiresAt || entry.expiresAt === Infinity) {\n return Infinity;\n }\n\n const remainingSeconds = Math.ceil((entry.expiresAt - Date.now()) / 1000);\n\n return remainingSeconds > 0 ? remainingSeconds : undefined;\n }\n\n /**\n * Block-and-fetch path of `swr()`: invoked on miss or past-`staleTtl`\n * expiry. Writes through `set()` with the SWR options translated into\n * standard `CacheSetOptions` (ttl = staleTtl, staleAt = now + freshTtl).\n */\n protected async swrFetchAndStore<T>(\n key: CacheKey,\n options: CacheSwrOptions,\n callback: () => Promise<T>,\n freshSeconds: number,\n staleSeconds: number,\n ): Promise<T> {\n const result = await callback();\n\n await this.set(key, result, {\n ttl: staleSeconds,\n staleAt: Date.now() + freshSeconds * 1000,\n tags: options.tags,\n });\n\n return result;\n }\n\n /**\n * Stale-window background refresh. Registers a single in-flight promise\n * per parsed key so concurrent SWR callers share one refresh. Failed\n * refreshes preserve the stale entry, log via `logError`, and emit on\n * `error` — the stale-returning caller never sees the failure.\n */\n protected scheduleSwrRefresh<T>(\n parsedKey: string,\n key: CacheKey,\n options: CacheSwrOptions,\n callback: () => Promise<T>,\n freshSeconds: number,\n staleSeconds: number,\n ): void {\n if (this.swrRefreshes.has(parsedKey)) {\n return;\n }\n\n let refresh!: Promise<void>;\n refresh = (async () => {\n try {\n const result = await callback();\n\n await this.set(key, result, {\n ttl: staleSeconds,\n staleAt: Date.now() + freshSeconds * 1000,\n tags: options.tags,\n });\n } catch (error) {\n this.logError(`SWR background refresh failed for ${parsedKey}`, error);\n await this.emit(\"error\", { key: parsedKey, error });\n } finally {\n if (this.swrRefreshes.get(parsedKey) === refresh) {\n this.swrRefreshes.delete(parsedKey);\n }\n }\n })();\n\n this.swrRefreshes.set(parsedKey, refresh);\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: get-then-remove, serialized per key in THIS\n * process. Drivers with a native primitive override it to be atomic across\n * servers (redis `GETDEL`, pg `DELETE … RETURNING`) or process-atomic\n * (memory, lru, mock).\n */\n public async pull(key: CacheKey): Promise<any | null> {\n return this.runSerialized(this.parseKey(key), async () => {\n // Events are emitted by get() and remove()\n const value = await this.get(key);\n\n if (value !== null) {\n await this.remove(key);\n }\n\n return value;\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async forever(key: CacheKey, value: any): Promise<any> {\n // Event is emitted by set() method\n return this.set(key, value, Infinity);\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: read-add-write serialized per key in THIS process,\n * keeping the entry's remaining TTL (a missing key starts from 0 with the\n * driver default TTL). Not atomic across servers: drivers with a native\n * primitive override it (redis `INCRBY`, pg single-statement upsert).\n */\n public async increment(key: CacheKey, value: number = 1): Promise<number> {\n const parsedKey = this.parseKey(key);\n\n return this.runSerialized(parsedKey, async () => {\n const current = await this.get(key);\n const base = current === null || current === undefined ? 0 : current;\n\n if (typeof base !== \"number\") {\n throw new Error(`Cannot increment non-numeric value for key: ${parsedKey}`);\n }\n\n const newValue = base + value;\n const remainingTtl = current === null ? undefined : await this.getRemainingTtl(key);\n\n if (remainingTtl !== undefined) {\n await this.set(key, newValue, { ttl: remainingTtl });\n } else {\n await this.set(key, newValue);\n }\n\n return newValue;\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async decrement(key: CacheKey, value: number = 1): Promise<number> {\n return this.increment(key, -value);\n }\n\n /**\n * {@inheritdoc}\n */\n public async many(keys: CacheKey[]): Promise<any[]> {\n return Promise.all(keys.map((key) => this.get(key)));\n }\n\n /**\n * {@inheritdoc}\n */\n public async setMany(\n items: Record<string, any>,\n ttl?: number,\n ): Promise<void> {\n await Promise.all(\n Object.entries(items).map(([key, value]) => this.set(key, value, ttl)),\n );\n }\n\n /**\n * Log the operation\n */\n protected log(operation: CacheOperationType, key?: string | any) {\n if (!this.shouldLog) return;\n\n if (typeof key === \"string\") {\n // this will be likely used with file cache driver as it will convert the dot to slash\n // to make it consistent and not to confuse developers we will output the key by making sure it's a dot\n key = key.replace(/\\//g, \".\");\n }\n\n if (operation === \"connectionFailed\") {\n log.fatal(`cache.${this.name}`, operation, key);\n }\n\n if (operation == \"notFound\" || operation == \"expired\") {\n return log.info(\n \"cache.\" + this.name,\n operation,\n (key ? key + \" \" : \"\") + messages[operation],\n );\n }\n\n if (operation.endsWith(\"ed\")) {\n return log.success(\n \"cache.\" + this.name,\n operation,\n (key ? key + \" \" : \"\") + messages[operation],\n );\n }\n\n log.info(\n \"cache.\" + this.name,\n operation,\n (key ? key + \" \" : \"\") + messages[operation],\n );\n }\n\n /**\n * Log error message\n *\n * Never logs the raw `error` object — driver connection errors (Redis,\n * Postgres, ...) can carry the connection string, including the password,\n * in the message/cause. Only a redacted `{ message, code }` shape is\n * passed to the structured logger.\n */\n protected logError(message: string, error?: any) {\n if (error) {\n log.error(\"cache.\" + this.name, \"error\", message, safeErrorInfo(error));\n } else {\n log.error(\"cache.\" + this.name, \"error\", message);\n }\n }\n\n /**\n * Get the default TTL in seconds. Parses human-readable strings (`\"1h\"`, `\"30m\"`)\n * from driver options if present; falls back to `Infinity` when no default is set.\n */\n public get ttl() {\n if (this.options.ttl === undefined) {\n return Infinity;\n }\n\n return parseTtl(this.options.ttl);\n }\n\n /**\n * Get time to live value in milliseconds\n */\n public getExpiresAt(ttl: number = this.ttl) {\n if (ttl) {\n return new Date().getTime() + ttl * 1000;\n }\n }\n\n /**\n * Wrap a value with TTL and optional freshness metadata for backend\n * storage. `staleAt` persists alongside `expiresAt` when supplied — used\n * by the SWR flow to mark when the entry stops being fresh.\n */\n protected prepareDataForStorage(data: any, ttl?: number, staleAt?: number) {\n const preparedData: CacheData = {\n data,\n };\n\n if (ttl) {\n preparedData.ttl = ttl;\n preparedData.expiresAt = this.getExpiresAt(ttl);\n }\n\n if (staleAt !== undefined) {\n preparedData.staleAt = staleAt;\n }\n\n return preparedData;\n }\n\n /**\n * Parse fetched data from cache\n */\n protected async parseCachedData(key: string, data: CacheData) {\n this.log(\"fetched\", key);\n\n if (data.expiresAt && data.expiresAt < Date.now()) {\n this.remove(key);\n return null;\n }\n\n const value = data.data;\n\n // Skip cloning for primitives (immutable types)\n if (value === null || value === undefined) {\n return value;\n }\n\n const type = typeof value;\n if (type === \"string\" || type === \"number\" || type === \"boolean\") {\n return value;\n }\n\n // Deep clone objects/arrays to prevent cache mutation\n try {\n return structuredClone(value);\n } catch (error) {\n this.logError(\n `Failed to clone cached value for ${key}, typeof value: ${typeof value}`,\n error,\n );\n throw error;\n }\n }\n\n /**\n * {@inheritdoc}\n */\n public async connect() {\n this.log(\"connecting\");\n this.log(\"connected\");\n await this.emit(\"connected\");\n }\n\n /**\n * {@inheritdoc}\n */\n public async disconnect() {\n this.log(\"disconnected\");\n await this.emit(\"disconnected\");\n }\n\n /**\n * Create a tagged cache instance for the given tags\n */\n public tags(tags: string[]): any {\n return new TaggedCache(tags, this);\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: read → transform → write, serialized per key in\n * THIS process only. Drivers that can offer cross-server atomicity (redis,\n * pg: compare-and-set with retries) override it.\n */\n public async update<T = any>(\n key: CacheKey,\n fn: (current: T | null) => T | null | Promise<T | null>,\n options: { ttl?: CacheTtl } = {},\n ): Promise<T | null> {\n // Chain each update onto the previous one for the same key so concurrent\n // callers are serialized end-to-end, not merely awakened together.\n return this.runSerialized(this.parseKey(key), async () => {\n const current = (await this.get(key)) as T | null;\n const result = await fn(current);\n\n if (result === null) {\n await this.remove(key);\n return null;\n }\n\n if (options.ttl !== undefined) {\n await this.set(key, result, { ttl: options.ttl });\n\n return result;\n }\n\n // No explicit TTL → preserve the existing entry's remaining lifetime\n // rather than resetting it to the driver default.\n const remainingTtl = await this.getRemainingTtl(key);\n\n if (remainingTtl !== undefined) {\n await this.set(key, result, { ttl: remainingTtl });\n } else {\n await this.set(key, result);\n }\n\n return result;\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async merge<T extends Record<string, any> = Record<string, any>>(\n key: CacheKey,\n partial: Partial<T>,\n options: { ttl?: CacheTtl } = {},\n ): Promise<T> {\n const result = await this.update<T>(\n key,\n (current) => {\n const base = (current ?? {}) as T;\n return { ...base, ...partial } as T;\n },\n options,\n );\n\n return result as T;\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: read-mutate-write array backed by the underlying\n * cache entry. Concrete drivers (e.g. Redis) override with native commands.\n */\n public list<T = any>(key: CacheKey): CacheListAccessor<T> {\n return new MemoryCacheList<T>(this, key);\n }\n\n /**\n * {@inheritdoc}\n *\n * Built on top of `set({ onConflict: \"create\" })` — Redis-native `SET … NX EX`\n * under the hood on Redis, emulated via key-existence check on other drivers.\n * The lock value is the resolved `owner` (defaults to `pid.<process.pid>`).\n *\n * Always releases in `finally`, even if `fn` throws — the thrown error\n * propagates to the caller unchanged, and a failed release is logged rather\n * than replacing `fn`'s result or error. The ttl must be finite and\n * positive; there is no renewal, so it must exceed the worst-case duration.\n */\n public async lock<T>(\n key: CacheKey,\n ttlOrOptions: CacheTtl | Omit<LockOptions, \"driver\">,\n fn: () => Promise<T>,\n ): Promise<LockOutcome<T>> {\n const { ttl, owner } = this.normalizeLockOptions(ttlOrOptions);\n\n // A lock with no expiry stays held forever if its holder crashes, on every\n // server. Refuse it up front (parseTtl also rejects undefined / NaN).\n const ttlSeconds = parseTtl(ttl);\n\n if (!Number.isFinite(ttlSeconds) || ttlSeconds <= 0) {\n throw new CacheConfigurationError(\n `cache.lock() requires a finite, positive ttl (got ${String(ttl)}). The ttl must exceed the worst-case duration of the locked work.`,\n );\n }\n // The stored value is `<owner>#<token>`: the token makes it unique per\n // acquisition so release can compare-and-delete instead of deleting blindly.\n const lockValue = `${owner ?? `pid.${process.pid}`}#${randomUUID()}`;\n\n const setResult = (await this.set(key, lockValue, {\n onConflict: \"create\",\n ttl,\n })) as CacheSetResult | unknown;\n\n // `onConflict` drivers return CacheSetResult. Drivers that no-op on set\n // (e.g. the null driver) may return anything else — treat that as\n // \"acquired\" since there's nothing to collide with.\n const wasSet =\n typeof setResult === \"object\" &&\n setResult !== null &&\n \"wasSet\" in setResult\n ? (setResult as CacheSetResult).wasSet\n : true;\n\n if (!wasSet) {\n return { acquired: false };\n }\n\n try {\n const value = await fn();\n return { acquired: true, value };\n } finally {\n // Only delete our own lock — if the TTL expired and a successor\n // acquired the key, its value differs and it is left alone. A release\n // failure (e.g. a Redis blip) is logged, never allowed to replace fn's\n // outcome: the lock still expires by its TTL.\n try {\n await this.deleteIfEquals(key, lockValue);\n } catch (error) {\n this.logError(`lock release failed for ${this.parseKey(key)}`, error);\n }\n }\n }\n\n /**\n * Compare-and-delete: remove `key` only when its current value equals\n * `expected`. Returns whether a delete happened.\n *\n * This default is get-then-remove and is NOT atomic across processes; drivers\n * with a real primitive (memory, redis, pg) override it.\n */\n protected async deleteIfEquals(key: CacheKey, expected: unknown): Promise<boolean> {\n if ((await this.get(key)) !== expected) {\n return false;\n }\n\n await this.remove(key);\n\n return true;\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation throws {@link CacheUnsupportedError}. Drivers that\n * support similarity retrieval (memory family, `pg`, `redis` w/ RediSearch)\n * override this with a real impl.\n */\n public async similar<T = any>(\n _vector: number[],\n _options: CacheSimilarOptions,\n ): Promise<CacheSimilarHit<T>[]> {\n throw new CacheUnsupportedError(\n `'${this.name}' driver does not support similarity retrieval. Use a memory driver, 'pg' (with pgvector), or 'redis' (with RediSearch).`,\n );\n }\n\n /**\n * Resolve the TTL-or-options arg of `lock` into a uniform shape.\n */\n protected normalizeLockOptions(\n ttlOrOptions: CacheTtl | Omit<LockOptions, \"driver\">,\n ): {\n ttl: CacheTtl;\n owner?: string;\n } {\n if (typeof ttlOrOptions === \"number\" || typeof ttlOrOptions === \"string\") {\n return { ttl: ttlOrOptions };\n }\n\n return { ttl: ttlOrOptions.ttl, owner: ttlOrOptions.owner };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base-cache-driver.mjs","names":[],"sources":["../../../../../../../cache/src/drivers/base-cache-driver.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { log } from \"@warlock.js/logger\";\nimport { MemoryCacheList } from \"../list/memory-cache-list\";\nimport { TaggedCache } from \"../tagged-cache\";\nimport type {\n CacheConflictPolicy,\n CacheData,\n CacheDriver,\n CacheEventData,\n CacheEventHandler,\n CacheEventType,\n CacheKey,\n CacheListAccessor,\n CacheOperationType,\n CacheSetOptions,\n CacheSetResult,\n CacheSimilarHit,\n CacheSimilarOptions,\n CacheSwrOptions,\n CacheTtl,\n LockOptions,\n LockOutcome,\n RememberOptions,\n} from \"../types\";\nimport { CacheConfigurationError, CacheUnsupportedError } from \"../types\";\nimport {\n normalizeToOptions,\n parseCacheKey,\n parseTtl,\n resolveTtl,\n safeErrorInfo,\n} from \"../utils\";\n\n/**\n * Normalized form of the 3rd `set` argument.\n *\n * All drivers operate on this shape internally regardless of whether the caller\n * passed a positional TTL, a duration string, or a rich options object.\n */\nexport type NormalizedSetOptions = {\n /**\n * Final TTL in seconds — already merged with the driver-level default\n * (`this.options.ttl`). `Infinity` means \"no expiration\".\n *\n * Always populated. Drivers do NOT need to fall back to `this.ttl`\n * themselves — `resolveSetOptions` does the merge centrally so that\n * every driver respects the configured default without ceremony.\n */\n ttl: number;\n /**\n * Inline tag list, or undefined when none were provided.\n */\n tags?: string[];\n /**\n * Conflict policy. Defaults to `\"upsert\"`.\n */\n onConflict: CacheConflictPolicy;\n /**\n * Optional embedding vector for similarity retrieval. Drivers that do not\n * support similarity must throw {@link CacheUnsupportedError} when this is\n * present (rather than silently dropping it).\n */\n vector?: number[];\n /**\n * Optional freshness deadline as a millisecond timestamp. Set by `swr()`\n * to mark when the entry stops being \"fresh\" and becomes\n * \"stale-but-revalidatable.\" Drivers route this through\n * `prepareDataForStorage` so it persists in the wrapper.\n */\n staleAt?: number;\n};\n\nconst messages = {\n clearing: \"Clearing namespace\",\n cleared: \"Namespace cleared\",\n fetching: \"Fetching key\",\n fetched: \"Key fetched\",\n caching: \"Caching key\",\n cached: \"Key cached\",\n flushing: \"Flushing cache\",\n flushed: \"Cache flushed\",\n removing: \"Removing key\",\n removed: \"Key removed\",\n expired: \"Key expired\",\n notFound: \"Key not found\",\n connecting: \"Connecting to the cache engine.\",\n connected: \"Connected to the cache engine.\",\n disconnecting: \"Disconnecting from the cache engine.\",\n disconnected: \"Disconnected from the cache engine.\",\n connectionFailed: \"Failed to connect to the cache engine.\",\n error: \"Error occurred\",\n};\n\nexport abstract class BaseCacheDriver<\n ClientType,\n Options extends Record<string, any>,\n> implements CacheDriver<ClientType, Options> {\n /**\n * CLient driver\n */\n protected clientDriver!: ClientType;\n\n /**\n * Determine whether to log or not\n */\n protected shouldLog: boolean = true;\n\n /**\n * {@inheritdoc}\n */\n public get client() {\n return (this.clientDriver || this) as unknown as ClientType;\n }\n\n /**\n * Set logging state\n */\n public setLoggingState(shouldLog: boolean) {\n this.shouldLog = shouldLog;\n\n return this;\n }\n\n /**\n * Set client driver\n */\n public set client(client: ClientType) {\n this.clientDriver = client;\n }\n\n /**\n * Get the cache driver name\n */\n public abstract name: string;\n\n /**\n * Options list\n */\n public options!: Options;\n\n /**\n * Event listeners storage\n */\n protected eventListeners: Map<CacheEventType, Set<CacheEventHandler>> =\n new Map();\n\n /**\n * {@inheritdoc}\n */\n public parseKey(key: CacheKey) {\n return parseCacheKey(key, this.options);\n }\n\n /**\n * {@inheritdoc}\n */\n public setOptions(options: Options) {\n this.options = options || {};\n return this;\n }\n\n /**\n * Register an event listener\n */\n public on(event: CacheEventType, handler: CacheEventHandler): this {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(handler);\n return this;\n }\n\n /**\n * Remove an event listener\n */\n public off(event: CacheEventType, handler: CacheEventHandler): this {\n const handlers = this.eventListeners.get(event);\n if (handlers) {\n handlers.delete(handler);\n }\n return this;\n }\n\n /**\n * Register a one-time event listener\n */\n public once(event: CacheEventType, handler: CacheEventHandler): this {\n const onceHandler: CacheEventHandler = async (data) => {\n await handler(data);\n this.off(event, onceHandler);\n };\n return this.on(event, onceHandler);\n }\n\n /**\n * Emit an event to all registered listeners\n */\n protected async emit(\n event: CacheEventType,\n data: Partial<CacheEventData> = {},\n ): Promise<void> {\n const handlers = this.eventListeners.get(event);\n if (!handlers || handlers.size === 0) return;\n\n const eventData: CacheEventData = {\n driver: this.name,\n ...data,\n };\n\n // Execute all handlers\n const promises: Promise<void>[] = [];\n for (const handler of handlers) {\n try {\n const result = handler(eventData);\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n this.logError(`Error in event handler for '${event}'`, error);\n }\n }\n\n // Wait for all async handlers\n if (promises.length > 0) {\n await Promise.allSettled(promises);\n }\n }\n\n /**\n * {@inheritdoc}\n */\n public abstract removeNamespace(namespace: string): Promise<any>;\n\n /**\n * {@inheritdoc}\n */\n public abstract set(\n key: CacheKey,\n value: any,\n ttlOrOptions?: CacheTtl | CacheSetOptions,\n ): Promise<any>;\n\n /**\n * Normalize the 3rd argument of a `set` call into a single shape every driver\n * can act on. Handles TTL parsing (number | string | Infinity), `expiresAt` →\n * relative TTL conversion, and mutual-exclusion validation.\n *\n * @throws {CacheConfigurationError} when `ttl` and `expiresAt` are passed together\n * or an unparseable duration string is supplied.\n */\n protected resolveSetOptions(\n ttlOrOptions?: CacheTtl | CacheSetOptions,\n ): NormalizedSetOptions {\n const options = normalizeToOptions(ttlOrOptions);\n\n return {\n ttl: resolveTtl(options.ttl, options.expiresAt, this.ttl),\n tags: options.tags,\n onConflict: options.onConflict ?? \"upsert\",\n vector: options.vector,\n staleAt: options.staleAt,\n };\n }\n\n /**\n * Resolve the union of cache keys associated with any of the given tags.\n * Used by `similar()` to narrow the candidate pool before similarity ranking.\n *\n * Returns `null` when no tags are passed (callers should treat that as \"no filter\").\n * Keys come back parsed (prefixed) — the index stores them un-prefixed, but\n * callers match them against their own parsed storage keys.\n */\n protected async getKeysForTags(\n tags: string[] | undefined,\n ): Promise<Set<string> | null> {\n if (!tags || tags.length === 0) {\n return null;\n }\n\n const allKeys = new Set<string>();\n for (const tag of tags) {\n const keys = await this.tagMembers(`cache:tags:${tag}`);\n for (const k of keys) {\n allKeys.add(this.parseKey(k));\n }\n }\n\n return allKeys;\n }\n\n // ============================================================\n // Tag index primitives\n // ============================================================\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: the index is an ordinary entry holding a string\n * array, read-modified-written under {@link runSerialized} — correct within\n * THIS process only. Drivers with a native primitive override it (redis SET,\n * pg atomic upsert, the in-process drivers' {@link InMemoryTagIndex}).\n */\n public async tagAdd(tagKey: CacheKey, members: string[]): Promise<void> {\n if (members.length === 0) {\n return;\n }\n\n await this.runSerialized(this.parseKey(tagKey), async () => {\n const current = await this.readTagArray(tagKey);\n const merged = new Set(current);\n\n for (const member of members) {\n merged.add(member);\n }\n\n if (merged.size !== current.length) {\n await this.set(tagKey, [...merged], Infinity);\n }\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async tagMembers(tagKey: CacheKey): Promise<string[]> {\n return this.readTagArray(tagKey);\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: serialized read-filter-write (process-local); an\n * emptied index is removed.\n */\n public async tagRemove(tagKey: CacheKey, members: string[]): Promise<void> {\n if (members.length === 0) {\n return;\n }\n\n await this.runSerialized(this.parseKey(tagKey), async () => {\n const current = await this.readTagArray(tagKey);\n const dropped = new Set(members);\n const kept = current.filter((member) => !dropped.has(member));\n\n if (kept.length === current.length) {\n return;\n }\n\n if (kept.length === 0) {\n await this.remove(tagKey);\n } else {\n await this.set(tagKey, kept, Infinity);\n }\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async tagDelete(tagKey: CacheKey): Promise<void> {\n await this.runSerialized(this.parseKey(tagKey), () => this.remove(tagKey));\n }\n\n /**\n * The index stored as a plain entry, or `[]`. Non-string members (a corrupted\n * or foreign value) are ignored rather than trusted.\n */\n protected async readTagArray(tagKey: CacheKey): Promise<string[]> {\n const value = await this.get(tagKey);\n\n if (!Array.isArray(value)) {\n return [];\n }\n\n return value.filter((member): member is string => typeof member === \"string\");\n }\n\n /**\n * Apply tag relationships after a successful write. Called by drivers once\n * the value is in storage.\n *\n * Pass the caller's key, not the parsed one: the tag index stores keys\n * un-prefixed so `invalidate()` can delete them through `remove(key)`.\n */\n protected async applyTags(key: CacheKey, tags: string[]): Promise<void> {\n if (tags.length === 0) {\n return;\n }\n\n const tagged = this.tags(tags);\n await (tagged as TaggedCache).storeTagRelationship(key);\n }\n\n /**\n * {@inheritdoc}\n */\n public abstract get(key: CacheKey): Promise<any>;\n\n /**\n * {@inheritdoc}\n */\n public abstract remove(key: CacheKey): Promise<void>;\n\n /**\n * {@inheritdoc}\n */\n public abstract flush(): Promise<void>;\n\n /**\n * {@inheritdoc}\n */\n public async has(key: CacheKey): Promise<boolean> {\n const value = await this.get(key);\n // Event is emitted by get() method\n return value !== null;\n }\n\n /**\n * In-flight `remember()` computations, one per parsed key (stampede guard).\n */\n protected rememberInFlight: Map<string, Promise<any>> = new Map();\n\n /**\n * In-flight `swr()` cold-miss fetches, one per parsed key.\n */\n protected swrFetchInFlight: Map<string, Promise<any>> = new Map();\n\n /**\n * In-flight `swr()` stale-window background refreshes, one per parsed key.\n */\n protected swrRefreshes: Map<string, Promise<void>> = new Map();\n\n /**\n * Per-key serialization chains for the in-process read-modify-write\n * operations (`update`, and the default `increment` / `pull`). Kept apart\n * from the stampede maps so a `remember()` can never break an update chain,\n * and never receives an unrelated promise.\n */\n protected updateChains: Map<string, Promise<any>> = new Map();\n\n /**\n * Run `task` once per key at a time: concurrent callers for the same\n * `parsedKey` share the in-flight promise registered in `inFlight`.\n */\n protected singleFlight<T>(\n inFlight: Map<string, Promise<any>>,\n parsedKey: string,\n task: () => Promise<T>,\n ): Promise<T> {\n const existing = inFlight.get(parsedKey);\n\n if (existing) {\n return existing as Promise<T>;\n }\n\n const promise: Promise<T> = task().finally(() => {\n if (inFlight.get(parsedKey) === promise) {\n inFlight.delete(parsedKey);\n }\n });\n\n inFlight.set(parsedKey, promise);\n\n return promise;\n }\n\n /**\n * Chain `task` after every earlier serialized task for the same key, so\n * read-modify-write callers in THIS process run one at a time. This is\n * process-local: it does not coordinate with other servers.\n */\n protected runSerialized<T>(parsedKey: string, task: () => Promise<T>): Promise<T> {\n const previous = this.updateChains.get(parsedKey) ?? Promise.resolve();\n\n const next = previous.catch(() => undefined).then(task);\n\n this.updateChains.set(parsedKey, next);\n\n // Clean up the slot once this link finishes, but only if nobody chained a\n // follow-up onto it meanwhile. The trailing catch keeps a rejected link\n // from surfacing as an unhandled rejection here (the caller still sees it).\n next\n .finally(() => {\n if (this.updateChains.get(parsedKey) === next) {\n this.updateChains.delete(parsedKey);\n }\n })\n .catch(() => undefined);\n\n return next;\n }\n\n /**\n * {@inheritdoc}\n */\n public async remember(\n key: CacheKey,\n ttlOrOptions: CacheTtl | RememberOptions,\n callback: () => Promise<any>,\n ): Promise<any> {\n const parsedKey = this.parseKey(key);\n\n // The options-form lets callers forward tags / driver-override through to\n // the cache-miss write. Normalize both shapes into a single CacheSetOptions\n // blob so there's one path from here on.\n const setOptions = this.normalizeRememberOptions(ttlOrOptions);\n\n // Only a real miss (`null`) recomputes: cached falsy values such as\n // `0`, `false` and `\"\"` are returned as-is.\n const cachedValue = await this.get(key);\n\n if (cachedValue !== null && cachedValue !== undefined) {\n return cachedValue;\n }\n\n return this.singleFlight(this.rememberInFlight, parsedKey, async () => {\n const result = await callback();\n\n await this.set(key, result, setOptions);\n\n return result;\n });\n }\n\n /**\n * Resolve the TTL-or-options arg of `remember` into a `CacheSetOptions` object\n * that can be passed straight to `set()`. Keeps the implementation unbranched.\n */\n protected normalizeRememberOptions(\n ttlOrOptions: CacheTtl | RememberOptions,\n ): CacheSetOptions {\n if (typeof ttlOrOptions === \"number\" || typeof ttlOrOptions === \"string\") {\n return { ttl: ttlOrOptions };\n }\n\n return {\n ttl: ttlOrOptions.ttl,\n tags: ttlOrOptions.tags,\n };\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: read raw entry, branch on freshness/staleness,\n * trigger background refresh in the stale window, fall through to\n * `callback` on miss/expiry. Concurrent cold-miss callers share one fetch\n * ({@link swrFetchInFlight}); concurrent stale-window callers share one\n * background refresh ({@link swrRefreshes}).\n *\n * Drivers without a real {@link getEntry} override degrade gracefully —\n * the synthetic entry has no `staleAt`, which the freshness check treats\n * as \"always fresh,\" so SWR behaves like a TTL-only cached read on those\n * drivers (no background refresh, but no double-fetch either).\n */\n public async swr<T = any>(\n key: CacheKey,\n options: CacheSwrOptions,\n callback: () => Promise<T>,\n ): Promise<T> {\n const parsedKey = this.parseKey(key);\n const freshSeconds = parseTtl(options.freshTtl);\n const staleSeconds = parseTtl(options.staleTtl);\n\n if (staleSeconds <= freshSeconds) {\n throw new Error(\n `cache.swr: 'staleTtl' (${staleSeconds}s) must be greater than 'freshTtl' (${freshSeconds}s).`,\n );\n }\n\n const entry = await this.getEntry(key);\n const now = Date.now();\n\n const isExpired = entry?.expiresAt !== undefined && entry.expiresAt <= now;\n\n if (!entry || isExpired) {\n return this.singleFlight(this.swrFetchInFlight, parsedKey, () =>\n this.swrFetchAndStore<T>(key, options, callback, freshSeconds, staleSeconds),\n );\n }\n\n const isFresh = entry.staleAt === undefined || entry.staleAt > now;\n\n if (isFresh) {\n return entry.data as T;\n }\n\n this.scheduleSwrRefresh<T>(\n parsedKey,\n key,\n options,\n callback,\n freshSeconds,\n staleSeconds,\n );\n\n return entry.data as T;\n }\n\n /**\n * Read the raw {@link CacheData} wrapper for a key, including any\n * `expiresAt` / `staleAt` metadata. Default implementation falls back to\n * `get()` and synthesizes a metadata-less wrapper — drivers that store\n * the wrapper directly (memory, lru, file, redis, pg, mock) override\n * this to return real metadata so SWR can branch on freshness.\n */\n protected async getEntry(key: CacheKey): Promise<CacheData | null> {\n const value = await this.get(key);\n\n if (value === null) {\n return null;\n }\n\n return { data: value };\n }\n\n /**\n * Remaining lifetime of an existing entry, in seconds — used by TTL-preserving\n * writes such as `update()` / `merge()` when the caller passes no explicit\n * `ttl`.\n *\n * - `Infinity` — the entry exists with no expiry (preserve \"never expires\").\n * - positive number — seconds left before the entry expires.\n * - `undefined` — the key is missing or already past its deadline; the caller\n * should fall back to the driver default TTL.\n *\n * Default reads `expiresAt` from {@link getEntry}, which the metadata-aware\n * drivers (memory, lru, mock, pg) populate. Drivers that track TTL natively\n * and don't carry `expiresAt` in their payload (Redis) override this.\n */\n protected async getRemainingTtl(key: CacheKey): Promise<number | undefined> {\n const entry = await this.getEntry(key);\n\n if (!entry) {\n return undefined;\n }\n\n if (!entry.expiresAt || entry.expiresAt === Infinity) {\n return Infinity;\n }\n\n const remainingSeconds = Math.ceil((entry.expiresAt - Date.now()) / 1000);\n\n return remainingSeconds > 0 ? remainingSeconds : undefined;\n }\n\n /**\n * Block-and-fetch path of `swr()`: invoked on miss or past-`staleTtl`\n * expiry. Writes through `set()` with the SWR options translated into\n * standard `CacheSetOptions` (ttl = staleTtl, staleAt = now + freshTtl).\n */\n protected async swrFetchAndStore<T>(\n key: CacheKey,\n options: CacheSwrOptions,\n callback: () => Promise<T>,\n freshSeconds: number,\n staleSeconds: number,\n ): Promise<T> {\n const result = await callback();\n\n await this.set(key, result, {\n ttl: staleSeconds,\n staleAt: Date.now() + freshSeconds * 1000,\n tags: options.tags,\n });\n\n return result;\n }\n\n /**\n * Stale-window background refresh. Registers a single in-flight promise\n * per parsed key so concurrent SWR callers share one refresh. Failed\n * refreshes preserve the stale entry, log via `logError`, and emit on\n * `error` — the stale-returning caller never sees the failure.\n */\n protected scheduleSwrRefresh<T>(\n parsedKey: string,\n key: CacheKey,\n options: CacheSwrOptions,\n callback: () => Promise<T>,\n freshSeconds: number,\n staleSeconds: number,\n ): void {\n if (this.swrRefreshes.has(parsedKey)) {\n return;\n }\n\n let refresh!: Promise<void>;\n refresh = (async () => {\n try {\n const result = await callback();\n\n await this.set(key, result, {\n ttl: staleSeconds,\n staleAt: Date.now() + freshSeconds * 1000,\n tags: options.tags,\n });\n } catch (error) {\n this.logError(`SWR background refresh failed for ${parsedKey}`, error);\n await this.emit(\"error\", { key: parsedKey, error });\n } finally {\n if (this.swrRefreshes.get(parsedKey) === refresh) {\n this.swrRefreshes.delete(parsedKey);\n }\n }\n })();\n\n this.swrRefreshes.set(parsedKey, refresh);\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: get-then-remove, serialized per key in THIS\n * process. Drivers with a native primitive override it to be atomic across\n * servers (redis `GETDEL`, pg `DELETE … RETURNING`) or process-atomic\n * (memory, lru, mock).\n */\n public async pull(key: CacheKey): Promise<any | null> {\n return this.runSerialized(this.parseKey(key), async () => {\n // Events are emitted by get() and remove()\n const value = await this.get(key);\n\n if (value !== null) {\n await this.remove(key);\n }\n\n return value;\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async forever(key: CacheKey, value: any): Promise<any> {\n // Event is emitted by set() method\n return this.set(key, value, Infinity);\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: read-add-write serialized per key in THIS process,\n * keeping the entry's remaining TTL (a missing key starts from 0 with the\n * driver default TTL). Not atomic across servers: drivers with a native\n * primitive override it (redis `INCRBY`, pg single-statement upsert).\n */\n public async increment(key: CacheKey, value: number = 1): Promise<number> {\n const parsedKey = this.parseKey(key);\n\n return this.runSerialized(parsedKey, async () => {\n const current = await this.get(key);\n const base = current === null || current === undefined ? 0 : current;\n\n if (typeof base !== \"number\") {\n throw new Error(`Cannot increment non-numeric value for key: ${parsedKey}`);\n }\n\n const newValue = base + value;\n const remainingTtl = current === null ? undefined : await this.getRemainingTtl(key);\n\n if (remainingTtl !== undefined) {\n await this.set(key, newValue, { ttl: remainingTtl });\n } else {\n await this.set(key, newValue);\n }\n\n return newValue;\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async decrement(key: CacheKey, value: number = 1): Promise<number> {\n return this.increment(key, -value);\n }\n\n /**\n * {@inheritdoc}\n */\n public async many(keys: CacheKey[]): Promise<any[]> {\n return Promise.all(keys.map((key) => this.get(key)));\n }\n\n /**\n * {@inheritdoc}\n */\n public async setMany(\n items: Record<string, any>,\n ttl?: number,\n ): Promise<void> {\n await Promise.all(\n Object.entries(items).map(([key, value]) => this.set(key, value, ttl)),\n );\n }\n\n /**\n * Log the operation\n */\n protected log(operation: CacheOperationType, key?: string | any) {\n if (!this.shouldLog) return;\n\n if (typeof key === \"string\") {\n // this will be likely used with file cache driver as it will convert the dot to slash\n // to make it consistent and not to confuse developers we will output the key by making sure it's a dot\n key = key.replace(/\\//g, \".\");\n }\n\n if (operation === \"connectionFailed\") {\n log.fatal(`cache.${this.name}`, operation, key);\n }\n\n if (operation == \"notFound\" || operation == \"expired\") {\n return log.info(\n \"cache.\" + this.name,\n operation,\n (key ? key + \" \" : \"\") + messages[operation],\n );\n }\n\n if (operation.endsWith(\"ed\")) {\n return log.success(\n \"cache.\" + this.name,\n operation,\n (key ? key + \" \" : \"\") + messages[operation],\n );\n }\n\n log.info(\n \"cache.\" + this.name,\n operation,\n (key ? key + \" \" : \"\") + messages[operation],\n );\n }\n\n /**\n * Log error message\n *\n * Never logs the raw `error` object — driver connection errors (Redis,\n * Postgres, ...) can carry the connection string, including the password,\n * in the message/cause. Only a redacted `{ message, code }` shape is\n * passed to the structured logger.\n */\n protected logError(message: string, error?: any) {\n if (error) {\n log.error(\"cache.\" + this.name, \"error\", message, safeErrorInfo(error));\n } else {\n log.error(\"cache.\" + this.name, \"error\", message);\n }\n }\n\n /**\n * Get the default TTL in seconds. Parses human-readable strings (`\"1h\"`, `\"30m\"`)\n * from driver options if present; falls back to `Infinity` when no default is set.\n */\n public get ttl() {\n if (this.options.ttl === undefined) {\n return Infinity;\n }\n\n return parseTtl(this.options.ttl);\n }\n\n /**\n * Get time to live value in milliseconds\n */\n public getExpiresAt(ttl: number = this.ttl) {\n if (ttl) {\n return new Date().getTime() + ttl * 1000;\n }\n }\n\n /**\n * Wrap a value with TTL and optional freshness metadata for backend\n * storage. `staleAt` persists alongside `expiresAt` when supplied — used\n * by the SWR flow to mark when the entry stops being fresh.\n */\n protected prepareDataForStorage(data: any, ttl?: number, staleAt?: number) {\n const preparedData: CacheData = {\n data,\n };\n\n if (ttl) {\n preparedData.ttl = ttl;\n preparedData.expiresAt = this.getExpiresAt(ttl);\n }\n\n if (staleAt !== undefined) {\n preparedData.staleAt = staleAt;\n }\n\n return preparedData;\n }\n\n /**\n * Parse fetched data from cache\n */\n protected async parseCachedData(key: string, data: CacheData) {\n this.log(\"fetched\", key);\n\n if (data.expiresAt && data.expiresAt < Date.now()) {\n this.remove(key);\n return null;\n }\n\n const value = data.data;\n\n // Skip cloning for primitives (immutable types)\n if (value === null || value === undefined) {\n return value;\n }\n\n const type = typeof value;\n if (type === \"string\" || type === \"number\" || type === \"boolean\") {\n return value;\n }\n\n // Deep clone objects/arrays to prevent cache mutation\n try {\n return structuredClone(value);\n } catch (error) {\n this.logError(\n `Failed to clone cached value for ${key}, typeof value: ${typeof value}`,\n error,\n );\n throw error;\n }\n }\n\n /**\n * {@inheritdoc}\n */\n public async connect() {\n this.log(\"connecting\");\n this.log(\"connected\");\n await this.emit(\"connected\");\n }\n\n /**\n * {@inheritdoc}\n */\n public async disconnect() {\n this.log(\"disconnected\");\n await this.emit(\"disconnected\");\n }\n\n /**\n * Create a tagged cache instance for the given tags\n */\n public tags(tags: string[]): any {\n return new TaggedCache(tags, this);\n }\n\n /**\n * Emit `invalidated` on behalf of a {@link TaggedCache} created by this\n * driver, once per `invalidate()` call. Listeners cannot fail the\n * invalidation: `emit` isolates them.\n *\n * @internal\n */\n public async emitTagsInvalidated(data: {\n tags: string[];\n keys: string[];\n durationMs: number;\n }): Promise<void> {\n await this.emit(\"invalidated\", data);\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: read → transform → write, serialized per key in\n * THIS process only. Drivers that can offer cross-server atomicity (redis,\n * pg: compare-and-set with retries) override it.\n */\n public async update<T = any>(\n key: CacheKey,\n fn: (current: T | null) => T | null | Promise<T | null>,\n options: { ttl?: CacheTtl } = {},\n ): Promise<T | null> {\n // Chain each update onto the previous one for the same key so concurrent\n // callers are serialized end-to-end, not merely awakened together.\n return this.runSerialized(this.parseKey(key), async () => {\n const current = (await this.get(key)) as T | null;\n const result = await fn(current);\n\n if (result === null) {\n await this.remove(key);\n return null;\n }\n\n if (options.ttl !== undefined) {\n await this.set(key, result, { ttl: options.ttl });\n\n return result;\n }\n\n // No explicit TTL → preserve the existing entry's remaining lifetime\n // rather than resetting it to the driver default.\n const remainingTtl = await this.getRemainingTtl(key);\n\n if (remainingTtl !== undefined) {\n await this.set(key, result, { ttl: remainingTtl });\n } else {\n await this.set(key, result);\n }\n\n return result;\n });\n }\n\n /**\n * {@inheritdoc}\n */\n public async merge<T extends Record<string, any> = Record<string, any>>(\n key: CacheKey,\n partial: Partial<T>,\n options: { ttl?: CacheTtl } = {},\n ): Promise<T> {\n const result = await this.update<T>(\n key,\n (current) => {\n const base = (current ?? {}) as T;\n return { ...base, ...partial } as T;\n },\n options,\n );\n\n return result as T;\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation: read-mutate-write array backed by the underlying\n * cache entry. Concrete drivers (e.g. Redis) override with native commands.\n */\n public list<T = any>(key: CacheKey): CacheListAccessor<T> {\n return new MemoryCacheList<T>(this, key);\n }\n\n /**\n * {@inheritdoc}\n *\n * Built on top of `set({ onConflict: \"create\" })` — Redis-native `SET … NX EX`\n * under the hood on Redis, emulated via key-existence check on other drivers.\n * The lock value is the resolved `owner` (defaults to `pid.<process.pid>`).\n *\n * Always releases in `finally`, even if `fn` throws — the thrown error\n * propagates to the caller unchanged, and a failed release is logged rather\n * than replacing `fn`'s result or error. The ttl must be finite and\n * positive; there is no renewal, so it must exceed the worst-case duration.\n */\n public async lock<T>(\n key: CacheKey,\n ttlOrOptions: CacheTtl | Omit<LockOptions, \"driver\">,\n fn: () => Promise<T>,\n ): Promise<LockOutcome<T>> {\n const { ttl, owner } = this.normalizeLockOptions(ttlOrOptions);\n\n // A lock with no expiry stays held forever if its holder crashes, on every\n // server. Refuse it up front (parseTtl also rejects undefined / NaN).\n const ttlSeconds = parseTtl(ttl);\n\n if (!Number.isFinite(ttlSeconds) || ttlSeconds <= 0) {\n throw new CacheConfigurationError(\n `cache.lock() requires a finite, positive ttl (got ${String(ttl)}). The ttl must exceed the worst-case duration of the locked work.`,\n );\n }\n // The stored value is `<owner>#<token>`: the token makes it unique per\n // acquisition so release can compare-and-delete instead of deleting blindly.\n const lockValue = `${owner ?? `pid.${process.pid}`}#${randomUUID()}`;\n\n const setResult = (await this.set(key, lockValue, {\n onConflict: \"create\",\n ttl,\n })) as CacheSetResult | unknown;\n\n // `onConflict` drivers return CacheSetResult. Drivers that no-op on set\n // (e.g. the null driver) may return anything else — treat that as\n // \"acquired\" since there's nothing to collide with.\n const wasSet =\n typeof setResult === \"object\" &&\n setResult !== null &&\n \"wasSet\" in setResult\n ? (setResult as CacheSetResult).wasSet\n : true;\n\n if (!wasSet) {\n return { acquired: false };\n }\n\n try {\n const value = await fn();\n return { acquired: true, value };\n } finally {\n // Only delete our own lock — if the TTL expired and a successor\n // acquired the key, its value differs and it is left alone. A release\n // failure (e.g. a Redis blip) is logged, never allowed to replace fn's\n // outcome: the lock still expires by its TTL.\n try {\n await this.deleteIfEquals(key, lockValue);\n } catch (error) {\n this.logError(`lock release failed for ${this.parseKey(key)}`, error);\n }\n }\n }\n\n /**\n * Compare-and-delete: remove `key` only when its current value equals\n * `expected`. Returns whether a delete happened.\n *\n * This default is get-then-remove and is NOT atomic across processes; drivers\n * with a real primitive (memory, redis, pg) override it.\n */\n protected async deleteIfEquals(key: CacheKey, expected: unknown): Promise<boolean> {\n if ((await this.get(key)) !== expected) {\n return false;\n }\n\n await this.remove(key);\n\n return true;\n }\n\n /**\n * {@inheritdoc}\n *\n * Default implementation throws {@link CacheUnsupportedError}. Drivers that\n * support similarity retrieval (memory family, `pg`, `redis` w/ RediSearch)\n * override this with a real impl.\n */\n public async similar<T = any>(\n _vector: number[],\n _options: CacheSimilarOptions,\n ): Promise<CacheSimilarHit<T>[]> {\n throw new CacheUnsupportedError(\n `'${this.name}' driver does not support similarity retrieval. Use a memory driver, 'pg' (with pgvector), or 'redis' (with RediSearch).`,\n );\n }\n\n /**\n * Resolve the TTL-or-options arg of `lock` into a uniform shape.\n */\n protected normalizeLockOptions(\n ttlOrOptions: CacheTtl | Omit<LockOptions, \"driver\">,\n ): {\n ttl: CacheTtl;\n owner?: string;\n } {\n if (typeof ttlOrOptions === \"number\" || typeof ttlOrOptions === \"string\") {\n return { ttl: ttlOrOptions };\n }\n\n return { ttl: ttlOrOptions.ttl, owner: ttlOrOptions.owner };\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"null-cache-driver.mjs","names":[],"sources":["../../../../../../../cache/src/drivers/null-cache-driver.ts"],"sourcesContent":["import type { GenericObject } from \"@mongez/reinforcements\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport type {\r\n CacheDriver,\r\n CacheKey,\r\n CacheSetOptions,\r\n CacheTtl,\r\n NullCacheDriverOptions,\r\n RememberOptions,\r\n} from \"../types\";\r\nimport { BaseCacheDriver } from \"./base-cache-driver\";\r\n\r\nexport class NullCacheDriver\r\n extends BaseCacheDriver<NullCacheDriver, NullCacheDriverOptions>\r\n implements CacheDriver<NullCacheDriver, NullCacheDriverOptions>\r\n{\r\n /**\r\n * Options list\r\n */\r\n public options: GenericObject = {};\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public name = \"null\";\r\n\r\n /**\r\n * Cached data\r\n */\r\n public data: GenericObject = {};\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public get client() {\r\n return this;\r\n }\r\n\r\n /**\r\n * Constructor\r\n */\r\n public constructor(options: GenericObject = {}) {\r\n super();\r\n this.setOptions(options);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public setOptions(options: GenericObject) {\r\n this.options = options;\r\n return this;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public parseKey(key: CacheKey) {\r\n // Real parsed key so the base lock map never merges distinct keys.\r\n return super.parseKey(key);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n *\r\n * Nothing is stored, so always run the callback and return its own result.\r\n */\r\n public async remember(\r\n _key: CacheKey,\r\n _ttlOrOptions: CacheTtl | RememberOptions,\r\n callback: () => Promise<any>,\r\n ): Promise<any> {\r\n return callback();\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async removeNamespace(namespace: string) {\r\n log.info(\"cache\", \"clearing namespace\", namespace);\r\n\r\n log.success(\"cache\", \"namespace cleared\", namespace);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async set(\r\n key: CacheKey,\r\n _value: any,\r\n _ttlOrOptions?: CacheTtl | CacheSetOptions,\r\n ): Promise<any> {\r\n log.info(\"cache\", \"setting key\", key);\r\n\r\n log.success(\"cache\", \"key set\", key);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async get(key: CacheKey) {\r\n log.info(\"cache\", \"fetching\", key);\r\n\r\n log.success(\"cache\", \"fetched\", key);\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async remove(key: CacheKey) {\r\n log.info(\"cache\", \"removing\", key);\r\n\r\n log.success(\"cache\", \"removed\", key);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async flush() {\r\n log.info(\"cache\", \"flushing\", \"all\");\r\n\r\n log.success(\"cache\", \"flushed\", \"all\");\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n *\r\n * The null driver is a black-hole — `similar()` mirrors `get()` and returns\r\n * an empty result set rather than throwing.\r\n */\r\n public async similar(): Promise<any[]> {\r\n return [];\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async connect() {\r\n log.success(\"cache\", \"connected\", \"Connected to null cache driver\");\r\n }\r\n}\r\n"],"mappings":";;;;AAYA,IAAa,kBAAb,cACU,gBAEV;;;;CAmBE,IAAW,SAAS;EAClB,OAAO;CACT;;;;CAKA,AAAO,YAAY,UAAyB,CAAC,GAAG;EAC9C,MAAM;iBAvBwB,CAAC;cAKnB;cAKe,CAAC;EAc5B,KAAK,WAAW,OAAO;CACzB;;;;CAKA,AAAO,WAAW,SAAwB;EACxC,KAAK,UAAU;EACf,OAAO;CACT;;;;CAKA,AAAO,SAAS,KAAe;EAE7B,OAAO,MAAM,SAAS,GAAG;CAC3B;;;;;;CAOA,MAAa,SACX,MACA,eACA,UACc;EACd,OAAO,SAAS;CAClB;;;;CAKA,MAAa,gBAAgB,WAAmB;EAC9C,IAAI,KAAK,SAAS,sBAAsB,SAAS;EAEjD,IAAI,QAAQ,SAAS,qBAAqB,SAAS;EAEnD,OAAO;CACT;;;;CAKA,MAAa,IACX,KACA,QACA,eACc;EACd,IAAI,KAAK,SAAS,eAAe,GAAG;EAEpC,IAAI,QAAQ,SAAS,WAAW,GAAG;EAEnC,OAAO;CACT;;;;CAKA,MAAa,IAAI,KAAe;EAC9B,IAAI,KAAK,SAAS,YAAY,GAAG;EAEjC,IAAI,QAAQ,SAAS,WAAW,GAAG;EAEnC,OAAO;CACT;;;;CAKA,MAAa,OAAO,KAAe;EACjC,IAAI,KAAK,SAAS,YAAY,GAAG;EAEjC,IAAI,QAAQ,SAAS,WAAW,GAAG;CACrC;;;;CAKA,MAAa,QAAQ;EACnB,IAAI,KAAK,SAAS,YAAY,KAAK;EAEnC,IAAI,QAAQ,SAAS,WAAW,KAAK;CACvC;;;;;;;CAQA,MAAa,UAA0B;EACrC,OAAO,CAAC;CACV;;;;CAKA,MAAa,UAAU;EACrB,IAAI,QAAQ,SAAS,aAAa,gCAAgC;CACpE;AACF"}
1
+ {"version":3,"file":"null-cache-driver.mjs","names":[],"sources":["../../../../../../../cache/src/drivers/null-cache-driver.ts"],"sourcesContent":["import type { GenericObject } from \"@mongez/reinforcements\";\nimport { log } from \"@warlock.js/logger\";\nimport type {\n CacheDriver,\n CacheKey,\n CacheSetOptions,\n CacheTtl,\n NullCacheDriverOptions,\n RememberOptions,\n} from \"../types\";\nimport { BaseCacheDriver } from \"./base-cache-driver\";\n\nexport class NullCacheDriver\n extends BaseCacheDriver<NullCacheDriver, NullCacheDriverOptions>\n implements CacheDriver<NullCacheDriver, NullCacheDriverOptions>\n{\n /**\n * Options list\n */\n public options: GenericObject = {};\n\n /**\n * {@inheritdoc}\n */\n public name = \"null\";\n\n /**\n * Cached data\n */\n public data: GenericObject = {};\n\n /**\n * {@inheritdoc}\n */\n public get client() {\n return this;\n }\n\n /**\n * Constructor\n */\n public constructor(options: GenericObject = {}) {\n super();\n this.setOptions(options);\n }\n\n /**\n * {@inheritdoc}\n */\n public setOptions(options: GenericObject) {\n this.options = options;\n return this;\n }\n\n /**\n * {@inheritdoc}\n */\n public parseKey(key: CacheKey) {\n // Real parsed key so the base lock map never merges distinct keys.\n return super.parseKey(key);\n }\n\n /**\n * {@inheritdoc}\n *\n * Nothing is stored, so always run the callback and return its own result.\n */\n public async remember(\n _key: CacheKey,\n _ttlOrOptions: CacheTtl | RememberOptions,\n callback: () => Promise<any>,\n ): Promise<any> {\n return callback();\n }\n\n /**\n * {@inheritdoc}\n */\n public async removeNamespace(namespace: string) {\n log.info(\"cache\", \"clearing namespace\", namespace);\n\n log.success(\"cache\", \"namespace cleared\", namespace);\n\n return this;\n }\n\n /**\n * {@inheritdoc}\n */\n public async set(\n key: CacheKey,\n _value: any,\n _ttlOrOptions?: CacheTtl | CacheSetOptions,\n ): Promise<any> {\n log.info(\"cache\", \"setting key\", key);\n\n log.success(\"cache\", \"key set\", key);\n\n return this;\n }\n\n /**\n * {@inheritdoc}\n */\n public async get(key: CacheKey) {\n log.info(\"cache\", \"fetching\", key);\n\n log.success(\"cache\", \"fetched\", key);\n\n return null;\n }\n\n /**\n * {@inheritdoc}\n */\n public async remove(key: CacheKey) {\n log.info(\"cache\", \"removing\", key);\n\n log.success(\"cache\", \"removed\", key);\n }\n\n /**\n * {@inheritdoc}\n */\n public async flush() {\n log.info(\"cache\", \"flushing\", \"all\");\n\n log.success(\"cache\", \"flushed\", \"all\");\n }\n\n /**\n * {@inheritdoc}\n *\n * The null driver is a black-hole — `similar()` mirrors `get()` and returns\n * an empty result set rather than throwing.\n */\n public async similar(): Promise<any[]> {\n return [];\n }\n\n /**\n * {@inheritdoc}\n */\n public async connect() {\n log.success(\"cache\", \"connected\", \"Connected to null cache driver\");\n }\n}\n"],"mappings":";;;;AAYA,IAAa,kBAAb,cACU,gBAEV;;;;CAmBE,IAAW,SAAS;EAClB,OAAO;CACT;;;;CAKA,AAAO,YAAY,UAAyB,CAAC,GAAG;EAC9C,MAAM;iBAvBwB,CAAC;cAKnB;cAKe,CAAC;EAc5B,KAAK,WAAW,OAAO;CACzB;;;;CAKA,AAAO,WAAW,SAAwB;EACxC,KAAK,UAAU;EACf,OAAO;CACT;;;;CAKA,AAAO,SAAS,KAAe;EAE7B,OAAO,MAAM,SAAS,GAAG;CAC3B;;;;;;CAOA,MAAa,SACX,MACA,eACA,UACc;EACd,OAAO,SAAS;CAClB;;;;CAKA,MAAa,gBAAgB,WAAmB;EAC9C,IAAI,KAAK,SAAS,sBAAsB,SAAS;EAEjD,IAAI,QAAQ,SAAS,qBAAqB,SAAS;EAEnD,OAAO;CACT;;;;CAKA,MAAa,IACX,KACA,QACA,eACc;EACd,IAAI,KAAK,SAAS,eAAe,GAAG;EAEpC,IAAI,QAAQ,SAAS,WAAW,GAAG;EAEnC,OAAO;CACT;;;;CAKA,MAAa,IAAI,KAAe;EAC9B,IAAI,KAAK,SAAS,YAAY,GAAG;EAEjC,IAAI,QAAQ,SAAS,WAAW,GAAG;EAEnC,OAAO;CACT;;;;CAKA,MAAa,OAAO,KAAe;EACjC,IAAI,KAAK,SAAS,YAAY,GAAG;EAEjC,IAAI,QAAQ,SAAS,WAAW,GAAG;CACrC;;;;CAKA,MAAa,QAAQ;EACnB,IAAI,KAAK,SAAS,YAAY,KAAK;EAEnC,IAAI,QAAQ,SAAS,WAAW,KAAK;CACvC;;;;;;;CAQA,MAAa,UAA0B;EACrC,OAAO,CAAC;CACV;;;;CAKA,MAAa,UAAU;EACrB,IAAI,QAAQ,SAAS,aAAa,gCAAgC;CACpE;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"tagged-cache.d.mts","names":[],"sources":["../../../../../../cache/src/tagged-cache.ts"],"mappings":";;;;;AAaA;;cAAa,WAAA,YAAuB,iBAAA;EAShB;;;EAAA,UALR,SAAA;EAsC6B;;;EAAA,UAjC7B,MAAA,EAAQ,WAAA;EAqGyB;;;cAhGxB,IAAA,YAAgB,MAAA,EAAQ,WAAA;EAqJF;;;EAAA,UA7I/B,MAAA,CAAO,GAAA;EA+JW;;;EAAA,UAxJZ,cAAA,CAAe,GAAA,EAAK,QAAA,GAAW,OAAA;EA2KtB;;;;;;;;;EA9JZ,oBAAA,CAAqB,GAAA,EAAK,QAAA,GAAW,OAAA;EA2O3B;;;;EAAA,0BA5NG,sBAAA;EAkPgC;;;;;;EAAA,UA1O1C,QAAA,CAAS,MAAA,UAAgB,WAAA,WAAsB,OAAA;EAAA,UAgC/C,QAAA,CAAS,MAAA,UAAgB,OAAA,aAAoB,OAAA;EAAA,UAa7C,SAAA,CAAU,MAAA,WAAiB,OAAA;EAAA,UAQ3B,aAAA,CAAc,MAAA,UAAgB,OAAA,aAAoB,OAAA;EAAA,UAoBlD,aAAA,CAAc,MAAA,WAAiB,OAAA;EA5H5B;;;;;;;;;;EAAA,UA8IT,UAAA,CAAW,GAAA,EAAK,QAAA;EAlHQ;;;EAAA,UAyHlB,aAAA,IAAiB,OAAA,CAAQ,GAAA;EAlGhB;;;EAiHZ,GAAA,CACX,GAAA,EAAK,QAAA,EACL,KAAA,OACA,YAAA,GAAe,QAAA,GAAW,eAAA,GACzB,OAAA;EArFsB;;;EAgGZ,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EAnFP;;;EA0Fb,MAAA,CAAO,GAAA,EAAK,QAAA,GAAW,OAAA;EAlFU;;;EA+FjC,UAAA,IAAc,OAAA;EA3EoB;;;EAAA,UA+F/B,cAAA,CAAe,UAAA,WAAqB,OAAA;EAtEpC;;;;EAgFH,KAAA,IAAS,OAAA;EAhEpB;;;EAuEW,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EArE/B;;;EA4EW,QAAA,CACX,GAAA,EAAK,QAAA,EACL,GAAA,UACA,QAAA,QAAgB,OAAA,QACf,OAAA;EApEc;;;EAoFJ,IAAA,CAAK,GAAA,EAAK,QAAA,GAAW,OAAA;EA7Ed;;;EA4FP,OAAA,CAAQ,GAAA,EAAK,QAAA,EAAU,KAAA,QAAa,OAAA;EA3DjC;;;EAkEH,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAoB,OAAA;EAxDpC;;;EAqET,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAoB,OAAA;AAAA"}
1
+ {"version":3,"file":"tagged-cache.d.mts","names":[],"sources":["../../../../../../cache/src/tagged-cache.ts"],"mappings":";;;;;AAkBA;;cAAa,WAAA,YAAuB,iBAAA;EAShB;;;EAAA,UALR,SAAA;EAsC6B;;;EAAA,UAjC7B,MAAA,EAAQ,WAAA;EAqGyB;;;cAhGxB,IAAA,YAAgB,MAAA,EAAQ,WAAA;EAqJF;;;EAAA,UA7I/B,MAAA,CAAO,GAAA;EA+JW;;;EAAA,UAxJZ,cAAA,CAAe,GAAA,EAAK,QAAA,GAAW,OAAA;EA2KtB;;;;;;;;;EA9JZ,oBAAA,CAAqB,GAAA,EAAK,QAAA,GAAW,OAAA;EAyP3B;;;;EAAA,0BA1OG,sBAAA;EAgQgC;;;;;;EAAA,UAxP1C,QAAA,CAAS,MAAA,UAAgB,WAAA,WAAsB,OAAA;EAAA,UAgC/C,QAAA,CAAS,MAAA,UAAgB,OAAA,aAAoB,OAAA;EAAA,UAa7C,SAAA,CAAU,MAAA,WAAiB,OAAA;EAAA,UAQ3B,aAAA,CAAc,MAAA,UAAgB,OAAA,aAAoB,OAAA;EAAA,UAoBlD,aAAA,CAAc,MAAA,WAAiB,OAAA;EA5H5B;;;;;;;;;;EAAA,UA8IT,UAAA,CAAW,GAAA,EAAK,QAAA;EAlHQ;;;EAAA,UAyHlB,aAAA,IAAiB,OAAA,CAAQ,GAAA;EAlGhB;;;EAiHZ,GAAA,CACX,GAAA,EAAK,QAAA,EACL,KAAA,OACA,YAAA,GAAe,QAAA,GAAW,eAAA,GACzB,OAAA;EArFsB;;;EAgGZ,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EAnFP;;;EA0Fb,MAAA,CAAO,GAAA,EAAK,QAAA,GAAW,OAAA;EAlFU;;;EA+FjC,UAAA,IAAc,OAAA;EA3EoB;;;EAAA,UA6G/B,cAAA,CAAe,UAAA,WAAqB,OAAA;EApFpC;;;;EA8FH,KAAA,IAAS,OAAA;EA9EpB;;;EAqFW,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EAnF/B;;;EA0FW,QAAA,CACX,GAAA,EAAK,QAAA,EACL,GAAA,UACA,QAAA,QAAgB,OAAA,QACf,OAAA;EAlFc;;;EAkGJ,IAAA,CAAK,GAAA,EAAK,QAAA,GAAW,OAAA;EA3Fd;;;EA0GP,OAAA,CAAQ,GAAA,EAAK,QAAA,EAAU,KAAA,QAAa,OAAA;EA3DjC;;;EAkEH,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAoB,OAAA;EAxDpC;;;EAqET,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAoB,OAAA;AAAA"}
@@ -131,12 +131,22 @@ var TaggedCache = class TaggedCache {
131
131
  * Invalidate (clear) all keys associated with the current tags
132
132
  */
133
133
  async invalidate() {
134
+ const startedAt = performance.now();
135
+ const removed = /* @__PURE__ */ new Set();
134
136
  for (const tag of this.cacheTags) {
135
137
  const tagKey = this.tagKey(tag);
136
138
  const members = await this.membersOf(tagKey);
137
- for (const member of members) await this.driver.remove(member);
139
+ for (const member of members) {
140
+ await this.driver.remove(member);
141
+ removed.add(member);
142
+ }
138
143
  await this.removeFromTag(tagKey, members);
139
144
  }
145
+ await this.driver.emitTagsInvalidated?.({
146
+ tags: [...this.cacheTags],
147
+ keys: [...removed],
148
+ durationMs: performance.now() - startedAt
149
+ });
140
150
  }
141
151
  /**
142
152
  * Remove `indexedKey` from every tag of this handle.
@@ -1 +1 @@
1
- {"version":3,"file":"tagged-cache.mjs","names":[],"sources":["../../../../../../cache/src/tagged-cache.ts"],"sourcesContent":["import type {\r\n CacheDriver,\r\n CacheKey,\r\n CacheSetOptions,\r\n CacheTtl,\r\n TaggedCacheDriver,\r\n} from \"./types\";\r\nimport { parseCacheKey } from \"./utils\";\r\n\r\n/**\r\n * Tagged Cache Wrapper\r\n * Wraps a cache driver to automatically manage tag relationships\r\n */\r\nexport class TaggedCache implements TaggedCacheDriver {\r\n /**\r\n * The tags associated with this tagged cache instance\r\n */\r\n protected cacheTags: string[];\r\n\r\n /**\r\n * The underlying cache driver\r\n */\r\n protected driver: CacheDriver<any, any>;\r\n\r\n /**\r\n * Constructor\r\n */\r\n public constructor(tags: string[], driver: CacheDriver<any, any>) {\r\n this.cacheTags = tags;\r\n this.driver = driver;\r\n }\r\n\r\n /**\r\n * Get the tag key prefix for storing tag-key relationships\r\n */\r\n protected tagKey(tag: string): string {\r\n return `cache:tags:${tag}`;\r\n }\r\n\r\n /**\r\n * Store tag-key relationship\r\n */\r\n protected async storeTaggedKey(key: CacheKey): Promise<void> {\r\n await this.storeTagRelationship(key);\r\n }\r\n\r\n /**\r\n * Public alias of the tag-index writer. Called by `BaseCacheDriver.applyTags`\r\n * when tags are passed inline through `CacheSetOptions.tags`.\r\n *\r\n * Takes the caller's key, never the driver-parsed one — see {@link indexedKey}.\r\n *\r\n * @internal — public for cross-class use within this package; not part of the\r\n * stable consumer API.\r\n */\r\n public async storeTagRelationship(key: CacheKey): Promise<void> {\r\n const indexedKey = this.indexedKey(key);\r\n\r\n for (const tag of this.cacheTags) {\r\n const tagKey = this.tagKey(tag);\r\n\r\n await this.addToTag(tagKey, [indexedKey]);\r\n await this.pruneTag(tagKey, indexedKey);\r\n }\r\n }\r\n\r\n /**\r\n * Upper bound on member-existence checks per tagged write, so pruning stays\r\n * O(1) per write no matter how large an index grows.\r\n */\r\n protected static readonly PRUNE_CHECKS_PER_WRITE = 20;\r\n\r\n /**\r\n * Drop index members whose entry no longer exists (expired, evicted, or\r\n * removed outside a tagged handle). Checks a random window of at most\r\n * {@link PRUNE_CHECKS_PER_WRITE} members, so a long-lived index converges\r\n * to its live members without any write paying for a full scan.\r\n */\r\n protected async pruneTag(tagKey: string, justWritten: string): Promise<void> {\r\n const members = (await this.membersOf(tagKey)).filter((member) => member !== justWritten);\r\n\r\n if (members.length === 0) {\r\n return;\r\n }\r\n\r\n const limit = TaggedCache.PRUNE_CHECKS_PER_WRITE;\r\n const start = members.length > limit ? Math.floor(Math.random() * members.length) : 0;\r\n const window = Array.from(\r\n { length: Math.min(limit, members.length) },\r\n (_, index) => members[(start + index) % members.length]!,\n );\r\n\r\n const missing: string[] = [];\r\n\r\n for (const member of window) {\r\n if (!(await this.driver.has(member))) {\r\n missing.push(member);\r\n }\r\n }\r\n\r\n if (missing.length > 0) {\r\n await this.removeFromTag(tagKey, missing);\r\n }\r\n }\r\n\r\n // ------------------------------------------------------------\r\n // Tag-index access: the driver's primitives when it has them, else\r\n // the legacy get/set array (third-party drivers without primitives).\r\n // ------------------------------------------------------------\r\n\r\n protected async addToTag(tagKey: string, members: string[]): Promise<void> {\r\n if (typeof this.driver.tagAdd === \"function\") {\r\n return this.driver.tagAdd(tagKey, members);\r\n }\r\n\r\n const current = await this.legacyMembers(tagKey);\r\n const merged = [...new Set([...current, ...members])];\r\n\r\n if (merged.length !== current.length) {\r\n await this.driver.set(tagKey, merged, Infinity);\r\n }\r\n }\r\n\r\n protected async membersOf(tagKey: string): Promise<string[]> {\r\n if (typeof this.driver.tagMembers === \"function\") {\r\n return this.driver.tagMembers(tagKey);\r\n }\r\n\r\n return this.legacyMembers(tagKey);\r\n }\r\n\r\n protected async removeFromTag(tagKey: string, members: string[]): Promise<void> {\r\n if (typeof this.driver.tagRemove === \"function\") {\r\n return this.driver.tagRemove(tagKey, members);\r\n }\r\n\r\n const dropped = new Set(members);\r\n const current = await this.legacyMembers(tagKey);\r\n const kept = current.filter((member) => !dropped.has(member));\r\n\r\n if (kept.length === current.length) {\r\n return;\r\n }\r\n\r\n if (kept.length === 0) {\r\n await this.driver.remove(tagKey);\r\n } else {\r\n await this.driver.set(tagKey, kept, Infinity);\r\n }\r\n }\r\n\r\n protected async legacyMembers(tagKey: string): Promise<string[]> {\r\n const value = await this.driver.get(tagKey);\r\n\r\n return Array.isArray(value)\r\n ? value.filter((member): member is string => typeof member === \"string\")\r\n : [];\r\n }\r\n\r\n /**\r\n * The form a key takes inside a tag index: normalized but un-prefixed.\r\n *\r\n * The index is read back and deleted through `driver.remove(key)`, which\r\n * applies `globalPrefix` itself — so the index must hold the key *before*\r\n * the prefix, or invalidation would prefix it twice and delete nothing.\r\n * With a function prefix, the current prefix is re-applied at invalidation\r\n * time; the tag index key is resolved under that same prefix, so the two\r\n * agree as long as the prefix is stable for a given request/tenant.\r\n */\r\n protected indexedKey(key: CacheKey): string {\r\n return parseCacheKey(key);\r\n }\r\n\r\n /**\r\n * Get all keys associated with tags\r\n */\r\n protected async getTaggedKeys(): Promise<Set<string>> {\r\n const allKeys = new Set<string>();\r\n\r\n for (const tag of this.cacheTags) {\r\n for (const key of await this.membersOf(this.tagKey(tag))) {\r\n allKeys.add(key);\r\n }\r\n }\r\n\r\n return allKeys;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async set(\r\n key: CacheKey,\r\n value: any,\r\n ttlOrOptions?: CacheTtl | CacheSetOptions,\r\n ): Promise<any> {\r\n await this.driver.set(key, value, ttlOrOptions);\r\n\r\n await this.storeTaggedKey(key);\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async get(key: CacheKey): Promise<any | null> {\r\n return this.driver.get(key);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async remove(key: CacheKey): Promise<void> {\r\n const indexedKey = this.indexedKey(key);\r\n\r\n // Remove the value\r\n await this.driver.remove(key);\r\n\r\n // Remove from all tag relationships\r\n await this.detachFromTags(indexedKey);\r\n }\r\n\r\n /**\r\n * Invalidate (clear) all keys associated with the current tags\r\n */\r\n public async invalidate(): Promise<void> {\r\n for (const tag of this.cacheTags) {\r\n const tagKey = this.tagKey(tag);\r\n const members = await this.membersOf(tagKey);\r\n\r\n // Remove the tagged entries — indexed un-prefixed, so `remove()` prefixes once\r\n for (const member of members) {\r\n await this.driver.remove(member);\r\n }\r\n\r\n // Remove exactly the members read above rather than dropping the whole\r\n // index: a key tagged concurrently (after the read) keeps its entry in\r\n // the index, so a later invalidate still reaches it.\r\n await this.removeFromTag(tagKey, members);\r\n }\r\n }\r\n\r\n /**\r\n * Remove `indexedKey` from every tag of this handle.\r\n */\r\n protected async detachFromTags(indexedKey: string): Promise<void> {\r\n for (const tag of this.cacheTags) {\r\n await this.removeFromTag(this.tagKey(tag), [indexedKey]);\r\n }\r\n }\r\n\r\n /**\r\n * Flush all keys associated with the current tags\r\n * @deprecated Use invalidate() instead for better semantics\r\n */\r\n public async flush(): Promise<void> {\r\n return this.invalidate();\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async has(key: CacheKey): Promise<boolean> {\r\n return this.driver.has(key);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async remember(\r\n key: CacheKey,\r\n ttl: number,\r\n callback: () => Promise<any>,\r\n ): Promise<any> {\r\n const value = await this.get(key);\r\n\r\n if (value !== null) {\r\n return value;\r\n }\r\n\r\n const result = await callback();\r\n await this.set(key, result, ttl);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async pull(key: CacheKey): Promise<any | null> {\r\n // The driver's own `pull` (atomic on redis / pg / in-process drivers)\r\n // hands the value out once; then the key leaves this handle's tags.\r\n const value = await this.driver.pull(key);\r\n\r\n if (value !== null) {\r\n await this.detachFromTags(this.indexedKey(key));\r\n }\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async forever(key: CacheKey, value: any): Promise<any> {\r\n return this.set(key, value, Infinity);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async increment(key: CacheKey, value: number = 1): Promise<number> {\r\n // The driver's atomic increment (INCRBY / pg upsert / synchronous\r\n // in-process), then record the tag relationship.\r\n const newValue = await this.driver.increment(key, value);\r\n\r\n await this.storeTaggedKey(key);\r\n\r\n return newValue;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async decrement(key: CacheKey, value: number = 1): Promise<number> {\r\n return this.increment(key, -value);\r\n }\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"tagged-cache.mjs","names":[],"sources":["../../../../../../cache/src/tagged-cache.ts"],"sourcesContent":["import type {\n CacheDriver,\n CacheKey,\n CacheSetOptions,\n CacheTtl,\n TaggedCacheDriver,\n} from \"./types\";\nimport { parseCacheKey } from \"./utils\";\n\n/** Implemented by `BaseCacheDriver`; a custom driver may not have it. */\ntype TagsInvalidatedEmitter = {\n emitTagsInvalidated(data: { tags: string[]; keys: string[]; durationMs: number }): Promise<void>;\n};\n\n/**\n * Tagged Cache Wrapper\n * Wraps a cache driver to automatically manage tag relationships\n */\nexport class TaggedCache implements TaggedCacheDriver {\n /**\n * The tags associated with this tagged cache instance\n */\n protected cacheTags: string[];\n\n /**\n * The underlying cache driver\n */\n protected driver: CacheDriver<any, any>;\n\n /**\n * Constructor\n */\n public constructor(tags: string[], driver: CacheDriver<any, any>) {\n this.cacheTags = tags;\n this.driver = driver;\n }\n\n /**\n * Get the tag key prefix for storing tag-key relationships\n */\n protected tagKey(tag: string): string {\n return `cache:tags:${tag}`;\n }\n\n /**\n * Store tag-key relationship\n */\n protected async storeTaggedKey(key: CacheKey): Promise<void> {\n await this.storeTagRelationship(key);\n }\n\n /**\n * Public alias of the tag-index writer. Called by `BaseCacheDriver.applyTags`\n * when tags are passed inline through `CacheSetOptions.tags`.\n *\n * Takes the caller's key, never the driver-parsed one — see {@link indexedKey}.\n *\n * @internal — public for cross-class use within this package; not part of the\n * stable consumer API.\n */\n public async storeTagRelationship(key: CacheKey): Promise<void> {\n const indexedKey = this.indexedKey(key);\n\n for (const tag of this.cacheTags) {\n const tagKey = this.tagKey(tag);\n\n await this.addToTag(tagKey, [indexedKey]);\n await this.pruneTag(tagKey, indexedKey);\n }\n }\n\n /**\n * Upper bound on member-existence checks per tagged write, so pruning stays\n * O(1) per write no matter how large an index grows.\n */\n protected static readonly PRUNE_CHECKS_PER_WRITE = 20;\n\n /**\n * Drop index members whose entry no longer exists (expired, evicted, or\n * removed outside a tagged handle). Checks a random window of at most\n * {@link PRUNE_CHECKS_PER_WRITE} members, so a long-lived index converges\n * to its live members without any write paying for a full scan.\n */\n protected async pruneTag(tagKey: string, justWritten: string): Promise<void> {\n const members = (await this.membersOf(tagKey)).filter((member) => member !== justWritten);\n\n if (members.length === 0) {\n return;\n }\n\n const limit = TaggedCache.PRUNE_CHECKS_PER_WRITE;\n const start = members.length > limit ? Math.floor(Math.random() * members.length) : 0;\n const window = Array.from(\n { length: Math.min(limit, members.length) },\n (_, index) => members[(start + index) % members.length]!,\n );\n\n const missing: string[] = [];\n\n for (const member of window) {\n if (!(await this.driver.has(member))) {\n missing.push(member);\n }\n }\n\n if (missing.length > 0) {\n await this.removeFromTag(tagKey, missing);\n }\n }\n\n // ------------------------------------------------------------\n // Tag-index access: the driver's primitives when it has them, else\n // the legacy get/set array (third-party drivers without primitives).\n // ------------------------------------------------------------\n\n protected async addToTag(tagKey: string, members: string[]): Promise<void> {\n if (typeof this.driver.tagAdd === \"function\") {\n return this.driver.tagAdd(tagKey, members);\n }\n\n const current = await this.legacyMembers(tagKey);\n const merged = [...new Set([...current, ...members])];\n\n if (merged.length !== current.length) {\n await this.driver.set(tagKey, merged, Infinity);\n }\n }\n\n protected async membersOf(tagKey: string): Promise<string[]> {\n if (typeof this.driver.tagMembers === \"function\") {\n return this.driver.tagMembers(tagKey);\n }\n\n return this.legacyMembers(tagKey);\n }\n\n protected async removeFromTag(tagKey: string, members: string[]): Promise<void> {\n if (typeof this.driver.tagRemove === \"function\") {\n return this.driver.tagRemove(tagKey, members);\n }\n\n const dropped = new Set(members);\n const current = await this.legacyMembers(tagKey);\n const kept = current.filter((member) => !dropped.has(member));\n\n if (kept.length === current.length) {\n return;\n }\n\n if (kept.length === 0) {\n await this.driver.remove(tagKey);\n } else {\n await this.driver.set(tagKey, kept, Infinity);\n }\n }\n\n protected async legacyMembers(tagKey: string): Promise<string[]> {\n const value = await this.driver.get(tagKey);\n\n return Array.isArray(value)\n ? value.filter((member): member is string => typeof member === \"string\")\n : [];\n }\n\n /**\n * The form a key takes inside a tag index: normalized but un-prefixed.\n *\n * The index is read back and deleted through `driver.remove(key)`, which\n * applies `globalPrefix` itself — so the index must hold the key *before*\n * the prefix, or invalidation would prefix it twice and delete nothing.\n * With a function prefix, the current prefix is re-applied at invalidation\n * time; the tag index key is resolved under that same prefix, so the two\n * agree as long as the prefix is stable for a given request/tenant.\n */\n protected indexedKey(key: CacheKey): string {\n return parseCacheKey(key);\n }\n\n /**\n * Get all keys associated with tags\n */\n protected async getTaggedKeys(): Promise<Set<string>> {\n const allKeys = new Set<string>();\n\n for (const tag of this.cacheTags) {\n for (const key of await this.membersOf(this.tagKey(tag))) {\n allKeys.add(key);\n }\n }\n\n return allKeys;\n }\n\n /**\n * {@inheritdoc}\n */\n public async set(\n key: CacheKey,\n value: any,\n ttlOrOptions?: CacheTtl | CacheSetOptions,\n ): Promise<any> {\n await this.driver.set(key, value, ttlOrOptions);\n\n await this.storeTaggedKey(key);\n\n return value;\n }\n\n /**\n * {@inheritdoc}\n */\n public async get(key: CacheKey): Promise<any | null> {\n return this.driver.get(key);\n }\n\n /**\n * {@inheritdoc}\n */\n public async remove(key: CacheKey): Promise<void> {\n const indexedKey = this.indexedKey(key);\n\n // Remove the value\n await this.driver.remove(key);\n\n // Remove from all tag relationships\n await this.detachFromTags(indexedKey);\n }\n\n /**\n * Invalidate (clear) all keys associated with the current tags\n */\n public async invalidate(): Promise<void> {\n const startedAt = performance.now();\n const removed = new Set<string>();\n\n for (const tag of this.cacheTags) {\n const tagKey = this.tagKey(tag);\n const members = await this.membersOf(tagKey);\n\n // Remove the tagged entries — indexed un-prefixed, so `remove()` prefixes once\n for (const member of members) {\n await this.driver.remove(member);\n removed.add(member);\n }\n\n // Remove exactly the members read above rather than dropping the whole\n // index: a key tagged concurrently (after the read) keeps its entry in\n // the index, so a later invalidate still reaches it.\n await this.removeFromTag(tagKey, members);\n }\n\n // Drivers built on `BaseCacheDriver` emit `invalidated`; a custom driver\n // without the method simply emits nothing.\n const driver = this.driver as Partial<TagsInvalidatedEmitter>;\n\n await driver.emitTagsInvalidated?.({\n tags: [...this.cacheTags],\n keys: [...removed],\n durationMs: performance.now() - startedAt,\n });\n }\n\n /**\n * Remove `indexedKey` from every tag of this handle.\n */\n protected async detachFromTags(indexedKey: string): Promise<void> {\n for (const tag of this.cacheTags) {\n await this.removeFromTag(this.tagKey(tag), [indexedKey]);\n }\n }\n\n /**\n * Flush all keys associated with the current tags\n * @deprecated Use invalidate() instead for better semantics\n */\n public async flush(): Promise<void> {\n return this.invalidate();\n }\n\n /**\n * {@inheritdoc}\n */\n public async has(key: CacheKey): Promise<boolean> {\n return this.driver.has(key);\n }\n\n /**\n * {@inheritdoc}\n */\n public async remember(\n key: CacheKey,\n ttl: number,\n callback: () => Promise<any>,\n ): Promise<any> {\n const value = await this.get(key);\n\n if (value !== null) {\n return value;\n }\n\n const result = await callback();\n await this.set(key, result, ttl);\n\n return result;\n }\n\n /**\n * {@inheritdoc}\n */\n public async pull(key: CacheKey): Promise<any | null> {\n // The driver's own `pull` (atomic on redis / pg / in-process drivers)\n // hands the value out once; then the key leaves this handle's tags.\n const value = await this.driver.pull(key);\n\n if (value !== null) {\n await this.detachFromTags(this.indexedKey(key));\n }\n\n return value;\n }\n\n /**\n * {@inheritdoc}\n */\n public async forever(key: CacheKey, value: any): Promise<any> {\n return this.set(key, value, Infinity);\n }\n\n /**\n * {@inheritdoc}\n */\n public async increment(key: CacheKey, value: number = 1): Promise<number> {\n // The driver's atomic increment (INCRBY / pg upsert / synchronous\n // in-process), then record the tag relationship.\n const newValue = await this.driver.increment(key, value);\n\n await this.storeTaggedKey(key);\n\n return newValue;\n }\n\n /**\n * {@inheritdoc}\n */\n public async decrement(key: CacheKey, value: number = 1): Promise<number> {\n return this.increment(key, -value);\n }\n}\n"],"mappings":"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"}
package/esm/types.d.mts CHANGED
@@ -324,7 +324,7 @@ type CacheOperationType = "fetching" | "fetched" | "caching" | "cached" | "flush
324
324
  /**
325
325
  * Cache event types for observability
326
326
  */
327
- type CacheEventType = "hit" | "miss" | "set" | "removed" | "flushed" | "expired" | "connected" | "disconnected" | "error";
327
+ type CacheEventType = "hit" | "miss" | "set" | "removed" | "invalidated" | "flushed" | "expired" | "connected" | "disconnected" | "error";
328
328
  /**
329
329
  * Cache event data structure
330
330
  */
@@ -352,7 +352,10 @@ type CacheEventData = {
352
352
  /**
353
353
  * Namespace (for namespace operations)
354
354
  */
355
- namespace?: string;
355
+ namespace?: string; /** Tags passed to `tags([...]).invalidate()` (`invalidated` events only). */
356
+ tags?: string[]; /** Keys a tag invalidation removed (`invalidated` events only). */
357
+ keys?: string[]; /** How long the operation took, in milliseconds (`invalidated` events only). */
358
+ durationMs?: number;
356
359
  };
357
360
  /**
358
361
  * Event handler function type
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../cache/src/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../cache/src/types.ts"],"mappings":";;;;;;;;;;;;;;;;cAiBa,UAAA,SAAmB,KAAK;cAChB,OAAA;AAAA;;;;cASR,oBAAA,SAA6B,UAAU;cAC/B,OAAA;AAAA;;;;cASR,uBAAA,SAAgC,UAAU;cAClC,OAAA;AAAA;;AApBe;AASpC;cAoBa,8BAAA,SAAuC,UAAU;cAE1D,OAAA;AAAA;;;;;AArBgC;AASpC;cAyBa,qBAAA,SAA8B,UAAU;cAChC,OAAA;AAAA;;;;cASR,qBAAA,SAA8B,UAAU;cAChC,OAAA;AAAA;;;;;;;;KAaT,QAAA;AAxBZ;;;;;;;AAAA,KAiCY,mBAAA;AAhCwB;AASpC;;AAToC,KAqCxB,cAAA;EA5ByC;;;EAgCnD,MAAA;EA/BkC;AAAA;AAapC;;EAuBE,QAAA,EAAU,CAAC;AAAA;AAvBO;AASpB;;;;AAA+B;AAK/B;;;;AAdoB,KAoCR,WAAA;EAlBV;;;;EAuBA,GAAA,EAAK,QAAQ;EALH;;;;EAUV,KAAA;EALK;;;EASL,MAAA;AAAA;AAgBF;;;;;;;;;;AAEc;AAad;;AAfA,KAAY,WAAA;EACN,QAAA;EAAgB,KAAA,EAAO,CAAC;AAAA;EACxB,QAAA;AAAA;;AA0BE;AAaR;;;;;;;;;KA1BY,eAAA;EAkCV;;;EA9BA,GAAA,GAAM,QAAQ;EAuCD;;;EAnCb,IAAA;EAkEA;;AAAO;AAWT;EAxEE,MAAA;AAAA;;;;;;AAqFI;AAoBN;;;;KA5FY,eAAA;EAkGA;;;EA9FV,GAAA,GAAM,QAAA;EA+GN;;AAAM;EA3GN,SAAA,YAAqB,IAAA;EAkHQ;;;;EA7G7B,IAAA;EA4HA;;AAAI;EAxHJ,UAAA,GAAa,mBAAA;EA+HY;;;EA3HzB,SAAA;EA+HA;;;;EA1HA,MAAA;EAmIK;AAMP;;;;AAA6C;AAE7C;;;;AAA8B;EA/H5B,MAAA;EAsJwB;;;AAAA;AAe1B;;;;;EA3JE,OAAA;AAAA;;;;;;;;AAyLU;KA9KA,qBAAA;EAoLiB;;;;EA/K3B,GAAA,GAAM,QAAQ;EA+KsD;;AAAO;AAU7E;;;;EAjLE,IAAA;AAAA;;;;;;;;;;;;;;;;;;KAoBU,eAAA;EAqLD;AAAA;AAMX;;;EArLE,QAAA,EAAU,QAAA;EAyLoC;;;;;EAnL9C,QAAA,EAAU,QAAQ;EA2LK;;;;EAtLvB,IAAA;EAuMc;;;;;EAjMd,MAAA;AAAA;;;;;KAOU,mBAAA;EA0MuC;;;;EArMjD,IAAA;EA4J8C;;;;EAvJ9C,SAAA;EA2JS;;;;EAtJT,IAAA;AAAA;;;;;KAOU,eAAA;EAgKV;;;EA5JA,GAAA;EAgKA;;;;EA3JA,KAAA,EAAO,CAAC;EA2J6B;;;EAvJrC,KAAA;AAAA;;;;KAMU,QAAA,YAAoB,aAAa;AAAA,KAEjC,kBAAA;;;;KAuBA,cAAA;;;;KAeA,cAAA;EAyHA;;;EArHV,GAAA;EAqHiD;AAGnD;;EApHE,KAAA;EA+Hc;;;EA3Hd,GAAA;EAkIA;;AAAO;EA9HP,MAAA;EAiIoC;;;EA7HpC,KAAA;EA+HU;;;EA3HV,SAAA,WAiIA;EA/HA,IAAA,aA2IA;EAzIA,IAAA,aAyIc;EAvId,UAAA;AAAA;;;;KAMU,iBAAA,IAAqB,SAAA,EAAW,cAAA,YAA0B,OAAO;;;;;;AA2JnE;AAGV;;KApJY,oBAAA;EA2LwB,kEAzLlC,IAAA,UA4JA;EA1JA,MAAA,UAkKA;EAhKA,IAAA,UA0KA;EAxKA,OAAA,UA+KM;EA7KN,MAAA,UAiLgB;EA/KhB,OAAA,UA+KkC;EA7KlC,SAAA;IACE,GAAA;IACA,GAAA;IACA,GAAA,UA6K8C;IA3K9C,OAAA;EAAA;EAGF,QAAA,EAAU,MAAA,SAAe,IAAA,CAAK,oBAAA,gBAmL9B;EAjLA,SAAA;AAAA;;AAuLc;AAQhB;UAzLiB,iBAAA;;;;EAIf,GAAA,CAAI,GAAA,EAAK,QAAA,EAAU,KAAA,OAAY,YAAA,GAAe,QAAA,GAAW,eAAA,GAAkB,OAAA;EAoM3E;;;EAhMA,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EAgNV;;;EA5MV,MAAA,CAAO,GAAA,EAAK,QAAA,GAAW,OAAA;EA6MvB;;;EAzMA,UAAA,IAAc,OAAA;EAyMqC;;;AAAqB;EApMxE,KAAA,IAAS,OAAA;EAuMe;;;EAnMxB,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EAwMZ;;;EApMR,QAAA,CAAS,GAAA,EAAK,QAAA,EAAU,GAAA,UAAa,QAAA,QAAgB,OAAA,QAAe,OAAA;EAsN9D;;;EAlNN,IAAA,CAAK,GAAA,EAAK,QAAA,GAAW,OAAA;EA2Od;AAAA;AAIT;EA3OE,OAAA,CAAQ,GAAA,EAAK,QAAA,EAAU,KAAA,QAAa,OAAA;EA2OV;;;EAvO1B,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EA+P5B;;;EA3Pd,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;AAAA;AAAA,KAGhC,kBAAA;EAqR2B;;;EAjRrC,YAAA;EAyRS;;;;;;EAlRT,GAAA,GAAM,QAAQ;EAsTE;;;;;;EA/ShB,OAAA;AAAA;AAAA,KAGU,0BAAA,GAA6B,kBAAkB;AAAA,KAE/C,qBAAA;EAkUC;;;;;EA5TX,QAAA;EAwUuC;;;;EAnUvC,YAAA;EAwV6B;;;;;;EAjV7B,GAAA,GAAM,QAAQ;AAAA;AAAA,KAGJ,gBAAA;EA2VS;;;EAvVnB,YAAA;EAyVG;;;;;;EAlVH,GAAA,GAAM,QAAQ;EA4Wa;;;;;EAtW3B,SAAA;EAoXe;;;;;EA9Wf,QAAA;AAAA;AAAA,KAGU,YAAA;EA8XA;;;;;EAxXV,IAAA;EAsYY;;;EAlYZ,IAAA;EAiZ8C;;;EA7Y9C,QAAA;EAsZiD;;;EAlZjD,QAAA;EAsa2B;;;;;EAha3B,GAAA;EAkIuC;;;EA9HvC,YAAA;EA0IA;;;;;;EAnIA,GAAA,GAAM,QAAA;EA2IK;;;EAvIX,aAAA,GAAgB,kBAAkB;AAAA;AAAA,KAGxB,sBAAA,GAAyB,aAAa;;;;;;KAOtC,gBAAA;EA8JV;;;EA1JA,YAAA;EA0J6B;;;;;EApJ7B,GAAA,GAAM,QAAQ;AAAA;;;;;;KAQJ,SAAA;EAgKI;;;;EA3Jd,SAAA;EAiLA;;;;EA5KA,GAAA;EA8K2B;;;;EAzK3B,IAAA;EA2KG;;;;EAtKH,SAAA;AAAA;;;;;;;;;KAWU,YAAA;EACV,KAAA,CAAM,IAAA,UAAc,MAAA,eAAqB,OAAO;IAAG,IAAA;IAAa,QAAA;EAAA;AAAA;AAAA,KAGtD,cAAA;EAyLY;;;;EApLtB,MAAA,EAAQ,YAAA;EAoL2C;;;;;;EA7KnD,KAAA;EAkM6B;;;EA9L7B,YAAA;EA+Lc;;;;;;EAxLd,GAAA,GAAM,QAAQ;EAkME;;;;;;;;;;;;EArLhB,MAAA;IAkMK;;;;IA7LH,UAAA;IA4MF;;;;;;IArME,KAAA;EAAA;AAAA;AAAA,UAIa,WAAA;EAoMb;;;EAhMF,OAAA,EAAS,OAAA;EA6MT;;;EAzMA,IAAA;EAyM0C;;;EArM1C,eAAA,CAAgB,SAAA;EA4MS;;;EAxMzB,eAAA,CAAgB,SAAA,WAAoB,OAAA;EA4M/B;;;EAxML,UAAA,CAAW,OAAA,EAAS,OAAA;EA4MZ;;;EAxMR,QAAA,CAAS,GAAA,EAAK,QAAA;EA4MJ;;;;;;;;;;;;;;;;;;;;EAvLV,GAAA,CACE,GAAA,EAAK,QAAA,EACL,KAAA,OACA,YAAA,GAAe,QAAA,GAAW,eAAA,GACzB,OAAA;EAqME;;;EAjML,GAAA,UAAa,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EA4M7B;;;EAxMR,MAAA,CAAO,GAAA,EAAK,QAAA,GAAW,OAAA;EA4MH;;;EAxMpB,KAAA,IAAS,OAAA;EA6MU;;;EAzMnB,OAAA,IAAW,OAAA;EA6MX;;;EAzMA,MAAA,GAAS,UAAA;EAsNT;;;EAlNA,UAAA,IAAc,OAAA;EAoNZ;;;EAhNF,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EAiNQ;AAAA;AAS9B;;;;;;;;;;;;;;;EAxME,QAAA,UACE,GAAA,EAAK,QAAA,EACL,YAAA,EAAc,QAAA,GAAW,eAAA,EACzB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IACvB,OAAA,CAAQ,CAAA;EAoOuB;;;;;;;;;;;;;;;;;EAlNlC,GAAA,UACE,GAAA,EAAK,QAAA,EACL,OAAA,EAAS,eAAA,EACT,QAAA,QAAgB,OAAA,CAAQ,CAAA,IACvB,OAAA,CAAQ,CAAA;EA8LM;;;;;;;EAtLjB,IAAA,UAAc,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EA8LvB;;;EA1Lf,OAAA,UAAiB,GAAA,EAAK,QAAA,EAAU,KAAA,EAAO,CAAA,GAAI,OAAA,CAAQ,CAAA;EAkM9C;;;;;;AAIW;AAWlB;;;;;;;;;;;EA9LE,MAAA,UACE,GAAA,EAAK,QAAA,EACL,EAAA,GAAK,OAAA,EAAS,CAAA,YAAa,CAAA,UAAW,OAAA,CAAQ,CAAA,UAC9C,OAAA;IAAY,GAAA,GAAM,QAAA;EAAA,IACjB,OAAA,CAAQ,CAAA;EA+LQ;;;;;;;;EAtLnB,KAAA,WAAgB,MAAA,gBAAsB,MAAA,eACpC,GAAA,EAAK,QAAA,EACL,OAAA,EAAS,OAAA,CAAQ,CAAA,GACjB,OAAA;IAAY,GAAA,GAAM,QAAA;EAAA,IACjB,OAAA,CAAQ,CAAA;EAuLgB;;;;;;;;EA9K3B,IAAA,UAAc,GAAA,EAAK,QAAA,GAAW,iBAAA,CAAkB,CAAA;EAuLlC;;;;;;;;;;;;;;EAxKd,IAAA,IACE,GAAA,EAAK,QAAA,EACL,YAAA,EAAc,QAAA,GAAW,IAAA,CAAK,WAAA,aAC9B,EAAA,QAAU,OAAA,CAAQ,CAAA,IACjB,OAAA,CAAQ,WAAA,CAAY,CAAA;EAmJM;;;;;;;;;;;EAvI7B,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EA0IvB;;;;;;EAnInB,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EAoIzB;;;EAhIjB,IAAA,CAAK,IAAA,EAAM,QAAA,KAAa,OAAA;EAgI2B;;;EA5HnD,OAAA,CAAQ,KAAA,EAAO,MAAA,eAAqB,GAAA,YAAe,OAAA;EA6H9B;;;EAzHrB,EAAA,CAAG,KAAA,EAAO,cAAA,EAAgB,OAAA,EAAS,iBAAA;EA0H1B;;;EAtHT,GAAA,CAAI,KAAA,EAAO,cAAA,EAAgB,OAAA,EAAS,iBAAA;EAwHT;;;EApH3B,IAAA,CAAK,KAAA,EAAO,cAAA,EAAgB,OAAA,EAAS,iBAAA;EAqHnC;;;;;EA/GF,KAAA,EAAO,GAAA,EAAK,QAAA,EAAU,KAAA,OAAY,GAAA,YAAe,OAAA;EAiHxB;;;EA7GzB,IAAA,CAAK,IAAA,aAAiB,iBAAA;EA8GZ;;;;;;AAKW;AAgBvB;;;EAxHE,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAU,OAAA,aAAoB,OAAA;EAoIc;;;EAhI5D,UAAA,EAAY,MAAA,EAAQ,QAAA,GAAW,OAAA;EA2IM;;;;EAtIrC,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAU,OAAA,aAAoB,OAAA;EAwIzB;;;EApIxB,SAAA,EAAW,MAAA,EAAQ,QAAA,GAAW,OAAA;EAwIrB;;;;;;;;;;;;EA3HT,OAAA,UACE,MAAA,YACA,OAAA,EAAS,mBAAA,GACR,OAAA,CAAQ,eAAA,CAAgB,CAAA;AAAA;;;;;;;UASZ,iBAAA;EA4HR;;;EAxHP,IAAA,IAAQ,KAAA,EAAO,CAAA,KAAM,OAAA;EA2HV;;;EAvHX,OAAA,IAAW,KAAA,EAAO,CAAA,KAAM,OAAA;EA2HT;;;EAvHf,GAAA,IAAO,OAAA,CAAQ,CAAA;EA0Hc;;;EAtH7B,KAAA,IAAS,OAAA,CAAQ,CAAA;EAwHN;;;EApHX,KAAA,CAAM,KAAA,WAAgB,GAAA,YAAe,OAAA,CAAQ,CAAA;EAsHtC;;;EAlHP,GAAA,IAAO,OAAA,CAAQ,CAAA;EAqHJ;;;EAjHX,MAAA,IAAU,OAAA;EAoHoB;;;EAhH9B,IAAA,CAAK,KAAA,UAAe,GAAA,WAAc,OAAA;EAqHP;;;EAjH3B,KAAA,IAAS,OAAA;AAAA;;;;;;;;;UAWM,yBAAA;EACf,GAAA,CAAI,GAAA,EAAK,QAAA,EAAU,KAAA,OAAY,YAAA,GAAe,QAAA,GAAW,eAAA,GAAkB,OAAA;EAC3E,GAAA,UAAa,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EACrC,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EACpB,MAAA,CAAO,GAAA,EAAK,QAAA,GAAW,OAAA;EACvB,IAAA,UAAc,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EACtC,OAAA,UAAiB,GAAA,EAAK,QAAA,EAAU,KAAA,EAAO,CAAA,GAAI,OAAA,CAAQ,CAAA;EACnD,KAAA,CAAM,GAAA,EAAK,QAAA,EAAU,KAAA,OAAY,GAAA,YAAe,OAAA;EAChD,QAAA,UACE,GAAA,EAAK,QAAA,EACL,YAAA,EAAc,QAAA,GAAW,eAAA,EACzB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IACvB,OAAA,CAAQ,CAAA;EACX,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EAC1C,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EA4CtC;;;;EAvCJ,UAAA,IAAc,OAAA;AAAA;;;;;;;;;;;;;;UAgBC,mBAAA;EA6BN;EAAA,SA3BA,MAAA;EA2BU;;;;;;;;EAjBnB,SAAA,CAAU,MAAA,UAAgB,OAAA,GAAU,qBAAA,GAAwB,mBAAA;EAkBT;;;EAbnD,IAAA,CAAK,IAAA,aAAiB,yBAAA;EAcD;EAXrB,KAAA,IAAS,OAAA;EAGT,GAAA,UAAa,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EACrC,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EACpB,IAAA,CAAK,IAAA,EAAM,QAAA,KAAa,OAAA;EACxB,IAAA,UAAc,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EAGtC,GAAA,CAAI,GAAA,EAAK,QAAA,EAAU,KAAA,OAAY,YAAA,GAAe,QAAA,GAAW,eAAA,GAAkB,OAAA;EAC3E,OAAA,CAAQ,KAAA,EAAO,MAAA,eAAqB,GAAA,YAAe,OAAA;EACnD,KAAA,CAAM,GAAA,EAAK,QAAA,EAAU,KAAA,OAAY,GAAA,YAAe,OAAA;EAChD,OAAA,UAAiB,GAAA,EAAK,QAAA,EAAU,KAAA,EAAO,CAAA,GAAI,OAAA,CAAQ,CAAA;EACnD,MAAA,CAAO,GAAA,EAAK,QAAA,GAAW,OAAA;EAGvB,QAAA,UACE,GAAA,EAAK,QAAA,EACL,YAAA,EAAc,QAAA,GAAW,eAAA,EACzB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IACvB,OAAA,CAAQ,CAAA;EACX,GAAA,UACE,GAAA,EAAK,QAAA,EACL,OAAA,EAAS,eAAA,EACT,QAAA,QAAgB,OAAA,CAAQ,CAAA,IACvB,OAAA,CAAQ,CAAA;EAGX,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EAC1C,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EAC1C,MAAA,UACE,GAAA,EAAK,QAAA,EACL,EAAA,GAAK,OAAA,EAAS,CAAA,YAAa,CAAA,UAAW,OAAA,CAAQ,CAAA,UAC9C,OAAA;IAAY,GAAA,GAAM,QAAA;EAAA,IACjB,OAAA,CAAQ,CAAA;EACX,KAAA,WAAgB,MAAA,gBAAsB,MAAA,eACpC,GAAA,EAAK,QAAA,EACL,OAAA,EAAS,OAAA,CAAQ,CAAA,GACjB,OAAA;IAAY,GAAA,GAAM,QAAA;EAAA,IACjB,OAAA,CAAQ,CAAA;EAGX,IAAA,UAAc,GAAA,EAAK,QAAA,GAAW,iBAAA,CAAkB,CAAA;EAGhD,IAAA,IACE,GAAA,EAAK,QAAA,EACL,YAAA,EAAc,QAAA,GAAW,IAAA,CAAK,WAAA,aAC9B,EAAA,QAAU,OAAA,CAAQ,CAAA,IACjB,OAAA,CAAQ,WAAA,CAAY,CAAA;EAGvB,OAAA,UACE,MAAA,YACA,OAAA,EAAS,mBAAA,GACR,OAAA,CAAQ,eAAA,CAAgB,CAAA;AAAA;AAAA,KAGjB,SAAA;EAtCC;;;EA0CX,IAAA;EAxCE;;;EA4CF,SAAA;EA1C0B;;;EA8C1B,GAAA;EA1CA;;;;;;;EAkDA,OAAA;AAAA;AAAA,KAGU,WAAA,aAAwB,WAAW;AAAA,KAE1C,cAAA;AAAA,KAUA,uBAAA,MAA6B,CAAA,qBAAsB,cAAA,GAAiB,cAAA,GAAiB,CAAA;AAAA,KAE9E,mBAAA,wDAEG,uBAAA,CAAwB,CAAA;EAlEnC;;;EAuEF,OAAA,GAAU,UAAA;EAtE8B;;;;;EA4ExC,OAAA;EA1EG;;;EA8EH,OAAA;IACE,KAAA,UAAe,gBAAA;IACf,IAAA,UAAc,eAAA;IACd,IAAA,UAAc,eAAA;IACd,MAAA,UAAgB,iBAAA;IAChB,cAAA,UAAwB,yBAAA;IACxB,GAAA,UAAa,oBAAA;IACb,EAAA,UAAY,aAAA;IACZ,IAAA,UAAc,eAAA;EAAA,cAEN,OAAA,CAAQ,CAAA,oBAAqB,eAAA;EAnF5B;;;EAwFX,OAAA;IACE,KAAA,GAAQ,YAAA;IACR,IAAA,GAAO,gBAAA;IACP,MAAA,GAAS,kBAAA;IACT,cAAA,GAAiB,0BAAA;IACjB,IAAA,GAAO,sBAAA;IACP,GAAA,GAAM,qBAAA;IACN,EAAA,GAAK,cAAA;IACL,IAAA,GAAO,gBAAA;EAAA,cAEC,OAAA,CAAQ,CAAA,aAAc,aAAA;AAAA"}