@docstack/react 0.1.1: lists can become empty again
@docstack/react 0.1.1 is on npm. It is a one-fix release on top of 0.1.0, which was the first publish of the rewritten bindings a week earlier. This post covers the fix and, for anyone still on 0.0.9, what the 0.1 line changed.
The fix: useFind applies empty results
useFind guarded its state update on result.docs.length, so a live list could gain rows but never lose its last one. Deleting the last task shown for a day left it on screen, clickable and pointing at a document that no longer existed, until the component remounted.
The guard was standing in for a staleness concern: a slow earlier query must not overwrite a fast later one. That concern is now owned by a run counter, the same discipline useQuerySQL already used, and every result is applied, including an empty one. Consumers that worked around the bug by intersecting the hook's result with their own set can drop the workaround on upgrade. See ADR-0035.
Paired client release
0.1.1 shipped alongside @docstack/client 0.1.8. One client change is visible from the hooks: a stack added after sync() now joins the running replication, so useSyncStatus reports workspaces mounted later instead of silently omitting them, and DocStack.getSyncCoverage() tells an idle stack apart from an unbound one. See ADR-0034.
What 0.1.0 changed
Published 2026-08-27, 0.1.0 rewrote the hooks around one idea: a query is a subscription.
useQuerySQLis live by default. It derives which classes to watch from the query's own AST, so aJOINacross three classes re-runs when any of the three changes. Bursts coalesce into one re-run (150 ms by default). Pass{ live: false }for a deliberate snapshot. The signature becameuseQuerySQL(stack, sql, params?, options?)withparamsas an array, and the hook returns arefetchfunction. See ADR-0025 and ADR-0026.StackProviderreconciles itsconfigprop. A stack that appears in the array is opened, one that disappears is closed, and the rest keep running. Reconciliations are serialized, which also removed a race under React's double-invoked effects that produced409conflicts on the system document. See ADR-0022.- The pre-ready window is startup, not an error. The context publishes
nulluntil the provider'sreadyevent, and every hook keepsloading: truethrough that window rather than reporting "loaded and empty". useSyncStatussubscribes to stacks, not to replication handles, so it survives arestart()after a refreshed credential and works whether it mounts before or aftersync()was called.- Types come from
@docstack/client.Patch,ClassModel,Document,SyncStatus,StackConfigand the rest are re-exported from the client so an application using both packages holds one copy of each type.
Installing
npm install @docstack/react @docstack/client pouchdb-browser pouchdb-find
React 19 is a peer dependency. The React bindings guide walks through the provider and every hook; the generated API reference lists their signatures.
