// Cut 10 (PA.f149): drives the real vendored Eve browser lowering // (`vendor/eve/packages/eve-browser-lowering`, submodule pin unmoved) over a // surface document Dungeon actually served, so the command intent this // prints is what a real client sends -- never a hand-built payload asserting // its own shape is correct. // // stdin: {"surface": , "steps": [{"set": {node_id: text}}, {"click": node_id}]} // stdout: one JSON line per intent the click(s) produced, in order. // // `set` types into a control by its Eve node id (the same id // `eve.rs`'s own `json!({"id": ...})` calls carry), by finding the rendered // element via `data-eve-node-id` (assignId) and dispatching a real `input` // event, exactly as a user's keystroke would. `click` clicks a // `control.button` node the same way. jsdom is resolved from the vendored // package's own devDependencies (its own test suite uses the identical // pattern in `test/host-isolation.test.mjs`) rather than adding a second copy // to this repo. import { fileURLToPath } from "node:url"; import { dirname, join } from "node:path"; import { createRequire } from "node:module"; const here = dirname(fileURLToPath(import.meta.url)); const loweringRoot = join(here, "..", "vendor", "eve", "packages", "eve-browser-lowering"); const vendorRequire = createRequire(join(loweringRoot, "package.json")); const { JSDOM } = vendorRequire("jsdom"); const { EveBrowserDraftStore, renderEveSurface } = await import( "file://" + join(loweringRoot, "dist", "index.js").replace(/\\/g, "/") ); function installDom() { const dom = new JSDOM("
", { url: "https://eve.bridge.test/", pretendToBeVisual: true, }); const names = [ "document", "window", "Element", "HTMLElement", "HTMLButtonElement", "HTMLInputElement", "HTMLSelectElement", "HTMLOptionElement", "HTMLTextAreaElement", "HTMLImageElement", "Event", "CustomEvent", ]; for (const name of names) globalThis[name] = dom.window[name]; return dom; } function cssEscape(value) { return value.replace(/[^a-zA-Z0-9_-]/g, char => `\\${char}`); } async function readStdin() { return new Promise((resolve, reject) => { let data = ""; process.stdin.setEncoding("utf8"); process.stdin.on("data", chunk => { data += chunk; }); process.stdin.on("end", () => resolve(data)); process.stdin.on("error", reject); }); } async function main() { const { surface, steps, provider } = JSON.parse(await readStdin()); const dom = installDom(); const host = dom.window.document.getElementById("host"); const intents = []; const draftStore = new EveBrowserDraftStore(); const options = { draftStore, clientId: "eve.bridge.test", commandSink: intent => { intents.push(intent); }, // `commandBoundary`/`receiptSchema` are not carried on the surface // document itself -- a real client learns them from the provider's own // CultMesh advertisement (`mesh.rs::provider_advertisement`, // `surfaces[].worldInteraction`), fetched separately. The caller passes // that same shape through here. provider, }; renderEveSurface(surface, host, options); for (const step of steps) { if (step.set) { for (const [nodeId, value] of Object.entries(step.set)) { const wrapper = host.querySelector(`[data-eve-node-id="${cssEscape(nodeId)}"]`); if (!wrapper) throw new Error(`bridge: no rendered control for node id ${nodeId}`); // `assignId` stamps the Eve node id onto the field's own wrapper // (`renderEditableControl`'s `