// M9 (plan §13): does the core give the same packet trace in Node and in a // browser? One run of an example — read from its .fls, through the shared // document, started and advanced tick by tick, with a few lines typed (a // command line installed where the example has none) — as // text: every card's capture in both views and every command line's window. // Node and Chromium each compute it; the texts must be equal. import * as Y from 'yjs'; import { NetworkRuntimeEngine } from '@mdg-filius/core'; import { docSnapshot, readProject, writeProject } from '@mdg-filius/doc'; import { openProjectArchive } from '@mdg-filius/fls'; import { traceFramesOf } from '../src/room.js'; export const M9_SECONDS = 30; const SEED = 14; export function traceText(archive: Uint8Array): string { let counter = 0; const opened = openProjectArchive(archive, () => `00000000-0000-0000-0000-${(++counter).toString(16).padStart(12, '0')}`); // An example without a command line gets one on its first PC or notebook, so that every run has traffic. if (![...opened.installedPrograms.values()].some((programs) => programs.has('commandPrompt'))) { const host = opened.graph.nodes.find((node) => node.kind === 'pc' || node.kind === 'notebook'); if (host !== undefined) opened.installedPrograms.set(host.id, new Set([...(opened.installedPrograms.get(host.id) ?? []), 'commandPrompt'])); } const doc = new Y.Doc(); writeProject(doc, opened); const project = readProject(doc); const engine = new NetworkRuntimeEngine(SEED, undefined, { wallClock: () => 0 }); engine.handle({ type: 'start', snapshot: docSnapshot(doc), seed: SEED, initialTimeMilliseconds: 0 }); // The first command line pings the first other host with an address and asks for a name. const terminal = project.graph.nodes.find((node) => project.installedPrograms.get(node.id)?.has('commandPrompt') === true); const target = project.graph.nodes.map((node) => project.deviceConfigurations.get(node.id)?.ipAddress).find((ip) => ip !== undefined && ip !== '' && ip !== project.deviceConfigurations.get(terminal?.id ?? '')?.ipAddress); const typed: [number, string][] = [ [5_000, 'ipconfig'], [6_000, `ping ${target ?? '127.0.0.1'}`], [15_000, 'host www.filius.de'], ]; for (let t = 200; t <= M9_SECONDS * 1_000; t += 200) { engine.handle({ type: 'advance', toMilliseconds: t }); for (const [at, line] of typed) if (at === t && terminal !== undefined) engine.terminal(terminal.id)?.enter(line); } const cards = engine.capture.portIds().sort().map((portId) => ({ portId, frames: traceFramesOf(engine.capture.frames(portId)) })); const windows = project.graph.nodes.flatMap((node) => { const log = engine.terminal(node.id)?.log.all; return log === undefined ? [] : [{ node: node.id, log }]; }); return JSON.stringify({ cards, windows }); }