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
package/dist/index.d.cts
CHANGED
|
@@ -1,505 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { I as InvalidationBus, C as CacheLogger, a as InvalidationMessage, b as CacheTagIndex, c as CacheStack, d as CacheWrapOptions, e as CacheGetOptions, f as CacheLayer, g as CacheSerializer, h as CacheLayerSetManyEntry, i as CacheSingleFlightCoordinator, j as CacheSingleFlightExecutionOptions } from './edge-DLpdQN0W.cjs';
|
|
2
|
+
export { k as CacheAdaptiveTtlOptions, l as CacheCircuitBreakerOptions, m as CacheDegradationOptions, n as CacheHealthCheckResult, o as CacheHitRateSnapshot, p as CacheInspectResult, q as CacheLayerLatency, r as CacheMGetEntry, s as CacheMSetEntry, t as CacheMetricsSnapshot, u as CacheMissError, v as CacheNamespace, w as CacheRateLimitOptions, x as CacheSnapshotEntry, y as CacheStackEvents, z as CacheStackOptions, A as CacheStatsSnapshot, B as CacheTtlPolicy, D as CacheTtlPolicyContext, E as CacheWarmEntry, F as CacheWarmOptions, G as CacheWarmProgress, H as CacheWriteBehindOptions, J as CacheWriteOptions, K as EvictionPolicy, L as LayerTtlMap, M as MemoryLayer, N as MemoryLayerOptions, O as MemoryLayerSnapshotEntry, P as PatternMatcher, T as TagIndex, Q as createHonoCacheMiddleware } from './edge-DLpdQN0W.cjs';
|
|
2
3
|
import Redis from 'ioredis';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Thrown by `CacheStack.getOrThrow()` when no value is found for the given key
|
|
6
|
-
* (fetcher returned null or no fetcher was provided and the key is absent).
|
|
7
|
-
*/
|
|
8
|
-
declare class CacheMissError extends Error {
|
|
9
|
-
readonly key: string;
|
|
10
|
-
constructor(key: string);
|
|
11
|
-
}
|
|
12
|
-
interface LayerTtlMap {
|
|
13
|
-
[layerName: string]: number | undefined;
|
|
14
|
-
}
|
|
15
|
-
interface CacheWriteOptions {
|
|
16
|
-
tags?: string[];
|
|
17
|
-
ttl?: number | LayerTtlMap;
|
|
18
|
-
negativeCache?: boolean;
|
|
19
|
-
negativeTtl?: number | LayerTtlMap;
|
|
20
|
-
staleWhileRevalidate?: number | LayerTtlMap;
|
|
21
|
-
staleIfError?: number | LayerTtlMap;
|
|
22
|
-
ttlJitter?: number | LayerTtlMap;
|
|
23
|
-
slidingTtl?: boolean;
|
|
24
|
-
refreshAhead?: number | LayerTtlMap;
|
|
25
|
-
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
26
|
-
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
27
|
-
/**
|
|
28
|
-
* Optional predicate called with the fetcher's return value before caching.
|
|
29
|
-
* Return `false` to skip storing the value in the cache (but still return it
|
|
30
|
-
* to the caller). Useful for not caching failed API responses or empty results.
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* cache.get('key', fetchData, { shouldCache: (v) => v.status === 200 })
|
|
34
|
-
*/
|
|
35
|
-
shouldCache?: (value: unknown) => boolean;
|
|
36
|
-
}
|
|
37
|
-
interface CacheGetOptions extends CacheWriteOptions {
|
|
38
|
-
}
|
|
39
|
-
interface CacheMGetEntry<T> {
|
|
40
|
-
key: string;
|
|
41
|
-
fetch?: () => Promise<T>;
|
|
42
|
-
options?: CacheGetOptions;
|
|
43
|
-
}
|
|
44
|
-
interface CacheMSetEntry<T> {
|
|
45
|
-
key: string;
|
|
46
|
-
value: T;
|
|
47
|
-
options?: CacheWriteOptions;
|
|
48
|
-
}
|
|
49
|
-
/** Interface that all cache backend implementations must satisfy. */
|
|
50
|
-
interface CacheLayer {
|
|
51
|
-
readonly name: string;
|
|
52
|
-
readonly defaultTtl?: number;
|
|
53
|
-
readonly isLocal?: boolean;
|
|
54
|
-
get<T>(key: string): Promise<T | null>;
|
|
55
|
-
getEntry?<T = unknown>(key: string): Promise<T | null>;
|
|
56
|
-
getMany?<T>(keys: string[]): Promise<Array<T | null>>;
|
|
57
|
-
set(key: string, value: unknown, ttl?: number): Promise<void>;
|
|
58
|
-
delete(key: string): Promise<void>;
|
|
59
|
-
clear(): Promise<void>;
|
|
60
|
-
deleteMany?(keys: string[]): Promise<void>;
|
|
61
|
-
keys?(): Promise<string[]>;
|
|
62
|
-
/**
|
|
63
|
-
* Returns true if the key exists and has not expired.
|
|
64
|
-
* Implementations may omit this; CacheStack will fall back to `get()`.
|
|
65
|
-
*/
|
|
66
|
-
has?(key: string): Promise<boolean>;
|
|
67
|
-
/**
|
|
68
|
-
* Returns the remaining TTL in seconds for the key, or null if the key
|
|
69
|
-
* does not exist, has no TTL, or has already expired.
|
|
70
|
-
* Implementations may omit this.
|
|
71
|
-
*/
|
|
72
|
-
ttl?(key: string): Promise<number | null>;
|
|
73
|
-
/**
|
|
74
|
-
* Returns the number of entries currently held by this layer.
|
|
75
|
-
* Implementations may omit this.
|
|
76
|
-
*/
|
|
77
|
-
size?(): Promise<number>;
|
|
78
|
-
}
|
|
79
|
-
interface CacheSerializer {
|
|
80
|
-
serialize(value: unknown): string | Buffer;
|
|
81
|
-
deserialize<T>(payload: string | Buffer): T;
|
|
82
|
-
}
|
|
83
|
-
/** Per-layer latency statistics (rolling window of sampled read durations). */
|
|
84
|
-
interface CacheLayerLatency {
|
|
85
|
-
/** Average read latency in milliseconds. */
|
|
86
|
-
avgMs: number;
|
|
87
|
-
/** Maximum observed read latency in milliseconds. */
|
|
88
|
-
maxMs: number;
|
|
89
|
-
/** Number of samples used to compute the statistics. */
|
|
90
|
-
count: number;
|
|
91
|
-
}
|
|
92
|
-
/** Snapshot of cumulative cache counters. */
|
|
93
|
-
interface CacheMetricsSnapshot {
|
|
94
|
-
hits: number;
|
|
95
|
-
misses: number;
|
|
96
|
-
fetches: number;
|
|
97
|
-
sets: number;
|
|
98
|
-
deletes: number;
|
|
99
|
-
backfills: number;
|
|
100
|
-
invalidations: number;
|
|
101
|
-
staleHits: number;
|
|
102
|
-
refreshes: number;
|
|
103
|
-
refreshErrors: number;
|
|
104
|
-
writeFailures: number;
|
|
105
|
-
singleFlightWaits: number;
|
|
106
|
-
negativeCacheHits: number;
|
|
107
|
-
circuitBreakerTrips: number;
|
|
108
|
-
degradedOperations: number;
|
|
109
|
-
hitsByLayer: Record<string, number>;
|
|
110
|
-
missesByLayer: Record<string, number>;
|
|
111
|
-
/** Per-layer read latency statistics (sampled from successful reads). */
|
|
112
|
-
latencyByLayer: Record<string, CacheLayerLatency>;
|
|
113
|
-
/** Timestamp (ms since epoch) when metrics were last reset. */
|
|
114
|
-
resetAt: number;
|
|
115
|
-
}
|
|
116
|
-
/** Computed hit-rate statistics derived from CacheMetricsSnapshot. */
|
|
117
|
-
interface CacheHitRateSnapshot {
|
|
118
|
-
/** Overall hit rate across all layers (0–1). */
|
|
119
|
-
overall: number;
|
|
120
|
-
/** Per-layer hit rates (0–1 each). */
|
|
121
|
-
byLayer: Record<string, number>;
|
|
122
|
-
}
|
|
123
|
-
interface CacheLogger {
|
|
124
|
-
debug?(message: string, context?: Record<string, unknown>): void;
|
|
125
|
-
info?(message: string, context?: Record<string, unknown>): void;
|
|
126
|
-
warn?(message: string, context?: Record<string, unknown>): void;
|
|
127
|
-
error?(message: string, context?: Record<string, unknown>): void;
|
|
128
|
-
}
|
|
129
|
-
interface CacheTagIndex {
|
|
130
|
-
touch(key: string): Promise<void>;
|
|
131
|
-
track(key: string, tags: string[]): Promise<void>;
|
|
132
|
-
remove(key: string): Promise<void>;
|
|
133
|
-
keysForTag(tag: string): Promise<string[]>;
|
|
134
|
-
/** Returns the tags associated with a specific key, or an empty array. */
|
|
135
|
-
tagsForKey?(key: string): Promise<string[]>;
|
|
136
|
-
matchPattern(pattern: string): Promise<string[]>;
|
|
137
|
-
clear(): Promise<void>;
|
|
138
|
-
}
|
|
139
|
-
interface InvalidationMessage {
|
|
140
|
-
scope: 'key' | 'keys' | 'clear';
|
|
141
|
-
sourceId: string;
|
|
142
|
-
keys?: string[];
|
|
143
|
-
operation?: 'write' | 'delete' | 'invalidate' | 'clear';
|
|
144
|
-
}
|
|
145
|
-
interface InvalidationBus {
|
|
146
|
-
subscribe(handler: (message: InvalidationMessage) => Promise<void> | void): Promise<() => Promise<void> | void>;
|
|
147
|
-
publish(message: InvalidationMessage): Promise<void>;
|
|
148
|
-
}
|
|
149
|
-
interface CacheSingleFlightExecutionOptions {
|
|
150
|
-
leaseMs: number;
|
|
151
|
-
waitTimeoutMs: number;
|
|
152
|
-
pollIntervalMs: number;
|
|
153
|
-
}
|
|
154
|
-
interface CacheSingleFlightCoordinator {
|
|
155
|
-
execute<T>(key: string, options: CacheSingleFlightExecutionOptions, worker: () => Promise<T>, waiter: () => Promise<T>): Promise<T>;
|
|
156
|
-
}
|
|
157
|
-
interface CacheStackOptions {
|
|
158
|
-
logger?: CacheLogger | boolean;
|
|
159
|
-
metrics?: boolean;
|
|
160
|
-
stampedePrevention?: boolean;
|
|
161
|
-
invalidationBus?: InvalidationBus;
|
|
162
|
-
tagIndex?: CacheTagIndex;
|
|
163
|
-
broadcastL1Invalidation?: boolean;
|
|
164
|
-
/**
|
|
165
|
-
* @deprecated Use `broadcastL1Invalidation` instead.
|
|
166
|
-
*/
|
|
167
|
-
publishSetInvalidation?: boolean;
|
|
168
|
-
negativeCaching?: boolean;
|
|
169
|
-
negativeTtl?: number | LayerTtlMap;
|
|
170
|
-
staleWhileRevalidate?: number | LayerTtlMap;
|
|
171
|
-
staleIfError?: number | LayerTtlMap;
|
|
172
|
-
ttlJitter?: number | LayerTtlMap;
|
|
173
|
-
refreshAhead?: number | LayerTtlMap;
|
|
174
|
-
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
175
|
-
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
176
|
-
gracefulDegradation?: boolean | CacheDegradationOptions;
|
|
177
|
-
writePolicy?: 'strict' | 'best-effort';
|
|
178
|
-
singleFlightCoordinator?: CacheSingleFlightCoordinator;
|
|
179
|
-
singleFlightLeaseMs?: number;
|
|
180
|
-
singleFlightTimeoutMs?: number;
|
|
181
|
-
singleFlightPollMs?: number;
|
|
182
|
-
/**
|
|
183
|
-
* Maximum number of entries in `accessProfiles` and `circuitBreakers` maps
|
|
184
|
-
* before the oldest entries are pruned. Prevents unbounded memory growth.
|
|
185
|
-
* Defaults to 100 000.
|
|
186
|
-
*/
|
|
187
|
-
maxProfileEntries?: number;
|
|
188
|
-
}
|
|
189
|
-
interface CacheAdaptiveTtlOptions {
|
|
190
|
-
hotAfter?: number;
|
|
191
|
-
step?: number | LayerTtlMap;
|
|
192
|
-
maxTtl?: number | LayerTtlMap;
|
|
193
|
-
}
|
|
194
|
-
interface CacheCircuitBreakerOptions {
|
|
195
|
-
failureThreshold?: number;
|
|
196
|
-
cooldownMs?: number;
|
|
197
|
-
}
|
|
198
|
-
interface CacheDegradationOptions {
|
|
199
|
-
retryAfterMs?: number;
|
|
200
|
-
}
|
|
201
|
-
interface CacheWarmEntry<T = unknown> {
|
|
202
|
-
key: string;
|
|
203
|
-
fetcher: () => Promise<T>;
|
|
204
|
-
options?: CacheGetOptions;
|
|
205
|
-
priority?: number;
|
|
206
|
-
}
|
|
207
|
-
/** Options controlling the cache warm-up process. */
|
|
208
|
-
interface CacheWarmOptions {
|
|
209
|
-
concurrency?: number;
|
|
210
|
-
continueOnError?: boolean;
|
|
211
|
-
/** Called after each entry is processed (success or failure). */
|
|
212
|
-
onProgress?: (progress: CacheWarmProgress) => void;
|
|
213
|
-
}
|
|
214
|
-
/** Progress information delivered to `CacheWarmOptions.onProgress`. */
|
|
215
|
-
interface CacheWarmProgress {
|
|
216
|
-
completed: number;
|
|
217
|
-
total: number;
|
|
218
|
-
key: string;
|
|
219
|
-
success: boolean;
|
|
220
|
-
}
|
|
221
|
-
interface CacheWrapOptions<TArgs extends unknown[] = unknown[]> extends CacheGetOptions {
|
|
222
|
-
keyResolver?: (...args: TArgs) => string;
|
|
223
|
-
}
|
|
224
|
-
interface CacheSnapshotEntry {
|
|
225
|
-
key: string;
|
|
226
|
-
value: unknown;
|
|
227
|
-
ttl?: number;
|
|
228
|
-
}
|
|
229
|
-
interface CacheStatsSnapshot {
|
|
230
|
-
metrics: CacheMetricsSnapshot;
|
|
231
|
-
layers: Array<{
|
|
232
|
-
name: string;
|
|
233
|
-
isLocal: boolean;
|
|
234
|
-
degradedUntil: number | null;
|
|
235
|
-
}>;
|
|
236
|
-
backgroundRefreshes: number;
|
|
237
|
-
}
|
|
238
|
-
/** Detailed inspection result for a single cache key. */
|
|
239
|
-
interface CacheInspectResult {
|
|
240
|
-
key: string;
|
|
241
|
-
/** Layers in which the key is currently stored (not expired). */
|
|
242
|
-
foundInLayers: string[];
|
|
243
|
-
/** Remaining fresh TTL in seconds, or null if no expiry or not an envelope. */
|
|
244
|
-
freshTtlSeconds: number | null;
|
|
245
|
-
/** Remaining stale-while-revalidate window in seconds, or null. */
|
|
246
|
-
staleTtlSeconds: number | null;
|
|
247
|
-
/** Remaining stale-if-error window in seconds, or null. */
|
|
248
|
-
errorTtlSeconds: number | null;
|
|
249
|
-
/** Whether the key is currently serving stale-while-revalidate. */
|
|
250
|
-
isStale: boolean;
|
|
251
|
-
/** Tags associated with this key (from the TagIndex). */
|
|
252
|
-
tags: string[];
|
|
253
|
-
}
|
|
254
|
-
/** All events emitted by CacheStack and their payload shapes. */
|
|
255
|
-
interface CacheStackEvents {
|
|
256
|
-
/** Fired on every cache hit. */
|
|
257
|
-
hit: {
|
|
258
|
-
key: string;
|
|
259
|
-
layer: string;
|
|
260
|
-
state: 'fresh' | 'stale-while-revalidate' | 'stale-if-error';
|
|
261
|
-
};
|
|
262
|
-
/** Fired on every cache miss before the fetcher runs. */
|
|
263
|
-
miss: {
|
|
264
|
-
key: string;
|
|
265
|
-
mode: string;
|
|
266
|
-
};
|
|
267
|
-
/** Fired after a value is stored in the cache. */
|
|
268
|
-
set: {
|
|
269
|
-
key: string;
|
|
270
|
-
kind: string;
|
|
271
|
-
tags?: string[];
|
|
272
|
-
};
|
|
273
|
-
/** Fired after one or more keys are deleted. */
|
|
274
|
-
delete: {
|
|
275
|
-
keys: string[];
|
|
276
|
-
};
|
|
277
|
-
/** Fired when a value is backfilled into a faster layer. */
|
|
278
|
-
backfill: {
|
|
279
|
-
key: string;
|
|
280
|
-
layer: string;
|
|
281
|
-
};
|
|
282
|
-
/** Fired when a stale value is returned to the caller. */
|
|
283
|
-
'stale-serve': {
|
|
284
|
-
key: string;
|
|
285
|
-
state: string;
|
|
286
|
-
layer: string;
|
|
287
|
-
};
|
|
288
|
-
/** Fired when a duplicate request is deduplicated in stampede prevention. */
|
|
289
|
-
'stampede-dedupe': {
|
|
290
|
-
key: string;
|
|
291
|
-
};
|
|
292
|
-
/** Fired after a key is successfully warmed. */
|
|
293
|
-
warm: {
|
|
294
|
-
key: string;
|
|
295
|
-
};
|
|
296
|
-
/** Fired when an error occurs (layer failure, circuit breaker, etc.). */
|
|
297
|
-
error: {
|
|
298
|
-
operation: string;
|
|
299
|
-
[key: string]: unknown;
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
declare class CacheNamespace {
|
|
304
|
-
private readonly cache;
|
|
305
|
-
private readonly prefix;
|
|
306
|
-
constructor(cache: CacheStack, prefix: string);
|
|
307
|
-
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
308
|
-
getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
309
|
-
/**
|
|
310
|
-
* Like `get()`, but throws `CacheMissError` instead of returning `null`.
|
|
311
|
-
*/
|
|
312
|
-
getOrThrow<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T>;
|
|
313
|
-
has(key: string): Promise<boolean>;
|
|
314
|
-
ttl(key: string): Promise<number | null>;
|
|
315
|
-
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
316
|
-
delete(key: string): Promise<void>;
|
|
317
|
-
mdelete(keys: string[]): Promise<void>;
|
|
318
|
-
clear(): Promise<void>;
|
|
319
|
-
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
320
|
-
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
321
|
-
invalidateByTag(tag: string): Promise<void>;
|
|
322
|
-
invalidateByPattern(pattern: string): Promise<void>;
|
|
323
|
-
/**
|
|
324
|
-
* Returns detailed metadata about a single cache key within this namespace.
|
|
325
|
-
*/
|
|
326
|
-
inspect(key: string): Promise<CacheInspectResult | null>;
|
|
327
|
-
wrap<TArgs extends unknown[], TResult>(keyPrefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
328
|
-
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
329
|
-
getMetrics(): CacheMetricsSnapshot;
|
|
330
|
-
getHitRate(): CacheHitRateSnapshot;
|
|
331
|
-
/**
|
|
332
|
-
* Creates a nested namespace. Keys are prefixed with `parentPrefix:childPrefix:`.
|
|
333
|
-
*
|
|
334
|
-
* ```ts
|
|
335
|
-
* const tenant = cache.namespace('tenant:abc')
|
|
336
|
-
* const posts = tenant.namespace('posts')
|
|
337
|
-
* // keys become: "tenant:abc:posts:mykey"
|
|
338
|
-
* ```
|
|
339
|
-
*/
|
|
340
|
-
namespace(childPrefix: string): CacheNamespace;
|
|
341
|
-
qualify(key: string): string;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/** Typed overloads for EventEmitter so callers get autocomplete on event names. */
|
|
345
|
-
interface CacheStack {
|
|
346
|
-
on<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
347
|
-
once<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
348
|
-
off<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
349
|
-
emit<K extends keyof CacheStackEvents>(event: K, data: CacheStackEvents[K]): boolean;
|
|
350
|
-
}
|
|
351
|
-
declare class CacheStack extends EventEmitter {
|
|
352
|
-
private readonly layers;
|
|
353
|
-
private readonly options;
|
|
354
|
-
private readonly stampedeGuard;
|
|
355
|
-
private readonly metricsCollector;
|
|
356
|
-
private readonly instanceId;
|
|
357
|
-
private readonly startup;
|
|
358
|
-
private unsubscribeInvalidation?;
|
|
359
|
-
private readonly logger;
|
|
360
|
-
private readonly tagIndex;
|
|
361
|
-
private readonly backgroundRefreshes;
|
|
362
|
-
private readonly layerDegradedUntil;
|
|
363
|
-
private readonly ttlResolver;
|
|
364
|
-
private readonly circuitBreakerManager;
|
|
365
|
-
private isDisconnecting;
|
|
366
|
-
private disconnectPromise?;
|
|
367
|
-
constructor(layers: CacheLayer[], options?: CacheStackOptions);
|
|
368
|
-
/**
|
|
369
|
-
* Read-through cache get.
|
|
370
|
-
* Returns the cached value if present and fresh, or invokes `fetcher` on a miss
|
|
371
|
-
* and stores the result across all layers. Returns `null` if the key is not found
|
|
372
|
-
* and no `fetcher` is provided.
|
|
373
|
-
*/
|
|
374
|
-
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
375
|
-
/**
|
|
376
|
-
* Alias for `get(key, fetcher, options)` — explicit get-or-set pattern.
|
|
377
|
-
* Fetches and caches the value if not already present.
|
|
378
|
-
*/
|
|
379
|
-
getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
380
|
-
/**
|
|
381
|
-
* Like `get()`, but throws `CacheMissError` instead of returning `null`.
|
|
382
|
-
* Useful when the value is expected to exist or the fetcher is expected to
|
|
383
|
-
* return non-null.
|
|
384
|
-
*/
|
|
385
|
-
getOrThrow<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T>;
|
|
386
|
-
/**
|
|
387
|
-
* Returns true if the given key exists and is not expired in any layer.
|
|
388
|
-
*/
|
|
389
|
-
has(key: string): Promise<boolean>;
|
|
390
|
-
/**
|
|
391
|
-
* Returns the remaining TTL in seconds for the key in the fastest layer
|
|
392
|
-
* that has it, or null if the key is not found / has no TTL.
|
|
393
|
-
*/
|
|
394
|
-
ttl(key: string): Promise<number | null>;
|
|
395
|
-
/**
|
|
396
|
-
* Stores a value in all cache layers. Overwrites any existing value.
|
|
397
|
-
*/
|
|
398
|
-
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
399
|
-
/**
|
|
400
|
-
* Deletes the key from all layers and publishes an invalidation message.
|
|
401
|
-
*/
|
|
402
|
-
delete(key: string): Promise<void>;
|
|
403
|
-
clear(): Promise<void>;
|
|
404
|
-
/**
|
|
405
|
-
* Deletes multiple keys at once. More efficient than calling `delete()` in a loop.
|
|
406
|
-
*/
|
|
407
|
-
mdelete(keys: string[]): Promise<void>;
|
|
408
|
-
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
409
|
-
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
410
|
-
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
411
|
-
/**
|
|
412
|
-
* Returns a cached version of `fetcher`. The cache key is derived from
|
|
413
|
-
* `prefix` plus the serialized arguments unless a `keyResolver` is provided.
|
|
414
|
-
*/
|
|
415
|
-
wrap<TArgs extends unknown[], TResult>(prefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
416
|
-
/**
|
|
417
|
-
* Creates a `CacheNamespace` that automatically prefixes all keys with
|
|
418
|
-
* `prefix:`. Useful for multi-tenant or module-level isolation.
|
|
419
|
-
*/
|
|
420
|
-
namespace(prefix: string): CacheNamespace;
|
|
421
|
-
invalidateByTag(tag: string): Promise<void>;
|
|
422
|
-
invalidateByPattern(pattern: string): Promise<void>;
|
|
423
|
-
getMetrics(): CacheMetricsSnapshot;
|
|
424
|
-
getStats(): CacheStatsSnapshot;
|
|
425
|
-
resetMetrics(): void;
|
|
426
|
-
/**
|
|
427
|
-
* Returns computed hit-rate statistics (overall and per-layer).
|
|
428
|
-
*/
|
|
429
|
-
getHitRate(): CacheHitRateSnapshot;
|
|
430
|
-
/**
|
|
431
|
-
* Returns detailed metadata about a single cache key: which layers contain it,
|
|
432
|
-
* remaining fresh/stale/error TTLs, and associated tags.
|
|
433
|
-
* Returns `null` if the key does not exist in any layer.
|
|
434
|
-
*/
|
|
435
|
-
inspect(key: string): Promise<CacheInspectResult | null>;
|
|
436
|
-
exportState(): Promise<CacheSnapshotEntry[]>;
|
|
437
|
-
importState(entries: CacheSnapshotEntry[]): Promise<void>;
|
|
438
|
-
persistToFile(filePath: string): Promise<void>;
|
|
439
|
-
restoreFromFile(filePath: string): Promise<void>;
|
|
440
|
-
disconnect(): Promise<void>;
|
|
441
|
-
private initialize;
|
|
442
|
-
private fetchWithGuards;
|
|
443
|
-
private waitForFreshValue;
|
|
444
|
-
private fetchAndPopulate;
|
|
445
|
-
private storeEntry;
|
|
446
|
-
private readFromLayers;
|
|
447
|
-
private readLayerEntry;
|
|
448
|
-
private backfill;
|
|
449
|
-
private writeAcrossLayers;
|
|
450
|
-
private executeLayerOperations;
|
|
451
|
-
private resolveFreshTtl;
|
|
452
|
-
private resolveLayerSeconds;
|
|
453
|
-
private shouldNegativeCache;
|
|
454
|
-
private scheduleBackgroundRefresh;
|
|
455
|
-
private resolveSingleFlightOptions;
|
|
456
|
-
private deleteKeys;
|
|
457
|
-
private publishInvalidation;
|
|
458
|
-
private handleInvalidationMessage;
|
|
459
|
-
private getTagsForKey;
|
|
460
|
-
private formatError;
|
|
461
|
-
private sleep;
|
|
462
|
-
private shouldBroadcastL1Invalidation;
|
|
463
|
-
private deleteKeysFromLayers;
|
|
464
|
-
private validateConfiguration;
|
|
465
|
-
private validateWriteOptions;
|
|
466
|
-
private validateLayerNumberOption;
|
|
467
|
-
private validatePositiveNumber;
|
|
468
|
-
private validateNonNegativeNumber;
|
|
469
|
-
private validateCacheKey;
|
|
470
|
-
private serializeOptions;
|
|
471
|
-
private validateAdaptiveTtlOptions;
|
|
472
|
-
private validateCircuitBreakerOptions;
|
|
473
|
-
private applyFreshReadPolicies;
|
|
474
|
-
private shouldSkipLayer;
|
|
475
|
-
private handleLayerFailure;
|
|
476
|
-
private isGracefulDegradationEnabled;
|
|
477
|
-
private recordCircuitFailure;
|
|
478
|
-
private isNegativeStoredValue;
|
|
479
|
-
private emitError;
|
|
480
|
-
private serializeKeyPart;
|
|
481
|
-
private isCacheSnapshotEntries;
|
|
482
|
-
private normalizeForSerialization;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
declare class PatternMatcher {
|
|
486
|
-
/**
|
|
487
|
-
* Tests whether a glob-style pattern matches a value.
|
|
488
|
-
* Supports `*` (any sequence of characters) and `?` (any single character).
|
|
489
|
-
* Uses a linear-time algorithm to avoid ReDoS vulnerabilities.
|
|
490
|
-
*/
|
|
491
|
-
static matches(pattern: string, value: string): boolean;
|
|
492
|
-
/**
|
|
493
|
-
* Linear-time glob matching using dynamic programming.
|
|
494
|
-
* Avoids catastrophic backtracking that RegExp-based glob matching can cause.
|
|
495
|
-
*/
|
|
496
|
-
private static matchLinear;
|
|
497
|
-
}
|
|
4
|
+
import 'node:events';
|
|
498
5
|
|
|
499
6
|
interface RedisInvalidationBusOptions {
|
|
500
7
|
publisher: Redis;
|
|
501
8
|
subscriber?: Redis;
|
|
502
9
|
channel?: string;
|
|
10
|
+
logger?: CacheLogger;
|
|
503
11
|
}
|
|
504
12
|
/**
|
|
505
13
|
* Redis pub/sub invalidation bus.
|
|
@@ -512,6 +20,7 @@ declare class RedisInvalidationBus implements InvalidationBus {
|
|
|
512
20
|
private readonly channel;
|
|
513
21
|
private readonly publisher;
|
|
514
22
|
private readonly subscriber;
|
|
23
|
+
private readonly logger?;
|
|
515
24
|
private readonly handlers;
|
|
516
25
|
private sharedListener?;
|
|
517
26
|
constructor(options: RedisInvalidationBusOptions);
|
|
@@ -526,49 +35,29 @@ interface RedisTagIndexOptions {
|
|
|
526
35
|
client: Redis;
|
|
527
36
|
prefix?: string;
|
|
528
37
|
scanCount?: number;
|
|
38
|
+
knownKeysShards?: number;
|
|
529
39
|
}
|
|
530
40
|
declare class RedisTagIndex implements CacheTagIndex {
|
|
531
41
|
private readonly client;
|
|
532
42
|
private readonly prefix;
|
|
533
43
|
private readonly scanCount;
|
|
44
|
+
private readonly knownKeysShards;
|
|
534
45
|
constructor(options: RedisTagIndexOptions);
|
|
535
46
|
touch(key: string): Promise<void>;
|
|
536
47
|
track(key: string, tags: string[]): Promise<void>;
|
|
537
48
|
remove(key: string): Promise<void>;
|
|
538
49
|
keysForTag(tag: string): Promise<string[]>;
|
|
50
|
+
keysForPrefix(prefix: string): Promise<string[]>;
|
|
539
51
|
tagsForKey(key: string): Promise<string[]>;
|
|
540
52
|
matchPattern(pattern: string): Promise<string[]>;
|
|
541
53
|
clear(): Promise<void>;
|
|
542
54
|
private scanIndexKeys;
|
|
543
|
-
private
|
|
55
|
+
private knownKeysKeyFor;
|
|
56
|
+
private knownKeysKeys;
|
|
544
57
|
private keyTagsKey;
|
|
545
58
|
private tagKeysKey;
|
|
546
59
|
}
|
|
547
60
|
|
|
548
|
-
interface TagIndexOptions {
|
|
549
|
-
/**
|
|
550
|
-
* Maximum number of keys tracked in `knownKeys`. When exceeded, the oldest
|
|
551
|
-
* 10 % of keys are pruned to keep memory bounded.
|
|
552
|
-
* Defaults to unlimited.
|
|
553
|
-
*/
|
|
554
|
-
maxKnownKeys?: number;
|
|
555
|
-
}
|
|
556
|
-
declare class TagIndex implements CacheTagIndex {
|
|
557
|
-
private readonly tagToKeys;
|
|
558
|
-
private readonly keyToTags;
|
|
559
|
-
private readonly knownKeys;
|
|
560
|
-
private readonly maxKnownKeys;
|
|
561
|
-
constructor(options?: TagIndexOptions);
|
|
562
|
-
touch(key: string): Promise<void>;
|
|
563
|
-
track(key: string, tags: string[]): Promise<void>;
|
|
564
|
-
remove(key: string): Promise<void>;
|
|
565
|
-
keysForTag(tag: string): Promise<string[]>;
|
|
566
|
-
tagsForKey(key: string): Promise<string[]>;
|
|
567
|
-
matchPattern(pattern: string): Promise<string[]>;
|
|
568
|
-
clear(): Promise<void>;
|
|
569
|
-
private pruneKnownKeysIfNeeded;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
61
|
declare function createCacheStatsHandler(cache: CacheStack): (_request: unknown, response: {
|
|
573
62
|
setHeader?: (name: string, value: string) => void;
|
|
574
63
|
end: (body: string) => void;
|
|
@@ -638,6 +127,27 @@ interface GraphqlCacheOptions<TArgs extends unknown[]> extends CacheGetOptions {
|
|
|
638
127
|
}
|
|
639
128
|
declare function cacheGraphqlResolver<TArgs extends unknown[], TResult>(cache: CacheStack, prefix: string, resolver: (...args: TArgs) => Promise<TResult>, options?: GraphqlCacheOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
640
129
|
|
|
130
|
+
interface OpenTelemetrySpan {
|
|
131
|
+
setAttribute?: (name: string, value: unknown) => void;
|
|
132
|
+
recordException?: (error: unknown) => void;
|
|
133
|
+
end: () => void;
|
|
134
|
+
}
|
|
135
|
+
interface OpenTelemetryTracer {
|
|
136
|
+
startSpan: (name: string, options?: {
|
|
137
|
+
attributes?: Record<string, unknown>;
|
|
138
|
+
}) => OpenTelemetrySpan;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Lightweight OpenTelemetry instrumentation for a CacheStack instance.
|
|
142
|
+
*
|
|
143
|
+
* Note: this implementation wraps instance methods directly. Avoid stacking
|
|
144
|
+
* multiple OpenTelemetry plugins on the same CacheStack at the same time,
|
|
145
|
+
* because each plugin replaces and later restores those methods.
|
|
146
|
+
*/
|
|
147
|
+
declare function createOpenTelemetryPlugin(cache: CacheStack, tracer: OpenTelemetryTracer): {
|
|
148
|
+
uninstall(): void;
|
|
149
|
+
};
|
|
150
|
+
|
|
641
151
|
interface TrpcCacheMiddlewareContext<TInput = unknown, TResult = unknown> {
|
|
642
152
|
path?: string;
|
|
643
153
|
type?: string;
|
|
@@ -655,83 +165,44 @@ declare function createTrpcCacheMiddleware<TInput = unknown, TResult = unknown>(
|
|
|
655
165
|
data?: TResult;
|
|
656
166
|
} | null>;
|
|
657
167
|
|
|
658
|
-
interface MemoryLayerSnapshotEntry {
|
|
659
|
-
key: string;
|
|
660
|
-
value: unknown;
|
|
661
|
-
expiresAt: number | null;
|
|
662
|
-
}
|
|
663
|
-
/**
|
|
664
|
-
* Eviction policy applied when `maxSize` is reached.
|
|
665
|
-
* - `lru` (default): evicts the Least Recently Used entry.
|
|
666
|
-
* - `lfu`: evicts the Least Frequently Used entry.
|
|
667
|
-
* - `fifo`: evicts the oldest inserted entry.
|
|
668
|
-
*/
|
|
669
|
-
type EvictionPolicy = 'lru' | 'lfu' | 'fifo';
|
|
670
|
-
interface MemoryLayerOptions {
|
|
671
|
-
ttl?: number;
|
|
672
|
-
maxSize?: number;
|
|
673
|
-
name?: string;
|
|
674
|
-
evictionPolicy?: EvictionPolicy;
|
|
675
|
-
}
|
|
676
|
-
declare class MemoryLayer implements CacheLayer {
|
|
677
|
-
readonly name: string;
|
|
678
|
-
readonly defaultTtl?: number;
|
|
679
|
-
readonly isLocal = true;
|
|
680
|
-
private readonly maxSize;
|
|
681
|
-
private readonly evictionPolicy;
|
|
682
|
-
private readonly entries;
|
|
683
|
-
constructor(options?: MemoryLayerOptions);
|
|
684
|
-
get<T>(key: string): Promise<T | null>;
|
|
685
|
-
getEntry<T = unknown>(key: string): Promise<T | null>;
|
|
686
|
-
getMany<T>(keys: string[]): Promise<Array<T | null>>;
|
|
687
|
-
set(key: string, value: unknown, ttl?: number | undefined): Promise<void>;
|
|
688
|
-
has(key: string): Promise<boolean>;
|
|
689
|
-
ttl(key: string): Promise<number | null>;
|
|
690
|
-
size(): Promise<number>;
|
|
691
|
-
delete(key: string): Promise<void>;
|
|
692
|
-
deleteMany(keys: string[]): Promise<void>;
|
|
693
|
-
clear(): Promise<void>;
|
|
694
|
-
keys(): Promise<string[]>;
|
|
695
|
-
exportState(): MemoryLayerSnapshotEntry[];
|
|
696
|
-
importState(entries: MemoryLayerSnapshotEntry[]): void;
|
|
697
|
-
private evict;
|
|
698
|
-
private pruneExpired;
|
|
699
|
-
private isExpired;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
168
|
type CompressionAlgorithm = 'gzip' | 'brotli';
|
|
703
169
|
interface RedisLayerOptions {
|
|
704
170
|
client: Redis;
|
|
705
171
|
ttl?: number;
|
|
706
172
|
name?: string;
|
|
707
|
-
serializer?: CacheSerializer;
|
|
173
|
+
serializer?: CacheSerializer | CacheSerializer[];
|
|
708
174
|
prefix?: string;
|
|
709
175
|
allowUnprefixedClear?: boolean;
|
|
710
176
|
scanCount?: number;
|
|
711
177
|
compression?: CompressionAlgorithm;
|
|
712
178
|
compressionThreshold?: number;
|
|
179
|
+
disconnectOnDispose?: boolean;
|
|
713
180
|
}
|
|
714
181
|
declare class RedisLayer implements CacheLayer {
|
|
715
182
|
readonly name: string;
|
|
716
183
|
readonly defaultTtl?: number;
|
|
717
184
|
readonly isLocal = false;
|
|
718
185
|
private readonly client;
|
|
719
|
-
private readonly
|
|
186
|
+
private readonly serializers;
|
|
720
187
|
private readonly prefix;
|
|
721
188
|
private readonly allowUnprefixedClear;
|
|
722
189
|
private readonly scanCount;
|
|
723
190
|
private readonly compression?;
|
|
724
191
|
private readonly compressionThreshold;
|
|
192
|
+
private readonly disconnectOnDispose;
|
|
725
193
|
constructor(options: RedisLayerOptions);
|
|
726
194
|
get<T>(key: string): Promise<T | null>;
|
|
727
195
|
getEntry<T = unknown>(key: string): Promise<T | null>;
|
|
728
196
|
getMany<T>(keys: string[]): Promise<Array<T | null>>;
|
|
197
|
+
setMany(entries: CacheLayerSetManyEntry[]): Promise<void>;
|
|
729
198
|
set(key: string, value: unknown, ttl?: number | undefined): Promise<void>;
|
|
730
199
|
delete(key: string): Promise<void>;
|
|
731
200
|
deleteMany(keys: string[]): Promise<void>;
|
|
732
201
|
has(key: string): Promise<boolean>;
|
|
733
202
|
ttl(key: string): Promise<number | null>;
|
|
734
203
|
size(): Promise<number>;
|
|
204
|
+
ping(): Promise<boolean>;
|
|
205
|
+
dispose(): Promise<void>;
|
|
735
206
|
/**
|
|
736
207
|
* Deletes all keys matching the layer's prefix in batches to avoid
|
|
737
208
|
* loading millions of keys into memory at once.
|
|
@@ -741,6 +212,8 @@ declare class RedisLayer implements CacheLayer {
|
|
|
741
212
|
private scanKeys;
|
|
742
213
|
private withPrefix;
|
|
743
214
|
private deserializeOrDelete;
|
|
215
|
+
private rewriteWithPrimarySerializer;
|
|
216
|
+
private primarySerializer;
|
|
744
217
|
private isSerializablePayload;
|
|
745
218
|
/**
|
|
746
219
|
* Compresses the payload asynchronously if compression is enabled and the
|
|
@@ -783,10 +256,13 @@ declare class DiskLayer implements CacheLayer {
|
|
|
783
256
|
private readonly directory;
|
|
784
257
|
private readonly serializer;
|
|
785
258
|
private readonly maxFiles;
|
|
259
|
+
private writeQueue;
|
|
786
260
|
constructor(options: DiskLayerOptions);
|
|
787
261
|
get<T>(key: string): Promise<T | null>;
|
|
788
262
|
getEntry<T = unknown>(key: string): Promise<T | null>;
|
|
789
263
|
set(key: string, value: unknown, ttl?: number | undefined): Promise<void>;
|
|
264
|
+
getMany<T>(keys: string[]): Promise<Array<T | null>>;
|
|
265
|
+
setMany(entries: CacheLayerSetManyEntry[]): Promise<void>;
|
|
790
266
|
has(key: string): Promise<boolean>;
|
|
791
267
|
ttl(key: string): Promise<number | null>;
|
|
792
268
|
delete(key: string): Promise<void>;
|
|
@@ -798,8 +274,14 @@ declare class DiskLayer implements CacheLayer {
|
|
|
798
274
|
*/
|
|
799
275
|
keys(): Promise<string[]>;
|
|
800
276
|
size(): Promise<number>;
|
|
277
|
+
ping(): Promise<boolean>;
|
|
278
|
+
dispose(): Promise<void>;
|
|
801
279
|
private keyToPath;
|
|
280
|
+
private resolveDirectory;
|
|
281
|
+
private normalizeMaxFiles;
|
|
282
|
+
private deserializeEntry;
|
|
802
283
|
private safeDelete;
|
|
284
|
+
private enqueueWrite;
|
|
803
285
|
/**
|
|
804
286
|
* Removes the oldest files (by mtime) when the directory exceeds maxFiles.
|
|
805
287
|
*/
|
|
@@ -886,6 +368,7 @@ declare class RedisSingleFlightCoordinator implements CacheSingleFlightCoordinat
|
|
|
886
368
|
private readonly prefix;
|
|
887
369
|
constructor(options: RedisSingleFlightCoordinatorOptions);
|
|
888
370
|
execute<T>(key: string, options: CacheSingleFlightExecutionOptions, worker: () => Promise<T>, waiter: () => Promise<T>): Promise<T>;
|
|
371
|
+
private startLeaseRenewal;
|
|
889
372
|
}
|
|
890
373
|
|
|
891
374
|
declare class StampedeGuard {
|
|
@@ -918,4 +401,4 @@ declare function createPrometheusMetricsExporter(stacks: CacheStack | Array<{
|
|
|
918
401
|
name: string;
|
|
919
402
|
}>): () => string;
|
|
920
403
|
|
|
921
|
-
export {
|
|
404
|
+
export { CacheGetOptions, CacheLayer, CacheLayerSetManyEntry, CacheLogger, CacheSerializer, CacheSingleFlightCoordinator, CacheSingleFlightExecutionOptions, CacheStack, CacheTagIndex, CacheWrapOptions, DiskLayer, InvalidationBus, InvalidationMessage, JsonSerializer, type MemcachedClient, MemcachedLayer, MsgpackSerializer, RedisInvalidationBus, RedisLayer, RedisSingleFlightCoordinator, RedisTagIndex, StampedeGuard, cacheGraphqlResolver, createCacheStatsHandler, createCachedMethodDecorator, createExpressCacheMiddleware, createFastifyLayercachePlugin, createOpenTelemetryPlugin, createPrometheusMetricsExporter, createTrpcCacheMiddleware };
|