Skip to content

feat(bridge): carry bridge traffic over simlock's multiplexed link - #203

Open
V3RON wants to merge 1 commit into
mainfrom
feat/bridge-link
Open

V3RON wants to merge 1 commit into
mainfrom
feat/bridge-link

Conversation

@V3RON

@V3RON V3RON commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

What is this?

The connection between the Harness CLI and the app now runs over the multiplexed WebSocket link from simlock. Previously, RPC messages and screenshot bytes shared one WebSocket with no ordering or flow control: a large screenshot went out as a single binary frame, and the CLI held it in memory until a separate RPC call claimed it. This PR replaces that transport. The RPC protocol and the public connectToHarness / createHarnessBridge APIs stay the same.

How does it work?

The link wraps one WebSocket and carries two kinds of traffic:

  • Text messages: the existing JSON RPC, test events, the ready message and heartbeat ping/pong. They travel in a priority lane.
  • Byte channels: multiplexed ReadableStream/WritableStream pairs, sent in 64 KiB frames with per-channel credit. A screenshot is written into a channel, and the RPC call carries only the channel id. The CLI accepts the channel, reads it to the end and writes the file.

The link lives in packages/bridge/src/link/. It is a copy of simlock's src/link at b730ef3 plus a standard-WebSocket transport used on both ends: over ws in the CLI, and over the platform WebSocket in the app. The copy stays close to upstream, and each local change is marked with a harness: comment. link/README.md explains each change; most are for React Native:

  • Hermes has no WHATWG streams, so the link falls back to the web-streams-polyfill ponyfill without installing globals, leaving the app under test unchanged.
  • React Native's WebSocket never sets bufferedAmount, so a missing value counts as 0.
  • Channel ids are encoded as ASCII instead of using TextEncoder/TextDecoder.
  • The client supplies its own channel ids because React Native has no crypto.randomUUID.

The upstream link tests come along with it, plus tests for the React Native conditions above and an end-to-end screenshot transfer between createHarnessBridge and connectToHarness.

Why is this useful?

Test events and heartbeats no longer queue behind screenshot data, and large binary payloads stream with backpressure instead of landing in memory as one frame. Byte channels also give the bridge a general way to move binary data in either direction, so future features such as files or other artifacts do not need a new ad hoc frame format. The CLI and the app runtime must run the same Harness version, because the wire protocol has changed.

@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
react-native-harness Ready Ready Preview Oct 15, 2026 12:46pm UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview — f9e6d915 Deployed Oct 15, 2026 by vercel[bot]
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.

1 participant