{"version":3,"file":"pool.cjs","sources":["../../src/pool.ts"],"sourcesContent":["import { defer } from \"@vibrant/types\";\nimport type { Defer } from \"@vibrant/types\";\n\nimport type {\n\tTaskWorker,\n\tTaskWorkerClass,\n\tWorkerErrorResponse,\n\tWorkerRequest,\n\tWorkerResponse,\n} from \"./common\";\n\ninterface Task<R> extends WorkerRequest {\n\tdeferred: Defer<R>;\n}\n\n// const WorkerClass: TaskWorkerClass = require('worker-loader?inline=true!./worker')\n\nconst MAX_WORKER_COUNT = 5;\n\n/**\n * @private\n */\nexport class WorkerPool {\n\tprivate _taskId = 0;\n\n\tprivate _workers: TaskWorker[] = [];\n\tprivate _queue: Task<{}>[] = [];\n\tprivate _executing: { [id: number]: Task<{}> } = {};\n\n\tconstructor(public WorkerClass: TaskWorkerClass) {}\n\n\tprivate _findIdleWorker(): TaskWorker | undefined {\n\t\tlet worker: TaskWorker | undefined;\n\t\t// if no idle worker && worker count < max count, make new one\n\t\tif (this._workers.length === 0 || this._workers.length < MAX_WORKER_COUNT) {\n\t\t\tworker = new this.WorkerClass();\n\t\t\tworker.id = this._workers.length;\n\t\t\tworker.idle = true;\n\t\t\tthis._workers.push(worker);\n\t\t\tworker.onmessage = this._onMessage.bind(this, worker.id);\n\t\t} else {\n\t\t\tworker = this._workers.find(({ idle }) => idle);\n\t\t}\n\n\t\treturn worker;\n\t}\n\n\tprivate _enqueue<R>(payload: any[], transferList?: any[]): Promise<R> {\n\t\tconst d = defer<R>();\n\n\t\t// make task item\n\t\tconst task: Task<R> = {\n\t\t\tid: this._taskId++,\n\t\t\tpayload,\n\t\t\ttransferList,\n\t\t\tdeferred: d,\n\t\t};\n\t\tthis._queue.push(task as never);\n\n\t\t// Try dequeue\n\t\tthis._tryDequeue();\n\n\t\treturn d.promise;\n\t}\n\n\tprivate _tryDequeue() {\n\t\t// Called when a work has finished or from _enqueue\n\n\t\t// No pending task\n\t\tif (this._queue.length <= 0) return;\n\n\t\t// Find idle worker\n\t\tconst worker = this._findIdleWorker();\n\t\t// No idle worker\n\t\tif (!worker) return;\n\n\t\t// Dequeue task\n\t\tconst task = this._queue.shift()!;\n\t\tthis._executing[task.id] = task;\n\n\t\t// Send payload\n\t\tconst transfers = task.transferList;\n\t\tconst { deferred, transferList, ...request } = task;\n\t\tworker.postMessage(request, transfers as any[]);\n\t\tworker.idle = false;\n\t}\n\tprivate _onMessage(workerId: number, event: MessageEvent) {\n\t\tconst data: WorkerResponse<{}> | WorkerErrorResponse | undefined =\n\t\t\tevent.data;\n\t\tif (!data) return;\n\t\t// Worker should send result along with payload id\n\t\tconst { id } = data;\n\t\t// Task is looked up by id\n\t\tconst task = this._executing[id];\n\t\tif (!task) return;\n\t\tdelete this._executing[id];\n\n\t\t// Resolve or reject deferred promise\n\t\tswitch (data.type) {\n\t\t\tcase \"return\":\n\t\t\t\ttask.deferred.resolve(data.payload);\n\t\t\t\tbreak;\n\t\t\tcase \"error\":\n\t\t\t\ttask.deferred.reject(new Error(data.payload));\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst worker = this._workers[workerId];\n\t\tif (!worker) return;\n\n\t\t// Update worker status\n\t\tworker.idle = true;\n\t\t// Try dequeue next task\n\t\tthis._tryDequeue();\n\t}\n\tinvoke<R>(args: any[], transferList?: any[]): Promise<R> {\n\t\treturn this._enqueue(args, transferList);\n\t}\n}\n"],"names":["defer"],"mappings":";;;AAiBA,MAAM,mBAAmB;AAKlB,MAAM,WAAW;AAAA,EAOvB,YAAmB,aAA8B;AAA9B,SAAA,cAAA;AANnB,SAAQ,UAAU;AAElB,SAAQ,WAAyB,CAAA;AACjC,SAAQ,SAAqB,CAAA;AAC7B,SAAQ,aAAyC,CAAA;AAAA,EAEC;AAAA,EAE1C,kBAA0C;AACjD,QAAI;AAEJ,QAAI,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,SAAS,kBAAkB;AAC1E,eAAS,IAAI,KAAK,YAAA;AAClB,aAAO,KAAK,KAAK,SAAS;AAC1B,aAAO,OAAO;AACd,WAAK,SAAS,KAAK,MAAM;AACzB,aAAO,YAAY,KAAK,WAAW,KAAK,MAAM,OAAO,EAAE;AAAA,IACxD,OAAO;AACN,eAAS,KAAK,SAAS,KAAK,CAAC,EAAE,KAAA,MAAW,IAAI;AAAA,IAC/C;AAEA,WAAO;AAAA,EACR;AAAA,EAEQ,SAAY,SAAgB,cAAkC;AACrE,UAAM,IAAIA,MAAAA,MAAA;AAGV,UAAM,OAAgB;AAAA,MACrB,IAAI,KAAK;AAAA,MACT;AAAA,MACA;AAAA,MACA,UAAU;AAAA,IAAA;AAEX,SAAK,OAAO,KAAK,IAAa;AAG9B,SAAK,YAAA;AAEL,WAAO,EAAE;AAAA,EACV;AAAA,EAEQ,cAAc;AAIrB,QAAI,KAAK,OAAO,UAAU,EAAG;AAG7B,UAAM,SAAS,KAAK,gBAAA;AAEpB,QAAI,CAAC,OAAQ;AAGb,UAAM,OAAO,KAAK,OAAO,MAAA;AACzB,SAAK,WAAW,KAAK,EAAE,IAAI;AAG3B,UAAM,YAAY,KAAK;AACvB,UAAM,EAAE,UAAU,cAAc,GAAG,YAAY;AAC/C,WAAO,YAAY,SAAS,SAAkB;AAC9C,WAAO,OAAO;AAAA,EACf;AAAA,EACQ,WAAW,UAAkB,OAAqB;AACzD,UAAM,OACL,MAAM;AACP,QAAI,CAAC,KAAM;AAEX,UAAM,EAAE,OAAO;AAEf,UAAM,OAAO,KAAK,WAAW,EAAE;AAC/B,QAAI,CAAC,KAAM;AACX,WAAO,KAAK,WAAW,EAAE;AAGzB,YAAQ,KAAK,MAAA;AAAA,MACZ,KAAK;AACJ,aAAK,SAAS,QAAQ,KAAK,OAAO;AAClC;AAAA,MACD,KAAK;AACJ,aAAK,SAAS,OAAO,IAAI,MAAM,KAAK,OAAO,CAAC;AAC5C;AAAA,IAAA;AAGF,UAAM,SAAS,KAAK,SAAS,QAAQ;AACrC,QAAI,CAAC,OAAQ;AAGb,WAAO,OAAO;AAEd,SAAK,YAAA;AAAA,EACN;AAAA,EACA,OAAU,MAAa,cAAkC;AACxD,WAAO,KAAK,SAAS,MAAM,YAAY;AAAA,EACxC;AACD;;"}