like-thread 1.0.0 → 1.0.2
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/index.js +199 -272
- package/package.json +4 -2
- package/worker.js +77 -0
package/index.js
CHANGED
|
@@ -1,369 +1,296 @@
|
|
|
1
|
-
const
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const { Worker } = require('worker_threads')
|
|
4
|
+
const promiseWithResolvers = require('promise-resolvers')
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
const promiseWithResolvers = require('promise-resolvers')
|
|
6
|
+
const WORKER_SCRIPT = fs.readFileSync(path.join(__dirname, 'worker.js'), 'utf8')
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
module.exports = class Thread {
|
|
9
|
+
static go (args, fn) {
|
|
10
|
+
const thread = new this(fn, args)
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
if (!thread.isGenerator) {
|
|
13
|
+
const value = thread.call(...args)
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
return value.finally(() => thread.close())
|
|
16
|
+
}
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
const iterator = thread.call(...args)
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
return {
|
|
21
|
+
[Symbol.asyncIterator] () {
|
|
22
|
+
return this
|
|
23
|
+
},
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
async next () {
|
|
26
|
+
const result = await iterator.next()
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
if (result.done) {
|
|
29
|
+
await thread.close()
|
|
30
|
+
}
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
return result
|
|
33
|
+
},
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
35
|
+
async return (value) {
|
|
36
|
+
try {
|
|
37
|
+
return await iterator.return(value)
|
|
38
|
+
} finally {
|
|
39
|
+
await thread.close()
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
}
|
|
43
|
+
}
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
constructor (fn, opts = {}) {
|
|
46
|
+
const workerData = {
|
|
47
|
+
fn: fn.toString()
|
|
48
|
+
}
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
const entrypoint = workerData.fn.match(/(async )?function( ?\* ?)? ([a-zA-Z0-9]+)? ?\(([^)]*?)\)/i)
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
this.isAsync = !!entrypoint[1]
|
|
53
|
+
this.isGenerator = !!entrypoint[2]
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
this.worker = new Worker(WORKER_SCRIPT, { eval: true, workerData, argv: opts.argv || null })
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
this.id = 1
|
|
58
|
+
this.requests = new Map()
|
|
57
59
|
|
|
58
|
-
|
|
60
|
+
this.worker.on('message', this._onMessage.bind(this))
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
this.promise = new Promise((resolve, reject) => {
|
|
63
|
+
let error = null
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
this.worker.on('error', err => {
|
|
66
|
+
error = err
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
for (const [id, req] of this.requests) {
|
|
69
|
+
this.requests.delete(id)
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
71
|
+
if (req.resolver) {
|
|
72
|
+
req.resolver.reject(err)
|
|
73
|
+
} else {
|
|
74
|
+
req.iterator.fail(err)
|
|
74
75
|
}
|
|
76
|
+
}
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this.worker.on('exit', (exitCode, signal) => {
|
|
80
|
-
if (error) return
|
|
81
|
-
|
|
82
|
-
const err = new Error('Worker closed (' + exitCode + ' and ' + signal + ')')
|
|
78
|
+
reject(err)
|
|
79
|
+
})
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
this.worker.on('exit', (exitCode, signal) => {
|
|
82
|
+
if (error) return
|
|
86
83
|
|
|
87
|
-
|
|
88
|
-
req.resolver.reject(err)
|
|
89
|
-
} else {
|
|
90
|
-
req.iterator.fail(err)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
84
|
+
const err = new Error('Worker closed (' + exitCode + ' and ' + signal + ')')
|
|
93
85
|
|
|
94
|
-
|
|
86
|
+
for (const [id, req] of this.requests) {
|
|
87
|
+
this.requests.delete(id)
|
|
95
88
|
|
|
96
|
-
if (
|
|
97
|
-
|
|
89
|
+
if (req.resolver) {
|
|
90
|
+
req.resolver.reject(err)
|
|
98
91
|
} else {
|
|
99
|
-
|
|
92
|
+
req.iterator.fail(err)
|
|
100
93
|
}
|
|
101
|
-
})
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
_onMessage (msg) {
|
|
106
|
-
const req = this.requests.get(msg.id)
|
|
107
|
-
|
|
108
|
-
if (!req) {
|
|
109
|
-
return
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// console.log('_onMessage', msg, !!req.iterator ? 'iterator' : 'promise')
|
|
113
|
-
|
|
114
|
-
if (msg.error) {
|
|
115
|
-
this.requests.delete(msg.id)
|
|
116
|
-
|
|
117
|
-
const err = new Error(msg.error)
|
|
118
|
-
|
|
119
|
-
if (req.resolver) {
|
|
120
|
-
req.resolver.reject(err)
|
|
121
|
-
} else {
|
|
122
|
-
req.iterator.fail(err)
|
|
123
94
|
}
|
|
124
95
|
|
|
125
|
-
|
|
126
|
-
}
|
|
96
|
+
const success = exitCode === 0 || exitCode === 130 || signal === 'SIGINT' || signal === 'SIGTERM' || signal === 'SIGHUP'
|
|
127
97
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (req.resolver) {
|
|
131
|
-
req.resolver.resolve(msg.value)
|
|
98
|
+
if (success) {
|
|
99
|
+
resolve()
|
|
132
100
|
} else {
|
|
133
|
-
|
|
101
|
+
reject(err)
|
|
134
102
|
}
|
|
103
|
+
})
|
|
104
|
+
})
|
|
135
105
|
|
|
136
|
-
|
|
137
|
-
|
|
106
|
+
this.promise.catch(noop)
|
|
107
|
+
}
|
|
138
108
|
|
|
139
|
-
|
|
140
|
-
|
|
109
|
+
_onMessage (msg) {
|
|
110
|
+
const req = this.requests.get(msg.id)
|
|
141
111
|
|
|
142
|
-
|
|
112
|
+
if (!req) {
|
|
113
|
+
return
|
|
114
|
+
}
|
|
143
115
|
|
|
144
|
-
|
|
145
|
-
}
|
|
116
|
+
// console.log('_onMessage', msg, !!req.iterator ? 'iterator' : 'promise')
|
|
146
117
|
|
|
118
|
+
if (msg.error) {
|
|
147
119
|
this.requests.delete(msg.id)
|
|
148
120
|
|
|
121
|
+
const err = new Error(msg.error)
|
|
122
|
+
|
|
149
123
|
if (req.resolver) {
|
|
150
|
-
req.resolver.reject(
|
|
124
|
+
req.resolver.reject(err)
|
|
151
125
|
} else {
|
|
152
|
-
req.iterator.fail(
|
|
126
|
+
req.iterator.fail(err)
|
|
153
127
|
}
|
|
128
|
+
|
|
129
|
+
return
|
|
154
130
|
}
|
|
155
131
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
132
|
+
// msg.value can be a falsy value like 0 or null
|
|
133
|
+
if (msg.v) {
|
|
134
|
+
if (req.resolver) {
|
|
135
|
+
req.resolver.resolve(msg.value)
|
|
136
|
+
} else {
|
|
137
|
+
req.iterator.push(msg.value)
|
|
159
138
|
}
|
|
160
139
|
|
|
161
|
-
|
|
140
|
+
return
|
|
141
|
+
}
|
|
162
142
|
|
|
163
|
-
|
|
164
|
-
|
|
143
|
+
if (msg.done) {
|
|
144
|
+
this.requests.delete(msg.id)
|
|
165
145
|
|
|
166
|
-
|
|
146
|
+
req.iterator.close()
|
|
167
147
|
|
|
168
|
-
|
|
169
|
-
|
|
148
|
+
return
|
|
149
|
+
}
|
|
170
150
|
|
|
171
|
-
|
|
151
|
+
this.requests.delete(msg.id)
|
|
172
152
|
|
|
173
|
-
|
|
153
|
+
if (req.resolver) {
|
|
154
|
+
req.resolver.reject(new Error('Invalid message'))
|
|
155
|
+
} else {
|
|
156
|
+
req.iterator.fail(new Error('Invalid message'))
|
|
157
|
+
}
|
|
158
|
+
}
|
|
174
159
|
|
|
175
|
-
|
|
176
|
-
|
|
160
|
+
call (...args) {
|
|
161
|
+
if (this.id === 0xffffffff) {
|
|
162
|
+
this.id = 1
|
|
163
|
+
}
|
|
177
164
|
|
|
178
|
-
|
|
179
|
-
resolver: promiseWithResolvers(),
|
|
180
|
-
queue: [],
|
|
181
|
-
closed: false,
|
|
182
|
-
push: function (value) {
|
|
183
|
-
if (this.closed) {
|
|
184
|
-
return
|
|
185
|
-
}
|
|
165
|
+
const id = this.id++
|
|
186
166
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
},
|
|
190
|
-
fail: function (err) {
|
|
191
|
-
if (this.closed) {
|
|
192
|
-
return
|
|
193
|
-
}
|
|
167
|
+
const sab = new SharedArrayBuffer(4)
|
|
168
|
+
const control = new Int32Array(sab)
|
|
194
169
|
|
|
195
|
-
|
|
196
|
-
this.resolver.resolve(err)
|
|
197
|
-
},
|
|
198
|
-
close: function () {
|
|
199
|
-
if (this.closed) {
|
|
200
|
-
return
|
|
201
|
-
}
|
|
170
|
+
Atomics.store(control, 0, 0)
|
|
202
171
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
}
|
|
172
|
+
if (!this.isGenerator) {
|
|
173
|
+
const resolver = promiseWithResolvers()
|
|
207
174
|
|
|
208
|
-
this.requests.set(id, {
|
|
175
|
+
this.requests.set(id, { resolver })
|
|
209
176
|
|
|
210
177
|
this.worker.postMessage({ id, args, sab })
|
|
211
178
|
|
|
212
|
-
return
|
|
213
|
-
|
|
214
|
-
return this
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
async next () {
|
|
218
|
-
Atomics.store(control, 0, 1)
|
|
219
|
-
Atomics.notify(control, 0, 1)
|
|
220
|
-
|
|
221
|
-
const err = await iterator.resolver.promise
|
|
179
|
+
return resolver.promise
|
|
180
|
+
}
|
|
222
181
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
182
|
+
const iterator = {
|
|
183
|
+
resolver: promiseWithResolvers(),
|
|
184
|
+
queue: [],
|
|
185
|
+
closed: false,
|
|
186
|
+
push: function (value) {
|
|
187
|
+
if (this.closed) {
|
|
188
|
+
return
|
|
189
|
+
}
|
|
226
190
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
191
|
+
this.queue.push({ value, done: false })
|
|
192
|
+
this.resolver.resolve()
|
|
193
|
+
},
|
|
194
|
+
fail: function (err) {
|
|
195
|
+
if (this.closed) {
|
|
196
|
+
return
|
|
197
|
+
}
|
|
230
198
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
199
|
+
this.closed = true
|
|
200
|
+
this.resolver.resolve(err)
|
|
201
|
+
},
|
|
202
|
+
close: function () {
|
|
203
|
+
if (this.closed) {
|
|
204
|
+
return
|
|
205
|
+
}
|
|
234
206
|
|
|
235
|
-
|
|
207
|
+
this.closed = true
|
|
208
|
+
this.resolver.resolve()
|
|
209
|
+
}
|
|
210
|
+
}
|
|
236
211
|
|
|
237
|
-
|
|
238
|
-
},
|
|
212
|
+
this.requests.set(id, { iterator })
|
|
239
213
|
|
|
240
|
-
|
|
241
|
-
iterator.closed = true
|
|
214
|
+
this.worker.postMessage({ id, args, sab })
|
|
242
215
|
|
|
243
|
-
|
|
244
|
-
|
|
216
|
+
return {
|
|
217
|
+
[Symbol.asyncIterator] () {
|
|
218
|
+
return this
|
|
219
|
+
},
|
|
245
220
|
|
|
246
|
-
|
|
247
|
-
|
|
221
|
+
async next () {
|
|
222
|
+
Atomics.store(control, 0, 1)
|
|
223
|
+
Atomics.notify(control, 0, 1)
|
|
248
224
|
|
|
249
|
-
|
|
250
|
-
// iterator.resolver.resolve()
|
|
225
|
+
const err = await iterator.resolver.promise
|
|
251
226
|
|
|
252
|
-
|
|
227
|
+
if (err) {
|
|
228
|
+
throw err
|
|
253
229
|
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
230
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
}
|
|
231
|
+
if (iterator.queue.length === 0) {
|
|
232
|
+
return { done: true }
|
|
233
|
+
}
|
|
262
234
|
|
|
263
|
-
|
|
264
|
-
|
|
235
|
+
if (iterator.queue.length === 1) {
|
|
236
|
+
iterator.resolver = promiseWithResolvers()
|
|
237
|
+
}
|
|
265
238
|
|
|
266
|
-
|
|
267
|
-
}
|
|
239
|
+
const item = iterator.queue.shift()
|
|
268
240
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
241
|
+
return item
|
|
242
|
+
},
|
|
272
243
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
244
|
+
return: () => {
|
|
245
|
+
iterator.closed = true
|
|
276
246
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
finally (onFinally) {
|
|
282
|
-
return this.promise.finally(onFinally)
|
|
283
|
-
}
|
|
247
|
+
Atomics.store(control, 0, 2)
|
|
248
|
+
Atomics.notify(control, 0, 1)
|
|
284
249
|
|
|
285
|
-
|
|
286
|
-
|
|
250
|
+
// this.worker.postMessage({ id, command: 'stop' })
|
|
251
|
+
// return
|
|
287
252
|
|
|
288
|
-
|
|
253
|
+
// iterator.queue.length = 0
|
|
254
|
+
// iterator.resolver.resolve()
|
|
289
255
|
|
|
290
|
-
|
|
256
|
+
return Promise.resolve({ done: true })
|
|
257
|
+
}
|
|
291
258
|
}
|
|
292
259
|
}
|
|
293
|
-
} else {
|
|
294
|
-
const entrypoint = workerData.fn.match(/(async )?function( ?\* ?)? ([a-zA-Z0-9]+)? ?\(([^)]*?)\)/i)
|
|
295
|
-
|
|
296
|
-
const isAsync = !!entrypoint[1]
|
|
297
|
-
const isGenerator = !!entrypoint[2]
|
|
298
|
-
const functionName = entrypoint[3] || '_WORKER_MAIN_'
|
|
299
|
-
const functionArgs = entrypoint[4] || ''
|
|
300
|
-
|
|
301
|
-
const fn = workerData.fn.replace(entrypoint[0], (isAsync ? 'async ' : '') + 'function ' + (isGenerator ? '* ' : '') + functionName + ' (' + (functionArgs) + ')')
|
|
302
260
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return
|
|
261
|
+
async * [Symbol.asyncIterator] () {
|
|
262
|
+
for await (const [value] of this.iterator) {
|
|
263
|
+
yield value
|
|
307
264
|
}
|
|
265
|
+
}
|
|
308
266
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const source = fn + '\n\nmodule.exports = ' + functionName + '(...' + JSON.stringify(msg.args || []) + ')'
|
|
312
|
-
|
|
313
|
-
const wrap = new Function('require', '__dirname', '__filename', 'module', 'exports', 'parentPort', source) // eslint-disable-line no-new-func
|
|
314
|
-
|
|
315
|
-
const mod = { exports: {} }
|
|
316
|
-
|
|
317
|
-
wrap(require, __dirname, __filename, mod, mod.exports, parentPort)
|
|
318
|
-
|
|
319
|
-
const out = mod.exports
|
|
320
|
-
|
|
321
|
-
if (isGenerator) {
|
|
322
|
-
const control = new Int32Array(msg.sab)
|
|
323
|
-
const it = out[Symbol.asyncIterator] ? out[Symbol.asyncIterator]() : out[Symbol.iterator]()
|
|
324
|
-
|
|
325
|
-
while (true) {
|
|
326
|
-
while (Atomics.load(control, 0) === 0) {
|
|
327
|
-
const res = Atomics.waitAsync(control, 0, 0)
|
|
328
|
-
|
|
329
|
-
if (res.async) {
|
|
330
|
-
await res.value
|
|
331
|
-
} else {
|
|
332
|
-
break
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
if (Atomics.load(control, 0) === 2) {
|
|
337
|
-
break
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const { value, done } = await it.next()
|
|
341
|
-
|
|
342
|
-
Atomics.store(control, 0, 0)
|
|
267
|
+
async next () {
|
|
268
|
+
const { done, value } = await this.iterator.next()
|
|
343
269
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
break
|
|
347
|
-
}
|
|
270
|
+
return { done, value: done ? undefined : value[0] }
|
|
271
|
+
}
|
|
348
272
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
273
|
+
return () {
|
|
274
|
+
return this.iterator.return()
|
|
275
|
+
}
|
|
352
276
|
|
|
353
|
-
|
|
354
|
-
|
|
277
|
+
then (onFulfilled, onRejected) {
|
|
278
|
+
return this.promise.then(onFulfilled, onRejected)
|
|
279
|
+
}
|
|
355
280
|
|
|
356
|
-
|
|
357
|
-
|
|
281
|
+
catch (onRejected) {
|
|
282
|
+
return this.promise.catch(onRejected)
|
|
283
|
+
}
|
|
358
284
|
|
|
359
|
-
|
|
285
|
+
finally (onFinally) {
|
|
286
|
+
return this.promise.finally(onFinally)
|
|
287
|
+
}
|
|
360
288
|
|
|
361
|
-
|
|
362
|
-
|
|
289
|
+
async close () {
|
|
290
|
+
this.worker.postMessage({ command: 'exit' })
|
|
363
291
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
parentPort.postMessage({ id: msg.id, error: err })
|
|
367
|
-
}
|
|
368
|
-
})
|
|
292
|
+
await this.promise.catch(noop)
|
|
293
|
+
}
|
|
369
294
|
}
|
|
295
|
+
|
|
296
|
+
function noop () {}
|
package/package.json
CHANGED
package/worker.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const { workerData, parentPort } = require('worker_threads')
|
|
2
|
+
|
|
3
|
+
const entrypoint = workerData.fn.match(/(async )?function( ?\* ?)? ([a-zA-Z0-9]+)? ?\(([^)]*?)\)/i)
|
|
4
|
+
|
|
5
|
+
const isAsync = !!entrypoint[1]
|
|
6
|
+
const isGenerator = !!entrypoint[2]
|
|
7
|
+
const functionName = entrypoint[3] || '_WORKER_MAIN_'
|
|
8
|
+
const functionArgs = entrypoint[4] || ''
|
|
9
|
+
|
|
10
|
+
const fn = workerData.fn.replace(entrypoint[0], (isAsync ? 'async ' : '') + 'function ' + (isGenerator ? '* ' : '') + functionName + ' (' + (functionArgs) + ')')
|
|
11
|
+
|
|
12
|
+
parentPort.on('message', async (msg) => {
|
|
13
|
+
if (msg.command === 'exit') {
|
|
14
|
+
process.exit()
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
// TODO: Optimize by creating the function only once by fixing the args
|
|
20
|
+
const source = fn + '\n\nmodule.exports = ' + functionName + '(...' + JSON.stringify(msg.args || []) + ')'
|
|
21
|
+
|
|
22
|
+
const wrap = new Function('require', '__dirname', '__filename', 'module', 'exports', 'parentPort', source) // eslint-disable-line no-new-func
|
|
23
|
+
|
|
24
|
+
const mod = { exports: {} }
|
|
25
|
+
|
|
26
|
+
wrap(require, __dirname, __filename, mod, mod.exports, parentPort)
|
|
27
|
+
|
|
28
|
+
const out = mod.exports
|
|
29
|
+
|
|
30
|
+
if (isGenerator) {
|
|
31
|
+
const control = new Int32Array(msg.sab)
|
|
32
|
+
const it = out[Symbol.asyncIterator] ? out[Symbol.asyncIterator]() : out[Symbol.iterator]()
|
|
33
|
+
|
|
34
|
+
while (true) {
|
|
35
|
+
while (Atomics.load(control, 0) === 0) {
|
|
36
|
+
const res = Atomics.waitAsync(control, 0, 0)
|
|
37
|
+
|
|
38
|
+
if (res.async) {
|
|
39
|
+
await res.value
|
|
40
|
+
} else {
|
|
41
|
+
break
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (Atomics.load(control, 0) === 2) {
|
|
46
|
+
break
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const { value, done } = await it.next()
|
|
50
|
+
|
|
51
|
+
Atomics.store(control, 0, 0)
|
|
52
|
+
|
|
53
|
+
if (done) {
|
|
54
|
+
parentPort.postMessage({ id: msg.id, done: true })
|
|
55
|
+
break
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Keep "v" because "value" can be falsy like 0 or null
|
|
59
|
+
parentPort.postMessage({ id: msg.id, value, v: true })
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (isAsync) {
|
|
66
|
+
const value = await out
|
|
67
|
+
|
|
68
|
+
parentPort.postMessage({ id: msg.id, value, v: true })
|
|
69
|
+
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
parentPort.postMessage({ id: msg.id, value: out, v: true })
|
|
74
|
+
} catch (err) {
|
|
75
|
+
parentPort.postMessage({ id: msg.id, error: err })
|
|
76
|
+
}
|
|
77
|
+
})
|