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>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
// 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;
|
||||
}
|
||||
Reference in New Issue
Block a user