Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
fd097e9
fix(sqlite-persistence): make every persisted hydration wait for a re…
Oct 26, 2026
b2cd4b8
Merge remote-tracking branch 'origin/main' into fix/persisted-reserve…
Oct 26, 2026
3fd2e5e
fix(electric): end a reserved transaction on every terminal stream stop
Oct 27, 2026
7b14a9b
test(browser-sqlite): return on every stream-stop path in the multi-t…
Oct 27, 2026
55bd60e
Merge remote-tracking branch 'origin/main' into fix/persisted-reserve…
Oct 27, 2026
9994578
test(browser-sqlite): cross every Electric stop path and recovery in …
Oct 27, 2026
767ea3a
docs(oracles): state which multi-tab storm cells compare rows
Oct 27, 2026
5a7c00c
test(browser-sqlite): judge the rows of a Collection in error after r…
Oct 27, 2026
851e8d9
fix(sqlite-persistence): keep Collection status when a peer's commit …
Oct 27, 2026
b1fbac2
fix(sqlite-persistence): make gap recovery one hydration cycle
Oct 27, 2026
e9ab9b3
fix(sqlite-persistence): release waiting loads when a reservation is …
Oct 27, 2026
fb74208
test(browser-sqlite): run the generated multi-tab campaigns through t…
Oct 27, 2026
e6d1610
Merge remote-tracking branch 'origin/main' into fix/persisted-reserve…
Oct 27, 2026
2047f42
test(oracles): name the owner of the generated multi-tab property
Oct 27, 2026
2ff2e2f
fix(sqlite-persistence): let a peer reset abandon an older reservation
Oct 27, 2026
5ac5a87
test(browser-sqlite): cross peer resets with Electric in the generate…
Oct 28, 2026
032fdc2
fix(sqlite-persistence): abandon every older reservation on a peer reset
Oct 28, 2026
09e0274
docs(electric): state that awaitTxId resolves on stream evidence
Oct 28, 2026
55d3cbf
Merge remote-tracking branch 'origin/main' into fix/persisted-reserve…
Oct 28, 2026
a7de625
test(browser-sqlite): judge source failures through health after #2168
Oct 28, 2026
b3cc7df
fix(sqlite-persistence): keep a follower's load waiting until the own…
Oct 28, 2026
7a6f32f
test(browser-sqlite): fold only updates for rows a tab holds
Oct 28, 2026
383ce48
fix(persistence): close the sixth review's reservation gaps
Oct 28, 2026
9c799e2
ci: apply automated fixes
autofix-ci[bot] Oct 28, 2026
f67c9f5
fix(persistence): retire an aborted demand while it waits for its turn
Oct 28, 2026
4fec3e5
Merge remote-tracking branch 'origin/fix/persisted-reserved-commit-hy…
Oct 28, 2026
4e2d0db
test(persistence): reach the follower window without a hook
Oct 28, 2026
60adb19
test(persistence): bound pullSince per wait, not per notice
Oct 28, 2026
82f496c
docs(persistence): state the pullSince law as gap filling
Oct 28, 2026
b24fd61
Merge origin/main into fix/persisted-reserved-commit-hydration
Oct 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/persisted-reload-keeps-status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/db-sqlite-persistence-core': patch
---

Keep a persisted Collection's status when another tab's commit reloads its rows. Before, a reload from durable rows could mark a tab `ready` while its own source was still loading, or move a tab whose initial sync failed from `error` to `ready`. Now only the Collection's own source changes its status.
13 changes: 13 additions & 0 deletions .changeset/reserved-commit-defers-every-hydration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'@tanstack/db-sqlite-persistence-core': patch
'@tanstack/db': patch
'@tanstack/electric-db-collection': patch
---

Keep a sync transaction that reserved its commit turn from failing when a persisted hydration starts while it is open. Before, only a subset load admitted during the reservation waited for the commit. A subset load admitted earlier, a reload or reset from a peer tab's notice, sequence-gap recovery, or a hydration that a shared scheduler held past its turn advanced the hydration cycle, and the commit then rejected with `a persisted sync transaction cannot cross a hydration cycle`. Electric reserves every stream transaction, so a deploy that made several tabs refetch at once could put their Collections into `error`. Each of these hydrations now waits outside the apply mutex until the reserved transaction commits, then starts. While it waits, readers keep the rows from before it. The `reserveCommitTurn` contract now covers every persisted hydration.

A peer reset now applies in arrival order with peer commit notices, so a commit from before the reset can no longer publish a row that the reset removed.

Electric now abandons its open transaction when its stream stops for good, so hydrations that wait for that transaction can run.

An abandoned reservation now releases the subset loads that waited for it, as a commit does, so they run. Before, a load admitted while the turn was reserved rejected with `SyncTransactionAbortedError` when the source abandoned the transaction.
1 change: 1 addition & 0 deletions docs/contributing/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ production queues, caches, or semantic helpers merely to share their names.
| optimistic state | The rows an optimistic transaction overlays on the applied synced rows while its mutation function runs. It drops when the mutation function settles, whether it fulfills or rejects. | Retained snapshot or accepted local snapshot. |
| accepted sync transaction | A committed sync transaction that core, or a wrapping sync after its durable step, has taken. It always applies, in commit order. While an optimistic transaction is persisting it is held, and it applies in the publication that drops that transaction's optimistic state. Handler-facing writes and Collection readiness wait for acceptance; commit receipts and subset loads wait for visibility. | Visible or applied sync transaction. |
| deferred sync transaction | A committed sync transaction that a wrapping sync has not handed to the Collection yet, because an earlier durable write is still running. Like a queued sync transaction, it holds settled optimistic rows on its keys until it applies. | Queued or accepted sync transaction. |
| reserved sync transaction | A sync transaction whose source called `reserveCommitTurn` and that has not committed or been abandoned. Every persisted hydration that would start while it is open waits for its commit. A source that stops for good abandons it. | Deferred sync transaction or held optimistic row. |
| held optimistic row | A successful transaction's optimistic row kept only while a committed sync transaction that has not applied touches its key, so the drop and that transaction publish together. The transaction may be queued in the Collection or deferred behind a wrapping sync's durable step. Its source attribution follows the key-and-timing rules in [VirtualOrigin](../reference/type-aliases/VirtualOrigin.md), not source-client identity. | Retained or accepted snapshot. |
| Collection status | One public Collection lifecycle value: `idle`, `loading`, `ready`, `error`, `crashed`, or `cleaned-up`. | Subscription status. |
| subscription status | One subscription value: `ready` or `loadingSubset`. | Collection status. |
Expand Down
198 changes: 196 additions & 2 deletions docs/contributing/oracle-coverage.md

Large diffs are not rendered by default.

1,462 changes: 1,462 additions & 0 deletions packages/browser-db-sqlite-persistence/tests/multi-tab-electric-oracle.test.ts

Large diffs are not rendered by default.

Loading
Loading