promise-worker-bi 4.1.1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/{esmodules.mjs → index.js} +50 -108
- package/package.json +74 -73
- package/dist/commonjs.js +0 -436
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type ErrorCallback = (a: Error) => void;
|
|
2
|
+
type QueryCallback = (a: any[], b: number | undefined) => any;
|
|
3
3
|
declare abstract class PWBBase {
|
|
4
4
|
_callbacks: Map<number, (a: Error | null, b: any) => void>;
|
|
5
5
|
_queryCallback: QueryCallback;
|
|
@@ -4,96 +4,82 @@ const MSGTYPE_RESPONSE = 1;
|
|
|
4
4
|
const MSGTYPE_HOST_ID = 2;
|
|
5
5
|
const MSGTYPE_HOST_CLOSE = 3;
|
|
6
6
|
const MSGTYPE_WORKER_ERROR = 4;
|
|
7
|
-
const MSGTYPES = [MSGTYPE_QUERY, MSGTYPE_RESPONSE, MSGTYPE_HOST_ID, MSGTYPE_HOST_CLOSE, MSGTYPE_WORKER_ERROR];
|
|
7
|
+
const MSGTYPES = [MSGTYPE_QUERY, MSGTYPE_RESPONSE, MSGTYPE_HOST_ID, MSGTYPE_HOST_CLOSE, MSGTYPE_WORKER_ERROR];
|
|
8
8
|
|
|
9
|
+
// Inlined from https://github.com/then/is-promise
|
|
9
10
|
const isPromise = obj => !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
|
|
10
|
-
|
|
11
11
|
const toFakeError = error => {
|
|
12
12
|
const fakeError = {
|
|
13
13
|
name: error.name,
|
|
14
14
|
message: error.message
|
|
15
15
|
};
|
|
16
|
-
|
|
17
16
|
if (typeof error.stack === "string") {
|
|
18
17
|
fakeError.stack = error.stack;
|
|
19
|
-
}
|
|
20
|
-
// @ts-expect-error
|
|
21
|
-
|
|
18
|
+
}
|
|
22
19
|
|
|
20
|
+
// These are non-standard properties, I think only in some versions of Firefox
|
|
21
|
+
// @ts-expect-error
|
|
23
22
|
if (typeof error.fileName === "string") {
|
|
24
23
|
// @ts-expect-error
|
|
25
24
|
fakeError.fileName = error.fileName;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
}
|
|
26
|
+
// @ts-expect-error
|
|
29
27
|
if (typeof error.columnNumber === "number") {
|
|
30
28
|
// @ts-expect-error
|
|
31
29
|
fakeError.columnNumber = error.columnNumber;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
}
|
|
31
|
+
// @ts-expect-error
|
|
35
32
|
if (typeof error.lineNumber === "number") {
|
|
36
33
|
// @ts-expect-error
|
|
37
34
|
fakeError.lineNumber = error.lineNumber;
|
|
38
35
|
}
|
|
39
|
-
|
|
40
36
|
return fakeError;
|
|
41
|
-
};
|
|
42
|
-
|
|
37
|
+
};
|
|
43
38
|
|
|
39
|
+
// Object rather than FakeError for convenience
|
|
44
40
|
const fromFakeError = fakeError => {
|
|
45
41
|
const error = new Error();
|
|
46
42
|
return Object.assign(error, fakeError);
|
|
47
43
|
};
|
|
48
|
-
|
|
49
44
|
const logError = err => {
|
|
50
45
|
// Logging in the console makes debugging in the worker easier
|
|
51
|
-
|
|
52
|
-
/* eslint-disable no-console */
|
|
53
46
|
console.error("Error in Worker:");
|
|
54
47
|
console.error(err); // Safari needs it on new line
|
|
55
|
-
|
|
56
|
-
/* eslint-enable no-console */
|
|
57
48
|
};
|
|
58
|
-
|
|
59
49
|
class PWBBase {
|
|
60
50
|
constructor() {
|
|
61
51
|
// console.log('constructor', worker);
|
|
62
|
-
this._callbacks = new Map();
|
|
63
|
-
|
|
64
|
-
this._queryCallback = () => {}; // @ts-expect-error
|
|
65
|
-
|
|
52
|
+
this._callbacks = new Map();
|
|
53
|
+
this._queryCallback = () => {};
|
|
66
54
|
|
|
55
|
+
// @ts-expect-error
|
|
67
56
|
this._onMessage = this._onMessage.bind(this);
|
|
68
57
|
}
|
|
69
|
-
|
|
70
58
|
register(cb) {
|
|
71
59
|
// console.log('register', cb);
|
|
72
60
|
this._queryCallback = cb;
|
|
73
|
-
}
|
|
61
|
+
}
|
|
74
62
|
|
|
63
|
+
// From worker, 2nd param could be hostID if sending to specific host. From UI, 2nd param could be an array of transferable objects
|
|
75
64
|
|
|
76
65
|
_postResponse(messageID, error, result, hostID) {
|
|
77
66
|
// console.log('_postResponse', messageID, error, result);
|
|
78
67
|
if (error) {
|
|
79
68
|
logError(error);
|
|
80
|
-
|
|
81
69
|
this._postMessage([MSGTYPE_RESPONSE, messageID, toFakeError(error)], hostID);
|
|
82
70
|
} else {
|
|
83
71
|
// Hackily identify when message contains transferable objects
|
|
84
|
-
if (typeof result === "object" && result !== null &&
|
|
72
|
+
if (typeof result === "object" && result !== null && Object.hasOwn(result, "message") && Object.hasOwn(result, "_PWB_TRANSFER")) {
|
|
85
73
|
this._postMessage([MSGTYPE_RESPONSE, messageID, null, result.message], hostID, result._PWB_TRANSFER);
|
|
86
74
|
} else {
|
|
87
75
|
this._postMessage([MSGTYPE_RESPONSE, messageID, null, result], hostID);
|
|
88
76
|
}
|
|
89
77
|
}
|
|
90
78
|
}
|
|
91
|
-
|
|
92
79
|
_handleQuery(messageID, query, hostID) {
|
|
93
80
|
// console.log('_handleQuery', messageID, query);
|
|
94
81
|
try {
|
|
95
82
|
const result = this._queryCallback(query, hostID);
|
|
96
|
-
|
|
97
83
|
if (!isPromise(result)) {
|
|
98
84
|
this._postResponse(messageID, null, result, hostID);
|
|
99
85
|
} else {
|
|
@@ -106,78 +92,61 @@ class PWBBase {
|
|
|
106
92
|
} catch (err) {
|
|
107
93
|
this._postResponse(messageID, err);
|
|
108
94
|
}
|
|
109
|
-
}
|
|
110
|
-
|
|
95
|
+
}
|
|
111
96
|
|
|
97
|
+
// Either return messageID and type if further processing is needed, or undefined otherwise
|
|
112
98
|
_onMessageCommon(e) {
|
|
113
|
-
// eslint-disable-line no-undef
|
|
114
99
|
// console.log('_onMessage', e.data);
|
|
115
100
|
const message = e.data;
|
|
116
|
-
|
|
117
101
|
if (!Array.isArray(message) || message.length < 3 || message.length > 4) {
|
|
118
102
|
return; // Ignore - this message is not for us
|
|
119
103
|
}
|
|
120
|
-
|
|
121
104
|
if (typeof message[0] !== "number" || MSGTYPES.indexOf(message[0]) < 0) {
|
|
122
105
|
throw new Error("Invalid messageID");
|
|
123
106
|
}
|
|
124
|
-
|
|
125
107
|
const type = message[0];
|
|
126
|
-
|
|
127
108
|
if (typeof message[1] !== "number") {
|
|
128
109
|
throw new Error("Invalid messageID");
|
|
129
110
|
}
|
|
130
|
-
|
|
131
111
|
const messageID = message[1];
|
|
132
|
-
|
|
133
112
|
if (type === MSGTYPE_QUERY) {
|
|
134
113
|
const query = message[2];
|
|
135
|
-
|
|
136
114
|
if (typeof message[3] !== "number" && message[3] !== undefined) {
|
|
137
115
|
throw new Error("Invalid hostID");
|
|
138
116
|
}
|
|
139
|
-
|
|
140
117
|
const hostID = message[3];
|
|
141
|
-
|
|
142
118
|
this._handleQuery(messageID, query, hostID);
|
|
143
|
-
|
|
144
119
|
return;
|
|
145
120
|
}
|
|
146
|
-
|
|
147
121
|
if (type === MSGTYPE_RESPONSE) {
|
|
148
122
|
if (message[2] !== null && typeof message[2] !== "object") {
|
|
149
123
|
throw new Error("Invalid error");
|
|
150
124
|
}
|
|
151
|
-
|
|
152
125
|
const error = message[2] === null ? null : fromFakeError(message[2]);
|
|
153
126
|
const result = message[3];
|
|
154
|
-
|
|
155
127
|
const callback = this._callbacks.get(messageID);
|
|
156
|
-
|
|
157
128
|
if (callback === undefined) {
|
|
158
129
|
// Ignore - user might have created multiple PromiseWorkers.
|
|
159
130
|
// This message is not for us.
|
|
160
131
|
return;
|
|
161
132
|
}
|
|
162
|
-
|
|
163
133
|
this._callbacks.delete(messageID);
|
|
164
|
-
|
|
165
134
|
callback(error, result);
|
|
166
135
|
return;
|
|
167
136
|
}
|
|
168
|
-
|
|
169
137
|
return {
|
|
170
138
|
message,
|
|
171
139
|
type
|
|
172
140
|
};
|
|
173
141
|
}
|
|
174
|
-
|
|
175
142
|
}
|
|
176
|
-
|
|
177
143
|
class PWBHost extends PWBBase {
|
|
178
144
|
// Only defined on host
|
|
145
|
+
|
|
179
146
|
constructor(worker) {
|
|
180
|
-
super();
|
|
147
|
+
super();
|
|
148
|
+
|
|
149
|
+
// The following if statement used to check `worker instanceof Worker` but I have recieved
|
|
181
150
|
// reports that in some weird cases, Safari will inappropriately return false for that, even
|
|
182
151
|
// in obvious cases like:
|
|
183
152
|
//
|
|
@@ -187,21 +156,23 @@ class PWBHost extends PWBBase {
|
|
|
187
156
|
//
|
|
188
157
|
// So instead, let's do this test for worker.port which only exists on shared workers.
|
|
189
158
|
// @ts-expect-error
|
|
190
|
-
|
|
191
159
|
if (worker.port === undefined) {
|
|
192
|
-
this._workerType = "Worker";
|
|
160
|
+
this._workerType = "Worker";
|
|
193
161
|
|
|
162
|
+
// @ts-expect-error
|
|
194
163
|
worker.addEventListener("message", this._onMessage);
|
|
195
164
|
} else {
|
|
196
|
-
this._workerType = "SharedWorker";
|
|
165
|
+
this._workerType = "SharedWorker";
|
|
197
166
|
|
|
198
|
-
|
|
167
|
+
// @ts-expect-error - it doesn't know if _worker is Worker or SharedWorker, but I do
|
|
168
|
+
worker.port.addEventListener("message", this._onMessage);
|
|
169
|
+
// @ts-expect-error - it doesn't know if _worker is Worker or SharedWorker, but I do
|
|
170
|
+
worker.port.start();
|
|
199
171
|
|
|
200
|
-
|
|
172
|
+
// Handle tab close. This isn't perfect, but there is no perfect method
|
|
201
173
|
// http://stackoverflow.com/q/13662089/786644 and this should work like
|
|
202
174
|
// 99% of the time. It is a memory leak if it fails, but for most use
|
|
203
175
|
// cases, it shouldn't be noticeable.
|
|
204
|
-
|
|
205
176
|
window.addEventListener("beforeunload", () => {
|
|
206
177
|
// Prevent firing if we don't know hostID yet
|
|
207
178
|
if (this._hostID !== undefined) {
|
|
@@ -209,22 +180,20 @@ class PWBHost extends PWBBase {
|
|
|
209
180
|
}
|
|
210
181
|
});
|
|
211
182
|
}
|
|
212
|
-
|
|
213
183
|
this._worker = worker;
|
|
214
184
|
this._hostIDQueue = [];
|
|
215
185
|
}
|
|
216
|
-
|
|
217
186
|
registerError(cb) {
|
|
218
187
|
// console.log('registerError', cb);
|
|
219
|
-
this._errorCallback = cb;
|
|
220
|
-
// (Chrome) do nothing. Let's disable that everywhere, for consistency.
|
|
188
|
+
this._errorCallback = cb;
|
|
221
189
|
|
|
190
|
+
// Some browsers (Firefox) call onerror on every host, while others
|
|
191
|
+
// (Chrome) do nothing. Let's disable that everywhere, for consistency.
|
|
222
192
|
this._worker.addEventListener("error", e => {
|
|
223
193
|
e.preventDefault();
|
|
224
194
|
e.stopPropagation();
|
|
225
195
|
});
|
|
226
196
|
}
|
|
227
|
-
|
|
228
197
|
_postMessage(obj, _hostID, transfer) {
|
|
229
198
|
// console.log('_postMessage', obj, _hostID, transfer);
|
|
230
199
|
if (this._workerType === "Worker") {
|
|
@@ -237,14 +206,12 @@ class PWBHost extends PWBBase {
|
|
|
237
206
|
throw new Error("WTF");
|
|
238
207
|
}
|
|
239
208
|
}
|
|
240
|
-
|
|
241
209
|
postMessage(userMessage, _hostID, transfer) {
|
|
242
210
|
// console.log('postMessage', userMessage, _hostID, transfer);
|
|
243
211
|
const actuallyPostMessage = (resolve, reject) => {
|
|
244
212
|
const messageID = messageIDs;
|
|
245
213
|
messageIDs += 1;
|
|
246
214
|
const messageToSend = [MSGTYPE_QUERY, messageID, userMessage, this._hostID];
|
|
247
|
-
|
|
248
215
|
this._callbacks.set(messageID, (error, result) => {
|
|
249
216
|
if (error) {
|
|
250
217
|
reject(error);
|
|
@@ -252,10 +219,8 @@ class PWBHost extends PWBBase {
|
|
|
252
219
|
resolve(result);
|
|
253
220
|
}
|
|
254
221
|
});
|
|
255
|
-
|
|
256
222
|
this._postMessage(messageToSend, undefined, transfer);
|
|
257
223
|
};
|
|
258
|
-
|
|
259
224
|
return new Promise((resolve, reject) => {
|
|
260
225
|
// Don't send a message until hostID is known, otherwise it's a race
|
|
261
226
|
// condition and sometimes hostID will be undefined.
|
|
@@ -268,25 +233,19 @@ class PWBHost extends PWBBase {
|
|
|
268
233
|
}
|
|
269
234
|
});
|
|
270
235
|
}
|
|
271
|
-
|
|
272
236
|
_onMessage(e) {
|
|
273
237
|
const common = this._onMessageCommon(e);
|
|
274
|
-
|
|
275
238
|
if (!common) {
|
|
276
239
|
return;
|
|
277
240
|
}
|
|
278
|
-
|
|
279
241
|
const message = common.message,
|
|
280
|
-
|
|
281
|
-
|
|
242
|
+
type = common.type;
|
|
282
243
|
if (type === MSGTYPE_HOST_ID) {
|
|
283
244
|
if (message[2] !== undefined && typeof message[2] !== "number") {
|
|
284
245
|
throw new Error("Invalid hostID");
|
|
285
246
|
}
|
|
286
|
-
|
|
287
247
|
const hostID = message[2];
|
|
288
248
|
this._hostID = hostID;
|
|
289
|
-
|
|
290
249
|
if (this._hostIDQueue !== undefined) {
|
|
291
250
|
this._hostIDQueue.forEach(func => {
|
|
292
251
|
// Not entirely sure why setTimeout is needed, might be just for unit tests
|
|
@@ -294,74 +253,68 @@ class PWBHost extends PWBBase {
|
|
|
294
253
|
func();
|
|
295
254
|
}, 0);
|
|
296
255
|
});
|
|
297
|
-
|
|
298
256
|
this._hostIDQueue = undefined; // Never needed again after initial setup
|
|
299
257
|
}
|
|
300
258
|
} else if (type === MSGTYPE_WORKER_ERROR) {
|
|
301
259
|
if (message[2] !== undefined && message[2] !== null && typeof message[2] === "object") {
|
|
302
260
|
const error = fromFakeError(message[2]);
|
|
303
|
-
|
|
304
261
|
if (this._errorCallback !== undefined) {
|
|
305
262
|
this._errorCallback(error);
|
|
306
263
|
}
|
|
307
264
|
}
|
|
308
265
|
}
|
|
309
266
|
}
|
|
310
|
-
|
|
311
267
|
}
|
|
312
|
-
|
|
313
268
|
class PWBWorker extends PWBBase {
|
|
314
269
|
constructor() {
|
|
315
|
-
super();
|
|
270
|
+
super();
|
|
316
271
|
|
|
272
|
+
// Only actually used for SharedWorker
|
|
317
273
|
this._hosts = new Map();
|
|
318
274
|
this._maxHostID = -1;
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
typeof SharedWorkerGlobalScope !== "undefined" &&
|
|
275
|
+
if (
|
|
276
|
+
// @ts-expect-error
|
|
277
|
+
typeof SharedWorkerGlobalScope !== "undefined" &&
|
|
278
|
+
// @ts-expect-error
|
|
322
279
|
self instanceof SharedWorkerGlobalScope) {
|
|
323
280
|
this._workerType = "SharedWorker";
|
|
324
281
|
self.addEventListener("connect", e => {
|
|
325
282
|
// @ts-expect-error
|
|
326
283
|
const port = e.ports[0];
|
|
327
|
-
port.addEventListener("message", e2 => this._onMessage(e2));
|
|
328
|
-
|
|
284
|
+
port.addEventListener("message", e2 => this._onMessage(e2));
|
|
329
285
|
port.start();
|
|
330
286
|
this._maxHostID += 1;
|
|
331
287
|
const hostID = this._maxHostID;
|
|
332
|
-
|
|
333
288
|
this._hosts.set(hostID, {
|
|
334
289
|
port
|
|
335
|
-
});
|
|
336
|
-
|
|
290
|
+
});
|
|
337
291
|
|
|
292
|
+
// Send back hostID to this host, otherwise it has no way to know it
|
|
338
293
|
this._postMessage([MSGTYPE_HOST_ID, -1, hostID], hostID);
|
|
339
294
|
});
|
|
340
295
|
self.addEventListener("error", e => {
|
|
341
|
-
logError(e.error);
|
|
296
|
+
logError(e.error);
|
|
342
297
|
|
|
298
|
+
// Just send to first host, so as to not duplicate error tracking
|
|
343
299
|
const hostID = this._hosts.keys().next().value;
|
|
344
|
-
|
|
345
300
|
if (hostID !== undefined) {
|
|
346
301
|
this._postMessage([MSGTYPE_WORKER_ERROR, -1, toFakeError(e.error)], hostID);
|
|
347
302
|
}
|
|
348
303
|
});
|
|
349
304
|
} else {
|
|
350
305
|
this._workerType = "Worker";
|
|
351
|
-
self.addEventListener("message", this._onMessage);
|
|
306
|
+
self.addEventListener("message", this._onMessage);
|
|
307
|
+
|
|
308
|
+
// Since this is not a Shared Worker, hostID is always 0 so it's not strictly required to
|
|
352
309
|
// send this back, but it makes the API a bit more consistent if there is the same
|
|
353
310
|
// initialization handshake in both cases.
|
|
354
|
-
|
|
355
311
|
this._postMessage([MSGTYPE_HOST_ID, -1, 0], 0);
|
|
356
|
-
|
|
357
312
|
self.addEventListener("error", e => {
|
|
358
313
|
logError(e.error);
|
|
359
|
-
|
|
360
314
|
this._postMessage([MSGTYPE_WORKER_ERROR, -1, toFakeError(e.error)]);
|
|
361
315
|
});
|
|
362
316
|
}
|
|
363
317
|
}
|
|
364
|
-
|
|
365
318
|
_postMessage(obj, targetHostID, transfer) {
|
|
366
319
|
// console.log('_postMessage', obj, targetHostID);
|
|
367
320
|
if (this._workerType === "SharedWorker") {
|
|
@@ -381,14 +334,12 @@ class PWBWorker extends PWBBase {
|
|
|
381
334
|
throw new Error("WTF");
|
|
382
335
|
}
|
|
383
336
|
}
|
|
384
|
-
|
|
385
337
|
postMessage(userMessage, targetHostID, transfer) {
|
|
386
338
|
// console.log('postMessage', userMessage, targetHostID);
|
|
387
339
|
const actuallyPostMessage = (resolve, reject) => {
|
|
388
340
|
const messageID = messageIDs;
|
|
389
341
|
messageIDs += 1;
|
|
390
342
|
const messageToSend = [MSGTYPE_QUERY, messageID, userMessage];
|
|
391
|
-
|
|
392
343
|
this._callbacks.set(messageID, (error, result) => {
|
|
393
344
|
if (error) {
|
|
394
345
|
reject(error);
|
|
@@ -396,36 +347,27 @@ class PWBWorker extends PWBBase {
|
|
|
396
347
|
resolve(result);
|
|
397
348
|
}
|
|
398
349
|
});
|
|
399
|
-
|
|
400
350
|
this._postMessage(messageToSend, targetHostID, transfer);
|
|
401
351
|
};
|
|
402
|
-
|
|
403
352
|
return new Promise((resolve, reject) => {
|
|
404
353
|
actuallyPostMessage(resolve, reject);
|
|
405
354
|
});
|
|
406
355
|
}
|
|
407
|
-
|
|
408
356
|
_onMessage(e) {
|
|
409
357
|
const common = this._onMessageCommon(e);
|
|
410
|
-
|
|
411
358
|
if (!common) {
|
|
412
359
|
return;
|
|
413
360
|
}
|
|
414
|
-
|
|
415
361
|
const message = common.message,
|
|
416
|
-
|
|
417
|
-
|
|
362
|
+
type = common.type;
|
|
418
363
|
if (type === MSGTYPE_HOST_CLOSE) {
|
|
419
364
|
if (typeof message[2] !== "number") {
|
|
420
365
|
throw new Error("Invalid hostID");
|
|
421
366
|
}
|
|
422
|
-
|
|
423
367
|
const hostID = message[2];
|
|
424
|
-
|
|
425
368
|
this._hosts.delete(hostID);
|
|
426
369
|
}
|
|
427
370
|
}
|
|
428
|
-
|
|
429
371
|
}
|
|
430
372
|
|
|
431
373
|
export { PWBHost, PWBWorker };
|
package/package.json
CHANGED
|
@@ -1,75 +1,76 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
2
|
+
"name": "promise-worker-bi",
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Promise-based messaging for Web Workers and Shared Workers",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"scripts": {
|
|
15
|
+
"prepublish": "node --run build",
|
|
16
|
+
"build": "rm -rf dist && rollup -c && tsc --emitDeclarationOnly",
|
|
17
|
+
"build-test": "node --run build && node scripts/build-test.js",
|
|
18
|
+
"lint": "eslint .",
|
|
19
|
+
"prettier": "prettier --write 'src/*.ts' && prettier --write 'test/*.js' && prettier --write 'scripts/*.js'",
|
|
20
|
+
"karma": "node --run build-test && karma start",
|
|
21
|
+
"test": "tsc --noEmit && node --run lint && node --run karma",
|
|
22
|
+
"prepare": "husky"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/dumbmatter/promise-worker-bi.git"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"promise",
|
|
30
|
+
"shared worker",
|
|
31
|
+
"sharedworker",
|
|
32
|
+
"web worker",
|
|
33
|
+
"webworker",
|
|
34
|
+
"worker"
|
|
35
|
+
],
|
|
36
|
+
"author": "Jeremy Scheff <jdscheff@gmail.com>",
|
|
37
|
+
"license": "Apache-2.0",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/dumbmatter/promise-worker-bi/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/dumbmatter/promise-worker-bi",
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@babel/core": "^7.19.3",
|
|
44
|
+
"@babel/plugin-transform-destructuring": "^7.18.13",
|
|
45
|
+
"@babel/preset-typescript": "^7.18.6",
|
|
46
|
+
"@eslint/js": "^9.25.1",
|
|
47
|
+
"@rollup/plugin-babel": "^6.0.4",
|
|
48
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
49
|
+
"@typescript-eslint/eslint-plugin": "^8.31.1",
|
|
50
|
+
"@typescript-eslint/parser": "^8.31.1",
|
|
51
|
+
"eslint": "^9.25.1",
|
|
52
|
+
"eslint-plugin-import-x": "^4.11.0",
|
|
53
|
+
"globals": "^16.0.0",
|
|
54
|
+
"husky": "^9.1.7",
|
|
55
|
+
"karma": "^6.4.1",
|
|
56
|
+
"karma-chrome-launcher": "^3.1.1",
|
|
57
|
+
"karma-firefox-launcher": "^2.1.2",
|
|
58
|
+
"karma-mocha": "^2.0.1",
|
|
59
|
+
"karma-mocha-reporter": "^2.2.5",
|
|
60
|
+
"lint-staged": "^15.5.1",
|
|
61
|
+
"mocha": "^11.2.2",
|
|
62
|
+
"prettier": "^3.5.3",
|
|
63
|
+
"rollup": "^4.40.1",
|
|
64
|
+
"rollup-plugin-node-builtins": "^2.1.2",
|
|
65
|
+
"rollup-plugin-node-globals": "^1.4.0",
|
|
66
|
+
"tinyglobby": "^0.2.13",
|
|
67
|
+
"typescript": "^5.8.3",
|
|
68
|
+
"typescript-eslint": "^8.31.1"
|
|
69
|
+
},
|
|
70
|
+
"files": [
|
|
71
|
+
"dist"
|
|
72
|
+
],
|
|
73
|
+
"lint-staged": {
|
|
74
|
+
"*.{js,cjs,mjs,jsx,json,scss,ts,cts,mts,tsx}": "prettier --write"
|
|
75
|
+
}
|
|
75
76
|
}
|
package/dist/commonjs.js
DELETED
|
@@ -1,436 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
let messageIDs = 0;
|
|
6
|
-
const MSGTYPE_QUERY = 0;
|
|
7
|
-
const MSGTYPE_RESPONSE = 1;
|
|
8
|
-
const MSGTYPE_HOST_ID = 2;
|
|
9
|
-
const MSGTYPE_HOST_CLOSE = 3;
|
|
10
|
-
const MSGTYPE_WORKER_ERROR = 4;
|
|
11
|
-
const MSGTYPES = [MSGTYPE_QUERY, MSGTYPE_RESPONSE, MSGTYPE_HOST_ID, MSGTYPE_HOST_CLOSE, MSGTYPE_WORKER_ERROR]; // Inlined from https://github.com/then/is-promise
|
|
12
|
-
|
|
13
|
-
const isPromise = obj => !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
|
|
14
|
-
|
|
15
|
-
const toFakeError = error => {
|
|
16
|
-
const fakeError = {
|
|
17
|
-
name: error.name,
|
|
18
|
-
message: error.message
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
if (typeof error.stack === "string") {
|
|
22
|
-
fakeError.stack = error.stack;
|
|
23
|
-
} // These are non-standard properties, I think only in some versions of Firefox
|
|
24
|
-
// @ts-expect-error
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (typeof error.fileName === "string") {
|
|
28
|
-
// @ts-expect-error
|
|
29
|
-
fakeError.fileName = error.fileName;
|
|
30
|
-
} // @ts-expect-error
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (typeof error.columnNumber === "number") {
|
|
34
|
-
// @ts-expect-error
|
|
35
|
-
fakeError.columnNumber = error.columnNumber;
|
|
36
|
-
} // @ts-expect-error
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (typeof error.lineNumber === "number") {
|
|
40
|
-
// @ts-expect-error
|
|
41
|
-
fakeError.lineNumber = error.lineNumber;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return fakeError;
|
|
45
|
-
}; // Object rather than FakeError for convenience
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const fromFakeError = fakeError => {
|
|
49
|
-
const error = new Error();
|
|
50
|
-
return Object.assign(error, fakeError);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const logError = err => {
|
|
54
|
-
// Logging in the console makes debugging in the worker easier
|
|
55
|
-
|
|
56
|
-
/* eslint-disable no-console */
|
|
57
|
-
console.error("Error in Worker:");
|
|
58
|
-
console.error(err); // Safari needs it on new line
|
|
59
|
-
|
|
60
|
-
/* eslint-enable no-console */
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
class PWBBase {
|
|
64
|
-
constructor() {
|
|
65
|
-
// console.log('constructor', worker);
|
|
66
|
-
this._callbacks = new Map(); // eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
67
|
-
|
|
68
|
-
this._queryCallback = () => {}; // @ts-expect-error
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this._onMessage = this._onMessage.bind(this);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
register(cb) {
|
|
75
|
-
// console.log('register', cb);
|
|
76
|
-
this._queryCallback = cb;
|
|
77
|
-
} // From worker, 2nd param could be hostID if sending to specific host. From UI, 2nd param could be an array of transferable objects
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
_postResponse(messageID, error, result, hostID) {
|
|
81
|
-
// console.log('_postResponse', messageID, error, result);
|
|
82
|
-
if (error) {
|
|
83
|
-
logError(error);
|
|
84
|
-
|
|
85
|
-
this._postMessage([MSGTYPE_RESPONSE, messageID, toFakeError(error)], hostID);
|
|
86
|
-
} else {
|
|
87
|
-
// Hackily identify when message contains transferable objects
|
|
88
|
-
if (typeof result === "object" && result !== null && result.hasOwnProperty("message") && result.hasOwnProperty("_PWB_TRANSFER")) {
|
|
89
|
-
this._postMessage([MSGTYPE_RESPONSE, messageID, null, result.message], hostID, result._PWB_TRANSFER);
|
|
90
|
-
} else {
|
|
91
|
-
this._postMessage([MSGTYPE_RESPONSE, messageID, null, result], hostID);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
_handleQuery(messageID, query, hostID) {
|
|
97
|
-
// console.log('_handleQuery', messageID, query);
|
|
98
|
-
try {
|
|
99
|
-
const result = this._queryCallback(query, hostID);
|
|
100
|
-
|
|
101
|
-
if (!isPromise(result)) {
|
|
102
|
-
this._postResponse(messageID, null, result, hostID);
|
|
103
|
-
} else {
|
|
104
|
-
result.then(finalResult => {
|
|
105
|
-
this._postResponse(messageID, null, finalResult, hostID);
|
|
106
|
-
}, finalError => {
|
|
107
|
-
this._postResponse(messageID, finalError, hostID);
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
} catch (err) {
|
|
111
|
-
this._postResponse(messageID, err);
|
|
112
|
-
}
|
|
113
|
-
} // Either return messageID and type if further processing is needed, or undefined otherwise
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
_onMessageCommon(e) {
|
|
117
|
-
// eslint-disable-line no-undef
|
|
118
|
-
// console.log('_onMessage', e.data);
|
|
119
|
-
const message = e.data;
|
|
120
|
-
|
|
121
|
-
if (!Array.isArray(message) || message.length < 3 || message.length > 4) {
|
|
122
|
-
return; // Ignore - this message is not for us
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (typeof message[0] !== "number" || MSGTYPES.indexOf(message[0]) < 0) {
|
|
126
|
-
throw new Error("Invalid messageID");
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const type = message[0];
|
|
130
|
-
|
|
131
|
-
if (typeof message[1] !== "number") {
|
|
132
|
-
throw new Error("Invalid messageID");
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const messageID = message[1];
|
|
136
|
-
|
|
137
|
-
if (type === MSGTYPE_QUERY) {
|
|
138
|
-
const query = message[2];
|
|
139
|
-
|
|
140
|
-
if (typeof message[3] !== "number" && message[3] !== undefined) {
|
|
141
|
-
throw new Error("Invalid hostID");
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const hostID = message[3];
|
|
145
|
-
|
|
146
|
-
this._handleQuery(messageID, query, hostID);
|
|
147
|
-
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (type === MSGTYPE_RESPONSE) {
|
|
152
|
-
if (message[2] !== null && typeof message[2] !== "object") {
|
|
153
|
-
throw new Error("Invalid error");
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const error = message[2] === null ? null : fromFakeError(message[2]);
|
|
157
|
-
const result = message[3];
|
|
158
|
-
|
|
159
|
-
const callback = this._callbacks.get(messageID);
|
|
160
|
-
|
|
161
|
-
if (callback === undefined) {
|
|
162
|
-
// Ignore - user might have created multiple PromiseWorkers.
|
|
163
|
-
// This message is not for us.
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this._callbacks.delete(messageID);
|
|
168
|
-
|
|
169
|
-
callback(error, result);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return {
|
|
174
|
-
message,
|
|
175
|
-
type
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
class PWBHost extends PWBBase {
|
|
182
|
-
// Only defined on host
|
|
183
|
-
constructor(worker) {
|
|
184
|
-
super(); // The following if statement used to check `worker instanceof Worker` but I have recieved
|
|
185
|
-
// reports that in some weird cases, Safari will inappropriately return false for that, even
|
|
186
|
-
// in obvious cases like:
|
|
187
|
-
//
|
|
188
|
-
// blob = new Blob(["self.onmessage = function() {};"], { type: "text/javascript" });
|
|
189
|
-
// worker = new Worker(window.URL.createObjectURL(blob));
|
|
190
|
-
// console.log(worker instanceof Worker);
|
|
191
|
-
//
|
|
192
|
-
// So instead, let's do this test for worker.port which only exists on shared workers.
|
|
193
|
-
// @ts-expect-error
|
|
194
|
-
|
|
195
|
-
if (worker.port === undefined) {
|
|
196
|
-
this._workerType = "Worker"; // @ts-expect-error
|
|
197
|
-
|
|
198
|
-
worker.addEventListener("message", this._onMessage);
|
|
199
|
-
} else {
|
|
200
|
-
this._workerType = "SharedWorker"; // @ts-expect-error - it doesn't know if _worker is Worker or SharedWorker, but I do
|
|
201
|
-
|
|
202
|
-
worker.port.addEventListener("message", this._onMessage); // @ts-expect-error - it doesn't know if _worker is Worker or SharedWorker, but I do
|
|
203
|
-
|
|
204
|
-
worker.port.start(); // Handle tab close. This isn't perfect, but there is no perfect method
|
|
205
|
-
// http://stackoverflow.com/q/13662089/786644 and this should work like
|
|
206
|
-
// 99% of the time. It is a memory leak if it fails, but for most use
|
|
207
|
-
// cases, it shouldn't be noticeable.
|
|
208
|
-
|
|
209
|
-
window.addEventListener("beforeunload", () => {
|
|
210
|
-
// Prevent firing if we don't know hostID yet
|
|
211
|
-
if (this._hostID !== undefined) {
|
|
212
|
-
this._postMessage([MSGTYPE_HOST_CLOSE, -1, this._hostID]);
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
this._worker = worker;
|
|
218
|
-
this._hostIDQueue = [];
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
registerError(cb) {
|
|
222
|
-
// console.log('registerError', cb);
|
|
223
|
-
this._errorCallback = cb; // Some browsers (Firefox) call onerror on every host, while others
|
|
224
|
-
// (Chrome) do nothing. Let's disable that everywhere, for consistency.
|
|
225
|
-
|
|
226
|
-
this._worker.addEventListener("error", e => {
|
|
227
|
-
e.preventDefault();
|
|
228
|
-
e.stopPropagation();
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
_postMessage(obj, _hostID, transfer) {
|
|
233
|
-
// console.log('_postMessage', obj, _hostID, transfer);
|
|
234
|
-
if (this._workerType === "Worker") {
|
|
235
|
-
// @ts-expect-error - it doesn't know if _worker is Worker or SharedWorker, but I do
|
|
236
|
-
this._worker.postMessage(obj, transfer);
|
|
237
|
-
} else if (this._workerType === "SharedWorker") {
|
|
238
|
-
// @ts-expect-error - it doesn't know if _worker is Worker or SharedWorker, but I do
|
|
239
|
-
this._worker.port.postMessage(obj, transfer);
|
|
240
|
-
} else {
|
|
241
|
-
throw new Error("WTF");
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
postMessage(userMessage, _hostID, transfer) {
|
|
246
|
-
// console.log('postMessage', userMessage, _hostID, transfer);
|
|
247
|
-
const actuallyPostMessage = (resolve, reject) => {
|
|
248
|
-
const messageID = messageIDs;
|
|
249
|
-
messageIDs += 1;
|
|
250
|
-
const messageToSend = [MSGTYPE_QUERY, messageID, userMessage, this._hostID];
|
|
251
|
-
|
|
252
|
-
this._callbacks.set(messageID, (error, result) => {
|
|
253
|
-
if (error) {
|
|
254
|
-
reject(error);
|
|
255
|
-
} else {
|
|
256
|
-
resolve(result);
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
this._postMessage(messageToSend, undefined, transfer);
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
return new Promise((resolve, reject) => {
|
|
264
|
-
// Don't send a message until hostID is known, otherwise it's a race
|
|
265
|
-
// condition and sometimes hostID will be undefined.
|
|
266
|
-
if (this._hostIDQueue !== undefined) {
|
|
267
|
-
this._hostIDQueue.push(() => {
|
|
268
|
-
actuallyPostMessage(resolve, reject);
|
|
269
|
-
});
|
|
270
|
-
} else {
|
|
271
|
-
actuallyPostMessage(resolve, reject);
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
_onMessage(e) {
|
|
277
|
-
const common = this._onMessageCommon(e);
|
|
278
|
-
|
|
279
|
-
if (!common) {
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const message = common.message,
|
|
284
|
-
type = common.type;
|
|
285
|
-
|
|
286
|
-
if (type === MSGTYPE_HOST_ID) {
|
|
287
|
-
if (message[2] !== undefined && typeof message[2] !== "number") {
|
|
288
|
-
throw new Error("Invalid hostID");
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const hostID = message[2];
|
|
292
|
-
this._hostID = hostID;
|
|
293
|
-
|
|
294
|
-
if (this._hostIDQueue !== undefined) {
|
|
295
|
-
this._hostIDQueue.forEach(func => {
|
|
296
|
-
// Not entirely sure why setTimeout is needed, might be just for unit tests
|
|
297
|
-
setTimeout(() => {
|
|
298
|
-
func();
|
|
299
|
-
}, 0);
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
this._hostIDQueue = undefined; // Never needed again after initial setup
|
|
303
|
-
}
|
|
304
|
-
} else if (type === MSGTYPE_WORKER_ERROR) {
|
|
305
|
-
if (message[2] !== undefined && message[2] !== null && typeof message[2] === "object") {
|
|
306
|
-
const error = fromFakeError(message[2]);
|
|
307
|
-
|
|
308
|
-
if (this._errorCallback !== undefined) {
|
|
309
|
-
this._errorCallback(error);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
class PWBWorker extends PWBBase {
|
|
318
|
-
constructor() {
|
|
319
|
-
super(); // Only actually used for SharedWorker
|
|
320
|
-
|
|
321
|
-
this._hosts = new Map();
|
|
322
|
-
this._maxHostID = -1;
|
|
323
|
-
|
|
324
|
-
if ( // @ts-expect-error
|
|
325
|
-
typeof SharedWorkerGlobalScope !== "undefined" && // @ts-expect-error
|
|
326
|
-
self instanceof SharedWorkerGlobalScope) {
|
|
327
|
-
this._workerType = "SharedWorker";
|
|
328
|
-
self.addEventListener("connect", e => {
|
|
329
|
-
// @ts-expect-error
|
|
330
|
-
const port = e.ports[0];
|
|
331
|
-
port.addEventListener("message", e2 => this._onMessage(e2)); // eslint-disable-line no-undef
|
|
332
|
-
|
|
333
|
-
port.start();
|
|
334
|
-
this._maxHostID += 1;
|
|
335
|
-
const hostID = this._maxHostID;
|
|
336
|
-
|
|
337
|
-
this._hosts.set(hostID, {
|
|
338
|
-
port
|
|
339
|
-
}); // Send back hostID to this host, otherwise it has no way to know it
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
this._postMessage([MSGTYPE_HOST_ID, -1, hostID], hostID);
|
|
343
|
-
});
|
|
344
|
-
self.addEventListener("error", e => {
|
|
345
|
-
logError(e.error); // Just send to first host, so as to not duplicate error tracking
|
|
346
|
-
|
|
347
|
-
const hostID = this._hosts.keys().next().value;
|
|
348
|
-
|
|
349
|
-
if (hostID !== undefined) {
|
|
350
|
-
this._postMessage([MSGTYPE_WORKER_ERROR, -1, toFakeError(e.error)], hostID);
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
} else {
|
|
354
|
-
this._workerType = "Worker";
|
|
355
|
-
self.addEventListener("message", this._onMessage); // Since this is not a Shared Worker, hostID is always 0 so it's not strictly required to
|
|
356
|
-
// send this back, but it makes the API a bit more consistent if there is the same
|
|
357
|
-
// initialization handshake in both cases.
|
|
358
|
-
|
|
359
|
-
this._postMessage([MSGTYPE_HOST_ID, -1, 0], 0);
|
|
360
|
-
|
|
361
|
-
self.addEventListener("error", e => {
|
|
362
|
-
logError(e.error);
|
|
363
|
-
|
|
364
|
-
this._postMessage([MSGTYPE_WORKER_ERROR, -1, toFakeError(e.error)]);
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
_postMessage(obj, targetHostID, transfer) {
|
|
370
|
-
// console.log('_postMessage', obj, targetHostID);
|
|
371
|
-
if (this._workerType === "SharedWorker") {
|
|
372
|
-
// If targetHostID has been deleted, this will do nothing, which is fine I think
|
|
373
|
-
this._hosts.forEach(({
|
|
374
|
-
port
|
|
375
|
-
}, hostID) => {
|
|
376
|
-
if (targetHostID === undefined || targetHostID === hostID) {
|
|
377
|
-
// @ts-expect-error TypeScript thinks transfer can't be undefined
|
|
378
|
-
port.postMessage(obj, transfer);
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
} else if (this._workerType === "Worker") {
|
|
382
|
-
// @ts-expect-error TypeScript thinks self is window, which has a different postMessage call signature. In a worker, this is correct.
|
|
383
|
-
self.postMessage(obj, transfer);
|
|
384
|
-
} else {
|
|
385
|
-
throw new Error("WTF");
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
postMessage(userMessage, targetHostID, transfer) {
|
|
390
|
-
// console.log('postMessage', userMessage, targetHostID);
|
|
391
|
-
const actuallyPostMessage = (resolve, reject) => {
|
|
392
|
-
const messageID = messageIDs;
|
|
393
|
-
messageIDs += 1;
|
|
394
|
-
const messageToSend = [MSGTYPE_QUERY, messageID, userMessage];
|
|
395
|
-
|
|
396
|
-
this._callbacks.set(messageID, (error, result) => {
|
|
397
|
-
if (error) {
|
|
398
|
-
reject(error);
|
|
399
|
-
} else {
|
|
400
|
-
resolve(result);
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
this._postMessage(messageToSend, targetHostID, transfer);
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
return new Promise((resolve, reject) => {
|
|
408
|
-
actuallyPostMessage(resolve, reject);
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
_onMessage(e) {
|
|
413
|
-
const common = this._onMessageCommon(e);
|
|
414
|
-
|
|
415
|
-
if (!common) {
|
|
416
|
-
return;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
const message = common.message,
|
|
420
|
-
type = common.type;
|
|
421
|
-
|
|
422
|
-
if (type === MSGTYPE_HOST_CLOSE) {
|
|
423
|
-
if (typeof message[2] !== "number") {
|
|
424
|
-
throw new Error("Invalid hostID");
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
const hostID = message[2];
|
|
428
|
-
|
|
429
|
-
this._hosts.delete(hostID);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
exports.PWBHost = PWBHost;
|
|
436
|
-
exports.PWBWorker = PWBWorker;
|