UNPKG

@xylabs/threads

Version:

Web workers & worker threads as simple as a function call

162 lines (159 loc) 5.55 kB
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); // src/master/implementation.node.ts import { EventEmitter } from "node:events"; import { cpus } from "node:os"; import path from "node:path"; import { cwd } from "node:process"; import { Worker as NativeWorker } from "node:worker_threads"; var defaultPoolSize = cpus().length; function resolveScriptPath(scriptPath, baseURL) { const makeAbsolute = (filePath) => { return path.isAbsolute(filePath) ? filePath : path.join(baseURL ?? cwd(), filePath); }; const absolutePath = makeAbsolute(scriptPath); return absolutePath; } function initWorkerThreadsWorker() { let allWorkers = []; class Worker2 extends NativeWorker { mappedEventListeners; constructor(scriptPath, options) { const resolvedScriptPath = options && options.fromSource ? null : resolveScriptPath(scriptPath, (options ?? {})._baseURL); if (resolvedScriptPath) { super(resolvedScriptPath, options); } else { const sourceCode = scriptPath; super(sourceCode, { ...options, eval: true }); } this.mappedEventListeners = /* @__PURE__ */ new WeakMap(); allWorkers.push(this); } addEventListener(eventName, rawListener) { const listener = (message) => { rawListener({ data: message }); }; this.mappedEventListeners.set(rawListener, listener); this.on(eventName, listener); } removeEventListener(eventName, rawListener) { const listener = this.mappedEventListeners.get(rawListener) || rawListener; this.off(eventName, listener); } } const terminateWorkersAndMaster = () => { Promise.all(allWorkers.map((worker) => worker.terminate())).then( () => process.exit(0), () => process.exit(1) ); allWorkers = []; }; process.on("SIGINT", () => terminateWorkersAndMaster()); process.on("SIGTERM", () => terminateWorkersAndMaster()); class BlobWorker2 extends Worker2 { constructor(blob, options) { super(Buffer.from(blob).toString("utf-8"), { ...options, fromSource: true }); } static fromText(source, options) { return new Worker2(source, { ...options, fromSource: true }); } } return { blob: BlobWorker2, default: Worker2 }; } function initTinyWorker() { const TinyWorker = __require("tiny-worker"); let allWorkers = []; class Worker2 extends TinyWorker { emitter; constructor(scriptPath, options) { const resolvedScriptPath = options && options.fromSource ? null : process.platform === "win32" ? `file:///${resolveScriptPath(scriptPath).replaceAll("\\", "/")}` : resolveScriptPath(scriptPath); if (resolvedScriptPath) { super(resolvedScriptPath, [], { esm: true }); } else { const sourceCode = scriptPath; super(new Function(sourceCode), [], { esm: true }); } allWorkers.push(this); this.emitter = new EventEmitter(); this.onerror = (error) => this.emitter.emit("error", error); this.onmessage = (message) => this.emitter.emit("message", message); } addEventListener(eventName, listener) { this.emitter.addListener(eventName, listener); } removeEventListener(eventName, listener) { this.emitter.removeListener(eventName, listener); } terminate() { allWorkers = allWorkers.filter((worker) => worker !== this); return super.terminate(); } } const terminateWorkersAndMaster = () => { Promise.all(allWorkers.map((worker) => worker.terminate())).then( () => process.exit(0), () => process.exit(1) ); allWorkers = []; }; process.on("SIGINT", () => terminateWorkersAndMaster()); process.on("SIGTERM", () => terminateWorkersAndMaster()); class BlobWorker2 extends Worker2 { constructor(blob, options) { super(Buffer.from(blob).toString("utf-8"), { ...options, fromSource: true }); } static fromText(source, options) { return new Worker2(source, { ...options, fromSource: true }); } } return { blob: BlobWorker2, default: Worker2 }; } var implementation; var isTinyWorker; function selectWorkerImplementation() { try { isTinyWorker = false; return initWorkerThreadsWorker(); } catch (ex) { console.error(ex); console.debug("Node worker_threads not available. Trying to fall back to tiny-worker polyfill..."); isTinyWorker = true; return initTinyWorker(); } } function getWorkerImplementation() { if (!implementation) { implementation = selectWorkerImplementation(); } return implementation; } function isWorkerRuntime() { if (isTinyWorker) { return globalThis !== void 0 && self["postMessage"] ? true : false; } else { const isMainThread = typeof __non_webpack_require__ === "function" ? __non_webpack_require__("worker_threads").isMainThread : eval("require")("worker_threads").isMainThread; return !isMainThread; } } // src/master/index-node.ts var BlobWorker = getWorkerImplementation().blob; var Worker = getWorkerImplementation().default; // src/master/register.ts if (typeof globalThis !== "undefined") { ; globalThis.Worker = Worker; } else if (window !== void 0) { ; window.Worker = Worker; } //# sourceMappingURL=register.mjs.map