webext-messenger 0.23.1 → 0.25.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.
@@ -2,4 +2,4 @@ export * from "./receiver.js";
2
2
  export * from "./sender.js";
3
3
  export * from "./types.js";
4
4
  export { getThisFrame, getTopLevelFrame } from "./thisTarget.js";
5
- export { toggleLogging } from "./shared.js";
5
+ export { toggleLogging } from "./logging.js";
@@ -3,6 +3,8 @@ export * from "./receiver.js";
3
3
  export * from "./sender.js";
4
4
  export * from "./types.js";
5
5
  export { getThisFrame, getTopLevelFrame } from "./thisTarget.js";
6
- export { toggleLogging } from "./shared.js";
6
+ export { toggleLogging } from "./logging.js";
7
7
  import { initPrivateApi } from "./thisTarget.js";
8
+ // Required side effect to better track errors:
9
+ // https://github.com/pixiebrix/webext-messenger/pull/80
8
10
  initPrivateApi();
@@ -0,0 +1,5 @@
1
+ export declare const log: {
2
+ debug: (...args: unknown[]) => void;
3
+ warn: (...args: unknown[]) => void;
4
+ };
5
+ export declare function toggleLogging(enabled: boolean): void;
@@ -0,0 +1,13 @@
1
+ /* Warning: Do not use import browser-polyfill directly or indirectly */
2
+ // .bind preserves the call location in the console
3
+ const debug = console.debug.bind(console, "Messenger:");
4
+ const warn = console.warn.bind(console, "Messenger:");
5
+ const noop = () => {
6
+ /* */
7
+ };
8
+ // Default to "no logs"
9
+ export const log = { debug: noop, warn: noop };
10
+ export function toggleLogging(enabled) {
11
+ log.debug = enabled ? debug : noop;
12
+ log.warn = enabled ? warn : noop;
13
+ }
@@ -1,7 +1,8 @@
1
1
  import { serializeError } from "serialize-error";
2
2
  import { getContextName } from "webext-detect-page";
3
3
  import { messenger } from "./sender.js";
4
- import { isObject, MessengerError, log, __webextMessenger } from "./shared.js";
4
+ import { isObject, MessengerError, __webextMessenger } from "./shared.js";
5
+ import { log } from "./logging.js";
5
6
  import { getActionForMessage } from "./thisTarget.js";
6
7
  import { didUserRegisterMethods, handlers } from "./handlers.js";
7
8
  export function isMessengerMessage(message) {
@@ -1,7 +1,8 @@
1
1
  import pRetry from "p-retry";
2
2
  import { isBackground } from "webext-detect-page";
3
3
  import { deserializeError } from "serialize-error";
4
- import { isObject, MessengerError, __webextMessenger, log } from "./shared.js";
4
+ import { isObject, MessengerError, __webextMessenger } from "./shared.js";
5
+ import { log } from "./logging.js";
5
6
  import { handlers } from "./handlers.js";
6
7
  const _errorNonExistingTarget = "Could not establish connection. Receiving end does not exist.";
7
8
  // https://github.com/mozilla/webextension-polyfill/issues/384
@@ -10,11 +10,6 @@ export declare function isObject(value: unknown): value is Record<string, unknow
10
10
  export declare class MessengerError extends Error {
11
11
  name: string;
12
12
  }
13
- export declare const log: {
14
- debug: (...args: any[]) => void;
15
- warn: (...args: any[]) => void;
16
- };
17
- export declare function toggleLogging(enabled: boolean): void;
18
13
  export declare function isErrorObject(error: unknown): error is ErrorObject;
19
14
  export declare function delay(milliseconds: number): Promise<void>;
20
15
  export declare function once<Callback extends (...arguments_: unknown[]) => unknown>(function_: Callback): Callback;
@@ -3,32 +3,11 @@ export const __webextMessenger = true;
3
3
  export function isObject(value) {
4
4
  return typeof value === "object" && value !== null;
5
5
  }
6
- function noop() {
7
- /* */
8
- }
9
6
  export class MessengerError extends Error {
10
- constructor() {
11
- super(...arguments);
12
- Object.defineProperty(this, "name", {
13
- enumerable: true,
14
- configurable: true,
15
- writable: true,
16
- value: "MessengerError"
17
- });
18
- }
7
+ name = "MessengerError";
19
8
  }
20
9
  // @ts-expect-error Wrong `errorConstructors` types
21
10
  errorConstructors.set("MessengerError", MessengerError);
22
- // .bind preserves the call location in the console
23
- const debug = console.debug.bind(console, "Messenger:");
24
- const warn = console.warn.bind(console, "Messenger:");
25
- export const log = { debug, warn };
26
- export function toggleLogging(enabled) {
27
- log.debug = enabled ? debug : noop;
28
- log.warn = enabled ? warn : noop;
29
- }
30
- // Default to "no logs"
31
- toggleLogging(false);
32
11
  export function isErrorObject(error) {
33
12
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a type guard function and it uses ?.
34
13
  return typeof error?.message === "string";
@@ -1,7 +1,8 @@
1
1
  import { isBackground, isContentScript, isExtensionContext, } from "webext-detect-page";
2
2
  import { messenger } from "./sender.js";
3
3
  import { registerMethods } from "./receiver.js";
4
- import { log, MessengerError, once } from "./shared.js";
4
+ import { MessengerError, once } from "./shared.js";
5
+ import { log } from "./logging.js";
5
6
  /**
6
7
  * @file This file exists because `runtime.sendMessage` acts as a broadcast to
7
8
  * all open extension pages, so the receiver needs a way to figure out if the
@@ -105,16 +106,14 @@ const storeTabData = once(async () => {
105
106
  }
106
107
  catch (error) {
107
108
  tabDataStatus = "error";
108
- throw new MessengerError("Tab registration failed. This page won’t be able to receive messages that require tab information",
109
- // @ts-expect-error TODO: update lib to accept Error#cause
110
- { cause: error });
109
+ throw new MessengerError("Tab registration failed. This page won’t be able to receive messages that require tab information", { cause: error });
111
110
  }
112
111
  });
113
112
  export function __getTabData() {
114
113
  return { tabId: this.trace[0]?.tab?.id, frameId: this.trace[0]?.frameId };
115
114
  }
116
115
  export async function getThisFrame() {
117
- await storeTabData(); // It should already have been called by we still need to await it
116
+ await storeTabData(); // It should already have been called but we still need to await it
118
117
  const { tabId, frameId } = thisTarget;
119
118
  if (typeof tabId !== "number" || typeof frameId !== "number") {
120
119
  throw new TypeError("This target is not in a frame");
@@ -130,6 +129,16 @@ export async function getTopLevelFrame() {
130
129
  };
131
130
  }
132
131
  export function initPrivateApi() {
132
+ // Improve DX by informing the developer that it's being loaded the wrong way
133
+ // https://github.com/pixiebrix/webext-messenger/issues/88
134
+ if (globalThis.__webextMessenger) {
135
+ // TODO: Use Error#cause after https://bugs.chromium.org/p/chromium/issues/detail?id=1211260
136
+ console.log(globalThis.__webextMessenger.replace(/^Error/, "webext-messenger"));
137
+ console.error("webext-messenger: Duplicate execution. This is a fatal error.\nhttps://github.com/pixiebrix/webext-messenger/issues/88");
138
+ return;
139
+ }
140
+ // Use Error to capture the stack and make it easier to find the cause
141
+ globalThis.__webextMessenger = new Error("First execution").stack;
133
142
  if (isExtensionContext()) {
134
143
  // Only `runtime` pages can handle this message but I can't remove it because its listener
135
144
  // also serves the purpose of throwing a specific error when no methods have been registered.
package/package.json CHANGED
@@ -1,13 +1,19 @@
1
1
  {
2
2
  "name": "webext-messenger",
3
- "version": "0.23.1",
3
+ "version": "0.25.0-0",
4
4
  "description": "Browser Extension component messaging framework",
5
5
  "keywords": [],
6
6
  "repository": "pixiebrix/webext-messenger",
7
7
  "license": "MIT",
8
8
  "author": "Federico Brigante for PixieBrix <federico@pixiebrix.com> (https://www.pixiebrix.com)",
9
9
  "type": "module",
10
- "main": "distribution/index.js",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./distribution/index.js",
13
+ "default": "./distribution/index.js"
14
+ },
15
+ "./*": "./distribution/*"
16
+ },
11
17
  "scripts": {
12
18
  "build": "tsc",
13
19
  "demo:watch": "parcel watch --no-cache --no-hmr",
@@ -21,25 +27,25 @@
21
27
  "dependencies": {
22
28
  "p-retry": "^6.0.0",
23
29
  "serialize-error": "^11.0.2",
24
- "type-fest": "^4.3.1",
30
+ "type-fest": "^4.6.0",
25
31
  "webext-detect-page": "^4.1.1"
26
32
  },
27
33
  "devDependencies": {
28
34
  "@parcel/config-webextension": "^2.6.2",
29
- "@sindresorhus/tsconfig": "^4.0.0",
30
- "@types/chrome": "^0.0.245",
31
- "@types/tape": "^5.6.1",
32
- "@types/webextension-polyfill": "^0.10.2",
35
+ "@sindresorhus/tsconfig": "^5.0.0",
36
+ "@types/chrome": "^0.0.248",
37
+ "@types/tape": "^5.6.3",
38
+ "@types/webextension-polyfill": "^0.10.5",
33
39
  "buffer": "^6.0.3",
34
- "eslint": "^8.50.0",
35
- "eslint-config-pixiebrix": "^0.27.2",
40
+ "eslint": "^8.52.0",
41
+ "eslint-config-pixiebrix": "^0.29.1",
36
42
  "events": "^3.3.0",
37
43
  "npm-run-all": "^4.1.5",
38
44
  "parcel": "^2.6.2",
39
45
  "path-browserify": "^1.0.1",
40
46
  "process": "^0.11.10",
41
47
  "stream-browserify": "^3.0.0",
42
- "tape": "^5.7.0",
48
+ "tape": "^5.7.2",
43
49
  "typescript": "^5.2.2",
44
50
  "webext-content-scripts": "^2.5.5",
45
51
  "webextension-polyfill": "^0.10.0"