Skip to content

Commit 023221d

Browse files
authored
refactor: frame bus + pipe mode tests (unified frame pipe follow-ups) (#725)
* test(runtimed): add pipe mode integration tests Cover the unified pipe code paths that had zero test coverage: - Sync frames forwarded with correct type byte prefix - Only valid frame types piped (never Request/Response) - Response frames consumed by request/response cycle, not piped - Frame ordering preserved across rapid mutations * refactor: replace webview.emit fan-out with in-memory frame bus Introduce notebook-frame-bus.ts — a module-level pub/sub that replaces the webview.emit('notebook:broadcast') and webview.emit('notebook:presence') fan-out pattern. Subscribers now receive payloads via direct function call instead of async Tauri event dispatch. - useAutomergeNotebook: calls emitBroadcast/emitPresence instead of webview.emit after WASM demux - useDaemonKernel: subscribeBroadcast() replaces webview.listen - useEnvProgress: subscribeBroadcast() replaces webview.listen - usePresence: subscribePresence() replaces webview.listen Only notebook:frame remains as a Tauri webview event (the relay pipe). All downstream dispatch is synchronous and in-memory. * test: strengthen pipe mode tests per Codex review - Rename test_pipe_mode_forwards_broadcast_frames to test_pipe_mode_only_pipes_allowed_frame_types — honest about what it checks (type-byte filter, not broadcast-specific forwarding) - Add comment noting broadcast frames require a kernel (E2E coverage) - test_pipe_mode_preserves_frame_order now verifies: - No duplicate frames (coalescing would violate ordering contract) - Third client convergence (all 3 cells with correct sources) * docs: note ordering test limitation per Codex review
1 parent 5db3d83 commit 023221d

File tree

6 files changed

+738
-332
lines changed

6 files changed

+738
-332
lines changed

apps/notebook/src/hooks/useAutomergeNotebook.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
updateNotebookCells,
2020
useNotebookCells,
2121
} from "../lib/notebook-cells";
22+
import { emitBroadcast, emitPresence } from "../lib/notebook-frame-bus";
2223
import {
2324
notifyMetadataChanged,
2425
setNotebookHandle,
@@ -216,8 +217,8 @@ export function useAutomergeNotebook() {
216217
// one event. The WASM handle.receive_frame() demuxes by the first byte,
217218
// applies sync internally, and returns typed FrameEvent JSON.
218219
//
219-
// Broadcasts are re-emitted as "notebook:broadcast" for backward compat
220-
// with useDaemonKernel and useEnvProgress (they listen independently).
220+
// Broadcasts and presence are dispatched via the frame bus (in-memory
221+
// pub/sub) to useDaemonKernel, useEnvProgress, and usePresence.
221222
const unlistenFrame = webview.listen<number[]>(
222223
"notebook:frame",
223224
async (event) => {
@@ -264,21 +265,14 @@ export function useAutomergeNotebook() {
264265
break;
265266
}
266267
case "broadcast": {
267-
// Re-emit as "notebook:broadcast" for useDaemonKernel/useEnvProgress
268-
// backward compat. They listen independently and expect JSON payloads.
269268
if (frameEvent.payload) {
270-
webview
271-
.emit("notebook:broadcast", frameEvent.payload)
272-
.catch(() => {});
269+
emitBroadcast(frameEvent.payload);
273270
}
274271
break;
275272
}
276273
case "presence": {
277-
// Re-emit for usePresence hook
278274
if (frameEvent.payload) {
279-
webview
280-
.emit("notebook:presence", frameEvent.payload)
281-
.catch(() => {});
275+
emitPresence(frameEvent.payload);
282276
}
283277
break;
284278
}

0 commit comments

Comments
 (0)