@cacheable/node-cache
Advanced tools
+90
-18
@@ -288,25 +288,36 @@ "use strict"; | ||
| * Sets a key value pair. It is possible to define a ttl (in seconds). Returns true on success. | ||
| * | ||
| * TTL behavior: | ||
| * - `ttl > 0`: cache expires after the given number of seconds | ||
| * - `ttl === 0`: cache indefinitely (overrides stdTTL) | ||
| * - `ttl < 0`: store the value but it expires immediately on next access (matches original node-cache behavior) | ||
| * - `ttl` omitted/undefined: use `stdTTL` from options (0 = unlimited if stdTTL is 0 or not set) | ||
| * - `ttl` as string: shorthand format like '1h', '30s', '5m', '2d' | ||
| * | ||
| * @param {string | number} key - it will convert the key to a string | ||
| * @param {T} value | ||
| * @param {number | string} [ttl] - this is in seconds and undefined will use the default ttl | ||
| * @returns {boolean} | ||
| * @param {number | string} [ttl] - TTL in seconds. 0 = unlimited, negative = expires immediately, string = shorthand format | ||
| * @returns {boolean} true on success | ||
| * @throws {Error} If the `key` or `ttl` is of an invalid type. | ||
| */ | ||
| set(key, value, ttl = 0) { | ||
| set(key, value, ttl) { | ||
| if (typeof key !== "string" && typeof key !== "number") { | ||
| throw this.createError("The key argument has to be of type `string` or `number`. Found: `__key`" /* EKEYTYPE */, key); | ||
| } | ||
| if (ttl && typeof ttl !== "number" && typeof ttl !== "string") { | ||
| if (ttl !== void 0 && typeof ttl !== "number" && typeof ttl !== "string") { | ||
| throw this.createError("The ttl argument has to be a number or a string for shorthand ttl." /* ETTLTYPE */, this.formatKey(key)); | ||
| } | ||
| const keyValue = this.formatKey(key); | ||
| let ttlValue = 0; | ||
| if (this.options.stdTTL) { | ||
| ttlValue = this.getExpirationTimestamp(this.options.stdTTL); | ||
| } | ||
| if (ttl) { | ||
| ttlValue = this.getExpirationTimestamp(ttl); | ||
| } | ||
| let expirationTimestamp = 0; | ||
| if (ttlValue && ttlValue > 0) { | ||
| expirationTimestamp = ttlValue; | ||
| if (this.isNegativeTtl(ttl)) { | ||
| expirationTimestamp = Math.max( | ||
| 1, | ||
| this.getExpirationTimestamp( | ||
| typeof ttl === "string" ? Number(ttl) : ttl | ||
| ) | ||
| ); | ||
| } else if (ttl !== void 0 && (typeof ttl === "string" || ttl > 0)) { | ||
| expirationTimestamp = this.resolveExpiration(ttl); | ||
| } else if (ttl === void 0 && this.options.stdTTL !== void 0 && this.options.stdTTL !== 0) { | ||
| expirationTimestamp = this.resolveExpiration(this.options.stdTTL); | ||
| } | ||
@@ -324,3 +335,3 @@ if (this.options.maxKeys) { | ||
| }); | ||
| this.emit("set", keyValue, value, ttlValue); | ||
| this.emit("set", keyValue, value, expirationTimestamp); | ||
| this._stats.incrementKSize(keyValue); | ||
@@ -333,4 +344,12 @@ this._stats.incrementVSize(value); | ||
| * Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success. | ||
| * | ||
| * Each item follows the same TTL behavior as `set()`: | ||
| * - Positive TTL: expires after the given seconds | ||
| * - `0`: cache indefinitely | ||
| * - Negative TTL: stored but expires immediately on next access | ||
| * - Omitted: uses `stdTTL` from options | ||
| * | ||
| * @param {PartialNodeCacheItem<T>[]} data an array of key value pairs with optional ttl | ||
| * @returns {boolean} | ||
| * @returns {boolean} true on success | ||
| * @throws {Error} If `data` is not an array, or if any item has an invalid key or ttl type. | ||
| */ | ||
@@ -447,11 +466,37 @@ mset(data) { | ||
| * Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used. | ||
| * | ||
| * TTL behavior: | ||
| * - `ttl > 0`: key expires after the given number of seconds | ||
| * - `ttl === 0`: key lives indefinitely (overrides stdTTL) | ||
| * - `ttl < 0`: key expires immediately on next access (matches original node-cache behavior) | ||
| * - `ttl` omitted/undefined: use `stdTTL` from options (0 = unlimited if stdTTL is 0 or not set) | ||
| * - `ttl` as string: shorthand format like '1h', '30s', '5m', '2d' | ||
| * | ||
| * @param {string | number} key if the key is a number it will convert it to a string | ||
| * @param {number | string} [ttl] the ttl in seconds if number, or a shorthand string like '1h' for 1 hour | ||
| * @param {number | string} [ttl] TTL in seconds. 0 = unlimited, negative = expires immediately, string = shorthand format | ||
| * @returns {boolean} true if the key has been found and changed. Otherwise returns false. | ||
| * @throws {Error} If the `ttl` is of an invalid type (must be a number or string). | ||
| */ | ||
| ttl(key, ttl) { | ||
| if (ttl !== void 0 && typeof ttl !== "number" && typeof ttl !== "string") { | ||
| throw this.createError("The ttl argument has to be a number or a string for shorthand ttl." /* ETTLTYPE */, this.formatKey(key)); | ||
| } | ||
| const result = this.store.get(this.formatKey(key)); | ||
| if (result) { | ||
| const ttlValue = ttl ?? this.options.stdTTL; | ||
| result.ttl = this.getExpirationTimestamp(ttlValue); | ||
| if (this.isNegativeTtl(ttl)) { | ||
| result.ttl = Math.max( | ||
| 1, | ||
| this.getExpirationTimestamp( | ||
| typeof ttl === "string" ? Number(ttl) : ttl | ||
| ) | ||
| ); | ||
| } else if (ttl !== void 0 && (typeof ttl === "string" || ttl > 0)) { | ||
| result.ttl = this.resolveExpiration(ttl); | ||
| } else if (ttl === 0) { | ||
| result.ttl = 0; | ||
| } else if (this.options.stdTTL !== void 0 && this.options.stdTTL !== 0) { | ||
| result.ttl = this.resolveExpiration(this.options.stdTTL); | ||
| } else { | ||
| result.ttl = 0; | ||
| } | ||
| this.store.set(this.formatKey(key), result); | ||
@@ -580,2 +625,29 @@ return true; | ||
| } | ||
| /** | ||
| * Resolves a TTL value to an expiration timestamp, returning 0 (unlimited) if the | ||
| * resolved timestamp is not in the future (e.g. "0s" or a zero-duration string). | ||
| */ | ||
| resolveExpiration(ttl) { | ||
| const timestamp = this.getExpirationTimestamp(ttl); | ||
| if (timestamp <= Date.now()) { | ||
| return 0; | ||
| } | ||
| return timestamp; | ||
| } | ||
| /** | ||
| * Checks whether a TTL value is negative. Handles both numbers and | ||
| * purely numeric strings (e.g. "-1"). | ||
| */ | ||
| isNegativeTtl(ttl) { | ||
| if (typeof ttl === "number") { | ||
| return ttl < 0; | ||
| } | ||
| if (typeof ttl === "string") { | ||
| const num = Number(ttl); | ||
| if (!Number.isNaN(num) && num < 0) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| checkData() { | ||
@@ -582,0 +654,0 @@ for (const [key, value] of this.store.entries()) { |
+40
-4
@@ -211,6 +211,15 @@ import { Hookified } from 'hookified'; | ||
| * Sets a key value pair. It is possible to define a ttl (in seconds). Returns true on success. | ||
| * | ||
| * TTL behavior: | ||
| * - `ttl > 0`: cache expires after the given number of seconds | ||
| * - `ttl === 0`: cache indefinitely (overrides stdTTL) | ||
| * - `ttl < 0`: store the value but it expires immediately on next access (matches original node-cache behavior) | ||
| * - `ttl` omitted/undefined: use `stdTTL` from options (0 = unlimited if stdTTL is 0 or not set) | ||
| * - `ttl` as string: shorthand format like '1h', '30s', '5m', '2d' | ||
| * | ||
| * @param {string | number} key - it will convert the key to a string | ||
| * @param {T} value | ||
| * @param {number | string} [ttl] - this is in seconds and undefined will use the default ttl | ||
| * @returns {boolean} | ||
| * @param {number | string} [ttl] - TTL in seconds. 0 = unlimited, negative = expires immediately, string = shorthand format | ||
| * @returns {boolean} true on success | ||
| * @throws {Error} If the `key` or `ttl` is of an invalid type. | ||
| */ | ||
@@ -220,4 +229,12 @@ set(key: string | number, value: T, ttl?: number | string): boolean; | ||
| * Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success. | ||
| * | ||
| * Each item follows the same TTL behavior as `set()`: | ||
| * - Positive TTL: expires after the given seconds | ||
| * - `0`: cache indefinitely | ||
| * - Negative TTL: stored but expires immediately on next access | ||
| * - Omitted: uses `stdTTL` from options | ||
| * | ||
| * @param {PartialNodeCacheItem<T>[]} data an array of key value pairs with optional ttl | ||
| * @returns {boolean} | ||
| * @returns {boolean} true on success | ||
| * @throws {Error} If `data` is not an array, or if any item has an invalid key or ttl type. | ||
| */ | ||
@@ -260,5 +277,14 @@ mset(data: Array<PartialNodeCacheItem<T>>): boolean; | ||
| * Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used. | ||
| * | ||
| * TTL behavior: | ||
| * - `ttl > 0`: key expires after the given number of seconds | ||
| * - `ttl === 0`: key lives indefinitely (overrides stdTTL) | ||
| * - `ttl < 0`: key expires immediately on next access (matches original node-cache behavior) | ||
| * - `ttl` omitted/undefined: use `stdTTL` from options (0 = unlimited if stdTTL is 0 or not set) | ||
| * - `ttl` as string: shorthand format like '1h', '30s', '5m', '2d' | ||
| * | ||
| * @param {string | number} key if the key is a number it will convert it to a string | ||
| * @param {number | string} [ttl] the ttl in seconds if number, or a shorthand string like '1h' for 1 hour | ||
| * @param {number | string} [ttl] TTL in seconds. 0 = unlimited, negative = expires immediately, string = shorthand format | ||
| * @returns {boolean} true if the key has been found and changed. Otherwise returns false. | ||
| * @throws {Error} If the `ttl` is of an invalid type (must be a number or string). | ||
| */ | ||
@@ -314,2 +340,12 @@ ttl(key: string | number, ttl?: number | string): boolean; | ||
| private getExpirationTimestamp; | ||
| /** | ||
| * Resolves a TTL value to an expiration timestamp, returning 0 (unlimited) if the | ||
| * resolved timestamp is not in the future (e.g. "0s" or a zero-duration string). | ||
| */ | ||
| private resolveExpiration; | ||
| /** | ||
| * Checks whether a TTL value is negative. Handles both numbers and | ||
| * purely numeric strings (e.g. "-1"). | ||
| */ | ||
| private isNegativeTtl; | ||
| private checkData; | ||
@@ -316,0 +352,0 @@ private createError; |
+40
-4
@@ -211,6 +211,15 @@ import { Hookified } from 'hookified'; | ||
| * Sets a key value pair. It is possible to define a ttl (in seconds). Returns true on success. | ||
| * | ||
| * TTL behavior: | ||
| * - `ttl > 0`: cache expires after the given number of seconds | ||
| * - `ttl === 0`: cache indefinitely (overrides stdTTL) | ||
| * - `ttl < 0`: store the value but it expires immediately on next access (matches original node-cache behavior) | ||
| * - `ttl` omitted/undefined: use `stdTTL` from options (0 = unlimited if stdTTL is 0 or not set) | ||
| * - `ttl` as string: shorthand format like '1h', '30s', '5m', '2d' | ||
| * | ||
| * @param {string | number} key - it will convert the key to a string | ||
| * @param {T} value | ||
| * @param {number | string} [ttl] - this is in seconds and undefined will use the default ttl | ||
| * @returns {boolean} | ||
| * @param {number | string} [ttl] - TTL in seconds. 0 = unlimited, negative = expires immediately, string = shorthand format | ||
| * @returns {boolean} true on success | ||
| * @throws {Error} If the `key` or `ttl` is of an invalid type. | ||
| */ | ||
@@ -220,4 +229,12 @@ set(key: string | number, value: T, ttl?: number | string): boolean; | ||
| * Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success. | ||
| * | ||
| * Each item follows the same TTL behavior as `set()`: | ||
| * - Positive TTL: expires after the given seconds | ||
| * - `0`: cache indefinitely | ||
| * - Negative TTL: stored but expires immediately on next access | ||
| * - Omitted: uses `stdTTL` from options | ||
| * | ||
| * @param {PartialNodeCacheItem<T>[]} data an array of key value pairs with optional ttl | ||
| * @returns {boolean} | ||
| * @returns {boolean} true on success | ||
| * @throws {Error} If `data` is not an array, or if any item has an invalid key or ttl type. | ||
| */ | ||
@@ -260,5 +277,14 @@ mset(data: Array<PartialNodeCacheItem<T>>): boolean; | ||
| * Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used. | ||
| * | ||
| * TTL behavior: | ||
| * - `ttl > 0`: key expires after the given number of seconds | ||
| * - `ttl === 0`: key lives indefinitely (overrides stdTTL) | ||
| * - `ttl < 0`: key expires immediately on next access (matches original node-cache behavior) | ||
| * - `ttl` omitted/undefined: use `stdTTL` from options (0 = unlimited if stdTTL is 0 or not set) | ||
| * - `ttl` as string: shorthand format like '1h', '30s', '5m', '2d' | ||
| * | ||
| * @param {string | number} key if the key is a number it will convert it to a string | ||
| * @param {number | string} [ttl] the ttl in seconds if number, or a shorthand string like '1h' for 1 hour | ||
| * @param {number | string} [ttl] TTL in seconds. 0 = unlimited, negative = expires immediately, string = shorthand format | ||
| * @returns {boolean} true if the key has been found and changed. Otherwise returns false. | ||
| * @throws {Error} If the `ttl` is of an invalid type (must be a number or string). | ||
| */ | ||
@@ -314,2 +340,12 @@ ttl(key: string | number, ttl?: number | string): boolean; | ||
| private getExpirationTimestamp; | ||
| /** | ||
| * Resolves a TTL value to an expiration timestamp, returning 0 (unlimited) if the | ||
| * resolved timestamp is not in the future (e.g. "0s" or a zero-duration string). | ||
| */ | ||
| private resolveExpiration; | ||
| /** | ||
| * Checks whether a TTL value is negative. Handles both numbers and | ||
| * purely numeric strings (e.g. "-1"). | ||
| */ | ||
| private isNegativeTtl; | ||
| private checkData; | ||
@@ -316,0 +352,0 @@ private createError; |
+90
-18
@@ -251,25 +251,36 @@ // src/index.ts | ||
| * Sets a key value pair. It is possible to define a ttl (in seconds). Returns true on success. | ||
| * | ||
| * TTL behavior: | ||
| * - `ttl > 0`: cache expires after the given number of seconds | ||
| * - `ttl === 0`: cache indefinitely (overrides stdTTL) | ||
| * - `ttl < 0`: store the value but it expires immediately on next access (matches original node-cache behavior) | ||
| * - `ttl` omitted/undefined: use `stdTTL` from options (0 = unlimited if stdTTL is 0 or not set) | ||
| * - `ttl` as string: shorthand format like '1h', '30s', '5m', '2d' | ||
| * | ||
| * @param {string | number} key - it will convert the key to a string | ||
| * @param {T} value | ||
| * @param {number | string} [ttl] - this is in seconds and undefined will use the default ttl | ||
| * @returns {boolean} | ||
| * @param {number | string} [ttl] - TTL in seconds. 0 = unlimited, negative = expires immediately, string = shorthand format | ||
| * @returns {boolean} true on success | ||
| * @throws {Error} If the `key` or `ttl` is of an invalid type. | ||
| */ | ||
| set(key, value, ttl = 0) { | ||
| set(key, value, ttl) { | ||
| if (typeof key !== "string" && typeof key !== "number") { | ||
| throw this.createError("The key argument has to be of type `string` or `number`. Found: `__key`" /* EKEYTYPE */, key); | ||
| } | ||
| if (ttl && typeof ttl !== "number" && typeof ttl !== "string") { | ||
| if (ttl !== void 0 && typeof ttl !== "number" && typeof ttl !== "string") { | ||
| throw this.createError("The ttl argument has to be a number or a string for shorthand ttl." /* ETTLTYPE */, this.formatKey(key)); | ||
| } | ||
| const keyValue = this.formatKey(key); | ||
| let ttlValue = 0; | ||
| if (this.options.stdTTL) { | ||
| ttlValue = this.getExpirationTimestamp(this.options.stdTTL); | ||
| } | ||
| if (ttl) { | ||
| ttlValue = this.getExpirationTimestamp(ttl); | ||
| } | ||
| let expirationTimestamp = 0; | ||
| if (ttlValue && ttlValue > 0) { | ||
| expirationTimestamp = ttlValue; | ||
| if (this.isNegativeTtl(ttl)) { | ||
| expirationTimestamp = Math.max( | ||
| 1, | ||
| this.getExpirationTimestamp( | ||
| typeof ttl === "string" ? Number(ttl) : ttl | ||
| ) | ||
| ); | ||
| } else if (ttl !== void 0 && (typeof ttl === "string" || ttl > 0)) { | ||
| expirationTimestamp = this.resolveExpiration(ttl); | ||
| } else if (ttl === void 0 && this.options.stdTTL !== void 0 && this.options.stdTTL !== 0) { | ||
| expirationTimestamp = this.resolveExpiration(this.options.stdTTL); | ||
| } | ||
@@ -287,3 +298,3 @@ if (this.options.maxKeys) { | ||
| }); | ||
| this.emit("set", keyValue, value, ttlValue); | ||
| this.emit("set", keyValue, value, expirationTimestamp); | ||
| this._stats.incrementKSize(keyValue); | ||
@@ -296,4 +307,12 @@ this._stats.incrementVSize(value); | ||
| * Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success. | ||
| * | ||
| * Each item follows the same TTL behavior as `set()`: | ||
| * - Positive TTL: expires after the given seconds | ||
| * - `0`: cache indefinitely | ||
| * - Negative TTL: stored but expires immediately on next access | ||
| * - Omitted: uses `stdTTL` from options | ||
| * | ||
| * @param {PartialNodeCacheItem<T>[]} data an array of key value pairs with optional ttl | ||
| * @returns {boolean} | ||
| * @returns {boolean} true on success | ||
| * @throws {Error} If `data` is not an array, or if any item has an invalid key or ttl type. | ||
| */ | ||
@@ -410,11 +429,37 @@ mset(data) { | ||
| * Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used. | ||
| * | ||
| * TTL behavior: | ||
| * - `ttl > 0`: key expires after the given number of seconds | ||
| * - `ttl === 0`: key lives indefinitely (overrides stdTTL) | ||
| * - `ttl < 0`: key expires immediately on next access (matches original node-cache behavior) | ||
| * - `ttl` omitted/undefined: use `stdTTL` from options (0 = unlimited if stdTTL is 0 or not set) | ||
| * - `ttl` as string: shorthand format like '1h', '30s', '5m', '2d' | ||
| * | ||
| * @param {string | number} key if the key is a number it will convert it to a string | ||
| * @param {number | string} [ttl] the ttl in seconds if number, or a shorthand string like '1h' for 1 hour | ||
| * @param {number | string} [ttl] TTL in seconds. 0 = unlimited, negative = expires immediately, string = shorthand format | ||
| * @returns {boolean} true if the key has been found and changed. Otherwise returns false. | ||
| * @throws {Error} If the `ttl` is of an invalid type (must be a number or string). | ||
| */ | ||
| ttl(key, ttl) { | ||
| if (ttl !== void 0 && typeof ttl !== "number" && typeof ttl !== "string") { | ||
| throw this.createError("The ttl argument has to be a number or a string for shorthand ttl." /* ETTLTYPE */, this.formatKey(key)); | ||
| } | ||
| const result = this.store.get(this.formatKey(key)); | ||
| if (result) { | ||
| const ttlValue = ttl ?? this.options.stdTTL; | ||
| result.ttl = this.getExpirationTimestamp(ttlValue); | ||
| if (this.isNegativeTtl(ttl)) { | ||
| result.ttl = Math.max( | ||
| 1, | ||
| this.getExpirationTimestamp( | ||
| typeof ttl === "string" ? Number(ttl) : ttl | ||
| ) | ||
| ); | ||
| } else if (ttl !== void 0 && (typeof ttl === "string" || ttl > 0)) { | ||
| result.ttl = this.resolveExpiration(ttl); | ||
| } else if (ttl === 0) { | ||
| result.ttl = 0; | ||
| } else if (this.options.stdTTL !== void 0 && this.options.stdTTL !== 0) { | ||
| result.ttl = this.resolveExpiration(this.options.stdTTL); | ||
| } else { | ||
| result.ttl = 0; | ||
| } | ||
| this.store.set(this.formatKey(key), result); | ||
@@ -543,2 +588,29 @@ return true; | ||
| } | ||
| /** | ||
| * Resolves a TTL value to an expiration timestamp, returning 0 (unlimited) if the | ||
| * resolved timestamp is not in the future (e.g. "0s" or a zero-duration string). | ||
| */ | ||
| resolveExpiration(ttl) { | ||
| const timestamp = this.getExpirationTimestamp(ttl); | ||
| if (timestamp <= Date.now()) { | ||
| return 0; | ||
| } | ||
| return timestamp; | ||
| } | ||
| /** | ||
| * Checks whether a TTL value is negative. Handles both numbers and | ||
| * purely numeric strings (e.g. "-1"). | ||
| */ | ||
| isNegativeTtl(ttl) { | ||
| if (typeof ttl === "number") { | ||
| return ttl < 0; | ||
| } | ||
| if (typeof ttl === "string") { | ||
| const num = Number(ttl); | ||
| if (!Number.isNaN(num) && num < 0) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| checkData() { | ||
@@ -545,0 +617,0 @@ for (const [key, value] of this.store.entries()) { |
+5
-8
| { | ||
| "name": "@cacheable/node-cache", | ||
| "version": "2.0.1", | ||
| "version": "2.0.2", | ||
| "description": "Simple and Maintained fast NodeJS internal caching", | ||
@@ -43,15 +43,12 @@ "type": "module", | ||
| "devDependencies": { | ||
| "@biomejs/biome": "^2.3.11", | ||
| "@faker-js/faker": "^10.2.0", | ||
| "@types/node": "^25.0.8", | ||
| "@vitest/coverage-v8": "^4.0.17", | ||
| "@types/node": "^24.10.10", | ||
| "rimraf": "^6.1.2", | ||
| "tsup": "^8.5.1", | ||
| "typescript": "^5.9.3", | ||
| "vitest": "^4.0.17" | ||
| "typescript": "^5.9.3" | ||
| }, | ||
| "dependencies": { | ||
| "hookified": "^1.15.0", | ||
| "keyv": "^5.5.5", | ||
| "@cacheable/utils": "^2.3.3" | ||
| "keyv": "^5.6.0", | ||
| "@cacheable/utils": "^2.4.0" | ||
| }, | ||
@@ -58,0 +55,0 @@ "files": [ |
+1
-1
@@ -7,3 +7,3 @@ [<img align="center" src="https://cacheable.org/symbol.svg" alt="Cacheable" />](https://github.com/jaredwray/cacheable) | ||
| [](https://codecov.io/gh/jaredwray/cacheable) | ||
| [](https://codecov.io/gh/jaredwray/cacheable) | ||
| [](https://github.com/jaredwray/cacheable/actions/workflows/tests.yml) | ||
@@ -10,0 +10,0 @@ [](https://www.npmjs.com/package/@cacheable/node-cache) |
84945
13.12%5
-37.5%1652
12.23%Updated
Updated