#!/usr/bin/env node import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import { createRequire } from "node:module"; import { pathToFileURL } from "node:url"; const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), ".."); const build = path.resolve(process.argv[2] ?? path.join(root, "freecad-source/build-web/configure/bin")); globalThis.__dirname = `${build}${path.sep}`; globalThis.require = createRequire(import.meta.url); const loader = await import(pathToFileURL(path.join(build, "FreeCADWebJtReaderRuntimeProbe.js"))); const kernel = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebJtReaderRuntimeProbe.wasm")) }); const call = (name, type = "number", argTypes = [], args = []) => kernel.ccall(name, type, argTypes, args); const initialize = (name) => ({ run: call("fc_web_jtreader_initialize", "number", ["string"], [name]), code: call("fc_web_jtreader_error_code", "string"), message: call("fc_web_jtreader_error_message", "string"), calls: call("fc_web_jtreader_initialization_calls"), runs: call("fc_web_jtreader_initialization_runs"), initialized: call("fc_web_jtreader_initialized") }); const first = initialize("JtReader"); const repeated = initialize("JtReader"); const type = { run: call("fc_web_jtreader_type_probe", "number", ["string"], ["App::InventorObject"]), type: call("fc_web_jtreader_last_type", "string"), code: call("fc_web_jtreader_error_code", "string") }; const missing = initialize("JtReaderMissing"); const gui = initialize("JtReaderGui"); const result = { first, repeated, type, missing, gui }; const stable = JSON.stringify(result); if (first.run !== 1 || repeated.run !== 1 || first.runs !== 1 || repeated.runs !== 1 || type.run !== 1 || type.type !== "App::InventorObject" || missing.code !== "module_unavailable" || gui.code !== "gui_dependency_unavailable") throw new Error(`JtReader runtime contract failed: ${stable}`); const report = { schema: "freecad-web-p6-jtreader-runtime/v1", taskId: "FW-P6-JTR-B", module: "JtReader", result: "pass", sourceRevision: "4f4e9244e613ea2df06e70027074a562695048cb", resultSha256: crypto.createHash("sha256").update(stable).digest("hex"), responses: result, initialization: { calls: repeated.calls, runs: repeated.runs, idempotent: repeated.runs === 1 }, dependencies: { mesh: true, occ: true, tkjt: false, gui: false }, commands: ["cmake -S freecad-source -B freecad-source/build-web/configure -DBUILD_JTREADER=ON", "cmake --build freecad-source/build-web/configure --target FreeCADWebJtReaderRuntimeProbe -j 8", "node tools/run_p6_jtreader_runtime_smoke.mjs freecad-source/build-web/configure/bin"], artifacts: { wasm: "freecad-source/build-web/configure/bin/FreeCADWebJtReaderRuntimeProbe.wasm", workerLog: "docs/freecad-p6-jtreader-b-runtime.log" }, boundaries: ["Runtime probe verifies module registration and App::InventorObject visibility only; JT fixture parsing is deferred to action C.", "TKJT is not present, so the built path is the in-tree JrJt fallback."] }; const wasmPath = path.join(build, "FreeCADWebJtReaderRuntimeProbe.wasm"); report.wasmSha256 = crypto.createHash("sha256").update(fs.readFileSync(wasmPath)).digest("hex"); fs.writeFileSync(path.join(root, "docs/p6/jtreader-runtime.json"), `${JSON.stringify(report, null, 2)}\n`); fs.writeFileSync(path.join(root, "docs/freecad-p6-jtreader-b-runtime.log"), `${JSON.stringify({ result: report.result, initializationRuns: report.initialization.runs, type: report.responses.type.type, missingCode: report.responses.missing.code, guiCode: report.responses.gui.code, wasmSha256: report.wasmSha256 })}\n`); console.log(JSON.stringify({ result: report.result, initializationRuns: report.initialization.runs, type: report.responses.type.type, wasmSha256: report.wasmSha256 }));