Skip to content

Update typescript sdk to use v3 websocket api#4762

Open
joshua-spacetime wants to merge 2 commits intojoshua/ws/v3from
joshua/ts/v3-ws-bindings
Open

Update typescript sdk to use v3 websocket api#4762
joshua-spacetime wants to merge 2 commits intojoshua/ws/v3from
joshua/ts/v3-ws-bindings

Conversation

@joshua-spacetime
Copy link
Copy Markdown
Collaborator

Description of Changes

Adds TypeScript SDK support for the v3.bsatn.spacetimedb websocket API which was added in #4761.

v3 just adds batching on top of v2, so adding support for it just required the following:

  1. The client negotiates the protocol with the server and falls back to v2 if necessary
  2. When v3 is negotiated, same-tick outbound client messages are batched into a single ws frame
  3. Inbound v3 server frames are unwrapped into their inner v2 messages and processed in-order

Some notes on the batching behavior:

  1. Outbound v3 frames are capped at 256 KiB (unless a single message exceeds the limit)
  2. The SDK sends one v3 frame per flush
  3. If more messages remain queued after hitting the cap, it schedules a follow-up flush on a later task instead of draining in a tight loop, so that outbound ws work doesn't starve inbound ws work or any other event-loop tasks

API and ABI breaking changes

None, v2 fallback remains supported, so existing servers that only negotiate v2 still work with the updated client.

Expected complexity level and risk

3

Constraints that must hold:

  1. Same-tick sends should coalesce under v3
  2. v2 should remain unaffected
  3. Capped batching should not starve inbound processing
  4. Server frames containing multiple logical messages must be processed in-order
  5. Handshake fallback to v2 must remain correct

Testing

Added tests for the fast path and fallback behavior

Copy link
Copy Markdown
Collaborator

@coolreader18 coolreader18 left a comment

Choose a reason for hiding this comment

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

LGTM

I know this isn't the topic of changes in this PR, but is there a point to having distinct Single / Batch frames? How is a Single frame different from a Batch of 1? And then you have redundant data in the binary payload: 0x01 /* <- this frame has more than 1 message */ 0x00_00_00_01 /* <- now here's how many messages this frame has */. The data in the enum tag is already communicated in the array length.

Comment on lines +6 to +7
type ClientFrame as ClientFrameValue,
type ServerFrame as ServerFrameValue,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This seems unnecessary. You can just use ClientFrame / ServerFrame as types, you don't even need these type imports.

@joshua-spacetime
Copy link
Copy Markdown
Collaborator Author

How is a Single frame different from a Batch of 1?

It's not.

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