推进 INI 面板状态 bundle helper
This commit is contained in:
62
text11.txt
62
text11.txt
@@ -896,3 +896,65 @@ host_wasm_opfs_browser_smokes=ok
|
|||||||
继续沿 `window.linuxCncIniPanelApi` 收敛控制面。下一批建议把当前散落的 report/export/
|
继续沿 `window.linuxCncIniPanelApi` 收敛控制面。下一批建议把当前散落的 report/export/
|
||||||
status getter 再包成一个明确的 `getMachineSessionStateBundle()` 或 `getMachineSessionView()`
|
status getter 再包成一个明确的 `getMachineSessionStateBundle()` 或 `getMachineSessionView()`
|
||||||
只读入口,给控制网页界面一个单点轮询对象;仍保持只读,不加按钮,不扩大 CNC 语义边界。
|
只读入口,给控制网页界面一个单点轮询对象;仍保持只读,不加按钮,不扩大 CNC 语义边界。
|
||||||
|
|
||||||
|
九、2026-06-14 继续执行记录:INI panel state bundle helper
|
||||||
|
|
||||||
|
本轮继续沿 `window.linuxCncIniPanelApi` 收敛控制面,把现有 report/export/status 入口
|
||||||
|
聚合成一个单点只读 bundle helper,给控制网页界面或上层 SDK 一个更稳的轮询对象。
|
||||||
|
|
||||||
|
完成内容:
|
||||||
|
|
||||||
|
- `wasm-port/runtime/ui/ini-panel/panel-state-summary.js` 新增
|
||||||
|
`createMachineSessionStateBundle(state, options)`;
|
||||||
|
- bundle helper 返回:
|
||||||
|
- `report`;
|
||||||
|
- `export`;
|
||||||
|
- `workflowStatus`;
|
||||||
|
- `wasm-port/runtime/ui/ini-panel/app.js` 在
|
||||||
|
`window.linuxCncIniPanelApi`、`window.getMachineSessionStateBundle()` 下暴露该 helper;
|
||||||
|
- `wasm-port/tests/ui/node/verify_ini_panel_state_summary.mjs` 覆盖 bundle 与单项 getter 的
|
||||||
|
结构一致性;
|
||||||
|
- `wasm-port/tests/browser/ini_panel_smoke.html` 在真实 save、restore-load、run 流程后验证
|
||||||
|
bundle,确认其 report/export/status 与单项 getter 一致;
|
||||||
|
- `wasm-port/docs/ui-panel-state-summary.md` 补充 bundle helper 说明,并明确它是控制页的
|
||||||
|
推荐单点只读入口;
|
||||||
|
- 未新增按钮;
|
||||||
|
- 未解析 G-code;
|
||||||
|
- 未改变 OPFS/session persistence、LinuxCNC interpreter、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
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
下一步建议:
|
||||||
|
|
||||||
|
继续沿“单点只读入口”推进,把 `window.linuxCncIniPanelApi` 再收敛成一个更明确的
|
||||||
|
`getMachineSessionView()` 或 `getMachineSessionStateBundle()` 的稳定消费者契约,并开始只
|
||||||
|
在这个 bundle 上面叠控制页展示逻辑;仍不新增按钮、不把 CNC 语义搬进 JS。
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ shims.
|
|||||||
For control-page polling, use
|
For control-page polling, use
|
||||||
`window.linuxCncIniPanelApi.getMachineSessionWorkflowStatus()`. It returns a
|
`window.linuxCncIniPanelApi.getMachineSessionWorkflowStatus()`. It returns a
|
||||||
smaller workflow-facing object derived from the same report data.
|
smaller workflow-facing object derived from the same report data.
|
||||||
|
For a single read call, use `window.linuxCncIniPanelApi.getMachineSessionStateBundle()`.
|
||||||
|
|
||||||
## `createIniPanelStateSummary(input)`
|
## `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
|
It is intended for polling or status panels that need current UI workflow
|
||||||
state without parsing logs, DOM nodes, or transient window state.
|
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
|
## Boundary Rules
|
||||||
|
|
||||||
- Do not parse G-code text in this helper.
|
- Do not parse G-code text in this helper.
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import {
|
|||||||
} from "./session-workflow.js";
|
} from "./session-workflow.js";
|
||||||
import {
|
import {
|
||||||
createMachineSessionStateSnapshot,
|
createMachineSessionStateSnapshot,
|
||||||
|
createMachineSessionStateBundle,
|
||||||
createMachineSessionStateReport,
|
createMachineSessionStateReport,
|
||||||
createMachineSessionStateReportExport,
|
createMachineSessionStateReportExport,
|
||||||
createMachineSessionWorkflowStatus,
|
createMachineSessionWorkflowStatus,
|
||||||
@@ -166,6 +167,10 @@ function getMachineSessionWorkflowStatus() {
|
|||||||
return createMachineSessionWorkflowStatus(window.linuxCncIniPanelMachineSessionState);
|
return createMachineSessionWorkflowStatus(window.linuxCncIniPanelMachineSessionState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMachineSessionStateBundle() {
|
||||||
|
return createMachineSessionStateBundle(window.linuxCncIniPanelMachineSessionState);
|
||||||
|
}
|
||||||
|
|
||||||
function updatePanelMachineSessionState(patch = {}) {
|
function updatePanelMachineSessionState(patch = {}) {
|
||||||
panelMachineSessionState = createMachineSessionStateSnapshot({
|
panelMachineSessionState = createMachineSessionStateSnapshot({
|
||||||
...panelMachineSessionState,
|
...panelMachineSessionState,
|
||||||
@@ -180,10 +185,12 @@ function updatePanelMachineSessionState(patch = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.linuxCncIniPanelApi = {
|
window.linuxCncIniPanelApi = {
|
||||||
|
getMachineSessionStateBundle,
|
||||||
getMachineSessionStateReport,
|
getMachineSessionStateReport,
|
||||||
getMachineSessionStateReportExport,
|
getMachineSessionStateReportExport,
|
||||||
getMachineSessionWorkflowStatus,
|
getMachineSessionWorkflowStatus,
|
||||||
};
|
};
|
||||||
|
window.getMachineSessionStateBundle = getMachineSessionStateBundle;
|
||||||
window.getMachineSessionStateReport = getMachineSessionStateReport;
|
window.getMachineSessionStateReport = getMachineSessionStateReport;
|
||||||
window.getMachineSessionStateReportExport = getMachineSessionStateReportExport;
|
window.getMachineSessionStateReportExport = getMachineSessionStateReportExport;
|
||||||
window.getMachineSessionWorkflowStatus = getMachineSessionWorkflowStatus;
|
window.getMachineSessionWorkflowStatus = getMachineSessionWorkflowStatus;
|
||||||
|
|||||||
@@ -129,3 +129,14 @@ export function createMachineSessionWorkflowStatus(state = {}) {
|
|||||||
run: report.run,
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -369,6 +369,7 @@ TOOL_TABLE = browser-tool.tbl
|
|||||||
);
|
);
|
||||||
const uiApi = uiDocument.defaultView.linuxCncIniPanelApi;
|
const uiApi = uiDocument.defaultView.linuxCncIniPanelApi;
|
||||||
if (
|
if (
|
||||||
|
!uiApi?.getMachineSessionStateBundle ||
|
||||||
!uiApi?.getMachineSessionStateReport ||
|
!uiApi?.getMachineSessionStateReport ||
|
||||||
!uiApi?.getMachineSessionStateReportExport ||
|
!uiApi?.getMachineSessionStateReportExport ||
|
||||||
!uiApi?.getMachineSessionWorkflowStatus
|
!uiApi?.getMachineSessionWorkflowStatus
|
||||||
@@ -808,6 +809,27 @@ TOOL_TABLE = browser-tool.tbl
|
|||||||
2,
|
2,
|
||||||
"UI machine session workflow status canonical event count",
|
"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(
|
assertEqual(
|
||||||
uiDocument.defaultView.getMachineSessionStateReport().status.lastAction,
|
uiDocument.defaultView.getMachineSessionStateReport().status.lastAction,
|
||||||
machineSessionStateReport.status.lastAction,
|
machineSessionStateReport.status.lastAction,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import assert from "node:assert/strict";
|
|||||||
import {
|
import {
|
||||||
createIniPanelStateSummary,
|
createIniPanelStateSummary,
|
||||||
createMachineSessionStateSnapshot,
|
createMachineSessionStateSnapshot,
|
||||||
|
createMachineSessionStateBundle,
|
||||||
createMachineSessionStateReport,
|
createMachineSessionStateReport,
|
||||||
createMachineSessionStateReportExport,
|
createMachineSessionStateReportExport,
|
||||||
createMachineSessionWorkflowStatus,
|
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(
|
assert.deepEqual(
|
||||||
{
|
{
|
||||||
getMachineSessionStateReport: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionStateReport,
|
getMachineSessionStateReport: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionStateReport,
|
||||||
getMachineSessionStateReportExport: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionStateReportExport,
|
getMachineSessionStateReportExport: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionStateReportExport,
|
||||||
getMachineSessionWorkflowStatus: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionWorkflowStatus,
|
getMachineSessionWorkflowStatus: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionWorkflowStatus,
|
||||||
|
getMachineSessionStateBundle: typeof globalThis.window?.linuxCncIniPanelApi?.getMachineSessionStateBundle,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
getMachineSessionStateReport: "undefined",
|
getMachineSessionStateReport: "undefined",
|
||||||
getMachineSessionStateReportExport: "undefined",
|
getMachineSessionStateReportExport: "undefined",
|
||||||
getMachineSessionWorkflowStatus: "undefined",
|
getMachineSessionWorkflowStatus: "undefined",
|
||||||
|
getMachineSessionStateBundle: "undefined",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user