@xylabs/threads
Version:
Web workers & worker threads as simple as a function call
352 lines (348 loc) • 12.2 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
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');
});
var __commonJS = (cb, mod) => function __require2() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
// ../../node_modules/.store/tiny-worker-npm-2.3.0-38c7100e1d/package/lib/index.js
var require_lib = __commonJS({
"../../node_modules/.store/tiny-worker-npm-2.3.0-38c7100e1d/package/lib/index.js"(exports, module) {
"use strict";
var _createClass = /* @__PURE__ */ function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
__name(defineProperties, "defineProperties");
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
__name(_classCallCheck, "_classCallCheck");
var path2 = __require("path");
var fork = __require("child_process").fork;
var worker = path2.join(__dirname, "worker.js");
var events = /^(error|message)$/;
var defaultPorts = {
inspect: 9229,
debug: 5858
};
var range = {
min: 1,
max: 300
};
var Worker2 = function() {
function Worker3(arg) {
var _this = this;
var args = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [];
var options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {
cwd: process.cwd()
};
_classCallCheck(this, Worker3);
var isfn = typeof arg === "function", input = isfn ? arg.toString() : arg;
if (!options.cwd) {
options.cwd = process.cwd();
}
var debugVars = process.execArgv.filter(function(execArg) {
return /(debug|inspect)/.test(execArg);
});
if (debugVars.length > 0 && !options.noDebugRedirection) {
if (!options.execArgv) {
debugVars = Array.from(process.execArgv);
options.execArgv = [];
}
var inspectIndex = debugVars.findIndex(function(debugArg) {
return /^--inspect(-brk)?(=\d+)?$/.test(debugArg);
});
var debugIndex = debugVars.findIndex(function(debugArg) {
return /^--debug(-brk)?(=\d+)?$/.test(debugArg);
});
var portIndex = inspectIndex >= 0 ? inspectIndex : debugIndex;
if (portIndex >= 0) {
var match = /^--(debug|inspect)(?:-brk)?(?:=(\d+))?$/.exec(debugVars[portIndex]);
var port = defaultPorts[match[1]];
if (match[2]) {
port = parseInt(match[2]);
}
debugVars[portIndex] = "--" + match[1] + "=" + (port + range.min + Math.floor(Math.random() * (range.max - range.min)));
if (debugIndex >= 0 && debugIndex !== portIndex) {
match = /^(--debug)(?:-brk)?(.*)/.exec(debugVars[debugIndex]);
debugVars[debugIndex] = match[1] + (match[2] ? match[2] : "");
}
}
options.execArgv = options.execArgv.concat(debugVars);
}
delete options.noDebugRedirection;
this.child = fork(worker, args, options);
this.onerror = void 0;
this.onmessage = void 0;
this.child.on("error", function(e) {
if (_this.onerror) {
_this.onerror.call(_this, e);
}
});
this.child.on("message", function(msg) {
var message = JSON.parse(msg);
var error = void 0;
if (!message.error && _this.onmessage) {
_this.onmessage.call(_this, message);
}
if (message.error && _this.onerror) {
error = new Error(message.error);
error.stack = message.stack;
_this.onerror.call(_this, error);
}
});
this.child.send({
input,
isfn,
cwd: options.cwd,
esm: options.esm
});
}
__name(Worker3, "Worker");
_createClass(Worker3, [
{
key: "addEventListener",
value: /* @__PURE__ */ __name(function addEventListener(event, fn) {
if (events.test(event)) {
this["on" + event] = fn;
}
}, "addEventListener")
},
{
key: "postMessage",
value: /* @__PURE__ */ __name(function postMessage(msg) {
this.child.send(JSON.stringify({
data: msg
}, null, 0));
}, "postMessage")
},
{
key: "terminate",
value: /* @__PURE__ */ __name(function terminate() {
this.child.kill("SIGINT");
}, "terminate")
}
], [
{
key: "setRange",
value: /* @__PURE__ */ __name(function setRange(min, max) {
if (min >= max) {
return false;
}
range.min = min;
range.max = max;
return true;
}, "setRange")
}
]);
return Worker3;
}();
module.exports = Worker2;
}
});
// src/master/implementation.node.ts
import { EventEmitter } from "events";
import { cpus } from "os";
import path from "path";
import { cwd } from "process";
import { Worker as NativeWorker } from "worker_threads";
var defaultPoolSize = cpus().length;
function resolveScriptPath(scriptPath, baseURL) {
const makeAbsolute = /* @__PURE__ */ __name((filePath) => {
return path.isAbsolute(filePath) ? filePath : path.join(baseURL ?? cwd(), filePath);
}, "makeAbsolute");
const absolutePath = makeAbsolute(scriptPath);
return absolutePath;
}
__name(resolveScriptPath, "resolveScriptPath");
function initWorkerThreadsWorker() {
let allWorkers = [];
let Worker2 = class Worker extends NativeWorker {
static {
__name(this, "Worker");
}
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 = /* @__PURE__ */ __name((message) => {
rawListener({
data: message
});
}, "listener");
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 = /* @__PURE__ */ __name(() => {
Promise.all(allWorkers.map((worker) => worker.terminate())).then(() => process.exit(0), () => process.exit(1));
allWorkers = [];
}, "terminateWorkersAndMaster");
process.on("SIGINT", () => terminateWorkersAndMaster());
process.on("SIGTERM", () => terminateWorkersAndMaster());
let BlobWorker2 = class BlobWorker extends Worker2 {
static {
__name(this, "BlobWorker");
}
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
};
}
__name(initWorkerThreadsWorker, "initWorkerThreadsWorker");
function initTinyWorker() {
const TinyWorker = require_lib();
let allWorkers = [];
let Worker2 = class Worker extends TinyWorker {
static {
__name(this, "Worker");
}
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 = /* @__PURE__ */ __name(() => {
Promise.all(allWorkers.map((worker) => worker.terminate())).then(() => process.exit(0), () => process.exit(1));
allWorkers = [];
}, "terminateWorkersAndMaster");
process.on("SIGINT", () => terminateWorkersAndMaster());
process.on("SIGTERM", () => terminateWorkersAndMaster());
let BlobWorker2 = class BlobWorker extends Worker2 {
static {
__name(this, "BlobWorker");
}
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
};
}
__name(initTinyWorker, "initTinyWorker");
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();
}
}
__name(selectWorkerImplementation, "selectWorkerImplementation");
function getWorkerImplementation() {
if (!implementation) {
implementation = selectWorkerImplementation();
}
return implementation;
}
__name(getWorkerImplementation, "getWorkerImplementation");
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;
}
}
__name(isWorkerRuntime, "isWorkerRuntime");
// 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