Skip to content

fix(bridge): keep the extension connected on dsh 0.2.1 (Peer is mandatory) - #130

Open
under-the-ocean wants to merge 1 commit into
omdsh-dev:mainfrom
under-the-ocean:fix/bridge-peer-scope
Open

under-the-ocean wants to merge 1 commit into
omdsh-dev:mainfrom
under-the-ocean:fix/bridge-peer-scope

Conversation

@under-the-ocean

Copy link
Copy Markdown

Problem

On dsh 0.2.1-rc.2 the Chrome/Edge extension can never stay connected: the panel loops on “dsh is not connected (check the bridge address and token in Settings)”, and the host log shows nothing.

Captured on the extension service worker (CDP, Edge 157) against a real dsh web host:

OPEN
SENT {"t":"hello","token":"","caps":{...}}
RECV {"t":"hello.ok","caps":{...}}
RECV {"t":"error","code":"stream-failed","message":"TypeError: Cannot read properties of undefined (reading 'signal')"}
CLOSE 1011 event stream failed        # → endless reconnect

Root cause

dsh 0.2.1 made PeerScope mandatory on both Gateway entry points the bridge uses:

  • TypertGatewayWireStream.open(endpoint, payload, uplink, peer, signal) — 0.2.1 runs assertPeerLive(peer) and reads peer.signal; the typings now say “@PARAM peer — Peer the stream speaks for; required, never defaulted.”
  • InvokeRemoteRequest.peer — likewise required (“every carrier and in-process caller names it explicitly”).

remote-host-api.ts passed undefined for that slot, which dsh 0.2.0 tolerated. On 0.2.1 the $events stream therefore fails right after hello.ok, so the extension never reaches a usable state — and every RPC would fail for the same reason.

Fix

Resolve the Peer once from the injected Connection service and forward it through every Gateway call:

  • resolvePeer(connection): connection.browserPeer (0.2.1 admits browser traffic through an owner Peer) → falls back to connection.createPeer({ principal: { kind: 'owner' } })
  • forwarded to invoke, workspace/follow, session/follow (including the one-shot snapshot helper) and $events
  • runtimes that expose neither peer source keep the previous peerless call, so 0.2.0 behaviour is unchanged (the existing test that asserts peer === undefined still passes)

Verification

  • Isolated 0.2.1-rc.2 host (temporary DSH_HOME, own port) probed with the extension’s own wire protocol: hello → hello.ok, then a real session.list RPC → {"t":"rpc.result","id":"probe-1","ok":true,...}, socket stays open (no stream-failed).
  • Against the reporter’s live host + Edge unpacked extension: browser_list_tabs returns real tabs, i.e. extension ↔ bridge ↔ dsh fully connected.
  • tests/remote-host-api.spec.ts: 22 passed (3 new tests: peer forwarded from browserPeer; owner Peer minted via createPeer; peerless fallback preserved).
  • Full plugin suite: 149 passed, 1 pre-existing failure unrelated to this change — token.spec.ts asserts file mode 0600, which Windows cannot represent.

Note for maintainers

peerDependencies still pins the dsh packages to 0.2.0-rc.2, so running this plugin on 0.2.1 currently needs
dsh plugin --profile web allow-version @yuxianglin/dsh-bridge-browser@0.0.7 --dsh-version 0.2.1-rc.2 --accept-risk.
I left that declaration alone: widening it is a support-policy call (semver ranges need an explicit prerelease tuple to admit 0.2.1-rc.x), and I would rather do it in a follow-up once you decide the supported window. Happy to add it here if you prefer a single patch.


CN 摘要:dsh 0.2.1 起 PeerScope 在 invoke / wireStream.open 上变成必填(内部 assertPeerLive(peer) 会读 peer.signal),插件仍按 0.2.0 传 undefined,于是 hello.ok 后立刻 stream-failed + WS 1011,扩展无限重连。本 PR 从 Connection 服务解析 Peer(browserPeer,回退 createPeer({principal:{kind:'owner'}}))并贯穿所有网关调用;无 peer 来源的运行时保持原行为,0.2.0 不受影响。已在隔离 0.2.1 宿主用扩展协议验证 hello.ok + 真实 RPC 成功,新增 3 个回归测试。

dsh 0.2.1-rc.2 made PeerScope mandatory on both TypertGateway.invoke and
wireStream.open: open() runs assertPeerLive(peer) and reads peer.signal, so a
call without a peer rejects with "TypeError: Cannot read properties of
undefined (reading 'signal')".

The bridge passed undefined for that slot, so on 0.2.1 the extension received
hello.ok and then an immediate { t: 'error', code: 'stream-failed' } followed by
WS 1011 and an endless reconnect loop: the side panel stayed on "dsh is not
connected".

Resolve the Peer once from the Connection service (browserPeer, else
createPeer({ principal: { kind: 'owner' } })) and forward it through invoke,
workspace/follow, session/follow and the $events stream. Runtimes that expose
neither keep the previous peerless call, so dsh 0.2.0 is unaffected.
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