Codexportfolio intelligence
Packages/TypeScript

@philiprehberger/cache-kit

In-memory LRU cache with TTL, stale-while-revalidate, and tag invalidation

TypeScriptnpm

Capabilities

README

@philiprehberger/cache-kit

CI npm version Last updated

In-memory LRU cache with TTL, stale-while-revalidate, and tag invalidation

Installation

npm install @philiprehberger/cache-kit

Usage

Basic

import { createCache } from '@philiprehberger/cache-kit';

const cache = createCache({ maxItems: 1000, defaultTTL: '5m' });

cache.set('user:123', userData);
cache.set('user:456', otherUser, { ttl: '10m' });

const user = cache.get('user:123'); // T | undefined
cache.has('user:123');              // boolean
cache.delete('user:123');           // boolean
cache.clear();

TTL Durations

Supports string durations or milliseconds:

cache.set('key', value, { ttl: '30s' });  // 30 seconds
cache.set('key', value, { ttl: '5m' });   // 5 minutes
cache.set('key', value, { ttl: '1h' });   // 1 hour
cache.set('key', value, { ttl: '1d' });   // 1 day
cache.set('key', value, { ttl: 60000 });  // 60000ms

Tag-Based Invalidation

cache.set('user:1', user1, { tags: ['users'] });
cache.set('user:2', user2, { tags: ['users'] });
cache.set('post:1', post1, { tags: ['posts'] });

cache.invalidateTag('users'); // removes user:1 and user:2

Wrap (Memoize)

const getUser = cache.wrap(
  'user',
  (id: string) => db.users.findById(id),
  { ttl: '5m' },
);

const user = await getUser('123'); // fetches from DB
const same = await getUser('123'); // served from cache

Stale-While-Revalidate

const getUser = cache.wrap(
  'user',
  (id: string) => db.users.findById(id),
  {
    ttl: '5m',
    staleWhileRevalidate: '1m',
    onRevalidateError: (err, key) => console.error(`SWR failed for ${key}:`, err),
  },
);
// Serves stale data immediately while refreshing in the background
// If revalidation fails, onRevalidateError is called instead of silently swallowing the error

Keys & Size

cache.keys();  // ['user:1', 'user:2'] — all non-expired keys (lazy-cleans expired entries)
cache.size();  // 2 — number of entries in the store

Stats

cache.stats();
// { hits: 150, misses: 23, hitRate: 0.867, size: 42 }

Persistence

const data = cache.dump();   // serialize to JSON
cache.load(data);            // restore from JSON

API

createCache<V>(options?: CacheOptions): Cache<V>

MethodSignatureDescription
set(key: string, value: V, opts?: SetOptions) => voidStore a value.
get(key: string) => V | undefinedRetrieve a value. Returns undefined if missing or expired.
has(key: string) => booleanCheck if a key exists and is not expired.
delete(key: string) => booleanRemove a key. Returns true if it existed.
clear() => voidRemove all entries and reset stats.
invalidateTag(tag: string) => numberRemove all entries with the given tag. Returns count removed.
wrap(keyPrefix, fn, opts?) => (...args) => PromiseMemoize an async function with cache.
stats() => CacheStatsGet hit/miss/size statistics.
keys() => string[]Return all non-expired keys. Lazy-cleans expired entries.
size() => numberReturn the number of entries in the store.
dump() => SerializedCacheSerialize cache contents for persistence.
load(data: SerializedCache) => voidRestore cache from serialized data.

CacheOptions

PropertyTypeDefaultDescription
maxItemsnumberInfinityMax entries before LRU eviction.
defaultTTLstring | numberNoneDefault TTL for all entries.

SetOptions

PropertyTypeDescription
ttlstring | numberTime-to-live (e.g. "5m", 60000).
tagsstring[]Tags for group invalidation.
staleWhileRevalidatestring | numberWindow before expiry where stale data is served while refreshing.

WrapOptions

Extends SetOptions with:

PropertyTypeDescription
onRevalidateError(error: Error, key: string) => voidCalled when a stale-while-revalidate background refresh fails. If omitted, errors are silently swallowed.

Duration Strings

"100ms", "30s", "5m", "1h", "1d" — or pass milliseconds as a number

Development

npm install
npm run build
npm test

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT