推进 INI 面板 session load summary helper

This commit is contained in:
2026-06-14 18:29:49 +08:00
parent aeb290b885
commit 3ca213a889
5 changed files with 239 additions and 10 deletions

View File

@@ -0,0 +1,85 @@
# UI Session Summary Helpers
## Purpose
`runtime/ui/ini-panel/session-summary.js` contains small host-boundary helpers
for summarizing machine session snapshot state.
`runtime/ui/ini-panel/session-load-summary.js` contains the matching helpers
for machine-session load state. These helpers are pure so browser UI panels,
SDK-facing wrappers, and Node smoke tests can share the same data shape without
parsing log text.
The helpers do not implement CNC behavior. G-code execution, canonical events,
tool handling, parameters, kinematics, and planner behavior remain owned by the
vendored LinuxCNC runtime.
## `createSessionSnapshotSummary(snapshot, fallbackLabel)`
`snapshot` is the saved machine session snapshot loaded by the UI.
`fallbackLabel` is the UI-selected label to prefer when present.
The returned summary has this shape:
```js
{
snapshotLabel: "ui-machine-session/ui-machine-session.json",
workflow: "save-session-snapshot",
defaultGcodeOpfsPath: "linuxcnc/gcode/ui-session.ngc",
iniOpfsPath: "linuxcnc/machines/xyzab-tdr/machine.ini",
parameterOpfsPath: "linuxcnc/machines/xyzab-tdr/linuxcnc.var",
toolTableOpfsPath: "linuxcnc/machines/xyzab-tdr/tool.tbl",
gcodeOpfsPath: "linuxcnc/gcode/ui-session.ngc"
}
```
## `createMachineSessionLoadSummary(session)`
`session` is the loaded interpreter/session bridge result. The helper extracts
the OPFS and WASM path mapping plus the captured parameter/tool-table result
texts.
The returned summary has this shape:
```js
{
iniOpfsPath: "linuxcnc/machines/xyzab-tdr/machine.ini",
iniWasmPath: "/work/session-machine.ini",
parameterOpfsPath: "linuxcnc/machines/xyzab-tdr/linuxcnc.var",
parameterWasmPath: "/work/session-linuxcnc.var",
parameterResult: "restore_parameters=0",
toolTableOpfsPath: "linuxcnc/machines/xyzab-tdr/tool.tbl",
toolTableWasmPath: "/work/session-tool.tbl",
toolTableResult: "tooldata_load=0"
}
```
## Log Helpers
- `sessionSnapshotSummaryLogLines(summary)` renders snapshot label, workflow,
and default G-code path.
- `sessionSnapshotMetadataLogLines(summary)` renders the metadata subset used in
save/restore log summaries.
- `machineSessionLoadLogLines(summary)` renders the interpreter/session
OPFS-to-WASM mapping and captured result lines.
## Boundary Rules
- Do not parse G-code text in these helpers.
- Do not infer tool, parameter, kinematics, planner, or modal semantics.
- Do not derive new CNC behavior from the load result strings.
- Keep new fields limited to host/runtime boundary facts already produced by the
LinuxCNC-owned runtime or UI staging layer.
## Validation
Run the focused Node smoke after changing these helpers:
```bash
wasm-port/tests/ui/node/verify_ini_panel_session_summary.sh
```
The aggregate UI Node smoke is:
```bash
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
```

View File

@@ -26,6 +26,10 @@ import {
createRunSummary,
summarizeRunResult,
} from "./run-summary.js";
import {
createMachineSessionLoadSummary,
machineSessionLoadLogLines,
} from "./session-load-summary.js";
import {
createSessionSnapshotSummary,
sessionSnapshotMetadataLogLines,
@@ -616,14 +620,11 @@ document.getElementById("restore-session-snapshot").addEventListener("click", as
document.getElementById("load-session").addEventListener("click", async () => {
try {
await loadMachineSessionIntoWasm();
const loadSummary = createMachineSessionLoadSummary(loadedSession);
setLog(
[
"Loaded machine session into the interpreter WASM filesystem.",
`INI: ${loadedSession.ini.opfsPath} -> ${loadedSession.ini.wasmPath}`,
`Parameter file: ${loadedSession.parameters.opfsPath} -> ${loadedSession.parameters.wasmPath}`,
`Parameters: ${loadedSession.parameters.result.trim()}`,
`Tool table file: ${loadedSession.toolTable.opfsPath} -> ${loadedSession.toolTable.wasmPath}`,
`Tool table: ${loadedSession.toolTable.result.trim()}`,
...machineSessionLoadLogLines(loadSummary),
].join("\n"),
);
} catch (error) {
@@ -637,15 +638,12 @@ document.getElementById("restore-load-session").addEventListener("click", async
await loadMachineSessionIntoWasm();
setField("sessionGcode", snapshot.payload.files.gcode);
const summary = createSessionSnapshotSummary(snapshot, sessionSnapshotLabel(snapshot.sessionId));
const loadSummary = createMachineSessionLoadSummary(loadedSession);
setLog(
[
"Restored and loaded machine session snapshot.",
...sessionSnapshotSummaryLogLines(summary),
`INI: ${loadedSession.ini.opfsPath} -> ${loadedSession.ini.wasmPath}`,
`Parameter file: ${loadedSession.parameters.opfsPath} -> ${loadedSession.parameters.wasmPath}`,
`Parameters: ${loadedSession.parameters.result.trim()}`,
`Tool table file: ${loadedSession.toolTable.opfsPath} -> ${loadedSession.toolTable.wasmPath}`,
`Tool table: ${loadedSession.toolTable.result.trim()}`,
...machineSessionLoadLogLines(loadSummary),
`G-code: ${summary.gcodeOpfsPath ?? "-"}`,
].join("\n"),
);

View File

@@ -0,0 +1,22 @@
export function createMachineSessionLoadSummary(session) {
return {
iniOpfsPath: session?.ini?.opfsPath ?? null,
iniWasmPath: session?.ini?.wasmPath ?? null,
parameterOpfsPath: session?.parameters?.opfsPath ?? null,
parameterWasmPath: session?.parameters?.wasmPath ?? null,
parameterResult: session?.parameters?.result ?? "",
toolTableOpfsPath: session?.toolTable?.opfsPath ?? null,
toolTableWasmPath: session?.toolTable?.wasmPath ?? null,
toolTableResult: session?.toolTable?.result ?? "",
};
}
export function machineSessionLoadLogLines(summary) {
return [
`INI: ${summary.iniOpfsPath ?? "-"} -> ${summary.iniWasmPath ?? "-"}`,
`Parameter file: ${summary.parameterOpfsPath ?? "-"} -> ${summary.parameterWasmPath ?? "-"}`,
`Parameters: ${summary.parameterResult.trim()}`,
`Tool table file: ${summary.toolTableOpfsPath ?? "-"} -> ${summary.toolTableWasmPath ?? "-"}`,
`Tool table: ${summary.toolTableResult.trim()}`,
];
}

View File

@@ -1,5 +1,9 @@
import assert from "node:assert/strict";
import {
createMachineSessionLoadSummary,
machineSessionLoadLogLines,
} from "../../../runtime/ui/ini-panel/session-load-summary.js";
import {
createSessionSnapshotSummary,
sessionSnapshotMetadataLogLines,
@@ -71,4 +75,56 @@ assert.deepEqual(
},
);
const loadSummary = createMachineSessionLoadSummary({
ini: {
opfsPath: "linuxcnc/machines/xyzab-tdr/machine.ini",
wasmPath: "/work/session-machine.ini",
},
parameters: {
opfsPath: "linuxcnc/machines/xyzab-tdr/linuxcnc.var",
wasmPath: "/work/session-linuxcnc.var",
result: "restore_parameters=0",
},
toolTable: {
opfsPath: "linuxcnc/machines/xyzab-tdr/tool.tbl",
wasmPath: "/work/session-tool.tbl",
result: "tooldata_load=0",
},
});
assert.deepEqual(loadSummary, {
iniOpfsPath: "linuxcnc/machines/xyzab-tdr/machine.ini",
iniWasmPath: "/work/session-machine.ini",
parameterOpfsPath: "linuxcnc/machines/xyzab-tdr/linuxcnc.var",
parameterWasmPath: "/work/session-linuxcnc.var",
parameterResult: "restore_parameters=0",
toolTableOpfsPath: "linuxcnc/machines/xyzab-tdr/tool.tbl",
toolTableWasmPath: "/work/session-tool.tbl",
toolTableResult: "tooldata_load=0",
});
assert.deepEqual(
machineSessionLoadLogLines(loadSummary),
[
"INI: linuxcnc/machines/xyzab-tdr/machine.ini -> /work/session-machine.ini",
"Parameter file: linuxcnc/machines/xyzab-tdr/linuxcnc.var -> /work/session-linuxcnc.var",
"Parameters: restore_parameters=0",
"Tool table file: linuxcnc/machines/xyzab-tdr/tool.tbl -> /work/session-tool.tbl",
"Tool table: tooldata_load=0",
],
);
assert.deepEqual(
createMachineSessionLoadSummary(null),
{
iniOpfsPath: null,
iniWasmPath: null,
parameterOpfsPath: null,
parameterWasmPath: null,
parameterResult: "",
toolTableOpfsPath: null,
toolTableWasmPath: null,
toolTableResult: "",
},
);
console.log("ini_panel_session_summary_node_smoke=ok");