Replicache cvr pull#363
Merged
Merged
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
jaredpereira
force-pushed
the
replicache-cvr-pull
branch
from
July 21, 2026 20:19
592b3cb to
5de4798
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before you pull, have you made sure...