@gravito/stasis 3.1.1 → 3.2.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.
@@ -0,0 +1,495 @@
1
+ import { type CacheEventMode, type CacheEvents } from './cache-events';
2
+ import type { CacheStore } from './store';
3
+ import { type CacheKey, type CacheTtl, type CompressionOptions } from './types';
4
+ export type { CacheEventMode, CacheEvents };
5
+ /**
6
+ * Options for configuring the `CacheRepository`.
7
+ *
8
+ * Controls behavior such as key prefixing, event emission, and background
9
+ * refresh strategies for flexible caching.
10
+ *
11
+ * @public
12
+ * @since 3.0.0
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const options: CacheRepositoryOptions = {
17
+ * prefix: 'v1:',
18
+ * defaultTtl: 3600,
19
+ * eventsMode: 'async'
20
+ * };
21
+ * ```
22
+ */
23
+ export type CacheRepositoryOptions = {
24
+ /** Optional prefix for all cache keys. */
25
+ prefix?: string;
26
+ /** Default time-to-live for cache entries. */
27
+ defaultTtl?: CacheTtl;
28
+ /** Event handlers for cache operations. */
29
+ events?: CacheEvents;
30
+ /** Mode for emitting events (sync, async, or off). */
31
+ eventsMode?: CacheEventMode;
32
+ /** Whether to throw an error if an event handler fails. @defaultValue false */
33
+ throwOnEventError?: boolean;
34
+ /** Callback triggered when an event handler encounters an error. */
35
+ onEventError?: (error: unknown, event: keyof CacheEvents, payload: {
36
+ key?: string;
37
+ }) => void;
38
+ /** Timeout for background flexible refresh in milliseconds. @defaultValue 30000 */
39
+ refreshTimeout?: number;
40
+ /**
41
+ * Maximum number of retries for the background flexible refresh callback.
42
+ * @defaultValue 0
43
+ */
44
+ maxRetries?: number;
45
+ /**
46
+ * Delay between retries for flexible refresh in milliseconds.
47
+ * @defaultValue 50
48
+ */
49
+ retryDelay?: number;
50
+ /**
51
+ * Compression settings for cached values.
52
+ *
53
+ * @since 3.1.0
54
+ */
55
+ compression?: CompressionOptions;
56
+ };
57
+ /**
58
+ * Statistics for flexible cache operations.
59
+ *
60
+ * Tracks the performance and reliability of background refresh operations
61
+ * used in stale-while-revalidate patterns.
62
+ *
63
+ * @public
64
+ * @since 3.0.0
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const stats: FlexibleStats = {
69
+ * refreshCount: 10,
70
+ * refreshFailures: 0,
71
+ * avgRefreshTime: 15.5
72
+ * };
73
+ * ```
74
+ */
75
+ export type FlexibleStats = {
76
+ /** Total number of successful background refreshes. */
77
+ refreshCount: number;
78
+ /** Total number of background refresh failures (after all retries). */
79
+ refreshFailures: number;
80
+ /** Average time taken for a successful refresh in milliseconds. */
81
+ avgRefreshTime: number;
82
+ };
83
+ /**
84
+ * High-level API for cache operations.
85
+ *
86
+ * Wraps a low-level `CacheStore` to provide developer-friendly features like
87
+ * key prefixing, event emission, and advanced patterns like `remember` and `flexible`.
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * const cache = new CacheRepository(redisStore, { prefix: 'app:' });
92
+ * const user = await cache.remember('user:1', 3600, () => fetchUser(1));
93
+ * ```
94
+ *
95
+ * @public
96
+ * @since 3.0.0
97
+ */
98
+ export declare class CacheRepository {
99
+ protected readonly store: CacheStore;
100
+ protected readonly options: CacheRepositoryOptions;
101
+ private refreshSemaphore;
102
+ private coalesceSemaphore;
103
+ private flexibleStats;
104
+ private eventEmitterConfig;
105
+ constructor(store: CacheStore, options?: CacheRepositoryOptions);
106
+ /**
107
+ * Retrieve statistics about flexible cache operations.
108
+ *
109
+ * Useful for monitoring the health and performance of background refreshes.
110
+ *
111
+ * @returns Current statistics for background refresh operations.
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * const stats = cache.getFlexibleStats();
116
+ * console.log(`Refreshed ${stats.refreshCount} times`);
117
+ * ```
118
+ */
119
+ getFlexibleStats(): FlexibleStats;
120
+ private emit;
121
+ protected key(key: CacheKey): string;
122
+ protected flexibleFreshUntilKey(fullKey: string): string;
123
+ protected putMetaKey(metaKey: string, value: unknown, ttl: CacheTtl): Promise<void>;
124
+ protected forgetMetaKey(metaKey: string): Promise<void>;
125
+ /**
126
+ * Retrieve an item from the cache by its key.
127
+ *
128
+ * Fetches the value from the underlying store. If not found, returns the
129
+ * provided default value or executes the factory function.
130
+ *
131
+ * @param key - The unique cache key.
132
+ * @param defaultValue - A default value or factory function to use if the key is not found.
133
+ * @returns The cached value, or the default value if not found.
134
+ * @throws {Error} If the underlying store fails to retrieve the value.
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const user = await cache.get('user:1', { name: 'Guest' });
139
+ * const settings = await cache.get('settings', () => fetchSettings());
140
+ * ```
141
+ */
142
+ get<T = unknown>(key: CacheKey, defaultValue?: T | (() => T | Promise<T>)): Promise<T | null>;
143
+ /**
144
+ * Determine if an item exists in the cache.
145
+ *
146
+ * Checks for the presence of a key without necessarily returning its value.
147
+ *
148
+ * @param key - The cache key.
149
+ * @returns True if the item exists, false otherwise.
150
+ * @throws {Error} If the underlying store fails to check existence.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * if (await cache.has('session:active')) {
155
+ * // ...
156
+ * }
157
+ * ```
158
+ */
159
+ has(key: CacheKey): Promise<boolean>;
160
+ /**
161
+ * Determine if an item is missing from the cache.
162
+ *
163
+ * Inverse of `has()`, used for cleaner conditional logic.
164
+ *
165
+ * @param key - The cache key.
166
+ * @returns True if the item is missing, false otherwise.
167
+ * @throws {Error} If the underlying store fails to check existence.
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * if (await cache.missing('config:loaded')) {
172
+ * await loadConfig();
173
+ * }
174
+ * ```
175
+ */
176
+ missing(key: CacheKey): Promise<boolean>;
177
+ /**
178
+ * Store an item in the cache for a specific duration.
179
+ *
180
+ * Persists the value in the underlying store with the given TTL.
181
+ *
182
+ * @param key - Unique cache key.
183
+ * @param value - Value to store.
184
+ * @param ttl - Expiration duration.
185
+ * @throws {Error} If the underlying store fails to persist the value or serialization fails.
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * await cache.put('token', 'xyz123', 3600);
190
+ * ```
191
+ */
192
+ put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
193
+ /**
194
+ * Store an item in the cache for a specific duration.
195
+ *
196
+ * Uses the repository's default TTL if none is provided.
197
+ *
198
+ * @param key - The unique cache key.
199
+ * @param value - The value to store.
200
+ * @param ttl - Optional time-to-live.
201
+ * @throws {Error} If the underlying store fails to persist the value.
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * await cache.set('theme', 'dark');
206
+ * ```
207
+ */
208
+ set(key: CacheKey, value: unknown, ttl?: CacheTtl): Promise<void>;
209
+ /**
210
+ * Store an item in the cache only if the key does not already exist.
211
+ *
212
+ * Atomic operation to prevent overwriting existing data.
213
+ *
214
+ * @param key - The unique cache key.
215
+ * @param value - The value to store.
216
+ * @param ttl - Optional time-to-live.
217
+ * @returns True if the item was added, false otherwise.
218
+ * @throws {Error} If the underlying store fails the atomic operation.
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * const added = await cache.add('lock:process', true, 60);
223
+ * ```
224
+ */
225
+ add(key: CacheKey, value: unknown, ttl?: CacheTtl): Promise<boolean>;
226
+ /**
227
+ * Store an item in the cache indefinitely.
228
+ *
229
+ * Sets the TTL to null, indicating the value should not expire automatically.
230
+ *
231
+ * @param key - The unique cache key.
232
+ * @param value - The value to store.
233
+ * @throws {Error} If the underlying store fails to persist the value.
234
+ *
235
+ * @example
236
+ * ```typescript
237
+ * await cache.forever('system:id', 'node-01');
238
+ * ```
239
+ */
240
+ forever(key: CacheKey, value: unknown): Promise<void>;
241
+ /**
242
+ * Get an item from the cache, or execute the given callback and store the result.
243
+ *
244
+ * Implements the "Cache-Aside" pattern, ensuring the callback is only executed
245
+ * on a cache miss.
246
+ *
247
+ * @param key - The unique cache key.
248
+ * @param ttl - Time-to-live.
249
+ * @param callback - The callback to execute if the key is not found.
250
+ * @returns The cached value or the result of the callback.
251
+ * @throws {Error} If the callback or the underlying store fails.
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * const data = await cache.remember('users:all', 300, () => db.users.findMany());
256
+ * ```
257
+ */
258
+ remember<T = unknown>(key: CacheKey, ttl: CacheTtl, callback: () => Promise<T> | T): Promise<T>;
259
+ /**
260
+ * Get an item from the cache, or execute the given callback and store the result indefinitely.
261
+ *
262
+ * Similar to `remember()`, but the value is stored without an expiration time.
263
+ *
264
+ * @param key - The unique cache key.
265
+ * @param callback - The callback to execute if the key is not found.
266
+ * @returns The cached value or the result of the callback.
267
+ * @throws {Error} If the callback or the underlying store fails.
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * const config = await cache.rememberForever('app:config', () => loadConfig());
272
+ * ```
273
+ */
274
+ rememberForever<T = unknown>(key: CacheKey, callback: () => Promise<T> | T): Promise<T>;
275
+ /**
276
+ * Retrieve multiple items from the cache by their keys.
277
+ *
278
+ * Efficiently fetches multiple values, returning a map of keys to values.
279
+ *
280
+ * @param keys - An array of unique cache keys.
281
+ * @returns An object where keys are the original keys and values are the cached values.
282
+ * @throws {Error} If the underlying store fails to retrieve values.
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * const results = await cache.many(['user:1', 'user:2']);
287
+ * ```
288
+ */
289
+ many<T = unknown>(keys: readonly CacheKey[]): Promise<Record<string, T | null>>;
290
+ /**
291
+ * Store multiple items in the cache for a specific duration.
292
+ *
293
+ * Persists multiple key-value pairs in a single operation if supported by the store.
294
+ *
295
+ * @param values - An object where keys are the unique cache keys and values are the values to store.
296
+ * @param ttl - Time-to-live.
297
+ * @throws {Error} If the underlying store fails to persist values.
298
+ *
299
+ * @example
300
+ * ```typescript
301
+ * await cache.putMany({ 'a': 1, 'b': 2 }, 60);
302
+ * ```
303
+ */
304
+ putMany(values: Record<string, unknown>, ttl: CacheTtl): Promise<void>;
305
+ /**
306
+ * Laravel-like flexible cache (stale-while-revalidate).
307
+ *
308
+ * Serves stale content while revalidating the cache in the background. This
309
+ * minimizes latency for users by avoiding synchronous revalidation.
310
+ *
311
+ * @param key - The unique cache key.
312
+ * @param ttlSeconds - How long the value is considered fresh.
313
+ * @param staleSeconds - How long the stale value may be served while a refresh happens.
314
+ * @param callback - The callback to execute to refresh the cache.
315
+ * @returns The fresh or stale cached value.
316
+ * @throws {Error} If the callback fails on a cache miss.
317
+ *
318
+ * @example
319
+ * ```typescript
320
+ * const value = await cache.flexible('stats', 60, 30, () => fetchStats());
321
+ * ```
322
+ */
323
+ flexible<T = unknown>(key: CacheKey, ttlSeconds: number, staleSeconds: number, callback: () => Promise<T> | T): Promise<T>;
324
+ private refreshFlexible;
325
+ private doRefresh;
326
+ /**
327
+ * Retrieve an item from the cache and delete it.
328
+ *
329
+ * Atomic-like operation to fetch and immediately remove a value, often used
330
+ * for one-time tokens or flash messages.
331
+ *
332
+ * @param key - The unique cache key.
333
+ * @param defaultValue - A default value to use if the key is not found.
334
+ * @returns The cached value, or the default value if not found.
335
+ * @throws {Error} If the underlying store fails to retrieve or forget the value.
336
+ *
337
+ * @example
338
+ * ```typescript
339
+ * const message = await cache.pull('flash:status');
340
+ * ```
341
+ */
342
+ pull<T = unknown>(key: CacheKey, defaultValue?: T): Promise<T | null>;
343
+ /**
344
+ * Remove an item from the cache by its key.
345
+ *
346
+ * Deletes the value and any associated metadata from the underlying store.
347
+ *
348
+ * @param key - The cache key to remove.
349
+ * @returns True if the item existed and was removed.
350
+ * @throws {Error} If the underlying store fails to remove the value.
351
+ *
352
+ * @example
353
+ * ```typescript
354
+ * const deleted = await cache.forget('user:session');
355
+ * ```
356
+ */
357
+ forget(key: CacheKey): Promise<boolean>;
358
+ /**
359
+ * Alias for `forget`.
360
+ *
361
+ * Provides compatibility with standard `Map`-like or `Storage` APIs.
362
+ *
363
+ * @param key - The cache key to remove.
364
+ * @returns True if the item existed and was removed.
365
+ * @throws {Error} If the underlying store fails to remove the value.
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * await cache.delete('temp:data');
370
+ * ```
371
+ */
372
+ delete(key: CacheKey): Promise<boolean>;
373
+ /**
374
+ * Remove all items from the cache storage.
375
+ *
376
+ * Clears the entire underlying store. Use with caution as this affects all
377
+ * keys regardless of prefix.
378
+ *
379
+ * @throws {Error} If the underlying store fails to flush.
380
+ *
381
+ * @example
382
+ * ```typescript
383
+ * await cache.flush();
384
+ * ```
385
+ */
386
+ flush(): Promise<void>;
387
+ /**
388
+ * Alias for `flush`.
389
+ *
390
+ * Provides compatibility with standard `Map`-like or `Storage` APIs.
391
+ *
392
+ * @throws {Error} If the underlying store fails to clear.
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * await cache.clear();
397
+ * ```
398
+ */
399
+ clear(): Promise<void>;
400
+ /**
401
+ * Increment the value of a numeric item in the cache.
402
+ *
403
+ * Atomically increases the value of a key. If the key does not exist, it is
404
+ * typically initialized to 0 before incrementing.
405
+ *
406
+ * @param key - The cache key.
407
+ * @param value - The amount to increment by.
408
+ * @returns The new value.
409
+ * @throws {Error} If the underlying store fails the atomic increment.
410
+ *
411
+ * @example
412
+ * ```typescript
413
+ * const count = await cache.increment('page:views');
414
+ * ```
415
+ */
416
+ increment(key: string, value?: number): Promise<number>;
417
+ /**
418
+ * Decrement the value of a numeric item in the cache.
419
+ *
420
+ * Atomically decreases the value of a key.
421
+ *
422
+ * @param key - The cache key.
423
+ * @param value - The amount to decrement by.
424
+ * @returns The new value.
425
+ * @throws {Error} If the underlying store fails the atomic decrement.
426
+ *
427
+ * @example
428
+ * ```typescript
429
+ * const remaining = await cache.decrement('stock:count');
430
+ * ```
431
+ */
432
+ decrement(key: string, value?: number): Promise<number>;
433
+ /**
434
+ * Get a distributed lock instance for the given name.
435
+ *
436
+ * Provides a mechanism for exclusive access to resources across multiple
437
+ * processes or servers.
438
+ *
439
+ * @param name - The lock name.
440
+ * @param seconds - Optional default duration for the lock in seconds.
441
+ * @returns A `CacheLock` instance if supported, otherwise undefined.
442
+ *
443
+ * @example
444
+ * ```typescript
445
+ * const lock = cache.lock('process:heavy', 10);
446
+ * if (await lock.acquire()) {
447
+ * try {
448
+ * // ...
449
+ * } finally {
450
+ * await lock.release();
451
+ * }
452
+ * }
453
+ * ```
454
+ */
455
+ lock(name: string, seconds?: number): import("./locks").CacheLock;
456
+ /**
457
+ * Create a new repository instance with the given tags.
458
+ *
459
+ * Enables grouping of cache entries for collective operations like flushing
460
+ * all keys associated with specific tags.
461
+ *
462
+ * @param tags - An array of tag names.
463
+ * @returns A new `CacheRepository` instance that uses the given tags.
464
+ * @throws {Error} If the underlying store does not support tagging.
465
+ *
466
+ * @example
467
+ * ```typescript
468
+ * await cache.tags(['users', 'profiles']).put('user:1', data, 3600);
469
+ * await cache.tags(['users']).flush();
470
+ * ```
471
+ */
472
+ tags(tags: readonly string[]): CacheRepository;
473
+ /**
474
+ * Retrieve the underlying cache store.
475
+ *
476
+ * Provides direct access to the low-level store implementation for advanced
477
+ * use cases or debugging.
478
+ *
479
+ * @returns The low-level cache store instance.
480
+ *
481
+ * @example
482
+ * ```typescript
483
+ * const store = cache.getStore();
484
+ * ```
485
+ */
486
+ getStore(): CacheStore;
487
+ /**
488
+ * Compress a value before storage if compression is enabled and thresholds are met.
489
+ */
490
+ private compress;
491
+ /**
492
+ * Decompress a value after retrieval if it was previously compressed.
493
+ */
494
+ private decompress;
495
+ }
@@ -0,0 +1,152 @@
1
+ import type { CacheStore } from './store';
2
+ /**
3
+ * Represents the response from a rate limiting attempt.
4
+ *
5
+ * This interface provides the necessary metadata to determine if a request
6
+ * should be throttled and when the client can safely retry.
7
+ *
8
+ * @public
9
+ * @since 3.0.0
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const res: RateLimiterResponse = { allowed: true, remaining: 4, reset: 1622548800 };
14
+ * ```
15
+ */
16
+ export interface RateLimiterResponse {
17
+ /** Whether the request is allowed based on current usage and limits. */
18
+ allowed: boolean;
19
+ /** Number of attempts remaining within the current time window. */
20
+ remaining: number;
21
+ /** Epoch timestamp in seconds when the rate limit window will reset. */
22
+ reset: number;
23
+ /** Seconds until the rate limit resets, typically used for the `Retry-After` header. */
24
+ retryAfter?: number;
25
+ }
26
+ /**
27
+ * Detailed information about the current rate limit status.
28
+ *
29
+ * Used for inspecting the state of a limiter without necessarily
30
+ * consuming an attempt or triggering a state change.
31
+ *
32
+ * @public
33
+ * @since 3.0.0
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const info: RateLimitInfo = { limit: 10, remaining: 5, reset: 1622548800 };
38
+ * ```
39
+ */
40
+ export interface RateLimitInfo {
41
+ /** Maximum number of attempts allowed within the configured window. */
42
+ limit: number;
43
+ /** Number of attempts remaining before the limit is reached. */
44
+ remaining: number;
45
+ /** Epoch timestamp in seconds when the rate limit window will reset. */
46
+ reset: number;
47
+ /** Seconds until the rate limit resets, only present when the limit has been exceeded. */
48
+ retryAfter?: number;
49
+ }
50
+ /**
51
+ * RateLimiter provides a simple mechanism for limiting request frequency.
52
+ *
53
+ * It uses a `CacheStore` backend to track attempt counts and handle
54
+ * expiration. This allows for distributed rate limiting when using
55
+ * shared stores like Redis, or local limiting with memory stores.
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const limiter = new RateLimiter(cacheStore);
60
+ * const status = await limiter.attempt('login:127.0.0.1', 5, 60);
61
+ *
62
+ * if (!status.allowed) {
63
+ * console.log(`Too many attempts. Retry after ${status.retryAfter}s`);
64
+ * }
65
+ * ```
66
+ *
67
+ * @public
68
+ * @since 3.0.0
69
+ */
70
+ export declare class RateLimiter {
71
+ private store;
72
+ /**
73
+ * Creates a new RateLimiter instance.
74
+ *
75
+ * @param store - Cache backend used to persist attempt counts.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const limiter = new RateLimiter(new MemoryStore());
80
+ * ```
81
+ */
82
+ constructor(store: CacheStore);
83
+ /**
84
+ * Attempt to consume a slot in the rate limit window.
85
+ *
86
+ * This method checks the current attempt count for the given key. If the
87
+ * count is below the limit, it increments the count and allows the request.
88
+ * Otherwise, it returns a rejected status with retry information.
89
+ *
90
+ * @param key - The unique identifier for the rate limit (e.g., IP address or user ID).
91
+ * @param maxAttempts - Maximum number of attempts allowed within the decay period.
92
+ * @param decaySeconds - Duration of the rate limit window in seconds.
93
+ * @returns A response indicating if the attempt was successful and the remaining capacity.
94
+ * @throws {Error} If the underlying cache store fails to read or write data.
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const response = await limiter.attempt('api-client:123', 100, 3600);
99
+ * if (response.allowed) {
100
+ * // Proceed with request
101
+ * }
102
+ * ```
103
+ */
104
+ attempt(key: string, maxAttempts: number, decaySeconds: number): Promise<RateLimiterResponse>;
105
+ /**
106
+ * Calculate the number of seconds until the rate limit resets.
107
+ *
108
+ * This helper method attempts to retrieve the TTL from the store. If the
109
+ * store does not support TTL inspection, it falls back to the provided
110
+ * decay period.
111
+ *
112
+ * @param key - Unique identifier for the rate limit.
113
+ * @param decaySeconds - Default decay period to use as a fallback.
114
+ * @returns Number of seconds until the key expires.
115
+ * @throws {Error} If the store fails to retrieve TTL metadata.
116
+ */
117
+ availableIn(key: string, decaySeconds: number): Promise<number>;
118
+ /**
119
+ * Get detailed information about the current rate limit status without consuming an attempt.
120
+ *
121
+ * Useful for returning rate limit headers (e.g., X-RateLimit-Limit) in
122
+ * middleware or for pre-flight checks.
123
+ *
124
+ * @param key - The unique identifier for the rate limit.
125
+ * @param maxAttempts - Maximum number of attempts allowed.
126
+ * @param decaySeconds - Duration of the rate limit window in seconds.
127
+ * @returns Current status including limit, remaining attempts, and reset time.
128
+ * @throws {Error} If the underlying cache store fails to retrieve data.
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * const info = await limiter.getInfo('user:42', 60, 60);
133
+ * console.log(`Remaining: ${info.remaining}/${info.limit}`);
134
+ * ```
135
+ */
136
+ getInfo(key: string, maxAttempts: number, decaySeconds: number): Promise<RateLimitInfo>;
137
+ /**
138
+ * Reset the rate limit counter for a specific key.
139
+ *
140
+ * Use this to manually clear a block, for example after a successful
141
+ * login or when an administrator manually unblocks a user.
142
+ *
143
+ * @param key - The unique identifier to clear.
144
+ * @throws {Error} If the store fails to delete the key.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * await limiter.clear('login-attempts:user@example.com');
149
+ * ```
150
+ */
151
+ clear(key: string): Promise<void>;
152
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Cache event system types and dispatcher.
3
+ *
4
+ * Provides event mode definitions, event handler contracts,
5
+ * and the core emit logic for cache lifecycle events.
6
+ *
7
+ * @public
8
+ * @since 3.0.0
9
+ */
10
+ /**
11
+ * Supported modes for emitting cache events.
12
+ *
13
+ * @public
14
+ * @since 3.0.0
15
+ */
16
+ export type CacheEventMode = 'sync' | 'async' | 'off';
17
+ /**
18
+ * Event handlers for cache lifecycle events.
19
+ *
20
+ * @public
21
+ * @since 3.0.0
22
+ */
23
+ export type CacheEvents = {
24
+ /** Triggered on a cache hit. */
25
+ hit?: (key: string) => void | Promise<void>;
26
+ /** Triggered on a cache miss. */
27
+ miss?: (key: string) => void | Promise<void>;
28
+ /** Triggered when a value is written to the cache. */
29
+ write?: (key: string) => void | Promise<void>;
30
+ /** Triggered when a value is removed from the cache. */
31
+ forget?: (key: string) => void | Promise<void>;
32
+ /** Triggered when the entire cache is flushed. */
33
+ flush?: () => void | Promise<void>;
34
+ };
35
+ /**
36
+ * Configuration for the cache event emitter.
37
+ *
38
+ * @internal
39
+ */
40
+ export type CacheEventEmitterConfig = {
41
+ mode: CacheEventMode;
42
+ throwOnError?: boolean;
43
+ onError?: (error: unknown, event: keyof CacheEvents, payload: {
44
+ key?: string;
45
+ }) => void;
46
+ };
47
+ /**
48
+ * Emit a cache lifecycle event according to the configured mode.
49
+ *
50
+ * @param event - The cache event name
51
+ * @param payload - Event payload
52
+ * @param events - Event handler map
53
+ * @param config - Emitter configuration
54
+ * @internal
55
+ */
56
+ export declare function emitCacheEvent(event: keyof CacheEvents, payload: {
57
+ key?: string;
58
+ }, events: CacheEvents | undefined, config: CacheEventEmitterConfig): void | Promise<void>;