接续L4-TOOL-DB浏览器Worker边界

结论:浏览器 Tool DB Worker 传输层已接入并明确阻塞缺失的 Python/WASM runtime,未冒充 DB_PROGRAM 执行就绪。
This commit is contained in:
2026-06-19 07:09:25 +08:00
parent d323511f8b
commit 63870fd6d7
10 changed files with 248 additions and 4 deletions

View File

@@ -9,6 +9,7 @@
<script type="module">
import {
createLinuxCncToolDbProcessPort,
createLinuxCncToolDbBrowserWorkerAdapter,
createToolDbProcessDiagnostics,
createToolDbStorePaths,
loadToolDbFile,
@@ -58,6 +59,32 @@
assertEqual(planResult.status, "blocked_runtime_adapter_required", "contract-only plan status");
assertEqual(planResult.tblFallbackSufficient, false, "tbl fallback guard");
const workerAdapter = createLinuxCncToolDbBrowserWorkerAdapter({
workerUrl: new URL("../../runtime/workers/tool-db-python-worker.js", import.meta.url),
});
const workerPort = 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: workerAdapter.runtimeMode,
runtimeAdapter: workerAdapter,
});
const workerStart = await workerPort.start();
assertEqual(workerStart.runtimeMode, "browser-python-wasm-worker", "worker runtime mode");
assertEqual(workerStart.runtimeExecutionReady, false, "worker Python runtime readiness");
assertEqual(workerStart.status, "blocked_browser_python_wasm_runtime_missing", "worker Python runtime status");
const workerPlanResult = await workerPort.runTransactionPlan();
assertEqual(
workerPlanResult.status,
"blocked_browser_python_wasm_runtime_missing",
"worker plan blocked without Python/WASM runtime",
);
assertEqual(workerPlanResult.promotionAllowed, false, "worker promotion guard");
await workerPort.close();
const transcript = [
{ direction: "read", line: "v2.1" },
{ direction: "write", line: "g" },

View File

@@ -90,6 +90,7 @@ import {
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
createProjectReleaseReadinessReport,
createProjectReleaseReadinessSummaryViewModel,
createLinuxCncToolDbBrowserWorkerAdapter,
createLinuxCncToolDbProcessPort,
createToolDbProcessDiagnostics,
createToolDbTransactionPlan,
@@ -522,6 +523,7 @@ const requiredExports = [
["saveMachineTextFiles", saveMachineTextFiles],
["loadMachineTextFiles", loadMachineTextFiles],
["gcodeFilenameFromProgramPath", gcodeFilenameFromProgramPath],
["createLinuxCncToolDbBrowserWorkerAdapter", createLinuxCncToolDbBrowserWorkerAdapter],
["createLinuxCncToolDbProcessPort", createLinuxCncToolDbProcessPort],
["createToolDbProcessDiagnostics", createToolDbProcessDiagnostics],
["createToolDbTransactionPlan", createToolDbTransactionPlan],

View File

@@ -83,6 +83,7 @@ const port = createLinuxCncToolDbProcessPort({
const startResult = await port.start();
assert.equal(startResult.runtimeMode, "node-linuxcnc-db-program");
assert.equal(startResult.runtimeExecutionReady, true);
assert.equal(startResult.status, "node_linuxcnc_db_program_started");
assert.equal(startResult.executionEnabled, false);
assert.equal(startResult.promotionAllowed, false);

View File

@@ -1,5 +1,8 @@
import assert from "node:assert/strict";
import {
createLinuxCncToolDbBrowserWorkerAdapter,
} from "../../../runtime/sdk/src/tool-db-browser-worker-adapter.js";
import {
TOOL_DB_PROCESS_PORT_CONTRACT_VERSION,
TOOL_DB_TRANSACTION_PLAN,
@@ -37,6 +40,7 @@ const startResult = await port.start();
assert.deepEqual(startResult, {
runtimeMode: "contract-only",
runtimeExecutionReady: false,
status: null,
executionEnabled: false,
promotionAllowed: false,
});
@@ -48,6 +52,53 @@ assert.equal(blockedPlan.executionEnabled, false);
assert.equal(blockedPlan.promotionAllowed, false);
assert.equal(blockedPlan.tblFallbackSufficient, false);
class FakeBlockedWorker {
constructor() {
this.listeners = new Map();
}
addEventListener(type, listener) {
this.listeners.set(type, listener);
}
postMessage(message) {
queueMicrotask(() => {
this.listeners.get("message")?.({
data: {
id: message.id,
type: message.type,
ok: true,
runtimeExecutionReady: false,
status: "blocked_browser_python_wasm_runtime_missing",
executionEnabled: false,
promotionAllowed: false,
},
});
});
}
terminate() {}
}
const browserWorkerAdapter = createLinuxCncToolDbBrowserWorkerAdapter({
workerUrl: "./tool-db-python-worker.js",
workerFactory: () => new FakeBlockedWorker(),
});
const browserWorkerPort = createLinuxCncToolDbProcessPort({
dbProgramPath: "./db_nonran.py",
runtimeMode: browserWorkerAdapter.runtimeMode,
runtimeAdapter: browserWorkerAdapter,
});
const browserWorkerStart = await browserWorkerPort.start();
assert.equal(browserWorkerStart.runtimeMode, "browser-python-wasm-worker");
assert.equal(browserWorkerStart.runtimeExecutionReady, false);
assert.equal(browserWorkerStart.status, "blocked_browser_python_wasm_runtime_missing");
const browserWorkerBlockedPlan = await browserWorkerPort.runTransactionPlan();
assert.equal(browserWorkerBlockedPlan.status, "blocked_browser_python_wasm_runtime_missing");
assert.equal(browserWorkerBlockedPlan.runtimeExecutionReady, false);
assert.equal(browserWorkerBlockedPlan.promotionAllowed, false);
await browserWorkerPort.close();
const transcript = [
{ direction: "read", line: "v2.1" },
{ direction: "write", line: "g" },