@offmain/workerkit 0.12.2 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -149,7 +149,7 @@ self.addEventListener('message', async (event) => {
149
149
  self.postMessage({ ok: false, error: err instanceof Error ? err.message : String(err) });
150
150
  }
151
151
  });
152
- `;var w=(n=>(n.Default="default",n.Pipeline="pipeline",n.Persistent="persistent",n))(w||{});const M=Object.freeze({persistent:W,pipeline:P,default:m});class h{constructor(e,r){k(this,"_worker");if(r!=null&&r.workerURL)this._worker=new Worker(r.workerURL,{type:"module"});else if(e){const o=(r==null?void 0:r.mode)??"default",a=M[o](e.toString()),i=new Blob([a],{type:"application/javascript"});this._worker=new Worker(URL.createObjectURL(i))}else throw new Error("Either workerFunction or options.workerURL must be provided to WorkerFactory.")}get getWorker(){return this._worker}}class b{constructor(e){this.results=e}}function g(n,e=new Set){return n===null||typeof n!="object"?[]:e.has(n)?[]:(e.add(n),n instanceof ArrayBuffer||n instanceof MessagePort||typeof ImageBitmap<"u"&&n instanceof ImageBitmap||typeof OffscreenCanvas<"u"&&n instanceof OffscreenCanvas?[n]:ArrayBuffer.isView(n)?[n.buffer]:Array.isArray(n)?n.flatMap(r=>g(r,e)):Object.values(n).flatMap(r=>g(r,e)))}class E{constructor(e){k(this,"_workers");k(this,"_threads");k(this,"_persistentWorkers",new Map);this._workers=e.workers,this._threads=navigator.hardwareConcurrency}initWorker(e){return new h(e.func,{workerURL:e.workerURL})}partitionArray(e,r){if(!e.length)return[];if(r<=0)throw new Error("numChunks must be positive");const o=Math.min(r,e.length),a=Math.floor(e.length/o),i=e.length%o,l=[];let f=0;for(let t=0;t<o;t++){const s=a+(t<i?1:0);l.push(e.slice(f,f+s)),f+=s}return l}findWorkerByName(e){return this._workers.find(r=>r.name===e)}async runWorker(e,{srcData:r,...o}){const a=this.findWorkerByName(e);if(!a)return Promise.reject(new Error(`Worker "${e}" not found`));const i=a.maxConcurrency??this._threads,l=!!(Array.isArray(r)&&r.length>1&&a.partition),f=l?this.partitionArray(r,i):r,t=this.createWorkerPromises(a,e,{data:f,...o},i,l),s=await Promise.allSettled(t);return new b(s)}createWorkerPromises(e,r,o,a,i){const{data:l,...f}=o;return Array.from({length:a},(t,s)=>{const u=i&&Array.isArray(l)?l[s]:l;return this.runWorkerWithRetry({workerFunc:e.func,workerURL:e.workerURL,workerName:r,index:s,data:{data:u,...f}},e.retries)})}async runWorkerWithRetry(e,r=2){try{return await this.initiateWorker(e)}catch(o){if(r>0)return console.error(`Worker ${e.index} failed, retrying (${r} left):`,o),this.runWorkerWithRetry(e,r-1);throw console.error("Worker failed after all retries:",o),o}}initiateWorker({workerFunc:e,workerURL:r,workerName:o,index:a,data:i}){return new Promise((l,f)=>{const s=this.initWorker({name:o,role:"",func:e,workerURL:r}).getWorker;s.onerror=c=>{s.terminate(),f({index:a,workerConfigs:{workerFunc:e,workerName:o,index:a,data:i},failedResult:c})},s.onmessage=c=>{var d,p;if(((d=c.data)==null?void 0:d.ok)===!1){s.terminate(),f({index:a,workerConfigs:{workerFunc:e,workerName:o,index:a,data:i},failedResult:new ErrorEvent("error",{message:c.data.error})});return}l({index:a,workerConfigs:{workerFunc:e,workerName:o,index:a,data:i},successResult:new MessageEvent("message",{data:(p=c.data)==null?void 0:p.data})}),s.terminate()};const u={index:a,...Array.isArray(i)?{data:i}:i};s.postMessage(u,g(u))})}async collectResults(e,r={}){const o=e.results.filter(t=>t.status==="fulfilled"),a=e.results.filter(t=>t.status==="rejected"),i=o.map(t=>t.value.successResult.data),l=r.reducer?r.reducer.toString():"(shards) => shards.flat()";return{data:await new Promise((t,s)=>{const u=`
152
+ `;var w=(n=>(n.Default="default",n.Pipeline="pipeline",n.Persistent="persistent",n))(w||{});const M=Object.freeze({persistent:W,pipeline:P,default:m});class h{constructor(e,r){k(this,"_worker");if(r!=null&&r.workerInstance)this._worker=r.workerInstance;else if(r!=null&&r.workerURL)this._worker=new Worker(r.workerURL,{type:"module"});else if(e){const o=(r==null?void 0:r.mode)??"default",a=M[o](e.toString()),i=new Blob([a],{type:"application/javascript"});this._worker=new Worker(URL.createObjectURL(i))}else throw new Error("Either workerFunction or options.workerURL must be provided to WorkerFactory.")}get getWorker(){return this._worker}}class b{constructor(e){this.results=e}}function g(n,e=new Set){return n===null||typeof n!="object"?[]:e.has(n)?[]:(e.add(n),n instanceof ArrayBuffer||n instanceof MessagePort||typeof ImageBitmap<"u"&&n instanceof ImageBitmap||typeof OffscreenCanvas<"u"&&n instanceof OffscreenCanvas?[n]:ArrayBuffer.isView(n)?[n.buffer]:Array.isArray(n)?n.flatMap(r=>g(r,e)):Object.values(n).flatMap(r=>g(r,e)))}class E{constructor(e){k(this,"_workers");k(this,"_threads");k(this,"_persistentWorkers",new Map);this._workers=e.workers,this._threads=navigator.hardwareConcurrency}initWorker(e){return new h(e.func,{workerURL:e.workerURL})}partitionArray(e,r){if(!e.length)return[];if(r<=0)throw new Error("numChunks must be positive");const o=Math.min(r,e.length),a=Math.floor(e.length/o),i=e.length%o,l=[];let f=0;for(let t=0;t<o;t++){const s=a+(t<i?1:0);l.push(e.slice(f,f+s)),f+=s}return l}findWorkerByName(e){return this._workers.find(r=>r.name===e)}async runWorker(e,{srcData:r,...o}){const a=this.findWorkerByName(e);if(!a)return Promise.reject(new Error(`Worker "${e}" not found`));const i=a.maxConcurrency??this._threads,l=!!(Array.isArray(r)&&r.length>1&&a.partition),f=l?this.partitionArray(r,i):r,t=this.createWorkerPromises(a,e,{data:f,...o},i,l),s=await Promise.allSettled(t);return new b(s)}createWorkerPromises(e,r,o,a,i){const{data:l,...f}=o;return Array.from({length:a},(t,s)=>{const u=i&&Array.isArray(l)?l[s]:l;return this.runWorkerWithRetry({workerFunc:e.func,workerURL:e.workerURL,workerName:r,index:s,data:{data:u,...f}},e.retries)})}async runWorkerWithRetry(e,r=2){try{return await this.initiateWorker(e)}catch(o){if(r>0)return console.error(`Worker ${e.index} failed, retrying (${r} left):`,o),this.runWorkerWithRetry(e,r-1);throw console.error("Worker failed after all retries:",o),o}}initiateWorker({workerFunc:e,workerURL:r,workerName:o,index:a,data:i}){return new Promise((l,f)=>{const s=this.initWorker({name:o,role:"",func:e,workerURL:r}).getWorker;s.onerror=c=>{s.terminate(),f({index:a,workerConfigs:{workerFunc:e,workerName:o,index:a,data:i},failedResult:c})},s.onmessage=c=>{var d,p;if(((d=c.data)==null?void 0:d.ok)===!1){s.terminate(),f({index:a,workerConfigs:{workerFunc:e,workerName:o,index:a,data:i},failedResult:new ErrorEvent("error",{message:c.data.error})});return}l({index:a,workerConfigs:{workerFunc:e,workerName:o,index:a,data:i},successResult:new MessageEvent("message",{data:(p=c.data)==null?void 0:p.data})}),s.terminate()};const u={index:a,...Array.isArray(i)?{data:i}:i};s.postMessage(u,g(u))})}async collectResults(e,r={}){const o=e.results.filter(t=>t.status==="fulfilled"),a=e.results.filter(t=>t.status==="rejected"),i=o.map(t=>t.value.successResult.data),l=r.reducer?r.reducer.toString():"(shards) => shards.flat()";return{data:await new Promise((t,s)=>{const u=`
153
153
  const reducer = ${l};
154
154
  self.addEventListener('message', (event) => {
155
155
  try {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var v = Object.defineProperty;
2
2
  var m = (n, e, r) => e in n ? v(n, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : n[e] = r;
3
- var h = (n, e, r) => m(n, typeof e != "symbol" ? e + "" : e, r);
3
+ var k = (n, e, r) => m(n, typeof e != "symbol" ? e + "" : e, r);
4
4
  const y = (n) => `
5
5
  const extractTransferables = (value, seen = new Set()) => {
6
6
  if (value === null || typeof value !== 'object') return [];
@@ -159,7 +159,7 @@ const M = Object.freeze({
159
159
  pipeline: P,
160
160
  default: y
161
161
  });
162
- class k {
162
+ class h {
163
163
  /**
164
164
  * Creates a new `Worker` from the given function.
165
165
  *
@@ -173,8 +173,10 @@ class k {
173
173
  * worker execution mode (default, pipeline, or persistent).
174
174
  */
175
175
  constructor(e, r) {
176
- h(this, "_worker");
177
- if (r != null && r.workerURL)
176
+ k(this, "_worker");
177
+ if (r != null && r.workerInstance)
178
+ this._worker = r.workerInstance;
179
+ else if (r != null && r.workerURL)
178
180
  this._worker = new Worker(r.workerURL, { type: "module" });
179
181
  else if (e) {
180
182
  const o = (r == null ? void 0 : r.mode) ?? "default", a = M[o](e.toString()), i = new Blob([a], {
@@ -206,16 +208,16 @@ function g(n, e = /* @__PURE__ */ new Set()) {
206
208
  (r) => g(r, e)
207
209
  ));
208
210
  }
209
- class A {
211
+ class _ {
210
212
  /**
211
213
  * Creates a new `MainWorkerFactory`.
212
214
  *
213
215
  * @param options - Configuration object containing the `workers` registry.
214
216
  */
215
217
  constructor(e) {
216
- h(this, "_workers");
217
- h(this, "_threads");
218
- h(this, "_persistentWorkers", /* @__PURE__ */ new Map());
218
+ k(this, "_workers");
219
+ k(this, "_threads");
220
+ k(this, "_persistentWorkers", /* @__PURE__ */ new Map());
219
221
  this._workers = e.workers, this._threads = navigator.hardwareConcurrency;
220
222
  }
221
223
  /**
@@ -225,7 +227,7 @@ class A {
225
227
  * @returns A new `WorkerFactory` wrapping the worker.
226
228
  */
227
229
  initWorker(e) {
228
- return new k(e.func, {
230
+ return new h(e.func, {
229
231
  workerURL: e.workerURL
230
232
  });
231
233
  }
@@ -543,7 +545,7 @@ class A {
543
545
  o(new Error(`Worker "${t.worker}" not found`));
544
546
  return;
545
547
  }
546
- const u = new k(s.func, {
548
+ const u = new h(s.func, {
547
549
  mode: w.Pipeline,
548
550
  workerURL: s.workerURL
549
551
  });
@@ -610,7 +612,7 @@ class A {
610
612
  const o = this.findWorkerByName(e);
611
613
  if (!o) throw new Error(`Worker "${e}" not found`);
612
614
  let a = this._persistentWorkers.get(e);
613
- return a || (a = new k(o.func, {
615
+ return a || (a = new h(o.func, {
614
616
  mode: w.Persistent,
615
617
  workerURL: o.workerURL
616
618
  }).getWorker, this._persistentWorkers.set(e, a)), new Promise((i, f) => {
@@ -642,6 +644,6 @@ class A {
642
644
  }
643
645
  }
644
646
  export {
645
- A as MainWorkerFactory,
646
- k as WorkerFactory
647
+ _ as MainWorkerFactory,
648
+ h as WorkerFactory
647
649
  };
@@ -7,6 +7,8 @@ export declare enum WorkerMode {
7
7
  export interface WorkerFactoryOptions {
8
8
  /** The worker execution mode. Defaults to `WorkerMode.Default`. */
9
9
  mode?: WorkerMode;
10
+ /** The worker instance to use instead of creating a worker from a function. */
11
+ workerInstance?: Worker;
10
12
  /** The worker URL to use instead of creating a worker from a function. */
11
13
  workerURL?: string | URL;
12
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@offmain/workerkit",
3
- "version": "0.12.2",
3
+ "version": "0.12.3",
4
4
  "description": "A lightweight manager for running functions in Web Workers with partitioning, retries, and concurrency control",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",