Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

cacheable

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cacheable - npm Package Compare versions

Comparing version
1.10.0
to
1.10.1
+47
-17
dist/index.cjs

@@ -42,2 +42,3 @@ "use strict";

createKeyv: () => createKeyv,
getOrSet: () => getOrSet,
shorthandToMilliseconds: () => shorthandToMilliseconds,

@@ -65,5 +66,3 @@ shorthandToTime: () => shorthandToTime,

if (!match) {
throw new Error(
`Unsupported time format: "${shorthand}". Use 'ms', 's', 'm', 'h', 'hr', or 'd'.`
);
throw new Error(`Unsupported time format: "${shorthand}". Use 'ms', 's', 'm', 'h', 'hr', or 'd'.`);
}

@@ -112,3 +111,3 @@ const [, value, unit] = match;

var shorthandToTime = (shorthand, fromDate) => {
fromDate ||= /* @__PURE__ */ new Date();
fromDate ??= /* @__PURE__ */ new Date();
const milliseconds = shorthandToMilliseconds(shorthand);

@@ -218,3 +217,6 @@ if (milliseconds === void 0) {

return function(...arguments_) {
const cacheKey = createWrapKey(function_, arguments_, keyPrefix);
let cacheKey = createWrapKey(function_, arguments_, keyPrefix);
if (options.createKey) {
cacheKey = options.createKey(function_, arguments_, options);
}
let value = cache.get(cacheKey);

@@ -236,10 +238,11 @@ if (value === void 0) {

async function getOrSet(key, function_, options) {
let value = await options.cache.get(key);
const keyString = typeof key === "function" ? key(options) : key;
let value = await options.cache.get(keyString);
if (value === void 0) {
const cacheId = options.cacheId ?? "default";
const coalesceKey = `${cacheId}::${key}`;
const coalesceKey = `${cacheId}::${keyString}`;
value = await coalesceAsync(coalesceKey, async () => {
try {
const result = await function_();
await options.cache.set(key, result, options.ttl);
await options.cache.set(keyString, result, options.ttl);
return result;

@@ -249,4 +252,7 @@ } catch (error) {

if (options.cacheErrors) {
await options.cache.set(key, error, options.ttl);
await options.cache.set(keyString, error, options.ttl);
}
if (options.throwErrors) {
throw error;
}
}

@@ -260,3 +266,6 @@ });

return async function(...arguments_) {
const cacheKey = createWrapKey(function_, arguments_, keyPrefix);
let cacheKey = createWrapKey(function_, arguments_, keyPrefix);
if (options.createKey) {
cacheKey = options.createKey(function_, arguments_, options);
}
return cache.getOrSet(cacheKey, async () => function_(...arguments_), options);

@@ -319,3 +328,3 @@ };

this.head = node;
this.tail ||= node;
this.tail ??= node;
}

@@ -1428,3 +1437,7 @@ // Get the oldest node (tail)

setPrimary(primary) {
this._primary = primary instanceof import_keyv2.Keyv ? primary : new import_keyv2.Keyv(primary);
if (this.isKeyvInstance(primary)) {
this._primary = primary;
} else {
this._primary = new import_keyv2.Keyv(primary);
}
this._primary.on("error", (error) => {

@@ -1440,3 +1453,7 @@ this.emit("error" /* ERROR */, error);

setSecondary(secondary) {
this._secondary = secondary instanceof import_keyv2.Keyv ? secondary : new import_keyv2.Keyv(secondary);
if (this.isKeyvInstance(secondary)) {
this._secondary = secondary;
} else {
this._secondary = new import_keyv2.Keyv(secondary);
}
this._secondary.on("error", (error) => {

@@ -1446,2 +1463,9 @@ this.emit("error" /* ERROR */, error);

}
isKeyvInstance(keyv) {
if (keyv instanceof import_keyv2.Keyv) {
return true;
}
const keyvMethods = ["generateIterator", "get", "getMany", "set", "setMany", "delete", "deleteMany", "has", "hasMany", "clear", "disconnect", "serialize", "deserialize"];
return keyvMethods.every((method) => typeof keyv[method] === "function");
}
getNameSpace() {

@@ -1504,3 +1528,6 @@ if (typeof this._namespace === "function") {

const cascadeTtl = getCascadingTtl(this._ttl, this._primary.ttl);
const expires = secondaryResults[i].expires;
let { expires } = secondaryResults[i];
if (expires === null) {
expires = void 0;
}
const ttl = calculateTtlFromExpiration(cascadeTtl, expires);

@@ -1761,5 +1788,6 @@ const setItem = { key, value: result[i].value, ttl };

*
* @param {string} key - The key to retrieve or set in the cache.
* @param {GetOrSetKey} key - The key to retrieve or set in the cache. This can also be a function that returns a string key.
* If a function is provided, it will be called with the cache options to generate the key.
* @param {() => Promise<T>} function_ - The asynchronous function that computes the value to be cached if the key does not exist.
* @param {WrapFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
* @param {GetOrSetFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
* @return {Promise<T | undefined>} - A promise that resolves to the cached or newly computed value, or undefined if an error occurs and caching is not configured for errors.

@@ -1772,3 +1800,4 @@ */

ttl: options?.ttl ?? this._ttl,
cacheErrors: options?.cacheErrors
cacheErrors: options?.cacheErrors,
throwErrors: options?.throwErrors
};

@@ -1845,2 +1874,3 @@ return getOrSet(key, function_, getOrSetOptions);

createKeyv,
getOrSet,
shorthandToMilliseconds,

@@ -1847,0 +1877,0 @@ shorthandToTime,

@@ -112,9 +112,17 @@ import { KeyvStoreAdapter, StoredData, Keyv, StoredDataRaw } from 'keyv';

type GetOrSetKey = string | ((options?: GetOrSetOptions) => string);
type GetOrSetFunctionOptions = {
ttl?: number | string;
cacheErrors?: boolean;
throwErrors?: boolean;
};
type GetOrSetOptions = GetOrSetFunctionOptions & {
cacheId?: string;
cache: Cacheable;
};
type CreateWrapKey = (function_: AnyFunction, arguments_: any[], options?: WrapFunctionOptions) => string;
type WrapFunctionOptions = {
ttl?: number | string;
keyPrefix?: string;
createKey?: CreateWrapKey;
cacheErrors?: boolean;

@@ -131,2 +139,3 @@ cacheId?: string;

declare function wrapSync<T>(function_: AnyFunction, options: WrapSyncOptions): AnyFunction;
declare function getOrSet<T>(key: GetOrSetKey, function_: () => Promise<T>, options: GetOrSetOptions): Promise<T | undefined>;
declare function wrap<T>(function_: AnyFunction, options: WrapOptions): AnyFunction;

@@ -616,2 +625,3 @@

setSecondary(secondary: Keyv | KeyvStoreAdapter): void;
isKeyvInstance(keyv: any): boolean;
getNameSpace(): string | undefined;

@@ -733,8 +743,9 @@ /**

*
* @param {string} key - The key to retrieve or set in the cache.
* @param {GetOrSetKey} key - The key to retrieve or set in the cache. This can also be a function that returns a string key.
* If a function is provided, it will be called with the cache options to generate the key.
* @param {() => Promise<T>} function_ - The asynchronous function that computes the value to be cached if the key does not exist.
* @param {WrapFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
* @param {GetOrSetFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
* @return {Promise<T | undefined>} - A promise that resolves to the cached or newly computed value, or undefined if an error occurs and caching is not configured for errors.
*/
getOrSet<T>(key: string, function_: () => Promise<T>, options?: GetOrSetFunctionOptions): Promise<T | undefined>;
getOrSet<T>(key: GetOrSetKey, function_: () => Promise<T>, options?: GetOrSetFunctionOptions): Promise<T | undefined>;
/**

@@ -755,2 +766,2 @@ * Will hash an object using the specified algorithm. The default algorithm is 'sha256'.

export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableMemoryOptions, type CacheableOptions, CacheableStats, KeyvCacheableMemory, type WrapOptions, type WrapSyncOptions, createKeyv, shorthandToMilliseconds, shorthandToTime, wrap, wrapSync };
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableMemoryOptions, type CacheableOptions, CacheableStats, type GetOrSetFunctionOptions, type GetOrSetKey, type GetOrSetOptions, KeyvCacheableMemory, type WrapOptions, type WrapSyncOptions, createKeyv, getOrSet, shorthandToMilliseconds, shorthandToTime, wrap, wrapSync };

@@ -112,9 +112,17 @@ import { KeyvStoreAdapter, StoredData, Keyv, StoredDataRaw } from 'keyv';

type GetOrSetKey = string | ((options?: GetOrSetOptions) => string);
type GetOrSetFunctionOptions = {
ttl?: number | string;
cacheErrors?: boolean;
throwErrors?: boolean;
};
type GetOrSetOptions = GetOrSetFunctionOptions & {
cacheId?: string;
cache: Cacheable;
};
type CreateWrapKey = (function_: AnyFunction, arguments_: any[], options?: WrapFunctionOptions) => string;
type WrapFunctionOptions = {
ttl?: number | string;
keyPrefix?: string;
createKey?: CreateWrapKey;
cacheErrors?: boolean;

@@ -131,2 +139,3 @@ cacheId?: string;

declare function wrapSync<T>(function_: AnyFunction, options: WrapSyncOptions): AnyFunction;
declare function getOrSet<T>(key: GetOrSetKey, function_: () => Promise<T>, options: GetOrSetOptions): Promise<T | undefined>;
declare function wrap<T>(function_: AnyFunction, options: WrapOptions): AnyFunction;

@@ -616,2 +625,3 @@

setSecondary(secondary: Keyv | KeyvStoreAdapter): void;
isKeyvInstance(keyv: any): boolean;
getNameSpace(): string | undefined;

@@ -733,8 +743,9 @@ /**

*
* @param {string} key - The key to retrieve or set in the cache.
* @param {GetOrSetKey} key - The key to retrieve or set in the cache. This can also be a function that returns a string key.
* If a function is provided, it will be called with the cache options to generate the key.
* @param {() => Promise<T>} function_ - The asynchronous function that computes the value to be cached if the key does not exist.
* @param {WrapFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
* @param {GetOrSetFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
* @return {Promise<T | undefined>} - A promise that resolves to the cached or newly computed value, or undefined if an error occurs and caching is not configured for errors.
*/
getOrSet<T>(key: string, function_: () => Promise<T>, options?: GetOrSetFunctionOptions): Promise<T | undefined>;
getOrSet<T>(key: GetOrSetKey, function_: () => Promise<T>, options?: GetOrSetFunctionOptions): Promise<T | undefined>;
/**

@@ -755,2 +766,2 @@ * Will hash an object using the specified algorithm. The default algorithm is 'sha256'.

export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableMemoryOptions, type CacheableOptions, CacheableStats, KeyvCacheableMemory, type WrapOptions, type WrapSyncOptions, createKeyv, shorthandToMilliseconds, shorthandToTime, wrap, wrapSync };
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableMemoryOptions, type CacheableOptions, CacheableStats, type GetOrSetFunctionOptions, type GetOrSetKey, type GetOrSetOptions, KeyvCacheableMemory, type WrapOptions, type WrapSyncOptions, createKeyv, getOrSet, shorthandToMilliseconds, shorthandToTime, wrap, wrapSync };

@@ -18,5 +18,3 @@ // src/index.ts

if (!match) {
throw new Error(
`Unsupported time format: "${shorthand}". Use 'ms', 's', 'm', 'h', 'hr', or 'd'.`
);
throw new Error(`Unsupported time format: "${shorthand}". Use 'ms', 's', 'm', 'h', 'hr', or 'd'.`);
}

@@ -65,3 +63,3 @@ const [, value, unit] = match;

var shorthandToTime = (shorthand, fromDate) => {
fromDate ||= /* @__PURE__ */ new Date();
fromDate ??= /* @__PURE__ */ new Date();
const milliseconds = shorthandToMilliseconds(shorthand);

@@ -173,3 +171,6 @@ if (milliseconds === void 0) {

return function(...arguments_) {
const cacheKey = createWrapKey(function_, arguments_, keyPrefix);
let cacheKey = createWrapKey(function_, arguments_, keyPrefix);
if (options.createKey) {
cacheKey = options.createKey(function_, arguments_, options);
}
let value = cache.get(cacheKey);

@@ -191,10 +192,11 @@ if (value === void 0) {

async function getOrSet(key, function_, options) {
let value = await options.cache.get(key);
const keyString = typeof key === "function" ? key(options) : key;
let value = await options.cache.get(keyString);
if (value === void 0) {
const cacheId = options.cacheId ?? "default";
const coalesceKey = `${cacheId}::${key}`;
const coalesceKey = `${cacheId}::${keyString}`;
value = await coalesceAsync(coalesceKey, async () => {
try {
const result = await function_();
await options.cache.set(key, result, options.ttl);
await options.cache.set(keyString, result, options.ttl);
return result;

@@ -204,4 +206,7 @@ } catch (error) {

if (options.cacheErrors) {
await options.cache.set(key, error, options.ttl);
await options.cache.set(keyString, error, options.ttl);
}
if (options.throwErrors) {
throw error;
}
}

@@ -215,3 +220,6 @@ });

return async function(...arguments_) {
const cacheKey = createWrapKey(function_, arguments_, keyPrefix);
let cacheKey = createWrapKey(function_, arguments_, keyPrefix);
if (options.createKey) {
cacheKey = options.createKey(function_, arguments_, options);
}
return cache.getOrSet(cacheKey, async () => function_(...arguments_), options);

@@ -274,3 +282,3 @@ };

this.head = node;
this.tail ||= node;
this.tail ??= node;
}

@@ -1386,3 +1394,7 @@ // Get the oldest node (tail)

setPrimary(primary) {
this._primary = primary instanceof Keyv2 ? primary : new Keyv2(primary);
if (this.isKeyvInstance(primary)) {
this._primary = primary;
} else {
this._primary = new Keyv2(primary);
}
this._primary.on("error", (error) => {

@@ -1398,3 +1410,7 @@ this.emit("error" /* ERROR */, error);

setSecondary(secondary) {
this._secondary = secondary instanceof Keyv2 ? secondary : new Keyv2(secondary);
if (this.isKeyvInstance(secondary)) {
this._secondary = secondary;
} else {
this._secondary = new Keyv2(secondary);
}
this._secondary.on("error", (error) => {

@@ -1404,2 +1420,9 @@ this.emit("error" /* ERROR */, error);

}
isKeyvInstance(keyv) {
if (keyv instanceof Keyv2) {
return true;
}
const keyvMethods = ["generateIterator", "get", "getMany", "set", "setMany", "delete", "deleteMany", "has", "hasMany", "clear", "disconnect", "serialize", "deserialize"];
return keyvMethods.every((method) => typeof keyv[method] === "function");
}
getNameSpace() {

@@ -1462,3 +1485,6 @@ if (typeof this._namespace === "function") {

const cascadeTtl = getCascadingTtl(this._ttl, this._primary.ttl);
const expires = secondaryResults[i].expires;
let { expires } = secondaryResults[i];
if (expires === null) {
expires = void 0;
}
const ttl = calculateTtlFromExpiration(cascadeTtl, expires);

@@ -1719,5 +1745,6 @@ const setItem = { key, value: result[i].value, ttl };

*
* @param {string} key - The key to retrieve or set in the cache.
* @param {GetOrSetKey} key - The key to retrieve or set in the cache. This can also be a function that returns a string key.
* If a function is provided, it will be called with the cache options to generate the key.
* @param {() => Promise<T>} function_ - The asynchronous function that computes the value to be cached if the key does not exist.
* @param {WrapFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
* @param {GetOrSetFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
* @return {Promise<T | undefined>} - A promise that resolves to the cached or newly computed value, or undefined if an error occurs and caching is not configured for errors.

@@ -1730,3 +1757,4 @@ */

ttl: options?.ttl ?? this._ttl,
cacheErrors: options?.cacheErrors
cacheErrors: options?.cacheErrors,
throwErrors: options?.throwErrors
};

@@ -1802,2 +1830,3 @@ return getOrSet(key, function_, getOrSetOptions);

createKeyv,
getOrSet,
shorthandToMilliseconds,

@@ -1804,0 +1833,0 @@ shorthandToTime,

{
"name": "cacheable",
"version": "1.10.0",
"version": "1.10.1",
"description": "High Performance Layer 1 / Layer 2 Caching with Keyv Storage",

@@ -24,16 +24,18 @@ "type": "module",

"devDependencies": {
"@faker-js/faker": "^9.7.0",
"@keyv/redis": "^4.4.0",
"@types/node": "^22.15.3",
"@vitest/coverage-v8": "^3.1.3",
"@faker-js/faker": "^9.8.0",
"@keyv/redis": "^4.5.0",
"@keyv/valkey": "^1.0.6",
"@types/eslint": "^9.6.1",
"@types/node": "^24.0.7",
"@vitest/coverage-v8": "^3.2.4",
"lru-cache": "^11.1.0",
"rimraf": "^6.0.1",
"tsup": "^8.4.0",
"tsup": "^8.5.0",
"typescript": "^5.8.3",
"vitest": "^3.1.3",
"xo": "^0.60.0"
"vitest": "^3.2.4",
"xo": "^1.1.1"
},
"dependencies": {
"hookified": "^1.8.2",
"keyv": "^5.3.3"
"hookified": "^1.10.0",
"keyv": "^5.3.4"
},

@@ -74,5 +76,5 @@ "keywords": [

"test": "xo --fix && vitest run --coverage",
"test:ci": "xo && vitest run",
"test:ci": "xo && vitest run --coverage",
"clean": "rimraf ./dist ./coverage ./node_modules"
}
}

@@ -47,2 +47,3 @@ [<img align="center" src="https://cacheable.org/logo.svg" alt="Cacheable" />](https://github.com/jaredwray/cacheable)

* [Wrap / Memoization for Sync and Async Functions](#wrap--memoization-for-sync-and-async-functions)
* [Get Or Set Memoization Function](#get-or-set-memoization-function)
* [How to Contribute](#how-to-contribute)

@@ -359,3 +360,3 @@ * [License and Copyright](#license-and-copyright)

* `wrap(function, WrapOptions)`: Wraps an `async` function in a cache.
* `getOrSet(key, valueFunction, ttl?)`: Gets a value from cache or sets it if not found using the provided function.
* `getOrSet(GetOrSetKey, valueFunction, GetOrSetFunctionOptions)`: Gets a value from cache or sets it if not found using the provided function.
* `disconnect()`: Disconnects from the cache stores.

@@ -619,2 +620,63 @@ * `onHook(hook, callback)`: Sets a hook.

If you would like to generate your own key for the wrapped function you can set the `createKey` property in the `wrap()` options. This is useful if you want to generate a key based on the arguments of the function or any other criteria.
```javascript
const cache = new Cacheable();
const options: WrapOptions = {
cache,
keyPrefix: 'test',
createKey: (function_, arguments_, options: WrapOptions) => `customKey:${options?.keyPrefix}:${arguments_[0]}`,
};
const wrapped = wrap((argument: string) => `Result for ${argument}`, options);
const result1 = await wrapped('arg1');
const result2 = await wrapped('arg1'); // Should hit the cache
console.log(result1); // Result for arg1
console.log(result2); // Result for arg1 (from cache)
```
We will pass in the `function` that is being wrapped, the `arguments` passed to the function, and the `options` used to wrap the function. You can then use these to generate a custom key for the cache.
# Get Or Set Memoization Function
The `getOrSet` method provides a convenient way to implement the cache-aside pattern. It attempts to retrieve a value from cache, and if not found, calls the provided function to compute the value and store it in cache before returning it. Here are the options:
```typescript
export type GetOrSetFunctionOptions = {
ttl?: number | string;
cacheErrors?: boolean;
throwErrors?: boolean;
};
```
Here is an example of how to use the `getOrSet` method:
```javascript
import { Cacheable } from 'cacheable';
const cache = new Cacheable();
// Use getOrSet to fetch user data
const function_ = async () => Math.random() * 100;
const value = await cache.getOrSet('randomValue', function_, { ttl: '1h' });
console.log(value); // e.g. 42.123456789
```
You can also use a function to compute the key for the function:
```javascript
import { Cacheable, GetOrSetOptions } from 'cacheable';
const cache = new Cacheable();
// Function to generate a key based on options
const generateKey = (options?: GetOrSetOptions) => {
return `custom_key_:${options?.cacheId || 'default'}`;
};
const function_ = async () => Math.random() * 100;
const value = await cache.getOrSet(generateKey(), function_, { ttl: '1h' });
```
# How to Contribute

@@ -621,0 +683,0 @@