webext-messenger 0.18.2 → 0.20.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/handlers.d.ts +10 -0
- package/distribution/handlers.js +6 -0
- package/distribution/receiver.js +6 -2
- package/distribution/sender.d.ts +2 -1
- package/distribution/sender.js +21 -4
- package/distribution/shared.d.ts +0 -2
- package/distribution/shared.js +1 -2
- package/distribution/thisTarget.d.ts +1 -7
- package/distribution/thisTarget.js +3 -5
- package/package.json +22 -103
- package/readme.md +4 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
import { __getTabData } from "./thisTarget.js";
|
2
|
+
import { Method } from "./types.js";
|
3
|
+
declare global {
|
4
|
+
interface MessengerMethods {
|
5
|
+
__getTabData: typeof __getTabData;
|
6
|
+
}
|
7
|
+
}
|
8
|
+
export declare const privateMethods: (typeof __getTabData)[];
|
9
|
+
export declare const handlers: Map<string, Method>;
|
10
|
+
export declare function didUserRegisterMethods(): boolean;
|
package/distribution/receiver.js
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
import { serializeError } from "serialize-error";
|
2
|
-
import { messenger } from "./sender.js";
|
3
|
-
import { handlers, isObject, MessengerError, debug, __webextMessenger, } from "./shared.js";
|
4
2
|
import { getContextName, isBackground } from "webext-detect-page";
|
3
|
+
import { messenger } from "./sender.js";
|
4
|
+
import { isObject, MessengerError, debug, __webextMessenger, } from "./shared.js";
|
5
5
|
import { getActionForMessage, nameThisTarget } from "./thisTarget.js";
|
6
|
+
import { didUserRegisterMethods, handlers } from "./handlers.js";
|
6
7
|
export function isMessengerMessage(message) {
|
7
8
|
return (isObject(message) &&
|
8
9
|
typeof message["type"] === "string" &&
|
@@ -42,6 +43,9 @@ action) {
|
|
42
43
|
args,
|
43
44
|
wasForwarded: trace.length > 1,
|
44
45
|
});
|
46
|
+
if (!didUserRegisterMethods()) {
|
47
|
+
throw new MessengerError(`No handlers registered in ${getContextName()}`);
|
48
|
+
}
|
45
49
|
const localHandler = handlers.get(type);
|
46
50
|
if (!localHandler) {
|
47
51
|
throw new MessengerError(`No handler registered for ${type} in ${getContextName()}`);
|
package/distribution/sender.d.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { PublicMethod, PublicMethodWithTarget, Options, Target, PageTarget } from "./types.js";
|
2
2
|
import { SetReturnType } from "type-fest";
|
3
|
-
export declare const
|
3
|
+
export declare const errorTargetClosedEarly = "The target was closed before receiving a response";
|
4
|
+
export declare const errorTabDoesntExist = "The tab doesn't exist";
|
4
5
|
declare function messenger<Type extends keyof MessengerMethods, Method extends MessengerMethods[Type]>(type: Type, options: {
|
5
6
|
isNotification: true;
|
6
7
|
}, target: Target | PageTarget, ...args: Parameters<Method>): void;
|
package/distribution/sender.js
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
import pRetry from "p-retry";
|
2
2
|
import { isBackground } from "webext-detect-page";
|
3
|
+
import { doesTabExist } from "webext-tools";
|
3
4
|
import { deserializeError } from "serialize-error";
|
4
|
-
import { isObject, MessengerError, __webextMessenger,
|
5
|
-
|
5
|
+
import { isObject, MessengerError, __webextMessenger, debug, warn, } from "./shared.js";
|
6
|
+
import { handlers } from "./handlers.js";
|
7
|
+
const _errorNonExistingTarget = "Could not establish connection. Receiving end does not exist.";
|
8
|
+
// https://github.com/mozilla/webextension-polyfill/issues/384
|
9
|
+
const _errorTargetClosedEarly = "A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received";
|
10
|
+
export const errorTargetClosedEarly = "The target was closed before receiving a response";
|
11
|
+
export const errorTabDoesntExist = "The tab doesn't exist";
|
6
12
|
function isMessengerResponse(response) {
|
7
13
|
return isObject(response) && response["__webextMessenger"] === true;
|
8
14
|
}
|
@@ -35,11 +41,22 @@ async function manageMessage(type, target, sendMessage) {
|
|
35
41
|
minTimeout: 100,
|
36
42
|
factor: 1.3,
|
37
43
|
maxRetryTime: 4000,
|
38
|
-
onFailedAttempt(error) {
|
44
|
+
async onFailedAttempt(error) {
|
45
|
+
if (error.message === _errorTargetClosedEarly) {
|
46
|
+
throw new Error(errorTargetClosedEarly);
|
47
|
+
}
|
39
48
|
if (
|
40
49
|
// Don't retry sending to the background page unless it really hasn't loaded yet
|
41
50
|
(target.page !== "background" && error instanceof MessengerError) ||
|
42
|
-
|
51
|
+
// Page or its content script not yet loaded
|
52
|
+
String(error.message).startsWith(_errorNonExistingTarget) ||
|
53
|
+
// `registerMethods` not yet loaded
|
54
|
+
String(error.message).startsWith("No handlers registered in ")) {
|
55
|
+
if (browser.tabs &&
|
56
|
+
typeof target.tabId === "number" &&
|
57
|
+
!(await doesTabExist(target.tabId))) {
|
58
|
+
throw new Error(errorTabDoesntExist);
|
59
|
+
}
|
43
60
|
debug(type, "will retry. Attempt", error.attemptNumber);
|
44
61
|
}
|
45
62
|
else {
|
package/distribution/shared.d.ts
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
import { JsonObject } from "type-fest";
|
2
|
-
import { Method } from "./types.js";
|
3
2
|
declare type ErrorObject = {
|
4
3
|
name?: string;
|
5
4
|
stack?: string;
|
@@ -11,7 +10,6 @@ export declare function isObject(value: unknown): value is Record<string, unknow
|
|
11
10
|
export declare class MessengerError extends Error {
|
12
11
|
name: string;
|
13
12
|
}
|
14
|
-
export declare const handlers: Map<string, Method>;
|
15
13
|
export declare const debug: (...args: any[]) => void;
|
16
14
|
export declare const warn: (...args: any[]) => void;
|
17
15
|
export declare function isErrorObject(error: unknown): error is ErrorObject;
|
package/distribution/shared.js
CHANGED
@@ -25,13 +25,12 @@ export class MessengerError extends Error {
|
|
25
25
|
});
|
26
26
|
}
|
27
27
|
}
|
28
|
-
export const handlers = new Map();
|
29
28
|
// .bind preserves the call location in the console
|
30
29
|
export const debug = logging ? console.debug.bind(console, "Messenger:") : noop;
|
31
30
|
export const warn = logging ? console.warn.bind(console, "Messenger:") : noop;
|
32
31
|
export function isErrorObject(error) {
|
33
32
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a type guard function and it uses ?.
|
34
|
-
return typeof
|
33
|
+
return typeof error?.message === "string";
|
35
34
|
}
|
36
35
|
export async function delay(milliseconds) {
|
37
36
|
return new Promise((resolve) => {
|
@@ -1,11 +1,5 @@
|
|
1
1
|
import { AnyTarget, MessengerMeta, Sender } from "./types.js";
|
2
2
|
export declare function getActionForMessage(from: Sender, { ...to }: AnyTarget): "respond" | "forward" | "ignore";
|
3
3
|
export declare function nameThisTarget(): Promise<void>;
|
4
|
-
declare function __getTabData(this: MessengerMeta): AnyTarget;
|
5
|
-
declare global {
|
6
|
-
interface MessengerMethods {
|
7
|
-
__getTabData: typeof __getTabData;
|
8
|
-
}
|
9
|
-
}
|
4
|
+
export declare function __getTabData(this: MessengerMeta): AnyTarget;
|
10
5
|
export declare function initPrivateApi(): void;
|
11
|
-
export {};
|
@@ -29,7 +29,6 @@ function compareTargets(to, thisTarget) {
|
|
29
29
|
}
|
30
30
|
export function getActionForMessage(from, { ...to } // Clone object because we're editing it
|
31
31
|
) {
|
32
|
-
var _a;
|
33
32
|
if (to.page === "any") {
|
34
33
|
return "respond";
|
35
34
|
}
|
@@ -48,7 +47,7 @@ export function getActionForMessage(from, { ...to } // Clone object because we'r
|
|
48
47
|
return "ignore";
|
49
48
|
}
|
50
49
|
// Set "this" tab to the current tabId
|
51
|
-
if (to.tabId === "this" && thisTarget.tabId ===
|
50
|
+
if (to.tabId === "this" && thisTarget.tabId === from.tab?.id) {
|
52
51
|
to.tabId = thisTarget.tabId;
|
53
52
|
}
|
54
53
|
// Every `target` key must match `thisTarget`
|
@@ -67,9 +66,8 @@ export async function nameThisTarget() {
|
|
67
66
|
thisTarget.page = location.pathname + location.search;
|
68
67
|
}
|
69
68
|
}
|
70
|
-
function __getTabData() {
|
71
|
-
|
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 };
|
69
|
+
export function __getTabData() {
|
70
|
+
return { tabId: this.trace[0]?.tab?.id, frameId: this.trace[0]?.frameId };
|
73
71
|
}
|
74
72
|
export function initPrivateApi() {
|
75
73
|
if (isBackground()) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "webext-messenger",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.20.0",
|
4
4
|
"description": "Browser Extension component messaging framework",
|
5
5
|
"keywords": [],
|
6
6
|
"repository": "pixiebrix/webext-messenger",
|
@@ -18,123 +18,42 @@
|
|
18
18
|
"fix": "eslint . --fix",
|
19
19
|
"watch": "tsc --watch"
|
20
20
|
},
|
21
|
-
"eslintConfig": {
|
22
|
-
"env": {
|
23
|
-
"browser": true
|
24
|
-
},
|
25
|
-
"parserOptions": {
|
26
|
-
"project": "tsconfig.json"
|
27
|
-
},
|
28
|
-
"plugins": [
|
29
|
-
"import"
|
30
|
-
],
|
31
|
-
"extends": [
|
32
|
-
"plugin:@typescript-eslint/recommended",
|
33
|
-
"xo",
|
34
|
-
"xo-typescript",
|
35
|
-
"prettier",
|
36
|
-
"plugin:import/recommended",
|
37
|
-
"plugin:import/typescript",
|
38
|
-
"plugin:unicorn/recommended"
|
39
|
-
],
|
40
|
-
"rules": {
|
41
|
-
"no-restricted-imports": [
|
42
|
-
"error",
|
43
|
-
{
|
44
|
-
"paths": [
|
45
|
-
{
|
46
|
-
"name": "./index",
|
47
|
-
"message": "The index file is only used to re-export internal files. Use direct imports instead."
|
48
|
-
}
|
49
|
-
]
|
50
|
-
}
|
51
|
-
],
|
52
|
-
"import/extensions": [
|
53
|
-
"error",
|
54
|
-
"always"
|
55
|
-
],
|
56
|
-
"import/no-unresolved": "off",
|
57
|
-
"unicorn/filename-case": [
|
58
|
-
"error",
|
59
|
-
{
|
60
|
-
"case": "camelCase"
|
61
|
-
}
|
62
|
-
],
|
63
|
-
"unicorn/no-useless-undefined": [
|
64
|
-
"error",
|
65
|
-
{
|
66
|
-
"checkArguments": false
|
67
|
-
}
|
68
|
-
],
|
69
|
-
"unicorn/prevent-abbreviations": [
|
70
|
-
"error",
|
71
|
-
{
|
72
|
-
"allowList": {
|
73
|
-
"args": true
|
74
|
-
}
|
75
|
-
}
|
76
|
-
]
|
77
|
-
},
|
78
|
-
"overrides": [
|
79
|
-
{
|
80
|
-
"files": [
|
81
|
-
"*.test.ts"
|
82
|
-
],
|
83
|
-
"rules": {
|
84
|
-
"@typescript-eslint/no-explicit-any": "off",
|
85
|
-
"@typescript-eslint/no-non-null-assertion": "off",
|
86
|
-
"@typescript-eslint/no-unsafe-member-access": "off"
|
87
|
-
}
|
88
|
-
},
|
89
|
-
{
|
90
|
-
"files": [
|
91
|
-
"source/test/**/*"
|
92
|
-
],
|
93
|
-
"rules": {
|
94
|
-
"import/extensions": "off"
|
95
|
-
}
|
96
|
-
}
|
97
|
-
]
|
98
|
-
},
|
99
21
|
"dependencies": {
|
100
|
-
"p-retry": "^5.1.
|
22
|
+
"p-retry": "^5.1.1",
|
101
23
|
"serialize-error": "^11.0.0",
|
102
|
-
"type-fest": "^2.
|
103
|
-
"webext-detect-page": "^4.0.1"
|
24
|
+
"type-fest": "^2.13.0",
|
25
|
+
"webext-detect-page": "^4.0.1",
|
26
|
+
"webext-tools": "^1.1.0"
|
104
27
|
},
|
105
28
|
"devDependencies": {
|
106
|
-
"@parcel/config-webextension": "^2.
|
107
|
-
"@sindresorhus/tsconfig": "^
|
108
|
-
"@types/chrome": "^0.0.
|
29
|
+
"@parcel/config-webextension": "^2.6.0",
|
30
|
+
"@sindresorhus/tsconfig": "^3.0.1",
|
31
|
+
"@types/chrome": "^0.0.188",
|
109
32
|
"@types/tape": "^4.13.2",
|
110
|
-
"@types/webextension-polyfill": "^0.
|
111
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
112
|
-
"@typescript-eslint/parser": "^5.
|
33
|
+
"@types/webextension-polyfill": "^0.9.0",
|
34
|
+
"@typescript-eslint/eslint-plugin": "^5.27.0",
|
35
|
+
"@typescript-eslint/parser": "^5.27.0",
|
113
36
|
"buffer": "^6.0.3",
|
114
|
-
"eslint": "^8.
|
37
|
+
"eslint": "^8.17.0",
|
115
38
|
"eslint-config-prettier": "^8.5.0",
|
116
|
-
"eslint-config-xo": "^0.
|
117
|
-
"eslint-config-xo-typescript": "^0.
|
118
|
-
"eslint-plugin-import": "^2.
|
119
|
-
"eslint-plugin-unicorn": "^
|
39
|
+
"eslint-config-xo": "^0.41.0",
|
40
|
+
"eslint-config-xo-typescript": "^0.51.1",
|
41
|
+
"eslint-plugin-import": "^2.26.0",
|
42
|
+
"eslint-plugin-unicorn": "^42.0.0",
|
120
43
|
"events": "^3.3.0",
|
121
44
|
"npm-run-all": "^4.1.5",
|
122
|
-
"parcel": "^2.
|
45
|
+
"parcel": "^2.6.0",
|
123
46
|
"path-browserify": "^1.0.1",
|
124
47
|
"process": "^0.11.10",
|
125
48
|
"stream-browserify": "^3.0.0",
|
126
|
-
"tape": "^5.5.
|
127
|
-
"typescript": "^4.
|
128
|
-
"webext-content-scripts": "^1.0.
|
49
|
+
"tape": "^5.5.3",
|
50
|
+
"typescript": "^4.7.3",
|
51
|
+
"webext-content-scripts": "^1.0.2",
|
129
52
|
"webextension-polyfill": "^0.9.0"
|
130
53
|
},
|
131
54
|
"alias": {
|
132
|
-
"./this-stuff-is-just-for-local-parcel-tests": "
|
133
|
-
"./source
|
134
|
-
"./source/receiver.js": "./source/receiver.ts",
|
135
|
-
"./source/types.js": "./source/types.ts",
|
136
|
-
"./source/shared.js": "./source/shared.ts",
|
137
|
-
"./source/thisTarget.js": "./source/thisTarget.ts"
|
55
|
+
"./this-stuff-is-just-for-local-parcel-tests": "https://github.com/parcel-bundler/parcel/issues/4936",
|
56
|
+
"./source/**/*.js": "./source/$1/$2.ts"
|
138
57
|
},
|
139
58
|
"targets": {
|
140
59
|
"main": false,
|