"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // dist/index.js var dist_exports = {}; __export(dist_exports, { AsyncQueue: () => AsyncQueue, ChildProcessProxy: () => ChildProcessProxy, NullWorker: () => NullWorker, WorkerBody: () => WorkerBody, WorkerFarm: () => WorkerFarm, WorkerJob: () => WorkerJob, WorkerPool: () => WorkerPool, WorkerThread: () => WorkerThread, assert: () => assert, canProcessOnWorker: () => canProcessOnWorker, createWorker: () => createWorker, getLibraryUrl: () => getLibraryUrl, getTransferList: () => getTransferList, getTransferListForWriter: () => getTransferListForWriter, getWorkerURL: () => getWorkerURL, isBrowser: () => isBrowser, isWorker: () => isWorker, loadLibrary: () => loadLibrary, processOnWorker: () => processOnWorker, validateWorkerVersion: () => validateWorkerVersion }); module.exports = __toCommonJS(dist_exports); // dist/lib/env-utils/version.js var NPM_TAG = "latest"; function getVersion() { var _a; if (!((_a = globalThis._loadersgl_) == null ? void 0 : _a.version)) { globalThis._loadersgl_ = globalThis._loadersgl_ || {}; if (false) { console.warn("loaders.gl: The __VERSION__ variable is not injected using babel plugin. Latest unstable workers would be fetched from the CDN."); globalThis._loadersgl_.version = NPM_TAG; } else { globalThis._loadersgl_.version = "4.3.1"; } } return globalThis._loadersgl_.version; } var VERSION = getVersion(); // dist/lib/env-utils/assert.js function assert(condition, message) { if (!condition) { throw new Error(message || "loaders.gl assertion failed."); } } // dist/lib/env-utils/globals.js var globals = { self: typeof self !== "undefined" && self, window: typeof window !== "undefined" && window, global: typeof global !== "undefined" && global, document: typeof document !== "undefined" && document }; var self_ = globals.self || globals.window || globals.global || {}; var window_ = globals.window || globals.self || globals.global || {}; var global_ = globals.global || globals.self || globals.window || {}; var document_ = globals.document || {}; var isBrowser = ( // @ts-ignore process.browser typeof process !== "object" || String(process) !== "[object process]" || process.browser ); var isWorker = typeof importScripts === "function"; var isMobile = typeof window !== "undefined" && typeof window.orientation !== "undefined"; var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version); var nodeVersion = matches && parseFloat(matches[1]) || 0; // dist/lib/worker-farm/worker-job.js var WorkerJob = class { name; workerThread; isRunning = true; /** Promise that resolves when Job is done */ result; _resolve = () => { }; _reject = () => { }; constructor(jobName, workerThread) { this.name = jobName; this.workerThread = workerThread; this.result = new Promise((resolve, reject) => { this._resolve = resolve; this._reject = reject; }); } /** * Send a message to the job's worker thread * @param data any data structure, ideally consisting mostly of transferrable objects */ postMessage(type, payload) { this.workerThread.postMessage({ source: "loaders.gl", // Lets worker ignore unrelated messages type, payload }); } /** * Call to resolve the `result` Promise with the supplied value */ done(value) { assert(this.isRunning); this.isRunning = false; this._resolve(value); } /** * Call to reject the `result` Promise with the supplied error */ error(error) { assert(this.isRunning); this.isRunning = false; this._reject(error); } }; // dist/lib/node/worker_threads-browser.js var NodeWorker = class { terminate() { } }; var parentPort = null; // dist/lib/worker-utils/get-loadable-worker-url.js var workerURLCache = /* @__PURE__ */ new Map(); function getLoadableWorkerURL(props) { assert(props.source && !props.url || !props.source && props.url); let workerURL = workerURLCache.get(props.source || props.url); if (!workerURL) { if (props.url) { workerURL = getLoadableWorkerURLFromURL(props.url); workerURLCache.set(props.url, workerURL); } if (props.source) { workerURL = getLoadableWorkerURLFromSource(props.source); workerURLCache.set(props.source, workerURL); } } assert(workerURL); return workerURL; } function getLoadableWorkerURLFromURL(url) { if (!url.startsWith("http")) { return url; } const workerSource = buildScriptSource(url); return getLoadableWorkerURLFromSource(workerSource); } function getLoadableWorkerURLFromSource(workerSource) { const blob = new Blob([workerSource], { type: "application/javascript" }); return URL.createObjectURL(blob); } function buildScriptSource(workerUrl) { return `try { importScripts('${workerUrl}'); } catch (error) { console.error(error); throw error; }`; } // dist/lib/worker-utils/get-transfer-list.js function getTransferList(object, recursive = true, transfers) { const transfersSet = transfers || /* @__PURE__ */ new Set(); if (!object) { } else if (isTransferable(object)) { transfersSet.add(object); } else if (isTransferable(object.buffer)) { transfersSet.add(object.buffer); } else if (ArrayBuffer.isView(object)) { } else if (recursive && typeof object === "object") { for (const key in object) { getTransferList(object[key], recursive, transfersSet); } } return transfers === void 0 ? Array.from(transfersSet) : []; } function isTransferable(object) { if (!object) { return false; } if (object instanceof ArrayBuffer) { return true; } if (typeof MessagePort !== "undefined" && object instanceof MessagePort) { return true; } if (typeof ImageBitmap !== "undefined" && object instanceof ImageBitmap) { return true; } if (typeof OffscreenCanvas !== "undefined" && object instanceof OffscreenCanvas) { return true; } return false; } function getTransferListForWriter(object) { if (object === null) { return {}; } const clone = Object.assign({}, object); Object.keys(clone).forEach((key) => { if (typeof object[key] === "object" && !ArrayBuffer.isView(object[key]) && !(object[key] instanceof Array)) { clone[key] = getTransferListForWriter(object[key]); } else if (typeof clone[key] === "function" || clone[key] instanceof RegExp) { clone[key] = {}; } else { clone[key] = object[key]; } }); return clone; } // dist/lib/worker-farm/worker-thread.js var NOOP = () => { }; var WorkerThread = class { name; source; url; terminated = false; worker; onMessage; onError; _loadableURL = ""; /** Checks if workers are supported on this platform */ static isSupported() { return typeof Worker !== "undefined" && isBrowser || typeof NodeWorker !== "undefined" && !isBrowser; } constructor(props) { const { name, source, url } = props; assert(source || url); this.name = name; this.source = source; this.url = url; this.onMessage = NOOP; this.onError = (error) => console.log(error); this.worker = isBrowser ? this._createBrowserWorker() : this._createNodeWorker(); } /** * Terminate this worker thread * @note Can free up significant memory */ destroy() { this.onMessage = NOOP; this.onError = NOOP; this.worker.terminate(); this.terminated = true; } get isRunning() { return Boolean(this.onMessage); } /** * Send a message to this worker thread * @param data any data structure, ideally consisting mostly of transferrable objects * @param transferList If not supplied, calculated automatically by traversing data */ postMessage(data, transferList) { transferList = transferList || getTransferList(data); this.worker.postMessage(data, transferList); } // PRIVATE /** * Generate a standard Error from an ErrorEvent * @param event */ _getErrorFromErrorEvent(event) { let message = "Failed to load "; message += `worker ${this.name} from ${this.url}. `; if (event.message) { message += `${event.message} in `; } if (event.lineno) { message += `:${event.lineno}:${event.colno}`; } return new Error(message); } /** * Creates a worker thread on the browser */ _createBrowserWorker() { this._loadableURL = getLoadableWorkerURL({ source: this.source, url: this.url }); const worker = new Worker(this._loadableURL, { name: this.name }); worker.onmessage = (event) => { if (!event.data) { this.onError(new Error("No data received")); } else { this.onMessage(event.data); } }; worker.onerror = (error) => { this.onError(this._getErrorFromErrorEvent(error)); this.terminated = true; }; worker.onmessageerror = (event) => console.error(event); return worker; } /** * Creates a worker thread in node.js * @todo https://nodejs.org/api/async_hooks.html#async-resource-worker-pool */ _createNodeWorker() { let worker; if (this.url) { const absolute = this.url.includes(":/") || this.url.startsWith("/"); const url = absolute ? this.url : `./${this.url}`; worker = new NodeWorker(url, { eval: false }); } else if (this.source) { worker = new NodeWorker(this.source, { eval: true }); } else { throw new Error("no worker"); } worker.on("message", (data) => { this.onMessage(data); }); worker.on("error", (error) => { this.onError(error); }); worker.on("exit", (code) => { }); return worker; } }; // dist/lib/worker-farm/worker-pool.js var WorkerPool = class { name = "unnamed"; source; // | Function; url; maxConcurrency = 1; maxMobileConcurrency = 1; onDebug = () => { }; reuseWorkers = true; props = {}; jobQueue = []; idleQueue = []; count = 0; isDestroyed = false; /** Checks if workers are supported on this platform */ static isSupported() { return WorkerThread.isSupported(); } /** * @param processor - worker function * @param maxConcurrency - max count of workers */ constructor(props) { this.source = props.source; this.url = props.url; this.setProps(props); } /** * Terminates all workers in the pool * @note Can free up significant memory */ destroy() { this.idleQueue.forEach((worker) => worker.destroy()); this.isDestroyed = true; } setProps(props) { this.props = { ...this.props, ...props }; if (props.name !== void 0) { this.name = props.name; } if (props.maxConcurrency !== void 0) { this.maxConcurrency = props.maxConcurrency; } if (props.maxMobileConcurrency !== void 0) { this.maxMobileConcurrency = props.maxMobileConcurrency; } if (props.reuseWorkers !== void 0) { this.reuseWorkers = props.reuseWorkers; } if (props.onDebug !== void 0) { this.onDebug = props.onDebug; } } async startJob(name, onMessage2 = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) { const startPromise = new Promise((onStart) => { this.jobQueue.push({ name, onMessage: onMessage2, onError, onStart }); return this; }); this._startQueuedJob(); return await startPromise; } // PRIVATE /** * Starts first queued job if worker is available or can be created * Called when job is started and whenever a worker returns to the idleQueue */ async _startQueuedJob() { if (!this.jobQueue.length) { return; } const workerThread = this._getAvailableWorker(); if (!workerThread) { return; } const queuedJob = this.jobQueue.shift(); if (queuedJob) { this.onDebug({ message: "Starting job", name: queuedJob.name, workerThread, backlog: this.jobQueue.length }); const job = new WorkerJob(queuedJob.name, workerThread); workerThread.onMessage = (data) => queuedJob.onMessage(job, data.type, data.payload); workerThread.onError = (error) => queuedJob.onError(job, error); queuedJob.onStart(job); try { await job.result; } catch (error) { console.error(`Worker exception: ${error}`); } finally { this.returnWorkerToQueue(workerThread); } } } /** * Returns a worker to the idle queue * Destroys the worker if * - pool is destroyed * - if this pool doesn't reuse workers * - if maxConcurrency has been lowered * @param worker */ returnWorkerToQueue(worker) { const shouldDestroyWorker = ( // Workers on Node.js prevent the process from exiting. // Until we figure out how to close them before exit, we always destroy them !isBrowser || // If the pool is destroyed, there is no reason to keep the worker around this.isDestroyed || // If the app has disabled worker reuse, any completed workers should be destroyed !this.reuseWorkers || // If concurrency has been lowered, this worker might be surplus to requirements this.count > this._getMaxConcurrency() ); if (shouldDestroyWorker) { worker.destroy(); this.count--; } else { this.idleQueue.push(worker); } if (!this.isDestroyed) { this._startQueuedJob(); } } /** * Returns idle worker or creates new worker if maxConcurrency has not been reached */ _getAvailableWorker() { if (this.idleQueue.length > 0) { return this.idleQueue.shift() || null; } if (this.count < this._getMaxConcurrency()) { this.count++; const name = `${this.name.toLowerCase()} (#${this.count} of ${this.maxConcurrency})`; return new WorkerThread({ name, source: this.source, url: this.url }); } return null; } _getMaxConcurrency() { return isMobile ? this.maxMobileConcurrency : this.maxConcurrency; } }; // dist/lib/worker-farm/worker-farm.js var DEFAULT_PROPS = { maxConcurrency: 3, maxMobileConcurrency: 1, reuseWorkers: true, onDebug: () => { } }; var _WorkerFarm = class { props; workerPools = /* @__PURE__ */ new Map(); /** Checks if workers are supported on this platform */ static isSupported() { return WorkerThread.isSupported(); } /** Get the singleton instance of the global worker farm */ static getWorkerFarm(props = {}) { _WorkerFarm._workerFarm = _WorkerFarm._workerFarm || new _WorkerFarm({}); _WorkerFarm._workerFarm.setProps(props); return _WorkerFarm._workerFarm; } /** get global instance with WorkerFarm.getWorkerFarm() */ constructor(props) { this.props = { ...DEFAULT_PROPS }; this.setProps(props); this.workerPools = /* @__PURE__ */ new Map(); } /** * Terminate all workers in the farm * @note Can free up significant memory */ destroy() { for (const workerPool of this.workerPools.values()) { workerPool.destroy(); } this.workerPools = /* @__PURE__ */ new Map(); } /** * Set props used when initializing worker pools * @param props */ setProps(props) { this.props = { ...this.props, ...props }; for (const workerPool of this.workerPools.values()) { workerPool.setProps(this._getWorkerPoolProps()); } } /** * Returns a worker pool for the specified worker * @param options - only used first time for a specific worker name * @param options.name - the name of the worker - used to identify worker pool * @param options.url - * @param options.source - * @example * const job = WorkerFarm.getWorkerFarm().getWorkerPool({name, url}).startJob(...); */ getWorkerPool(options2) { const { name, source, url } = options2; let workerPool = this.workerPools.get(name); if (!workerPool) { workerPool = new WorkerPool({ name, source, url }); workerPool.setProps(this._getWorkerPoolProps()); this.workerPools.set(name, workerPool); } return workerPool; } _getWorkerPoolProps() { return { maxConcurrency: this.props.maxConcurrency, maxMobileConcurrency: this.props.maxMobileConcurrency, reuseWorkers: this.props.reuseWorkers, onDebug: this.props.onDebug }; } }; var WorkerFarm = _WorkerFarm; // singleton __publicField(WorkerFarm, "_workerFarm"); // dist/lib/worker-farm/worker-body.js async function getParentPort() { return parentPort; } var onMessageWrapperMap = /* @__PURE__ */ new Map(); var WorkerBody = class { /** Check that we are actually in a worker thread */ static async inWorkerThread() { return typeof self !== "undefined" || Boolean(await getParentPort()); } /* * (type: WorkerMessageType, payload: WorkerMessagePayload) => any */ static set onmessage(onMessage2) { async function handleMessage(message) { const parentPort2 = await getParentPort(); const { type, payload } = parentPort2 ? message : message.data; onMessage2(type, payload); } getParentPort().then((parentPort2) => { if (parentPort2) { parentPort2.on("message", (message) => { handleMessage(message); }); parentPort2.on("exit", () => console.debug("Node worker closing")); } else { globalThis.onmessage = handleMessage; } }); } static async addEventListener(onMessage2) { let onMessageWrapper = onMessageWrapperMap.get(onMessage2); if (!onMessageWrapper) { onMessageWrapper = async (message) => { if (!isKnownMessage(message)) { return; } const parentPort3 = await getParentPort(); const { type, payload } = parentPort3 ? message : message.data; onMessage2(type, payload); }; } const parentPort2 = await getParentPort(); if (parentPort2) { console.error("not implemented"); } else { globalThis.addEventListener("message", onMessageWrapper); } } static async removeEventListener(onMessage2) { const onMessageWrapper = onMessageWrapperMap.get(onMessage2); onMessageWrapperMap.delete(onMessage2); const parentPort2 = await getParentPort(); if (parentPort2) { console.error("not implemented"); } else { globalThis.removeEventListener("message", onMessageWrapper); } } /** * Send a message from a worker to creating thread (main thread) * @param type * @param payload */ static async postMessage(type, payload) { const data = { source: "loaders.gl", type, payload }; const transferList = getTransferList(payload); const parentPort2 = await getParentPort(); if (parentPort2) { parentPort2.postMessage(data, transferList); } else { globalThis.postMessage(data, transferList); } } }; function isKnownMessage(message) { const { type, data } = message; return type === "message" && data && typeof data.source === "string" && data.source.startsWith("loaders.gl"); } // dist/lib/worker-api/get-worker-url.js function getWorkerName(worker) { const warning = worker.version !== VERSION ? ` (worker-utils@${VERSION})` : ""; return `${worker.name}@${worker.version}${warning}`; } function getWorkerURL(worker, options2 = {}) { const workerOptions = options2[worker.id] || {}; const workerFile = isBrowser ? `${worker.id}-worker.js` : `${worker.id}-worker-node.js`; let url = workerOptions.workerUrl; if (!url && worker.id === "compression") { url = options2.workerUrl; } if (options2._workerType === "test") { if (isBrowser) { url = `modules/${worker.module}/dist/${workerFile}`; } else { url = `modules/${worker.module}/src/workers/${worker.id}-worker-node.ts`; } } if (!url) { let version = worker.version; if (version === "latest") { version = NPM_TAG; } const versionTag = version ? `@${version}` : ""; url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`; } assert(url); return url; } // dist/lib/worker-api/process-on-worker.js function canProcessOnWorker(worker, options2) { if (!WorkerFarm.isSupported()) { return false; } return worker.worker && (options2 == null ? void 0 : options2.worker); } async function processOnWorker(worker, data, options2 = {}, context = {}) { const name = getWorkerName(worker); const workerFarm = WorkerFarm.getWorkerFarm(options2); const { source } = options2; const workerPoolProps = { name, source }; if (!source) { workerPoolProps.url = getWorkerURL(worker, options2); } const workerPool = workerFarm.getWorkerPool(workerPoolProps); const jobName = options2.jobName || worker.name; const job = await workerPool.startJob( jobName, // eslint-disable-next-line onMessage.bind(null, context) ); const transferableOptions = getTransferListForWriter(options2); job.postMessage("process", { input: data, options: transferableOptions }); const result = await job.result; return result.result; } async function onMessage(context, job, type, payload) { switch (type) { case "done": job.done(payload); break; case "error": job.error(new Error(payload.error)); break; case "process": const { id, input, options: options2 } = payload; try { if (!context.process) { job.postMessage("error", { id, error: "Worker not set up to process on main thread" }); return; } const result = await context.process(input, options2); job.postMessage("done", { id, result }); } catch (error) { const message = error instanceof Error ? error.message : "unknown error"; job.postMessage("error", { id, error: message }); } break; default: console.warn(`process-on-worker: unknown message ${type}`); } } // dist/lib/async-queue/async-queue.js var AsyncQueue = class { _values; _settlers; _closed; constructor() { this._values = []; this._settlers = []; this._closed = false; } /** Return an async iterator for this queue */ [Symbol.asyncIterator]() { return this; } /** Push a new value - the async iterator will yield a promise resolved to this value */ push(value) { return this.enqueue(value); } /** * Push a new value - the async iterator will yield a promise resolved to this value * Add an error - the async iterator will yield a promise rejected with this value */ enqueue(value) { if (this._closed) { throw new Error("Closed"); } if (this._settlers.length > 0) { if (this._values.length > 0) { throw new Error("Illegal internal state"); } const settler = this._settlers.shift(); if (value instanceof Error) { settler.reject(value); } else { settler.resolve({ value }); } } else { this._values.push(value); } } /** Indicate that we not waiting for more values - The async iterator will be done */ close() { while (this._settlers.length > 0) { const settler = this._settlers.shift(); settler.resolve({ done: true }); } this._closed = true; } // ITERATOR IMPLEMENTATION /** @returns a Promise for an IteratorResult */ next() { if (this._values.length > 0) { const value = this._values.shift(); if (value instanceof Error) { return Promise.reject(value); } return Promise.resolve({ done: false, value }); } if (this._closed) { if (this._settlers.length > 0) { throw new Error("Illegal internal state"); } return Promise.resolve({ done: true, value: void 0 }); } return new Promise((resolve, reject) => { this._settlers.push({ resolve, reject }); }); } }; // dist/lib/worker-api/create-worker.js var requestId = 0; var inputBatches; var options; async function createWorker(process2, processInBatches) { if (!await WorkerBody.inWorkerThread()) { return; } const context = { process: processOnMainThread }; WorkerBody.onmessage = async (type, payload) => { try { switch (type) { case "process": if (!process2) { throw new Error("Worker does not support atomic processing"); } const result = await process2(payload.input, payload.options || {}, context); WorkerBody.postMessage("done", { result }); break; case "process-in-batches": if (!processInBatches) { throw new Error("Worker does not support batched processing"); } inputBatches = new AsyncQueue(); options = payload.options || {}; const resultIterator = processInBatches(inputBatches, options, context); for await (const batch of resultIterator) { WorkerBody.postMessage("output-batch", { result: batch }); } WorkerBody.postMessage("done", {}); break; case "input-batch": inputBatches.push(payload.input); break; case "input-done": inputBatches.close(); break; default: } } catch (error) { const message = error instanceof Error ? error.message : ""; WorkerBody.postMessage("error", { error: message }); } }; } function processOnMainThread(arrayBuffer, options2 = {}) { return new Promise((resolve, reject) => { const id = requestId++; const onMessage2 = (type, payload2) => { if (payload2.id !== id) { return; } switch (type) { case "done": WorkerBody.removeEventListener(onMessage2); resolve(payload2.result); break; case "error": WorkerBody.removeEventListener(onMessage2); reject(payload2.error); break; default: } }; WorkerBody.addEventListener(onMessage2); const payload = { id, input: arrayBuffer, options: options2 }; WorkerBody.postMessage("process", payload); }); } // dist/lib/worker-api/validate-worker-version.js function validateWorkerVersion(worker, coreVersion = VERSION) { assert(worker, "no worker provided"); const workerVersion = worker.version; if (!coreVersion || !workerVersion) { return false; } return true; } // dist/lib/library-utils/library-utils.js var loadLibraryPromises = {}; async function loadLibrary(libraryUrl, moduleName = null, options2 = {}, libraryName = null) { if (moduleName) { libraryUrl = getLibraryUrl(libraryUrl, moduleName, options2, libraryName); } loadLibraryPromises[libraryUrl] = // eslint-disable-next-line @typescript-eslint/no-misused-promises loadLibraryPromises[libraryUrl] || loadLibraryFromFile(libraryUrl); return await loadLibraryPromises[libraryUrl]; } function getLibraryUrl(library, moduleName, options2 = {}, libraryName = null) { if (!options2.useLocalLibraries && library.startsWith("http")) { return library; } libraryName = libraryName || library; const modules = options2.modules || {}; if (modules[libraryName]) { return modules[libraryName]; } if (!isBrowser) { return `modules/${moduleName}/dist/libs/${libraryName}`; } if (options2.CDN) { assert(options2.CDN.startsWith("http")); return `${options2.CDN}/${moduleName}@${VERSION}/dist/libs/${libraryName}`; } if (isWorker) { return `../src/libs/${libraryName}`; } return `modules/${moduleName}/src/libs/${libraryName}`; } async function loadLibraryFromFile(libraryUrl) { if (libraryUrl.endsWith("wasm")) { return await loadAsArrayBuffer(libraryUrl); } if (!isBrowser) { try { const { requireFromFile } = globalThis.loaders || {}; return await (requireFromFile == null ? void 0 : requireFromFile(libraryUrl)); } catch (error) { console.error(error); return null; } } if (isWorker) { return importScripts(libraryUrl); } const scriptSource = await loadAsText(libraryUrl); return loadLibraryFromString(scriptSource, libraryUrl); } function loadLibraryFromString(scriptSource, id) { if (!isBrowser) { const { requireFromString } = globalThis.loaders || {}; return requireFromString == null ? void 0 : requireFromString(scriptSource, id); } if (isWorker) { eval.call(globalThis, scriptSource); return null; } const script = document.createElement("script"); script.id = id; try { script.appendChild(document.createTextNode(scriptSource)); } catch (e) { script.text = scriptSource; } document.body.appendChild(script); return null; } async function loadAsArrayBuffer(url) { const { readFileAsArrayBuffer } = globalThis.loaders || {}; if (isBrowser || !readFileAsArrayBuffer || url.startsWith("http")) { const response = await fetch(url); return await response.arrayBuffer(); } return await readFileAsArrayBuffer(url); } async function loadAsText(url) { const { readFileAsText } = globalThis.loaders || {}; if (isBrowser || !readFileAsText || url.startsWith("http")) { const response = await fetch(url); return await response.text(); } return await readFileAsText(url); } // dist/lib/process-utils/child-process-proxy.js var ChildProcess2 = __toESM(require("child_process"), 1); // dist/lib/process-utils/process-utils.js var import_child_process = __toESM(require("child_process"), 1); function getAvailablePort(defaultPort = 3e3) { return new Promise((resolve) => { import_child_process.default.exec("lsof -i -P -n | grep LISTEN", (error, stdout) => { if (error) { resolve(defaultPort); return; } const portsInUse = []; const regex = /:(\d+) \(LISTEN\)/; stdout.split("\n").forEach((line) => { const match = regex.exec(line); if (match) { portsInUse.push(Number(match[1])); } }); let port = defaultPort; while (portsInUse.includes(port)) { port++; } resolve(port); }); }); } // dist/lib/process-utils/child-process-proxy.js var DEFAULT_PROPS2 = { command: "", arguments: [], port: 5e3, autoPort: true, wait: 2e3, onSuccess: (processProxy) => { console.log(`Started ${processProxy.props.command}`); } }; var ChildProcessProxy = class { id; props = { ...DEFAULT_PROPS2 }; childProcess = null; port = 0; successTimer; // NodeJS.Timeout; // constructor(props?: {id?: string}); constructor({ id = "browser-driver" } = {}) { this.id = id; } /** Starts a child process with the provided props */ async start(props) { props = { ...DEFAULT_PROPS2, ...props }; this.props = props; const args = [...props.arguments]; this.port = Number(props.port); if (props.portArg) { if (props.autoPort) { this.port = await getAvailablePort(props.port); } args.push(props.portArg, String(this.port)); } return await new Promise((resolve, reject) => { try { this._setTimeout(() => { if (props.onSuccess) { props.onSuccess(this); } resolve({}); }); console.log(`Spawning ${props.command} ${props.arguments.join(" ")}`); const childProcess = ChildProcess2.spawn(props.command, args, props.spawn); this.childProcess = childProcess; childProcess.stdout.on("data", (data) => { console.log(data.toString()); }); childProcess.stderr.on("data", (data) => { console.log(`Child process wrote to stderr: "${data}".`); if (!props.ignoreStderr) { this._clearTimeout(); reject(new Error(data)); } }); childProcess.on("error", (error) => { console.log(`Child process errored with ${error}`); this._clearTimeout(); reject(error); }); childProcess.on("close", (code) => { console.log(`Child process exited with ${code}`); this.childProcess = null; this._clearTimeout(); resolve({}); }); } catch (error) { reject(error); } }); } /** Stops a running child process */ async stop() { if (this.childProcess) { this.childProcess.kill(); this.childProcess = null; } } /** Exits this process */ async exit(statusCode = 0) { try { await this.stop(); process.exit(statusCode); } catch (error) { console.error(error.message || error); process.exit(1); } } _setTimeout(callback) { if (Number(this.props.wait) > 0) { this.successTimer = setTimeout(callback, this.props.wait); } } _clearTimeout() { if (this.successTimer) { clearTimeout(this.successTimer); } } }; // dist/index.js var NullWorker = { id: "null", name: "null", module: "worker-utils", version: VERSION, options: { null: {} } }; //# sourceMappingURL=index.cjs.map