import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import createModule from "../../build-wasm/linuxcnc-sim-core.js"; import { IoAckTracker } from "./io-ack.mjs"; import { SimSession, CONTEXT_ID } from "./sim-session.mjs"; const tracker = new IoAckTracker(); assert.equal(tracker.issue("op-1", "TOOL_CHANGE", 0, 2).status, "verified"); assert.equal(tracker.step(1).status, "verified"); assert.equal(tracker.ack("op-1", 1).command.status, "acked"); assert.equal(tracker.issue("op-2", "SPINDLE", 1, 1).status, "verified"); assert.equal(tracker.step(2).state.commands.find((command) => command.operation_id === "op-2").status, "timed_out"); assert.equal(tracker.ack("op-2", 2).code, "io_ack_late"); const saved = tracker.export(); const restored = new IoAckTracker(); assert.deepEqual(restored.restore(saved), saved); const core = await createModule({ wasmBinary: await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url)) }); const session = new SimSession(core, { sessionId: "io-ack" }); const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: "io-ack" }; const send = (kind, seq, operation_id, payload = {}) => session.accept({ ...base, kind, seq, operation_id, payload }); send("HELLO", 1); send("SESSION_ATTACH", 2, "attach"); send("LOAD_WORKSPACE", 3, "workspace", { root_path: "/workspace" }); assert.equal(send("IO_COMMAND", 4, "io-command", { command_id: "io-command", kind: "TOOL_CHANGE", timeout_ticks: 2 }).payload.io_ack.commands[0].status, "pending"); assert.equal(send("SIM_STEP", 5, "step", { cycles: 2 }).payload.io_ack.commands[0].status, "timed_out"); const late = send("IO_ACK", 6, "io-ack-late", { operation_id: "io-command" }); assert.equal(late.kind, "ERROR"); assert.equal(late.payload.code, "io_ack_late"); console.log(`io_ack=passed timeout=${tracker.state.commands[1].status} worker=${late.payload.code} hash=${tracker.hash()}`);