@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 CHANGED
@@ -20,14 +20,15 @@ yarn install @sebspark/promise-cache
20
20
 
21
21
  ### **PromiseCache Class**
22
22
 
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
- | onSuccess | function | undefined | Callback function if connection is success |
29
- | onError | function | undefined | Callback function if there is an error |
30
- | logger | winston Logger | undefined | Logger |
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
- console.error(cause);
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
- const cached = await this.persistor.get(effectiveKey);
336
- if (cached) {
337
- if (!ttlKeyInSeconds && cached.ttl !== effectiveTTL) {
338
- console.error(
339
- "WARNING: TTL mismatch for key. It is recommended to use the same TTL for the same key."
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
- return cached.value;
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
- this.persistor.set(effectiveKey, {
351
- value: response,
352
- timestamp: now,
353
- ttl: effectiveTTL
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
- console.error(cause);
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
- const cached = await this.persistor.get(effectiveKey);
317
- if (cached) {
318
- if (!ttlKeyInSeconds && cached.ttl !== effectiveTTL) {
319
- console.error(
320
- "WARNING: TTL mismatch for key. It is recommended to use the same TTL for the same key."
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
- return cached.value;
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
- this.persistor.set(effectiveKey, {
332
- value: response,
333
- timestamp: now,
334
- ttl: effectiveTTL
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.9.0",
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": "^10.18.0",
21
- "testcontainers": "^10.18.0",
20
+ "@testcontainers/redis": "10.25.0",
21
+ "testcontainers": "10.25.0",
22
22
  "tsconfig": "*"
23
23
  },
24
24
  "dependencies": {