Skip to content

feat(sdk): serialize/hydrate LruMemoCache for SSR - #1007

Merged
Jaydbrown merged 2 commits into
conduit-protocol:mainfrom
arkhindi12:feat/977-lru-cache-serialize
Oct 20, 2026
Merged

Jaydbrown merged 2 commits into
conduit-protocol:mainfrom
arkhindi12:feat/977-lru-cache-serialize

Conversation

@arkhindi12

@arkhindi12 arkhindi12 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Closes #977.

Problem

LruMemoCache lives in memory. In a Next.js server component the instance dies
with the request, so every request repeats the same contract-metadata queries
that the cache was supposed to absorb.

What this adds

serialize() writes a versioned snapshot; hydrate() restores it.

const json = cache.serialize();          // drop into a session/Redis entry
// next request:
cache.hydrate(json);                     // returns entries restored

Also exported as free functions — serializeCache(cache) /
hydrateCache(cache, json) — for callers holding the cache through an
interface.

Details that matter

  • Absolute deadlines survive. Hydration restores the original expiresAt
    instead of restarting every TTL, so a snapshot taken at T+9s of a 10s entry
    expires 1s later, not 10s later.
  • Expired entries are dropped at both ends.
  • LRU order is preserved, so eviction after hydration still drops the
    coldest entry.
  • Capacity still applies: a snapshot taken with maxSize: 10 cannot
    overflow a cache built with maxSize: 3.
  • Malformed input throws (SyntaxError / TypeError, including a version
    mismatch) rather than leaving a half-filled cache.
  • Metrics are not fabricated — a hydrated cache reports 0 hits / 0 misses
    and measuredSpeedupPercent: null, because it has measured nothing.

Tests

src/tests/lru-memo-cache-serialize.test.ts — 10 cases: round-trip, deadline
preservation with fake timers, expired-entry filtering, LRU order after
hydration, capacity clamping, metrics untouched, malformed input rejected,
non-primitive keys rejected, and the exported helpers.

Test Files  1 passed (1)
     Tests  10 passed (10)

Rebased on main after #1004. npx tsc --noEmit and this PR's test suite are green on the current head.

The memo cache loses everything when a Next.js server component finishes,
so the next request repeats the same contract queries. serialize() writes
a versioned snapshot (expired entries dropped, LRU order preserved) and
hydrate() restores it with the original absolute deadlines instead of
restarting every TTL.

Malformed input throws instead of leaving a half-filled cache, and metrics
stay untouched so measuredSpeedupPercent is not fabricated.
@Jaydbrown
Jaydbrown merged commit 905acb5 into conduit-protocol:main Oct 20, 2026
0 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

src/lru-memo-cache.ts: export serializeCache and hydrateCache methods for SSR persistence

2 participants