Skip to content

Commit 3615213

Browse files
authored
docs(zero-swift): storage waits, schemas sharing a table name, and an IVM difference from JS (#43)
Amp-Thread-ID: https://ampcode.com/threads/T-01a17664-8fd0-76be-8fd5-75ac6e7aa0d8
1 parent 81cdb09 commit 3615213

4 files changed

Lines changed: 26 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'zero-swift': patch
3+
---
4+
5+
Documents that the main thread waits up to about 5 s when it opens a database another program holds locked, and up to about 10 s in `flush()` or `close()` on a busy one; that two generated schemas with a table of the same name need modules of their own; and that a flipped `whereExists` reaching a `limit` early, where JS asserts "Unexpected early return prevented full hydration", keeps working in Swift.

‎packages/zero-swift-cli/README.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ Rename a row struct whose name clashes with a type you use. A table named
5656
`list` generates `struct List`, which hides SwiftUI's `List`; set
5757
`tables.list.type` to `NoteList`, or set a `typePrefix`.
5858

59+
Two generated schemas with a table of the same name can't share a module:
60+
both declare `tx.mutate.<table>`. Generate each into a module of its own.
61+
Code that imports both names the row type, as in
62+
`TypedTableMutator<Issue>(tx.mutate).insert(…)`.
63+
5964
### Names
6065

6166
Tables, columns, relationships, JSON fields and enumeration values keep

‎swift/DESIGN.md‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,18 @@ Rationale:
219219
- If the store can't be opened, the client runs on memory and calls
220220
`onStorageFailure`, as JS does. A failed write stops writing and calls it
221221
too. A write that finds the database busy is kept and written with the
222-
next one, or by `flush()` and `close()`, which try twice more before they
222+
next one, or by `flush()` and `close()`, which try once more before they
223223
call it a failure. Stored data that doesn't decode is lost client state,
224224
as a corrupt ref count is in JS: the client deletes the database, starts
225225
a new one, and calls `onClientStateNotFound` if the app set it.
226+
- These waits are on the main thread, each up to SQLite's 5 s busy
227+
timeout. Opening a database another connection holds locked blocks
228+
`Zero.init` for about 5 s before the client falls back to memory, and
229+
`flush()` or `close()` on a busy database blocks for up to about 10 s:
230+
the queued write, then the retry. With one process per store, only
231+
another program with the file open, such as a SQLite browser, holds
232+
such a lock. Opening and closing the store off the main actor would
233+
avoid the waits; that is deferred.
226234
- A client writes a poke's snapshot only when its cookie is newer than the
227235
stored one, as Replicache persists, so a client of the group that is
228236
behind another doesn't overwrite it.

‎swift/Sources/Zero/Zero.docc/JSParity.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ is written or sent.
163163
connection in the `error` state, a mutation that fails is committed and
164164
its `client` outcome is the error, and later mutations, `materialize`,
165165
and `run` fail with the same message.
166+
- **A flipped `whereExists` stopping a `limit` early.** To learn whether a
167+
row a change brings has a match, a flipped `whereExists` reads its
168+
subquery's first row only. When that read goes through a `limit` whose
169+
rows for this row weren't read before, JS asserts ("Unexpected early
170+
return prevented full hydration") and the change fails as above. Swift
171+
keeps working and shows the rows JS shows once its `Take` reads the rest
172+
of such a fetch, as the comment by that assertion proposes.
166173
- **Nulls in columns that can't be null.** When the server sends null for
167174
a column the schema says isn't optional, a `String`, `Double`, `Int`, or
168175
`Bool` property reads as `""`, `0`, or `false`. JS hands the null

0 commit comments

Comments
 (0)