-
Notifications
You must be signed in to change notification settings - Fork 20
stale-while-revalidate, Cache Tags & Inspector#3Description
HTTP-Semantics Aware Caching: ETag/304 Revalidation, stale-while-revalidate, Cache Tags & Inspector
Summary
Upgrade GhostCache from time-only TTL to full HTTP-aware caching: parse and honor Cache-Control, support conditional requests (ETag/Last-Modified → 304), add stale-while-revalidate/stale-if-error, introduce cache tags for targeted invalidation, and ship a tiny DevTools-style inspector API for visibility.
Motivation
Many APIs expose validators and caching hints (ETag, Last-Modified, Cache-Control, Vary). Today we rely primarily on TTL. Supporting HTTP semantics improves correctness, reduces bandwidth, and enables instant UI while background-refreshing.
Goals
-
Conditional Revalidation
- Store ETag / Last-Modified from responses.
- On refresh, send
If-None-Match/If-Modified-Since; treat 304 as a fast cache hit (update age/headers).
-
Cache-ControlParsing- Respect
max-age,s-maxage,no-store,no-cache,must-revalidate,stale-while-revalidate,stale-if-error. - Normalize with existing
ttl(explicitttloverrides headers unlessrespectHeaders: true).
- Respect
-
Stale While Revalidate (SWR)
- Serve stale immediately when within
stale-while-revalidatewindow, then refresh in background and update store; expose a hook/callback for “refreshed” events.
- Serve stale immediately when within
-
Stale-If-Error
- If network/5xx during refresh and stale exists within
stale-if-error, serve stale and surface a soft warning event/metric.
- If network/5xx during refresh and stale exists within
-
Cache Key Normalization
- Option to include/exclude query params, headers, and method; support a custom
keyFn(req)to unify semantically identical requests.
- Option to include/exclude query params, headers, and method; support a custom
-
Cache Tags & Batch Invalidation
- Allow setting
tags: string[]per entry; exposeinvalidateByTag("user:42")to drop related keys (useful after POST/PUT/DELETE).
- Allow setting
-
Inspector / DevTools Hooks
-
Optional tiny overlay API:
getEntry(key),listEntries({tag}),stats()(hits/misses/revalidations).- Event hooks:
onHit,onMiss,onRevalidate,onInvalidate.
-
-
Axios & fetch Parity
- Implement revalidation and header handling for both adapters.
Non-Goals
- Full HTTP proxy behavior or full RFC 9111 edge cases.
- Persisted header normalization across all custom adapters beyond documented subset.
API Proposal
enableGhostCache({
ttl: 60_000,
respectHeaders: true, // NEW: honor Cache-Control / validators
swr: true, // NEW: enable stale-while-revalidate behavior
keyFn: (req) => string, // NEW: optional custom cache key builder
});
setCache("user/42", data, { tags: ["user:42"] }); // NEW: tags
invalidateByTag("user:42"); // NEW
const info = GhostCacheInspector.getEntry(key); // NEW
GhostCacheInspector.on("revalidate", (e) => { ... }); // NEWDesign Notes
-
Storage Layout: extend stored metadata to
{ body, status, headers, etag, lastModified, cacheControl, tags, createdAt, lastValidatedAt }. -
Revalidation Flow:
- Lookup entry; if fresh → hit.
- If stale and
swr→ return stale immediately; kick off background fetch withIf-None-Match/If-Modified-Since. - On 304 → update timestamps/headers; on 200 → replace body/headers.
- On error and
stale-if-errorwindow → serve stale, emit event.
-
Key Normalization: default includes method + URL + sorted query; exclude transient headers unless
varyHeaders: ["Accept-Language"]is set. -
Security/Privacy: never cache
Authorization-bearing responses unlesscacheAuth: trueandprivate: trueare set; scrub PII headers from stored metadata by default.
Acceptance Criteria
- ETag & Last-Modified captured and used for conditional requests with 304 handling.
-
Cache-Controldirectives respected whenrespectHeaders: true. - SWR path serves stale immediately and refreshes in background; events emitted.
-
stale-if-errorreturns stale on refresh failure within window. - Cache tags supported;
invalidateByTag()removes affected entries across adapters. - Inspector API exposes
getEntry,listEntries,stats, and event hooks. - Works with both
fetchandaxios; 95%+ unit test coverage for new logic. - README updated with examples and migration notes.
Testing Plan
-
Unit tests covering:
- 200 → store validators; later 304 → metadata refresh only.
max-age/no-cache/SWR/stale-if-errorbranches.- Tag invalidation correctness.
- Key normalization edge cases (query order, header variations).
-
Integration tests:
- Axios and fetch parity using a mock HTTP server returning ETag/Last-Modified and varying directives.
-
Performance:
- Ensure overhead for header parsing and background revalidation is negligible (<1ms average per call in Node 18+).