Skip to content

Implement server-side support for the v2 websocket protocol#4213

Merged
jsdt merged 61 commits intomasterfrom
jsdt/ws-v2
Feb 12, 2026
Merged

Implement server-side support for the v2 websocket protocol#4213
jsdt merged 61 commits intomasterfrom
jsdt/ws-v2

Conversation

@cloutiertyler
Copy link
Contributor

@cloutiertyler cloutiertyler commented Feb 5, 2026

Description of Changes

This adds the v2 websocket protocol and adds support on the server side. For context on many of the changes/decisions, you can look at the discussion on #4023.

To restate some of the key changes:

  • The reducer event information is no longer sent with transaction updates (because we don't want to broadcast reducer call information anymore).
  • If a client calls a reducer, they are sent a ReducerResult which includes the outcome of the reducer call and and related row updates for queries that the client is subscribed to.
  • We no longer dedupe queries that appear in multiple query sets for the same client. This is because we are moving toward per-query storage.
  • Related to that, Unsubscribe requests have an option to send the related rows. We need this for now, since clients don't have per-query storage implemented yet.
  • We don't have the json format in v2.

Notes for reviewers:

  • This moves around the messages in crates/client-api-messages/src/websocket (into common, v1, and v2), and this renaming of existing messages adds a lot of noise to the PR.
  • In many places, I chose to duplicate a lot of code to have a v1 version and a v2 version. I went with this to make it easier to remove the v1 version in the future (hopefully we can just fully delete most of the v1 functions).
  • module_subscription_manager.rs has probably has the biggest changes, since we now track queries by query_set_id, and we get to remove some complexity of v1's FormatSwitch.

API and ABI breaking changes

The v1 protocol still works, though we won't send the reducer event info for v10 modules.

Expected complexity level and risk

  1. This touches a lot of places.

Testing

Unit testing is pretty minimal for the new code paths. I've done some manual e2e testing with the typescript quickstart, and this has been tested with a different branch implementing the v2 rust client.

Resolve merge conflicts and fix compilation errors:
- Recreate message_handlers_v1.rs and message_handlers_v2.rs (v1/v2 dispatch)
- Adapt for Option<ReducerName> change from master
- Convert TableName to Box<str> for TableUpdate::new calls
- Fix async closure annotations in call_view_add_v2_subscription
- Fix BTreeMap key type (TableName doesn't impl Ord)
Copy link
Contributor

@Centril Centril left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned about the amount of duplication that could turn into high-interest technical debt if we don't fuse the code and v1 stays on for more than a few months. I do think we should fuse the code, but not in this PR, which now looks good from a semantic and performance standpoint.

This is good to merge :)

@jsdt jsdt enabled auto-merge February 12, 2026 17:00
@jsdt jsdt added this pull request to the merge queue Feb 12, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to a conflict with the base branch Feb 12, 2026
@jsdt jsdt enabled auto-merge February 12, 2026 19:27
@jsdt jsdt added this pull request to the merge queue Feb 12, 2026
Merged via the queue into master with commit 184d4e9 Feb 12, 2026
31 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants