From 4ac2f6fbf6089527aa87072f2a92d813fda5db70 Mon Sep 17 00:00:00 2001 From: wangdequan Date: Sun, 14 Jun 2026 17:54:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E8=BF=9B=20INI=20=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E7=BB=93=E6=9E=9C=E6=91=98=E8=A6=81=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- text10.txt | 64 +++++++++++++++++++ wasm-port/runtime/ui/ini-panel/app.js | 9 +-- wasm-port/runtime/ui/ini-panel/run-summary.js | 7 ++ .../ui/node/verify_ini_panel_run_summary.mjs | 23 +++++++ 4 files changed, 97 insertions(+), 6 deletions(-) diff --git a/text10.txt b/text10.txt index ae4f368..3b48864 100644 --- a/text10.txt +++ b/text10.txt @@ -1226,3 +1226,67 @@ host_wasm_opfs_browser_smokes=ok result 轻量统计也收敛到可导出的 helper,例如 `summarizeRunResult(resultText, snapshots)`, 并补 Node 侧纯函数测试;保持只统计 LinuxCNC-owned runtime 输出行和 UI 已解析 motion snapshot 数量,不解释或改写 G-code、tool、parameter、planner 等 CNC 语义。 + +十七、2026-06-14 继续执行记录:INI panel run result summary helper + +本轮继续沿 OPFS/session/UI boundary 推进,把 runtime result 的轻量统计收敛到可导出的 +纯 helper,方便后续 SDK/API 或其他 UI panel 复用。 + +完成内容: + +- 在 `wasm-port/runtime/ui/ini-panel/run-summary.js` 新增 + `summarizeRunResult(resultText, snapshots)`; +- helper 返回: + - `canonicalEventCount`; + - `motionSnapshotCount`; +- `canonicalEventCount` 只统计 LinuxCNC interpreter 输出中以 `canon_event=` 开头的行; +- `motionSnapshotCount` 只取 UI 已解析 motion snapshots 数量; +- `wasm-port/runtime/ui/ini-panel/app.js` 移除本地 `countCanonicalEvents(...)`,改为调用 + `summarizeRunResult(...)`; +- `Run G-code` 成功路径继续复用同一份 motion snapshots 进行 summary 与 playback; +- Node smoke 增加纯函数覆盖: + - canonical event 前缀计数; + - 非前缀文本不计数; + - 空输出与空 snapshots; +- browser INI panel smoke 继续覆盖真实 UI run summary; +- 未改变 OPFS path model、snapshot envelope、G-code 文本、interpreter run API、 + canonical-event 文本输出、motion playback 行为或 LinuxCNC-owned runtime semantics。 + +验证已通过: + +```bash +git diff --check +wasm-port/tests/ui/node/verify_ini_panel_run_summary.sh +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh +wasm-port/tests/opfs/node/verify_file_service.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 +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_interp_browser.sh +wasm-port/tests/host/verify_host_smokes.sh +``` + +关键输出: + +```text +ini_panel_run_summary_node_smoke=ok +browser_ini_opfs_smoke=ok +opfs_file_service_node_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 +browser_interp_smoke=ok +host_wasm_opfs_browser_smokes=ok +``` + +下一步建议: + +继续沿 OPFS/session/UI boundary 推进。优先把 run summary helper 的 Node smoke 纳入 +host smoke 或新增统一 UI node smoke wrapper,让这类 UI/API helper 在常规 gate 中自动执行; +仍只覆盖 host/runtime 边界 helper,不触碰 interpreter、OPFS bridge 或 LinuxCNC-owned +runtime semantics。 diff --git a/wasm-port/runtime/ui/ini-panel/app.js b/wasm-port/runtime/ui/ini-panel/app.js index 323d7cf..6b8bb6b 100644 --- a/wasm-port/runtime/ui/ini-panel/app.js +++ b/wasm-port/runtime/ui/ini-panel/app.js @@ -24,6 +24,7 @@ import { } from "../../opfs/snapshot-store.js"; import { createRunSummary, + summarizeRunResult, } from "./run-summary.js"; const SAMPLE_PATH = @@ -305,10 +306,6 @@ function playRunMotion(resultText, programText, snapshots = parseRunMotion(resul }, 220); } -function countCanonicalEvents(resultText) { - return resultText.split("\n").filter((line) => line.startsWith("canon_event=")).length; -} - function requireIniSdk() { if (!iniSdk) { throw new Error("INI WASM module is not ready yet."); @@ -671,13 +668,13 @@ document.getElementById("run-gcode").addEventListener("click", async () => { const result = interp.runFileWithIni(program.wasmPath, loadedSession.ini.wasmPath); const trimmedResult = result.trim(); const motionSnapshots = parseRunMotion(trimmedResult, program.text); + const runResultSummary = summarizeRunResult(trimmedResult, motionSnapshots); setField("sessionGcode", program.opfsPath); setField("runStatus", "ok"); setLastRunSummary(program, { runStatus: "ok", iniWasmPath: loadedSession.ini.wasmPath, - canonicalEventCount: countCanonicalEvents(trimmedResult), - motionSnapshotCount: motionSnapshots.length, + ...runResultSummary, }); setCanonicalEvents(trimmedResult); playRunMotion(trimmedResult, program.text, motionSnapshots); diff --git a/wasm-port/runtime/ui/ini-panel/run-summary.js b/wasm-port/runtime/ui/ini-panel/run-summary.js index 0114d9a..95948f1 100644 --- a/wasm-port/runtime/ui/ini-panel/run-summary.js +++ b/wasm-port/runtime/ui/ini-panel/run-summary.js @@ -1,3 +1,10 @@ +export function summarizeRunResult(resultText, snapshots = []) { + return { + canonicalEventCount: resultText.split("\n").filter((line) => line.startsWith("canon_event=")).length, + motionSnapshotCount: snapshots.length, + }; +} + export function createRunSummary(program, runtime = {}, snapshot = null) { const metadata = snapshot?.metadata ?? {}; return { diff --git a/wasm-port/tests/ui/node/verify_ini_panel_run_summary.mjs b/wasm-port/tests/ui/node/verify_ini_panel_run_summary.mjs index 7866863..76929ad 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_run_summary.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_run_summary.mjs @@ -2,6 +2,7 @@ import assert from "node:assert/strict"; import { createRunSummary, + summarizeRunResult, } from "../../../runtime/ui/ini-panel/run-summary.js"; const program = { @@ -63,4 +64,26 @@ assert.equal( "override-session/override.json", ); +assert.deepEqual( + summarizeRunResult([ + "canon_event=STRAIGHT_TRAVERSE line=1 x=1 y=2", + "run_step phase=execute line=1", + "canon_event=STRAIGHT_FEED line=2 x=3 y=4", + "message=canon_event=not-a-canonical-prefix", + "", + ].join("\n"), [{}, {}]), + { + canonicalEventCount: 2, + motionSnapshotCount: 2, + }, +); + +assert.deepEqual( + summarizeRunResult("", []), + { + canonicalEventCount: 0, + motionSnapshotCount: 0, + }, +); + console.log("ini_panel_run_summary_node_smoke=ok");