New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

webext-messenger

Package Overview
Dependencies
Maintainers
1
Versions
82
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webext-messenger - npm Package Compare versions

Comparing version 0.13.0-5 to 0.13.0-6

3

distribution/index.d.ts
export { registerMethods } from "./receiver.js";
export { getContentScriptMethod, getMethod } from "./sender.js";
export { MessengerMeta, NamedTarget, Target } from "./types.js";
export { registerTarget } from "./namedTargets.js";
export { MessengerMeta, Target } from "./types.js";
export { registerMethods } from "./receiver.js";
export { getContentScriptMethod, getMethod } from "./sender.js";
export { registerTarget } from "./namedTargets.js";
import { initTargets } from "./namedTargets.js";
initTargets();
import { serializeError } from "serialize-error";
import { isBackgroundPage } from "webext-detect-page";
import { getContentScriptMethod } from "./sender.js";
import { resolveNamedTarget } from "./namedTargets.js";
import { handlers, isObject, MessengerError, __webext_messenger__, } from "./shared.js";
import { handlers, isObject, MessengerError, debug, warn, __webextMessenger, } from "./shared.js";
export function isMessengerMessage(message) {
return (isObject(message) &&
typeof message["type"] === "string" &&
message["__webext_messenger__"] === true &&
message["__webextMessenger"] === true &&
Array.isArray(message["args"]));
}
async function handleCall(message, meta, call) {
console.debug(`Messenger:`, message.type, message.args, "from", { meta });
// The handler could actually be a synchronous function
const response = await Promise.resolve(call).then((value) => ({ value }), (error) => ({
// Errors must be serialized because the stacktraces are currently lost on Chrome and
// https://github.com/mozilla/webextension-polyfill/issues/210
error: serializeError(error),
}));
console.debug(`Messenger:`, message.type, "responds", response);
// eslint-disable-next-line @typescript-eslint/naming-convention -- Private key
return { ...response, __webext_messenger__ };
}
function getHandler(message, sender) {
if (message.target && !isBackgroundPage()) {
console.warn("Messenger:", message.type, "received but ignored; Wrong context");
return;
}
if (message.target) {
const resolvedTarget = "name" in message.target
? resolveNamedTarget(message.target, sender)
: message.target;
const publicMethod = getContentScriptMethod(message.type);
// @ts-expect-error You're wrong, TypeScript
return publicMethod.bind(undefined, resolvedTarget);
}
const handler = handlers.get(message.type);
if (handler) {
return handler;
}
}
// MUST NOT be `async` or Promise-returning-only

@@ -48,9 +16,33 @@ function onMessageListener(message, sender) {

}
const handler = getHandler(message, sender);
if (handler) {
const { type, target, args } = message;
debug(type, "↘️ received", { sender, args });
let handleMessage;
if (target) {
if (!browser.tabs) {
throw new MessengerError(`Message ${type} sent to wrong context, it can't be forwarded to ${JSON.stringify(target)}`);
}
debug(type, "🔀 forwarded", { sender, target });
const publicMethod = getContentScriptMethod(type);
handleMessage = async () => publicMethod(target, ...args);
}
else {
const localHandler = handlers.get(type);
if (!localHandler) {
warn(type, "⚠️ ignored, can't be handled here");
return;
}
debug(type, "➡️ will be handled here");
const meta = { trace: [sender] };
return handleCall(message, meta, handler.apply(meta, message.args));
handleMessage = async () => localHandler.apply(meta, args);
}
// More context in https://github.com/pixiebrix/webext-messenger/issues/45
console.warn("Messenger:", message.type, "received but ignored; No handlers were registered here");
return handleMessage()
.then((value) => ({ value }), (error) => ({
// Errors must be serialized because the stacktraces are currently lost on Chrome
// and https://github.com/mozilla/webextension-polyfill/issues/210
error: serializeError(error),
}))
.then((response) => {
debug(type, "↗️ responding", response);
return { ...response, __webextMessenger };
});
}

@@ -65,3 +57,2 @@ export function registerMethods(methods) {

}
// Use "chrome" because the polyfill might not be available when `_registerTarget` is registered
if ("browser" in globalThis) {

@@ -71,6 +62,4 @@ browser.runtime.onMessage.addListener(onMessageListener);

else {
console.error("Messenger: webextension-polyfill was not loaded in time, this might cause a runtime error later");
// @ts-expect-error Temporary workaround until I drop the webextension-polyfill dependency
chrome.runtime.onMessage.addListener(onMessageListener);
throw new Error("`webext-messenger` requires `webextension");
}
}
import pRetry from "p-retry";
import { isBackgroundPage } from "webext-detect-page";
import { deserializeError } from "serialize-error";
import { isObject, MessengerError, __webext_messenger__, handlers, } from "./shared.js";
import { resolveNamedTarget } from "./namedTargets.js";
import { isObject, MessengerError, __webextMessenger, handlers, debug, warn, } from "./shared.js";
export const errorNonExistingTarget = "Could not establish connection. Receiving end does not exist.";
function isMessengerResponse(response) {
return isObject(response) && response["__webext_messenger__"] === true;
return isObject(response) && response["__webextMessenger"] === true;
}
function makeMessage(type, args, target) {
return {
// eslint-disable-next-line @typescript-eslint/naming-convention -- Private key
__webext_messenger__,
__webextMessenger,
type,

@@ -25,3 +23,3 @@ args,

void sendMessage().catch((error) => {
console.debug("Messenger:", type, "notification failed", { error });
debug(type, "notification failed", { error });
});

@@ -38,3 +36,3 @@ }

}
console.debug("Messenger:", type, "will retry");
debug(type, "will retry");
},

@@ -52,9 +50,8 @@ });

const publicMethod = (target, ...args) => {
// Named targets and contexts without direct Tab access must go through background, unless we're already in it
if (!browser.tabs || ("name" in target && !isBackgroundPage())) {
// Contexts without direct Tab access must go through background
if (!browser.tabs) {
return manageConnection(type, options, async () => browser.runtime.sendMessage(makeMessage(type, args, target)));
}
const resolvedTarget = "name" in target ? resolveNamedTarget(target) : target;
// `frameId` must be specified. If missing, the message is sent to every frame
const { tabId, frameId = 0 } = resolvedTarget;
const { tabId, frameId = 0 } = target;
// Message tab directly

@@ -70,3 +67,3 @@ return manageConnection(type, options, async () => browser.tabs.sendMessage(tabId, makeMessage(type, args), { frameId }));

if (handler) {
console.warn("Messenger:", type, "is being handled locally");
warn(type, "is being handled locally");
return handler.apply({ trace: [] }, args);

@@ -73,0 +70,0 @@ }

import { Method } from "./types.js";
export declare const __webext_messenger__ = true;
export declare const __webextMessenger = true;
export declare function isObject(value: unknown): value is Record<string, unknown>;

@@ -8,1 +8,3 @@ export declare class MessengerError extends Error {

export declare const handlers: Map<string, Method>;
export declare const debug: (...args: any[]) => void;
export declare const warn: (...args: any[]) => void;

@@ -1,3 +0,2 @@

// eslint-disable-next-line @typescript-eslint/naming-convention -- Private key
export const __webext_messenger__ = true;
export const __webextMessenger = true;
export function isObject(value) {

@@ -18,1 +17,4 @@ return typeof value === "object" && value !== null;

export const handlers = new Map();
// .bind preserves the call location in the console
export const debug = console.debug.bind(console, "Messenger:");
export const warn = console.warn.bind(console, "Messenger:");

@@ -9,3 +9,3 @@ /// <reference types="firefox-webext-browser" />

}
declare type WithTarget<Method> = Method extends (...args: infer PreviousArguments) => infer TReturnValue ? (target: Target | NamedTarget, ...args: PreviousArguments) => TReturnValue : never;
declare type WithTarget<Method> = Method extends (...args: infer PreviousArguments) => infer TReturnValue ? (target: Target, ...args: PreviousArguments) => TReturnValue : never;
declare type ActuallyOmitThisParameter<T> = T extends (...args: infer A) => infer R ? (...args: A) => R : T;

@@ -25,3 +25,3 @@ /** Removes the `this` type and ensure it's always Promised */

/** Guarantees that the message was handled by this library */
__webext_messenger__: true;
__webextMessenger: true;
};

@@ -41,3 +41,3 @@ declare type Arguments = any[];

/** If the message is being sent to an intermediary receiver, also set the target */
target?: Target | NamedTarget;
target?: Target;
/** If the message is being sent to an intermediary receiver, also set the options */

@@ -48,3 +48,3 @@ options?: Target;

/** Guarantees that a message is meant to be handled by this library */
__webext_messenger__: true;
__webextMessenger: true;
};

@@ -55,7 +55,2 @@ export interface Target {

}
export interface NamedTarget {
/** If the id is missing, it will use the sender’s tabId instead */
tabId?: number;
name: string;
}
export {};
{
"name": "webext-messenger",
"version": "0.13.0-5",
"version": "0.13.0-6",
"description": "Browser Extension component messaging framework",

@@ -15,3 +15,2 @@ "keywords": [],

"./source/receiver.js": "./source/receiver.ts",
"./source/namedTargets.js": "./source/namedTargets.ts",
"./source/types.js": "./source/types.ts",

@@ -50,3 +49,2 @@ "./source/shared.js": "./source/shared.ts"

"rules": {
"@typescript-eslint/no-unsafe-member-access": "off",
"import/no-unresolved": "off",

@@ -80,3 +78,5 @@ "unicorn/filename-case": [

"rules": {
"@typescript-eslint/no-non-null-assertion": "off"
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unsafe-member-access": "off"
}

@@ -83,0 +83,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc