npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

keyv-caching

v2.0.0

Published

Cache module for Node.js build on top of Keyv

Downloads

43,092

Readme

Logo

test license npm npm

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';

// Memory store by default
const cache = createCache()

// Single store
const cache = createCache({
  stores: [new Keyv()],
})

// Multiple stores
const cache = createCache({
  stores: [
    // Redis store
    new Keyv({
      store: new KeyvRedis('redis://user:pass@localhost:6379'),
    }),

    // Sqlite store
    new Keyv({
      store: new KeyvSqlite('cache.db'),
    }),
  ],
})

// With default ttl and refreshThreshold
const cache = createCache({
  ttl: 10000,
  refreshThreshold: 3000,
})

await cache.set('foo', 'bar')
// => bar

await cache.get('foo')
// => bar

await cache.del('foo')
// => true

await cache.get('foo')
// => null

await cache.wrap('key', () => 'value')
// => 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')

// expires after 5 seconds
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')
// => value

await cache.get('foo')
// => null

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')
// => value

await cache.del('key')

await cache.get('key')
// => null

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')
// => value 1
await cache.get('key-2')
// => value 2

await cache.clear()

await cache.get('key-1')
// => null
await cache.get('key-2')
// => null

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)
// call function then save the result to cache
// =>  1

await cache.wrap('key', () => 2, 5000, 3000)
// return data from cache, function will not be called again
// => 1

// wait 3 seconds
await sleep(3000)

await cache.wrap('key', () => 2, 5000, 3000)
// return data from cache, call function in background and save the result to cache
// =>  1

await cache.wrap('key', () => 3, 5000, 3000)
// return data from cache, function will not be called
// =>  2

await cache.wrap('error', () => {
  throw new Error('failed')
})
// => error

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 }) => {
	// ... do something ...
})

del

Fired when a key has been removed manually.

cache.on('del', ({ key, error }) => {
	// ... do something ...
})

clear

Fired when the cache has been flushed.

cache.on('clear', (error) => {
  if (error) {
    // ... do something ...
  }
})

refresh

Fired when the cache has been refreshed in the background.

cache.on('refresh', ({ key, value, error }) => {
  if (error) {
    // ... do something ...
  }
})

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.