81 lines
2.1 KiB
JavaScript
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 });
|
|
});
|
|
};
|
|
}
|