@gravito/stasis 3.0.1 → 3.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.
- package/README.md +54 -64
- package/README.zh-TW.md +62 -24
- package/dist/index.cjs +2046 -129
- package/dist/index.d.cts +2360 -335
- package/dist/index.d.ts +2360 -335
- package/dist/index.js +2032 -129
- package/package.json +13 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Error thrown when a lock cannot be acquired within the specified timeout.
|
|
5
5
|
*
|
|
6
|
+
* This error indicates that the maximum waiting time for a distributed lock
|
|
7
|
+
* has been exceeded without successfully gaining ownership.
|
|
8
|
+
*
|
|
6
9
|
* @public
|
|
7
10
|
* @since 3.0.0
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* try {
|
|
15
|
+
* await cache.lock('resource', 10).block(5, async () => {
|
|
16
|
+
* // ...
|
|
17
|
+
* });
|
|
18
|
+
* } catch (error) {
|
|
19
|
+
* if (error instanceof LockTimeoutError) {
|
|
20
|
+
* console.error('Failed to acquire lock within 5 seconds');
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
8
24
|
*/
|
|
9
25
|
declare class LockTimeoutError extends Error {
|
|
10
26
|
name: string;
|
|
@@ -12,212 +28,515 @@ declare class LockTimeoutError extends Error {
|
|
|
12
28
|
/**
|
|
13
29
|
* Interface for a cache-backed distributed lock.
|
|
14
30
|
*
|
|
31
|
+
* A distributed lock ensures mutual exclusion across multiple processes or
|
|
32
|
+
* instances by using a shared cache as the synchronization primitive.
|
|
33
|
+
*
|
|
15
34
|
* @public
|
|
16
35
|
* @since 3.0.0
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const lock = cache.lock('process', 60);
|
|
40
|
+
* const result = await lock.block(10, async () => {
|
|
41
|
+
* // Exclusive work
|
|
42
|
+
* return 42;
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
17
45
|
*/
|
|
18
46
|
interface CacheLock {
|
|
19
47
|
/**
|
|
20
|
-
* Attempt to acquire the lock.
|
|
48
|
+
* Attempt to acquire the lock immediately.
|
|
49
|
+
*
|
|
50
|
+
* Uses an atomic "set if not exists" operation in the underlying cache
|
|
51
|
+
* to ensure only one owner can hold the lock at a time.
|
|
21
52
|
*
|
|
22
|
-
* @returns `true` if acquired, `false`
|
|
53
|
+
* @returns `true` if the lock was successfully acquired, `false` if it is already held.
|
|
54
|
+
* @throws {Error} If the underlying cache store fails.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const acquired = await lock.acquire();
|
|
59
|
+
* if (acquired) {
|
|
60
|
+
* try {
|
|
61
|
+
* // Critical section
|
|
62
|
+
* } finally {
|
|
63
|
+
* await lock.release();
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
23
67
|
*/
|
|
24
68
|
acquire(): Promise<boolean>;
|
|
25
69
|
/**
|
|
26
70
|
* Release the lock.
|
|
71
|
+
*
|
|
72
|
+
* Removes the lock entry from the cache, allowing other processes to acquire it.
|
|
73
|
+
* Should typically be called in a `finally` block to ensure the lock is not leaked.
|
|
74
|
+
*
|
|
75
|
+
* @returns A promise that resolves when the lock is released.
|
|
76
|
+
* @throws {Error} If the underlying cache store fails.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* await lock.release();
|
|
81
|
+
* ```
|
|
27
82
|
*/
|
|
28
83
|
release(): Promise<void>;
|
|
29
84
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
85
|
+
* Extend the lock's time-to-live (TTL).
|
|
86
|
+
*
|
|
87
|
+
* Increases the expiration time of the lock to prevent it from being
|
|
88
|
+
* automatically released while a long-running task is still in progress.
|
|
89
|
+
*
|
|
90
|
+
* @param seconds - Duration in seconds to add to the current TTL.
|
|
91
|
+
* @returns `true` if the lock was extended (still owned by this process), `false` otherwise.
|
|
92
|
+
* @throws {Error} If the underlying cache store fails.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const extended = await lock.extend(30);
|
|
97
|
+
* if (!extended) {
|
|
98
|
+
* throw new Error('Lock lost or expired before extension');
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
extend?(seconds: number): Promise<boolean>;
|
|
103
|
+
/**
|
|
104
|
+
* Get the remaining time-to-live for the lock.
|
|
32
105
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* @
|
|
36
|
-
* @
|
|
37
|
-
*
|
|
106
|
+
* Useful for monitoring or determining if a lock extension is necessary.
|
|
107
|
+
*
|
|
108
|
+
* @returns Remaining TTL in seconds. Returns -1 if the lock doesn't exist, or -2 if it has no TTL.
|
|
109
|
+
* @throws {Error} If the underlying cache store fails.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const ttl = await lock.getRemainingTime();
|
|
114
|
+
* if (ttl > 0 && ttl < 5) {
|
|
115
|
+
* await lock.extend(10);
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
getRemainingTime?(): Promise<number>;
|
|
120
|
+
/**
|
|
121
|
+
* Attempt to acquire the lock and execute a callback with automatic retry.
|
|
122
|
+
*
|
|
123
|
+
* If the lock is currently held, this method will poll the cache at regular
|
|
124
|
+
* intervals until the lock is acquired or the timeout is reached.
|
|
125
|
+
*
|
|
126
|
+
* @param seconds - Maximum duration to wait for the lock in seconds.
|
|
127
|
+
* @param callback - Logic to execute once the lock is successfully acquired.
|
|
128
|
+
* @param options - Configuration for polling and retry behavior.
|
|
129
|
+
* @returns The value returned by the callback.
|
|
130
|
+
* @throws {LockTimeoutError} If the lock cannot be acquired within the specified timeout.
|
|
131
|
+
* @throws {Error} If the callback throws or the cache store fails.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const result = await lock.block(10, async () => {
|
|
136
|
+
* return await performAtomicOperation();
|
|
137
|
+
* });
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
block<T>(seconds: number, callback: () => Promise<T> | T, options?: BlockOptions): Promise<T>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Configuration for the `block()` method's retry logic.
|
|
144
|
+
*
|
|
145
|
+
* Defines how the lock acquisition should behave when the lock is already held,
|
|
146
|
+
* including polling intervals and cancellation support.
|
|
147
|
+
*
|
|
148
|
+
* @public
|
|
149
|
+
* @since 3.1.0
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const options: BlockOptions = {
|
|
154
|
+
* retryInterval: 250,
|
|
155
|
+
* maxRetries: 10
|
|
156
|
+
* };
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
interface BlockOptions {
|
|
160
|
+
/**
|
|
161
|
+
* Delay between consecutive acquisition attempts.
|
|
162
|
+
* @defaultValue 100
|
|
163
|
+
*/
|
|
164
|
+
retryInterval?: number;
|
|
165
|
+
/**
|
|
166
|
+
* Maximum number of times to attempt acquisition before failing.
|
|
167
|
+
* @defaultValue Infinity
|
|
168
|
+
*/
|
|
169
|
+
maxRetries?: number;
|
|
170
|
+
/**
|
|
171
|
+
* Signal to allow external cancellation of the waiting process.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const controller = new AbortController();
|
|
176
|
+
* setTimeout(() => controller.abort(), 2000);
|
|
177
|
+
* await lock.block(10, task, { signal: controller.signal });
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
signal?: AbortSignal;
|
|
181
|
+
/**
|
|
182
|
+
* @deprecated Use `retryInterval` instead.
|
|
38
183
|
*/
|
|
39
|
-
|
|
40
|
-
sleepMillis?: number;
|
|
41
|
-
}): Promise<T>;
|
|
184
|
+
sleepMillis?: number;
|
|
42
185
|
}
|
|
43
186
|
/**
|
|
44
|
-
* Pause execution for a specified
|
|
187
|
+
* Pause execution for a specified duration.
|
|
45
188
|
*
|
|
46
|
-
*
|
|
189
|
+
* Internal utility used for implementing polling delays in lock acquisition.
|
|
190
|
+
*
|
|
191
|
+
* @param ms - Duration to pause in milliseconds.
|
|
192
|
+
* @returns A promise that resolves after the delay.
|
|
47
193
|
* @internal
|
|
48
194
|
*/
|
|
49
195
|
declare function sleep(ms: number): Promise<void>;
|
|
50
196
|
|
|
51
197
|
/**
|
|
52
|
-
*
|
|
198
|
+
* Unique identifier for a cached item.
|
|
199
|
+
*
|
|
200
|
+
* Used to reference and retrieve specific data entries within the cache storage.
|
|
53
201
|
*
|
|
54
202
|
* @public
|
|
55
203
|
* @since 3.0.0
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```typescript
|
|
207
|
+
* const key: CacheKey = 'user:123:profile';
|
|
208
|
+
* ```
|
|
56
209
|
*/
|
|
57
210
|
type CacheKey = string;
|
|
58
211
|
/**
|
|
59
212
|
* Time-to-live (TTL) configuration for cache entries.
|
|
60
213
|
*
|
|
61
|
-
*
|
|
62
|
-
* - `
|
|
63
|
-
* - `
|
|
64
|
-
* - `
|
|
214
|
+
* Defines the duration or point in time when a cache entry becomes invalid.
|
|
215
|
+
* - `number`: Relative duration in seconds from the current time.
|
|
216
|
+
* - `Date`: Absolute point in time for expiration.
|
|
217
|
+
* - `null`: Persistent storage that never expires automatically.
|
|
218
|
+
* - `undefined`: Fallback to the default TTL configured in the store or repository.
|
|
65
219
|
*
|
|
66
220
|
* @public
|
|
67
221
|
* @since 3.0.0
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* const ttl: CacheTtl = 3600; // 1 hour
|
|
226
|
+
* const absoluteTtl: CacheTtl = new Date('2026-12-31');
|
|
227
|
+
* ```
|
|
68
228
|
*/
|
|
69
229
|
type CacheTtl = number | Date | null | undefined;
|
|
70
230
|
/**
|
|
71
|
-
* Result of a cache retrieval.
|
|
72
|
-
*
|
|
231
|
+
* Result of a cache retrieval operation.
|
|
232
|
+
*
|
|
233
|
+
* Represents the cached data of type `T`, or `null` if the entry is missing or has expired.
|
|
73
234
|
*
|
|
74
235
|
* @public
|
|
75
236
|
* @since 3.0.0
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* const val: CacheValue<string> = 'cached content';
|
|
241
|
+
* const miss: CacheValue<number> = null;
|
|
242
|
+
* ```
|
|
76
243
|
*/
|
|
77
244
|
type CacheValue<T = unknown> = T | null;
|
|
78
245
|
/**
|
|
79
|
-
*
|
|
246
|
+
* Validates and prepares a cache key for storage operations.
|
|
247
|
+
*
|
|
248
|
+
* Ensures the key meets the minimum requirements for cache storage, such as being non-empty.
|
|
80
249
|
*
|
|
81
|
-
* @param key - The raw cache key.
|
|
82
|
-
* @returns The
|
|
83
|
-
* @throws {Error}
|
|
250
|
+
* @param key - The raw string to be used as a cache key.
|
|
251
|
+
* @returns The validated cache key.
|
|
252
|
+
* @throws {Error} Thrown if the provided key is an empty string or falsy.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```typescript
|
|
256
|
+
* const key = normalizeCacheKey('user_profile_123');
|
|
257
|
+
* ```
|
|
84
258
|
*
|
|
85
259
|
* @public
|
|
86
260
|
* @since 3.0.0
|
|
87
261
|
*/
|
|
88
262
|
declare function normalizeCacheKey(key: string): string;
|
|
89
263
|
/**
|
|
90
|
-
*
|
|
264
|
+
* Converts a flexible TTL definition into an absolute Unix epoch timestamp.
|
|
91
265
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
266
|
+
* Normalizes various TTL formats into a consistent millisecond-based timestamp
|
|
267
|
+
* used for expiration checks.
|
|
268
|
+
*
|
|
269
|
+
* @param ttl - The TTL configuration to convert.
|
|
270
|
+
* @param now - Reference timestamp in milliseconds for relative calculations. Defaults to current time.
|
|
271
|
+
* @returns The expiration timestamp in milliseconds, `null` for permanent storage, or `undefined` for default behavior.
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```typescript
|
|
275
|
+
* // Relative TTL (60 seconds)
|
|
276
|
+
* const expiresAt = ttlToExpiresAt(60);
|
|
277
|
+
*
|
|
278
|
+
* // Absolute Date
|
|
279
|
+
* const expiresAtDate = ttlToExpiresAt(new Date('2026-12-31'));
|
|
280
|
+
* ```
|
|
95
281
|
*
|
|
96
282
|
* @public
|
|
97
283
|
* @since 3.0.0
|
|
98
284
|
*/
|
|
99
285
|
declare function ttlToExpiresAt(ttl: CacheTtl, now?: number): number | null | undefined;
|
|
100
286
|
/**
|
|
101
|
-
*
|
|
287
|
+
* Evaluates whether a cache entry has exceeded its expiration time.
|
|
288
|
+
*
|
|
289
|
+
* Compares the provided expiration timestamp against a reference time to determine
|
|
290
|
+
* if the cached data should be considered stale.
|
|
291
|
+
*
|
|
292
|
+
* @param expiresAt - The expiration timestamp in milliseconds, or `null`/`undefined` for non-expiring entries.
|
|
293
|
+
* @param now - Reference timestamp in milliseconds for the comparison. Defaults to current time.
|
|
294
|
+
* @returns `true` if the current time has passed the expiration point; otherwise `false`.
|
|
102
295
|
*
|
|
103
|
-
* @
|
|
104
|
-
*
|
|
105
|
-
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```typescript
|
|
298
|
+
* const expired = isExpired(Date.now() - 1000); // true
|
|
299
|
+
* const persistent = isExpired(null); // false
|
|
300
|
+
* ```
|
|
106
301
|
*
|
|
107
302
|
* @public
|
|
108
303
|
* @since 3.0.0
|
|
109
304
|
*/
|
|
110
305
|
declare function isExpired(expiresAt: number | null | undefined, now?: number): boolean;
|
|
306
|
+
/**
|
|
307
|
+
* Options for data compression within the cache.
|
|
308
|
+
*
|
|
309
|
+
* Defines how and when data should be compressed before storage to save space
|
|
310
|
+
* and reduce I/O overhead.
|
|
311
|
+
*
|
|
312
|
+
* @public
|
|
313
|
+
* @since 3.1.0
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```typescript
|
|
317
|
+
* const options: CompressionOptions = {
|
|
318
|
+
* enabled: true,
|
|
319
|
+
* minSize: 2048,
|
|
320
|
+
* level: 9
|
|
321
|
+
* };
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
type CompressionOptions = {
|
|
325
|
+
/**
|
|
326
|
+
* Whether to enable compression for cached values.
|
|
327
|
+
*
|
|
328
|
+
* @defaultValue false
|
|
329
|
+
*/
|
|
330
|
+
enabled: boolean;
|
|
331
|
+
/**
|
|
332
|
+
* Minimum size in bytes for the value to be compressed.
|
|
333
|
+
* Values smaller than this threshold will be stored uncompressed.
|
|
334
|
+
*
|
|
335
|
+
* @defaultValue 1024
|
|
336
|
+
*/
|
|
337
|
+
minSize?: number;
|
|
338
|
+
/**
|
|
339
|
+
* Compression level for zlib (1-9).
|
|
340
|
+
* Higher levels provide better compression but require more CPU.
|
|
341
|
+
*
|
|
342
|
+
* @defaultValue 6
|
|
343
|
+
*/
|
|
344
|
+
level?: number;
|
|
345
|
+
};
|
|
111
346
|
|
|
112
347
|
/**
|
|
113
|
-
*
|
|
348
|
+
* Low-level cache storage contract.
|
|
114
349
|
*
|
|
115
|
-
*
|
|
350
|
+
* Defines the essential operations for cache backends. Implementations of this interface
|
|
351
|
+
* (e.g., Memory, Redis, File) provide the actual persistence logic for the cache system.
|
|
116
352
|
*
|
|
117
353
|
* @public
|
|
118
354
|
* @since 3.0.0
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```typescript
|
|
358
|
+
* class MyStore implements CacheStore {
|
|
359
|
+
* async get(key) { ... }
|
|
360
|
+
* async put(key, value, ttl) { ... }
|
|
361
|
+
* // ... other methods
|
|
362
|
+
* }
|
|
363
|
+
* ```
|
|
119
364
|
*/
|
|
120
365
|
interface CacheStore {
|
|
121
366
|
/**
|
|
122
|
-
* Retrieve an item from the cache
|
|
367
|
+
* Retrieve an item from the cache.
|
|
123
368
|
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
369
|
+
* Fetches the value associated with the given key. If the item has expired or does not exist,
|
|
370
|
+
* the implementation should return null.
|
|
371
|
+
*
|
|
372
|
+
* @param key - Unique identifier for the cached item.
|
|
373
|
+
* @returns The cached value or null if missing/expired.
|
|
374
|
+
* @throws {Error} If the storage backend is unreachable or encounters a read failure.
|
|
126
375
|
*/
|
|
127
376
|
get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
|
|
128
377
|
/**
|
|
129
|
-
* Store an item in the cache
|
|
378
|
+
* Store an item in the cache.
|
|
130
379
|
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* @param
|
|
380
|
+
* Persists a value with a specific expiration time. Overwrites any existing value for the same key.
|
|
381
|
+
*
|
|
382
|
+
* @param key - Unique identifier for the cached item.
|
|
383
|
+
* @param value - Data to be persisted.
|
|
384
|
+
* @param ttl - Duration in seconds until the item expires.
|
|
385
|
+
* @returns Resolves when the write operation completes.
|
|
386
|
+
* @throws {Error} If the storage backend is full or encounters a write failure.
|
|
134
387
|
*/
|
|
135
388
|
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
136
389
|
/**
|
|
137
|
-
* Store an item
|
|
390
|
+
* Store an item if it does not already exist.
|
|
138
391
|
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* @param
|
|
142
|
-
* @
|
|
392
|
+
* Atomic operation to ensure a value is only stored if the key is currently vacant.
|
|
393
|
+
*
|
|
394
|
+
* @param key - Unique identifier for the cached item.
|
|
395
|
+
* @param value - Data to be persisted.
|
|
396
|
+
* @param ttl - Duration in seconds until the item expires.
|
|
397
|
+
* @returns True if the item was successfully added, false if it already existed.
|
|
398
|
+
* @throws {Error} If the storage backend encounters a concurrency or write failure.
|
|
143
399
|
*/
|
|
144
400
|
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
145
401
|
/**
|
|
146
|
-
* Remove an item from the cache
|
|
402
|
+
* Remove an item from the cache.
|
|
147
403
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
404
|
+
* Deletes the entry associated with the specified key.
|
|
405
|
+
*
|
|
406
|
+
* @param key - Identifier of the item to be removed.
|
|
407
|
+
* @returns True if the item existed and was removed, false otherwise.
|
|
408
|
+
* @throws {Error} If the storage backend encounters a deletion failure.
|
|
150
409
|
*/
|
|
151
410
|
forget(key: CacheKey): Promise<boolean>;
|
|
152
411
|
/**
|
|
153
|
-
*
|
|
412
|
+
* Wipe all items from the cache storage.
|
|
413
|
+
*
|
|
414
|
+
* Clears the entire cache backend. Use with caution as this operation is destructive.
|
|
415
|
+
*
|
|
416
|
+
* @returns Resolves when the flush operation completes.
|
|
417
|
+
* @throws {Error} If the storage backend fails to clear the data.
|
|
154
418
|
*/
|
|
155
419
|
flush(): Promise<void>;
|
|
156
420
|
/**
|
|
157
|
-
* Increment
|
|
421
|
+
* Increment a numeric value in the cache.
|
|
158
422
|
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
423
|
+
* Atomically increases the value of a numeric item. If the key does not exist,
|
|
424
|
+
* it is typically initialized to zero before incrementing.
|
|
425
|
+
*
|
|
426
|
+
* @param key - Identifier of the numeric item.
|
|
427
|
+
* @param value - Amount to add to the current value.
|
|
428
|
+
* @returns The updated numeric value.
|
|
429
|
+
* @throws {TypeError} If the existing value is not numeric.
|
|
430
|
+
* @throws {Error} If the storage backend encounters an atomic update failure.
|
|
162
431
|
*/
|
|
163
432
|
increment(key: CacheKey, value?: number): Promise<number>;
|
|
164
433
|
/**
|
|
165
|
-
* Decrement
|
|
434
|
+
* Decrement a numeric value in the cache.
|
|
166
435
|
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
436
|
+
* Atomically decreases the value of a numeric item. If the key does not exist,
|
|
437
|
+
* it is typically initialized to zero before decrementing.
|
|
438
|
+
*
|
|
439
|
+
* @param key - Identifier of the numeric item.
|
|
440
|
+
* @param value - Amount to subtract from the current value.
|
|
441
|
+
* @returns The updated numeric value.
|
|
442
|
+
* @throws {TypeError} If the existing value is not numeric.
|
|
443
|
+
* @throws {Error} If the storage backend encounters an atomic update failure.
|
|
170
444
|
*/
|
|
171
445
|
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
172
446
|
/**
|
|
173
|
-
*
|
|
447
|
+
* Create a distributed lock instance.
|
|
174
448
|
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
449
|
+
* Provides a mechanism for mutual exclusion across multiple processes or servers
|
|
450
|
+
* using the cache backend as the synchronization provider.
|
|
451
|
+
*
|
|
452
|
+
* @param name - Unique name for the lock.
|
|
453
|
+
* @param seconds - Default duration for which the lock should be held.
|
|
454
|
+
* @returns A lock instance if supported by the driver, otherwise undefined.
|
|
178
455
|
*/
|
|
179
456
|
lock?(name: string, seconds?: number): CacheLock | undefined;
|
|
457
|
+
/**
|
|
458
|
+
* Get the remaining lifetime of a cached item.
|
|
459
|
+
*
|
|
460
|
+
* Calculates how many seconds are left before the item expires.
|
|
461
|
+
*
|
|
462
|
+
* @param key - Identifier of the cached item.
|
|
463
|
+
* @returns Seconds remaining until expiration, or null if the key has no TTL or does not exist.
|
|
464
|
+
* @throws {Error} If the storage backend encounters a read failure.
|
|
465
|
+
*/
|
|
466
|
+
ttl?(key: CacheKey): Promise<number | null>;
|
|
180
467
|
}
|
|
181
468
|
/**
|
|
182
|
-
*
|
|
469
|
+
* Contract for cache stores supporting tag-based invalidation.
|
|
470
|
+
*
|
|
471
|
+
* Allows grouping cache entries under one or more tags, enabling bulk invalidation
|
|
472
|
+
* of related items without knowing their individual keys.
|
|
183
473
|
*
|
|
184
474
|
* @public
|
|
185
475
|
* @since 3.0.0
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* ```typescript
|
|
479
|
+
* if (isTaggableStore(store)) {
|
|
480
|
+
* await store.flushTags(['users']);
|
|
481
|
+
* }
|
|
482
|
+
* ```
|
|
186
483
|
*/
|
|
187
484
|
interface TaggableStore {
|
|
188
485
|
/**
|
|
189
|
-
*
|
|
486
|
+
* Invalidate all items associated with specific tags.
|
|
190
487
|
*
|
|
191
|
-
*
|
|
488
|
+
* Effectively clears all cache entries that were stored with any of the provided tags.
|
|
489
|
+
*
|
|
490
|
+
* @param tags - List of tags to be flushed.
|
|
491
|
+
* @returns Resolves when the tag invalidation completes.
|
|
492
|
+
* @throws {Error} If the storage backend fails to process the tag flush.
|
|
192
493
|
*/
|
|
193
494
|
flushTags(tags: readonly string[]): Promise<void>;
|
|
194
495
|
/**
|
|
195
|
-
*
|
|
496
|
+
* Compute a namespaced key based on tags.
|
|
196
497
|
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
498
|
+
* Generates a unique internal key that incorporates tag versioning to ensure
|
|
499
|
+
* proper isolation and invalidation.
|
|
500
|
+
*
|
|
501
|
+
* @param key - Original user-provided cache key.
|
|
502
|
+
* @param tags - Tags to associate with the key.
|
|
503
|
+
* @returns A derived key string used for actual storage.
|
|
200
504
|
*/
|
|
201
505
|
tagKey(key: string, tags: readonly string[]): string;
|
|
202
506
|
/**
|
|
203
|
-
*
|
|
507
|
+
* Register a key in the tag index.
|
|
204
508
|
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
509
|
+
* Maintains the relationship between tags and their associated keys for tracking.
|
|
510
|
+
*
|
|
511
|
+
* @param tags - Tags to index the key under.
|
|
512
|
+
* @param taggedKey - The derived key to be indexed.
|
|
513
|
+
* @returns Resolves when the indexing completes.
|
|
207
514
|
*/
|
|
208
|
-
tagIndexAdd(tags: readonly string[], taggedKey: string): void
|
|
515
|
+
tagIndexAdd(tags: readonly string[], taggedKey: string): void | Promise<void>;
|
|
209
516
|
/**
|
|
210
|
-
*
|
|
517
|
+
* Unregister a key from all tag indexes.
|
|
518
|
+
*
|
|
519
|
+
* Removes the tracking information for a specific derived key.
|
|
211
520
|
*
|
|
212
|
-
* @param taggedKey - The key to remove from
|
|
521
|
+
* @param taggedKey - The derived key to remove from indexes.
|
|
522
|
+
* @returns Resolves when the removal completes.
|
|
213
523
|
*/
|
|
214
|
-
tagIndexRemove(taggedKey: string): void
|
|
524
|
+
tagIndexRemove(taggedKey: string): void | Promise<void>;
|
|
215
525
|
}
|
|
216
526
|
/**
|
|
217
|
-
*
|
|
527
|
+
* Validates if a cache store supports tagging operations.
|
|
528
|
+
*
|
|
529
|
+
* Performs a runtime check to determine if the provided store implements the `TaggableStore` interface.
|
|
218
530
|
*
|
|
219
|
-
* @param store - The cache store instance to
|
|
220
|
-
* @returns
|
|
531
|
+
* @param store - The cache store instance to evaluate.
|
|
532
|
+
* @returns True if the store supports tagging, false otherwise.
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```typescript
|
|
536
|
+
* if (isTaggableStore(myStore)) {
|
|
537
|
+
* await myStore.flushTags(['users', 'posts']);
|
|
538
|
+
* }
|
|
539
|
+
* ```
|
|
221
540
|
*
|
|
222
541
|
* @public
|
|
223
542
|
* @since 3.0.0
|
|
@@ -227,15 +546,33 @@ declare function isTaggableStore(store: CacheStore): store is CacheStore & Tagga
|
|
|
227
546
|
/**
|
|
228
547
|
* Supported modes for emitting cache events.
|
|
229
548
|
*
|
|
549
|
+
* Defines how lifecycle hooks (hit, miss, write, etc.) are dispatched to handlers.
|
|
550
|
+
*
|
|
230
551
|
* @public
|
|
231
552
|
* @since 3.0.0
|
|
553
|
+
*
|
|
554
|
+
* @example
|
|
555
|
+
* ```typescript
|
|
556
|
+
* const mode: CacheEventMode = 'async';
|
|
557
|
+
* ```
|
|
232
558
|
*/
|
|
233
559
|
type CacheEventMode = 'sync' | 'async' | 'off';
|
|
234
560
|
/**
|
|
235
561
|
* Event handlers for cache lifecycle events.
|
|
236
562
|
*
|
|
563
|
+
* Provides a contract for reacting to cache operations, enabling logging,
|
|
564
|
+
* monitoring, or custom side effects.
|
|
565
|
+
*
|
|
237
566
|
* @public
|
|
238
567
|
* @since 3.0.0
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```typescript
|
|
571
|
+
* const events: CacheEvents = {
|
|
572
|
+
* hit: (key) => console.log(`Cache hit: ${key}`),
|
|
573
|
+
* miss: (key) => console.log(`Cache miss: ${key}`)
|
|
574
|
+
* };
|
|
575
|
+
* ```
|
|
239
576
|
*/
|
|
240
577
|
type CacheEvents = {
|
|
241
578
|
/** Triggered on a cache hit. */
|
|
@@ -252,8 +589,20 @@ type CacheEvents = {
|
|
|
252
589
|
/**
|
|
253
590
|
* Options for configuring the `CacheRepository`.
|
|
254
591
|
*
|
|
592
|
+
* Controls behavior such as key prefixing, event emission, and background
|
|
593
|
+
* refresh strategies for flexible caching.
|
|
594
|
+
*
|
|
255
595
|
* @public
|
|
256
596
|
* @since 3.0.0
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
* ```typescript
|
|
600
|
+
* const options: CacheRepositoryOptions = {
|
|
601
|
+
* prefix: 'v1:',
|
|
602
|
+
* defaultTtl: 3600,
|
|
603
|
+
* eventsMode: 'async'
|
|
604
|
+
* };
|
|
605
|
+
* ```
|
|
257
606
|
*/
|
|
258
607
|
type CacheRepositoryOptions = {
|
|
259
608
|
/** Optional prefix for all cache keys. */
|
|
@@ -262,24 +611,64 @@ type CacheRepositoryOptions = {
|
|
|
262
611
|
defaultTtl?: CacheTtl;
|
|
263
612
|
/** Event handlers for cache operations. */
|
|
264
613
|
events?: CacheEvents;
|
|
265
|
-
/** Mode for emitting events (sync, async, or off).
|
|
614
|
+
/** Mode for emitting events (sync, async, or off). */
|
|
266
615
|
eventsMode?: CacheEventMode;
|
|
267
|
-
/** Whether to throw an error if an event handler fails. @
|
|
616
|
+
/** Whether to throw an error if an event handler fails. @defaultValue false */
|
|
268
617
|
throwOnEventError?: boolean;
|
|
269
618
|
/** Callback triggered when an event handler encounters an error. */
|
|
270
619
|
onEventError?: (error: unknown, event: keyof CacheEvents, payload: {
|
|
271
620
|
key?: string;
|
|
272
621
|
}) => void;
|
|
622
|
+
/** Timeout for background flexible refresh in milliseconds. @defaultValue 30000 */
|
|
623
|
+
refreshTimeout?: number;
|
|
624
|
+
/**
|
|
625
|
+
* Maximum number of retries for the background flexible refresh callback.
|
|
626
|
+
* @defaultValue 0
|
|
627
|
+
*/
|
|
628
|
+
maxRetries?: number;
|
|
629
|
+
/**
|
|
630
|
+
* Delay between retries for flexible refresh in milliseconds.
|
|
631
|
+
* @defaultValue 50
|
|
632
|
+
*/
|
|
633
|
+
retryDelay?: number;
|
|
634
|
+
/**
|
|
635
|
+
* Compression settings for cached values.
|
|
636
|
+
*
|
|
637
|
+
* @since 3.1.0
|
|
638
|
+
*/
|
|
639
|
+
compression?: CompressionOptions;
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* Statistics for flexible cache operations.
|
|
643
|
+
*
|
|
644
|
+
* Tracks the performance and reliability of background refresh operations
|
|
645
|
+
* used in stale-while-revalidate patterns.
|
|
646
|
+
*
|
|
647
|
+
* @public
|
|
648
|
+
* @since 3.0.0
|
|
649
|
+
*
|
|
650
|
+
* @example
|
|
651
|
+
* ```typescript
|
|
652
|
+
* const stats: FlexibleStats = {
|
|
653
|
+
* refreshCount: 10,
|
|
654
|
+
* refreshFailures: 0,
|
|
655
|
+
* avgRefreshTime: 15.5
|
|
656
|
+
* };
|
|
657
|
+
* ```
|
|
658
|
+
*/
|
|
659
|
+
type FlexibleStats = {
|
|
660
|
+
/** Total number of successful background refreshes. */
|
|
661
|
+
refreshCount: number;
|
|
662
|
+
/** Total number of background refresh failures (after all retries). */
|
|
663
|
+
refreshFailures: number;
|
|
664
|
+
/** Average time taken for a successful refresh in milliseconds. */
|
|
665
|
+
avgRefreshTime: number;
|
|
273
666
|
};
|
|
274
667
|
/**
|
|
275
|
-
*
|
|
668
|
+
* High-level API for cache operations.
|
|
276
669
|
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
* - Event emission (hit, miss, write, etc.).
|
|
280
|
-
* - Automatic serialization/deserialization.
|
|
281
|
-
* - Higher-level helpers like `remember`, `flexible`, and `pull`.
|
|
282
|
-
* - Support for tagged cache entries (if the store supports it).
|
|
670
|
+
* Wraps a low-level `CacheStore` to provide developer-friendly features like
|
|
671
|
+
* key prefixing, event emission, and advanced patterns like `remember` and `flexible`.
|
|
283
672
|
*
|
|
284
673
|
* @example
|
|
285
674
|
* ```typescript
|
|
@@ -293,72 +682,463 @@ type CacheRepositoryOptions = {
|
|
|
293
682
|
declare class CacheRepository {
|
|
294
683
|
protected readonly store: CacheStore;
|
|
295
684
|
protected readonly options: CacheRepositoryOptions;
|
|
685
|
+
private refreshSemaphore;
|
|
686
|
+
private coalesceSemaphore;
|
|
687
|
+
private flexibleStats;
|
|
296
688
|
constructor(store: CacheStore, options?: CacheRepositoryOptions);
|
|
689
|
+
/**
|
|
690
|
+
* Retrieve statistics about flexible cache operations.
|
|
691
|
+
*
|
|
692
|
+
* Useful for monitoring the health and performance of background refreshes.
|
|
693
|
+
*
|
|
694
|
+
* @returns Current statistics for background refresh operations.
|
|
695
|
+
*
|
|
696
|
+
* @example
|
|
697
|
+
* ```typescript
|
|
698
|
+
* const stats = cache.getFlexibleStats();
|
|
699
|
+
* console.log(`Refreshed ${stats.refreshCount} times`);
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
getFlexibleStats(): FlexibleStats;
|
|
297
703
|
private emit;
|
|
298
704
|
protected key(key: CacheKey): string;
|
|
299
705
|
protected flexibleFreshUntilKey(fullKey: string): string;
|
|
300
706
|
protected putMetaKey(metaKey: string, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
301
707
|
protected forgetMetaKey(metaKey: string): Promise<void>;
|
|
708
|
+
/**
|
|
709
|
+
* Retrieve an item from the cache by its key.
|
|
710
|
+
*
|
|
711
|
+
* Fetches the value from the underlying store. If not found, returns the
|
|
712
|
+
* provided default value or executes the factory function.
|
|
713
|
+
*
|
|
714
|
+
* @param key - The unique cache key.
|
|
715
|
+
* @param defaultValue - A default value or factory function to use if the key is not found.
|
|
716
|
+
* @returns The cached value, or the default value if not found.
|
|
717
|
+
* @throws {Error} If the underlying store fails to retrieve the value.
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* ```typescript
|
|
721
|
+
* const user = await cache.get('user:1', { name: 'Guest' });
|
|
722
|
+
* const settings = await cache.get('settings', () => fetchSettings());
|
|
723
|
+
* ```
|
|
724
|
+
*/
|
|
302
725
|
get<T = unknown>(key: CacheKey, defaultValue?: T | (() => T | Promise<T>)): Promise<T | null>;
|
|
303
|
-
has(key: CacheKey): Promise<boolean>;
|
|
304
|
-
missing(key: CacheKey): Promise<boolean>;
|
|
305
|
-
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
306
|
-
set(key: CacheKey, value: unknown, ttl?: CacheTtl): Promise<void>;
|
|
307
|
-
add(key: CacheKey, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
308
|
-
forever(key: CacheKey, value: unknown): Promise<void>;
|
|
309
|
-
remember<T = unknown>(key: CacheKey, ttl: CacheTtl, callback: () => Promise<T> | T): Promise<T>;
|
|
310
|
-
rememberForever<T = unknown>(key: CacheKey, callback: () => Promise<T> | T): Promise<T>;
|
|
311
|
-
many<T = unknown>(keys: readonly CacheKey[]): Promise<Record<string, T | null>>;
|
|
312
|
-
putMany(values: Record<string, unknown>, ttl: CacheTtl): Promise<void>;
|
|
313
726
|
/**
|
|
314
|
-
*
|
|
727
|
+
* Determine if an item exists in the cache.
|
|
728
|
+
*
|
|
729
|
+
* Checks for the presence of a key without necessarily returning its value.
|
|
315
730
|
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
731
|
+
* @param key - The cache key.
|
|
732
|
+
* @returns True if the item exists, false otherwise.
|
|
733
|
+
* @throws {Error} If the underlying store fails to check existence.
|
|
734
|
+
*
|
|
735
|
+
* @example
|
|
736
|
+
* ```typescript
|
|
737
|
+
* if (await cache.has('session:active')) {
|
|
738
|
+
* // ...
|
|
739
|
+
* }
|
|
740
|
+
* ```
|
|
741
|
+
*/
|
|
742
|
+
has(key: CacheKey): Promise<boolean>;
|
|
743
|
+
/**
|
|
744
|
+
* Determine if an item is missing from the cache.
|
|
745
|
+
*
|
|
746
|
+
* Inverse of `has()`, used for cleaner conditional logic.
|
|
747
|
+
*
|
|
748
|
+
* @param key - The cache key.
|
|
749
|
+
* @returns True if the item is missing, false otherwise.
|
|
750
|
+
* @throws {Error} If the underlying store fails to check existence.
|
|
751
|
+
*
|
|
752
|
+
* @example
|
|
753
|
+
* ```typescript
|
|
754
|
+
* if (await cache.missing('config:loaded')) {
|
|
755
|
+
* await loadConfig();
|
|
756
|
+
* }
|
|
757
|
+
* ```
|
|
758
|
+
*/
|
|
759
|
+
missing(key: CacheKey): Promise<boolean>;
|
|
760
|
+
/**
|
|
761
|
+
* Store an item in the cache for a specific duration.
|
|
762
|
+
*
|
|
763
|
+
* Persists the value in the underlying store with the given TTL.
|
|
764
|
+
*
|
|
765
|
+
* @param key - Unique cache key.
|
|
766
|
+
* @param value - Value to store.
|
|
767
|
+
* @param ttl - Expiration duration.
|
|
768
|
+
* @throws {Error} If the underlying store fails to persist the value or serialization fails.
|
|
769
|
+
*
|
|
770
|
+
* @example
|
|
771
|
+
* ```typescript
|
|
772
|
+
* await cache.put('token', 'xyz123', 3600);
|
|
773
|
+
* ```
|
|
774
|
+
*/
|
|
775
|
+
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
776
|
+
/**
|
|
777
|
+
* Store an item in the cache for a specific duration.
|
|
778
|
+
*
|
|
779
|
+
* Uses the repository's default TTL if none is provided.
|
|
780
|
+
*
|
|
781
|
+
* @param key - The unique cache key.
|
|
782
|
+
* @param value - The value to store.
|
|
783
|
+
* @param ttl - Optional time-to-live.
|
|
784
|
+
* @throws {Error} If the underlying store fails to persist the value.
|
|
785
|
+
*
|
|
786
|
+
* @example
|
|
787
|
+
* ```typescript
|
|
788
|
+
* await cache.set('theme', 'dark');
|
|
789
|
+
* ```
|
|
790
|
+
*/
|
|
791
|
+
set(key: CacheKey, value: unknown, ttl?: CacheTtl): Promise<void>;
|
|
792
|
+
/**
|
|
793
|
+
* Store an item in the cache only if the key does not already exist.
|
|
794
|
+
*
|
|
795
|
+
* Atomic operation to prevent overwriting existing data.
|
|
796
|
+
*
|
|
797
|
+
* @param key - The unique cache key.
|
|
798
|
+
* @param value - The value to store.
|
|
799
|
+
* @param ttl - Optional time-to-live.
|
|
800
|
+
* @returns True if the item was added, false otherwise.
|
|
801
|
+
* @throws {Error} If the underlying store fails the atomic operation.
|
|
802
|
+
*
|
|
803
|
+
* @example
|
|
804
|
+
* ```typescript
|
|
805
|
+
* const added = await cache.add('lock:process', true, 60);
|
|
806
|
+
* ```
|
|
807
|
+
*/
|
|
808
|
+
add(key: CacheKey, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
809
|
+
/**
|
|
810
|
+
* Store an item in the cache indefinitely.
|
|
811
|
+
*
|
|
812
|
+
* Sets the TTL to null, indicating the value should not expire automatically.
|
|
813
|
+
*
|
|
814
|
+
* @param key - The unique cache key.
|
|
815
|
+
* @param value - The value to store.
|
|
816
|
+
* @throws {Error} If the underlying store fails to persist the value.
|
|
817
|
+
*
|
|
818
|
+
* @example
|
|
819
|
+
* ```typescript
|
|
820
|
+
* await cache.forever('system:id', 'node-01');
|
|
821
|
+
* ```
|
|
822
|
+
*/
|
|
823
|
+
forever(key: CacheKey, value: unknown): Promise<void>;
|
|
824
|
+
/**
|
|
825
|
+
* Get an item from the cache, or execute the given callback and store the result.
|
|
826
|
+
*
|
|
827
|
+
* Implements the "Cache-Aside" pattern, ensuring the callback is only executed
|
|
828
|
+
* on a cache miss.
|
|
829
|
+
*
|
|
830
|
+
* @param key - The unique cache key.
|
|
831
|
+
* @param ttl - Time-to-live.
|
|
832
|
+
* @param callback - The callback to execute if the key is not found.
|
|
833
|
+
* @returns The cached value or the result of the callback.
|
|
834
|
+
* @throws {Error} If the callback or the underlying store fails.
|
|
835
|
+
*
|
|
836
|
+
* @example
|
|
837
|
+
* ```typescript
|
|
838
|
+
* const data = await cache.remember('users:all', 300, () => db.users.findMany());
|
|
839
|
+
* ```
|
|
840
|
+
*/
|
|
841
|
+
remember<T = unknown>(key: CacheKey, ttl: CacheTtl, callback: () => Promise<T> | T): Promise<T>;
|
|
842
|
+
/**
|
|
843
|
+
* Get an item from the cache, or execute the given callback and store the result indefinitely.
|
|
844
|
+
*
|
|
845
|
+
* Similar to `remember()`, but the value is stored without an expiration time.
|
|
846
|
+
*
|
|
847
|
+
* @param key - The unique cache key.
|
|
848
|
+
* @param callback - The callback to execute if the key is not found.
|
|
849
|
+
* @returns The cached value or the result of the callback.
|
|
850
|
+
* @throws {Error} If the callback or the underlying store fails.
|
|
851
|
+
*
|
|
852
|
+
* @example
|
|
853
|
+
* ```typescript
|
|
854
|
+
* const config = await cache.rememberForever('app:config', () => loadConfig());
|
|
855
|
+
* ```
|
|
856
|
+
*/
|
|
857
|
+
rememberForever<T = unknown>(key: CacheKey, callback: () => Promise<T> | T): Promise<T>;
|
|
858
|
+
/**
|
|
859
|
+
* Retrieve multiple items from the cache by their keys.
|
|
860
|
+
*
|
|
861
|
+
* Efficiently fetches multiple values, returning a map of keys to values.
|
|
862
|
+
*
|
|
863
|
+
* @param keys - An array of unique cache keys.
|
|
864
|
+
* @returns An object where keys are the original keys and values are the cached values.
|
|
865
|
+
* @throws {Error} If the underlying store fails to retrieve values.
|
|
866
|
+
*
|
|
867
|
+
* @example
|
|
868
|
+
* ```typescript
|
|
869
|
+
* const results = await cache.many(['user:1', 'user:2']);
|
|
870
|
+
* ```
|
|
871
|
+
*/
|
|
872
|
+
many<T = unknown>(keys: readonly CacheKey[]): Promise<Record<string, T | null>>;
|
|
873
|
+
/**
|
|
874
|
+
* Store multiple items in the cache for a specific duration.
|
|
875
|
+
*
|
|
876
|
+
* Persists multiple key-value pairs in a single operation if supported by the store.
|
|
877
|
+
*
|
|
878
|
+
* @param values - An object where keys are the unique cache keys and values are the values to store.
|
|
879
|
+
* @param ttl - Time-to-live.
|
|
880
|
+
* @throws {Error} If the underlying store fails to persist values.
|
|
881
|
+
*
|
|
882
|
+
* @example
|
|
883
|
+
* ```typescript
|
|
884
|
+
* await cache.putMany({ 'a': 1, 'b': 2 }, 60);
|
|
885
|
+
* ```
|
|
886
|
+
*/
|
|
887
|
+
putMany(values: Record<string, unknown>, ttl: CacheTtl): Promise<void>;
|
|
888
|
+
/**
|
|
889
|
+
* Laravel-like flexible cache (stale-while-revalidate).
|
|
890
|
+
*
|
|
891
|
+
* Serves stale content while revalidating the cache in the background. This
|
|
892
|
+
* minimizes latency for users by avoiding synchronous revalidation.
|
|
893
|
+
*
|
|
894
|
+
* @param key - The unique cache key.
|
|
895
|
+
* @param ttlSeconds - How long the value is considered fresh.
|
|
896
|
+
* @param staleSeconds - How long the stale value may be served while a refresh happens.
|
|
897
|
+
* @param callback - The callback to execute to refresh the cache.
|
|
898
|
+
* @returns The fresh or stale cached value.
|
|
899
|
+
* @throws {Error} If the callback fails on a cache miss.
|
|
900
|
+
*
|
|
901
|
+
* @example
|
|
902
|
+
* ```typescript
|
|
903
|
+
* const value = await cache.flexible('stats', 60, 30, () => fetchStats());
|
|
904
|
+
* ```
|
|
905
|
+
*/
|
|
906
|
+
flexible<T = unknown>(key: CacheKey, ttlSeconds: number, staleSeconds: number, callback: () => Promise<T> | T): Promise<T>;
|
|
907
|
+
private refreshFlexible;
|
|
908
|
+
private doRefresh;
|
|
909
|
+
/**
|
|
910
|
+
* Retrieve an item from the cache and delete it.
|
|
911
|
+
*
|
|
912
|
+
* Atomic-like operation to fetch and immediately remove a value, often used
|
|
913
|
+
* for one-time tokens or flash messages.
|
|
914
|
+
*
|
|
915
|
+
* @param key - The unique cache key.
|
|
916
|
+
* @param defaultValue - A default value to use if the key is not found.
|
|
917
|
+
* @returns The cached value, or the default value if not found.
|
|
918
|
+
* @throws {Error} If the underlying store fails to retrieve or forget the value.
|
|
919
|
+
*
|
|
920
|
+
* @example
|
|
921
|
+
* ```typescript
|
|
922
|
+
* const message = await cache.pull('flash:status');
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
925
|
+
pull<T = unknown>(key: CacheKey, defaultValue?: T): Promise<T | null>;
|
|
926
|
+
/**
|
|
927
|
+
* Remove an item from the cache by its key.
|
|
928
|
+
*
|
|
929
|
+
* Deletes the value and any associated metadata from the underlying store.
|
|
930
|
+
*
|
|
931
|
+
* @param key - The cache key to remove.
|
|
932
|
+
* @returns True if the item existed and was removed.
|
|
933
|
+
* @throws {Error} If the underlying store fails to remove the value.
|
|
934
|
+
*
|
|
935
|
+
* @example
|
|
936
|
+
* ```typescript
|
|
937
|
+
* const deleted = await cache.forget('user:session');
|
|
938
|
+
* ```
|
|
318
939
|
*/
|
|
319
|
-
flexible<T = unknown>(key: CacheKey, ttlSeconds: number, staleSeconds: number, callback: () => Promise<T> | T): Promise<T>;
|
|
320
|
-
private refreshFlexible;
|
|
321
|
-
pull<T = unknown>(key: CacheKey, defaultValue?: T): Promise<T | null>;
|
|
322
940
|
forget(key: CacheKey): Promise<boolean>;
|
|
941
|
+
/**
|
|
942
|
+
* Alias for `forget`.
|
|
943
|
+
*
|
|
944
|
+
* Provides compatibility with standard `Map`-like or `Storage` APIs.
|
|
945
|
+
*
|
|
946
|
+
* @param key - The cache key to remove.
|
|
947
|
+
* @returns True if the item existed and was removed.
|
|
948
|
+
* @throws {Error} If the underlying store fails to remove the value.
|
|
949
|
+
*
|
|
950
|
+
* @example
|
|
951
|
+
* ```typescript
|
|
952
|
+
* await cache.delete('temp:data');
|
|
953
|
+
* ```
|
|
954
|
+
*/
|
|
323
955
|
delete(key: CacheKey): Promise<boolean>;
|
|
956
|
+
/**
|
|
957
|
+
* Remove all items from the cache storage.
|
|
958
|
+
*
|
|
959
|
+
* Clears the entire underlying store. Use with caution as this affects all
|
|
960
|
+
* keys regardless of prefix.
|
|
961
|
+
*
|
|
962
|
+
* @throws {Error} If the underlying store fails to flush.
|
|
963
|
+
*
|
|
964
|
+
* @example
|
|
965
|
+
* ```typescript
|
|
966
|
+
* await cache.flush();
|
|
967
|
+
* ```
|
|
968
|
+
*/
|
|
324
969
|
flush(): Promise<void>;
|
|
970
|
+
/**
|
|
971
|
+
* Alias for `flush`.
|
|
972
|
+
*
|
|
973
|
+
* Provides compatibility with standard `Map`-like or `Storage` APIs.
|
|
974
|
+
*
|
|
975
|
+
* @throws {Error} If the underlying store fails to clear.
|
|
976
|
+
*
|
|
977
|
+
* @example
|
|
978
|
+
* ```typescript
|
|
979
|
+
* await cache.clear();
|
|
980
|
+
* ```
|
|
981
|
+
*/
|
|
325
982
|
clear(): Promise<void>;
|
|
983
|
+
/**
|
|
984
|
+
* Increment the value of a numeric item in the cache.
|
|
985
|
+
*
|
|
986
|
+
* Atomically increases the value of a key. If the key does not exist, it is
|
|
987
|
+
* typically initialized to 0 before incrementing.
|
|
988
|
+
*
|
|
989
|
+
* @param key - The cache key.
|
|
990
|
+
* @param value - The amount to increment by.
|
|
991
|
+
* @returns The new value.
|
|
992
|
+
* @throws {Error} If the underlying store fails the atomic increment.
|
|
993
|
+
*
|
|
994
|
+
* @example
|
|
995
|
+
* ```typescript
|
|
996
|
+
* const count = await cache.increment('page:views');
|
|
997
|
+
* ```
|
|
998
|
+
*/
|
|
326
999
|
increment(key: string, value?: number): Promise<number>;
|
|
1000
|
+
/**
|
|
1001
|
+
* Decrement the value of a numeric item in the cache.
|
|
1002
|
+
*
|
|
1003
|
+
* Atomically decreases the value of a key.
|
|
1004
|
+
*
|
|
1005
|
+
* @param key - The cache key.
|
|
1006
|
+
* @param value - The amount to decrement by.
|
|
1007
|
+
* @returns The new value.
|
|
1008
|
+
* @throws {Error} If the underlying store fails the atomic decrement.
|
|
1009
|
+
*
|
|
1010
|
+
* @example
|
|
1011
|
+
* ```typescript
|
|
1012
|
+
* const remaining = await cache.decrement('stock:count');
|
|
1013
|
+
* ```
|
|
1014
|
+
*/
|
|
327
1015
|
decrement(key: string, value?: number): Promise<number>;
|
|
1016
|
+
/**
|
|
1017
|
+
* Get a distributed lock instance for the given name.
|
|
1018
|
+
*
|
|
1019
|
+
* Provides a mechanism for exclusive access to resources across multiple
|
|
1020
|
+
* processes or servers.
|
|
1021
|
+
*
|
|
1022
|
+
* @param name - The lock name.
|
|
1023
|
+
* @param seconds - Optional default duration for the lock in seconds.
|
|
1024
|
+
* @returns A `CacheLock` instance if supported, otherwise undefined.
|
|
1025
|
+
*
|
|
1026
|
+
* @example
|
|
1027
|
+
* ```typescript
|
|
1028
|
+
* const lock = cache.lock('process:heavy', 10);
|
|
1029
|
+
* if (await lock.acquire()) {
|
|
1030
|
+
* try {
|
|
1031
|
+
* // ...
|
|
1032
|
+
* } finally {
|
|
1033
|
+
* await lock.release();
|
|
1034
|
+
* }
|
|
1035
|
+
* }
|
|
1036
|
+
* ```
|
|
1037
|
+
*/
|
|
328
1038
|
lock(name: string, seconds?: number): CacheLock | undefined;
|
|
1039
|
+
/**
|
|
1040
|
+
* Create a new repository instance with the given tags.
|
|
1041
|
+
*
|
|
1042
|
+
* Enables grouping of cache entries for collective operations like flushing
|
|
1043
|
+
* all keys associated with specific tags.
|
|
1044
|
+
*
|
|
1045
|
+
* @param tags - An array of tag names.
|
|
1046
|
+
* @returns A new `CacheRepository` instance that uses the given tags.
|
|
1047
|
+
* @throws {Error} If the underlying store does not support tagging.
|
|
1048
|
+
*
|
|
1049
|
+
* @example
|
|
1050
|
+
* ```typescript
|
|
1051
|
+
* await cache.tags(['users', 'profiles']).put('user:1', data, 3600);
|
|
1052
|
+
* await cache.tags(['users']).flush();
|
|
1053
|
+
* ```
|
|
1054
|
+
*/
|
|
329
1055
|
tags(tags: readonly string[]): CacheRepository;
|
|
330
1056
|
/**
|
|
331
|
-
*
|
|
1057
|
+
* Retrieve the underlying cache store.
|
|
1058
|
+
*
|
|
1059
|
+
* Provides direct access to the low-level store implementation for advanced
|
|
1060
|
+
* use cases or debugging.
|
|
1061
|
+
*
|
|
1062
|
+
* @returns The low-level cache store instance.
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```typescript
|
|
1066
|
+
* const store = cache.getStore();
|
|
1067
|
+
* ```
|
|
332
1068
|
*/
|
|
333
1069
|
getStore(): CacheStore;
|
|
1070
|
+
/**
|
|
1071
|
+
* Compress a value before storage if compression is enabled and thresholds are met.
|
|
1072
|
+
*/
|
|
1073
|
+
private compress;
|
|
1074
|
+
/**
|
|
1075
|
+
* Decompress a value after retrieval if it was previously compressed.
|
|
1076
|
+
*/
|
|
1077
|
+
private decompress;
|
|
334
1078
|
}
|
|
335
1079
|
|
|
336
1080
|
/**
|
|
337
1081
|
* Represents the response from a rate limiting attempt.
|
|
338
1082
|
*
|
|
1083
|
+
* This interface provides the necessary metadata to determine if a request
|
|
1084
|
+
* should be throttled and when the client can safely retry.
|
|
1085
|
+
*
|
|
339
1086
|
* @public
|
|
340
1087
|
* @since 3.0.0
|
|
1088
|
+
*
|
|
1089
|
+
* @example
|
|
1090
|
+
* ```typescript
|
|
1091
|
+
* const res: RateLimiterResponse = { allowed: true, remaining: 4, reset: 1622548800 };
|
|
1092
|
+
* ```
|
|
341
1093
|
*/
|
|
342
1094
|
interface RateLimiterResponse {
|
|
343
|
-
/** Whether the request is allowed. */
|
|
1095
|
+
/** Whether the request is allowed based on current usage and limits. */
|
|
344
1096
|
allowed: boolean;
|
|
345
|
-
/** Number of attempts remaining within the current window. */
|
|
1097
|
+
/** Number of attempts remaining within the current time window. */
|
|
1098
|
+
remaining: number;
|
|
1099
|
+
/** Epoch timestamp in seconds when the rate limit window will reset. */
|
|
1100
|
+
reset: number;
|
|
1101
|
+
/** Seconds until the rate limit resets, typically used for the `Retry-After` header. */
|
|
1102
|
+
retryAfter?: number;
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Detailed information about the current rate limit status.
|
|
1106
|
+
*
|
|
1107
|
+
* Used for inspecting the state of a limiter without necessarily
|
|
1108
|
+
* consuming an attempt or triggering a state change.
|
|
1109
|
+
*
|
|
1110
|
+
* @public
|
|
1111
|
+
* @since 3.0.0
|
|
1112
|
+
*
|
|
1113
|
+
* @example
|
|
1114
|
+
* ```typescript
|
|
1115
|
+
* const info: RateLimitInfo = { limit: 10, remaining: 5, reset: 1622548800 };
|
|
1116
|
+
* ```
|
|
1117
|
+
*/
|
|
1118
|
+
interface RateLimitInfo {
|
|
1119
|
+
/** Maximum number of attempts allowed within the configured window. */
|
|
1120
|
+
limit: number;
|
|
1121
|
+
/** Number of attempts remaining before the limit is reached. */
|
|
346
1122
|
remaining: number;
|
|
347
|
-
/** Epoch timestamp in seconds when the rate limit will reset. */
|
|
1123
|
+
/** Epoch timestamp in seconds when the rate limit window will reset. */
|
|
348
1124
|
reset: number;
|
|
1125
|
+
/** Seconds until the rate limit resets, only present when the limit has been exceeded. */
|
|
1126
|
+
retryAfter?: number;
|
|
349
1127
|
}
|
|
350
1128
|
/**
|
|
351
1129
|
* RateLimiter provides a simple mechanism for limiting request frequency.
|
|
352
1130
|
*
|
|
353
1131
|
* It uses a `CacheStore` backend to track attempt counts and handle
|
|
354
|
-
* expiration
|
|
1132
|
+
* expiration. This allows for distributed rate limiting when using
|
|
1133
|
+
* shared stores like Redis, or local limiting with memory stores.
|
|
355
1134
|
*
|
|
356
1135
|
* @example
|
|
357
1136
|
* ```typescript
|
|
358
1137
|
* const limiter = new RateLimiter(cacheStore);
|
|
359
1138
|
* const status = await limiter.attempt('login:127.0.0.1', 5, 60);
|
|
1139
|
+
*
|
|
360
1140
|
* if (!status.allowed) {
|
|
361
|
-
*
|
|
1141
|
+
* console.log(`Too many attempts. Retry after ${status.retryAfter}s`);
|
|
362
1142
|
* }
|
|
363
1143
|
* ```
|
|
364
1144
|
*
|
|
@@ -367,25 +1147,101 @@ interface RateLimiterResponse {
|
|
|
367
1147
|
*/
|
|
368
1148
|
declare class RateLimiter {
|
|
369
1149
|
private store;
|
|
1150
|
+
/**
|
|
1151
|
+
* Creates a new RateLimiter instance.
|
|
1152
|
+
*
|
|
1153
|
+
* @param store - Cache backend used to persist attempt counts.
|
|
1154
|
+
*
|
|
1155
|
+
* @example
|
|
1156
|
+
* ```typescript
|
|
1157
|
+
* const limiter = new RateLimiter(new MemoryStore());
|
|
1158
|
+
* ```
|
|
1159
|
+
*/
|
|
370
1160
|
constructor(store: CacheStore);
|
|
371
1161
|
/**
|
|
372
|
-
* Attempt to
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
1162
|
+
* Attempt to consume a slot in the rate limit window.
|
|
1163
|
+
*
|
|
1164
|
+
* This method checks the current attempt count for the given key. If the
|
|
1165
|
+
* count is below the limit, it increments the count and allows the request.
|
|
1166
|
+
* Otherwise, it returns a rejected status with retry information.
|
|
1167
|
+
*
|
|
1168
|
+
* @param key - The unique identifier for the rate limit (e.g., IP address or user ID).
|
|
1169
|
+
* @param maxAttempts - Maximum number of attempts allowed within the decay period.
|
|
1170
|
+
* @param decaySeconds - Duration of the rate limit window in seconds.
|
|
1171
|
+
* @returns A response indicating if the attempt was successful and the remaining capacity.
|
|
1172
|
+
* @throws {Error} If the underlying cache store fails to read or write data.
|
|
1173
|
+
*
|
|
1174
|
+
* @example
|
|
1175
|
+
* ```typescript
|
|
1176
|
+
* const response = await limiter.attempt('api-client:123', 100, 3600);
|
|
1177
|
+
* if (response.allowed) {
|
|
1178
|
+
* // Proceed with request
|
|
1179
|
+
* }
|
|
1180
|
+
* ```
|
|
376
1181
|
*/
|
|
377
1182
|
attempt(key: string, maxAttempts: number, decaySeconds: number): Promise<RateLimiterResponse>;
|
|
378
1183
|
/**
|
|
379
|
-
*
|
|
1184
|
+
* Calculate the number of seconds until the rate limit resets.
|
|
1185
|
+
*
|
|
1186
|
+
* This helper method attempts to retrieve the TTL from the store. If the
|
|
1187
|
+
* store does not support TTL inspection, it falls back to the provided
|
|
1188
|
+
* decay period.
|
|
1189
|
+
*
|
|
1190
|
+
* @param key - Unique identifier for the rate limit.
|
|
1191
|
+
* @param decaySeconds - Default decay period to use as a fallback.
|
|
1192
|
+
* @returns Number of seconds until the key expires.
|
|
1193
|
+
* @throws {Error} If the store fails to retrieve TTL metadata.
|
|
380
1194
|
*/
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
1195
|
+
availableIn(key: string, decaySeconds: number): Promise<number>;
|
|
1196
|
+
/**
|
|
1197
|
+
* Get detailed information about the current rate limit status without consuming an attempt.
|
|
1198
|
+
*
|
|
1199
|
+
* Useful for returning rate limit headers (e.g., X-RateLimit-Limit) in
|
|
1200
|
+
* middleware or for pre-flight checks.
|
|
1201
|
+
*
|
|
1202
|
+
* @param key - The unique identifier for the rate limit.
|
|
1203
|
+
* @param maxAttempts - Maximum number of attempts allowed.
|
|
1204
|
+
* @param decaySeconds - Duration of the rate limit window in seconds.
|
|
1205
|
+
* @returns Current status including limit, remaining attempts, and reset time.
|
|
1206
|
+
* @throws {Error} If the underlying cache store fails to retrieve data.
|
|
1207
|
+
*
|
|
1208
|
+
* @example
|
|
1209
|
+
* ```typescript
|
|
1210
|
+
* const info = await limiter.getInfo('user:42', 60, 60);
|
|
1211
|
+
* console.log(`Remaining: ${info.remaining}/${info.limit}`);
|
|
1212
|
+
* ```
|
|
1213
|
+
*/
|
|
1214
|
+
getInfo(key: string, maxAttempts: number, decaySeconds: number): Promise<RateLimitInfo>;
|
|
1215
|
+
/**
|
|
1216
|
+
* Reset the rate limit counter for a specific key.
|
|
1217
|
+
*
|
|
1218
|
+
* Use this to manually clear a block, for example after a successful
|
|
1219
|
+
* login or when an administrator manually unblocks a user.
|
|
1220
|
+
*
|
|
1221
|
+
* @param key - The unique identifier to clear.
|
|
1222
|
+
* @throws {Error} If the store fails to delete the key.
|
|
1223
|
+
*
|
|
1224
|
+
* @example
|
|
1225
|
+
* ```typescript
|
|
1226
|
+
* await limiter.clear('login-attempts:user@example.com');
|
|
1227
|
+
* ```
|
|
1228
|
+
*/
|
|
1229
|
+
clear(key: string): Promise<void>;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
/**
|
|
1233
|
+
* Configuration for a specific cache store driver.
|
|
1234
|
+
*
|
|
1235
|
+
* Defines the connection parameters and behavior for different storage backends
|
|
1236
|
+
* like in-memory, local filesystem, or Redis.
|
|
1237
|
+
*
|
|
1238
|
+
* @public
|
|
1239
|
+
* @since 3.0.0
|
|
1240
|
+
*
|
|
1241
|
+
* @example
|
|
1242
|
+
* ```typescript
|
|
1243
|
+
* const config: StoreConfig = { driver: 'redis', connection: 'default' };
|
|
1244
|
+
* ```
|
|
389
1245
|
*/
|
|
390
1246
|
type StoreConfig = {
|
|
391
1247
|
driver: 'memory';
|
|
@@ -401,31 +1257,63 @@ type StoreConfig = {
|
|
|
401
1257
|
driver: 'null';
|
|
402
1258
|
} | {
|
|
403
1259
|
driver: 'provider';
|
|
1260
|
+
} | {
|
|
1261
|
+
driver: 'tiered';
|
|
1262
|
+
local: string;
|
|
1263
|
+
remote: string;
|
|
1264
|
+
} | {
|
|
1265
|
+
driver: 'circuit-breaker';
|
|
1266
|
+
primary: string;
|
|
1267
|
+
maxFailures?: number;
|
|
1268
|
+
resetTimeout?: number;
|
|
1269
|
+
fallback?: string;
|
|
404
1270
|
};
|
|
405
1271
|
/**
|
|
406
|
-
* Global cache configuration for multiple stores.
|
|
1272
|
+
* Global cache configuration for managing multiple named stores.
|
|
1273
|
+
*
|
|
1274
|
+
* Provides a central manifest to define default behavior, global key prefixing,
|
|
1275
|
+
* and the registry of available storage backends.
|
|
407
1276
|
*
|
|
408
1277
|
* @public
|
|
409
1278
|
* @since 3.0.0
|
|
1279
|
+
*
|
|
1280
|
+
* @example
|
|
1281
|
+
* ```typescript
|
|
1282
|
+
* const config: CacheConfig = {
|
|
1283
|
+
* default: 'redis',
|
|
1284
|
+
* prefix: 'app:',
|
|
1285
|
+
* stores: {
|
|
1286
|
+
* redis: { driver: 'redis' }
|
|
1287
|
+
* }
|
|
1288
|
+
* };
|
|
1289
|
+
* ```
|
|
410
1290
|
*/
|
|
411
1291
|
type CacheConfig = {
|
|
412
|
-
/**
|
|
1292
|
+
/**
|
|
1293
|
+
* The name of the default store to use when no store is explicitly requested.
|
|
1294
|
+
*/
|
|
413
1295
|
default?: string;
|
|
414
|
-
/**
|
|
1296
|
+
/**
|
|
1297
|
+
* Global prefix prepended to all cache keys across all stores to prevent collisions.
|
|
1298
|
+
*/
|
|
415
1299
|
prefix?: string;
|
|
416
|
-
/**
|
|
1300
|
+
/**
|
|
1301
|
+
* Global default time-to-live for cache entries when not specified in write operations.
|
|
1302
|
+
*/
|
|
417
1303
|
defaultTtl?: CacheTtl;
|
|
418
|
-
/**
|
|
1304
|
+
/**
|
|
1305
|
+
* Map of named store configurations, optionally including pre-instantiated providers.
|
|
1306
|
+
*/
|
|
419
1307
|
stores?: Record<string, StoreConfig & {
|
|
420
1308
|
provider?: CacheStore;
|
|
421
1309
|
}>;
|
|
422
1310
|
};
|
|
423
1311
|
/**
|
|
424
|
-
*
|
|
1312
|
+
* Orchestrates multiple cache stores and provides a unified API.
|
|
425
1313
|
*
|
|
426
|
-
*
|
|
427
|
-
* a multi-store API
|
|
428
|
-
* proxy API
|
|
1314
|
+
* Acts as a central registry for cache repositories, supporting various drivers
|
|
1315
|
+
* (Memory, File, Redis). It provides both a multi-store API for targeted operations
|
|
1316
|
+
* and a proxy API that forwards calls to the default store.
|
|
429
1317
|
*
|
|
430
1318
|
* @example
|
|
431
1319
|
* ```typescript
|
|
@@ -448,7 +1336,18 @@ declare class CacheManager {
|
|
|
448
1336
|
private readonly config;
|
|
449
1337
|
private readonly events?;
|
|
450
1338
|
private readonly eventOptions?;
|
|
1339
|
+
/**
|
|
1340
|
+
* Internal registry of initialized cache repositories.
|
|
1341
|
+
*/
|
|
451
1342
|
private stores;
|
|
1343
|
+
/**
|
|
1344
|
+
* Initialize a new CacheManager instance.
|
|
1345
|
+
*
|
|
1346
|
+
* @param storeFactory - Factory function to create low-level store instances by name.
|
|
1347
|
+
* @param config - Configuration manifest for stores and global defaults.
|
|
1348
|
+
* @param events - Optional event handlers for cache lifecycle hooks.
|
|
1349
|
+
* @param eventOptions - Configuration for how events are dispatched and handled.
|
|
1350
|
+
*/
|
|
452
1351
|
constructor(storeFactory: (name: string) => CacheStore, config?: CacheConfig, events?: CacheEvents | undefined, eventOptions?: {
|
|
453
1352
|
mode?: CacheEventMode;
|
|
454
1353
|
throwOnError?: boolean;
|
|
@@ -457,17 +1356,51 @@ declare class CacheManager {
|
|
|
457
1356
|
}) => void;
|
|
458
1357
|
} | undefined);
|
|
459
1358
|
/**
|
|
460
|
-
* Get a rate limiter instance for a store
|
|
461
|
-
*
|
|
1359
|
+
* Get a rate limiter instance for a specific store.
|
|
1360
|
+
*
|
|
1361
|
+
* Provides a specialized interface for throttling actions based on cache keys,
|
|
1362
|
+
* leveraging the underlying storage for persistence.
|
|
1363
|
+
*
|
|
1364
|
+
* @param name - Store name (defaults to the configured default store).
|
|
1365
|
+
* @returns A RateLimiter instance bound to the requested store.
|
|
1366
|
+
* @throws {Error} If the requested store cannot be initialized.
|
|
1367
|
+
*
|
|
1368
|
+
* @example
|
|
1369
|
+
* ```typescript
|
|
1370
|
+
* const limiter = cache.limiter('redis');
|
|
1371
|
+
* if (await limiter.tooManyAttempts('login:1', 5)) {
|
|
1372
|
+
* throw new Error('Too many attempts');
|
|
1373
|
+
* }
|
|
1374
|
+
* ```
|
|
462
1375
|
*/
|
|
463
1376
|
limiter(name?: string): RateLimiter;
|
|
1377
|
+
/**
|
|
1378
|
+
* Resolve a named cache repository.
|
|
1379
|
+
*
|
|
1380
|
+
* Lazily initializes and caches the repository instance for the given store name.
|
|
1381
|
+
* If no name is provided, it falls back to the default store.
|
|
1382
|
+
*
|
|
1383
|
+
* @param name - Store name to retrieve.
|
|
1384
|
+
* @returns Initialized CacheRepository instance.
|
|
1385
|
+
* @throws {Error} If the store factory fails to create the underlying store or the driver is unsupported.
|
|
1386
|
+
*
|
|
1387
|
+
* @example
|
|
1388
|
+
* ```typescript
|
|
1389
|
+
* const redis = cache.store('redis');
|
|
1390
|
+
* await redis.put('key', 'value', 60);
|
|
1391
|
+
* ```
|
|
1392
|
+
*/
|
|
464
1393
|
store(name?: string): CacheRepository;
|
|
465
1394
|
/**
|
|
466
|
-
* Retrieve an item from the cache.
|
|
1395
|
+
* Retrieve an item from the default cache store.
|
|
467
1396
|
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
1397
|
+
* If the key is missing, the provided default value or the result of the
|
|
1398
|
+
* default value closure will be returned.
|
|
1399
|
+
*
|
|
1400
|
+
* @param key - Unique cache key.
|
|
1401
|
+
* @param defaultValue - Fallback value or factory to execute on cache miss.
|
|
1402
|
+
* @returns Cached value or the resolved default.
|
|
1403
|
+
* @throws {Error} If the underlying store driver encounters a read error or connection failure.
|
|
471
1404
|
*
|
|
472
1405
|
* @example
|
|
473
1406
|
* ```typescript
|
|
@@ -476,183 +1409,1131 @@ declare class CacheManager {
|
|
|
476
1409
|
*/
|
|
477
1410
|
get<T = unknown>(key: string, defaultValue?: T | (() => T | Promise<T>)): Promise<T | null>;
|
|
478
1411
|
/**
|
|
479
|
-
*
|
|
1412
|
+
* Determine if an item exists in the default cache store.
|
|
1413
|
+
*
|
|
1414
|
+
* @param key - The unique cache key.
|
|
1415
|
+
* @returns True if the key exists and has not expired.
|
|
1416
|
+
* @throws {Error} If the underlying store driver encounters a connection error.
|
|
1417
|
+
*
|
|
1418
|
+
* @example
|
|
1419
|
+
* ```typescript
|
|
1420
|
+
* if (await cache.has('session:active')) {
|
|
1421
|
+
* // ...
|
|
1422
|
+
* }
|
|
1423
|
+
* ```
|
|
480
1424
|
*/
|
|
481
1425
|
has(key: string): Promise<boolean>;
|
|
482
1426
|
/**
|
|
483
|
-
*
|
|
1427
|
+
* Determine if an item is missing from the default cache store.
|
|
1428
|
+
*
|
|
1429
|
+
* @param key - The unique cache key.
|
|
1430
|
+
* @returns True if the key does not exist or has expired.
|
|
1431
|
+
* @throws {Error} If the underlying store driver encounters a connection error.
|
|
1432
|
+
*
|
|
1433
|
+
* @example
|
|
1434
|
+
* ```typescript
|
|
1435
|
+
* if (await cache.missing('config:loaded')) {
|
|
1436
|
+
* await loadConfig();
|
|
1437
|
+
* }
|
|
1438
|
+
* ```
|
|
1439
|
+
*/
|
|
1440
|
+
missing(key: string): Promise<boolean>;
|
|
1441
|
+
/**
|
|
1442
|
+
* Store an item in the default cache store for a specific duration.
|
|
1443
|
+
*
|
|
1444
|
+
* @param key - The unique cache key.
|
|
1445
|
+
* @param value - The data to be cached.
|
|
1446
|
+
* @param ttl - Expiration time in seconds or a specific Date.
|
|
1447
|
+
* @returns A promise that resolves when the write is complete.
|
|
1448
|
+
* @throws {Error} If the value cannot be serialized or the store is read-only.
|
|
1449
|
+
*
|
|
1450
|
+
* @example
|
|
1451
|
+
* ```typescript
|
|
1452
|
+
* await cache.put('key', 'value', 60); // 60 seconds
|
|
1453
|
+
* ```
|
|
1454
|
+
*/
|
|
1455
|
+
put(key: string, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
1456
|
+
/**
|
|
1457
|
+
* Store an item in the default cache store (alias for put).
|
|
1458
|
+
*
|
|
1459
|
+
* @param key - The unique cache key.
|
|
1460
|
+
* @param value - The data to be cached.
|
|
1461
|
+
* @param ttl - Optional expiration time.
|
|
1462
|
+
* @returns A promise that resolves when the write is complete.
|
|
1463
|
+
* @throws {Error} If the underlying store driver encounters a write error.
|
|
1464
|
+
*
|
|
1465
|
+
* @example
|
|
1466
|
+
* ```typescript
|
|
1467
|
+
* await cache.set('theme', 'dark');
|
|
1468
|
+
* ```
|
|
1469
|
+
*/
|
|
1470
|
+
set(key: string, value: unknown, ttl?: CacheTtl): Promise<void>;
|
|
1471
|
+
/**
|
|
1472
|
+
* Store an item in the default cache store only if it does not already exist.
|
|
1473
|
+
*
|
|
1474
|
+
* @param key - The unique cache key.
|
|
1475
|
+
* @param value - The data to be cached.
|
|
1476
|
+
* @param ttl - Optional expiration time.
|
|
1477
|
+
* @returns True if the item was added, false if it already existed.
|
|
1478
|
+
* @throws {Error} If the underlying store driver encounters a write error.
|
|
1479
|
+
*
|
|
1480
|
+
* @example
|
|
1481
|
+
* ```typescript
|
|
1482
|
+
* const added = await cache.add('lock:process', true, 30);
|
|
1483
|
+
* ```
|
|
1484
|
+
*/
|
|
1485
|
+
add(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
1486
|
+
/**
|
|
1487
|
+
* Store an item in the default cache store indefinitely.
|
|
1488
|
+
*
|
|
1489
|
+
* @param key - The unique cache key.
|
|
1490
|
+
* @param value - The data to be cached.
|
|
1491
|
+
* @returns A promise that resolves when the write is complete.
|
|
1492
|
+
* @throws {Error} If the underlying store driver encounters a write error.
|
|
1493
|
+
*
|
|
1494
|
+
* @example
|
|
1495
|
+
* ```typescript
|
|
1496
|
+
* await cache.forever('system:version', '1.0.0');
|
|
1497
|
+
* ```
|
|
1498
|
+
*/
|
|
1499
|
+
forever(key: string, value: unknown): Promise<void>;
|
|
1500
|
+
/**
|
|
1501
|
+
* Get an item from the cache, or execute the callback and store the result.
|
|
1502
|
+
*
|
|
1503
|
+
* Ensures the value is cached after the first miss. This provides an atomic-like
|
|
1504
|
+
* "get or set" flow to prevent multiple concurrent fetches of the same data.
|
|
1505
|
+
*
|
|
1506
|
+
* @param key - Unique cache key.
|
|
1507
|
+
* @param ttl - Duration to cache the result if a miss occurs.
|
|
1508
|
+
* @param callback - Logic to execute to fetch fresh data.
|
|
1509
|
+
* @returns Cached or freshly fetched value.
|
|
1510
|
+
* @throws {Error} If the callback fails or the store write operation errors.
|
|
1511
|
+
*
|
|
1512
|
+
* @example
|
|
1513
|
+
* ```typescript
|
|
1514
|
+
* const user = await cache.remember('user:1', 60, async () => {
|
|
1515
|
+
* return await db.findUser(1);
|
|
1516
|
+
* });
|
|
1517
|
+
* ```
|
|
1518
|
+
*/
|
|
1519
|
+
remember<T = unknown>(key: string, ttl: CacheTtl, callback: () => Promise<T> | T): Promise<T>;
|
|
1520
|
+
/**
|
|
1521
|
+
* Get an item from the cache, or execute the callback and store the result forever.
|
|
1522
|
+
*
|
|
1523
|
+
* @param key - The unique cache key.
|
|
1524
|
+
* @param callback - The closure to execute to fetch the fresh data.
|
|
1525
|
+
* @returns The cached or freshly fetched value.
|
|
1526
|
+
* @throws {Error} If the callback throws or the store write fails.
|
|
1527
|
+
*
|
|
1528
|
+
* @example
|
|
1529
|
+
* ```typescript
|
|
1530
|
+
* const settings = await cache.rememberForever('global:settings', () => {
|
|
1531
|
+
* return fetchSettingsFromApi();
|
|
1532
|
+
* });
|
|
1533
|
+
* ```
|
|
1534
|
+
*/
|
|
1535
|
+
rememberForever<T = unknown>(key: string, callback: () => Promise<T> | T): Promise<T>;
|
|
1536
|
+
/**
|
|
1537
|
+
* Retrieve multiple items from the default cache store by their keys.
|
|
1538
|
+
*
|
|
1539
|
+
* @param keys - An array of unique cache keys.
|
|
1540
|
+
* @returns An object mapping keys to their cached values (or null if missing).
|
|
1541
|
+
* @throws {Error} If the underlying store driver encounters a read error.
|
|
1542
|
+
*
|
|
1543
|
+
* @example
|
|
1544
|
+
* ```typescript
|
|
1545
|
+
* const values = await cache.many(['key1', 'key2']);
|
|
1546
|
+
* ```
|
|
1547
|
+
*/
|
|
1548
|
+
many<T = unknown>(keys: readonly string[]): Promise<Record<string, T | null>>;
|
|
1549
|
+
/**
|
|
1550
|
+
* Store multiple items in the default cache store for a specific duration.
|
|
1551
|
+
*
|
|
1552
|
+
* @param values - An object mapping keys to the values to be stored.
|
|
1553
|
+
* @param ttl - Expiration time in seconds or a specific Date.
|
|
1554
|
+
* @returns A promise that resolves when all writes are complete.
|
|
1555
|
+
* @throws {Error} If the underlying store driver encounters a write error.
|
|
1556
|
+
*
|
|
1557
|
+
* @example
|
|
1558
|
+
* ```typescript
|
|
1559
|
+
* await cache.putMany({ a: 1, b: 2 }, 60);
|
|
1560
|
+
* ```
|
|
1561
|
+
*/
|
|
1562
|
+
putMany(values: Record<string, unknown>, ttl: CacheTtl): Promise<void>;
|
|
1563
|
+
/**
|
|
1564
|
+
* Get an item from the cache, allowing stale data while refreshing in background.
|
|
1565
|
+
*
|
|
1566
|
+
* Implements the Stale-While-Revalidate pattern to minimize latency for
|
|
1567
|
+
* frequently accessed but expensive data.
|
|
1568
|
+
*
|
|
1569
|
+
* @param key - The unique cache key.
|
|
1570
|
+
* @param ttlSeconds - How long the value is considered fresh.
|
|
1571
|
+
* @param staleSeconds - How long to serve stale data while refreshing.
|
|
1572
|
+
* @param callback - The closure to execute to refresh the data.
|
|
1573
|
+
* @returns The cached (possibly stale) or freshly fetched value.
|
|
1574
|
+
* @throws {Error} If the callback throws during an initial fetch.
|
|
1575
|
+
*
|
|
1576
|
+
* @example
|
|
1577
|
+
* ```typescript
|
|
1578
|
+
* const data = await cache.flexible('stats', 60, 30, () => fetchStats());
|
|
1579
|
+
* ```
|
|
1580
|
+
*/
|
|
1581
|
+
flexible<T = unknown>(key: string, ttlSeconds: number, staleSeconds: number, callback: () => Promise<T> | T): Promise<T>;
|
|
1582
|
+
/**
|
|
1583
|
+
* Retrieve an item from the default cache store and then delete it.
|
|
1584
|
+
*
|
|
1585
|
+
* Useful for one-time notifications or temporary tokens.
|
|
1586
|
+
*
|
|
1587
|
+
* @param key - The unique cache key.
|
|
1588
|
+
* @param defaultValue - Fallback value if the key is missing.
|
|
1589
|
+
* @returns The cached value before deletion, or the default.
|
|
1590
|
+
* @throws {Error} If the underlying store driver encounters a read or delete error.
|
|
1591
|
+
*
|
|
1592
|
+
* @example
|
|
1593
|
+
* ```typescript
|
|
1594
|
+
* const token = await cache.pull('temp_token');
|
|
1595
|
+
* ```
|
|
1596
|
+
*/
|
|
1597
|
+
pull<T = unknown>(key: string, defaultValue?: T): Promise<T | null>;
|
|
1598
|
+
/**
|
|
1599
|
+
* Remove an item from the default cache store.
|
|
1600
|
+
*
|
|
1601
|
+
* @param key - The unique cache key.
|
|
1602
|
+
* @returns True if the item was removed, false otherwise.
|
|
1603
|
+
* @throws {Error} If the underlying store driver encounters a delete error.
|
|
1604
|
+
*
|
|
1605
|
+
* @example
|
|
1606
|
+
* ```typescript
|
|
1607
|
+
* await cache.forget('user:1');
|
|
1608
|
+
* ```
|
|
1609
|
+
*/
|
|
1610
|
+
forget(key: string): Promise<boolean>;
|
|
1611
|
+
/**
|
|
1612
|
+
* Remove an item from the default cache store (alias for forget).
|
|
1613
|
+
*
|
|
1614
|
+
* @param key - The unique cache key.
|
|
1615
|
+
* @returns True if the item was removed, false otherwise.
|
|
1616
|
+
* @throws {Error} If the underlying store driver encounters a delete error.
|
|
1617
|
+
*
|
|
1618
|
+
* @example
|
|
1619
|
+
* ```typescript
|
|
1620
|
+
* await cache.delete('old_key');
|
|
1621
|
+
* ```
|
|
1622
|
+
*/
|
|
1623
|
+
delete(key: string): Promise<boolean>;
|
|
1624
|
+
/**
|
|
1625
|
+
* Remove all items from the default cache store.
|
|
1626
|
+
*
|
|
1627
|
+
* @returns A promise that resolves when the flush is complete.
|
|
1628
|
+
* @throws {Error} If the underlying store driver encounters a flush error.
|
|
1629
|
+
*
|
|
1630
|
+
* @example
|
|
1631
|
+
* ```typescript
|
|
1632
|
+
* await cache.flush();
|
|
1633
|
+
* ```
|
|
1634
|
+
*/
|
|
1635
|
+
flush(): Promise<void>;
|
|
1636
|
+
/**
|
|
1637
|
+
* Clear the entire default cache store (alias for flush).
|
|
1638
|
+
*
|
|
1639
|
+
* @returns A promise that resolves when the clear is complete.
|
|
1640
|
+
* @throws {Error} If the underlying store driver encounters a clear error.
|
|
1641
|
+
*
|
|
1642
|
+
* @example
|
|
1643
|
+
* ```typescript
|
|
1644
|
+
* await cache.clear();
|
|
1645
|
+
* ```
|
|
1646
|
+
*/
|
|
1647
|
+
clear(): Promise<void>;
|
|
1648
|
+
/**
|
|
1649
|
+
* Increment the value of an integer item in the default cache store.
|
|
1650
|
+
*
|
|
1651
|
+
* @param key - Unique cache key.
|
|
1652
|
+
* @param value - Amount to add.
|
|
1653
|
+
* @returns New value after incrementing.
|
|
1654
|
+
* @throws {Error} If existing value is not a number or the store is read-only.
|
|
1655
|
+
*
|
|
1656
|
+
* @example
|
|
1657
|
+
* ```typescript
|
|
1658
|
+
* const count = await cache.increment('page_views');
|
|
1659
|
+
* ```
|
|
1660
|
+
*/
|
|
1661
|
+
increment(key: string, value?: number): Promise<number>;
|
|
1662
|
+
/**
|
|
1663
|
+
* Decrement the value of an integer item in the default cache store.
|
|
1664
|
+
*
|
|
1665
|
+
* @param key - Unique cache key.
|
|
1666
|
+
* @param value - Amount to subtract.
|
|
1667
|
+
* @returns New value after decrementing.
|
|
1668
|
+
* @throws {Error} If existing value is not a number or the store is read-only.
|
|
1669
|
+
*
|
|
1670
|
+
* @example
|
|
1671
|
+
* ```typescript
|
|
1672
|
+
* const remaining = await cache.decrement('stock:1');
|
|
1673
|
+
* ```
|
|
1674
|
+
*/
|
|
1675
|
+
decrement(key: string, value?: number): Promise<number>;
|
|
1676
|
+
/**
|
|
1677
|
+
* Get a distributed lock instance from the default cache store.
|
|
1678
|
+
*
|
|
1679
|
+
* @param name - The unique name of the lock.
|
|
1680
|
+
* @param seconds - The duration the lock should be held for.
|
|
1681
|
+
* @returns A CacheLock instance.
|
|
1682
|
+
* @throws {Error} If the underlying store does not support locking.
|
|
1683
|
+
*
|
|
1684
|
+
* @example
|
|
1685
|
+
* ```typescript
|
|
1686
|
+
* const lock = cache.lock('process_data', 10);
|
|
1687
|
+
* if (await lock.get()) {
|
|
1688
|
+
* // ...
|
|
1689
|
+
* await lock.release();
|
|
1690
|
+
* }
|
|
1691
|
+
* ```
|
|
1692
|
+
*/
|
|
1693
|
+
lock(name: string, seconds?: number): CacheLock | undefined;
|
|
1694
|
+
/**
|
|
1695
|
+
* Access a tagged cache section for grouped operations.
|
|
1696
|
+
*
|
|
1697
|
+
* Tags allow you to clear groups of cache entries simultaneously.
|
|
1698
|
+
* Note: This is only supported by specific drivers like 'memory'.
|
|
1699
|
+
*
|
|
1700
|
+
* @param tags - An array of tag names.
|
|
1701
|
+
* @returns A tagged cache repository instance.
|
|
1702
|
+
* @throws {Error} If the underlying store driver does not support tags.
|
|
1703
|
+
*
|
|
1704
|
+
* @example
|
|
1705
|
+
* ```typescript
|
|
1706
|
+
* await cache.tags(['users', 'profiles']).put('user:1', data, 60);
|
|
1707
|
+
* await cache.tags(['users']).flush(); // Clears all 'users' tagged entries
|
|
1708
|
+
* ```
|
|
1709
|
+
*/
|
|
1710
|
+
tags(tags: readonly string[]): CacheRepository;
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
/**
|
|
1714
|
+
* Contract for a mechanism that predicts future cache key accesses.
|
|
1715
|
+
*
|
|
1716
|
+
* Implementations observe sequential access patterns to predict which keys
|
|
1717
|
+
* are likely to be requested next, enabling prefetching strategies.
|
|
1718
|
+
*
|
|
1719
|
+
* @public
|
|
1720
|
+
* @since 3.2.0
|
|
1721
|
+
*/
|
|
1722
|
+
interface AccessPredictor {
|
|
1723
|
+
/**
|
|
1724
|
+
* Record a cache key access to learn temporal patterns.
|
|
1725
|
+
*
|
|
1726
|
+
* @param key - Cache key currently being accessed.
|
|
1727
|
+
*/
|
|
1728
|
+
record(key: string): void;
|
|
1729
|
+
/**
|
|
1730
|
+
* Predict potential future keys based on learned access history.
|
|
1731
|
+
*
|
|
1732
|
+
* @param key - Current cache key acting as the trigger for prediction.
|
|
1733
|
+
* @returns Array of predicted keys, ordered by likelihood.
|
|
1734
|
+
*/
|
|
1735
|
+
predict(key: string): string[];
|
|
1736
|
+
/**
|
|
1737
|
+
* Reset all learned transition probabilities and state.
|
|
1738
|
+
*/
|
|
1739
|
+
reset(): void;
|
|
1740
|
+
}
|
|
1741
|
+
/**
|
|
1742
|
+
* A simple Markov Chain predictor (Order-1).
|
|
1743
|
+
*
|
|
1744
|
+
* Records transitions (A -> B) between sequential accesses and predicts
|
|
1745
|
+
* B when A is next encountered. This is particularly effective for
|
|
1746
|
+
* predictable resource loading sequences.
|
|
1747
|
+
*
|
|
1748
|
+
* @public
|
|
1749
|
+
* @since 3.2.0
|
|
1750
|
+
*
|
|
1751
|
+
* @example
|
|
1752
|
+
* ```typescript
|
|
1753
|
+
* const predictor = new MarkovPredictor();
|
|
1754
|
+
* predictor.record('user:1');
|
|
1755
|
+
* predictor.record('user:1:profile');
|
|
1756
|
+
* const next = predictor.predict('user:1'); // ['user:1:profile']
|
|
1757
|
+
* ```
|
|
1758
|
+
*/
|
|
1759
|
+
declare class MarkovPredictor implements AccessPredictor {
|
|
1760
|
+
private transitions;
|
|
1761
|
+
private lastKey;
|
|
1762
|
+
private readonly maxNodes;
|
|
1763
|
+
private readonly maxEdgesPerNode;
|
|
1764
|
+
/**
|
|
1765
|
+
* Initialize a new MarkovPredictor.
|
|
1766
|
+
*
|
|
1767
|
+
* @param options - Limits for internal transition graph to manage memory.
|
|
1768
|
+
*/
|
|
1769
|
+
constructor(options?: {
|
|
1770
|
+
maxNodes?: number;
|
|
1771
|
+
maxEdgesPerNode?: number;
|
|
1772
|
+
});
|
|
1773
|
+
record(key: string): void;
|
|
1774
|
+
predict(key: string): string[];
|
|
1775
|
+
reset(): void;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
|
|
1779
|
+
/**
|
|
1780
|
+
* Options for the CircuitBreakerStore.
|
|
1781
|
+
*
|
|
1782
|
+
* @public
|
|
1783
|
+
* @since 3.2.0
|
|
1784
|
+
*
|
|
1785
|
+
* @example
|
|
1786
|
+
* ```typescript
|
|
1787
|
+
* const options: CircuitBreakerOptions = {
|
|
1788
|
+
* maxFailures: 3,
|
|
1789
|
+
* resetTimeout: 30000,
|
|
1790
|
+
* fallback: new MemoryStore()
|
|
1791
|
+
* };
|
|
1792
|
+
* ```
|
|
1793
|
+
*/
|
|
1794
|
+
type CircuitBreakerOptions = {
|
|
1795
|
+
/**
|
|
1796
|
+
* Number of consecutive failures before opening the circuit.
|
|
1797
|
+
* @defaultValue 5
|
|
1798
|
+
*/
|
|
1799
|
+
maxFailures?: number;
|
|
1800
|
+
/**
|
|
1801
|
+
* Time in milliseconds to stay in OPEN state before transitioning to HALF_OPEN.
|
|
1802
|
+
* @defaultValue 60000
|
|
1803
|
+
*/
|
|
1804
|
+
resetTimeout?: number;
|
|
1805
|
+
/**
|
|
1806
|
+
* Optional fallback store to use when the primary store is unavailable.
|
|
1807
|
+
*/
|
|
1808
|
+
fallback?: CacheStore;
|
|
1809
|
+
};
|
|
1810
|
+
/**
|
|
1811
|
+
* A protective wrapper for cache stores that prevents cascading failures
|
|
1812
|
+
* through circuit-breaking logic.
|
|
1813
|
+
*
|
|
1814
|
+
* When the primary store encounters repeated failures, the circuit opens,
|
|
1815
|
+
* temporarily bypassing the primary store and optionally using a fallback.
|
|
1816
|
+
*
|
|
1817
|
+
* @public
|
|
1818
|
+
* @since 3.2.0
|
|
1819
|
+
*/
|
|
1820
|
+
declare class CircuitBreakerStore implements CacheStore {
|
|
1821
|
+
private readonly primary;
|
|
1822
|
+
private state;
|
|
1823
|
+
private failures;
|
|
1824
|
+
private lastErrorTime;
|
|
1825
|
+
private options;
|
|
1826
|
+
constructor(primary: CacheStore, options?: CircuitBreakerOptions);
|
|
1827
|
+
private execute;
|
|
1828
|
+
private onSuccess;
|
|
1829
|
+
private onFailure;
|
|
1830
|
+
private handleFallback;
|
|
1831
|
+
get<T = unknown>(key: CacheKey): Promise<T | null>;
|
|
1832
|
+
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
1833
|
+
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
1834
|
+
forget(key: CacheKey): Promise<boolean>;
|
|
1835
|
+
flush(): Promise<void>;
|
|
1836
|
+
increment(key: CacheKey, value?: number): Promise<number>;
|
|
1837
|
+
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
1838
|
+
ttl(key: CacheKey): Promise<number | null>;
|
|
1839
|
+
/**
|
|
1840
|
+
* Returns current state for monitoring.
|
|
1841
|
+
*
|
|
1842
|
+
* @returns Current state of the circuit breaker.
|
|
1843
|
+
*
|
|
1844
|
+
* @example
|
|
1845
|
+
* ```typescript
|
|
1846
|
+
* const state = store.getState();
|
|
1847
|
+
* if (state === 'OPEN') {
|
|
1848
|
+
* console.warn('Primary cache is unavailable');
|
|
1849
|
+
* }
|
|
1850
|
+
* ```
|
|
1851
|
+
*/
|
|
1852
|
+
getState(): CircuitState;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
/**
|
|
1856
|
+
* Configuration options for the `FileStore` implementation.
|
|
1857
|
+
*
|
|
1858
|
+
* Defines how the file-based cache behaves, including storage location,
|
|
1859
|
+
* cleanup policies, and filesystem organization.
|
|
1860
|
+
*
|
|
1861
|
+
* @public
|
|
1862
|
+
* @since 3.0.0
|
|
1863
|
+
*
|
|
1864
|
+
* @example
|
|
1865
|
+
* ```typescript
|
|
1866
|
+
* const options: FileStoreOptions = {
|
|
1867
|
+
* directory: './cache',
|
|
1868
|
+
* enableCleanup: true,
|
|
1869
|
+
* maxFiles: 1000,
|
|
1870
|
+
* useSubdirectories: true
|
|
1871
|
+
* };
|
|
1872
|
+
* ```
|
|
1873
|
+
*/
|
|
1874
|
+
type FileStoreOptions = {
|
|
1875
|
+
/**
|
|
1876
|
+
* The absolute or relative path to the directory where cache files are stored.
|
|
1877
|
+
* The directory will be created automatically if it does not exist.
|
|
1878
|
+
*/
|
|
1879
|
+
directory: string;
|
|
1880
|
+
/**
|
|
1881
|
+
* Whether to enable the background cleanup daemon for removing expired entries.
|
|
1882
|
+
*
|
|
1883
|
+
* @default true
|
|
1884
|
+
*/
|
|
1885
|
+
enableCleanup?: boolean;
|
|
1886
|
+
/**
|
|
1887
|
+
* The frequency in milliseconds at which the cleanup daemon scans for expired files.
|
|
1888
|
+
*
|
|
1889
|
+
* @default 60000
|
|
1890
|
+
*/
|
|
1891
|
+
cleanupInterval?: number;
|
|
1892
|
+
/**
|
|
1893
|
+
* The maximum number of cache files allowed in the storage directory.
|
|
1894
|
+
*
|
|
1895
|
+
* When this limit is exceeded, the store performs LRU (Least Recently Used)
|
|
1896
|
+
* eviction based on file modification times.
|
|
1897
|
+
*/
|
|
1898
|
+
maxFiles?: number;
|
|
1899
|
+
/**
|
|
1900
|
+
* Whether to distribute cache files across nested subdirectories.
|
|
1901
|
+
*
|
|
1902
|
+
* Enabling this prevents performance degradation on filesystems with limits
|
|
1903
|
+
* on the number of files per single directory by using a 2-level hash-based structure.
|
|
1904
|
+
*
|
|
1905
|
+
* @default false
|
|
1906
|
+
*/
|
|
1907
|
+
useSubdirectories?: boolean;
|
|
1908
|
+
};
|
|
1909
|
+
/**
|
|
1910
|
+
* A persistent filesystem-based implementation of the `CacheStore` interface.
|
|
1911
|
+
*
|
|
1912
|
+
* `FileStore` manages cache entries as individual JSON files on the local disk.
|
|
1913
|
+
* It is designed for scenarios requiring data persistence across application
|
|
1914
|
+
* restarts without the overhead of external database dependencies like Redis.
|
|
1915
|
+
*
|
|
1916
|
+
* Key features:
|
|
1917
|
+
* - Atomic writes using temporary files and renames.
|
|
1918
|
+
* - Background cleanup daemon for expired entries.
|
|
1919
|
+
* - LRU eviction when `maxFiles` limit is reached.
|
|
1920
|
+
* - Optional subdirectory nesting for high-volume storage.
|
|
1921
|
+
* - File-based distributed locking mechanism.
|
|
1922
|
+
*
|
|
1923
|
+
* @public
|
|
1924
|
+
* @since 3.0.0
|
|
1925
|
+
*
|
|
1926
|
+
* @example
|
|
1927
|
+
* ```typescript
|
|
1928
|
+
* const store = new FileStore({
|
|
1929
|
+
* directory: './storage/cache',
|
|
1930
|
+
* useSubdirectories: true
|
|
1931
|
+
* });
|
|
1932
|
+
*
|
|
1933
|
+
* await store.put('user:1', { name: 'John' }, 3600);
|
|
1934
|
+
* const user = await store.get('user:1');
|
|
1935
|
+
* ```
|
|
1936
|
+
*/
|
|
1937
|
+
declare class FileStore implements CacheStore {
|
|
1938
|
+
private options;
|
|
1939
|
+
private cleanupTimer;
|
|
1940
|
+
/**
|
|
1941
|
+
* Initializes a new instance of the FileStore.
|
|
1942
|
+
*
|
|
1943
|
+
* @param options - Configuration settings for the store.
|
|
1944
|
+
*/
|
|
1945
|
+
constructor(options: FileStoreOptions);
|
|
1946
|
+
/**
|
|
1947
|
+
* Starts the background process for periodic cache maintenance.
|
|
1948
|
+
*
|
|
1949
|
+
* @param interval - Time between cleanup cycles in milliseconds.
|
|
1950
|
+
* @internal
|
|
1951
|
+
*/
|
|
1952
|
+
private startCleanupDaemon;
|
|
1953
|
+
/**
|
|
1954
|
+
* Scans the cache directory to remove expired files and enforce capacity limits.
|
|
1955
|
+
*
|
|
1956
|
+
* This method performs a recursive scan of the storage directory. It deletes
|
|
1957
|
+
* files that have passed their expiration time and, if `maxFiles` is configured,
|
|
1958
|
+
* evicts the oldest files to stay within the limit.
|
|
1959
|
+
*
|
|
1960
|
+
* @returns The total number of files removed during this operation.
|
|
1961
|
+
* @throws {Error} If the directory cannot be read or files cannot be deleted.
|
|
1962
|
+
*
|
|
1963
|
+
* @example
|
|
1964
|
+
* ```typescript
|
|
1965
|
+
* const removedCount = await store.cleanExpiredFiles();
|
|
1966
|
+
* console.log(`Cleaned up ${removedCount} files.`);
|
|
1967
|
+
* ```
|
|
1968
|
+
*/
|
|
1969
|
+
cleanExpiredFiles(): Promise<number>;
|
|
1970
|
+
/**
|
|
1971
|
+
* Stops the cleanup daemon and releases associated resources.
|
|
1972
|
+
*
|
|
1973
|
+
* Should be called when the store is no longer needed to prevent memory leaks
|
|
1974
|
+
* and allow the process to exit gracefully.
|
|
1975
|
+
*
|
|
1976
|
+
* @example
|
|
1977
|
+
* ```typescript
|
|
1978
|
+
* await store.destroy();
|
|
1979
|
+
* ```
|
|
1980
|
+
*/
|
|
1981
|
+
destroy(): Promise<void>;
|
|
1982
|
+
/**
|
|
1983
|
+
* Ensures that the base storage directory exists.
|
|
1984
|
+
*
|
|
1985
|
+
* @throws {Error} If the directory cannot be created due to permissions or path conflicts.
|
|
1986
|
+
* @internal
|
|
1987
|
+
*/
|
|
1988
|
+
private ensureDir;
|
|
1989
|
+
/**
|
|
1990
|
+
* Resolves the filesystem path for a given cache key.
|
|
1991
|
+
*
|
|
1992
|
+
* @param key - Normalized cache key.
|
|
1993
|
+
* @returns Absolute path to the JSON file representing the key.
|
|
1994
|
+
* @internal
|
|
1995
|
+
*/
|
|
1996
|
+
private filePathForKey;
|
|
1997
|
+
/**
|
|
1998
|
+
* Retrieves an item from the cache by its key.
|
|
1999
|
+
*
|
|
2000
|
+
* If the item exists but has expired, it will be deleted and `null` will be returned.
|
|
2001
|
+
*
|
|
2002
|
+
* @param key - The unique identifier for the cache item.
|
|
2003
|
+
* @returns The cached value, or `null` if not found or expired.
|
|
2004
|
+
* @throws {Error} If the file exists but cannot be read or parsed.
|
|
2005
|
+
*
|
|
2006
|
+
* @example
|
|
2007
|
+
* ```typescript
|
|
2008
|
+
* const value = await store.get<string>('my-key');
|
|
2009
|
+
* ```
|
|
2010
|
+
*/
|
|
2011
|
+
get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
|
|
2012
|
+
/**
|
|
2013
|
+
* Stores an item in the cache with a specified expiration time.
|
|
2014
|
+
*
|
|
2015
|
+
* Uses an atomic write strategy (write to temp file then rename) to ensure
|
|
2016
|
+
* data integrity even if the process crashes during the write operation.
|
|
2017
|
+
*
|
|
2018
|
+
* @param key - The unique identifier for the cache item.
|
|
2019
|
+
* @param value - The data to be cached.
|
|
2020
|
+
* @param ttl - Time-to-live in seconds or a Date object for absolute expiration.
|
|
2021
|
+
* @throws {Error} If the file system is not writable or disk is full.
|
|
2022
|
+
*
|
|
2023
|
+
* @example
|
|
2024
|
+
* ```typescript
|
|
2025
|
+
* await store.put('settings', { theme: 'dark' }, 86400);
|
|
2026
|
+
* ```
|
|
2027
|
+
*/
|
|
2028
|
+
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
2029
|
+
/**
|
|
2030
|
+
* Stores an item in the cache only if it does not already exist.
|
|
2031
|
+
*
|
|
2032
|
+
* @param key - The unique identifier for the cache item.
|
|
2033
|
+
* @param value - The data to be cached.
|
|
2034
|
+
* @param ttl - Time-to-live in seconds or a Date object.
|
|
2035
|
+
* @returns `true` if the item was stored, `false` if it already existed.
|
|
2036
|
+
*
|
|
2037
|
+
* @example
|
|
2038
|
+
* ```typescript
|
|
2039
|
+
* const success = await store.add('unique-task', { status: 'pending' }, 60);
|
|
2040
|
+
* ```
|
|
2041
|
+
*/
|
|
2042
|
+
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
2043
|
+
/**
|
|
2044
|
+
* Removes an item from the cache by its key.
|
|
2045
|
+
*
|
|
2046
|
+
* @param key - The unique identifier for the cache item.
|
|
2047
|
+
* @returns `true` if the file was deleted or didn't exist, `false` on failure.
|
|
2048
|
+
*
|
|
2049
|
+
* @example
|
|
2050
|
+
* ```typescript
|
|
2051
|
+
* await store.forget('my-key');
|
|
2052
|
+
* ```
|
|
2053
|
+
*/
|
|
2054
|
+
forget(key: CacheKey): Promise<boolean>;
|
|
2055
|
+
/**
|
|
2056
|
+
* Removes all items from the cache directory.
|
|
2057
|
+
*
|
|
2058
|
+
* This operation deletes the entire cache directory and recreates it.
|
|
2059
|
+
* Use with caution as it is destructive and non-reversible.
|
|
2060
|
+
*
|
|
2061
|
+
* @throws {Error} If the directory cannot be removed or recreated.
|
|
2062
|
+
*
|
|
2063
|
+
* @example
|
|
2064
|
+
* ```typescript
|
|
2065
|
+
* await store.flush();
|
|
2066
|
+
* ```
|
|
2067
|
+
*/
|
|
2068
|
+
flush(): Promise<void>;
|
|
2069
|
+
/**
|
|
2070
|
+
* Increments the value of an integer item in the cache.
|
|
2071
|
+
*
|
|
2072
|
+
* If the key does not exist, it is initialized to 0 before incrementing.
|
|
2073
|
+
*
|
|
2074
|
+
* @param key - The unique identifier for the cache item.
|
|
2075
|
+
* @param value - The amount to increment by.
|
|
2076
|
+
* @returns The new value after incrementing.
|
|
2077
|
+
* @throws {Error} If the existing value is not a number.
|
|
2078
|
+
*
|
|
2079
|
+
* @example
|
|
2080
|
+
* ```typescript
|
|
2081
|
+
* const newCount = await store.increment('page-views');
|
|
2082
|
+
* ```
|
|
2083
|
+
*/
|
|
2084
|
+
increment(key: CacheKey, value?: number): Promise<number>;
|
|
2085
|
+
/**
|
|
2086
|
+
* Decrements the value of an integer item in the cache.
|
|
2087
|
+
*
|
|
2088
|
+
* If the key does not exist, it is initialized to 0 before decrementing.
|
|
2089
|
+
*
|
|
2090
|
+
* @param key - The unique identifier for the cache item.
|
|
2091
|
+
* @param value - The amount to decrement by.
|
|
2092
|
+
* @returns The new value after decrementing.
|
|
2093
|
+
* @throws {Error} If the existing value is not a number.
|
|
2094
|
+
*
|
|
2095
|
+
* @example
|
|
2096
|
+
* ```typescript
|
|
2097
|
+
* const newCount = await store.decrement('stock-level');
|
|
2098
|
+
* ```
|
|
2099
|
+
*/
|
|
2100
|
+
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
2101
|
+
/**
|
|
2102
|
+
* Retrieves the remaining time-to-live for a cache item in seconds.
|
|
2103
|
+
*
|
|
2104
|
+
* @param key - The unique identifier for the cache item.
|
|
2105
|
+
* @returns The seconds remaining until expiration, or `null` if it never expires or doesn't exist.
|
|
2106
|
+
*
|
|
2107
|
+
* @example
|
|
2108
|
+
* ```typescript
|
|
2109
|
+
* const secondsLeft = await store.ttl('session:123');
|
|
2110
|
+
* ```
|
|
2111
|
+
*/
|
|
2112
|
+
ttl(key: CacheKey): Promise<number | null>;
|
|
2113
|
+
/**
|
|
2114
|
+
* Creates a distributed lock instance based on the filesystem.
|
|
2115
|
+
*
|
|
2116
|
+
* Locks are implemented using atomic file creation (`wx` flag). They include
|
|
2117
|
+
* protection against stale locks by checking process IDs and expiration times.
|
|
2118
|
+
*
|
|
2119
|
+
* @param name - The unique name of the lock.
|
|
2120
|
+
* @param seconds - The duration in seconds for which the lock should be held.
|
|
2121
|
+
* @returns A `CacheLock` instance for managing the lock lifecycle.
|
|
2122
|
+
*
|
|
2123
|
+
* @example
|
|
2124
|
+
* ```typescript
|
|
2125
|
+
* const lock = store.lock('process-report', 60);
|
|
2126
|
+
* if (await lock.acquire()) {
|
|
2127
|
+
* try {
|
|
2128
|
+
* // Critical section
|
|
2129
|
+
* } finally {
|
|
2130
|
+
* await lock.release();
|
|
2131
|
+
* }
|
|
2132
|
+
* }
|
|
2133
|
+
* ```
|
|
2134
|
+
*/
|
|
2135
|
+
lock(name: string, seconds?: number): CacheLock;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
/**
|
|
2139
|
+
* Configuration options for the `MemoryStore`.
|
|
2140
|
+
*
|
|
2141
|
+
* Used to define the behavior of the in-memory cache, such as eviction policies.
|
|
2142
|
+
*
|
|
2143
|
+
* @public
|
|
2144
|
+
* @since 3.0.0
|
|
2145
|
+
*
|
|
2146
|
+
* @example
|
|
2147
|
+
* ```typescript
|
|
2148
|
+
* const options: MemoryStoreOptions = { maxItems: 500 };
|
|
2149
|
+
* ```
|
|
2150
|
+
*/
|
|
2151
|
+
type MemoryStoreOptions = {
|
|
2152
|
+
/**
|
|
2153
|
+
* Maximum number of items to keep in memory.
|
|
2154
|
+
*
|
|
2155
|
+
* When the limit is reached, the Least Recently Used (LRU) item is evicted.
|
|
2156
|
+
* Set to 0 or undefined for unlimited capacity (not recommended for production).
|
|
2157
|
+
*/
|
|
2158
|
+
maxItems?: number;
|
|
2159
|
+
};
|
|
2160
|
+
/**
|
|
2161
|
+
* Performance and usage statistics for the `MemoryStore`.
|
|
2162
|
+
*
|
|
2163
|
+
* Provides insights into cache efficiency and capacity management.
|
|
2164
|
+
*
|
|
2165
|
+
* @public
|
|
2166
|
+
* @since 3.0.0
|
|
2167
|
+
*
|
|
2168
|
+
* @example
|
|
2169
|
+
* ```typescript
|
|
2170
|
+
* const stats: MemoryCacheStats = {
|
|
2171
|
+
* hits: 100,
|
|
2172
|
+
* misses: 20,
|
|
2173
|
+
* hitRate: 0.83,
|
|
2174
|
+
* size: 500,
|
|
2175
|
+
* evictions: 5
|
|
2176
|
+
* };
|
|
2177
|
+
* ```
|
|
2178
|
+
*/
|
|
2179
|
+
type MemoryCacheStats = {
|
|
2180
|
+
/** Total number of successful cache lookups. */
|
|
2181
|
+
hits: number;
|
|
2182
|
+
/** Total number of failed cache lookups (key not found or expired). */
|
|
2183
|
+
misses: number;
|
|
2184
|
+
/**
|
|
2185
|
+
* The efficiency ratio of the cache.
|
|
2186
|
+
*
|
|
2187
|
+
* Calculated as hits / (hits + misses). Ranges from 0.0 to 1.0.
|
|
2188
|
+
*/
|
|
2189
|
+
hitRate: number;
|
|
2190
|
+
/** Current number of active items stored in the cache. */
|
|
2191
|
+
size: number;
|
|
2192
|
+
/** Total number of items removed to make room for new entries. */
|
|
2193
|
+
evictions: number;
|
|
2194
|
+
};
|
|
2195
|
+
/**
|
|
2196
|
+
* Fast, non-persistent in-memory cache implementation.
|
|
2197
|
+
*
|
|
2198
|
+
* `MemoryStore` provides a high-performance backend for the `CacheStore` interface.
|
|
2199
|
+
* It supports TTL-based expiration, LRU eviction, basic tagging for bulk invalidation,
|
|
2200
|
+
* and local mutex locking for atomic operations.
|
|
2201
|
+
*
|
|
2202
|
+
* @public
|
|
2203
|
+
* @since 3.0.0
|
|
2204
|
+
*
|
|
2205
|
+
* @example
|
|
2206
|
+
* ```typescript
|
|
2207
|
+
* const store = new MemoryStore({ maxItems: 1000 });
|
|
2208
|
+
* await store.put('user:1', { name: 'Alice' }, 3600);
|
|
2209
|
+
* const user = await store.get('user:1');
|
|
2210
|
+
* ```
|
|
2211
|
+
*/
|
|
2212
|
+
declare class MemoryStore implements CacheStore, TaggableStore {
|
|
2213
|
+
private entries;
|
|
2214
|
+
private locks;
|
|
2215
|
+
private stats;
|
|
2216
|
+
private tagToKeys;
|
|
2217
|
+
private keyToTags;
|
|
2218
|
+
/**
|
|
2219
|
+
* Creates a new MemoryStore instance.
|
|
2220
|
+
*
|
|
2221
|
+
* @param options - Configuration for capacity and eviction.
|
|
2222
|
+
*/
|
|
2223
|
+
constructor(options?: MemoryStoreOptions);
|
|
2224
|
+
/**
|
|
2225
|
+
* Retrieves current performance metrics.
|
|
2226
|
+
*
|
|
2227
|
+
* @returns A snapshot of hits, misses, size, and eviction counts.
|
|
2228
|
+
*
|
|
2229
|
+
* @example
|
|
2230
|
+
* ```typescript
|
|
2231
|
+
* const stats = store.getStats();
|
|
2232
|
+
* console.log(`Cache hit rate: ${stats.hitRate * 100}%`);
|
|
2233
|
+
* ```
|
|
2234
|
+
*/
|
|
2235
|
+
getStats(): MemoryCacheStats;
|
|
2236
|
+
private cleanupExpired;
|
|
2237
|
+
/**
|
|
2238
|
+
* Retrieves an item from the cache by its key.
|
|
2239
|
+
*
|
|
2240
|
+
* If the item is expired, it will be automatically removed and `null` will be returned.
|
|
2241
|
+
*
|
|
2242
|
+
* @param key - The unique identifier for the cached item.
|
|
2243
|
+
* @returns The cached value, or `null` if not found or expired.
|
|
2244
|
+
*
|
|
2245
|
+
* @example
|
|
2246
|
+
* ```typescript
|
|
2247
|
+
* const value = await store.get('my-key');
|
|
2248
|
+
* ```
|
|
2249
|
+
*/
|
|
2250
|
+
get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
|
|
2251
|
+
/**
|
|
2252
|
+
* Stores an item in the cache with a specific TTL.
|
|
2253
|
+
*
|
|
2254
|
+
* If the key already exists, it will be overwritten.
|
|
2255
|
+
*
|
|
2256
|
+
* @param key - The unique identifier for the item.
|
|
2257
|
+
* @param value - The data to store.
|
|
2258
|
+
* @param ttl - Time-to-live in seconds, or a Date object for absolute expiration.
|
|
2259
|
+
*
|
|
2260
|
+
* @example
|
|
2261
|
+
* ```typescript
|
|
2262
|
+
* await store.put('settings', { theme: 'dark' }, 3600);
|
|
2263
|
+
* ```
|
|
2264
|
+
*/
|
|
2265
|
+
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
2266
|
+
/**
|
|
2267
|
+
* Stores an item only if it does not already exist in the cache.
|
|
2268
|
+
*
|
|
2269
|
+
* @param key - The unique identifier for the item.
|
|
2270
|
+
* @param value - The data to store.
|
|
2271
|
+
* @param ttl - Time-to-live in seconds or absolute expiration.
|
|
2272
|
+
* @returns `true` if the item was added, `false` if it already existed.
|
|
2273
|
+
*
|
|
2274
|
+
* @example
|
|
2275
|
+
* ```typescript
|
|
2276
|
+
* const added = await store.add('unique-task', data, 60);
|
|
2277
|
+
* ```
|
|
2278
|
+
*/
|
|
2279
|
+
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
2280
|
+
/**
|
|
2281
|
+
* Removes an item from the cache.
|
|
2282
|
+
*
|
|
2283
|
+
* @param key - The unique identifier for the item to remove.
|
|
2284
|
+
* @returns `true` if the item existed and was removed, `false` otherwise.
|
|
2285
|
+
*
|
|
2286
|
+
* @example
|
|
2287
|
+
* ```typescript
|
|
2288
|
+
* await store.forget('user:session');
|
|
2289
|
+
* ```
|
|
2290
|
+
*/
|
|
2291
|
+
forget(key: CacheKey): Promise<boolean>;
|
|
2292
|
+
/**
|
|
2293
|
+
* Removes all items from the cache and resets all internal indexes.
|
|
2294
|
+
*
|
|
2295
|
+
* @example
|
|
2296
|
+
* ```typescript
|
|
2297
|
+
* await store.flush();
|
|
2298
|
+
* ```
|
|
2299
|
+
*/
|
|
2300
|
+
flush(): Promise<void>;
|
|
2301
|
+
/**
|
|
2302
|
+
* Increments the value of an item in the cache.
|
|
2303
|
+
*
|
|
2304
|
+
* If the key does not exist, it starts from 0.
|
|
2305
|
+
*
|
|
2306
|
+
* @param key - The identifier for the numeric value.
|
|
2307
|
+
* @param value - The amount to increment by (defaults to 1).
|
|
2308
|
+
* @returns The new incremented value.
|
|
2309
|
+
*
|
|
2310
|
+
* @example
|
|
2311
|
+
* ```typescript
|
|
2312
|
+
* const count = await store.increment('page_views');
|
|
2313
|
+
* ```
|
|
2314
|
+
*/
|
|
2315
|
+
increment(key: CacheKey, value?: number): Promise<number>;
|
|
2316
|
+
/**
|
|
2317
|
+
* Decrements the value of an item in the cache.
|
|
2318
|
+
*
|
|
2319
|
+
* @param key - The identifier for the numeric value.
|
|
2320
|
+
* @param value - The amount to decrement by (defaults to 1).
|
|
2321
|
+
* @returns The new decremented value.
|
|
2322
|
+
*
|
|
2323
|
+
* @example
|
|
2324
|
+
* ```typescript
|
|
2325
|
+
* const remaining = await store.decrement('stock_count', 5);
|
|
2326
|
+
* ```
|
|
2327
|
+
*/
|
|
2328
|
+
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
2329
|
+
/**
|
|
2330
|
+
* Gets the remaining time-to-live for a cached item.
|
|
2331
|
+
*
|
|
2332
|
+
* @param key - The identifier for the cached item.
|
|
2333
|
+
* @returns Remaining seconds, or `null` if the item has no expiration or does not exist.
|
|
2334
|
+
*
|
|
2335
|
+
* @example
|
|
2336
|
+
* ```typescript
|
|
2337
|
+
* const secondsLeft = await store.ttl('token');
|
|
2338
|
+
* ```
|
|
2339
|
+
*/
|
|
2340
|
+
ttl(key: CacheKey): Promise<number | null>;
|
|
2341
|
+
/**
|
|
2342
|
+
* Creates a lock instance for managing exclusive access to a resource.
|
|
2343
|
+
*
|
|
2344
|
+
* @param name - The name of the lock.
|
|
2345
|
+
* @param seconds - The duration the lock should be held (defaults to 10).
|
|
2346
|
+
* @returns A `CacheLock` instance.
|
|
2347
|
+
*
|
|
2348
|
+
* @example
|
|
2349
|
+
* ```typescript
|
|
2350
|
+
* const lock = store.lock('process-report', 30);
|
|
2351
|
+
* if (await lock.acquire()) {
|
|
2352
|
+
* try {
|
|
2353
|
+
* // Critical section
|
|
2354
|
+
* } finally {
|
|
2355
|
+
* await lock.release();
|
|
2356
|
+
* }
|
|
2357
|
+
* }
|
|
2358
|
+
* ```
|
|
2359
|
+
*/
|
|
2360
|
+
lock(name: string, seconds?: number): CacheLock;
|
|
2361
|
+
/**
|
|
2362
|
+
* Generates a tagged key for storage.
|
|
2363
|
+
*
|
|
2364
|
+
* Used internally to prefix keys with their associated tags.
|
|
2365
|
+
*
|
|
2366
|
+
* @param key - The original cache key.
|
|
2367
|
+
* @param tags - List of tags to associate with the key.
|
|
2368
|
+
* @returns A formatted string containing tags and the key.
|
|
2369
|
+
*/
|
|
2370
|
+
tagKey(key: string, tags: readonly string[]): string;
|
|
2371
|
+
/**
|
|
2372
|
+
* Indexes a tagged key for bulk invalidation.
|
|
2373
|
+
*
|
|
2374
|
+
* @param tags - The tags to index.
|
|
2375
|
+
* @param taggedKey - The full key (including tag prefix) to store.
|
|
2376
|
+
*/
|
|
2377
|
+
tagIndexAdd(tags: readonly string[], taggedKey: string): void;
|
|
2378
|
+
/**
|
|
2379
|
+
* Removes a key from the tag indexes.
|
|
2380
|
+
*
|
|
2381
|
+
* @param taggedKey - The key to remove from all tag sets.
|
|
2382
|
+
*/
|
|
2383
|
+
tagIndexRemove(taggedKey: string): void;
|
|
2384
|
+
/**
|
|
2385
|
+
* Invalidates all cache entries associated with any of the given tags.
|
|
2386
|
+
*
|
|
2387
|
+
* @param tags - The tags to flush.
|
|
2388
|
+
*
|
|
2389
|
+
* @example
|
|
2390
|
+
* ```typescript
|
|
2391
|
+
* await store.flushTags(['users', 'profiles']);
|
|
2392
|
+
* ```
|
|
2393
|
+
*/
|
|
2394
|
+
flushTags(tags: readonly string[]): Promise<void>;
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
/**
|
|
2398
|
+
* A "black-hole" cache implementation that discards all data.
|
|
2399
|
+
*
|
|
2400
|
+
* NullStore implements the `CacheStore` interface but performs no actual storage
|
|
2401
|
+
* or retrieval operations. It is primarily used to disable caching globally
|
|
2402
|
+
* without changing application logic, or as a mock in testing environments.
|
|
2403
|
+
*
|
|
2404
|
+
* @example
|
|
2405
|
+
* ```typescript
|
|
2406
|
+
* const store = new NullStore();
|
|
2407
|
+
* await store.put('key', 'value', 60);
|
|
2408
|
+
* const value = await store.get('key'); // always returns null
|
|
2409
|
+
* ```
|
|
2410
|
+
*
|
|
2411
|
+
* @public
|
|
2412
|
+
* @since 3.0.0
|
|
2413
|
+
*/
|
|
2414
|
+
declare class NullStore implements CacheStore {
|
|
2415
|
+
/**
|
|
2416
|
+
* Simulates a cache miss for any given key.
|
|
2417
|
+
*
|
|
2418
|
+
* @param _key - Identifier for the cached item.
|
|
2419
|
+
* @returns Always `null` regardless of requested key.
|
|
2420
|
+
*
|
|
2421
|
+
* @example
|
|
2422
|
+
* ```typescript
|
|
2423
|
+
* const value = await store.get('my-key');
|
|
2424
|
+
* ```
|
|
484
2425
|
*/
|
|
485
|
-
|
|
2426
|
+
get<T = unknown>(_key: CacheKey): Promise<CacheValue<T>>;
|
|
486
2427
|
/**
|
|
487
|
-
*
|
|
2428
|
+
* Discards the provided value instead of storing it.
|
|
488
2429
|
*
|
|
489
|
-
* @param
|
|
490
|
-
* @param
|
|
491
|
-
* @param
|
|
2430
|
+
* @param _key - The identifier for the item.
|
|
2431
|
+
* @param _value - The data to be cached.
|
|
2432
|
+
* @param _ttl - Time-to-live in seconds.
|
|
2433
|
+
* @returns Resolves immediately after discarding the data.
|
|
492
2434
|
*
|
|
493
2435
|
* @example
|
|
494
2436
|
* ```typescript
|
|
495
|
-
* await
|
|
2437
|
+
* await store.put('user:1', { id: 1 }, 3600);
|
|
496
2438
|
* ```
|
|
497
2439
|
*/
|
|
498
|
-
put(
|
|
499
|
-
/**
|
|
500
|
-
* Store an item in the cache (alias for put with optional TTL).
|
|
501
|
-
*/
|
|
502
|
-
set(key: string, value: unknown, ttl?: CacheTtl): Promise<void>;
|
|
2440
|
+
put(_key: CacheKey, _value: unknown, _ttl: CacheTtl): Promise<void>;
|
|
503
2441
|
/**
|
|
504
|
-
*
|
|
2442
|
+
* Simulates a failed attempt to add an item to the cache.
|
|
505
2443
|
*
|
|
506
|
-
*
|
|
507
|
-
|
|
508
|
-
add(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
509
|
-
/**
|
|
510
|
-
* Store an item in the cache indefinitely.
|
|
511
|
-
*/
|
|
512
|
-
forever(key: string, value: unknown): Promise<void>;
|
|
513
|
-
/**
|
|
514
|
-
* Get an item from the cache, or execute the callback and store the result.
|
|
2444
|
+
* Since NullStore does not store data, this method always indicates that
|
|
2445
|
+
* the item was not added.
|
|
515
2446
|
*
|
|
516
|
-
* @param
|
|
517
|
-
* @param
|
|
518
|
-
* @param
|
|
519
|
-
* @returns
|
|
2447
|
+
* @param _key - The identifier for the item.
|
|
2448
|
+
* @param _value - The data to be cached.
|
|
2449
|
+
* @param _ttl - Time-to-live in seconds.
|
|
2450
|
+
* @returns Always returns `false`.
|
|
520
2451
|
*
|
|
521
2452
|
* @example
|
|
522
2453
|
* ```typescript
|
|
523
|
-
* const
|
|
524
|
-
* return await db.findUser(1);
|
|
525
|
-
* });
|
|
2454
|
+
* const added = await store.add('key', 'value', 60); // false
|
|
526
2455
|
* ```
|
|
527
2456
|
*/
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Get an item from the cache, or execute the callback and store the result forever.
|
|
531
|
-
*/
|
|
532
|
-
rememberForever<T = unknown>(key: string, callback: () => Promise<T> | T): Promise<T>;
|
|
533
|
-
/**
|
|
534
|
-
* Retrieve multiple items from the cache.
|
|
535
|
-
*/
|
|
536
|
-
many<T = unknown>(keys: readonly string[]): Promise<Record<string, T | null>>;
|
|
537
|
-
/**
|
|
538
|
-
* Store multiple items in the cache.
|
|
539
|
-
*/
|
|
540
|
-
putMany(values: Record<string, unknown>, ttl: CacheTtl): Promise<void>;
|
|
2457
|
+
add(_key: CacheKey, _value: unknown, _ttl: CacheTtl): Promise<boolean>;
|
|
541
2458
|
/**
|
|
542
|
-
*
|
|
2459
|
+
* Simulates a failed attempt to remove an item from the cache.
|
|
543
2460
|
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
* @param
|
|
547
|
-
* @
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
*
|
|
552
|
-
|
|
553
|
-
pull<T = unknown>(key: string, defaultValue?: T): Promise<T | null>;
|
|
554
|
-
/**
|
|
555
|
-
* Remove an item from the cache.
|
|
556
|
-
*/
|
|
557
|
-
forget(key: string): Promise<boolean>;
|
|
558
|
-
/**
|
|
559
|
-
* Remove an item from the cache (alias for forget).
|
|
2461
|
+
* Since no data is ever stored, there is nothing to remove.
|
|
2462
|
+
*
|
|
2463
|
+
* @param _key - The identifier for the item to remove.
|
|
2464
|
+
* @returns Always returns `false`.
|
|
2465
|
+
*
|
|
2466
|
+
* @example
|
|
2467
|
+
* ```typescript
|
|
2468
|
+
* const forgotten = await store.forget('key'); // false
|
|
2469
|
+
* ```
|
|
560
2470
|
*/
|
|
561
|
-
|
|
2471
|
+
forget(_key: CacheKey): Promise<boolean>;
|
|
562
2472
|
/**
|
|
563
|
-
*
|
|
2473
|
+
* Performs a no-op flush operation.
|
|
2474
|
+
*
|
|
2475
|
+
* @returns Resolves immediately as there is no data to clear.
|
|
2476
|
+
*
|
|
2477
|
+
* @example
|
|
2478
|
+
* ```typescript
|
|
2479
|
+
* await store.flush();
|
|
2480
|
+
* ```
|
|
564
2481
|
*/
|
|
565
2482
|
flush(): Promise<void>;
|
|
566
2483
|
/**
|
|
567
|
-
*
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
*
|
|
572
|
-
*/
|
|
573
|
-
increment(key: string, value?: number): Promise<number>;
|
|
574
|
-
/**
|
|
575
|
-
* Decrement an integer item in the cache.
|
|
576
|
-
*/
|
|
577
|
-
decrement(key: string, value?: number): Promise<number>;
|
|
578
|
-
/**
|
|
579
|
-
* Get a lock instance.
|
|
2484
|
+
* Simulates an increment operation on a non-existent key.
|
|
2485
|
+
*
|
|
2486
|
+
* @param _key - The identifier for the numeric item.
|
|
2487
|
+
* @param _value - The amount to increment by.
|
|
2488
|
+
* @returns Always returns `0`.
|
|
580
2489
|
*
|
|
581
|
-
* @
|
|
582
|
-
*
|
|
583
|
-
*
|
|
2490
|
+
* @example
|
|
2491
|
+
* ```typescript
|
|
2492
|
+
* const newValue = await store.increment('counter', 1); // 0
|
|
2493
|
+
* ```
|
|
584
2494
|
*/
|
|
585
|
-
|
|
2495
|
+
increment(_key: CacheKey, _value?: number): Promise<number>;
|
|
586
2496
|
/**
|
|
587
|
-
*
|
|
2497
|
+
* Simulates a decrement operation on a non-existent key.
|
|
2498
|
+
*
|
|
2499
|
+
* @param _key - The identifier for the numeric item.
|
|
2500
|
+
* @param _value - The amount to decrement by.
|
|
2501
|
+
* @returns Always returns `0`.
|
|
2502
|
+
*
|
|
2503
|
+
* @example
|
|
2504
|
+
* ```typescript
|
|
2505
|
+
* const newValue = await store.decrement('counter', 1); // 0
|
|
2506
|
+
* ```
|
|
588
2507
|
*/
|
|
589
|
-
|
|
2508
|
+
decrement(_key: CacheKey, _value?: number): Promise<number>;
|
|
590
2509
|
}
|
|
591
2510
|
|
|
592
2511
|
/**
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
* @public
|
|
596
|
-
* @since 3.0.0
|
|
597
|
-
*/
|
|
598
|
-
type FileStoreOptions = {
|
|
599
|
-
/** The directory where cache files will be stored. */
|
|
600
|
-
directory: string;
|
|
601
|
-
};
|
|
602
|
-
/**
|
|
603
|
-
* FileStore implements the `CacheStore` interface using the local file system.
|
|
2512
|
+
* A CacheStore wrapper that predicts usage patterns and prefetches data.
|
|
604
2513
|
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
* application restarts without external dependencies.
|
|
2514
|
+
* This store observes access patterns (A -> B) and when A is requested,
|
|
2515
|
+
* automatically attempts to 'touch' B in the underlying store.
|
|
608
2516
|
*
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
|
|
612
|
-
declare class FileStore implements CacheStore {
|
|
613
|
-
private options;
|
|
614
|
-
constructor(options: FileStoreOptions);
|
|
615
|
-
private ensureDir;
|
|
616
|
-
private filePathForKey;
|
|
617
|
-
get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
|
|
618
|
-
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
619
|
-
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
620
|
-
forget(key: CacheKey): Promise<boolean>;
|
|
621
|
-
flush(): Promise<void>;
|
|
622
|
-
increment(key: CacheKey, value?: number): Promise<number>;
|
|
623
|
-
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
624
|
-
lock(name: string, seconds?: number): CacheLock;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
/**
|
|
628
|
-
* Options for configuring the `MemoryStore`.
|
|
2517
|
+
* If the underlying store is a TieredStore, this effectively promotes B
|
|
2518
|
+
* from the remote core (e.g. Redis) to the local cache (e.g. Memory)
|
|
2519
|
+
* before it is explicitly requested, reducing latency.
|
|
629
2520
|
*
|
|
630
2521
|
* @public
|
|
631
|
-
* @since 3.
|
|
632
|
-
*/
|
|
633
|
-
type MemoryStoreOptions = {
|
|
634
|
-
/** Maximum number of items to keep in memory. Uses LRU eviction. */
|
|
635
|
-
maxItems?: number;
|
|
636
|
-
};
|
|
637
|
-
/**
|
|
638
|
-
* MemoryStore implements the `CacheStore` interface using a Map.
|
|
639
|
-
*
|
|
640
|
-
* It provides a fast, non-persistent cache backend with support for
|
|
641
|
-
* TTL expiration, basic tagging, and local locking.
|
|
2522
|
+
* @since 3.2.0
|
|
642
2523
|
*
|
|
643
|
-
* @
|
|
644
|
-
*
|
|
2524
|
+
* @example
|
|
2525
|
+
* ```typescript
|
|
2526
|
+
* const store = new PredictiveStore(new TieredStore(l1, l2));
|
|
2527
|
+
* // Accessing 'a' will prefetch 'b' if a -> b pattern is detected
|
|
2528
|
+
* await store.get('a');
|
|
2529
|
+
* ```
|
|
645
2530
|
*/
|
|
646
|
-
declare class
|
|
647
|
-
private
|
|
648
|
-
private
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
constructor(options?: MemoryStoreOptions);
|
|
653
|
-
private touchLRU;
|
|
654
|
-
private pruneIfNeeded;
|
|
655
|
-
private cleanupExpired;
|
|
2531
|
+
declare class PredictiveStore implements CacheStore {
|
|
2532
|
+
private store;
|
|
2533
|
+
private predictor;
|
|
2534
|
+
constructor(store: CacheStore, options?: {
|
|
2535
|
+
predictor?: AccessPredictor;
|
|
2536
|
+
});
|
|
656
2537
|
get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
|
|
657
2538
|
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
658
2539
|
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
@@ -660,31 +2541,8 @@ declare class MemoryStore implements CacheStore, TaggableStore {
|
|
|
660
2541
|
flush(): Promise<void>;
|
|
661
2542
|
increment(key: CacheKey, value?: number): Promise<number>;
|
|
662
2543
|
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
663
|
-
lock(name: string, seconds?: number): CacheLock;
|
|
664
|
-
|
|
665
|
-
tagIndexAdd(tags: readonly string[], taggedKey: string): void;
|
|
666
|
-
tagIndexRemove(taggedKey: string): void;
|
|
667
|
-
flushTags(tags: readonly string[]): Promise<void>;
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* NullStore is a black-hole cache implementation.
|
|
672
|
-
*
|
|
673
|
-
* It implements the `CacheStore` interface but does not actually store or
|
|
674
|
-
* retrieve any data. This is useful for disabling caching entirely or for
|
|
675
|
-
* testing.
|
|
676
|
-
*
|
|
677
|
-
* @public
|
|
678
|
-
* @since 3.0.0
|
|
679
|
-
*/
|
|
680
|
-
declare class NullStore implements CacheStore {
|
|
681
|
-
get<T = unknown>(_key: CacheKey): Promise<CacheValue<T>>;
|
|
682
|
-
put(_key: CacheKey, _value: unknown, _ttl: CacheTtl): Promise<void>;
|
|
683
|
-
add(_key: CacheKey, _value: unknown, _ttl: CacheTtl): Promise<boolean>;
|
|
684
|
-
forget(_key: CacheKey): Promise<boolean>;
|
|
685
|
-
flush(): Promise<void>;
|
|
686
|
-
increment(_key: CacheKey, _value?: number): Promise<number>;
|
|
687
|
-
decrement(_key: CacheKey, _value?: number): Promise<number>;
|
|
2544
|
+
lock(name: string, seconds?: number): CacheLock | undefined;
|
|
2545
|
+
ttl(key: CacheKey): Promise<number | null>;
|
|
688
2546
|
}
|
|
689
2547
|
|
|
690
2548
|
/**
|
|
@@ -692,6 +2550,14 @@ declare class NullStore implements CacheStore {
|
|
|
692
2550
|
*
|
|
693
2551
|
* @public
|
|
694
2552
|
* @since 3.0.0
|
|
2553
|
+
*
|
|
2554
|
+
* @example
|
|
2555
|
+
* ```typescript
|
|
2556
|
+
* const options: RedisStoreOptions = {
|
|
2557
|
+
* connection: 'primary',
|
|
2558
|
+
* prefix: 'cache:'
|
|
2559
|
+
* };
|
|
2560
|
+
* ```
|
|
695
2561
|
*/
|
|
696
2562
|
type RedisStoreOptions = {
|
|
697
2563
|
/** The name of the Redis connection to use. */
|
|
@@ -710,22 +2576,92 @@ type RedisStoreOptions = {
|
|
|
710
2576
|
*/
|
|
711
2577
|
declare class RedisStore implements CacheStore, TaggableStore {
|
|
712
2578
|
private connectionName?;
|
|
2579
|
+
/**
|
|
2580
|
+
* Initialize a new RedisStore instance.
|
|
2581
|
+
*
|
|
2582
|
+
* @param options - Redis connection and prefix settings.
|
|
2583
|
+
*
|
|
2584
|
+
* @example
|
|
2585
|
+
* ```typescript
|
|
2586
|
+
* const store = new RedisStore({ prefix: 'app:' });
|
|
2587
|
+
* ```
|
|
2588
|
+
*/
|
|
713
2589
|
constructor(options?: RedisStoreOptions);
|
|
714
2590
|
private get client();
|
|
2591
|
+
/**
|
|
2592
|
+
* Retrieve an item from Redis.
|
|
2593
|
+
*
|
|
2594
|
+
* @param key - Unique cache key identifier.
|
|
2595
|
+
* @returns Parsed JSON value or null if missing/expired.
|
|
2596
|
+
* @throws {Error} If Redis connection fails or read errors occur.
|
|
2597
|
+
*/
|
|
715
2598
|
get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
|
|
2599
|
+
/**
|
|
2600
|
+
* Store an item in Redis.
|
|
2601
|
+
*
|
|
2602
|
+
* @param key - Unique cache key identifier.
|
|
2603
|
+
* @param value - Value to serialize and store.
|
|
2604
|
+
* @param ttl - Expiration duration.
|
|
2605
|
+
* @throws {Error} If Redis connection fails or write errors occur.
|
|
2606
|
+
*/
|
|
716
2607
|
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
717
2608
|
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
718
2609
|
forget(key: CacheKey): Promise<boolean>;
|
|
719
2610
|
flush(): Promise<void>;
|
|
720
2611
|
increment(key: CacheKey, value?: number): Promise<number>;
|
|
2612
|
+
/**
|
|
2613
|
+
* Decrement a numeric value in Redis.
|
|
2614
|
+
*
|
|
2615
|
+
* @param key - Unique cache key identifier.
|
|
2616
|
+
* @param value - Amount to subtract.
|
|
2617
|
+
* @returns Updated numeric value.
|
|
2618
|
+
* @throws {Error} If key is not numeric or Redis errors occur.
|
|
2619
|
+
*/
|
|
721
2620
|
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
722
2621
|
tagKey(key: string, _tags: readonly string[]): string;
|
|
723
2622
|
tagIndexAdd(tags: readonly string[], taggedKey: string): Promise<void>;
|
|
724
|
-
tagIndexRemove(
|
|
2623
|
+
tagIndexRemove(taggedKey: string): Promise<void>;
|
|
725
2624
|
flushTags(tags: readonly string[]): Promise<void>;
|
|
2625
|
+
ttl(key: CacheKey): Promise<number | null>;
|
|
726
2626
|
lock(name: string, seconds?: number): CacheLock;
|
|
727
2627
|
}
|
|
728
2628
|
|
|
2629
|
+
/**
|
|
2630
|
+
* A multi-level cache store that coordinates access between a fast local L1 cache
|
|
2631
|
+
* and a persistent remote L2 cache.
|
|
2632
|
+
*
|
|
2633
|
+
* It implements the read-through and write-through patterns to ensure that the
|
|
2634
|
+
* most frequently accessed data remains in the fastest storage tier.
|
|
2635
|
+
*
|
|
2636
|
+
* @public
|
|
2637
|
+
* @since 3.2.0
|
|
2638
|
+
*
|
|
2639
|
+
* @example
|
|
2640
|
+
* ```typescript
|
|
2641
|
+
* const store = new TieredStore(new MemoryStore(), new RedisStore());
|
|
2642
|
+
* await store.put('key', 'value', 3600);
|
|
2643
|
+
* ```
|
|
2644
|
+
*/
|
|
2645
|
+
declare class TieredStore implements CacheStore {
|
|
2646
|
+
private readonly local;
|
|
2647
|
+
private readonly remote;
|
|
2648
|
+
/**
|
|
2649
|
+
* Initializes a new TieredStore.
|
|
2650
|
+
*
|
|
2651
|
+
* @param local - The L1 cache store (usually MemoryStore).
|
|
2652
|
+
* @param remote - The L2 cache store (usually RedisStore or FileStore).
|
|
2653
|
+
*/
|
|
2654
|
+
constructor(local: CacheStore, remote: CacheStore);
|
|
2655
|
+
get<T = unknown>(key: CacheKey): Promise<T | null>;
|
|
2656
|
+
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
2657
|
+
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
2658
|
+
forget(key: CacheKey): Promise<boolean>;
|
|
2659
|
+
flush(): Promise<void>;
|
|
2660
|
+
increment(key: CacheKey, value?: number): Promise<number>;
|
|
2661
|
+
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
2662
|
+
ttl(key: CacheKey): Promise<number | null>;
|
|
2663
|
+
}
|
|
2664
|
+
|
|
729
2665
|
/**
|
|
730
2666
|
* Interface for a low-level cache storage provider.
|
|
731
2667
|
*
|
|
@@ -733,6 +2669,16 @@ declare class RedisStore implements CacheStore, TaggableStore {
|
|
|
733
2669
|
*
|
|
734
2670
|
* @public
|
|
735
2671
|
* @since 3.0.0
|
|
2672
|
+
*
|
|
2673
|
+
* @example
|
|
2674
|
+
* ```typescript
|
|
2675
|
+
* class MyProvider implements CacheStorageProvider {
|
|
2676
|
+
* async get(key) { ... }
|
|
2677
|
+
* async set(key, value, ttl) { ... }
|
|
2678
|
+
* async delete(key) { ... }
|
|
2679
|
+
* async clear() { ... }
|
|
2680
|
+
* }
|
|
2681
|
+
* ```
|
|
736
2682
|
*/
|
|
737
2683
|
interface CacheStorageProvider {
|
|
738
2684
|
/**
|
|
@@ -774,70 +2720,107 @@ type CacheProvider = CacheStorageProvider;
|
|
|
774
2720
|
*/
|
|
775
2721
|
interface CacheService {
|
|
776
2722
|
/**
|
|
777
|
-
*
|
|
2723
|
+
* Retrieves an item from the cache.
|
|
778
2724
|
*
|
|
779
|
-
* @param key - The unique
|
|
780
|
-
* @returns The cached value, or null if
|
|
2725
|
+
* @param key - The unique identifier for the cached item.
|
|
2726
|
+
* @returns The cached value, or `null` if the item is missing or has expired.
|
|
2727
|
+
*
|
|
2728
|
+
* @example
|
|
2729
|
+
* const user = await cache.get<User>('user:123');
|
|
781
2730
|
*/
|
|
782
2731
|
get<T = unknown>(key: string): Promise<T | null>;
|
|
783
2732
|
/**
|
|
784
|
-
*
|
|
2733
|
+
* Stores an item in the cache with an optional time-to-live.
|
|
785
2734
|
*
|
|
786
|
-
* @param key - The unique
|
|
787
|
-
* @param value - The value to store.
|
|
788
|
-
* @param ttl - Time-to-live in seconds or
|
|
2735
|
+
* @param key - The unique identifier for the item.
|
|
2736
|
+
* @param value - The value to store (must be serializable).
|
|
2737
|
+
* @param ttl - Time-to-live in seconds or as a `Date` object. If omitted, uses the default TTL.
|
|
2738
|
+
*
|
|
2739
|
+
* @example
|
|
2740
|
+
* await cache.set('key', 'value', 60);
|
|
789
2741
|
*/
|
|
790
2742
|
set(key: string, value: unknown, ttl?: CacheTtl): Promise<void>;
|
|
791
2743
|
/**
|
|
792
|
-
*
|
|
2744
|
+
* Checks if an item exists in the cache and has not expired.
|
|
793
2745
|
*
|
|
794
2746
|
* @param key - The cache key to check.
|
|
795
|
-
* @returns
|
|
2747
|
+
* @returns `true` if the item exists and is valid, `false` otherwise.
|
|
2748
|
+
*
|
|
2749
|
+
* @example
|
|
2750
|
+
* if (await cache.has('lock:processing')) {
|
|
2751
|
+
* return;
|
|
2752
|
+
* }
|
|
796
2753
|
*/
|
|
797
2754
|
has(key: string): Promise<boolean>;
|
|
798
2755
|
/**
|
|
799
|
-
*
|
|
2756
|
+
* Stores an item in the cache only if it does not already exist.
|
|
800
2757
|
*
|
|
801
|
-
* @param key - The unique
|
|
2758
|
+
* @param key - The unique identifier for the item.
|
|
802
2759
|
* @param value - The value to store.
|
|
803
|
-
* @param ttl - Time-to-live.
|
|
804
|
-
* @returns
|
|
2760
|
+
* @param ttl - Time-to-live in seconds or as a `Date` object.
|
|
2761
|
+
* @returns `true` if the item was added, `false` if it already existed.
|
|
2762
|
+
*
|
|
2763
|
+
* @example
|
|
2764
|
+
* const acquired = await cache.add('lock:job:1', true, 60);
|
|
805
2765
|
*/
|
|
806
2766
|
add(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
807
2767
|
/**
|
|
808
|
-
*
|
|
2768
|
+
* Removes an item from the cache.
|
|
809
2769
|
*
|
|
810
2770
|
* @param key - The cache key to remove.
|
|
811
|
-
* @returns
|
|
2771
|
+
* @returns `true` if the item was successfully removed, `false` otherwise.
|
|
2772
|
+
*
|
|
2773
|
+
* @example
|
|
2774
|
+
* await cache.delete('user:session:1');
|
|
812
2775
|
*/
|
|
813
2776
|
delete(key: string): Promise<boolean>;
|
|
814
2777
|
/**
|
|
815
|
-
*
|
|
2778
|
+
* Retrieves an item from the cache and then removes it.
|
|
816
2779
|
*
|
|
817
|
-
*
|
|
818
|
-
*
|
|
819
|
-
* @
|
|
2780
|
+
* This operation is atomic depending on the underlying driver support.
|
|
2781
|
+
*
|
|
2782
|
+
* @param key - The cache key to pull.
|
|
2783
|
+
* @param defaultValue - Optional value to return if the item is missing.
|
|
2784
|
+
* @returns The cached value (before deletion) or the default value.
|
|
2785
|
+
*
|
|
2786
|
+
* @example
|
|
2787
|
+
* const otp = await cache.pull('otp:user:1');
|
|
820
2788
|
*/
|
|
821
2789
|
pull<T = unknown>(key: string, defaultValue?: T): Promise<T | null>;
|
|
822
2790
|
/**
|
|
823
|
-
*
|
|
2791
|
+
* Retrieves an item from the cache, or executes the callback and stores the result.
|
|
2792
|
+
*
|
|
2793
|
+
* This is a "read-through" cache pattern.
|
|
824
2794
|
*
|
|
825
2795
|
* @param key - The cache key.
|
|
826
|
-
* @param ttl - Time-to-live if the item
|
|
827
|
-
* @param callback -
|
|
828
|
-
* @returns The cached or fetched value.
|
|
2796
|
+
* @param ttl - Time-to-live to use if the item is fetched from the callback.
|
|
2797
|
+
* @param callback - Function to retrieve the value if missing. Can be async.
|
|
2798
|
+
* @returns The cached or newly fetched value.
|
|
2799
|
+
*
|
|
2800
|
+
* @example
|
|
2801
|
+
* const user = await cache.remember('user:1', 300, async () => {
|
|
2802
|
+
* return await db.findUser(1);
|
|
2803
|
+
* });
|
|
829
2804
|
*/
|
|
830
2805
|
remember<T>(key: string, ttl: CacheTtl, callback: () => Promise<T> | T): Promise<T>;
|
|
831
2806
|
/**
|
|
832
|
-
*
|
|
2807
|
+
* Stores an item in the cache indefinitely (or until manually removed).
|
|
833
2808
|
*
|
|
834
2809
|
* @param key - The unique cache key.
|
|
835
|
-
* @param callback -
|
|
2810
|
+
* @param callback - Function to retrieve the value if missing.
|
|
836
2811
|
* @returns The cached or fetched value.
|
|
2812
|
+
*
|
|
2813
|
+
* @example
|
|
2814
|
+
* const settings = await cache.rememberForever('app:settings', () => loadSettings());
|
|
837
2815
|
*/
|
|
838
2816
|
rememberForever<T>(key: string, callback: () => Promise<T> | T): Promise<T>;
|
|
839
2817
|
/**
|
|
840
|
-
*
|
|
2818
|
+
* Clears all items from the cache.
|
|
2819
|
+
*
|
|
2820
|
+
* @warning This will wipe the entire cache storage for the current context.
|
|
2821
|
+
*
|
|
2822
|
+
* @example
|
|
2823
|
+
* await cache.clear();
|
|
841
2824
|
*/
|
|
842
2825
|
clear(): Promise<void>;
|
|
843
2826
|
}
|
|
@@ -890,27 +2873,57 @@ type OrbitCacheStoreConfig =
|
|
|
890
2873
|
| {
|
|
891
2874
|
driver: 'provider';
|
|
892
2875
|
provider: CacheStorageProvider;
|
|
2876
|
+
}
|
|
2877
|
+
/** Multi-level cache. */
|
|
2878
|
+
| {
|
|
2879
|
+
driver: 'tiered';
|
|
2880
|
+
local: string;
|
|
2881
|
+
remote: string;
|
|
2882
|
+
}
|
|
2883
|
+
/** Predictive cache that prefetches keys based on usage patterns. */
|
|
2884
|
+
| {
|
|
2885
|
+
driver: 'predictive';
|
|
2886
|
+
inner: string;
|
|
2887
|
+
maxNodes?: number;
|
|
2888
|
+
}
|
|
2889
|
+
/** Fault tolerance layer. */
|
|
2890
|
+
| {
|
|
2891
|
+
driver: 'circuit-breaker';
|
|
2892
|
+
primary: string;
|
|
2893
|
+
maxFailures?: number;
|
|
2894
|
+
resetTimeout?: number;
|
|
2895
|
+
fallback?: string;
|
|
893
2896
|
};
|
|
894
2897
|
/**
|
|
895
2898
|
* Options for configuring the `OrbitStasis` cache orbit.
|
|
896
2899
|
*
|
|
897
2900
|
* @public
|
|
898
2901
|
* @since 3.0.0
|
|
2902
|
+
*
|
|
2903
|
+
* @example
|
|
2904
|
+
* ```typescript
|
|
2905
|
+
* const options: OrbitCacheOptions = {
|
|
2906
|
+
* default: 'redis',
|
|
2907
|
+
* stores: {
|
|
2908
|
+
* redis: { driver: 'redis', connection: 'default' }
|
|
2909
|
+
* }
|
|
2910
|
+
* };
|
|
2911
|
+
* ```
|
|
899
2912
|
*/
|
|
900
2913
|
interface OrbitCacheOptions {
|
|
901
|
-
/** The key used to expose the cache manager in the request context. @
|
|
2914
|
+
/** The key used to expose the cache manager in the request context. @defaultValue 'cache' */
|
|
902
2915
|
exposeAs?: string;
|
|
903
|
-
/** The name of the default store to use for proxy methods. @
|
|
2916
|
+
/** The name of the default store to use for proxy methods. @defaultValue 'memory' */
|
|
904
2917
|
default?: string;
|
|
905
2918
|
/** Global prefix for all cache keys across all stores. */
|
|
906
2919
|
prefix?: string;
|
|
907
|
-
/** Default time-to-live for cache entries if not specified. @
|
|
2920
|
+
/** Default time-to-live for cache entries if not specified. @defaultValue 60 */
|
|
908
2921
|
defaultTtl?: CacheTtl;
|
|
909
2922
|
/** Map of named cache stores and their configurations. */
|
|
910
2923
|
stores?: Record<string, OrbitCacheStoreConfig>;
|
|
911
2924
|
/** How to handle cache events (hit/miss/etc) */
|
|
912
2925
|
eventsMode?: CacheEventMode;
|
|
913
|
-
/** Whether to throw if an event listener fails. @
|
|
2926
|
+
/** Whether to throw if an event listener fails. @defaultValue false */
|
|
914
2927
|
throwOnEventError?: boolean;
|
|
915
2928
|
/** Custom error handler for cache events. */
|
|
916
2929
|
onEventError?: (error: unknown, event: keyof CacheEvents, payload: {
|
|
@@ -951,6 +2964,18 @@ declare class OrbitStasis implements GravitoOrbit {
|
|
|
951
2964
|
install(core: PlanetCore): void;
|
|
952
2965
|
getCache(): CacheManager;
|
|
953
2966
|
}
|
|
2967
|
+
/**
|
|
2968
|
+
* Helper function to create and install the OrbitStasis orbit.
|
|
2969
|
+
*
|
|
2970
|
+
* @param core - Gravito PlanetCore instance.
|
|
2971
|
+
* @param options - Cache configuration options.
|
|
2972
|
+
* @returns Initialized CacheManager.
|
|
2973
|
+
*
|
|
2974
|
+
* @example
|
|
2975
|
+
* ```typescript
|
|
2976
|
+
* const cache = orbitCache(core, { default: 'memory' });
|
|
2977
|
+
* ```
|
|
2978
|
+
*/
|
|
954
2979
|
declare function orbitCache(core: PlanetCore, options?: OrbitCacheOptions): CacheManager;
|
|
955
2980
|
/** @deprecated Use OrbitStasis instead */
|
|
956
2981
|
declare const OrbitCache: typeof OrbitStasis;
|
|
@@ -961,4 +2986,4 @@ declare module '@gravito/core' {
|
|
|
961
2986
|
}
|
|
962
2987
|
}
|
|
963
2988
|
|
|
964
|
-
export { type CacheConfig, type CacheEventMode, type CacheEvents, type CacheKey, type CacheLock, CacheManager, type CacheProvider, CacheRepository, type CacheRepositoryOptions, type CacheService, type CacheStorageProvider, type CacheStore, type CacheTtl, type CacheValue, FileStore, type FileStoreOptions, LockTimeoutError, MemoryCacheProvider, MemoryStore, type MemoryStoreOptions, NullStore, OrbitCache, type OrbitCacheOptions, type OrbitCacheStoreConfig, OrbitStasis, RateLimiter, type RateLimiterResponse, RedisStore, type RedisStoreOptions, type StoreConfig, type TaggableStore, orbitCache as default, isExpired, isTaggableStore, normalizeCacheKey, sleep, ttlToExpiresAt };
|
|
2989
|
+
export { type AccessPredictor, type BlockOptions, type CacheConfig, type CacheEventMode, type CacheEvents, type CacheKey, type CacheLock, CacheManager, type CacheProvider, CacheRepository, type CacheRepositoryOptions, type CacheService, type CacheStorageProvider, type CacheStore, type CacheTtl, type CacheValue, type CircuitBreakerOptions, CircuitBreakerStore, type CircuitState, type CompressionOptions, FileStore, type FileStoreOptions, type FlexibleStats, LockTimeoutError, MarkovPredictor, MemoryCacheProvider, type MemoryCacheStats, MemoryStore, type MemoryStoreOptions, NullStore, OrbitCache, type OrbitCacheOptions, type OrbitCacheStoreConfig, OrbitStasis, PredictiveStore, type RateLimitInfo, RateLimiter, type RateLimiterResponse, RedisStore, type RedisStoreOptions, type StoreConfig, type TaggableStore, TieredStore, orbitCache as default, isExpired, isTaggableStore, normalizeCacheKey, sleep, ttlToExpiresAt };
|