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.
@@ -31,6 +31,7 @@ interface CacheMSetEntry<T> {
31
31
  value: T;
32
32
  options?: CacheWriteOptions;
33
33
  }
34
+ /** Interface that all cache backend implementations must satisfy. */
34
35
  interface CacheLayer {
35
36
  readonly name: string;
36
37
  readonly defaultTtl?: number;
@@ -43,7 +44,24 @@ interface CacheLayer {
43
44
  clear(): Promise<void>;
44
45
  deleteMany?(keys: string[]): Promise<void>;
45
46
  keys?(): Promise<string[]>;
47
+ /**
48
+ * Returns true if the key exists and has not expired.
49
+ * Implementations may omit this; CacheStack will fall back to `get()`.
50
+ */
51
+ has?(key: string): Promise<boolean>;
52
+ /**
53
+ * Returns the remaining TTL in seconds for the key, or null if the key
54
+ * does not exist, has no TTL, or has already expired.
55
+ * Implementations may omit this.
56
+ */
57
+ ttl?(key: string): Promise<number | null>;
58
+ /**
59
+ * Returns the number of entries currently held by this layer.
60
+ * Implementations may omit this.
61
+ */
62
+ size?(): Promise<number>;
46
63
  }
64
+ /** Snapshot of cumulative cache counters. */
47
65
  interface CacheMetricsSnapshot {
48
66
  hits: number;
49
67
  misses: number;
@@ -62,6 +80,15 @@ interface CacheMetricsSnapshot {
62
80
  degradedOperations: number;
63
81
  hitsByLayer: Record<string, number>;
64
82
  missesByLayer: Record<string, number>;
83
+ /** Timestamp (ms since epoch) when metrics were last reset. */
84
+ resetAt: number;
85
+ }
86
+ /** Computed hit-rate statistics derived from CacheMetricsSnapshot. */
87
+ interface CacheHitRateSnapshot {
88
+ /** Overall hit rate across all layers (0–1). */
89
+ overall: number;
90
+ /** Per-layer hit rates (0–1 each). */
91
+ byLayer: Record<string, number>;
65
92
  }
66
93
  interface CacheLogger {
67
94
  debug?(message: string, context?: Record<string, unknown>): void;
@@ -102,6 +129,9 @@ interface CacheStackOptions {
102
129
  invalidationBus?: InvalidationBus;
103
130
  tagIndex?: CacheTagIndex;
104
131
  broadcastL1Invalidation?: boolean;
132
+ /**
133
+ * @deprecated Use `broadcastL1Invalidation` instead.
134
+ */
105
135
  publishSetInvalidation?: boolean;
106
136
  negativeCaching?: boolean;
107
137
  negativeTtl?: number | LayerTtlMap;
@@ -117,6 +147,12 @@ interface CacheStackOptions {
117
147
  singleFlightLeaseMs?: number;
118
148
  singleFlightTimeoutMs?: number;
119
149
  singleFlightPollMs?: number;
150
+ /**
151
+ * Maximum number of entries in `accessProfiles` and `circuitBreakers` maps
152
+ * before the oldest entries are pruned. Prevents unbounded memory growth.
153
+ * Defaults to 100 000.
154
+ */
155
+ maxProfileEntries?: number;
120
156
  }
121
157
  interface CacheAdaptiveTtlOptions {
122
158
  hotAfter?: number;
@@ -136,9 +172,19 @@ interface CacheWarmEntry<T = unknown> {
136
172
  options?: CacheGetOptions;
137
173
  priority?: number;
138
174
  }
175
+ /** Options controlling the cache warm-up process. */
139
176
  interface CacheWarmOptions {
140
177
  concurrency?: number;
141
178
  continueOnError?: boolean;
179
+ /** Called after each entry is processed (success or failure). */
180
+ onProgress?: (progress: CacheWarmProgress) => void;
181
+ }
182
+ /** Progress information delivered to `CacheWarmOptions.onProgress`. */
183
+ interface CacheWarmProgress {
184
+ completed: number;
185
+ total: number;
186
+ key: string;
187
+ success: boolean;
142
188
  }
143
189
  interface CacheWrapOptions<TArgs extends unknown[] = unknown[]> extends CacheGetOptions {
144
190
  keyResolver?: (...args: TArgs) => string;
@@ -157,14 +203,66 @@ interface CacheStatsSnapshot {
157
203
  }>;
158
204
  backgroundRefreshes: number;
159
205
  }
206
+ /** All events emitted by CacheStack and their payload shapes. */
207
+ interface CacheStackEvents {
208
+ /** Fired on every cache hit. */
209
+ hit: {
210
+ key: string;
211
+ layer: string;
212
+ state: 'fresh' | 'stale-while-revalidate' | 'stale-if-error';
213
+ };
214
+ /** Fired on every cache miss before the fetcher runs. */
215
+ miss: {
216
+ key: string;
217
+ mode: string;
218
+ };
219
+ /** Fired after a value is stored in the cache. */
220
+ set: {
221
+ key: string;
222
+ kind: string;
223
+ tags?: string[];
224
+ };
225
+ /** Fired after one or more keys are deleted. */
226
+ delete: {
227
+ keys: string[];
228
+ };
229
+ /** Fired when a value is backfilled into a faster layer. */
230
+ backfill: {
231
+ key: string;
232
+ layer: string;
233
+ };
234
+ /** Fired when a stale value is returned to the caller. */
235
+ 'stale-serve': {
236
+ key: string;
237
+ state: string;
238
+ layer: string;
239
+ };
240
+ /** Fired when a duplicate request is deduplicated in stampede prevention. */
241
+ 'stampede-dedupe': {
242
+ key: string;
243
+ };
244
+ /** Fired after a key is successfully warmed. */
245
+ warm: {
246
+ key: string;
247
+ };
248
+ /** Fired when an error occurs (layer failure, circuit breaker, etc.). */
249
+ error: {
250
+ operation: string;
251
+ [key: string]: unknown;
252
+ };
253
+ }
160
254
 
161
255
  declare class CacheNamespace {
162
256
  private readonly cache;
163
257
  private readonly prefix;
164
258
  constructor(cache: CacheStack, prefix: string);
165
259
  get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
260
+ getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
261
+ has(key: string): Promise<boolean>;
262
+ ttl(key: string): Promise<number | null>;
166
263
  set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
167
264
  delete(key: string): Promise<void>;
265
+ mdelete(keys: string[]): Promise<void>;
168
266
  clear(): Promise<void>;
169
267
  mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
170
268
  mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
@@ -173,40 +271,90 @@ declare class CacheNamespace {
173
271
  wrap<TArgs extends unknown[], TResult>(keyPrefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
174
272
  warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
175
273
  getMetrics(): CacheMetricsSnapshot;
274
+ getHitRate(): CacheHitRateSnapshot;
176
275
  qualify(key: string): string;
177
276
  }
178
277
 
278
+ /** Typed overloads for EventEmitter so callers get autocomplete on event names. */
279
+ interface CacheStack {
280
+ on<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
281
+ once<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
282
+ off<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
283
+ emit<K extends keyof CacheStackEvents>(event: K, data: CacheStackEvents[K]): boolean;
284
+ }
179
285
  declare class CacheStack extends EventEmitter {
180
286
  private readonly layers;
181
287
  private readonly options;
182
288
  private readonly stampedeGuard;
183
- private readonly metrics;
289
+ private readonly metricsCollector;
184
290
  private readonly instanceId;
185
291
  private readonly startup;
186
292
  private unsubscribeInvalidation?;
187
293
  private readonly logger;
188
294
  private readonly tagIndex;
189
295
  private readonly backgroundRefreshes;
190
- private readonly accessProfiles;
191
296
  private readonly layerDegradedUntil;
192
- private readonly circuitBreakers;
297
+ private readonly ttlResolver;
298
+ private readonly circuitBreakerManager;
193
299
  private isDisconnecting;
194
300
  private disconnectPromise?;
195
301
  constructor(layers: CacheLayer[], options?: CacheStackOptions);
302
+ /**
303
+ * Read-through cache get.
304
+ * Returns the cached value if present and fresh, or invokes `fetcher` on a miss
305
+ * and stores the result across all layers. Returns `null` if the key is not found
306
+ * and no `fetcher` is provided.
307
+ */
196
308
  get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
309
+ /**
310
+ * Alias for `get(key, fetcher, options)` — explicit get-or-set pattern.
311
+ * Fetches and caches the value if not already present.
312
+ */
313
+ getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
314
+ /**
315
+ * Returns true if the given key exists and is not expired in any layer.
316
+ */
317
+ has(key: string): Promise<boolean>;
318
+ /**
319
+ * Returns the remaining TTL in seconds for the key in the fastest layer
320
+ * that has it, or null if the key is not found / has no TTL.
321
+ */
322
+ ttl(key: string): Promise<number | null>;
323
+ /**
324
+ * Stores a value in all cache layers. Overwrites any existing value.
325
+ */
197
326
  set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
327
+ /**
328
+ * Deletes the key from all layers and publishes an invalidation message.
329
+ */
198
330
  delete(key: string): Promise<void>;
199
331
  clear(): Promise<void>;
332
+ /**
333
+ * Deletes multiple keys at once. More efficient than calling `delete()` in a loop.
334
+ */
335
+ mdelete(keys: string[]): Promise<void>;
200
336
  mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
201
337
  mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
202
338
  warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
339
+ /**
340
+ * Returns a cached version of `fetcher`. The cache key is derived from
341
+ * `prefix` plus the serialized arguments unless a `keyResolver` is provided.
342
+ */
203
343
  wrap<TArgs extends unknown[], TResult>(prefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
344
+ /**
345
+ * Creates a `CacheNamespace` that automatically prefixes all keys with
346
+ * `prefix:`. Useful for multi-tenant or module-level isolation.
347
+ */
204
348
  namespace(prefix: string): CacheNamespace;
205
349
  invalidateByTag(tag: string): Promise<void>;
206
350
  invalidateByPattern(pattern: string): Promise<void>;
207
351
  getMetrics(): CacheMetricsSnapshot;
208
352
  getStats(): CacheStatsSnapshot;
209
353
  resetMetrics(): void;
354
+ /**
355
+ * Returns computed hit-rate statistics (overall and per-layer).
356
+ */
357
+ getHitRate(): CacheHitRateSnapshot;
210
358
  exportState(): Promise<CacheSnapshotEntry[]>;
211
359
  importState(entries: CacheSnapshotEntry[]): Promise<void>;
212
360
  persistToFile(filePath: string): Promise<void>;
@@ -224,8 +372,6 @@ declare class CacheStack extends EventEmitter {
224
372
  private executeLayerOperations;
225
373
  private resolveFreshTtl;
226
374
  private resolveLayerSeconds;
227
- private readLayerNumber;
228
- private applyJitter;
229
375
  private shouldNegativeCache;
230
376
  private scheduleBackgroundRefresh;
231
377
  private resolveSingleFlightOptions;
@@ -246,15 +392,10 @@ declare class CacheStack extends EventEmitter {
246
392
  private validateAdaptiveTtlOptions;
247
393
  private validateCircuitBreakerOptions;
248
394
  private applyFreshReadPolicies;
249
- private applyAdaptiveTtl;
250
- private recordAccess;
251
- private incrementMetricMap;
252
395
  private shouldSkipLayer;
253
396
  private handleLayerFailure;
254
397
  private isGracefulDegradationEnabled;
255
- private assertCircuitClosed;
256
398
  private recordCircuitFailure;
257
- private resetCircuitBreaker;
258
399
  private isNegativeStoredValue;
259
400
  private emitError;
260
401
  private serializeKeyPart;
@@ -31,6 +31,7 @@ interface CacheMSetEntry<T> {
31
31
  value: T;
32
32
  options?: CacheWriteOptions;
33
33
  }
34
+ /** Interface that all cache backend implementations must satisfy. */
34
35
  interface CacheLayer {
35
36
  readonly name: string;
36
37
  readonly defaultTtl?: number;
@@ -43,7 +44,24 @@ interface CacheLayer {
43
44
  clear(): Promise<void>;
44
45
  deleteMany?(keys: string[]): Promise<void>;
45
46
  keys?(): Promise<string[]>;
47
+ /**
48
+ * Returns true if the key exists and has not expired.
49
+ * Implementations may omit this; CacheStack will fall back to `get()`.
50
+ */
51
+ has?(key: string): Promise<boolean>;
52
+ /**
53
+ * Returns the remaining TTL in seconds for the key, or null if the key
54
+ * does not exist, has no TTL, or has already expired.
55
+ * Implementations may omit this.
56
+ */
57
+ ttl?(key: string): Promise<number | null>;
58
+ /**
59
+ * Returns the number of entries currently held by this layer.
60
+ * Implementations may omit this.
61
+ */
62
+ size?(): Promise<number>;
46
63
  }
64
+ /** Snapshot of cumulative cache counters. */
47
65
  interface CacheMetricsSnapshot {
48
66
  hits: number;
49
67
  misses: number;
@@ -62,6 +80,15 @@ interface CacheMetricsSnapshot {
62
80
  degradedOperations: number;
63
81
  hitsByLayer: Record<string, number>;
64
82
  missesByLayer: Record<string, number>;
83
+ /** Timestamp (ms since epoch) when metrics were last reset. */
84
+ resetAt: number;
85
+ }
86
+ /** Computed hit-rate statistics derived from CacheMetricsSnapshot. */
87
+ interface CacheHitRateSnapshot {
88
+ /** Overall hit rate across all layers (0–1). */
89
+ overall: number;
90
+ /** Per-layer hit rates (0–1 each). */
91
+ byLayer: Record<string, number>;
65
92
  }
66
93
  interface CacheLogger {
67
94
  debug?(message: string, context?: Record<string, unknown>): void;
@@ -102,6 +129,9 @@ interface CacheStackOptions {
102
129
  invalidationBus?: InvalidationBus;
103
130
  tagIndex?: CacheTagIndex;
104
131
  broadcastL1Invalidation?: boolean;
132
+ /**
133
+ * @deprecated Use `broadcastL1Invalidation` instead.
134
+ */
105
135
  publishSetInvalidation?: boolean;
106
136
  negativeCaching?: boolean;
107
137
  negativeTtl?: number | LayerTtlMap;
@@ -117,6 +147,12 @@ interface CacheStackOptions {
117
147
  singleFlightLeaseMs?: number;
118
148
  singleFlightTimeoutMs?: number;
119
149
  singleFlightPollMs?: number;
150
+ /**
151
+ * Maximum number of entries in `accessProfiles` and `circuitBreakers` maps
152
+ * before the oldest entries are pruned. Prevents unbounded memory growth.
153
+ * Defaults to 100 000.
154
+ */
155
+ maxProfileEntries?: number;
120
156
  }
121
157
  interface CacheAdaptiveTtlOptions {
122
158
  hotAfter?: number;
@@ -136,9 +172,19 @@ interface CacheWarmEntry<T = unknown> {
136
172
  options?: CacheGetOptions;
137
173
  priority?: number;
138
174
  }
175
+ /** Options controlling the cache warm-up process. */
139
176
  interface CacheWarmOptions {
140
177
  concurrency?: number;
141
178
  continueOnError?: boolean;
179
+ /** Called after each entry is processed (success or failure). */
180
+ onProgress?: (progress: CacheWarmProgress) => void;
181
+ }
182
+ /** Progress information delivered to `CacheWarmOptions.onProgress`. */
183
+ interface CacheWarmProgress {
184
+ completed: number;
185
+ total: number;
186
+ key: string;
187
+ success: boolean;
142
188
  }
143
189
  interface CacheWrapOptions<TArgs extends unknown[] = unknown[]> extends CacheGetOptions {
144
190
  keyResolver?: (...args: TArgs) => string;
@@ -157,14 +203,66 @@ interface CacheStatsSnapshot {
157
203
  }>;
158
204
  backgroundRefreshes: number;
159
205
  }
206
+ /** All events emitted by CacheStack and their payload shapes. */
207
+ interface CacheStackEvents {
208
+ /** Fired on every cache hit. */
209
+ hit: {
210
+ key: string;
211
+ layer: string;
212
+ state: 'fresh' | 'stale-while-revalidate' | 'stale-if-error';
213
+ };
214
+ /** Fired on every cache miss before the fetcher runs. */
215
+ miss: {
216
+ key: string;
217
+ mode: string;
218
+ };
219
+ /** Fired after a value is stored in the cache. */
220
+ set: {
221
+ key: string;
222
+ kind: string;
223
+ tags?: string[];
224
+ };
225
+ /** Fired after one or more keys are deleted. */
226
+ delete: {
227
+ keys: string[];
228
+ };
229
+ /** Fired when a value is backfilled into a faster layer. */
230
+ backfill: {
231
+ key: string;
232
+ layer: string;
233
+ };
234
+ /** Fired when a stale value is returned to the caller. */
235
+ 'stale-serve': {
236
+ key: string;
237
+ state: string;
238
+ layer: string;
239
+ };
240
+ /** Fired when a duplicate request is deduplicated in stampede prevention. */
241
+ 'stampede-dedupe': {
242
+ key: string;
243
+ };
244
+ /** Fired after a key is successfully warmed. */
245
+ warm: {
246
+ key: string;
247
+ };
248
+ /** Fired when an error occurs (layer failure, circuit breaker, etc.). */
249
+ error: {
250
+ operation: string;
251
+ [key: string]: unknown;
252
+ };
253
+ }
160
254
 
161
255
  declare class CacheNamespace {
162
256
  private readonly cache;
163
257
  private readonly prefix;
164
258
  constructor(cache: CacheStack, prefix: string);
165
259
  get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
260
+ getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
261
+ has(key: string): Promise<boolean>;
262
+ ttl(key: string): Promise<number | null>;
166
263
  set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
167
264
  delete(key: string): Promise<void>;
265
+ mdelete(keys: string[]): Promise<void>;
168
266
  clear(): Promise<void>;
169
267
  mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
170
268
  mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
@@ -173,40 +271,90 @@ declare class CacheNamespace {
173
271
  wrap<TArgs extends unknown[], TResult>(keyPrefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
174
272
  warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
175
273
  getMetrics(): CacheMetricsSnapshot;
274
+ getHitRate(): CacheHitRateSnapshot;
176
275
  qualify(key: string): string;
177
276
  }
178
277
 
278
+ /** Typed overloads for EventEmitter so callers get autocomplete on event names. */
279
+ interface CacheStack {
280
+ on<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
281
+ once<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
282
+ off<K extends keyof CacheStackEvents>(event: K, listener: (data: CacheStackEvents[K]) => void): this;
283
+ emit<K extends keyof CacheStackEvents>(event: K, data: CacheStackEvents[K]): boolean;
284
+ }
179
285
  declare class CacheStack extends EventEmitter {
180
286
  private readonly layers;
181
287
  private readonly options;
182
288
  private readonly stampedeGuard;
183
- private readonly metrics;
289
+ private readonly metricsCollector;
184
290
  private readonly instanceId;
185
291
  private readonly startup;
186
292
  private unsubscribeInvalidation?;
187
293
  private readonly logger;
188
294
  private readonly tagIndex;
189
295
  private readonly backgroundRefreshes;
190
- private readonly accessProfiles;
191
296
  private readonly layerDegradedUntil;
192
- private readonly circuitBreakers;
297
+ private readonly ttlResolver;
298
+ private readonly circuitBreakerManager;
193
299
  private isDisconnecting;
194
300
  private disconnectPromise?;
195
301
  constructor(layers: CacheLayer[], options?: CacheStackOptions);
302
+ /**
303
+ * Read-through cache get.
304
+ * Returns the cached value if present and fresh, or invokes `fetcher` on a miss
305
+ * and stores the result across all layers. Returns `null` if the key is not found
306
+ * and no `fetcher` is provided.
307
+ */
196
308
  get<T>(key: string, fetcher?: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
309
+ /**
310
+ * Alias for `get(key, fetcher, options)` — explicit get-or-set pattern.
311
+ * Fetches and caches the value if not already present.
312
+ */
313
+ getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheGetOptions): Promise<T | null>;
314
+ /**
315
+ * Returns true if the given key exists and is not expired in any layer.
316
+ */
317
+ has(key: string): Promise<boolean>;
318
+ /**
319
+ * Returns the remaining TTL in seconds for the key in the fastest layer
320
+ * that has it, or null if the key is not found / has no TTL.
321
+ */
322
+ ttl(key: string): Promise<number | null>;
323
+ /**
324
+ * Stores a value in all cache layers. Overwrites any existing value.
325
+ */
197
326
  set<T>(key: string, value: T, options?: CacheWriteOptions): Promise<void>;
327
+ /**
328
+ * Deletes the key from all layers and publishes an invalidation message.
329
+ */
198
330
  delete(key: string): Promise<void>;
199
331
  clear(): Promise<void>;
332
+ /**
333
+ * Deletes multiple keys at once. More efficient than calling `delete()` in a loop.
334
+ */
335
+ mdelete(keys: string[]): Promise<void>;
200
336
  mget<T>(entries: CacheMGetEntry<T>[]): Promise<Array<T | null>>;
201
337
  mset<T>(entries: CacheMSetEntry<T>[]): Promise<void>;
202
338
  warm(entries: CacheWarmEntry[], options?: CacheWarmOptions): Promise<void>;
339
+ /**
340
+ * Returns a cached version of `fetcher`. The cache key is derived from
341
+ * `prefix` plus the serialized arguments unless a `keyResolver` is provided.
342
+ */
203
343
  wrap<TArgs extends unknown[], TResult>(prefix: string, fetcher: (...args: TArgs) => Promise<TResult>, options?: CacheWrapOptions<TArgs>): (...args: TArgs) => Promise<TResult | null>;
344
+ /**
345
+ * Creates a `CacheNamespace` that automatically prefixes all keys with
346
+ * `prefix:`. Useful for multi-tenant or module-level isolation.
347
+ */
204
348
  namespace(prefix: string): CacheNamespace;
205
349
  invalidateByTag(tag: string): Promise<void>;
206
350
  invalidateByPattern(pattern: string): Promise<void>;
207
351
  getMetrics(): CacheMetricsSnapshot;
208
352
  getStats(): CacheStatsSnapshot;
209
353
  resetMetrics(): void;
354
+ /**
355
+ * Returns computed hit-rate statistics (overall and per-layer).
356
+ */
357
+ getHitRate(): CacheHitRateSnapshot;
210
358
  exportState(): Promise<CacheSnapshotEntry[]>;
211
359
  importState(entries: CacheSnapshotEntry[]): Promise<void>;
212
360
  persistToFile(filePath: string): Promise<void>;
@@ -224,8 +372,6 @@ declare class CacheStack extends EventEmitter {
224
372
  private executeLayerOperations;
225
373
  private resolveFreshTtl;
226
374
  private resolveLayerSeconds;
227
- private readLayerNumber;
228
- private applyJitter;
229
375
  private shouldNegativeCache;
230
376
  private scheduleBackgroundRefresh;
231
377
  private resolveSingleFlightOptions;
@@ -246,15 +392,10 @@ declare class CacheStack extends EventEmitter {
246
392
  private validateAdaptiveTtlOptions;
247
393
  private validateCircuitBreakerOptions;
248
394
  private applyFreshReadPolicies;
249
- private applyAdaptiveTtl;
250
- private recordAccess;
251
- private incrementMetricMap;
252
395
  private shouldSkipLayer;
253
396
  private handleLayerFailure;
254
397
  private isGracefulDegradationEnabled;
255
- private assertCircuitClosed;
256
398
  private recordCircuitFailure;
257
- private resetCircuitBreaker;
258
399
  private isNegativeStoredValue;
259
400
  private emitError;
260
401
  private serializeKeyPart;