新增 OPFS session readiness SDK helper

This commit is contained in:
2026-06-16 06:27:31 +08:00
parent d076763ef4
commit 8e37c69bc4
9 changed files with 246 additions and 2 deletions

View File

@@ -17,6 +17,7 @@ for (const phrase of [
"OPFS/session persistence and release gate",
"runtime/sdk/src/index.js",
"createMachineSessionSnapshotPayload",
"readMachineSessionReadiness",
"loadMachineSessionFromOpfs",
"restoreMachineParametersFromOpfs",
"loadMachineToolTableFromOpfs",
@@ -33,6 +34,7 @@ for (const phrase of [
assert.match(readmeText, /docs\/opfs-session-persistence\.md/);
assert.match(sdkReadmeText, /OPFS\/session persistence exports/);
assert.match(sdkReadmeText, /readMachineSessionReadiness/);
assert.match(hostSmokeText, /verify_sdk_surface\.sh/);
assert.match(hostSmokeText, /verify_file_service\.sh/);
assert.match(browserSmokeText, /browser_ini_opfs_smoke=ok/);

View File

@@ -43,6 +43,9 @@ import {
import {
loadMachineSessionFromOpfs,
} from "../../../runtime/opfs/linuxcnc-machine-session-bridge.js";
import {
readMachineSessionReadiness,
} from "../../../runtime/opfs/machine-session-readiness.js";
class MockFileHandle {
constructor(name) {
@@ -420,6 +423,54 @@ assertGcodeProgramStoragePath(
);
assert.equal(await loadGcodeProgram("custom-fixture.ngc", { storage }), "G1 X1 F10\nM2\n");
const readyMachineSession = await readMachineSessionReadiness("xyzab-tdr", {
storage,
sessionId: "machine-session-1",
snapshotFilename: "machine-session-snapshot.json",
gcodeFilename: "fixture.ngc",
});
assert.equal(readyMachineSession.ready, true);
assert.equal(readyMachineSession.phase, "ready");
assert.deepEqual(readyMachineSession.missing, []);
assert.deepEqual(readyMachineSession.errors, []);
assert.deepEqual(
readyMachineSession.checks.map((check) => [check.name, check.ok, check.path]),
[
["ini", true, "linuxcnc/machines/xyzab-tdr/machine.ini"],
["parameters", true, "linuxcnc/machines/xyzab-tdr/linuxcnc.var"],
["toolTable", true, "linuxcnc/machines/xyzab-tdr/tool.tbl"],
["gcode", true, "linuxcnc/gcode/fixture.ngc"],
],
);
assert.deepEqual(readyMachineSession.snapshotCheck, {
name: "snapshot",
path: "linuxcnc/sessions/machine-session-1/machine-session-snapshot.json",
ok: true,
error: null,
});
assert.equal(readyMachineSession.snapshot.sessionId, "machine-session-1");
const missingMachineSession = await readMachineSessionReadiness("missing-machine", {
storage,
sessionId: "missing-session",
gcodeRequired: true,
gcodeFilename: "missing.ngc",
});
assert.equal(missingMachineSession.ready, false);
assert.equal(missingMachineSession.phase, "blocked");
assert.deepEqual(missingMachineSession.missing, [
"ini",
"parameters",
"toolTable",
"gcode",
"snapshot",
]);
assert.deepEqual(
missingMachineSession.errors.map((error) => error.name),
["ini", "parameters", "toolTable", "gcode", "snapshot"],
);
assert.match(missingMachineSession.errors[0].error, /missing directory|missing file/);
const bridgeFiles = new Map();
const bridgeInterp = {
writeTextFile(path, text) {
@@ -897,6 +948,13 @@ await assert.rejects(
() => loadGcodeProgram("../escape.ngc", { storage }),
/Invalid G-code filename/,
);
await assert.rejects(
() => readMachineSessionReadiness("xyzab-tdr", {
storage,
gcodeOpfsPath: "../escape.ngc",
}),
/Invalid OPFS path/,
);
await assert.rejects(
() => saveSessionSnapshot("session-1", {}, {
storage,

View File

@@ -30,6 +30,7 @@ import {
parameterFilePath,
planIniFileContextStaging,
planSimConfigStaging,
readMachineSessionReadiness,
renderIniPanelShellWorkflowOverviewEmbeddingMountState,
restoreMachineParametersFromOpfs,
saveMachineSessionSnapshot,
@@ -76,6 +77,7 @@ const requiredExports = [
["restoreMachineParametersFromOpfs", restoreMachineParametersFromOpfs],
["loadMachineToolTableFromOpfs", loadMachineToolTableFromOpfs],
["loadMachineSessionFromOpfs", loadMachineSessionFromOpfs],
["readMachineSessionReadiness", readMachineSessionReadiness],
["createIniPanelLaunchApiManifest", createIniPanelLaunchApiManifest],
["isSupportedIniPanelLaunchApiManifest", isSupportedIniPanelLaunchApiManifest],
["createIniPanelShellViewModel", createIniPanelShellViewModel],