layercache 1.0.1 → 1.0.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 +286 -7
- package/dist/chunk-IILH5XTS.js +103 -0
- package/dist/cli.cjs +228 -0
- package/dist/cli.d.cts +4 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +96 -0
- package/dist/index.cjs +833 -95
- package/dist/index.d.cts +182 -4
- package/dist/index.d.ts +182 -4
- package/dist/index.js +821 -183
- package/package.json +5 -2
- package/packages/nestjs/dist/index.cjs +652 -81
- package/packages/nestjs/dist/index.d.cts +204 -2
- package/packages/nestjs/dist/index.d.ts +204 -2
- package/packages/nestjs/dist/index.js +651 -81
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
1
2
|
import Redis from 'ioredis';
|
|
2
3
|
|
|
3
4
|
interface LayerTtlMap {
|
|
@@ -11,6 +12,10 @@ interface CacheWriteOptions {
|
|
|
11
12
|
staleWhileRevalidate?: number | LayerTtlMap;
|
|
12
13
|
staleIfError?: number | LayerTtlMap;
|
|
13
14
|
ttlJitter?: number | LayerTtlMap;
|
|
15
|
+
slidingTtl?: boolean;
|
|
16
|
+
refreshAhead?: number | LayerTtlMap;
|
|
17
|
+
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
18
|
+
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
14
19
|
}
|
|
15
20
|
interface CacheGetOptions extends CacheWriteOptions {
|
|
16
21
|
}
|
|
@@ -54,9 +59,17 @@ interface CacheMetricsSnapshot {
|
|
|
54
59
|
refreshErrors: number;
|
|
55
60
|
writeFailures: number;
|
|
56
61
|
singleFlightWaits: number;
|
|
62
|
+
negativeCacheHits: number;
|
|
63
|
+
circuitBreakerTrips: number;
|
|
64
|
+
degradedOperations: number;
|
|
65
|
+
hitsByLayer: Record<string, number>;
|
|
66
|
+
missesByLayer: Record<string, number>;
|
|
57
67
|
}
|
|
58
68
|
interface CacheLogger {
|
|
59
|
-
debug(message: string, context?: Record<string, unknown>): void;
|
|
69
|
+
debug?(message: string, context?: Record<string, unknown>): void;
|
|
70
|
+
info?(message: string, context?: Record<string, unknown>): void;
|
|
71
|
+
warn?(message: string, context?: Record<string, unknown>): void;
|
|
72
|
+
error?(message: string, context?: Record<string, unknown>): void;
|
|
60
73
|
}
|
|
61
74
|
interface CacheTagIndex {
|
|
62
75
|
touch(key: string): Promise<void>;
|
|
@@ -90,20 +103,82 @@ interface CacheStackOptions {
|
|
|
90
103
|
stampedePrevention?: boolean;
|
|
91
104
|
invalidationBus?: InvalidationBus;
|
|
92
105
|
tagIndex?: CacheTagIndex;
|
|
106
|
+
broadcastL1Invalidation?: boolean;
|
|
93
107
|
publishSetInvalidation?: boolean;
|
|
94
108
|
negativeCaching?: boolean;
|
|
95
109
|
negativeTtl?: number | LayerTtlMap;
|
|
96
110
|
staleWhileRevalidate?: number | LayerTtlMap;
|
|
97
111
|
staleIfError?: number | LayerTtlMap;
|
|
98
112
|
ttlJitter?: number | LayerTtlMap;
|
|
113
|
+
refreshAhead?: number | LayerTtlMap;
|
|
114
|
+
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
115
|
+
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
116
|
+
gracefulDegradation?: boolean | CacheDegradationOptions;
|
|
99
117
|
writePolicy?: 'strict' | 'best-effort';
|
|
100
118
|
singleFlightCoordinator?: CacheSingleFlightCoordinator;
|
|
101
119
|
singleFlightLeaseMs?: number;
|
|
102
120
|
singleFlightTimeoutMs?: number;
|
|
103
121
|
singleFlightPollMs?: number;
|
|
104
122
|
}
|
|
123
|
+
interface CacheAdaptiveTtlOptions {
|
|
124
|
+
hotAfter?: number;
|
|
125
|
+
step?: number | LayerTtlMap;
|
|
126
|
+
maxTtl?: number | LayerTtlMap;
|
|
127
|
+
}
|
|
128
|
+
interface CacheCircuitBreakerOptions {
|
|
129
|
+
failureThreshold?: number;
|
|
130
|
+
cooldownMs?: number;
|
|
131
|
+
}
|
|
132
|
+
interface CacheDegradationOptions {
|
|
133
|
+
retryAfterMs?: number;
|
|
134
|
+
}
|
|
135
|
+
interface CacheWarmEntry<T = unknown> {
|
|
136
|
+
key: string;
|
|
137
|
+
fetcher: () => Promise<T>;
|
|
138
|
+
options?: CacheGetOptions;
|
|
139
|
+
priority?: number;
|
|
140
|
+
}
|
|
141
|
+
interface CacheWarmOptions {
|
|
142
|
+
concurrency?: number;
|
|
143
|
+
continueOnError?: boolean;
|
|
144
|
+
}
|
|
145
|
+
interface CacheWrapOptions<TArgs extends unknown[] = unknown[]> extends CacheGetOptions {
|
|
146
|
+
keyResolver?: (...args: TArgs) => string;
|
|
147
|
+
}
|
|
148
|
+
interface CacheSnapshotEntry {
|
|
149
|
+
key: string;
|
|
150
|
+
value: unknown;
|
|
151
|
+
ttl?: number;
|
|
152
|
+
}
|
|
153
|
+
interface CacheStatsSnapshot {
|
|
154
|
+
metrics: CacheMetricsSnapshot;
|
|
155
|
+
layers: Array<{
|
|
156
|
+
name: string;
|
|
157
|
+
isLocal: boolean;
|
|
158
|
+
degradedUntil: number | null;
|
|
159
|
+
}>;
|
|
160
|
+
backgroundRefreshes: number;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
declare class CacheNamespace {
|
|
164
|
+
private readonly cache;
|
|
165
|
+
private readonly prefix;
|
|
166
|
+
constructor(cache: CacheStack, prefix: string);
|
|
167
|
+
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
168
|
+
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
169
|
+
delete(key: string): Promise<void>;
|
|
170
|
+
clear(): Promise<void>;
|
|
171
|
+
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
172
|
+
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
173
|
+
invalidateByTag(tag: string): Promise<void>;
|
|
174
|
+
invalidateByPattern(pattern: string): Promise<void>;
|
|
175
|
+
wrap<TArgs extends unknown[], TResult>(keyPrefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
176
|
+
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
177
|
+
getMetrics(): CacheMetricsSnapshot;
|
|
178
|
+
qualify(key: string): string;
|
|
179
|
+
}
|
|
105
180
|
|
|
106
|
-
declare class CacheStack {
|
|
181
|
+
declare class CacheStack extends EventEmitter {
|
|
107
182
|
private readonly layers;
|
|
108
183
|
private readonly options;
|
|
109
184
|
private readonly stampedeGuard;
|
|
@@ -114,6 +189,11 @@ declare class CacheStack {
|
|
|
114
189
|
private readonly logger;
|
|
115
190
|
private readonly tagIndex;
|
|
116
191
|
private readonly backgroundRefreshes;
|
|
192
|
+
private readonly accessProfiles;
|
|
193
|
+
private readonly layerDegradedUntil;
|
|
194
|
+
private readonly circuitBreakers;
|
|
195
|
+
private isDisconnecting;
|
|
196
|
+
private disconnectPromise?;
|
|
117
197
|
constructor(layers: CacheLayer[], options?: CacheStackOptions);
|
|
118
198
|
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
119
199
|
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
@@ -121,10 +201,18 @@ declare class CacheStack {
|
|
|
121
201
|
clear(): Promise<void>;
|
|
122
202
|
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
123
203
|
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
204
|
+
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
205
|
+
wrap<TArgs extends unknown[], TResult>(prefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
206
|
+
namespace(prefix: string): CacheNamespace;
|
|
124
207
|
invalidateByTag(tag: string): Promise<void>;
|
|
125
208
|
invalidateByPattern(pattern: string): Promise<void>;
|
|
126
209
|
getMetrics(): CacheMetricsSnapshot;
|
|
210
|
+
getStats(): CacheStatsSnapshot;
|
|
127
211
|
resetMetrics(): void;
|
|
212
|
+
exportState(): Promise<CacheSnapshotEntry[]>;
|
|
213
|
+
importState(entries: CacheSnapshotEntry[]): Promise<void>;
|
|
214
|
+
persistToFile(filePath: string): Promise<void>;
|
|
215
|
+
restoreFromFile(filePath: string): Promise<void>;
|
|
128
216
|
disconnect(): Promise<void>;
|
|
129
217
|
private initialize;
|
|
130
218
|
private fetchWithGuards;
|
|
@@ -148,6 +236,32 @@ declare class CacheStack {
|
|
|
148
236
|
private handleInvalidationMessage;
|
|
149
237
|
private formatError;
|
|
150
238
|
private sleep;
|
|
239
|
+
private shouldBroadcastL1Invalidation;
|
|
240
|
+
private deleteKeysFromLayers;
|
|
241
|
+
private validateConfiguration;
|
|
242
|
+
private validateWriteOptions;
|
|
243
|
+
private validateLayerNumberOption;
|
|
244
|
+
private validatePositiveNumber;
|
|
245
|
+
private validateNonNegativeNumber;
|
|
246
|
+
private validateCacheKey;
|
|
247
|
+
private serializeOptions;
|
|
248
|
+
private validateAdaptiveTtlOptions;
|
|
249
|
+
private validateCircuitBreakerOptions;
|
|
250
|
+
private applyFreshReadPolicies;
|
|
251
|
+
private applyAdaptiveTtl;
|
|
252
|
+
private recordAccess;
|
|
253
|
+
private incrementMetricMap;
|
|
254
|
+
private shouldSkipLayer;
|
|
255
|
+
private handleLayerFailure;
|
|
256
|
+
private isGracefulDegradationEnabled;
|
|
257
|
+
private assertCircuitClosed;
|
|
258
|
+
private recordCircuitFailure;
|
|
259
|
+
private resetCircuitBreaker;
|
|
260
|
+
private isNegativeStoredValue;
|
|
261
|
+
private emitError;
|
|
262
|
+
private serializeKeyPart;
|
|
263
|
+
private isCacheSnapshotEntries;
|
|
264
|
+
private normalizeForSerialization;
|
|
151
265
|
}
|
|
152
266
|
|
|
153
267
|
declare class PatternMatcher {
|
|
@@ -163,9 +277,13 @@ declare class RedisInvalidationBus implements InvalidationBus {
|
|
|
163
277
|
private readonly channel;
|
|
164
278
|
private readonly publisher;
|
|
165
279
|
private readonly subscriber;
|
|
280
|
+
private activeListener?;
|
|
166
281
|
constructor(options: RedisInvalidationBusOptions);
|
|
167
282
|
subscribe(handler: (message: InvalidationMessage) => Promise<void> | void): Promise<() => Promise<void>>;
|
|
168
283
|
publish(message: InvalidationMessage): Promise<void>;
|
|
284
|
+
private handleMessage;
|
|
285
|
+
private isInvalidationMessage;
|
|
286
|
+
private reportError;
|
|
169
287
|
}
|
|
170
288
|
|
|
171
289
|
interface RedisTagIndexOptions {
|
|
@@ -202,6 +320,55 @@ declare class TagIndex implements CacheTagIndex {
|
|
|
202
320
|
clear(): Promise<void>;
|
|
203
321
|
}
|
|
204
322
|
|
|
323
|
+
declare function createCacheStatsHandler(cache: CacheStack): (_request: unknown, response: {
|
|
324
|
+
setHeader?: (name: string, value: string) => void;
|
|
325
|
+
end: (body: string) => void;
|
|
326
|
+
statusCode?: number;
|
|
327
|
+
}) => Promise<void>;
|
|
328
|
+
|
|
329
|
+
interface CachedMethodDecoratorOptions<TArgs extends unknown[]> extends CacheWrapOptions<TArgs> {
|
|
330
|
+
cache: (instance: unknown) => CacheStack;
|
|
331
|
+
prefix?: string;
|
|
332
|
+
}
|
|
333
|
+
declare function createCachedMethodDecorator<TArgs extends unknown[] = unknown[]>(options: CachedMethodDecoratorOptions<TArgs>): MethodDecorator;
|
|
334
|
+
|
|
335
|
+
interface FastifyLike {
|
|
336
|
+
decorate: (name: string, value: unknown) => void;
|
|
337
|
+
get?: (path: string, handler: () => unknown | Promise<unknown>) => void;
|
|
338
|
+
}
|
|
339
|
+
interface FastifyLayercachePluginOptions {
|
|
340
|
+
exposeStatsRoute?: boolean;
|
|
341
|
+
statsPath?: string;
|
|
342
|
+
}
|
|
343
|
+
declare function createFastifyLayercachePlugin(cache: CacheStack, options?: FastifyLayercachePluginOptions): (fastify: FastifyLike) => Promise<void>;
|
|
344
|
+
|
|
345
|
+
interface GraphqlCacheOptions<TArgs extends unknown[]> extends CacheGetOptions {
|
|
346
|
+
keyResolver?: (...args: TArgs) => string;
|
|
347
|
+
}
|
|
348
|
+
declare function cacheGraphqlResolver<TArgs extends unknown[], TResult>(cache: CacheStack, prefix: string, resolver: (...args: TArgs) => Promise<TResult>, options?: GraphqlCacheOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
349
|
+
|
|
350
|
+
interface TrpcCacheMiddlewareContext<TInput = unknown, TResult = unknown> {
|
|
351
|
+
path?: string;
|
|
352
|
+
type?: string;
|
|
353
|
+
rawInput?: TInput;
|
|
354
|
+
next: () => Promise<{
|
|
355
|
+
ok: boolean;
|
|
356
|
+
data?: TResult;
|
|
357
|
+
}>;
|
|
358
|
+
}
|
|
359
|
+
interface TrpcCacheMiddlewareOptions<TInput> extends CacheGetOptions {
|
|
360
|
+
keyResolver?: (input: TInput, path?: string, type?: string) => string;
|
|
361
|
+
}
|
|
362
|
+
declare function createTrpcCacheMiddleware<TInput = unknown, TResult = unknown>(cache: CacheStack, prefix: string, options?: TrpcCacheMiddlewareOptions<TInput>): (context: TrpcCacheMiddlewareContext<TInput, TResult>) => Promise<{
|
|
363
|
+
ok: boolean;
|
|
364
|
+
data?: TResult;
|
|
365
|
+
} | null>;
|
|
366
|
+
|
|
367
|
+
interface MemoryLayerSnapshotEntry {
|
|
368
|
+
key: string;
|
|
369
|
+
value: unknown;
|
|
370
|
+
expiresAt: number | null;
|
|
371
|
+
}
|
|
205
372
|
interface MemoryLayerOptions {
|
|
206
373
|
ttl?: number;
|
|
207
374
|
maxSize?: number;
|
|
@@ -222,10 +389,13 @@ declare class MemoryLayer implements CacheLayer {
|
|
|
222
389
|
deleteMany(keys: string[]): Promise<void>;
|
|
223
390
|
clear(): Promise<void>;
|
|
224
391
|
keys(): Promise<string[]>;
|
|
392
|
+
exportState(): MemoryLayerSnapshotEntry[];
|
|
393
|
+
importState(entries: MemoryLayerSnapshotEntry[]): void;
|
|
225
394
|
private pruneExpired;
|
|
226
395
|
private isExpired;
|
|
227
396
|
}
|
|
228
397
|
|
|
398
|
+
type CompressionAlgorithm = 'gzip' | 'brotli';
|
|
229
399
|
interface RedisLayerOptions {
|
|
230
400
|
client: Redis;
|
|
231
401
|
ttl?: number;
|
|
@@ -234,6 +404,8 @@ interface RedisLayerOptions {
|
|
|
234
404
|
prefix?: string;
|
|
235
405
|
allowUnprefixedClear?: boolean;
|
|
236
406
|
scanCount?: number;
|
|
407
|
+
compression?: CompressionAlgorithm;
|
|
408
|
+
compressionThreshold?: number;
|
|
237
409
|
}
|
|
238
410
|
declare class RedisLayer implements CacheLayer {
|
|
239
411
|
readonly name: string;
|
|
@@ -244,6 +416,8 @@ declare class RedisLayer implements CacheLayer {
|
|
|
244
416
|
private readonly prefix;
|
|
245
417
|
private readonly allowUnprefixedClear;
|
|
246
418
|
private readonly scanCount;
|
|
419
|
+
private readonly compression?;
|
|
420
|
+
private readonly compressionThreshold;
|
|
247
421
|
constructor(options: RedisLayerOptions);
|
|
248
422
|
get<T>(key: string): Promise<T | null>;
|
|
249
423
|
getEntry<T = unknown>(key: string): Promise<T | null>;
|
|
@@ -255,6 +429,10 @@ declare class RedisLayer implements CacheLayer {
|
|
|
255
429
|
keys(): Promise<string[]>;
|
|
256
430
|
private scanKeys;
|
|
257
431
|
private withPrefix;
|
|
432
|
+
private deserializeOrDelete;
|
|
433
|
+
private isSerializablePayload;
|
|
434
|
+
private encodePayload;
|
|
435
|
+
private decodePayload;
|
|
258
436
|
}
|
|
259
437
|
|
|
260
438
|
declare class JsonSerializer implements CacheSerializer {
|
|
@@ -281,7 +459,7 @@ declare class RedisSingleFlightCoordinator implements CacheSingleFlightCoordinat
|
|
|
281
459
|
declare class StampedeGuard {
|
|
282
460
|
private readonly mutexes;
|
|
283
461
|
execute<T>(key: string, task: () => Promise<T>): Promise<T>;
|
|
284
|
-
private
|
|
462
|
+
private getMutexEntry;
|
|
285
463
|
}
|
|
286
464
|
|
|
287
|
-
export { type CacheGetOptions, type CacheLayer, type CacheLogger, type CacheMGetEntry, type CacheMSetEntry, type CacheMetricsSnapshot, type CacheSerializer, type CacheSingleFlightCoordinator, type CacheSingleFlightExecutionOptions, CacheStack, type CacheStackOptions, type CacheTagIndex, type CacheWriteOptions, type InvalidationBus, type InvalidationMessage, JsonSerializer, type LayerTtlMap, MemoryLayer, MsgpackSerializer, PatternMatcher, RedisInvalidationBus, RedisLayer, RedisSingleFlightCoordinator, RedisTagIndex, StampedeGuard, TagIndex };
|
|
465
|
+
export { type CacheAdaptiveTtlOptions, type CacheCircuitBreakerOptions, type CacheDegradationOptions, type CacheGetOptions, type CacheLayer, type CacheLogger, type CacheMGetEntry, type CacheMSetEntry, type CacheMetricsSnapshot, CacheNamespace, type CacheSerializer, type CacheSingleFlightCoordinator, type CacheSingleFlightExecutionOptions, type CacheSnapshotEntry, CacheStack, type CacheStackOptions, type CacheStatsSnapshot, type CacheTagIndex, type CacheWarmEntry, type CacheWarmOptions, type CacheWrapOptions, type CacheWriteOptions, type InvalidationBus, type InvalidationMessage, JsonSerializer, type LayerTtlMap, MemoryLayer, MsgpackSerializer, PatternMatcher, RedisInvalidationBus, RedisLayer, RedisSingleFlightCoordinator, RedisTagIndex, StampedeGuard, TagIndex, cacheGraphqlResolver, createCacheStatsHandler, createCachedMethodDecorator, createFastifyLayercachePlugin, createTrpcCacheMiddleware };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
1
2
|
import Redis from 'ioredis';
|
|
2
3
|
|
|
3
4
|
interface LayerTtlMap {
|
|
@@ -11,6 +12,10 @@ interface CacheWriteOptions {
|
|
|
11
12
|
staleWhileRevalidate?: number | LayerTtlMap;
|
|
12
13
|
staleIfError?: number | LayerTtlMap;
|
|
13
14
|
ttlJitter?: number | LayerTtlMap;
|
|
15
|
+
slidingTtl?: boolean;
|
|
16
|
+
refreshAhead?: number | LayerTtlMap;
|
|
17
|
+
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
18
|
+
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
14
19
|
}
|
|
15
20
|
interface CacheGetOptions extends CacheWriteOptions {
|
|
16
21
|
}
|
|
@@ -54,9 +59,17 @@ interface CacheMetricsSnapshot {
|
|
|
54
59
|
refreshErrors: number;
|
|
55
60
|
writeFailures: number;
|
|
56
61
|
singleFlightWaits: number;
|
|
62
|
+
negativeCacheHits: number;
|
|
63
|
+
circuitBreakerTrips: number;
|
|
64
|
+
degradedOperations: number;
|
|
65
|
+
hitsByLayer: Record<string, number>;
|
|
66
|
+
missesByLayer: Record<string, number>;
|
|
57
67
|
}
|
|
58
68
|
interface CacheLogger {
|
|
59
|
-
debug(message: string, context?: Record<string, unknown>): void;
|
|
69
|
+
debug?(message: string, context?: Record<string, unknown>): void;
|
|
70
|
+
info?(message: string, context?: Record<string, unknown>): void;
|
|
71
|
+
warn?(message: string, context?: Record<string, unknown>): void;
|
|
72
|
+
error?(message: string, context?: Record<string, unknown>): void;
|
|
60
73
|
}
|
|
61
74
|
interface CacheTagIndex {
|
|
62
75
|
touch(key: string): Promise<void>;
|
|
@@ -90,20 +103,82 @@ interface CacheStackOptions {
|
|
|
90
103
|
stampedePrevention?: boolean;
|
|
91
104
|
invalidationBus?: InvalidationBus;
|
|
92
105
|
tagIndex?: CacheTagIndex;
|
|
106
|
+
broadcastL1Invalidation?: boolean;
|
|
93
107
|
publishSetInvalidation?: boolean;
|
|
94
108
|
negativeCaching?: boolean;
|
|
95
109
|
negativeTtl?: number | LayerTtlMap;
|
|
96
110
|
staleWhileRevalidate?: number | LayerTtlMap;
|
|
97
111
|
staleIfError?: number | LayerTtlMap;
|
|
98
112
|
ttlJitter?: number | LayerTtlMap;
|
|
113
|
+
refreshAhead?: number | LayerTtlMap;
|
|
114
|
+
adaptiveTtl?: boolean | CacheAdaptiveTtlOptions;
|
|
115
|
+
circuitBreaker?: CacheCircuitBreakerOptions;
|
|
116
|
+
gracefulDegradation?: boolean | CacheDegradationOptions;
|
|
99
117
|
writePolicy?: 'strict' | 'best-effort';
|
|
100
118
|
singleFlightCoordinator?: CacheSingleFlightCoordinator;
|
|
101
119
|
singleFlightLeaseMs?: number;
|
|
102
120
|
singleFlightTimeoutMs?: number;
|
|
103
121
|
singleFlightPollMs?: number;
|
|
104
122
|
}
|
|
123
|
+
interface CacheAdaptiveTtlOptions {
|
|
124
|
+
hotAfter?: number;
|
|
125
|
+
step?: number | LayerTtlMap;
|
|
126
|
+
maxTtl?: number | LayerTtlMap;
|
|
127
|
+
}
|
|
128
|
+
interface CacheCircuitBreakerOptions {
|
|
129
|
+
failureThreshold?: number;
|
|
130
|
+
cooldownMs?: number;
|
|
131
|
+
}
|
|
132
|
+
interface CacheDegradationOptions {
|
|
133
|
+
retryAfterMs?: number;
|
|
134
|
+
}
|
|
135
|
+
interface CacheWarmEntry<T = unknown> {
|
|
136
|
+
key: string;
|
|
137
|
+
fetcher: () => Promise<T>;
|
|
138
|
+
options?: CacheGetOptions;
|
|
139
|
+
priority?: number;
|
|
140
|
+
}
|
|
141
|
+
interface CacheWarmOptions {
|
|
142
|
+
concurrency?: number;
|
|
143
|
+
continueOnError?: boolean;
|
|
144
|
+
}
|
|
145
|
+
interface CacheWrapOptions<TArgs extends unknown[] = unknown[]> extends CacheGetOptions {
|
|
146
|
+
keyResolver?: (...args: TArgs) => string;
|
|
147
|
+
}
|
|
148
|
+
interface CacheSnapshotEntry {
|
|
149
|
+
key: string;
|
|
150
|
+
value: unknown;
|
|
151
|
+
ttl?: number;
|
|
152
|
+
}
|
|
153
|
+
interface CacheStatsSnapshot {
|
|
154
|
+
metrics: CacheMetricsSnapshot;
|
|
155
|
+
layers: Array<{
|
|
156
|
+
name: string;
|
|
157
|
+
isLocal: boolean;
|
|
158
|
+
degradedUntil: number | null;
|
|
159
|
+
}>;
|
|
160
|
+
backgroundRefreshes: number;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
declare class CacheNamespace {
|
|
164
|
+
private readonly cache;
|
|
165
|
+
private readonly prefix;
|
|
166
|
+
constructor(cache: CacheStack, prefix: string);
|
|
167
|
+
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
168
|
+
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
169
|
+
delete(key: string): Promise<void>;
|
|
170
|
+
clear(): Promise<void>;
|
|
171
|
+
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
172
|
+
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
173
|
+
invalidateByTag(tag: string): Promise<void>;
|
|
174
|
+
invalidateByPattern(pattern: string): Promise<void>;
|
|
175
|
+
wrap<TArgs extends unknown[], TResult>(keyPrefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
176
|
+
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
177
|
+
getMetrics(): CacheMetricsSnapshot;
|
|
178
|
+
qualify(key: string): string;
|
|
179
|
+
}
|
|
105
180
|
|
|
106
|
-
declare class CacheStack {
|
|
181
|
+
declare class CacheStack extends EventEmitter {
|
|
107
182
|
private readonly layers;
|
|
108
183
|
private readonly options;
|
|
109
184
|
private readonly stampedeGuard;
|
|
@@ -114,6 +189,11 @@ declare class CacheStack {
|
|
|
114
189
|
private readonly logger;
|
|
115
190
|
private readonly tagIndex;
|
|
116
191
|
private readonly backgroundRefreshes;
|
|
192
|
+
private readonly accessProfiles;
|
|
193
|
+
private readonly layerDegradedUntil;
|
|
194
|
+
private readonly circuitBreakers;
|
|
195
|
+
private isDisconnecting;
|
|
196
|
+
private disconnectPromise?;
|
|
117
197
|
constructor(layers: CacheLayer[], options?: CacheStackOptions);
|
|
118
198
|
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
119
199
|
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
@@ -121,10 +201,18 @@ declare class CacheStack {
|
|
|
121
201
|
clear(): Promise<void>;
|
|
122
202
|
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
123
203
|
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
204
|
+
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
205
|
+
wrap<TArgs extends unknown[], TResult>(prefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
206
|
+
namespace(prefix: string): CacheNamespace;
|
|
124
207
|
invalidateByTag(tag: string): Promise<void>;
|
|
125
208
|
invalidateByPattern(pattern: string): Promise<void>;
|
|
126
209
|
getMetrics(): CacheMetricsSnapshot;
|
|
210
|
+
getStats(): CacheStatsSnapshot;
|
|
127
211
|
resetMetrics(): void;
|
|
212
|
+
exportState(): Promise<CacheSnapshotEntry[]>;
|
|
213
|
+
importState(entries: CacheSnapshotEntry[]): Promise<void>;
|
|
214
|
+
persistToFile(filePath: string): Promise<void>;
|
|
215
|
+
restoreFromFile(filePath: string): Promise<void>;
|
|
128
216
|
disconnect(): Promise<void>;
|
|
129
217
|
private initialize;
|
|
130
218
|
private fetchWithGuards;
|
|
@@ -148,6 +236,32 @@ declare class CacheStack {
|
|
|
148
236
|
private handleInvalidationMessage;
|
|
149
237
|
private formatError;
|
|
150
238
|
private sleep;
|
|
239
|
+
private shouldBroadcastL1Invalidation;
|
|
240
|
+
private deleteKeysFromLayers;
|
|
241
|
+
private validateConfiguration;
|
|
242
|
+
private validateWriteOptions;
|
|
243
|
+
private validateLayerNumberOption;
|
|
244
|
+
private validatePositiveNumber;
|
|
245
|
+
private validateNonNegativeNumber;
|
|
246
|
+
private validateCacheKey;
|
|
247
|
+
private serializeOptions;
|
|
248
|
+
private validateAdaptiveTtlOptions;
|
|
249
|
+
private validateCircuitBreakerOptions;
|
|
250
|
+
private applyFreshReadPolicies;
|
|
251
|
+
private applyAdaptiveTtl;
|
|
252
|
+
private recordAccess;
|
|
253
|
+
private incrementMetricMap;
|
|
254
|
+
private shouldSkipLayer;
|
|
255
|
+
private handleLayerFailure;
|
|
256
|
+
private isGracefulDegradationEnabled;
|
|
257
|
+
private assertCircuitClosed;
|
|
258
|
+
private recordCircuitFailure;
|
|
259
|
+
private resetCircuitBreaker;
|
|
260
|
+
private isNegativeStoredValue;
|
|
261
|
+
private emitError;
|
|
262
|
+
private serializeKeyPart;
|
|
263
|
+
private isCacheSnapshotEntries;
|
|
264
|
+
private normalizeForSerialization;
|
|
151
265
|
}
|
|
152
266
|
|
|
153
267
|
declare class PatternMatcher {
|
|
@@ -163,9 +277,13 @@ declare class RedisInvalidationBus implements InvalidationBus {
|
|
|
163
277
|
private readonly channel;
|
|
164
278
|
private readonly publisher;
|
|
165
279
|
private readonly subscriber;
|
|
280
|
+
private activeListener?;
|
|
166
281
|
constructor(options: RedisInvalidationBusOptions);
|
|
167
282
|
subscribe(handler: (message: InvalidationMessage) => Promise<void> | void): Promise<() => Promise<void>>;
|
|
168
283
|
publish(message: InvalidationMessage): Promise<void>;
|
|
284
|
+
private handleMessage;
|
|
285
|
+
private isInvalidationMessage;
|
|
286
|
+
private reportError;
|
|
169
287
|
}
|
|
170
288
|
|
|
171
289
|
interface RedisTagIndexOptions {
|
|
@@ -202,6 +320,55 @@ declare class TagIndex implements CacheTagIndex {
|
|
|
202
320
|
clear(): Promise<void>;
|
|
203
321
|
}
|
|
204
322
|
|
|
323
|
+
declare function createCacheStatsHandler(cache: CacheStack): (_request: unknown, response: {
|
|
324
|
+
setHeader?: (name: string, value: string) => void;
|
|
325
|
+
end: (body: string) => void;
|
|
326
|
+
statusCode?: number;
|
|
327
|
+
}) => Promise<void>;
|
|
328
|
+
|
|
329
|
+
interface CachedMethodDecoratorOptions<TArgs extends unknown[]> extends CacheWrapOptions<TArgs> {
|
|
330
|
+
cache: (instance: unknown) => CacheStack;
|
|
331
|
+
prefix?: string;
|
|
332
|
+
}
|
|
333
|
+
declare function createCachedMethodDecorator<TArgs extends unknown[] = unknown[]>(options: CachedMethodDecoratorOptions<TArgs>): MethodDecorator;
|
|
334
|
+
|
|
335
|
+
interface FastifyLike {
|
|
336
|
+
decorate: (name: string, value: unknown) => void;
|
|
337
|
+
get?: (path: string, handler: () => unknown | Promise<unknown>) => void;
|
|
338
|
+
}
|
|
339
|
+
interface FastifyLayercachePluginOptions {
|
|
340
|
+
exposeStatsRoute?: boolean;
|
|
341
|
+
statsPath?: string;
|
|
342
|
+
}
|
|
343
|
+
declare function createFastifyLayercachePlugin(cache: CacheStack, options?: FastifyLayercachePluginOptions): (fastify: FastifyLike) => Promise<void>;
|
|
344
|
+
|
|
345
|
+
interface GraphqlCacheOptions<TArgs extends unknown[]> extends CacheGetOptions {
|
|
346
|
+
keyResolver?: (...args: TArgs) => string;
|
|
347
|
+
}
|
|
348
|
+
declare function cacheGraphqlResolver<TArgs extends unknown[], TResult>(cache: CacheStack, prefix: string, resolver: (...args: TArgs) => Promise<TResult>, options?: GraphqlCacheOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
349
|
+
|
|
350
|
+
interface TrpcCacheMiddlewareContext<TInput = unknown, TResult = unknown> {
|
|
351
|
+
path?: string;
|
|
352
|
+
type?: string;
|
|
353
|
+
rawInput?: TInput;
|
|
354
|
+
next: () => Promise<{
|
|
355
|
+
ok: boolean;
|
|
356
|
+
data?: TResult;
|
|
357
|
+
}>;
|
|
358
|
+
}
|
|
359
|
+
interface TrpcCacheMiddlewareOptions<TInput> extends CacheGetOptions {
|
|
360
|
+
keyResolver?: (input: TInput, path?: string, type?: string) => string;
|
|
361
|
+
}
|
|
362
|
+
declare function createTrpcCacheMiddleware<TInput = unknown, TResult = unknown>(cache: CacheStack, prefix: string, options?: TrpcCacheMiddlewareOptions<TInput>): (context: TrpcCacheMiddlewareContext<TInput, TResult>) => Promise<{
|
|
363
|
+
ok: boolean;
|
|
364
|
+
data?: TResult;
|
|
365
|
+
} | null>;
|
|
366
|
+
|
|
367
|
+
interface MemoryLayerSnapshotEntry {
|
|
368
|
+
key: string;
|
|
369
|
+
value: unknown;
|
|
370
|
+
expiresAt: number | null;
|
|
371
|
+
}
|
|
205
372
|
interface MemoryLayerOptions {
|
|
206
373
|
ttl?: number;
|
|
207
374
|
maxSize?: number;
|
|
@@ -222,10 +389,13 @@ declare class MemoryLayer implements CacheLayer {
|
|
|
222
389
|
deleteMany(keys: string[]): Promise<void>;
|
|
223
390
|
clear(): Promise<void>;
|
|
224
391
|
keys(): Promise<string[]>;
|
|
392
|
+
exportState(): MemoryLayerSnapshotEntry[];
|
|
393
|
+
importState(entries: MemoryLayerSnapshotEntry[]): void;
|
|
225
394
|
private pruneExpired;
|
|
226
395
|
private isExpired;
|
|
227
396
|
}
|
|
228
397
|
|
|
398
|
+
type CompressionAlgorithm = 'gzip' | 'brotli';
|
|
229
399
|
interface RedisLayerOptions {
|
|
230
400
|
client: Redis;
|
|
231
401
|
ttl?: number;
|
|
@@ -234,6 +404,8 @@ interface RedisLayerOptions {
|
|
|
234
404
|
prefix?: string;
|
|
235
405
|
allowUnprefixedClear?: boolean;
|
|
236
406
|
scanCount?: number;
|
|
407
|
+
compression?: CompressionAlgorithm;
|
|
408
|
+
compressionThreshold?: number;
|
|
237
409
|
}
|
|
238
410
|
declare class RedisLayer implements CacheLayer {
|
|
239
411
|
readonly name: string;
|
|
@@ -244,6 +416,8 @@ declare class RedisLayer implements CacheLayer {
|
|
|
244
416
|
private readonly prefix;
|
|
245
417
|
private readonly allowUnprefixedClear;
|
|
246
418
|
private readonly scanCount;
|
|
419
|
+
private readonly compression?;
|
|
420
|
+
private readonly compressionThreshold;
|
|
247
421
|
constructor(options: RedisLayerOptions);
|
|
248
422
|
get<T>(key: string): Promise<T | null>;
|
|
249
423
|
getEntry<T = unknown>(key: string): Promise<T | null>;
|
|
@@ -255,6 +429,10 @@ declare class RedisLayer implements CacheLayer {
|
|
|
255
429
|
keys(): Promise<string[]>;
|
|
256
430
|
private scanKeys;
|
|
257
431
|
private withPrefix;
|
|
432
|
+
private deserializeOrDelete;
|
|
433
|
+
private isSerializablePayload;
|
|
434
|
+
private encodePayload;
|
|
435
|
+
private decodePayload;
|
|
258
436
|
}
|
|
259
437
|
|
|
260
438
|
declare class JsonSerializer implements CacheSerializer {
|
|
@@ -281,7 +459,7 @@ declare class RedisSingleFlightCoordinator implements CacheSingleFlightCoordinat
|
|
|
281
459
|
declare class StampedeGuard {
|
|
282
460
|
private readonly mutexes;
|
|
283
461
|
execute<T>(key: string, task: () => Promise<T>): Promise<T>;
|
|
284
|
-
private
|
|
462
|
+
private getMutexEntry;
|
|
285
463
|
}
|
|
286
464
|
|
|
287
|
-
export { type CacheGetOptions, type CacheLayer, type CacheLogger, type CacheMGetEntry, type CacheMSetEntry, type CacheMetricsSnapshot, type CacheSerializer, type CacheSingleFlightCoordinator, type CacheSingleFlightExecutionOptions, CacheStack, type CacheStackOptions, type CacheTagIndex, type CacheWriteOptions, type InvalidationBus, type InvalidationMessage, JsonSerializer, type LayerTtlMap, MemoryLayer, MsgpackSerializer, PatternMatcher, RedisInvalidationBus, RedisLayer, RedisSingleFlightCoordinator, RedisTagIndex, StampedeGuard, TagIndex };
|
|
465
|
+
export { type CacheAdaptiveTtlOptions, type CacheCircuitBreakerOptions, type CacheDegradationOptions, type CacheGetOptions, type CacheLayer, type CacheLogger, type CacheMGetEntry, type CacheMSetEntry, type CacheMetricsSnapshot, CacheNamespace, type CacheSerializer, type CacheSingleFlightCoordinator, type CacheSingleFlightExecutionOptions, type CacheSnapshotEntry, CacheStack, type CacheStackOptions, type CacheStatsSnapshot, type CacheTagIndex, type CacheWarmEntry, type CacheWarmOptions, type CacheWrapOptions, type CacheWriteOptions, type InvalidationBus, type InvalidationMessage, JsonSerializer, type LayerTtlMap, MemoryLayer, MsgpackSerializer, PatternMatcher, RedisInvalidationBus, RedisLayer, RedisSingleFlightCoordinator, RedisTagIndex, StampedeGuard, TagIndex, cacheGraphqlResolver, createCacheStatsHandler, createCachedMethodDecorator, createFastifyLayercachePlugin, createTrpcCacheMiddleware };
|