Skip to content

Clarify local write status docs and pending sync contract#1652

Open
KyleAMathews wants to merge 5 commits into
mainfrom
docs-tests-write-status-contract
Open

Clarify local write status docs and pending sync contract#1652
KyleAMathews wants to merge 5 commits into
mainfrom
docs-tests-write-status-contract

Conversation

@KyleAMathews

@KyleAMathews KyleAMathews commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Clarifies TanStack DB's existing local write status docs and tightens the core pending-sync contract around optimistic temp-key inserts. User-visible docs now distinguish local optimistic write state from backend upload/read-path confirmation, and the core test makes explicit that ambiguous server-key sync is not exposed while the local mutation is still pending.

Root cause

$synced and tx.isPersisted.promise were easy to read as backend confirmation APIs. In practice, they describe TanStack DB's local transaction/projection state: a row may have no pending local optimistic mutation without proving backend read-back, and a transaction may settle without representing a generic sync-observation guarantee.

Approach

  • Reword $synced JSDoc to describe whether a row currently has pending local optimistic mutations in the collection's visible projection.
  • Reword isPersisted.promise JSDoc to describe transaction settlement, including rollback/failure, while noting that non-empty commits normally settle through the mutation function.
  • Tighten the core collection test for an optimistic insert using a temporary key followed by synced data under a different server key. While the mutation is pending, the possible server-key echo stays queued and the collection does not expose both rows.
  • Add a changeset for @tanstack/db.

Key invariants

  • $synced is local write/projection status; it is not backend upload, confirmation, or read-path observation.
  • tx.isPersisted.promise is the promise to await for transaction settlement; callers should not await the deferred object itself.
  • Without explicit temp-key to server-key mapping, core must not expose both an optimistic temp row and a possible server-key echo while the mutation function is still pending.

Non-goals

  • No new public write status APIs in this PR.
  • No mutation log rewrite.
  • No generic immediate sync application while mutation functions are pending.
  • No temp-key/server-key mapping or mutation receipts.
  • No generated reference docs updates; this PR updates the source JSDoc that feeds them.

Verification

pnpm --filter @tanstack/db exec vitest run tests/collection.test.ts --pool-options.threads.maxThreads=2
pnpm --filter @tanstack/db exec tsc --noEmit

Files changed

  • .changeset/clarify-local-write-status.md — records the patch-level docs/test clarification for @tanstack/db.
  • packages/db/src/virtual-props.ts — clarifies $synced as local pending optimistic write state.
  • packages/db/src/transactions.ts — clarifies isPersisted.promise transaction settlement semantics.
  • packages/db/src/collection/state.ts — aligns an internal $synced helper comment with the new wording.
  • packages/db/tests/collection.test.ts — makes the ambiguous temp/server-key pending sync contract explicit.

Refs #20, #661, #1017, #1166, #1215, #1219, #1322, #1431, #1526.

Summary by CodeRabbit

  • Documentation

    • Clarified how local sync and persistence status indicators should be interpreted.
    • Added clearer examples for status-related API guidance.
  • Bug Fixes

    • Improved handling and documentation for cases where a server-generated key arrives while a temporary local row is still pending.
    • Ensured the visible row state stays consistent until the pending write completes.
  • Tests

    • Updated coverage for the queued key-sync scenario to match the intended user-visible behavior.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR clarifies documentation for $synced, isRowSynced, and isPersisted to specify that they reflect local optimistic mutation/settlement status rather than backend confirmation. It also updates a collection test to assert that server-generated keys remain hidden while a persist transaction is pending, and adds a changeset.

Changes

Write-status semantics clarification

Layer / File(s) Summary
Source JSDoc clarifications
packages/db/src/transactions.ts, packages/db/src/collection/state.ts
Expands isPersisted JSDoc to describe promise settlement tied to mutationFn completion rather than backend confirmation; revises isRowSynced comment to describe pending local optimistic mutations.
Virtual $synced property docs
packages/db/src/virtual-props.ts
Rewrites $synced JSDoc and examples to describe local write/projection status, renames example variable and log message text accordingly.
Changeset and collection test update
.changeset/clarify-local-write-status.md, packages/db/tests/collection.test.ts
Adds changeset documenting the clarification; renames a test scenario and adds assertions that the server-generated key is not exposed while the persist transaction is pending, becoming visible only after settlement.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • TanStack/db#1547: Overlaps directly with handling and tests for replacing stale optimistic temp-key rows when txid sync confirms a server-generated key.

Suggested reviewers: samwillis, kevin-dp

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main docs and pending-sync contract clarification.
Description check ✅ Passed Covers changes, motivation, approach, verification, and files; only the template's checklist and release-impact sections are omitted.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs-tests-write-status-contract

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Jul 7, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-db

npm i https://pkg.pr.new/@tanstack/angular-db@1652

@tanstack/browser-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/browser-db-sqlite-persistence@1652

@tanstack/capacitor-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/capacitor-db-sqlite-persistence@1652

@tanstack/cloudflare-durable-objects-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/cloudflare-durable-objects-db-sqlite-persistence@1652

@tanstack/db

npm i https://pkg.pr.new/@tanstack/db@1652

@tanstack/db-ivm

npm i https://pkg.pr.new/@tanstack/db-ivm@1652

@tanstack/db-sqlite-persistence-core

npm i https://pkg.pr.new/@tanstack/db-sqlite-persistence-core@1652

@tanstack/electric-db-collection

npm i https://pkg.pr.new/@tanstack/electric-db-collection@1652

@tanstack/electron-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/electron-db-sqlite-persistence@1652

@tanstack/expo-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/expo-db-sqlite-persistence@1652

@tanstack/node-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/node-db-sqlite-persistence@1652

@tanstack/offline-transactions

npm i https://pkg.pr.new/@tanstack/offline-transactions@1652

@tanstack/powersync-db-collection

npm i https://pkg.pr.new/@tanstack/powersync-db-collection@1652

@tanstack/query-db-collection

npm i https://pkg.pr.new/@tanstack/query-db-collection@1652

@tanstack/react-db

npm i https://pkg.pr.new/@tanstack/react-db@1652

@tanstack/react-native-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/react-native-db-sqlite-persistence@1652

@tanstack/rxdb-db-collection

npm i https://pkg.pr.new/@tanstack/rxdb-db-collection@1652

@tanstack/solid-db

npm i https://pkg.pr.new/@tanstack/solid-db@1652

@tanstack/svelte-db

npm i https://pkg.pr.new/@tanstack/svelte-db@1652

@tanstack/tauri-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/tauri-db-sqlite-persistence@1652

@tanstack/trailbase-db-collection

npm i https://pkg.pr.new/@tanstack/trailbase-db-collection@1652

@tanstack/vue-db

npm i https://pkg.pr.new/@tanstack/vue-db@1652

commit: b5e76e0

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Size Change: +1 B (0%)

Total Size: 125 kB

📦 View Changed
Filename Size Change
packages/db/dist/esm/collection/state.js 5.4 kB +1 B (+0.02%)
ℹ️ View Unchanged
Filename Size
packages/db/dist/esm/collection/change-events.js 1.43 kB
packages/db/dist/esm/collection/changes.js 1.38 kB
packages/db/dist/esm/collection/cleanup-queue.js 810 B
packages/db/dist/esm/collection/events.js 434 B
packages/db/dist/esm/collection/index.js 3.62 kB
packages/db/dist/esm/collection/indexes.js 1.99 kB
packages/db/dist/esm/collection/lifecycle.js 1.69 kB
packages/db/dist/esm/collection/mutations.js 2.47 kB
packages/db/dist/esm/collection/subscription.js 3.74 kB
packages/db/dist/esm/collection/sync.js 2.88 kB
packages/db/dist/esm/collection/transaction-metadata.js 144 B
packages/db/dist/esm/deferred.js 207 B
packages/db/dist/esm/errors.js 5.1 kB
packages/db/dist/esm/event-emitter.js 748 B
packages/db/dist/esm/index.js 3.1 kB
packages/db/dist/esm/indexes/auto-index.js 829 B
packages/db/dist/esm/indexes/base-index.js 767 B
packages/db/dist/esm/indexes/basic-index.js 2.06 kB
packages/db/dist/esm/indexes/btree-index.js 2.19 kB
packages/db/dist/esm/indexes/index-registry.js 820 B
packages/db/dist/esm/indexes/reverse-index.js 557 B
packages/db/dist/esm/local-only.js 916 B
packages/db/dist/esm/local-storage.js 2.12 kB
packages/db/dist/esm/optimistic-action.js 359 B
packages/db/dist/esm/paced-mutations.js 496 B
packages/db/dist/esm/proxy.js 3.75 kB
packages/db/dist/esm/query/builder/functions.js 1.47 kB
packages/db/dist/esm/query/builder/index.js 5.84 kB
packages/db/dist/esm/query/builder/ref-proxy.js 1.24 kB
packages/db/dist/esm/query/compiler/evaluators.js 1.89 kB
packages/db/dist/esm/query/compiler/expressions.js 430 B
packages/db/dist/esm/query/compiler/group-by.js 3.56 kB
packages/db/dist/esm/query/compiler/index.js 6.67 kB
packages/db/dist/esm/query/compiler/joins.js 2.5 kB
packages/db/dist/esm/query/compiler/lazy-targets.js 923 B
packages/db/dist/esm/query/compiler/order-by.js 1.74 kB
packages/db/dist/esm/query/compiler/select.js 1.53 kB
packages/db/dist/esm/query/effect.js 4.77 kB
packages/db/dist/esm/query/expression-helpers.js 1.43 kB
packages/db/dist/esm/query/ir.js 1.25 kB
packages/db/dist/esm/query/live-query-collection.js 360 B
packages/db/dist/esm/query/live/collection-config-builder.js 9.1 kB
packages/db/dist/esm/query/live/collection-registry.js 264 B
packages/db/dist/esm/query/live/collection-subscriber.js 1.93 kB
packages/db/dist/esm/query/live/internal.js 145 B
packages/db/dist/esm/query/live/utils.js 1.81 kB
packages/db/dist/esm/query/optimizer.js 2.92 kB
packages/db/dist/esm/query/predicate-utils.js 2.97 kB
packages/db/dist/esm/query/query-once.js 359 B
packages/db/dist/esm/query/subset-dedupe.js 960 B
packages/db/dist/esm/scheduler.js 1.3 kB
packages/db/dist/esm/SortedMap.js 1.3 kB
packages/db/dist/esm/strategies/debounceStrategy.js 247 B
packages/db/dist/esm/strategies/queueStrategy.js 428 B
packages/db/dist/esm/strategies/throttleStrategy.js 246 B
packages/db/dist/esm/transactions.js 3.04 kB
packages/db/dist/esm/utils.js 927 B
packages/db/dist/esm/utils/array-utils.js 273 B
packages/db/dist/esm/utils/browser-polyfills.js 304 B
packages/db/dist/esm/utils/btree.js 5.61 kB
packages/db/dist/esm/utils/comparison.js 1.11 kB
packages/db/dist/esm/utils/cursor.js 457 B
packages/db/dist/esm/utils/index-optimization.js 2.39 kB
packages/db/dist/esm/utils/type-guards.js 157 B
packages/db/dist/esm/utils/uuid.js 449 B
packages/db/dist/esm/virtual-props.js 360 B

compressed-size-action::db-package-size

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 4.26 kB

ℹ️ View Unchanged
Filename Size
packages/react-db/dist/esm/index.js 249 B
packages/react-db/dist/esm/useLiveInfiniteQuery.js 1.32 kB
packages/react-db/dist/esm/useLiveQuery.js 1.37 kB
packages/react-db/dist/esm/useLiveQueryEffect.js 355 B
packages/react-db/dist/esm/useLiveSuspenseQuery.js 567 B
packages/react-db/dist/esm/usePacedMutations.js 401 B

compressed-size-action::react-db-package-size

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