layercache 1.2.0 → 1.2.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 +110 -8
- package/dist/chunk-46UH7LNM.js +312 -0
- package/dist/{chunk-BWM4MU2X.js → chunk-IXCMHVHP.js} +62 -56
- package/dist/chunk-ZMDB5KOK.js +159 -0
- package/dist/cli.cjs +170 -39
- package/dist/cli.js +57 -2
- package/dist/edge-DLpdQN0W.d.cts +672 -0
- package/dist/edge-DLpdQN0W.d.ts +672 -0
- package/dist/edge.cjs +399 -0
- package/dist/edge.d.cts +2 -0
- package/dist/edge.d.ts +2 -0
- package/dist/edge.js +14 -0
- package/dist/index.cjs +1173 -221
- package/dist/index.d.cts +51 -568
- package/dist/index.d.ts +51 -568
- package/dist/index.js +1005 -505
- package/package.json +8 -3
- package/packages/nestjs/dist/index.cjs +980 -370
- package/packages/nestjs/dist/index.d.cts +80 -0
- package/packages/nestjs/dist/index.d.ts +80 -0
- package/packages/nestjs/dist/index.js +968 -368
|
@@ -9,6 +9,7 @@ interface LayerTtlMap {
|
|
|
9
9
|
interface CacheWriteOptions {
|
|
10
10
|
tags?: string[];
|
|
11
11
|
ttl?: number | LayerTtlMap;
|
|
12
|
+
ttlPolicy?: CacheTtlPolicy;
|
|
12
13
|
negativeCache?: boolean;
|
|
13
14
|
negativeTtl?: number | LayerTtlMap;
|
|
14
15
|
staleWhileRevalidate?: number | LayerTtlMap;
|
|
@@ -18,6 +19,7 @@ interface CacheWriteOptions {
|
|
|
18
19
|
refreshAhead?: number | LayerTtlMap;
|
|
19
20
|
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
20
21
|
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
22
|
+
fetcherRateLimit?: CacheRateLimitOptions;
|
|
21
23
|
/**
|
|
22
24
|
* Optional predicate called with the fetcher's return value before caching.
|
|
23
25
|
* Return `false` to skip storing the value in the cache (but still return it
|
|
@@ -47,12 +49,20 @@ interface CacheLayer {
|
|
|
47
49
|
readonly isLocal?: boolean;
|
|
48
50
|
get<T>(key: string): Promise<T | null>;
|
|
49
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
|
+
*/
|
|
50
57
|
getMany?<T>(keys: string[]): Promise<Array<T | null>>;
|
|
58
|
+
setMany?(entries: CacheLayerSetManyEntry[]): Promise<void>;
|
|
51
59
|
set(key: string, value: unknown, ttl?: number): Promise<void>;
|
|
52
60
|
delete(key: string): Promise<void>;
|
|
53
61
|
clear(): Promise<void>;
|
|
54
62
|
deleteMany?(keys: string[]): Promise<void>;
|
|
55
63
|
keys?(): Promise<string[]>;
|
|
64
|
+
ping?(): Promise<boolean>;
|
|
65
|
+
dispose?(): Promise<void>;
|
|
56
66
|
/**
|
|
57
67
|
* Returns true if the key exists and has not expired.
|
|
58
68
|
* Implementations may omit this; CacheStack will fall back to `get()`.
|
|
@@ -121,11 +131,17 @@ interface CacheTagIndex {
|
|
|
121
131
|
track(key: string, tags: string[]): Promise<void>;
|
|
122
132
|
remove(key: string): Promise<void>;
|
|
123
133
|
keysForTag(tag: string): Promise<string[]>;
|
|
134
|
+
keysForPrefix?(prefix: string): Promise<string[]>;
|
|
124
135
|
/** Returns the tags associated with a specific key, or an empty array. */
|
|
125
136
|
tagsForKey?(key: string): Promise<string[]>;
|
|
126
137
|
matchPattern(pattern: string): Promise<string[]>;
|
|
127
138
|
clear(): Promise<void>;
|
|
128
139
|
}
|
|
140
|
+
interface CacheLayerSetManyEntry {
|
|
141
|
+
key: string;
|
|
142
|
+
value: unknown;
|
|
143
|
+
ttl?: number;
|
|
144
|
+
}
|
|
129
145
|
interface InvalidationMessage {
|
|
130
146
|
scope: 'key' | 'keys' | 'clear';
|
|
131
147
|
sourceId: string;
|
|
@@ -140,6 +156,7 @@ interface CacheSingleFlightExecutionOptions {
|
|
|
140
156
|
leaseMs: number;
|
|
141
157
|
waitTimeoutMs: number;
|
|
142
158
|
pollIntervalMs: number;
|
|
159
|
+
renewIntervalMs?: number;
|
|
143
160
|
}
|
|
144
161
|
interface CacheSingleFlightCoordinator {
|
|
145
162
|
execute<T>(key: string, options: CacheSingleFlightExecutionOptions, worker: () => Promise<T>, waiter: () => Promise<T>): Promise<T>;
|
|
@@ -150,6 +167,7 @@ interface CacheStackOptions {
|
|
|
150
167
|
stampedePrevention?: boolean;
|
|
151
168
|
invalidationBus?: InvalidationBus;
|
|
152
169
|
tagIndex?: CacheTagIndex;
|
|
170
|
+
generation?: number;
|
|
153
171
|
broadcastL1Invalidation?: boolean;
|
|
154
172
|
/**
|
|
155
173
|
* @deprecated Use `broadcastL1Invalidation` instead.
|
|
@@ -165,10 +183,14 @@ interface CacheStackOptions {
|
|
|
165
183
|
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
166
184
|
gracefulDegradation?: boolean | CacheDegradationOptions;
|
|
167
185
|
writePolicy?: 'strict' | 'best-effort';
|
|
186
|
+
writeStrategy?: 'write-through' | 'write-behind';
|
|
187
|
+
writeBehind?: CacheWriteBehindOptions;
|
|
188
|
+
fetcherRateLimit?: CacheRateLimitOptions;
|
|
168
189
|
singleFlightCoordinator?: CacheSingleFlightCoordinator;
|
|
169
190
|
singleFlightLeaseMs?: number;
|
|
170
191
|
singleFlightTimeoutMs?: number;
|
|
171
192
|
singleFlightPollMs?: number;
|
|
193
|
+
singleFlightRenewIntervalMs?: number;
|
|
172
194
|
/**
|
|
173
195
|
* Maximum number of entries in `accessProfiles` and `circuitBreakers` maps
|
|
174
196
|
* before the oldest entries are pruned. Prevents unbounded memory growth.
|
|
@@ -181,6 +203,13 @@ interface CacheAdaptiveTtlOptions {
|
|
|
181
203
|
step?: number | LayerTtlMap;
|
|
182
204
|
maxTtl?: number | LayerTtlMap;
|
|
183
205
|
}
|
|
206
|
+
type CacheTtlPolicy = 'until-midnight' | 'next-hour' | {
|
|
207
|
+
alignTo: number;
|
|
208
|
+
} | ((context: CacheTtlPolicyContext) => number | undefined);
|
|
209
|
+
interface CacheTtlPolicyContext {
|
|
210
|
+
key: string;
|
|
211
|
+
value: unknown;
|
|
212
|
+
}
|
|
184
213
|
interface CacheCircuitBreakerOptions {
|
|
185
214
|
failureThreshold?: number;
|
|
186
215
|
cooldownMs?: number;
|
|
@@ -188,6 +217,18 @@ interface CacheCircuitBreakerOptions {
|
|
|
188
217
|
interface CacheDegradationOptions {
|
|
189
218
|
retryAfterMs?: number;
|
|
190
219
|
}
|
|
220
|
+
interface CacheRateLimitOptions {
|
|
221
|
+
maxConcurrent?: number;
|
|
222
|
+
intervalMs?: number;
|
|
223
|
+
maxPerInterval?: number;
|
|
224
|
+
scope?: 'global' | 'key' | 'fetcher';
|
|
225
|
+
bucketKey?: string;
|
|
226
|
+
}
|
|
227
|
+
interface CacheWriteBehindOptions {
|
|
228
|
+
flushIntervalMs?: number;
|
|
229
|
+
batchSize?: number;
|
|
230
|
+
maxQueueSize?: number;
|
|
231
|
+
}
|
|
191
232
|
interface CacheWarmEntry<T = unknown> {
|
|
192
233
|
key: string;
|
|
193
234
|
fetcher: () => Promise<T>;
|
|
@@ -225,6 +266,12 @@ interface CacheStatsSnapshot {
|
|
|
225
266
|
}>;
|
|
226
267
|
backgroundRefreshes: number;
|
|
227
268
|
}
|
|
269
|
+
interface CacheHealthCheckResult {
|
|
270
|
+
layer: string;
|
|
271
|
+
healthy: boolean;
|
|
272
|
+
latencyMs: number;
|
|
273
|
+
error?: string;
|
|
274
|
+
}
|
|
228
275
|
/** Detailed inspection result for a single cache key. */
|
|
229
276
|
interface CacheInspectResult {
|
|
230
277
|
key: string;
|
|
@@ -293,6 +340,8 @@ interface CacheStackEvents {
|
|
|
293
340
|
declare class CacheNamespace {
|
|
294
341
|
private readonly cache;
|
|
295
342
|
private readonly prefix;
|
|
343
|
+
private static readonly metricsMutexes;
|
|
344
|
+
private metrics;
|
|
296
345
|
constructor(cache: CacheStack, prefix: string);
|
|
297
346
|
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
298
347
|
getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
@@ -309,7 +358,9 @@ declare class CacheNamespace {
|
|
|
309
358
|
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
310
359
|
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
311
360
|
invalidateByTag(tag: string): Promise<void>;
|
|
361
|
+
invalidateByTags(tags: string[], mode?: 'any' | 'all'): Promise<void>;
|
|
312
362
|
invalidateByPattern(pattern: string): Promise<void>;
|
|
363
|
+
invalidateByPrefix(prefix: string): Promise<void>;
|
|
313
364
|
/**
|
|
314
365
|
* Returns detailed metadata about a single cache key within this namespace.
|
|
315
366
|
*/
|
|
@@ -329,6 +380,8 @@ declare class CacheNamespace {
|
|
|
329
380
|
*/
|
|
330
381
|
namespace(childPrefix: string): CacheNamespace;
|
|
331
382
|
qualify(key: string): string;
|
|
383
|
+
private trackMetrics;
|
|
384
|
+
private getMetricsMutex;
|
|
332
385
|
}
|
|
333
386
|
|
|
334
387
|
/** Typed overloads for EventEmitter so callers get autocomplete on event names. */
|
|
@@ -336,6 +389,9 @@ interface CacheStack {
|
|
|
336
389
|
on<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
337
390
|
once<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
338
391
|
off<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
392
|
+
removeAllListeners<K extends keyof CacheStackEvents>(event?: K): this;
|
|
393
|
+
listeners<K extends keyof CacheStackEvents>(event: K): Array<(data: CacheStackEvents[K]) => void>;
|
|
394
|
+
listenerCount<K extends keyof CacheStackEvents>(event: K): number;
|
|
339
395
|
emit<K extends keyof CacheStackEvents>(event: K, data: CacheStackEvents[K]): boolean;
|
|
340
396
|
}
|
|
341
397
|
declare class CacheStack extends EventEmitter {
|
|
@@ -348,10 +404,15 @@ declare class CacheStack extends EventEmitter {
|
|
|
348
404
|
private unsubscribeInvalidation?;
|
|
349
405
|
private readonly logger;
|
|
350
406
|
private readonly tagIndex;
|
|
407
|
+
private readonly fetchRateLimiter;
|
|
351
408
|
private readonly backgroundRefreshes;
|
|
352
409
|
private readonly layerDegradedUntil;
|
|
353
410
|
private readonly ttlResolver;
|
|
354
411
|
private readonly circuitBreakerManager;
|
|
412
|
+
private currentGeneration?;
|
|
413
|
+
private readonly writeBehindQueue;
|
|
414
|
+
private writeBehindTimer?;
|
|
415
|
+
private writeBehindFlushPromise?;
|
|
355
416
|
private isDisconnecting;
|
|
356
417
|
private disconnectPromise?;
|
|
357
418
|
constructor(layers: CacheLayer[], options?: CacheStackOptions);
|
|
@@ -409,7 +470,9 @@ declare class CacheStack extends EventEmitter {
|
|
|
409
470
|
*/
|
|
410
471
|
namespace(prefix: string): CacheNamespace;
|
|
411
472
|
invalidateByTag(tag: string): Promise<void>;
|
|
473
|
+
invalidateByTags(tags: string[], mode?: 'any' | 'all'): Promise<void>;
|
|
412
474
|
invalidateByPattern(pattern: string): Promise<void>;
|
|
475
|
+
invalidateByPrefix(prefix: string): Promise<void>;
|
|
413
476
|
getMetrics(): CacheMetricsSnapshot;
|
|
414
477
|
getStats(): CacheStatsSnapshot;
|
|
415
478
|
resetMetrics(): void;
|
|
@@ -417,6 +480,8 @@ declare class CacheStack extends EventEmitter {
|
|
|
417
480
|
* Returns computed hit-rate statistics (overall and per-layer).
|
|
418
481
|
*/
|
|
419
482
|
getHitRate(): CacheHitRateSnapshot;
|
|
483
|
+
healthCheck(): Promise<CacheHealthCheckResult[]>;
|
|
484
|
+
bumpGeneration(nextGeneration?: number): number;
|
|
420
485
|
/**
|
|
421
486
|
* Returns detailed metadata about a single cache key: which layers contain it,
|
|
422
487
|
* remaining fresh/stale/error TTLs, and associated tags.
|
|
@@ -433,6 +498,7 @@ declare class CacheStack extends EventEmitter {
|
|
|
433
498
|
private waitForFreshValue;
|
|
434
499
|
private fetchAndPopulate;
|
|
435
500
|
private storeEntry;
|
|
501
|
+
private writeBatch;
|
|
436
502
|
private readFromLayers;
|
|
437
503
|
private readLayerEntry;
|
|
438
504
|
private backfill;
|
|
@@ -450,13 +516,27 @@ declare class CacheStack extends EventEmitter {
|
|
|
450
516
|
private formatError;
|
|
451
517
|
private sleep;
|
|
452
518
|
private shouldBroadcastL1Invalidation;
|
|
519
|
+
private initializeWriteBehind;
|
|
520
|
+
private shouldWriteBehind;
|
|
521
|
+
private enqueueWriteBehind;
|
|
522
|
+
private flushWriteBehindQueue;
|
|
523
|
+
private buildLayerSetEntry;
|
|
524
|
+
private intersectKeys;
|
|
525
|
+
private qualifyKey;
|
|
526
|
+
private qualifyPattern;
|
|
527
|
+
private stripQualifiedKey;
|
|
528
|
+
private generationPrefix;
|
|
453
529
|
private deleteKeysFromLayers;
|
|
454
530
|
private validateConfiguration;
|
|
455
531
|
private validateWriteOptions;
|
|
456
532
|
private validateLayerNumberOption;
|
|
457
533
|
private validatePositiveNumber;
|
|
534
|
+
private validateRateLimitOptions;
|
|
458
535
|
private validateNonNegativeNumber;
|
|
459
536
|
private validateCacheKey;
|
|
537
|
+
private validateTtlPolicy;
|
|
538
|
+
private assertActive;
|
|
539
|
+
private awaitStartup;
|
|
460
540
|
private serializeOptions;
|
|
461
541
|
private validateAdaptiveTtlOptions;
|
|
462
542
|
private validateCircuitBreakerOptions;
|
|
@@ -9,6 +9,7 @@ interface LayerTtlMap {
|
|
|
9
9
|
interface CacheWriteOptions {
|
|
10
10
|
tags?: string[];
|
|
11
11
|
ttl?: number | LayerTtlMap;
|
|
12
|
+
ttlPolicy?: CacheTtlPolicy;
|
|
12
13
|
negativeCache?: boolean;
|
|
13
14
|
negativeTtl?: number | LayerTtlMap;
|
|
14
15
|
staleWhileRevalidate?: number | LayerTtlMap;
|
|
@@ -18,6 +19,7 @@ interface CacheWriteOptions {
|
|
|
18
19
|
refreshAhead?: number | LayerTtlMap;
|
|
19
20
|
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
20
21
|
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
22
|
+
fetcherRateLimit?: CacheRateLimitOptions;
|
|
21
23
|
/**
|
|
22
24
|
* Optional predicate called with the fetcher's return value before caching.
|
|
23
25
|
* Return `false` to skip storing the value in the cache (but still return it
|
|
@@ -47,12 +49,20 @@ interface CacheLayer {
|
|
|
47
49
|
readonly isLocal?: boolean;
|
|
48
50
|
get<T>(key: string): Promise<T | null>;
|
|
49
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
|
+
*/
|
|
50
57
|
getMany?<T>(keys: string[]): Promise<Array<T | null>>;
|
|
58
|
+
setMany?(entries: CacheLayerSetManyEntry[]): Promise<void>;
|
|
51
59
|
set(key: string, value: unknown, ttl?: number): Promise<void>;
|
|
52
60
|
delete(key: string): Promise<void>;
|
|
53
61
|
clear(): Promise<void>;
|
|
54
62
|
deleteMany?(keys: string[]): Promise<void>;
|
|
55
63
|
keys?(): Promise<string[]>;
|
|
64
|
+
ping?(): Promise<boolean>;
|
|
65
|
+
dispose?(): Promise<void>;
|
|
56
66
|
/**
|
|
57
67
|
* Returns true if the key exists and has not expired.
|
|
58
68
|
* Implementations may omit this; CacheStack will fall back to `get()`.
|
|
@@ -121,11 +131,17 @@ interface CacheTagIndex {
|
|
|
121
131
|
track(key: string, tags: string[]): Promise<void>;
|
|
122
132
|
remove(key: string): Promise<void>;
|
|
123
133
|
keysForTag(tag: string): Promise<string[]>;
|
|
134
|
+
keysForPrefix?(prefix: string): Promise<string[]>;
|
|
124
135
|
/** Returns the tags associated with a specific key, or an empty array. */
|
|
125
136
|
tagsForKey?(key: string): Promise<string[]>;
|
|
126
137
|
matchPattern(pattern: string): Promise<string[]>;
|
|
127
138
|
clear(): Promise<void>;
|
|
128
139
|
}
|
|
140
|
+
interface CacheLayerSetManyEntry {
|
|
141
|
+
key: string;
|
|
142
|
+
value: unknown;
|
|
143
|
+
ttl?: number;
|
|
144
|
+
}
|
|
129
145
|
interface InvalidationMessage {
|
|
130
146
|
scope: 'key' | 'keys' | 'clear';
|
|
131
147
|
sourceId: string;
|
|
@@ -140,6 +156,7 @@ interface CacheSingleFlightExecutionOptions {
|
|
|
140
156
|
leaseMs: number;
|
|
141
157
|
waitTimeoutMs: number;
|
|
142
158
|
pollIntervalMs: number;
|
|
159
|
+
renewIntervalMs?: number;
|
|
143
160
|
}
|
|
144
161
|
interface CacheSingleFlightCoordinator {
|
|
145
162
|
execute<T>(key: string, options: CacheSingleFlightExecutionOptions, worker: () => Promise<T>, waiter: () => Promise<T>): Promise<T>;
|
|
@@ -150,6 +167,7 @@ interface CacheStackOptions {
|
|
|
150
167
|
stampedePrevention?: boolean;
|
|
151
168
|
invalidationBus?: InvalidationBus;
|
|
152
169
|
tagIndex?: CacheTagIndex;
|
|
170
|
+
generation?: number;
|
|
153
171
|
broadcastL1Invalidation?: boolean;
|
|
154
172
|
/**
|
|
155
173
|
* @deprecated Use `broadcastL1Invalidation` instead.
|
|
@@ -165,10 +183,14 @@ interface CacheStackOptions {
|
|
|
165
183
|
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
166
184
|
gracefulDegradation?: boolean | CacheDegradationOptions;
|
|
167
185
|
writePolicy?: 'strict' | 'best-effort';
|
|
186
|
+
writeStrategy?: 'write-through' | 'write-behind';
|
|
187
|
+
writeBehind?: CacheWriteBehindOptions;
|
|
188
|
+
fetcherRateLimit?: CacheRateLimitOptions;
|
|
168
189
|
singleFlightCoordinator?: CacheSingleFlightCoordinator;
|
|
169
190
|
singleFlightLeaseMs?: number;
|
|
170
191
|
singleFlightTimeoutMs?: number;
|
|
171
192
|
singleFlightPollMs?: number;
|
|
193
|
+
singleFlightRenewIntervalMs?: number;
|
|
172
194
|
/**
|
|
173
195
|
* Maximum number of entries in `accessProfiles` and `circuitBreakers` maps
|
|
174
196
|
* before the oldest entries are pruned. Prevents unbounded memory growth.
|
|
@@ -181,6 +203,13 @@ interface CacheAdaptiveTtlOptions {
|
|
|
181
203
|
step?: number | LayerTtlMap;
|
|
182
204
|
maxTtl?: number | LayerTtlMap;
|
|
183
205
|
}
|
|
206
|
+
type CacheTtlPolicy = 'until-midnight' | 'next-hour' | {
|
|
207
|
+
alignTo: number;
|
|
208
|
+
} | ((context: CacheTtlPolicyContext) => number | undefined);
|
|
209
|
+
interface CacheTtlPolicyContext {
|
|
210
|
+
key: string;
|
|
211
|
+
value: unknown;
|
|
212
|
+
}
|
|
184
213
|
interface CacheCircuitBreakerOptions {
|
|
185
214
|
failureThreshold?: number;
|
|
186
215
|
cooldownMs?: number;
|
|
@@ -188,6 +217,18 @@ interface CacheCircuitBreakerOptions {
|
|
|
188
217
|
interface CacheDegradationOptions {
|
|
189
218
|
retryAfterMs?: number;
|
|
190
219
|
}
|
|
220
|
+
interface CacheRateLimitOptions {
|
|
221
|
+
maxConcurrent?: number;
|
|
222
|
+
intervalMs?: number;
|
|
223
|
+
maxPerInterval?: number;
|
|
224
|
+
scope?: 'global' | 'key' | 'fetcher';
|
|
225
|
+
bucketKey?: string;
|
|
226
|
+
}
|
|
227
|
+
interface CacheWriteBehindOptions {
|
|
228
|
+
flushIntervalMs?: number;
|
|
229
|
+
batchSize?: number;
|
|
230
|
+
maxQueueSize?: number;
|
|
231
|
+
}
|
|
191
232
|
interface CacheWarmEntry<T = unknown> {
|
|
192
233
|
key: string;
|
|
193
234
|
fetcher: () => Promise<T>;
|
|
@@ -225,6 +266,12 @@ interface CacheStatsSnapshot {
|
|
|
225
266
|
}>;
|
|
226
267
|
backgroundRefreshes: number;
|
|
227
268
|
}
|
|
269
|
+
interface CacheHealthCheckResult {
|
|
270
|
+
layer: string;
|
|
271
|
+
healthy: boolean;
|
|
272
|
+
latencyMs: number;
|
|
273
|
+
error?: string;
|
|
274
|
+
}
|
|
228
275
|
/** Detailed inspection result for a single cache key. */
|
|
229
276
|
interface CacheInspectResult {
|
|
230
277
|
key: string;
|
|
@@ -293,6 +340,8 @@ interface CacheStackEvents {
|
|
|
293
340
|
declare class CacheNamespace {
|
|
294
341
|
private readonly cache;
|
|
295
342
|
private readonly prefix;
|
|
343
|
+
private static readonly metricsMutexes;
|
|
344
|
+
private metrics;
|
|
296
345
|
constructor(cache: CacheStack, prefix: string);
|
|
297
346
|
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
298
347
|
getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
@@ -309,7 +358,9 @@ declare class CacheNamespace {
|
|
|
309
358
|
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
310
359
|
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
311
360
|
invalidateByTag(tag: string): Promise<void>;
|
|
361
|
+
invalidateByTags(tags: string[], mode?: 'any' | 'all'): Promise<void>;
|
|
312
362
|
invalidateByPattern(pattern: string): Promise<void>;
|
|
363
|
+
invalidateByPrefix(prefix: string): Promise<void>;
|
|
313
364
|
/**
|
|
314
365
|
* Returns detailed metadata about a single cache key within this namespace.
|
|
315
366
|
*/
|
|
@@ -329,6 +380,8 @@ declare class CacheNamespace {
|
|
|
329
380
|
*/
|
|
330
381
|
namespace(childPrefix: string): CacheNamespace;
|
|
331
382
|
qualify(key: string): string;
|
|
383
|
+
private trackMetrics;
|
|
384
|
+
private getMetricsMutex;
|
|
332
385
|
}
|
|
333
386
|
|
|
334
387
|
/** Typed overloads for EventEmitter so callers get autocomplete on event names. */
|
|
@@ -336,6 +389,9 @@ interface CacheStack {
|
|
|
336
389
|
on<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
337
390
|
once<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
338
391
|
off<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
392
|
+
removeAllListeners<K extends keyof CacheStackEvents>(event?: K): this;
|
|
393
|
+
listeners<K extends keyof CacheStackEvents>(event: K): Array<(data: CacheStackEvents[K]) => void>;
|
|
394
|
+
listenerCount<K extends keyof CacheStackEvents>(event: K): number;
|
|
339
395
|
emit<K extends keyof CacheStackEvents>(event: K, data: CacheStackEvents[K]): boolean;
|
|
340
396
|
}
|
|
341
397
|
declare class CacheStack extends EventEmitter {
|
|
@@ -348,10 +404,15 @@ declare class CacheStack extends EventEmitter {
|
|
|
348
404
|
private unsubscribeInvalidation?;
|
|
349
405
|
private readonly logger;
|
|
350
406
|
private readonly tagIndex;
|
|
407
|
+
private readonly fetchRateLimiter;
|
|
351
408
|
private readonly backgroundRefreshes;
|
|
352
409
|
private readonly layerDegradedUntil;
|
|
353
410
|
private readonly ttlResolver;
|
|
354
411
|
private readonly circuitBreakerManager;
|
|
412
|
+
private currentGeneration?;
|
|
413
|
+
private readonly writeBehindQueue;
|
|
414
|
+
private writeBehindTimer?;
|
|
415
|
+
private writeBehindFlushPromise?;
|
|
355
416
|
private isDisconnecting;
|
|
356
417
|
private disconnectPromise?;
|
|
357
418
|
constructor(layers: CacheLayer[], options?: CacheStackOptions);
|
|
@@ -409,7 +470,9 @@ declare class CacheStack extends EventEmitter {
|
|
|
409
470
|
*/
|
|
410
471
|
namespace(prefix: string): CacheNamespace;
|
|
411
472
|
invalidateByTag(tag: string): Promise<void>;
|
|
473
|
+
invalidateByTags(tags: string[], mode?: 'any' | 'all'): Promise<void>;
|
|
412
474
|
invalidateByPattern(pattern: string): Promise<void>;
|
|
475
|
+
invalidateByPrefix(prefix: string): Promise<void>;
|
|
413
476
|
getMetrics(): CacheMetricsSnapshot;
|
|
414
477
|
getStats(): CacheStatsSnapshot;
|
|
415
478
|
resetMetrics(): void;
|
|
@@ -417,6 +480,8 @@ declare class CacheStack extends EventEmitter {
|
|
|
417
480
|
* Returns computed hit-rate statistics (overall and per-layer).
|
|
418
481
|
*/
|
|
419
482
|
getHitRate(): CacheHitRateSnapshot;
|
|
483
|
+
healthCheck(): Promise<CacheHealthCheckResult[]>;
|
|
484
|
+
bumpGeneration(nextGeneration?: number): number;
|
|
420
485
|
/**
|
|
421
486
|
* Returns detailed metadata about a single cache key: which layers contain it,
|
|
422
487
|
* remaining fresh/stale/error TTLs, and associated tags.
|
|
@@ -433,6 +498,7 @@ declare class CacheStack extends EventEmitter {
|
|
|
433
498
|
private waitForFreshValue;
|
|
434
499
|
private fetchAndPopulate;
|
|
435
500
|
private storeEntry;
|
|
501
|
+
private writeBatch;
|
|
436
502
|
private readFromLayers;
|
|
437
503
|
private readLayerEntry;
|
|
438
504
|
private backfill;
|
|
@@ -450,13 +516,27 @@ declare class CacheStack extends EventEmitter {
|
|
|
450
516
|
private formatError;
|
|
451
517
|
private sleep;
|
|
452
518
|
private shouldBroadcastL1Invalidation;
|
|
519
|
+
private initializeWriteBehind;
|
|
520
|
+
private shouldWriteBehind;
|
|
521
|
+
private enqueueWriteBehind;
|
|
522
|
+
private flushWriteBehindQueue;
|
|
523
|
+
private buildLayerSetEntry;
|
|
524
|
+
private intersectKeys;
|
|
525
|
+
private qualifyKey;
|
|
526
|
+
private qualifyPattern;
|
|
527
|
+
private stripQualifiedKey;
|
|
528
|
+
private generationPrefix;
|
|
453
529
|
private deleteKeysFromLayers;
|
|
454
530
|
private validateConfiguration;
|
|
455
531
|
private validateWriteOptions;
|
|
456
532
|
private validateLayerNumberOption;
|
|
457
533
|
private validatePositiveNumber;
|
|
534
|
+
private validateRateLimitOptions;
|
|
458
535
|
private validateNonNegativeNumber;
|
|
459
536
|
private validateCacheKey;
|
|
537
|
+
private validateTtlPolicy;
|
|
538
|
+
private assertActive;
|
|
539
|
+
private awaitStartup;
|
|
460
540
|
private serializeOptions;
|
|
461
541
|
private validateAdaptiveTtlOptions;
|
|
462
542
|
private validateCircuitBreakerOptions;
|