@sebspark/promise-cache 6.3.1 → 6.4.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/dist/index.d.mts +22 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +30 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -199,6 +199,13 @@ interface IPersistor {
|
|
|
199
199
|
hGetAll(key: string): Promise<{
|
|
200
200
|
[x: string]: string;
|
|
201
201
|
}>;
|
|
202
|
+
/**
|
|
203
|
+
* Deletes one or more fields from a hash.
|
|
204
|
+
* @param key - The hash key.
|
|
205
|
+
* @param fields - The field name(s) to delete.
|
|
206
|
+
* @returns Resolves to the number of fields removed.
|
|
207
|
+
*/
|
|
208
|
+
hDel(key: string, fields: string | string[]): Promise<number>;
|
|
202
209
|
/**
|
|
203
210
|
* Pushes values to the left (head) of a list.
|
|
204
211
|
* @param key - The list key.
|
|
@@ -465,6 +472,13 @@ interface IPersistorMulti {
|
|
|
465
472
|
* @returns Resolves to the value, or null if the hash does not exist.
|
|
466
473
|
*/
|
|
467
474
|
hGetAll(key: string): IPersistorMulti;
|
|
475
|
+
/**
|
|
476
|
+
* Deletes one or more fields from a hash.
|
|
477
|
+
* @param key - The hash key.
|
|
478
|
+
* @param fields - The field name(s) to delete.
|
|
479
|
+
* @returns The multi-instance for chaining.
|
|
480
|
+
*/
|
|
481
|
+
hDel(key: string, fields: string | string[]): IPersistorMulti;
|
|
468
482
|
/**
|
|
469
483
|
* Pushes values to the left (head) of a list.
|
|
470
484
|
* @param key - The list key.
|
|
@@ -788,6 +802,14 @@ declare class InMemoryPersistor implements IPersistor {
|
|
|
788
802
|
hGetAll(key: string): Promise<{
|
|
789
803
|
[x: string]: string;
|
|
790
804
|
}>;
|
|
805
|
+
/**
|
|
806
|
+
* Deletes one or more fields from a hash.
|
|
807
|
+
*
|
|
808
|
+
* @param key - The hash key.
|
|
809
|
+
* @param fields - The field name(s) to delete.
|
|
810
|
+
* @returns Resolves to the number of fields removed.
|
|
811
|
+
*/
|
|
812
|
+
hDel(key: string, fields: string | string[]): Promise<number>;
|
|
791
813
|
/**
|
|
792
814
|
* Pushes elements to the left (head) of a list.
|
|
793
815
|
*
|
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"],"mappings":";;;;;KAEY,oBAAA;EAAA,CAGL,CAAA;AAAA,uBAGH,OAAA;;;AANJ;;;;;KAiBY,MAAA,YAAkB,IAAA;;;;;KAMlB,cAAA;EAAc;;;EAIxB,GAAA,gBAAmB,IAAA,EAAM,CAAA;EAYC;;;;;;;;;;EAA1B,MAAA,GAAS,MAAA,KAAW,IAAA,EAAM,CAAA,EAAG,QAAA,EAAU,CAAA,KAAM,MAAA;AAAA;;;;KAMnC,KAAA;EANmC;;;EAU7C,SAAA,EAAW,UAAA;EAJI;;;;;;;;EAcf,IAAA,yBACE,QAAA,MAAc,IAAA,EAAM,CAAA,KAAM,OAAA,CAAQ,CAAA,GAClC,OAAA,EAAS,cAAA,CAAe,CAAA,EAAG,CAAA,QACtB,IAAA,EAAM,CAAA,KAAM,OAAA,CAAQ,CAAA;AAAA;AAAA,KAGjB,SAAA;AAAA,KACA,SAAA;EAAA,CAEL,CAAA,WAAY,SAAA;EAAA,CACZ,CAAA,WAAY,SAAA;AAAA,IAEf,GAAA,CAAI,SAAA,EAAW,SAAA;AAAA,UAEF,OAAA;EACf,KAAA;EACA,KAAA;AAAA;;;;;UAOe,UAAA;EArBJ;;;;;;;EA6BX,GAAA,CACE,GAAA,UACA,KAAA,EAAO,SAAA,EACP,OAAA,GAAU,UAAA,GACT,OAAA;EAhCyB;;AAG9B;;;EAoCE,GAAA,CAAI,GAAA,WAAc,OAAA;EApCC;AACrB;;;;EA0CE,GAAA,CAAI,GAAA,WAAc,OAAA;EArCZ;;;;;;EA6CN,MAAA,CAAO,GAAA,UAAa,OAAA,WAAkB,OAAA;EA/CjC;;;;;;;AAIP;EAqDE,GAAA,CAAI,GAAA,WAAc,OAAA;;;;AA5CpB;EAkDE,QAAA,IAAY,OAAA;;;;;;;;EASZ,KAAA,CAAM,GAAA,UAAa,OAAA,UAAiB,KAAA,WAAgB,OAAA;EATxC;;;;;;;EAkBZ,MAAA,CACE,GAAA,UACA,YAAA,UACA,KAAA,WACC,OAAA;EA4CqC;;;;;;EApCxC,KAAA,CAAM,GAAA,UAAa,KAAA,WAAgB,OAAA;EA4Eb;;;;;EArEtB,KAAA,IAAS,eAAA;
|
|
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"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -354,6 +354,24 @@ var InMemoryPersistor = class {
|
|
|
354
354
|
return JSON.parse(this.store.get(key) ?? "{}");
|
|
355
355
|
}
|
|
356
356
|
/**
|
|
357
|
+
* Deletes one or more fields from a hash.
|
|
358
|
+
*
|
|
359
|
+
* @param key - The hash key.
|
|
360
|
+
* @param fields - The field name(s) to delete.
|
|
361
|
+
* @returns Resolves to the number of fields removed.
|
|
362
|
+
*/
|
|
363
|
+
async hDel(key, fields) {
|
|
364
|
+
const hash = JSON.parse(this.store.get(key) ?? "{}");
|
|
365
|
+
const fieldsToDelete = Array.isArray(fields) ? fields : [fields];
|
|
366
|
+
let removed = 0;
|
|
367
|
+
for (const field of fieldsToDelete) if (Object.hasOwn(hash, field)) {
|
|
368
|
+
delete hash[field];
|
|
369
|
+
removed++;
|
|
370
|
+
}
|
|
371
|
+
if (removed > 0) this.store.set(key, JSON.stringify(hash));
|
|
372
|
+
return removed;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
357
375
|
* Pushes elements to the left (head) of a list.
|
|
358
376
|
*
|
|
359
377
|
* @param key - The list key.
|
|
@@ -839,6 +857,18 @@ var InMemoryMulti = class {
|
|
|
839
857
|
return this;
|
|
840
858
|
}
|
|
841
859
|
/**
|
|
860
|
+
* Queues an `hDel` command to delete one or more fields from a hash.
|
|
861
|
+
* The command will be executed when `exec()` is called.
|
|
862
|
+
*
|
|
863
|
+
* @param key - The hash key.
|
|
864
|
+
* @param fields - The field name(s) to delete.
|
|
865
|
+
* @returns The `IPersistorMulti` instance to allow method chaining.
|
|
866
|
+
*/
|
|
867
|
+
hDel(key, fields) {
|
|
868
|
+
this.commands.add(() => this.persistor.hDel(key, fields));
|
|
869
|
+
return this;
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
842
872
|
* Queues an `lPush` command to add elements to the left (head) of a list.
|
|
843
873
|
* The command will be executed when `exec()` is called.
|
|
844
874
|
*
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"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 ZMember,\n} from './types'\n\nconst sortMembers = (members: ZMember[]): ZMember[] =>\n [...members].sort((a, b) => a.score - b.score)\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 * @param key - The sorted set key.\n * @param members - A member or array of members with `score` and `value`.\n * @returns Resolves to the number of elements successfully added.\n */\n async zAdd(key: string, members: ZMember | ZMember[]): Promise<number> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const initialSize = sortedSet.length\n for (const { score, value } of Array.isArray(members)\n ? members\n : [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 this.store.set(key, JSON.stringify(sortMembers(sortedSet)))\n return sortedSet.length - initialSize\n }\n /**\n * Increments the score of a member in a sorted set.\n * @param key - The sorted set key.\n * @param increment - The amount to increment the score by.\n * @param member - The member to increment.\n * @returns Resolves to the new score.\n */\n async zIncrBy(\n key: string,\n increment: number,\n member: string\n ): Promise<number> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const existingIndex = sortedSet.findIndex((entry) => entry.value === member)\n const newScore =\n existingIndex !== -1\n ? sortedSet[existingIndex].score + increment\n : increment\n const updated: ZMember = { score: newScore, value: member }\n if (existingIndex !== -1) {\n sortedSet[existingIndex] = updated\n } else {\n sortedSet.push(updated)\n }\n this.store.set(key, JSON.stringify(sortMembers(sortedSet)))\n return newScore\n }\n /**\n * Retrieves a range of members from a sorted set.\n * @param key - The sorted set key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @returns Resolves to an array of member values in the range.\n */\n async zRange(key: string, start: number, stop: number): Promise<string[]> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const normalizedStop = stop === -1 ? sortedSet.length : stop + 1\n return sortedSet.slice(start, normalizedStop).map((entry) => entry.value)\n }\n /**\n * Retrieves a range of members with scores from a sorted set.\n * @param key - The sorted set key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @param options - Optional. Pass `{ REV: true }` to return in descending score order.\n * @returns Resolves to an array of ZMember in the range.\n */\n async zRangeWithScores(\n key: string,\n start: number,\n stop: number,\n options?: { REV: boolean }\n ): Promise<ZMember[]> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const ordered = options?.REV ? [...sortedSet].reverse() : sortedSet\n const normalizedStop = stop === -1 ? ordered.length : stop + 1\n return ordered.slice(start, normalizedStop)\n }\n /**\n * Returns the score of a member in a sorted set.\n * @param key - The sorted set key.\n * @param member - The member to get the score for.\n * @returns Resolves to the score or null if the member does not exist.\n */\n async zScore(key: string, member: string): Promise<number | null> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n return sortedSet.find((entry) => entry.value === member)?.score ?? null\n }\n /**\n * Returns the rank of a member in a sorted set, ordered from low to high.\n * @param key - The sorted set key.\n * @param member - The member to get the rank for.\n * @returns Resolves to the rank or null if the member does not exist.\n */\n async zRank(key: string, member: string): Promise<number | null> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const index = sortedSet.findIndex((entry) => entry.value === member)\n return index === -1 ? null : index\n }\n /**\n * Returns the number of members in a sorted set with scores between min and max.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns Resolves to the number of members in the score range.\n */\n async zCount(key: string, min: number, max: number): Promise<number> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n return sortedSet.filter((entry) => entry.score >= min && entry.score <= max)\n .length\n }\n /**\n * Returns members in a sorted set with scores between min and max.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns Resolves to an array of member values in the score range.\n */\n async zRangeByScore(\n key: string,\n min: number,\n max: number\n ): Promise<string[]> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n return sortedSet\n .filter((entry) => entry.score >= min && entry.score <= max)\n .map((entry) => entry.value)\n }\n /**\n * Returns members with scores in a sorted set with scores between min and max.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns Resolves to an array of ZMember in the score range.\n */\n async zRangeByScoreWithScores(\n key: string,\n min: number,\n max: number\n ): Promise<ZMember[]> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n return sortedSet.filter((entry) => entry.score >= min && entry.score <= max)\n }\n /**\n * Removes members from a sorted set.\n * @param key - The sorted set key.\n * @param members - The members 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: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const valuesToRemove = Array.isArray(members) ? members : [members]\n const filtered = sortedSet.filter(\n (entry) => !valuesToRemove.includes(entry.value)\n )\n this.store.set(key, JSON.stringify(filtered))\n return sortedSet.length - filtered.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 members to a sorted set with scores.\n * @param key - The sorted set key.\n * @param members - A member or array of members with `score` and `value`.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zAdd(key: string, members: ZMember | ZMember[]): IPersistorMulti {\n this.commands.add(() => this.persistor.zAdd(key, members))\n return this\n }\n /**\n * Queues a `zIncrBy` command to increment the score of a member in a sorted set.\n * @param key - The sorted set key.\n * @param increment - The amount to increment the score by.\n * @param member - The member to increment.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zIncrBy(key: string, increment: number, member: string): IPersistorMulti {\n this.commands.add(() => this.persistor.zIncrBy(key, increment, member))\n return this\n }\n /**\n * Queues a `zRange` command to retrieve a range of members from a sorted set.\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 * Queues a `zRangeWithScores` command to retrieve a range of members with scores from a sorted set.\n * @param key - The sorted set key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @param options - Optional. Pass `{ REV: true }` to return in descending score order.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRangeWithScores(\n key: string,\n start: number,\n stop: number,\n options?: { REV: boolean }\n ): IPersistorMulti {\n this.commands.add(() =>\n this.persistor.zRangeWithScores(key, start, stop, options)\n )\n return this\n }\n /**\n * Queues a `zScore` command to get the score of a member in a sorted set.\n * @param key - The sorted set key.\n * @param member - The member to get the score for.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zScore(key: string, member: string): IPersistorMulti {\n this.commands.add(() => this.persistor.zScore(key, member))\n return this\n }\n /**\n * Queues a `zRank` command to get the rank of a member in a sorted set.\n * @param key - The sorted set key.\n * @param member - The member to get the rank for.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRank(key: string, member: string): IPersistorMulti {\n this.commands.add(() => this.persistor.zRank(key, member))\n return this\n }\n /**\n * Queues a `zCount` command to count members in a score range.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zCount(key: string, min: number, max: number): IPersistorMulti {\n this.commands.add(() => this.persistor.zCount(key, min, max))\n return this\n }\n /**\n * Queues a `zRangeByScore` command to retrieve members within a score range.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRangeByScore(key: string, min: number, max: number): IPersistorMulti {\n this.commands.add(() => this.persistor.zRangeByScore(key, min, max))\n return this\n }\n /**\n * Queues a `zRangeByScoreWithScores` command to retrieve members with scores within a score range.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRangeByScoreWithScores(\n key: string,\n min: number,\n max: number\n ): IPersistorMulti {\n this.commands.add(() =>\n this.persistor.zRangeByScoreWithScores(key, min, max)\n )\n return this\n }\n /**\n * Queues a `zRem` command to remove members from a sorted set.\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":[],"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 ZMember,\n} from './types'\n\nconst sortMembers = (members: ZMember[]): ZMember[] =>\n [...members].sort((a, b) => a.score - b.score)\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 * Deletes one or more fields from a hash.\n *\n * @param key - The hash key.\n * @param fields - The field name(s) to delete.\n * @returns Resolves to the number of fields removed.\n */\n async hDel(key: string, fields: string | string[]): Promise<number> {\n const hash = JSON.parse(this.store.get(key) ?? '{}')\n const fieldsToDelete = Array.isArray(fields) ? fields : [fields]\n let removed = 0\n for (const field of fieldsToDelete) {\n if (Object.hasOwn(hash, field)) {\n delete hash[field]\n removed++\n }\n }\n if (removed > 0) {\n this.store.set(key, JSON.stringify(hash))\n }\n return removed\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 * @param key - The sorted set key.\n * @param members - A member or array of members with `score` and `value`.\n * @returns Resolves to the number of elements successfully added.\n */\n async zAdd(key: string, members: ZMember | ZMember[]): Promise<number> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const initialSize = sortedSet.length\n for (const { score, value } of Array.isArray(members)\n ? members\n : [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 this.store.set(key, JSON.stringify(sortMembers(sortedSet)))\n return sortedSet.length - initialSize\n }\n /**\n * Increments the score of a member in a sorted set.\n * @param key - The sorted set key.\n * @param increment - The amount to increment the score by.\n * @param member - The member to increment.\n * @returns Resolves to the new score.\n */\n async zIncrBy(\n key: string,\n increment: number,\n member: string\n ): Promise<number> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const existingIndex = sortedSet.findIndex((entry) => entry.value === member)\n const newScore =\n existingIndex !== -1\n ? sortedSet[existingIndex].score + increment\n : increment\n const updated: ZMember = { score: newScore, value: member }\n if (existingIndex !== -1) {\n sortedSet[existingIndex] = updated\n } else {\n sortedSet.push(updated)\n }\n this.store.set(key, JSON.stringify(sortMembers(sortedSet)))\n return newScore\n }\n /**\n * Retrieves a range of members from a sorted set.\n * @param key - The sorted set key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @returns Resolves to an array of member values in the range.\n */\n async zRange(key: string, start: number, stop: number): Promise<string[]> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const normalizedStop = stop === -1 ? sortedSet.length : stop + 1\n return sortedSet.slice(start, normalizedStop).map((entry) => entry.value)\n }\n /**\n * Retrieves a range of members with scores from a sorted set.\n * @param key - The sorted set key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @param options - Optional. Pass `{ REV: true }` to return in descending score order.\n * @returns Resolves to an array of ZMember in the range.\n */\n async zRangeWithScores(\n key: string,\n start: number,\n stop: number,\n options?: { REV: boolean }\n ): Promise<ZMember[]> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const ordered = options?.REV ? [...sortedSet].reverse() : sortedSet\n const normalizedStop = stop === -1 ? ordered.length : stop + 1\n return ordered.slice(start, normalizedStop)\n }\n /**\n * Returns the score of a member in a sorted set.\n * @param key - The sorted set key.\n * @param member - The member to get the score for.\n * @returns Resolves to the score or null if the member does not exist.\n */\n async zScore(key: string, member: string): Promise<number | null> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n return sortedSet.find((entry) => entry.value === member)?.score ?? null\n }\n /**\n * Returns the rank of a member in a sorted set, ordered from low to high.\n * @param key - The sorted set key.\n * @param member - The member to get the rank for.\n * @returns Resolves to the rank or null if the member does not exist.\n */\n async zRank(key: string, member: string): Promise<number | null> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const index = sortedSet.findIndex((entry) => entry.value === member)\n return index === -1 ? null : index\n }\n /**\n * Returns the number of members in a sorted set with scores between min and max.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns Resolves to the number of members in the score range.\n */\n async zCount(key: string, min: number, max: number): Promise<number> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n return sortedSet.filter((entry) => entry.score >= min && entry.score <= max)\n .length\n }\n /**\n * Returns members in a sorted set with scores between min and max.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns Resolves to an array of member values in the score range.\n */\n async zRangeByScore(\n key: string,\n min: number,\n max: number\n ): Promise<string[]> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n return sortedSet\n .filter((entry) => entry.score >= min && entry.score <= max)\n .map((entry) => entry.value)\n }\n /**\n * Returns members with scores in a sorted set with scores between min and max.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns Resolves to an array of ZMember in the score range.\n */\n async zRangeByScoreWithScores(\n key: string,\n min: number,\n max: number\n ): Promise<ZMember[]> {\n const sortedSet: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n return sortedSet.filter((entry) => entry.score >= min && entry.score <= max)\n }\n /**\n * Removes members from a sorted set.\n * @param key - The sorted set key.\n * @param members - The members 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: ZMember[] = JSON.parse(this.store.get(key) ?? '[]')\n const valuesToRemove = Array.isArray(members) ? members : [members]\n const filtered = sortedSet.filter(\n (entry) => !valuesToRemove.includes(entry.value)\n )\n this.store.set(key, JSON.stringify(filtered))\n return sortedSet.length - filtered.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 `hDel` command to delete one or more fields from a hash.\n * The command will be executed when `exec()` is called.\n *\n * @param key - The hash key.\n * @param fields - The field name(s) to delete.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n hDel(key: string, fields: string | string[]): IPersistorMulti {\n this.commands.add(() => this.persistor.hDel(key, fields))\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 members to a sorted set with scores.\n * @param key - The sorted set key.\n * @param members - A member or array of members with `score` and `value`.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zAdd(key: string, members: ZMember | ZMember[]): IPersistorMulti {\n this.commands.add(() => this.persistor.zAdd(key, members))\n return this\n }\n /**\n * Queues a `zIncrBy` command to increment the score of a member in a sorted set.\n * @param key - The sorted set key.\n * @param increment - The amount to increment the score by.\n * @param member - The member to increment.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zIncrBy(key: string, increment: number, member: string): IPersistorMulti {\n this.commands.add(() => this.persistor.zIncrBy(key, increment, member))\n return this\n }\n /**\n * Queues a `zRange` command to retrieve a range of members from a sorted set.\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 * Queues a `zRangeWithScores` command to retrieve a range of members with scores from a sorted set.\n * @param key - The sorted set key.\n * @param start - The start index.\n * @param stop - The stop index (inclusive).\n * @param options - Optional. Pass `{ REV: true }` to return in descending score order.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRangeWithScores(\n key: string,\n start: number,\n stop: number,\n options?: { REV: boolean }\n ): IPersistorMulti {\n this.commands.add(() =>\n this.persistor.zRangeWithScores(key, start, stop, options)\n )\n return this\n }\n /**\n * Queues a `zScore` command to get the score of a member in a sorted set.\n * @param key - The sorted set key.\n * @param member - The member to get the score for.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zScore(key: string, member: string): IPersistorMulti {\n this.commands.add(() => this.persistor.zScore(key, member))\n return this\n }\n /**\n * Queues a `zRank` command to get the rank of a member in a sorted set.\n * @param key - The sorted set key.\n * @param member - The member to get the rank for.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRank(key: string, member: string): IPersistorMulti {\n this.commands.add(() => this.persistor.zRank(key, member))\n return this\n }\n /**\n * Queues a `zCount` command to count members in a score range.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zCount(key: string, min: number, max: number): IPersistorMulti {\n this.commands.add(() => this.persistor.zCount(key, min, max))\n return this\n }\n /**\n * Queues a `zRangeByScore` command to retrieve members within a score range.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRangeByScore(key: string, min: number, max: number): IPersistorMulti {\n this.commands.add(() => this.persistor.zRangeByScore(key, min, max))\n return this\n }\n /**\n * Queues a `zRangeByScoreWithScores` command to retrieve members with scores within a score range.\n * @param key - The sorted set key.\n * @param min - The minimum score.\n * @param max - The maximum score.\n * @returns The `IPersistorMulti` instance to allow method chaining.\n */\n zRangeByScoreWithScores(\n key: string,\n min: number,\n max: number\n ): IPersistorMulti {\n this.commands.add(() =>\n this.persistor.zRangeByScoreWithScores(key, min, max)\n )\n return this\n }\n /**\n * Queues a `zRem` command to remove members from a sorted set.\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.
|
|
3
|
+
"version": "6.4.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"testcontainers": "11.12.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@sebspark/otel": "2.0.
|
|
30
|
+
"@sebspark/otel": "2.0.13",
|
|
31
31
|
"date-fns": "4.1.0",
|
|
32
32
|
"redis": "5.11.0",
|
|
33
33
|
"superjson": "2.2.6"
|