Skip to content

Replicache cvr pull#363

Merged
jaredpereira merged 7 commits into
mainfrom
replicache-cvr-pull
Jul 21, 2026
Merged

Replicache cvr pull#363
jaredpereira merged 7 commits into
mainfrom
replicache-cvr-pull

Conversation

@jaredpereira

Copy link
Copy Markdown
Contributor

Before you pull, have you made sure...

  • it looks good on both mobile and desktop
  • it undo's like it ought to
  • it handles keyboard interactions reasonably well
  • no build errors!!!

jaredpereira and others added 3 commits July 18, 2026 21:27
Pulls previously ignored the cookie and shipped a clear op plus every
fact on every pull. The pull handler now diffs against a Client View
Record per https://doc.replicache.dev/strategies/row-version: the cookie
carries {order, cvrID}, the CVR itself lives in a single Redis slot per
token+clientGroup (SETEX 30d, overwritten in place so editing churn
never accumulates keys), and facts are versioned by Postgres xmin so no
schema changes are needed. Data is fetched with direct SQL replicating
the pull_data RPC (plus xmin) in one repeatable-read snapshot, so a
mutation's lastMutationID is never visible without its writes.

Every degraded path — legacy Date.now() cookies, null first pulls,
Redis down/evicted/superseded slots — falls back to the legacy
full-snapshot response, and cookie orders stay above wall clock so
rollback to the reset-strategy server cannot strand upgraded clients.
Without REDIS_URL (dev) every pull is a full snapshot.

Adds the repo's first test setup (vitest): randomized equivalence
simulation against the naive strategy including lost-response and
eviction recovery, and integration tests against local supabase with
row-for-row parity checks between fetchPullData and the pull_data RPC.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The pull query previously shipped every fact's full row out of Postgres
on every pull and diffed in app code. The base CVR's fact versions are
now passed in as a jsonb argument; the closure walk still runs in full,
but row_to_json only leaves the database for facts whose xmin is new or
changed against that base — everything else returns as (id, row_version)
pairs, which the next CVR needs anyway. This is the row-version docs'
"CVR as query argument" variation: two-phase savings (DB egress and
app-side parse/memory drop from O(document) to O(changes) per pull) with
no extra round trip. A null base hydrates everything, so full snapshots
and all fallback paths are unchanged.

The app-side diff remains authoritative for the patch; a changed fact
arriving unhydrated (a base-CVR mismatch between query and diff, which
the shared computePull plumbing makes structurally impossible) throws
and degrades to ClientStateNotFound rather than silently dropping the
update.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fetchPullData ran inline SQL over the shared pg pool, which put pull —
the highest-QPS RPC — on direct database connections and needed an
explicit repeatable-read transaction to keep its reads on one snapshot.
The new pull_data_cvr(token_id, client_group_id, base_cvr) function is a
single SQL statement, so every read shares a snapshot for free, and the
handler reaches it through the existing supabase client: one stateless
PostgREST round trip and no pool connections held by pulls. The base-CVR
hydration contract is unchanged — full fact rows only leave the database
for facts new or changed against base_cvr.

The pull_data_cvr entry in database.types.ts is hand-added because the
local database is behind the committed migrations; a future
generate-db-types run against a migrated database produces the same.

Integration tests now exercise the real PostgREST path with the local
supabase demo credentials, keeping the direct pg connection only for
seeding and for row-for-row parity checks against the legacy pull_data
function.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
minilink Ready Ready Preview, Comment Jul 21, 2026 8:22pm

Request Review

@jaredpereira
jaredpereira force-pushed the replicache-cvr-pull branch from 592b3cb to 5de4798 Compare July 21, 2026 20:19
@jaredpereira
jaredpereira merged commit 2335134 into main Jul 21, 2026
3 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.

1 participant