

Simple and fast NodeJS caching module.
Folk and modify from cache-manager.
A cache module for NodeJS that allows easy wrapping of functions in cache, tiered caches, and a consistent interface.
- Made with Typescript and compatible with ESModules.
- Easy way to wrap any function in cache, supports a mechanism to refresh expiring cache keys in background.
- Tiered caches -- data gets stored in each cache and fetched from the highest priority cache(s) first.
- Use with any Keyv-compatible storage adapter.
- 100% test coverage via vitest.
Table of Contents
Installation
yarn add keyv-caching
By default, everything is stored in memory; you can optionally also install a storage adapter; choose one from any of the storage adapters supported by Keyv:
yarn add @keyv/redis
yarn add @keyv/memcache
yarn add @keyv/mongo
yarn add @keyv/sqlite
yarn add @keyv/postgres
yarn add @keyv/mysql
yarn add @keyv/etcd
Please read Keyv document for more information.
Quick start
import Keyv from 'keyv'
import KeyvRedis from '@keyv/redis'
import KeyvSqlite from '@keyv/sqlite'
import { createCache } from 'keyv-caching';
const cache = createCache()
const cache = createCache({
stores: [new Keyv()],
})
const cache = createCache({
stores: [
new Keyv({
store: new KeyvRedis('redis://user:pass@localhost:6379'),
}),
new Keyv({
store: new KeyvSqlite('cache.db'),
}),
],
})
const cache = createCache({
ttl: 10000,
refreshThreshold: 3000,
})
await cache.set('foo', 'bar')
await cache.get('foo')
await cache.del('foo')
await cache.get('foo')
await cache.wrap('key', () => 'value')
Options
-
stores?: Keyv[]
List of Keyv instance. Please refer to the Keyv document for more information.
-
ttl?: number - Default time to live in milliseconds.
The time to live in milliseconds. This is the maximum amount of time that an item can be in the cache before it is removed.
-
refreshThreshold?: number - Default refreshThreshold in milliseconds.
If the remaining TTL is less than refreshThreshold, the system will update the value asynchronously in background.
Methods
set
set(key, value, [ttl]): Promise<value>
Sets a key value pair. It is possible to define a ttl (in miliseconds). An error will be throw on any failed
await cache.set('key-1', 'value 1')
await cache.set('key 2', 'value 2', 5000)
See unit tests in test/set.test.ts
for more information.
get
get(key): Promise<value>
Gets a saved value from the cache. Returns a null if not found or expired. If the value was found it returns the value.
await cache.set('key', 'value')
await cache.get('key')
await cache.get('foo')
See unit tests in test/get.test.ts
for more information.
del
del(key): Promise<true>
Delete a key, an error will be throw on any failed.
await cache.set('key', 'value')
await cache.get('key')
await cache.del('key')
await cache.get('key')
See unit tests in test/del.test.ts
for more information.
clear
clear(): Promise<true>
Flush all data, an error will be throw on any failed.
await cache.set('key-1', 'value 1')
await cache.set('key-2', 'value 2')
await cache.get('key-1')
await cache.get('key-2')
await cache.clear()
await cache.get('key-1')
await cache.get('key-2')
See unit tests in test/clear.test.ts
for more information.
wrap
wrap(key, fn: async () => value, [ttl], [refreshThreshold]): Promise<value>
Wraps a function in cache. The first time the function is run, its results are stored in cache so subsequent calls retrieve from cache instead of calling the function.
If refreshThreshold
is set and the remaining TTL is less than refreshThreshold
, the system will update the value asynchronously. In the meantime, the system will return the old value until expiration.
await cache.wrap('key', () => 1, 5000, 3000)
await cache.wrap('key', () => 2, 5000, 3000)
await sleep(3000)
await cache.wrap('key', () => 2, 5000, 3000)
await cache.wrap('key', () => 3, 5000, 3000)
await cache.wrap('error', () => {
throw new Error('failed')
})
NOTES:
- 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.
- If no
ttl
is set for the key, the refresh mechanism will not be triggered.
See unit tests in test/wrap.test.ts
for more information.
Events
set
Fired when a key has been added or changed.
cache.on('set', ({ key, value, error }) => {
})
del
Fired when a key has been removed manually.
cache.on('del', ({ key, error }) => {
})
clear
Fired when the cache has been flushed.
cache.on('clear', (error) => {
if (error) {
}
})
refresh
Fired when the cache has been refreshed in the background.
cache.on('refresh', ({ key, value, error }) => {
if (error) {
}
})
See unit tests in test/events.test.ts
for more information.
Contribute
If you would like to contribute to the project, please read how to contribute here CONTRIBUTING.md.
License
Released under the MIT license.