Files
mdg-filius/packages/sim/src/serveRoom.ts
T
julian.kiedaischandClaude Opus 5.5 0fd42f10e2 feat(sim): F4.2 the sim protocol, the simulation room and LocalSimHost; M9 measured
packages/protocol holds the one list of /sim messages and checks every
field, naming what is wrong. packages/sim has the simulation room for F and
the web worker: the document's snapshot at start, the engine's clock on the
wall clock with Java's speed as cable delay, subscriptions to cable
activity, a card's new frames and a program's new window lines, capture and
clock kept over a stop, the command line as first action, a core failure
told to every client. LocalSimHost mirrors the document into the worker and
back without echo. M9 in Chromium: 17 examples give the same capture as in
Node, character for character; the room runs in a real worker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 08:32:20 +00:00

29 lines
1.2 KiB
TypeScript

// The worker's side: a replica of the editor's document and the room that
// reads it, ticking every TICK_MILLISECONDS.
import * as Y from 'yjs';
import { CHANNEL_ORIGIN, type ChannelMessage, type Port } from './channel.js';
import { SimulationRoom, TICK_MILLISECONDS, type RoomOptions } from './room.js';
export interface ServeOptions extends RoomOptions {
/** Calls `tick` every so many milliseconds. */
readonly every: (milliseconds: number, tick: () => void) => void;
}
export function serveRoom(port: Port, options: ServeOptions): SimulationRoom {
const doc = new Y.Doc();
doc.on('update', (update: Uint8Array, origin: unknown) => {
if (origin !== CHANNEL_ORIGIN) port.postMessage({ type: 'doc', update });
});
const room = new SimulationRoom(doc, options);
const client = room.connect((message) => port.postMessage({ type: 'host', message }));
port.addEventListener('message', (event) => {
const data = event.data as ChannelMessage;
if (data?.type === 'doc') Y.applyUpdate(doc, data.update, CHANNEL_ORIGIN);
else if (data?.type === 'client') room.receive(client, data.message);
});
port.start?.();
options.every(TICK_MILLISECONDS, () => room.tick());
return room;
}