webext-messenger 0.23.1 → 0.25.0-0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"