@chttp/cache
@chttp/cache
@chttp/cache
LRU + TTL in-process memory cache with lru-cache-parity semantics, authored in the scriptc-compilable subset — the same source runs under Node and lowers into a native ELF.
Quickstart
Node
Native
pnpm add @chttp/cache
import { Cache } from "@chttp/cache";
const sessions: Cache<string> = new Cache({ max: 10_000, ttl: 60_000 });
sessions.set("sess-1", "uid:42");
sessions.get("sess-1"); // "uid:42" — bumps recency
sessions.get("missing"); // null — misses are never undefined
import { Cache } from "@chttp/cache";
const seen: Cache<number> = new Cache({ max: 1_000 });
seen.set("job-7", 1);
scriptc build src/main.ts -o app
Semantics
getbumps recency;peekandhasdon’t. Recency picks the eviction victim whensize > max.maxevicts least-recently-used first (insertion-orderedMap);ttlexpires lazily on access — no timers.- Misses return
null;has()distinguishes a storednullfrom a miss. set(key, value, { ttl })overrides the constructor TTL per entry.- Non-positive
max/ttlthrowsE_BAD_CACHE_OPTIONSat construction — config fails fast, traffic never does.
Divergences from lru-cache
| lru-cache | @chttp/cache |
|---|---|
V | undefined misses |
V | null; has() disambiguates |
LRUCache<K, V> typed keys + values |
Cache<V> phantom alias; keys are string, values narrow at the call site |
ttlAutopurge / timers |
lazy purge on access; max bounds memory |
dispose, fetch, sizeCalculation, stale reads |
not shipped — demand-gated follow-ups |
mget/mset |
loop get/set |
ttl: 0 = no expiry |
ttl <= 0 throws E_BAD_CACHE_OPTIONS |
Bigger than memory
When one process isn’t enough (multi-replica coherence, persistence), layer a remote store under the memory cache — cache-aside, not a different API. Implement the documented CacheStore shape (in the package README) against your backend; the README carries the full recipe and a getUser walkthrough.