@warlock.js/cache 4.0.171 → 4.1.1

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 (213) hide show
  1. package/README.md +85 -0
  2. package/cjs/index.cjs +4088 -0
  3. package/cjs/index.cjs.map +1 -0
  4. package/esm/cache-manager.d.mts +314 -0
  5. package/esm/cache-manager.d.mts.map +1 -0
  6. package/esm/cache-manager.mjs +486 -0
  7. package/esm/cache-manager.mjs.map +1 -0
  8. package/esm/cached/auto-key.d.mts +25 -0
  9. package/esm/cached/auto-key.d.mts.map +1 -0
  10. package/esm/cached/auto-key.mjs +55 -0
  11. package/esm/cached/auto-key.mjs.map +1 -0
  12. package/esm/cached/cached.d.mts +54 -0
  13. package/esm/cached/cached.d.mts.map +1 -0
  14. package/esm/cached/cached.mjs +25 -0
  15. package/esm/cached/cached.mjs.map +1 -0
  16. package/esm/cached/index.d.mts +3 -0
  17. package/esm/cached/index.mjs +5 -0
  18. package/esm/cached/normalize-args.d.mts +51 -0
  19. package/esm/cached/normalize-args.d.mts.map +1 -0
  20. package/esm/cached/normalize-args.mjs +26 -0
  21. package/esm/cached/normalize-args.mjs.map +1 -0
  22. package/esm/drivers/base-cache-driver.d.mts +322 -0
  23. package/esm/drivers/base-cache-driver.d.mts.map +1 -0
  24. package/esm/drivers/base-cache-driver.mjs +522 -0
  25. package/esm/drivers/base-cache-driver.mjs.map +1 -0
  26. package/esm/drivers/file-cache-driver.d.mts +68 -0
  27. package/esm/drivers/file-cache-driver.d.mts.map +1 -0
  28. package/esm/drivers/file-cache-driver.mjs +174 -0
  29. package/esm/drivers/file-cache-driver.mjs.map +1 -0
  30. package/esm/drivers/index.d.mts +9 -0
  31. package/esm/drivers/index.mjs +11 -0
  32. package/esm/drivers/lru-memory-cache-driver.d.mts +136 -0
  33. package/esm/drivers/lru-memory-cache-driver.d.mts.map +1 -0
  34. package/esm/drivers/lru-memory-cache-driver.mjs +317 -0
  35. package/esm/drivers/lru-memory-cache-driver.mjs.map +1 -0
  36. package/esm/drivers/memory-cache-driver.d.mts +112 -0
  37. package/esm/drivers/memory-cache-driver.d.mts.map +1 -0
  38. package/esm/drivers/memory-cache-driver.mjs +241 -0
  39. package/esm/drivers/memory-cache-driver.mjs.map +1 -0
  40. package/esm/drivers/memory-extended-cache-driver.d.mts +17 -0
  41. package/esm/drivers/memory-extended-cache-driver.d.mts.map +1 -0
  42. package/esm/drivers/memory-extended-cache-driver.mjs +34 -0
  43. package/esm/drivers/memory-extended-cache-driver.mjs.map +1 -0
  44. package/esm/drivers/mock-cache-driver.d.mts +137 -0
  45. package/esm/drivers/mock-cache-driver.d.mts.map +1 -0
  46. package/esm/drivers/mock-cache-driver.mjs +226 -0
  47. package/esm/drivers/mock-cache-driver.mjs.map +1 -0
  48. package/esm/drivers/null-cache-driver.d.mts +69 -0
  49. package/esm/drivers/null-cache-driver.d.mts.map +1 -0
  50. package/esm/drivers/null-cache-driver.mjs +92 -0
  51. package/esm/drivers/null-cache-driver.mjs.map +1 -0
  52. package/esm/drivers/pg-cache-driver.d.mts +148 -0
  53. package/esm/drivers/pg-cache-driver.d.mts.map +1 -0
  54. package/esm/drivers/pg-cache-driver.mjs +437 -0
  55. package/esm/drivers/pg-cache-driver.mjs.map +1 -0
  56. package/esm/drivers/redis-cache-driver.d.mts +86 -0
  57. package/esm/drivers/redis-cache-driver.d.mts.map +1 -0
  58. package/esm/drivers/redis-cache-driver.mjs +312 -0
  59. package/esm/drivers/redis-cache-driver.mjs.map +1 -0
  60. package/esm/index.d.mts +21 -0
  61. package/esm/index.mjs +24 -0
  62. package/esm/list/index.d.mts +1 -0
  63. package/esm/list/memory-cache-list.d.mts +77 -0
  64. package/esm/list/memory-cache-list.d.mts.map +1 -0
  65. package/esm/list/memory-cache-list.mjs +119 -0
  66. package/esm/list/memory-cache-list.mjs.map +1 -0
  67. package/esm/metrics.d.mts +118 -0
  68. package/esm/metrics.d.mts.map +1 -0
  69. package/esm/metrics.mjs +197 -0
  70. package/esm/metrics.mjs.map +1 -0
  71. package/esm/scoped-cache.d.mts +205 -0
  72. package/esm/scoped-cache.d.mts.map +1 -0
  73. package/esm/scoped-cache.mjs +274 -0
  74. package/esm/scoped-cache.mjs.map +1 -0
  75. package/esm/tagged-cache.d.mts +89 -0
  76. package/esm/tagged-cache.d.mts.map +1 -0
  77. package/esm/tagged-cache.mjs +147 -0
  78. package/esm/tagged-cache.mjs.map +1 -0
  79. package/esm/tagged-scoped-cache.d.mts +111 -0
  80. package/esm/tagged-scoped-cache.d.mts.map +1 -0
  81. package/esm/tagged-scoped-cache.mjs +142 -0
  82. package/esm/tagged-scoped-cache.mjs.map +1 -0
  83. package/esm/types.d.mts +1067 -0
  84. package/esm/types.d.mts.map +1 -0
  85. package/esm/types.mjs +62 -0
  86. package/esm/types.mjs.map +1 -0
  87. package/esm/utils.d.mts +161 -0
  88. package/esm/utils.d.mts.map +1 -0
  89. package/esm/utils.mjs +222 -0
  90. package/esm/utils.mjs.map +1 -0
  91. package/llms-full.txt +2071 -0
  92. package/llms.txt +28 -0
  93. package/package.json +53 -39
  94. package/skills/apply-cache-patterns/SKILL.md +97 -0
  95. package/skills/cache-basics/SKILL.md +121 -0
  96. package/skills/configure-pg-cache/SKILL.md +115 -0
  97. package/skills/configure-set-options/SKILL.md +96 -0
  98. package/skills/handle-cache-errors/SKILL.md +91 -0
  99. package/skills/observe-cache/SKILL.md +103 -0
  100. package/skills/overview/SKILL.md +69 -0
  101. package/skills/pick-cache-driver/SKILL.md +115 -0
  102. package/skills/test-cache-code/SKILL.md +219 -0
  103. package/skills/use-cache-atomic/SKILL.md +67 -0
  104. package/skills/use-cache-bulk/SKILL.md +57 -0
  105. package/skills/use-cache-list/SKILL.md +85 -0
  106. package/skills/use-cache-lock/SKILL.md +104 -0
  107. package/skills/use-cache-namespace/SKILL.md +88 -0
  108. package/skills/use-cache-similarity/SKILL.md +94 -0
  109. package/skills/use-cache-tags/SKILL.md +85 -0
  110. package/skills/use-cache-update-merge/SKILL.md +84 -0
  111. package/skills/use-cache-utils/SKILL.md +89 -0
  112. package/skills/use-cached-hof/SKILL.md +102 -0
  113. package/skills/use-swr/SKILL.md +104 -0
  114. package/cjs/cache-manager.d.ts +0 -163
  115. package/cjs/cache-manager.d.ts.map +0 -1
  116. package/cjs/cache-manager.js +0 -322
  117. package/cjs/cache-manager.js.map +0 -1
  118. package/cjs/drivers/base-cache-driver.d.ts +0 -152
  119. package/cjs/drivers/base-cache-driver.d.ts.map +0 -1
  120. package/cjs/drivers/base-cache-driver.js +0 -321
  121. package/cjs/drivers/base-cache-driver.js.map +0 -1
  122. package/cjs/drivers/file-cache-driver.d.ts +0 -45
  123. package/cjs/drivers/file-cache-driver.d.ts.map +0 -1
  124. package/cjs/drivers/file-cache-driver.js +0 -133
  125. package/cjs/drivers/file-cache-driver.js.map +0 -1
  126. package/cjs/drivers/index.d.ts +0 -8
  127. package/cjs/drivers/index.d.ts.map +0 -1
  128. package/cjs/drivers/lru-memory-cache-driver.d.ts +0 -98
  129. package/cjs/drivers/lru-memory-cache-driver.d.ts.map +0 -1
  130. package/cjs/drivers/lru-memory-cache-driver.js +0 -252
  131. package/cjs/drivers/lru-memory-cache-driver.js.map +0 -1
  132. package/cjs/drivers/memory-cache-driver.d.ts +0 -82
  133. package/cjs/drivers/memory-cache-driver.d.ts.map +0 -1
  134. package/cjs/drivers/memory-cache-driver.js +0 -218
  135. package/cjs/drivers/memory-cache-driver.js.map +0 -1
  136. package/cjs/drivers/memory-extended-cache-driver.d.ts +0 -13
  137. package/cjs/drivers/memory-extended-cache-driver.d.ts.map +0 -1
  138. package/cjs/drivers/memory-extended-cache-driver.js +0 -25
  139. package/cjs/drivers/memory-extended-cache-driver.js.map +0 -1
  140. package/cjs/drivers/null-cache-driver.d.ts +0 -58
  141. package/cjs/drivers/null-cache-driver.d.ts.map +0 -1
  142. package/cjs/drivers/null-cache-driver.js +0 -84
  143. package/cjs/drivers/null-cache-driver.js.map +0 -1
  144. package/cjs/drivers/redis-cache-driver.d.ts +0 -57
  145. package/cjs/drivers/redis-cache-driver.d.ts.map +0 -1
  146. package/cjs/drivers/redis-cache-driver.js +0 -263
  147. package/cjs/drivers/redis-cache-driver.js.map +0 -1
  148. package/cjs/index.d.ts +0 -6
  149. package/cjs/index.d.ts.map +0 -1
  150. package/cjs/index.js +0 -1
  151. package/cjs/index.js.map +0 -1
  152. package/cjs/tagged-cache.d.ts +0 -77
  153. package/cjs/tagged-cache.d.ts.map +0 -1
  154. package/cjs/tagged-cache.js +0 -160
  155. package/cjs/tagged-cache.js.map +0 -1
  156. package/cjs/types.d.ts +0 -391
  157. package/cjs/types.d.ts.map +0 -1
  158. package/cjs/types.js +0 -36
  159. package/cjs/types.js.map +0 -1
  160. package/cjs/utils.d.ts +0 -50
  161. package/cjs/utils.d.ts.map +0 -1
  162. package/cjs/utils.js +0 -55
  163. package/cjs/utils.js.map +0 -1
  164. package/esm/cache-manager.d.ts +0 -163
  165. package/esm/cache-manager.d.ts.map +0 -1
  166. package/esm/cache-manager.js +0 -322
  167. package/esm/cache-manager.js.map +0 -1
  168. package/esm/drivers/base-cache-driver.d.ts +0 -152
  169. package/esm/drivers/base-cache-driver.d.ts.map +0 -1
  170. package/esm/drivers/base-cache-driver.js +0 -321
  171. package/esm/drivers/base-cache-driver.js.map +0 -1
  172. package/esm/drivers/file-cache-driver.d.ts +0 -45
  173. package/esm/drivers/file-cache-driver.d.ts.map +0 -1
  174. package/esm/drivers/file-cache-driver.js +0 -133
  175. package/esm/drivers/file-cache-driver.js.map +0 -1
  176. package/esm/drivers/index.d.ts +0 -8
  177. package/esm/drivers/index.d.ts.map +0 -1
  178. package/esm/drivers/lru-memory-cache-driver.d.ts +0 -98
  179. package/esm/drivers/lru-memory-cache-driver.d.ts.map +0 -1
  180. package/esm/drivers/lru-memory-cache-driver.js +0 -252
  181. package/esm/drivers/lru-memory-cache-driver.js.map +0 -1
  182. package/esm/drivers/memory-cache-driver.d.ts +0 -82
  183. package/esm/drivers/memory-cache-driver.d.ts.map +0 -1
  184. package/esm/drivers/memory-cache-driver.js +0 -218
  185. package/esm/drivers/memory-cache-driver.js.map +0 -1
  186. package/esm/drivers/memory-extended-cache-driver.d.ts +0 -13
  187. package/esm/drivers/memory-extended-cache-driver.d.ts.map +0 -1
  188. package/esm/drivers/memory-extended-cache-driver.js +0 -25
  189. package/esm/drivers/memory-extended-cache-driver.js.map +0 -1
  190. package/esm/drivers/null-cache-driver.d.ts +0 -58
  191. package/esm/drivers/null-cache-driver.d.ts.map +0 -1
  192. package/esm/drivers/null-cache-driver.js +0 -84
  193. package/esm/drivers/null-cache-driver.js.map +0 -1
  194. package/esm/drivers/redis-cache-driver.d.ts +0 -57
  195. package/esm/drivers/redis-cache-driver.d.ts.map +0 -1
  196. package/esm/drivers/redis-cache-driver.js +0 -263
  197. package/esm/drivers/redis-cache-driver.js.map +0 -1
  198. package/esm/index.d.ts +0 -6
  199. package/esm/index.d.ts.map +0 -1
  200. package/esm/index.js +0 -1
  201. package/esm/index.js.map +0 -1
  202. package/esm/tagged-cache.d.ts +0 -77
  203. package/esm/tagged-cache.d.ts.map +0 -1
  204. package/esm/tagged-cache.js +0 -160
  205. package/esm/tagged-cache.js.map +0 -1
  206. package/esm/types.d.ts +0 -391
  207. package/esm/types.d.ts.map +0 -1
  208. package/esm/types.js +0 -36
  209. package/esm/types.js.map +0 -1
  210. package/esm/utils.d.ts +0 -50
  211. package/esm/utils.d.ts.map +0 -1
  212. package/esm/utils.js +0 -55
  213. package/esm/utils.js.map +0 -1
@@ -0,0 +1,1067 @@
1
+ import { BaseCacheDriver } from "./drivers/base-cache-driver.mjs";
2
+ import { FileCacheDriver } from "./drivers/file-cache-driver.mjs";
3
+ import { LRUMemoryCacheDriver } from "./drivers/lru-memory-cache-driver.mjs";
4
+ import { MemoryCacheDriver } from "./drivers/memory-cache-driver.mjs";
5
+ import { MemoryExtendedCacheDriver } from "./drivers/memory-extended-cache-driver.mjs";
6
+ import { MockCacheDriver } from "./drivers/mock-cache-driver.mjs";
7
+ import { NullCacheDriver } from "./drivers/null-cache-driver.mjs";
8
+ import { PgCacheDriver } from "./drivers/pg-cache-driver.mjs";
9
+ import { RedisCacheDriver } from "./drivers/redis-cache-driver.mjs";
10
+ import { GenericObject } from "@mongez/reinforcements";
11
+ import { RedisClientOptions } from "redis";
12
+
13
+ //#region ../../@warlock.js/cache/src/types.d.ts
14
+ /**
15
+ * Base error class for cache-related errors
16
+ */
17
+ declare class CacheError extends Error {
18
+ constructor(message: string);
19
+ }
20
+ /**
21
+ * Error thrown when cache connection fails
22
+ */
23
+ declare class CacheConnectionError extends CacheError {
24
+ constructor(message: string);
25
+ }
26
+ /**
27
+ * Error thrown when cache driver configuration is invalid
28
+ */
29
+ declare class CacheConfigurationError extends CacheError {
30
+ constructor(message: string);
31
+ }
32
+ /**
33
+ * Error thrown when cache driver is not initialized
34
+ */
35
+ declare class CacheDriverNotInitializedError extends CacheError {
36
+ constructor(message?: string);
37
+ }
38
+ /**
39
+ * Error thrown when a driver does not implement a requested operation.
40
+ *
41
+ * Raised when a caller invokes a method the driver cannot fulfill —
42
+ * e.g. `update()` on the file driver before the file-lock primitive lands.
43
+ */
44
+ declare class CacheUnsupportedError extends CacheError {
45
+ constructor(message: string);
46
+ }
47
+ /**
48
+ * Error thrown when an optimistic-concurrency update exhausts its retry budget.
49
+ */
50
+ declare class CacheConcurrencyError extends CacheError {
51
+ constructor(message: string);
52
+ }
53
+ /**
54
+ * TTL shape accepted by set/remember/config calls.
55
+ *
56
+ * - `number` — seconds
57
+ * - `string` — human-readable duration parsed via `ms` (`"1h"`, `"30m"`, `"7d"`, `"2 weeks"`, …)
58
+ * - `Infinity` — no expiration
59
+ */
60
+ type CacheTtl = number | string;
61
+ /**
62
+ * Conflict resolution policy for `set` operations.
63
+ *
64
+ * - `"create"` — set only if the key does not exist (Redis `NX`)
65
+ * - `"update"` — set only if the key already exists (Redis `XX`)
66
+ * - `"upsert"` — default; overwrite whether the key exists or not
67
+ */
68
+ type CacheConflictPolicy = "create" | "update" | "upsert";
69
+ /**
70
+ * Result of a conditional write (`onConflict: "create" | "update"`).
71
+ */
72
+ type CacheSetResult<T = any> = {
73
+ /**
74
+ * Whether the write actually took effect.
75
+ */
76
+ wasSet: boolean;
77
+ /**
78
+ * The existing value when the write was rejected. Undefined for successful writes
79
+ * and for unconditional `upsert` writes.
80
+ */
81
+ existing: T | null;
82
+ };
83
+ /**
84
+ * Options for `lock()` — TTL is required (forgotten locks would stay forever),
85
+ * `owner` identifies who holds the lock (handy for debugging), `driver` routes
86
+ * the call through a non-default driver.
87
+ *
88
+ * @example
89
+ * await cache.lock("lock.import", { ttl: "5m", driver: "redis" }, async () => {
90
+ * await runImport();
91
+ * });
92
+ */
93
+ type LockOptions = {
94
+ /**
95
+ * How long the lock lives before auto-release. Required — guards against
96
+ * forgotten locks if the process crashes between acquire and release.
97
+ */
98
+ ttl: CacheTtl;
99
+ /**
100
+ * Identifying value stored under the lock key. Defaults to `pid.<process.pid>`.
101
+ * Use a custom owner when you want a human-readable label (e.g. `"worker.jobs-2"`).
102
+ */
103
+ owner?: string;
104
+ /**
105
+ * Per-call driver override by registered name. Manager-level only.
106
+ */
107
+ driver?: string;
108
+ };
109
+ /**
110
+ * Discriminated-union result of `lock()`. Unambiguous even when the wrapped
111
+ * function legitimately returns `undefined` — the `acquired` flag tells you
112
+ * whether `fn` ran at all.
113
+ *
114
+ * @example
115
+ * const outcome = await cache.lock("lock.x", "1m", async () => computeValue());
116
+ * if (outcome.acquired) {
117
+ * console.log("ran, got", outcome.value);
118
+ * } else {
119
+ * console.log("skipped — someone else holds the lock");
120
+ * }
121
+ */
122
+ type LockOutcome<T> = {
123
+ acquired: true;
124
+ value: T;
125
+ } | {
126
+ acquired: false;
127
+ };
128
+ /**
129
+ * Options for `remember()` when you need more than just a TTL — e.g. attaching
130
+ * tags to the cache-miss write, or routing the single call to a non-default driver.
131
+ *
132
+ * Passed in the TTL position: `cache.remember(key, { ttl: "1h", tags: ["users"] }, fn)`.
133
+ *
134
+ * @example
135
+ * await cache.remember("user.1", { ttl: "1h", tags: ["users"] }, () =>
136
+ * db.users.find(1),
137
+ * );
138
+ */
139
+ type RememberOptions = {
140
+ /**
141
+ * TTL applied on cache miss. Accepts seconds (number) or duration string.
142
+ */
143
+ ttl?: CacheTtl;
144
+ /**
145
+ * Tags attached to the entry created on miss. Invalidate via `cache.tags([...]).invalidate()`.
146
+ */
147
+ tags?: string[];
148
+ /**
149
+ * Per-call driver override. Routes this remember call (both read and write)
150
+ * to the named driver without mutating `currentDriver`.
151
+ */
152
+ driver?: string;
153
+ };
154
+ /**
155
+ * Rich options for the `set` call-site. Mutually exclusive with a positional TTL.
156
+ *
157
+ * @example
158
+ * await cache.set("user:1", user, {
159
+ * ttl: "1h",
160
+ * tags: ["users", "active"],
161
+ * onConflict: "create",
162
+ * });
163
+ */
164
+ type CacheSetOptions = {
165
+ /**
166
+ * Relative TTL (seconds or duration string). Mutually exclusive with `expiresAt`.
167
+ */
168
+ ttl?: CacheTtl;
169
+ /**
170
+ * Absolute expiration as a Unix epoch in milliseconds or a Date. Mutually exclusive with `ttl`.
171
+ */
172
+ expiresAt?: number | Date;
173
+ /**
174
+ * Tags attached to this entry for tag-based invalidation. Inline equivalent of
175
+ * `cache.tags([...]).set(key, value)`.
176
+ */
177
+ tags?: string[];
178
+ /**
179
+ * Conflict resolution policy. Defaults to `"upsert"`.
180
+ */
181
+ onConflict?: CacheConflictPolicy;
182
+ /**
183
+ * Per-call namespace override. Applied ahead of `globalPrefix` for this write only.
184
+ */
185
+ namespace?: string;
186
+ /**
187
+ * Per-call driver override by registered name. Routes this write to a non-default driver
188
+ * without mutating `currentDriver`.
189
+ */
190
+ driver?: string;
191
+ /**
192
+ * Optional embedding vector indexed alongside the entry for similarity retrieval
193
+ * via `cache.similar(...)`. Drivers without similarity support throw
194
+ * {@link CacheUnsupportedError} when this option is supplied.
195
+ *
196
+ * Cache is embedding-agnostic — callers compute the vector with whichever embedder
197
+ * they like and pass the result here.
198
+ *
199
+ * @example
200
+ * await cache.set("doc.123", doc, { vector: await embed(doc.text), ttl: "1d" });
201
+ */
202
+ vector?: number[];
203
+ /**
204
+ * Freshness deadline as a Unix epoch in milliseconds. Primarily set by
205
+ * {@link CacheSwrOptions} flow — entries with `staleAt` in the future are
206
+ * considered "fresh" by `cache.swr()`; entries past `staleAt` but before
207
+ * `expiresAt` are "stale-but-revalidatable."
208
+ *
209
+ * Direct callers can pin this manually when bypassing `swr()`, but the
210
+ * common path is `cache.swr(key, { freshTtl, staleTtl }, fn)`.
211
+ */
212
+ staleAt?: number;
213
+ };
214
+ /**
215
+ * Options for `cache.namespace(prefix, options)` — defaults applied to every
216
+ * write produced through the returned scope.
217
+ *
218
+ * Per-call options always win over scope defaults. Tags merge additively
219
+ * (scope tags + call tags, deduped). Nested scopes inherit from the parent;
220
+ * the child's own values override.
221
+ */
222
+ type CacheNamespaceOptions = {
223
+ /**
224
+ * Default TTL for writes inside this scope. Same shape as everywhere else
225
+ * — number of seconds or a duration string (`"1h"`, `"30d"`, …).
226
+ */
227
+ ttl?: CacheTtl;
228
+ /**
229
+ * Tags auto-attached to every write inside this scope. Useful for cross-scope
230
+ * invalidation hooks (e.g. tag every entry with `user.<id>` so a single
231
+ * `cache.flushTag("user.42")` wipes the user's footprint everywhere).
232
+ *
233
+ * Merged additively with per-call tags; scope tags are never replaced.
234
+ */
235
+ tags?: string[];
236
+ };
237
+ /**
238
+ * Options for `cache.swr(key, options, callback)` — stale-while-revalidate.
239
+ *
240
+ * Two TTLs split the entry's lifecycle into three windows:
241
+ * - `now < freshTtl` → fresh, return cached value, no upstream call.
242
+ * - `freshTtl <= now < staleTtl` → stale-but-revalidatable, return cached
243
+ * value immediately, kick off `callback` in the background to refresh.
244
+ * - `now >= staleTtl` → expired, block on `callback` like a normal miss.
245
+ *
246
+ * Concurrent SWR callers in the stale window all return the cached value;
247
+ * the background refresh runs exactly once per key (deduped via the
248
+ * driver's per-key lock map).
249
+ *
250
+ * If the background refresh fails, the stale entry is preserved and the
251
+ * error is logged + emitted on the `error` event. Callers that received
252
+ * the stale value never see the failure — they got their data.
253
+ */
254
+ type CacheSwrOptions = {
255
+ /**
256
+ * How long the value is considered fresh. Within this window, SWR returns
257
+ * the cached value with no upstream call. Accepts seconds or duration
258
+ * string (`"1m"`, `"30s"`).
259
+ */
260
+ freshTtl: CacheTtl;
261
+ /**
262
+ * Total lifetime of the entry (must be greater than `freshTtl`). Between
263
+ * `freshTtl` and `staleTtl`, SWR returns the stale value and triggers a
264
+ * background refresh. Past `staleTtl`, SWR blocks and refetches.
265
+ */
266
+ staleTtl: CacheTtl;
267
+ /**
268
+ * Optional tags applied on the first miss-fetch and on every successful
269
+ * background refresh. Same semantics as `CacheSetOptions.tags`.
270
+ */
271
+ tags?: string[];
272
+ /**
273
+ * Per-call driver override by registered name. Routes both the read and
274
+ * any write/refresh through the named driver without mutating
275
+ * `currentDriver`. Same semantics as `RememberOptions.driver`.
276
+ */
277
+ driver?: string;
278
+ };
279
+ /**
280
+ * Options for `cache.similar(vector, options)` — similarity retrieval against
281
+ * stored entries previously written with `set({ vector })`.
282
+ */
283
+ type CacheSimilarOptions = {
284
+ /**
285
+ * Maximum number of hits to return. Required — no implicit default keeps
286
+ * callers from accidentally pulling the entire candidate set.
287
+ */
288
+ topK: number;
289
+ /**
290
+ * Cosine similarity floor in `[0, 1]`. Hits scoring strictly below this are
291
+ * filtered out before `topK` truncation.
292
+ */
293
+ threshold?: number;
294
+ /**
295
+ * Optional tag filter. Only entries tagged with at least one of the given
296
+ * tags are considered (matches the union semantics elsewhere in the package).
297
+ */
298
+ tags?: string[];
299
+ };
300
+ /**
301
+ * One result from a `similar()` query — the original key, its stored value,
302
+ * and the cosine similarity to the query vector.
303
+ */
304
+ type CacheSimilarHit<T = unknown> = {
305
+ /**
306
+ * The original cache key, post-`parseKey` normalization.
307
+ */
308
+ key: string;
309
+ /**
310
+ * Stored value, deep-cloned to protect the cache from accidental mutation
311
+ * (same semantics as `get`).
312
+ */
313
+ value: T;
314
+ /**
315
+ * Cosine similarity in `[0, 1]`. Higher means more similar.
316
+ */
317
+ score: number;
318
+ };
319
+ /**
320
+ * Cache key type - can be a string or an object
321
+ */
322
+ type CacheKey = string | GenericObject;
323
+ type CacheOperationType = "fetching" | "fetched" | "caching" | "cached" | "flushing" | "flushed" | "removing" | "removed" | "clearing" | "cleared" | "expired" | "notFound" | "connecting" | "error" | "connected" | "disconnecting" | "disconnected";
324
+ /**
325
+ * Cache event types for observability
326
+ */
327
+ type CacheEventType = "hit" | "miss" | "set" | "removed" | "flushed" | "expired" | "connected" | "disconnected" | "error";
328
+ /**
329
+ * Cache event data structure
330
+ */
331
+ type CacheEventData = {
332
+ /**
333
+ * The cache key involved in the event
334
+ */
335
+ key?: string;
336
+ /**
337
+ * The value (for set/hit events)
338
+ */
339
+ value?: any;
340
+ /**
341
+ * TTL in seconds (for set events)
342
+ */
343
+ ttl?: number;
344
+ /**
345
+ * Driver name that emitted the event
346
+ */
347
+ driver: string;
348
+ /**
349
+ * Error object (for error events)
350
+ */
351
+ error?: any;
352
+ /**
353
+ * Namespace (for namespace operations)
354
+ */
355
+ namespace?: string;
356
+ };
357
+ /**
358
+ * Event handler function type
359
+ */
360
+ type CacheEventHandler = (eventData: CacheEventData) => void | Promise<void>;
361
+ /**
362
+ * Per-operation latency + counter snapshot returned by `cache.metrics()`.
363
+ *
364
+ * The shape is a single recursive level — the top object covers all drivers
365
+ * and each entry under `byDriver` repeats the same fields without nesting
366
+ * further. Use this for ad-hoc dashboards, exporters to Prometheus / StatsD,
367
+ * or just `console.log` during development.
368
+ */
369
+ type CacheMetricsSnapshot = {
370
+ /** Cumulative cache hits across the lifetime of the collector. */hits: number; /** Cumulative cache misses (lookups that returned null). */
371
+ misses: number; /** Cumulative successful writes. */
372
+ sets: number; /** Cumulative key removals. */
373
+ removed: number; /** Cumulative cache errors emitted via the `error` event. */
374
+ errors: number; /** `hits / (hits + misses)` — `0` when no read ops have happened yet. */
375
+ hitRate: number; /** Latency percentiles in milliseconds, computed from a circular buffer. */
376
+ latencyMs: {
377
+ p50: number;
378
+ p95: number;
379
+ p99: number; /** Size of the underlying buffer at snapshot time (capped at the configured max). */
380
+ samples: number;
381
+ }; /** Per-driver breakdowns keyed by driver name (`"memory"`, `"redis"`, …). */
382
+ byDriver: Record<string, Omit<CacheMetricsSnapshot, "byDriver">>; /** Millisecond timestamp the collector last reset (or was instantiated). */
383
+ startedAt: number;
384
+ };
385
+ /**
386
+ * Tagged cache interface for working with cache tags
387
+ */
388
+ interface TaggedCacheDriver {
389
+ /**
390
+ * Set a value in cache with tags
391
+ */
392
+ set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;
393
+ /**
394
+ * Get a value from cache (checks tags)
395
+ */
396
+ get(key: CacheKey): Promise<any | null>;
397
+ /**
398
+ * Remove a specific key
399
+ */
400
+ remove(key: CacheKey): Promise<void>;
401
+ /**
402
+ * Invalidate (clear) all keys associated with the current tags
403
+ */
404
+ invalidate(): Promise<void>;
405
+ /**
406
+ * Flush all keys associated with the current tags
407
+ * @deprecated Use invalidate() instead
408
+ */
409
+ flush(): Promise<void>;
410
+ /**
411
+ * Check if a key exists
412
+ */
413
+ has(key: CacheKey): Promise<boolean>;
414
+ /**
415
+ * Remember pattern with tags
416
+ */
417
+ remember(key: CacheKey, ttl: number, callback: () => Promise<any>): Promise<any>;
418
+ /**
419
+ * Pull value with tags
420
+ */
421
+ pull(key: CacheKey): Promise<any | null>;
422
+ /**
423
+ * Forever with tags
424
+ */
425
+ forever(key: CacheKey, value: any): Promise<any>;
426
+ /**
427
+ * Increment with tags
428
+ */
429
+ increment(key: CacheKey, value?: number): Promise<number>;
430
+ /**
431
+ * Decrement with tags
432
+ */
433
+ decrement(key: CacheKey, value?: number): Promise<number>;
434
+ }
435
+ type MemoryCacheOptions = {
436
+ /**
437
+ * The global prefix for the cache key
438
+ */
439
+ globalPrefix?: string | (() => string);
440
+ /**
441
+ * The default TTL for the cache. Accepts a number of seconds or a human-readable
442
+ * duration string like `"1h"`, `"30m"`, `"7d"`.
443
+ *
444
+ * @default Infinity
445
+ */
446
+ ttl?: CacheTtl;
447
+ /**
448
+ * Maximum number of items in cache
449
+ * When exceeded, least recently used items will be evicted
450
+ *
451
+ * @default undefined (no limit)
452
+ */
453
+ maxSize?: number;
454
+ };
455
+ type MemoryExtendedCacheOptions = MemoryCacheOptions;
456
+ type LRUMemoryCacheOptions = {
457
+ /**
458
+ * The maximum number of items in the cache
459
+ *
460
+ * @default 1000
461
+ */
462
+ capacity?: number;
463
+ /**
464
+ * The global prefix for the cache key. Applied via `parseCacheKey`, same
465
+ * semantics as the other drivers.
466
+ */
467
+ globalPrefix?: string | (() => string);
468
+ /**
469
+ * The default TTL for new entries. Accepts a number of seconds or a
470
+ * human-readable duration string like `"1h"`, `"30m"`, `"7d"`.
471
+ *
472
+ * @default Infinity
473
+ */
474
+ ttl?: CacheTtl;
475
+ };
476
+ type FileCacheOptions = {
477
+ /**
478
+ * The global prefix for the cache key
479
+ */
480
+ globalPrefix?: string | (() => string);
481
+ /**
482
+ * The default TTL for the cache. Accepts a number of seconds or a human-readable
483
+ * duration string like `"1h"`, `"30m"`, `"7d"`.
484
+ *
485
+ * @default 0
486
+ */
487
+ ttl?: CacheTtl;
488
+ /**
489
+ * Storage cache directory
490
+ *
491
+ * @default storagePath("cache")
492
+ */
493
+ directory: string | (() => string);
494
+ /**
495
+ * File name
496
+ *
497
+ * @default cache.json
498
+ */
499
+ fileName?: string | (() => string);
500
+ };
501
+ type RedisOptions = {
502
+ /**
503
+ * Redis Port
504
+ *
505
+ * @default 6379
506
+ */
507
+ port?: number;
508
+ /**
509
+ * Redis Host
510
+ */
511
+ host?: string;
512
+ /**
513
+ * Redis Username
514
+ */
515
+ username?: string;
516
+ /**
517
+ * Redis Password
518
+ */
519
+ password?: string;
520
+ /**
521
+ * Redis URL
522
+ *
523
+ * If used, it will override the host and port options
524
+ */
525
+ url?: string;
526
+ /**
527
+ * Global prefix for the cache key
528
+ */
529
+ globalPrefix?: string | (() => string);
530
+ /**
531
+ * Default TTL. Accepts a number of seconds or a human-readable duration string
532
+ * like `"1h"`, `"30m"`, `"7d"`.
533
+ *
534
+ * @default Infinity
535
+ */
536
+ ttl?: CacheTtl;
537
+ /**
538
+ * Redis client options
539
+ */
540
+ clientOptions?: RedisClientOptions;
541
+ };
542
+ type NullCacheDriverOptions = GenericObject;
543
+ /**
544
+ * Options accepted by {@link MockCacheDriver}. Same shape as the memory
545
+ * driver — only `globalPrefix` and `ttl` apply, since the mock's storage is
546
+ * a plain `Map` with no eviction policy.
547
+ */
548
+ type MockCacheOptions = {
549
+ /**
550
+ * Global key prefix, applied via `parseKey` (matches the other drivers).
551
+ */
552
+ globalPrefix?: string | (() => string);
553
+ /**
554
+ * Default TTL for new entries. Accepts seconds or a duration string.
555
+ *
556
+ * @default Infinity
557
+ */
558
+ ttl?: CacheTtl;
559
+ };
560
+ /**
561
+ * One row in {@link MockCacheDriver.callLog} — captures every public op
562
+ * the driver received in arrival order. Useful for behavioral assertions
563
+ * in downstream tests ("did my service actually invalidate the cache?").
564
+ */
565
+ type CacheCall = {
566
+ /**
567
+ * Operation name as it appears on the driver contract — `"set"`, `"get"`,
568
+ * `"remove"`, `"flush"`, `"removeNamespace"`, `"has"`, etc.
569
+ */
570
+ operation: string;
571
+ /**
572
+ * Post-`parseKey` cache key when the op is key-addressed; `undefined` for
573
+ * keyless ops (`flush`, `connect`, `disconnect`).
574
+ */
575
+ key?: string;
576
+ /**
577
+ * Raw arguments passed to the call site, in declaration order. Lets
578
+ * callers assert on TTLs, options objects, vector payloads, etc.
579
+ */
580
+ args: unknown[];
581
+ /**
582
+ * `Date.now()` when the call was recorded. Useful for timing-related
583
+ * assertions (e.g. "the second invalidation came within 100ms").
584
+ */
585
+ timestamp: number;
586
+ };
587
+ /**
588
+ * Minimal `pg`-compatible client surface the cache driver depends on.
589
+ *
590
+ * Both `pg.Pool` and `pg.Client` from the `pg` package satisfy this — the
591
+ * driver only ever calls `query(text, values)`. Typing it loosely keeps
592
+ * `pg` strictly optional: consumers without the `pg` package installed
593
+ * never hit a missing import.
594
+ */
595
+ type PgClientLike = {
596
+ query(text: string, values?: unknown[]): Promise<{
597
+ rows: any[];
598
+ rowCount?: number | null;
599
+ }>;
600
+ };
601
+ type PgCacheOptions = {
602
+ /**
603
+ * User-supplied `pg.Pool` or `pg.Client`. The driver does NOT own the
604
+ * connection lifecycle — `cache.disconnect()` will not close this client.
605
+ */
606
+ client: PgClientLike;
607
+ /**
608
+ * Database table name. Default: `"warlock_cache"`.
609
+ *
610
+ * Sanitized: only `[A-Za-z0-9_]` are allowed; anything else throws
611
+ * {@link CacheConfigurationError} at `setOptions` time.
612
+ */
613
+ table?: string;
614
+ /**
615
+ * Global key prefix, applied via `parseKey` (same semantics as the other drivers).
616
+ */
617
+ globalPrefix?: string | (() => string);
618
+ /**
619
+ * Default TTL for new entries. Accepts seconds or a duration string
620
+ * (`"1h"`, `"7d"`, …).
621
+ *
622
+ * @default Infinity
623
+ */
624
+ ttl?: CacheTtl;
625
+ /**
626
+ * Optional pgvector configuration. When present, the driver provisions an
627
+ * `embedding VECTOR(dimensions)` column + similarity index, and `similar()`
628
+ * queries via the `<=>` cosine-distance operator.
629
+ *
630
+ * Requires the pgvector extension (`CREATE EXTENSION vector;`) — the driver
631
+ * verifies its presence on the first vector operation and throws
632
+ * {@link CacheConfigurationError} if missing.
633
+ *
634
+ * Omit this block (or remove it) to run the driver in KV-only mode —
635
+ * `set({ vector })` and `similar()` then throw {@link CacheUnsupportedError}.
636
+ */
637
+ vector?: {
638
+ /**
639
+ * Vector dimension count. Must match the embedder you use throughout the
640
+ * lifetime of the table. Mixing dimensions on the same table is unsupported.
641
+ */
642
+ dimensions: number;
643
+ /**
644
+ * pgvector index strategy. `hnsw` (default) is faster to query and slightly
645
+ * slower to build; `ivfflat` is faster to build but typically slower to query.
646
+ *
647
+ * @default "hnsw"
648
+ */
649
+ index?: "hnsw" | "ivfflat";
650
+ };
651
+ };
652
+ interface CacheDriver<ClientType, Options> {
653
+ /**
654
+ * The cache driver options
655
+ */
656
+ options: Options;
657
+ /**
658
+ * Cache driver name
659
+ */
660
+ name: string;
661
+ /**
662
+ * Set logging state
663
+ */
664
+ setLoggingState(shouldLog: boolean): any;
665
+ /**
666
+ * Remove all cached items by namespace
667
+ */
668
+ removeNamespace(namespace: string): Promise<any>;
669
+ /**
670
+ * Set the cache driver options
671
+ */
672
+ setOptions(options: Options): any;
673
+ /**
674
+ * Parse the key to be used in the cache
675
+ */
676
+ parseKey(key: CacheKey): string;
677
+ /**
678
+ * Set a value in the cache.
679
+ *
680
+ * @param key The cache key, could be an object or string
681
+ * @param value The value to be stored in the cache
682
+ * @param ttlOrOptions Either a TTL (seconds number, or duration string like `"1h"`),
683
+ * or a full {@link CacheSetOptions} object.
684
+ *
685
+ * @example
686
+ * // Positional TTL (back-compat)
687
+ * await cache.set("user:1", user, 3600);
688
+ *
689
+ * @example
690
+ * // Human-readable duration
691
+ * await cache.set("user:1", user, "1h");
692
+ *
693
+ * @example
694
+ * // Rich options
695
+ * await cache.set("user:1", user, { ttl: "1h", tags: ["users"], onConflict: "create" });
696
+ */
697
+ set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;
698
+ /**
699
+ * Get a value from the cache
700
+ */
701
+ get<T = any>(key: CacheKey): Promise<T | null>;
702
+ /**
703
+ * Remove a value from the cache
704
+ */
705
+ remove(key: CacheKey): Promise<void>;
706
+ /**
707
+ * Flush the entire cache
708
+ */
709
+ flush(): Promise<void>;
710
+ /**
711
+ * Connect to the cache driver
712
+ */
713
+ connect(): Promise<any>;
714
+ /**
715
+ * The cache client
716
+ */
717
+ client?: ClientType;
718
+ /**
719
+ * Disconnect the cache driver
720
+ */
721
+ disconnect(): Promise<void>;
722
+ /**
723
+ * Check if a key exists in the cache without fetching its value
724
+ */
725
+ has(key: CacheKey): Promise<boolean>;
726
+ /**
727
+ * Get value from cache or execute callback and cache the result.
728
+ *
729
+ * The second argument accepts a TTL (number of seconds or duration string like `"1h"`)
730
+ * or a full {@link RememberOptions} object when you need to attach tags or route to
731
+ * a non-default driver.
732
+ *
733
+ * @example
734
+ * // Positional TTL — the common case
735
+ * const user = await cache.remember("user.1", "1h", () => db.users.find(1));
736
+ *
737
+ * @example
738
+ * // Options form — tag the cache-miss write for bulk invalidation
739
+ * const user = await cache.remember("user.1", { ttl: "1h", tags: ["users"] }, () =>
740
+ * db.users.find(1),
741
+ * );
742
+ */
743
+ remember<T = any>(key: CacheKey, ttlOrOptions: CacheTtl | RememberOptions, callback: () => Promise<T>): Promise<T>;
744
+ /**
745
+ * Stale-while-revalidate. Returns the cached value when fresh; returns
746
+ * the stale value + kicks off a background refresh when within the
747
+ * `freshTtl..staleTtl` window; blocks like a normal miss when past
748
+ * `staleTtl`. Concurrent stale-window callers share one in-flight
749
+ * refresh.
750
+ *
751
+ * Background refresh failures preserve the stale entry and emit an
752
+ * `error` event — the stale-returning caller never sees the failure.
753
+ *
754
+ * @example
755
+ * const product = await cache.swr(
756
+ * "product.42",
757
+ * { freshTtl: "1m", staleTtl: "1h" },
758
+ * () => db.products.find(42),
759
+ * );
760
+ */
761
+ swr<T = any>(key: CacheKey, options: CacheSwrOptions, callback: () => Promise<T>): Promise<T>;
762
+ /**
763
+ * Get value and remove it from cache (atomic operation)
764
+ */
765
+ pull<T = any>(key: CacheKey): Promise<T | null>;
766
+ /**
767
+ * Set a value in cache permanently (no expiration)
768
+ */
769
+ forever<T = any>(key: CacheKey, value: T): Promise<T>;
770
+ /**
771
+ * Atomically read, transform, and write a cached value.
772
+ *
773
+ * The callback receives the current value (or `null` on miss) and returns the
774
+ * next value. Returning `null` removes the key. TTL is preserved unless
775
+ * explicitly overridden via options.
776
+ *
777
+ * @example
778
+ * await cache.update<User>("user:1", (current) => {
779
+ * if (!current) return null;
780
+ * return { ...current, lastSeen: Date.now() };
781
+ * });
782
+ */
783
+ update<T = any>(key: CacheKey, fn: (current: T | null) => T | null | Promise<T | null>, options?: {
784
+ ttl?: CacheTtl;
785
+ }): Promise<T | null>;
786
+ /**
787
+ * Shallow-merge a partial object into a cached value.
788
+ *
789
+ * If the key is missing, treats the current value as `{}`. Preserves TTL by default.
790
+ *
791
+ * @example
792
+ * await cache.merge<User>("user:1", { name: "Jane" });
793
+ */
794
+ merge<T extends Record<string, any> = Record<string, any>>(key: CacheKey, partial: Partial<T>, options?: {
795
+ ttl?: CacheTtl;
796
+ }): Promise<T>;
797
+ /**
798
+ * List sub-API factory — returns a {@link CacheListAccessor} bound to the given key.
799
+ *
800
+ * @example
801
+ * const recent = cache.list<Event>("recent-events");
802
+ * await recent.push(event);
803
+ * const last10 = await recent.slice(0, 10);
804
+ */
805
+ list<T = any>(key: CacheKey): CacheListAccessor<T>;
806
+ /**
807
+ * Acquire a distributed lock, run `fn`, and auto-release. Returns a
808
+ * {@link LockOutcome} so callers can distinguish "ran and produced this value"
809
+ * from "skipped because someone else holds the lock."
810
+ *
811
+ * Built on top of `set({ onConflict: "create" })` — Redis-native, emulated
812
+ * on other drivers (single-process semantics elsewhere).
813
+ *
814
+ * @example
815
+ * const outcome = await cache.lock("lock.import", "5m", async () => {
816
+ * await runImport();
817
+ * return "done";
818
+ * });
819
+ */
820
+ lock<T>(key: CacheKey, ttlOrOptions: CacheTtl | Omit<LockOptions, "driver">, fn: () => Promise<T>): Promise<LockOutcome<T>>;
821
+ /**
822
+ * Increment a numeric value in cache
823
+ *
824
+ * @param key The cache key
825
+ * @param value The value to increment by (default 1)
826
+ */
827
+ increment(key: CacheKey, value?: number): Promise<number>;
828
+ /**
829
+ * Decrement a numeric value in cache
830
+ *
831
+ * @param key The cache key
832
+ * @param value The value to decrement by (default 1)
833
+ */
834
+ decrement(key: CacheKey, value?: number): Promise<number>;
835
+ /**
836
+ * Get multiple values from cache at once
837
+ */
838
+ many(keys: CacheKey[]): Promise<any[]>;
839
+ /**
840
+ * Set multiple values in cache at once
841
+ */
842
+ setMany(items: Record<string, any>, ttl?: number): Promise<void>;
843
+ /**
844
+ * Register an event listener
845
+ */
846
+ on(event: CacheEventType, handler: CacheEventHandler): this;
847
+ /**
848
+ * Remove an event listener
849
+ */
850
+ off(event: CacheEventType, handler: CacheEventHandler): this;
851
+ /**
852
+ * Register a one-time event listener
853
+ */
854
+ once(event: CacheEventType, handler: CacheEventHandler): this;
855
+ /**
856
+ * Set if not exists (atomic operation)
857
+ * Returns true if key was set, false if key already existed
858
+ * Note: Not all drivers support this operation
859
+ */
860
+ setNX?(key: CacheKey, value: any, ttl?: number): Promise<boolean>;
861
+ /**
862
+ * Create a tagged cache instance for the given tags
863
+ */
864
+ tags(tags: string[]): TaggedCacheDriver;
865
+ /**
866
+ * Similarity retrieval. Returns the nearest stored entries to `vector` by
867
+ * cosine similarity, ordered by descending score.
868
+ *
869
+ * Drivers without a similarity index throw {@link CacheUnsupportedError}.
870
+ * Memory-family drivers brute-force scan in O(N) — suitable for development
871
+ * but not for production knowledge bases beyond a few thousand entries; use
872
+ * the `pg` driver (with pgvector) or `redis` driver (with RediSearch) instead.
873
+ *
874
+ * @example
875
+ * const hits = await cache.similar(await embed(query), { topK: 5, threshold: 0.7 });
876
+ */
877
+ similar<T = any>(vector: number[], options: CacheSimilarOptions): Promise<CacheSimilarHit<T>[]>;
878
+ }
879
+ /**
880
+ * Accessor for list-shaped cached values.
881
+ *
882
+ * Defaults to read-mutate-write semantics on non-native drivers (memory, file, LRU).
883
+ * The Redis driver overrides this with native `LPUSH` / `RPUSH` / `LRANGE` / `LTRIM` for O(1) ops.
884
+ */
885
+ interface CacheListAccessor<T = any> {
886
+ /**
887
+ * Append one or more items to the tail of the list. Returns the new length.
888
+ */
889
+ push(...items: T[]): Promise<number>;
890
+ /**
891
+ * Prepend one or more items to the head of the list. Returns the new length.
892
+ */
893
+ unshift(...items: T[]): Promise<number>;
894
+ /**
895
+ * Remove and return the tail item, or `null` if the list is empty.
896
+ */
897
+ pop(): Promise<T | null>;
898
+ /**
899
+ * Remove and return the head item, or `null` if the list is empty.
900
+ */
901
+ shift(): Promise<T | null>;
902
+ /**
903
+ * Return a slice of the list. End is exclusive, mirroring `Array.prototype.slice`.
904
+ */
905
+ slice(start?: number, end?: number): Promise<T[]>;
906
+ /**
907
+ * Return the full list.
908
+ */
909
+ all(): Promise<T[]>;
910
+ /**
911
+ * Return the length of the list.
912
+ */
913
+ length(): Promise<number>;
914
+ /**
915
+ * Trim the list to the inclusive range `[start, end]`. Outside elements are dropped.
916
+ */
917
+ trim(start: number, end: number): Promise<void>;
918
+ /**
919
+ * Remove the entire list.
920
+ */
921
+ clear(): Promise<void>;
922
+ }
923
+ /**
924
+ * One-shot tagged handle returned by `ScopedCacheContract.tags(...)`.
925
+ *
926
+ * Identical write surface to {@link TaggedCacheDriver}, except the underlying
927
+ * scope's prefix is applied to every key and the scope's default TTL/tags
928
+ * still flow through. Tags supplied here merge additively with scope-level
929
+ * tags.
930
+ */
931
+ interface TaggedScopedCacheContract {
932
+ set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;
933
+ get<T = any>(key: CacheKey): Promise<T | null>;
934
+ has(key: CacheKey): Promise<boolean>;
935
+ remove(key: CacheKey): Promise<void>;
936
+ pull<T = any>(key: CacheKey): Promise<T | null>;
937
+ forever<T = any>(key: CacheKey, value: T): Promise<T>;
938
+ setNX(key: CacheKey, value: any, ttl?: number): Promise<boolean>;
939
+ remember<T = any>(key: CacheKey, ttlOrOptions: CacheTtl | RememberOptions, callback: () => Promise<T>): Promise<T>;
940
+ increment(key: CacheKey, value?: number): Promise<number>;
941
+ decrement(key: CacheKey, value?: number): Promise<number>;
942
+ /**
943
+ * Invalidate every entry tagged with the union of scope tags + handle tags.
944
+ * Forwarded to the underlying tag index — tags are global, scope-agnostic.
945
+ */
946
+ invalidate(): Promise<void>;
947
+ }
948
+ /**
949
+ * Scoped view over the cache. Returned by `cache.namespace(prefix, options?)`.
950
+ *
951
+ * A scope prepends its `prefix` to every key, applies optional default TTL/tags
952
+ * to every write, and forwards everything else to the underlying source. It
953
+ * stores nothing of its own — purely a convenience wrapper.
954
+ *
955
+ * @example
956
+ * const chat = cache.namespace("chats.10", { ttl: "30d" });
957
+ * await chat.set("messages.1", msg); // → "chats.10.messages.1", TTL 30d
958
+ * await chat.set("draft", d, { ttl: "1h" }); // per-call ttl wins
959
+ * await chat.clear(); // wipe the whole scope
960
+ */
961
+ interface ScopedCacheContract {
962
+ /** The fully-qualified prefix this scope prepends to every key. */
963
+ readonly prefix: string;
964
+ /**
965
+ * Nested scope. Inherits the parent's defaults; child's own options override.
966
+ *
967
+ * @example
968
+ * const chat = cache.namespace("chats.10", { ttl: "30d" });
969
+ * const typing = chat.namespace("typing", { ttl: "5s" });
970
+ * // typing.prefix === "chats.10.typing"
971
+ */
972
+ namespace(prefix: string, options?: CacheNamespaceOptions): ScopedCacheContract;
973
+ /**
974
+ * One-shot tagged write handle. Tags merge additively with scope defaults.
975
+ */
976
+ tags(tags: string[]): TaggedScopedCacheContract;
977
+ /** Wipe every entry under this scope's prefix. Sugar for `removeNamespace(prefix)`. */
978
+ clear(): Promise<void>;
979
+ get<T = any>(key: CacheKey): Promise<T | null>;
980
+ has(key: CacheKey): Promise<boolean>;
981
+ many(keys: CacheKey[]): Promise<any[]>;
982
+ pull<T = any>(key: CacheKey): Promise<T | null>;
983
+ set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;
984
+ setMany(items: Record<string, any>, ttl?: number): Promise<void>;
985
+ setNX(key: CacheKey, value: any, ttl?: number): Promise<boolean>;
986
+ forever<T = any>(key: CacheKey, value: T): Promise<T>;
987
+ remove(key: CacheKey): Promise<void>;
988
+ remember<T = any>(key: CacheKey, ttlOrOptions: CacheTtl | RememberOptions, callback: () => Promise<T>): Promise<T>;
989
+ swr<T = any>(key: CacheKey, options: CacheSwrOptions, callback: () => Promise<T>): Promise<T>;
990
+ increment(key: CacheKey, value?: number): Promise<number>;
991
+ decrement(key: CacheKey, value?: number): Promise<number>;
992
+ update<T = any>(key: CacheKey, fn: (current: T | null) => T | null | Promise<T | null>, options?: {
993
+ ttl?: CacheTtl;
994
+ }): Promise<T | null>;
995
+ merge<T extends Record<string, any> = Record<string, any>>(key: CacheKey, partial: Partial<T>, options?: {
996
+ ttl?: CacheTtl;
997
+ }): Promise<T>;
998
+ list<T = any>(key: CacheKey): CacheListAccessor<T>;
999
+ lock<T>(key: CacheKey, ttlOrOptions: CacheTtl | Omit<LockOptions, "driver">, fn: () => Promise<T>): Promise<LockOutcome<T>>;
1000
+ similar<T = any>(vector: number[], options: CacheSimilarOptions): Promise<CacheSimilarHit<T>[]>;
1001
+ }
1002
+ type CacheData = {
1003
+ /**
1004
+ * Value stored in the cache
1005
+ */
1006
+ data: any;
1007
+ /**
1008
+ * The expiration date in milliseconds
1009
+ */
1010
+ expiresAt?: number;
1011
+ /**
1012
+ * Time to live in seconds
1013
+ */
1014
+ ttl?: number;
1015
+ /**
1016
+ * Freshness deadline as a millisecond timestamp. Used by `swr()` — entries
1017
+ * with `staleAt` in the future are "fresh"; past `staleAt` but before
1018
+ * `expiresAt` are "stale-but-revalidatable" and trigger a background
1019
+ * refresh on the next read. Optional — entries written through plain
1020
+ * `set()` skip this field entirely and `swr()` treats them as always-fresh.
1021
+ */
1022
+ staleAt?: number;
1023
+ };
1024
+ type DriverClass = new () => CacheDriver<any, any>;
1025
+ type DefaultDrivers = "redis" | "file" | "memory" | "memoryExtended" | "null" | "lru" | "pg" | "mock";
1026
+ type MergeWithDefaultDrivers<T> = T extends undefined ? DefaultDrivers : DefaultDrivers | T;
1027
+ type CacheConfigurations<T extends string | undefined = undefined, DriverName = MergeWithDefaultDrivers<T>> = {
1028
+ /**
1029
+ * The default cache driver name
1030
+ */
1031
+ default?: DriverName;
1032
+ /**
1033
+ * Determine whether to log or not
1034
+ *
1035
+ * @default true
1036
+ */
1037
+ logging?: boolean;
1038
+ /**
1039
+ * The cache drivers list
1040
+ */
1041
+ drivers: {
1042
+ redis?: typeof RedisCacheDriver;
1043
+ file?: typeof FileCacheDriver;
1044
+ null?: typeof NullCacheDriver;
1045
+ memory?: typeof MemoryCacheDriver;
1046
+ memoryExtended?: typeof MemoryExtendedCacheDriver;
1047
+ lru?: typeof LRUMemoryCacheDriver;
1048
+ pg?: typeof PgCacheDriver;
1049
+ mock?: typeof MockCacheDriver;
1050
+ } & { [key in Extract<T, string>]?: typeof BaseCacheDriver<any, any> | undefined };
1051
+ /**
1052
+ * The cache driver options
1053
+ */
1054
+ options: {
1055
+ redis?: RedisOptions;
1056
+ file?: FileCacheOptions;
1057
+ memory?: MemoryCacheOptions;
1058
+ memoryExtended?: MemoryExtendedCacheOptions;
1059
+ null?: NullCacheDriverOptions;
1060
+ lru?: LRUMemoryCacheOptions;
1061
+ pg?: PgCacheOptions;
1062
+ mock?: MockCacheOptions;
1063
+ } & { [key in Extract<T, string>]?: GenericObject };
1064
+ };
1065
+ //#endregion
1066
+ export { CacheCall, CacheConcurrencyError, CacheConfigurationError, CacheConfigurations, CacheConflictPolicy, CacheConnectionError, CacheData, CacheDriver, CacheDriverNotInitializedError, CacheError, CacheEventData, CacheEventHandler, CacheEventType, CacheKey, CacheListAccessor, CacheMetricsSnapshot, CacheNamespaceOptions, CacheOperationType, CacheSetOptions, CacheSetResult, CacheSimilarHit, CacheSimilarOptions, CacheSwrOptions, CacheTtl, CacheUnsupportedError, DriverClass, FileCacheOptions, LRUMemoryCacheOptions, LockOptions, LockOutcome, MemoryCacheOptions, MemoryExtendedCacheOptions, MockCacheOptions, NullCacheDriverOptions, PgCacheOptions, PgClientLike, RedisOptions, RememberOptions, ScopedCacheContract, TaggedCacheDriver, TaggedScopedCacheContract };
1067
+ //# sourceMappingURL=types.d.mts.map