@atlaspack/core 2.12.1-canary.3486 → 2.12.1-canary.3488

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.
@@ -4,20 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.AtlaspackV3 = void 0;
7
- function _path() {
8
- const data = _interopRequireDefault(require("path"));
9
- _path = function () {
10
- return data;
11
- };
12
- return data;
13
- }
14
- function _worker_threads() {
15
- const data = require("worker_threads");
16
- _worker_threads = function () {
17
- return data;
18
- };
19
- return data;
20
- }
7
+ var _WorkerPool = require("./WorkerPool");
21
8
  function _rust() {
22
9
  const data = require("@atlaspack/rust");
23
10
  _rust = function () {
@@ -25,8 +12,6 @@ function _rust() {
25
12
  };
26
13
  return data;
27
14
  }
28
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
- const WORKER_PATH = _path().default.join(__dirname, 'worker', 'index.js');
30
15
  class AtlaspackV3 {
31
16
  constructor({
32
17
  fs,
@@ -50,23 +35,16 @@ class AtlaspackV3 {
50
35
  });
51
36
  }
52
37
  async buildAssetGraph() {
53
- const [workers, registerWorker] = this.#createWorkers();
38
+ const workerIds = [];
54
39
  let result = await this._internal.buildAssetGraph({
55
- registerWorker
40
+ registerWorker: tx_worker => {
41
+ // $FlowFixMe
42
+ const workerId = _WorkerPool.workerPool.registerWorker(tx_worker);
43
+ workerIds.push(workerId);
44
+ }
56
45
  });
57
- for (const worker of workers) worker.terminate();
46
+ _WorkerPool.workerPool.releaseWorkers(workerIds);
58
47
  return result;
59
48
  }
60
- #createWorkers() {
61
- const workers = [];
62
- return [workers, tx_worker => {
63
- let worker = new (_worker_threads().Worker)(WORKER_PATH, {
64
- workerData: {
65
- tx_worker
66
- }
67
- });
68
- workers.push(worker);
69
- }];
70
- }
71
49
  }
72
50
  exports.AtlaspackV3 = AtlaspackV3;
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.WorkerPool = void 0;
7
+ exports.waitForMessage = waitForMessage;
8
+ exports.workerPool = void 0;
9
+ function _path() {
10
+ const data = _interopRequireDefault(require("path"));
11
+ _path = function () {
12
+ return data;
13
+ };
14
+ return data;
15
+ }
16
+ function _worker_threads() {
17
+ const data = require("worker_threads");
18
+ _worker_threads = function () {
19
+ return data;
20
+ };
21
+ return data;
22
+ }
23
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
+ /*!
25
+ * Atlaspack V3 delegates work to node.js worker threads.
26
+ *
27
+ * Starting-up each worker is relatively expensive, in particular when atlaspack
28
+ * is running in development mode, in which case each worker will transpile the
29
+ * project on startup.
30
+ *
31
+ * This "WorkerPool" mitigates this problem by reusing worker threads across
32
+ * builds.
33
+ */
34
+ const WORKER_PATH = _path().default.join(__dirname, 'worker', 'index.js');
35
+ function waitForMessage(worker, type) {
36
+ return new Promise(resolve => {
37
+ const onMessage = message => {
38
+ if (message.type === type) {
39
+ resolve(message);
40
+ worker.off('message', onMessage);
41
+ }
42
+ };
43
+ worker.on('message', onMessage);
44
+ });
45
+ }
46
+ class WorkerPool {
47
+ #workerPool = [];
48
+ #usedWorkers = new Set();
49
+ #workerPath;
50
+ constructor(workerPath = WORKER_PATH) {
51
+ this.#workerPath = workerPath;
52
+
53
+ // $FlowFixMe
54
+ this[Symbol.dispose] = () => {
55
+ this.shutdown();
56
+ };
57
+ }
58
+
59
+ /**
60
+ * Find a worker thread that is free to use or create a new one.
61
+ *
62
+ * Then register the `tx_worker` channel ID with the worker thread.
63
+ */
64
+ registerWorker(tx_worker) {
65
+ const availableIndex = this.#workerPool.findIndex((worker, index) => !this.#usedWorkers.has(index));
66
+ const [workerId, worker] = availableIndex !== -1 ? [availableIndex, this.#workerPool[availableIndex]] : this.#createWorker();
67
+ this.#bootWorker(worker, tx_worker).catch(err => {
68
+ // eslint-disable-next-line no-console
69
+ console.error('Worker failed, retrying to create it...', err);
70
+ this.#workerPool[workerId] = new (_worker_threads().Worker)(WORKER_PATH, {});
71
+ this.#bootWorker(this.#workerPool[workerId], tx_worker).catch(err => {
72
+ // eslint-disable-next-line no-console
73
+ console.error('Worker failed to start. The build may hang', err);
74
+ });
75
+ });
76
+ this.#usedWorkers.add(workerId);
77
+ return workerId;
78
+ }
79
+
80
+ /**
81
+ * Release a set of workers back into the pool for re-use
82
+ */
83
+ releaseWorkers(ids) {
84
+ for (let id of ids) {
85
+ this.#usedWorkers.delete(id);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Terminate all worker threads and reset state.
91
+ */
92
+ shutdown() {
93
+ for (let worker of this.#workerPool) {
94
+ worker.terminate();
95
+ }
96
+ this.#usedWorkers.clear();
97
+ this.#workerPool = [];
98
+ }
99
+ getStats() {
100
+ return {
101
+ totalWorkers: this.#workerPool.length,
102
+ workersInUse: this.#usedWorkers.size
103
+ };
104
+ }
105
+
106
+ /**
107
+ * Get the worker thread. Used for testing.
108
+ */
109
+ getWorker(workerId) {
110
+ if (!this.#workerPool[workerId]) {
111
+ throw new Error('Worker does not exist');
112
+ }
113
+ return this.#workerPool[workerId];
114
+ }
115
+ async #bootWorker(worker, tx_worker) {
116
+ const timeout = new Promise((_, reject) => {
117
+ setTimeout(() => {
118
+ reject(new Error('Worker failed to register in time'));
119
+ }, 5000);
120
+ });
121
+ const workerReady = waitForMessage(worker, 'workerRegistered');
122
+ worker.postMessage({
123
+ type: 'registerWorker',
124
+ tx_worker
125
+ });
126
+ await Promise.race([workerReady, timeout]);
127
+ }
128
+ #createWorker() {
129
+ const worker = new (_worker_threads().Worker)(this.#workerPath, {});
130
+ const workerId = this.#workerPool.length;
131
+ this.#workerPool.push(worker);
132
+ return [workerId, worker];
133
+ }
134
+ }
135
+ exports.WorkerPool = WorkerPool;
136
+ const workerPool = exports.workerPool = new WorkerPool();
@@ -265,4 +265,29 @@ class AtlaspackWorker {
265
265
  });
266
266
  }
267
267
  exports.AtlaspackWorker = AtlaspackWorker;
268
- napi().registerWorker(_worker_threads().workerData.tx_worker, new AtlaspackWorker());
268
+ const worker = new AtlaspackWorker();
269
+ _worker_threads().parentPort === null || _worker_threads().parentPort === void 0 || _worker_threads().parentPort.on('message', event => {
270
+ if (event.type === 'registerWorker') {
271
+ try {
272
+ napi().registerWorker(event.tx_worker, worker);
273
+ } catch (err) {
274
+ // eslint-disable-next-line no-console
275
+ console.error('Registering worker failed... This might mean atlaspack is getting shut-down before the worker registered', err);
276
+ _worker_threads().parentPort === null || _worker_threads().parentPort === void 0 || _worker_threads().parentPort.postMessage({
277
+ type: 'workerError',
278
+ error: err
279
+ });
280
+ }
281
+ _worker_threads().parentPort === null || _worker_threads().parentPort === void 0 || _worker_threads().parentPort.postMessage({
282
+ type: 'workerRegistered'
283
+ });
284
+ } else if (event.type === 'probeStatus') {
285
+ _worker_threads().parentPort.postMessage({
286
+ type: 'status',
287
+ status: 'ok'
288
+ });
289
+ }
290
+ });
291
+ _worker_threads().parentPort === null || _worker_threads().parentPort === void 0 || _worker_threads().parentPort.postMessage({
292
+ type: 'workerLoaded'
293
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaspack/core",
3
- "version": "2.12.1-canary.3486+ed60801bc",
3
+ "version": "2.12.1-canary.3488+bacf813b1",
4
4
  "license": "(MIT OR Apache-2.0)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -20,21 +20,21 @@
20
20
  "check-ts": "tsc --noEmit index.d.ts"
21
21
  },
22
22
  "dependencies": {
23
- "@atlaspack/build-cache": "2.12.1-canary.3486+ed60801bc",
24
- "@atlaspack/cache": "2.12.1-canary.3486+ed60801bc",
25
- "@atlaspack/diagnostic": "2.12.1-canary.3486+ed60801bc",
26
- "@atlaspack/events": "2.12.1-canary.3486+ed60801bc",
27
- "@atlaspack/feature-flags": "2.12.1-canary.3486+ed60801bc",
28
- "@atlaspack/fs": "2.12.1-canary.3486+ed60801bc",
29
- "@atlaspack/graph": "3.2.1-canary.3486+ed60801bc",
30
- "@atlaspack/logger": "2.12.1-canary.3486+ed60801bc",
31
- "@atlaspack/package-manager": "2.12.1-canary.3486+ed60801bc",
32
- "@atlaspack/plugin": "2.12.1-canary.3486+ed60801bc",
33
- "@atlaspack/profiler": "2.12.1-canary.3486+ed60801bc",
34
- "@atlaspack/rust": "2.12.1-canary.3486+ed60801bc",
35
- "@atlaspack/types": "2.12.1-canary.3486+ed60801bc",
36
- "@atlaspack/utils": "2.12.1-canary.3486+ed60801bc",
37
- "@atlaspack/workers": "2.12.1-canary.3486+ed60801bc",
23
+ "@atlaspack/build-cache": "2.12.1-canary.3488+bacf813b1",
24
+ "@atlaspack/cache": "2.12.1-canary.3488+bacf813b1",
25
+ "@atlaspack/diagnostic": "2.12.1-canary.3488+bacf813b1",
26
+ "@atlaspack/events": "2.12.1-canary.3488+bacf813b1",
27
+ "@atlaspack/feature-flags": "2.12.1-canary.3488+bacf813b1",
28
+ "@atlaspack/fs": "2.12.1-canary.3488+bacf813b1",
29
+ "@atlaspack/graph": "3.2.1-canary.3488+bacf813b1",
30
+ "@atlaspack/logger": "2.12.1-canary.3488+bacf813b1",
31
+ "@atlaspack/package-manager": "2.12.1-canary.3488+bacf813b1",
32
+ "@atlaspack/plugin": "2.12.1-canary.3488+bacf813b1",
33
+ "@atlaspack/profiler": "2.12.1-canary.3488+bacf813b1",
34
+ "@atlaspack/rust": "2.12.1-canary.3488+bacf813b1",
35
+ "@atlaspack/types": "2.12.1-canary.3488+bacf813b1",
36
+ "@atlaspack/utils": "2.12.1-canary.3488+bacf813b1",
37
+ "@atlaspack/workers": "2.12.1-canary.3488+bacf813b1",
38
38
  "@mischnic/json-sourcemap": "^0.1.0",
39
39
  "@parcel/source-map": "^2.1.1",
40
40
  "base-x": "^3.0.8",
@@ -65,5 +65,5 @@
65
65
  "browser": {
66
66
  "./src/serializerCore.js": "./src/serializerCore.browser.js"
67
67
  },
68
- "gitHead": "ed60801bcda8951391d16e375ecb0e33d0d5ad15"
68
+ "gitHead": "bacf813b1fd2c475991643425e6e1d1545791424"
69
69
  }
@@ -1,11 +1,8 @@
1
1
  // @flow
2
2
 
3
- import path from 'path';
4
- import {Worker} from 'worker_threads';
3
+ import {workerPool} from './WorkerPool';
5
4
  import {AtlaspackNapi, type AtlaspackNapiOptions} from '@atlaspack/rust';
6
5
 
7
- const WORKER_PATH = path.join(__dirname, 'worker', 'index.js');
8
-
9
6
  export type AtlaspackV3Options = {|
10
7
  fs?: AtlaspackNapiOptions['fs'],
11
8
  nodeWorkers?: number,
@@ -42,29 +39,17 @@ export class AtlaspackV3 {
42
39
  }
43
40
 
44
41
  async buildAssetGraph(): Promise<any> {
45
- const [workers, registerWorker] = this.#createWorkers();
46
-
42
+ const workerIds = [];
47
43
  let result = await this._internal.buildAssetGraph({
48
- registerWorker,
44
+ registerWorker: (tx_worker) => {
45
+ // $FlowFixMe
46
+ const workerId = workerPool.registerWorker(tx_worker);
47
+ workerIds.push(workerId);
48
+ },
49
49
  });
50
50
 
51
- for (const worker of workers) worker.terminate();
52
- return result;
53
- }
54
-
55
- #createWorkers() {
56
- const workers = [];
51
+ workerPool.releaseWorkers(workerIds);
57
52
 
58
- return [
59
- workers,
60
- (tx_worker) => {
61
- let worker = new Worker(WORKER_PATH, {
62
- workerData: {
63
- tx_worker,
64
- },
65
- });
66
- workers.push(worker);
67
- },
68
- ];
53
+ return result;
69
54
  }
70
55
  }
@@ -0,0 +1,129 @@
1
+ // @flow strict-local
2
+ /*!
3
+ * Atlaspack V3 delegates work to node.js worker threads.
4
+ *
5
+ * Starting-up each worker is relatively expensive, in particular when atlaspack
6
+ * is running in development mode, in which case each worker will transpile the
7
+ * project on startup.
8
+ *
9
+ * This "WorkerPool" mitigates this problem by reusing worker threads across
10
+ * builds.
11
+ */
12
+ import path from 'path';
13
+ import {Worker} from 'worker_threads';
14
+
15
+ const WORKER_PATH = path.join(__dirname, 'worker', 'index.js');
16
+
17
+ export function waitForMessage<T>(worker: Worker, type: string): Promise<T> {
18
+ return new Promise((resolve) => {
19
+ const onMessage = (message: T & {|type: string|}) => {
20
+ if (message.type === type) {
21
+ resolve(message);
22
+ worker.off('message', onMessage);
23
+ }
24
+ };
25
+ worker.on('message', onMessage);
26
+ });
27
+ }
28
+
29
+ export class WorkerPool {
30
+ #workerPool: Worker[] = [];
31
+ #usedWorkers: Set<number> = new Set();
32
+ #workerPath: string;
33
+
34
+ constructor(workerPath: string = WORKER_PATH) {
35
+ this.#workerPath = workerPath;
36
+
37
+ // $FlowFixMe
38
+ this[Symbol.dispose] = () => {
39
+ this.shutdown();
40
+ };
41
+ }
42
+
43
+ /**
44
+ * Find a worker thread that is free to use or create a new one.
45
+ *
46
+ * Then register the `tx_worker` channel ID with the worker thread.
47
+ */
48
+ registerWorker(tx_worker: number): number {
49
+ const availableIndex = this.#workerPool.findIndex(
50
+ (worker, index) => !this.#usedWorkers.has(index),
51
+ );
52
+
53
+ const [workerId, worker] =
54
+ availableIndex !== -1
55
+ ? [availableIndex, this.#workerPool[availableIndex]]
56
+ : this.#createWorker();
57
+
58
+ this.#bootWorker(worker, tx_worker).catch((err) => {
59
+ // eslint-disable-next-line no-console
60
+ console.error('Worker failed, retrying to create it...', err);
61
+ this.#workerPool[workerId] = new Worker(WORKER_PATH, {});
62
+ this.#bootWorker(this.#workerPool[workerId], tx_worker).catch((err) => {
63
+ // eslint-disable-next-line no-console
64
+ console.error('Worker failed to start. The build may hang', err);
65
+ });
66
+ });
67
+
68
+ this.#usedWorkers.add(workerId);
69
+
70
+ return workerId;
71
+ }
72
+
73
+ /**
74
+ * Release a set of workers back into the pool for re-use
75
+ */
76
+ releaseWorkers(ids: number[]) {
77
+ for (let id of ids) {
78
+ this.#usedWorkers.delete(id);
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Terminate all worker threads and reset state.
84
+ */
85
+ shutdown() {
86
+ for (let worker of this.#workerPool) {
87
+ worker.terminate();
88
+ }
89
+ this.#usedWorkers.clear();
90
+ this.#workerPool = [];
91
+ }
92
+
93
+ getStats(): {|totalWorkers: number, workersInUse: number|} {
94
+ return {
95
+ totalWorkers: this.#workerPool.length,
96
+ workersInUse: this.#usedWorkers.size,
97
+ };
98
+ }
99
+
100
+ /**
101
+ * Get the worker thread. Used for testing.
102
+ */
103
+ getWorker(workerId: number): Worker {
104
+ if (!this.#workerPool[workerId]) {
105
+ throw new Error('Worker does not exist');
106
+ }
107
+ return this.#workerPool[workerId];
108
+ }
109
+
110
+ async #bootWorker(worker: Worker, tx_worker: number): Promise<void> {
111
+ const timeout = new Promise((_, reject) => {
112
+ setTimeout(() => {
113
+ reject(new Error('Worker failed to register in time'));
114
+ }, 5000);
115
+ });
116
+ const workerReady = waitForMessage(worker, 'workerRegistered');
117
+ worker.postMessage({type: 'registerWorker', tx_worker});
118
+ await Promise.race([workerReady, timeout]);
119
+ }
120
+
121
+ #createWorker(): [number, Worker] {
122
+ const worker = new Worker(this.#workerPath, {});
123
+ const workerId = this.#workerPool.length;
124
+ this.#workerPool.push(worker);
125
+ return [workerId, worker];
126
+ }
127
+ }
128
+
129
+ export const workerPool: WorkerPool = new WorkerPool();
@@ -10,7 +10,7 @@ import type {
10
10
  FilePath,
11
11
  FileSystem,
12
12
  } from '@atlaspack/types';
13
- import {workerData} from 'worker_threads';
13
+ import {parentPort} from 'worker_threads';
14
14
  import * as module from 'module';
15
15
 
16
16
  import {
@@ -273,7 +273,28 @@ export class AtlaspackWorker {
273
273
  });
274
274
  }
275
275
 
276
- napi.registerWorker(workerData.tx_worker, new AtlaspackWorker());
276
+ const worker = new AtlaspackWorker();
277
+ parentPort?.on('message', (event) => {
278
+ if (event.type === 'registerWorker') {
279
+ try {
280
+ napi.registerWorker(event.tx_worker, worker);
281
+ } catch (err) {
282
+ // eslint-disable-next-line no-console
283
+ console.error(
284
+ 'Registering worker failed... This might mean atlaspack is getting shut-down before the worker registered',
285
+ err,
286
+ );
287
+ parentPort?.postMessage({type: 'workerError', error: err});
288
+ }
289
+ parentPort?.postMessage({type: 'workerRegistered'});
290
+ } else if (event.type === 'probeStatus') {
291
+ parentPort.postMessage({
292
+ type: 'status',
293
+ status: 'ok',
294
+ });
295
+ }
296
+ });
297
+ parentPort?.postMessage({type: 'workerLoaded'});
277
298
 
278
299
  type ResolverState<T> = {|
279
300
  resolver: Resolver<T>,
@@ -0,0 +1,121 @@
1
+ // @flow strict-local
2
+
3
+ import path from 'path';
4
+ import {Worker} from 'worker_threads';
5
+ import {WorkerPool, waitForMessage} from '../../src/atlaspack-v3/WorkerPool';
6
+ import assert from 'assert';
7
+
8
+ function probeStatus(worker: Worker) {
9
+ const response = waitForMessage(worker, 'status');
10
+ worker.postMessage({type: 'probeStatus'});
11
+ return response;
12
+ }
13
+
14
+ describe('WorkerPool', () => {
15
+ it('can create workers and will send them the tx_worker value', async () => {
16
+ const workerPool = new WorkerPool(path.join(__dirname, 'worker.js'));
17
+ const workerId = workerPool.registerWorker(0);
18
+ const worker = workerPool.getWorker(workerId);
19
+ const status = await probeStatus(worker);
20
+
21
+ assert.deepEqual(status, {
22
+ type: 'status',
23
+ status: 'test-status-ok',
24
+ receivedMessages: [
25
+ {
26
+ type: 'registerWorker',
27
+ tx_worker: 0,
28
+ },
29
+ ],
30
+ });
31
+ });
32
+
33
+ it('when a worker is created, it is tracked', () => {
34
+ const workerPool = new WorkerPool(path.join(__dirname, 'worker.js'));
35
+ const w1 = workerPool.registerWorker(0);
36
+ const w2 = workerPool.registerWorker(0);
37
+ const w3 = workerPool.registerWorker(0);
38
+ assert.notEqual(w1, w2);
39
+ assert.notEqual(w2, w3);
40
+ assert.notEqual(w1, w3);
41
+
42
+ assert.deepEqual(workerPool.getStats(), {
43
+ totalWorkers: 3,
44
+ workersInUse: 3,
45
+ });
46
+ });
47
+
48
+ it('workers can be released and will then be reused', async () => {
49
+ const workerPool = new WorkerPool(path.join(__dirname, 'worker.js'));
50
+ const worker1 = workerPool.registerWorker(0);
51
+ workerPool.registerWorker(5);
52
+ assert.deepEqual(workerPool.getStats(), {
53
+ totalWorkers: 2,
54
+ workersInUse: 2,
55
+ });
56
+
57
+ // Release the worker
58
+ workerPool.releaseWorkers([worker1]);
59
+ assert.deepEqual(workerPool.getStats(), {
60
+ totalWorkers: 2,
61
+ workersInUse: 1,
62
+ });
63
+
64
+ const worker3 = workerPool.registerWorker(33);
65
+ assert.equal(worker1, worker3);
66
+
67
+ const worker = workerPool.getWorker(worker3);
68
+ const status = await probeStatus(worker);
69
+ assert.deepEqual(status, {
70
+ type: 'status',
71
+ status: 'test-status-ok',
72
+ receivedMessages: [
73
+ {
74
+ type: 'registerWorker',
75
+ tx_worker: 0,
76
+ },
77
+ {
78
+ type: 'registerWorker',
79
+ tx_worker: 33,
80
+ },
81
+ ],
82
+ });
83
+ });
84
+
85
+ describe('shutdown', () => {
86
+ it('terminates all workers', async () => {
87
+ const workerPool = new WorkerPool(path.join(__dirname, 'worker.js'));
88
+ const worker1Id = workerPool.registerWorker(0);
89
+ const worker2Id = workerPool.registerWorker(0);
90
+ const worker1 = workerPool.getWorker(worker1Id);
91
+ const worker2 = workerPool.getWorker(worker2Id);
92
+
93
+ const worker1Exit = new Promise((resolve) => {
94
+ worker1.on('exit', () => {
95
+ resolve(null);
96
+ });
97
+ });
98
+ const worker2Exit = new Promise((resolve) => {
99
+ worker2.on('exit', () => {
100
+ resolve(null);
101
+ });
102
+ });
103
+
104
+ workerPool.shutdown();
105
+ assert.throws(() => {
106
+ workerPool.getWorker(worker1Id);
107
+ });
108
+ assert.throws(() => {
109
+ workerPool.getWorker(worker2Id);
110
+ });
111
+
112
+ await worker1Exit;
113
+ await worker2Exit;
114
+
115
+ assert.deepEqual(workerPool.getStats(), {
116
+ totalWorkers: 0,
117
+ workersInUse: 0,
118
+ });
119
+ });
120
+ });
121
+ });
@@ -0,0 +1,23 @@
1
+ const {parentPort} = require('worker_threads');
2
+
3
+ const receivedMessages = [];
4
+
5
+ parentPort.on('message', (message) => {
6
+ if (message.type === 'registerWorker') {
7
+ parentPort.postMessage({
8
+ type: 'workerRegistered',
9
+ });
10
+ } else if (message.type === 'probeStatus') {
11
+ parentPort.postMessage({
12
+ type: 'status',
13
+ status: 'test-status-ok',
14
+ receivedMessages,
15
+ });
16
+ }
17
+
18
+ receivedMessages.push(message);
19
+ parentPort.postMessage({
20
+ type: 'received',
21
+ message,
22
+ });
23
+ });