@sebspark/promise-cache 3.9.0 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/dist/index.d.mts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +36 -14
- package/dist/index.mjs +36 -14
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -20,14 +20,15 @@ yarn install @sebspark/promise-cache
|
|
|
20
20
|
|
|
21
21
|
### **PromiseCache Class**
|
|
22
22
|
|
|
23
|
-
| Params
|
|
24
|
-
|
|
25
|
-
| redis
|
|
26
|
-
| ttlInSeconds
|
|
27
|
-
| caseSensituve
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
23
|
+
| Params | Type | Default | Description |
|
|
24
|
+
|--------------------|---------------------|-----------|--------------------------------------------------|
|
|
25
|
+
| redis | RedisClientOptions | undefined | Redis instance url, skip if use local memory |
|
|
26
|
+
| ttlInSeconds | number | undefined | Persist time in Seconds |
|
|
27
|
+
| caseSensituve | boolean | false | Retrieving cache with case sensitive |
|
|
28
|
+
| fallbackToFunction | boolean | false | Executes the wrapped function if persistor fails |
|
|
29
|
+
| onSuccess | function | undefined | Callback function if connection is success |
|
|
30
|
+
| onError | function | undefined | Callback function if there is an error |
|
|
31
|
+
| logger | winston Logger | undefined | Logger |
|
|
31
32
|
|
|
32
33
|
```typescript
|
|
33
34
|
import { PromiseCache } from '@sebspark/promise-cache'
|
package/dist/index.d.mts
CHANGED
|
@@ -23,10 +23,10 @@ type PersistorConstructorType = {
|
|
|
23
23
|
};
|
|
24
24
|
declare class Persistor {
|
|
25
25
|
client: ReturnType<typeof createClient> | null;
|
|
26
|
-
private clientId?;
|
|
27
|
-
private onError;
|
|
28
|
-
private onSuccess;
|
|
29
|
-
private logger;
|
|
26
|
+
private readonly clientId?;
|
|
27
|
+
private readonly onError;
|
|
28
|
+
private readonly onSuccess;
|
|
29
|
+
private readonly logger;
|
|
30
30
|
private readonly redis?;
|
|
31
31
|
constructor({ redis, clientId, onSuccess, onError, logger, }: PersistorConstructorType);
|
|
32
32
|
startConnection(): Promise<void>;
|
|
@@ -59,21 +59,24 @@ type PromiseCacheOptions = {
|
|
|
59
59
|
ttlInSeconds?: number;
|
|
60
60
|
caseSensitive?: boolean;
|
|
61
61
|
redis?: RedisClientOptions;
|
|
62
|
+
fallbackToFunction?: boolean;
|
|
62
63
|
onError?: (error: string) => void;
|
|
63
64
|
onSuccess?: () => void;
|
|
64
65
|
logger?: Logger;
|
|
65
66
|
};
|
|
66
67
|
declare class PromiseCache<U> {
|
|
67
68
|
persistor: Persistor;
|
|
68
|
-
private clientId;
|
|
69
|
+
private readonly clientId;
|
|
69
70
|
private readonly caseSensitive;
|
|
71
|
+
private readonly fallbackToFunction;
|
|
70
72
|
private readonly ttl?;
|
|
73
|
+
private readonly logger;
|
|
71
74
|
/**
|
|
72
75
|
* Initialize a new PromiseCache.
|
|
73
76
|
* @param ttlInSeconds Default cache TTL.
|
|
74
77
|
* @param caseSensitive Set to true if you want to differentiate between keys with different casing.
|
|
75
78
|
*/
|
|
76
|
-
constructor({ ttlInSeconds, caseSensitive, redis, onSuccess, onError, logger, }: PromiseCacheOptions);
|
|
79
|
+
constructor({ ttlInSeconds, caseSensitive, redis, fallbackToFunction, onSuccess, onError, logger, }: PromiseCacheOptions);
|
|
77
80
|
/**
|
|
78
81
|
* Cache size.
|
|
79
82
|
* @returns The number of entries in the cache.
|
package/dist/index.d.ts
CHANGED
|
@@ -23,10 +23,10 @@ type PersistorConstructorType = {
|
|
|
23
23
|
};
|
|
24
24
|
declare class Persistor {
|
|
25
25
|
client: ReturnType<typeof createClient> | null;
|
|
26
|
-
private clientId?;
|
|
27
|
-
private onError;
|
|
28
|
-
private onSuccess;
|
|
29
|
-
private logger;
|
|
26
|
+
private readonly clientId?;
|
|
27
|
+
private readonly onError;
|
|
28
|
+
private readonly onSuccess;
|
|
29
|
+
private readonly logger;
|
|
30
30
|
private readonly redis?;
|
|
31
31
|
constructor({ redis, clientId, onSuccess, onError, logger, }: PersistorConstructorType);
|
|
32
32
|
startConnection(): Promise<void>;
|
|
@@ -59,21 +59,24 @@ type PromiseCacheOptions = {
|
|
|
59
59
|
ttlInSeconds?: number;
|
|
60
60
|
caseSensitive?: boolean;
|
|
61
61
|
redis?: RedisClientOptions;
|
|
62
|
+
fallbackToFunction?: boolean;
|
|
62
63
|
onError?: (error: string) => void;
|
|
63
64
|
onSuccess?: () => void;
|
|
64
65
|
logger?: Logger;
|
|
65
66
|
};
|
|
66
67
|
declare class PromiseCache<U> {
|
|
67
68
|
persistor: Persistor;
|
|
68
|
-
private clientId;
|
|
69
|
+
private readonly clientId;
|
|
69
70
|
private readonly caseSensitive;
|
|
71
|
+
private readonly fallbackToFunction;
|
|
70
72
|
private readonly ttl?;
|
|
73
|
+
private readonly logger;
|
|
71
74
|
/**
|
|
72
75
|
* Initialize a new PromiseCache.
|
|
73
76
|
* @param ttlInSeconds Default cache TTL.
|
|
74
77
|
* @param caseSensitive Set to true if you want to differentiate between keys with different casing.
|
|
75
78
|
*/
|
|
76
|
-
constructor({ ttlInSeconds, caseSensitive, redis, onSuccess, onError, logger, }: PromiseCacheOptions);
|
|
79
|
+
constructor({ ttlInSeconds, caseSensitive, redis, fallbackToFunction, onSuccess, onError, logger, }: PromiseCacheOptions);
|
|
77
80
|
/**
|
|
78
81
|
* Cache size.
|
|
79
82
|
* @returns The number of entries in the cache.
|
package/dist/index.js
CHANGED
|
@@ -124,7 +124,7 @@ var Persistor = class {
|
|
|
124
124
|
socket: {
|
|
125
125
|
...this.redis?.socket,
|
|
126
126
|
reconnectStrategy: (retries, cause) => {
|
|
127
|
-
|
|
127
|
+
this.logger?.error(cause);
|
|
128
128
|
return 1e3 * 2 ** retries;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
@@ -263,8 +263,11 @@ var PromiseCache = class {
|
|
|
263
263
|
persistor;
|
|
264
264
|
clientId = (0, import_node_crypto.randomUUID)();
|
|
265
265
|
caseSensitive;
|
|
266
|
+
fallbackToFunction;
|
|
267
|
+
// If true, the cache will fallback to the delegate function if there is an error retrieving the cache.
|
|
266
268
|
ttl;
|
|
267
269
|
// Time to live in milliseconds.
|
|
270
|
+
logger;
|
|
268
271
|
/**
|
|
269
272
|
* Initialize a new PromiseCache.
|
|
270
273
|
* @param ttlInSeconds Default cache TTL.
|
|
@@ -274,18 +277,21 @@ var PromiseCache = class {
|
|
|
274
277
|
ttlInSeconds,
|
|
275
278
|
caseSensitive = false,
|
|
276
279
|
redis,
|
|
280
|
+
fallbackToFunction = false,
|
|
277
281
|
onSuccess,
|
|
278
282
|
onError,
|
|
279
283
|
logger
|
|
280
284
|
}) {
|
|
285
|
+
this.logger = logger;
|
|
281
286
|
this.persistor = getPersistor({
|
|
282
287
|
redis,
|
|
283
288
|
onError,
|
|
284
289
|
onSuccess,
|
|
285
290
|
clientId: this.clientId,
|
|
286
|
-
logger
|
|
291
|
+
logger: this.logger
|
|
287
292
|
});
|
|
288
293
|
this.caseSensitive = caseSensitive;
|
|
294
|
+
this.fallbackToFunction = fallbackToFunction;
|
|
289
295
|
if (ttlInSeconds) {
|
|
290
296
|
this.ttl = ttlInSeconds;
|
|
291
297
|
}
|
|
@@ -332,14 +338,25 @@ var PromiseCache = class {
|
|
|
332
338
|
const now = Date.now();
|
|
333
339
|
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
334
340
|
let effectiveTTL = ttlInSeconds ?? this.ttl;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
+
try {
|
|
342
|
+
const cached = await this.persistor.get(effectiveKey);
|
|
343
|
+
if (cached) {
|
|
344
|
+
if (!ttlKeyInSeconds && cached.ttl !== effectiveTTL) {
|
|
345
|
+
this.logger?.error(
|
|
346
|
+
"WARNING: TTL mismatch for key. It is recommended to use the same TTL for the same key."
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
return cached.value;
|
|
350
|
+
}
|
|
351
|
+
} catch (err) {
|
|
352
|
+
const error = err;
|
|
353
|
+
if (!this.fallbackToFunction) {
|
|
354
|
+
throw error;
|
|
341
355
|
}
|
|
342
|
-
|
|
356
|
+
this.logger?.error(
|
|
357
|
+
"redis error, falling back to function execution",
|
|
358
|
+
error instanceof Error ? error.message : String(error)
|
|
359
|
+
);
|
|
343
360
|
}
|
|
344
361
|
const response = await delegate();
|
|
345
362
|
if (ttlKeyInSeconds) {
|
|
@@ -347,11 +364,16 @@ var PromiseCache = class {
|
|
|
347
364
|
const responseTTL = Number(responseDict[ttlKeyInSeconds]);
|
|
348
365
|
effectiveTTL = responseTTL || effectiveTTL;
|
|
349
366
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
367
|
+
try {
|
|
368
|
+
await this.persistor.set(effectiveKey, {
|
|
369
|
+
value: response,
|
|
370
|
+
timestamp: now,
|
|
371
|
+
ttl: effectiveTTL
|
|
372
|
+
});
|
|
373
|
+
} catch (err) {
|
|
374
|
+
const error = err;
|
|
375
|
+
console.error("failed to cache result", error.message);
|
|
376
|
+
}
|
|
355
377
|
return response;
|
|
356
378
|
}
|
|
357
379
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -105,7 +105,7 @@ var Persistor = class {
|
|
|
105
105
|
socket: {
|
|
106
106
|
...this.redis?.socket,
|
|
107
107
|
reconnectStrategy: (retries, cause) => {
|
|
108
|
-
|
|
108
|
+
this.logger?.error(cause);
|
|
109
109
|
return 1e3 * 2 ** retries;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
@@ -244,8 +244,11 @@ var PromiseCache = class {
|
|
|
244
244
|
persistor;
|
|
245
245
|
clientId = randomUUID();
|
|
246
246
|
caseSensitive;
|
|
247
|
+
fallbackToFunction;
|
|
248
|
+
// If true, the cache will fallback to the delegate function if there is an error retrieving the cache.
|
|
247
249
|
ttl;
|
|
248
250
|
// Time to live in milliseconds.
|
|
251
|
+
logger;
|
|
249
252
|
/**
|
|
250
253
|
* Initialize a new PromiseCache.
|
|
251
254
|
* @param ttlInSeconds Default cache TTL.
|
|
@@ -255,18 +258,21 @@ var PromiseCache = class {
|
|
|
255
258
|
ttlInSeconds,
|
|
256
259
|
caseSensitive = false,
|
|
257
260
|
redis,
|
|
261
|
+
fallbackToFunction = false,
|
|
258
262
|
onSuccess,
|
|
259
263
|
onError,
|
|
260
264
|
logger
|
|
261
265
|
}) {
|
|
266
|
+
this.logger = logger;
|
|
262
267
|
this.persistor = getPersistor({
|
|
263
268
|
redis,
|
|
264
269
|
onError,
|
|
265
270
|
onSuccess,
|
|
266
271
|
clientId: this.clientId,
|
|
267
|
-
logger
|
|
272
|
+
logger: this.logger
|
|
268
273
|
});
|
|
269
274
|
this.caseSensitive = caseSensitive;
|
|
275
|
+
this.fallbackToFunction = fallbackToFunction;
|
|
270
276
|
if (ttlInSeconds) {
|
|
271
277
|
this.ttl = ttlInSeconds;
|
|
272
278
|
}
|
|
@@ -313,14 +319,25 @@ var PromiseCache = class {
|
|
|
313
319
|
const now = Date.now();
|
|
314
320
|
const effectiveKey = this.caseSensitive ? key : key.toLowerCase();
|
|
315
321
|
let effectiveTTL = ttlInSeconds ?? this.ttl;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if (
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
+
try {
|
|
323
|
+
const cached = await this.persistor.get(effectiveKey);
|
|
324
|
+
if (cached) {
|
|
325
|
+
if (!ttlKeyInSeconds && cached.ttl !== effectiveTTL) {
|
|
326
|
+
this.logger?.error(
|
|
327
|
+
"WARNING: TTL mismatch for key. It is recommended to use the same TTL for the same key."
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
return cached.value;
|
|
331
|
+
}
|
|
332
|
+
} catch (err) {
|
|
333
|
+
const error = err;
|
|
334
|
+
if (!this.fallbackToFunction) {
|
|
335
|
+
throw error;
|
|
322
336
|
}
|
|
323
|
-
|
|
337
|
+
this.logger?.error(
|
|
338
|
+
"redis error, falling back to function execution",
|
|
339
|
+
error instanceof Error ? error.message : String(error)
|
|
340
|
+
);
|
|
324
341
|
}
|
|
325
342
|
const response = await delegate();
|
|
326
343
|
if (ttlKeyInSeconds) {
|
|
@@ -328,11 +345,16 @@ var PromiseCache = class {
|
|
|
328
345
|
const responseTTL = Number(responseDict[ttlKeyInSeconds]);
|
|
329
346
|
effectiveTTL = responseTTL || effectiveTTL;
|
|
330
347
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
348
|
+
try {
|
|
349
|
+
await this.persistor.set(effectiveKey, {
|
|
350
|
+
value: response,
|
|
351
|
+
timestamp: now,
|
|
352
|
+
ttl: effectiveTTL
|
|
353
|
+
});
|
|
354
|
+
} catch (err) {
|
|
355
|
+
const error = err;
|
|
356
|
+
console.error("failed to cache result", error.message);
|
|
357
|
+
}
|
|
336
358
|
return response;
|
|
337
359
|
}
|
|
338
360
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sebspark/promise-cache",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"typecheck": "vitest --typecheck.only --passWithNoTests"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@testcontainers/redis": "
|
|
21
|
-
"testcontainers": "
|
|
20
|
+
"@testcontainers/redis": "10.25.0",
|
|
21
|
+
"testcontainers": "10.25.0",
|
|
22
22
|
"tsconfig": "*"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|