layercache 1.0.2 → 1.1.0
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/benchmarks/latency.ts +1 -1
- package/benchmarks/stampede.ts +1 -4
- package/dist/{chunk-IILH5XTS.js → chunk-QUB5VZFZ.js} +33 -4
- package/dist/cli.cjs +75 -7
- package/dist/cli.js +43 -4
- package/dist/index.cjs +894 -240
- package/dist/index.d.cts +291 -11
- package/dist/index.d.ts +291 -11
- package/dist/index.js +858 -236
- package/examples/express-api/index.ts +12 -8
- package/examples/nestjs-module/app.module.ts +2 -5
- package/examples/nextjs-api-routes/route.ts +1 -4
- package/package.json +6 -1
- package/packages/nestjs/dist/index.cjs +552 -220
- package/packages/nestjs/dist/index.d.cts +151 -10
- package/packages/nestjs/dist/index.d.ts +151 -10
- package/packages/nestjs/dist/index.js +552 -220
package/dist/index.d.cts
CHANGED
|
@@ -29,6 +29,7 @@ interface CacheMSetEntry<T> {
|
|
|
29
29
|
value: T;
|
|
30
30
|
options?: CacheWriteOptions;
|
|
31
31
|
}
|
|
32
|
+
/** Interface that all cache backend implementations must satisfy. */
|
|
32
33
|
interface CacheLayer {
|
|
33
34
|
readonly name: string;
|
|
34
35
|
readonly defaultTtl?: number;
|
|
@@ -41,11 +42,28 @@ interface CacheLayer {
|
|
|
41
42
|
clear(): Promise<void>;
|
|
42
43
|
deleteMany?(keys: string[]): Promise<void>;
|
|
43
44
|
keys?(): Promise<string[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Returns true if the key exists and has not expired.
|
|
47
|
+
* Implementations may omit this; CacheStack will fall back to `get()`.
|
|
48
|
+
*/
|
|
49
|
+
has?(key: string): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Returns the remaining TTL in seconds for the key, or null if the key
|
|
52
|
+
* does not exist, has no TTL, or has already expired.
|
|
53
|
+
* Implementations may omit this.
|
|
54
|
+
*/
|
|
55
|
+
ttl?(key: string): Promise<number | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Returns the number of entries currently held by this layer.
|
|
58
|
+
* Implementations may omit this.
|
|
59
|
+
*/
|
|
60
|
+
size?(): Promise<number>;
|
|
44
61
|
}
|
|
45
62
|
interface CacheSerializer {
|
|
46
63
|
serialize(value: unknown): string | Buffer;
|
|
47
64
|
deserialize<T>(payload: string | Buffer): T;
|
|
48
65
|
}
|
|
66
|
+
/** Snapshot of cumulative cache counters. */
|
|
49
67
|
interface CacheMetricsSnapshot {
|
|
50
68
|
hits: number;
|
|
51
69
|
misses: number;
|
|
@@ -64,6 +82,15 @@ interface CacheMetricsSnapshot {
|
|
|
64
82
|
degradedOperations: number;
|
|
65
83
|
hitsByLayer: Record<string, number>;
|
|
66
84
|
missesByLayer: Record<string, number>;
|
|
85
|
+
/** Timestamp (ms since epoch) when metrics were last reset. */
|
|
86
|
+
resetAt: number;
|
|
87
|
+
}
|
|
88
|
+
/** Computed hit-rate statistics derived from CacheMetricsSnapshot. */
|
|
89
|
+
interface CacheHitRateSnapshot {
|
|
90
|
+
/** Overall hit rate across all layers (0–1). */
|
|
91
|
+
overall: number;
|
|
92
|
+
/** Per-layer hit rates (0–1 each). */
|
|
93
|
+
byLayer: Record<string, number>;
|
|
67
94
|
}
|
|
68
95
|
interface CacheLogger {
|
|
69
96
|
debug?(message: string, context?: Record<string, unknown>): void;
|
|
@@ -104,6 +131,9 @@ interface CacheStackOptions {
|
|
|
104
131
|
invalidationBus?: InvalidationBus;
|
|
105
132
|
tagIndex?: CacheTagIndex;
|
|
106
133
|
broadcastL1Invalidation?: boolean;
|
|
134
|
+
/**
|
|
135
|
+
* @deprecated Use `broadcastL1Invalidation` instead.
|
|
136
|
+
*/
|
|
107
137
|
publishSetInvalidation?: boolean;
|
|
108
138
|
negativeCaching?: boolean;
|
|
109
139
|
negativeTtl?: number | LayerTtlMap;
|
|
@@ -119,6 +149,12 @@ interface CacheStackOptions {
|
|
|
119
149
|
singleFlightLeaseMs?: number;
|
|
120
150
|
singleFlightTimeoutMs?: number;
|
|
121
151
|
singleFlightPollMs?: number;
|
|
152
|
+
/**
|
|
153
|
+
* Maximum number of entries in `accessProfiles` and `circuitBreakers` maps
|
|
154
|
+
* before the oldest entries are pruned. Prevents unbounded memory growth.
|
|
155
|
+
* Defaults to 100 000.
|
|
156
|
+
*/
|
|
157
|
+
maxProfileEntries?: number;
|
|
122
158
|
}
|
|
123
159
|
interface CacheAdaptiveTtlOptions {
|
|
124
160
|
hotAfter?: number;
|
|
@@ -138,9 +174,19 @@ interface CacheWarmEntry<T = unknown> {
|
|
|
138
174
|
options?: CacheGetOptions;
|
|
139
175
|
priority?: number;
|
|
140
176
|
}
|
|
177
|
+
/** Options controlling the cache warm-up process. */
|
|
141
178
|
interface CacheWarmOptions {
|
|
142
179
|
concurrency?: number;
|
|
143
180
|
continueOnError?: boolean;
|
|
181
|
+
/** Called after each entry is processed (success or failure). */
|
|
182
|
+
onProgress?: (progress: CacheWarmProgress) => void;
|
|
183
|
+
}
|
|
184
|
+
/** Progress information delivered to `CacheWarmOptions.onProgress`. */
|
|
185
|
+
interface CacheWarmProgress {
|
|
186
|
+
completed: number;
|
|
187
|
+
total: number;
|
|
188
|
+
key: string;
|
|
189
|
+
success: boolean;
|
|
144
190
|
}
|
|
145
191
|
interface CacheWrapOptions<TArgs extends unknown[] = unknown[]> extends CacheGetOptions {
|
|
146
192
|
keyResolver?: (...args: TArgs) => string;
|
|
@@ -159,14 +205,66 @@ interface CacheStatsSnapshot {
|
|
|
159
205
|
}>;
|
|
160
206
|
backgroundRefreshes: number;
|
|
161
207
|
}
|
|
208
|
+
/** All events emitted by CacheStack and their payload shapes. */
|
|
209
|
+
interface CacheStackEvents {
|
|
210
|
+
/** Fired on every cache hit. */
|
|
211
|
+
hit: {
|
|
212
|
+
key: string;
|
|
213
|
+
layer: string;
|
|
214
|
+
state: 'fresh' | 'stale-while-revalidate' | 'stale-if-error';
|
|
215
|
+
};
|
|
216
|
+
/** Fired on every cache miss before the fetcher runs. */
|
|
217
|
+
miss: {
|
|
218
|
+
key: string;
|
|
219
|
+
mode: string;
|
|
220
|
+
};
|
|
221
|
+
/** Fired after a value is stored in the cache. */
|
|
222
|
+
set: {
|
|
223
|
+
key: string;
|
|
224
|
+
kind: string;
|
|
225
|
+
tags?: string[];
|
|
226
|
+
};
|
|
227
|
+
/** Fired after one or more keys are deleted. */
|
|
228
|
+
delete: {
|
|
229
|
+
keys: string[];
|
|
230
|
+
};
|
|
231
|
+
/** Fired when a value is backfilled into a faster layer. */
|
|
232
|
+
backfill: {
|
|
233
|
+
key: string;
|
|
234
|
+
layer: string;
|
|
235
|
+
};
|
|
236
|
+
/** Fired when a stale value is returned to the caller. */
|
|
237
|
+
'stale-serve': {
|
|
238
|
+
key: string;
|
|
239
|
+
state: string;
|
|
240
|
+
layer: string;
|
|
241
|
+
};
|
|
242
|
+
/** Fired when a duplicate request is deduplicated in stampede prevention. */
|
|
243
|
+
'stampede-dedupe': {
|
|
244
|
+
key: string;
|
|
245
|
+
};
|
|
246
|
+
/** Fired after a key is successfully warmed. */
|
|
247
|
+
warm: {
|
|
248
|
+
key: string;
|
|
249
|
+
};
|
|
250
|
+
/** Fired when an error occurs (layer failure, circuit breaker, etc.). */
|
|
251
|
+
error: {
|
|
252
|
+
operation: string;
|
|
253
|
+
[key: string]: unknown;
|
|
254
|
+
};
|
|
255
|
+
}
|
|
162
256
|
|
|
163
257
|
declare class CacheNamespace {
|
|
164
258
|
private readonly cache;
|
|
165
259
|
private readonly prefix;
|
|
166
260
|
constructor(cache: CacheStack, prefix: string);
|
|
167
261
|
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
262
|
+
getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
263
|
+
has(key: string): Promise<boolean>;
|
|
264
|
+
ttl(key: string): Promise<number | null>;
|
|
168
265
|
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
169
266
|
delete(key: string): Promise<void>;
|
|
267
|
+
mdelete(keys: string[]): Promise<void>;
|
|
170
268
|
clear(): Promise<void>;
|
|
171
269
|
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
172
270
|
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
@@ -175,40 +273,90 @@ declare class CacheNamespace {
|
|
|
175
273
|
wrap<TArgs extends unknown[], TResult>(keyPrefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
176
274
|
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
177
275
|
getMetrics(): CacheMetricsSnapshot;
|
|
276
|
+
getHitRate(): CacheHitRateSnapshot;
|
|
178
277
|
qualify(key: string): string;
|
|
179
278
|
}
|
|
180
279
|
|
|
280
|
+
/** Typed overloads for EventEmitter so callers get autocomplete on event names. */
|
|
281
|
+
interface CacheStack {
|
|
282
|
+
on<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
283
|
+
once<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
284
|
+
off<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
|
|
285
|
+
emit<K extends keyof CacheStackEvents>(event: K, data: CacheStackEvents[K]): boolean;
|
|
286
|
+
}
|
|
181
287
|
declare class CacheStack extends EventEmitter {
|
|
182
288
|
private readonly layers;
|
|
183
289
|
private readonly options;
|
|
184
290
|
private readonly stampedeGuard;
|
|
185
|
-
private readonly
|
|
291
|
+
private readonly metricsCollector;
|
|
186
292
|
private readonly instanceId;
|
|
187
293
|
private readonly startup;
|
|
188
294
|
private unsubscribeInvalidation?;
|
|
189
295
|
private readonly logger;
|
|
190
296
|
private readonly tagIndex;
|
|
191
297
|
private readonly backgroundRefreshes;
|
|
192
|
-
private readonly accessProfiles;
|
|
193
298
|
private readonly layerDegradedUntil;
|
|
194
|
-
private readonly
|
|
299
|
+
private readonly ttlResolver;
|
|
300
|
+
private readonly circuitBreakerManager;
|
|
195
301
|
private isDisconnecting;
|
|
196
302
|
private disconnectPromise?;
|
|
197
303
|
constructor(layers: CacheLayer[], options?: CacheStackOptions);
|
|
304
|
+
/**
|
|
305
|
+
* Read-through cache get.
|
|
306
|
+
* Returns the cached value if present and fresh, or invokes `fetcher` on a miss
|
|
307
|
+
* and stores the result across all layers. Returns `null` if the key is not found
|
|
308
|
+
* and no `fetcher` is provided.
|
|
309
|
+
*/
|
|
198
310
|
get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
311
|
+
/**
|
|
312
|
+
* Alias for `get(key, fetcher, options)` — explicit get-or-set pattern.
|
|
313
|
+
* Fetches and caches the value if not already present.
|
|
314
|
+
*/
|
|
315
|
+
getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
|
|
316
|
+
/**
|
|
317
|
+
* Returns true if the given key exists and is not expired in any layer.
|
|
318
|
+
*/
|
|
319
|
+
has(key: string): Promise<boolean>;
|
|
320
|
+
/**
|
|
321
|
+
* Returns the remaining TTL in seconds for the key in the fastest layer
|
|
322
|
+
* that has it, or null if the key is not found / has no TTL.
|
|
323
|
+
*/
|
|
324
|
+
ttl(key: string): Promise<number | null>;
|
|
325
|
+
/**
|
|
326
|
+
* Stores a value in all cache layers. Overwrites any existing value.
|
|
327
|
+
*/
|
|
199
328
|
set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
|
|
329
|
+
/**
|
|
330
|
+
* Deletes the key from all layers and publishes an invalidation message.
|
|
331
|
+
*/
|
|
200
332
|
delete(key: string): Promise<void>;
|
|
201
333
|
clear(): Promise<void>;
|
|
334
|
+
/**
|
|
335
|
+
* Deletes multiple keys at once. More efficient than calling `delete()` in a loop.
|
|
336
|
+
*/
|
|
337
|
+
mdelete(keys: string[]): Promise<void>;
|
|
202
338
|
mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
|
|
203
339
|
mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
|
|
204
340
|
warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
|
|
341
|
+
/**
|
|
342
|
+
* Returns a cached version of `fetcher`. The cache key is derived from
|
|
343
|
+
* `prefix` plus the serialized arguments unless a `keyResolver` is provided.
|
|
344
|
+
*/
|
|
205
345
|
wrap<TArgs extends unknown[], TResult>(prefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
|
|
346
|
+
/**
|
|
347
|
+
* Creates a `CacheNamespace` that automatically prefixes all keys with
|
|
348
|
+
* `prefix:`. Useful for multi-tenant or module-level isolation.
|
|
349
|
+
*/
|
|
206
350
|
namespace(prefix: string): CacheNamespace;
|
|
207
351
|
invalidateByTag(tag: string): Promise<void>;
|
|
208
352
|
invalidateByPattern(pattern: string): Promise<void>;
|
|
209
353
|
getMetrics(): CacheMetricsSnapshot;
|
|
210
354
|
getStats(): CacheStatsSnapshot;
|
|
211
355
|
resetMetrics(): void;
|
|
356
|
+
/**
|
|
357
|
+
* Returns computed hit-rate statistics (overall and per-layer).
|
|
358
|
+
*/
|
|
359
|
+
getHitRate(): CacheHitRateSnapshot;
|
|
212
360
|
exportState(): Promise<CacheSnapshotEntry[]>;
|
|
213
361
|
importState(entries: CacheSnapshotEntry[]): Promise<void>;
|
|
214
362
|
persistToFile(filePath: string): Promise<void>;
|
|
@@ -226,8 +374,6 @@ declare class CacheStack extends EventEmitter {
|
|
|
226
374
|
private executeLayerOperations;
|
|
227
375
|
private resolveFreshTtl;
|
|
228
376
|
private resolveLayerSeconds;
|
|
229
|
-
private readLayerNumber;
|
|
230
|
-
private applyJitter;
|
|
231
377
|
private shouldNegativeCache;
|
|
232
378
|
private scheduleBackgroundRefresh;
|
|
233
379
|
private resolveSingleFlightOptions;
|
|
@@ -248,15 +394,10 @@ declare class CacheStack extends EventEmitter {
|
|
|
248
394
|
private validateAdaptiveTtlOptions;
|
|
249
395
|
private validateCircuitBreakerOptions;
|
|
250
396
|
private applyFreshReadPolicies;
|
|
251
|
-
private applyAdaptiveTtl;
|
|
252
|
-
private recordAccess;
|
|
253
|
-
private incrementMetricMap;
|
|
254
397
|
private shouldSkipLayer;
|
|
255
398
|
private handleLayerFailure;
|
|
256
399
|
private isGracefulDegradationEnabled;
|
|
257
|
-
private assertCircuitClosed;
|
|
258
400
|
private recordCircuitFailure;
|
|
259
|
-
private resetCircuitBreaker;
|
|
260
401
|
private isNegativeStoredValue;
|
|
261
402
|
private emitError;
|
|
262
403
|
private serializeKeyPart;
|
|
@@ -265,7 +406,17 @@ declare class CacheStack extends EventEmitter {
|
|
|
265
406
|
}
|
|
266
407
|
|
|
267
408
|
declare class PatternMatcher {
|
|
409
|
+
/**
|
|
410
|
+
* Tests whether a glob-style pattern matches a value.
|
|
411
|
+
* Supports `*` (any sequence of characters) and `?` (any single character).
|
|
412
|
+
* Uses a linear-time algorithm to avoid ReDoS vulnerabilities.
|
|
413
|
+
*/
|
|
268
414
|
static matches(pattern: string, value: string): boolean;
|
|
415
|
+
/**
|
|
416
|
+
* Linear-time glob matching using dynamic programming.
|
|
417
|
+
* Avoids catastrophic backtracking that RegExp-based glob matching can cause.
|
|
418
|
+
*/
|
|
419
|
+
private static matchLinear;
|
|
269
420
|
}
|
|
270
421
|
|
|
271
422
|
interface RedisInvalidationBusOptions {
|
|
@@ -369,28 +520,41 @@ interface MemoryLayerSnapshotEntry {
|
|
|
369
520
|
value: unknown;
|
|
370
521
|
expiresAt: number | null;
|
|
371
522
|
}
|
|
523
|
+
/**
|
|
524
|
+
* Eviction policy applied when `maxSize` is reached.
|
|
525
|
+
* - `lru` (default): evicts the Least Recently Used entry.
|
|
526
|
+
* - `lfu`: evicts the Least Frequently Used entry.
|
|
527
|
+
* - `fifo`: evicts the oldest inserted entry.
|
|
528
|
+
*/
|
|
529
|
+
type EvictionPolicy = 'lru' | 'lfu' | 'fifo';
|
|
372
530
|
interface MemoryLayerOptions {
|
|
373
531
|
ttl?: number;
|
|
374
532
|
maxSize?: number;
|
|
375
533
|
name?: string;
|
|
534
|
+
evictionPolicy?: EvictionPolicy;
|
|
376
535
|
}
|
|
377
536
|
declare class MemoryLayer implements CacheLayer {
|
|
378
537
|
readonly name: string;
|
|
379
538
|
readonly defaultTtl?: number;
|
|
380
539
|
readonly isLocal = true;
|
|
381
540
|
private readonly maxSize;
|
|
541
|
+
private readonly evictionPolicy;
|
|
382
542
|
private readonly entries;
|
|
383
543
|
constructor(options?: MemoryLayerOptions);
|
|
384
544
|
get<T>(key: string): Promise<T | null>;
|
|
385
545
|
getEntry<T = unknown>(key: string): Promise<T | null>;
|
|
386
546
|
getMany<T>(keys: string[]): Promise<Array<T | null>>;
|
|
387
547
|
set(key: string, value: unknown, ttl?: number | undefined): Promise<void>;
|
|
548
|
+
has(key: string): Promise<boolean>;
|
|
549
|
+
ttl(key: string): Promise<number | null>;
|
|
550
|
+
size(): Promise<number>;
|
|
388
551
|
delete(key: string): Promise<void>;
|
|
389
552
|
deleteMany(keys: string[]): Promise<void>;
|
|
390
553
|
clear(): Promise<void>;
|
|
391
554
|
keys(): Promise<string[]>;
|
|
392
555
|
exportState(): MemoryLayerSnapshotEntry[];
|
|
393
556
|
importState(entries: MemoryLayerSnapshotEntry[]): void;
|
|
557
|
+
private evict;
|
|
394
558
|
private pruneExpired;
|
|
395
559
|
private isExpired;
|
|
396
560
|
}
|
|
@@ -425,6 +589,13 @@ declare class RedisLayer implements CacheLayer {
|
|
|
425
589
|
set(key: string, value: unknown, ttl?: number | undefined): Promise<void>;
|
|
426
590
|
delete(key: string): Promise<void>;
|
|
427
591
|
deleteMany(keys: string[]): Promise<void>;
|
|
592
|
+
has(key: string): Promise<boolean>;
|
|
593
|
+
ttl(key: string): Promise<number | null>;
|
|
594
|
+
size(): Promise<number>;
|
|
595
|
+
/**
|
|
596
|
+
* Deletes all keys matching the layer's prefix in batches to avoid
|
|
597
|
+
* loading millions of keys into memory at once.
|
|
598
|
+
*/
|
|
428
599
|
clear(): Promise<void>;
|
|
429
600
|
keys(): Promise<string[]>;
|
|
430
601
|
private scanKeys;
|
|
@@ -435,6 +606,94 @@ declare class RedisLayer implements CacheLayer {
|
|
|
435
606
|
private decodePayload;
|
|
436
607
|
}
|
|
437
608
|
|
|
609
|
+
interface DiskLayerOptions {
|
|
610
|
+
directory: string;
|
|
611
|
+
ttl?: number;
|
|
612
|
+
name?: string;
|
|
613
|
+
serializer?: CacheSerializer;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* A file-system backed cache layer.
|
|
617
|
+
* Each key is stored as a separate JSON file in `directory`.
|
|
618
|
+
* Useful for persisting cache across process restarts without needing Redis.
|
|
619
|
+
*
|
|
620
|
+
* NOTE: DiskLayer is designed for low-to-medium traffic scenarios.
|
|
621
|
+
* For high-throughput workloads, use MemoryLayer + RedisLayer.
|
|
622
|
+
*/
|
|
623
|
+
declare class DiskLayer implements CacheLayer {
|
|
624
|
+
readonly name: string;
|
|
625
|
+
readonly defaultTtl?: number;
|
|
626
|
+
readonly isLocal = true;
|
|
627
|
+
private readonly directory;
|
|
628
|
+
private readonly serializer;
|
|
629
|
+
constructor(options: DiskLayerOptions);
|
|
630
|
+
get<T>(key: string): Promise<T | null>;
|
|
631
|
+
getEntry<T = unknown>(key: string): Promise<T | null>;
|
|
632
|
+
set(key: string, value: unknown, ttl?: number | undefined): Promise<void>;
|
|
633
|
+
has(key: string): Promise<boolean>;
|
|
634
|
+
ttl(key: string): Promise<number | null>;
|
|
635
|
+
delete(key: string): Promise<void>;
|
|
636
|
+
deleteMany(keys: string[]): Promise<void>;
|
|
637
|
+
clear(): Promise<void>;
|
|
638
|
+
keys(): Promise<string[]>;
|
|
639
|
+
size(): Promise<number>;
|
|
640
|
+
private keyToPath;
|
|
641
|
+
private safeDelete;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Minimal interface that MemcachedLayer expects from a Memcached client.
|
|
646
|
+
* Compatible with the `memjs` and `memcache-client` npm packages.
|
|
647
|
+
*
|
|
648
|
+
* Install one of:
|
|
649
|
+
* npm install memjs
|
|
650
|
+
* npm install memcache-client
|
|
651
|
+
*/
|
|
652
|
+
interface MemcachedClient {
|
|
653
|
+
get(key: string): Promise<{
|
|
654
|
+
value: Buffer | null;
|
|
655
|
+
} | null>;
|
|
656
|
+
set(key: string, value: string | Buffer, options?: {
|
|
657
|
+
expires?: number;
|
|
658
|
+
}): Promise<boolean | undefined>;
|
|
659
|
+
delete(key: string): Promise<boolean | undefined>;
|
|
660
|
+
}
|
|
661
|
+
interface MemcachedLayerOptions {
|
|
662
|
+
client: MemcachedClient;
|
|
663
|
+
ttl?: number;
|
|
664
|
+
name?: string;
|
|
665
|
+
keyPrefix?: string;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Memcached-backed cache layer.
|
|
669
|
+
*
|
|
670
|
+
* Example usage with `memjs`:
|
|
671
|
+
* ```ts
|
|
672
|
+
* import Memjs from 'memjs'
|
|
673
|
+
* import { CacheStack, MemcachedLayer, MemoryLayer } from 'layercache'
|
|
674
|
+
*
|
|
675
|
+
* const memcached = Memjs.Client.create('localhost:11211')
|
|
676
|
+
* const cache = new CacheStack([
|
|
677
|
+
* new MemoryLayer({ ttl: 30 }),
|
|
678
|
+
* new MemcachedLayer({ client: memcached, ttl: 300 })
|
|
679
|
+
* ])
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
declare class MemcachedLayer implements CacheLayer {
|
|
683
|
+
readonly name: string;
|
|
684
|
+
readonly defaultTtl?: number;
|
|
685
|
+
readonly isLocal = false;
|
|
686
|
+
private readonly client;
|
|
687
|
+
private readonly keyPrefix;
|
|
688
|
+
constructor(options: MemcachedLayerOptions);
|
|
689
|
+
get<T>(key: string): Promise<T | null>;
|
|
690
|
+
set(key: string, value: unknown, ttl?: number | undefined): Promise<void>;
|
|
691
|
+
delete(key: string): Promise<void>;
|
|
692
|
+
deleteMany(keys: string[]): Promise<void>;
|
|
693
|
+
clear(): Promise<void>;
|
|
694
|
+
private withPrefix;
|
|
695
|
+
}
|
|
696
|
+
|
|
438
697
|
declare class JsonSerializer implements CacheSerializer {
|
|
439
698
|
serialize(value: unknown): string;
|
|
440
699
|
deserialize<T>(payload: string | Buffer): T;
|
|
@@ -462,4 +721,25 @@ declare class StampedeGuard {
|
|
|
462
721
|
private getMutexEntry;
|
|
463
722
|
}
|
|
464
723
|
|
|
465
|
-
|
|
724
|
+
/**
|
|
725
|
+
* Returns a function that generates a Prometheus-compatible text exposition
|
|
726
|
+
* of the cache metrics from one or more CacheStack instances.
|
|
727
|
+
*
|
|
728
|
+
* Usage example:
|
|
729
|
+
* ```ts
|
|
730
|
+
* const collect = createPrometheusMetricsExporter(cache)
|
|
731
|
+
* http.createServer(async (_req, res) => {
|
|
732
|
+
* res.setHeader('content-type', 'text/plain; version=0.0.4; charset=utf-8')
|
|
733
|
+
* res.end(collect())
|
|
734
|
+
* }).listen(9091)
|
|
735
|
+
* ```
|
|
736
|
+
*
|
|
737
|
+
* @param stacks One or more CacheStack instances. When multiple stacks are
|
|
738
|
+
* given, each must be named via the optional `name` parameter.
|
|
739
|
+
*/
|
|
740
|
+
declare function createPrometheusMetricsExporter(stacks: CacheStack | Array<{
|
|
741
|
+
stack: CacheStack;
|
|
742
|
+
name: string;
|
|
743
|
+
}>): () => string;
|
|
744
|
+
|
|
745
|
+
export { type CacheAdaptiveTtlOptions, type CacheCircuitBreakerOptions, type CacheDegradationOptions, type CacheGetOptions, type CacheHitRateSnapshot, type CacheLayer, type CacheLogger, type CacheMGetEntry, type CacheMSetEntry, type CacheMetricsSnapshot, CacheNamespace, type CacheSerializer, type CacheSingleFlightCoordinator, type CacheSingleFlightExecutionOptions, type CacheSnapshotEntry, CacheStack, type CacheStackEvents, type CacheStackOptions, type CacheStatsSnapshot, type CacheTagIndex, type CacheWarmEntry, type CacheWarmOptions, type CacheWarmProgress, type CacheWrapOptions, type CacheWriteOptions, DiskLayer, type EvictionPolicy, type InvalidationBus, type InvalidationMessage, JsonSerializer, type LayerTtlMap, type MemcachedClient, MemcachedLayer, MemoryLayer, type MemoryLayerSnapshotEntry, MsgpackSerializer, PatternMatcher, RedisInvalidationBus, RedisLayer, RedisSingleFlightCoordinator, RedisTagIndex, StampedeGuard, TagIndex, cacheGraphqlResolver, createCacheStatsHandler, createCachedMethodDecorator, createFastifyLayercachePlugin, createPrometheusMetricsExporter, createTrpcCacheMiddleware };
|