webext-messenger 0.15.0 → 0.17.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.
- package/distribution/receiver.js +13 -8
- package/distribution/sender.js +2 -2
- package/distribution/shared.js +14 -2
- package/distribution/thisTarget.js +25 -6
- package/package.json +10 -10
package/distribution/receiver.js
CHANGED
@@ -2,7 +2,7 @@ import browser from "webextension-polyfill";
|
|
2
2
|
import { serializeError } from "serialize-error";
|
3
3
|
import { messenger } from "./sender.js";
|
4
4
|
import { handlers, isObject, MessengerError, debug, __webextMessenger, } from "./shared.js";
|
5
|
-
import { getContextName,
|
5
|
+
import { getContextName, isBackground } from "webext-detect-page";
|
6
6
|
import { getActionForMessage, nameThisTarget } from "./thisTarget.js";
|
7
7
|
export function isMessengerMessage(message) {
|
8
8
|
return (isObject(message) &&
|
@@ -28,20 +28,25 @@ function onMessageListener(message, sender) {
|
|
28
28
|
async function handleMessage(message, sender,
|
29
29
|
// Once messages reach this function they cannot be "ignored", they're already being handled
|
30
30
|
action) {
|
31
|
-
const { type, target, args, options
|
32
|
-
|
31
|
+
const { type, target, args, options = {} } = message;
|
32
|
+
const { trace = [] } = options;
|
33
|
+
trace.push(sender);
|
34
|
+
const meta = { trace };
|
33
35
|
let handleMessage;
|
34
36
|
if (action === "forward") {
|
35
37
|
debug(type, "🔀 forwarded", { sender, target });
|
36
|
-
handleMessage = async () => messenger(type,
|
38
|
+
handleMessage = async () => messenger(type, meta, target, ...args);
|
37
39
|
}
|
38
40
|
else {
|
41
|
+
debug(type, "↘️ received in", getContextName(), {
|
42
|
+
sender,
|
43
|
+
args,
|
44
|
+
wasForwarded: trace.length > 1,
|
45
|
+
});
|
39
46
|
const localHandler = handlers.get(type);
|
40
47
|
if (!localHandler) {
|
41
48
|
throw new MessengerError(`No handler registered for ${type} in ${getContextName()}`);
|
42
49
|
}
|
43
|
-
debug(type, "➡️ will be handled here");
|
44
|
-
const meta = { trace: [sender] };
|
45
50
|
handleMessage = async () => localHandler.apply(meta, args);
|
46
51
|
}
|
47
52
|
const response = await handleMessage().then((value) => ({ value }), (error) => ({
|
@@ -53,14 +58,14 @@ action) {
|
|
53
58
|
return { ...response, __webextMessenger };
|
54
59
|
}
|
55
60
|
export function registerMethods(methods) {
|
56
|
-
if (!
|
61
|
+
if (!isBackground()) {
|
57
62
|
void nameThisTarget();
|
58
63
|
}
|
59
64
|
for (const [type, method] of Object.entries(methods)) {
|
60
65
|
if (handlers.has(type)) {
|
61
66
|
throw new MessengerError(`Handler already set for ${type}`);
|
62
67
|
}
|
63
|
-
|
68
|
+
debug("Registered", type);
|
64
69
|
handlers.set(type, method);
|
65
70
|
}
|
66
71
|
browser.runtime.onMessage.addListener(onMessageListener);
|
package/distribution/sender.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import browser from "webextension-polyfill";
|
2
2
|
import pRetry from "p-retry";
|
3
|
-
import {
|
3
|
+
import { isBackground } from "webext-detect-page";
|
4
4
|
import { deserializeError } from "serialize-error";
|
5
5
|
import { isObject, MessengerError, __webextMessenger, handlers, debug, warn, } from "./shared.js";
|
6
6
|
export const errorNonExistingTarget = "Could not establish connection. Receiving end does not exist.";
|
@@ -58,7 +58,7 @@ async function manageMessage(type, target, sendMessage) {
|
|
58
58
|
function messenger(type, options, target, ...args) {
|
59
59
|
// Message goes to extension page
|
60
60
|
if ("page" in target) {
|
61
|
-
if (target.page === "background" &&
|
61
|
+
if (target.page === "background" && isBackground()) {
|
62
62
|
const handler = handlers.get(type);
|
63
63
|
if (handler) {
|
64
64
|
warn(type, "is being handled locally");
|
package/distribution/shared.js
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
const logging = (() => {
|
2
|
+
try {
|
3
|
+
// @ts-expect-error it would break Webpack
|
4
|
+
return process.env.WEBEXT_MESSENGER_LOGGING === "true";
|
5
|
+
}
|
6
|
+
catch {
|
7
|
+
return false;
|
8
|
+
}
|
9
|
+
})();
|
10
|
+
function noop() {
|
11
|
+
/* */
|
12
|
+
}
|
1
13
|
export const __webextMessenger = true;
|
2
14
|
export function isObject(value) {
|
3
15
|
return typeof value === "object" && value !== null;
|
@@ -15,8 +27,8 @@ export class MessengerError extends Error {
|
|
15
27
|
}
|
16
28
|
export const handlers = new Map();
|
17
29
|
// .bind preserves the call location in the console
|
18
|
-
export const debug = console.debug.bind(console, "Messenger:");
|
19
|
-
export const warn = console.warn.bind(console, "Messenger:");
|
30
|
+
export const debug = logging ? console.debug.bind(console, "Messenger:") : noop;
|
31
|
+
export const warn = logging ? console.warn.bind(console, "Messenger:") : noop;
|
20
32
|
export function isErrorObject(error) {
|
21
33
|
var _a;
|
22
34
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a type guard function and it uses ?.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { isBackground, isContentScript, isExtensionContext, } from "webext-detect-page";
|
2
2
|
import { messenger } from "./sender.js";
|
3
3
|
import { registerMethods } from "./receiver.js";
|
4
4
|
import { debug } from "./shared.js";
|
@@ -6,6 +6,27 @@ import { debug } from "./shared.js";
|
|
6
6
|
// This CANNOT be awaited because waiting for it means "I will handle the message."
|
7
7
|
// If a message is received before this is ready, it will just have to be ignored.
|
8
8
|
let thisTarget;
|
9
|
+
function compareTargets(to, thisTarget) {
|
10
|
+
for (const [key, value] of Object.entries(to)) {
|
11
|
+
if (thisTarget[key] === value) {
|
12
|
+
continue;
|
13
|
+
}
|
14
|
+
if (key !== "page") {
|
15
|
+
return false;
|
16
|
+
}
|
17
|
+
const toUrl = new URL(to.page, location.origin);
|
18
|
+
const thisUrl = new URL(thisTarget.page, location.origin);
|
19
|
+
if (toUrl.pathname !== thisUrl.pathname) {
|
20
|
+
return false;
|
21
|
+
}
|
22
|
+
for (const [parameterKey, parameterValue] of toUrl.searchParams) {
|
23
|
+
if (thisUrl.searchParams.get(parameterKey) !== parameterValue) {
|
24
|
+
return false;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
return true;
|
29
|
+
}
|
9
30
|
export function getActionForMessage(from, { ...to } // Clone object because we're editing it
|
10
31
|
) {
|
11
32
|
var _a;
|
@@ -31,9 +52,7 @@ export function getActionForMessage(from, { ...to } // Clone object because we'r
|
|
31
52
|
to.tabId = thisTarget.tabId;
|
32
53
|
}
|
33
54
|
// Every `target` key must match `thisTarget`
|
34
|
-
const isThisTarget =
|
35
|
-
// @ts-expect-error Optional properties
|
36
|
-
([key, value]) => thisTarget[key] === value);
|
55
|
+
const isThisTarget = compareTargets(to, thisTarget);
|
37
56
|
if (!isThisTarget) {
|
38
57
|
debug("The message’s target is", to, "but this is", thisTarget);
|
39
58
|
}
|
@@ -45,7 +64,7 @@ export async function nameThisTarget() {
|
|
45
64
|
if (!nameRequested && !thisTarget && !isContentScript()) {
|
46
65
|
nameRequested = true;
|
47
66
|
thisTarget = await messenger("__getTabData", {}, { page: "any" });
|
48
|
-
thisTarget.page = location.pathname;
|
67
|
+
thisTarget.page = location.pathname + location.search;
|
49
68
|
}
|
50
69
|
}
|
51
70
|
function __getTabData() {
|
@@ -53,7 +72,7 @@ function __getTabData() {
|
|
53
72
|
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 };
|
54
73
|
}
|
55
74
|
export function initPrivateApi() {
|
56
|
-
if (
|
75
|
+
if (isBackground()) {
|
57
76
|
thisTarget = { page: "background" };
|
58
77
|
}
|
59
78
|
if (isExtensionContext()) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "webext-messenger",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.17.0",
|
4
4
|
"description": "Browser Extension component messaging framework",
|
5
5
|
"keywords": [],
|
6
6
|
"repository": "pixiebrix/webext-messenger",
|
@@ -18,7 +18,7 @@
|
|
18
18
|
},
|
19
19
|
"scripts": {
|
20
20
|
"build": "tsc",
|
21
|
-
"demo:watch": "parcel watch --no-cache --no-hmr",
|
21
|
+
"demo:watch": "WEBEXT_MESSENGER_LOGGING=true parcel watch --no-cache --no-hmr",
|
22
22
|
"demo:build": "parcel build --no-cache",
|
23
23
|
"prepack": "tsc --sourceMap false",
|
24
24
|
"test": "eslint . && tsc --noEmit",
|
@@ -107,19 +107,19 @@
|
|
107
107
|
"dependencies": {
|
108
108
|
"p-retry": "^5.0.0",
|
109
109
|
"serialize-error": "^9.0.0",
|
110
|
-
"type-fest": "^2.
|
111
|
-
"webext-detect-page": "^
|
110
|
+
"type-fest": "^2.8.0",
|
111
|
+
"webext-detect-page": "^4.0.0",
|
112
112
|
"webextension-polyfill": "^0.8.0"
|
113
113
|
},
|
114
114
|
"devDependencies": {
|
115
115
|
"@parcel/config-webextension": "^2.0.1",
|
116
116
|
"@sindresorhus/tsconfig": "^2.0.0",
|
117
|
-
"@types/chrome": "^0.0.
|
117
|
+
"@types/chrome": "^0.0.171",
|
118
118
|
"@types/tape": "^4.13.2",
|
119
119
|
"@types/webextension-polyfill": "^0.8.2",
|
120
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
121
|
-
"@typescript-eslint/parser": "^5.
|
122
|
-
"eslint": "^8.
|
120
|
+
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
121
|
+
"@typescript-eslint/parser": "^5.7.0",
|
122
|
+
"eslint": "^8.4.1",
|
123
123
|
"eslint-config-prettier": "^8.3.0",
|
124
124
|
"eslint-config-xo": "^0.39.0",
|
125
125
|
"eslint-config-xo-typescript": "^0.47.1",
|
@@ -128,8 +128,8 @@
|
|
128
128
|
"npm-run-all": "^4.1.5",
|
129
129
|
"parcel": "^2.0.1",
|
130
130
|
"tape": "^5.3.2",
|
131
|
-
"typescript": "^4.5.
|
132
|
-
"webext-content-scripts": "^0.
|
131
|
+
"typescript": "^4.5.4",
|
132
|
+
"webext-content-scripts": "^0.12.0"
|
133
133
|
},
|
134
134
|
"targets": {
|
135
135
|
"main": false,
|