// 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; }