promise-worker-bi 3.0.2 → 4.0.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.
- package/README.md +104 -95
- package/dist/commonjs.js +434 -0
- package/dist/esmodules.js +429 -0
- package/dist/index.d.ts +38 -0
- package/dist/test/test.js +3774 -0
- package/dist/test/worker-bidirectional-echo.js +3169 -0
- package/dist/test/worker-echo-custom-2.js +308 -0
- package/dist/test/worker-echo-custom.js +308 -0
- package/dist/test/worker-echo.js +301 -0
- package/dist/test/worker-empty.js +300 -0
- package/dist/test/worker-error-async.js +303 -0
- package/dist/test/worker-error-sync.js +301 -0
- package/dist/test/worker-host-echo-custom.js +3183 -0
- package/dist/test/worker-host-echo-multiple.js +3182 -0
- package/dist/test/worker-host-echo.js +3164 -0
- package/dist/test/worker-host-empty.js +3172 -0
- package/dist/test/worker-host-error-async.js +3169 -0
- package/dist/test/worker-host-error-outside-response.js +303 -0
- package/dist/test/worker-host-error-sync.js +3169 -0
- package/dist/test/worker-host-ping.js +3164 -0
- package/dist/test/worker-hostid.js +302 -0
- package/dist/test/worker-pong-promise.js +301 -0
- package/dist/test/worker-pong.js +301 -0
- package/dist/test/worker-shared.js +309 -0
- package/package.json +41 -37
- package/CHANGELOG.md +0 -49
- package/dist/index.js +0 -375
package/README.md
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
promise-worker-bi [](https://travis-ci.org/dumbmatter/promise-worker-bi)
|
|
2
|
-
====
|
|
1
|
+
# promise-worker-bi [](https://travis-ci.org/dumbmatter/promise-worker-bi)
|
|
3
2
|
|
|
4
3
|
A small (~2 kB min+gz) and performant library for communicating with web workers and shared workers, using promises. Post a message from the browser to the worker, get a promise that resolves to the response. Post a message from the worker to the browser, get a promise that resolves to the response. And with shared workers, you can either broadcast to all browser tabs or send a message to a specific tab.
|
|
5
4
|
|
|
6
5
|
This is based on [promise-worker](https://github.com/nolanlawson/promise-worker) which only allows you to send messages from the browser to the worker, not in reverse. This library allows both, using the exact same API, and has additional support for shared workers.
|
|
7
6
|
|
|
8
|
-
Usage
|
|
9
|
-
---
|
|
7
|
+
## Usage
|
|
10
8
|
|
|
11
9
|
Install:
|
|
12
10
|
|
|
@@ -16,41 +14,47 @@ Inside your main bundle:
|
|
|
16
14
|
|
|
17
15
|
```js
|
|
18
16
|
// main.js
|
|
19
|
-
|
|
17
|
+
import { PWBHost } from "promise-worker-bi";
|
|
20
18
|
|
|
21
|
-
var worker = new Worker(
|
|
22
|
-
var promiseWorker = new
|
|
19
|
+
var worker = new Worker("worker.js");
|
|
20
|
+
var promiseWorker = new PWBHost(worker);
|
|
23
21
|
|
|
24
22
|
// Only needed if you send messages from the worker to the host
|
|
25
|
-
promiseWorker.register(function
|
|
26
|
-
return
|
|
23
|
+
promiseWorker.register(function(message) {
|
|
24
|
+
return "pong2";
|
|
27
25
|
});
|
|
28
26
|
|
|
29
|
-
promiseWorker
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
})
|
|
27
|
+
promiseWorker
|
|
28
|
+
.postMessage("ping")
|
|
29
|
+
.then(function(response) {
|
|
30
|
+
// handle response 'pong'
|
|
31
|
+
})
|
|
32
|
+
.catch(function(error) {
|
|
33
|
+
// handle error
|
|
34
|
+
});
|
|
34
35
|
```
|
|
35
36
|
|
|
36
37
|
Inside your `worker.js` bundle:
|
|
37
38
|
|
|
38
39
|
```js
|
|
39
40
|
// worker.js
|
|
40
|
-
|
|
41
|
+
import { PWBWorker } from "promise-worker-bi";
|
|
41
42
|
|
|
42
|
-
var promiseWorker = new
|
|
43
|
+
var promiseWorker = new PWBWorker();
|
|
43
44
|
|
|
44
45
|
// Only needed if you send messages from the host to the worker
|
|
45
|
-
promiseWorker.register(function
|
|
46
|
-
return
|
|
46
|
+
promiseWorker.register(function(message) {
|
|
47
|
+
return "pong";
|
|
47
48
|
});
|
|
48
49
|
|
|
49
|
-
promiseWorker
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
})
|
|
50
|
+
promiseWorker
|
|
51
|
+
.postMessage("ping2")
|
|
52
|
+
.then(function(response) {
|
|
53
|
+
// handle response 'pong2'
|
|
54
|
+
})
|
|
55
|
+
.catch(function(error) {
|
|
56
|
+
// handle error
|
|
57
|
+
});
|
|
54
58
|
```
|
|
55
59
|
|
|
56
60
|
**Notice that except for initialization of the `promiseWorker` object, the API is identical in the browser and in the worker. Either one can initiate a message.** In all of the subsequent examples, `promiseWorker` initialization is omitted, so you can put the two blocks of code respectively in the worker and browser, or in the browser and worker.
|
|
@@ -58,7 +62,7 @@ promiseWorker.postMessage('ping2').then(function (response) {
|
|
|
58
62
|
And it's even better with async/await:
|
|
59
63
|
|
|
60
64
|
```js
|
|
61
|
-
const response = await promiseWorker.postMessage(
|
|
65
|
+
const response = await promiseWorker.postMessage("ping2");
|
|
62
66
|
// response contains 'pong2'
|
|
63
67
|
```
|
|
64
68
|
|
|
@@ -67,15 +71,17 @@ const response = await promiseWorker.postMessage('ping2');
|
|
|
67
71
|
The message you send can be any object, array, string, number, etc. - anything that is serializable by the structured clone algorithm:
|
|
68
72
|
|
|
69
73
|
```js
|
|
70
|
-
promiseWorker
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
promiseWorker
|
|
75
|
+
.postMessage({
|
|
76
|
+
hello: "world",
|
|
77
|
+
answer: 42,
|
|
78
|
+
"this is fun": true
|
|
79
|
+
})
|
|
80
|
+
.then(/* ... */);
|
|
75
81
|
```
|
|
76
82
|
|
|
77
83
|
```js
|
|
78
|
-
promiseWorker.register(function
|
|
84
|
+
promiseWorker.register(function(message) {
|
|
79
85
|
console.log(message); // { hello: 'world', answer: 42, 'this is fun': true }
|
|
80
86
|
});
|
|
81
87
|
```
|
|
@@ -85,9 +91,9 @@ promiseWorker.register(function (message) {
|
|
|
85
91
|
The registered handler can return either a Promise or a normal value:
|
|
86
92
|
|
|
87
93
|
```js
|
|
88
|
-
promiseWorker.register(function
|
|
89
|
-
return Promise.resolve().then(function
|
|
90
|
-
return
|
|
94
|
+
promiseWorker.register(function() {
|
|
95
|
+
return Promise.resolve().then(function() {
|
|
96
|
+
return "much async, very promise";
|
|
91
97
|
});
|
|
92
98
|
});
|
|
93
99
|
```
|
|
@@ -103,24 +109,24 @@ promiseWorker.postMessage(null).then(function (message) {
|
|
|
103
109
|
Any thrown errors or asynchronous rejections during a response will be propagated as a rejected promise. For instance:
|
|
104
110
|
|
|
105
111
|
```js
|
|
106
|
-
promiseWorker.register(function
|
|
107
|
-
throw new Error(
|
|
112
|
+
promiseWorker.register(function(message) {
|
|
113
|
+
throw new Error("naughty!");
|
|
108
114
|
});
|
|
109
115
|
```
|
|
110
116
|
|
|
111
117
|
```js
|
|
112
|
-
promiseWorker.postMessage(
|
|
118
|
+
promiseWorker.postMessage("whoops").catch(function(err) {
|
|
113
119
|
console.log(err.message); // 'naughty!'
|
|
114
120
|
});
|
|
115
121
|
```
|
|
116
122
|
|
|
117
|
-
But what about errors in the worker that are
|
|
123
|
+
But what about errors in the worker that are _not_ during a response? (Errors in the host, you can handle as you would normally do.)
|
|
118
124
|
|
|
119
125
|
For a Web Worker, we could just use [the normal `error` event](https://developer.mozilla.org/en-US/docs/Web/API/AbstractWorker/onerror) and be fine. But for a Shared Worker, that is not the case, because browsers seem to handle errors inside Shared Workers differently (currently Firefox seems to send the normal `error` event to all hosts, but [Chrome does not](https://bugs.chromium.org/p/chromium/issues/detail?id=105001)). Therefore, promise-worker-bi includes a unified API that works in Web Workers and Shared Workers.
|
|
120
126
|
|
|
121
127
|
```js
|
|
122
|
-
promiseWorker.registerError(function
|
|
123
|
-
console.log(
|
|
128
|
+
promiseWorker.registerError(function(err) {
|
|
129
|
+
console.log("Error inside worker!", err);
|
|
124
130
|
});
|
|
125
131
|
```
|
|
126
132
|
|
|
@@ -135,21 +141,25 @@ If you use a source map for your worker script, this will not be reflected in th
|
|
|
135
141
|
If you need to send messages of multiple types to the worker, just add some type information to the message you send:
|
|
136
142
|
|
|
137
143
|
```js
|
|
138
|
-
promiseWorker
|
|
139
|
-
|
|
140
|
-
|
|
144
|
+
promiseWorker
|
|
145
|
+
.postMessage({
|
|
146
|
+
type: "en"
|
|
147
|
+
})
|
|
148
|
+
.then(/* ... */);
|
|
141
149
|
|
|
142
|
-
promiseWorker
|
|
143
|
-
|
|
144
|
-
|
|
150
|
+
promiseWorker
|
|
151
|
+
.postMessage({
|
|
152
|
+
type: "fr"
|
|
153
|
+
})
|
|
154
|
+
.then(/* ... */);
|
|
145
155
|
```
|
|
146
156
|
|
|
147
157
|
```js
|
|
148
|
-
promiseWorker.register(function
|
|
149
|
-
if (message.type ===
|
|
150
|
-
return
|
|
151
|
-
} else if (message.type ===
|
|
152
|
-
return
|
|
158
|
+
promiseWorker.register(function(message) {
|
|
159
|
+
if (message.type === "en") {
|
|
160
|
+
return "Hello!";
|
|
161
|
+
} else if (message.type === "fr") {
|
|
162
|
+
return "Bonjour!";
|
|
153
163
|
}
|
|
154
164
|
});
|
|
155
165
|
```
|
|
@@ -162,60 +172,59 @@ Here's an example:
|
|
|
162
172
|
|
|
163
173
|
```js
|
|
164
174
|
// main.js
|
|
165
|
-
|
|
175
|
+
import { PWBHost } from "promise-worker-bi";
|
|
166
176
|
|
|
167
|
-
var worker = new SharedWorker(
|
|
168
|
-
var promiseWorker = new
|
|
177
|
+
var worker = new SharedWorker("worker.js");
|
|
178
|
+
var promiseWorker = new PWBHost(worker);
|
|
169
179
|
|
|
170
|
-
promiseWorker.register(function
|
|
180
|
+
promiseWorker.register(function(message) {
|
|
171
181
|
console.log(message);
|
|
172
182
|
});
|
|
173
183
|
|
|
174
184
|
// setTimeout is just to give you enough time to open main.js and main2.js in
|
|
175
185
|
// two separate tabs.
|
|
176
|
-
setTimeout(function
|
|
177
|
-
promiseWorker.postMessage(
|
|
178
|
-
console.log(
|
|
179
|
-
})
|
|
186
|
+
setTimeout(function() {
|
|
187
|
+
promiseWorker.postMessage("broadcast").then(function(response) {
|
|
188
|
+
console.log("Echoed response:", response);
|
|
189
|
+
});
|
|
180
190
|
}, 1000);
|
|
181
191
|
```
|
|
182
192
|
|
|
183
193
|
```js
|
|
184
194
|
// main2.js
|
|
185
|
-
|
|
195
|
+
import { PWBHost } from "promise-worker-bi";
|
|
186
196
|
|
|
187
|
-
var worker = new SharedWorker(
|
|
188
|
-
var promiseWorker = new
|
|
197
|
+
var worker = new SharedWorker("worker.js");
|
|
198
|
+
var promiseWorker = new PWBHost(worker);
|
|
189
199
|
|
|
190
|
-
promiseWorker.register(function
|
|
200
|
+
promiseWorker.register(function(message) {
|
|
191
201
|
console.log(message);
|
|
192
202
|
});
|
|
193
203
|
|
|
194
204
|
// setTimeout is just to give you enough time to open main.js and main2.js in
|
|
195
205
|
// two separate tabs.
|
|
196
|
-
setTimeout(function
|
|
197
|
-
promiseWorker.postMessage(
|
|
198
|
-
console.log(
|
|
199
|
-
})
|
|
206
|
+
setTimeout(function() {
|
|
207
|
+
promiseWorker.postMessage("just this tab").then(function(response) {
|
|
208
|
+
console.log("Echoed response:", response);
|
|
209
|
+
});
|
|
200
210
|
}, 2000);
|
|
201
211
|
```
|
|
202
212
|
|
|
203
213
|
```js
|
|
204
214
|
// worker.js
|
|
205
|
-
|
|
215
|
+
import { PWBWorker } from "promise-worker-bi";
|
|
206
216
|
|
|
207
|
-
var promiseWorker = new
|
|
217
|
+
var promiseWorker = new PWBWorker();
|
|
208
218
|
|
|
209
|
-
promiseWorker.register(function
|
|
210
|
-
if (message ===
|
|
211
|
-
promiseWorker.postMessage(
|
|
219
|
+
promiseWorker.register(function(message, hostID) {
|
|
220
|
+
if (message === "broadcast") {
|
|
221
|
+
promiseWorker.postMessage("to all tabs");
|
|
212
222
|
} else {
|
|
213
|
-
promiseWorker.postMessage(
|
|
223
|
+
promiseWorker.postMessage("hello host " + hostID, hostID);
|
|
214
224
|
}
|
|
215
225
|
|
|
216
226
|
return message;
|
|
217
227
|
});
|
|
218
|
-
|
|
219
228
|
```
|
|
220
229
|
|
|
221
230
|
Then open main.js and main2.js in two browser tabs. The message sent from main.js ('broadcast') will result in worker.js sending a message to both tabs, but the message sent in main2.js will result in a message sent only to that one tab. So if you look in the consoles in your two tabs, you will see this in the first tab:
|
|
@@ -231,37 +240,43 @@ And this in the second tab:
|
|
|
231
240
|
|
|
232
241
|
(If you open main2.js first, "hello host 1" will instead be "hello host 0".)
|
|
233
242
|
|
|
234
|
-
Browser support
|
|
235
|
-
----
|
|
243
|
+
## Browser support
|
|
236
244
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
245
|
+
- Chrome
|
|
246
|
+
- Firefox
|
|
247
|
+
- Safari 8+
|
|
248
|
+
- IE 10+
|
|
249
|
+
- Edge
|
|
250
|
+
- iOS 8+
|
|
251
|
+
- Android 4.4+
|
|
244
252
|
|
|
245
253
|
Old browsers will need Map and Promise polyfills.
|
|
246
254
|
|
|
247
255
|
There used to be automated tests in various browsers via [zuul](https://github.com/defunctzombie/zuul) and Sauce Labs, but it suffered bit rot and I could no longer get it to work consistently (PRs welcome!). Currently, `yarn test` uses [Karma](https://karma-runner.github.io/) to run tests in whatever versions of Chrome and Firefox you have installed.
|
|
248
256
|
|
|
249
|
-
API
|
|
250
|
-
---
|
|
257
|
+
## API
|
|
251
258
|
|
|
252
259
|
### Main bundle
|
|
253
260
|
|
|
254
|
-
#### `new
|
|
261
|
+
#### `new PWBHost(worker: Worker | SharedWorker)`
|
|
262
|
+
|
|
263
|
+
Create a new instance of `PWBHost`, using the given worker.
|
|
264
|
+
|
|
265
|
+
- `worker` - the `Worker`, `SharedWorker` or [PseudoWorker](https://github.com/nolanlawson/pseudo-worker) to use.
|
|
266
|
+
|
|
267
|
+
#### `promiseWorker.registerError((error: Error) => void)`
|
|
268
|
+
|
|
269
|
+
This should only be called in the browser, not in a worker.
|
|
255
270
|
|
|
256
|
-
|
|
271
|
+
When an error in your web/shared worker process occurs that is _not_ directly in response to a `promiseWorker.postMessage` call, it will be sent to the callback you provide here to `promiseWorker.registerError`.
|
|
257
272
|
|
|
258
|
-
|
|
273
|
+
Although [normally stack traces are not sent from the worker to the main thread](https://github.com/mknichel/javascript-errors/blob/master/README.md#dedicated-workers), promise-worker-bi magically works around this problem so you will see a stack trace in `error`.
|
|
259
274
|
|
|
260
275
|
### Worker bundle
|
|
261
276
|
|
|
262
|
-
#### `new
|
|
277
|
+
#### `new PWBWorker()`
|
|
263
278
|
|
|
264
|
-
Create a new instance of `
|
|
279
|
+
Create a new instance of `PWBWorker`.
|
|
265
280
|
|
|
266
281
|
### Both bundles
|
|
267
282
|
|
|
@@ -276,9 +291,3 @@ The `hostID` parameter is only defined inside a shared worker, in which case it
|
|
|
276
291
|
Send a message to the browser or worker and return a Promise.
|
|
277
292
|
|
|
278
293
|
The `hostID` parameter is only meaningful when sending a message from a shared worker. If you leave it out, it will send the message to all hosts. If you include it, it will send the message only to that specific host. You can get the `hostID` from the `promiseWorker.register` function described above.
|
|
279
|
-
|
|
280
|
-
#### `promiseWorker.registerError((error: Error) => void)`
|
|
281
|
-
|
|
282
|
-
When an error in your web/shared worker process occurs that is *not* directly in response to a `promiseWorker.postMessage` call, it will be sent to the callback you provide here to `promiseWorker.registerError`.
|
|
283
|
-
|
|
284
|
-
Although [normally stack traces are not sent from the worker to the main thread](https://github.com/mknichel/javascript-errors/blob/master/README.md#dedicated-workers), promise-worker-bi magically works around this problem so you will see a stack trace in `error`.
|