diff --git a/text11.txt b/text11.txt index e8a707f..7497fd3 100644 --- a/text11.txt +++ b/text11.txt @@ -523,3 +523,66 @@ host_wasm_opfs_browser_smokes=ok 整理成更明确的 API/文档使用方式,或者在 `run-gcode`/restore/load/save 之外再补一层 更高阶的 UI consumer helper,用于读取状态并生成上层展示/导出结果;只围绕已有 host/runtime boundary facts 组合,不回到 path guard。 + +四、2026-06-14 继续执行记录:INI panel machine session state report helper + +本轮继续按 `text11.txt` 第一原则推进上层 UI/API 可消费能力,把 machine session state +snapshot 转成稳定的 consumer report 结构,方便外部 UI、导出路径或测试直接读取状态。 + +完成内容: + +- 扩展 `wasm-port/runtime/ui/ini-panel/panel-state-summary.js`; +- 新增导出 `createMachineSessionStateReport(state)`; +- report helper 输出稳定分组: + - readiness; + - session; + - loaded; + - program; + - run; + - status; +- `wasm-port/tests/ui/node/verify_ini_panel_state_summary.mjs` 覆盖 report 输出结构; +- `wasm-port/docs/ui-panel-state-summary.md` 增加 report API、用途和边界说明; +- 未改变 INI panel UI workflow、OPFS bridge、snapshot-store、machine-file-store、 + LinuxCNC interpreter、G-code 文本、canonical-event 语义、tool、parameter、planner 或 + LinuxCNC-owned runtime semantics。 + +验证已通过: + +```bash +git diff --check +wasm-port/tests/ui/node/verify_ini_panel_state_summary.sh +wasm-port/tests/ui/node/verify_ui_node_smokes.sh +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh +wasm-port/tools/verify_vendor_sync.sh +wasm-port/tools/verify_no_standalone_cnc_semantics.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh +wasm-port/tests/host/verify_host_smokes.sh +``` + +关键输出: + +```text +ini_panel_state_summary_node_smoke=ok +ini_panel_run_summary_node_smoke=ok +ini_panel_run_workflow_node_smoke=ok +ini_panel_session_summary_node_smoke=ok +ini_panel_session_workflow_node_smoke=ok +ini_panel_machine_file_summary_node_smoke=ok +ui_node_smokes=ok +browser_ini_opfs_smoke=ok +vendor sync up to date +standalone CNC semantics guard complete +interp_wasm_node_smoke=ok +sim_configs_wasm_node_inventory_executed=28 +sim_configs_wasm_node_inventory_passed=28 +sim_configs_wasm_node_inventory_skipped=131 +sim_configs_wasm_node_inventory_unexpected_fail=0 +host_wasm_opfs_browser_smokes=ok +``` + +下一步建议: + +继续按“实质性能力优先”推进。优先把该 state report 接入浏览器 UI 的真实可用流程,例如 +新增一个导出/复制 report 的 UI action 或一个明确的 SDK-facing getter,使上层消费者不必 +直接读取 `window` 内部对象;仍只导出 host/runtime boundary facts,不解析或实现 CNC 语义。 diff --git a/wasm-port/docs/ui-panel-state-summary.md b/wasm-port/docs/ui-panel-state-summary.md index caae3d8..747b44d 100644 --- a/wasm-port/docs/ui-panel-state-summary.md +++ b/wasm-port/docs/ui-panel-state-summary.md @@ -62,6 +62,25 @@ The INI panel updates this state after save, restore, load, run, and error paths so browser tests and future API consumers can read one machine-readable state object instead of collecting DOM fields and log text. +## `createMachineSessionStateReport(state)` + +This helper converts the richer state snapshot into a stable consumer report +with four sections: + +```js +{ + readiness: { ini: "...", interp: "...", opfs: "..." }, + session: { snapshotLabel: "...", workflow: "...", ini: "...", parameters: "...", toolTable: "...", gcode: "..." }, + loaded: { iniWasmPath: "...", parameterWasmPath: "...", toolTableWasmPath: "..." }, + program: { source: "snapshot", opfsPath: "...", wasmPath: "..." }, + run: { status: "ok", canonicalEventCount: 2, motionSnapshotCount: 2, iniWasmPath: "..." }, + status: { lastAction: "run-gcode", error: null, fiveaxisRemap: "ok" } +} +``` + +The report is intended for upper-level UI consumers or export paths that want a +stable summary shape without touching DOM nodes. + ## Boundary Rules - Do not parse G-code text in this helper. diff --git a/wasm-port/runtime/ui/ini-panel/panel-state-summary.js b/wasm-port/runtime/ui/ini-panel/panel-state-summary.js index d7cc507..75e35f9 100644 --- a/wasm-port/runtime/ui/ini-panel/panel-state-summary.js +++ b/wasm-port/runtime/ui/ini-panel/panel-state-summary.js @@ -63,3 +63,48 @@ export function createMachineSessionStateSnapshot({ error: error ?? null, }; } + +export function createMachineSessionStateReport(state = {}) { + const badges = state.badges ?? {}; + const fields = state.fields ?? {}; + const sessionSnapshot = state.sessionSnapshot ?? {}; + const sessionLoad = state.sessionLoad ?? {}; + const selectedProgram = state.selectedProgram ?? {}; + const run = state.run ?? {}; + return { + readiness: { + ini: badges.ini ?? null, + interp: badges.interp ?? null, + opfs: badges.opfs ?? null, + }, + session: { + snapshotLabel: sessionSnapshot.snapshotLabel ?? fields.sessionSnapshot ?? null, + workflow: sessionSnapshot.workflow ?? fields.runWorkflow ?? null, + ini: fields.sessionIni ?? sessionSnapshot.iniOpfsPath ?? sessionLoad.iniWasmPath ?? null, + parameters: fields.sessionParameters ?? sessionSnapshot.parameterOpfsPath ?? sessionLoad.parameterWasmPath ?? null, + toolTable: fields.sessionToolTable ?? sessionSnapshot.toolTableOpfsPath ?? sessionLoad.toolTableWasmPath ?? null, + gcode: fields.sessionGcode ?? sessionSnapshot.gcodeOpfsPath ?? null, + }, + loaded: { + iniWasmPath: sessionLoad.iniWasmPath ?? null, + parameterWasmPath: sessionLoad.parameterWasmPath ?? null, + toolTableWasmPath: sessionLoad.toolTableWasmPath ?? null, + }, + program: { + source: selectedProgram.source ?? run.programSource ?? fields.runSource ?? null, + opfsPath: selectedProgram.opfsPath ?? run.programOpfsPath ?? fields.runOpfsPath ?? null, + wasmPath: selectedProgram.wasmPath ?? run.programWasmPath ?? fields.runWasmPath ?? null, + }, + run: { + status: run.runStatus ?? fields.runStatus ?? null, + canonicalEventCount: run.canonicalEventCount ?? 0, + motionSnapshotCount: run.motionSnapshotCount ?? 0, + iniWasmPath: run.iniWasmPath ?? null, + }, + status: { + lastAction: state.lastAction ?? null, + error: state.error ?? null, + fiveaxisRemap: state.fiveaxisRemap ?? null, + }, + }; +} diff --git a/wasm-port/tests/ui/node/verify_ini_panel_state_summary.mjs b/wasm-port/tests/ui/node/verify_ini_panel_state_summary.mjs index 6926040..f81dec3 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_state_summary.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_state_summary.mjs @@ -3,6 +3,7 @@ import assert from "node:assert/strict"; import { createIniPanelStateSummary, createMachineSessionStateSnapshot, + createMachineSessionStateReport, } from "../../../runtime/ui/ini-panel/panel-state-summary.js"; const summary = createIniPanelStateSummary({ @@ -186,4 +187,85 @@ assert.deepEqual( }, ); +assert.deepEqual( + createMachineSessionStateReport({ + badges: { + ini: "INI WASM: ready", + interp: "Interpreter WASM: ready", + opfs: "OPFS: ready", + }, + fields: { + sessionSnapshot: "ui-machine-session/ui-machine-session.json", + sessionIni: "/work/session-machine.ini", + sessionParameters: "/work/session-linuxcnc.var", + sessionToolTable: "/work/session-tool.tbl", + sessionGcode: "linuxcnc/gcode/ui-session.ngc", + runStatus: "ok", + runSource: "snapshot", + runSnapshot: "ui-machine-session/ui-machine-session.json", + runWorkflow: "save-session-snapshot", + runOpfsPath: "linuxcnc/gcode/ui-session.ngc", + runWasmPath: "/work/ui-session.ngc", + }, + sessionLoad: { + iniWasmPath: "/work/session-machine.ini", + parameterWasmPath: "/work/session-linuxcnc.var", + toolTableWasmPath: "/work/session-tool.tbl", + }, + selectedProgram: { + source: "snapshot", + opfsPath: "linuxcnc/gcode/ui-session.ngc", + wasmPath: "/work/ui-session.ngc", + }, + run: { + runStatus: "ok", + programSource: "snapshot", + programOpfsPath: "linuxcnc/gcode/ui-session.ngc", + programWasmPath: "/work/ui-session.ngc", + iniWasmPath: "/work/session-machine.ini", + canonicalEventCount: 2, + motionSnapshotCount: 2, + }, + lastAction: "run-gcode", + error: null, + fiveaxisRemap: "ok", + }), + { + readiness: { + ini: "INI WASM: ready", + interp: "Interpreter WASM: ready", + opfs: "OPFS: ready", + }, + session: { + snapshotLabel: "ui-machine-session/ui-machine-session.json", + workflow: "save-session-snapshot", + ini: "/work/session-machine.ini", + parameters: "/work/session-linuxcnc.var", + toolTable: "/work/session-tool.tbl", + gcode: "linuxcnc/gcode/ui-session.ngc", + }, + loaded: { + iniWasmPath: "/work/session-machine.ini", + parameterWasmPath: "/work/session-linuxcnc.var", + toolTableWasmPath: "/work/session-tool.tbl", + }, + program: { + source: "snapshot", + opfsPath: "linuxcnc/gcode/ui-session.ngc", + wasmPath: "/work/ui-session.ngc", + }, + run: { + status: "ok", + canonicalEventCount: 2, + motionSnapshotCount: 2, + iniWasmPath: "/work/session-machine.ini", + }, + status: { + lastAction: "run-gcode", + error: null, + fiveaxisRemap: "ok", + }, + }, +); + console.log("ini_panel_state_summary_node_smoke=ok");