webext-messenger 0.14.0 → 0.14.1

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.
@@ -0,0 +1,10 @@
1
+ import { Target, MessengerMeta } from "./types";
2
+ declare function __getTabData(this: MessengerMeta): Target;
3
+ declare global {
4
+ interface MessengerMethods {
5
+ __getTabData: typeof __getTabData;
6
+ }
7
+ }
8
+ export declare const getTabData: () => Promise<Target>;
9
+ export declare function initPrivateApi(): void;
10
+ export {};
@@ -0,0 +1,13 @@
1
+ import { getMethod } from "./sender";
2
+ import { registerMethods } from "./receiver";
3
+ import { isBackgroundPage } from "webext-detect-page";
4
+ function __getTabData() {
5
+ return { tabId: this.trace[0].tab.id, frameId: this.trace[0].frameId };
6
+ }
7
+ // First page to respond wins. Any context has this piece of information.
8
+ export const getTabData = getMethod("__getTabData", { page: "any" });
9
+ export function initPrivateApi() {
10
+ if (isBackgroundPage()) {
11
+ registerMethods({ __getTabData });
12
+ }
13
+ }
@@ -1,3 +1,3 @@
1
- export { registerMethods } from "./receiver.js";
2
- export { messenger, getMethod, getNotifier, backgroundTarget, } from "./sender.js";
3
- export { MessengerMeta, Target } from "./types.js";
1
+ export * from "./receiver.js";
2
+ export * from "./sender.js";
3
+ export * from "./types.js";
@@ -1,2 +1,8 @@
1
- export { registerMethods } from "./receiver.js";
2
- export { messenger, getMethod, getNotifier, backgroundTarget, } from "./sender.js";
1
+ // Imports must use the .js extension because of ESM requires it and TS refuses to rewrite .ts to .js
2
+ // This works in TS even if the .js doesn't exist, but it breaks Parcel (the tests builder)
3
+ // For this reason, there's an `alias` field in package.json to redirect these imports.
4
+ // If you see "@parcel/resolver-default: Cannot load file './yourNewFile.js'" you need to add it to the `alias` list
5
+ // 🥲
6
+ export * from "./receiver.js";
7
+ export * from "./sender.js";
8
+ export * from "./types.js";
@@ -53,10 +53,5 @@ export function registerMethods(methods) {
53
53
  console.debug("Messenger: Registered", type);
54
54
  handlers.set(type, method);
55
55
  }
56
- if ("browser" in globalThis) {
57
- browser.runtime.onMessage.addListener(onMessageListener);
58
- }
59
- else {
60
- throw new Error("`webext-messenger` requires `webextension");
61
- }
56
+ browser.runtime.onMessage.addListener(onMessageListener);
62
57
  }
@@ -0,0 +1,12 @@
1
+ import { Target, PageTarget, MessengerMeta } from "./types.js";
2
+ declare type AnyTarget = Partial<Target & PageTarget>;
3
+ export declare function getActionForMessage(target: AnyTarget): "respond" | "forward" | "ignore";
4
+ export declare function nameThisTarget(): Promise<void>;
5
+ declare function __getTabData(this: MessengerMeta): AnyTarget;
6
+ declare global {
7
+ interface MessengerMethods {
8
+ __getTabData: typeof __getTabData;
9
+ }
10
+ }
11
+ export declare function initPrivateApi(): void;
12
+ export {};
@@ -0,0 +1,53 @@
1
+ import { isBackgroundPage, isContentScript } from "webext-detect-page";
2
+ import { messenger } from "./sender.js";
3
+ import { registerMethods } from "./receiver.js";
4
+ import { debug } from "./shared.js";
5
+ // Soft warning: Race conditions are possible.
6
+ // This CANNOT be awaited because waiting for it means "I will handle the message."
7
+ // If a message is received before this is ready, it will just have to be ignored.
8
+ let thisTarget;
9
+ //
10
+ export function getActionForMessage(target) {
11
+ if (target.page === "any") {
12
+ return "respond";
13
+ }
14
+ // Content scripts only receive messages that are meant for them. In the future
15
+ // they'll also forward them, but that still means they need to be handled here.
16
+ if (isContentScript()) {
17
+ return "respond";
18
+ }
19
+ // We're in an extension page, but the target is not one.
20
+ if (!("page" in target)) {
21
+ return "forward";
22
+ }
23
+ if (!thisTarget) {
24
+ console.warn("A message was received before this context was ready");
25
+ // If this *was* the target, then probably no one else answered
26
+ return "ignore";
27
+ }
28
+ // Every `target` key must match `thisTarget`
29
+ const isThisTarget = Object.entries(target).every(
30
+ // @ts-expect-error Optional properties
31
+ ([key, value]) => thisTarget[key] === value);
32
+ if (!isThisTarget) {
33
+ debug("The message’s target is", target, "but this is", thisTarget);
34
+ }
35
+ return isThisTarget ? "respond" : "ignore";
36
+ }
37
+ export async function nameThisTarget() {
38
+ // Same as above: CS receives messages correctly
39
+ if (!thisTarget && !isContentScript()) {
40
+ thisTarget = await messenger("__getTabData", {}, { page: "any" });
41
+ thisTarget.page = location.pathname;
42
+ }
43
+ }
44
+ function __getTabData() {
45
+ var _a, _b, _c;
46
+ return { tabId: (_b = (_a = this.trace[0]) === null || _a === void 0 ? void 0 : _a.tab) === null || _b === void 0 ? void 0 : _b.id, frameId: (_c = this.trace[0]) === null || _c === void 0 ? void 0 : _c.frameId };
47
+ }
48
+ export function initPrivateApi() {
49
+ if (isBackgroundPage()) {
50
+ thisTarget = { page: "background" };
51
+ registerMethods({ __getTabData });
52
+ }
53
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webext-messenger",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "description": "Browser Extension component messaging framework",
5
5
  "keywords": [],
6
6
  "repository": "pixiebrix/webext-messenger",
@@ -17,8 +17,8 @@
17
17
  },
18
18
  "scripts": {
19
19
  "build": "tsc",
20
- "demo:watch": "parcel watch --no-cache --no-hmr --detailed-report 0",
21
- "demo:build": "parcel build --no-cache --detailed-report 0",
20
+ "demo:watch": "parcel watch --no-cache --no-hmr",
21
+ "demo:build": "parcel build --no-cache",
22
22
  "prepack": "tsc --sourceMap false",
23
23
  "test": "eslint . && tsc --noEmit",
24
24
  "lint": "eslint .",
@@ -45,6 +45,21 @@
45
45
  "plugin:unicorn/recommended"
46
46
  ],
47
47
  "rules": {
48
+ "no-restricted-imports": [
49
+ "error",
50
+ {
51
+ "paths": [
52
+ {
53
+ "name": "./index",
54
+ "message": "The index file is only used to re-export internal files. Use direct imports instead."
55
+ }
56
+ ]
57
+ }
58
+ ],
59
+ "import/extensions": [
60
+ "error",
61
+ "always"
62
+ ],
48
63
  "import/no-unresolved": "off",
49
64
  "unicorn/filename-case": [
50
65
  "error",
@@ -77,34 +92,42 @@
77
92
  "@typescript-eslint/no-explicit-any": "off",
78
93
  "@typescript-eslint/no-unsafe-member-access": "off"
79
94
  }
95
+ },
96
+ {
97
+ "files": [
98
+ "source/test/**/*"
99
+ ],
100
+ "rules": {
101
+ "import/extensions": "off"
102
+ }
80
103
  }
81
104
  ]
82
105
  },
83
106
  "dependencies": {
84
- "p-retry": "^4.6.1",
85
- "serialize-error": "^8.1.0",
86
- "type-fest": "^2.5.1",
87
- "webext-detect-page": "^3.0.2",
107
+ "p-retry": "^5.0.0",
108
+ "serialize-error": "^9.0.0",
109
+ "type-fest": "^2.6.0",
110
+ "webext-detect-page": "^3.1.0",
88
111
  "webextension-polyfill": "^0.8.0"
89
112
  },
90
113
  "devDependencies": {
91
- "@parcel/config-webextension": "^2.0.0",
114
+ "@parcel/config-webextension": "^2.0.1",
92
115
  "@sindresorhus/tsconfig": "^2.0.0",
93
- "@types/chrome": "^0.0.159",
94
- "@types/webextension-polyfill": "^0.8.0",
95
- "@typescript-eslint/eslint-plugin": "^5.1.0",
96
- "@typescript-eslint/parser": "^5.1.0",
97
- "eslint": "^8.1.0",
116
+ "@types/chrome": "^0.0.164",
117
+ "@types/tape": "^4.13.2",
118
+ "@types/webextension-polyfill": "^0.8.2",
119
+ "@typescript-eslint/eslint-plugin": "^5.4.0",
120
+ "@typescript-eslint/parser": "^5.4.0",
121
+ "eslint": "^8.3.0",
98
122
  "eslint-config-prettier": "^8.3.0",
99
123
  "eslint-config-xo": "^0.39.0",
100
- "eslint-config-xo-typescript": "^0.45.2",
101
- "eslint-plugin-import": "^2.25.2",
102
- "eslint-plugin-unicorn": "^37.0.1",
103
- "fresh-tape": "^5.3.1",
124
+ "eslint-config-xo-typescript": "^0.47.1",
125
+ "eslint-plugin-import": "^2.25.3",
126
+ "eslint-plugin-unicorn": "^39.0.0",
104
127
  "npm-run-all": "^4.1.5",
105
- "parcel": "^2.0.0",
106
- "typescript": "^4.4.4",
107
- "xo": "^0.45.0"
128
+ "parcel": "^2.0.1",
129
+ "tape": "^5.3.2",
130
+ "typescript": "^4.5.2"
108
131
  },
109
132
  "targets": {
110
133
  "main": false,