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