Zero 0.24
Join Flipping, Cookie Auth, Previews
Installation
npm install @rocicorp/zero@0.24
Features
- Join Flipping: Dramatically improves the performance of
whereExists()
in many common cases. Join flipping is a form of manual query planning that tells Zero the order to evaluate joins. An automatic planner will follow in a future release. - Simplified Auth: If you are using custom mutators and synced queries, you no longer need to use JWT auth. You can use opaque tokens or even better, plain old cookies. This even means you can use HTTP-only cookies. In our demo apps this eliminated hundreds of lines of code. It's a big improvement.
- Full Preview Support: We tried to get this out in 0.23 but it didn't quite make it. You can now dynamically configure Zero with the location of your mutator and query endpoints. This allows easily using preview URLs on platforms like Vercel.
- Analyze Query from Inspector: No more
npx zero-analyze-query
or ssh'ing into production. You can analyze any query right from the dev tools of your browser. On by default in every Zero app. - Simplified Metrics Output in Inspector: No more
.metrics["long-name-i-cant-remember"].quantile(0.99)
. The most important metrics – hydration and update time – are right on the query object. Also, you don't have to(await __zero.inspect()).client.queries
anymore. It's just__zero.inspector.client.queries()
. - New Type helpers:
QueryResultType
andQueryRowType
are handy ways to get the type of a query result or one of its rows. - Faster storage for React Native via op-sqlite: The op-sqlite bindings are faster than the expo built-in ones. We now provide this built-in to Zero.
- Brand New Cloudflare Sample: Turned the old hello-zero-do sample into a complete Cloudflare sample using workers for everything.
- Improved ZQL server-side APIs: More convenient setup, and added
node-postgres
and Drizzle support.
Fixes
- Expose server errors from
get-queries
endpoint to client - Correctly map primary keys to server names in some edge cases
- Reduce some OTEL error logging to
warn
- Fix a case of deadlock related to CVR cleanup
- Fix hang on shutdown under Bun CLI (thanks David!)
- Fix "View already exists" error, Discord
- Fix rows sometimes missing from
startAt
queries - Improve performance of CVR cleanup
- Disable statement-level timeouts that were preventing CVR cleanup
- Fix WAL growth when no connected clients
- Fix exception with local-only queries and
enableLegacyQueries:false
- Fix inability to use
--flags
withzero-cache-dev
(thanks Alizain!). - Reduce ping timeouts during slow queries with better time-slicing
- Improve handling of ownership changes in the change-streamer
Breaking Changes
- If you are using the
push.url
param to theZero
constructor, rename it tomutateURL
(more info). - If you are using the
ZERO_PUSH_URL
config param, rename it toZERO_MUTATE_URL
(more info). - If you are awaiting queries directly without calling
run()
, likeawait z.query.foo.where(...)
, orawait tx.query.foo.where(...)
, add.run()
to the end, likeawait z.query.foo.where(...).run()
orawait tx.query.foo.where(...).run()
.. This is most common in custom mutator implementations (more info) - If you are building for React Native, change your import path from
@rocicorp/zero/react-native
to@rocicorp/zero/expo-sqlite
(more info) - Add a
ZERO_ADMIN_PASSWORD
env var to your production config. This is now required (more info)
Example Upgrades
- ztunes
- zslack
- hello-zero-solid
- hello-zero – Note that we are keeping
hello-zero
on the legacy query and mutator APIs until they are deprecated, for testing reasons. So this PR doesn't include custom mutator, synced query, or auth-related changes.