@gravito/stasis 3.1.1 → 3.2.1
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 +28 -5
- package/dist/CacheManager.d.ts +484 -0
- package/dist/CacheRepository.d.ts +495 -0
- package/dist/RateLimiter.d.ts +152 -0
- package/dist/cache-events.d.ts +58 -0
- package/dist/index.d.ts +29 -2676
- package/dist/index.js +349 -1706
- package/dist/index.js.map +27 -0
- package/dist/locks.d.ts +193 -0
- package/dist/prediction/AccessPredictor.d.ts +64 -0
- package/dist/store.d.ts +200 -0
- package/dist/stores/CircuitBreakerStore.d.ts +78 -0
- package/dist/stores/FileStore.d.ts +36 -0
- package/dist/stores/MemoryStore.d.ts +261 -0
- package/dist/stores/NullStore.d.ts +115 -0
- package/dist/stores/PredictiveStore.d.ts +40 -0
- package/dist/stores/RedisStore.d.ts +83 -0
- package/dist/stores/TieredStore.d.ts +37 -0
- package/dist/tagged-store.d.ts +29 -0
- package/dist/types.d.ts +149 -0
- package/dist/utils/LRUCache.d.ts +104 -0
- package/package.json +11 -10
- package/dist/index.cjs +0 -3279
- package/dist/index.d.cts +0 -2989
package/dist/locks.d.ts
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error thrown when a lock cannot be acquired within the specified timeout.
|
|
3
|
+
*
|
|
4
|
+
* This error indicates that the maximum waiting time for a distributed lock
|
|
5
|
+
* has been exceeded without successfully gaining ownership.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
* @since 3.0.0
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* try {
|
|
13
|
+
* await cache.lock('resource', 10).block(5, async () => {
|
|
14
|
+
* // ...
|
|
15
|
+
* });
|
|
16
|
+
* } catch (error) {
|
|
17
|
+
* if (error instanceof LockTimeoutError) {
|
|
18
|
+
* console.error('Failed to acquire lock within 5 seconds');
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare class LockTimeoutError extends Error {
|
|
24
|
+
name: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Interface for a cache-backed distributed lock.
|
|
28
|
+
*
|
|
29
|
+
* A distributed lock ensures mutual exclusion across multiple processes or
|
|
30
|
+
* instances by using a shared cache as the synchronization primitive.
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
33
|
+
* @since 3.0.0
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const lock = cache.lock('process', 60);
|
|
38
|
+
* const result = await lock.block(10, async () => {
|
|
39
|
+
* // Exclusive work
|
|
40
|
+
* return 42;
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export interface CacheLock {
|
|
45
|
+
/**
|
|
46
|
+
* Attempt to acquire the lock immediately.
|
|
47
|
+
*
|
|
48
|
+
* Uses an atomic "set if not exists" operation in the underlying cache
|
|
49
|
+
* to ensure only one owner can hold the lock at a time.
|
|
50
|
+
*
|
|
51
|
+
* @returns `true` if the lock was successfully acquired, `false` if it is already held.
|
|
52
|
+
* @throws {Error} If the underlying cache store fails.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const acquired = await lock.acquire();
|
|
57
|
+
* if (acquired) {
|
|
58
|
+
* try {
|
|
59
|
+
* // Critical section
|
|
60
|
+
* } finally {
|
|
61
|
+
* await lock.release();
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
acquire(): Promise<boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* Release the lock.
|
|
69
|
+
*
|
|
70
|
+
* Removes the lock entry from the cache, allowing other processes to acquire it.
|
|
71
|
+
* Should typically be called in a `finally` block to ensure the lock is not leaked.
|
|
72
|
+
*
|
|
73
|
+
* @returns A promise that resolves when the lock is released.
|
|
74
|
+
* @throws {Error} If the underlying cache store fails.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* await lock.release();
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
release(): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Extend the lock's time-to-live (TTL).
|
|
84
|
+
*
|
|
85
|
+
* Increases the expiration time of the lock to prevent it from being
|
|
86
|
+
* automatically released while a long-running task is still in progress.
|
|
87
|
+
*
|
|
88
|
+
* @param seconds - Duration in seconds to add to the current TTL.
|
|
89
|
+
* @returns `true` if the lock was extended (still owned by this process), `false` otherwise.
|
|
90
|
+
* @throws {Error} If the underlying cache store fails.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const extended = await lock.extend(30);
|
|
95
|
+
* if (!extended) {
|
|
96
|
+
* throw new Error('Lock lost or expired before extension');
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
extend?(seconds: number): Promise<boolean>;
|
|
101
|
+
/**
|
|
102
|
+
* Get the remaining time-to-live for the lock.
|
|
103
|
+
*
|
|
104
|
+
* Useful for monitoring or determining if a lock extension is necessary.
|
|
105
|
+
*
|
|
106
|
+
* @returns Remaining TTL in seconds. Returns -1 if the lock doesn't exist, or -2 if it has no TTL.
|
|
107
|
+
* @throws {Error} If the underlying cache store fails.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const ttl = await lock.getRemainingTime();
|
|
112
|
+
* if (ttl > 0 && ttl < 5) {
|
|
113
|
+
* await lock.extend(10);
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
getRemainingTime?(): Promise<number>;
|
|
118
|
+
/**
|
|
119
|
+
* Attempt to acquire the lock and execute a callback with automatic retry.
|
|
120
|
+
*
|
|
121
|
+
* If the lock is currently held, this method will poll the cache at regular
|
|
122
|
+
* intervals until the lock is acquired or the timeout is reached.
|
|
123
|
+
*
|
|
124
|
+
* @param seconds - Maximum duration to wait for the lock in seconds.
|
|
125
|
+
* @param callback - Logic to execute once the lock is successfully acquired.
|
|
126
|
+
* @param options - Configuration for polling and retry behavior.
|
|
127
|
+
* @returns The value returned by the callback.
|
|
128
|
+
* @throws {LockTimeoutError} If the lock cannot be acquired within the specified timeout.
|
|
129
|
+
* @throws {Error} If the callback throws or the cache store fails.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const result = await lock.block(10, async () => {
|
|
134
|
+
* return await performAtomicOperation();
|
|
135
|
+
* });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
block<T>(seconds: number, callback: () => Promise<T> | T, options?: BlockOptions): Promise<T>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Configuration for the `block()` method's retry logic.
|
|
142
|
+
*
|
|
143
|
+
* Defines how the lock acquisition should behave when the lock is already held,
|
|
144
|
+
* including polling intervals and cancellation support.
|
|
145
|
+
*
|
|
146
|
+
* @public
|
|
147
|
+
* @since 3.1.0
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const options: BlockOptions = {
|
|
152
|
+
* retryInterval: 250,
|
|
153
|
+
* maxRetries: 10
|
|
154
|
+
* };
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export interface BlockOptions {
|
|
158
|
+
/**
|
|
159
|
+
* Delay between consecutive acquisition attempts.
|
|
160
|
+
* @defaultValue 100
|
|
161
|
+
*/
|
|
162
|
+
retryInterval?: number;
|
|
163
|
+
/**
|
|
164
|
+
* Maximum number of times to attempt acquisition before failing.
|
|
165
|
+
* @defaultValue Infinity
|
|
166
|
+
*/
|
|
167
|
+
maxRetries?: number;
|
|
168
|
+
/**
|
|
169
|
+
* Signal to allow external cancellation of the waiting process.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* const controller = new AbortController();
|
|
174
|
+
* setTimeout(() => controller.abort(), 2000);
|
|
175
|
+
* await lock.block(10, task, { signal: controller.signal });
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
signal?: AbortSignal;
|
|
179
|
+
/**
|
|
180
|
+
* @deprecated Use `retryInterval` instead.
|
|
181
|
+
*/
|
|
182
|
+
sleepMillis?: number;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Pause execution for a specified duration.
|
|
186
|
+
*
|
|
187
|
+
* Internal utility used for implementing polling delays in lock acquisition.
|
|
188
|
+
*
|
|
189
|
+
* @param ms - Duration to pause in milliseconds.
|
|
190
|
+
* @returns A promise that resolves after the delay.
|
|
191
|
+
* @internal
|
|
192
|
+
*/
|
|
193
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract for a mechanism that predicts future cache key accesses.
|
|
3
|
+
*
|
|
4
|
+
* Implementations observe sequential access patterns to predict which keys
|
|
5
|
+
* are likely to be requested next, enabling prefetching strategies.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
* @since 3.2.0
|
|
9
|
+
*/
|
|
10
|
+
export interface AccessPredictor {
|
|
11
|
+
/**
|
|
12
|
+
* Record a cache key access to learn temporal patterns.
|
|
13
|
+
*
|
|
14
|
+
* @param key - Cache key currently being accessed.
|
|
15
|
+
*/
|
|
16
|
+
record(key: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Predict potential future keys based on learned access history.
|
|
19
|
+
*
|
|
20
|
+
* @param key - Current cache key acting as the trigger for prediction.
|
|
21
|
+
* @returns Array of predicted keys, ordered by likelihood.
|
|
22
|
+
*/
|
|
23
|
+
predict(key: string): string[];
|
|
24
|
+
/**
|
|
25
|
+
* Reset all learned transition probabilities and state.
|
|
26
|
+
*/
|
|
27
|
+
reset(): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A simple Markov Chain predictor (Order-1).
|
|
31
|
+
*
|
|
32
|
+
* Records transitions (A -> B) between sequential accesses and predicts
|
|
33
|
+
* B when A is next encountered. This is particularly effective for
|
|
34
|
+
* predictable resource loading sequences.
|
|
35
|
+
*
|
|
36
|
+
* @public
|
|
37
|
+
* @since 3.2.0
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const predictor = new MarkovPredictor();
|
|
42
|
+
* predictor.record('user:1');
|
|
43
|
+
* predictor.record('user:1:profile');
|
|
44
|
+
* const next = predictor.predict('user:1'); // ['user:1:profile']
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare class MarkovPredictor implements AccessPredictor {
|
|
48
|
+
private transitions;
|
|
49
|
+
private lastKey;
|
|
50
|
+
private readonly maxNodes;
|
|
51
|
+
private readonly maxEdgesPerNode;
|
|
52
|
+
/**
|
|
53
|
+
* Initialize a new MarkovPredictor.
|
|
54
|
+
*
|
|
55
|
+
* @param options - Limits for internal transition graph to manage memory.
|
|
56
|
+
*/
|
|
57
|
+
constructor(options?: {
|
|
58
|
+
maxNodes?: number;
|
|
59
|
+
maxEdgesPerNode?: number;
|
|
60
|
+
});
|
|
61
|
+
record(key: string): void;
|
|
62
|
+
predict(key: string): string[];
|
|
63
|
+
reset(): void;
|
|
64
|
+
}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import type { CacheLock } from './locks';
|
|
2
|
+
import type { CacheKey, CacheTtl, CacheValue } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Low-level cache storage contract.
|
|
5
|
+
*
|
|
6
|
+
* Defines the essential operations for cache backends. Implementations of this interface
|
|
7
|
+
* (e.g., Memory, Redis, File) provide the actual persistence logic for the cache system.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
* @since 3.0.0
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* class MyStore implements CacheStore {
|
|
15
|
+
* async get(key) { ... }
|
|
16
|
+
* async put(key, value, ttl) { ... }
|
|
17
|
+
* // ... other methods
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export interface CacheStore {
|
|
22
|
+
/**
|
|
23
|
+
* Retrieve an item from the cache.
|
|
24
|
+
*
|
|
25
|
+
* Fetches the value associated with the given key. If the item has expired or does not exist,
|
|
26
|
+
* the implementation should return null.
|
|
27
|
+
*
|
|
28
|
+
* @param key - Unique identifier for the cached item.
|
|
29
|
+
* @returns The cached value or null if missing/expired.
|
|
30
|
+
* @throws {Error} If the storage backend is unreachable or encounters a read failure.
|
|
31
|
+
*/
|
|
32
|
+
get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
|
|
33
|
+
/**
|
|
34
|
+
* Store an item in the cache.
|
|
35
|
+
*
|
|
36
|
+
* Persists a value with a specific expiration time. Overwrites any existing value for the same key.
|
|
37
|
+
*
|
|
38
|
+
* @param key - Unique identifier for the cached item.
|
|
39
|
+
* @param value - Data to be persisted.
|
|
40
|
+
* @param ttl - Duration in seconds until the item expires.
|
|
41
|
+
* @returns Resolves when the write operation completes.
|
|
42
|
+
* @throws {Error} If the storage backend is full or encounters a write failure.
|
|
43
|
+
*/
|
|
44
|
+
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Store an item if it does not already exist.
|
|
47
|
+
*
|
|
48
|
+
* Atomic operation to ensure a value is only stored if the key is currently vacant.
|
|
49
|
+
*
|
|
50
|
+
* @param key - Unique identifier for the cached item.
|
|
51
|
+
* @param value - Data to be persisted.
|
|
52
|
+
* @param ttl - Duration in seconds until the item expires.
|
|
53
|
+
* @returns True if the item was successfully added, false if it already existed.
|
|
54
|
+
* @throws {Error} If the storage backend encounters a concurrency or write failure.
|
|
55
|
+
*/
|
|
56
|
+
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* Remove an item from the cache.
|
|
59
|
+
*
|
|
60
|
+
* Deletes the entry associated with the specified key.
|
|
61
|
+
*
|
|
62
|
+
* @param key - Identifier of the item to be removed.
|
|
63
|
+
* @returns True if the item existed and was removed, false otherwise.
|
|
64
|
+
* @throws {Error} If the storage backend encounters a deletion failure.
|
|
65
|
+
*/
|
|
66
|
+
forget(key: CacheKey): Promise<boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* Wipe all items from the cache storage.
|
|
69
|
+
*
|
|
70
|
+
* Clears the entire cache backend. Use with caution as this operation is destructive.
|
|
71
|
+
*
|
|
72
|
+
* @returns Resolves when the flush operation completes.
|
|
73
|
+
* @throws {Error} If the storage backend fails to clear the data.
|
|
74
|
+
*/
|
|
75
|
+
flush(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Increment a numeric value in the cache.
|
|
78
|
+
*
|
|
79
|
+
* Atomically increases the value of a numeric item. If the key does not exist,
|
|
80
|
+
* it is typically initialized to zero before incrementing.
|
|
81
|
+
*
|
|
82
|
+
* @param key - Identifier of the numeric item.
|
|
83
|
+
* @param value - Amount to add to the current value.
|
|
84
|
+
* @returns The updated numeric value.
|
|
85
|
+
* @throws {TypeError} If the existing value is not numeric.
|
|
86
|
+
* @throws {Error} If the storage backend encounters an atomic update failure.
|
|
87
|
+
*/
|
|
88
|
+
increment(key: CacheKey, value?: number): Promise<number>;
|
|
89
|
+
/**
|
|
90
|
+
* Decrement a numeric value in the cache.
|
|
91
|
+
*
|
|
92
|
+
* Atomically decreases the value of a numeric item. If the key does not exist,
|
|
93
|
+
* it is typically initialized to zero before decrementing.
|
|
94
|
+
*
|
|
95
|
+
* @param key - Identifier of the numeric item.
|
|
96
|
+
* @param value - Amount to subtract from the current value.
|
|
97
|
+
* @returns The updated numeric value.
|
|
98
|
+
* @throws {TypeError} If the existing value is not numeric.
|
|
99
|
+
* @throws {Error} If the storage backend encounters an atomic update failure.
|
|
100
|
+
*/
|
|
101
|
+
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
102
|
+
/**
|
|
103
|
+
* Create a distributed lock instance.
|
|
104
|
+
*
|
|
105
|
+
* Provides a mechanism for mutual exclusion across multiple processes or servers
|
|
106
|
+
* using the cache backend as the synchronization provider.
|
|
107
|
+
*
|
|
108
|
+
* @param name - Unique name for the lock.
|
|
109
|
+
* @param seconds - Default duration for which the lock should be held.
|
|
110
|
+
* @returns A lock instance if supported by the driver, otherwise undefined.
|
|
111
|
+
*/
|
|
112
|
+
lock?(name: string, seconds?: number): CacheLock | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* Get the remaining lifetime of a cached item.
|
|
115
|
+
*
|
|
116
|
+
* Calculates how many seconds are left before the item expires.
|
|
117
|
+
*
|
|
118
|
+
* @param key - Identifier of the cached item.
|
|
119
|
+
* @returns Seconds remaining until expiration, or null if the key has no TTL or does not exist.
|
|
120
|
+
* @throws {Error} If the storage backend encounters a read failure.
|
|
121
|
+
*/
|
|
122
|
+
ttl?(key: CacheKey): Promise<number | null>;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Contract for cache stores supporting tag-based invalidation.
|
|
126
|
+
*
|
|
127
|
+
* Allows grouping cache entries under one or more tags, enabling bulk invalidation
|
|
128
|
+
* of related items without knowing their individual keys.
|
|
129
|
+
*
|
|
130
|
+
* @public
|
|
131
|
+
* @since 3.0.0
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* if (isTaggableStore(store)) {
|
|
136
|
+
* await store.flushTags(['users']);
|
|
137
|
+
* }
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
export interface TaggableStore {
|
|
141
|
+
/**
|
|
142
|
+
* Invalidate all items associated with specific tags.
|
|
143
|
+
*
|
|
144
|
+
* Effectively clears all cache entries that were stored with any of the provided tags.
|
|
145
|
+
*
|
|
146
|
+
* @param tags - List of tags to be flushed.
|
|
147
|
+
* @returns Resolves when the tag invalidation completes.
|
|
148
|
+
* @throws {Error} If the storage backend fails to process the tag flush.
|
|
149
|
+
*/
|
|
150
|
+
flushTags(tags: readonly string[]): Promise<void>;
|
|
151
|
+
/**
|
|
152
|
+
* Compute a namespaced key based on tags.
|
|
153
|
+
*
|
|
154
|
+
* Generates a unique internal key that incorporates tag versioning to ensure
|
|
155
|
+
* proper isolation and invalidation.
|
|
156
|
+
*
|
|
157
|
+
* @param key - Original user-provided cache key.
|
|
158
|
+
* @param tags - Tags to associate with the key.
|
|
159
|
+
* @returns A derived key string used for actual storage.
|
|
160
|
+
*/
|
|
161
|
+
tagKey(key: string, tags: readonly string[]): string;
|
|
162
|
+
/**
|
|
163
|
+
* Register a key in the tag index.
|
|
164
|
+
*
|
|
165
|
+
* Maintains the relationship between tags and their associated keys for tracking.
|
|
166
|
+
*
|
|
167
|
+
* @param tags - Tags to index the key under.
|
|
168
|
+
* @param taggedKey - The derived key to be indexed.
|
|
169
|
+
* @returns Resolves when the indexing completes.
|
|
170
|
+
*/
|
|
171
|
+
tagIndexAdd(tags: readonly string[], taggedKey: string): void | Promise<void>;
|
|
172
|
+
/**
|
|
173
|
+
* Unregister a key from all tag indexes.
|
|
174
|
+
*
|
|
175
|
+
* Removes the tracking information for a specific derived key.
|
|
176
|
+
*
|
|
177
|
+
* @param taggedKey - The derived key to remove from indexes.
|
|
178
|
+
* @returns Resolves when the removal completes.
|
|
179
|
+
*/
|
|
180
|
+
tagIndexRemove(taggedKey: string): void | Promise<void>;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Validates if a cache store supports tagging operations.
|
|
184
|
+
*
|
|
185
|
+
* Performs a runtime check to determine if the provided store implements the `TaggableStore` interface.
|
|
186
|
+
*
|
|
187
|
+
* @param store - The cache store instance to evaluate.
|
|
188
|
+
* @returns True if the store supports tagging, false otherwise.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* if (isTaggableStore(myStore)) {
|
|
193
|
+
* await myStore.flushTags(['users', 'posts']);
|
|
194
|
+
* }
|
|
195
|
+
* ```
|
|
196
|
+
*
|
|
197
|
+
* @public
|
|
198
|
+
* @since 3.0.0
|
|
199
|
+
*/
|
|
200
|
+
export declare function isTaggableStore(store: CacheStore): store is CacheStore & TaggableStore;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { CacheStore } from '../store';
|
|
2
|
+
import type { CacheKey, CacheTtl } from '../types';
|
|
3
|
+
export type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
|
|
4
|
+
/**
|
|
5
|
+
* Options for the CircuitBreakerStore.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
* @since 3.2.0
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const options: CircuitBreakerOptions = {
|
|
13
|
+
* maxFailures: 3,
|
|
14
|
+
* resetTimeout: 30000,
|
|
15
|
+
* fallback: new MemoryStore()
|
|
16
|
+
* };
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export type CircuitBreakerOptions = {
|
|
20
|
+
/**
|
|
21
|
+
* Number of consecutive failures before opening the circuit.
|
|
22
|
+
* @defaultValue 5
|
|
23
|
+
*/
|
|
24
|
+
maxFailures?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Time in milliseconds to stay in OPEN state before transitioning to HALF_OPEN.
|
|
27
|
+
* @defaultValue 60000
|
|
28
|
+
*/
|
|
29
|
+
resetTimeout?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Optional fallback store to use when the primary store is unavailable.
|
|
32
|
+
*/
|
|
33
|
+
fallback?: CacheStore;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* A protective wrapper for cache stores that prevents cascading failures
|
|
37
|
+
* through circuit-breaking logic.
|
|
38
|
+
*
|
|
39
|
+
* When the primary store encounters repeated failures, the circuit opens,
|
|
40
|
+
* temporarily bypassing the primary store and optionally using a fallback.
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
* @since 3.2.0
|
|
44
|
+
*/
|
|
45
|
+
export declare class CircuitBreakerStore implements CacheStore {
|
|
46
|
+
private readonly primary;
|
|
47
|
+
private state;
|
|
48
|
+
private failures;
|
|
49
|
+
private lastErrorTime;
|
|
50
|
+
private options;
|
|
51
|
+
constructor(primary: CacheStore, options?: CircuitBreakerOptions);
|
|
52
|
+
private execute;
|
|
53
|
+
private onSuccess;
|
|
54
|
+
private onFailure;
|
|
55
|
+
private handleFallback;
|
|
56
|
+
get<T = unknown>(key: CacheKey): Promise<T | null>;
|
|
57
|
+
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
58
|
+
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
59
|
+
forget(key: CacheKey): Promise<boolean>;
|
|
60
|
+
flush(): Promise<void>;
|
|
61
|
+
increment(key: CacheKey, value?: number): Promise<number>;
|
|
62
|
+
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
63
|
+
ttl(key: CacheKey): Promise<number | null>;
|
|
64
|
+
/**
|
|
65
|
+
* Returns current state for monitoring.
|
|
66
|
+
*
|
|
67
|
+
* @returns Current state of the circuit breaker.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const state = store.getState();
|
|
72
|
+
* if (state === 'OPEN') {
|
|
73
|
+
* console.warn('Primary cache is unavailable');
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
getState(): CircuitState;
|
|
78
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type CacheLock } from '../locks';
|
|
2
|
+
import type { CacheStore } from '../store';
|
|
3
|
+
import { type CacheKey, type CacheTtl, type CacheValue } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the `FileStore` implementation.
|
|
6
|
+
*/
|
|
7
|
+
export type FileStoreOptions = {
|
|
8
|
+
directory: string;
|
|
9
|
+
enableCleanup?: boolean;
|
|
10
|
+
cleanupInterval?: number;
|
|
11
|
+
maxFiles?: number;
|
|
12
|
+
useSubdirectories?: boolean;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A persistent filesystem-based implementation of the `CacheStore` interface.
|
|
16
|
+
*/
|
|
17
|
+
export declare class FileStore implements CacheStore {
|
|
18
|
+
private options;
|
|
19
|
+
private cleanupTimer;
|
|
20
|
+
private runtime;
|
|
21
|
+
constructor(options: FileStoreOptions);
|
|
22
|
+
private startCleanupDaemon;
|
|
23
|
+
cleanExpiredFiles(): Promise<number>;
|
|
24
|
+
destroy(): Promise<void>;
|
|
25
|
+
private ensureDir;
|
|
26
|
+
private filePathForKey;
|
|
27
|
+
get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
|
|
28
|
+
put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
|
|
29
|
+
add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
|
|
30
|
+
forget(key: CacheKey): Promise<boolean>;
|
|
31
|
+
flush(): Promise<void>;
|
|
32
|
+
increment(key: CacheKey, value?: number): Promise<number>;
|
|
33
|
+
decrement(key: CacheKey, value?: number): Promise<number>;
|
|
34
|
+
ttl(key: CacheKey): Promise<number | null>;
|
|
35
|
+
lock(name: string, seconds?: number): CacheLock;
|
|
36
|
+
}
|