fix(dashboard): null WebSocket handlers before close to stop terminal tab doubling

Creating a new terminal tab caused every pty data chunk (including
keystroke echo) to render twice in xterm. The connect-effect's
`contextChanged` dep flips true→false in the same render cycle as
the new connection: the effect re-runs, React calls cleanup which
closed the still-CONNECTING WS without nulling its handlers, then
connect() opens a fresh WS. The ghost socket's onmessage continued
firing on the shared `onDataCallbacksRef` Set, delivering each chunk
twice (and producing the "WebSocket is closed before the connection
is established" warning). Null onopen/onmessage/onclose/onerror in
both cleanup() and connect()'s pre-close branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-05 23:29:07 -07:00
parent 9ff2af567d
commit b6ffb613b0
2 changed files with 22 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
"@runfusion/fusion": patch
---
Fix terminal input/output doubling triggered by creating a new tab. The connect-effect's `contextChanged` dependency flips true→false in the same render cycle as the new connection, re-running the effect and closing the still-CONNECTING WebSocket. Because `cleanup()` and `connect()`'s pre-close paths weren't nulling `ws.onopen`/`onmessage`/`onclose`/`onerror`, the ghost socket's `onmessage` continued to fire on the shared callback Set, delivering each pty data chunk (including keystroke echo) twice to xterm.