Skip to content

feat(zero-rust): getTraceparent and batchViewUpdates options, preload's default TTL - #206

Merged
tmm merged 4 commits into
mainfrom
feat/zero-rust-traceparent
Nov 14, 2026
Merged

tmm merged 4 commits into
mainfrom
feat/zero-rust-traceparent

Conversation

@tmm

@tmm tmm commented Nov 14, 2026 •

Copy link
Copy Markdown
Member

Part of the Rust parity push: two JS options the Rust client lacked.

Releases as zero-rust 0.2.0 (minor changeset): adding public fields to ZeroOptions breaks a struct literal that names every field (constructible_struct_adds_field). ZeroOptions stays a plain struct; later new options are minor bumps too.

getTraceparent. JS puts a W3C traceparent on every changeDesiredQueries, initConnection message, and push it sends. Rust and Swift hard-coded none.

  • ZeroOptions::get_traceparent in Rust and ZeroOptions.getTraceparent in Swift fill it in the places JS does.
  • The Sec-WebSocket-Protocol header stays without one, as in JS.

batchViewUpdates. JS wraps each update of the views in it: a new view's creation, and each change (poke, mutation, first hydration) together with its listener calls. That lets a UI render one batch at once.

  • ZeroOptions::batch_view_updates does the same in Rust. A callback that doesn't call the function it's given panics with JS's assertion message.
  • Swift's QueryContext already took this internally; ZeroOptions.batchViewUpdates exposes it.

Ttl::DEFAULT_PRELOAD. JS's preload default is none (0 ms). Ttl::default() is the 5 minutes that views and run use, so passing it to a preload would keep the query synced 5 minutes longer than JS does.

rust/PARITY.md.

  • Lists the options still not ported: slowMaterializeThreshold, and the deprecated maxRecentQueries.
  • Maps the deprecated aliases (server, getQueriesURL, onOnlineChange).
  • Explains the two defaults that differ from JS: memory storage, and no delay before a hidden app disconnects.

Vectors. Three new JS client scenarios, through traceparent and batchViewUpdates scenario options in harness.ts:

  • connection.ts: traceparents on query changes before and after connecting, and on a push.
  • connection.ts: a traceparent on an initConnection too large for the header.
  • pokes.ts: each batch that wrapped listener calls, with how many: one per poke and per mutation, across every view. How often JS calls the callback with nothing to update (while hydrating) isn't recorded.

Without the Rust changes, these scenarios fail in Rust. Removing the batch around a change fails the batching scenario on memory and on SQLite.

Checks.

  • Rust conformance: client.json 187/187, memory and SQLite.
  • Swift: swift test --filter ClientConformanceTests and swift format lint --strict pass.
  • Rust: cargo test --workspace, clippy -D warnings, and cargo doc -D warnings pass.
  • Benchmarks: pokes, mutations, and first sync against main in turns, in both orders, are within ±4% noise.

ampagent and others added 2 commits November 14, 2026 03:49
JS's `getTraceparent` option adds a W3C traceparent to each
changeDesiredQueries, initConnection message, and push the client sends.
Rust and Swift hard-coded none. `ZeroOptions::get_traceparent` (Swift:
`ZeroOptions.getTraceparent`) now fills it where JS does, and not in the
Sec-WebSocket-Protocol header, which JS leaves without one.

Two new client scenarios record JS's messages with a traceparent: query
changes before and after connecting with a push, and an initConnection too
large for the header. Both clients' runners map the scenario option.

`Ttl::DEFAULT_PRELOAD` is JS's preload default (none), since
`Ttl::default()` is the 5 minutes of views and run. PARITY.md lists the
remaining options JS has and Rust doesn't, and the two defaults that
differ (memory storage, no hidden-app delay).

Amp-Thread-ID: https://ampcode.com/threads/T-db04f816-97ed-4bc9-b19e-9ee68611a0ab
Co-authored-by: tmm <tmm@tmm.dev>
JS's `batchViewUpdates` option wraps each update of the views: a new view's
creation, and each change that updates the views (a poke, a mutation, the
first hydration) with its listener calls, so a UI can render a batch of
state changes at once. `ZeroOptions::batch_view_updates` (Swift:
`ZeroOptions.batchViewUpdates`, which Swift's QueryContext already took
internally) now does the same, and panics with JS's message when the
callback doesn't call the function it is given.

A new client scenario records, through a `batchViewUpdates` scenario
option, each batch that wrapped listener calls and how many: one per poke
and per mutation, over every view. How often JS calls it with nothing to
update, such as while hydrating, isn't recorded. Without the batch around
a change, Rust fails it.

Amp-Thread-ID: https://ampcode.com/threads/T-db04f816-97ed-4bc9-b19e-9ee68611a0ab
Co-authored-by: tmm <tmm@tmm.dev>
@tmm tmm changed the title feat(zero-rust): getTraceparent, and preload's default TTL feat(zero-rust): getTraceparent and batchViewUpdates options, preload's default TTL Nov 14, 2026
ampagent and others added 2 commits November 14, 2026 05:23
Adding a public field to ZeroOptions breaks a struct literal that names
every field, so the changeset is a minor bump (0.1.3 to 0.2.0), as
decided for how ZeroOptions grows: it stays a plain struct, and later
options are minor bumps too.

Amp-Thread-ID: https://ampcode.com/threads/T-db04f816-97ed-4bc9-b19e-9ee68611a0ab
Co-authored-by: tmm <tmm@tmm.dev>
Before 1.0, a changeset minor (0.1.3 to 0.2.0) is the release Cargo lets
break the API, but the API-break check passed cargo-semver-checks
--release-type minor, which allows only additive changes, so the new
ZeroOptions fields failed it. A 0.x minor is now checked as major; patch
and major are unchanged.

Amp-Thread-ID: https://ampcode.com/threads/T-db04f816-97ed-4bc9-b19e-9ee68611a0ab
Co-authored-by: tmm <tmm@tmm.dev>
@tmm
tmm merged commit 8f4916a into main Nov 14, 2026
24 checks passed
@tmm
tmm deleted the feat/zero-rust-traceparent branch November 14, 2026 12:35
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