@offmain/workerkit 0.12.3 → 0.13.0
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/README.md +21 -15
- package/dist/index.cjs +6 -6
- package/dist/index.js +200 -105
- package/dist/types/tools/main-worker-factory/main-worker-factory.d.ts +39 -6
- package/dist/types/tools/main-worker-factory/types.d.ts +8 -7
- package/dist/types/tools/worker-factory/worker-factory.d.ts +4 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,23 +57,23 @@ console.log(data); // [15]
|
|
|
57
57
|
|
|
58
58
|
## WorkerConfig Options
|
|
59
59
|
|
|
60
|
-
| Option | Type
|
|
61
|
-
| ---------------- |
|
|
62
|
-
| `name` | `string`
|
|
63
|
-
| `role` | `string`
|
|
64
|
-
| `func` | `Function`
|
|
65
|
-
| `
|
|
66
|
-
| `maxConcurrency` | `number`
|
|
67
|
-
| `retries` | `number`
|
|
68
|
-
| `partition` | `boolean`
|
|
60
|
+
| Option | Type | Default | Description |
|
|
61
|
+
| ---------------- | -------------- | ------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
62
|
+
| `name` | `string` | — | Unique identifier used to call the worker |
|
|
63
|
+
| `role` | `string` | — | Logical grouping label |
|
|
64
|
+
| `func` | `Function` | — | The exported worker function to run (optional if `createWorker` is provided) |
|
|
65
|
+
| `createWorker` | `() => Worker` | — | Worker factory function `() => new Worker(new URL(...))` for Webpack 5 / Vite static analysis |
|
|
66
|
+
| `maxConcurrency` | `number` | `navigator.hardwareConcurrency` | Max parallel worker instances — defaults to the number of logical CPU cores reported by the browser |
|
|
67
|
+
| `retries` | `number` | `0` | How many times to retry a failed shard before marking it as rejected |
|
|
68
|
+
| `partition` | `boolean` | `false` | Split array input across multiple workers automatically |
|
|
69
69
|
|
|
70
70
|
---
|
|
71
71
|
|
|
72
|
-
## Module Bundler Integration (`
|
|
72
|
+
## Module Bundler Integration (`createWorker`)
|
|
73
73
|
|
|
74
74
|
When worker logic relies on external npm packages (such as Luxon, `date-fns`, `i18next`, or custom data transformation modules), dynamic inline stringification (`.toString()`) cannot access those closed-over imports.
|
|
75
75
|
|
|
76
|
-
Passing `
|
|
76
|
+
Passing `createWorker` enables modern module bundlers (Webpack 5, Vite, Rollup, Parcel) to analyze and bundle the worker file along with all of its dependencies into a dedicated ES module worker chunk.
|
|
77
77
|
|
|
78
78
|
### Dedicated Worker Script
|
|
79
79
|
|
|
@@ -98,7 +98,9 @@ self.addEventListener('message', (event) => {
|
|
|
98
98
|
});
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
###
|
|
101
|
+
### Webpack 5 & Vite Static Analysis (`createWorker`)
|
|
102
|
+
|
|
103
|
+
Webpack 5 and Vite look for literal `new Worker(new URL(..., import.meta.url))` calls inside consumer source files. By providing a `createWorker` factory function, bundlers statically detect and bundle the worker into a separate JS file, while allowing `MainWorkerFactory` to scale `maxConcurrency` across multiple threads:
|
|
102
104
|
|
|
103
105
|
```ts
|
|
104
106
|
import { MainWorkerFactory } from '@offmain/workerkit';
|
|
@@ -108,9 +110,13 @@ const factory = new MainWorkerFactory({
|
|
|
108
110
|
{
|
|
109
111
|
name: 'transformData',
|
|
110
112
|
role: 'compute',
|
|
111
|
-
// Webpack 5
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
// Webpack 5 and Vite statically analyze new Worker(new URL(..., import.meta.url))
|
|
114
|
+
// written inside this factory function and emit an individual bundled JS chunk.
|
|
115
|
+
createWorker: () =>
|
|
116
|
+
new Worker(new URL('./transform-data.worker.ts', import.meta.url), {
|
|
117
|
+
type: 'module',
|
|
118
|
+
}),
|
|
119
|
+
maxConcurrency: 4, // Spawns up to 4 parallel worker instances
|
|
114
120
|
},
|
|
115
121
|
] as const,
|
|
116
122
|
});
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var y=Object.defineProperty;var w=(n,e,r)=>e in n?y(n,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):n[e]=r;var h=(n,e,r)=>w(n,typeof e!="symbol"?e+"":e,r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=n=>`
|
|
2
2
|
const extractTransferables = (value, seen = new Set()) => {
|
|
3
3
|
if (value === null || typeof value !== 'object') return [];
|
|
4
4
|
if (seen.has(value)) return [];
|
|
@@ -21,7 +21,7 @@ self.addEventListener('message', async (event) => {
|
|
|
21
21
|
self.postMessage({ ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
22
22
|
}
|
|
23
23
|
})
|
|
24
|
-
`,
|
|
24
|
+
`,W=n=>`
|
|
25
25
|
const extractTransferables = (value, seen = new Set()) => {
|
|
26
26
|
if (value === null || typeof value !== 'object') return [];
|
|
27
27
|
if (seen.has(value)) return [];
|
|
@@ -93,7 +93,7 @@ self.addEventListener('message', (event) => {
|
|
|
93
93
|
pendingData = event.data;
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
|
-
`,
|
|
96
|
+
`,M=n=>`
|
|
97
97
|
const extractTransferables = (value, seen = new Set()) => {
|
|
98
98
|
if (value === null || typeof value !== 'object') return [];
|
|
99
99
|
if (seen.has(value)) return [];
|
|
@@ -149,8 +149,8 @@ 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
|
|
153
|
-
const reducer = ${
|
|
152
|
+
`;var m=(n=>(n.Default="default",n.Pipeline="pipeline",n.Persistent="persistent",n))(m||{});const P=Object.freeze({persistent:M,pipeline:W,default:v});class g{constructor(e,r){h(this,"_worker");if(r!=null&&r.createWorker)this._worker=r.createWorker();else if(e){const o=(r==null?void 0:r.mode)??"default",a=P[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.createWorker must be provided to WorkerFactory.")}get getWorker(){return this._worker}}class b{constructor(e){this.results=e}}function k(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=>k(r,e)):Object.values(n).flatMap(r=>k(r,e)))}class _{constructor(e){h(this,"_workers");h(this,"_threads");h(this,"_persistentWorkers",new Map);h(this,"_activeWorkers",new Set);h(this,"_isTerminated",!1);this._workers=e.workers,this._threads=navigator.hardwareConcurrency}get isTerminated(){return this._isTerminated}trackWorker(e){if(this._isTerminated)throw e.terminate(),new Error("MainWorkerFactory has been terminated");return this._activeWorkers.add(e),e}terminateWorker(e){this._activeWorkers.delete(e);try{e.terminate()}catch{}}initWorker(e){const r=new g(e.func,{createWorker:e.createWorker});return this.trackWorker(r.getWorker),r}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,c=[];let u=0;for(let t=0;t<o;t++){const s=a+(t<i?1:0);c.push(e.slice(u,u+s)),u+=s}return c}findWorkerByName(e){return this._workers.find(r=>r.name===e)}async runWorker(e,{srcData:r,...o}){if(this._isTerminated)return Promise.reject(new Error("MainWorkerFactory has been terminated"));const a=this.findWorkerByName(e);if(!a)return Promise.reject(new Error(`Worker "${e}" not found`));const i=a.maxConcurrency??this._threads,c=!!(Array.isArray(r)&&r.length>1&&a.partition),u=c?this.partitionArray(r,i):r,t=this.createWorkerPromises(a,e,{data:u,...o},i,c),s=await Promise.allSettled(t);return new b(s)}createWorkerPromises(e,r,o,a,i){const{data:c,...u}=o;return Array.from({length:a},(t,s)=>{const f=i&&Array.isArray(c)?c[s]:c;return this.runWorkerWithRetry({workerFunc:e.func,createWorker:e.createWorker,workerName:r,index:s,data:{data:f,...u}},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,createWorker:r,workerName:o,index:a,data:i}){return new Promise((c,u)=>{const s=this.initWorker({name:o,role:"",func:e,createWorker:r}).getWorker;s.onerror=l=>{this.terminateWorker(s),u({index:a,workerConfigs:{workerFunc:e,createWorker:r,workerName:o,index:a,data:i},failedResult:l})},s.onmessage=l=>{var d,p;if(((d=l.data)==null?void 0:d.ok)===!1){this.terminateWorker(s),u({index:a,workerConfigs:{workerFunc:e,createWorker:r,workerName:o,index:a,data:i},failedResult:new ErrorEvent("error",{message:l.data.error})});return}c({index:a,workerConfigs:{workerFunc:e,createWorker:r,workerName:o,index:a,data:i},successResult:new MessageEvent("message",{data:(p=l.data)==null?void 0:p.data})}),this.terminateWorker(s)};const f={index:a,...Array.isArray(i)?{data:i}:i};s.postMessage(f,k(f))})}async collectResults(e,r={}){if(this._isTerminated)throw new Error("MainWorkerFactory has been terminated");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),c=r.reducer?r.reducer.toString():"(shards) => shards.flat()";return{data:await new Promise((t,s)=>{const f=`
|
|
153
|
+
const reducer = ${c};
|
|
154
154
|
self.addEventListener('message', (event) => {
|
|
155
155
|
try {
|
|
156
156
|
const result = reducer(event.data);
|
|
@@ -159,4 +159,4 @@ self.addEventListener('message', async (event) => {
|
|
|
159
159
|
self.postMessage({ ok: false, error: String(err) });
|
|
160
160
|
}
|
|
161
161
|
});
|
|
162
|
-
`,
|
|
162
|
+
`,l=new Blob([f],{type:"application/javascript"}),d=this.trackWorker(new Worker(URL.createObjectURL(l)));d.onmessage=p=>{this.terminateWorker(d),p.data.ok?t(p.data.data):s(new Error(p.data.error))},d.onerror=p=>{this.terminateWorker(d),s(p)},d.postMessage(i)}),succeeded:o.length,failed:a.length,errors:a}}async pipeline(e){if(this._isTerminated)throw new Error("MainWorkerFactory has been terminated");if(e.length===0)throw new Error("Pipeline requires at least one step");if(e.length===1){const r=e[0],o=this.findWorkerByName(r.worker);if(!o)throw new Error(`Worker "${r.worker}" not found`);const i=this.initWorker(o).getWorker;return new Promise((c,u)=>{i.onmessage=s=>{var f,l;this.terminateWorker(i),((f=s.data)==null?void 0:f.ok)===!1?u(new Error(s.data.error)):c((l=s.data)==null?void 0:l.data)},i.onerror=s=>{this.terminateWorker(i),u(s)};const t=r.srcData??{};i.postMessage({data:t,index:0},k(t))})}return new Promise((r,o)=>{const a=[],i=[];for(const t of e){const s=this.findWorkerByName(t.worker);if(!s){o(new Error(`Worker "${t.worker}" not found`));return}const f=new g(s.func,{mode:m.Pipeline,createWorker:s.createWorker}),l=this.trackWorker(f.getWorker);a.push(l)}for(let t=0;t<a.length-1;t++)i.push(new MessageChannel);for(let t=0;t<a.length;t++){const s=[],f={};t>0&&(f.inputPort=i[t-1].port1,s.push(f.inputPort)),t<a.length-1&&(f.outputPort=i[t].port2,s.push(f.outputPort)),a[t].postMessage({__pipeline_ports__:!0,...f},s)}const c=a[a.length-1];c.onmessage=t=>{var s,f;a.forEach(l=>this.terminateWorker(l)),((s=t.data)==null?void 0:s.ok)===!1?o(new Error(t.data.error)):r((f=t.data)==null?void 0:f.data)},c.onerror=t=>{a.forEach(s=>this.terminateWorker(s)),o(t)};const u=e[0].srcData??{};a[0].postMessage({data:u,index:0},k(u))})}async runPersistent(e,r){if(this._isTerminated)throw new Error("MainWorkerFactory has been terminated");const o=this.findWorkerByName(e);if(!o)throw new Error(`Worker "${e}" not found`);let a=this._persistentWorkers.get(e);if(!a){const i=new g(o.func,{mode:m.Persistent,createWorker:o.createWorker});a=this.trackWorker(i.getWorker),this._persistentWorkers.set(e,a)}return new Promise((i,c)=>{a.onmessage=t=>{var s,f;((s=t.data)==null?void 0:s.ok)===!1?c(new Error(t.data.error)):i((f=t.data)==null?void 0:f.data)},a.onerror=t=>{c(t)};const u={type:"run",config:r.config};r.dataset!==void 0&&(u.dataset=r.dataset),a.postMessage(u,k(u))})}release(e){const r=this._persistentWorkers.get(e);if(r){try{r.postMessage({type:"release"})}catch{}this.terminateWorker(r),this._persistentWorkers.delete(e)}}terminate(){this._isTerminated=!0;for(const e of this._persistentWorkers.values()){try{e.postMessage({type:"release"})}catch{}this.terminateWorker(e)}this._persistentWorkers.clear();for(const e of Array.from(this._activeWorkers))this.terminateWorker(e);this._activeWorkers.clear()}destroy(){this.terminate()}reset(){this.terminate(),this._isTerminated=!1}restart(){this.reset()}}exports.MainWorkerFactory=_;exports.WorkerFactory=g;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
1
|
+
var w = Object.defineProperty;
|
|
2
|
+
var v = (n, e, r) => e in n ? w(n, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : n[e] = r;
|
|
3
|
+
var h = (n, e, r) => v(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 [];
|
|
@@ -24,7 +24,7 @@ self.addEventListener('message', async (event) => {
|
|
|
24
24
|
self.postMessage({ ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
25
25
|
}
|
|
26
26
|
})
|
|
27
|
-
`,
|
|
27
|
+
`, W = (n) => `
|
|
28
28
|
const extractTransferables = (value, seen = new Set()) => {
|
|
29
29
|
if (value === null || typeof value !== 'object') return [];
|
|
30
30
|
if (seen.has(value)) return [];
|
|
@@ -96,7 +96,7 @@ self.addEventListener('message', (event) => {
|
|
|
96
96
|
pendingData = event.data;
|
|
97
97
|
}
|
|
98
98
|
});
|
|
99
|
-
`,
|
|
99
|
+
`, M = (n) => `
|
|
100
100
|
const extractTransferables = (value, seen = new Set()) => {
|
|
101
101
|
if (value === null || typeof value !== 'object') return [];
|
|
102
102
|
if (seen.has(value)) return [];
|
|
@@ -153,39 +153,33 @@ self.addEventListener('message', async (event) => {
|
|
|
153
153
|
}
|
|
154
154
|
});
|
|
155
155
|
`;
|
|
156
|
-
var
|
|
157
|
-
const
|
|
158
|
-
persistent:
|
|
159
|
-
pipeline:
|
|
156
|
+
var m = /* @__PURE__ */ ((n) => (n.Default = "default", n.Pipeline = "pipeline", n.Persistent = "persistent", n))(m || {});
|
|
157
|
+
const P = Object.freeze({
|
|
158
|
+
persistent: M,
|
|
159
|
+
pipeline: W,
|
|
160
160
|
default: y
|
|
161
161
|
});
|
|
162
|
-
class
|
|
162
|
+
class g {
|
|
163
163
|
/**
|
|
164
|
-
* Creates a new `Worker` from the given function.
|
|
165
|
-
*
|
|
166
|
-
* The function is stringified, embedded into a self-contained worker script,
|
|
167
|
-
* converted to a `Blob` URL, and passed to the `Worker` constructor.
|
|
164
|
+
* Creates a new `Worker` from the given function or factory option.
|
|
168
165
|
*
|
|
169
166
|
* @param workerFunction - The function to run inside the worker thread.
|
|
170
167
|
* Must be self-contained — it cannot reference variables from the outer
|
|
171
168
|
* scope because it is serialized via `.toString()`.
|
|
172
|
-
* @param options - Optional configuration
|
|
173
|
-
* worker execution mode (default, pipeline, or persistent).
|
|
169
|
+
* @param options - Optional configuration containing `createWorker` or `mode`.
|
|
174
170
|
*/
|
|
175
171
|
constructor(e, r) {
|
|
176
|
-
|
|
177
|
-
if (r != null && r.
|
|
178
|
-
this._worker = r.
|
|
179
|
-
else if (r != null && r.workerURL)
|
|
180
|
-
this._worker = new Worker(r.workerURL, { type: "module" });
|
|
172
|
+
h(this, "_worker");
|
|
173
|
+
if (r != null && r.createWorker)
|
|
174
|
+
this._worker = r.createWorker();
|
|
181
175
|
else if (e) {
|
|
182
|
-
const o = (r == null ? void 0 : r.mode) ?? "default", a =
|
|
176
|
+
const o = (r == null ? void 0 : r.mode) ?? "default", a = P[o](e.toString()), i = new Blob([a], {
|
|
183
177
|
type: "application/javascript"
|
|
184
178
|
});
|
|
185
179
|
this._worker = new Worker(URL.createObjectURL(i));
|
|
186
180
|
} else
|
|
187
181
|
throw new Error(
|
|
188
|
-
"Either workerFunction or options.
|
|
182
|
+
"Either workerFunction or options.createWorker must be provided to WorkerFactory."
|
|
189
183
|
);
|
|
190
184
|
}
|
|
191
185
|
/**
|
|
@@ -203,33 +197,60 @@ class b {
|
|
|
203
197
|
this.results = e;
|
|
204
198
|
}
|
|
205
199
|
}
|
|
206
|
-
function
|
|
207
|
-
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) =>
|
|
208
|
-
(r) =>
|
|
200
|
+
function k(n, e = /* @__PURE__ */ new Set()) {
|
|
201
|
+
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) => k(r, e)) : Object.values(n).flatMap(
|
|
202
|
+
(r) => k(r, e)
|
|
209
203
|
));
|
|
210
204
|
}
|
|
211
|
-
class
|
|
205
|
+
class E {
|
|
212
206
|
/**
|
|
213
207
|
* Creates a new `MainWorkerFactory`.
|
|
214
208
|
*
|
|
215
209
|
* @param options - Configuration object containing the `workers` registry.
|
|
216
210
|
*/
|
|
217
211
|
constructor(e) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
212
|
+
h(this, "_workers");
|
|
213
|
+
h(this, "_threads");
|
|
214
|
+
h(this, "_persistentWorkers", /* @__PURE__ */ new Map());
|
|
215
|
+
h(this, "_activeWorkers", /* @__PURE__ */ new Set());
|
|
216
|
+
h(this, "_isTerminated", !1);
|
|
221
217
|
this._workers = e.workers, this._threads = navigator.hardwareConcurrency;
|
|
222
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Returns `true` if the factory has been terminated.
|
|
221
|
+
*/
|
|
222
|
+
get isTerminated() {
|
|
223
|
+
return this._isTerminated;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Registers an active worker instance for lifecycle tracking.
|
|
227
|
+
*/
|
|
228
|
+
trackWorker(e) {
|
|
229
|
+
if (this._isTerminated)
|
|
230
|
+
throw e.terminate(), new Error("MainWorkerFactory has been terminated");
|
|
231
|
+
return this._activeWorkers.add(e), e;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Terminates a worker instance and removes it from tracking.
|
|
235
|
+
*/
|
|
236
|
+
terminateWorker(e) {
|
|
237
|
+
this._activeWorkers.delete(e);
|
|
238
|
+
try {
|
|
239
|
+
e.terminate();
|
|
240
|
+
} catch {
|
|
241
|
+
}
|
|
242
|
+
}
|
|
223
243
|
/**
|
|
224
244
|
* Instantiates a {@link WorkerFactory} for the given worker configuration.
|
|
225
245
|
*
|
|
226
|
-
* @param config - The worker configuration containing `func` or `
|
|
246
|
+
* @param config - The worker configuration containing `func` or `createWorker`.
|
|
227
247
|
* @returns A new `WorkerFactory` wrapping the worker.
|
|
228
248
|
*/
|
|
229
249
|
initWorker(e) {
|
|
230
|
-
|
|
231
|
-
|
|
250
|
+
const r = new g(e.func, {
|
|
251
|
+
createWorker: e.createWorker
|
|
232
252
|
});
|
|
253
|
+
return this.trackWorker(r.getWorker), r;
|
|
233
254
|
}
|
|
234
255
|
/**
|
|
235
256
|
* Splits an array into up to `numChunks` evenly-sized sub-arrays.
|
|
@@ -250,13 +271,13 @@ class _ {
|
|
|
250
271
|
partitionArray(e, r) {
|
|
251
272
|
if (!e.length) return [];
|
|
252
273
|
if (r <= 0) throw new Error("numChunks must be positive");
|
|
253
|
-
const o = Math.min(r, e.length), a = Math.floor(e.length / o), i = e.length % o,
|
|
254
|
-
let
|
|
274
|
+
const o = Math.min(r, e.length), a = Math.floor(e.length / o), i = e.length % o, c = [];
|
|
275
|
+
let u = 0;
|
|
255
276
|
for (let t = 0; t < o; t++) {
|
|
256
277
|
const s = a + (t < i ? 1 : 0);
|
|
257
|
-
|
|
278
|
+
c.push(e.slice(u, u + s)), u += s;
|
|
258
279
|
}
|
|
259
|
-
return
|
|
280
|
+
return c;
|
|
260
281
|
}
|
|
261
282
|
/**
|
|
262
283
|
* Looks up a registered worker configuration by name.
|
|
@@ -297,15 +318,17 @@ class _ {
|
|
|
297
318
|
srcData: r,
|
|
298
319
|
...o
|
|
299
320
|
}) {
|
|
321
|
+
if (this._isTerminated)
|
|
322
|
+
return Promise.reject(new Error("MainWorkerFactory has been terminated"));
|
|
300
323
|
const a = this.findWorkerByName(e);
|
|
301
324
|
if (!a)
|
|
302
325
|
return Promise.reject(new Error(`Worker "${e}" not found`));
|
|
303
|
-
const i = a.maxConcurrency ?? this._threads,
|
|
326
|
+
const i = a.maxConcurrency ?? this._threads, c = !!(Array.isArray(r) && r.length > 1 && a.partition), u = c ? this.partitionArray(r, i) : r, t = this.createWorkerPromises(
|
|
304
327
|
a,
|
|
305
328
|
e,
|
|
306
|
-
{ data:
|
|
329
|
+
{ data: u, ...o },
|
|
307
330
|
i,
|
|
308
|
-
|
|
331
|
+
c
|
|
309
332
|
), s = await Promise.allSettled(t);
|
|
310
333
|
return new b(s);
|
|
311
334
|
}
|
|
@@ -324,16 +347,16 @@ class _ {
|
|
|
324
347
|
* @returns An array of promises, one per thread.
|
|
325
348
|
*/
|
|
326
349
|
createWorkerPromises(e, r, o, a, i) {
|
|
327
|
-
const { data:
|
|
350
|
+
const { data: c, ...u } = o;
|
|
328
351
|
return Array.from({ length: a }, (t, s) => {
|
|
329
|
-
const
|
|
352
|
+
const f = i && Array.isArray(c) ? c[s] : c;
|
|
330
353
|
return this.runWorkerWithRetry(
|
|
331
354
|
{
|
|
332
355
|
workerFunc: e.func,
|
|
333
|
-
|
|
356
|
+
createWorker: e.createWorker,
|
|
334
357
|
workerName: r,
|
|
335
358
|
index: s,
|
|
336
|
-
data: { data:
|
|
359
|
+
data: { data: f, ...u }
|
|
337
360
|
},
|
|
338
361
|
e.retries
|
|
339
362
|
);
|
|
@@ -375,57 +398,74 @@ class _ {
|
|
|
375
398
|
* Any transferable objects found in the payload are moved (not copied) to
|
|
376
399
|
* the worker via the `transfer` list of `postMessage`.
|
|
377
400
|
*
|
|
378
|
-
* The underlying `Worker` is always terminated after the
|
|
379
|
-
* whether it succeeded or failed.
|
|
401
|
+
* The underlying `Worker` is always terminated after the message completes.
|
|
380
402
|
*
|
|
381
|
-
* @param instanceConfig - Worker function,
|
|
403
|
+
* @param instanceConfig - Worker function, factory, name, shard index, and data.
|
|
382
404
|
* @returns A promise that resolves with the worker's result.
|
|
383
405
|
*/
|
|
384
406
|
initiateWorker({
|
|
385
407
|
workerFunc: e,
|
|
386
|
-
|
|
408
|
+
createWorker: r,
|
|
387
409
|
workerName: o,
|
|
388
410
|
index: a,
|
|
389
411
|
data: i
|
|
390
412
|
}) {
|
|
391
|
-
return new Promise((
|
|
413
|
+
return new Promise((c, u) => {
|
|
392
414
|
const s = this.initWorker({
|
|
393
415
|
name: o,
|
|
394
416
|
role: "",
|
|
395
417
|
func: e,
|
|
396
|
-
|
|
418
|
+
createWorker: r
|
|
397
419
|
}).getWorker;
|
|
398
|
-
s.onerror = (
|
|
399
|
-
|
|
420
|
+
s.onerror = (l) => {
|
|
421
|
+
this.terminateWorker(s), u({
|
|
400
422
|
index: a,
|
|
401
|
-
workerConfigs: {
|
|
402
|
-
|
|
423
|
+
workerConfigs: {
|
|
424
|
+
workerFunc: e,
|
|
425
|
+
createWorker: r,
|
|
426
|
+
workerName: o,
|
|
427
|
+
index: a,
|
|
428
|
+
data: i
|
|
429
|
+
},
|
|
430
|
+
failedResult: l
|
|
403
431
|
});
|
|
404
|
-
}, s.onmessage = (
|
|
432
|
+
}, s.onmessage = (l) => {
|
|
405
433
|
var d, p;
|
|
406
|
-
if (((d =
|
|
407
|
-
|
|
434
|
+
if (((d = l.data) == null ? void 0 : d.ok) === !1) {
|
|
435
|
+
this.terminateWorker(s), u({
|
|
408
436
|
index: a,
|
|
409
|
-
workerConfigs: {
|
|
437
|
+
workerConfigs: {
|
|
438
|
+
workerFunc: e,
|
|
439
|
+
createWorker: r,
|
|
440
|
+
workerName: o,
|
|
441
|
+
index: a,
|
|
442
|
+
data: i
|
|
443
|
+
},
|
|
410
444
|
failedResult: new ErrorEvent("error", {
|
|
411
|
-
message:
|
|
445
|
+
message: l.data.error
|
|
412
446
|
})
|
|
413
447
|
});
|
|
414
448
|
return;
|
|
415
449
|
}
|
|
416
|
-
|
|
450
|
+
c({
|
|
417
451
|
index: a,
|
|
418
|
-
workerConfigs: {
|
|
452
|
+
workerConfigs: {
|
|
453
|
+
workerFunc: e,
|
|
454
|
+
createWorker: r,
|
|
455
|
+
workerName: o,
|
|
456
|
+
index: a,
|
|
457
|
+
data: i
|
|
458
|
+
},
|
|
419
459
|
successResult: new MessageEvent("message", {
|
|
420
|
-
data: (p =
|
|
460
|
+
data: (p = l.data) == null ? void 0 : p.data
|
|
421
461
|
})
|
|
422
|
-
}),
|
|
462
|
+
}), this.terminateWorker(s);
|
|
423
463
|
};
|
|
424
|
-
const
|
|
464
|
+
const f = {
|
|
425
465
|
index: a,
|
|
426
466
|
...Array.isArray(i) ? { data: i } : i
|
|
427
467
|
};
|
|
428
|
-
s.postMessage(
|
|
468
|
+
s.postMessage(f, k(f));
|
|
429
469
|
});
|
|
430
470
|
}
|
|
431
471
|
/**
|
|
@@ -461,15 +501,17 @@ class _ {
|
|
|
461
501
|
* });
|
|
462
502
|
*/
|
|
463
503
|
async collectResults(e, r = {}) {
|
|
504
|
+
if (this._isTerminated)
|
|
505
|
+
throw new Error("MainWorkerFactory has been terminated");
|
|
464
506
|
const o = e.results.filter(
|
|
465
507
|
(t) => t.status === "fulfilled"
|
|
466
508
|
), a = e.results.filter(
|
|
467
509
|
(t) => t.status === "rejected"
|
|
468
|
-
), i = o.map((t) => t.value.successResult.data),
|
|
510
|
+
), i = o.map((t) => t.value.successResult.data), c = r.reducer ? r.reducer.toString() : "(shards) => shards.flat()";
|
|
469
511
|
return {
|
|
470
512
|
data: await new Promise((t, s) => {
|
|
471
|
-
const
|
|
472
|
-
const reducer = ${
|
|
513
|
+
const f = `
|
|
514
|
+
const reducer = ${c};
|
|
473
515
|
self.addEventListener('message', (event) => {
|
|
474
516
|
try {
|
|
475
517
|
const result = reducer(event.data);
|
|
@@ -478,11 +520,11 @@ class _ {
|
|
|
478
520
|
self.postMessage({ ok: false, error: String(err) });
|
|
479
521
|
}
|
|
480
522
|
});
|
|
481
|
-
`,
|
|
523
|
+
`, l = new Blob([f], { type: "application/javascript" }), d = this.trackWorker(new Worker(URL.createObjectURL(l)));
|
|
482
524
|
d.onmessage = (p) => {
|
|
483
|
-
|
|
525
|
+
this.terminateWorker(d), p.data.ok ? t(p.data.data) : s(new Error(p.data.error));
|
|
484
526
|
}, d.onerror = (p) => {
|
|
485
|
-
|
|
527
|
+
this.terminateWorker(d), s(p);
|
|
486
528
|
}, d.postMessage(i);
|
|
487
529
|
}),
|
|
488
530
|
succeeded: o.length,
|
|
@@ -517,23 +559,25 @@ class _ {
|
|
|
517
559
|
* console.log(result); // final transformed + filtered data
|
|
518
560
|
*/
|
|
519
561
|
async pipeline(e) {
|
|
562
|
+
if (this._isTerminated)
|
|
563
|
+
throw new Error("MainWorkerFactory has been terminated");
|
|
520
564
|
if (e.length === 0)
|
|
521
565
|
throw new Error("Pipeline requires at least one step");
|
|
522
566
|
if (e.length === 1) {
|
|
523
567
|
const r = e[0], o = this.findWorkerByName(r.worker);
|
|
524
568
|
if (!o) throw new Error(`Worker "${r.worker}" not found`);
|
|
525
569
|
const i = this.initWorker(o).getWorker;
|
|
526
|
-
return new Promise((
|
|
570
|
+
return new Promise((c, u) => {
|
|
527
571
|
i.onmessage = (s) => {
|
|
528
|
-
var
|
|
529
|
-
|
|
572
|
+
var f, l;
|
|
573
|
+
this.terminateWorker(i), ((f = s.data) == null ? void 0 : f.ok) === !1 ? u(new Error(s.data.error)) : c((l = s.data) == null ? void 0 : l.data);
|
|
530
574
|
}, i.onerror = (s) => {
|
|
531
|
-
|
|
575
|
+
this.terminateWorker(i), u(s);
|
|
532
576
|
};
|
|
533
577
|
const t = r.srcData ?? {};
|
|
534
578
|
i.postMessage(
|
|
535
579
|
{ data: t, index: 0 },
|
|
536
|
-
|
|
580
|
+
k(t)
|
|
537
581
|
);
|
|
538
582
|
});
|
|
539
583
|
}
|
|
@@ -545,32 +589,32 @@ class _ {
|
|
|
545
589
|
o(new Error(`Worker "${t.worker}" not found`));
|
|
546
590
|
return;
|
|
547
591
|
}
|
|
548
|
-
const
|
|
549
|
-
mode:
|
|
550
|
-
|
|
551
|
-
});
|
|
552
|
-
a.push(
|
|
592
|
+
const f = new g(s.func, {
|
|
593
|
+
mode: m.Pipeline,
|
|
594
|
+
createWorker: s.createWorker
|
|
595
|
+
}), l = this.trackWorker(f.getWorker);
|
|
596
|
+
a.push(l);
|
|
553
597
|
}
|
|
554
598
|
for (let t = 0; t < a.length - 1; t++)
|
|
555
599
|
i.push(new MessageChannel());
|
|
556
600
|
for (let t = 0; t < a.length; t++) {
|
|
557
|
-
const s = [],
|
|
558
|
-
t > 0 && (
|
|
559
|
-
{ __pipeline_ports__: !0, ...
|
|
601
|
+
const s = [], f = {};
|
|
602
|
+
t > 0 && (f.inputPort = i[t - 1].port1, s.push(f.inputPort)), t < a.length - 1 && (f.outputPort = i[t].port2, s.push(f.outputPort)), a[t].postMessage(
|
|
603
|
+
{ __pipeline_ports__: !0, ...f },
|
|
560
604
|
s
|
|
561
605
|
);
|
|
562
606
|
}
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
var s,
|
|
566
|
-
a.forEach((
|
|
567
|
-
},
|
|
568
|
-
a.forEach((s) =>
|
|
607
|
+
const c = a[a.length - 1];
|
|
608
|
+
c.onmessage = (t) => {
|
|
609
|
+
var s, f;
|
|
610
|
+
a.forEach((l) => this.terminateWorker(l)), ((s = t.data) == null ? void 0 : s.ok) === !1 ? o(new Error(t.data.error)) : r((f = t.data) == null ? void 0 : f.data);
|
|
611
|
+
}, c.onerror = (t) => {
|
|
612
|
+
a.forEach((s) => this.terminateWorker(s)), o(t);
|
|
569
613
|
};
|
|
570
|
-
const
|
|
614
|
+
const u = e[0].srcData ?? {};
|
|
571
615
|
a[0].postMessage(
|
|
572
|
-
{ data:
|
|
573
|
-
|
|
616
|
+
{ data: u, index: 0 },
|
|
617
|
+
k(u)
|
|
574
618
|
);
|
|
575
619
|
});
|
|
576
620
|
}
|
|
@@ -609,24 +653,30 @@ class _ {
|
|
|
609
653
|
* factory.release('transform');
|
|
610
654
|
*/
|
|
611
655
|
async runPersistent(e, r) {
|
|
656
|
+
if (this._isTerminated)
|
|
657
|
+
throw new Error("MainWorkerFactory has been terminated");
|
|
612
658
|
const o = this.findWorkerByName(e);
|
|
613
659
|
if (!o) throw new Error(`Worker "${e}" not found`);
|
|
614
660
|
let a = this._persistentWorkers.get(e);
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
661
|
+
if (!a) {
|
|
662
|
+
const i = new g(o.func, {
|
|
663
|
+
mode: m.Persistent,
|
|
664
|
+
createWorker: o.createWorker
|
|
665
|
+
});
|
|
666
|
+
a = this.trackWorker(i.getWorker), this._persistentWorkers.set(e, a);
|
|
667
|
+
}
|
|
668
|
+
return new Promise((i, c) => {
|
|
619
669
|
a.onmessage = (t) => {
|
|
620
|
-
var s,
|
|
621
|
-
((s = t.data) == null ? void 0 : s.ok) === !1 ?
|
|
670
|
+
var s, f;
|
|
671
|
+
((s = t.data) == null ? void 0 : s.ok) === !1 ? c(new Error(t.data.error)) : i((f = t.data) == null ? void 0 : f.data);
|
|
622
672
|
}, a.onerror = (t) => {
|
|
623
|
-
|
|
673
|
+
c(t);
|
|
624
674
|
};
|
|
625
|
-
const
|
|
675
|
+
const u = {
|
|
626
676
|
type: "run",
|
|
627
677
|
config: r.config
|
|
628
678
|
};
|
|
629
|
-
r.dataset !== void 0 && (
|
|
679
|
+
r.dataset !== void 0 && (u.dataset = r.dataset), a.postMessage(u, k(u));
|
|
630
680
|
});
|
|
631
681
|
}
|
|
632
682
|
/**
|
|
@@ -640,10 +690,55 @@ class _ {
|
|
|
640
690
|
*/
|
|
641
691
|
release(e) {
|
|
642
692
|
const r = this._persistentWorkers.get(e);
|
|
643
|
-
|
|
693
|
+
if (r) {
|
|
694
|
+
try {
|
|
695
|
+
r.postMessage({ type: "release" });
|
|
696
|
+
} catch {
|
|
697
|
+
}
|
|
698
|
+
this.terminateWorker(r), this._persistentWorkers.delete(e);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Terminates the factory and all active and persistent worker instances.
|
|
703
|
+
*
|
|
704
|
+
* Calling `terminate()` immediately stops all running worker threads, releases
|
|
705
|
+
* cached persistent workers, and clears all internal worker state.
|
|
706
|
+
*/
|
|
707
|
+
terminate() {
|
|
708
|
+
this._isTerminated = !0;
|
|
709
|
+
for (const e of this._persistentWorkers.values()) {
|
|
710
|
+
try {
|
|
711
|
+
e.postMessage({ type: "release" });
|
|
712
|
+
} catch {
|
|
713
|
+
}
|
|
714
|
+
this.terminateWorker(e);
|
|
715
|
+
}
|
|
716
|
+
this._persistentWorkers.clear();
|
|
717
|
+
for (const e of Array.from(this._activeWorkers))
|
|
718
|
+
this.terminateWorker(e);
|
|
719
|
+
this._activeWorkers.clear();
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Alias for {@link terminate}. Terminates the factory and all worker instances.
|
|
723
|
+
*/
|
|
724
|
+
destroy() {
|
|
725
|
+
this.terminate();
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Resets the factory by terminating all active and persistent workers
|
|
729
|
+
* and resetting the factory state, allowing new worker instances to be initiated.
|
|
730
|
+
*/
|
|
731
|
+
reset() {
|
|
732
|
+
this.terminate(), this._isTerminated = !1;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Alias for {@link reset}. Resets the factory state to initiate new worker instances.
|
|
736
|
+
*/
|
|
737
|
+
restart() {
|
|
738
|
+
this.reset();
|
|
644
739
|
}
|
|
645
740
|
}
|
|
646
741
|
export {
|
|
647
|
-
|
|
648
|
-
|
|
742
|
+
E as MainWorkerFactory,
|
|
743
|
+
g as WorkerFactory
|
|
649
744
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CollectOptions, CollectedResult, PipelineStep, WorkerConfig, WorkerConfigMap, WorkerDataParam, WorkerFunction, WorkerReturnType, TypedSettledResults } from './types.ts';
|
|
2
2
|
/**
|
|
3
3
|
* Recursively collects all Transferable objects from a value.
|
|
4
|
-
*
|
|
4
|
+
* Transferable (ArrayBuffer, MessagePort, ImageBitmap, OffscreenCanvas)
|
|
5
5
|
* are zero-copy — they are moved to the worker instead of cloned.
|
|
6
6
|
*/
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function extractTransferable(value: unknown, seen?: Set<object>): Transferable[];
|
|
8
8
|
/**
|
|
9
9
|
* Central orchestrator for running typed Web Workers in parallel.
|
|
10
10
|
*
|
|
@@ -36,6 +36,8 @@ declare class MainWorkerFactory<TConfigs extends readonly WorkerConfig<WorkerFun
|
|
|
36
36
|
private readonly _workers;
|
|
37
37
|
private readonly _threads;
|
|
38
38
|
private readonly _persistentWorkers;
|
|
39
|
+
private readonly _activeWorkers;
|
|
40
|
+
private _isTerminated;
|
|
39
41
|
/**
|
|
40
42
|
* Creates a new `MainWorkerFactory`.
|
|
41
43
|
*
|
|
@@ -44,10 +46,22 @@ declare class MainWorkerFactory<TConfigs extends readonly WorkerConfig<WorkerFun
|
|
|
44
46
|
constructor(options: {
|
|
45
47
|
workers: TConfigs;
|
|
46
48
|
});
|
|
49
|
+
/**
|
|
50
|
+
* Returns `true` if the factory has been terminated.
|
|
51
|
+
*/
|
|
52
|
+
get isTerminated(): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Registers an active worker instance for lifecycle tracking.
|
|
55
|
+
*/
|
|
56
|
+
private trackWorker;
|
|
57
|
+
/**
|
|
58
|
+
* Terminates a worker instance and removes it from tracking.
|
|
59
|
+
*/
|
|
60
|
+
private terminateWorker;
|
|
47
61
|
/**
|
|
48
62
|
* Instantiates a {@link WorkerFactory} for the given worker configuration.
|
|
49
63
|
*
|
|
50
|
-
* @param config - The worker configuration containing `func` or `
|
|
64
|
+
* @param config - The worker configuration containing `func` or `createWorker`.
|
|
51
65
|
* @returns A new `WorkerFactory` wrapping the worker.
|
|
52
66
|
*/
|
|
53
67
|
private initWorker;
|
|
@@ -144,10 +158,9 @@ declare class MainWorkerFactory<TConfigs extends readonly WorkerConfig<WorkerFun
|
|
|
144
158
|
* Any transferable objects found in the payload are moved (not copied) to
|
|
145
159
|
* the worker via the `transfer` list of `postMessage`.
|
|
146
160
|
*
|
|
147
|
-
* The underlying `Worker` is always terminated after the
|
|
148
|
-
* whether it succeeded or failed.
|
|
161
|
+
* The underlying `Worker` is always terminated after the message completes.
|
|
149
162
|
*
|
|
150
|
-
* @param instanceConfig - Worker function,
|
|
163
|
+
* @param instanceConfig - Worker function, factory, name, shard index, and data.
|
|
151
164
|
* @returns A promise that resolves with the worker's result.
|
|
152
165
|
*/
|
|
153
166
|
private initiateWorker;
|
|
@@ -259,5 +272,25 @@ declare class MainWorkerFactory<TConfigs extends readonly WorkerConfig<WorkerFun
|
|
|
259
272
|
* @param workerName - Name of the persistent worker to release.
|
|
260
273
|
*/
|
|
261
274
|
release(workerName: string): void;
|
|
275
|
+
/**
|
|
276
|
+
* Terminates the factory and all active and persistent worker instances.
|
|
277
|
+
*
|
|
278
|
+
* Calling `terminate()` immediately stops all running worker threads, releases
|
|
279
|
+
* cached persistent workers, and clears all internal worker state.
|
|
280
|
+
*/
|
|
281
|
+
terminate(): void;
|
|
282
|
+
/**
|
|
283
|
+
* Alias for {@link terminate}. Terminates the factory and all worker instances.
|
|
284
|
+
*/
|
|
285
|
+
destroy(): void;
|
|
286
|
+
/**
|
|
287
|
+
* Resets the factory by terminating all active and persistent workers
|
|
288
|
+
* and resetting the factory state, allowing new worker instances to be initiated.
|
|
289
|
+
*/
|
|
290
|
+
reset(): void;
|
|
291
|
+
/**
|
|
292
|
+
* Alias for {@link reset}. Resets the factory state to initiate new worker instances.
|
|
293
|
+
*/
|
|
294
|
+
restart(): void;
|
|
262
295
|
}
|
|
263
296
|
export default MainWorkerFactory;
|
|
@@ -23,13 +23,14 @@ export interface WorkerConfig<TFunc extends WorkerFunction = WorkerFunction> {
|
|
|
23
23
|
name: WorkerName;
|
|
24
24
|
/** Human-readable role label (e.g. `'compute'`, `'transform'`). */
|
|
25
25
|
role: WorkerRole;
|
|
26
|
-
/** The worker function that will be serialised and run in a thread. Optional if `
|
|
26
|
+
/** The worker function that will be serialised and run in a thread. Optional if `createWorker` is provided. */
|
|
27
27
|
func?: TFunc;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
* Enables
|
|
29
|
+
* Factory function returning a native `Worker` instance (e.g. `() => new Worker(new URL('./worker.ts', import.meta.url))`).
|
|
30
|
+
* Enables bundlers like Webpack 5, Vite, Rollup, and Parcel to statically analyze and bundle worker code into individual chunks,
|
|
31
|
+
* while allowing `MainWorkerFactory` to scale concurrency and manage worker thread lifecycles.
|
|
31
32
|
*/
|
|
32
|
-
|
|
33
|
+
createWorker?: () => Worker;
|
|
33
34
|
/**
|
|
34
35
|
* Maximum number of parallel threads to spawn for this worker.
|
|
35
36
|
* Defaults to `navigator.hardwareConcurrency` when omitted.
|
|
@@ -103,10 +104,10 @@ export interface MainWorkerFactoryWorker extends WorkerConfig {
|
|
|
103
104
|
export interface WorkerInstanceConfig<TFunc extends WorkerFunction = WorkerFunction> {
|
|
104
105
|
/** Name of the parent worker config, used in logs and error objects. */
|
|
105
106
|
workerName: WorkerName;
|
|
106
|
-
/** The function serialised and executed inside the thread (optional if `
|
|
107
|
+
/** The function serialised and executed inside the thread (optional if `createWorker` is set). */
|
|
107
108
|
workerFunc?: TFunc;
|
|
108
|
-
/**
|
|
109
|
-
|
|
109
|
+
/** Factory function returning a Worker instance. */
|
|
110
|
+
createWorker?: () => Worker;
|
|
110
111
|
/** Zero-based shard index assigned to this thread. */
|
|
111
112
|
index: number;
|
|
112
113
|
/** The data payload (full or partitioned shard) sent to the thread. */
|
|
@@ -7,10 +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
|
-
/**
|
|
11
|
-
|
|
12
|
-
/** The worker URL to use instead of creating a worker from a function. */
|
|
13
|
-
workerURL?: string | URL;
|
|
10
|
+
/** Factory function returning a native `Worker` instance. */
|
|
11
|
+
createWorker?: () => Worker;
|
|
14
12
|
}
|
|
15
13
|
/**
|
|
16
14
|
* Low-level factory that serializes a {@link WorkerFunction} into a Blob URL
|
|
@@ -36,16 +34,12 @@ export interface WorkerFactoryOptions {
|
|
|
36
34
|
declare class WorkerFactory {
|
|
37
35
|
readonly _worker: Worker;
|
|
38
36
|
/**
|
|
39
|
-
* Creates a new `Worker` from the given function.
|
|
40
|
-
*
|
|
41
|
-
* The function is stringified, embedded into a self-contained worker script,
|
|
42
|
-
* converted to a `Blob` URL, and passed to the `Worker` constructor.
|
|
37
|
+
* Creates a new `Worker` from the given function or factory option.
|
|
43
38
|
*
|
|
44
39
|
* @param workerFunction - The function to run inside the worker thread.
|
|
45
40
|
* Must be self-contained — it cannot reference variables from the outer
|
|
46
41
|
* scope because it is serialized via `.toString()`.
|
|
47
|
-
* @param options - Optional configuration
|
|
48
|
-
* worker execution mode (default, pipeline, or persistent).
|
|
42
|
+
* @param options - Optional configuration containing `createWorker` or `mode`.
|
|
49
43
|
*/
|
|
50
44
|
constructor(workerFunction?: WorkerFunction, options?: WorkerFactoryOptions);
|
|
51
45
|
/**
|
package/package.json
CHANGED