@sebspark/promise-cache 6.1.3 → 6.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/dist/index.d.mts +109 -66
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +30 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -3,7 +3,9 @@ import { UUID } from "node:crypto";
|
|
|
3
3
|
import { add, sub } from "date-fns";
|
|
4
4
|
|
|
5
5
|
//#region src/types.d.ts
|
|
6
|
-
type MultiExecReturnTypes = string[] | string |
|
|
6
|
+
type MultiExecReturnTypes = string[] | string | {
|
|
7
|
+
[x: string]: string;
|
|
8
|
+
} | number | boolean | null | undefined;
|
|
7
9
|
/**
|
|
8
10
|
* Defines the expiration strategy for cached values.
|
|
9
11
|
*
|
|
@@ -49,8 +51,13 @@ type Cache = {
|
|
|
49
51
|
* @param {CachingOptions<A>} options - Caching options, including key strategy.
|
|
50
52
|
* @returns {Delegate<A, R>} A new function that caches results.
|
|
51
53
|
*/
|
|
52
|
-
wrap
|
|
54
|
+
wrap<A extends unknown[], R>(delegate: (...args: A) => Promise<R>, options: CachingOptions<A, R>): (...args: A) => Promise<R>;
|
|
53
55
|
};
|
|
56
|
+
type HashTypes = string | number;
|
|
57
|
+
type HashValue = {
|
|
58
|
+
[x: string]: HashTypes;
|
|
59
|
+
[x: number]: HashTypes;
|
|
60
|
+
} | Map<HashTypes, HashTypes>;
|
|
54
61
|
/**
|
|
55
62
|
* Interface for a key-value storage system that supports Redis-like commands.
|
|
56
63
|
* Provides methods for storing, retrieving, and managing data with optional expiration.
|
|
@@ -63,26 +70,26 @@ interface IPersistor {
|
|
|
63
70
|
* @param options - Expiration options (TTL, absolute expiration, etc.).
|
|
64
71
|
* @returns Resolves to `"OK"` if successful, otherwise `null` if the operation fails.
|
|
65
72
|
*/
|
|
66
|
-
set
|
|
73
|
+
set(key: string, value: HashTypes, options?: SetOptions): Promise<string | null>;
|
|
67
74
|
/**
|
|
68
75
|
* Retrieves a value from Redis or Memory.
|
|
69
76
|
* @param key - The storage key.
|
|
70
77
|
* @returns Resolves to the stored value as a string, or `null` if the key does not exist.
|
|
71
78
|
*/
|
|
72
|
-
get
|
|
79
|
+
get(key: string): Promise<string | null>;
|
|
73
80
|
/**
|
|
74
81
|
* Deletes a key from Redis or Memory.
|
|
75
82
|
* @param key - The storage key.
|
|
76
83
|
* @returns Resolves to the number of keys removed (`1` if deleted, `0` if the key was not found).
|
|
77
84
|
*/
|
|
78
|
-
del
|
|
85
|
+
del(key: string): Promise<number>;
|
|
79
86
|
/**
|
|
80
87
|
* Sets a time-to-live (TTL) in seconds for a key.
|
|
81
88
|
* @param key - The storage key.
|
|
82
89
|
* @param seconds - TTL in seconds.
|
|
83
90
|
* @returns Resolves to `true` if the expiration was successfully set, `false` if the key does not exist.
|
|
84
91
|
*/
|
|
85
|
-
expire
|
|
92
|
+
expire(key: string, seconds: number): Promise<number>;
|
|
86
93
|
/**
|
|
87
94
|
* Gets the remaining TTL (time-to-live) of a key.
|
|
88
95
|
* @param key - The storage key.
|
|
@@ -91,12 +98,12 @@ interface IPersistor {
|
|
|
91
98
|
* - `-1` if the key exists but has no expiration.
|
|
92
99
|
* - `-2` if the key does not exist.
|
|
93
100
|
*/
|
|
94
|
-
ttl
|
|
101
|
+
ttl(key: string): Promise<number>;
|
|
95
102
|
/**
|
|
96
103
|
* Clears all keys from the storage system.
|
|
97
104
|
* @returns Resolves to `"OK"` when the operation completes successfully.
|
|
98
105
|
*/
|
|
99
|
-
flushAll
|
|
106
|
+
flushAll(): Promise<string>;
|
|
100
107
|
/**
|
|
101
108
|
* Stores a value and sets an expiration time in seconds.
|
|
102
109
|
* @param key - The storage key.
|
|
@@ -104,7 +111,7 @@ interface IPersistor {
|
|
|
104
111
|
* @param value - The string value to store.
|
|
105
112
|
* @returns Resolves to `"OK"` if successful, otherwise `null` if the operation fails.
|
|
106
113
|
*/
|
|
107
|
-
setEx
|
|
114
|
+
setEx(key: string, seconds: number, value: string): Promise<string | null>;
|
|
108
115
|
/**
|
|
109
116
|
* Stores a value and sets an expiration time in milliseconds.
|
|
110
117
|
* @param key - The storage key.
|
|
@@ -112,52 +119,52 @@ interface IPersistor {
|
|
|
112
119
|
* @param value - The string value to store.
|
|
113
120
|
* @returns Resolves to `"OK"` if successful, otherwise `null` if the operation fails.
|
|
114
121
|
*/
|
|
115
|
-
pSetEx
|
|
122
|
+
pSetEx(key: string, milliseconds: number, value: string): Promise<string | null>;
|
|
116
123
|
/**
|
|
117
124
|
* Stores a value **only if the key does not already exist**.
|
|
118
125
|
* @param key - The storage key.
|
|
119
126
|
* @param value - The string value to store.
|
|
120
127
|
* @returns Resolves to `true` if the key was set, or `false` if the key already exists.
|
|
121
128
|
*/
|
|
122
|
-
setNX
|
|
129
|
+
setNX(key: string, value: string): Promise<number>;
|
|
123
130
|
/**
|
|
124
131
|
* Creates a multi-command batch operation.
|
|
125
132
|
* This allows multiple commands to be executed in a batch, improving performance.
|
|
126
133
|
* @returns An instance of `IPersistorMulti` to queue multiple commands.
|
|
127
134
|
*/
|
|
128
|
-
multi
|
|
135
|
+
multi(): IPersistorMulti;
|
|
129
136
|
/**
|
|
130
137
|
* Checks if keys exist in storage.
|
|
131
138
|
* @param keys - One or more keys to check.
|
|
132
139
|
* @returns Resolves to the number of keys that exist.
|
|
133
140
|
*/
|
|
134
|
-
exists
|
|
141
|
+
exists(key: string | string[]): Promise<number>;
|
|
135
142
|
/**
|
|
136
143
|
* Increments a key by 1.
|
|
137
144
|
* @param key - The key to increment.
|
|
138
145
|
* @returns Resolves to the new value after increment.
|
|
139
146
|
*/
|
|
140
|
-
incr
|
|
147
|
+
incr(key: string): Promise<number>;
|
|
141
148
|
/**
|
|
142
149
|
* Decrements a key by 1.
|
|
143
150
|
* @param key - The key to decrement.
|
|
144
151
|
* @returns Resolves to the new value after decrement.
|
|
145
152
|
*/
|
|
146
|
-
decr
|
|
153
|
+
decr(key: string): Promise<number>;
|
|
147
154
|
/**
|
|
148
155
|
* Increments a key by a specified amount.
|
|
149
156
|
* @param key - The key to increment.
|
|
150
157
|
* @param increment - The amount to increase by.
|
|
151
158
|
* @returns Resolves to the new value after increment.
|
|
152
159
|
*/
|
|
153
|
-
incrBy
|
|
160
|
+
incrBy(key: string, increment: number): Promise<number>;
|
|
154
161
|
/**
|
|
155
162
|
* Decrements a key by a specified amount.
|
|
156
163
|
* @param key - The key to decrement.
|
|
157
164
|
* @param decrement - The amount to decrease by.
|
|
158
165
|
* @returns Resolves to the new value after decrement.
|
|
159
166
|
*/
|
|
160
|
-
decrBy
|
|
167
|
+
decrBy(key: string, decrement: number): Promise<number>;
|
|
161
168
|
/**
|
|
162
169
|
* Sets a field in a hash.
|
|
163
170
|
* @param key - The hash key.
|
|
@@ -165,40 +172,55 @@ interface IPersistor {
|
|
|
165
172
|
* @param value - The value to store.
|
|
166
173
|
* @returns Resolves to `1` if the field was added, or `0` if updated.
|
|
167
174
|
*/
|
|
168
|
-
hSet
|
|
175
|
+
hSet(key: string, field: string, value: HashTypes): Promise<number>;
|
|
176
|
+
/**
|
|
177
|
+
* Sets a (partial) hash.
|
|
178
|
+
* @param key - The hash key.
|
|
179
|
+
* @param value - The (partial) value to store.
|
|
180
|
+
* @returns Resolves to `1` if a field was added, or `0` if updated.
|
|
181
|
+
*/
|
|
182
|
+
hSet(key: string, value: HashValue): Promise<number>;
|
|
169
183
|
/**
|
|
170
184
|
* Retrieves a field from a hash.
|
|
171
185
|
* @param key - The hash key.
|
|
172
186
|
* @param field - The field name.
|
|
173
|
-
* @returns Resolves to the value, or
|
|
187
|
+
* @returns Resolves to the value, or null if the field does not exist.
|
|
188
|
+
*/
|
|
189
|
+
hGet(key: string, field: string): Promise<string | null>;
|
|
190
|
+
/**
|
|
191
|
+
* Retrieves a hash value.
|
|
192
|
+
* @param key - The hash key.
|
|
193
|
+
* @returns Resolves to the value, or null if the hash does not exist.
|
|
174
194
|
*/
|
|
175
|
-
|
|
195
|
+
hGetAll(key: string): Promise<{
|
|
196
|
+
[x: string]: string;
|
|
197
|
+
}>;
|
|
176
198
|
/**
|
|
177
199
|
* Pushes values to the left (head) of a list.
|
|
178
200
|
* @param key - The list key.
|
|
179
201
|
* @param values - The values to add.
|
|
180
202
|
* @returns Resolves to the length of the list after the operation.
|
|
181
203
|
*/
|
|
182
|
-
lPush
|
|
204
|
+
lPush(key: string, values: string | string[]): Promise<number>;
|
|
183
205
|
/**
|
|
184
206
|
* Pushes values to the right (tail) of a list.
|
|
185
207
|
* @param key - The list key.
|
|
186
208
|
* @param values - The values to add.
|
|
187
209
|
* @returns Resolves to the length of the list after the operation.
|
|
188
210
|
*/
|
|
189
|
-
rPush
|
|
211
|
+
rPush(key: string, values: string | string[]): Promise<number>;
|
|
190
212
|
/**
|
|
191
213
|
* Removes and returns the first element from a list.
|
|
192
214
|
* @param key - The list key.
|
|
193
215
|
* @returns Resolves to the removed element, or `null` if the list is empty.
|
|
194
216
|
*/
|
|
195
|
-
lPop
|
|
217
|
+
lPop(key: string): Promise<string | null>;
|
|
196
218
|
/**
|
|
197
219
|
* Removes and returns the last element from a list.
|
|
198
220
|
* @param key - The list key.
|
|
199
221
|
* @returns Resolves to the removed element, or `null` if the list is empty.
|
|
200
222
|
*/
|
|
201
|
-
rPop
|
|
223
|
+
rPop(key: string): Promise<string | null>;
|
|
202
224
|
/**
|
|
203
225
|
* Retrieves a range of elements from a list.
|
|
204
226
|
* @param key - The list key.
|
|
@@ -206,37 +228,37 @@ interface IPersistor {
|
|
|
206
228
|
* @param stop - The stop index (inclusive).
|
|
207
229
|
* @returns Resolves to an array of elements in the range.
|
|
208
230
|
*/
|
|
209
|
-
lRange
|
|
231
|
+
lRange(key: string, start: number, stop: number): Promise<string[]>;
|
|
210
232
|
/**
|
|
211
233
|
* Adds members to a set.
|
|
212
234
|
* @param key - The set key.
|
|
213
235
|
* @param values - The values to add.
|
|
214
236
|
* @returns Resolves to the number of elements successfully added.
|
|
215
237
|
*/
|
|
216
|
-
sAdd
|
|
238
|
+
sAdd(key: string, values: string | string[]): Promise<number>;
|
|
217
239
|
/**
|
|
218
240
|
* Removes members from a set.
|
|
219
241
|
* @param key - The set key.
|
|
220
242
|
* @param values - The values to remove.
|
|
221
243
|
* @returns Resolves to the number of elements removed.
|
|
222
244
|
*/
|
|
223
|
-
sRem
|
|
245
|
+
sRem(key: string, values: string | string[]): Promise<number>;
|
|
224
246
|
/**
|
|
225
247
|
* Retrieves all members of a set.
|
|
226
248
|
* @param key - The set key.
|
|
227
249
|
* @returns Resolves to an array of all members in the set.
|
|
228
250
|
*/
|
|
229
|
-
sMembers
|
|
251
|
+
sMembers(key: string): Promise<string[]>;
|
|
230
252
|
/**
|
|
231
253
|
* Adds members to a sorted set with scores.
|
|
232
254
|
* @param key - The sorted set key.
|
|
233
255
|
* @param members - An array of objects with `score` and `value`.
|
|
234
256
|
* @returns Resolves to the number of elements successfully added.
|
|
235
257
|
*/
|
|
236
|
-
zAdd
|
|
258
|
+
zAdd(key: string, members: {
|
|
237
259
|
score: number;
|
|
238
260
|
value: string;
|
|
239
|
-
}[])
|
|
261
|
+
}[]): Promise<number>;
|
|
240
262
|
/**
|
|
241
263
|
* Retrieves a range of members from a sorted set.
|
|
242
264
|
* @param key - The sorted set key.
|
|
@@ -244,18 +266,18 @@ interface IPersistor {
|
|
|
244
266
|
* @param stop - The stop index (inclusive).
|
|
245
267
|
* @returns Resolves to an array of member values in the range.
|
|
246
268
|
*/
|
|
247
|
-
zRange
|
|
269
|
+
zRange(key: string, start: number, stop: number): Promise<string[]>;
|
|
248
270
|
/**
|
|
249
271
|
* Removes members from a sorted set.
|
|
250
272
|
* @param key - The sorted set key.
|
|
251
273
|
* @param members - The members to remove.
|
|
252
274
|
* @returns Resolves to the number of elements removed.
|
|
253
275
|
*/
|
|
254
|
-
zRem
|
|
276
|
+
zRem(key: string, members: string | string[]): Promise<number>;
|
|
255
277
|
isReady: boolean;
|
|
256
278
|
isOpen: boolean;
|
|
257
|
-
connect
|
|
258
|
-
once
|
|
279
|
+
connect(): Promise<IPersistor>;
|
|
280
|
+
once(event: IPersistorEvent, cb: EventCallback): IPersistor;
|
|
259
281
|
}
|
|
260
282
|
type IPersistorEvent = 'ready' | 'connect' | 'reconnecting';
|
|
261
283
|
type EventCallback = () => void;
|
|
@@ -271,7 +293,7 @@ interface IPersistorMulti {
|
|
|
271
293
|
* @param options - Expiration options (TTL, absolute expiration, etc.).
|
|
272
294
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
273
295
|
*/
|
|
274
|
-
set
|
|
296
|
+
set(key: string, value: HashTypes, options?: SetOptions): IPersistorMulti;
|
|
275
297
|
/**
|
|
276
298
|
* Stores a value and sets an expiration time in seconds.
|
|
277
299
|
* @param key - The storage key.
|
|
@@ -279,7 +301,7 @@ interface IPersistorMulti {
|
|
|
279
301
|
* @param value - The string value to store.
|
|
280
302
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
281
303
|
*/
|
|
282
|
-
setEx
|
|
304
|
+
setEx(key: string, seconds: number, value: string): IPersistorMulti;
|
|
283
305
|
/**
|
|
284
306
|
* Stores a value and sets an expiration time in milliseconds.
|
|
285
307
|
* @param key - The storage key.
|
|
@@ -287,76 +309,76 @@ interface IPersistorMulti {
|
|
|
287
309
|
* @param value - The string value to store.
|
|
288
310
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
289
311
|
*/
|
|
290
|
-
pSetEx
|
|
312
|
+
pSetEx(key: string, milliseconds: number, value: string): IPersistorMulti;
|
|
291
313
|
/**
|
|
292
314
|
* Stores a value **only if the key does not already exist**.
|
|
293
315
|
* @param key - The storage key.
|
|
294
316
|
* @param value - The string value to store.
|
|
295
317
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
296
318
|
*/
|
|
297
|
-
setNX
|
|
319
|
+
setNX(key: string, value: string): IPersistorMulti;
|
|
298
320
|
/**
|
|
299
321
|
* Retrieves a value from Redis or Memory.
|
|
300
322
|
* @param key - The storage key.
|
|
301
323
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
302
324
|
*/
|
|
303
|
-
get
|
|
325
|
+
get(key: string): IPersistorMulti;
|
|
304
326
|
/**
|
|
305
327
|
* Deletes a key from Redis or Memory.
|
|
306
328
|
* @param key - The storage key.
|
|
307
329
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
308
330
|
*/
|
|
309
|
-
del
|
|
331
|
+
del(key: string): IPersistorMulti;
|
|
310
332
|
/**
|
|
311
333
|
* Sets a time-to-live (TTL) in seconds for a key.
|
|
312
334
|
* @param key - The storage key.
|
|
313
335
|
* @param seconds - TTL in seconds.
|
|
314
336
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
315
337
|
*/
|
|
316
|
-
expire
|
|
338
|
+
expire(key: string, seconds: number): IPersistorMulti;
|
|
317
339
|
/**
|
|
318
340
|
* Gets the remaining TTL (time-to-live) of a key.
|
|
319
341
|
* @param key - The storage key.
|
|
320
342
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
321
343
|
*/
|
|
322
|
-
ttl
|
|
344
|
+
ttl(key: string): IPersistorMulti;
|
|
323
345
|
/**
|
|
324
346
|
* Clears all keys from the storage system.
|
|
325
347
|
* @returns The same `IPersistorMulti` instance, enabling method chaining.
|
|
326
348
|
*/
|
|
327
|
-
flushAll
|
|
349
|
+
flushAll(): IPersistorMulti;
|
|
328
350
|
/**
|
|
329
351
|
* Queues an `exists` operation in the transaction.
|
|
330
352
|
* @param key - The storage key or an array of keys.
|
|
331
353
|
* @returns The `IPersistorMulti` instance for method chaining.
|
|
332
354
|
*/
|
|
333
|
-
exists
|
|
355
|
+
exists(key: string | string[]): IPersistorMulti;
|
|
334
356
|
/**
|
|
335
357
|
* Queues an `incr` operation in the transaction.
|
|
336
358
|
* @param key - The storage key.
|
|
337
359
|
* @returns The `IPersistorMulti` instance for method chaining.
|
|
338
360
|
*/
|
|
339
|
-
incr
|
|
361
|
+
incr(key: string): IPersistorMulti;
|
|
340
362
|
/**
|
|
341
363
|
* Queues an `incrBy` operation in the transaction.
|
|
342
364
|
* @param key - The storage key.
|
|
343
365
|
* @param increment - The amount to increment by.
|
|
344
366
|
* @returns The `IPersistorMulti` instance for method chaining.
|
|
345
367
|
*/
|
|
346
|
-
incrBy
|
|
368
|
+
incrBy(key: string, increment: number): IPersistorMulti;
|
|
347
369
|
/**
|
|
348
370
|
* Queues a `decr` operation in the transaction.
|
|
349
371
|
* @param key - The storage key.
|
|
350
372
|
* @returns The `IPersistorMulti` instance for method chaining.
|
|
351
373
|
*/
|
|
352
|
-
decr
|
|
374
|
+
decr(key: string): IPersistorMulti;
|
|
353
375
|
/**
|
|
354
376
|
* Queues a `decrBy` operation in the transaction.
|
|
355
377
|
* @param key - The storage key.
|
|
356
378
|
* @param decrement - The amount to decrement by.
|
|
357
379
|
* @returns The `IPersistorMulti` instance for method chaining.
|
|
358
380
|
*/
|
|
359
|
-
decrBy
|
|
381
|
+
decrBy(key: string, decrement: number): IPersistorMulti;
|
|
360
382
|
/**
|
|
361
383
|
* Sets a field in a hash.
|
|
362
384
|
* @param key - The hash key.
|
|
@@ -364,40 +386,53 @@ interface IPersistorMulti {
|
|
|
364
386
|
* @param value - The value to store.
|
|
365
387
|
* @returns The multi-instance for chaining.
|
|
366
388
|
*/
|
|
367
|
-
hSet
|
|
389
|
+
hSet(key: string, field: string, value: HashTypes): IPersistorMulti;
|
|
390
|
+
/**
|
|
391
|
+
* Sets a (partial) hash.
|
|
392
|
+
* @param key - The hash key.
|
|
393
|
+
* @param value - The (partial) value to store.
|
|
394
|
+
* @returns Resolves to `1` if a field was added, or `0` if updated.
|
|
395
|
+
*/
|
|
396
|
+
hSet(key: string, value: HashValue): IPersistorMulti;
|
|
368
397
|
/**
|
|
369
398
|
* Retrieves a field from a hash.
|
|
370
399
|
* @param key - The hash key.
|
|
371
400
|
* @param field - The field name.
|
|
372
|
-
* @returns
|
|
401
|
+
* @returns Resolves to the value, or null if the field does not exist.
|
|
402
|
+
*/
|
|
403
|
+
hGet(key: string, field: string): IPersistorMulti;
|
|
404
|
+
/**
|
|
405
|
+
* Retrieves a hash value.
|
|
406
|
+
* @param key - The hash key.
|
|
407
|
+
* @returns Resolves to the value, or null if the hash does not exist.
|
|
373
408
|
*/
|
|
374
|
-
|
|
409
|
+
hGetAll(key: string): IPersistorMulti;
|
|
375
410
|
/**
|
|
376
411
|
* Pushes values to the left (head) of a list.
|
|
377
412
|
* @param key - The list key.
|
|
378
413
|
* @param values - The values to add.
|
|
379
414
|
* @returns The multi-instance for chaining.
|
|
380
415
|
*/
|
|
381
|
-
lPush
|
|
416
|
+
lPush(key: string, values: string | string[]): IPersistorMulti;
|
|
382
417
|
/**
|
|
383
418
|
* Pushes values to the right (tail) of a list.
|
|
384
419
|
* @param key - The list key.
|
|
385
420
|
* @param values - The values to add.
|
|
386
421
|
* @returns The multi-instance for chaining.
|
|
387
422
|
*/
|
|
388
|
-
rPush
|
|
423
|
+
rPush(key: string, values: string | string[]): IPersistorMulti;
|
|
389
424
|
/**
|
|
390
425
|
* Removes and returns the first element from a list.
|
|
391
426
|
* @param key - The list key.
|
|
392
427
|
* @returns The multi-instance for chaining.
|
|
393
428
|
*/
|
|
394
|
-
lPop
|
|
429
|
+
lPop(key: string): IPersistorMulti;
|
|
395
430
|
/**
|
|
396
431
|
* Removes and returns the last element from a list.
|
|
397
432
|
* @param key - The list key.
|
|
398
433
|
* @returns The multi-instance for chaining.
|
|
399
434
|
*/
|
|
400
|
-
rPop
|
|
435
|
+
rPop(key: string): IPersistorMulti;
|
|
401
436
|
/**
|
|
402
437
|
* Retrieves a range of elements from a list.
|
|
403
438
|
* @param key - The list key.
|
|
@@ -405,37 +440,37 @@ interface IPersistorMulti {
|
|
|
405
440
|
* @param stop - The stop index (inclusive).
|
|
406
441
|
* @returns The multi-instance for chaining.
|
|
407
442
|
*/
|
|
408
|
-
lRange
|
|
443
|
+
lRange(key: string, start: number, stop: number): IPersistorMulti;
|
|
409
444
|
/**
|
|
410
445
|
* Adds members to a set.
|
|
411
446
|
* @param key - The set key.
|
|
412
447
|
* @param values - The values to add.
|
|
413
448
|
* @returns The multi-instance for chaining.
|
|
414
449
|
*/
|
|
415
|
-
sAdd
|
|
450
|
+
sAdd(key: string, values: string | string[]): IPersistorMulti;
|
|
416
451
|
/**
|
|
417
452
|
* Removes members from a set.
|
|
418
453
|
* @param key - The set key.
|
|
419
454
|
* @param values - The values to remove.
|
|
420
455
|
* @returns The multi-instance for chaining.
|
|
421
456
|
*/
|
|
422
|
-
sRem
|
|
457
|
+
sRem(key: string, values: string | string[]): IPersistorMulti;
|
|
423
458
|
/**
|
|
424
459
|
* Retrieves all members of a set.
|
|
425
460
|
* @param key - The set key.
|
|
426
461
|
* @returns The multi-instance for chaining.
|
|
427
462
|
*/
|
|
428
|
-
sMembers
|
|
463
|
+
sMembers(key: string): IPersistorMulti;
|
|
429
464
|
/**
|
|
430
465
|
* Adds members to a sorted set with scores.
|
|
431
466
|
* @param key - The sorted set key.
|
|
432
467
|
* @param members - An array of objects with `score` and `value`.
|
|
433
468
|
* @returns The multi-instance for chaining.
|
|
434
469
|
*/
|
|
435
|
-
zAdd
|
|
470
|
+
zAdd(key: string, members: {
|
|
436
471
|
score: number;
|
|
437
472
|
value: string;
|
|
438
|
-
}[])
|
|
473
|
+
}[]): IPersistorMulti;
|
|
439
474
|
/**
|
|
440
475
|
* Retrieves a range of members from a sorted set.
|
|
441
476
|
* @param key - The sorted set key.
|
|
@@ -443,20 +478,20 @@ interface IPersistorMulti {
|
|
|
443
478
|
* @param stop - The stop index (inclusive).
|
|
444
479
|
* @returns The multi-instance for chaining.
|
|
445
480
|
*/
|
|
446
|
-
zRange
|
|
481
|
+
zRange(key: string, start: number, stop: number): IPersistorMulti;
|
|
447
482
|
/**
|
|
448
483
|
* Removes members from a sorted set.
|
|
449
484
|
* @param key - The sorted set key.
|
|
450
485
|
* @param members - The members to remove.
|
|
451
486
|
* @returns The multi-instance for chaining.
|
|
452
487
|
*/
|
|
453
|
-
zRem
|
|
488
|
+
zRem(key: string, members: string | string[]): IPersistorMulti;
|
|
454
489
|
/**
|
|
455
490
|
* Executes all queued commands and returns their results.
|
|
456
491
|
* @returns A promise resolving to an array of results for each command.
|
|
457
492
|
* The result type can be `string | number | boolean | null`, depending on the command.
|
|
458
493
|
*/
|
|
459
|
-
exec
|
|
494
|
+
exec(): Promise<MultiExecReturnTypes[] | unknown>;
|
|
460
495
|
}
|
|
461
496
|
//#endregion
|
|
462
497
|
//#region src/cache.d.ts
|
|
@@ -510,7 +545,7 @@ declare class InMemoryPersistor implements IPersistor {
|
|
|
510
545
|
* @param {SetOptions} [options] - Optional Redis-style expiration settings.
|
|
511
546
|
* @returns {Promise<'OK' | null>} Resolves to `'OK'` on success, or `null` if a conditional set (`NX`) fails.
|
|
512
547
|
*/
|
|
513
|
-
set(key: string, value:
|
|
548
|
+
set(key: string, value: HashTypes, options?: SetOptions): Promise<'OK' | null>;
|
|
514
549
|
/**
|
|
515
550
|
* Stores a key-value pair with an expiration time in seconds.
|
|
516
551
|
* If the key already exists, it will be overwritten.
|
|
@@ -624,7 +659,7 @@ declare class InMemoryPersistor implements IPersistor {
|
|
|
624
659
|
* @param value - The value to store.
|
|
625
660
|
* @returns Resolves to `1` if a new field was added, `0` if an existing field was updated.
|
|
626
661
|
*/
|
|
627
|
-
hSet(key: string,
|
|
662
|
+
hSet(key: string, fieldOrValue: string | HashValue, value?: HashTypes): Promise<number>;
|
|
628
663
|
/**
|
|
629
664
|
* Retrieves a field from a hash.
|
|
630
665
|
*
|
|
@@ -633,6 +668,14 @@ declare class InMemoryPersistor implements IPersistor {
|
|
|
633
668
|
* @returns Resolves to the field value, or `null` if the field does not exist.
|
|
634
669
|
*/
|
|
635
670
|
hGet(key: string, field: string): Promise<string | null>;
|
|
671
|
+
/**
|
|
672
|
+
* Retrieves a hash value.
|
|
673
|
+
* @param key - The hash key.
|
|
674
|
+
* @returns Resolves to the value, or null if the hash does not exist.
|
|
675
|
+
*/
|
|
676
|
+
hGetAll(key: string): Promise<{
|
|
677
|
+
[x: string]: string;
|
|
678
|
+
}>;
|
|
636
679
|
/**
|
|
637
680
|
* Pushes elements to the left (head) of a list.
|
|
638
681
|
*
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/cache.ts","../src/inMemoryPersistor.ts","../src/persistor.ts","../src/promiseCache.ts","../src/serializer.ts","../src/time.ts"],"sourcesContent":[],"mappings":";;;;;KAEY,oBAAA;;;;;AAAZ;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/cache.ts","../src/inMemoryPersistor.ts","../src/persistor.ts","../src/promiseCache.ts","../src/serializer.ts","../src/time.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -152,7 +152,7 @@ var InMemoryPersistor = class {
|
|
|
152
152
|
async set(key, value, options) {
|
|
153
153
|
if (options?.NX && this.store.has(key)) return null;
|
|
154
154
|
if (options?.XX && !this.store.has(key)) return null;
|
|
155
|
-
this.store.set(key, value);
|
|
155
|
+
this.store.set(key, String(value));
|
|
156
156
|
if (options?.EX !== void 0) this.setExpiration(key, options.EX * 1e3);
|
|
157
157
|
else if (options?.PX !== void 0) this.setExpiration(key, options.PX);
|
|
158
158
|
else if (options?.EXAT !== void 0) {
|
|
@@ -323,12 +323,16 @@ var InMemoryPersistor = class {
|
|
|
323
323
|
* @param value - The value to store.
|
|
324
324
|
* @returns Resolves to `1` if a new field was added, `0` if an existing field was updated.
|
|
325
325
|
*/
|
|
326
|
-
async hSet(key,
|
|
326
|
+
async hSet(key, fieldOrValue, value) {
|
|
327
327
|
const existingHash = JSON.parse(this.store.get(key) ?? "{}");
|
|
328
|
-
|
|
329
|
-
|
|
328
|
+
let newFields = 0;
|
|
329
|
+
const hashValue = value !== void 0 ? { [fieldOrValue]: value } : fieldOrValue;
|
|
330
|
+
for (const [key$1, val] of Object.entries(hashValue)) {
|
|
331
|
+
if (!Object.hasOwn(existingHash, key$1)) newFields++;
|
|
332
|
+
existingHash[key$1] = String(val);
|
|
333
|
+
}
|
|
330
334
|
this.store.set(key, JSON.stringify(existingHash));
|
|
331
|
-
return
|
|
335
|
+
return newFields;
|
|
332
336
|
}
|
|
333
337
|
/**
|
|
334
338
|
* Retrieves a field from a hash.
|
|
@@ -341,6 +345,14 @@ var InMemoryPersistor = class {
|
|
|
341
345
|
return JSON.parse(this.store.get(key) ?? "{}")[field] ?? null;
|
|
342
346
|
}
|
|
343
347
|
/**
|
|
348
|
+
* Retrieves a hash value.
|
|
349
|
+
* @param key - The hash key.
|
|
350
|
+
* @returns Resolves to the value, or null if the hash does not exist.
|
|
351
|
+
*/
|
|
352
|
+
async hGetAll(key) {
|
|
353
|
+
return JSON.parse(this.store.get(key) ?? "{}");
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
344
356
|
* Pushes elements to the left (head) of a list.
|
|
345
357
|
*
|
|
346
358
|
* @param key - The list key.
|
|
@@ -719,8 +731,9 @@ var InMemoryMulti = class {
|
|
|
719
731
|
* @param value - The value to store.
|
|
720
732
|
* @returns The `IPersistorMulti` instance to allow method chaining.
|
|
721
733
|
*/
|
|
722
|
-
hSet(key,
|
|
723
|
-
this.commands.add(() => this.persistor.hSet(key,
|
|
734
|
+
hSet(key, fieldOrValue, value) {
|
|
735
|
+
if (value !== void 0) this.commands.add(() => this.persistor.hSet(key, fieldOrValue, value));
|
|
736
|
+
else this.commands.add(() => this.persistor.hSet(key, fieldOrValue));
|
|
724
737
|
return this;
|
|
725
738
|
}
|
|
726
739
|
/**
|
|
@@ -736,6 +749,16 @@ var InMemoryMulti = class {
|
|
|
736
749
|
return this;
|
|
737
750
|
}
|
|
738
751
|
/**
|
|
752
|
+
* Queues an `hSet` command to store a field-value pair in a hash.
|
|
753
|
+
* The command will be executed when `exec()` is called.
|
|
754
|
+
* @param key - The hash key.
|
|
755
|
+
* @returns The `IPersistorMulti` instance to allow method chaining.
|
|
756
|
+
*/
|
|
757
|
+
hGetAll(key) {
|
|
758
|
+
this.commands.add(() => this.persistor.hGetAll(key));
|
|
759
|
+
return this;
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
739
762
|
* Queues an `lPush` command to add elements to the left (head) of a list.
|
|
740
763
|
* The command will be executed when `exec()` is called.
|
|
741
764
|
*
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["options: SetOptions","seconds","sortedSet: { score: number; value: string }[]","seconds","persistors: Record<string, Persistor>","hours","minutes","seconds"],"sources":["../src/serializer.ts","../src/setOptions.ts","../src/cache.ts","../src/inMemoryPersistor.ts","../src/localMemory.ts","../src/persistor.ts","../src/promiseCache.ts","../src/time.ts"],"sourcesContent":["import superjson from 'superjson'\n\nexport const serialize = <T>(data: T): string => {\n return superjson.stringify(data)\n}\n\nexport const deserialize = <T>(serialized: string | null): T | null => {\n if (serialized === undefined || serialized === null) return serialized\n\n return superjson.parse<T>(serialized)\n}\n","import type { SetOptions } from 'redis'\nimport type { Expiry } from './types'\n\n/**\n * Converts an Expiry value into Redis SetOptions.\n * @param {Expiry | undefined} expiry - The expiration time, either as a TTL in milliseconds or an exact Date.\n * @returns {SetOptions | undefined} Redis-compatible options, or undefined if no expiry.\n */\nexport const toSetOptions = (\n expiry: Expiry | undefined\n): SetOptions | undefined => {\n const options: SetOptions = {}\n\n // Expiry has a value\n if (expiry !== undefined) {\n if (typeof expiry === 'number') {\n options.PX = expiry // Store TTL in milliseconds\n } else if (expiry instanceof Date && !Number.isNaN(expiry.getTime())) {\n const timestamp = expiry.getTime()\n if (timestamp > Date.now()) {\n options.PXAT = timestamp // Use exact expiration time in milliseconds\n } else {\n options.PX = 1 // Past timestamps are invalid - expire immediately\n }\n }\n }\n\n // If expiry does not have a value, fall back to 1 sec\n if (!options.PX && !options.PXAT) {\n options.EX = 1\n }\n\n return options\n}\n","import { deserialize, serialize } from './serializer'\nimport { toSetOptions } from './setOptions'\nimport type { Cache, CachingOptions, IPersistor } from './types'\n\n/**\n * Creates a cache instance using a given persistor.\n * @param {IPersistor} persistor - The underlying storage for caching.\n * @param {string?} prefix - An optional prefix that will be prepended to the key, formatted as `prefix:key`.\n * @returns {Cache} A cache instance.\n */\nexport const createCache = (persistor: IPersistor, prefix?: string): Cache => {\n // Tracks in-progress requests to prevent duplicate calls\n const pendingPromises = new Map<string, Promise<unknown>>()\n\n const cache: Cache = {\n persistor,\n wrap: <A extends unknown[], R>(\n delegate: (...args: A) => Promise<R>,\n options: CachingOptions<A, R>\n ): ((...args: A) => Promise<R>) => {\n return async (...args: A): Promise<R> => {\n // Compute key\n let key =\n typeof options.key === 'string' ? options.key : options.key(...args)\n\n // Apply prefix if provided\n if (prefix) {\n key = `${prefix}:${key}`\n }\n\n // Return the pending request if one exists\n if (pendingPromises.has(key)) {\n return pendingPromises.get(key) as R\n }\n\n // Create a new promise to prevent duplicate processing\n const resultPromise = (async () => {\n try {\n // Ensure persistor is connected and ready\n await ensurePersistorIsReady(persistor)\n\n // Check cache\n const cached = deserialize<R>(await persistor.get(key))\n if (cached !== null) {\n return cached\n }\n\n // No cached value\n const result = await delegate(...args)\n\n // Calculate expiry\n const expiry =\n typeof options.expiry === 'function'\n ? options.expiry(args, result)\n : options.expiry\n\n // Ensure persistor is still connected and ready\n await ensurePersistorIsReady(persistor)\n\n // Save to cache\n const serialized = serialize(result)\n const setOptions = toSetOptions(expiry)\n await persistor.set(key, serialized, setOptions)\n\n // Return result\n return result\n } finally {\n pendingPromises.delete(key)\n }\n })()\n\n // Store promise until it resolves or fails\n pendingPromises.set(key, resultPromise)\n\n return resultPromise\n }\n },\n }\n return cache\n}\n\nconst ensurePersistorIsReady = async (persistor: IPersistor) => {\n // Persistor is connected and ready\n if (persistor.isReady) {\n return\n }\n\n // Persistor is connecting but not ready\n if (persistor.isOpen) {\n await new Promise<void>((resolve) => {\n if (persistor.isReady) return resolve()\n persistor.once('ready', resolve)\n return\n })\n }\n\n // Persistor should connect\n try {\n await persistor.connect()\n } catch (err) {\n if ((err as Error).message === 'Socket already opened') {\n // Connection is already in progress\n await new Promise<void>((resolve) => {\n if (persistor.isReady) return resolve()\n persistor.once('ready', resolve)\n })\n }\n }\n}\n","import type { SetOptions } from 'redis'\nimport type { IPersistor, IPersistorMulti, MultiExecReturnTypes } from './types'\n\n/**\n * An in-memory key-value store with Redis-like behavior.\n * Supports basic operations like `set`, `get`, `del`, `expire`, `ttl`, and `flushAll`.\n * Implements expiration using `setTimeout` for automatic key deletion.\n */\nexport class InMemoryPersistor implements IPersistor {\n /**\n * Internal key-value store for caching string values.\n * @private\n */\n private readonly store: Map<string, string>\n\n /**\n * Tracks active timeouts for expiring keys.\n * Each key maps to a `setTimeout` reference that deletes the key when triggered.\n * @private\n */\n private readonly expirations: Map<string, NodeJS.Timeout>\n\n /**\n * Stores absolute expiration timestamps (in milliseconds since epoch) for each key.\n * Used to compute remaining TTL.\n * @private\n */\n private readonly expiryTimestamps: Map<string, number>\n\n /**\n * Creates a new instance of `InMemoryPersistor`.\n * Initializes an empty store, expiration map, and TTL tracker.\n */\n constructor() {\n this.store = new Map()\n this.expirations = new Map()\n this.expiryTimestamps = new Map()\n }\n\n async connect() {\n return this\n }\n\n get isReady(): boolean {\n return true\n }\n\n get isOpen(): boolean {\n return true\n }\n\n once() {\n return this\n }\n\n /**\n * Stores a key-value pair with optional expiration settings.\n * If an expiration is provided (`EX`, `PX`, `EXAT`, `PXAT`), the key is automatically removed when TTL expires.\n *\n * @param {string} key - The key to store.\n * @param {string} value - The string value to associate with the key.\n * @param {SetOptions} [options] - Optional Redis-style expiration settings.\n * @returns {Promise<'OK' | null>} Resolves to `'OK'` on success, or `null` if a conditional set (`NX`) fails.\n */\n async set(\n key: string,\n value: string,\n options?: SetOptions\n ): Promise<'OK' | null> {\n if (options?.NX && this.store.has(key)) {\n return null // NX means \"only set if key does not exist\"\n }\n if (options?.XX && !this.store.has(key)) {\n return null // XX means \"only set if key exists\"\n }\n\n this.store.set(key, value)\n\n // Handle TTL (Expiration)\n if (options?.EX !== undefined) {\n this.setExpiration(key, options.EX * 1000) // Convert seconds to ms\n } else if (options?.PX !== undefined) {\n this.setExpiration(key, options.PX) // Milliseconds\n } else if (options?.EXAT !== undefined) {\n const timeToExpire = options.EXAT * 1000 - Date.now()\n this.setExpiration(key, Math.max(0, timeToExpire))\n } else if (options?.PXAT !== undefined) {\n const timeToExpire = options.PXAT - Date.now()\n this.setExpiration(key, Math.max(0, timeToExpire))\n }\n\n return 'OK'\n }\n\n /**\n * Stores a key-value pair with an expiration time in seconds.\n * If the key already exists, it will be overwritten.\n *\n * @param key - The storage key.\n * @param seconds - Expiration time in seconds.\n * @param value - The string value to store.\n * @returns Resolves to `'OK'` on success.\n */\n async setEx(\n key: string,\n seconds: number,\n value: string\n ): Promise<string | null> {\n this.store.set(key, value)\n await this.expire(key, seconds)\n return 'OK'\n }\n\n /**\n * Stores a key-value pair with an expiration time in milliseconds.\n * If the key already exists, it will be overwritten.\n *\n * @param key - The storage key.\n * @param milliseconds - Expiration time in milliseconds.\n * @param value - The string value to store.\n * @returns Resolves to `'OK'` on success.\n */\n async pSetEx(\n key: string,\n milliseconds: number,\n value: string\n ): Promise<string | null> {\n return this.setEx(key, milliseconds / 1000, value)\n }\n\n /**\n * Stores a key-value pair **only if the key does not already exist**.\n * If the key exists, the operation fails and returns `false`.\n *\n * @param key - The storage key.\n * @param value - The string value to store.\n * @returns Resolves to `true` if the key was set, or `false` if the key already exists.\n */\n async setNX(key: string, value: string): Promise<number> {\n if (this.store.has(key)) return 0\n this.store.set(key, value)\n return 1\n }\n\n /**\n * Retrieves the value associated with a key.\n *\n * @param {string} key - The key to retrieve.\n * @returns {Promise<string | null>} Resolves to the string value, or `null` if the key does not exist.\n */\n async get(key: string): Promise<string | null> {\n return this.store.get(key) ?? null\n }\n\n /**\n * Deletes a key from the store.\n * If the key exists, it is removed along with any associated expiration.\n *\n * @param {string} key - The key to delete.\n * @returns {Promise<number>} Resolves to `1` if the key was deleted, or `0` if the key did not exist.\n */\n async del(key: string): Promise<number> {\n const existed = this.store.has(key)\n if (existed) {\n this.store.delete(key)\n this.clearExpiration(key)\n }\n return existed ? 1 : 0\n }\n\n /**\n * Sets a time-to-live (TTL) in seconds for a key.\n * If the key exists, it will be deleted after the specified duration.\n *\n * @param {string} key - The key to set an expiration on.\n * @param {number} seconds - The TTL in seconds.\n * @returns {Promise<number>} Resolves to `1` if the TTL was set, or `0` if the key does not exist.\n */\n async expire(key: string, seconds: number): Promise<number> {\n if (!this.store.has(key)) return 0\n this.setExpiration(key, seconds * 1000) // Convert seconds to ms\n return 1\n }\n\n /**\n * Retrieves the remaining time-to-live (TTL) of a key in seconds.\n *\n * @param {string} key - The key to check.\n * @returns {Promise<number>} Resolves to:\n * - Remaining TTL in **seconds** if the key exists and has an expiration.\n * - `-1` if the key exists but has no expiration.\n * - `-2` if the key does not exist.\n */\n async ttl(key: string): Promise<number> {\n if (!this.store.has(key)) return -2 // Key does not exist\n if (!this.expiryTimestamps.has(key)) return -1 // No TTL set\n\n const timeLeft = (this.expiryTimestamps.get(key) as number) - Date.now()\n return timeLeft > 0 ? Math.ceil(timeLeft / 1000) : -2 // Return in seconds\n }\n\n /**\n * Checks if one or more keys exist in the store.\n *\n * @param {string | string[]} keys - A single key or an array of keys to check.\n * @returns {Promise<number>} Resolves to the number of keys that exist.\n */\n async exists(keys: string | string[]): Promise<number> {\n const keyArray = Array.isArray(keys) ? keys : [keys]\n return keyArray.reduce(\n (count, key) => (this.store.has(key) ? count + 1 : count),\n 0\n )\n }\n\n /**\n * Increments a numeric value stored at a key by 1.\n * If the key does not exist, it is set to `1`.\n *\n * @param {string} key - The key to increment.\n * @returns {Promise<number>} Resolves to the new value after increment.\n */\n async incr(key: string): Promise<number> {\n const current = Number(this.store.get(key)) || 0\n const newValue = current + 1\n this.store.set(key, newValue.toString())\n return newValue\n }\n\n /**\n * Increments a numeric value stored at a key by a specified amount.\n * If the key does not exist, it is set to the increment value.\n *\n * @param {string} key - The key to increment.\n * @param {number} increment - The amount to increase by.\n * @returns {Promise<number>} Resolves to the new value after increment.\n */\n async incrBy(key: string, increment: number): Promise<number> {\n const current = Number(this.store.get(key)) || 0\n const newValue = current + increment\n this.store.set(key, newValue.toString())\n return newValue\n }\n\n /**\n * Decrements a numeric value stored at a key by 1.\n * If the key does not exist, it is set to `-1`.\n *\n * @param {string} key - The key to decrement.\n * @returns {Promise<number>} Resolves to the new value after decrement.\n */\n async decr(key: string): Promise<number> {\n const current = Number(this.store.get(key)) || 0\n const newValue = current - 1\n this.store.set(key, newValue.toString())\n return newValue\n }\n\n /**\n * Decrements a numeric value stored at a key by a specified amount.\n * If the key does not exist, it is set to the negative decrement value.\n *\n * @param {string} key - The key to decrement.\n * @param {number} decrement - The amount to decrease by.\n * @returns {Promise<number>} Resolves to the new value after decrement.\n */\n async decrBy(key: string, decrement: number): Promise<number> {\n const current = Number(this.store.get(key)) || 0\n const newValue = current - decrement\n this.store.set(key, newValue.toString())\n return newValue\n }\n\n /**\n * Sets a field in a hash.\n * If the field already exists, its value is updated.\n *\n * @param key - The hash key.\n * @param field - The field name.\n * @param value - The value to store.\n * @returns Resolves to `1` if a new field was added, `0` if an existing field was updated.\n */\n async hSet(key: string, field: string, value: string): Promise<number> {\n const existingHash = JSON.parse(this.store.get(key) ?? '{}')\n const isNewField = !Object.hasOwn(existingHash, field)\n existingHash[field] = value\n this.store.set(key, JSON.stringify(existingHash))\n return isNewField ? 1 : 0\n }\n\n /**\n * Retrieves a field from a hash.\n *\n * @param key - The hash key.\n * @param field - The field name to retrieve.\n * @returns Resolves to the field value, or `null` if the field does not exist.\n */\n async hGet(key: string, field: string): Promise<string | null> {\n const hash = JSON.parse(this.store.get(key) ?? '{}')\n return hash[field] ?? null\n }\n\n /**\n * Pushes elements to the left (head) of a list.\n *\n * @param key - The list key.\n * @param values - One or more values to add.\n * @returns Resolves to the length of the list after the operation.\n */\n async lPush(key: string, values: string | string[]): Promise<number> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n const newValues = Array.isArray(values) ? values : [values]\n const updatedList = [...newValues.reverse(), ...list] // Prepend new values\n this.store.set(key, JSON.stringify(updatedList))\n return updatedList.length\n }\n\n /**\n * Pushes elements to the right (tail) of a list.\n *\n * @param key - The list key.\n * @param values - One or more values to add.\n * @returns Resolves to the length of the list after the operation.\n */\n async rPush(key: string, values: string | string[]): Promise<number> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n const newValues = Array.isArray(values) ? values : [values]\n const updatedList = [...list, ...newValues] // Append new values\n this.store.set(key, JSON.stringify(updatedList))\n return updatedList.length\n }\n\n /**\n * Removes and returns the first element from a list.\n *\n * @param key - The list key.\n * @returns Resolves to the removed element, or `null` if the list is empty.\n */\n async lPop(key: string): Promise<string | null> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n if (list.length === 0) return null\n const value = list.shift()\n if (list.length > 0) {\n this.store.set(key, JSON.stringify(list))\n } else {\n this.store.delete(key) // Remove key if empty\n }\n return value\n }\n\n /**\n * Removes and returns the last element from a list.\n *\n * @param key - The list key.\n * @returns Resolves to the removed element, or `null` if the list is empty.\n */\n async rPop(key: string): Promise<string | null> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n if (list.length === 0) return null\n const value = list.pop()\n if (list.length > 0) {\n this.store.set(key, JSON.stringify(list))\n } else {\n this.store.delete(key) // Remove key if empty\n }\n return value\n }\n\n /**\n * Retrieves a range of elements from a list.\n *\n * @param key - The list key.\n * @param start - The starting index.\n * @param stop - The stopping index.\n * @returns Resolves to an array containing the requested range.\n */\n async lRange(key: string, start: number, stop: number): Promise<string[]> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n const normalizedStop = stop === -1 ? list.length : stop + 1\n return list.slice(start, normalizedStop) // Extract range\n }\n\n /**\n * Adds elements to a set.\n *\n * @param key - The set key.\n * @param values - One or more values to add.\n * @returns Resolves to the number of new elements added.\n */\n async sAdd(key: string, values: string | string[]): Promise<number> {\n const set = new Set(JSON.parse(this.store.get(key) ?? '[]'))\n const newValues = Array.isArray(values) ? values : [values]\n const initialSize = set.size\n for (const value of newValues) {\n set.add(value)\n }\n this.store.set(key, JSON.stringify([...set]))\n return set.size - initialSize\n }\n\n /**\n * Removes elements from a set.\n *\n * @param key - The set key.\n * @param values - One or more values to remove.\n * @returns Resolves to the number of elements removed.\n */\n async sRem(key: string, values: string | string[]): Promise<number> {\n const set = new Set(JSON.parse(this.store.get(key) ?? '[]'))\n const valuesToRemove = Array.isArray(values) ? values : [values]\n const initialSize = set.size\n for (const value of valuesToRemove) {\n set.delete(value)\n }\n this.store.set(key, JSON.stringify([...set]))\n return initialSize - set.size\n }\n\n /**\n * Retrieves all elements from a set.\n *\n * @param key - The set key.\n * @returns Resolves to an array of all set members.\n */\n async sMembers(key: string): Promise<string[]> {\n return JSON.parse(this.store.get(key) ?? '[]')\n }\n\n /**\n * Adds members to a sorted set with scores.\n *\n * @param key - The sorted set key.\n * @param members - An array of objects containing `{ score, value }`.\n * @returns Resolves to the number of new elements added.\n */\n async zAdd(\n key: string,\n members: { score: number; value: string }[]\n ): Promise<number> {\n const sortedSet: { score: number; value: string }[] = JSON.parse(\n this.store.get(key) ?? '[]'\n )\n const initialSize = sortedSet.length\n for (const { score, value } of members) {\n const existingIndex = sortedSet.findIndex(\n (entry) => entry.value === value\n )\n if (existingIndex !== -1) {\n sortedSet[existingIndex].score = score\n } else {\n sortedSet.push({ score, value })\n }\n }\n sortedSet.sort((a, b) => a.score - b.score)\n this.store.set(key, JSON.stringify(sortedSet))\n return sortedSet.length - initialSize\n }\n\n /**\n * Retrieves a range of elements from a sorted set.\n *\n * @param key - The sorted set key.\n * @param start - The starting index.\n * @param stop - The stopping index.\n * @returns Resolves to an array of sorted set values in the range.\n */\n async zRange(key: string, start: number, stop: number): Promise<string[]> {\n const sortedSet: { score: number; value: string }[] = JSON.parse(\n this.store.get(key) ?? '[]'\n )\n const normalizedStop = stop === -1 ? sortedSet.length : stop + 1\n return sortedSet.slice(start, normalizedStop).map((entry) => entry.value)\n }\n\n /**\n * Removes elements from a sorted set.\n *\n * @param key - The sorted set key.\n * @param members - One or more values to remove.\n * @returns Resolves to the number of elements removed.\n */\n async zRem(key: string, members: string | string[]): Promise<number> {\n const sortedSet: { score: number; value: string }[] = JSON.parse(\n this.store.get(key) ?? '[]'\n )\n const valuesToRemove = Array.isArray(members) ? members : [members]\n const initialSize = sortedSet.length\n this.store.set(\n key,\n JSON.stringify(\n sortedSet.filter((entry) => !valuesToRemove.includes(entry.value))\n )\n )\n return initialSize - JSON.parse(this.store.get(key) ?? '[]').length\n }\n\n /**\n * Removes all keys from the store and clears all active expirations.\n *\n * @returns {Promise<'OK'>} Resolves to `'OK'` after all data is cleared.\n */\n async flushAll(): Promise<'OK'> {\n this.store.clear()\n for (const timeout of this.expirations.values()) {\n clearTimeout(timeout)\n }\n this.expirations.clear()\n this.expiryTimestamps.clear()\n return 'OK'\n }\n\n /**\n * Creates a new multi-command batch instance.\n * Commands queued in this batch will be executed together when `exec()` is called.\n *\n * @returns A new `IPersistorMulti` instance for batching commands.\n */\n multi(): IPersistorMulti {\n return new InMemoryMulti(this)\n }\n\n /**\n * Sets an expiration timeout for a key.\n * Cancels any existing expiration before setting a new one.\n *\n * @private\n * @param {string} key - The key to expire.\n * @param {number} ttlMs - Time-to-live in milliseconds.\n */\n private setExpiration(key: string, ttlMs: number) {\n // Clear existing timeout if any\n this.clearExpiration(key)\n\n // Store the absolute expiration timestamp\n const expiryTimestamp = Date.now() + ttlMs\n this.expiryTimestamps.set(key, expiryTimestamp)\n\n // Schedule deletion\n const timeout = setTimeout(() => {\n this.store.delete(key)\n this.expirations.delete(key)\n this.expiryTimestamps.delete(key)\n }, ttlMs)\n\n this.expirations.set(key, timeout)\n }\n\n /**\n * Cancels an active expiration timeout for a key and removes its TTL record.\n *\n * @private\n * @param {string} key - The key whose expiration should be cleared.\n */\n private clearExpiration(key: string) {\n if (this.expirations.has(key)) {\n clearTimeout(this.expirations.get(key))\n this.expirations.delete(key)\n this.expiryTimestamps.delete(key)\n }\n }\n}\n\n/**\n * Implements `IPersistorMulti` for `InMemoryPersistor`.\n */\nclass InMemoryMulti implements IPersistorMulti {\n private readonly persistor: IPersistor\n private readonly commands: Set<() => Promise<MultiExecReturnTypes>> =\n new Set()\n\n constructor(persistor: IPersistor) {\n this.persistor = persistor\n }\n\n /**\n * Queues a `SET` command to store a key-value pair with optional expiration settings.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param value - The string value to store.\n * @param options - Optional expiration settings.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n set(key: string, value: string, options?: SetOptions): IPersistorMulti {\n this.commands.add(() => this.persistor.set(key, value, options))\n return this\n }\n\n /**\n * Queues a `SETEX` command to store a key-value pair with an expiration time in seconds.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param seconds - Expiration time in seconds.\n * @param value - The string value to store.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n setEx(key: string, seconds: number, value: string): IPersistorMulti {\n this.commands.add(() => this.persistor.setEx(key, seconds, value))\n return this\n }\n\n /**\n * Queues a `PSETEX` command to store a key-value pair with an expiration time in milliseconds.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param milliseconds - Expiration time in milliseconds.\n * @param value - The string value to store.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n pSetEx(key: string, milliseconds: number, value: string): IPersistorMulti {\n this.commands.add(() => this.persistor.pSetEx(key, milliseconds, value))\n return this\n }\n\n /**\n * Queues a `SETNX` command to store a key-value pair **only if the key does not already exist**.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param value - The string value to store.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n setNX(key: string, value: string): IPersistorMulti {\n this.commands.add(() => this.persistor.setNX(key, value))\n return this\n }\n\n /**\n * Queues a `GET` command to retrieve the value associated with a key.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key to retrieve.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n get(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.get(key))\n return this\n }\n\n /**\n * Queues a `DEL` command to delete a key from the store.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key to delete.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n del(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.del(key))\n return this\n }\n\n /**\n * Queues an `EXPIRE` command to set a time-to-live (TTL) in seconds for a key.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param seconds - TTL in seconds.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n expire(key: string, seconds: number): IPersistorMulti {\n this.commands.add(() => this.persistor.expire(key, seconds))\n return this\n }\n\n /**\n * Queues a `TTL` command to get the remaining time-to-live (TTL) of a key in seconds.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key to check.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n ttl(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.ttl(key))\n return this\n }\n\n /**\n * Queues an `exists` operation in the batch.\n * @param key - The key(s) to check existence.\n * @returns The multi instance for method chaining.\n */\n exists(key: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.exists(key))\n return this\n }\n\n /**\n * Queues an `incr` operation in the batch.\n * @param key - The key to increment.\n * @returns The multi instance for method chaining.\n */\n incr(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.incr(key))\n return this\n }\n\n /**\n * Queues an `incrBy` operation in the batch.\n * @param key - The key to increment.\n * @param increment - The amount to increment by.\n * @returns The multi instance for method chaining.\n */\n incrBy(key: string, increment: number): IPersistorMulti {\n this.commands.add(() => this.persistor.incrBy(key, increment))\n return this\n }\n\n /**\n * Queues a `decr` operation in the batch.\n * @param key - The key to decrement.\n * @returns The multi instance for method chaining.\n */\n decr(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.decr(key))\n return this\n }\n\n /**\n * Queues a `decrBy` operation in the batch.\n * @param key - The key to decrement.\n * @param decrement - The amount to decrement by.\n * @returns The multi instance for method chaining.\n */\n decrBy(key: string, decrement: number): IPersistorMulti {\n this.commands.add(() => this.persistor.decrBy(key, decrement))\n return this\n }\n\n /**\n * Queues a `flushAll` operation in the batch.\n * @returns The multi instance for method chaining.\n */\n flushAll(): IPersistorMulti {\n this.commands.add(() => this.persistor.flushAll())\n return this\n }\n\n /**\n * Queues an `hSet` command to store a field-value pair in a hash.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The hash key.\n * @param field - The field name.\n * @param value - The value to store.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n hSet(key: string, field: string, value: string): IPersistorMulti {\n this.commands.add(() => this.persistor.hSet(key, field, value))\n return this\n }\n\n /**\n * Queues an `hGet` command to retrieve a field value from a hash.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The hash key.\n * @param field - The field to retrieve.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n hGet(key: string, field: string): IPersistorMulti {\n this.commands.add(() => this.persistor.hGet(key, field))\n return this\n }\n\n /**\n * Queues an `lPush` command to add elements to the left (head) of a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @param values - The values to add.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n lPush(key: string, values: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.lPush(key, values))\n return this\n }\n\n /**\n * Queues an `rPush` command to add elements to the right (tail) of a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @param values - The values to add.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n rPush(key: string, values: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.rPush(key, values))\n return this\n }\n\n /**\n * Queues an `lPop` command to remove and return the first element of a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n lPop(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.lPop(key))\n return this\n }\n\n /**\n * Queues an `rPop` command to remove and return the last element of a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n rPop(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.rPop(key))\n return this\n }\n\n /**\n * Queues an `lRange` command to retrieve a range of elements from a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n lRange(key: string, start: number, stop: number): IPersistorMulti {\n this.commands.add(() => this.persistor.lRange(key, start, stop))\n return this\n }\n\n /**\n * Queues an `sAdd` command to add elements to a set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The set key.\n * @param values - The values to add.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n sAdd(key: string, values: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.sAdd(key, values))\n return this\n }\n\n /**\n * Queues an `sRem` command to remove elements from a set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The set key.\n * @param values - The values to remove.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n sRem(key: string, values: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.sRem(key, values))\n return this\n }\n\n /**\n * Queues an `sMembers` command to retrieve all members of a set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The set key.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n sMembers(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.sMembers(key))\n return this\n }\n\n /**\n * Queues a `zAdd` command to add elements to a sorted set with scores.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The sorted set key.\n * @param members - An array of objects with `score` and `value`.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zAdd(\n key: string,\n members: { score: number; value: string }[]\n ): IPersistorMulti {\n this.commands.add(() => this.persistor.zAdd(key, members))\n return this\n }\n\n /**\n * Queues a `zRange` command to retrieve a range of elements from a sorted set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The sorted set key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRange(key: string, start: number, stop: number): IPersistorMulti {\n this.commands.add(() => this.persistor.zRange(key, start, stop))\n return this\n }\n\n /**\n * Queues a `zRem` command to remove elements from a sorted set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The sorted set key.\n * @param members - The members to remove.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRem(key: string, members: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.zRem(key, members))\n return this\n }\n\n /**\n * Executes multiple commands in a batch operation.\n * Each command is executed in sequence, and results are collected in an array.\n *\n * @returns Resolves to an array containing the results of each queued command.\n */\n async exec(): Promise<MultiExecReturnTypes[]> {\n return Promise.all([...this.commands].map((cmd) => cmd()))\n }\n}\n","export class LocalStorage {\n client = new Map()\n public isReady = false\n\n get(key: string) {\n return this.client.get(key)\n }\n\n set(key: string, value: string, options?: { PX: number }) {\n this.client.set(key, value)\n\n if (options?.PX) {\n setTimeout(() => {\n this.client.delete(key)\n }, options.PX)\n }\n }\n\n del(key: string) {\n this.client.delete(key)\n }\n\n clear() {\n this.client.clear()\n }\n\n async DBSIZE(): Promise<number> {\n return Promise.resolve(this.client.size)\n }\n\n // This is just for testing\n on(event: string, callback: (message: string) => void) {\n if (event === 'ready' && callback) {\n this.isReady = true\n callback('ready')\n }\n\n return this\n }\n\n connect(): Promise<this> {\n return Promise.resolve(this)\n }\n}\n\nconst localStorage = new LocalStorage()\n\nexport const createLocalMemoryClient = () => {\n return localStorage\n}\n","import type { UUID } from 'node:crypto'\nimport { getLogger } from '@sebspark/otel'\nimport { createClient, type RedisClientOptions } from 'redis'\nimport superjson from 'superjson'\nimport { createLocalMemoryClient } from './localMemory'\n\nlet CACHE_CLIENT = createClient\nconst isTestRunning = process.env.NODE_ENV === 'test'\n\ntype GetType<T> = {\n value: T\n ttl?: number\n timestamp: number\n}\n\ntype SetParams<T> = {\n value: T\n timestamp?: number\n ttl?: number\n}\n\nexport type PersistorConstructorType = {\n redis?: RedisClientOptions\n redisClient?: ReturnType<typeof createClient>\n clientId?: UUID\n onError?: (error: string) => void\n onSuccess?: () => void\n}\n\nfunction toMillis(seconds: number) {\n return seconds * 1000\n}\n\nexport class Persistor {\n public client: ReturnType<typeof createClient> | null = null\n private readonly clientId?: UUID\n private readonly onError\n private readonly onSuccess\n private readonly logger: ReturnType<typeof getLogger>\n private readonly redis?: RedisClientOptions\n\n constructor({\n redis,\n redisClient,\n clientId,\n onSuccess,\n onError,\n }: PersistorConstructorType) {\n this.logger = getLogger('Persistor')\n this.logger.warn(\n 'Persistor class is deprecated. Use InMemoryPersistor or redis: createClient instead'\n )\n\n this.onError = onError || (() => {})\n this.onSuccess = onSuccess || (() => {})\n this.clientId = clientId\n\n if (redisClient) {\n this.client = redisClient\n } else if (redis && !isTestRunning) {\n this.redis = redis\n } else {\n //@ts-expect-error\n CACHE_CLIENT = createLocalMemoryClient\n }\n\n if (!this.client || !this.client.isReady) {\n this.startConnection()\n }\n }\n\n public async startConnection() {\n try {\n await new Promise((resolve, reject) => {\n this.client = CACHE_CLIENT({\n url: this.redis?.url,\n username: this.redis?.username,\n password: this.redis?.password,\n pingInterval: this.redis?.pingInterval || undefined,\n socket: {\n ...this.redis?.socket,\n reconnectStrategy: (retries, cause) => {\n this.logger.error(cause)\n return 1000 * 2 ** retries\n },\n },\n })\n .on('error', (err) => {\n this.onError(err)\n reject(err)\n })\n .on('ready', () => {\n this.onSuccess()\n resolve(true)\n })\n .on('reconnecting', () => {\n this.logger.info(`reconnecting... ${this.clientId}`)\n })\n .on('end', () => {\n this.logger.info(`end... ${this.clientId}`)\n })\n\n this.client.connect()\n })\n } catch (err) {\n this.onError(`${err}`)\n this.logger.error(err as Error)\n }\n }\n\n public async size(): Promise<number> {\n if (!this.client) {\n throw new Error('Client not initialized')\n }\n return await this.client.DBSIZE()\n }\n\n public getClientId(): UUID | undefined {\n return this.clientId\n }\n\n public getIsClientConnected(): boolean {\n return !!this.client?.isReady\n }\n\n private createOptions(ttl?: number): { EX: number } | object {\n if (ttl !== null && ttl !== undefined && ttl > 0) {\n return { PX: Math.round(toMillis(ttl)) } // Return options object with Expiration time property in ms as an integer\n }\n return {} // Return empty object when ttl is null or undefined\n }\n\n /**\n * Set a value in the cache.\n * @param key Cache key.\n * @param object.value Value to set in the cache.\n * @param object.ttl Time to live in seconds.\n * @param object.timestamp Timestamp\n */\n public async set<T>(\n key: string,\n { value, timestamp = Date.now(), ttl }: SetParams<T>\n ): Promise<void> {\n if (!this.client || !this.client.isReady) {\n this.logger.error('Client not ready')\n return\n }\n try {\n const serializedData = superjson.stringify({\n value,\n ttl,\n timestamp,\n })\n const options = this.createOptions(ttl)\n await this.client.set(key, serializedData, options)\n } catch (error) {\n this.logger.error('Error setting data in redis', error as Error)\n throw new Error(`Error setting data in redis: ${error}`)\n }\n }\n\n /**\n * Get a value from the cache.\n * @param key Cache key.\n * @returns GetType<T> value\n */\n public async get<T>(key: string): Promise<GetType<T> | null> {\n if (!this.client) {\n this.logger.error('Client not ready')\n return null\n }\n try {\n const data = await this.client.get(key)\n if (!data) {\n return null\n }\n\n return superjson.parse(data) as GetType<T>\n } catch (error) {\n this.logger.error(`Error getting data in redis: ${error}`)\n throw new Error(`Error getting data from redis: ${error}`)\n }\n }\n\n /**\n * Delete a value from the cache.\n * @param key Cache key\n */\n public async delete(key: string): Promise<void> {\n if (!this.client || !this.client.isReady) {\n this.logger.error('Client not ready')\n return\n }\n try {\n await this.client.del(key)\n } catch (error) {\n this.logger.error(`Error deleting data from redis: ${error}`)\n throw new Error(`Error deleting data from redis: ${error}`)\n }\n }\n}\n","import type { UUID } from 'node:crypto'\nimport { randomUUID } from 'node:crypto'\nimport { getLogger } from '@sebspark/otel'\nimport type { RedisClientOptions } from 'redis'\nimport { Persistor } from './persistor'\n\nexport type { RedisClientOptions }\n\nexport type PromiseCacheOptions = {\n ttlInSeconds?: number\n caseSensitive?: boolean\n redis?: RedisClientOptions\n fallbackToFunction?: boolean\n onError?: (error: string) => void\n onSuccess?: () => void\n}\n\nconst persistors: Record<string, Persistor> = {}\n\nconst getPersistor = ({\n redis,\n onError,\n onSuccess,\n clientId,\n}: PromiseCacheOptions & { clientId: UUID }) => {\n const logger = getLogger('PromiseCache persistor')\n\n const connectionName = redis ? redis?.name || 'default' : 'local'\n\n if (!persistors[connectionName]) {\n persistors[connectionName] = new Persistor({\n redis,\n onError: (error: string) => {\n onError?.(error)\n logger?.error(\n `❌ REDIS | Client Error | ${connectionName} | ${redis?.url}: ${error}`\n )\n },\n onSuccess: () => {\n onSuccess?.()\n logger?.info(\n `📦 REDIS | Connection Ready | ${connectionName} | ${redis?.url}`\n )\n },\n clientId,\n })\n }\n return persistors[connectionName]\n}\n\nexport class PromiseCache<U> {\n public persistor: Persistor\n private readonly clientId: UUID = randomUUID()\n private readonly caseSensitive: boolean\n private readonly fallbackToFunction: boolean // If true, the cache will fallback to the delegate function if there is an error retrieving the cache.\n private readonly ttl?: number // Time to live in milliseconds.\n private readonly logger: ReturnType<typeof getLogger>\n /**\n * Initialize a new PromiseCache.\n * @param ttlInSeconds Default cache TTL.\n * @param caseSensitive Set to true if you want to differentiate between keys with different casing.\n */\n constructor({\n ttlInSeconds,\n caseSensitive = false,\n redis,\n fallbackToFunction = false,\n onSuccess,\n onError,\n }: PromiseCacheOptions) {\n this.logger = getLogger('PromiseCache')\n this.logger.warn(\n 'PromiseCache class is deprecated. Use createCache instead'\n )\n\n this.persistor = getPersistor({\n redis,\n onError,\n onSuccess,\n clientId: this.clientId,\n })\n\n this.caseSensitive = caseSensitive\n this.fallbackToFunction = fallbackToFunction\n\n if (ttlInSeconds) {\n this.ttl = ttlInSeconds // Conversion to milliseconds is done in the persistor.\n }\n }\n\n /**\n * Cache size.\n * @returns The number of entries in the cache.\n */\n async size(): Promise<number> {\n return await this.persistor.size()\n }\n\n /**\n * Override a value in the cache.\n * @param key Cache key.\n * @param value Cache value.\n * @param ttlInSeconds Time to live in seconds.\n */\n async override<U>(\n key: string,\n value: U,\n ttlInSeconds?: number\n ): Promise<void> {\n // Normalize the key if case insensitive.\n const effectiveKey = this.caseSensitive ? key : key.toLowerCase()\n\n // Determine the TTL and unique cache key for this specific call.\n const effectiveTTL = ttlInSeconds !== undefined ? ttlInSeconds : this.ttl\n\n await this.persistor.set(effectiveKey, {\n value,\n timestamp: Date.now(),\n ttl: effectiveTTL,\n })\n }\n\n /**\n * Get a value from the cache.\n * @param key Cache key.\n */\n async find<U>(key: string): Promise<U | null> {\n const result = await this.persistor.get<U>(key)\n return result?.value ?? null\n }\n\n /**\n * A simple promise cache wrapper.\n * @param key Cache key.\n * @param delegate The function to execute if the key is not in the cache.\n * @param ttlInSeconds Time to live in seconds.\n * @param ttlKeyInSeconds The key in the response object that contains the TTL.\n * @returns The result of the delegate function.\n */\n async wrap(\n key: string,\n delegate: () => Promise<U>,\n ttlInSeconds?: number,\n ttlKeyInSeconds?: string\n ): Promise<U> {\n const now = Date.now()\n\n // Normalize the key if case insensitive.\n const effectiveKey = this.caseSensitive ? key : key.toLowerCase()\n\n // Determine the TTL and unique cache key for this specific call.\n let effectiveTTL = ttlInSeconds ?? this.ttl\n\n try {\n const cached = await this.persistor.get<U>(effectiveKey)\n\n if (cached) {\n if (!ttlKeyInSeconds && cached.ttl !== effectiveTTL) {\n this.logger?.error(\n 'WARNING: TTL mismatch for key. It is recommended to use the same TTL for the same key.'\n )\n }\n\n return cached.value\n }\n } catch (err) {\n const error = err as Error\n if (!this.fallbackToFunction) {\n throw error\n }\n\n this.logger?.error(\n 'redis error, falling back to function execution',\n error as Error\n )\n }\n\n // Execute the delegate, cache the response with the current timestamp, and return it.\n const response = await delegate()\n\n // Get the TTL from the response if a TTL key is provided.\n if (ttlKeyInSeconds) {\n const responseDict = response as Record<string, unknown>\n const responseTTL = Number(responseDict[ttlKeyInSeconds] as string)\n effectiveTTL = responseTTL || effectiveTTL // Fall back to the default TTL if the TTL key is not found.\n }\n\n try {\n await this.persistor.set(effectiveKey, {\n value: response,\n timestamp: now,\n ttl: effectiveTTL,\n })\n } catch (err) {\n const error = err as Error\n console.error('failed to cache result', error.message)\n }\n\n return response\n }\n}\n","import { add, sub } from 'date-fns'\n\nexport { add, sub }\n\nexport const SECOND = 1000\nexport const MINUTE = 60 * SECOND\nexport const HOUR = 60 * MINUTE\nexport const DAY = 24 * HOUR\nexport const WEEK = 7 * DAY\n\nexport const seconds = (num: number) => num * SECOND\nexport const minutes = (num: number) => num * MINUTE\nexport const hours = (num: number) => num * HOUR\nexport const days = (num: number) => num * DAY\nexport const weeks = (num: number) => num * WEEK\n\nexport const today = (hours = 0, minutes = 0, seconds = 0) => {\n const local = new Date()\n const utc = Date.UTC(\n local.getUTCFullYear(),\n local.getUTCMonth(),\n local.getUTCDate(),\n hours,\n minutes,\n seconds\n )\n return new Date(utc)\n}\n\nexport const tomorrow = (hours = 0, minutes = 0, seconds = 0) =>\n add(today(hours, minutes, seconds), { days: 1 })\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["options: SetOptions","seconds","key","sortedSet: { score: number; value: string }[]","seconds","persistors: Record<string, Persistor>","hours","minutes","seconds"],"sources":["../src/serializer.ts","../src/setOptions.ts","../src/cache.ts","../src/inMemoryPersistor.ts","../src/localMemory.ts","../src/persistor.ts","../src/promiseCache.ts","../src/time.ts"],"sourcesContent":["import superjson from 'superjson'\n\nexport const serialize = <T>(data: T): string => {\n return superjson.stringify(data)\n}\n\nexport const deserialize = <T>(serialized: string | null): T | null => {\n if (serialized === undefined || serialized === null) return serialized\n\n return superjson.parse<T>(serialized)\n}\n","import type { SetOptions } from 'redis'\nimport type { Expiry } from './types'\n\n/**\n * Converts an Expiry value into Redis SetOptions.\n * @param {Expiry | undefined} expiry - The expiration time, either as a TTL in milliseconds or an exact Date.\n * @returns {SetOptions | undefined} Redis-compatible options, or undefined if no expiry.\n */\nexport const toSetOptions = (\n expiry: Expiry | undefined\n): SetOptions | undefined => {\n const options: SetOptions = {}\n\n // Expiry has a value\n if (expiry !== undefined) {\n if (typeof expiry === 'number') {\n options.PX = expiry // Store TTL in milliseconds\n } else if (expiry instanceof Date && !Number.isNaN(expiry.getTime())) {\n const timestamp = expiry.getTime()\n if (timestamp > Date.now()) {\n options.PXAT = timestamp // Use exact expiration time in milliseconds\n } else {\n options.PX = 1 // Past timestamps are invalid - expire immediately\n }\n }\n }\n\n // If expiry does not have a value, fall back to 1 sec\n if (!options.PX && !options.PXAT) {\n options.EX = 1\n }\n\n return options\n}\n","import { deserialize, serialize } from './serializer'\nimport { toSetOptions } from './setOptions'\nimport type { Cache, CachingOptions, IPersistor } from './types'\n\n/**\n * Creates a cache instance using a given persistor.\n * @param {IPersistor} persistor - The underlying storage for caching.\n * @param {string?} prefix - An optional prefix that will be prepended to the key, formatted as `prefix:key`.\n * @returns {Cache} A cache instance.\n */\nexport const createCache = (persistor: IPersistor, prefix?: string): Cache => {\n // Tracks in-progress requests to prevent duplicate calls\n const pendingPromises = new Map<string, Promise<unknown>>()\n\n const cache: Cache = {\n persistor,\n wrap: <A extends unknown[], R>(\n delegate: (...args: A) => Promise<R>,\n options: CachingOptions<A, R>\n ): ((...args: A) => Promise<R>) => {\n return async (...args: A): Promise<R> => {\n // Compute key\n let key =\n typeof options.key === 'string' ? options.key : options.key(...args)\n\n // Apply prefix if provided\n if (prefix) {\n key = `${prefix}:${key}`\n }\n\n // Return the pending request if one exists\n if (pendingPromises.has(key)) {\n return pendingPromises.get(key) as R\n }\n\n // Create a new promise to prevent duplicate processing\n const resultPromise = (async () => {\n try {\n // Ensure persistor is connected and ready\n await ensurePersistorIsReady(persistor)\n\n // Check cache\n const cached = deserialize<R>(await persistor.get(key))\n if (cached !== null) {\n return cached\n }\n\n // No cached value\n const result = await delegate(...args)\n\n // Calculate expiry\n const expiry =\n typeof options.expiry === 'function'\n ? options.expiry(args, result)\n : options.expiry\n\n // Ensure persistor is still connected and ready\n await ensurePersistorIsReady(persistor)\n\n // Save to cache\n const serialized = serialize(result)\n const setOptions = toSetOptions(expiry)\n await persistor.set(key, serialized, setOptions)\n\n // Return result\n return result\n } finally {\n pendingPromises.delete(key)\n }\n })()\n\n // Store promise until it resolves or fails\n pendingPromises.set(key, resultPromise)\n\n return resultPromise\n }\n },\n }\n return cache\n}\n\nconst ensurePersistorIsReady = async (persistor: IPersistor) => {\n // Persistor is connected and ready\n if (persistor.isReady) {\n return\n }\n\n // Persistor is connecting but not ready\n if (persistor.isOpen) {\n await new Promise<void>((resolve) => {\n if (persistor.isReady) return resolve()\n persistor.once('ready', resolve)\n return\n })\n }\n\n // Persistor should connect\n try {\n await persistor.connect()\n } catch (err) {\n if ((err as Error).message === 'Socket already opened') {\n // Connection is already in progress\n await new Promise<void>((resolve) => {\n if (persistor.isReady) return resolve()\n persistor.once('ready', resolve)\n })\n }\n }\n}\n","import type { SetOptions } from 'redis'\nimport type {\n HashTypes,\n HashValue,\n IPersistor,\n IPersistorMulti,\n MultiExecReturnTypes,\n} from './types'\n\n/**\n * An in-memory key-value store with Redis-like behavior.\n * Supports basic operations like `set`, `get`, `del`, `expire`, `ttl`, and `flushAll`.\n * Implements expiration using `setTimeout` for automatic key deletion.\n */\nexport class InMemoryPersistor implements IPersistor {\n /**\n * Internal key-value store for caching string values.\n * @private\n */\n private readonly store: Map<string, string>\n\n /**\n * Tracks active timeouts for expiring keys.\n * Each key maps to a `setTimeout` reference that deletes the key when triggered.\n * @private\n */\n private readonly expirations: Map<string, NodeJS.Timeout>\n\n /**\n * Stores absolute expiration timestamps (in milliseconds since epoch) for each key.\n * Used to compute remaining TTL.\n * @private\n */\n private readonly expiryTimestamps: Map<string, number>\n\n /**\n * Creates a new instance of `InMemoryPersistor`.\n * Initializes an empty store, expiration map, and TTL tracker.\n */\n constructor() {\n this.store = new Map()\n this.expirations = new Map()\n this.expiryTimestamps = new Map()\n }\n\n async connect() {\n return this\n }\n\n get isReady(): boolean {\n return true\n }\n\n get isOpen(): boolean {\n return true\n }\n\n once() {\n return this\n }\n\n /**\n * Stores a key-value pair with optional expiration settings.\n * If an expiration is provided (`EX`, `PX`, `EXAT`, `PXAT`), the key is automatically removed when TTL expires.\n *\n * @param {string} key - The key to store.\n * @param {string} value - The string value to associate with the key.\n * @param {SetOptions} [options] - Optional Redis-style expiration settings.\n * @returns {Promise<'OK' | null>} Resolves to `'OK'` on success, or `null` if a conditional set (`NX`) fails.\n */\n async set(\n key: string,\n value: HashTypes,\n options?: SetOptions\n ): Promise<'OK' | null> {\n if (options?.NX && this.store.has(key)) {\n return null // NX means \"only set if key does not exist\"\n }\n if (options?.XX && !this.store.has(key)) {\n return null // XX means \"only set if key exists\"\n }\n\n this.store.set(key, String(value))\n\n // Handle TTL (Expiration)\n if (options?.EX !== undefined) {\n this.setExpiration(key, options.EX * 1000) // Convert seconds to ms\n } else if (options?.PX !== undefined) {\n this.setExpiration(key, options.PX) // Milliseconds\n } else if (options?.EXAT !== undefined) {\n const timeToExpire = options.EXAT * 1000 - Date.now()\n this.setExpiration(key, Math.max(0, timeToExpire))\n } else if (options?.PXAT !== undefined) {\n const timeToExpire = options.PXAT - Date.now()\n this.setExpiration(key, Math.max(0, timeToExpire))\n }\n\n return 'OK'\n }\n\n /**\n * Stores a key-value pair with an expiration time in seconds.\n * If the key already exists, it will be overwritten.\n *\n * @param key - The storage key.\n * @param seconds - Expiration time in seconds.\n * @param value - The string value to store.\n * @returns Resolves to `'OK'` on success.\n */\n async setEx(\n key: string,\n seconds: number,\n value: string\n ): Promise<string | null> {\n this.store.set(key, value)\n await this.expire(key, seconds)\n return 'OK'\n }\n\n /**\n * Stores a key-value pair with an expiration time in milliseconds.\n * If the key already exists, it will be overwritten.\n *\n * @param key - The storage key.\n * @param milliseconds - Expiration time in milliseconds.\n * @param value - The string value to store.\n * @returns Resolves to `'OK'` on success.\n */\n async pSetEx(\n key: string,\n milliseconds: number,\n value: string\n ): Promise<string | null> {\n return this.setEx(key, milliseconds / 1000, value)\n }\n\n /**\n * Stores a key-value pair **only if the key does not already exist**.\n * If the key exists, the operation fails and returns `false`.\n *\n * @param key - The storage key.\n * @param value - The string value to store.\n * @returns Resolves to `true` if the key was set, or `false` if the key already exists.\n */\n async setNX(key: string, value: string): Promise<number> {\n if (this.store.has(key)) return 0\n this.store.set(key, value)\n return 1\n }\n\n /**\n * Retrieves the value associated with a key.\n *\n * @param {string} key - The key to retrieve.\n * @returns {Promise<string | null>} Resolves to the string value, or `null` if the key does not exist.\n */\n async get(key: string): Promise<string | null> {\n return this.store.get(key) ?? null\n }\n\n /**\n * Deletes a key from the store.\n * If the key exists, it is removed along with any associated expiration.\n *\n * @param {string} key - The key to delete.\n * @returns {Promise<number>} Resolves to `1` if the key was deleted, or `0` if the key did not exist.\n */\n async del(key: string): Promise<number> {\n const existed = this.store.has(key)\n if (existed) {\n this.store.delete(key)\n this.clearExpiration(key)\n }\n return existed ? 1 : 0\n }\n\n /**\n * Sets a time-to-live (TTL) in seconds for a key.\n * If the key exists, it will be deleted after the specified duration.\n *\n * @param {string} key - The key to set an expiration on.\n * @param {number} seconds - The TTL in seconds.\n * @returns {Promise<number>} Resolves to `1` if the TTL was set, or `0` if the key does not exist.\n */\n async expire(key: string, seconds: number): Promise<number> {\n if (!this.store.has(key)) return 0\n this.setExpiration(key, seconds * 1000) // Convert seconds to ms\n return 1\n }\n\n /**\n * Retrieves the remaining time-to-live (TTL) of a key in seconds.\n *\n * @param {string} key - The key to check.\n * @returns {Promise<number>} Resolves to:\n * - Remaining TTL in **seconds** if the key exists and has an expiration.\n * - `-1` if the key exists but has no expiration.\n * - `-2` if the key does not exist.\n */\n async ttl(key: string): Promise<number> {\n if (!this.store.has(key)) return -2 // Key does not exist\n if (!this.expiryTimestamps.has(key)) return -1 // No TTL set\n\n const timeLeft = (this.expiryTimestamps.get(key) as number) - Date.now()\n return timeLeft > 0 ? Math.ceil(timeLeft / 1000) : -2 // Return in seconds\n }\n\n /**\n * Checks if one or more keys exist in the store.\n *\n * @param {string | string[]} keys - A single key or an array of keys to check.\n * @returns {Promise<number>} Resolves to the number of keys that exist.\n */\n async exists(keys: string | string[]): Promise<number> {\n const keyArray = Array.isArray(keys) ? keys : [keys]\n return keyArray.reduce(\n (count, key) => (this.store.has(key) ? count + 1 : count),\n 0\n )\n }\n\n /**\n * Increments a numeric value stored at a key by 1.\n * If the key does not exist, it is set to `1`.\n *\n * @param {string} key - The key to increment.\n * @returns {Promise<number>} Resolves to the new value after increment.\n */\n async incr(key: string): Promise<number> {\n const current = Number(this.store.get(key)) || 0\n const newValue = current + 1\n this.store.set(key, newValue.toString())\n return newValue\n }\n\n /**\n * Increments a numeric value stored at a key by a specified amount.\n * If the key does not exist, it is set to the increment value.\n *\n * @param {string} key - The key to increment.\n * @param {number} increment - The amount to increase by.\n * @returns {Promise<number>} Resolves to the new value after increment.\n */\n async incrBy(key: string, increment: number): Promise<number> {\n const current = Number(this.store.get(key)) || 0\n const newValue = current + increment\n this.store.set(key, newValue.toString())\n return newValue\n }\n\n /**\n * Decrements a numeric value stored at a key by 1.\n * If the key does not exist, it is set to `-1`.\n *\n * @param {string} key - The key to decrement.\n * @returns {Promise<number>} Resolves to the new value after decrement.\n */\n async decr(key: string): Promise<number> {\n const current = Number(this.store.get(key)) || 0\n const newValue = current - 1\n this.store.set(key, newValue.toString())\n return newValue\n }\n\n /**\n * Decrements a numeric value stored at a key by a specified amount.\n * If the key does not exist, it is set to the negative decrement value.\n *\n * @param {string} key - The key to decrement.\n * @param {number} decrement - The amount to decrease by.\n * @returns {Promise<number>} Resolves to the new value after decrement.\n */\n async decrBy(key: string, decrement: number): Promise<number> {\n const current = Number(this.store.get(key)) || 0\n const newValue = current - decrement\n this.store.set(key, newValue.toString())\n return newValue\n }\n\n /**\n * Sets a field in a hash.\n * If the field already exists, its value is updated.\n *\n * @param key - The hash key.\n * @param field - The field name.\n * @param value - The value to store.\n * @returns Resolves to `1` if a new field was added, `0` if an existing field was updated.\n */\n async hSet(\n key: string,\n fieldOrValue: string | HashValue,\n value?: HashTypes\n ): Promise<number> {\n const existingHash = JSON.parse(this.store.get(key) ?? '{}')\n let newFields = 0\n const hashValue =\n value !== undefined\n ? { [fieldOrValue as string]: value }\n : (fieldOrValue as HashValue)\n\n for (const [key, val] of Object.entries(hashValue)) {\n if (!Object.hasOwn(existingHash, key)) {\n newFields++\n }\n existingHash[key] = String(val)\n }\n this.store.set(key, JSON.stringify(existingHash))\n return newFields\n }\n\n /**\n * Retrieves a field from a hash.\n *\n * @param key - The hash key.\n * @param field - The field name to retrieve.\n * @returns Resolves to the field value, or `null` if the field does not exist.\n */\n async hGet(key: string, field: string): Promise<string | null> {\n const hash = JSON.parse(this.store.get(key) ?? '{}')\n return hash[field] ?? null\n }\n\n /**\n * Retrieves a hash value.\n * @param key - The hash key.\n * @returns Resolves to the value, or null if the hash does not exist.\n */\n async hGetAll(key: string): Promise<{ [x: string]: string }> {\n return JSON.parse(this.store.get(key) ?? '{}')\n }\n\n /**\n * Pushes elements to the left (head) of a list.\n *\n * @param key - The list key.\n * @param values - One or more values to add.\n * @returns Resolves to the length of the list after the operation.\n */\n async lPush(key: string, values: string | string[]): Promise<number> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n const newValues = Array.isArray(values) ? values : [values]\n const updatedList = [...newValues.reverse(), ...list] // Prepend new values\n this.store.set(key, JSON.stringify(updatedList))\n return updatedList.length\n }\n\n /**\n * Pushes elements to the right (tail) of a list.\n *\n * @param key - The list key.\n * @param values - One or more values to add.\n * @returns Resolves to the length of the list after the operation.\n */\n async rPush(key: string, values: string | string[]): Promise<number> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n const newValues = Array.isArray(values) ? values : [values]\n const updatedList = [...list, ...newValues] // Append new values\n this.store.set(key, JSON.stringify(updatedList))\n return updatedList.length\n }\n\n /**\n * Removes and returns the first element from a list.\n *\n * @param key - The list key.\n * @returns Resolves to the removed element, or `null` if the list is empty.\n */\n async lPop(key: string): Promise<string | null> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n if (list.length === 0) return null\n const value = list.shift()\n if (list.length > 0) {\n this.store.set(key, JSON.stringify(list))\n } else {\n this.store.delete(key) // Remove key if empty\n }\n return value\n }\n\n /**\n * Removes and returns the last element from a list.\n *\n * @param key - The list key.\n * @returns Resolves to the removed element, or `null` if the list is empty.\n */\n async rPop(key: string): Promise<string | null> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n if (list.length === 0) return null\n const value = list.pop()\n if (list.length > 0) {\n this.store.set(key, JSON.stringify(list))\n } else {\n this.store.delete(key) // Remove key if empty\n }\n return value\n }\n\n /**\n * Retrieves a range of elements from a list.\n *\n * @param key - The list key.\n * @param start - The starting index.\n * @param stop - The stopping index.\n * @returns Resolves to an array containing the requested range.\n */\n async lRange(key: string, start: number, stop: number): Promise<string[]> {\n const list = JSON.parse(this.store.get(key) ?? '[]')\n const normalizedStop = stop === -1 ? list.length : stop + 1\n return list.slice(start, normalizedStop) // Extract range\n }\n\n /**\n * Adds elements to a set.\n *\n * @param key - The set key.\n * @param values - One or more values to add.\n * @returns Resolves to the number of new elements added.\n */\n async sAdd(key: string, values: string | string[]): Promise<number> {\n const set = new Set(JSON.parse(this.store.get(key) ?? '[]'))\n const newValues = Array.isArray(values) ? values : [values]\n const initialSize = set.size\n for (const value of newValues) {\n set.add(value)\n }\n this.store.set(key, JSON.stringify([...set]))\n return set.size - initialSize\n }\n\n /**\n * Removes elements from a set.\n *\n * @param key - The set key.\n * @param values - One or more values to remove.\n * @returns Resolves to the number of elements removed.\n */\n async sRem(key: string, values: string | string[]): Promise<number> {\n const set = new Set(JSON.parse(this.store.get(key) ?? '[]'))\n const valuesToRemove = Array.isArray(values) ? values : [values]\n const initialSize = set.size\n for (const value of valuesToRemove) {\n set.delete(value)\n }\n this.store.set(key, JSON.stringify([...set]))\n return initialSize - set.size\n }\n\n /**\n * Retrieves all elements from a set.\n *\n * @param key - The set key.\n * @returns Resolves to an array of all set members.\n */\n async sMembers(key: string): Promise<string[]> {\n return JSON.parse(this.store.get(key) ?? '[]')\n }\n\n /**\n * Adds members to a sorted set with scores.\n *\n * @param key - The sorted set key.\n * @param members - An array of objects containing `{ score, value }`.\n * @returns Resolves to the number of new elements added.\n */\n async zAdd(\n key: string,\n members: { score: number; value: string }[]\n ): Promise<number> {\n const sortedSet: { score: number; value: string }[] = JSON.parse(\n this.store.get(key) ?? '[]'\n )\n const initialSize = sortedSet.length\n for (const { score, value } of members) {\n const existingIndex = sortedSet.findIndex(\n (entry) => entry.value === value\n )\n if (existingIndex !== -1) {\n sortedSet[existingIndex].score = score\n } else {\n sortedSet.push({ score, value })\n }\n }\n sortedSet.sort((a, b) => a.score - b.score)\n this.store.set(key, JSON.stringify(sortedSet))\n return sortedSet.length - initialSize\n }\n\n /**\n * Retrieves a range of elements from a sorted set.\n *\n * @param key - The sorted set key.\n * @param start - The starting index.\n * @param stop - The stopping index.\n * @returns Resolves to an array of sorted set values in the range.\n */\n async zRange(key: string, start: number, stop: number): Promise<string[]> {\n const sortedSet: { score: number; value: string }[] = JSON.parse(\n this.store.get(key) ?? '[]'\n )\n const normalizedStop = stop === -1 ? sortedSet.length : stop + 1\n return sortedSet.slice(start, normalizedStop).map((entry) => entry.value)\n }\n\n /**\n * Removes elements from a sorted set.\n *\n * @param key - The sorted set key.\n * @param members - One or more values to remove.\n * @returns Resolves to the number of elements removed.\n */\n async zRem(key: string, members: string | string[]): Promise<number> {\n const sortedSet: { score: number; value: string }[] = JSON.parse(\n this.store.get(key) ?? '[]'\n )\n const valuesToRemove = Array.isArray(members) ? members : [members]\n const initialSize = sortedSet.length\n this.store.set(\n key,\n JSON.stringify(\n sortedSet.filter((entry) => !valuesToRemove.includes(entry.value))\n )\n )\n return initialSize - JSON.parse(this.store.get(key) ?? '[]').length\n }\n\n /**\n * Removes all keys from the store and clears all active expirations.\n *\n * @returns {Promise<'OK'>} Resolves to `'OK'` after all data is cleared.\n */\n async flushAll(): Promise<'OK'> {\n this.store.clear()\n for (const timeout of this.expirations.values()) {\n clearTimeout(timeout)\n }\n this.expirations.clear()\n this.expiryTimestamps.clear()\n return 'OK'\n }\n\n /**\n * Creates a new multi-command batch instance.\n * Commands queued in this batch will be executed together when `exec()` is called.\n *\n * @returns A new `IPersistorMulti` instance for batching commands.\n */\n multi(): IPersistorMulti {\n return new InMemoryMulti(this)\n }\n\n /**\n * Sets an expiration timeout for a key.\n * Cancels any existing expiration before setting a new one.\n *\n * @private\n * @param {string} key - The key to expire.\n * @param {number} ttlMs - Time-to-live in milliseconds.\n */\n private setExpiration(key: string, ttlMs: number) {\n // Clear existing timeout if any\n this.clearExpiration(key)\n\n // Store the absolute expiration timestamp\n const expiryTimestamp = Date.now() + ttlMs\n this.expiryTimestamps.set(key, expiryTimestamp)\n\n // Schedule deletion\n const timeout = setTimeout(() => {\n this.store.delete(key)\n this.expirations.delete(key)\n this.expiryTimestamps.delete(key)\n }, ttlMs)\n\n this.expirations.set(key, timeout)\n }\n\n /**\n * Cancels an active expiration timeout for a key and removes its TTL record.\n *\n * @private\n * @param {string} key - The key whose expiration should be cleared.\n */\n private clearExpiration(key: string) {\n if (this.expirations.has(key)) {\n clearTimeout(this.expirations.get(key))\n this.expirations.delete(key)\n this.expiryTimestamps.delete(key)\n }\n }\n}\n\n/**\n * Implements `IPersistorMulti` for `InMemoryPersistor`.\n */\nclass InMemoryMulti implements IPersistorMulti {\n private readonly persistor: IPersistor\n private readonly commands: Set<() => Promise<MultiExecReturnTypes>> =\n new Set()\n\n constructor(persistor: IPersistor) {\n this.persistor = persistor\n }\n\n /**\n * Queues a `SET` command to store a key-value pair with optional expiration settings.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param value - The string value to store.\n * @param options - Optional expiration settings.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n set(key: string, value: string, options?: SetOptions): IPersistorMulti {\n this.commands.add(() => this.persistor.set(key, value, options))\n return this\n }\n\n /**\n * Queues a `SETEX` command to store a key-value pair with an expiration time in seconds.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param seconds - Expiration time in seconds.\n * @param value - The string value to store.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n setEx(key: string, seconds: number, value: string): IPersistorMulti {\n this.commands.add(() => this.persistor.setEx(key, seconds, value))\n return this\n }\n\n /**\n * Queues a `PSETEX` command to store a key-value pair with an expiration time in milliseconds.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param milliseconds - Expiration time in milliseconds.\n * @param value - The string value to store.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n pSetEx(key: string, milliseconds: number, value: string): IPersistorMulti {\n this.commands.add(() => this.persistor.pSetEx(key, milliseconds, value))\n return this\n }\n\n /**\n * Queues a `SETNX` command to store a key-value pair **only if the key does not already exist**.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param value - The string value to store.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n setNX(key: string, value: string): IPersistorMulti {\n this.commands.add(() => this.persistor.setNX(key, value))\n return this\n }\n\n /**\n * Queues a `GET` command to retrieve the value associated with a key.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key to retrieve.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n get(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.get(key))\n return this\n }\n\n /**\n * Queues a `DEL` command to delete a key from the store.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key to delete.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n del(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.del(key))\n return this\n }\n\n /**\n * Queues an `EXPIRE` command to set a time-to-live (TTL) in seconds for a key.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key.\n * @param seconds - TTL in seconds.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n expire(key: string, seconds: number): IPersistorMulti {\n this.commands.add(() => this.persistor.expire(key, seconds))\n return this\n }\n\n /**\n * Queues a `TTL` command to get the remaining time-to-live (TTL) of a key in seconds.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The storage key to check.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n ttl(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.ttl(key))\n return this\n }\n\n /**\n * Queues an `exists` operation in the batch.\n * @param key - The key(s) to check existence.\n * @returns The multi instance for method chaining.\n */\n exists(key: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.exists(key))\n return this\n }\n\n /**\n * Queues an `incr` operation in the batch.\n * @param key - The key to increment.\n * @returns The multi instance for method chaining.\n */\n incr(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.incr(key))\n return this\n }\n\n /**\n * Queues an `incrBy` operation in the batch.\n * @param key - The key to increment.\n * @param increment - The amount to increment by.\n * @returns The multi instance for method chaining.\n */\n incrBy(key: string, increment: number): IPersistorMulti {\n this.commands.add(() => this.persistor.incrBy(key, increment))\n return this\n }\n\n /**\n * Queues a `decr` operation in the batch.\n * @param key - The key to decrement.\n * @returns The multi instance for method chaining.\n */\n decr(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.decr(key))\n return this\n }\n\n /**\n * Queues a `decrBy` operation in the batch.\n * @param key - The key to decrement.\n * @param decrement - The amount to decrement by.\n * @returns The multi instance for method chaining.\n */\n decrBy(key: string, decrement: number): IPersistorMulti {\n this.commands.add(() => this.persistor.decrBy(key, decrement))\n return this\n }\n\n /**\n * Queues a `flushAll` operation in the batch.\n * @returns The multi instance for method chaining.\n */\n flushAll(): IPersistorMulti {\n this.commands.add(() => this.persistor.flushAll())\n return this\n }\n\n /**\n * Queues an `hSet` command to store a field-value pair in a hash.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The hash key.\n * @param field - The field name.\n * @param value - The value to store.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n hSet(\n key: string,\n fieldOrValue: string | HashValue,\n value?: HashTypes\n ): IPersistorMulti {\n if (value !== undefined) {\n this.commands.add(() =>\n this.persistor.hSet(key, fieldOrValue as string, value)\n )\n } else {\n this.commands.add(() =>\n this.persistor.hSet(key, fieldOrValue as HashValue)\n )\n }\n\n return this\n }\n\n /**\n * Queues an `hGet` command to retrieve a field value from a hash.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The hash key.\n * @param field - The field to retrieve.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n hGet(key: string, field: string): IPersistorMulti {\n this.commands.add(() => this.persistor.hGet(key, field))\n return this\n }\n\n /**\n * Queues an `hSet` command to store a field-value pair in a hash.\n * The command will be executed when `exec()` is called.\n * @param key - The hash key.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n hGetAll(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.hGetAll(key))\n return this\n }\n\n /**\n * Queues an `lPush` command to add elements to the left (head) of a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @param values - The values to add.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n lPush(key: string, values: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.lPush(key, values))\n return this\n }\n\n /**\n * Queues an `rPush` command to add elements to the right (tail) of a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @param values - The values to add.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n rPush(key: string, values: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.rPush(key, values))\n return this\n }\n\n /**\n * Queues an `lPop` command to remove and return the first element of a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n lPop(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.lPop(key))\n return this\n }\n\n /**\n * Queues an `rPop` command to remove and return the last element of a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n rPop(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.rPop(key))\n return this\n }\n\n /**\n * Queues an `lRange` command to retrieve a range of elements from a list.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The list key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n lRange(key: string, start: number, stop: number): IPersistorMulti {\n this.commands.add(() => this.persistor.lRange(key, start, stop))\n return this\n }\n\n /**\n * Queues an `sAdd` command to add elements to a set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The set key.\n * @param values - The values to add.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n sAdd(key: string, values: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.sAdd(key, values))\n return this\n }\n\n /**\n * Queues an `sRem` command to remove elements from a set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The set key.\n * @param values - The values to remove.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n sRem(key: string, values: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.sRem(key, values))\n return this\n }\n\n /**\n * Queues an `sMembers` command to retrieve all members of a set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The set key.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n sMembers(key: string): IPersistorMulti {\n this.commands.add(() => this.persistor.sMembers(key))\n return this\n }\n\n /**\n * Queues a `zAdd` command to add elements to a sorted set with scores.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The sorted set key.\n * @param members - An array of objects with `score` and `value`.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zAdd(\n key: string,\n members: { score: number; value: string }[]\n ): IPersistorMulti {\n this.commands.add(() => this.persistor.zAdd(key, members))\n return this\n }\n\n /**\n * Queues a `zRange` command to retrieve a range of elements from a sorted set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The sorted set key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRange(key: string, start: number, stop: number): IPersistorMulti {\n this.commands.add(() => this.persistor.zRange(key, start, stop))\n return this\n }\n\n /**\n * Queues a `zRem` command to remove elements from a sorted set.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The sorted set key.\n * @param members - The members to remove.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRem(key: string, members: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.zRem(key, members))\n return this\n }\n\n /**\n * Executes multiple commands in a batch operation.\n * Each command is executed in sequence, and results are collected in an array.\n *\n * @returns Resolves to an array containing the results of each queued command.\n */\n async exec(): Promise<MultiExecReturnTypes[]> {\n return Promise.all([...this.commands].map((cmd) => cmd()))\n }\n}\n","export class LocalStorage {\n client = new Map()\n public isReady = false\n\n get(key: string) {\n return this.client.get(key)\n }\n\n set(key: string, value: string, options?: { PX: number }) {\n this.client.set(key, value)\n\n if (options?.PX) {\n setTimeout(() => {\n this.client.delete(key)\n }, options.PX)\n }\n }\n\n del(key: string) {\n this.client.delete(key)\n }\n\n clear() {\n this.client.clear()\n }\n\n async DBSIZE(): Promise<number> {\n return Promise.resolve(this.client.size)\n }\n\n // This is just for testing\n on(event: string, callback: (message: string) => void) {\n if (event === 'ready' && callback) {\n this.isReady = true\n callback('ready')\n }\n\n return this\n }\n\n connect(): Promise<this> {\n return Promise.resolve(this)\n }\n}\n\nconst localStorage = new LocalStorage()\n\nexport const createLocalMemoryClient = () => {\n return localStorage\n}\n","import type { UUID } from 'node:crypto'\nimport { getLogger } from '@sebspark/otel'\nimport { createClient, type RedisClientOptions } from 'redis'\nimport superjson from 'superjson'\nimport { createLocalMemoryClient } from './localMemory'\n\nlet CACHE_CLIENT = createClient\nconst isTestRunning = process.env.NODE_ENV === 'test'\n\ntype GetType<T> = {\n value: T\n ttl?: number\n timestamp: number\n}\n\ntype SetParams<T> = {\n value: T\n timestamp?: number\n ttl?: number\n}\n\nexport type PersistorConstructorType = {\n redis?: RedisClientOptions\n redisClient?: ReturnType<typeof createClient>\n clientId?: UUID\n onError?: (error: string) => void\n onSuccess?: () => void\n}\n\nfunction toMillis(seconds: number) {\n return seconds * 1000\n}\n\nexport class Persistor {\n public client: ReturnType<typeof createClient> | null = null\n private readonly clientId?: UUID\n private readonly onError\n private readonly onSuccess\n private readonly logger: ReturnType<typeof getLogger>\n private readonly redis?: RedisClientOptions\n\n constructor({\n redis,\n redisClient,\n clientId,\n onSuccess,\n onError,\n }: PersistorConstructorType) {\n this.logger = getLogger('Persistor')\n this.logger.warn(\n 'Persistor class is deprecated. Use InMemoryPersistor or redis: createClient instead'\n )\n\n this.onError = onError || (() => {})\n this.onSuccess = onSuccess || (() => {})\n this.clientId = clientId\n\n if (redisClient) {\n this.client = redisClient\n } else if (redis && !isTestRunning) {\n this.redis = redis\n } else {\n //@ts-expect-error\n CACHE_CLIENT = createLocalMemoryClient\n }\n\n if (!this.client || !this.client.isReady) {\n this.startConnection()\n }\n }\n\n public async startConnection() {\n try {\n await new Promise((resolve, reject) => {\n this.client = CACHE_CLIENT({\n url: this.redis?.url,\n username: this.redis?.username,\n password: this.redis?.password,\n pingInterval: this.redis?.pingInterval || undefined,\n socket: {\n ...this.redis?.socket,\n reconnectStrategy: (retries, cause) => {\n this.logger.error(cause)\n return 1000 * 2 ** retries\n },\n },\n })\n .on('error', (err) => {\n this.onError(err)\n reject(err)\n })\n .on('ready', () => {\n this.onSuccess()\n resolve(true)\n })\n .on('reconnecting', () => {\n this.logger.info(`reconnecting... ${this.clientId}`)\n })\n .on('end', () => {\n this.logger.info(`end... ${this.clientId}`)\n })\n\n this.client.connect()\n })\n } catch (err) {\n this.onError(`${err}`)\n this.logger.error(err as Error)\n }\n }\n\n public async size(): Promise<number> {\n if (!this.client) {\n throw new Error('Client not initialized')\n }\n return await this.client.DBSIZE()\n }\n\n public getClientId(): UUID | undefined {\n return this.clientId\n }\n\n public getIsClientConnected(): boolean {\n return !!this.client?.isReady\n }\n\n private createOptions(ttl?: number): { EX: number } | object {\n if (ttl !== null && ttl !== undefined && ttl > 0) {\n return { PX: Math.round(toMillis(ttl)) } // Return options object with Expiration time property in ms as an integer\n }\n return {} // Return empty object when ttl is null or undefined\n }\n\n /**\n * Set a value in the cache.\n * @param key Cache key.\n * @param object.value Value to set in the cache.\n * @param object.ttl Time to live in seconds.\n * @param object.timestamp Timestamp\n */\n public async set<T>(\n key: string,\n { value, timestamp = Date.now(), ttl }: SetParams<T>\n ): Promise<void> {\n if (!this.client || !this.client.isReady) {\n this.logger.error('Client not ready')\n return\n }\n try {\n const serializedData = superjson.stringify({\n value,\n ttl,\n timestamp,\n })\n const options = this.createOptions(ttl)\n await this.client.set(key, serializedData, options)\n } catch (error) {\n this.logger.error('Error setting data in redis', error as Error)\n throw new Error(`Error setting data in redis: ${error}`)\n }\n }\n\n /**\n * Get a value from the cache.\n * @param key Cache key.\n * @returns GetType<T> value\n */\n public async get<T>(key: string): Promise<GetType<T> | null> {\n if (!this.client) {\n this.logger.error('Client not ready')\n return null\n }\n try {\n const data = await this.client.get(key)\n if (!data) {\n return null\n }\n\n return superjson.parse(data) as GetType<T>\n } catch (error) {\n this.logger.error(`Error getting data in redis: ${error}`)\n throw new Error(`Error getting data from redis: ${error}`)\n }\n }\n\n /**\n * Delete a value from the cache.\n * @param key Cache key\n */\n public async delete(key: string): Promise<void> {\n if (!this.client || !this.client.isReady) {\n this.logger.error('Client not ready')\n return\n }\n try {\n await this.client.del(key)\n } catch (error) {\n this.logger.error(`Error deleting data from redis: ${error}`)\n throw new Error(`Error deleting data from redis: ${error}`)\n }\n }\n}\n","import type { UUID } from 'node:crypto'\nimport { randomUUID } from 'node:crypto'\nimport { getLogger } from '@sebspark/otel'\nimport type { RedisClientOptions } from 'redis'\nimport { Persistor } from './persistor'\n\nexport type { RedisClientOptions }\n\nexport type PromiseCacheOptions = {\n ttlInSeconds?: number\n caseSensitive?: boolean\n redis?: RedisClientOptions\n fallbackToFunction?: boolean\n onError?: (error: string) => void\n onSuccess?: () => void\n}\n\nconst persistors: Record<string, Persistor> = {}\n\nconst getPersistor = ({\n redis,\n onError,\n onSuccess,\n clientId,\n}: PromiseCacheOptions & { clientId: UUID }) => {\n const logger = getLogger('PromiseCache persistor')\n\n const connectionName = redis ? redis?.name || 'default' : 'local'\n\n if (!persistors[connectionName]) {\n persistors[connectionName] = new Persistor({\n redis,\n onError: (error: string) => {\n onError?.(error)\n logger?.error(\n `❌ REDIS | Client Error | ${connectionName} | ${redis?.url}: ${error}`\n )\n },\n onSuccess: () => {\n onSuccess?.()\n logger?.info(\n `📦 REDIS | Connection Ready | ${connectionName} | ${redis?.url}`\n )\n },\n clientId,\n })\n }\n return persistors[connectionName]\n}\n\nexport class PromiseCache<U> {\n public persistor: Persistor\n private readonly clientId: UUID = randomUUID()\n private readonly caseSensitive: boolean\n private readonly fallbackToFunction: boolean // If true, the cache will fallback to the delegate function if there is an error retrieving the cache.\n private readonly ttl?: number // Time to live in milliseconds.\n private readonly logger: ReturnType<typeof getLogger>\n /**\n * Initialize a new PromiseCache.\n * @param ttlInSeconds Default cache TTL.\n * @param caseSensitive Set to true if you want to differentiate between keys with different casing.\n */\n constructor({\n ttlInSeconds,\n caseSensitive = false,\n redis,\n fallbackToFunction = false,\n onSuccess,\n onError,\n }: PromiseCacheOptions) {\n this.logger = getLogger('PromiseCache')\n this.logger.warn(\n 'PromiseCache class is deprecated. Use createCache instead'\n )\n\n this.persistor = getPersistor({\n redis,\n onError,\n onSuccess,\n clientId: this.clientId,\n })\n\n this.caseSensitive = caseSensitive\n this.fallbackToFunction = fallbackToFunction\n\n if (ttlInSeconds) {\n this.ttl = ttlInSeconds // Conversion to milliseconds is done in the persistor.\n }\n }\n\n /**\n * Cache size.\n * @returns The number of entries in the cache.\n */\n async size(): Promise<number> {\n return await this.persistor.size()\n }\n\n /**\n * Override a value in the cache.\n * @param key Cache key.\n * @param value Cache value.\n * @param ttlInSeconds Time to live in seconds.\n */\n async override<U>(\n key: string,\n value: U,\n ttlInSeconds?: number\n ): Promise<void> {\n // Normalize the key if case insensitive.\n const effectiveKey = this.caseSensitive ? key : key.toLowerCase()\n\n // Determine the TTL and unique cache key for this specific call.\n const effectiveTTL = ttlInSeconds !== undefined ? ttlInSeconds : this.ttl\n\n await this.persistor.set(effectiveKey, {\n value,\n timestamp: Date.now(),\n ttl: effectiveTTL,\n })\n }\n\n /**\n * Get a value from the cache.\n * @param key Cache key.\n */\n async find<U>(key: string): Promise<U | null> {\n const result = await this.persistor.get<U>(key)\n return result?.value ?? null\n }\n\n /**\n * A simple promise cache wrapper.\n * @param key Cache key.\n * @param delegate The function to execute if the key is not in the cache.\n * @param ttlInSeconds Time to live in seconds.\n * @param ttlKeyInSeconds The key in the response object that contains the TTL.\n * @returns The result of the delegate function.\n */\n async wrap(\n key: string,\n delegate: () => Promise<U>,\n ttlInSeconds?: number,\n ttlKeyInSeconds?: string\n ): Promise<U> {\n const now = Date.now()\n\n // Normalize the key if case insensitive.\n const effectiveKey = this.caseSensitive ? key : key.toLowerCase()\n\n // Determine the TTL and unique cache key for this specific call.\n let effectiveTTL = ttlInSeconds ?? this.ttl\n\n try {\n const cached = await this.persistor.get<U>(effectiveKey)\n\n if (cached) {\n if (!ttlKeyInSeconds && cached.ttl !== effectiveTTL) {\n this.logger?.error(\n 'WARNING: TTL mismatch for key. It is recommended to use the same TTL for the same key.'\n )\n }\n\n return cached.value\n }\n } catch (err) {\n const error = err as Error\n if (!this.fallbackToFunction) {\n throw error\n }\n\n this.logger?.error(\n 'redis error, falling back to function execution',\n error as Error\n )\n }\n\n // Execute the delegate, cache the response with the current timestamp, and return it.\n const response = await delegate()\n\n // Get the TTL from the response if a TTL key is provided.\n if (ttlKeyInSeconds) {\n const responseDict = response as Record<string, unknown>\n const responseTTL = Number(responseDict[ttlKeyInSeconds] as string)\n effectiveTTL = responseTTL || effectiveTTL // Fall back to the default TTL if the TTL key is not found.\n }\n\n try {\n await this.persistor.set(effectiveKey, {\n value: response,\n timestamp: now,\n ttl: effectiveTTL,\n })\n } catch (err) {\n const error = err as Error\n console.error('failed to cache result', error.message)\n }\n\n return response\n }\n}\n","import { add, sub } from 'date-fns'\n\nexport { add, sub }\n\nexport const SECOND = 1000\nexport const MINUTE = 60 * SECOND\nexport const HOUR = 60 * MINUTE\nexport const DAY = 24 * HOUR\nexport const WEEK = 7 * DAY\n\nexport const seconds = (num: number) => num * SECOND\nexport const minutes = (num: number) => num * MINUTE\nexport const hours = (num: number) => num * HOUR\nexport const days = (num: number) => num * DAY\nexport const weeks = (num: number) => num * WEEK\n\nexport const today = (hours = 0, minutes = 0, seconds = 0) => {\n const local = new Date()\n const utc = Date.UTC(\n local.getUTCFullYear(),\n local.getUTCMonth(),\n local.getUTCDate(),\n hours,\n minutes,\n seconds\n )\n return new Date(utc)\n}\n\nexport const tomorrow = (hours = 0, minutes = 0, seconds = 0) =>\n add(today(hours, minutes, seconds), { days: 1 })\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sebspark/promise-cache",
|
|
3
|
-
"version": "6.1
|
|
3
|
+
"version": "6.2.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@sebspark/otel": "*",
|
|
27
27
|
"@sebspark/tsconfig": "*",
|
|
28
|
-
"@testcontainers/redis": "11.
|
|
28
|
+
"@testcontainers/redis": "11.10.0",
|
|
29
29
|
"testcontainers": "11.9.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|