cache-manager
Advanced tools
Comparing version 5.2.3 to 5.2.4
import { MemoryCache, MemoryConfig } from './stores'; | ||
export type Config = { | ||
ttl?: Milliseconds; | ||
refreshThreshold?: Milliseconds; | ||
isCacheable?: (val: unknown) => boolean; | ||
@@ -27,2 +28,3 @@ }; | ||
export type CachingConfig<T> = MemoryConfig | StoreConfig | FactoryConfig<T>; | ||
export type WrapTTL<T> = Milliseconds | ((v: T) => Milliseconds); | ||
export type Cache<S extends Store = Store> = { | ||
@@ -33,3 +35,3 @@ set: (key: string, value: unknown, ttl?: Milliseconds) => Promise<void>; | ||
reset: () => Promise<void>; | ||
wrap<T>(key: string, fn: () => Promise<T>, ttl?: Milliseconds): Promise<T>; | ||
wrap<T>(key: string, fn: () => Promise<T>, ttl?: WrapTTL<T>): Promise<T>; | ||
store: S; | ||
@@ -36,0 +38,0 @@ }; |
@@ -40,5 +40,13 @@ "use strict"; | ||
const result = yield fn(); | ||
yield store.set(key, result, ttl); | ||
const cacheTTL = typeof ttl === 'function' ? ttl(result) : ttl; | ||
yield store.set(key, result, cacheTTL); | ||
return result; | ||
} | ||
else if (args === null || args === void 0 ? void 0 : args.refreshThreshold) { | ||
const cacheTTL = typeof ttl === 'function' ? ttl(value) : ttl; | ||
const remainingTtl = yield store.ttl(key); | ||
if (remainingTtl < args.refreshThreshold) { | ||
fn().then((result) => store.set(key, result, cacheTTL)); | ||
} | ||
} | ||
return value; | ||
@@ -45,0 +53,0 @@ }), |
@@ -50,7 +50,10 @@ "use strict"; | ||
const result = yield fn(); | ||
yield set(key, result, ttl); | ||
const cacheTTL = typeof ttl === 'function' ? ttl(result) : ttl; | ||
yield set(key, result, cacheTTL); | ||
return result; | ||
} | ||
else { | ||
yield Promise.all(caches.slice(0, i).map((cache) => cache.set(key, value, ttl))); | ||
const cacheTTL = typeof ttl === 'function' ? ttl(value) : ttl; | ||
Promise.all(caches.slice(0, i).map((cache) => cache.set(key, value, cacheTTL))).then(); | ||
caches[i].wrap(key, fn, ttl).then(); // call wrap for store for internal refreshThreshold logic, see: src/caching.ts caching.wrap | ||
} | ||
@@ -57,0 +60,0 @@ return value; |
{ | ||
"name": "cache-manager", | ||
"version": "5.2.3", | ||
"version": "5.2.4", | ||
"description": "Cache module for Node.js", | ||
@@ -10,2 +10,13 @@ "main": "dist/index.js", | ||
], | ||
"scripts": { | ||
"build": "rm -rf dist && tsc -p tsconfig.build.json", | ||
"test": "vitest", | ||
"release": "yarn check && yarn test -- --run && yarn build", | ||
"fix": "yarn lint && yarn fmt", | ||
"check": "yarn lint:check && yarn fmt:check", | ||
"lint": "eslint --cache --max-warnings 0 --fix '**/*.{ts,mts,js}'", | ||
"fmt": "prettier --write '**/*.{md,json,yml}'", | ||
"lint:check": "eslint --cache --max-warnings 0 '**/*.{ts,mts,js}'", | ||
"fmt:check": "prettier --check '**/*.{md,json,yml}'" | ||
}, | ||
"repository": { | ||
@@ -24,2 +35,6 @@ "type": "git", | ||
{ | ||
"name": "Jared Wray", | ||
"email": "me@jaredwray.com" | ||
}, | ||
{ | ||
"name": "Bryan Donovan" | ||
@@ -35,24 +50,19 @@ }, | ||
"lodash.clonedeep": "^4.5.0", | ||
"lru-cache": "^9.1.2" | ||
"lru-cache": "^10.0.1" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "17.6.5", | ||
"@commitlint/config-conventional": "17.6.5", | ||
"@faker-js/faker": "8.0.2", | ||
"@release-it/conventional-changelog": "5.1.1", | ||
"@faker-js/faker": "8.1.0", | ||
"@types/lodash.clonedeep": "4.5.7", | ||
"@types/node": "20.3.1", | ||
"@typescript-eslint/eslint-plugin": "5.59.11", | ||
"@typescript-eslint/parser": "5.59.11", | ||
"@vitest/coverage-v8": "0.32.0", | ||
"dotenv-cli": "7.2.1", | ||
"eslint": "8.42.0", | ||
"eslint-config-prettier": "8.8.0", | ||
"eslint-plugin-prettier": "4.2.1", | ||
"husky": "8.0.3", | ||
"lint-staged": "13.2.2", | ||
"prettier": "2.8.8", | ||
"release-it": "15.11.0", | ||
"typescript": "5.1.3", | ||
"vitest": "0.32.0" | ||
"@types/node": "20.8.2", | ||
"@typescript-eslint/eslint-plugin": "6.7.4", | ||
"@typescript-eslint/parser": "6.7.4", | ||
"@vitest/coverage-v8": "0.34.6", | ||
"dotenv-cli": "7.3.0", | ||
"eslint": "8.50.0", | ||
"eslint-config-prettier": "9.0.0", | ||
"eslint-plugin-prettier": "5.0.0", | ||
"lint-staged": "14.0.1", | ||
"prettier": "3.0.3", | ||
"typescript": "5.2.2", | ||
"vitest": "0.34.6" | ||
}, | ||
@@ -62,14 +72,3 @@ "lint-staged": { | ||
"*.{md,json,yml}": "prettier --write" | ||
}, | ||
"scripts": { | ||
"build": "rm -rf dist && tsc -p tsconfig.build.json", | ||
"test": "vitest", | ||
"release": "pnpm check && pnpm test -- --run && pnpm build && dotenv release-it", | ||
"fix": "pnpm lint && pnpm fmt", | ||
"check": "pnpm lint:check && pnpm fmt:check", | ||
"lint": "eslint --cache --max-warnings 0 --fix '**/*.{ts,mts,js}'", | ||
"fmt": "prettier --write '**/*.{md,json,yml}'", | ||
"lint:check": "eslint --cache --max-warnings 0 '**/*.{ts,mts,js}'", | ||
"fmt:check": "prettier --check '**/*.{md,json,yml}'" | ||
} | ||
} | ||
} |
@@ -1,2 +0,7 @@ | ||
# node-cache-manager [![npm version](https://badge.fury.io/js/cache-manager.svg)](https://www.npmjs.com/package/cache-manager) [![codecov](https://codecov.io/gh/node-cache-manager/node-cache-manager/branch/master/graph/badge.svg?token=ZV3G5IFigq)](https://codecov.io/gh/node-cache-manager/node-cache-manager) | ||
# node-cache-manager | ||
[![codecov](https://codecov.io/gh/node-cache-manager/node-cache-manager/branch/master/graph/badge.svg?token=ZV3G5IFigq)](https://codecov.io/gh/node-cache-manager/node-cache-manager) | ||
[![tests](https://github.com/node-cache-manager/node-cache-manager/actions/workflows/test.yml/badge.svg)](https://github.com/node-cache-manager/node-cache-manager/actions/workflows/test.yml) | ||
[![license](https://img.shields.io/github/license/node-cache-manager/node-cache-manager)](https://github.com/node-cache-manager/node-cache-manager/blob/master/LICENSE) | ||
[![npm](https://img.shields.io/npm/dm/cache-manager)](https://npmjs.com/package/cache-manager) | ||
![npm](https://img.shields.io/npm/v/cache-manager) | ||
@@ -118,3 +123,3 @@ # Flexible NodeJS cache module | ||
// - all caches has been fetched | ||
console.log(await multiCache.mget('key', 'key2'); | ||
console.log(await multiCache.mget('key', 'key2')); | ||
// >> ['bar', 'bar2'] | ||
@@ -124,3 +129,2 @@ | ||
await multiCache.mdel('foo', 'foo2'); | ||
``` | ||
@@ -130,2 +134,29 @@ | ||
### Refresh cache keys in background | ||
Both the `caching` and `multicaching` modules support a mechanism to refresh expiring cache keys in background when using the `wrap` function. | ||
This is done by adding a `refreshThreshold` attribute while creating the caching store. | ||
If `refreshThreshold` is set and after retrieving a value from cache the TTL will be checked. | ||
If the remaining TTL is less than `refreshThreshold`, the system will update the value asynchronously, | ||
following same rules as standard fetching. In the meantime, the system will return the old value until expiration. | ||
NOTES: | ||
* In case of multicaching, the store that will be checked for refresh is the one where the key will be found first (highest priority). | ||
* If the threshold is low and the worker function is slow, the key may expire and you may encounter a racing condition with updating values. | ||
* The background refresh mechanism currently does not support providing multiple keys to `wrap` function. | ||
For example, pass the refreshThreshold to `caching` like this: | ||
```typescript | ||
const memoryCache = await caching('memory', { | ||
max: 100, | ||
ttl: 10 * 1000 /*milliseconds*/, | ||
refreshThreshold: 3 * 1000 /*milliseconds*/, | ||
}); | ||
``` | ||
When a value will be retrieved from Redis with a TTL minor than 3sec, the value will be updated in the background. | ||
## Store Engines | ||
@@ -132,0 +163,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79116
14
20
352
201
1
+ Addedlru-cache@10.4.3(transitive)
- Removedlru-cache@9.1.2(transitive)
Updatedlru-cache@^10.0.1