@nexusts/cache 0.9.6 → 0.9.8

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.
package/dist/index.js CHANGED
@@ -35,32 +35,95 @@ var __require = import.meta.require;
35
35
  // packages/cache/src/types.ts
36
36
  import { METADATA_KEY } from "@nexusts/core";
37
37
  import { safeGetMeta, safeDefineMeta } from "@nexusts/core/di/safe-reflect";
38
+ var FN_SPEC_KEY = Symbol.for("nexus:cache:fn:spec");
39
+ function collectFnSpecs(target, key) {
40
+ const result = [];
41
+ const proto = target.prototype;
42
+ if (!proto)
43
+ return result;
44
+ for (const name of Object.getOwnPropertyNames(proto)) {
45
+ const fn = proto[name];
46
+ if (typeof fn !== "function")
47
+ continue;
48
+ const spec = fn[FN_SPEC_KEY]?.[key];
49
+ if (spec)
50
+ result.push(spec);
51
+ }
52
+ return result;
53
+ }
38
54
  var CACHEABLE_META = "nexus:cache:cacheable";
39
55
  var CACHE_INVALIDATE_META = "nexus:cache:invalidate";
40
56
  function Cacheable(prefix, keyFn, ttlSeconds = 60) {
41
- return (target, propertyKey, descriptor) => {
57
+ return function(targetOrFn, contextOrKey) {
58
+ if (contextOrKey?.kind === "method") {
59
+ const fn = targetOrFn;
60
+ const { name, metadata } = contextOrKey;
61
+ const existing2 = metadata[CACHEABLE_META] ?? [];
62
+ const spec = {
63
+ prefix,
64
+ keyFn,
65
+ ttl: ttlSeconds,
66
+ propertyKey: name,
67
+ original: fn
68
+ };
69
+ existing2.push(spec);
70
+ metadata[CACHEABLE_META] = existing2;
71
+ if (!fn[FN_SPEC_KEY])
72
+ fn[FN_SPEC_KEY] = {};
73
+ fn[FN_SPEC_KEY][CACHEABLE_META] = spec;
74
+ return;
75
+ }
76
+ const target = targetOrFn;
77
+ const propertyKey = contextOrKey;
78
+ const descriptor = arguments[2];
42
79
  const existing = safeGetMeta(CACHEABLE_META, target.constructor) ?? [];
43
80
  existing.push({
44
81
  prefix,
45
82
  keyFn,
46
83
  ttl: ttlSeconds,
47
84
  propertyKey,
48
- original: descriptor.value
85
+ original: descriptor?.value
49
86
  });
50
87
  safeDefineMeta(CACHEABLE_META, existing, target.constructor);
51
88
  };
52
89
  }
53
90
  function CacheInvalidate(prefix, keyFn) {
54
- return (target, propertyKey, descriptor) => {
91
+ return function(targetOrFn, contextOrKey) {
92
+ if (contextOrKey?.kind === "method") {
93
+ const fn = targetOrFn;
94
+ const { name, metadata } = contextOrKey;
95
+ const existing2 = metadata[CACHE_INVALIDATE_META] ?? [];
96
+ const spec = {
97
+ prefix,
98
+ keyFn,
99
+ propertyKey: name,
100
+ original: fn
101
+ };
102
+ existing2.push(spec);
103
+ metadata[CACHE_INVALIDATE_META] = existing2;
104
+ if (!fn[FN_SPEC_KEY])
105
+ fn[FN_SPEC_KEY] = {};
106
+ fn[FN_SPEC_KEY][CACHE_INVALIDATE_META] = spec;
107
+ return;
108
+ }
109
+ const target = targetOrFn;
110
+ const propertyKey = contextOrKey;
111
+ const descriptor = arguments[2];
55
112
  const existing = safeGetMeta(CACHE_INVALIDATE_META, target.constructor) ?? [];
56
- existing.push({ prefix, keyFn, propertyKey, original: descriptor.value });
113
+ existing.push({ prefix, keyFn, propertyKey, original: descriptor?.value });
57
114
  safeDefineMeta(CACHE_INVALIDATE_META, existing, target.constructor);
58
115
  };
59
116
  }
60
117
  function getCacheableSpecs(target) {
118
+ const fromFn = collectFnSpecs(target, CACHEABLE_META);
119
+ if (fromFn.length > 0)
120
+ return fromFn;
61
121
  return safeGetMeta(CACHEABLE_META, target) ?? [];
62
122
  }
63
123
  function getCacheInvalidateSpecs(target) {
124
+ const fromFn = collectFnSpecs(target, CACHE_INVALIDATE_META);
125
+ if (fromFn.length > 0)
126
+ return fromFn;
64
127
  return safeGetMeta(CACHE_INVALIDATE_META, target) ?? [];
65
128
  }
66
129
  // packages/cache/src/stores/memory.ts
@@ -190,7 +253,7 @@ class MemoryStore {
190
253
  }
191
254
  }
192
255
  function globToRegExp(pattern) {
193
- return new RegExp("^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "::DBL::").replace(/\*/g, "[^:]+").replace(/::DBL::/g, ".*") + "$");
256
+ return new RegExp("^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "::DBL::").replace(/\*/g, "[^:]*").replace(/::DBL::/g, ".*") + "$");
194
257
  }
195
258
  // packages/cache/src/stores/drizzle.ts
196
259
  class DrizzleCacheStore {
@@ -601,5 +664,5 @@ export {
601
664
  CACHEABLE_META
602
665
  };
603
666
 
604
- //# debugId=F6EEF964BF46C91D64756E2164756E21
667
+ //# debugId=A6E1EE368DAEA82164756E2164756E21
605
668
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -2,14 +2,14 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/types.ts", "../src/stores/memory.ts", "../src/stores/drizzle.ts", "../src/stores/redis.ts", "../src/cache.service.ts", "../src/cache.module.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * `@nexusts/cache` — application-level caching.\n *\n * Two backends ship out of the box:\n * - `MemoryStore` — single-process LRU with TTL eviction\n * - `RedisStore` — multi-pod via ioredis (peer dep, optional)\n *\n * const cache = new CacheService({ store: new MemoryStore({ max: 10_000 }) });\n * await cache.set('user:42', user, 60); // 60-second TTL\n * const u = await cache.get<User>('user:42');\n *\n * Decorators are also provided for service methods:\n *\n * @Cacheable('user', (id: string) => id, 60)\n * async findById(id: string) { ... }\n */\n\nimport { METADATA_KEY } from \"@nexusts/core\";\nimport { safeGetMeta, safeDefineMeta, safeHasMeta } from \"@nexusts/core/di/safe-reflect\";\n\n/** A single cache entry. */\nexport interface CacheEntry<T = unknown> {\n\tvalue: T;\n\t/** Unix-ms timestamp when this entry expires. 0 = never. */\n\texpiresAt: number;\n\t/** Stash tags for invalidation. */\n\ttags?: string[];\n}\n\n/** Storage backend for cache entries. */\nexport interface CacheStore {\n\treadonly kind: string;\n\t/** Get a value. Returns `undefined` if missing or expired. */\n\tget<T = unknown>(key: string): Promise<T | undefined>;\n\t/** Set a value with optional TTL (seconds) and tags. */\n\tset<T = unknown>(\n\t\tkey: string,\n\t\tvalue: T,\n\t\topts?: CacheSetOptions,\n\t): Promise<void>;\n\t/** Delete a single key. */\n\tdelete(key: string): Promise<boolean>;\n\t/** Delete every key matching `pattern` (glob: `*`, `**`). */\n\tclear(pattern?: string): Promise<number>;\n\t/** Wrap a function with cache-or-compute semantics. */\n\twrap<T>(key: string, fn: () => Promise<T>, ttl?: number): Promise<T>;\n\t/**\n\t * Remove every entry tagged with `tag`. Backends without a tag\n\t * index (e.g. MemoryStore) return 0.\n\t */\n\tinvalidateByTag?(tag: string): Promise<number>;\n\t/** Sweep expired entries. Backends without a sweep loop return 0. */\n\tgc?(): Promise<number>;\n\t/** Optional: free resources. */\n\tclose?(): Promise<void>;\n}\n\n/** Options for `set()`. */\nexport interface CacheSetOptions {\n\t/** Time-to-live in seconds. 0 = forever. */\n\tttl?: number;\n\t/** Tags for grouped invalidation. */\n\ttags?: string[];\n}\n\nexport interface CacheConfig {\n\t/**\n\t * Shorthand backend selector. When set, an appropriate store is\n\t * created automatically — no need to pass `store` explicitly.\n\t * - `'memory'` (default) — in-process LRU\n\t * - `'redis'` — requires `redis` config field\n\t */\n\tbackend?: \"memory\" | \"redis\";\n\t/**\n\t * Redis connection options — used when `backend: 'redis'`.\n\t * Passed directly to `createRedisClient()` from `@nexusts/redis`.\n\t */\n\tredis?: {\n\t\turl?: string;\n\t\thost?: string;\n\t\tport?: number;\n\t\tpassword?: string;\n\t\tdb?: number;\n\t\t/** Key prefix for the underlying RedisCacheStore. Default: \"cache:\". */\n\t\tkeyPrefix?: string;\n\t};\n\t/** Explicit store instance. Overrides `backend` when provided. */\n\tstore?: CacheStore;\n\t/** Default TTL in seconds when none is provided. Default: 60. */\n\tdefaultTtl?: number;\n\t/** Prefix prepended to all keys. Default: 'nexusts'. */\n\tprefix?: string;\n}\n\n/** Internal metadata key. */\nexport const CACHEABLE_META = \"nexus:cache:cacheable\";\nexport const CACHE_INVALIDATE_META = \"nexus:cache:invalidate\";\n\n/** @Cacheable decorator. Caches the result of a method. */\nexport function Cacheable(\n\tprefix: string,\n\tkeyFn: (...args: any[]) => string,\n\tttlSeconds = 60,\n): MethodDecorator {\n\treturn (\n\t\ttarget: any,\n\t\tpropertyKey: string | symbol,\n\t\tdescriptor: PropertyDescriptor,\n\t) => {\n\t\tconst existing: CacheableSpec[] =\n\t\t\tsafeGetMeta(CACHEABLE_META, target.constructor) ?? [];\n\t\texisting.push({\n\t\t\tprefix,\n\t\t\tkeyFn,\n\t\t\tttl: ttlSeconds,\n\t\t\tpropertyKey,\n\t\t\toriginal: descriptor.value,\n\t\t});\n\t\tsafeDefineMeta(CACHEABLE_META, existing, target.constructor);\n\t};\n}\n\n/** @CacheInvalidate decorator. Removes matching keys after a method runs. */\nexport function CacheInvalidate(\n\tprefix: string,\n\tkeyFn: (...args: any[]) => string,\n): MethodDecorator {\n\treturn (\n\t\ttarget: any,\n\t\tpropertyKey: string | symbol,\n\t\tdescriptor: PropertyDescriptor,\n\t) => {\n\t\tconst existing: CacheInvalidateSpec[] =\n\t\t\tsafeGetMeta(CACHE_INVALIDATE_META, target.constructor) ?? [];\n\t\texisting.push({ prefix, keyFn, propertyKey, original: descriptor.value });\n\t\tsafeDefineMeta(CACHE_INVALIDATE_META, existing, target.constructor);\n\t};\n}\n\nexport interface CacheableSpec {\n\tprefix: string;\n\tkeyFn: (...args: any[]) => string;\n\tttl: number;\n\tpropertyKey: string | symbol;\n\toriginal: (...args: any[]) => any;\n}\n\nexport interface CacheInvalidateSpec {\n\tprefix: string;\n\tkeyFn: (...args: any[]) => string;\n\tpropertyKey: string | symbol;\n\toriginal: (...args: any[]) => any;\n}\n\nexport function getCacheableSpecs(target: any): CacheableSpec[] {\n\treturn safeGetMeta(CACHEABLE_META, target) ?? [];\n}\nexport function getCacheInvalidateSpecs(target: any): CacheInvalidateSpec[] {\n\treturn safeGetMeta(CACHE_INVALIDATE_META, target) ?? [];\n}\n\nexport { METADATA_KEY };\n",
6
- "/**\n * In-memory LRU cache store with TTL eviction.\n *\n * Simple and fast; not cluster-safe. Use `RedisStore` for shared state\n * across multiple Bun processes.\n */\nimport type { CacheEntry, CacheSetOptions, CacheStore } from \"../types.js\";\n\nexport interface MemoryStoreOptions {\n\t/** Maximum number of entries. Default: 10_000. */\n\tmax?: number;\n\t/** Sweep interval for expired entries. Default: 30_000 ms. 0 = no sweep. */\n\tsweepIntervalMs?: number;\n}\n\nexport class MemoryStore implements CacheStore {\n\treadonly kind = \"memory\";\n\tprivate data = new Map<string, CacheEntry>();\n\tprivate tagIndex = new Map<string, Set<string>>();\n\tprivate readonly max: number;\n\tprivate sweepTimer: ReturnType<typeof setInterval> | null = null;\n\n\tconstructor(opts: MemoryStoreOptions = {}) {\n\t\tthis.max = opts.max ?? 10_000;\n\t\tconst sweepMs = opts.sweepIntervalMs ?? 30_000;\n\t\tif (sweepMs > 0) {\n\t\t\tthis.sweepTimer = setInterval(() => this.sweepExpired(), sweepMs);\n\t\t\t// Don't keep the event loop alive for the sweep timer.\n\t\t\tif (typeof this.sweepTimer === \"object\" && this.sweepTimer !== null) {\n\t\t\t\t(this.sweepTimer as any).unref?.();\n\t\t\t}\n\t\t}\n\t}\n\n\tasync get<T = unknown>(key: string): Promise<T | undefined> {\n\t\tconst e = this.data.get(key);\n\t\tif (!e) return undefined;\n\t\tif (e.expiresAt > 0 && e.expiresAt <= Date.now()) {\n\t\t\tthis.data.delete(key);\n\t\t\treturn undefined;\n\t\t}\n\t\t// Touch for LRU.\n\t\tthis.data.delete(key);\n\t\tthis.data.set(key, e);\n\t\treturn e.value as T;\n\t}\n\n\tasync set<T = unknown>(\n\t\tkey: string,\n\t\tvalue: T,\n\t\topts: CacheSetOptions = {},\n\t): Promise<void> {\n\t\tconst ttl = opts.ttl ?? 0;\n\t\tconst entry: CacheEntry<T> = {\n\t\t\tvalue,\n\t\t\texpiresAt: ttl > 0 ? Date.now() + ttl * 1000 : 0,\n\t\t\ttags: opts.tags,\n\t\t};\n\t\t// Insert (and possibly evict).\n\t\tif (!this.data.has(key) && this.data.size >= this.max) {\n\t\t\t// Evict oldest (first key in iteration order).\n\t\t\tconst oldest = this.data.keys().next().value;\n\t\t\tif (oldest !== undefined) {\n\t\t\t\tthis.data.delete(oldest);\n\t\t\t\tfor (const keys of this.tagIndex.values()) keys.delete(oldest);\n\t\t\t}\n\t\t}\n\t\tthis.data.set(key, entry);\n\t\t// Refresh tag index: remove old tag associations for this key, then add new ones.\n\t\tif (opts.tags) {\n\t\t\tfor (const [, keys] of this.tagIndex.entries()) keys.delete(key);\n\t\t\tfor (const tag of opts.tags) {\n\t\t\t\tlet set = this.tagIndex.get(tag);\n\t\t\t\tif (!set) {\n\t\t\t\t\tset = new Set();\n\t\t\t\t\tthis.tagIndex.set(tag, set);\n\t\t\t\t}\n\t\t\t\tset.add(key);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync delete(key: string): Promise<boolean> {\n\t\tconst deleted = this.data.delete(key);\n\t\t// Remove this key from every tag index.\n\t\tfor (const keys of this.tagIndex.values()) keys.delete(key);\n\t\treturn deleted;\n\t}\n\n\tasync clear(pattern?: string): Promise<number> {\n\t\tif (!pattern) {\n\t\t\tconst n = this.data.size;\n\t\t\tthis.data.clear();\n\t\t\tthis.tagIndex.clear();\n\t\t\treturn n;\n\t\t}\n\t\tconst rx = globToRegExp(pattern);\n\t\tlet n = 0;\n\t\tfor (const k of [...this.data.keys()]) {\n\t\t\tif (rx.test(k)) {\n\t\t\t\tthis.data.delete(k);\n\t\t\t\tfor (const keys of this.tagIndex.values()) keys.delete(k);\n\t\t\t\tn++;\n\t\t\t}\n\t\t}\n\t\treturn n;\n\t}\n\n\tasync wrap<T>(key: string, fn: () => Promise<T>, ttl?: number): Promise<T> {\n\t\tconst v = await this.get<T>(key);\n\t\tif (v !== undefined) return v;\n\t\tconst result = await fn();\n\t\tawait this.set(key, result, { ttl });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Tag-based invalidation. Maintains a `tag -> Set<key>` index in\n\t * addition to the main map. Returns the number of keys removed.\n\t */\n\tasync invalidateByTag(tag: string): Promise<number> {\n\t\tconst keys = this.tagIndex.get(tag);\n\t\tif (!keys) return 0;\n\t\tlet n = 0;\n\t\tfor (const k of keys) {\n\t\t\tif (this.data.delete(k)) n++;\n\t\t}\n\t\tthis.tagIndex.delete(tag);\n\t\treturn n;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.sweepTimer) clearInterval(this.sweepTimer);\n\t\tthis.sweepTimer = null;\n\t\tthis.data.clear();\n\t\tthis.tagIndex.clear();\n\t}\n\n\tprivate sweepExpired(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [k, e] of this.data.entries()) {\n\t\t\tif (e.expiresAt > 0 && e.expiresAt <= now) this.data.delete(k);\n\t\t}\n\t\t// Drop tags whose keys are all gone.\n\t\tfor (const [tag, keys] of this.tagIndex.entries()) {\n\t\t\tfor (const k of keys) {\n\t\t\t\tif (!this.data.has(k)) keys.delete(k);\n\t\t\t}\n\t\t\tif (keys.size === 0) this.tagIndex.delete(tag);\n\t\t}\n\t}\n}\n\nfunction globToRegExp(pattern: string): RegExp {\n\treturn new RegExp(\n\t\t\"^\" +\n\t\t\tpattern\n\t\t\t\t.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\t\t\t\t.replace(/\\*\\*/g, \"::DBL::\")\n\t\t\t\t.replace(/\\*/g, \"[^:]+\")\n\t\t\t\t.replace(/::DBL::/g, \".*\") +\n\t\t\t\"$\",\n\t);\n}\n",
5
+ "/**\n * `@nexusts/cache` — application-level caching.\n *\n * Two backends ship out of the box:\n * - `MemoryStore` — single-process LRU with TTL eviction\n * - `RedisStore` — multi-pod via ioredis (peer dep, optional)\n *\n * const cache = new CacheService({ store: new MemoryStore({ max: 10_000 }) });\n * await cache.set('user:42', user, 60); // 60-second TTL\n * const u = await cache.get<User>('user:42');\n *\n * Decorators are also provided for service methods:\n *\n * @Cacheable('user', (id: string) => id, 60)\n * async findById(id: string) { ... }\n */\n\nimport { METADATA_KEY } from \"@nexusts/core\";\nimport { safeGetMeta, safeDefineMeta } from \"@nexusts/core/di/safe-reflect\";\n\n// ── Standard-mode helper ──────────────────────────────────────────\n// In TC39 standard decorator mode (Bun 1.3+ default), `fn.constructor`\n// is `Function`, not the class. To bridge metadata we store it directly\n// on the prototype function using a Symbol key.\n// ───────────────────────────────────────────────────────────────────\n\n/** Symbol key used to stash CacheableSpec on the decorated function. */\nconst FN_SPEC_KEY = Symbol.for(\"nexus:cache:fn:spec\");\n\n/** Collect specs stored on prototype methods (standard mode path). */\nfunction collectFnSpecs<T>(target: any, key: string): T[] {\n\tconst result: T[] = [];\n\t// Methods live on `target.prototype` for classes.\n\tconst proto = target.prototype;\n\tif (!proto) return result;\n\tfor (const name of Object.getOwnPropertyNames(proto)) {\n\t\tconst fn = proto[name];\n\t\tif (typeof fn !== \"function\") continue;\n\t\tconst spec = (fn as any)[FN_SPEC_KEY]?.[key] as T | undefined;\n\t\tif (spec) result.push(spec);\n\t}\n\treturn result;\n}\n\n/** A single cache entry. */\nexport interface CacheEntry<T = unknown> {\n\tvalue: T;\n\t/** Unix-ms timestamp when this entry expires. 0 = never. */\n\texpiresAt: number;\n\t/** Stash tags for invalidation. */\n\ttags?: string[];\n}\n\n/** Storage backend for cache entries. */\nexport interface CacheStore {\n\treadonly kind: string;\n\t/** Get a value. Returns `undefined` if missing or expired. */\n\tget<T = unknown>(key: string): Promise<T | undefined>;\n\t/** Set a value with optional TTL (seconds) and tags. */\n\tset<T = unknown>(\n\t\tkey: string,\n\t\tvalue: T,\n\t\topts?: CacheSetOptions,\n\t): Promise<void>;\n\t/** Delete a single key. */\n\tdelete(key: string): Promise<boolean>;\n\t/** Delete every key matching `pattern` (glob: `*`, `**`). */\n\tclear(pattern?: string): Promise<number>;\n\t/** Wrap a function with cache-or-compute semantics. */\n\twrap<T>(key: string, fn: () => Promise<T>, ttl?: number): Promise<T>;\n\t/**\n\t * Remove every entry tagged with `tag`. Backends without a tag\n\t * index (e.g. MemoryStore) return 0.\n\t */\n\tinvalidateByTag?(tag: string): Promise<number>;\n\t/** Sweep expired entries. Backends without a sweep loop return 0. */\n\tgc?(): Promise<number>;\n\t/** Optional: free resources. */\n\tclose?(): Promise<void>;\n}\n\n/** Options for `set()`. */\nexport interface CacheSetOptions {\n\t/** Time-to-live in seconds. 0 = forever. */\n\tttl?: number;\n\t/** Tags for grouped invalidation. */\n\ttags?: string[];\n}\n\nexport interface CacheConfig {\n\t/**\n\t * Shorthand backend selector. When set, an appropriate store is\n\t * created automatically — no need to pass `store` explicitly.\n\t * - `'memory'` (default) — in-process LRU\n\t * - `'redis'` — requires `redis` config field\n\t */\n\tbackend?: \"memory\" | \"redis\";\n\t/**\n\t * Redis connection options — used when `backend: 'redis'`.\n\t * Passed directly to `createRedisClient()` from `@nexusts/redis`.\n\t */\n\tredis?: {\n\t\turl?: string;\n\t\thost?: string;\n\t\tport?: number;\n\t\tpassword?: string;\n\t\tdb?: number;\n\t\t/** Key prefix for the underlying RedisCacheStore. Default: \"cache:\". */\n\t\tkeyPrefix?: string;\n\t};\n\t/** Explicit store instance. Overrides `backend` when provided. */\n\tstore?: CacheStore;\n\t/** Default TTL in seconds when none is provided. Default: 60. */\n\tdefaultTtl?: number;\n\t/** Prefix prepended to all keys. Default: 'nexusts'. */\n\tprefix?: string;\n}\n\n/** Internal metadata key. */\nexport const CACHEABLE_META = \"nexus:cache:cacheable\";\nexport const CACHE_INVALIDATE_META = \"nexus:cache:invalidate\";\n\n/**\n * @Cacheable decorator. Caches the result of a method.\n *\n * Dual-mode: supports both TC39 standard ES decorators (Bun 1.3+ default)\n * and legacy experimentalDecorators.\n */\nexport function Cacheable(\n\tprefix: string,\n\tkeyFn: (...args: any[]) => string,\n\tttlSeconds = 60,\n): any {\n\treturn function (this: any, targetOrFn: any, contextOrKey: any): void {\n\t\t// Standard (TC39) decorator mode\n\t\tif (contextOrKey?.kind === \"method\") {\n\t\t\tconst fn = targetOrFn;\n\t\t\tconst { name, metadata } = contextOrKey;\n\n\t\t\tconst existing: CacheableSpec[] = metadata[CACHEABLE_META] ?? [];\n\t\t\tconst spec: CacheableSpec = {\n\t\t\t\tprefix,\n\t\t\t\tkeyFn,\n\t\t\t\tttl: ttlSeconds,\n\t\t\t\tpropertyKey: name,\n\t\t\t\toriginal: fn,\n\t\t\t};\n\t\t\texisting.push(spec);\n\t\t\tmetadata[CACHEABLE_META] = existing;\n\n\t\t\t// Stash the spec on the function itself so getCacheableSpecs\n\t\t\t// can find it without going through the class constructor.\n\t\t\tif (!(fn as any)[FN_SPEC_KEY]) (fn as any)[FN_SPEC_KEY] = {};\n\t\t\t(fn as any)[FN_SPEC_KEY][CACHEABLE_META] = spec;\n\t\t\treturn;\n\t\t}\n\n\t\t// Legacy (experimentalDecorators) mode\n\t\tconst target = targetOrFn;\n\t\tconst propertyKey = contextOrKey;\n\t\tconst descriptor = arguments[2];\n\n\t\tconst existing: CacheableSpec[] =\n\t\t\tsafeGetMeta(CACHEABLE_META, target.constructor) ?? [];\n\t\texisting.push({\n\t\t\tprefix,\n\t\t\tkeyFn,\n\t\t\tttl: ttlSeconds,\n\t\t\tpropertyKey,\n\t\t\toriginal: descriptor?.value,\n\t\t});\n\t\tsafeDefineMeta(CACHEABLE_META, existing, target.constructor);\n\t};\n}\n\n/**\n * @CacheInvalidate decorator. Removes matching keys after a method runs.\n *\n * Dual-mode: supports both TC39 standard ES decorators (Bun 1.3+ default)\n * and legacy experimentalDecorators.\n */\nexport function CacheInvalidate(\n\tprefix: string,\n\tkeyFn: (...args: any[]) => string,\n): any {\n\treturn function (this: any, targetOrFn: any, contextOrKey: any): void {\n\t\t// Standard (TC39) decorator mode\n\t\tif (contextOrKey?.kind === \"method\") {\n\t\t\tconst fn = targetOrFn;\n\t\t\tconst { name, metadata } = contextOrKey;\n\n\t\t\tconst existing: CacheInvalidateSpec[] =\n\t\t\t\tmetadata[CACHE_INVALIDATE_META] ?? [];\n\t\t\tconst spec: CacheInvalidateSpec = {\n\t\t\t\tprefix,\n\t\t\t\tkeyFn,\n\t\t\t\tpropertyKey: name,\n\t\t\t\toriginal: fn,\n\t\t\t};\n\t\t\texisting.push(spec);\n\t\t\tmetadata[CACHE_INVALIDATE_META] = existing;\n\n\t\t\t// Stash the spec on the function itself.\n\t\t\tif (!(fn as any)[FN_SPEC_KEY]) (fn as any)[FN_SPEC_KEY] = {};\n\t\t\t(fn as any)[FN_SPEC_KEY][CACHE_INVALIDATE_META] = spec;\n\t\t\treturn;\n\t\t}\n\n\t\t// Legacy (experimentalDecorators) mode\n\t\tconst target = targetOrFn;\n\t\tconst propertyKey = contextOrKey;\n\t\tconst descriptor = arguments[2];\n\n\t\tconst existing: CacheInvalidateSpec[] =\n\t\t\tsafeGetMeta(CACHE_INVALIDATE_META, target.constructor) ?? [];\n\t\texisting.push({ prefix, keyFn, propertyKey, original: descriptor?.value });\n\t\tsafeDefineMeta(CACHE_INVALIDATE_META, existing, target.constructor);\n\t};\n}\n\nexport interface CacheableSpec {\n\tprefix: string;\n\tkeyFn: (...args: any[]) => string;\n\tttl: number;\n\tpropertyKey: string | symbol;\n\toriginal: (...args: any[]) => any;\n}\n\nexport interface CacheInvalidateSpec {\n\tprefix: string;\n\tkeyFn: (...args: any[]) => string;\n\tpropertyKey: string | symbol;\n\toriginal: (...args: any[]) => any;\n}\n\nexport function getCacheableSpecs(target: any): CacheableSpec[] {\n\t// Standard mode: specs are stashed on prototype functions.\n\tconst fromFn = collectFnSpecs<CacheableSpec>(target, CACHEABLE_META);\n\tif (fromFn.length > 0) return fromFn;\n\t// Legacy mode: stored via safeDefineMeta on the constructor.\n\treturn safeGetMeta(CACHEABLE_META, target) ?? [];\n}\n\nexport function getCacheInvalidateSpecs(target: any): CacheInvalidateSpec[] {\n\tconst fromFn = collectFnSpecs<CacheInvalidateSpec>(target, CACHE_INVALIDATE_META);\n\tif (fromFn.length > 0) return fromFn;\n\treturn safeGetMeta(CACHE_INVALIDATE_META, target) ?? [];\n}\n\nexport { METADATA_KEY };\n",
6
+ "/**\n * In-memory LRU cache store with TTL eviction.\n *\n * Simple and fast; not cluster-safe. Use `RedisStore` for shared state\n * across multiple Bun processes.\n */\nimport type { CacheEntry, CacheSetOptions, CacheStore } from \"../types.js\";\n\nexport interface MemoryStoreOptions {\n\t/** Maximum number of entries. Default: 10_000. */\n\tmax?: number;\n\t/** Sweep interval for expired entries. Default: 30_000 ms. 0 = no sweep. */\n\tsweepIntervalMs?: number;\n}\n\nexport class MemoryStore implements CacheStore {\n\treadonly kind = \"memory\";\n\tprivate data = new Map<string, CacheEntry>();\n\tprivate tagIndex = new Map<string, Set<string>>();\n\tprivate readonly max: number;\n\tprivate sweepTimer: ReturnType<typeof setInterval> | null = null;\n\n\tconstructor(opts: MemoryStoreOptions = {}) {\n\t\tthis.max = opts.max ?? 10_000;\n\t\tconst sweepMs = opts.sweepIntervalMs ?? 30_000;\n\t\tif (sweepMs > 0) {\n\t\t\tthis.sweepTimer = setInterval(() => this.sweepExpired(), sweepMs);\n\t\t\t// Don't keep the event loop alive for the sweep timer.\n\t\t\tif (typeof this.sweepTimer === \"object\" && this.sweepTimer !== null) {\n\t\t\t\t(this.sweepTimer as any).unref?.();\n\t\t\t}\n\t\t}\n\t}\n\n\tasync get<T = unknown>(key: string): Promise<T | undefined> {\n\t\tconst e = this.data.get(key);\n\t\tif (!e) return undefined;\n\t\tif (e.expiresAt > 0 && e.expiresAt <= Date.now()) {\n\t\t\tthis.data.delete(key);\n\t\t\treturn undefined;\n\t\t}\n\t\t// Touch for LRU.\n\t\tthis.data.delete(key);\n\t\tthis.data.set(key, e);\n\t\treturn e.value as T;\n\t}\n\n\tasync set<T = unknown>(\n\t\tkey: string,\n\t\tvalue: T,\n\t\topts: CacheSetOptions = {},\n\t): Promise<void> {\n\t\tconst ttl = opts.ttl ?? 0;\n\t\tconst entry: CacheEntry<T> = {\n\t\t\tvalue,\n\t\t\texpiresAt: ttl > 0 ? Date.now() + ttl * 1000 : 0,\n\t\t\ttags: opts.tags,\n\t\t};\n\t\t// Insert (and possibly evict).\n\t\tif (!this.data.has(key) && this.data.size >= this.max) {\n\t\t\t// Evict oldest (first key in iteration order).\n\t\t\tconst oldest = this.data.keys().next().value;\n\t\t\tif (oldest !== undefined) {\n\t\t\t\tthis.data.delete(oldest);\n\t\t\t\tfor (const keys of this.tagIndex.values()) keys.delete(oldest);\n\t\t\t}\n\t\t}\n\t\tthis.data.set(key, entry);\n\t\t// Refresh tag index: remove old tag associations for this key, then add new ones.\n\t\tif (opts.tags) {\n\t\t\tfor (const [, keys] of this.tagIndex.entries()) keys.delete(key);\n\t\t\tfor (const tag of opts.tags) {\n\t\t\t\tlet set = this.tagIndex.get(tag);\n\t\t\t\tif (!set) {\n\t\t\t\t\tset = new Set();\n\t\t\t\t\tthis.tagIndex.set(tag, set);\n\t\t\t\t}\n\t\t\t\tset.add(key);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync delete(key: string): Promise<boolean> {\n\t\tconst deleted = this.data.delete(key);\n\t\t// Remove this key from every tag index.\n\t\tfor (const keys of this.tagIndex.values()) keys.delete(key);\n\t\treturn deleted;\n\t}\n\n\tasync clear(pattern?: string): Promise<number> {\n\t\tif (!pattern) {\n\t\t\tconst n = this.data.size;\n\t\t\tthis.data.clear();\n\t\t\tthis.tagIndex.clear();\n\t\t\treturn n;\n\t\t}\n\t\tconst rx = globToRegExp(pattern);\n\t\tlet n = 0;\n\t\tfor (const k of [...this.data.keys()]) {\n\t\t\tif (rx.test(k)) {\n\t\t\t\tthis.data.delete(k);\n\t\t\t\tfor (const keys of this.tagIndex.values()) keys.delete(k);\n\t\t\t\tn++;\n\t\t\t}\n\t\t}\n\t\treturn n;\n\t}\n\n\tasync wrap<T>(key: string, fn: () => Promise<T>, ttl?: number): Promise<T> {\n\t\tconst v = await this.get<T>(key);\n\t\tif (v !== undefined) return v;\n\t\tconst result = await fn();\n\t\tawait this.set(key, result, { ttl });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Tag-based invalidation. Maintains a `tag -> Set<key>` index in\n\t * addition to the main map. Returns the number of keys removed.\n\t */\n\tasync invalidateByTag(tag: string): Promise<number> {\n\t\tconst keys = this.tagIndex.get(tag);\n\t\tif (!keys) return 0;\n\t\tlet n = 0;\n\t\tfor (const k of keys) {\n\t\t\tif (this.data.delete(k)) n++;\n\t\t}\n\t\tthis.tagIndex.delete(tag);\n\t\treturn n;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.sweepTimer) clearInterval(this.sweepTimer);\n\t\tthis.sweepTimer = null;\n\t\tthis.data.clear();\n\t\tthis.tagIndex.clear();\n\t}\n\n\tprivate sweepExpired(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [k, e] of this.data.entries()) {\n\t\t\tif (e.expiresAt > 0 && e.expiresAt <= now) this.data.delete(k);\n\t\t}\n\t\t// Drop tags whose keys are all gone.\n\t\tfor (const [tag, keys] of this.tagIndex.entries()) {\n\t\t\tfor (const k of keys) {\n\t\t\t\tif (!this.data.has(k)) keys.delete(k);\n\t\t\t}\n\t\t\tif (keys.size === 0) this.tagIndex.delete(tag);\n\t\t}\n\t}\n}\n\nfunction globToRegExp(pattern: string): RegExp {\n\treturn new RegExp(\n\t\t\"^\" +\n\t\t\tpattern\n\t\t\t\t.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\t\t\t\t.replace(/\\*\\*/g, \"::DBL::\")\n\t\t\t\t.replace(/\\*/g, \"[^:]*\")\n\t\t\t\t.replace(/::DBL::/g, \".*\") +\n\t\t\t\"$\",\n\t);\n}\n",
7
7
  "/**\n * `DrizzleCacheStore` — cache entries backed by any Drizzle database.\n *\n * import { DrizzleService } from '@nexusts/drizzle';\n * import { DrizzleCacheStore } from '@nexusts/cache';\n *\n * const db = new DrizzleService({ dialect: 'postgres', connection: {...} });\n * await db.open();\n *\n * const store = new DrizzleCacheStore(db, {\n * tableName: 'nexus_cache',\n * });\n *\n * CacheModule.forRoot({ store, defaultTtl: 300 });\n *\n * Schema (managed by your migration):\n *\n * CREATE TABLE nexus_cache (\n * key TEXT PRIMARY KEY,\n * value TEXT NOT NULL, -- JSON-encoded\n * expires_at TEXT, -- ISO timestamp, null = never\n * created_at TEXT NOT NULL,\n * updated_at TEXT NOT NULL\n * );\n *\n * CREATE TABLE nexus_cache_tags ( -- tag → key index\n * tag TEXT NOT NULL,\n * key TEXT NOT NULL,\n * PRIMARY KEY (tag, key)\n * );\n * CREATE INDEX nexus_cache_tags_key_idx ON nexus_cache_tags(key);\n *\n * Why a tag table? It enables true `invalidateByTag('users')` that\n * removes every entry tagged 'users' in a single statement, regardless\n * of how many keys share the tag.\n */\nimport type { DrizzleService } from \"@nexusts/drizzle\";\nimport type { CacheSetOptions, CacheStore } from \"../types.js\";\n\nexport interface DrizzleCacheOptions {\n\tdb: DrizzleService;\n\t/** Cache row table. Default: 'nexus_cache'. */\n\ttableName?: string;\n\t/** Tag index table. Default: 'nexus_cache_tags'. */\n\ttagsTableName?: string;\n\t/** Column names — override to match your schema. */\n\tcolumns?: {\n\t\tkey?: string;\n\t\tvalue?: string;\n\t\texpiresAt?: string;\n\t\tcreatedAt?: string;\n\t\tupdatedAt?: string;\n\t\ttag?: string;\n\t};\n}\n\ntype CacheRow = Record<string, string | null>;\ntype TagRow = Record<string, string>;\n\nexport class DrizzleCacheStore implements CacheStore {\n\treadonly kind = \"drizzle\" as const;\n\n\tprivate db: DrizzleService;\n\tprivate t: string;\n\tprivate tagsT: string;\n\tprivate c: {\n\t\tkey: string;\n\t\tvalue: string;\n\t\texpiresAt: string;\n\t\tcreatedAt: string;\n\t\tupdatedAt: string;\n\t\ttag: string;\n\t};\n\n\tconstructor(db: DrizzleService, options: Omit<DrizzleCacheOptions, \"db\"> = {}) {\n\t\tthis.db = db;\n\t\tthis.t = options.tableName ?? \"nexus_cache\";\n\t\tthis.tagsT = options.tagsTableName ?? \"nexus_cache_tags\";\n\t\tthis.c = {\n\t\t\tkey: options.columns?.key ?? \"key\",\n\t\t\tvalue: options.columns?.value ?? \"value\",\n\t\t\texpiresAt: options.columns?.expiresAt ?? \"expires_at\",\n\t\t\tcreatedAt: options.columns?.createdAt ?? \"created_at\",\n\t\t\tupdatedAt: options.columns?.updatedAt ?? \"updated_at\",\n\t\t\ttag: options.columns?.tag ?? \"tag\",\n\t\t};\n\t}\n\n\tasync get<T = unknown>(key: string): Promise<T | undefined> {\n\t\tconst rows = await this.db.rawQuery<CacheRow>(\n\t\t\t`SELECT * FROM ${this.t} WHERE ${this.c.key} = ? LIMIT 1`,\n\t\t\t[key],\n\t\t);\n\t\tconst row = rows[0];\n\t\tif (!row) return undefined;\n\t\tconst expiresAt = row[this.c.expiresAt];\n\t\tif (expiresAt && new Date(expiresAt).getTime() <= Date.now()) {\n\t\t\t// Expired — clean up lazily.\n\t\t\tawait this.delete(key);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst raw = row[this.c.value];\n\t\tif (raw === null || raw === undefined) return undefined;\n\t\ttry {\n\t\t\treturn JSON.parse(String(raw)) as T;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tasync set<T = unknown>(\n\t\tkey: string,\n\t\tvalue: T,\n\t\topts: CacheSetOptions = {},\n\t): Promise<void> {\n\t\tconst now = new Date().toISOString();\n\t\tconst expiresAt =\n\t\t\topts.ttl && opts.ttl > 0\n\t\t\t\t? new Date(Date.now() + opts.ttl * 1000).toISOString()\n\t\t\t\t: null;\n\t\tconst serialized = JSON.stringify(value);\n\n\t\t// Upsert the cache row. Different dialects use different syntax;\n\t\t// we use the simple INSERT ... ON CONFLICT pattern (works in\n\t\t// sqlite, postgres, mysql 8+).\n\t\tawait this.db.rawQuery(\n\t\t\t`INSERT INTO ${this.t} (${this.c.key}, ${this.c.value}, ${this.c.expiresAt}, ${this.c.createdAt}, ${this.c.updatedAt})\n\t\t\t VALUES (?, ?, ?, ?, ?)\n\t\t\t ON CONFLICT (${this.c.key}) DO UPDATE SET\n\t\t\t ${this.c.value} = excluded.${this.c.value},\n\t\t\t ${this.c.expiresAt} = excluded.${this.c.expiresAt},\n\t\t\t ${this.c.updatedAt} = excluded.${this.c.updatedAt}`,\n\t\t\t[key, serialized, expiresAt, now, now],\n\t\t);\n\n\t\t// Refresh tag index: delete old tags, then insert new ones.\n\t\tif (opts.tags && opts.tags.length > 0) {\n\t\t\tawait this.db.rawQuery(\n\t\t\t\t`DELETE FROM ${this.tagsT} WHERE ${this.c.key} = ?`,\n\t\t\t\t[key],\n\t\t\t);\n\t\t\tfor (const tag of opts.tags) {\n\t\t\t\tawait this.db.rawQuery(\n\t\t\t\t\t`INSERT OR IGNORE INTO ${this.tagsT} (${this.c.tag}, ${this.c.key}) VALUES (?, ?)`,\n\t\t\t\t\t[tag, key],\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync delete(key: string): Promise<boolean> {\n\t\t// Cheap probe: does the row exist at all (even expired)?\n\t\tconst probe = await this.db.rawQuery<CacheRow>(\n\t\t\t`SELECT ${this.c.key} FROM ${this.t} WHERE ${this.c.key} = ? LIMIT 1`,\n\t\t\t[key],\n\t\t);\n\t\tif (probe.length === 0) return false;\n\t\tawait this.db.rawQuery(`DELETE FROM ${this.t} WHERE ${this.c.key} = ?`, [key]);\n\t\tawait this.db.rawQuery(\n\t\t\t`DELETE FROM ${this.tagsT} WHERE ${this.c.key} = ?`,\n\t\t\t[key],\n\t\t);\n\t\treturn true;\n\t}\n\n\tasync clear(pattern?: string): Promise<number> {\n\t\tif (!pattern) {\n\t\t\tawait this.db.rawQuery(`DELETE FROM ${this.tagsT}`);\n\t\t\tconst before = await this.db.rawQuery<unknown>(\n\t\t\t\t`SELECT COUNT(*) as n FROM ${this.t}`,\n\t\t\t);\n\t\t\tawait this.db.rawQuery(`DELETE FROM ${this.t}`);\n\t\t\tconst n = Number((before[0] as { n?: number } | undefined)?.n ?? 0);\n\t\t\treturn n;\n\t\t}\n\t\t// Translate glob to SQL LIKE. `*` -> `%`.\n\t\tconst likePattern = pattern\n\t\t\t.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\t\t\t.replace(/\\*\\*/g, \"%\")\n\t\t\t.replace(/\\*/g, \"%\");\n\t\tconst before = await this.db.rawQuery<unknown>(\n\t\t\t`SELECT COUNT(*) as n FROM ${this.t} WHERE ${this.c.key} LIKE ? ESCAPE '\\\\'`,\n\t\t\t[likePattern],\n\t\t);\n\t\tawait this.db.rawQuery(\n\t\t\t`DELETE FROM ${this.t} WHERE ${this.c.key} LIKE ? ESCAPE '\\\\'`,\n\t\t\t[likePattern],\n\t\t);\n\t\treturn Number((before[0] as { n?: number } | undefined)?.n ?? 0);\n\t}\n\n\tasync wrap<T>(key: string, fn: () => Promise<T>, ttl?: number): Promise<T> {\n\t\tconst hit = await this.get<T>(key);\n\t\tif (hit !== undefined) return hit;\n\t\tconst v = await fn();\n\t\tawait this.set(key, v, { ttl });\n\t\treturn v;\n\t}\n\n\t/**\n\t * Remove every cache entry that has been tagged with `tag`.\n\t * Returns the number of keys removed.\n\t */\n\tasync invalidateByTag(tag: string): Promise<number> {\n\t\tconst tagRows = await this.db.rawQuery<TagRow>(\n\t\t\t`SELECT ${this.c.key} FROM ${this.tagsT} WHERE ${this.c.tag} = ?`,\n\t\t\t[tag],\n\t\t);\n\t\tconst keys = tagRows.map((r) => r[this.c.key]);\n\t\tif (keys.length === 0) return 0;\n\t\t// Use a parameter list to safely delete. We chunk in case there\n\t\t// are many keys (some DBs cap the parameter count).\n\t\tconst chunkSize = 100;\n\t\tlet removed = 0;\n\t\tfor (let i = 0; i < keys.length; i += chunkSize) {\n\t\t\tconst chunk = keys.slice(i, i + chunkSize);\n\t\t\tconst placeholders = chunk.map(() => \"?\").join(\", \");\n\t\t\tconst r1 = await this.db.rawQuery<unknown>(\n\t\t\t\t`DELETE FROM ${this.t} WHERE ${this.c.key} IN (${placeholders})`,\n\t\t\t\tchunk,\n\t\t\t);\n\t\t\tconst r2 = await this.db.rawQuery<unknown>(\n\t\t\t\t`DELETE FROM ${this.tagsT} WHERE ${this.c.key} IN (${placeholders})`,\n\t\t\t\tchunk,\n\t\t\t);\n\t\t\tremoved += Math.max(r1.length, r2.length, chunk.length);\n\t\t}\n\t\treturn removed;\n\t}\n\n\t/** Clean up expired entries. */\n\tasync gc(): Promise<number> {\n\t\tconst now = new Date().toISOString();\n\t\tconst before = await this.db.rawQuery<unknown>(\n\t\t\t`SELECT COUNT(*) as n FROM ${this.t} WHERE ${this.c.expiresAt} IS NOT NULL AND ${this.c.expiresAt} <= ?`,\n\t\t\t[now],\n\t\t);\n\t\tawait this.db.rawQuery(\n\t\t\t`DELETE FROM ${this.t} WHERE ${this.c.expiresAt} IS NOT NULL AND ${this.c.expiresAt} <= ?`,\n\t\t\t[now],\n\t\t);\n\t\t// Drop dangling tag rows.\n\t\tawait this.db.rawQuery(\n\t\t\t`DELETE FROM ${this.tagsT} WHERE ${this.c.key} NOT IN (SELECT ${this.c.key} FROM ${this.t})`,\n\t\t);\n\t\treturn Number((before[0] as { n?: number } | undefined)?.n ?? 0);\n\t}\n\n\tasync close(): Promise<void> {\n\t\t// No resources to release — the underlying db is owned by the user.\n\t}\n}\n",
8
8
  "/**\n * `RedisCacheStore` — a `CacheStore` backed by `@nexusts/redis`.\n *\n * Works on **Bun** (`Bun.redis`), **Node** (`ioredis`), and\n * **Cloudflare Workers KV** (via `CloudflareKVAdapter`). The\n * same adapter selection applies as for sessions.\n *\n * import { CacheService } from '@nexusts/cache';\n * import { RedisCacheStore, createRedisClient } from '@nexusts/redis';\n *\n * const cache = new CacheService({\n * store: new RedisCacheStore(createRedisClient({ url: 'redis://localhost:6379' }), {\n * keyPrefix: 'cache:',\n * }),\n * });\n *\n * Values are JSON-serialized. The store uses the KV backend's\n * own TTL (Redis `EX` / KV `expirationTtl`).\n *\n * Tag-based invalidation is supported on the Redis and Node\n * adapters (a per-tag Set is maintained as a separate KV key).\n * On Cloudflare KV, tag invalidation degrades to a SCAN — slower\n * but correct.\n */\n\nimport type { RedisClient } from \"@nexusts/redis\";\nimport type { CacheEntry, CacheSetOptions, CacheStore } from \"../types.js\";\n\nconst DEFAULT_KEY_PREFIX = \"cache:\";\n\nexport interface RedisCacheStoreOptions {\n\t/** Key prefix. Default: \"cache:\". */\n\tkeyPrefix?: string;\n}\n\nexport class RedisCacheStore implements CacheStore {\n\treadonly kind = \"redis\";\n\t#client: RedisClient;\n\t#keyPrefix: string;\n\t#tagKeyPrefix: string;\n\n\tconstructor(client: RedisClient, options: RedisCacheStoreOptions = {}) {\n\t\tthis.#client = client;\n\t\tthis.#keyPrefix = options.keyPrefix ?? DEFAULT_KEY_PREFIX;\n\t\tthis.#tagKeyPrefix = `${this.#keyPrefix}tag:`;\n\t}\n\n\t#key(key: string): string {\n\t\treturn `${this.#keyPrefix}${key}`;\n\t}\n\n\t#tagKey(tag: string): string {\n\t\treturn `${this.#tagKeyPrefix}${crc32(tag)}`;\n\t}\n\n\tasync get<T = unknown>(key: string): Promise<T | undefined> {\n\t\tconst raw = await this.#client.get(this.#key(key));\n\t\tif (raw === null) return undefined;\n\t\ttry {\n\t\t\tconst entry = JSON.parse(raw) as CacheEntry<T>;\n\t\t\tif (entry.expiresAt && entry.expiresAt <= Date.now()) {\n\t\t\t\tawait this.#client.del(this.#key(key));\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn entry.value;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tasync set<T = unknown>(\n\t\tkey: string,\n\t\tvalue: T,\n\t\topts?: CacheSetOptions,\n\t): Promise<void> {\n\t\tconst ttl = opts?.ttl ?? 0;\n\t\tconst tags = opts?.tags ?? [];\n\t\tconst entry: CacheEntry<T> = {\n\t\t\tvalue,\n\t\t\texpiresAt: ttl > 0 ? Date.now() + ttl * 1000 : 0,\n\t\t\t...(tags.length > 0 ? { tags } : {}),\n\t\t};\n\t\tconst fullKey = this.#key(key);\n\t\tconst ex = ttl > 0 ? ttl : undefined;\n\t\tawait this.#client.set(fullKey, JSON.stringify(entry), ex ? { ex } : undefined);\n\t\t// Update per-tag indexes.\n\t\tfor (const tag of tags) {\n\t\t\tawait this.#addToTagIndex(tag, key);\n\t\t}\n\t}\n\n\tasync delete(key: string): Promise<boolean> {\n\t\tconst fullKey = this.#key(key);\n\t\tconst existed = (await this.#client.get(fullKey)) !== null;\n\t\tawait this.#client.del(fullKey);\n\t\t// The tag indexes are best-effort — leave them; gc() will\n\t\t// eventually prune orphans. (A full implementation would\n\t\t// need to read the entry to find its tags before deleting,\n\t\t// which is an extra round-trip.)\n\t\treturn existed;\n\t}\n\n\tasync has(key: string): Promise<boolean> {\n\t\treturn this.#client.exists(this.#key(key));\n\t}\n\n\tasync clear(): Promise<number> {\n\t\tlet n = 0;\n\t\tlet cursor: string | number = \"0\";\n\t\tdo {\n\t\t\tconst res = await this.#client.scan({\n\t\t\t\tmatch: `${this.#keyPrefix}*`,\n\t\t\t\tcursor,\n\t\t\t\tcount: 100,\n\t\t\t});\n\t\t\tfor (const k of res.keys) {\n\t\t\t\tawait this.#client.del(k);\n\t\t\t\tn++;\n\t\t\t}\n\t\t\tcursor = res.cursor;\n\t\t} while (cursor !== \"0\" && cursor !== 0);\n\t\treturn n;\n\t}\n\n\tasync gc(): Promise<number> {\n\t\t// The KV store evicts on TTL. Here we clean up orphan tag\n\t\t// indexes — keys in the tag set that no longer exist in\n\t\t// the value store.\n\t\tlet removed = 0;\n\t\tlet cursor: string | number = \"0\";\n\t\tdo {\n\t\t\tconst res = await this.#client.scan({\n\t\t\t\tmatch: `${this.#tagKeyPrefix}*`,\n\t\t\t\tcursor,\n\t\t\t\tcount: 100,\n\t\t\t});\n\t\t\tfor (const k of res.keys) {\n\t\t\t\tconst raw = await this.#client.get(k);\n\t\t\t\tconst ids = raw ? safeParseStringArray(raw) : [];\n\t\t\t\tconst live: string[] = [];\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tif (await this.#client.exists(this.#key(id))) live.push(id);\n\t\t\t\t}\n\t\t\t\tif (live.length === 0) {\n\t\t\t\t\tawait this.#client.del(k);\n\t\t\t\t\tremoved++;\n\t\t\t\t} else if (live.length !== ids.length) {\n\t\t\t\t\tawait this.#client.set(k, JSON.stringify(live));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcursor = res.cursor;\n\t\t} while (cursor !== \"0\" && cursor !== 0);\n\t\treturn removed;\n\t}\n\n\tasync invalidateByTag(tag: string): Promise<number> {\n\t\tconst tagK = this.#tagKey(tag);\n\t\tconst raw = await this.#client.get(tagK);\n\t\tif (!raw) return 0;\n\t\tconst keys = safeParseStringArray(raw);\n\t\tlet n = 0;\n\t\tfor (const k of keys) {\n\t\t\tawait this.#client.del(this.#key(k));\n\t\t\tn++;\n\t\t}\n\t\tawait this.#client.del(tagK);\n\t\treturn n;\n\t}\n\n\tasync invalidateByTags(tags: string[]): Promise<number> {\n\t\tlet n = 0;\n\t\tfor (const t of tags) n += await this.invalidateByTag(t);\n\t\treturn n;\n\t}\n\n\tasync wrap<T>(key: string, fn: () => Promise<T>, ttl?: number): Promise<T> {\n\t\tconst hit = await this.get<T>(key);\n\t\tif (hit !== undefined) return hit;\n\t\tconst value = await fn();\n\t\tawait this.set(key, value, ttl !== undefined ? { ttl } : undefined);\n\t\treturn value;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tawait this.#client.close();\n\t}\n\n\tasync #addToTagIndex(tag: string, key: string): Promise<void> {\n\t\tconst k = this.#tagKey(tag);\n\t\tconst raw = await this.#client.get(k);\n\t\tconst ids = raw ? safeParseStringArray(raw) : [];\n\t\tif (!ids.includes(key)) ids.push(key);\n\t\tawait this.#client.set(k, JSON.stringify(ids));\n\t}\n}\n\nfunction safeParseStringArray(raw: string): string[] {\n\ttry {\n\t\tconst v = JSON.parse(raw);\n\t\treturn Array.isArray(v) ? v.filter((x) => typeof x === \"string\") : [];\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction crc32(s: string): string {\n\tlet c = 0xffffffff;\n\tfor (let i = 0; i < s.length; i++) {\n\t\tc ^= s.charCodeAt(i);\n\t\tfor (let k = 0; k < 8; k++) {\n\t\t\tc = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n\t\t}\n\t}\n\treturn (c ^ 0xffffffff).toString(16);\n}\n",
9
9
  "/**\n * `CacheService` — main entry point for caching.\n *\n * const cache = new CacheService({ store: new MemoryStore() });\n * await cache.set('user:42', user, { ttl: 60 });\n * const u = await cache.get<User>('user:42');\n *\n * Provides:\n * - `get`, `set`, `delete`, `clear` — direct key operations\n * - `wrap` — cache-or-compute\n * - `getOrSet` — alias for wrap with a default TTL\n * - `invalidateByTag`, `invalidateByPrefix` — bulk removal\n * - `applyDecorators(target)` — wires @Cacheable / @CacheInvalidate\n * onto an existing service instance.\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport { MemoryStore } from \"./stores/memory.js\";\nimport type { CacheConfig, CacheStore } from \"./types.js\";\nimport {\n\tgetCacheableSpecs,\n\tgetCacheInvalidateSpecs,\n} from \"./types.js\";\n\n@Injectable()\nexport class CacheService {\n\t/** DI token. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:CacheService\");\n\n\tstore: CacheStore;\n\tdefaultTtl: number;\n\tprefix: string;\n\n\tconstructor(@Inject(\"CACHE_CONFIG\") config: CacheConfig = {}) {\n\t\tthis.store = config.store ?? new MemoryStore();\n\t\tthis.defaultTtl = config.defaultTtl ?? 60;\n\t\tthis.prefix = config.prefix ?? \"nexusts\";\n\t}\n\n\tprivate key(k: string): string {\n\t\treturn `${this.prefix}:${k}`;\n\t}\n\n\tasync get<T = unknown>(k: string): Promise<T | undefined> {\n\t\treturn this.store.get<T>(this.key(k));\n\t}\n\n\tasync set<T = unknown>(k: string, value: T, ttl?: number): Promise<void>;\n\tasync set<T = unknown>(k: string, value: T, opts: { ttl?: number; tags?: string[] }): Promise<void>;\n\tasync set<T = unknown>(\n\t\tk: string,\n\t\tvalue: T,\n\t\toptsOrTtl: number | { ttl?: number; tags?: string[] } = this.defaultTtl,\n\t): Promise<void> {\n\t\tconst opts =\n\t\t\ttypeof optsOrTtl === \"number\"\n\t\t\t\t? { ttl: optsOrTtl }\n\t\t\t\t: { ttl: optsOrTtl.ttl ?? this.defaultTtl, tags: optsOrTtl.tags };\n\t\tawait this.store.set<T>(this.key(k), value, opts);\n\t}\n\n\tasync delete(k: string): Promise<boolean> {\n\t\treturn this.store.delete(this.key(k));\n\t}\n\n\tasync clear(pattern?: string): Promise<number> {\n\t\treturn this.store.clear(pattern ? `${this.prefix}:${pattern}` : undefined);\n\t}\n\n\t/** Get or compute-and-store. */\n\tasync wrap<T>(k: string, fn: () => Promise<T>, ttl?: number): Promise<T> {\n\t\treturn this.store.wrap<T>(this.key(k), fn, ttl ?? this.defaultTtl);\n\t}\n\n\t/**\n\t * Tag-based invalidation. Delegates to the underlying store.\n\t * Stores without a tag index (the default `MemoryStore`) return 0.\n\t * Use `DrizzleCacheStore` (or implement `invalidateByTag` on a\n\t * custom store) for true tag-based removal.\n\t */\n\tasync invalidateByTag(tag: string): Promise<number> {\n\t\tif (typeof (this.store as any).invalidateByTag === \"function\") {\n\t\t\treturn await (this.store as any).invalidateByTag(this.prefixedTag(tag));\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/** Sweep expired entries. No-op on stores that don't implement `gc()`. */\n\tasync gc(): Promise<number> {\n\t\tif (typeof this.store.gc === \"function\") {\n\t\t\treturn await this.store.gc();\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/** Apply the configured prefix to a tag name. */\n\tprivate prefixedTag(tag: string): string {\n\t\treturn `${this.prefix}:${tag}`;\n\t}\n\n\t/**\n\t * Apply @Cacheable / @CacheInvalidate decorators to an existing service\n\t * instance. The framework's DI container does this automatically.\n\t */\n\tapplyDecorators(target: any): void {\n\t\tconst ctor = target.constructor;\n\t\tconst cacheables = getCacheableSpecs(ctor);\n\t\tfor (const spec of cacheables) {\n\t\t\tconst original = spec.original;\n\t\t\t(target as any)[spec.propertyKey] = async (...args: any[]) => {\n\t\t\t\tconst subKey = spec.keyFn(...args);\n\t\t\t\treturn this.wrap(`${spec.prefix}:${subKey}`, () =>\n\t\t\t\t\toriginal.apply(target, args),\n\t\t\t\t);\n\t\t\t};\n\t\t}\n\t\tconst invalidates = getCacheInvalidateSpecs(ctor);\n\t\tfor (const spec of invalidates) {\n\t\t\tconst original = spec.original;\n\t\t\t(target as any)[spec.propertyKey] = async (...args: any[]) => {\n\t\t\t\tconst result = await original.apply(target, args);\n\t\t\t\tconst subKey = spec.keyFn(...args);\n\t\t\t\tawait this.clear(`${spec.prefix}:${subKey}*`);\n\t\t\t\treturn result;\n\t\t\t};\n\t\t}\n\t}\n}\n",
10
10
  "/**\n * `CacheModule` — drop-in caching.\n *\n * @Module({\n * imports: [\n * CacheModule.forRoot({\n * store: new MemoryStore({ max: 50_000 }),\n * defaultTtl: 300, // 5 min\n * prefix: 'myapp',\n * }),\n * ],\n * })\n * export class AppModule {}\n */\nimport { Module } from \"@nexusts/core\";\nimport { CacheService } from \"./cache.service.js\";\nimport { MemoryStore } from \"./stores/memory.js\";\nimport { RedisCacheStore } from \"./stores/redis.js\";\nimport type { CacheConfig } from \"./types.js\";\nimport { safeGetMeta, safeDefineMeta, safeHasMeta } from \"@nexusts/core/di/safe-reflect\";\n\n@Module({\n\tproviders: [\n\t\tCacheService,\n\t\t{ provide: CacheService.TOKEN, useExisting: CacheService },\n\t],\n\texports: [CacheService, CacheService.TOKEN],\n})\nexport class CacheModule {\n\tstatic forRoot(config: CacheConfig = {}) {\n\t\t@Module({\n\t\t\tproviders: [\n\t\t\t\tCacheService,\n\t\t\t\t{ provide: CacheService.TOKEN, useExisting: CacheService },\n\t\t\t\t{\n\t\t\t\t\tprovide: \"CACHE_CONFIG\",\n\t\t\t\t\tuseFactory: async () => {\n\t\t\t\t\t\t// Explicit store wins; otherwise fall back to backend shorthand.\n\t\t\t\t\t\tif (config.store) {\n\t\t\t\t\t\t\treturn { ...config };\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (config.backend === \"redis\") {\n\t\t\t\t\t\t\tconst { createRedisClient } = await import(\"@nexusts/redis\");\n\t\t\t\t\t\t\tconst { keyPrefix, ...redisOpts } = config.redis ?? {};\n\t\t\t\t\t\t\tconst client = createRedisClient(redisOpts);\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...config,\n\t\t\t\t\t\t\t\tstore: new RedisCacheStore(client, { keyPrefix }),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { ...config, store: new MemoryStore() };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\texports: [CacheService, CacheService.TOKEN],\n\t\t})\n\t\tclass ConfiguredCacheModule {}\n\t\tObject.defineProperty(ConfiguredCacheModule, \"name\", {\n\t\t\tvalue: \"ConfiguredCacheModule\",\n\t\t});\n\t\treturn ConfiguredCacheModule;\n\t}\n}\n"
11
11
  ],
12
- "mappings": "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",
13
- "debugId": "F6EEF964BF46C91D64756E2164756E21",
12
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA;AACA;AASA,IAAM,cAAc,OAAO,IAAI,qBAAqB;AAGpD,SAAS,cAAiB,CAAC,QAAa,KAAkB;AAAA,EACzD,MAAM,SAAc,CAAC;AAAA,EAErB,MAAM,QAAQ,OAAO;AAAA,EACrB,IAAI,CAAC;AAAA,IAAO,OAAO;AAAA,EACnB,WAAW,QAAQ,OAAO,oBAAoB,KAAK,GAAG;AAAA,IACrD,MAAM,KAAK,MAAM;AAAA,IACjB,IAAI,OAAO,OAAO;AAAA,MAAY;AAAA,IAC9B,MAAM,OAAQ,GAAW,eAAe;AAAA,IACxC,IAAI;AAAA,MAAM,OAAO,KAAK,IAAI;AAAA,EAC3B;AAAA,EACA,OAAO;AAAA;AA8ED,IAAM,iBAAiB;AACvB,IAAM,wBAAwB;AAQ9B,SAAS,SAAS,CACxB,QACA,OACA,aAAa,IACP;AAAA,EACN,OAAO,QAAS,CAAY,YAAiB,cAAyB;AAAA,IAErE,IAAI,cAAc,SAAS,UAAU;AAAA,MACpC,MAAM,KAAK;AAAA,MACX,QAAQ,MAAM,aAAa;AAAA,MAE3B,MAAM,YAA4B,SAAS,mBAAmB,CAAC;AAAA,MAC/D,MAAM,OAAsB;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL,aAAa;AAAA,QACb,UAAU;AAAA,MACX;AAAA,MACA,UAAS,KAAK,IAAI;AAAA,MAClB,SAAS,kBAAkB;AAAA,MAI3B,IAAI,CAAE,GAAW;AAAA,QAAe,GAAW,eAAe,CAAC;AAAA,MAC1D,GAAW,aAAa,kBAAkB;AAAA,MAC3C;AAAA,IACD;AAAA,IAGA,MAAM,SAAS;AAAA,IACf,MAAM,cAAc;AAAA,IACpB,MAAM,aAAa,UAAU;AAAA,IAE7B,MAAM,WACL,YAAY,gBAAgB,OAAO,WAAW,KAAK,CAAC;AAAA,IACrD,SAAS,KAAK;AAAA,MACb;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,UAAU,YAAY;AAAA,IACvB,CAAC;AAAA,IACD,eAAe,gBAAgB,UAAU,OAAO,WAAW;AAAA;AAAA;AAUtD,SAAS,eAAe,CAC9B,QACA,OACM;AAAA,EACN,OAAO,QAAS,CAAY,YAAiB,cAAyB;AAAA,IAErE,IAAI,cAAc,SAAS,UAAU;AAAA,MACpC,MAAM,KAAK;AAAA,MACX,QAAQ,MAAM,aAAa;AAAA,MAE3B,MAAM,YACL,SAAS,0BAA0B,CAAC;AAAA,MACrC,MAAM,OAA4B;AAAA,QACjC;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb,UAAU;AAAA,MACX;AAAA,MACA,UAAS,KAAK,IAAI;AAAA,MAClB,SAAS,yBAAyB;AAAA,MAGlC,IAAI,CAAE,GAAW;AAAA,QAAe,GAAW,eAAe,CAAC;AAAA,MAC1D,GAAW,aAAa,yBAAyB;AAAA,MAClD;AAAA,IACD;AAAA,IAGA,MAAM,SAAS;AAAA,IACf,MAAM,cAAc;AAAA,IACpB,MAAM,aAAa,UAAU;AAAA,IAE7B,MAAM,WACL,YAAY,uBAAuB,OAAO,WAAW,KAAK,CAAC;AAAA,IAC5D,SAAS,KAAK,EAAE,QAAQ,OAAO,aAAa,UAAU,YAAY,MAAM,CAAC;AAAA,IACzE,eAAe,uBAAuB,UAAU,OAAO,WAAW;AAAA;AAAA;AAmB7D,SAAS,iBAAiB,CAAC,QAA8B;AAAA,EAE/D,MAAM,SAAS,eAA8B,QAAQ,cAAc;AAAA,EACnE,IAAI,OAAO,SAAS;AAAA,IAAG,OAAO;AAAA,EAE9B,OAAO,YAAY,gBAAgB,MAAM,KAAK,CAAC;AAAA;AAGzC,SAAS,uBAAuB,CAAC,QAAoC;AAAA,EAC3E,MAAM,SAAS,eAAoC,QAAQ,qBAAqB;AAAA,EAChF,IAAI,OAAO,SAAS;AAAA,IAAG,OAAO;AAAA,EAC9B,OAAO,YAAY,uBAAuB,MAAM,KAAK,CAAC;AAAA;;ACvOhD,MAAM,YAAkC;AAAA,EACrC,OAAO;AAAA,EACR,OAAO,IAAI;AAAA,EACX,WAAW,IAAI;AAAA,EACN;AAAA,EACT,aAAoD;AAAA,EAE5D,WAAW,CAAC,OAA2B,CAAC,GAAG;AAAA,IAC1C,KAAK,MAAM,KAAK,OAAO;AAAA,IACvB,MAAM,UAAU,KAAK,mBAAmB;AAAA,IACxC,IAAI,UAAU,GAAG;AAAA,MAChB,KAAK,aAAa,YAAY,MAAM,KAAK,aAAa,GAAG,OAAO;AAAA,MAEhE,IAAI,OAAO,KAAK,eAAe,YAAY,KAAK,eAAe,MAAM;AAAA,QACnE,KAAK,WAAmB,QAAQ;AAAA,MAClC;AAAA,IACD;AAAA;AAAA,OAGK,IAAgB,CAAC,KAAqC;AAAA,IAC3D,MAAM,IAAI,KAAK,KAAK,IAAI,GAAG;AAAA,IAC3B,IAAI,CAAC;AAAA,MAAG;AAAA,IACR,IAAI,EAAE,YAAY,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG;AAAA,MACjD,KAAK,KAAK,OAAO,GAAG;AAAA,MACpB;AAAA,IACD;AAAA,IAEA,KAAK,KAAK,OAAO,GAAG;AAAA,IACpB,KAAK,KAAK,IAAI,KAAK,CAAC;AAAA,IACpB,OAAO,EAAE;AAAA;AAAA,OAGJ,IAAgB,CACrB,KACA,OACA,OAAwB,CAAC,GACT;AAAA,IAChB,MAAM,MAAM,KAAK,OAAO;AAAA,IACxB,MAAM,QAAuB;AAAA,MAC5B;AAAA,MACA,WAAW,MAAM,IAAI,KAAK,IAAI,IAAI,MAAM,OAAO;AAAA,MAC/C,MAAM,KAAK;AAAA,IACZ;AAAA,IAEA,IAAI,CAAC,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK;AAAA,MAEtD,MAAM,SAAS,KAAK,KAAK,KAAK,EAAE,KAAK,EAAE;AAAA,MACvC,IAAI,WAAW,WAAW;AAAA,QACzB,KAAK,KAAK,OAAO,MAAM;AAAA,QACvB,WAAW,QAAQ,KAAK,SAAS,OAAO;AAAA,UAAG,KAAK,OAAO,MAAM;AAAA,MAC9D;AAAA,IACD;AAAA,IACA,KAAK,KAAK,IAAI,KAAK,KAAK;AAAA,IAExB,IAAI,KAAK,MAAM;AAAA,MACd,cAAc,SAAS,KAAK,SAAS,QAAQ;AAAA,QAAG,KAAK,OAAO,GAAG;AAAA,MAC/D,WAAW,OAAO,KAAK,MAAM;AAAA,QAC5B,IAAI,MAAM,KAAK,SAAS,IAAI,GAAG;AAAA,QAC/B,IAAI,CAAC,KAAK;AAAA,UACT,MAAM,IAAI;AAAA,UACV,KAAK,SAAS,IAAI,KAAK,GAAG;AAAA,QAC3B;AAAA,QACA,IAAI,IAAI,GAAG;AAAA,MACZ;AAAA,IACD;AAAA;AAAA,OAGK,OAAM,CAAC,KAA+B;AAAA,IAC3C,MAAM,UAAU,KAAK,KAAK,OAAO,GAAG;AAAA,IAEpC,WAAW,QAAQ,KAAK,SAAS,OAAO;AAAA,MAAG,KAAK,OAAO,GAAG;AAAA,IAC1D,OAAO;AAAA;AAAA,OAGF,MAAK,CAAC,SAAmC;AAAA,IAC9C,IAAI,CAAC,SAAS;AAAA,MACb,MAAM,KAAI,KAAK,KAAK;AAAA,MACpB,KAAK,KAAK,MAAM;AAAA,MAChB,KAAK,SAAS,MAAM;AAAA,MACpB,OAAO;AAAA,IACR;AAAA,IACA,MAAM,KAAK,aAAa,OAAO;AAAA,IAC/B,IAAI,IAAI;AAAA,IACR,WAAW,KAAK,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,GAAG;AAAA,MACtC,IAAI,GAAG,KAAK,CAAC,GAAG;AAAA,QACf,KAAK,KAAK,OAAO,CAAC;AAAA,QAClB,WAAW,QAAQ,KAAK,SAAS,OAAO;AAAA,UAAG,KAAK,OAAO,CAAC;AAAA,QACxD;AAAA,MACD;AAAA,IACD;AAAA,IACA,OAAO;AAAA;AAAA,OAGF,KAAO,CAAC,KAAa,IAAsB,KAA0B;AAAA,IAC1E,MAAM,IAAI,MAAM,KAAK,IAAO,GAAG;AAAA,IAC/B,IAAI,MAAM;AAAA,MAAW,OAAO;AAAA,IAC5B,MAAM,SAAS,MAAM,GAAG;AAAA,IACxB,MAAM,KAAK,IAAI,KAAK,QAAQ,EAAE,IAAI,CAAC;AAAA,IACnC,OAAO;AAAA;AAAA,OAOF,gBAAe,CAAC,KAA8B;AAAA,IACnD,MAAM,OAAO,KAAK,SAAS,IAAI,GAAG;AAAA,IAClC,IAAI,CAAC;AAAA,MAAM,OAAO;AAAA,IAClB,IAAI,IAAI;AAAA,IACR,WAAW,KAAK,MAAM;AAAA,MACrB,IAAI,KAAK,KAAK,OAAO,CAAC;AAAA,QAAG;AAAA,IAC1B;AAAA,IACA,KAAK,SAAS,OAAO,GAAG;AAAA,IACxB,OAAO;AAAA;AAAA,OAGF,MAAK,GAAkB;AAAA,IAC5B,IAAI,KAAK;AAAA,MAAY,cAAc,KAAK,UAAU;AAAA,IAClD,KAAK,aAAa;AAAA,IAClB,KAAK,KAAK,MAAM;AAAA,IAChB,KAAK,SAAS,MAAM;AAAA;AAAA,EAGb,YAAY,GAAS;AAAA,IAC5B,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,YAAY,GAAG,MAAM,KAAK,KAAK,QAAQ,GAAG;AAAA,MACzC,IAAI,EAAE,YAAY,KAAK,EAAE,aAAa;AAAA,QAAK,KAAK,KAAK,OAAO,CAAC;AAAA,IAC9D;AAAA,IAEA,YAAY,KAAK,SAAS,KAAK,SAAS,QAAQ,GAAG;AAAA,MAClD,WAAW,KAAK,MAAM;AAAA,QACrB,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC;AAAA,UAAG,KAAK,OAAO,CAAC;AAAA,MACrC;AAAA,MACA,IAAI,KAAK,SAAS;AAAA,QAAG,KAAK,SAAS,OAAO,GAAG;AAAA,IAC9C;AAAA;AAEF;AAEA,SAAS,YAAY,CAAC,SAAyB;AAAA,EAC9C,OAAO,IAAI,OACV,MACC,QACE,QAAQ,qBAAqB,MAAM,EACnC,QAAQ,SAAS,SAAS,EAC1B,QAAQ,OAAO,OAAO,EACtB,QAAQ,YAAY,IAAI,IAC1B,GACF;AAAA;;ACvGM,MAAM,kBAAwC;AAAA,EAC3C,OAAO;AAAA,EAER;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EASR,WAAW,CAAC,IAAoB,UAA2C,CAAC,GAAG;AAAA,IAC9E,KAAK,KAAK;AAAA,IACV,KAAK,IAAI,QAAQ,aAAa;AAAA,IAC9B,KAAK,QAAQ,QAAQ,iBAAiB;AAAA,IACtC,KAAK,IAAI;AAAA,MACR,KAAK,QAAQ,SAAS,OAAO;AAAA,MAC7B,OAAO,QAAQ,SAAS,SAAS;AAAA,MACjC,WAAW,QAAQ,SAAS,aAAa;AAAA,MACzC,WAAW,QAAQ,SAAS,aAAa;AAAA,MACzC,WAAW,QAAQ,SAAS,aAAa;AAAA,MACzC,KAAK,QAAQ,SAAS,OAAO;AAAA,IAC9B;AAAA;AAAA,OAGK,IAAgB,CAAC,KAAqC;AAAA,IAC3D,MAAM,OAAO,MAAM,KAAK,GAAG,SAC1B,iBAAiB,KAAK,WAAW,KAAK,EAAE,mBACxC,CAAC,GAAG,CACL;AAAA,IACA,MAAM,MAAM,KAAK;AAAA,IACjB,IAAI,CAAC;AAAA,MAAK;AAAA,IACV,MAAM,YAAY,IAAI,KAAK,EAAE;AAAA,IAC7B,IAAI,aAAa,IAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,KAAK,IAAI,GAAG;AAAA,MAE7D,MAAM,KAAK,OAAO,GAAG;AAAA,MACrB;AAAA,IACD;AAAA,IACA,MAAM,MAAM,IAAI,KAAK,EAAE;AAAA,IACvB,IAAI,QAAQ,QAAQ,QAAQ;AAAA,MAAW;AAAA,IACvC,IAAI;AAAA,MACH,OAAO,KAAK,MAAM,OAAO,GAAG,CAAC;AAAA,MAC5B,MAAM;AAAA,MACP;AAAA;AAAA;AAAA,OAII,IAAgB,CACrB,KACA,OACA,OAAwB,CAAC,GACT;AAAA,IAChB,MAAM,MAAM,IAAI,KAAK,EAAE,YAAY;AAAA,IACnC,MAAM,YACL,KAAK,OAAO,KAAK,MAAM,IACpB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM,IAAI,EAAE,YAAY,IACnD;AAAA,IACJ,MAAM,aAAa,KAAK,UAAU,KAAK;AAAA,IAKvC,MAAM,KAAK,GAAG,SACb,eAAe,KAAK,MAAM,KAAK,EAAE,QAAQ,KAAK,EAAE,UAAU,KAAK,EAAE,cAAc,KAAK,EAAE,cAAc,KAAK,EAAE;AAAA;AAAA,mBAE3F,KAAK,EAAE;AAAA,QAClB,KAAK,EAAE,oBAAoB,KAAK,EAAE;AAAA,QAClC,KAAK,EAAE,wBAAwB,KAAK,EAAE;AAAA,QACtC,KAAK,EAAE,wBAAwB,KAAK,EAAE,aAC3C,CAAC,KAAK,YAAY,WAAW,KAAK,GAAG,CACtC;AAAA,IAGA,IAAI,KAAK,QAAQ,KAAK,KAAK,SAAS,GAAG;AAAA,MACtC,MAAM,KAAK,GAAG,SACb,eAAe,KAAK,eAAe,KAAK,EAAE,WAC1C,CAAC,GAAG,CACL;AAAA,MACA,WAAW,OAAO,KAAK,MAAM;AAAA,QAC5B,MAAM,KAAK,GAAG,SACb,yBAAyB,KAAK,UAAU,KAAK,EAAE,QAAQ,KAAK,EAAE,sBAC9D,CAAC,KAAK,GAAG,CACV;AAAA,MACD;AAAA,IACD;AAAA;AAAA,OAGK,OAAM,CAAC,KAA+B;AAAA,IAE3C,MAAM,QAAQ,MAAM,KAAK,GAAG,SAC3B,UAAU,KAAK,EAAE,YAAY,KAAK,WAAW,KAAK,EAAE,mBACpD,CAAC,GAAG,CACL;AAAA,IACA,IAAI,MAAM,WAAW;AAAA,MAAG,OAAO;AAAA,IAC/B,MAAM,KAAK,GAAG,SAAS,eAAe,KAAK,WAAW,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC;AAAA,IAC7E,MAAM,KAAK,GAAG,SACb,eAAe,KAAK,eAAe,KAAK,EAAE,WAC1C,CAAC,GAAG,CACL;AAAA,IACA,OAAO;AAAA;AAAA,OAGF,MAAK,CAAC,SAAmC;AAAA,IAC9C,IAAI,CAAC,SAAS;AAAA,MACb,MAAM,KAAK,GAAG,SAAS,eAAe,KAAK,OAAO;AAAA,MAClD,MAAM,UAAS,MAAM,KAAK,GAAG,SAC5B,6BAA6B,KAAK,GACnC;AAAA,MACA,MAAM,KAAK,GAAG,SAAS,eAAe,KAAK,GAAG;AAAA,MAC9C,MAAM,IAAI,OAAQ,QAAO,IAAmC,KAAK,CAAC;AAAA,MAClE,OAAO;AAAA,IACR;AAAA,IAEA,MAAM,cAAc,QAClB,QAAQ,qBAAqB,MAAM,EACnC,QAAQ,SAAS,GAAG,EACpB,QAAQ,OAAO,GAAG;AAAA,IACpB,MAAM,SAAS,MAAM,KAAK,GAAG,SAC5B,6BAA6B,KAAK,WAAW,KAAK,EAAE,0BACpD,CAAC,WAAW,CACb;AAAA,IACA,MAAM,KAAK,GAAG,SACb,eAAe,KAAK,WAAW,KAAK,EAAE,0BACtC,CAAC,WAAW,CACb;AAAA,IACA,OAAO,OAAQ,OAAO,IAAmC,KAAK,CAAC;AAAA;AAAA,OAG1D,KAAO,CAAC,KAAa,IAAsB,KAA0B;AAAA,IAC1E,MAAM,MAAM,MAAM,KAAK,IAAO,GAAG;AAAA,IACjC,IAAI,QAAQ;AAAA,MAAW,OAAO;AAAA,IAC9B,MAAM,IAAI,MAAM,GAAG;AAAA,IACnB,MAAM,KAAK,IAAI,KAAK,GAAG,EAAE,IAAI,CAAC;AAAA,IAC9B,OAAO;AAAA;AAAA,OAOF,gBAAe,CAAC,KAA8B;AAAA,IACnD,MAAM,UAAU,MAAM,KAAK,GAAG,SAC7B,UAAU,KAAK,EAAE,YAAY,KAAK,eAAe,KAAK,EAAE,WACxD,CAAC,GAAG,CACL;AAAA,IACA,MAAM,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI;AAAA,IAC7C,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO;AAAA,IAG9B,MAAM,YAAY;AAAA,IAClB,IAAI,UAAU;AAAA,IACd,SAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK,WAAW;AAAA,MAChD,MAAM,QAAQ,KAAK,MAAM,GAAG,IAAI,SAAS;AAAA,MACzC,MAAM,eAAe,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AAAA,MACnD,MAAM,KAAK,MAAM,KAAK,GAAG,SACxB,eAAe,KAAK,WAAW,KAAK,EAAE,WAAW,iBACjD,KACD;AAAA,MACA,MAAM,KAAK,MAAM,KAAK,GAAG,SACxB,eAAe,KAAK,eAAe,KAAK,EAAE,WAAW,iBACrD,KACD;AAAA,MACA,WAAW,KAAK,IAAI,GAAG,QAAQ,GAAG,QAAQ,MAAM,MAAM;AAAA,IACvD;AAAA,IACA,OAAO;AAAA;AAAA,OAIF,GAAE,GAAoB;AAAA,IAC3B,MAAM,MAAM,IAAI,KAAK,EAAE,YAAY;AAAA,IACnC,MAAM,SAAS,MAAM,KAAK,GAAG,SAC5B,6BAA6B,KAAK,WAAW,KAAK,EAAE,6BAA6B,KAAK,EAAE,kBACxF,CAAC,GAAG,CACL;AAAA,IACA,MAAM,KAAK,GAAG,SACb,eAAe,KAAK,WAAW,KAAK,EAAE,6BAA6B,KAAK,EAAE,kBAC1E,CAAC,GAAG,CACL;AAAA,IAEA,MAAM,KAAK,GAAG,SACb,eAAe,KAAK,eAAe,KAAK,EAAE,sBAAsB,KAAK,EAAE,YAAY,KAAK,IACzF;AAAA,IACA,OAAO,OAAQ,OAAO,IAAmC,KAAK,CAAC;AAAA;AAAA,OAG1D,MAAK,GAAkB;AAG9B;;AC/NA,IAAM,qBAAqB;AAAA;AAOpB,MAAM,gBAAsC;AAAA,EACzC,OAAO;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EAEA,WAAW,CAAC,QAAqB,UAAkC,CAAC,GAAG;AAAA,IACtE,KAAK,UAAU;AAAA,IACf,KAAK,aAAa,QAAQ,aAAa;AAAA,IACvC,KAAK,gBAAgB,GAAG,KAAK;AAAA;AAAA,EAG9B,IAAI,CAAC,KAAqB;AAAA,IACzB,OAAO,GAAG,KAAK,aAAa;AAAA;AAAA,EAG7B,OAAO,CAAC,KAAqB;AAAA,IAC5B,OAAO,GAAG,KAAK,gBAAgB,MAAM,GAAG;AAAA;AAAA,OAGnC,IAAgB,CAAC,KAAqC;AAAA,IAC3D,MAAM,MAAM,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,IACjD,IAAI,QAAQ;AAAA,MAAM;AAAA,IAClB,IAAI;AAAA,MACH,MAAM,QAAQ,KAAK,MAAM,GAAG;AAAA,MAC5B,IAAI,MAAM,aAAa,MAAM,aAAa,KAAK,IAAI,GAAG;AAAA,QACrD,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,QACrC;AAAA,MACD;AAAA,MACA,OAAO,MAAM;AAAA,MACZ,MAAM;AAAA,MACP;AAAA;AAAA;AAAA,OAII,IAAgB,CACrB,KACA,OACA,MACgB;AAAA,IAChB,MAAM,MAAM,MAAM,OAAO;AAAA,IACzB,MAAM,OAAO,MAAM,QAAQ,CAAC;AAAA,IAC5B,MAAM,QAAuB;AAAA,MAC5B;AAAA,MACA,WAAW,MAAM,IAAI,KAAK,IAAI,IAAI,MAAM,OAAO;AAAA,SAC3C,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,IACnC;AAAA,IACA,MAAM,UAAU,KAAK,KAAK,GAAG;AAAA,IAC7B,MAAM,KAAK,MAAM,IAAI,MAAM;AAAA,IAC3B,MAAM,KAAK,QAAQ,IAAI,SAAS,KAAK,UAAU,KAAK,GAAG,KAAK,EAAE,GAAG,IAAI,SAAS;AAAA,IAE9E,WAAW,OAAO,MAAM;AAAA,MACvB,MAAM,KAAK,eAAe,KAAK,GAAG;AAAA,IACnC;AAAA;AAAA,OAGK,OAAM,CAAC,KAA+B;AAAA,IAC3C,MAAM,UAAU,KAAK,KAAK,GAAG;AAAA,IAC7B,MAAM,UAAW,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAO;AAAA,IACtD,MAAM,KAAK,QAAQ,IAAI,OAAO;AAAA,IAK9B,OAAO;AAAA;AAAA,OAGF,IAAG,CAAC,KAA+B;AAAA,IACxC,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAK,GAAG,CAAC;AAAA;AAAA,OAGpC,MAAK,GAAoB;AAAA,IAC9B,IAAI,IAAI;AAAA,IACR,IAAI,SAA0B;AAAA,IAC9B,GAAG;AAAA,MACF,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;AAAA,QACnC,OAAO,GAAG,KAAK;AAAA,QACf;AAAA,QACA,OAAO;AAAA,MACR,CAAC;AAAA,MACD,WAAW,KAAK,IAAI,MAAM;AAAA,QACzB,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,QACxB;AAAA,MACD;AAAA,MACA,SAAS,IAAI;AAAA,IACd,SAAS,WAAW,OAAO,WAAW;AAAA,IACtC,OAAO;AAAA;AAAA,OAGF,GAAE,GAAoB;AAAA,IAI3B,IAAI,UAAU;AAAA,IACd,IAAI,SAA0B;AAAA,IAC9B,GAAG;AAAA,MACF,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;AAAA,QACnC,OAAO,GAAG,KAAK;AAAA,QACf;AAAA,QACA,OAAO;AAAA,MACR,CAAC;AAAA,MACD,WAAW,KAAK,IAAI,MAAM;AAAA,QACzB,MAAM,MAAM,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,QACpC,MAAM,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAAA,QAC/C,MAAM,OAAiB,CAAC;AAAA,QACxB,WAAW,MAAM,KAAK;AAAA,UACrB,IAAI,MAAM,KAAK,QAAQ,OAAO,KAAK,KAAK,EAAE,CAAC;AAAA,YAAG,KAAK,KAAK,EAAE;AAAA,QAC3D;AAAA,QACA,IAAI,KAAK,WAAW,GAAG;AAAA,UACtB,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,UACxB;AAAA,QACD,EAAO,SAAI,KAAK,WAAW,IAAI,QAAQ;AAAA,UACtC,MAAM,KAAK,QAAQ,IAAI,GAAG,KAAK,UAAU,IAAI,CAAC;AAAA,QAC/C;AAAA,MACD;AAAA,MACA,SAAS,IAAI;AAAA,IACd,SAAS,WAAW,OAAO,WAAW;AAAA,IACtC,OAAO;AAAA;AAAA,OAGF,gBAAe,CAAC,KAA8B;AAAA,IACnD,MAAM,OAAO,KAAK,QAAQ,GAAG;AAAA,IAC7B,MAAM,MAAM,MAAM,KAAK,QAAQ,IAAI,IAAI;AAAA,IACvC,IAAI,CAAC;AAAA,MAAK,OAAO;AAAA,IACjB,MAAM,OAAO,qBAAqB,GAAG;AAAA,IACrC,IAAI,IAAI;AAAA,IACR,WAAW,KAAK,MAAM;AAAA,MACrB,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK,CAAC,CAAC;AAAA,MACnC;AAAA,IACD;AAAA,IACA,MAAM,KAAK,QAAQ,IAAI,IAAI;AAAA,IAC3B,OAAO;AAAA;AAAA,OAGF,iBAAgB,CAAC,MAAiC;AAAA,IACvD,IAAI,IAAI;AAAA,IACR,WAAW,KAAK;AAAA,MAAM,KAAK,MAAM,KAAK,gBAAgB,CAAC;AAAA,IACvD,OAAO;AAAA;AAAA,OAGF,KAAO,CAAC,KAAa,IAAsB,KAA0B;AAAA,IAC1E,MAAM,MAAM,MAAM,KAAK,IAAO,GAAG;AAAA,IACjC,IAAI,QAAQ;AAAA,MAAW,OAAO;AAAA,IAC9B,MAAM,QAAQ,MAAM,GAAG;AAAA,IACvB,MAAM,KAAK,IAAI,KAAK,OAAO,QAAQ,YAAY,EAAE,IAAI,IAAI,SAAS;AAAA,IAClE,OAAO;AAAA;AAAA,OAGF,MAAK,GAAkB;AAAA,IAC5B,MAAM,KAAK,QAAQ,MAAM;AAAA;AAAA,OAGpB,cAAc,CAAC,KAAa,KAA4B;AAAA,IAC7D,MAAM,IAAI,KAAK,QAAQ,GAAG;AAAA,IAC1B,MAAM,MAAM,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,IACpC,MAAM,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAAA,IAC/C,IAAI,CAAC,IAAI,SAAS,GAAG;AAAA,MAAG,IAAI,KAAK,GAAG;AAAA,IACpC,MAAM,KAAK,QAAQ,IAAI,GAAG,KAAK,UAAU,GAAG,CAAC;AAAA;AAE/C;AAEA,SAAS,oBAAoB,CAAC,KAAuB;AAAA,EACpD,IAAI;AAAA,IACH,MAAM,IAAI,KAAK,MAAM,GAAG;AAAA,IACxB,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,OAAO,MAAM,QAAQ,IAAI,CAAC;AAAA,IACnE,MAAM;AAAA,IACP,OAAO,CAAC;AAAA;AAAA;AAIV,SAAS,KAAK,CAAC,GAAmB;AAAA,EACjC,IAAI,IAAI;AAAA,EACR,SAAS,IAAI,EAAG,IAAI,EAAE,QAAQ,KAAK;AAAA,IAClC,KAAK,EAAE,WAAW,CAAC;AAAA,IACnB,SAAS,IAAI,EAAG,IAAI,GAAG,KAAK;AAAA,MAC3B,IAAI,IAAI,IAAI,aAAc,MAAM,IAAK,MAAM;AAAA,IAC5C;AAAA,EACD;AAAA,EACA,QAAQ,IAAI,YAAY,SAAS,EAAE;AAAA;;ACtMpC;AASO,MAAM,aAAa;AAAA,SAET,QAAQ,OAAO,IAAI,oBAAoB;AAAA,EAEvD;AAAA,EACA;AAAA,EACA;AAAA,EAEA,WAAW,CAAyB,SAAsB,CAAC,GAAG;AAAA,IAC7D,KAAK,QAAQ,OAAO,SAAS,IAAI;AAAA,IACjC,KAAK,aAAa,OAAO,cAAc;AAAA,IACvC,KAAK,SAAS,OAAO,UAAU;AAAA;AAAA,EAGxB,GAAG,CAAC,GAAmB;AAAA,IAC9B,OAAO,GAAG,KAAK,UAAU;AAAA;AAAA,OAGpB,IAAgB,CAAC,GAAmC;AAAA,IACzD,OAAO,KAAK,MAAM,IAAO,KAAK,IAAI,CAAC,CAAC;AAAA;AAAA,OAK/B,IAAgB,CACrB,GACA,OACA,YAAwD,KAAK,YAC7C;AAAA,IAChB,MAAM,OACL,OAAO,cAAc,WAClB,EAAE,KAAK,UAAU,IACjB,EAAE,KAAK,UAAU,OAAO,KAAK,YAAY,MAAM,UAAU,KAAK;AAAA,IAClE,MAAM,KAAK,MAAM,IAAO,KAAK,IAAI,CAAC,GAAG,OAAO,IAAI;AAAA;AAAA,OAG3C,OAAM,CAAC,GAA6B;AAAA,IACzC,OAAO,KAAK,MAAM,OAAO,KAAK,IAAI,CAAC,CAAC;AAAA;AAAA,OAG/B,MAAK,CAAC,SAAmC;AAAA,IAC9C,OAAO,KAAK,MAAM,MAAM,UAAU,GAAG,KAAK,UAAU,YAAY,SAAS;AAAA;AAAA,OAIpE,KAAO,CAAC,GAAW,IAAsB,KAA0B;AAAA,IACxE,OAAO,KAAK,MAAM,KAAQ,KAAK,IAAI,CAAC,GAAG,IAAI,OAAO,KAAK,UAAU;AAAA;AAAA,OAS5D,gBAAe,CAAC,KAA8B;AAAA,IACnD,IAAI,OAAQ,KAAK,MAAc,oBAAoB,YAAY;AAAA,MAC9D,OAAO,MAAO,KAAK,MAAc,gBAAgB,KAAK,YAAY,GAAG,CAAC;AAAA,IACvE;AAAA,IACA,OAAO;AAAA;AAAA,OAIF,GAAE,GAAoB;AAAA,IAC3B,IAAI,OAAO,KAAK,MAAM,OAAO,YAAY;AAAA,MACxC,OAAO,MAAM,KAAK,MAAM,GAAG;AAAA,IAC5B;AAAA,IACA,OAAO;AAAA;AAAA,EAIA,WAAW,CAAC,KAAqB;AAAA,IACxC,OAAO,GAAG,KAAK,UAAU;AAAA;AAAA,EAO1B,eAAe,CAAC,QAAmB;AAAA,IAClC,MAAM,OAAO,OAAO;AAAA,IACpB,MAAM,aAAa,kBAAkB,IAAI;AAAA,IACzC,WAAW,QAAQ,YAAY;AAAA,MAC9B,MAAM,WAAW,KAAK;AAAA,MACrB,OAAe,KAAK,eAAe,UAAU,SAAgB;AAAA,QAC7D,MAAM,SAAS,KAAK,MAAM,GAAG,IAAI;AAAA,QACjC,OAAO,KAAK,KAAK,GAAG,KAAK,UAAU,UAAU,MAC5C,SAAS,MAAM,QAAQ,IAAI,CAC5B;AAAA;AAAA,IAEF;AAAA,IACA,MAAM,cAAc,wBAAwB,IAAI;AAAA,IAChD,WAAW,QAAQ,aAAa;AAAA,MAC/B,MAAM,WAAW,KAAK;AAAA,MACrB,OAAe,KAAK,eAAe,UAAU,SAAgB;AAAA,QAC7D,MAAM,SAAS,MAAM,SAAS,MAAM,QAAQ,IAAI;AAAA,QAChD,MAAM,SAAS,KAAK,MAAM,GAAG,IAAI;AAAA,QACjC,MAAM,KAAK,MAAM,GAAG,KAAK,UAAU,SAAS;AAAA,QAC5C,OAAO;AAAA;AAAA,IAET;AAAA;AAEF;AAtGa,eAAN;AAAA,EADN,WAAW;AAAA,EASE,kCAAO,cAAc;AAAA,EAR5B;AAAA;AAAA;AAAA,GAAM;;ACVb;AAcO,MAAM,YAAY;AAAA,SACjB,OAAO,CAAC,SAAsB,CAAC,GAAG;AAAA,IA2BxC,MAAM,sBAAsB;AAAA,IAAC;AAAA,IAAvB,wBAAN;AAAA,MA1BC,OAAO;AAAA,QACP,WAAW;AAAA,UACV;AAAA,UACA,EAAE,SAAS,aAAa,OAAO,aAAa,aAAa;AAAA,UACzD;AAAA,YACC,SAAS;AAAA,YACT,YAAY,YAAY;AAAA,cAEvB,IAAI,OAAO,OAAO;AAAA,gBACjB,OAAO,KAAK,OAAO;AAAA,cACpB;AAAA,cACA,IAAI,OAAO,YAAY,SAAS;AAAA,gBAC/B,QAAQ,sBAAsB,MAAa;AAAA,gBAC3C,QAAQ,cAAc,cAAc,OAAO,SAAS,CAAC;AAAA,gBACrD,MAAM,SAAS,kBAAkB,SAAS;AAAA,gBAC1C,OAAO;AAAA,qBACH;AAAA,kBACH,OAAO,IAAI,gBAAgB,QAAQ,EAAE,UAAU,CAAC;AAAA,gBACjD;AAAA,cACD;AAAA,cACA,OAAO,KAAK,QAAQ,OAAO,IAAI,YAAc;AAAA;AAAA,UAE/C;AAAA,QACD;AAAA,QACA,SAAS,CAAC,cAAc,aAAa,KAAK;AAAA,MAC3C,CAAC;AAAA,OACK;AAAA,IACN,OAAO,eAAe,uBAAuB,QAAQ;AAAA,MACpD,OAAO;AAAA,IACR,CAAC;AAAA,IACD,OAAO;AAAA;AAET;AAlCa,cAAN;AAAA,EAPN,OAAO;AAAA,IACP,WAAW;AAAA,MACV;AAAA,MACA,EAAE,SAAS,aAAa,OAAO,aAAa,aAAa;AAAA,IAC1D;AAAA,IACA,SAAS,CAAC,cAAc,aAAa,KAAK;AAAA,EAC3C,CAAC;AAAA,GACY;",
13
+ "debugId": "A6E1EE368DAEA82164756E2164756E21",
14
14
  "names": []
15
15
  }
package/dist/types.d.ts CHANGED
@@ -84,10 +84,20 @@ export interface CacheConfig {
84
84
  /** Internal metadata key. */
85
85
  export declare const CACHEABLE_META = "nexus:cache:cacheable";
86
86
  export declare const CACHE_INVALIDATE_META = "nexus:cache:invalidate";
87
- /** @Cacheable decorator. Caches the result of a method. */
88
- export declare function Cacheable(prefix: string, keyFn: (...args: any[]) => string, ttlSeconds?: number): MethodDecorator;
89
- /** @CacheInvalidate decorator. Removes matching keys after a method runs. */
90
- export declare function CacheInvalidate(prefix: string, keyFn: (...args: any[]) => string): MethodDecorator;
87
+ /**
88
+ * @Cacheable decorator. Caches the result of a method.
89
+ *
90
+ * Dual-mode: supports both TC39 standard ES decorators (Bun 1.3+ default)
91
+ * and legacy experimentalDecorators.
92
+ */
93
+ export declare function Cacheable(prefix: string, keyFn: (...args: any[]) => string, ttlSeconds?: number): any;
94
+ /**
95
+ * @CacheInvalidate decorator. Removes matching keys after a method runs.
96
+ *
97
+ * Dual-mode: supports both TC39 standard ES decorators (Bun 1.3+ default)
98
+ * and legacy experimentalDecorators.
99
+ */
100
+ export declare function CacheInvalidate(prefix: string, keyFn: (...args: any[]) => string): any;
91
101
  export interface CacheableSpec {
92
102
  prefix: string;
93
103
  keyFn: (...args: any[]) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexusts/cache",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
4
4
  "description": "Application cache (memory / Redis / Drizzle backends)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
- "@nexusts/core": "^0.9.6"
29
+ "@nexusts/core": "^0.9.8"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "@nexusts/redis": ">=0.7.0"