Repository navigation
v0.2.0
Changed
-
Author-owned schema;
registerSyncwires the sync. Breaking. Collection
definitions are now{ table, pk }—ddlis removed. You create your tables
yourself (raw DDL, Drizzle, any migrator), then callthis.registerSync(registry)
— typically in your constructor'sblockConcurrencyWhile, after migrating. It
validates each table (onePRAGMA: the pk is a soleTEXTclient key — D9) and
installs the CDC triggers. LazyinitRegistry-on-fetchis gone; schema exists
before the first event. Forget the call →this.registrythrows loud. This also
retiresrunSyncedWrite's "caller ensures init" caveat. See
ADR-0007. -
The cursor
fetchframe now mirrors@tanstack/db'sLoadSubsetOptions.
Breaking wire change (client and server ship together). The frame carries a
basewhereplus a rawcursor: { whereFrom, whereCurrent }— TanStack's own
CursorExpressionsnames and semantics (the cursor expressions exclude the
basewhere) — replacing the previous privatewhere/tiesfields that
combined the predicates client-side. The server now composesbase AND whereCurrent(ties, unbounded) andbase AND whereFrom(next page, bounded by
limit). Behaviour is unchanged (identical compiled SQL); the win is
traceability to upstream. A malformed cursor (a missing half) is now rejected
loudly instead of degrading to an unbounded scan. See
ADR-0005. -
Collection pk validation accepts TEXT affinity, not the literal
"TEXT".
registerSyncnow admits any TEXT-affinity pk (TEXT,VARCHAR,CHAR,
NVARCHAR, …) so ORM/migrator-generated DDL composes;INTEGER(rowid alias)
and other non-TEXT affinities are still rejected loudly (they'd break optimistic
id parity). Part of ADR-0007.
Added
runSyncedWrite(fn)— aprotectedSyncDurableObjectprimitive for
server-originated writes (an agent inserting a row, a webhook, a cron/
alarmjob, an admin edit, a bulk seed): apply a raw synchronous SQL closure
in a transaction, then broadcast the resulting CDC to connected clients.
Outside the client mutation flow — notxId, no receipt, no dedup (idempotency
rides the collection's mandated stable keys).
See ADR-0006.examples/board— an at-scale stress example: 5,000 tasks on one DO,
bounded window load,useLiveInfiniteQuerycursor scroll-back, and a mutable
order key (updated_at) so voting/starring bumps a task to the top (move-in
via the always-emit upsert). A server-side firehose makes the deferred
bounded-window-under-churn limitation visible:loadedclimbs pastwindow.- A real-tie integration test (unbounded boundary ties + limited next page + base
predicate composed into both halves) covering the cursorfetchagainst the DO. - A move-in integration test: a cold row bumped server-side arrives via the
no-wherelive sub and upserts into the collection (ADR-0002 C4).