promise-worker-bi 6.0.1 → 6.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 CHANGED
@@ -85,7 +85,7 @@ The registered handler can return either a Promise or a normal value:
85
85
 
86
86
  ```js
87
87
  promiseWorker.register(async () => {
88
- "much async, very promise";
88
+ return "much async, very promise";
89
89
  });
90
90
  ```
91
91
 
@@ -126,6 +126,8 @@ promiseWorker.addEventListener("error", (errorError) => {
126
126
 
127
127
  That will work if `worker` is a Web Worker or a Shared Worker, but there is one important difference. For a Shared Worker, it will only fire in the first host, to prevent duplicate errors from reaching an error log (assuming you're logging these errors somewhere).
128
128
 
129
+ This also includes unhandled promise rejections inside the worker, which browsers otherwise only report in the worker's own console.
130
+
129
131
  #### Source maps
130
132
 
131
133
  If you use a source map for your worker script, this will not be reflected in the stack traces from promise-worker-bi (either in `promiseWorker.registerError` in response to `promiseWorker.postMessage`). However, you can still use your source map to translate the file/line/column numbers. Clever third-party error reporting services like [Bugsnag](https://www.bugsnag.com/) do this automatically!
@@ -287,7 +289,7 @@ Create a new instance of `PWBHost`, using the given worker.
287
289
 
288
290
  #### `promiseWorker.addEventListener("error", (event: ErrorEvent) => void)`
289
291
 
290
- When an error in your web/shared worker process occurs that is _not_ directly in response to a `promiseWorker.postMessage` call, you can see it by listening to the "error" event here.
292
+ When an error in your web/shared worker process occurs that is _not_ directly in response to a `promiseWorker.postMessage` call, you can see it by listening to the "error" event here. This includes both uncaught errors and unhandled promise rejections.
291
293
 
292
294
  `promiseWorker` is EventTarget so you can use `addEventListener`, `removeEventListener`, and all their normal options.
293
295
 
@@ -309,7 +311,9 @@ Create a new instance of `PWBWorker`.
309
311
 
310
312
  Register a message handler wherever you will be receiving messages: in the worker, in the browser, or both. Your handler consumes a message and returns a promise or value.
311
313
 
312
- The `hostID` parameter is only defined inside a shared worker, in which case it is a unique number identifying the host that the message came from.
314
+ If a message arrives and no handler has been registered, the sender's `postMessage` promise rejects with a "No handler registered" error.
315
+
316
+ The `hostID` parameter is only meaningful inside a shared worker, in which case it is a unique number identifying the host that the message came from.
313
317
 
314
318
  The return value of the callback function (shown above as `unknown`) must resolve to something [structured cloneable](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm).
315
319
 
package/dist/index.d.ts CHANGED
@@ -18,7 +18,7 @@ type QueryCallback = (a: unknown, b: number | undefined) => unknown;
18
18
  type EventMap = Record<string, Event>;
19
19
  declare abstract class PWBBase<Events extends EventMap> extends EventTarget {
20
20
  protected _callbacks: Map<number, (a: Error | null, b: unknown) => void>;
21
- protected _queryCallback: QueryCallback;
21
+ protected _queryCallback: QueryCallback | undefined;
22
22
  constructor();
23
23
  addEventListener<K extends keyof Events>(type: K, listener: ((event: Events[K]) => void) | {
24
24
  handleEvent(object: Events[K]): void;
@@ -45,19 +45,20 @@ export declare class PWBHost extends PWBBase<HostEvents> {
45
45
  private _worker;
46
46
  constructor(worker: SharedWorker | Worker);
47
47
  protected _postMessage(obj: QueryMessage | ResponseMessage | HostLockMessage, _hostID?: unknown, transfer?: Transferable[] | undefined): void;
48
- postMessage(userMessage: unknown, _hostID?: undefined, transfer?: Transferable[] | undefined): Promise<any>;
48
+ postMessage(userMessage: unknown, _hostID?: undefined, transfer?: Transferable[] | undefined): Promise<unknown>;
49
49
  private handleWorkerLock;
50
50
  private _onMessage;
51
51
  }
52
52
  //#endregion
53
53
  //#region src/PWBWorker.d.ts
54
- type WorkerEvents = Record<string, Event>;
54
+ type WorkerEvents = Record<never, never>;
55
55
  export declare class PWBWorker extends PWBBase<WorkerEvents> {
56
56
  private _hosts;
57
57
  private _maxHostID;
58
58
  private _sharedWorker;
59
59
  private _workerLockAcquired;
60
60
  constructor();
61
+ private _postWorkerError;
61
62
  protected _postMessage(message: QueryMessage | ResponseMessage | HostIdMessage | WorkerLockMessage | WorkerErrorMessage, targetHostID?: number | undefined, transfer?: Transferable[] | undefined): void;
62
63
  postMessage(userMessage: unknown, targetHostID?: number | undefined, transfer?: Transferable[] | undefined): Promise<unknown>;
63
64
  private _onMessage;
package/dist/index.js CHANGED
@@ -1,5 +1,8 @@
1
+ const isDOMException = (value) => {
2
+ return typeof DOMException !== "undefined" && value instanceof DOMException;
3
+ };
1
4
  const isError = (error) => {
2
- if (Error.isError) return Error.isError(error);
5
+ if (Error.isError) return Error.isError(error) || isDOMException(error);
3
6
  return true;
4
7
  };
5
8
  const parseMessage = (message) => {
@@ -42,6 +45,17 @@ const logError = (err) => {
42
45
  console.error("Error in worker:");
43
46
  console.error(err);
44
47
  };
48
+ const toError = (value) => {
49
+ if (Error.isError ? Error.isError(value) || isDOMException(value) : value instanceof Error) return value;
50
+ let message;
51
+ if (typeof value === "string") message = value;
52
+ else try {
53
+ message = JSON.stringify(value) ?? String(value);
54
+ } catch {
55
+ message = String(value);
56
+ }
57
+ return new Error(message);
58
+ };
45
59
  const isSharedWorker = (worker) => {
46
60
  return worker.port !== void 0;
47
61
  };
@@ -51,7 +65,6 @@ var PWBBase = class extends EventTarget {
51
65
  constructor() {
52
66
  super();
53
67
  this._callbacks = /* @__PURE__ */ new Map();
54
- this._queryCallback = () => {};
55
68
  this._onMessage = this._onMessage.bind(this);
56
69
  }
57
70
  addEventListener(type, listener, options) {
@@ -91,16 +104,20 @@ var PWBBase = class extends EventTarget {
91
104
  const messageID = message[1];
92
105
  const query = message[2];
93
106
  const hostID = message[3];
107
+ if (this._queryCallback === void 0) {
108
+ this._postResponse(messageID, /* @__PURE__ */ new Error("No handler registered to receive this message"), void 0, hostID);
109
+ return;
110
+ }
94
111
  try {
95
112
  const result = this._queryCallback(query, hostID);
96
113
  if (!isPromise(result)) this._postResponse(messageID, null, result, hostID);
97
114
  else result.then((finalResult) => {
98
115
  this._postResponse(messageID, null, finalResult, hostID);
99
116
  }, (finalError) => {
100
- this._postResponse(messageID, finalError, void 0, hostID);
117
+ this._postResponse(messageID, toError(finalError), void 0, hostID);
101
118
  });
102
119
  } catch (err) {
103
- this._postResponse(messageID, err);
120
+ this._postResponse(messageID, toError(err), void 0, hostID);
104
121
  }
105
122
  }
106
123
  _onMessageCommon(e) {
@@ -221,8 +238,7 @@ var PWBWorker = class extends PWBBase {
221
238
  });
222
239
  if (typeof SharedWorkerGlobalScope !== "undefined" && self instanceof SharedWorkerGlobalScope) {
223
240
  this._sharedWorker = true;
224
- const _self = self;
225
- _self.addEventListener("connect", (e) => {
241
+ self.addEventListener("connect", (e) => {
226
242
  const port = e.ports[0];
227
243
  port.addEventListener("message", (e2) => this._onMessage(e2));
228
244
  port.start();
@@ -238,23 +254,24 @@ var PWBWorker = class extends PWBBase {
238
254
  else message = [2, hostID];
239
255
  this._postMessage(message, hostID);
240
256
  });
241
- _self.addEventListener("error", (e) => {
242
- logError(e.error);
243
- e.preventDefault();
244
- const hostID = this._hosts.keys().next().value;
245
- if (hostID !== void 0) this._postMessage([5, e.error], hostID);
246
- });
247
257
  } else {
248
258
  this._sharedWorker = false;
249
- const _self = self;
250
- _self.addEventListener("message", this._onMessage);
259
+ self.addEventListener("message", this._onMessage);
251
260
  this._postMessage([2, 0], 0);
252
- _self.addEventListener("error", (e) => {
253
- logError(e.error);
254
- e.preventDefault();
255
- this._postMessage([5, e.error]);
256
- });
257
261
  }
262
+ self.addEventListener("error", (e) => {
263
+ logError(e.error);
264
+ e.preventDefault();
265
+ this._postWorkerError(e.error ?? e.message);
266
+ });
267
+ self.addEventListener("unhandledrejection", (e) => {
268
+ this._postWorkerError(e.reason);
269
+ });
270
+ }
271
+ _postWorkerError(value) {
272
+ const hostID = this._sharedWorker ? this._hosts.keys().next().value : void 0;
273
+ if (this._sharedWorker && hostID === void 0) return;
274
+ this._postMessage([5, toError(value)], hostID);
258
275
  }
259
276
  _postMessage(message, targetHostID, transfer) {
260
277
  if (this._sharedWorker) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promise-worker-bi",
3
- "version": "6.0.1",
3
+ "version": "6.0.3",
4
4
  "description": "Promise-based messaging for Web Workers and Shared Workers",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",