Files
cnc_wams/web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-interpreter-worker-client.js

81 lines
2.1 KiB
JavaScript

const SOURCE_MODE = "linuxcnc-interpreter-wasm";
const SEMANTIC_BOUNDARY = "linuxcnc_interpreter_wasm_canonical_events";
export async function createLinuxCncInterpreterWorkerRuntime({
sdkModuleUrl,
workerUrl = new URL("./linuxcnc-interpreter-worker.js", import.meta.url).href,
} = {}) {
if (typeof Worker !== "function") {
throw new Error("Web Worker is not available in this runtime");
}
const worker = new Worker(workerUrl, { type: "module" });
const request = createWorkerRequest(worker);
const readiness = await request("init", { sdkModuleUrl });
const runtime = {
apiName: "web-rtcp-5axis-linuxcnc-interpreter-worker-runtime",
loaded: true,
sourceMode: SOURCE_MODE,
semanticBoundary: SEMANTIC_BOUNDARY,
executionContext: "worker",
workerUrl,
readiness() {
return {
...readiness,
apiName: "web-rtcp-5axis-linuxcnc-interpreter-worker-runtime-readiness",
executionContext: "worker",
workerUrl,
};
},
runProgram(programText) {
return request("runProgram", { programText });
},
runMachineFileProgram(options = {}) {
return request("runMachineFileProgram", options);
},
terminate() {
worker.terminate();
},
};
return runtime;
}
function createWorkerRequest(worker) {
let nextId = 1;
const pending = new Map();
worker.addEventListener("message", (event) => {
const { id, ok, value, error } = event.data || {};
const request = pending.get(id);
if (!request) return;
pending.delete(id);
if (ok) {
request.resolve(value);
} else {
request.reject(new Error(error || "LinuxCNC interpreter worker request failed"));
}
});
worker.addEventListener("error", (event) => {
const error = new Error(event.message || "LinuxCNC interpreter worker error");
for (const request of pending.values()) {
request.reject(error);
}
pending.clear();
});
return function request(type, payload = {}) {
const id = nextId++;
return new Promise((resolve, reject) => {
pending.set(id, { resolve, reject });
worker.postMessage({ id, type, payload });
});
};
}