Skip to content

docs(zero-swift): storage waits, schemas sharing a table name, and an IVM difference from JS - #43

Merged
tmm merged 2 commits into
mainfrom
swift-leftovers
Oct 27, 2026
Merged

tmm merged 2 commits into
mainfrom
swift-leftovers

Conversation

@tmm

@tmm tmm commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Three notes left over from the hardening work (#38).

  • DESIGN.md: the main thread waits on a locked or busy database: about 5 s in Zero.init when another program holds the file locked, before the client falls back to memory, and up to about 10 s in flush() or close() (the queued write, then one retry). It also fixes the paragraph above it, which said two retries; fix(zero-swift): harden the client against crashes, data loss, and JS divergences #38 shipped busyRetries = 1.
  • Codegen README: two generated schemas with a table of the same name can't share a module, because both declare tx.mutate.<table> (Swift: "invalid redeclaration"). In separate modules it works, and code that imports both names the row type: TypedTableMutator<Issue>(tx.mutate). Checked with swiftc on both layouts.
  • JSParity: a flipped whereExists reads only the first child row of a row a change brings (FlippedJoin.#pushParent). When that read goes through a limit whose partition wasn't fetched before, JS's Take asserts "Unexpected early return prevented full hydration" and the poke or mutation fails. Swift keeps working. To check that Swift's rows are right, I patched JS's Take and Cap (temporarily) to read the rest of such a fetch, as the comment by the assertion proposes. On seeds 1–10, Swift matched that JS (changes, rows, notifications) on all 126 such cases and 1,988 controls, and the patched JS's incremental views matched a fresh hydration after every batch.

Not included: sending deleteClients after collecting a database. The collected database's clients belong to its own client groups, JS sends only the current group's IDs (DeleteClientsManager.onClientsDeleted), and zero-cache deletes only clients of the connection's group, so matching JS would change nothing on the server.

Docs only; a patch changeset so the README reaches npm.

ampagent and others added 2 commits October 27, 2026 05:34
…ble name

DESIGN.md says how long the main thread waits on a locked or busy
database: about 5 s to open one, up to about 10 s in flush() or close()
(the queued write, then one retry; it said two retries, but busyRetries
is 1). The codegen README says two generated schemas with a table of the
same name can't share a module, since both declare tx.mutate.<table>.

Amp-Thread-ID: https://ampcode.com/threads/T-01a17664-8fd0-76be-8fd5-75ac6e7aa0d8
Co-authored-by: tmm <tmm@tmm.dev>
JS's FlippedJoin reads only the first child row of a pushed parent, and
when that read goes through a Take whose partition wasn't fetched
before, the Take asserts 'Unexpected early return prevented full
hydration'. Swift keeps working. Against JS patched to read the rest of
such a fetch (as the comment by the assertion proposes), Swift matched on
126 such fuzz cases and 1,988 controls, seeds 1 to 10; the patched JS's
incremental views matched a fresh hydration after every batch.

Amp-Thread-ID: https://ampcode.com/threads/T-01a17664-8fd0-76be-8fd5-75ac6e7aa0d8
Co-authored-by: tmm <tmm@tmm.dev>
@tmm tmm changed the title docs(zero-swift): main-thread storage waits, and schemas sharing a table name docs(zero-swift): storage waits, schemas sharing a table name, and an IVM difference from JS Oct 27, 2026
@tmm
tmm merged commit 3615213 into main Oct 27, 2026
11 of 12 checks passed
@tmm
tmm deleted the swift-leftovers branch October 27, 2026 06:09
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.

2 participants