import { Worker, WorkerOptions } from 'node:worker_threads'; import msgFacade, { MappedMsgFacade, MsgFacade } from 'msg-facade'; import { SpawnedWorker } from './types.js'; const handleSpawn = async (filename: string | URL, workerOptions: WorkerOptions, getFacade: (worker: Worker) => Promise>) => { const worker = new Worker(filename, { execArgv: process.execArgv, ...(workerOptions || {}) }); let terminated = false; const facade = await getFacade(worker); const { promise, ...facadeRest } = facade; const callObj = facadeRest as unknown as MappedMsgFacade; const exit = promise.then( (code: number) => new Promise((resolve, reject) => { if (code !== 0 && !terminated) { reject(new Error(`Worker stopped with exit code ${code}`) as any); } else { resolve(code); } }) ); const terminate = () => { terminated = true; worker.terminate(); return promise; }; return { ...callObj, exit, terminate }; }; export const spawn = (filename: string | URL, workerOptions?: WorkerOptions): Promise> => { return handleSpawn(filename, workerOptions, (worker) => msgFacade.obtain(worker, msgFacade.configs.workers)); }; export const spawnBidirectional = async ( exposeObj: ParentT, filename: string | URL, workerOptions?: WorkerOptions ) => { return handleSpawn(filename, workerOptions, (worker) => msgFacade.bidirectional(exposeObj, worker, msgFacade.configs.workers) ); };