@rspack/core 1.3.15 → 1.4.0-beta.1
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/compiled/@swc/types/index.d.ts +18 -2
- package/compiled/@swc/types/package.json +1 -1
- package/compiled/tinypool/README.md +4 -196
- package/compiled/tinypool/dist/common-Qw-RoVFD.js +28 -0
- package/compiled/tinypool/dist/entry/process.d.ts +1 -2
- package/compiled/tinypool/dist/entry/process.js +63 -83
- package/compiled/tinypool/dist/entry/utils.d.ts +3 -1
- package/compiled/tinypool/dist/entry/utils.js +3 -9
- package/compiled/tinypool/dist/entry/worker.d.ts +1 -2
- package/compiled/tinypool/dist/entry/worker.js +66 -94
- package/compiled/tinypool/dist/index.d.ts +132 -125
- package/compiled/tinypool/dist/index.js +771 -1035
- package/compiled/tinypool/dist/utils-B--2TaWv.js +38 -0
- package/compiled/tinypool/dist/utils-De75vAgL.js +10 -0
- package/compiled/tinypool/package.json +6 -22
- package/compiled/zod/dist/types/v4/classic/schemas.d.ts +19 -14
- package/compiled/zod/dist/types/v4/core/api.d.ts +5 -4
- package/compiled/zod/dist/types/v4/core/checks.d.ts +1 -1
- package/compiled/zod/dist/types/v4/core/core.d.ts +1 -1
- package/compiled/zod/dist/types/v4/core/registries.d.ts +3 -1
- package/compiled/zod/dist/types/v4/core/schemas.d.ts +33 -39
- package/compiled/zod/dist/types/v4/core/to-json-schema.d.ts +2 -2
- package/compiled/zod/dist/types/v4/core/util.d.ts +1 -1
- package/compiled/zod/dist/types/v4/locales/index.d.ts +1 -0
- package/compiled/zod/dist/types/v4/locales/ps.d.ts +4 -0
- package/compiled/zod/dist/types/v4/mini/schemas.d.ts +77 -125
- package/compiled/zod/index.js +33 -33
- package/compiled/zod/package.json +1 -1
- package/dist/BuildInfo.d.ts +17 -0
- package/dist/FileSystem.d.ts +26 -3
- package/dist/Module.d.ts +1 -13
- package/dist/MultiCompiler.d.ts +4 -1
- package/dist/MultiWatching.d.ts +1 -0
- package/dist/builtin-loader/swc/types.d.ts +315 -296
- package/dist/builtin-plugin/lazy-compilation/middleware.d.ts +3 -3
- package/dist/config/devServer.d.ts +10 -10
- package/dist/config/normalization.d.ts +2 -0
- package/dist/config/types.d.ts +17 -1
- package/dist/config/utils.d.ts +1 -0
- package/dist/config/zod.d.ts +1707 -1086
- package/dist/cssExtractLoader.js +5 -5
- package/dist/exports.d.ts +5 -2
- package/dist/index.js +1130 -982
- package/dist/loader-runner/index.d.ts +0 -9
- package/dist/swc.d.ts +2 -0
- package/dist/trace/index.d.ts +16 -18
- package/dist/worker.js +2 -2
- package/module.d.ts +1 -1
- package/package.json +10 -10
- package/compiled/tinypool/dist/chunk-6LX4VMOV.js +0 -31
- package/compiled/tinypool/dist/chunk-ACQHDOFQ.js +0 -12
- package/compiled/tinypool/dist/chunk-E2J7JLFN.js +0 -53
- package/compiled/tinypool/dist/chunk-UBWFVGJX.js +0 -38
@@ -1,1080 +1,816 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
} from "
|
13
|
-
import {
|
14
|
-
__privateAdd,
|
15
|
-
__privateGet,
|
16
|
-
__privateSet,
|
17
|
-
__publicField
|
18
|
-
} from "./chunk-6LX4VMOV.js";
|
1
|
+
import { isMovable, isTaskQueue, isTransferable, kFieldCount, kQueueOptions, kRequestCountField, kResponseCountField, kTransferable, kValue, markMovable } from "./common-Qw-RoVFD.js";
|
2
|
+
import { MessageChannel, MessagePort, Worker, receiveMessageOnPort } from "node:worker_threads";
|
3
|
+
import { EventEmitterAsyncResource, once } from "node:events";
|
4
|
+
import { AsyncResource } from "node:async_hooks";
|
5
|
+
import { URL, fileURLToPath } from "node:url";
|
6
|
+
import { join } from "node:path";
|
7
|
+
import { inspect, types } from "node:util";
|
8
|
+
import assert from "node:assert";
|
9
|
+
import { performance } from "node:perf_hooks";
|
10
|
+
import { readFileSync } from "node:fs";
|
11
|
+
import os from "node:os";
|
12
|
+
import childProcess, { fork } from "node:child_process";
|
19
13
|
|
20
|
-
|
21
|
-
import {
|
22
|
-
MessageChannel,
|
23
|
-
receiveMessageOnPort
|
24
|
-
} from "worker_threads";
|
25
|
-
import { once, EventEmitterAsyncResource } from "events";
|
26
|
-
import { AsyncResource } from "async_hooks";
|
27
|
-
import { fileURLToPath as fileURLToPath3, URL } from "url";
|
28
|
-
import { join } from "path";
|
29
|
-
import { inspect, types } from "util";
|
30
|
-
import assert from "assert";
|
31
|
-
import { performance } from "perf_hooks";
|
32
|
-
import { readFileSync } from "fs";
|
33
|
-
|
34
|
-
// src/physicalCpuCount.ts
|
35
|
-
import os from "os";
|
36
|
-
import childProcess from "child_process";
|
14
|
+
//#region src/physicalCpuCount.ts
|
37
15
|
function exec(command) {
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
16
|
+
const output = childProcess.execSync(command, {
|
17
|
+
encoding: "utf8",
|
18
|
+
stdio: [
|
19
|
+
null,
|
20
|
+
null,
|
21
|
+
null
|
22
|
+
]
|
23
|
+
});
|
24
|
+
return output;
|
43
25
|
}
|
44
|
-
|
26
|
+
let amount;
|
45
27
|
try {
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
const isOdd = index % 2 === 1;
|
66
|
-
return !hasHyperthreading || isOdd;
|
67
|
-
});
|
68
|
-
amount = cores.length;
|
69
|
-
}
|
28
|
+
const platform = os.platform();
|
29
|
+
if (platform === "linux") {
|
30
|
+
const output1 = exec("cat /proc/cpuinfo | grep \"physical id\" | sort |uniq | wc -l");
|
31
|
+
const output2 = exec("cat /proc/cpuinfo | grep \"core id\" | sort | uniq | wc -l");
|
32
|
+
const physicalCpuAmount = parseInt(output1.trim(), 10);
|
33
|
+
const physicalCoreAmount = parseInt(output2.trim(), 10);
|
34
|
+
amount = physicalCpuAmount * physicalCoreAmount;
|
35
|
+
} else if (platform === "darwin") {
|
36
|
+
const output = exec("sysctl -n hw.physicalcpu_max");
|
37
|
+
amount = parseInt(output.trim(), 10);
|
38
|
+
} else if (platform === "win32") throw new Error();
|
39
|
+
else {
|
40
|
+
const cores = os.cpus().filter(function(cpu, index) {
|
41
|
+
const hasHyperthreading = cpu.model.includes("Intel");
|
42
|
+
const isOdd = index % 2 === 1;
|
43
|
+
return !hasHyperthreading || isOdd;
|
44
|
+
});
|
45
|
+
amount = cores.length;
|
46
|
+
}
|
70
47
|
} catch {
|
71
|
-
|
72
|
-
}
|
73
|
-
if (amount === 0) {
|
74
|
-
amount = os.cpus().length;
|
48
|
+
amount = os.cpus().length;
|
75
49
|
}
|
50
|
+
if (amount === 0) amount = os.cpus().length;
|
76
51
|
|
77
|
-
|
78
|
-
|
79
|
-
import { Worker } from "worker_threads";
|
52
|
+
//#endregion
|
53
|
+
//#region src/runtime/thread-worker.ts
|
80
54
|
var ThreadWorker = class {
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
throw new Error(
|
117
|
-
"{ runtime: 'worker_threads' } doesn't support channel. Use transferListItem instead."
|
118
|
-
);
|
119
|
-
}
|
55
|
+
name = "ThreadWorker";
|
56
|
+
runtime = "worker_threads";
|
57
|
+
initialize(options) {
|
58
|
+
this.thread = new Worker(fileURLToPath(import.meta.url + "/../entry/worker.js"), options);
|
59
|
+
this.threadId = this.thread.threadId;
|
60
|
+
}
|
61
|
+
async terminate() {
|
62
|
+
const output = await this.thread.terminate();
|
63
|
+
this.channel?.onClose?.();
|
64
|
+
return output;
|
65
|
+
}
|
66
|
+
postMessage(message, transferListItem) {
|
67
|
+
return this.thread.postMessage(message, transferListItem);
|
68
|
+
}
|
69
|
+
on(event, callback) {
|
70
|
+
return this.thread.on(event, callback);
|
71
|
+
}
|
72
|
+
once(event, callback) {
|
73
|
+
return this.thread.once(event, callback);
|
74
|
+
}
|
75
|
+
emit(event, ...data) {
|
76
|
+
return this.thread.emit(event, ...data);
|
77
|
+
}
|
78
|
+
ref() {
|
79
|
+
return this.thread.ref();
|
80
|
+
}
|
81
|
+
unref() {
|
82
|
+
return this.thread.unref();
|
83
|
+
}
|
84
|
+
setChannel(channel) {
|
85
|
+
if (channel.onMessage) throw new Error("{ runtime: 'worker_threads' } doesn't support channel.onMessage. Use transferListItem for listening to messages instead.");
|
86
|
+
if (channel.postMessage) throw new Error("{ runtime: 'worker_threads' } doesn't support channel.postMessage. Use transferListItem for sending to messages instead.");
|
87
|
+
if (this.channel && this.channel !== channel) this.channel.onClose?.();
|
88
|
+
this.channel = channel;
|
89
|
+
}
|
120
90
|
};
|
121
91
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
var __tinypool_worker_message__ = true;
|
127
|
-
var SIGKILL_TIMEOUT = 1e3;
|
92
|
+
//#endregion
|
93
|
+
//#region src/runtime/process-worker.ts
|
94
|
+
const __tinypool_worker_message__ = true;
|
95
|
+
const SIGKILL_TIMEOUT = 1e3;
|
128
96
|
var ProcessWorker = class {
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
return callback(data);
|
214
|
-
}
|
215
|
-
if (!data || !data.__tinypool_worker_message__) {
|
216
|
-
return this.channel?.postMessage(data);
|
217
|
-
}
|
218
|
-
if (data.source === "pool") {
|
219
|
-
callback(data);
|
220
|
-
} else if (data.source === "port") {
|
221
|
-
this.port.postMessage(data);
|
222
|
-
}
|
223
|
-
});
|
224
|
-
}
|
225
|
-
once(event, callback) {
|
226
|
-
return this.process.once(event, callback);
|
227
|
-
}
|
228
|
-
emit(event, ...data) {
|
229
|
-
return this.process.emit(event, ...data);
|
230
|
-
}
|
231
|
-
ref() {
|
232
|
-
return this.process.ref();
|
233
|
-
}
|
234
|
-
unref() {
|
235
|
-
this.port?.unref();
|
236
|
-
this.process.channel?.unref();
|
237
|
-
if (hasUnref(this.process.stdout)) {
|
238
|
-
this.process.stdout.unref();
|
239
|
-
}
|
240
|
-
if (hasUnref(this.process.stderr)) {
|
241
|
-
this.process.stderr.unref();
|
242
|
-
}
|
243
|
-
return this.process.unref();
|
244
|
-
}
|
97
|
+
name = "ProcessWorker";
|
98
|
+
runtime = "child_process";
|
99
|
+
isTerminating = false;
|
100
|
+
initialize(options) {
|
101
|
+
this.process = fork(fileURLToPath(import.meta.url + "/../entry/process.js"), options.argv, {
|
102
|
+
...options,
|
103
|
+
stdio: "pipe",
|
104
|
+
env: {
|
105
|
+
...options.env,
|
106
|
+
TINYPOOL_WORKER_ID: options.workerData[0].workerId.toString()
|
107
|
+
}
|
108
|
+
});
|
109
|
+
process.stdout.setMaxListeners(1 + process.stdout.getMaxListeners());
|
110
|
+
process.stderr.setMaxListeners(1 + process.stderr.getMaxListeners());
|
111
|
+
this.process.stdout?.pipe(process.stdout);
|
112
|
+
this.process.stderr?.pipe(process.stderr);
|
113
|
+
this.threadId = this.process.pid;
|
114
|
+
this.process.on("exit", this.onUnexpectedExit);
|
115
|
+
this.waitForExit = new Promise((r) => this.process.on("exit", r));
|
116
|
+
}
|
117
|
+
onUnexpectedExit = () => {
|
118
|
+
this.process.emit("error", new Error("Worker exited unexpectedly"));
|
119
|
+
};
|
120
|
+
async terminate() {
|
121
|
+
this.isTerminating = true;
|
122
|
+
this.process.off("exit", this.onUnexpectedExit);
|
123
|
+
const sigkillTimeout = setTimeout(() => this.process.kill("SIGKILL"), SIGKILL_TIMEOUT);
|
124
|
+
this.process.kill();
|
125
|
+
await this.waitForExit;
|
126
|
+
this.process.stdout?.unpipe(process.stdout);
|
127
|
+
this.process.stderr?.unpipe(process.stderr);
|
128
|
+
this.port?.close();
|
129
|
+
this.channel?.onClose?.();
|
130
|
+
clearTimeout(sigkillTimeout);
|
131
|
+
}
|
132
|
+
setChannel(channel) {
|
133
|
+
if (this.channel && this.channel !== channel) this.channel.onClose?.();
|
134
|
+
this.channel = channel;
|
135
|
+
this.channel.onMessage?.((message) => {
|
136
|
+
this.send(message);
|
137
|
+
});
|
138
|
+
}
|
139
|
+
send(message) {
|
140
|
+
if (!this.isTerminating) this.process.send(message);
|
141
|
+
}
|
142
|
+
postMessage(message, transferListItem) {
|
143
|
+
transferListItem?.forEach((item) => {
|
144
|
+
if (item instanceof MessagePort) this.port = item;
|
145
|
+
});
|
146
|
+
if (this.port) this.port.on("message", (message$1) => this.send({
|
147
|
+
...message$1,
|
148
|
+
source: "port",
|
149
|
+
__tinypool_worker_message__
|
150
|
+
}));
|
151
|
+
return this.send({
|
152
|
+
...message,
|
153
|
+
source: "pool",
|
154
|
+
__tinypool_worker_message__
|
155
|
+
});
|
156
|
+
}
|
157
|
+
on(event, callback) {
|
158
|
+
return this.process.on(event, (data) => {
|
159
|
+
if (event === "error") return callback(data);
|
160
|
+
if (!data || !data.__tinypool_worker_message__) return this.channel?.postMessage?.(data);
|
161
|
+
if (data.source === "pool") callback(data);
|
162
|
+
else if (data.source === "port") this.port.postMessage(data);
|
163
|
+
});
|
164
|
+
}
|
165
|
+
once(event, callback) {
|
166
|
+
return this.process.once(event, callback);
|
167
|
+
}
|
168
|
+
emit(event, ...data) {
|
169
|
+
return this.process.emit(event, ...data);
|
170
|
+
}
|
171
|
+
ref() {
|
172
|
+
return this.process.ref();
|
173
|
+
}
|
174
|
+
unref() {
|
175
|
+
this.port?.unref();
|
176
|
+
this.process.channel?.unref();
|
177
|
+
if (hasUnref(this.process.stdout)) this.process.stdout.unref();
|
178
|
+
if (hasUnref(this.process.stderr)) this.process.stderr.unref();
|
179
|
+
return this.process.unref();
|
180
|
+
}
|
245
181
|
};
|
246
182
|
function hasUnref(stream) {
|
247
|
-
|
183
|
+
return stream != null && "unref" in stream && typeof stream.unref === "function";
|
248
184
|
}
|
249
185
|
|
250
|
-
|
251
|
-
|
186
|
+
//#endregion
|
187
|
+
//#region src/index.ts
|
188
|
+
const cpuCount = amount;
|
252
189
|
function onabort(abortSignal, listener) {
|
253
|
-
|
254
|
-
|
255
|
-
} else {
|
256
|
-
abortSignal.once("abort", listener);
|
257
|
-
}
|
190
|
+
if ("addEventListener" in abortSignal) abortSignal.addEventListener("abort", listener, { once: true });
|
191
|
+
else abortSignal.once("abort", listener);
|
258
192
|
}
|
259
193
|
var AbortError = class extends Error {
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
194
|
+
constructor() {
|
195
|
+
super("The task has been aborted");
|
196
|
+
}
|
197
|
+
get name() {
|
198
|
+
return "AbortError";
|
199
|
+
}
|
266
200
|
};
|
267
201
|
var CancelError = class extends Error {
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
202
|
+
constructor() {
|
203
|
+
super("The task has been cancelled");
|
204
|
+
}
|
205
|
+
get name() {
|
206
|
+
return "CancelError";
|
207
|
+
}
|
274
208
|
};
|
275
209
|
var ArrayTaskQueue = class {
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
}
|
298
|
-
}
|
210
|
+
tasks = [];
|
211
|
+
get size() {
|
212
|
+
return this.tasks.length;
|
213
|
+
}
|
214
|
+
shift() {
|
215
|
+
return this.tasks.shift();
|
216
|
+
}
|
217
|
+
push(task) {
|
218
|
+
this.tasks.push(task);
|
219
|
+
}
|
220
|
+
remove(task) {
|
221
|
+
const index = this.tasks.indexOf(task);
|
222
|
+
assert.notStrictEqual(index, -1);
|
223
|
+
this.tasks.splice(index, 1);
|
224
|
+
}
|
225
|
+
cancel() {
|
226
|
+
while (this.tasks.length > 0) {
|
227
|
+
const task = this.tasks.pop();
|
228
|
+
task?.cancel();
|
229
|
+
}
|
230
|
+
}
|
299
231
|
};
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
232
|
+
const kDefaultOptions = {
|
233
|
+
filename: null,
|
234
|
+
name: "default",
|
235
|
+
runtime: "worker_threads",
|
236
|
+
minThreads: Math.max(cpuCount / 2, 1),
|
237
|
+
maxThreads: cpuCount,
|
238
|
+
idleTimeout: 0,
|
239
|
+
maxQueue: Infinity,
|
240
|
+
concurrentTasksPerWorker: 1,
|
241
|
+
useAtomics: true,
|
242
|
+
taskQueue: new ArrayTaskQueue(),
|
243
|
+
trackUnmanagedFds: true
|
312
244
|
};
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
245
|
+
const kDefaultRunOptions = {
|
246
|
+
transferList: void 0,
|
247
|
+
filename: null,
|
248
|
+
signal: null,
|
249
|
+
name: null
|
318
250
|
};
|
319
|
-
var _value;
|
320
251
|
var DirectlyTransferable = class {
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
252
|
+
#value;
|
253
|
+
constructor(value) {
|
254
|
+
this.#value = value;
|
255
|
+
}
|
256
|
+
get [kTransferable]() {
|
257
|
+
return this.#value;
|
258
|
+
}
|
259
|
+
get [kValue]() {
|
260
|
+
return this.#value;
|
261
|
+
}
|
331
262
|
};
|
332
|
-
_value = new WeakMap();
|
333
|
-
var _view;
|
334
263
|
var ArrayBufferViewTransferable = class {
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
264
|
+
#view;
|
265
|
+
constructor(view) {
|
266
|
+
this.#view = view;
|
267
|
+
}
|
268
|
+
get [kTransferable]() {
|
269
|
+
return this.#view.buffer;
|
270
|
+
}
|
271
|
+
get [kValue]() {
|
272
|
+
return this.#view;
|
273
|
+
}
|
345
274
|
};
|
346
|
-
|
347
|
-
var taskIdCounter = 0;
|
275
|
+
let taskIdCounter = 0;
|
348
276
|
function maybeFileURLToPath(filename) {
|
349
|
-
|
277
|
+
return filename.startsWith("file:") ? fileURLToPath(new URL(filename)) : filename;
|
350
278
|
}
|
351
279
|
var TaskInfo = class extends AsyncResource {
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
done(err, result) {
|
392
|
-
this.emitDestroy();
|
393
|
-
this.runInAsyncScope(this.callback, null, err, result);
|
394
|
-
if (this.abortSignal && this.abortListener) {
|
395
|
-
if ("removeEventListener" in this.abortSignal && this.abortListener) {
|
396
|
-
this.abortSignal.removeEventListener("abort", this.abortListener);
|
397
|
-
} else {
|
398
|
-
;
|
399
|
-
this.abortSignal.off(
|
400
|
-
"abort",
|
401
|
-
this.abortListener
|
402
|
-
);
|
403
|
-
}
|
404
|
-
}
|
405
|
-
}
|
406
|
-
get [kQueueOptions]() {
|
407
|
-
return kQueueOptions in this.task ? this.task[kQueueOptions] : null;
|
408
|
-
}
|
280
|
+
abortListener = null;
|
281
|
+
workerInfo = null;
|
282
|
+
constructor(task, transferList, filename, name, callback, abortSignal, triggerAsyncId, channel) {
|
283
|
+
super("Tinypool.Task", {
|
284
|
+
requireManualDestroy: true,
|
285
|
+
triggerAsyncId
|
286
|
+
});
|
287
|
+
this.callback = callback;
|
288
|
+
this.task = task;
|
289
|
+
this.transferList = transferList;
|
290
|
+
this.cancel = () => this.callback(new CancelError(), null);
|
291
|
+
this.channel = channel;
|
292
|
+
if (isMovable(task)) {
|
293
|
+
/* istanbul ignore if */
|
294
|
+
if (this.transferList == null) this.transferList = [];
|
295
|
+
this.transferList = this.transferList.concat(task[kTransferable]);
|
296
|
+
this.task = task[kValue];
|
297
|
+
}
|
298
|
+
this.filename = filename;
|
299
|
+
this.name = name;
|
300
|
+
this.taskId = taskIdCounter++;
|
301
|
+
this.abortSignal = abortSignal;
|
302
|
+
this.created = performance.now();
|
303
|
+
this.started = 0;
|
304
|
+
}
|
305
|
+
releaseTask() {
|
306
|
+
const ret = this.task;
|
307
|
+
this.task = null;
|
308
|
+
return ret;
|
309
|
+
}
|
310
|
+
done(err, result) {
|
311
|
+
this.emitDestroy();
|
312
|
+
this.runInAsyncScope(this.callback, null, err, result);
|
313
|
+
if (this.abortSignal && this.abortListener) if ("removeEventListener" in this.abortSignal && this.abortListener) this.abortSignal.removeEventListener("abort", this.abortListener);
|
314
|
+
else this.abortSignal.off("abort", this.abortListener);
|
315
|
+
}
|
316
|
+
get [kQueueOptions]() {
|
317
|
+
return kQueueOptions in this.task ? this.task[kQueueOptions] : null;
|
318
|
+
}
|
409
319
|
};
|
410
320
|
var AsynchronouslyCreatedResource = class {
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
return;
|
429
|
-
}
|
430
|
-
this.onreadyListeners.push(fn);
|
431
|
-
}
|
321
|
+
onreadyListeners = [];
|
322
|
+
markAsReady() {
|
323
|
+
const listeners = this.onreadyListeners;
|
324
|
+
assert(listeners !== null);
|
325
|
+
this.onreadyListeners = null;
|
326
|
+
for (const listener of listeners) listener();
|
327
|
+
}
|
328
|
+
isReady() {
|
329
|
+
return this.onreadyListeners === null;
|
330
|
+
}
|
331
|
+
onReady(fn) {
|
332
|
+
if (this.onreadyListeners === null) {
|
333
|
+
fn();
|
334
|
+
return;
|
335
|
+
}
|
336
|
+
this.onreadyListeners.push(fn);
|
337
|
+
}
|
432
338
|
};
|
433
339
|
var AsynchronouslyCreatedResourcePool = class {
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
}
|
483
|
-
}
|
484
|
-
onAvailable(fn) {
|
485
|
-
this.onAvailableListeners.push(fn);
|
486
|
-
}
|
340
|
+
pendingItems = new Set();
|
341
|
+
readyItems = new Set();
|
342
|
+
constructor(maximumUsage) {
|
343
|
+
this.maximumUsage = maximumUsage;
|
344
|
+
this.onAvailableListeners = [];
|
345
|
+
}
|
346
|
+
add(item) {
|
347
|
+
this.pendingItems.add(item);
|
348
|
+
item.onReady(() => {
|
349
|
+
/* istanbul ignore else */
|
350
|
+
if (this.pendingItems.has(item)) {
|
351
|
+
this.pendingItems.delete(item);
|
352
|
+
this.readyItems.add(item);
|
353
|
+
this.maybeAvailable(item);
|
354
|
+
}
|
355
|
+
});
|
356
|
+
}
|
357
|
+
delete(item) {
|
358
|
+
this.pendingItems.delete(item);
|
359
|
+
this.readyItems.delete(item);
|
360
|
+
}
|
361
|
+
findAvailable() {
|
362
|
+
let minUsage = this.maximumUsage;
|
363
|
+
let candidate = null;
|
364
|
+
for (const item of this.readyItems) {
|
365
|
+
const usage = item.currentUsage();
|
366
|
+
if (usage === 0) return item;
|
367
|
+
if (usage < minUsage) {
|
368
|
+
candidate = item;
|
369
|
+
minUsage = usage;
|
370
|
+
}
|
371
|
+
}
|
372
|
+
return candidate;
|
373
|
+
}
|
374
|
+
*[Symbol.iterator]() {
|
375
|
+
yield* this.pendingItems;
|
376
|
+
yield* this.readyItems;
|
377
|
+
}
|
378
|
+
get size() {
|
379
|
+
return this.pendingItems.size + this.readyItems.size;
|
380
|
+
}
|
381
|
+
maybeAvailable(item) {
|
382
|
+
/* istanbul ignore else */
|
383
|
+
if (item.currentUsage() < this.maximumUsage) for (const listener of this.onAvailableListeners) listener(item);
|
384
|
+
}
|
385
|
+
onAvailable(fn) {
|
386
|
+
this.onAvailableListeners.push(fn);
|
387
|
+
}
|
487
388
|
};
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
389
|
+
const Errors = {
|
390
|
+
ThreadTermination: () => new Error("Terminating worker thread"),
|
391
|
+
FilenameNotProvided: () => new Error("filename must be provided to run() or in options object"),
|
392
|
+
TaskQueueAtLimit: () => new Error("Task queue is at limit"),
|
393
|
+
NoTaskQueueAvailable: () => new Error("No task queue available and all Workers are busy")
|
493
394
|
};
|
494
395
|
var WorkerInfo = class extends AsynchronouslyCreatedResource {
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
const actualResponseCount = Atomics.load(
|
594
|
-
this.sharedBuffer,
|
595
|
-
kResponseCountField
|
596
|
-
);
|
597
|
-
if (actualResponseCount !== this.lastSeenResponseCount) {
|
598
|
-
this.lastSeenResponseCount = actualResponseCount;
|
599
|
-
let entry;
|
600
|
-
while ((entry = receiveMessageOnPort(this.port)) !== void 0) {
|
601
|
-
this._handleResponse(entry.message);
|
602
|
-
}
|
603
|
-
}
|
604
|
-
}
|
605
|
-
isRunningAbortableTask() {
|
606
|
-
if (this.taskInfos.size !== 1)
|
607
|
-
return false;
|
608
|
-
const [first] = this.taskInfos;
|
609
|
-
const [, task] = first || [];
|
610
|
-
return task?.abortSignal !== null;
|
611
|
-
}
|
612
|
-
currentUsage() {
|
613
|
-
if (this.isRunningAbortableTask())
|
614
|
-
return Infinity;
|
615
|
-
return this.taskInfos.size;
|
616
|
-
}
|
396
|
+
idleTimeout = null;
|
397
|
+
lastSeenResponseCount = 0;
|
398
|
+
constructor(worker, port, workerId, freeWorkerId, onMessage, filename, teardown) {
|
399
|
+
super();
|
400
|
+
this.worker = worker;
|
401
|
+
this.workerId = workerId;
|
402
|
+
this.freeWorkerId = freeWorkerId;
|
403
|
+
this.teardown = teardown;
|
404
|
+
this.filename = filename;
|
405
|
+
this.port = port;
|
406
|
+
this.port.on("message", (message) => this._handleResponse(message));
|
407
|
+
this.onMessage = onMessage;
|
408
|
+
this.taskInfos = new Map();
|
409
|
+
this.sharedBuffer = new Int32Array(new SharedArrayBuffer(kFieldCount * Int32Array.BYTES_PER_ELEMENT));
|
410
|
+
}
|
411
|
+
async destroy(timeout) {
|
412
|
+
let resolve;
|
413
|
+
let reject;
|
414
|
+
const ret = new Promise((res, rej) => {
|
415
|
+
resolve = res;
|
416
|
+
reject = rej;
|
417
|
+
});
|
418
|
+
if (this.teardown && this.filename) {
|
419
|
+
const { teardown, filename } = this;
|
420
|
+
await new Promise((resolve$1, reject$1) => {
|
421
|
+
this.postTask(new TaskInfo({}, [], filename, teardown, (error, result) => error ? reject$1(error) : resolve$1(result), null, 1, void 0));
|
422
|
+
});
|
423
|
+
}
|
424
|
+
const timer = timeout ? setTimeout(() => reject(new Error("Failed to terminate worker")), timeout) : null;
|
425
|
+
this.worker.terminate().then(() => {
|
426
|
+
if (timer !== null) clearTimeout(timer);
|
427
|
+
this.port.close();
|
428
|
+
this.clearIdleTimeout();
|
429
|
+
for (const taskInfo of this.taskInfos.values()) taskInfo.done(Errors.ThreadTermination());
|
430
|
+
this.taskInfos.clear();
|
431
|
+
resolve();
|
432
|
+
});
|
433
|
+
return ret;
|
434
|
+
}
|
435
|
+
clearIdleTimeout() {
|
436
|
+
if (this.idleTimeout !== null) {
|
437
|
+
clearTimeout(this.idleTimeout);
|
438
|
+
this.idleTimeout = null;
|
439
|
+
}
|
440
|
+
}
|
441
|
+
ref() {
|
442
|
+
this.port.ref();
|
443
|
+
return this;
|
444
|
+
}
|
445
|
+
unref() {
|
446
|
+
this.port.unref();
|
447
|
+
return this;
|
448
|
+
}
|
449
|
+
_handleResponse(message) {
|
450
|
+
this.usedMemory = message.usedMemory;
|
451
|
+
this.onMessage(message);
|
452
|
+
if (this.taskInfos.size === 0) this.unref();
|
453
|
+
}
|
454
|
+
postTask(taskInfo) {
|
455
|
+
assert(!this.taskInfos.has(taskInfo.taskId));
|
456
|
+
const message = {
|
457
|
+
task: taskInfo.releaseTask(),
|
458
|
+
taskId: taskInfo.taskId,
|
459
|
+
filename: taskInfo.filename,
|
460
|
+
name: taskInfo.name
|
461
|
+
};
|
462
|
+
try {
|
463
|
+
if (taskInfo.channel) this.worker.setChannel?.(taskInfo.channel);
|
464
|
+
this.port.postMessage(message, taskInfo.transferList);
|
465
|
+
} catch (err) {
|
466
|
+
taskInfo.done(err);
|
467
|
+
return;
|
468
|
+
}
|
469
|
+
taskInfo.workerInfo = this;
|
470
|
+
this.taskInfos.set(taskInfo.taskId, taskInfo);
|
471
|
+
this.ref();
|
472
|
+
this.clearIdleTimeout();
|
473
|
+
Atomics.add(this.sharedBuffer, kRequestCountField, 1);
|
474
|
+
Atomics.notify(this.sharedBuffer, kRequestCountField, 1);
|
475
|
+
}
|
476
|
+
processPendingMessages() {
|
477
|
+
const actualResponseCount = Atomics.load(this.sharedBuffer, kResponseCountField);
|
478
|
+
if (actualResponseCount !== this.lastSeenResponseCount) {
|
479
|
+
this.lastSeenResponseCount = actualResponseCount;
|
480
|
+
let entry;
|
481
|
+
while ((entry = receiveMessageOnPort(this.port)) !== void 0) this._handleResponse(entry.message);
|
482
|
+
}
|
483
|
+
}
|
484
|
+
isRunningAbortableTask() {
|
485
|
+
if (this.taskInfos.size !== 1) return false;
|
486
|
+
const [first] = this.taskInfos;
|
487
|
+
const [, task] = first || [];
|
488
|
+
return task?.abortSignal !== null;
|
489
|
+
}
|
490
|
+
currentUsage() {
|
491
|
+
if (this.isRunningAbortableTask()) return Infinity;
|
492
|
+
return this.taskInfos.size;
|
493
|
+
}
|
617
494
|
};
|
618
495
|
var ThreadPool = class {
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
taskInfo.abortListener = () => {
|
855
|
-
reject(new AbortError());
|
856
|
-
if (taskInfo.workerInfo !== null) {
|
857
|
-
void this._removeWorker(taskInfo.workerInfo);
|
858
|
-
this._ensureMinimumWorkers();
|
859
|
-
} else {
|
860
|
-
this.taskQueue.remove(taskInfo);
|
861
|
-
}
|
862
|
-
};
|
863
|
-
onabort(signal, taskInfo.abortListener);
|
864
|
-
}
|
865
|
-
if (this.taskQueue.size > 0) {
|
866
|
-
const totalCapacity = this.options.maxQueue + this.pendingCapacity();
|
867
|
-
if (this.taskQueue.size >= totalCapacity) {
|
868
|
-
if (this.options.maxQueue === 0) {
|
869
|
-
return Promise.reject(Errors.NoTaskQueueAvailable());
|
870
|
-
} else {
|
871
|
-
return Promise.reject(Errors.TaskQueueAtLimit());
|
872
|
-
}
|
873
|
-
} else {
|
874
|
-
if (this.workers.size < this.options.maxThreads) {
|
875
|
-
this._addNewWorker();
|
876
|
-
}
|
877
|
-
this.taskQueue.push(taskInfo);
|
878
|
-
}
|
879
|
-
return ret;
|
880
|
-
}
|
881
|
-
let workerInfo = this.workers.findAvailable();
|
882
|
-
if (workerInfo !== null && workerInfo.currentUsage() > 0 && signal) {
|
883
|
-
workerInfo = null;
|
884
|
-
}
|
885
|
-
let waitingForNewWorker = false;
|
886
|
-
if ((workerInfo === null || workerInfo.currentUsage() > 0) && this.workers.size < this.options.maxThreads) {
|
887
|
-
this._addNewWorker();
|
888
|
-
waitingForNewWorker = true;
|
889
|
-
}
|
890
|
-
if (workerInfo === null) {
|
891
|
-
if (this.options.maxQueue <= 0 && !waitingForNewWorker) {
|
892
|
-
return Promise.reject(Errors.NoTaskQueueAvailable());
|
893
|
-
} else {
|
894
|
-
this.taskQueue.push(taskInfo);
|
895
|
-
}
|
896
|
-
return ret;
|
897
|
-
}
|
898
|
-
const now = performance.now();
|
899
|
-
taskInfo.started = now;
|
900
|
-
workerInfo.postTask(taskInfo);
|
901
|
-
this._maybeDrain();
|
902
|
-
return ret;
|
903
|
-
}
|
904
|
-
shouldRecycleWorker(taskInfo) {
|
905
|
-
if (taskInfo?.workerInfo?.shouldRecycle) {
|
906
|
-
return true;
|
907
|
-
}
|
908
|
-
if (this.options.isolateWorkers && taskInfo?.workerInfo) {
|
909
|
-
return true;
|
910
|
-
}
|
911
|
-
if (!this.options.isolateWorkers && this.options.maxMemoryLimitBeforeRecycle !== void 0 && (taskInfo?.workerInfo?.usedMemory || 0) > this.options.maxMemoryLimitBeforeRecycle) {
|
912
|
-
return true;
|
913
|
-
}
|
914
|
-
return false;
|
915
|
-
}
|
916
|
-
pendingCapacity() {
|
917
|
-
return this.workers.pendingItems.size * this.options.concurrentTasksPerWorker;
|
918
|
-
}
|
919
|
-
_maybeDrain() {
|
920
|
-
if (this.taskQueue.size === 0 && this.skipQueue.length === 0) {
|
921
|
-
this.publicInterface.emit("drain");
|
922
|
-
}
|
923
|
-
}
|
924
|
-
async destroy() {
|
925
|
-
while (this.skipQueue.length > 0) {
|
926
|
-
const taskInfo = this.skipQueue.shift();
|
927
|
-
taskInfo.done(new Error("Terminating worker thread"));
|
928
|
-
}
|
929
|
-
while (this.taskQueue.size > 0) {
|
930
|
-
const taskInfo = this.taskQueue.shift();
|
931
|
-
taskInfo.done(new Error("Terminating worker thread"));
|
932
|
-
}
|
933
|
-
const exitEvents = [];
|
934
|
-
while (this.workers.size > 0) {
|
935
|
-
const [workerInfo] = this.workers;
|
936
|
-
exitEvents.push(once(workerInfo.worker, "exit"));
|
937
|
-
void this._removeWorker(workerInfo);
|
938
|
-
}
|
939
|
-
await Promise.all(exitEvents);
|
940
|
-
}
|
941
|
-
async recycleWorkers(options = {}) {
|
942
|
-
const runtimeChanged = options?.runtime && options.runtime !== this.options.runtime;
|
943
|
-
if (options?.runtime) {
|
944
|
-
this.options.runtime = options.runtime;
|
945
|
-
}
|
946
|
-
if (this.options.isolateWorkers && !runtimeChanged) {
|
947
|
-
return;
|
948
|
-
}
|
949
|
-
const exitEvents = [];
|
950
|
-
Array.from(this.workers).filter((workerInfo) => {
|
951
|
-
if (workerInfo.currentUsage() === 0) {
|
952
|
-
exitEvents.push(once(workerInfo.worker, "exit"));
|
953
|
-
void this._removeWorker(workerInfo);
|
954
|
-
} else {
|
955
|
-
workerInfo.shouldRecycle = true;
|
956
|
-
}
|
957
|
-
});
|
958
|
-
await Promise.all(exitEvents);
|
959
|
-
this._ensureMinimumWorkers();
|
960
|
-
}
|
496
|
+
skipQueue = [];
|
497
|
+
completed = 0;
|
498
|
+
start = performance.now();
|
499
|
+
inProcessPendingMessages = false;
|
500
|
+
startingUp = false;
|
501
|
+
workerFailsDuringBootstrap = false;
|
502
|
+
constructor(publicInterface, options) {
|
503
|
+
this.publicInterface = publicInterface;
|
504
|
+
this.taskQueue = options.taskQueue || new ArrayTaskQueue();
|
505
|
+
const filename = options.filename ? maybeFileURLToPath(options.filename) : null;
|
506
|
+
this.options = {
|
507
|
+
...kDefaultOptions,
|
508
|
+
...options,
|
509
|
+
filename,
|
510
|
+
maxQueue: 0
|
511
|
+
};
|
512
|
+
if (options.maxThreads !== void 0 && this.options.minThreads >= options.maxThreads) this.options.minThreads = options.maxThreads;
|
513
|
+
if (options.minThreads !== void 0 && this.options.maxThreads <= options.minThreads) this.options.maxThreads = options.minThreads;
|
514
|
+
if (options.maxQueue === "auto") this.options.maxQueue = this.options.maxThreads ** 2;
|
515
|
+
else this.options.maxQueue = options.maxQueue ?? kDefaultOptions.maxQueue;
|
516
|
+
this.workerIds = new Map(new Array(this.options.maxThreads).fill(0).map((_, i) => [i + 1, true]));
|
517
|
+
this.workers = new AsynchronouslyCreatedResourcePool(this.options.concurrentTasksPerWorker);
|
518
|
+
this.workers.onAvailable((w) => this._onWorkerAvailable(w));
|
519
|
+
this.startingUp = true;
|
520
|
+
this._ensureMinimumWorkers();
|
521
|
+
this.startingUp = false;
|
522
|
+
}
|
523
|
+
_ensureEnoughWorkersForTaskQueue() {
|
524
|
+
while (this.workers.size < this.taskQueue.size && this.workers.size < this.options.maxThreads) this._addNewWorker();
|
525
|
+
}
|
526
|
+
_ensureMaximumWorkers() {
|
527
|
+
while (this.workers.size < this.options.maxThreads) this._addNewWorker();
|
528
|
+
}
|
529
|
+
_ensureMinimumWorkers() {
|
530
|
+
while (this.workers.size < this.options.minThreads) this._addNewWorker();
|
531
|
+
}
|
532
|
+
_addNewWorker() {
|
533
|
+
const workerIds = this.workerIds;
|
534
|
+
let workerId;
|
535
|
+
workerIds.forEach((isIdAvailable, _workerId$1) => {
|
536
|
+
if (isIdAvailable && !workerId) {
|
537
|
+
workerId = _workerId$1;
|
538
|
+
workerIds.set(_workerId$1, false);
|
539
|
+
}
|
540
|
+
});
|
541
|
+
const tinypoolPrivateData = { workerId };
|
542
|
+
const worker = this.options.runtime === "child_process" ? new ProcessWorker() : new ThreadWorker();
|
543
|
+
worker.initialize({
|
544
|
+
env: this.options.env,
|
545
|
+
argv: this.options.argv,
|
546
|
+
execArgv: this.options.execArgv,
|
547
|
+
resourceLimits: this.options.resourceLimits,
|
548
|
+
workerData: [tinypoolPrivateData, this.options.workerData],
|
549
|
+
trackUnmanagedFds: this.options.trackUnmanagedFds
|
550
|
+
});
|
551
|
+
const onMessage = (message$1) => {
|
552
|
+
const { taskId, result } = message$1;
|
553
|
+
const taskInfo = workerInfo.taskInfos.get(taskId);
|
554
|
+
workerInfo.taskInfos.delete(taskId);
|
555
|
+
if (!this.shouldRecycleWorker(taskInfo)) this.workers.maybeAvailable(workerInfo);
|
556
|
+
/* istanbul ignore if */
|
557
|
+
if (taskInfo === void 0) {
|
558
|
+
const err = new Error(`Unexpected message from Worker: ${inspect(message$1)}`);
|
559
|
+
this.publicInterface.emit("error", err);
|
560
|
+
} else taskInfo.done(message$1.error, result);
|
561
|
+
this._processPendingMessages();
|
562
|
+
};
|
563
|
+
const { port1, port2 } = new MessageChannel();
|
564
|
+
const workerInfo = new WorkerInfo(worker, port1, workerId, () => workerIds.set(workerId, true), onMessage, this.options.filename, this.options.teardown);
|
565
|
+
if (this.startingUp) workerInfo.markAsReady();
|
566
|
+
const message = {
|
567
|
+
filename: this.options.filename,
|
568
|
+
name: this.options.name,
|
569
|
+
port: port2,
|
570
|
+
sharedBuffer: workerInfo.sharedBuffer,
|
571
|
+
useAtomics: this.options.useAtomics
|
572
|
+
};
|
573
|
+
worker.postMessage(message, [port2]);
|
574
|
+
worker.on("message", (message$1) => {
|
575
|
+
if (message$1.ready === true) {
|
576
|
+
if (workerInfo.currentUsage() === 0) workerInfo.unref();
|
577
|
+
if (!workerInfo.isReady()) workerInfo.markAsReady();
|
578
|
+
return;
|
579
|
+
}
|
580
|
+
worker.emit("error", new Error(`Unexpected message on Worker: ${inspect(message$1)}`));
|
581
|
+
});
|
582
|
+
worker.on("error", (err) => {
|
583
|
+
worker.ref = () => {};
|
584
|
+
const taskInfos = [...workerInfo.taskInfos.values()];
|
585
|
+
workerInfo.taskInfos.clear();
|
586
|
+
this._removeWorker(workerInfo);
|
587
|
+
if (workerInfo.isReady() && !this.workerFailsDuringBootstrap) this._ensureMinimumWorkers();
|
588
|
+
else this.workerFailsDuringBootstrap = true;
|
589
|
+
if (taskInfos.length > 0) for (const taskInfo of taskInfos) taskInfo.done(err, null);
|
590
|
+
else this.publicInterface.emit("error", err);
|
591
|
+
});
|
592
|
+
worker.unref();
|
593
|
+
port1.on("close", () => {
|
594
|
+
worker.ref();
|
595
|
+
});
|
596
|
+
this.workers.add(workerInfo);
|
597
|
+
}
|
598
|
+
_processPendingMessages() {
|
599
|
+
if (this.inProcessPendingMessages || !this.options.useAtomics) return;
|
600
|
+
this.inProcessPendingMessages = true;
|
601
|
+
try {
|
602
|
+
for (const workerInfo of this.workers) workerInfo.processPendingMessages();
|
603
|
+
} finally {
|
604
|
+
this.inProcessPendingMessages = false;
|
605
|
+
}
|
606
|
+
}
|
607
|
+
_removeWorker(workerInfo) {
|
608
|
+
workerInfo.freeWorkerId();
|
609
|
+
this.workers.delete(workerInfo);
|
610
|
+
return workerInfo.destroy(this.options.terminateTimeout);
|
611
|
+
}
|
612
|
+
_onWorkerAvailable(workerInfo) {
|
613
|
+
while ((this.taskQueue.size > 0 || this.skipQueue.length > 0) && workerInfo.currentUsage() < this.options.concurrentTasksPerWorker) {
|
614
|
+
const taskInfo = this.skipQueue.shift() || this.taskQueue.shift();
|
615
|
+
if (taskInfo.abortSignal && workerInfo.taskInfos.size > 0) {
|
616
|
+
this.skipQueue.push(taskInfo);
|
617
|
+
break;
|
618
|
+
}
|
619
|
+
const now = performance.now();
|
620
|
+
taskInfo.started = now;
|
621
|
+
workerInfo.postTask(taskInfo);
|
622
|
+
this._maybeDrain();
|
623
|
+
return;
|
624
|
+
}
|
625
|
+
if (workerInfo.taskInfos.size === 0 && this.workers.size > this.options.minThreads) workerInfo.idleTimeout = setTimeout(() => {
|
626
|
+
assert.strictEqual(workerInfo.taskInfos.size, 0);
|
627
|
+
if (this.workers.size > this.options.minThreads) this._removeWorker(workerInfo);
|
628
|
+
}, this.options.idleTimeout).unref();
|
629
|
+
}
|
630
|
+
runTask(task, options) {
|
631
|
+
let { filename, name } = options;
|
632
|
+
const { transferList = [], signal = null, channel } = options;
|
633
|
+
if (filename == null) filename = this.options.filename;
|
634
|
+
if (name == null) name = this.options.name;
|
635
|
+
if (typeof filename !== "string") return Promise.reject(Errors.FilenameNotProvided());
|
636
|
+
filename = maybeFileURLToPath(filename);
|
637
|
+
let resolve;
|
638
|
+
let reject;
|
639
|
+
const ret = new Promise((res, rej) => {
|
640
|
+
resolve = res;
|
641
|
+
reject = rej;
|
642
|
+
});
|
643
|
+
const taskInfo = new TaskInfo(task, transferList, filename, name, (err, result) => {
|
644
|
+
this.completed++;
|
645
|
+
if (err !== null) reject(err);
|
646
|
+
if (this.shouldRecycleWorker(taskInfo)) this._removeWorker(taskInfo.workerInfo).then(() => this._ensureMinimumWorkers()).then(() => this._ensureEnoughWorkersForTaskQueue()).then(() => resolve(result)).catch(reject);
|
647
|
+
else resolve(result);
|
648
|
+
}, signal, this.publicInterface.asyncResource.asyncId(), channel);
|
649
|
+
if (signal !== null) {
|
650
|
+
if (signal.aborted) return Promise.reject(new AbortError());
|
651
|
+
taskInfo.abortListener = () => {
|
652
|
+
reject(new AbortError());
|
653
|
+
if (taskInfo.workerInfo !== null) {
|
654
|
+
this._removeWorker(taskInfo.workerInfo);
|
655
|
+
this._ensureMinimumWorkers();
|
656
|
+
} else this.taskQueue.remove(taskInfo);
|
657
|
+
};
|
658
|
+
onabort(signal, taskInfo.abortListener);
|
659
|
+
}
|
660
|
+
if (this.taskQueue.size > 0) {
|
661
|
+
const totalCapacity = this.options.maxQueue + this.pendingCapacity();
|
662
|
+
if (this.taskQueue.size >= totalCapacity) if (this.options.maxQueue === 0) return Promise.reject(Errors.NoTaskQueueAvailable());
|
663
|
+
else return Promise.reject(Errors.TaskQueueAtLimit());
|
664
|
+
else {
|
665
|
+
if (this.workers.size < this.options.maxThreads) this._addNewWorker();
|
666
|
+
this.taskQueue.push(taskInfo);
|
667
|
+
}
|
668
|
+
return ret;
|
669
|
+
}
|
670
|
+
let workerInfo = this.workers.findAvailable();
|
671
|
+
if (workerInfo !== null && workerInfo.currentUsage() > 0 && signal) workerInfo = null;
|
672
|
+
let waitingForNewWorker = false;
|
673
|
+
if ((workerInfo === null || workerInfo.currentUsage() > 0) && this.workers.size < this.options.maxThreads) {
|
674
|
+
this._addNewWorker();
|
675
|
+
waitingForNewWorker = true;
|
676
|
+
}
|
677
|
+
if (workerInfo === null) {
|
678
|
+
if (this.options.maxQueue <= 0 && !waitingForNewWorker) return Promise.reject(Errors.NoTaskQueueAvailable());
|
679
|
+
else this.taskQueue.push(taskInfo);
|
680
|
+
return ret;
|
681
|
+
}
|
682
|
+
const now = performance.now();
|
683
|
+
taskInfo.started = now;
|
684
|
+
workerInfo.postTask(taskInfo);
|
685
|
+
this._maybeDrain();
|
686
|
+
return ret;
|
687
|
+
}
|
688
|
+
shouldRecycleWorker(taskInfo) {
|
689
|
+
if (taskInfo?.workerInfo?.shouldRecycle) return true;
|
690
|
+
if (this.options.isolateWorkers && taskInfo?.workerInfo) return true;
|
691
|
+
if (!this.options.isolateWorkers && this.options.maxMemoryLimitBeforeRecycle !== void 0 && (taskInfo?.workerInfo?.usedMemory || 0) > this.options.maxMemoryLimitBeforeRecycle) return true;
|
692
|
+
return false;
|
693
|
+
}
|
694
|
+
pendingCapacity() {
|
695
|
+
return this.workers.pendingItems.size * this.options.concurrentTasksPerWorker;
|
696
|
+
}
|
697
|
+
_maybeDrain() {
|
698
|
+
if (this.taskQueue.size === 0 && this.skipQueue.length === 0) this.publicInterface.emit("drain");
|
699
|
+
}
|
700
|
+
async destroy() {
|
701
|
+
while (this.skipQueue.length > 0) {
|
702
|
+
const taskInfo = this.skipQueue.shift();
|
703
|
+
taskInfo.done(new Error("Terminating worker thread"));
|
704
|
+
}
|
705
|
+
while (this.taskQueue.size > 0) {
|
706
|
+
const taskInfo = this.taskQueue.shift();
|
707
|
+
taskInfo.done(new Error("Terminating worker thread"));
|
708
|
+
}
|
709
|
+
const exitEvents = [];
|
710
|
+
while (this.workers.size > 0) {
|
711
|
+
const [workerInfo] = this.workers;
|
712
|
+
exitEvents.push(once(workerInfo.worker, "exit"));
|
713
|
+
this._removeWorker(workerInfo);
|
714
|
+
}
|
715
|
+
await Promise.all(exitEvents);
|
716
|
+
}
|
717
|
+
async recycleWorkers(options = {}) {
|
718
|
+
const runtimeChanged = options?.runtime && options.runtime !== this.options.runtime;
|
719
|
+
if (options?.runtime) this.options.runtime = options.runtime;
|
720
|
+
if (this.options.isolateWorkers && !runtimeChanged) return;
|
721
|
+
const exitEvents = [];
|
722
|
+
Array.from(this.workers).filter((workerInfo) => {
|
723
|
+
if (workerInfo.currentUsage() === 0) {
|
724
|
+
exitEvents.push(once(workerInfo.worker, "exit"));
|
725
|
+
this._removeWorker(workerInfo);
|
726
|
+
} else workerInfo.shouldRecycle = true;
|
727
|
+
});
|
728
|
+
await Promise.all(exitEvents);
|
729
|
+
this._ensureMinimumWorkers();
|
730
|
+
}
|
961
731
|
};
|
962
|
-
var _pool;
|
963
732
|
var Tinypool = class extends EventEmitterAsyncResource {
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
if (!isTransferable(val)) {
|
1043
|
-
if (types.isArrayBufferView(val)) {
|
1044
|
-
val = new ArrayBufferViewTransferable(val);
|
1045
|
-
} else {
|
1046
|
-
val = new DirectlyTransferable(val);
|
1047
|
-
}
|
1048
|
-
}
|
1049
|
-
markMovable(val);
|
1050
|
-
}
|
1051
|
-
return val;
|
1052
|
-
}
|
1053
|
-
static get transferableSymbol() {
|
1054
|
-
return kTransferable;
|
1055
|
-
}
|
1056
|
-
static get valueSymbol() {
|
1057
|
-
return kValue;
|
1058
|
-
}
|
1059
|
-
static get queueOptionsSymbol() {
|
1060
|
-
return kQueueOptions;
|
1061
|
-
}
|
733
|
+
#pool;
|
734
|
+
constructor(options = {}) {
|
735
|
+
if (options.minThreads !== void 0 && options.minThreads > 0 && options.minThreads < 1) options.minThreads = Math.max(1, Math.floor(options.minThreads * cpuCount));
|
736
|
+
if (options.maxThreads !== void 0 && options.maxThreads > 0 && options.maxThreads < 1) options.maxThreads = Math.max(1, Math.floor(options.maxThreads * cpuCount));
|
737
|
+
super({
|
738
|
+
...options,
|
739
|
+
name: "Tinypool"
|
740
|
+
});
|
741
|
+
if (options.minThreads !== void 0 && options.maxThreads !== void 0 && options.minThreads > options.maxThreads) throw new RangeError("options.minThreads and options.maxThreads must not conflict");
|
742
|
+
this.#pool = new ThreadPool(this, options);
|
743
|
+
}
|
744
|
+
run(task, options = kDefaultRunOptions) {
|
745
|
+
const { transferList, filename, name, signal, runtime, channel } = options;
|
746
|
+
return this.#pool.runTask(task, {
|
747
|
+
transferList,
|
748
|
+
filename,
|
749
|
+
name,
|
750
|
+
signal,
|
751
|
+
runtime,
|
752
|
+
channel
|
753
|
+
});
|
754
|
+
}
|
755
|
+
async destroy() {
|
756
|
+
await this.#pool.destroy();
|
757
|
+
this.emitDestroy();
|
758
|
+
}
|
759
|
+
get options() {
|
760
|
+
return this.#pool.options;
|
761
|
+
}
|
762
|
+
get threads() {
|
763
|
+
const ret = [];
|
764
|
+
for (const workerInfo of this.#pool.workers) ret.push(workerInfo.worker);
|
765
|
+
return ret;
|
766
|
+
}
|
767
|
+
get queueSize() {
|
768
|
+
const pool = this.#pool;
|
769
|
+
return Math.max(pool.taskQueue.size - pool.pendingCapacity(), 0);
|
770
|
+
}
|
771
|
+
cancelPendingTasks() {
|
772
|
+
const pool = this.#pool;
|
773
|
+
pool.taskQueue.cancel();
|
774
|
+
}
|
775
|
+
async recycleWorkers(options = {}) {
|
776
|
+
await this.#pool.recycleWorkers(options);
|
777
|
+
}
|
778
|
+
get completed() {
|
779
|
+
return this.#pool.completed;
|
780
|
+
}
|
781
|
+
get duration() {
|
782
|
+
return performance.now() - this.#pool.start;
|
783
|
+
}
|
784
|
+
static get isWorkerThread() {
|
785
|
+
return process.__tinypool_state__?.isWorkerThread || false;
|
786
|
+
}
|
787
|
+
static get workerData() {
|
788
|
+
return process.__tinypool_state__?.workerData || void 0;
|
789
|
+
}
|
790
|
+
static get version() {
|
791
|
+
const { version } = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
|
792
|
+
return version;
|
793
|
+
}
|
794
|
+
static move(val) {
|
795
|
+
if (val != null && typeof val === "object" && typeof val !== "function") {
|
796
|
+
if (!isTransferable(val)) if (types.isArrayBufferView(val)) val = new ArrayBufferViewTransferable(val);
|
797
|
+
else val = new DirectlyTransferable(val);
|
798
|
+
markMovable(val);
|
799
|
+
}
|
800
|
+
return val;
|
801
|
+
}
|
802
|
+
static get transferableSymbol() {
|
803
|
+
return kTransferable;
|
804
|
+
}
|
805
|
+
static get valueSymbol() {
|
806
|
+
return kValue;
|
807
|
+
}
|
808
|
+
static get queueOptionsSymbol() {
|
809
|
+
return kQueueOptions;
|
810
|
+
}
|
1062
811
|
};
|
1063
|
-
|
1064
|
-
var _workerId = process.__tinypool_state__?.workerId;
|
812
|
+
const _workerId = process.__tinypool_state__?.workerId;
|
1065
813
|
var src_default = Tinypool;
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
isMovable,
|
1070
|
-
isTaskQueue,
|
1071
|
-
isTransferable,
|
1072
|
-
kFieldCount,
|
1073
|
-
kQueueOptions,
|
1074
|
-
kRequestCountField,
|
1075
|
-
kResponseCountField,
|
1076
|
-
kTransferable,
|
1077
|
-
kValue,
|
1078
|
-
markMovable,
|
1079
|
-
_workerId as workerId
|
1080
|
-
};
|
814
|
+
|
815
|
+
//#endregion
|
816
|
+
export { Tinypool, src_default as default, isMovable, isTaskQueue, isTransferable, kFieldCount, kQueueOptions, kRequestCountField, kResponseCountField, kTransferable, kValue, markMovable, _workerId as workerId };
|