@rspack/core 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -813,7 +813,26 @@ interface ReactConfig {
813
813
  /**
814
814
  * Enable fast refresh feature for React app
815
815
  */
816
- refresh?: boolean;
816
+ refresh?: boolean | {
817
+ /**
818
+ * Identifier for the `react-refresh` register function.
819
+ *
820
+ * Defaults to `$RefreshReg$`
821
+ */
822
+ refreshReg?: string;
823
+ /**
824
+ * Identifier for the `react-refresh` signature function.
825
+ *
826
+ * Defaults to `$RefreshSig$`
827
+ */
828
+ refreshSig?: string;
829
+ /**
830
+ * Flag to emit full signatures.
831
+ *
832
+ * Defaults to `false`
833
+ */
834
+ emitFullSignatures?: boolean;
835
+ };
817
836
  /**
818
837
  * jsx runtime
819
838
  */
@@ -1020,6 +1039,12 @@ interface BaseModuleConfig {
1020
1039
  * ```
1021
1040
  */
1022
1041
  importInterop?: "swc" | "babel" | "node" | "none";
1042
+ /**
1043
+ * Output extension for generated files.
1044
+ *
1045
+ * Defaults to `js`.
1046
+ */
1047
+ outFileExtension?: "js" | "mjs" | "cjs";
1023
1048
  /**
1024
1049
  * Emits `cjs-module-lexer` annotation
1025
1050
  * `cjs-module-lexer` is used in Node.js core for detecting the named exports available when importing a CJS module into ESM.
@@ -1 +1 @@
1
- {"name":"@swc/types","author":"강동윤 <kdy1997.dev@gmail.com>","version":"0.1.19","license":"Apache-2.0","types":"index.d.ts","type":"commonjs"}
1
+ {"name":"@swc/types","author":"강동윤 <kdy1997.dev@gmail.com>","version":"0.1.20","license":"Apache-2.0","types":"index.d.ts","type":"commonjs"}
@@ -0,0 +1,24 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 James M Snell and the Piscina contributors
4
+
5
+ Piscina contributors listed at https://github.com/jasnell/piscina#the-team and
6
+ in the README file.
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
@@ -0,0 +1,212 @@
1
+ # Tinypool - the node.js worker pool 🧵
2
+
3
+ > Piscina: A fast, efficient Node.js Worker Thread Pool implementation
4
+
5
+ Tinypool is a fork of piscina. What we try to achieve in this library, is to eliminate some dependencies and features that our target users don't need (currently, our main user will be Vitest). Tinypool's install size (38KB) can then be smaller than Piscina's install size (6MB). If you need features like [utilization](https://github.com/piscinajs/piscina#property-utilization-readonly) or [NAPI](https://github.com/piscinajs/piscina#thread-priority-on-linux-systems), [Piscina](https://github.com/piscinajs/piscina) is a better choice for you. We think that Piscina is an amazing library, and we may try to upstream some of the dependencies optimization in this fork.
6
+
7
+ - ✅ Smaller install size, 38KB
8
+ - ✅ Minimal
9
+ - ✅ No dependencies
10
+ - ✅ Physical cores instead of Logical cores with [physical-cpu-count](https://www.npmjs.com/package/physical-cpu-count)
11
+ - ✅ Supports `worker_threads` and `child_process`
12
+ - ❌ No utilization
13
+ - ❌ No NAPI
14
+
15
+ - Written in TypeScript, and ESM support only. For Node.js 18.x and higher.
16
+
17
+ _In case you need more tiny libraries like tinypool or tinyspy, please consider submitting an [RFC](https://github.com/tinylibs/rfcs)_
18
+
19
+ ## Example
20
+
21
+ ### Using `node:worker_threads`
22
+
23
+ #### Basic usage
24
+
25
+ ```js
26
+ // main.mjs
27
+ import Tinypool from 'tinypool'
28
+
29
+ const pool = new Tinypool({
30
+ filename: new URL('./worker.mjs', import.meta.url).href,
31
+ })
32
+ const result = await pool.run({ a: 4, b: 6 })
33
+ console.log(result) // Prints 10
34
+
35
+ // Make sure to destroy pool once it's not needed anymore
36
+ // This terminates all pool's idle workers
37
+ await pool.destroy()
38
+ ```
39
+
40
+ ```js
41
+ // worker.mjs
42
+ export default ({ a, b }) => {
43
+ return a + b
44
+ }
45
+ ```
46
+
47
+ #### Main thread <-> worker thread communication
48
+
49
+ <details>
50
+ <summary>See code</summary>
51
+
52
+ ```js
53
+ // main.mjs
54
+ import Tinypool from 'tinypool'
55
+ import { MessageChannel } from 'node:worker_threads'
56
+
57
+ const pool = new Tinypool({
58
+ filename: new URL('./worker.mjs', import.meta.url).href,
59
+ })
60
+ const { port1, port2 } = new MessageChannel()
61
+ const promise = pool.run({ port: port1 }, { transferList: [port1] })
62
+
63
+ port2.on('message', (message) => console.log('Main thread received:', message))
64
+ setTimeout(() => port2.postMessage('Hello from main thread!'), 1000)
65
+
66
+ await promise
67
+
68
+ port1.close()
69
+ port2.close()
70
+ ```
71
+
72
+ ```js
73
+ // worker.mjs
74
+ export default ({ port }) => {
75
+ return new Promise((resolve) => {
76
+ port.on('message', (message) => {
77
+ console.log('Worker received:', message)
78
+
79
+ port.postMessage('Hello from worker thread!')
80
+ resolve()
81
+ })
82
+ })
83
+ }
84
+ ```
85
+
86
+ </details>
87
+
88
+ ### Using `node:child_process`
89
+
90
+ #### Basic usage
91
+
92
+ <details>
93
+ <summary>See code</summary>
94
+
95
+ ```js
96
+ // main.mjs
97
+ import Tinypool from 'tinypool'
98
+
99
+ const pool = new Tinypool({
100
+ runtime: 'child_process',
101
+ filename: new URL('./worker.mjs', import.meta.url).href,
102
+ })
103
+ const result = await pool.run({ a: 4, b: 6 })
104
+ console.log(result) // Prints 10
105
+ ```
106
+
107
+ ```js
108
+ // worker.mjs
109
+ export default ({ a, b }) => {
110
+ return a + b
111
+ }
112
+ ```
113
+
114
+ </details>
115
+
116
+ #### Main process <-> worker process communication
117
+
118
+ <details>
119
+ <summary>See code</summary>
120
+
121
+ ```js
122
+ // main.mjs
123
+ import Tinypool from 'tinypool'
124
+
125
+ const pool = new Tinypool({
126
+ runtime: 'child_process',
127
+ filename: new URL('./worker.mjs', import.meta.url).href,
128
+ })
129
+
130
+ const messages = []
131
+ const listeners = []
132
+ const channel = {
133
+ onMessage: (listener) => listeners.push(listener),
134
+ postMessage: (message) => messages.push(message),
135
+ }
136
+
137
+ const promise = pool.run({}, { channel })
138
+
139
+ // Send message to worker
140
+ setTimeout(
141
+ () => listeners.forEach((listener) => listener('Hello from main process')),
142
+ 1000
143
+ )
144
+
145
+ // Wait for task to finish
146
+ await promise
147
+
148
+ console.log(messages)
149
+ // [{ received: 'Hello from main process', response: 'Hello from worker' }]
150
+ ```
151
+
152
+ ```js
153
+ // worker.mjs
154
+ export default async function run() {
155
+ return new Promise((resolve) => {
156
+ process.on('message', (message) => {
157
+ // Ignore Tinypool's internal messages
158
+ if (message?.__tinypool_worker_message__) return
159
+
160
+ process.send({ received: message, response: 'Hello from worker' })
161
+ resolve()
162
+ })
163
+ })
164
+ }
165
+ ```
166
+
167
+ </details>
168
+
169
+ ## API
170
+
171
+ We have a similar API to Piscina, so for more information, you can read Piscina's detailed [documentation](https://github.com/piscinajs/piscina#piscina---the-nodejs-worker-pool) and apply the same techniques here.
172
+
173
+ ### Tinypool specific APIs
174
+
175
+ #### Pool constructor options
176
+
177
+ - `isolateWorkers`: Disabled by default. Always starts with a fresh worker when running tasks to isolate the environment.
178
+ - `terminateTimeout`: Disabled by default. If terminating a worker takes `terminateTimeout` amount of milliseconds to execute, an error is raised.
179
+ - `maxMemoryLimitBeforeRecycle`: Disabled by default. When defined, the worker's heap memory usage is compared against this value after task has been finished. If the current memory usage exceeds this limit, worker is terminated and a new one is started to take its place. This option is useful when your tasks leak memory and you don't want to enable `isolateWorkers` option.
180
+ - `runtime`: Used to pick worker runtime. Default value is `worker_threads`.
181
+ - `worker_threads`: Runs workers in [`node:worker_threads`](https://nodejs.org/api/worker_threads.html). For `main thread <-> worker thread` communication you can use [`MessagePort`](https://nodejs.org/api/worker_threads.html#class-messageport) in the `pool.run()` method's [`transferList` option](https://nodejs.org/api/worker_threads.html#portpostmessagevalue-transferlist). See [example](#main-thread---worker-thread-communication).
182
+ - `child_process`: Runs workers in [`node:child_process`](https://nodejs.org/api/child_process.html). For `main thread <-> worker process` communication you can use `TinypoolChannel` in the `pool.run()` method's `channel` option. For filtering out the Tinypool's internal messages see `TinypoolWorkerMessage`. See [example](#main-process---worker-process-communication).
183
+
184
+ #### Pool methods
185
+
186
+ - `cancelPendingTasks()`: Gracefully cancels all pending tasks without stopping or interfering with on-going tasks. This method is useful when your tasks may have side effects and should not be terminated forcefully during task execution. If your tasks don't have any side effects you may want to use [`{ signal }`](https://github.com/piscinajs/piscina#cancelable-tasks) option for forcefully terminating all tasks, including the on-going ones, instead.
187
+ - `recycleWorkers(options)`: Waits for all current tasks to finish and re-creates all workers. Can be used to force isolation imperatively even when `isolateWorkers` is disabled. Accepts `{ runtime }` option as argument.
188
+
189
+ #### Exports
190
+
191
+ - `workerId`: Each worker now has an id ( <= `maxThreads`) that can be imported from `tinypool` in the worker itself (or `process.__tinypool_state__.workerId`).
192
+
193
+ ## Authors
194
+
195
+ | <a href="https://github.com/Aslemammad"> <img width='150' src="https://avatars.githubusercontent.com/u/37929992?v=4" /><br> Mohammad Bagher </a> |
196
+ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
197
+
198
+ ## Sponsors
199
+
200
+ Your sponsorship can make a huge difference in continuing our work in open source!
201
+
202
+ <p align="center">
203
+ <a href="https://cdn.jsdelivr.net/gh/aslemammad/static/sponsors.svg">
204
+ <img src='https://cdn.jsdelivr.net/gh/aslemammad/static/sponsors.svg'/>
205
+ </a>
206
+ </p>
207
+
208
+ ## Credits
209
+
210
+ [The Vitest team](https://vitest.dev/) for giving me the chance of creating and maintaing this project for vitest.
211
+
212
+ [Piscina](https://github.com/piscinajs/piscina), because Tinypool is not more than a friendly fork of piscina.
@@ -0,0 +1,31 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+ var __accessCheck = (obj, member, msg) => {
8
+ if (!member.has(obj))
9
+ throw TypeError("Cannot " + msg);
10
+ };
11
+ var __privateGet = (obj, member, getter) => {
12
+ __accessCheck(obj, member, "read from private field");
13
+ return getter ? getter.call(obj) : member.get(obj);
14
+ };
15
+ var __privateAdd = (obj, member, value) => {
16
+ if (member.has(obj))
17
+ throw TypeError("Cannot add the same private member more than once");
18
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
19
+ };
20
+ var __privateSet = (obj, member, value, setter) => {
21
+ __accessCheck(obj, member, "write to private field");
22
+ setter ? setter.call(obj, value) : member.set(obj, value);
23
+ return value;
24
+ };
25
+
26
+ export {
27
+ __publicField,
28
+ __privateGet,
29
+ __privateAdd,
30
+ __privateSet
31
+ };
@@ -0,0 +1,12 @@
1
+ // src/utils.ts
2
+ function stdout() {
3
+ return console._stdout || process.stdout || void 0;
4
+ }
5
+ function stderr() {
6
+ return console._stderr || process.stderr || void 0;
7
+ }
8
+
9
+ export {
10
+ stdout,
11
+ stderr
12
+ };
@@ -0,0 +1,53 @@
1
+ // src/entry/utils.ts
2
+ import { pathToFileURL } from "url";
3
+ var importESMCached;
4
+ function getImportESM() {
5
+ if (importESMCached === void 0) {
6
+ importESMCached = new Function(
7
+ "specifier",
8
+ "return import(specifier)"
9
+ );
10
+ }
11
+ return importESMCached;
12
+ }
13
+ var handlerCache = /* @__PURE__ */ new Map();
14
+ async function getHandler(filename, name) {
15
+ let handler = handlerCache.get(`${filename}/${name}`);
16
+ if (handler !== void 0) {
17
+ return handler;
18
+ }
19
+ try {
20
+ const handlerModule = await import(filename);
21
+ handler = typeof handlerModule.default !== "function" && handlerModule.default || handlerModule;
22
+ if (typeof handler !== "function") {
23
+ handler = await handler[name];
24
+ }
25
+ } catch {
26
+ }
27
+ if (typeof handler !== "function") {
28
+ handler = await getImportESM()(pathToFileURL(filename).href);
29
+ if (typeof handler !== "function") {
30
+ handler = await handler[name];
31
+ }
32
+ }
33
+ if (typeof handler !== "function") {
34
+ return null;
35
+ }
36
+ if (handlerCache.size > 1e3) {
37
+ const [handler2] = handlerCache;
38
+ const key = handler2[0];
39
+ handlerCache.delete(key);
40
+ }
41
+ handlerCache.set(`${filename}/${name}`, handler);
42
+ return handler;
43
+ }
44
+ function throwInNextTick(error) {
45
+ process.nextTick(() => {
46
+ throw error;
47
+ });
48
+ }
49
+
50
+ export {
51
+ getHandler,
52
+ throwInNextTick
53
+ };
@@ -0,0 +1,38 @@
1
+ // src/common.ts
2
+ var kMovable = Symbol("Tinypool.kMovable");
3
+ var kTransferable = Symbol.for("Tinypool.transferable");
4
+ var kValue = Symbol.for("Tinypool.valueOf");
5
+ var kQueueOptions = Symbol.for("Tinypool.queueOptions");
6
+ function isTransferable(value) {
7
+ return value != null && typeof value === "object" && kTransferable in value && kValue in value;
8
+ }
9
+ function isMovable(value) {
10
+ return isTransferable(value) && value[kMovable] === true;
11
+ }
12
+ function markMovable(value) {
13
+ Object.defineProperty(value, kMovable, {
14
+ enumerable: false,
15
+ configurable: true,
16
+ writable: true,
17
+ value: true
18
+ });
19
+ }
20
+ function isTaskQueue(value) {
21
+ return typeof value === "object" && value !== null && "size" in value && typeof value.shift === "function" && typeof value.remove === "function" && typeof value.push === "function";
22
+ }
23
+ var kRequestCountField = 0;
24
+ var kResponseCountField = 1;
25
+ var kFieldCount = 2;
26
+
27
+ export {
28
+ kTransferable,
29
+ kValue,
30
+ kQueueOptions,
31
+ isTransferable,
32
+ isMovable,
33
+ markMovable,
34
+ isTaskQueue,
35
+ kRequestCountField,
36
+ kResponseCountField,
37
+ kFieldCount
38
+ };
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,92 @@
1
+ import {
2
+ stderr,
3
+ stdout
4
+ } from "../chunk-ACQHDOFQ.js";
5
+ import {
6
+ getHandler,
7
+ throwInNextTick
8
+ } from "../chunk-E2J7JLFN.js";
9
+ import "../chunk-6LX4VMOV.js";
10
+
11
+ // src/entry/process.ts
12
+ process.__tinypool_state__ = {
13
+ isChildProcess: true,
14
+ isTinypoolWorker: true,
15
+ workerData: null,
16
+ workerId: Number(process.env.TINYPOOL_WORKER_ID)
17
+ };
18
+ var memoryUsage = process.memoryUsage.bind(process);
19
+ var send = process.send.bind(process);
20
+ process.on("message", (message) => {
21
+ if (!message || !message.__tinypool_worker_message__)
22
+ return;
23
+ if (message.source === "pool") {
24
+ const { filename, name } = message;
25
+ (async function() {
26
+ if (filename !== null) {
27
+ await getHandler(filename, name);
28
+ }
29
+ send(
30
+ {
31
+ ready: true,
32
+ source: "pool",
33
+ __tinypool_worker_message__: true
34
+ },
35
+ () => {
36
+ }
37
+ );
38
+ })().catch(throwInNextTick);
39
+ return;
40
+ }
41
+ if (message.source === "port") {
42
+ onMessage(message).catch(throwInNextTick);
43
+ return;
44
+ }
45
+ throw new Error(`Unexpected TinypoolWorkerMessage ${JSON.stringify(message)}`);
46
+ });
47
+ async function onMessage(message) {
48
+ const { taskId, task, filename, name } = message;
49
+ let response;
50
+ try {
51
+ const handler = await getHandler(filename, name);
52
+ if (handler === null) {
53
+ throw new Error(`No handler function exported from ${filename}`);
54
+ }
55
+ const result = await handler(task);
56
+ response = {
57
+ source: "port",
58
+ __tinypool_worker_message__: true,
59
+ taskId,
60
+ result,
61
+ error: null,
62
+ usedMemory: memoryUsage().heapUsed
63
+ };
64
+ if (stdout()?.writableLength > 0) {
65
+ await new Promise((resolve) => process.stdout.write("", resolve));
66
+ }
67
+ if (stderr()?.writableLength > 0) {
68
+ await new Promise((resolve) => process.stderr.write("", resolve));
69
+ }
70
+ } catch (error) {
71
+ response = {
72
+ source: "port",
73
+ __tinypool_worker_message__: true,
74
+ taskId,
75
+ result: null,
76
+ error: serializeError(error),
77
+ usedMemory: memoryUsage().heapUsed
78
+ };
79
+ }
80
+ send(response);
81
+ }
82
+ function serializeError(error) {
83
+ if (error instanceof Error) {
84
+ return {
85
+ ...error,
86
+ name: error.name,
87
+ stack: error.stack,
88
+ message: error.message
89
+ };
90
+ }
91
+ return String(error);
92
+ }
@@ -0,0 +1,5 @@
1
+ type Handler = Function;
2
+ declare function getHandler(filename: string, name: string): Promise<Handler | null>;
3
+ declare function throwInNextTick(error: Error): void;
4
+
5
+ export { getHandler, throwInNextTick };
@@ -0,0 +1,9 @@
1
+ import {
2
+ getHandler,
3
+ throwInNextTick
4
+ } from "../chunk-E2J7JLFN.js";
5
+ import "../chunk-6LX4VMOV.js";
6
+ export {
7
+ getHandler,
8
+ throwInNextTick
9
+ };
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,103 @@
1
+ import {
2
+ isMovable,
3
+ kRequestCountField,
4
+ kResponseCountField,
5
+ kTransferable,
6
+ kValue
7
+ } from "../chunk-UBWFVGJX.js";
8
+ import {
9
+ stderr,
10
+ stdout
11
+ } from "../chunk-ACQHDOFQ.js";
12
+ import {
13
+ getHandler,
14
+ throwInNextTick
15
+ } from "../chunk-E2J7JLFN.js";
16
+ import "../chunk-6LX4VMOV.js";
17
+
18
+ // src/entry/worker.ts
19
+ import {
20
+ parentPort,
21
+ receiveMessageOnPort,
22
+ workerData as tinypoolData
23
+ } from "worker_threads";
24
+ var [tinypoolPrivateData, workerData] = tinypoolData;
25
+ process.__tinypool_state__ = {
26
+ isWorkerThread: true,
27
+ isTinypoolWorker: true,
28
+ workerData,
29
+ workerId: tinypoolPrivateData.workerId
30
+ };
31
+ var memoryUsage = process.memoryUsage.bind(process);
32
+ var useAtomics = process.env.PISCINA_DISABLE_ATOMICS !== "1";
33
+ parentPort.on("message", (message) => {
34
+ useAtomics = process.env.PISCINA_DISABLE_ATOMICS === "1" ? false : message.useAtomics;
35
+ const { port, sharedBuffer, filename, name } = message;
36
+ (async function() {
37
+ if (filename !== null) {
38
+ await getHandler(filename, name);
39
+ }
40
+ const readyMessage = { ready: true };
41
+ parentPort.postMessage(readyMessage);
42
+ port.on("message", onMessage.bind(null, port, sharedBuffer));
43
+ atomicsWaitLoop(port, sharedBuffer);
44
+ })().catch(throwInNextTick);
45
+ });
46
+ var currentTasks = 0;
47
+ var lastSeenRequestCount = 0;
48
+ function atomicsWaitLoop(port, sharedBuffer) {
49
+ if (!useAtomics)
50
+ return;
51
+ while (currentTasks === 0) {
52
+ Atomics.wait(sharedBuffer, kRequestCountField, lastSeenRequestCount);
53
+ lastSeenRequestCount = Atomics.load(sharedBuffer, kRequestCountField);
54
+ let entry;
55
+ while ((entry = receiveMessageOnPort(port)) !== void 0) {
56
+ onMessage(port, sharedBuffer, entry.message);
57
+ }
58
+ }
59
+ }
60
+ function onMessage(port, sharedBuffer, message) {
61
+ currentTasks++;
62
+ const { taskId, task, filename, name } = message;
63
+ (async function() {
64
+ let response;
65
+ let transferList = [];
66
+ try {
67
+ const handler = await getHandler(filename, name);
68
+ if (handler === null) {
69
+ throw new Error(`No handler function exported from ${filename}`);
70
+ }
71
+ let result = await handler(task);
72
+ if (isMovable(result)) {
73
+ transferList = transferList.concat(result[kTransferable]);
74
+ result = result[kValue];
75
+ }
76
+ response = {
77
+ taskId,
78
+ result,
79
+ error: null,
80
+ usedMemory: memoryUsage().heapUsed
81
+ };
82
+ if (stdout()?.writableLength > 0) {
83
+ await new Promise((resolve) => process.stdout.write("", resolve));
84
+ }
85
+ if (stderr()?.writableLength > 0) {
86
+ await new Promise((resolve) => process.stderr.write("", resolve));
87
+ }
88
+ } catch (error) {
89
+ response = {
90
+ taskId,
91
+ result: null,
92
+ // It may be worth taking a look at the error cloning algorithm we
93
+ // use in Node.js core here, it's quite a bit more flexible
94
+ error,
95
+ usedMemory: memoryUsage().heapUsed
96
+ };
97
+ }
98
+ currentTasks--;
99
+ port.postMessage(response, transferList);
100
+ Atomics.add(sharedBuffer, kResponseCountField, 1);
101
+ atomicsWaitLoop(port, sharedBuffer);
102
+ })().catch(throwInNextTick);
103
+ }