1.0.8 • Published 10 months ago

better-memory-cache v1.0.8

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

better-memory-cache

Version Min size Minzip size License Codecov

A lightweight, dependency-free memory cache written in Typescript, with support for stale-while-revalidate, background refresh, LRU and FIFO strategy.

Install

npm install --save better-memory-cache

Usage

import Cache, { HOUR, MINUTE, SECOND } from 'better-memory-cache';
// Or using CommonJS require:
// const { default: Cache, HOUR, MINUTE, SECOND } = require('better-memory-cache');

const fruitCache = new Cache<string>({
    namespace: 'fruits',
    expireAfterMs: 1 * HOUR,
    staleAfterMs: 15 * MINUTE,
    staleTimeoutMs: 1 * SECOND,
    refreshAfterMs: 45 * MINUTE,
    fetchMethod: async (key: string) => {
        return `${key}_value`;
    },
    maxKeys: 10,
    evictStrategy: 'LRU',
});

(async () => {
    // Setting a key-value pair directly
    fruitCache.set('apple', 'apple_value');
    console.log(fruitCache.has('apple')); // true
    console.log(fruitCache.get('apple')); // "apple_value"

    // Deleting it from the cache
    fruitCache.del('apple');
    console.log(fruitCache.has('apple')); // false
    console.log(fruitCache.get('apple')); // undefined

    // Multiple keys at once
    fruitCache.mset([
        ['kiwi', 'kiwi_value'],
        ['lemon', 'lemon_value']
    ]);
    console.log(fruitCache.mget(['kiwi', 'lemon'])); // ["kiwi_value", "lemon_value"]
    fruitCache.mdel(['kiwi', 'lemon']); 
    console.log(fruitCache.mget(['kiwi', 'lemon'])); // [undefined, undefined]

    // Fetching a value asynchronously
    const banana = await fruitCache.fetch('banana');
    console.log(banana); // "banana_value"

    // Listing all keys, flushing the cache
    console.log(fruitCache.keys()); // ["banana"]
    fruitCache.flushAll();
    console.log(fruitCache.keys()); // []

    // Refreshing a key
    fruitCache.set('cherry', 'initial_value');
    await fruitCache.refresh('cherry');
    console.log(fruitCache.get('cherry')); // "cherry_value"

    // Getting a dump of the cache, to reuse it later
    const cacheDump = fruitCache.dump();
    fruitCache.load(cacheDump);

    // Clear all internal timers or resume them
    fruitCache.stop(); // auto-refreshes/evicts will not work when stopped
    console.log(fruitCache.isStopped()); // true
    fruitCache.resume();

    fruitCache.stop();
})();

Options

interface CacheOptions<T> {
    /**
     * Namespace for the cache, used in error messages.
     */
    namespace?: string | null;

    /**
     * Delay in milliseconds between a key creation or refresh and its deletion.
     * If set to null, keys will never expire unless `maxKeys` is reached
     * and an `evictStrategy` is set.
     * @default null
     */
    expireAfterMs?: number | null;

    /**
     * Delay in milliseconds between a key creation and it becoming stale.
     * Requires a `fetchMethod` to be set.
     * @default null
     */
    staleAfterMs?: number | null;

    /**
     * Timeout in milliseconds for fetching a new value when a key is stale.
     * If the timeout is exceeded, the stale value is returned
     * and the value will be refreshed in the background.
     * If the fetch is fast enough, the new value is returned.
     * If set to null, the old value will always be returned
     * while it is refreshed in the background.
     * @default null
     */
    staleTimeoutMs?: number | null;

    /**
     * Delay in milliseconds between automatic key refreshes.
     * Useful for keeping the cache up-to-date even when not in use.
     * Requires a `fetchMethod` to be set.
     * If set to null, keys will not be refreshed automatically.
     * @default null
     */
    refreshAfterMs?: number | null;

    /**
     * Precision in milliseconds used for auto-eviction and auto-refresh timers.
     * A higher value is recommended for performance,
     * and a lower one for precision.
     * @default 10000
     */
    timePrecisionMs?: number | null;

    /**
     * Method used for fetching a new value when a key is stale, missing,
     * or needs to be refreshed in the background.
     * It it returns undefined, the value will not be stored in the cache.
     * Only required if `staleAfterMs` or `refreshAfterMs` is set.
     * @param {string} key 
     * @returns {T | undefined | Promise<T | undefined>}
     */
    fetchMethod?: (key: string) => T | undefined | Promise<T | undefined>;

    /**
     * Maximum number of keys in the cache. If set to null,
     * the cache will grow indefinitely.
     * Exceeding this limit will trigger an eviction
     * based on the `evictStrategy` if one is set, or throw an error otherwise.
     * @default null
     */
    maxKeys?: number | null;

    /**
     * Strategy used for evicting keys when the `maxKeys` limit is reached.
     * - "LRU" will evict the least recently used key, or the least recently
     *   refreshed one if accessed at the same time or never.
     * - "FIFO" will evict the first key that was added to the cache.
     * If set to null, exceeding the limit will throw an error.
     * @enum {'LRU' | 'FIFO' | null}
     * @default null
     */
    evictStrategy?: 'LRU' | 'FIFO' | null;
}
1.0.8

10 months ago

1.0.7

10 months ago

1.0.6

10 months ago

1.0.5

10 months ago

1.0.4

10 months ago

1.0.3

10 months ago

1.0.2

10 months ago

1.0.1

10 months ago

1.0.0

10 months ago