@xylabs/threads 5.0.13 → 5.0.15
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/browser/index-browser.mjs +119 -209
- package/dist/browser/index-browser.mjs.map +1 -1
- package/dist/browser/master/implementation.browser.mjs +11 -36
- package/dist/browser/master/implementation.browser.mjs.map +1 -1
- package/dist/browser/master/index-browser.mjs +117 -201
- package/dist/browser/master/index-browser.mjs.map +1 -1
- package/dist/browser/master/pool-browser.mjs +53 -65
- package/dist/browser/master/pool-browser.mjs.map +1 -1
- package/dist/browser/worker/worker.browser.mjs +43 -79
- package/dist/browser/worker/worker.browser.mjs.map +1 -1
- package/dist/neutral/master/register.mjs +62 -121
- package/dist/neutral/master/register.mjs.map +1 -1
- package/dist/neutral/master/spawn.mjs +53 -106
- package/dist/neutral/master/spawn.mjs.map +1 -1
- package/dist/neutral/master/thread.mjs +0 -4
- package/dist/neutral/master/thread.mjs.map +1 -1
- package/dist/neutral/observable-promise.mjs +20 -27
- package/dist/neutral/observable-promise.mjs.map +1 -1
- package/dist/neutral/observable.mjs +3 -12
- package/dist/neutral/observable.mjs.map +1 -1
- package/dist/neutral/types/messages.mjs +4 -4
- package/dist/neutral/types/messages.mjs.map +1 -1
- package/dist/node/index-node.mjs +169 -293
- package/dist/node/index-node.mjs.map +1 -1
- package/dist/node/master/implementation.node.mjs +62 -121
- package/dist/node/master/implementation.node.mjs.map +1 -1
- package/dist/node/master/index-node.mjs +168 -286
- package/dist/node/master/index-node.mjs.map +1 -1
- package/dist/node/master/pool-node.mjs +115 -183
- package/dist/node/master/pool-node.mjs.map +1 -1
- package/dist/node/worker/worker.node.mjs +43 -80
- package/dist/node/worker/worker.node.mjs.map +1 -1
- package/package.json +3 -4
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
|
|
4
1
|
// src/serializers.ts
|
|
5
2
|
function extendSerializer(extend, implementation2) {
|
|
6
3
|
const fallbackDeserializer = extend.deserialize.bind(extend);
|
|
@@ -14,7 +11,6 @@ function extendSerializer(extend, implementation2) {
|
|
|
14
11
|
}
|
|
15
12
|
};
|
|
16
13
|
}
|
|
17
|
-
__name(extendSerializer, "extendSerializer");
|
|
18
14
|
var DefaultErrorSerializer = {
|
|
19
15
|
deserialize(message) {
|
|
20
16
|
return Object.assign(new Error(message.message), {
|
|
@@ -31,7 +27,7 @@ var DefaultErrorSerializer = {
|
|
|
31
27
|
};
|
|
32
28
|
}
|
|
33
29
|
};
|
|
34
|
-
var isSerializedError =
|
|
30
|
+
var isSerializedError = (thing) => thing && typeof thing === "object" && "__error_marker" in thing && thing.__error_marker === "$$error";
|
|
35
31
|
var DefaultSerializer = {
|
|
36
32
|
deserialize(message) {
|
|
37
33
|
return isSerializedError(message) ? DefaultErrorSerializer.deserialize(message) : message;
|
|
@@ -46,15 +42,12 @@ globalThis.registeredSerializer = globalThis.registeredSerializer ?? DefaultSeri
|
|
|
46
42
|
function registerSerializer(serializer) {
|
|
47
43
|
globalThis.registeredSerializer = extendSerializer(globalThis.registeredSerializer, serializer);
|
|
48
44
|
}
|
|
49
|
-
__name(registerSerializer, "registerSerializer");
|
|
50
45
|
function deserialize(message) {
|
|
51
46
|
return globalThis.registeredSerializer.deserialize(message);
|
|
52
47
|
}
|
|
53
|
-
__name(deserialize, "deserialize");
|
|
54
48
|
function serialize(input) {
|
|
55
49
|
return globalThis.registeredSerializer.serialize(input);
|
|
56
50
|
}
|
|
57
|
-
__name(serialize, "serialize");
|
|
58
51
|
|
|
59
52
|
// src/master/get-bundle-url.browser.ts
|
|
60
53
|
var bundleURL;
|
|
@@ -64,7 +57,6 @@ function getBundleURLCached() {
|
|
|
64
57
|
}
|
|
65
58
|
return bundleURL;
|
|
66
59
|
}
|
|
67
|
-
__name(getBundleURLCached, "getBundleURLCached");
|
|
68
60
|
function getBundleURL() {
|
|
69
61
|
try {
|
|
70
62
|
throw new Error("getBundleURL failed");
|
|
@@ -77,39 +69,28 @@ function getBundleURL() {
|
|
|
77
69
|
}
|
|
78
70
|
return "/";
|
|
79
71
|
}
|
|
80
|
-
__name(getBundleURL, "getBundleURL");
|
|
81
72
|
function getBaseURL(url) {
|
|
82
73
|
return ("" + url).replace(/^((?:https?|file|ftp|chrome-extension|moz-extension):\/\/.+)?\/[^/]+(?:\?.*)?$/, "$1") + "/";
|
|
83
74
|
}
|
|
84
|
-
__name(getBaseURL, "getBaseURL");
|
|
85
75
|
|
|
86
76
|
// src/master/implementation.browser.ts
|
|
87
77
|
var defaultPoolSize = typeof navigator !== "undefined" && navigator.hardwareConcurrency ? navigator.hardwareConcurrency : 4;
|
|
88
|
-
var isAbsoluteURL =
|
|
78
|
+
var isAbsoluteURL = (value) => /^[A-Za-z][\d+.A-Za-z\-]*:/.test(value);
|
|
89
79
|
function createSourceBlobURL(code) {
|
|
90
|
-
const blob = new Blob([
|
|
91
|
-
code
|
|
92
|
-
], {
|
|
93
|
-
type: "application/javascript"
|
|
94
|
-
});
|
|
80
|
+
const blob = new Blob([code], { type: "application/javascript" });
|
|
95
81
|
return URL.createObjectURL(blob);
|
|
96
82
|
}
|
|
97
|
-
__name(createSourceBlobURL, "createSourceBlobURL");
|
|
98
83
|
function selectWorkerImplementation() {
|
|
99
84
|
if (typeof Worker === "undefined") {
|
|
100
85
|
return class NoWebWorker {
|
|
101
|
-
static {
|
|
102
|
-
__name(this, "NoWebWorker");
|
|
103
|
-
}
|
|
104
86
|
constructor() {
|
|
105
|
-
throw new Error(
|
|
87
|
+
throw new Error(
|
|
88
|
+
"No web worker implementation available. You might have tried to spawn a worker within a worker in a browser that doesn't support workers in workers."
|
|
89
|
+
);
|
|
106
90
|
}
|
|
107
91
|
};
|
|
108
92
|
}
|
|
109
|
-
|
|
110
|
-
static {
|
|
111
|
-
__name(this, "WebWorker");
|
|
112
|
-
}
|
|
93
|
+
class WebWorker extends Worker {
|
|
113
94
|
constructor(url, options) {
|
|
114
95
|
if (typeof url === "string" && options && options._baseURL) {
|
|
115
96
|
url = new URL(url, options._baseURL);
|
|
@@ -124,30 +105,22 @@ function selectWorkerImplementation() {
|
|
|
124
105
|
}
|
|
125
106
|
super(url, options);
|
|
126
107
|
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
static {
|
|
130
|
-
__name(this, "BlobWorker");
|
|
131
|
-
}
|
|
108
|
+
}
|
|
109
|
+
class BlobWorker2 extends WebWorker {
|
|
132
110
|
constructor(blob, options) {
|
|
133
111
|
const url = globalThis.URL.createObjectURL(blob);
|
|
134
112
|
super(url, options);
|
|
135
113
|
}
|
|
136
114
|
static fromText(source, options) {
|
|
137
|
-
const blob = new globalThis.Blob([
|
|
138
|
-
|
|
139
|
-
], {
|
|
140
|
-
type: "text/javascript"
|
|
141
|
-
});
|
|
142
|
-
return new BlobWorker3(blob, options);
|
|
115
|
+
const blob = new globalThis.Blob([source], { type: "text/javascript" });
|
|
116
|
+
return new BlobWorker2(blob, options);
|
|
143
117
|
}
|
|
144
|
-
}
|
|
118
|
+
}
|
|
145
119
|
return {
|
|
146
120
|
blob: BlobWorker2,
|
|
147
121
|
default: WebWorker
|
|
148
122
|
};
|
|
149
123
|
}
|
|
150
|
-
__name(selectWorkerImplementation, "selectWorkerImplementation");
|
|
151
124
|
var implementation;
|
|
152
125
|
function getWorkerImplementation() {
|
|
153
126
|
if (!implementation) {
|
|
@@ -155,19 +128,21 @@ function getWorkerImplementation() {
|
|
|
155
128
|
}
|
|
156
129
|
return implementation;
|
|
157
130
|
}
|
|
158
|
-
__name(getWorkerImplementation, "getWorkerImplementation");
|
|
159
131
|
function isWorkerRuntime() {
|
|
160
132
|
const isWindowContext = typeof globalThis !== "undefined" && typeof Window !== "undefined" && globalThis instanceof Window;
|
|
161
133
|
return typeof globalThis !== "undefined" && self["postMessage"] && !isWindowContext ? true : false;
|
|
162
134
|
}
|
|
163
|
-
__name(isWorkerRuntime, "isWorkerRuntime");
|
|
164
135
|
|
|
165
136
|
// src/master/pool-browser.ts
|
|
166
137
|
import DebugLogger from "debug";
|
|
167
|
-
import {
|
|
138
|
+
import {
|
|
139
|
+
multicast,
|
|
140
|
+
Observable,
|
|
141
|
+
Subject
|
|
142
|
+
} from "observable-fns";
|
|
168
143
|
|
|
169
144
|
// src/master/pool-types.ts
|
|
170
|
-
var PoolEventType = /* @__PURE__ */
|
|
145
|
+
var PoolEventType = /* @__PURE__ */ ((PoolEventType2) => {
|
|
171
146
|
PoolEventType2["initialized"] = "initialized";
|
|
172
147
|
PoolEventType2["taskCanceled"] = "taskCanceled";
|
|
173
148
|
PoolEventType2["taskCompleted"] = "taskCompleted";
|
|
@@ -177,7 +152,7 @@ var PoolEventType = /* @__PURE__ */ function(PoolEventType2) {
|
|
|
177
152
|
PoolEventType2["taskStart"] = "taskStart";
|
|
178
153
|
PoolEventType2["terminated"] = "terminated";
|
|
179
154
|
return PoolEventType2;
|
|
180
|
-
}({});
|
|
155
|
+
})(PoolEventType || {});
|
|
181
156
|
|
|
182
157
|
// src/symbols.ts
|
|
183
158
|
var $errors = Symbol("thread.errors");
|
|
@@ -190,7 +165,6 @@ var $worker = Symbol("thread.worker");
|
|
|
190
165
|
function fail(message) {
|
|
191
166
|
throw new Error(message);
|
|
192
167
|
}
|
|
193
|
-
__name(fail, "fail");
|
|
194
168
|
var Thread = {
|
|
195
169
|
/** Return an observable that can be used to subscribe to all errors happening in the thread. */
|
|
196
170
|
errors(thread) {
|
|
@@ -215,33 +189,24 @@ function createArray(size) {
|
|
|
215
189
|
}
|
|
216
190
|
return array;
|
|
217
191
|
}
|
|
218
|
-
__name(createArray, "createArray");
|
|
219
192
|
function delay(ms) {
|
|
220
193
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
221
194
|
}
|
|
222
|
-
__name(delay, "delay");
|
|
223
195
|
function flatMap(array, mapper) {
|
|
224
|
-
return array.reduce((flattened, element) => [
|
|
225
|
-
...flattened,
|
|
226
|
-
...mapper(element)
|
|
227
|
-
], []);
|
|
196
|
+
return array.reduce((flattened, element) => [...flattened, ...mapper(element)], []);
|
|
228
197
|
}
|
|
229
|
-
__name(flatMap, "flatMap");
|
|
230
198
|
function slugify(text) {
|
|
231
199
|
return text.replaceAll(/\W/g, " ").trim().replaceAll(/\s+/g, "-");
|
|
232
200
|
}
|
|
233
|
-
__name(slugify, "slugify");
|
|
234
201
|
function spawnWorkers(spawnWorker, count) {
|
|
235
|
-
return createArray(count).map(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
__name(this, "WorkerPool");
|
|
244
|
-
}
|
|
202
|
+
return createArray(count).map(
|
|
203
|
+
() => ({
|
|
204
|
+
init: spawnWorker(),
|
|
205
|
+
runningTasks: []
|
|
206
|
+
})
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
var WorkerPool = class {
|
|
245
210
|
static EventType = PoolEventType;
|
|
246
211
|
debug;
|
|
247
212
|
eventObservable;
|
|
@@ -253,22 +218,23 @@ var WorkerPool = class WorkerPool2 {
|
|
|
253
218
|
nextTaskID = 1;
|
|
254
219
|
taskQueue = [];
|
|
255
220
|
constructor(spawnWorker, optionsOrSize) {
|
|
256
|
-
const options = typeof optionsOrSize === "number" ? {
|
|
257
|
-
size: optionsOrSize
|
|
258
|
-
} : optionsOrSize || {};
|
|
221
|
+
const options = typeof optionsOrSize === "number" ? { size: optionsOrSize } : optionsOrSize || {};
|
|
259
222
|
const { size = defaultPoolSize } = options;
|
|
260
223
|
this.debug = DebugLogger(`threads:pool:${slugify(options.name || String(nextPoolID++))}`);
|
|
261
224
|
this.options = options;
|
|
262
225
|
this.workers = spawnWorkers(spawnWorker, size);
|
|
263
226
|
this.eventObservable = multicast(Observable.from(this.eventSubject));
|
|
264
|
-
Promise.all(this.workers.map((worker) => worker.init)).then(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
227
|
+
Promise.all(this.workers.map((worker) => worker.init)).then(
|
|
228
|
+
() => this.eventSubject.next({
|
|
229
|
+
size: this.workers.length,
|
|
230
|
+
type: "initialized" /* initialized */
|
|
231
|
+
}),
|
|
232
|
+
(error) => {
|
|
233
|
+
this.debug("Error while initializing pool worker:", error);
|
|
234
|
+
this.eventSubject.error(error);
|
|
235
|
+
this.initErrors.push(error);
|
|
236
|
+
}
|
|
237
|
+
);
|
|
272
238
|
}
|
|
273
239
|
findIdlingWorker() {
|
|
274
240
|
const { concurrency = 1 } = this.options;
|
|
@@ -279,7 +245,7 @@ var WorkerPool = class WorkerPool2 {
|
|
|
279
245
|
this.debug(`Running task #${task.id} on worker #${workerID}...`);
|
|
280
246
|
this.eventSubject.next({
|
|
281
247
|
taskID: task.id,
|
|
282
|
-
type:
|
|
248
|
+
type: "taskStart" /* taskStart */,
|
|
283
249
|
workerID
|
|
284
250
|
});
|
|
285
251
|
try {
|
|
@@ -288,7 +254,7 @@ var WorkerPool = class WorkerPool2 {
|
|
|
288
254
|
this.eventSubject.next({
|
|
289
255
|
returnValue,
|
|
290
256
|
taskID: task.id,
|
|
291
|
-
type:
|
|
257
|
+
type: "taskCompleted" /* taskCompleted */,
|
|
292
258
|
workerID
|
|
293
259
|
});
|
|
294
260
|
} catch (ex) {
|
|
@@ -297,16 +263,16 @@ var WorkerPool = class WorkerPool2 {
|
|
|
297
263
|
this.eventSubject.next({
|
|
298
264
|
error,
|
|
299
265
|
taskID: task.id,
|
|
300
|
-
type:
|
|
266
|
+
type: "taskFailed" /* taskFailed */,
|
|
301
267
|
workerID
|
|
302
268
|
});
|
|
303
269
|
}
|
|
304
270
|
}
|
|
305
271
|
run(worker, task) {
|
|
306
272
|
const runPromise = (async () => {
|
|
307
|
-
const removeTaskFromWorkersRunningTasks =
|
|
273
|
+
const removeTaskFromWorkersRunningTasks = () => {
|
|
308
274
|
worker.runningTasks = worker.runningTasks.filter((someRunPromise) => someRunPromise !== runPromise);
|
|
309
|
-
}
|
|
275
|
+
};
|
|
310
276
|
await delay(0);
|
|
311
277
|
try {
|
|
312
278
|
await this.runPoolTask(worker, task);
|
|
@@ -326,9 +292,7 @@ var WorkerPool = class WorkerPool2 {
|
|
|
326
292
|
const nextTask = this.taskQueue.shift();
|
|
327
293
|
if (!nextTask) {
|
|
328
294
|
this.debug("Task queue is empty");
|
|
329
|
-
this.eventSubject.next({
|
|
330
|
-
type: PoolEventType.taskQueueDrained
|
|
331
|
-
});
|
|
295
|
+
this.eventSubject.next({ type: "taskQueueDrained" /* taskQueueDrained */ });
|
|
332
296
|
return;
|
|
333
297
|
}
|
|
334
298
|
this.run(availableWorker, nextTask);
|
|
@@ -336,13 +300,13 @@ var WorkerPool = class WorkerPool2 {
|
|
|
336
300
|
taskCompletion(taskID) {
|
|
337
301
|
return new Promise((resolve, reject) => {
|
|
338
302
|
const eventSubscription = this.events().subscribe((event) => {
|
|
339
|
-
if (event.type ===
|
|
303
|
+
if (event.type === "taskCompleted" /* taskCompleted */ && event.taskID === taskID) {
|
|
340
304
|
eventSubscription.unsubscribe();
|
|
341
305
|
resolve(event.returnValue);
|
|
342
|
-
} else if (event.type ===
|
|
306
|
+
} else if (event.type === "taskFailed" /* taskFailed */ && event.taskID === taskID) {
|
|
343
307
|
eventSubscription.unsubscribe();
|
|
344
308
|
reject(event.error);
|
|
345
|
-
} else if (event.type ===
|
|
309
|
+
} else if (event.type === "terminated" /* terminated */) {
|
|
346
310
|
eventSubscription.unsubscribe();
|
|
347
311
|
reject(new Error("Pool has been terminated before task was run."));
|
|
348
312
|
}
|
|
@@ -350,10 +314,10 @@ var WorkerPool = class WorkerPool2 {
|
|
|
350
314
|
});
|
|
351
315
|
}
|
|
352
316
|
async settled(allowResolvingImmediately = false) {
|
|
353
|
-
const getCurrentlyRunningTasks =
|
|
317
|
+
const getCurrentlyRunningTasks = () => flatMap(this.workers, (worker) => worker.runningTasks);
|
|
354
318
|
const taskFailures = [];
|
|
355
319
|
const failureSubscription = this.eventObservable.subscribe((event) => {
|
|
356
|
-
if (event.type ===
|
|
320
|
+
if (event.type === "taskFailed" /* taskFailed */) {
|
|
357
321
|
taskFailures.push(event.error);
|
|
358
322
|
}
|
|
359
323
|
});
|
|
@@ -368,11 +332,12 @@ var WorkerPool = class WorkerPool2 {
|
|
|
368
332
|
const subscription = this.eventObservable.subscribe({
|
|
369
333
|
error: reject,
|
|
370
334
|
next(event) {
|
|
371
|
-
if (event.type ===
|
|
335
|
+
if (event.type === "taskQueueDrained" /* taskQueueDrained */) {
|
|
372
336
|
subscription.unsubscribe();
|
|
373
337
|
resolve(void 0);
|
|
374
338
|
}
|
|
375
339
|
}
|
|
340
|
+
// make a pool-wide error reject the completed() result promise
|
|
376
341
|
});
|
|
377
342
|
});
|
|
378
343
|
await Promise.allSettled(getCurrentlyRunningTasks());
|
|
@@ -385,20 +350,18 @@ var WorkerPool = class WorkerPool2 {
|
|
|
385
350
|
const subscription = this.eventObservable.subscribe({
|
|
386
351
|
error: reject,
|
|
387
352
|
next(event) {
|
|
388
|
-
if (event.type ===
|
|
353
|
+
if (event.type === "taskQueueDrained" /* taskQueueDrained */) {
|
|
389
354
|
subscription.unsubscribe();
|
|
390
355
|
resolve(settlementPromise);
|
|
391
|
-
} else if (event.type ===
|
|
356
|
+
} else if (event.type === "taskFailed" /* taskFailed */) {
|
|
392
357
|
subscription.unsubscribe();
|
|
393
358
|
reject(event.error);
|
|
394
359
|
}
|
|
395
360
|
}
|
|
361
|
+
// make a pool-wide error reject the completed() result promise
|
|
396
362
|
});
|
|
397
363
|
});
|
|
398
|
-
const errors = await Promise.race([
|
|
399
|
-
settlementPromise,
|
|
400
|
-
earlyExitPromise
|
|
401
|
-
]);
|
|
364
|
+
const errors = await Promise.race([settlementPromise, earlyExitPromise]);
|
|
402
365
|
if (errors.length > 0) {
|
|
403
366
|
throw errors[0];
|
|
404
367
|
}
|
|
@@ -420,26 +383,28 @@ var WorkerPool = class WorkerPool2 {
|
|
|
420
383
|
this.debug(`Task #${taskID} errored:`, error);
|
|
421
384
|
});
|
|
422
385
|
const task = {
|
|
423
|
-
cancel:
|
|
386
|
+
cancel: () => {
|
|
424
387
|
if (!this.taskQueue.includes(task)) return;
|
|
425
388
|
this.taskQueue = this.taskQueue.filter((someTask) => someTask !== task);
|
|
426
389
|
this.eventSubject.next({
|
|
427
390
|
taskID: task.id,
|
|
428
|
-
type:
|
|
391
|
+
type: "taskCanceled" /* taskCanceled */
|
|
429
392
|
});
|
|
430
|
-
},
|
|
393
|
+
},
|
|
431
394
|
id: taskID,
|
|
432
395
|
run: taskFunction,
|
|
433
396
|
then: taskCompletion.then.bind(taskCompletion)
|
|
434
397
|
};
|
|
435
398
|
if (this.taskQueue.length >= maxQueuedJobs) {
|
|
436
|
-
throw new Error(
|
|
399
|
+
throw new Error(
|
|
400
|
+
"Maximum number of pool tasks queued. Refusing to queue another one.\nThis usually happens for one of two reasons: We are either at peak workload right now or some tasks just won't finish, thus blocking the pool."
|
|
401
|
+
);
|
|
437
402
|
}
|
|
438
403
|
this.debug(`Queueing task #${task.id}...`);
|
|
439
404
|
this.taskQueue.push(task);
|
|
440
405
|
this.eventSubject.next({
|
|
441
406
|
taskID: task.id,
|
|
442
|
-
type:
|
|
407
|
+
type: "taskQueued" /* taskQueued */
|
|
443
408
|
});
|
|
444
409
|
this.scheduleWork();
|
|
445
410
|
return task;
|
|
@@ -450,10 +415,8 @@ var WorkerPool = class WorkerPool2 {
|
|
|
450
415
|
await this.completed(true);
|
|
451
416
|
}
|
|
452
417
|
this.eventSubject.next({
|
|
453
|
-
remainingQueue: [
|
|
454
|
-
|
|
455
|
-
],
|
|
456
|
-
type: PoolEventType.terminated
|
|
418
|
+
remainingQueue: [...this.taskQueue],
|
|
419
|
+
type: "terminated" /* terminated */
|
|
457
420
|
});
|
|
458
421
|
this.eventSubject.complete();
|
|
459
422
|
await Promise.all(this.workers.map(async (worker) => Thread.terminate(await worker.init)));
|
|
@@ -462,7 +425,6 @@ var WorkerPool = class WorkerPool2 {
|
|
|
462
425
|
function PoolConstructor(spawnWorker, optionsOrSize) {
|
|
463
426
|
return new WorkerPool(spawnWorker, optionsOrSize);
|
|
464
427
|
}
|
|
465
|
-
__name(PoolConstructor, "PoolConstructor");
|
|
466
428
|
PoolConstructor.EventType = PoolEventType;
|
|
467
429
|
var Pool = PoolConstructor;
|
|
468
430
|
|
|
@@ -471,7 +433,7 @@ import DebugLogger3 from "debug";
|
|
|
471
433
|
import { Observable as Observable4 } from "observable-fns";
|
|
472
434
|
|
|
473
435
|
// src/promise.ts
|
|
474
|
-
var doNothing =
|
|
436
|
+
var doNothing = () => void 0;
|
|
475
437
|
function createPromiseWithResolver() {
|
|
476
438
|
let alreadyResolved = false;
|
|
477
439
|
let resolvedTo;
|
|
@@ -483,25 +445,13 @@ function createPromiseWithResolver() {
|
|
|
483
445
|
resolver = resolve;
|
|
484
446
|
}
|
|
485
447
|
});
|
|
486
|
-
const exposedResolver =
|
|
448
|
+
const exposedResolver = (value) => {
|
|
487
449
|
alreadyResolved = true;
|
|
488
450
|
resolvedTo = value;
|
|
489
451
|
resolver(resolvedTo);
|
|
490
|
-
}
|
|
491
|
-
return [
|
|
492
|
-
promise,
|
|
493
|
-
exposedResolver
|
|
494
|
-
];
|
|
452
|
+
};
|
|
453
|
+
return [promise, exposedResolver];
|
|
495
454
|
}
|
|
496
|
-
__name(createPromiseWithResolver, "createPromiseWithResolver");
|
|
497
|
-
|
|
498
|
-
// src/types/master.ts
|
|
499
|
-
var WorkerEventType = /* @__PURE__ */ function(WorkerEventType2) {
|
|
500
|
-
WorkerEventType2["internalError"] = "internalError";
|
|
501
|
-
WorkerEventType2["message"] = "message";
|
|
502
|
-
WorkerEventType2["termination"] = "termination";
|
|
503
|
-
return WorkerEventType2;
|
|
504
|
-
}({});
|
|
505
455
|
|
|
506
456
|
// src/master/invocation-proxy.ts
|
|
507
457
|
import DebugLogger2 from "debug";
|
|
@@ -509,22 +459,17 @@ import { multicast as multicast2, Observable as Observable3 } from "observable-f
|
|
|
509
459
|
|
|
510
460
|
// src/observable-promise.ts
|
|
511
461
|
import { Observable as Observable2 } from "observable-fns";
|
|
512
|
-
var doNothing2 =
|
|
513
|
-
}
|
|
514
|
-
var returnInput =
|
|
515
|
-
var runDeferred =
|
|
462
|
+
var doNothing2 = () => {
|
|
463
|
+
};
|
|
464
|
+
var returnInput = (input) => input;
|
|
465
|
+
var runDeferred = (fn) => Promise.resolve().then(fn);
|
|
516
466
|
function fail2(error) {
|
|
517
467
|
throw error;
|
|
518
468
|
}
|
|
519
|
-
__name(fail2, "fail");
|
|
520
469
|
function isThenable(thing) {
|
|
521
470
|
return thing && typeof thing.then === "function";
|
|
522
471
|
}
|
|
523
|
-
__name(isThenable, "isThenable");
|
|
524
472
|
var ObservablePromise = class _ObservablePromise extends Observable2 {
|
|
525
|
-
static {
|
|
526
|
-
__name(this, "ObservablePromise");
|
|
527
|
-
}
|
|
528
473
|
[Symbol.toStringTag] = "[object ObservablePromise]";
|
|
529
474
|
initHasRun = false;
|
|
530
475
|
fulfillmentCallbacks = [];
|
|
@@ -583,7 +528,7 @@ var ObservablePromise = class _ObservablePromise extends Observable2 {
|
|
|
583
528
|
const onRejected = onRejectedRaw || fail2;
|
|
584
529
|
let onRejectedCalled = false;
|
|
585
530
|
return new Promise((resolve, reject) => {
|
|
586
|
-
const rejectionCallback =
|
|
531
|
+
const rejectionCallback = (error) => {
|
|
587
532
|
if (onRejectedCalled) return;
|
|
588
533
|
onRejectedCalled = true;
|
|
589
534
|
try {
|
|
@@ -591,19 +536,17 @@ var ObservablePromise = class _ObservablePromise extends Observable2 {
|
|
|
591
536
|
} catch (anotherError) {
|
|
592
537
|
reject(anotherError);
|
|
593
538
|
}
|
|
594
|
-
}
|
|
595
|
-
const fulfillmentCallback =
|
|
539
|
+
};
|
|
540
|
+
const fulfillmentCallback = (value) => {
|
|
596
541
|
try {
|
|
597
542
|
resolve(onFulfilled(value));
|
|
598
543
|
} catch (ex) {
|
|
599
544
|
const error = ex;
|
|
600
545
|
rejectionCallback(error);
|
|
601
546
|
}
|
|
602
|
-
}
|
|
547
|
+
};
|
|
603
548
|
if (!this.initHasRun) {
|
|
604
|
-
this.subscribe({
|
|
605
|
-
error: rejectionCallback
|
|
606
|
-
});
|
|
549
|
+
this.subscribe({ error: rejectionCallback });
|
|
607
550
|
}
|
|
608
551
|
if (this.state === "fulfilled") {
|
|
609
552
|
return resolve(onFulfilled(this.firstValue));
|
|
@@ -621,20 +564,23 @@ var ObservablePromise = class _ObservablePromise extends Observable2 {
|
|
|
621
564
|
}
|
|
622
565
|
finally(onCompleted) {
|
|
623
566
|
const handler = onCompleted || doNothing2;
|
|
624
|
-
return this.then(
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
567
|
+
return this.then(
|
|
568
|
+
(value) => {
|
|
569
|
+
handler();
|
|
570
|
+
return value;
|
|
571
|
+
},
|
|
572
|
+
() => handler()
|
|
573
|
+
);
|
|
628
574
|
}
|
|
629
575
|
static from(thing) {
|
|
630
576
|
return isThenable(thing) ? new _ObservablePromise((observer) => {
|
|
631
|
-
const onFulfilled =
|
|
577
|
+
const onFulfilled = (value) => {
|
|
632
578
|
observer.next(value);
|
|
633
579
|
observer.complete();
|
|
634
|
-
}
|
|
635
|
-
const onRejected =
|
|
580
|
+
};
|
|
581
|
+
const onRejected = (error) => {
|
|
636
582
|
observer.error(error);
|
|
637
|
-
}
|
|
583
|
+
};
|
|
638
584
|
thing.then(onFulfilled, onRejected);
|
|
639
585
|
}) : super.from(thing);
|
|
640
586
|
}
|
|
@@ -645,18 +591,14 @@ function isTransferable(thing) {
|
|
|
645
591
|
if (!thing || typeof thing !== "object") return false;
|
|
646
592
|
return true;
|
|
647
593
|
}
|
|
648
|
-
__name(isTransferable, "isTransferable");
|
|
649
594
|
function isTransferDescriptor(thing) {
|
|
650
595
|
return thing && typeof thing === "object" && thing[$transferable];
|
|
651
596
|
}
|
|
652
|
-
__name(isTransferDescriptor, "isTransferDescriptor");
|
|
653
597
|
function Transfer(payload, transferables) {
|
|
654
598
|
console.log("Transfer");
|
|
655
599
|
if (!transferables) {
|
|
656
600
|
if (!isTransferable(payload)) throw new Error("Not transferable");
|
|
657
|
-
transferables = [
|
|
658
|
-
payload
|
|
659
|
-
];
|
|
601
|
+
transferables = [payload];
|
|
660
602
|
}
|
|
661
603
|
return {
|
|
662
604
|
[$transferable]: true,
|
|
@@ -664,36 +606,18 @@ function Transfer(payload, transferables) {
|
|
|
664
606
|
transferables
|
|
665
607
|
};
|
|
666
608
|
}
|
|
667
|
-
__name(Transfer, "Transfer");
|
|
668
|
-
|
|
669
|
-
// src/types/messages.ts
|
|
670
|
-
var MasterMessageType = /* @__PURE__ */ function(MasterMessageType2) {
|
|
671
|
-
MasterMessageType2["cancel"] = "cancel";
|
|
672
|
-
MasterMessageType2["run"] = "run";
|
|
673
|
-
return MasterMessageType2;
|
|
674
|
-
}({});
|
|
675
|
-
var WorkerMessageType = /* @__PURE__ */ function(WorkerMessageType2) {
|
|
676
|
-
WorkerMessageType2["error"] = "error";
|
|
677
|
-
WorkerMessageType2["init"] = "init";
|
|
678
|
-
WorkerMessageType2["result"] = "result";
|
|
679
|
-
WorkerMessageType2["running"] = "running";
|
|
680
|
-
WorkerMessageType2["uncaughtError"] = "uncaughtError";
|
|
681
|
-
return WorkerMessageType2;
|
|
682
|
-
}({});
|
|
683
609
|
|
|
684
610
|
// src/master/invocation-proxy.ts
|
|
685
611
|
var debugMessages = DebugLogger2("threads:master:messages");
|
|
686
612
|
var nextJobUID = 1;
|
|
687
|
-
var dedupe =
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
var
|
|
691
|
-
var isJobResultMessage = /* @__PURE__ */ __name((data) => data && data.type === WorkerMessageType.result, "isJobResultMessage");
|
|
692
|
-
var isJobStartMessage = /* @__PURE__ */ __name((data) => data && data.type === WorkerMessageType.running, "isJobStartMessage");
|
|
613
|
+
var dedupe = (array) => [...new Set(array)];
|
|
614
|
+
var isJobErrorMessage = (data) => data && data.type === "error" /* error */;
|
|
615
|
+
var isJobResultMessage = (data) => data && data.type === "result" /* result */;
|
|
616
|
+
var isJobStartMessage = (data) => data && data.type === "running" /* running */;
|
|
693
617
|
function createObservableForJob(worker, jobUID) {
|
|
694
618
|
return new Observable3((observer) => {
|
|
695
619
|
let asyncType;
|
|
696
|
-
const messageHandler =
|
|
620
|
+
const messageHandler = (event) => {
|
|
697
621
|
debugMessages("Message from worker:", event.data);
|
|
698
622
|
if (!event.data || event.data.uid !== jobUID) return;
|
|
699
623
|
if (isJobStartMessage(event.data)) {
|
|
@@ -723,12 +647,12 @@ function createObservableForJob(worker, jobUID) {
|
|
|
723
647
|
}
|
|
724
648
|
worker.removeEventListener("message", messageHandler);
|
|
725
649
|
}
|
|
726
|
-
}
|
|
650
|
+
};
|
|
727
651
|
worker.addEventListener("message", messageHandler);
|
|
728
652
|
return () => {
|
|
729
653
|
if (asyncType === "observable" || !asyncType) {
|
|
730
654
|
const cancelMessage = {
|
|
731
|
-
type:
|
|
655
|
+
type: "cancel" /* cancel */,
|
|
732
656
|
uid: jobUID
|
|
733
657
|
};
|
|
734
658
|
worker.postMessage(cancelMessage);
|
|
@@ -737,7 +661,6 @@ function createObservableForJob(worker, jobUID) {
|
|
|
737
661
|
};
|
|
738
662
|
});
|
|
739
663
|
}
|
|
740
|
-
__name(createObservableForJob, "createObservableForJob");
|
|
741
664
|
function prepareArguments(rawArgs) {
|
|
742
665
|
if (rawArgs.length === 0) {
|
|
743
666
|
return {
|
|
@@ -760,7 +683,6 @@ function prepareArguments(rawArgs) {
|
|
|
760
683
|
transferables: transferables.length === 0 ? transferables : dedupe(transferables)
|
|
761
684
|
};
|
|
762
685
|
}
|
|
763
|
-
__name(prepareArguments, "prepareArguments");
|
|
764
686
|
function createProxyFunction(worker, method) {
|
|
765
687
|
return (...rawArgs) => {
|
|
766
688
|
const uid = nextJobUID++;
|
|
@@ -768,7 +690,7 @@ function createProxyFunction(worker, method) {
|
|
|
768
690
|
const runMessage = {
|
|
769
691
|
args,
|
|
770
692
|
method,
|
|
771
|
-
type:
|
|
693
|
+
type: "run" /* run */,
|
|
772
694
|
uid
|
|
773
695
|
};
|
|
774
696
|
debugMessages("Sending command to run function to worker:", runMessage);
|
|
@@ -780,7 +702,6 @@ function createProxyFunction(worker, method) {
|
|
|
780
702
|
return ObservablePromise.from(multicast2(createObservableForJob(worker, uid)));
|
|
781
703
|
};
|
|
782
704
|
}
|
|
783
|
-
__name(createProxyFunction, "createProxyFunction");
|
|
784
705
|
function createProxyModule(worker, methodNames) {
|
|
785
706
|
const proxy = {};
|
|
786
707
|
for (const methodName of methodNames) {
|
|
@@ -788,31 +709,26 @@ function createProxyModule(worker, methodNames) {
|
|
|
788
709
|
}
|
|
789
710
|
return proxy;
|
|
790
711
|
}
|
|
791
|
-
__name(createProxyModule, "createProxyModule");
|
|
792
712
|
|
|
793
713
|
// src/master/spawn.ts
|
|
794
714
|
var debugMessages2 = DebugLogger3("threads:master:messages");
|
|
795
715
|
var debugSpawn = DebugLogger3("threads:master:spawn");
|
|
796
716
|
var debugThreadUtils = DebugLogger3("threads:master:thread-utils");
|
|
797
|
-
var isInitMessage =
|
|
798
|
-
var isUncaughtErrorMessage =
|
|
717
|
+
var isInitMessage = (data) => data && data.type === "init";
|
|
718
|
+
var isUncaughtErrorMessage = (data) => data && data.type === "uncaughtError";
|
|
799
719
|
var initMessageTimeout = typeof process !== "undefined" && process.env !== void 0 && process.env.THREADS_WORKER_INIT_TIMEOUT ? Number.parseInt(process.env.THREADS_WORKER_INIT_TIMEOUT, 10) : 1e4;
|
|
800
720
|
async function withTimeout(promise, timeoutInMs, errorMessage) {
|
|
801
721
|
let timeoutHandle;
|
|
802
722
|
const timeout = new Promise((resolve, reject) => {
|
|
803
723
|
timeoutHandle = setTimeout(() => reject(new Error(errorMessage)), timeoutInMs);
|
|
804
724
|
});
|
|
805
|
-
const result = await Promise.race([
|
|
806
|
-
promise,
|
|
807
|
-
timeout
|
|
808
|
-
]);
|
|
725
|
+
const result = await Promise.race([promise, timeout]);
|
|
809
726
|
clearTimeout(timeoutHandle);
|
|
810
727
|
return result;
|
|
811
728
|
}
|
|
812
|
-
__name(withTimeout, "withTimeout");
|
|
813
729
|
function receiveInitMessage(worker) {
|
|
814
730
|
return new Promise((resolve, reject) => {
|
|
815
|
-
const messageHandler =
|
|
731
|
+
const messageHandler = (event) => {
|
|
816
732
|
debugMessages2("Message from worker before finishing initialization:", event.data);
|
|
817
733
|
if (isInitMessage(event.data)) {
|
|
818
734
|
worker.removeEventListener("message", messageHandler);
|
|
@@ -821,34 +737,31 @@ function receiveInitMessage(worker) {
|
|
|
821
737
|
worker.removeEventListener("message", messageHandler);
|
|
822
738
|
reject(deserialize(event.data.error));
|
|
823
739
|
}
|
|
824
|
-
}
|
|
740
|
+
};
|
|
825
741
|
worker.addEventListener("message", messageHandler);
|
|
826
742
|
});
|
|
827
743
|
}
|
|
828
|
-
__name(receiveInitMessage, "receiveInitMessage");
|
|
829
744
|
function createEventObservable(worker, workerTermination) {
|
|
830
745
|
return new Observable4((observer) => {
|
|
831
|
-
const messageHandler =
|
|
746
|
+
const messageHandler = (messageEvent) => {
|
|
832
747
|
const workerEvent = {
|
|
833
748
|
data: messageEvent.data,
|
|
834
|
-
type:
|
|
749
|
+
type: "message" /* message */
|
|
835
750
|
};
|
|
836
751
|
observer.next(workerEvent);
|
|
837
|
-
}
|
|
838
|
-
const rejectionHandler =
|
|
752
|
+
};
|
|
753
|
+
const rejectionHandler = (errorEvent) => {
|
|
839
754
|
debugThreadUtils("Unhandled promise rejection event in thread:", errorEvent);
|
|
840
755
|
const workerEvent = {
|
|
841
756
|
error: new Error(errorEvent.reason),
|
|
842
|
-
type:
|
|
757
|
+
type: "internalError" /* internalError */
|
|
843
758
|
};
|
|
844
759
|
observer.next(workerEvent);
|
|
845
|
-
}
|
|
760
|
+
};
|
|
846
761
|
worker.addEventListener("message", messageHandler);
|
|
847
762
|
worker.addEventListener("unhandledrejection", rejectionHandler);
|
|
848
763
|
workerTermination.then(() => {
|
|
849
|
-
const terminationEvent = {
|
|
850
|
-
type: WorkerEventType.termination
|
|
851
|
-
};
|
|
764
|
+
const terminationEvent = { type: "termination" /* termination */ };
|
|
852
765
|
worker.removeEventListener("message", messageHandler);
|
|
853
766
|
worker.removeEventListener("unhandledrejection", rejectionHandler);
|
|
854
767
|
observer.next(terminationEvent);
|
|
@@ -856,22 +769,17 @@ function createEventObservable(worker, workerTermination) {
|
|
|
856
769
|
});
|
|
857
770
|
});
|
|
858
771
|
}
|
|
859
|
-
__name(createEventObservable, "createEventObservable");
|
|
860
772
|
function createTerminator(worker) {
|
|
861
773
|
const [termination, resolver] = createPromiseWithResolver();
|
|
862
|
-
const terminate =
|
|
774
|
+
const terminate = async () => {
|
|
863
775
|
debugThreadUtils("Terminating worker");
|
|
864
776
|
await worker.terminate();
|
|
865
777
|
resolver();
|
|
866
|
-
}, "terminate");
|
|
867
|
-
return {
|
|
868
|
-
terminate,
|
|
869
|
-
termination
|
|
870
778
|
};
|
|
779
|
+
return { terminate, termination };
|
|
871
780
|
}
|
|
872
|
-
__name(createTerminator, "createTerminator");
|
|
873
781
|
function setPrivateThreadProps(raw, worker, workerEvents, terminate) {
|
|
874
|
-
const workerErrors = workerEvents.filter((event) => event.type ===
|
|
782
|
+
const workerErrors = workerEvents.filter((event) => event.type === "internalError" /* internalError */).map((errorEvent) => errorEvent.error);
|
|
875
783
|
return Object.assign(raw, {
|
|
876
784
|
[$errors]: workerErrors,
|
|
877
785
|
[$events]: workerEvents,
|
|
@@ -879,11 +787,14 @@ function setPrivateThreadProps(raw, worker, workerEvents, terminate) {
|
|
|
879
787
|
[$worker]: worker
|
|
880
788
|
});
|
|
881
789
|
}
|
|
882
|
-
__name(setPrivateThreadProps, "setPrivateThreadProps");
|
|
883
790
|
async function spawn(worker, options) {
|
|
884
791
|
debugSpawn("Initializing new thread");
|
|
885
792
|
const timeout = options && options.timeout ? options.timeout : initMessageTimeout;
|
|
886
|
-
const initMessage = await withTimeout(
|
|
793
|
+
const initMessage = await withTimeout(
|
|
794
|
+
receiveInitMessage(worker),
|
|
795
|
+
timeout,
|
|
796
|
+
`Timeout: Did not receive an init message from worker after ${timeout}ms. Make sure the worker calls expose().`
|
|
797
|
+
);
|
|
887
798
|
const exposed = initMessage.exposed;
|
|
888
799
|
const { termination, terminate } = createTerminator(worker);
|
|
889
800
|
const events = createEventObservable(worker, termination);
|
|
@@ -898,7 +809,6 @@ async function spawn(worker, options) {
|
|
|
898
809
|
throw new Error(`Worker init message states unexpected type of expose(): ${type}`);
|
|
899
810
|
}
|
|
900
811
|
}
|
|
901
|
-
__name(spawn, "spawn");
|
|
902
812
|
|
|
903
813
|
// src/master/index-browser.ts
|
|
904
814
|
var BlobWorker = getWorkerImplementation().blob;
|