Important
This version contains breaking changes! Please read the Migration Guide for more info.
✨ What’s new in ocache v0.3
This release makes ocache safer and more predictable for production workloads while adding new ways to reduce latency and compose storage:
- Safer HTTP caching by default — cache keys now account for authority and request method, undeclared request headers are hidden from handlers, credentials are stripped by default, and
Vary,Set-Cookie, cache-control directives, conditional requests, and cacheable status codes are handled more defensively. - Bounded memory and response buffering — memory storage is limited by bytes, HTTP bodies are refused while reading once they exceed the configured backend limit, and cache entries can no longer live forever without an expiry or storage TTL.
- Layered and binary-friendly storage — combine fast and persistent backends with
composeStorage, store native binary payloads without base64 when supported, cache binary function results, and adapt blob stores withcreateBlobStorage. - Faster responses and safer background work — opt into
streamto serve a cache fill while it is still being buffered, usewaitUntilfor background tasks, and rely on the new 30-secondmaxResolveTimedefault to abort abandoned resolutions. - Smaller, faster, runtime-independent hashing — ocache now ships its own deterministic SHA-256-based hashing with stronger collision protection and improved performance, while keeping zero runtime dependencies.
Key upgrade notes
Query parameters are now ignored unless enabled with allowQuery; storage must be configured per cache instance; HEAD and GET use separate entries; and responses with Set-Cookie are not cached or replayed on cacheable routes. See the Migration Guide before upgrading.
🚀 Enhancements
- storage:
⚠️ Only per-instance storage (ce8e0e6) - storage:
⚠️ Bound memory storage by bytes, not just entry count (#90) - cache:
⚠️ maxResolveTimedefaulting to 30sec (#85) - Standalone hash (5f97883)
- cache: Abort abandoned resolutions on timeout (e3a7dfd)
- http: Limit the body size that may be buffered (b4e1034)
- storage: Support native binary storage (df3a009)
- cache: Support binary values in cached functions (5ef98f3)
- storage:
createBlobStorageframe codec (5a73e3c) - storage: Reserve blob frame compression flags (bc49c15)
- cache: WaitUntil option for background work (ce0fbae)
- http:
⚠️ Make allowQuery opt-in (2b0f7e8) - storage: Add
composeStoragefor layered backends (0bd1b01) - http: Add opt-in stream to serve a fill while it buffers (548ad7a)
🔥 Performance
- Speed-up hashing (ad2a22e)
- http: Derive the key prefix without a second URL parse (23e53fb)
- http: Encode binary bodies with the runtime's own base64 (9f22264)
🩹 Fixes
- http: Strip credentials by default, forward varies headers (61f09db)
- http:
⚠️ Key HEAD entries separately from GET (5160adc) - http:
⚠️ Never cache or return Set-Cookie on cacheable routes (e3975c5) - http:
⚠️ Advertise Vary: Cookie when allowCookies is set (2710f10) - http: Never store or replay null-body statuses (204/205/304) (d975131)
- cache: Use a Map for in-flight dedup so prototype-named keys resolv (529fbda)
- http: Carry bound waitUntil onto the narrowed request (daac727)
- http:
⚠️ Forward the raw Cookie header when varies includes "cookie" (47731fb) - http:
⚠️ Resolve handler name before merging defaults (bdf8c84) - http:
⚠️ Include the request authority in the cache key (fb0efaa) - http:
⚠️ Gate storage and cache-control on a cacheable-status allowlist (14f8019) - http:
⚠️ Honor no-cache, zero lifetimes and Vary:* as storage opt-outs (c3501ea) - http:
⚠️ Fail closed on a handler-declared Vary we don't key on (660bee6) - http: Respect shouldBypassCache when narrowing requests (12f09f0)
- cache: Never store an entry with neither an expiry nor a TTL (183f36a)
- http:
⚠️ Advertise the lifetimes ocache actually enforces (#86) - cache:
⚠️ Escape the name segment of the storage key (#88) - http: Copy response headers before serializing (ec43253)
- http:
⚠️ Narrow request headers by allowlist (#91) - hash: Length-prefix text in serialize to prevent key collisions (a20beb4)
- hash: Treat a null constructor as a plain object (d11521f)
- http: Never cache a request that could not be narrowed (2035d6d)
- hash: Render built-ins by value and length-prefix type tags (00b399e)
- hash: Collapse a line break in function source to a space (623d714)
- http: Narrow Host to the keyed URL authority (b8d95f3)
- hash: Cap traversal depth instead of overflowing the stack (0abcfd1)
- storage: Close two byte-ceiling bypasses (bdf47ad)
- http: Give If-None-Match precedence over If-Modified-Since (6014259)
- cache: Fence in-flight resolutions against a concurrent purge (0cb0de7)
- cache: Stop discarding falsy transform results (9ef94f6)
- http: Decide headersOnly 304s from the handler's own validators (ff31b27)
- http: Domain-separate binary and text etags (71aa086)
- http: Stop synthesizing last-modified (d4eea12)
- cache: Require matching integrity to serve stale (74cdcad)
- cache: Order a purge after an in-flight write (9f1bc84)
- http: Remove unkeyed header exemptions (acf56ab)
- cache: Escape the group cache key segment (1747b51)
- http: Echo validators and cache policy on 304 (07931fc)
- http:
⚠️ Refuse handler values the defaulttoResponsecannot convert (981ac27)