接续L4-TOOL-DB持久化闭环
结论:真实 Node/native DB_PROGRAM transcript 与 flat-file 已接入 Tool DB OPFS store 证据链,浏览器执行仍保持锁定等待 Python/WASM Worker。
This commit is contained in:
@@ -93,6 +93,7 @@ import {
|
||||
createLinuxCncToolDbProcessPort,
|
||||
createToolDbProcessDiagnostics,
|
||||
createToolDbTransactionPlan,
|
||||
runToolDbProcessPortPersistenceSession,
|
||||
createVirtualHalBridgeActionPlan,
|
||||
createVirtualHalBridgeReadiness,
|
||||
createVirtualHalCommandScriptFixtureReport,
|
||||
@@ -524,6 +525,7 @@ const requiredExports = [
|
||||
["createLinuxCncToolDbProcessPort", createLinuxCncToolDbProcessPort],
|
||||
["createToolDbProcessDiagnostics", createToolDbProcessDiagnostics],
|
||||
["createToolDbTransactionPlan", createToolDbTransactionPlan],
|
||||
["runToolDbProcessPortPersistenceSession", runToolDbProcessPortPersistenceSession],
|
||||
["validateToolDbTranscript", validateToolDbTranscript],
|
||||
["saveToolDbFile", saveToolDbFile],
|
||||
["loadToolDbFile", loadToolDbFile],
|
||||
|
||||
@@ -4,12 +4,64 @@ import { resolve } from "node:path";
|
||||
|
||||
import {
|
||||
createLinuxCncToolDbProcessPort,
|
||||
createToolDbProcessDiagnostics,
|
||||
validateToolDbTranscript,
|
||||
} from "../../../runtime/sdk/src/tool-db-process-port.js";
|
||||
import {
|
||||
createLinuxCncToolDbNodeRuntimeAdapter,
|
||||
} from "../../../runtime/sdk/src/tool-db-node-runtime-adapter.js";
|
||||
import {
|
||||
runToolDbProcessPortPersistenceSession,
|
||||
} from "../../../runtime/sdk/src/tool-db-runtime-session.js";
|
||||
|
||||
class MockFileHandle {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
this.textValue = "";
|
||||
}
|
||||
|
||||
async createWritable() {
|
||||
return {
|
||||
write: async (text) => {
|
||||
this.textValue = String(text);
|
||||
},
|
||||
close: async () => {},
|
||||
};
|
||||
}
|
||||
|
||||
async getFile() {
|
||||
return {
|
||||
text: async () => this.textValue,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class MockDirectoryHandle {
|
||||
constructor(name = "") {
|
||||
this.name = name;
|
||||
this.dirs = new Map();
|
||||
this.files = new Map();
|
||||
}
|
||||
|
||||
async getDirectoryHandle(name, options = {}) {
|
||||
if (!this.dirs.has(name)) {
|
||||
if (!options.create) {
|
||||
throw new Error(`missing directory: ${name}`);
|
||||
}
|
||||
this.dirs.set(name, new MockDirectoryHandle(name));
|
||||
}
|
||||
return this.dirs.get(name);
|
||||
}
|
||||
|
||||
async getFileHandle(name, options = {}) {
|
||||
if (!this.files.has(name)) {
|
||||
if (!options.create) {
|
||||
throw new Error(`missing file: ${name}`);
|
||||
}
|
||||
this.files.set(name, new MockFileHandle(name));
|
||||
}
|
||||
return this.files.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
const adapter = createLinuxCncToolDbNodeRuntimeAdapter({
|
||||
dbSavefile: resolve("wasm-port/build/native/tool-db-runtime/sdk-node-runtime-adapter-db-nonran"),
|
||||
@@ -59,22 +111,42 @@ const dbFileText = readFileSync(adapter.dbSavefile, "utf8");
|
||||
assert.match(dbFileText, /T11 P111 D0.33 Z0.11/);
|
||||
assert.match(dbFileText, /T14 P114\b/);
|
||||
|
||||
const diagnostics = createToolDbProcessDiagnostics({
|
||||
dbProgramPath: "./db_nonran.py",
|
||||
opfsDbPath: "/machines/db-demo/tool-db/db_nonran_file",
|
||||
transcript,
|
||||
dbFileText,
|
||||
startupToolCount: 10,
|
||||
mutationCount: 3,
|
||||
runtimeMode: adapter.runtimeMode,
|
||||
runtimeExecutionReady: true,
|
||||
const storageRoot = new MockDirectoryHandle();
|
||||
const storage = { getDirectory: async () => storageRoot };
|
||||
const sessionAdapter = createLinuxCncToolDbNodeRuntimeAdapter({
|
||||
dbSavefile: resolve("wasm-port/build/native/tool-db-runtime/sdk-node-runtime-persistence-db-nonran"),
|
||||
stdoutLog: resolve("wasm-port/build/native/tool-db-runtime/sdk-node-runtime-persistence.stdout.log"),
|
||||
stderrLog: resolve("wasm-port/build/native/tool-db-runtime/sdk-node-runtime-persistence.stderr.log"),
|
||||
});
|
||||
assert.equal(diagnostics.runtimeMode, "node-linuxcnc-db-program");
|
||||
assert.equal(diagnostics.runtimeExecutionReady, true);
|
||||
assert.equal(diagnostics.protocolTranscriptReady, true);
|
||||
assert.equal(diagnostics.opfsPersistenceReady, true);
|
||||
assert.equal(diagnostics.tblFallbackSufficient, false);
|
||||
assert.equal(diagnostics.executionEnabled, false);
|
||||
assert.equal(diagnostics.promotionAllowed, false);
|
||||
const session = await runToolDbProcessPortPersistenceSession({
|
||||
port: createLinuxCncToolDbProcessPort({
|
||||
dbProgramPath: "./db_nonran.py",
|
||||
sourceFiles: [
|
||||
"configs/sim/axis/db_demo/db_nonran.py",
|
||||
"configs/sim/axis/db_demo/db.py",
|
||||
"lib/python/tooldb.py",
|
||||
],
|
||||
runtimeMode: sessionAdapter.runtimeMode,
|
||||
runtimeAdapter: sessionAdapter,
|
||||
}),
|
||||
machineId: "db-demo",
|
||||
runId: "node-runtime-session",
|
||||
dbProgramPath: "./db_nonran.py",
|
||||
readDbFileText: () => sessionAdapter.readDbFileText(),
|
||||
storage,
|
||||
});
|
||||
assert.equal(session.apiName, "linuxcnc-tool-db-process-runtime-persistence-session");
|
||||
assert.equal(session.ready, true);
|
||||
assert.equal(session.diagnostics.runtimeMode, "node-linuxcnc-db-program");
|
||||
assert.equal(session.diagnostics.runtimeExecutionReady, true);
|
||||
assert.equal(session.diagnostics.protocolTranscriptReady, true);
|
||||
assert.equal(session.diagnostics.opfsPersistenceReady, true);
|
||||
assert.equal(session.diagnostics.tblFallbackSufficient, false);
|
||||
assert.equal(session.diagnostics.executionEnabled, false);
|
||||
assert.equal(session.diagnostics.promotionAllowed, false);
|
||||
assert.equal(session.savedDb.displayPath, "/machines/db-demo/tool-db/db_nonran_file");
|
||||
assert.equal(session.savedTranscript.displayPath, "/machines/db-demo/tool-db/transcripts/node-runtime-session/transcript.json");
|
||||
assert.match(session.loadedDb.text, /T11 P111 D0.33 Z0.11/);
|
||||
assert.match(session.loadedTranscript.payload.transcript[0].line, /^v2\.1$/);
|
||||
|
||||
console.log("tool_db_node_runtime_adapter=ok");
|
||||
|
||||
Reference in New Issue
Block a user