layercache 1.3.0 → 1.3.2
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 +2 -52
- package/dist/cli.cjs +23 -1
- package/dist/cli.js +23 -1
- package/dist/{edge-BXWTKlI1.d.cts → edge-CUHTP9Bc.d.cts} +2 -0
- package/dist/{edge-BXWTKlI1.d.ts → edge-CUHTP9Bc.d.ts} +2 -0
- package/dist/edge.d.cts +1 -1
- package/dist/edge.d.ts +1 -1
- package/dist/index.cjs +267 -31
- package/dist/index.d.cts +48 -3
- package/dist/index.d.ts +48 -3
- package/dist/index.js +265 -29
- package/package.json +2 -12
- package/examples/nestjs-module/app.module.ts +0 -15
- package/packages/nestjs/dist/index.cjs +0 -3906
- package/packages/nestjs/dist/index.d.cts +0 -627
- package/packages/nestjs/dist/index.d.ts +0 -627
- package/packages/nestjs/dist/index.js +0 -3869
|
@@ -1,627 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from 'node:events';
|
|
2
|
-
import { DynamicModule, Type } from '@nestjs/common';
|
|
3
|
-
|
|
4
|
-
declare const CACHE_STACK: unique symbol;
|
|
5
|
-
|
|
6
|
-
interface LayerTtlMap {
|
|
7
|
-
[layerName: string]: number | undefined;
|
|
8
|
-
}
|
|
9
|
-
interface CacheWriteOptions {
|
|
10
|
-
tags?: string[];
|
|
11
|
-
ttl?: number | LayerTtlMap;
|
|
12
|
-
ttlPolicy?: CacheTtlPolicy;
|
|
13
|
-
negativeCache?: boolean;
|
|
14
|
-
negativeTtl?: number | LayerTtlMap;
|
|
15
|
-
staleWhileRevalidate?: number | LayerTtlMap;
|
|
16
|
-
staleIfError?: number | LayerTtlMap;
|
|
17
|
-
ttlJitter?: number | LayerTtlMap;
|
|
18
|
-
slidingTtl?: boolean;
|
|
19
|
-
refreshAhead?: number | LayerTtlMap;
|
|
20
|
-
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
21
|
-
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
22
|
-
fetcherRateLimit?: CacheRateLimitOptions;
|
|
23
|
-
/**
|
|
24
|
-
* Optional predicate called with the fetcher's return value before caching.
|
|
25
|
-
* Return `false` to skip storing the value in the cache (but still return it
|
|
26
|
-
* to the caller). Useful for not caching failed API responses or empty results.
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* cache.get('key', fetchData, { shouldCache: (v) => v.status === 200 })
|
|
30
|
-
*/
|
|
31
|
-
shouldCache?: (value: unknown) => boolean;
|
|
32
|
-
}
|
|
33
|
-
interface CacheGetOptions extends CacheWriteOptions {
|
|
34
|
-
}
|
|
35
|
-
interface CacheMGetEntry<T> {
|
|
36
|
-
key: string;
|
|
37
|
-
fetch?: () => Promise<T>;
|
|
38
|
-
options?: CacheGetOptions;
|
|
39
|
-
}
|
|
40
|
-
interface CacheMSetEntry<T> {
|
|
41
|
-
key: string;
|
|
42
|
-
value: T;
|
|
43
|
-
options?: CacheWriteOptions;
|
|
44
|
-
}
|
|
45
|
-
/** Interface that all cache backend implementations must satisfy. */
|
|
46
|
-
interface CacheLayer {
|
|
47
|
-
readonly name: string;
|
|
48
|
-
readonly defaultTtl?: number;
|
|
49
|
-
readonly isLocal?: boolean;
|
|
50
|
-
get<T>(key: string): Promise<T | null>;
|
|
51
|
-
getEntry?<T = unknown>(key: string): Promise<T | null>;
|
|
52
|
-
/**
|
|
53
|
-
* Bulk read fast-path. Implementations should return raw stored entries using
|
|
54
|
-
* the same semantics as `getEntry()` so CacheStack can resolve envelopes,
|
|
55
|
-
* stale windows, and negative-cache markers consistently.
|
|
56
|
-
*/
|
|
57
|
-
getMany?<T>(keys: string[]): Promise<Array<T | null>>;
|
|
58
|
-
setMany?(entries: CacheLayerSetManyEntry[]): Promise<void>;
|
|
59
|
-
set(key: string, value: unknown, ttl?: number): Promise<void>;
|
|
60
|
-
delete(key: string): Promise<void>;
|
|
61
|
-
clear(): Promise<void>;
|
|
62
|
-
deleteMany?(keys: string[]): Promise<void>;
|
|
63
|
-
keys?(): Promise<string[]>;
|
|
64
|
-
forEachKey?(visitor: (key: string) => void | Promise<void>): Promise<void>;
|
|
65
|
-
ping?(): Promise<boolean>;
|
|
66
|
-
dispose?(): Promise<void>;
|
|
67
|
-
/**
|
|
68
|
-
* Returns true if the key exists and has not expired.
|
|
69
|
-
* Implementations may omit this; CacheStack will fall back to `get()`.
|
|
70
|
-
*/
|
|
71
|
-
has?(key: string): Promise<boolean>;
|
|
72
|
-
/**
|
|
73
|
-
* Returns the remaining TTL in seconds for the key, or null if the key
|
|
74
|
-
* does not exist, has no TTL, or has already expired.
|
|
75
|
-
* Implementations may omit this.
|
|
76
|
-
*/
|
|
77
|
-
ttl?(key: string): Promise<number | null>;
|
|
78
|
-
/**
|
|
79
|
-
* Returns the number of entries currently held by this layer.
|
|
80
|
-
* Implementations may omit this.
|
|
81
|
-
*/
|
|
82
|
-
size?(): Promise<number>;
|
|
83
|
-
}
|
|
84
|
-
/** Per-layer latency statistics (rolling window of sampled read durations). */
|
|
85
|
-
interface CacheLayerLatency {
|
|
86
|
-
/** Average read latency in milliseconds. */
|
|
87
|
-
avgMs: number;
|
|
88
|
-
/** Maximum observed read latency in milliseconds. */
|
|
89
|
-
maxMs: number;
|
|
90
|
-
/** Number of samples used to compute the statistics. */
|
|
91
|
-
count: number;
|
|
92
|
-
}
|
|
93
|
-
/** Snapshot of cumulative cache counters. */
|
|
94
|
-
interface CacheMetricsSnapshot {
|
|
95
|
-
hits: number;
|
|
96
|
-
misses: number;
|
|
97
|
-
fetches: number;
|
|
98
|
-
sets: number;
|
|
99
|
-
deletes: number;
|
|
100
|
-
backfills: number;
|
|
101
|
-
invalidations: number;
|
|
102
|
-
staleHits: number;
|
|
103
|
-
refreshes: number;
|
|
104
|
-
refreshErrors: number;
|
|
105
|
-
writeFailures: number;
|
|
106
|
-
singleFlightWaits: number;
|
|
107
|
-
negativeCacheHits: number;
|
|
108
|
-
circuitBreakerTrips: number;
|
|
109
|
-
degradedOperations: number;
|
|
110
|
-
hitsByLayer: Record<string, number>;
|
|
111
|
-
missesByLayer: Record<string, number>;
|
|
112
|
-
/** Per-layer read latency statistics (sampled from successful reads). */
|
|
113
|
-
latencyByLayer: Record<string, CacheLayerLatency>;
|
|
114
|
-
/** Timestamp (ms since epoch) when metrics were last reset. */
|
|
115
|
-
resetAt: number;
|
|
116
|
-
}
|
|
117
|
-
/** Computed hit-rate statistics derived from CacheMetricsSnapshot. */
|
|
118
|
-
interface CacheHitRateSnapshot {
|
|
119
|
-
/** Overall hit rate across all layers (0–1). */
|
|
120
|
-
overall: number;
|
|
121
|
-
/** Per-layer hit rates (0–1 each). */
|
|
122
|
-
byLayer: Record<string, number>;
|
|
123
|
-
}
|
|
124
|
-
interface CacheLogger {
|
|
125
|
-
debug?(message: string, context?: Record<string, unknown>): void;
|
|
126
|
-
info?(message: string, context?: Record<string, unknown>): void;
|
|
127
|
-
warn?(message: string, context?: Record<string, unknown>): void;
|
|
128
|
-
error?(message: string, context?: Record<string, unknown>): void;
|
|
129
|
-
}
|
|
130
|
-
interface CacheTagIndex {
|
|
131
|
-
touch(key: string): Promise<void>;
|
|
132
|
-
track(key: string, tags: string[]): Promise<void>;
|
|
133
|
-
remove(key: string): Promise<void>;
|
|
134
|
-
keysForTag(tag: string): Promise<string[]>;
|
|
135
|
-
forEachKeyForTag?(tag: string, visitor: (key: string) => void | Promise<void>): Promise<void>;
|
|
136
|
-
keysForPrefix?(prefix: string): Promise<string[]>;
|
|
137
|
-
forEachKeyForPrefix?(prefix: string, visitor: (key: string) => void | Promise<void>): Promise<void>;
|
|
138
|
-
/** Returns the tags associated with a specific key, or an empty array. */
|
|
139
|
-
tagsForKey?(key: string): Promise<string[]>;
|
|
140
|
-
matchPattern(pattern: string): Promise<string[]>;
|
|
141
|
-
forEachKeyMatchingPattern?(pattern: string, visitor: (key: string) => void | Promise<void>): Promise<void>;
|
|
142
|
-
clear(): Promise<void>;
|
|
143
|
-
}
|
|
144
|
-
interface CacheLayerSetManyEntry {
|
|
145
|
-
key: string;
|
|
146
|
-
value: unknown;
|
|
147
|
-
ttl?: number;
|
|
148
|
-
}
|
|
149
|
-
interface InvalidationMessage {
|
|
150
|
-
scope: 'key' | 'keys' | 'clear';
|
|
151
|
-
sourceId: string;
|
|
152
|
-
keys?: string[];
|
|
153
|
-
operation?: 'write' | 'delete' | 'invalidate' | 'clear';
|
|
154
|
-
}
|
|
155
|
-
interface InvalidationBus {
|
|
156
|
-
subscribe(handler: (message: InvalidationMessage) => Promise<void> | void): Promise<() => Promise<void> | void>;
|
|
157
|
-
publish(message: InvalidationMessage): Promise<void>;
|
|
158
|
-
}
|
|
159
|
-
interface CacheSingleFlightExecutionOptions {
|
|
160
|
-
leaseMs: number;
|
|
161
|
-
waitTimeoutMs: number;
|
|
162
|
-
pollIntervalMs: number;
|
|
163
|
-
renewIntervalMs?: number;
|
|
164
|
-
}
|
|
165
|
-
interface CacheSingleFlightCoordinator {
|
|
166
|
-
execute<T>(key: string, options: CacheSingleFlightExecutionOptions, worker: () => Promise<T>, waiter: () => Promise<T>): Promise<T>;
|
|
167
|
-
}
|
|
168
|
-
interface CacheStackOptions {
|
|
169
|
-
logger?: CacheLogger | boolean;
|
|
170
|
-
metrics?: boolean;
|
|
171
|
-
stampedePrevention?: boolean;
|
|
172
|
-
invalidationBus?: InvalidationBus;
|
|
173
|
-
tagIndex?: CacheTagIndex;
|
|
174
|
-
generation?: number;
|
|
175
|
-
generationCleanup?: boolean | CacheGenerationCleanupOptions;
|
|
176
|
-
broadcastL1Invalidation?: boolean;
|
|
177
|
-
/**
|
|
178
|
-
* @deprecated Use `broadcastL1Invalidation` instead.
|
|
179
|
-
*/
|
|
180
|
-
publishSetInvalidation?: boolean;
|
|
181
|
-
negativeCaching?: boolean;
|
|
182
|
-
negativeTtl?: number | LayerTtlMap;
|
|
183
|
-
staleWhileRevalidate?: number | LayerTtlMap;
|
|
184
|
-
staleIfError?: number | LayerTtlMap;
|
|
185
|
-
ttlJitter?: number | LayerTtlMap;
|
|
186
|
-
refreshAhead?: number | LayerTtlMap;
|
|
187
|
-
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
188
|
-
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
189
|
-
gracefulDegradation?: boolean | CacheDegradationOptions;
|
|
190
|
-
writePolicy?: 'strict' | 'best-effort';
|
|
191
|
-
writeStrategy?: 'write-through' | 'write-behind';
|
|
192
|
-
writeBehind?: CacheWriteBehindOptions;
|
|
193
|
-
fetcherRateLimit?: CacheRateLimitOptions;
|
|
194
|
-
backgroundRefreshTimeoutMs?: number;
|
|
195
|
-
singleFlightCoordinator?: CacheSingleFlightCoordinator;
|
|
196
|
-
singleFlightLeaseMs?: number;
|
|
197
|
-
singleFlightTimeoutMs?: number;
|
|
198
|
-
singleFlightPollMs?: number;
|
|
199
|
-
singleFlightRenewIntervalMs?: number;
|
|
200
|
-
snapshotBaseDir?: string | false;
|
|
201
|
-
snapshotMaxBytes?: number | false;
|
|
202
|
-
snapshotMaxEntries?: number | false;
|
|
203
|
-
invalidationMaxKeys?: number | false;
|
|
204
|
-
/**
|
|
205
|
-
* Maximum number of entries in `accessProfiles` and `circuitBreakers` maps
|
|
206
|
-
* before the oldest entries are pruned. Prevents unbounded memory growth.
|
|
207
|
-
* Defaults to 100 000.
|
|
208
|
-
*/
|
|
209
|
-
maxProfileEntries?: number;
|
|
210
|
-
}
|
|
211
|
-
interface CacheAdaptiveTtlOptions {
|
|
212
|
-
hotAfter?: number;
|
|
213
|
-
step?: number | LayerTtlMap;
|
|
214
|
-
maxTtl?: number | LayerTtlMap;
|
|
215
|
-
}
|
|
216
|
-
interface CacheGenerationCleanupOptions {
|
|
217
|
-
batchSize?: number;
|
|
218
|
-
}
|
|
219
|
-
type CacheTtlPolicy = 'until-midnight' | 'next-hour' | {
|
|
220
|
-
alignTo: number;
|
|
221
|
-
} | ((context: CacheTtlPolicyContext) => number | undefined);
|
|
222
|
-
interface CacheTtlPolicyContext {
|
|
223
|
-
key: string;
|
|
224
|
-
value: unknown;
|
|
225
|
-
}
|
|
226
|
-
interface CacheCircuitBreakerOptions {
|
|
227
|
-
failureThreshold?: number;
|
|
228
|
-
cooldownMs?: number;
|
|
229
|
-
}
|
|
230
|
-
interface CacheDegradationOptions {
|
|
231
|
-
retryAfterMs?: number;
|
|
232
|
-
}
|
|
233
|
-
interface CacheRateLimitOptions {
|
|
234
|
-
maxConcurrent?: number;
|
|
235
|
-
intervalMs?: number;
|
|
236
|
-
maxPerInterval?: number;
|
|
237
|
-
scope?: 'global' | 'key' | 'fetcher';
|
|
238
|
-
bucketKey?: string;
|
|
239
|
-
}
|
|
240
|
-
interface CacheWriteBehindOptions {
|
|
241
|
-
flushIntervalMs?: number;
|
|
242
|
-
batchSize?: number;
|
|
243
|
-
maxQueueSize?: number;
|
|
244
|
-
}
|
|
245
|
-
interface CacheWarmEntry<T = unknown> {
|
|
246
|
-
key: string;
|
|
247
|
-
fetcher: () => Promise<T>;
|
|
248
|
-
options?: CacheGetOptions;
|
|
249
|
-
priority?: number;
|
|
250
|
-
}
|
|
251
|
-
/** Options controlling the cache warm-up process. */
|
|
252
|
-
interface CacheWarmOptions {
|
|
253
|
-
concurrency?: number;
|
|
254
|
-
continueOnError?: boolean;
|
|
255
|
-
/** Called after each entry is processed (success or failure). */
|
|
256
|
-
onProgress?: (progress: CacheWarmProgress) => void;
|
|
257
|
-
}
|
|
258
|
-
/** Progress information delivered to `CacheWarmOptions.onProgress`. */
|
|
259
|
-
interface CacheWarmProgress {
|
|
260
|
-
completed: number;
|
|
261
|
-
total: number;
|
|
262
|
-
key: string;
|
|
263
|
-
success: boolean;
|
|
264
|
-
}
|
|
265
|
-
interface CacheWrapOptions<TArgs extends unknown[] = unknown[]> extends CacheGetOptions {
|
|
266
|
-
keyResolver?: (...args: TArgs) => string;
|
|
267
|
-
}
|
|
268
|
-
interface CacheSnapshotEntry {
|
|
269
|
-
key: string;
|
|
270
|
-
value: unknown;
|
|
271
|
-
ttl?: number;
|
|
272
|
-
}
|
|
273
|
-
interface CacheStatsSnapshot {
|
|
274
|
-
metrics: CacheMetricsSnapshot;
|
|
275
|
-
layers: Array<{
|
|
276
|
-
name: string;
|
|
277
|
-
isLocal: boolean;
|
|
278
|
-
degradedUntil: number | null;
|
|
279
|
-
}>;
|
|
280
|
-
backgroundRefreshes: number;
|
|
281
|
-
}
|
|
282
|
-
interface CacheHealthCheckResult {
|
|
283
|
-
layer: string;
|
|
284
|
-
healthy: boolean;
|
|
285
|
-
latencyMs: number;
|
|
286
|
-
error?: string;
|
|
287
|
-
}
|
|
288
|
-
/** Detailed inspection result for a single cache key. */
|
|
289
|
-
interface CacheInspectResult {
|
|
290
|
-
key: string;
|
|
291
|
-
/** Layers in which the key is currently stored (not expired). */
|
|
292
|
-
foundInLayers: string[];
|
|
293
|
-
/** Remaining fresh TTL in seconds, or null if no expiry or not an envelope. */
|
|
294
|
-
freshTtlSeconds: number | null;
|
|
295
|
-
/** Remaining stale-while-revalidate window in seconds, or null. */
|
|
296
|
-
staleTtlSeconds: number | null;
|
|
297
|
-
/** Remaining stale-if-error window in seconds, or null. */
|
|
298
|
-
errorTtlSeconds: number | null;
|
|
299
|
-
/** Whether the key is currently serving stale-while-revalidate. */
|
|
300
|
-
isStale: boolean;
|
|
301
|
-
/** Tags associated with this key (from the TagIndex). */
|
|
302
|
-
tags: string[];
|
|
303
|
-
}
|
|
304
|
-
/** All events emitted by CacheStack and their payload shapes. */
|
|
305
|
-
interface CacheStackEvents {
|
|
306
|
-
/** Fired on every cache hit. */
|
|
307
|
-
hit: {
|
|
308
|
-
key: string;
|
|
309
|
-
layer: string;
|
|
310
|
-
state: 'fresh' | 'stale-while-revalidate' | 'stale-if-error';
|
|
311
|
-
};
|
|
312
|
-
/** Fired on every cache miss before the fetcher runs. */
|
|
313
|
-
miss: {
|
|
314
|
-
key: string;
|
|
315
|
-
mode: string;
|
|
316
|
-
};
|
|
317
|
-
/** Fired after a value is stored in the cache. */
|
|
318
|
-
set: {
|
|
319
|
-
key: string;
|
|
320
|
-
kind: string;
|
|
321
|
-
tags?: string[];
|
|
322
|
-
};
|
|
323
|
-
/** Fired after one or more keys are deleted. */
|
|
324
|
-
delete: {
|
|
325
|
-
keys: string[];
|
|
326
|
-
};
|
|
327
|
-
/** Fired when a value is backfilled into a faster layer. */
|
|
328
|
-
backfill: {
|
|
329
|
-
key: string;
|
|
330
|
-
layer: string;
|
|
331
|
-
};
|
|
332
|
-
/** Fired when a stale value is returned to the caller. */
|
|
333
|
-
'stale-serve': {
|
|
334
|
-
key: string;
|
|
335
|
-
state: string;
|
|
336
|
-
layer: string;
|
|
337
|
-
};
|
|
338
|
-
/** Fired when a duplicate request is deduplicated in stampede prevention. */
|
|
339
|
-
'stampede-dedupe': {
|
|
340
|
-
key: string;
|
|
341
|
-
};
|
|
342
|
-
/** Fired after a key is successfully warmed. */
|
|
343
|
-
warm: {
|
|
344
|
-
key: string;
|
|
345
|
-
};
|
|
346
|
-
/** Fired immediately before a high-level cache operation begins. */
|
|
347
|
-
'operation-start': {
|
|
348
|
-
id: number;
|
|
349
|
-
name: string;
|
|
350
|
-
attributes?: Record<string, unknown>;
|
|
351
|
-
};
|
|
352
|
-
/** Fired after a high-level cache operation finishes. */
|
|
353
|
-
'operation-end': {
|
|
354
|
-
id: number;
|
|
355
|
-
name: string;
|
|
356
|
-
attributes?: Record<string, unknown>;
|
|
357
|
-
success: boolean;
|
|
358
|
-
result?: 'null';
|
|
359
|
-
error?: unknown;
|
|
360
|
-
};
|
|
361
|
-
/** Fired when an error occurs (layer failure, circuit breaker, etc.). */
|
|
362
|
-
error: {
|
|
363
|
-
operation: string;
|
|
364
|
-
[key: string]: unknown;
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
declare class CacheNamespace {
|
|
369
|
-
private readonly cache;
|
|
370
|
-
private readonly prefix;
|
|
371
|
-
private static readonly metricsMutexes;
|
|
372
|
-
private metrics;
|
|
373
|
-
constructor(cache: CacheStack, prefix: string);
|
|
374
|
-
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
375
|
-
getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
376
|
-
/**
|
|
377
|
-
* Like `get()`, but throws `CacheMissError` instead of returning `null`.
|
|
378
|
-
*/
|
|
379
|
-
getOrThrow<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T>;
|
|
380
|
-
has(key: string): Promise<boolean>;
|
|
381
|
-
ttl(key: string): Promise<number | null>;
|
|
382
|
-
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
383
|
-
delete(key: string): Promise<void>;
|
|
384
|
-
mdelete(keys: string[]): Promise<void>;
|
|
385
|
-
clear(): Promise<void>;
|
|
386
|
-
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
387
|
-
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
388
|
-
invalidateByTag(tag: string): Promise<void>;
|
|
389
|
-
invalidateByTags(tags: string[], mode?: 'any' | 'all'): Promise<void>;
|
|
390
|
-
invalidateByPattern(pattern: string): Promise<void>;
|
|
391
|
-
invalidateByPrefix(prefix: string): Promise<void>;
|
|
392
|
-
/**
|
|
393
|
-
* Returns detailed metadata about a single cache key within this namespace.
|
|
394
|
-
*/
|
|
395
|
-
inspect(key: string): Promise<CacheInspectResult | null>;
|
|
396
|
-
wrap<TArgs extends unknown[], TResult>(keyPrefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
397
|
-
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
398
|
-
getMetrics(): CacheMetricsSnapshot;
|
|
399
|
-
getHitRate(): CacheHitRateSnapshot;
|
|
400
|
-
/**
|
|
401
|
-
* Creates a nested namespace. Keys are prefixed with `parentPrefix:childPrefix:`.
|
|
402
|
-
*
|
|
403
|
-
* ```ts
|
|
404
|
-
* const tenant = cache.namespace('tenant:abc')
|
|
405
|
-
* const posts = tenant.namespace('posts')
|
|
406
|
-
* // keys become: "tenant:abc:posts:mykey"
|
|
407
|
-
* ```
|
|
408
|
-
*/
|
|
409
|
-
namespace(childPrefix: string): CacheNamespace;
|
|
410
|
-
qualify(key: string): string;
|
|
411
|
-
private qualifyTag;
|
|
412
|
-
private qualifyGetOptions;
|
|
413
|
-
private qualifyWrapOptions;
|
|
414
|
-
private qualifyWriteOptions;
|
|
415
|
-
private trackMetrics;
|
|
416
|
-
private getMetricsMutex;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
/** Typed overloads for EventEmitter so callers get autocomplete on event names. */
|
|
420
|
-
interface CacheStack {
|
|
421
|
-
on<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
422
|
-
once<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
423
|
-
off<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
424
|
-
removeAllListeners<K extends keyof CacheStackEvents>(event?: K): this;
|
|
425
|
-
listeners<K extends keyof CacheStackEvents>(event: K): Array<(data: CacheStackEvents[K]) => void>;
|
|
426
|
-
listenerCount<K extends keyof CacheStackEvents>(event: K): number;
|
|
427
|
-
emit<K extends keyof CacheStackEvents>(event: K, data: CacheStackEvents[K]): boolean;
|
|
428
|
-
}
|
|
429
|
-
declare class CacheStack extends EventEmitter {
|
|
430
|
-
private readonly layers;
|
|
431
|
-
private readonly options;
|
|
432
|
-
private readonly stampedeGuard;
|
|
433
|
-
private readonly metricsCollector;
|
|
434
|
-
private readonly instanceId;
|
|
435
|
-
private readonly startup;
|
|
436
|
-
private unsubscribeInvalidation?;
|
|
437
|
-
private readonly logger;
|
|
438
|
-
private readonly tagIndex;
|
|
439
|
-
private readonly keyDiscovery;
|
|
440
|
-
private readonly fetchRateLimiter;
|
|
441
|
-
private readonly snapshotSerializer;
|
|
442
|
-
private readonly invalidation;
|
|
443
|
-
private readonly layerWriter;
|
|
444
|
-
private readonly snapshots;
|
|
445
|
-
private readonly backgroundRefreshes;
|
|
446
|
-
private readonly backgroundRefreshAbort;
|
|
447
|
-
private readonly layerDegradedUntil;
|
|
448
|
-
private readonly maintenance;
|
|
449
|
-
private readonly ttlResolver;
|
|
450
|
-
private readonly circuitBreakerManager;
|
|
451
|
-
private nextOperationId;
|
|
452
|
-
private currentGeneration?;
|
|
453
|
-
private isDisconnecting;
|
|
454
|
-
private disconnectPromise?;
|
|
455
|
-
constructor(layers: CacheLayer[], options?: CacheStackOptions);
|
|
456
|
-
/**
|
|
457
|
-
* Read-through cache get.
|
|
458
|
-
* Returns the cached value if present and fresh, or invokes `fetcher` on a miss
|
|
459
|
-
* and stores the result across all layers. Returns `null` if the key is not found
|
|
460
|
-
* and no `fetcher` is provided.
|
|
461
|
-
*/
|
|
462
|
-
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
463
|
-
private getPrepared;
|
|
464
|
-
/**
|
|
465
|
-
* Alias for `get(key, fetcher, options)` — explicit get-or-set pattern.
|
|
466
|
-
* Fetches and caches the value if not already present.
|
|
467
|
-
*/
|
|
468
|
-
getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
469
|
-
/**
|
|
470
|
-
* Like `get()`, but throws `CacheMissError` instead of returning `null`.
|
|
471
|
-
* Useful when the value is expected to exist or the fetcher is expected to
|
|
472
|
-
* return non-null.
|
|
473
|
-
*/
|
|
474
|
-
getOrThrow<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T>;
|
|
475
|
-
/**
|
|
476
|
-
* Returns true if the given key exists and is not expired in any layer.
|
|
477
|
-
*/
|
|
478
|
-
has(key: string): Promise<boolean>;
|
|
479
|
-
/**
|
|
480
|
-
* Returns the remaining TTL in seconds for the key in the fastest layer
|
|
481
|
-
* that has it, or null if the key is not found / has no TTL.
|
|
482
|
-
*/
|
|
483
|
-
ttl(key: string): Promise<number | null>;
|
|
484
|
-
/**
|
|
485
|
-
* Stores a value in all cache layers. Overwrites any existing value.
|
|
486
|
-
*/
|
|
487
|
-
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
488
|
-
/**
|
|
489
|
-
* Deletes the key from all layers and publishes an invalidation message.
|
|
490
|
-
*/
|
|
491
|
-
delete(key: string): Promise<void>;
|
|
492
|
-
clear(): Promise<void>;
|
|
493
|
-
/**
|
|
494
|
-
* Deletes multiple keys at once. More efficient than calling `delete()` in a loop.
|
|
495
|
-
*/
|
|
496
|
-
mdelete(keys: string[]): Promise<void>;
|
|
497
|
-
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
498
|
-
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
499
|
-
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
500
|
-
/**
|
|
501
|
-
* Returns a cached version of `fetcher`. The cache key is derived from
|
|
502
|
-
* `prefix` plus the serialized arguments unless a `keyResolver` is provided.
|
|
503
|
-
*/
|
|
504
|
-
wrap<TArgs extends unknown[], TResult>(prefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
505
|
-
/**
|
|
506
|
-
* Creates a `CacheNamespace` that automatically prefixes all keys with
|
|
507
|
-
* `prefix:`. Useful for multi-tenant or module-level isolation.
|
|
508
|
-
*/
|
|
509
|
-
namespace(prefix: string): CacheNamespace;
|
|
510
|
-
invalidateByTag(tag: string): Promise<void>;
|
|
511
|
-
invalidateByTags(tags: string[], mode?: 'any' | 'all'): Promise<void>;
|
|
512
|
-
invalidateByPattern(pattern: string): Promise<void>;
|
|
513
|
-
invalidateByPrefix(prefix: string): Promise<void>;
|
|
514
|
-
getMetrics(): CacheMetricsSnapshot;
|
|
515
|
-
getStats(): CacheStatsSnapshot;
|
|
516
|
-
resetMetrics(): void;
|
|
517
|
-
/**
|
|
518
|
-
* Returns computed hit-rate statistics (overall and per-layer).
|
|
519
|
-
*/
|
|
520
|
-
getHitRate(): CacheHitRateSnapshot;
|
|
521
|
-
healthCheck(): Promise<CacheHealthCheckResult[]>;
|
|
522
|
-
/**
|
|
523
|
-
* Rotates the active generation prefix used for all future cache keys.
|
|
524
|
-
* Previous-generation keys remain in the underlying layers until they expire,
|
|
525
|
-
* unless `generationCleanup` is enabled to prune them in the background.
|
|
526
|
-
*/
|
|
527
|
-
bumpGeneration(nextGeneration?: number): number;
|
|
528
|
-
/**
|
|
529
|
-
* Returns detailed metadata about a single cache key: which layers contain it,
|
|
530
|
-
* remaining fresh/stale/error TTLs, and associated tags.
|
|
531
|
-
* Returns `null` if the key does not exist in any layer.
|
|
532
|
-
*/
|
|
533
|
-
inspect(key: string): Promise<CacheInspectResult | null>;
|
|
534
|
-
exportState(): Promise<CacheSnapshotEntry[]>;
|
|
535
|
-
importState(entries: CacheSnapshotEntry[]): Promise<void>;
|
|
536
|
-
persistToFile(filePath: string): Promise<void>;
|
|
537
|
-
restoreFromFile(filePath: string): Promise<void>;
|
|
538
|
-
disconnect(): Promise<void>;
|
|
539
|
-
private initialize;
|
|
540
|
-
private fetchWithGuards;
|
|
541
|
-
private waitForFreshValue;
|
|
542
|
-
private fetchAndPopulate;
|
|
543
|
-
private storeEntry;
|
|
544
|
-
private writeBatch;
|
|
545
|
-
private readFromLayers;
|
|
546
|
-
private readLayerEntry;
|
|
547
|
-
private backfill;
|
|
548
|
-
private resolveFreshTtl;
|
|
549
|
-
private resolveLayerSeconds;
|
|
550
|
-
private shouldNegativeCache;
|
|
551
|
-
private scheduleBackgroundRefresh;
|
|
552
|
-
private runBackgroundRefresh;
|
|
553
|
-
private resolveSingleFlightOptions;
|
|
554
|
-
private deleteKeys;
|
|
555
|
-
private publishInvalidation;
|
|
556
|
-
private handleInvalidationMessage;
|
|
557
|
-
private getTagsForKey;
|
|
558
|
-
private formatError;
|
|
559
|
-
private sleep;
|
|
560
|
-
private withTimeout;
|
|
561
|
-
private shouldBroadcastL1Invalidation;
|
|
562
|
-
private observeOperation;
|
|
563
|
-
private scheduleGenerationCleanup;
|
|
564
|
-
private cleanupGeneration;
|
|
565
|
-
private initializeWriteBehind;
|
|
566
|
-
private shouldWriteBehind;
|
|
567
|
-
private enqueueWriteBehind;
|
|
568
|
-
private flushWriteBehindQueue;
|
|
569
|
-
private runWriteBehindBatch;
|
|
570
|
-
private qualifyKey;
|
|
571
|
-
private qualifyPattern;
|
|
572
|
-
private stripQualifiedKey;
|
|
573
|
-
private validateConfiguration;
|
|
574
|
-
private validateWriteOptions;
|
|
575
|
-
private assertActive;
|
|
576
|
-
private awaitStartup;
|
|
577
|
-
private applyFreshReadPolicies;
|
|
578
|
-
private shouldSkipLayer;
|
|
579
|
-
private handleLayerFailure;
|
|
580
|
-
private reportRecoverableLayerFailure;
|
|
581
|
-
private isGracefulDegradationEnabled;
|
|
582
|
-
private recordCircuitFailure;
|
|
583
|
-
private isNegativeStoredValue;
|
|
584
|
-
private emitError;
|
|
585
|
-
private snapshotMaxBytes;
|
|
586
|
-
private snapshotMaxEntries;
|
|
587
|
-
private invalidationMaxKeys;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
interface CacheableOptions<TArgs extends unknown[]> extends CacheWrapOptions<TArgs> {
|
|
591
|
-
cache: (instance: unknown) => CacheStack;
|
|
592
|
-
prefix?: string;
|
|
593
|
-
}
|
|
594
|
-
declare function Cacheable<TArgs extends unknown[] = unknown[]>(options: CacheableOptions<TArgs>): MethodDecorator;
|
|
595
|
-
|
|
596
|
-
interface CacheStackModuleOptions {
|
|
597
|
-
layers: CacheLayer[];
|
|
598
|
-
bridgeOptions?: CacheStackOptions;
|
|
599
|
-
}
|
|
600
|
-
interface CacheStackModuleAsyncOptions {
|
|
601
|
-
/**
|
|
602
|
-
* Tokens to inject into the `useFactory` function.
|
|
603
|
-
*/
|
|
604
|
-
inject?: Array<Type | string | symbol>;
|
|
605
|
-
/**
|
|
606
|
-
* Async factory function that returns `CacheStackModuleOptions`.
|
|
607
|
-
* Useful when the Redis client or other dependencies must be resolved
|
|
608
|
-
* from the NestJS DI container first.
|
|
609
|
-
*
|
|
610
|
-
* ```ts
|
|
611
|
-
* CacheStackModule.forRootAsync({
|
|
612
|
-
* inject: [ConfigService],
|
|
613
|
-
* useFactory: (config: ConfigService) => ({
|
|
614
|
-
* layers: [new MemoryLayer(), new RedisLayer({ client: createRedis(config) })],
|
|
615
|
-
* })
|
|
616
|
-
* })
|
|
617
|
-
* ```
|
|
618
|
-
*/
|
|
619
|
-
useFactory: (...args: unknown[]) => CacheStackModuleOptions | Promise<CacheStackModuleOptions>;
|
|
620
|
-
}
|
|
621
|
-
declare const InjectCacheStack: () => ParameterDecorator & PropertyDecorator;
|
|
622
|
-
declare class CacheStackModule {
|
|
623
|
-
static forRoot(options: CacheStackModuleOptions): DynamicModule;
|
|
624
|
-
static forRootAsync(options: CacheStackModuleAsyncOptions): DynamicModule;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
export { CACHE_STACK, CacheStackModule, type CacheStackModuleOptions, Cacheable, InjectCacheStack };
|