Skip to content

Repository files navigation

obcachejs

npm versionCILicense: MITNode

Object caching for Node.js. Wraps async functions and caches results with automatic key generation.

Features

  • LRU in-memory cache with TTL support
  • Optional Redis backend for distributed caching
  • Request deduplication (prevents thundering herd)
  • Promise and callback APIs
  • TypeScript definitions included

Installation

npm install obcachejs

Requires Node.js 18+

Quick Start

constobcache=require('obcachejs');constcache=newobcache.Create({max: 1000,maxAge: 60000});constgetUser=cache.wrap(function(id,callback){// Simulate async database lookupsetTimeout(()=>callback(null,{ id,name: 'User '+id}),10);});// Promise styleconstuser=awaitgetUser(123);console.log(user);// { id: 123, name: 'User 123' }// Callback stylegetUser(456,(err,user)=>console.log(user));

API

obcache.Create(options)

Creates a cache instance.

constcache=newobcache.Create({max: 1000,// max keys (default: 1000)maxAge: 60000,// TTL in msqueueEnabled: true// deduplicate concurrent requests});

Options:

OptionDescription
maxMaximum number of cached keys
maxSizeMaximum cache size in bytes (alternative to max)
maxAgeTime-to-live in milliseconds
queueEnabledEnable request deduplication
disposeFunction called when entries are evicted
reset.intervalAuto-reset interval in ms
reset.firstResetFirst reset time (Date or ms)

cache.wrap(fn, [thisobj], [skipArgs])

Wraps a callback-based function with caching. The wrapped function:

  • Returns a Promise when called without a callback
  • Calls the callback when provided as last argument
  • Generates cache keys from function name and arguments
constcached=cache.wrap(myAsyncFn);// Exclude arguments from key generationconstcached=cache.wrap(function(id,timestamp,cb){// timestamp won't affect cache keycb(null,result);},null,[1]);

cache.warmup(fn, ...args, value)

Pre-populate cache for given arguments.

cache.warmup(getUser,123,{id: 123,name: 'Alice'});

cache.invalidate(fn, ...args)

Remove cached entry for given arguments.

cache.invalidate(getUser,123);

cache.isReady()

Returns true when cache backend is ready. Always true for LRU, waits for connection with Redis.

cache.stats

Cache statistics object.

{hit: 0,// cache hitsmiss: 0,// cache missesreset: 0,// number of resetspending: 0// queued requests}

Redis Backend

constcache=newobcache.Create({max: 10000,maxAge: 300000,id: 1,// required for Redisredis: {host: 'localhost',port: 6379,connectTimeout: 5000}});// Wait for connectionif(!cache.isReady()){// handle not ready}

Redis options:

OptionDescription
hostRedis host
portRedis port
urlConnection URL (alternative to host/port)
databaseRedis database number
connectTimeoutConnection timeout in ms (default: 5000)
twemproxyEnable twemproxy compatibility

Debug Interface

Register caches for inspection:

obcache.debug.register(cache,'users');// Express middlewareapp.get('/debug/cache',obcache.debug.view);// Console outputobcache.debug.log();

Security Warning: The debug endpoint exposes cached data via ?detail=cachename and allows cache flushing via POST with ?flush=cachename. Never expose this endpoint publicly. Always protect it with authentication middleware:

app.get('/debug/cache',requireAdmin,obcache.debug.view);

How It Works

obcachejs generates cache keys by hashing the function name and serialized arguments using sigmund. When a wrapped function is called:

  1. Generate key from function name + arguments
  2. Check cache for existing value
  3. On hit: return cached value
  4. On miss: call original function, cache result, return

With queueEnabled, concurrent calls with the same key are queued and resolved together, preventing duplicate work.

TypeScript

Type definitions are included.

constobcache=require('obcachejs');// or with ES modules: import obcache from 'obcachejs';constcache=newobcache.Create({max: 100});

Types available: Cache, CacheOptions, CacheStats, CachedFunction.

Security

  • Redis authentication: Use the url option with credentials: redis://user:pass@host:port
  • Secrets: Never cache sensitive data (tokens, passwords, PII) without encryption
  • Network: Use TLS for Redis in production (rediss:// protocol)
  • Eviction: Cached data persists until TTL expires or LRU evicts; plan accordingly

Report security issues via GitHub issues with [SECURITY] prefix.

License

MIT

About

Object caching for Node.js with LRU and Redis backends. Wraps async functions with automatic key generation and request deduplication.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages