-
Notifications
You must be signed in to change notification settings - Fork 0
Cookbook: caching
double-meh ships an in-memory GET cache that is opt-in per request — attached by default, but it stores nothing until a request asks for it. It also revalidates stale entries with ETags, so a 304 Not Modified reuses the cached body for free.
The cache is already attached when you import io from 'double-meh'. Call attach() / detach() only to toggle it globally.
import io from 'double-meh';
io.cache.attach(); // no-op by default; the cache is already on
io.cache.detach(); // turn caching off process-wideAdd cache: true to store the response and serve later identical GETs from memory (default TTL is 5 minutes). Only GETs are ever cached — writes and streams pass straight through.
const a = await io.get('https://api.example.com/config', null, {cache: true});
const b = await io.get('https://api.example.com/config', null, {cache: true});
// second call is served from the cache — no network requestPass an object to control freshness. {ttl: 0} stores the entry but forces revalidation on the next read; a large TTL keeps a rarely-changing resource around.
await io.get('https://api.example.com/countries', null, {cache: {ttl: 24 * 60 * 60 * 1000}});When a stale entry carries an ETag (or Last-Modified), the next read sends a conditional request; a 304 refreshes the TTL and reuses the stored body.
cache: false bypasses the cache for a single call — handy for a forced refresh even while caching is on globally.
const fresh = await io.get('https://api.example.com/config', null, {cache: false});io.cache.remove(target) accepts three shapes. A plain URL evicts that exact entry; a string ending in * evicts by prefix; a RegExp or a predicate is matched against the cache key, which has the form GET <canonical-url> (query sorted, fragment dropped).
await io.cache.remove('https://api.example.com/users/42'); // exact URL
await io.cache.remove('https://api.example.com/users/*'); // prefix
await io.cache.remove(/\/users\//); // RegExp over the key
await io.cache.remove(key => key.includes('draft')); // predicate over the keyclear() drops the whole cache; sweep() removes only entries past their TTL, which is useful to run on a timer to reclaim memory.
await io.cache.clear(); // wipe all entries
await io.cache.sweep(); // drop only expired entries
setInterval(() => io.cache.sweep(), 60 * 1000);Guides
Concepts
Services
Modules
- fetch transport
- keys & URLs
- helpers
- records
- sse
- storage backends
- compression encoders
- Service Worker integration
Cookbook