@itwin/core-frontend
Version:
iTwin.js frontend components
60 lines • 2.36 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Utils
*/
import { assert } from "@itwin/core-bentley";
/** Create a [[WorkerProxy]] implementing the methods of `T` using the specified worker script.
* See [this article]($docs/learning/frontend/WorkerProxy.md) for more details and examples.
* @beta
*/
export function createWorkerProxy(workerJsPath) {
const tasks = new Map();
let curMsgId = 0;
let terminated = false;
let worker;
const sameOrigin = workerJsPath.substring(0, globalThis.origin.length) === globalThis.origin;
if (sameOrigin || !workerJsPath.startsWith("http")) {
worker = new Worker(workerJsPath);
}
else {
const workerBlob = new Blob([`importScripts("${workerJsPath}");`]);
const workerBlobUrl = URL.createObjectURL(workerBlob);
worker = new Worker(workerBlobUrl);
}
worker.onmessage = (e) => {
const response = e.data;
assert(typeof response === "object");
assert("result" in response || "error" in response);
const task = tasks.get(response.msgId);
if (task) {
tasks.delete(response.msgId);
if (response.error)
task.reject(response.error);
else
task.resolve(response.result);
}
};
return new Proxy({}, {
get(_target, operation) {
if (operation === "terminate") {
assert(!terminated);
terminated = true;
return () => worker.terminate();
}
else if (operation === "isTerminated") {
return terminated;
}
else {
return async (...args) => new Promise((resolve, reject) => {
const msgId = ++curMsgId;
tasks.set(msgId, { resolve, reject });
worker.postMessage({ operation, payload: args[0], msgId }, args[1] ?? []);
});
}
},
});
}
//# sourceMappingURL=WorkerProxy.js.map