@sebspark/promise-cache 3.8.0 → 3.9.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 CHANGED
@@ -1,4 +1,4 @@
1
- import { RedisClientOptions, createClient, SetOptions } from 'redis';
1
+ import { createClient, RedisClientOptions, SetOptions } from 'redis';
2
2
  export { RedisClientOptions } from 'redis';
3
3
  import { Logger } from 'winston';
4
4
  import { UUID } from 'node:crypto';
@@ -353,7 +353,13 @@ interface IPersistor {
353
353
  * @returns Resolves to the number of elements removed.
354
354
  */
355
355
  zRem: (key: string, members: string | string[]) => Promise<number>;
356
+ isReady: boolean;
357
+ isOpen: boolean;
358
+ connect: () => Promise<IPersistor>;
359
+ once: (event: IPersistorEvent, cb: EventCallback) => IPersistor;
356
360
  }
361
+ type IPersistorEvent = 'ready' | 'connect' | 'reconnecting';
362
+ type EventCallback = () => void;
357
363
  /**
358
364
  * Interface for executing multiple storage commands in a batch operation.
359
365
  * All commands are queued and executed when `exec()` is called.
@@ -590,6 +596,10 @@ declare class InMemoryPersistor implements IPersistor {
590
596
  * Initializes an empty store, expiration map, and TTL tracker.
591
597
  */
592
598
  constructor();
599
+ connect(): Promise<this>;
600
+ get isReady(): boolean;
601
+ get isOpen(): boolean;
602
+ once(): this;
593
603
  /**
594
604
  * Stores a key-value pair with optional expiration settings.
595
605
  * If an expiration is provided (`EX`, `PX`, `EXAT`, `PXAT`), the key is automatically removed when TTL expires.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { RedisClientOptions, createClient, SetOptions } from 'redis';
1
+ import { createClient, RedisClientOptions, SetOptions } from 'redis';
2
2
  export { RedisClientOptions } from 'redis';
3
3
  import { Logger } from 'winston';
4
4
  import { UUID } from 'node:crypto';
@@ -353,7 +353,13 @@ interface IPersistor {
353
353
  * @returns Resolves to the number of elements removed.
354
354
  */
355
355
  zRem: (key: string, members: string | string[]) => Promise<number>;
356
+ isReady: boolean;
357
+ isOpen: boolean;
358
+ connect: () => Promise<IPersistor>;
359
+ once: (event: IPersistorEvent, cb: EventCallback) => IPersistor;
356
360
  }
361
+ type IPersistorEvent = 'ready' | 'connect' | 'reconnecting';
362
+ type EventCallback = () => void;
357
363
  /**
358
364
  * Interface for executing multiple storage commands in a batch operation.
359
365
  * All commands are queued and executed when `exec()` is called.
@@ -590,6 +596,10 @@ declare class InMemoryPersistor implements IPersistor {
590
596
  * Initializes an empty store, expiration map, and TTL tracker.
591
597
  */
592
598
  constructor();
599
+ connect(): Promise<this>;
600
+ get isReady(): boolean;
601
+ get isOpen(): boolean;
602
+ once(): this;
593
603
  /**
594
604
  * Stores a key-value pair with optional expiration settings.
595
605
  * If an expiration is provided (`EX`, `PX`, `EXAT`, `PXAT`), the key is automatically removed when TTL expires.
package/dist/index.js CHANGED
@@ -409,12 +409,14 @@ var createCache = (persistor, prefix) => {
409
409
  }
410
410
  const resultPromise = (async () => {
411
411
  try {
412
+ await ensurePersistorIsReady(persistor);
412
413
  const cached = deserialize(await persistor.get(key));
413
414
  if (cached !== null) {
414
415
  return cached;
415
416
  }
416
417
  const result = await delegate(...args);
417
418
  const expiry = typeof options.expiry === "function" ? options.expiry(args, result) : options.expiry;
419
+ await ensurePersistorIsReady(persistor);
418
420
  const serialized = serialize(result);
419
421
  const setOptions = toSetOptions(expiry);
420
422
  await persistor.set(key, serialized, setOptions);
@@ -430,6 +432,28 @@ var createCache = (persistor, prefix) => {
430
432
  };
431
433
  return cache;
432
434
  };
435
+ var ensurePersistorIsReady = async (persistor) => {
436
+ if (persistor.isReady) {
437
+ return;
438
+ }
439
+ if (persistor.isOpen) {
440
+ await new Promise((resolve) => {
441
+ if (persistor.isReady) return resolve();
442
+ persistor.once("ready", resolve);
443
+ return;
444
+ });
445
+ }
446
+ try {
447
+ await persistor.connect();
448
+ } catch (err) {
449
+ if (err.message === "Socket already opened") {
450
+ await new Promise((resolve) => {
451
+ if (persistor.isReady) return resolve();
452
+ persistor.once("ready", resolve);
453
+ });
454
+ }
455
+ }
456
+ };
433
457
 
434
458
  // src/inMemoryPersistor.ts
435
459
  var InMemoryPersistor = class {
@@ -459,6 +483,18 @@ var InMemoryPersistor = class {
459
483
  this.expirations = /* @__PURE__ */ new Map();
460
484
  this.expiryTimestamps = /* @__PURE__ */ new Map();
461
485
  }
486
+ async connect() {
487
+ return this;
488
+ }
489
+ get isReady() {
490
+ return true;
491
+ }
492
+ get isOpen() {
493
+ return true;
494
+ }
495
+ once() {
496
+ return this;
497
+ }
462
498
  /**
463
499
  * Stores a key-value pair with optional expiration settings.
464
500
  * If an expiration is provided (`EX`, `PX`, `EXAT`, `PXAT`), the key is automatically removed when TTL expires.
package/dist/index.mjs CHANGED
@@ -390,12 +390,14 @@ var createCache = (persistor, prefix) => {
390
390
  }
391
391
  const resultPromise = (async () => {
392
392
  try {
393
+ await ensurePersistorIsReady(persistor);
393
394
  const cached = deserialize(await persistor.get(key));
394
395
  if (cached !== null) {
395
396
  return cached;
396
397
  }
397
398
  const result = await delegate(...args);
398
399
  const expiry = typeof options.expiry === "function" ? options.expiry(args, result) : options.expiry;
400
+ await ensurePersistorIsReady(persistor);
399
401
  const serialized = serialize(result);
400
402
  const setOptions = toSetOptions(expiry);
401
403
  await persistor.set(key, serialized, setOptions);
@@ -411,6 +413,28 @@ var createCache = (persistor, prefix) => {
411
413
  };
412
414
  return cache;
413
415
  };
416
+ var ensurePersistorIsReady = async (persistor) => {
417
+ if (persistor.isReady) {
418
+ return;
419
+ }
420
+ if (persistor.isOpen) {
421
+ await new Promise((resolve) => {
422
+ if (persistor.isReady) return resolve();
423
+ persistor.once("ready", resolve);
424
+ return;
425
+ });
426
+ }
427
+ try {
428
+ await persistor.connect();
429
+ } catch (err) {
430
+ if (err.message === "Socket already opened") {
431
+ await new Promise((resolve) => {
432
+ if (persistor.isReady) return resolve();
433
+ persistor.once("ready", resolve);
434
+ });
435
+ }
436
+ }
437
+ };
414
438
 
415
439
  // src/inMemoryPersistor.ts
416
440
  var InMemoryPersistor = class {
@@ -440,6 +464,18 @@ var InMemoryPersistor = class {
440
464
  this.expirations = /* @__PURE__ */ new Map();
441
465
  this.expiryTimestamps = /* @__PURE__ */ new Map();
442
466
  }
467
+ async connect() {
468
+ return this;
469
+ }
470
+ get isReady() {
471
+ return true;
472
+ }
473
+ get isOpen() {
474
+ return true;
475
+ }
476
+ once() {
477
+ return this;
478
+ }
443
479
  /**
444
480
  * Stores a key-value pair with optional expiration settings.
445
481
  * If an expiration is provided (`EX`, `PX`, `EXAT`, `PXAT`), the key is automatically removed when TTL expires.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebspark/promise-cache",
3
- "version": "3.8.0",
3
+ "version": "3.9.1",
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.17.2",
21
- "testcontainers": "^10.17.2",
20
+ "@testcontainers/redis": "10.25.0",
21
+ "testcontainers": "10.25.0",
22
22
  "tsconfig": "*"
23
23
  },
24
24
  "dependencies": {