推进 INI 面板状态 bundle helper

This commit is contained in:
2026-06-14 22:34:38 +08:00
parent f537a8fa42
commit e6f55d775f
6 changed files with 216 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ shims.
For control-page polling, use
`window.linuxCncIniPanelApi.getMachineSessionWorkflowStatus()`. It returns a
smaller workflow-facing object derived from the same report data.
For a single read call, use `window.linuxCncIniPanelApi.getMachineSessionStateBundle()`.
## `createIniPanelStateSummary(input)`
@@ -124,6 +125,23 @@ This helper derives a lightweight status object for upper-level control pages:
It is intended for polling or status panels that need current UI workflow
state without parsing logs, DOM nodes, or transient window state.
## `createMachineSessionStateBundle(state, options)`
This helper packages the current report, export payload, and workflow status
into one read-only object:
```js
{
report: { ... },
export: { filename: "...", mediaType: "application/json", report: { ... }, text: "{...}\n" },
workflowStatus: { readiness: { ... }, lastAction: "...", error: null, session: { ... }, run: { ... } }
}
```
It is the preferred single-entry helper for control-page polling and other
upper-level UI consumers that want one stable read instead of stitching the
three views together themselves.
## Boundary Rules
- Do not parse G-code text in this helper.

View File

@@ -47,6 +47,7 @@ import {
} from "./session-workflow.js";
import {
createMachineSessionStateSnapshot,
createMachineSessionStateBundle,
createMachineSessionStateReport,
createMachineSessionStateReportExport,
createMachineSessionWorkflowStatus,
@@ -166,6 +167,10 @@ function getMachineSessionWorkflowStatus() {
return createMachineSessionWorkflowStatus(window.linuxCncIniPanelMachineSessionState);
}
function getMachineSessionStateBundle() {
return createMachineSessionStateBundle(window.linuxCncIniPanelMachineSessionState);
}
function updatePanelMachineSessionState(patch = {}) {
panelMachineSessionState = createMachineSessionStateSnapshot({
...panelMachineSessionState,
@@ -180,10 +185,12 @@ function updatePanelMachineSessionState(patch = {}) {
}
window.linuxCncIniPanelApi = {
getMachineSessionStateBundle,
getMachineSessionStateReport,
getMachineSessionStateReportExport,
getMachineSessionWorkflowStatus,
};
window.getMachineSessionStateBundle = getMachineSessionStateBundle;
window.getMachineSessionStateReport = getMachineSessionStateReport;
window.getMachineSessionStateReportExport = getMachineSessionStateReportExport;
window.getMachineSessionWorkflowStatus = getMachineSessionWorkflowStatus;

View File

@@ -129,3 +129,14 @@ export function createMachineSessionWorkflowStatus(state = {}) {
run: report.run,
};
}
export function createMachineSessionStateBundle(state = {}, options = {}) {
const report = createMachineSessionStateReport(state);
const exportPayload = createMachineSessionStateReportExport(state, options);
const workflowStatus = createMachineSessionWorkflowStatus(state);
return {
report,
export: exportPayload,
workflowStatus,
};
}

View File

@@ -369,6 +369,7 @@ TOOL_TABLE = browser-tool.tbl
);
const uiApi = uiDocument.defaultView.linuxCncIniPanelApi;
if (
!uiApi?.getMachineSessionStateBundle ||
!uiApi?.getMachineSessionStateReport ||
!uiApi?.getMachineSessionStateReportExport ||
!uiApi?.getMachineSessionWorkflowStatus
@@ -808,6 +809,27 @@ TOOL_TABLE = browser-tool.tbl
2,
"UI machine session workflow status canonical event count",
);
const machineSessionStateBundle = uiApi.getMachineSessionStateBundle();
assertEqual(
machineSessionStateBundle.report.status.lastAction,
machineSessionStateReport.status.lastAction,
"UI machine session state bundle report last action",
);
assertEqual(
machineSessionStateBundle.export.text,
machineSessionStateReportExport.text,
"UI machine session state bundle export text",
);
assertEqual(
machineSessionStateBundle.workflowStatus.run.canonicalEventCount,
machineSessionWorkflowStatus.run.canonicalEventCount,
"UI machine session state bundle workflow status canonical event count",
);
assertEqual(
uiDocument.defaultView.getMachineSessionStateBundle().workflowStatus.lastAction,
machineSessionStateBundle.workflowStatus.lastAction,
"UI legacy machine session state bundle getter matches API namespace",
);
assertEqual(
uiDocument.defaultView.getMachineSessionStateReport().status.lastAction,
machineSessionStateReport.status.lastAction,

View File

@@ -3,6 +3,7 @@ import assert from "node:assert/strict";
import {
createIniPanelStateSummary,
createMachineSessionStateSnapshot,
createMachineSessionStateBundle,
createMachineSessionStateReport,
createMachineSessionStateReportExport,
createMachineSessionWorkflowStatus,
@@ -378,16 +379,111 @@ assert.deepEqual(
},
);
const expectedBundleReport = {
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: null,
toolTable: null,
gcode: "linuxcnc/gcode/ui-session.ngc",
},
loaded: {
iniWasmPath: null,
parameterWasmPath: null,
toolTableWasmPath: null,
},
program: {
source: null,
opfsPath: null,
wasmPath: null,
},
run: {
status: "ok",
canonicalEventCount: 2,
motionSnapshotCount: 2,
iniWasmPath: null,
},
status: {
lastAction: "run-gcode",
error: null,
fiveaxisRemap: null,
},
};
assert.deepEqual(
createMachineSessionStateBundle({
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",
sessionGcode: "linuxcnc/gcode/ui-session.ngc",
runStatus: "ok",
runWorkflow: "save-session-snapshot",
},
run: {
runStatus: "ok",
canonicalEventCount: 2,
motionSnapshotCount: 2,
},
lastAction: "run-gcode",
error: null,
}),
{
report: expectedBundleReport,
export: {
filename: "machine-session-state-report.json",
mediaType: "application/json",
report: expectedBundleReport,
text: `${JSON.stringify(expectedBundleReport, null, 2)}\n`,
},
workflowStatus: {
readiness: {
ini: "INI WASM: ready",
interp: "Interpreter WASM: ready",
opfs: "OPFS: ready",
},
lastAction: "run-gcode",
error: null,
session: {
snapshotLabel: "ui-machine-session/ui-machine-session.json",
workflow: "save-session-snapshot",
ini: "/work/session-machine.ini",
parameters: null,
toolTable: null,
gcode: "linuxcnc/gcode/ui-session.ngc",
},
run: {
status: "ok",
canonicalEventCount: 2,
motionSnapshotCount: 2,
iniWasmPath: null,
},
},
},
);
assert.deepEqual(
{
getMachineSessionStateReport: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionStateReport,
getMachineSessionStateReportExport: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionStateReportExport,
getMachineSessionWorkflowStatus: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionWorkflowStatus,
getMachineSessionStateBundle: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionStateBundle,
},
{
getMachineSessionStateReport: "undefined",
getMachineSessionStateReportExport: "undefined",
getMachineSessionWorkflowStatus: "undefined",
getMachineSessionStateBundle: "undefined",
},
);