UNPKG

@webext-core/messaging

Version:

Light weight, type-safe wrapper around the web extension messaging APIs. Supports all browsers (Chrome, Firefox, Safari)

1,392 lines (1,384 loc) 46.2 kB
"use strict"; var webExtCoreMessaging = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // ../../node_modules/webextension-polyfill/dist/browser-polyfill.js var require_browser_polyfill = __commonJS({ "../../node_modules/webextension-polyfill/dist/browser-polyfill.js"(exports, module) { (function(global, factory) { if (typeof define === "function" && define.amd) { define("webextension-polyfill", ["module"], factory); } else if (typeof exports !== "undefined") { factory(module); } else { var mod = { exports: {} }; factory(mod); global.browser = mod.exports; } })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : exports, function(module2) { var _a, _b; "use strict"; if (!((_b = (_a = globalThis.chrome) == null ? void 0 : _a.runtime) == null ? void 0 : _b.id)) { throw new Error("This script should only be loaded in a browser extension."); } if (typeof globalThis.browser === "undefined" || Object.getPrototypeOf(globalThis.browser) !== Object.prototype) { const CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE = "The message port closed before a response was received."; const wrapAPIs = (extensionAPIs) => { const apiMetadata = { "alarms": { "clear": { "minArgs": 0, "maxArgs": 1 }, "clearAll": { "minArgs": 0, "maxArgs": 0 }, "get": { "minArgs": 0, "maxArgs": 1 }, "getAll": { "minArgs": 0, "maxArgs": 0 } }, "bookmarks": { "create": { "minArgs": 1, "maxArgs": 1 }, "get": { "minArgs": 1, "maxArgs": 1 }, "getChildren": { "minArgs": 1, "maxArgs": 1 }, "getRecent": { "minArgs": 1, "maxArgs": 1 }, "getSubTree": { "minArgs": 1, "maxArgs": 1 }, "getTree": { "minArgs": 0, "maxArgs": 0 }, "move": { "minArgs": 2, "maxArgs": 2 }, "remove": { "minArgs": 1, "maxArgs": 1 }, "removeTree": { "minArgs": 1, "maxArgs": 1 }, "search": { "minArgs": 1, "maxArgs": 1 }, "update": { "minArgs": 2, "maxArgs": 2 } }, "browserAction": { "disable": { "minArgs": 0, "maxArgs": 1, "fallbackToNoCallback": true }, "enable": { "minArgs": 0, "maxArgs": 1, "fallbackToNoCallback": true }, "getBadgeBackgroundColor": { "minArgs": 1, "maxArgs": 1 }, "getBadgeText": { "minArgs": 1, "maxArgs": 1 }, "getPopup": { "minArgs": 1, "maxArgs": 1 }, "getTitle": { "minArgs": 1, "maxArgs": 1 }, "openPopup": { "minArgs": 0, "maxArgs": 0 }, "setBadgeBackgroundColor": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true }, "setBadgeText": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true }, "setIcon": { "minArgs": 1, "maxArgs": 1 }, "setPopup": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true }, "setTitle": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true } }, "browsingData": { "remove": { "minArgs": 2, "maxArgs": 2 }, "removeCache": { "minArgs": 1, "maxArgs": 1 }, "removeCookies": { "minArgs": 1, "maxArgs": 1 }, "removeDownloads": { "minArgs": 1, "maxArgs": 1 }, "removeFormData": { "minArgs": 1, "maxArgs": 1 }, "removeHistory": { "minArgs": 1, "maxArgs": 1 }, "removeLocalStorage": { "minArgs": 1, "maxArgs": 1 }, "removePasswords": { "minArgs": 1, "maxArgs": 1 }, "removePluginData": { "minArgs": 1, "maxArgs": 1 }, "settings": { "minArgs": 0, "maxArgs": 0 } }, "commands": { "getAll": { "minArgs": 0, "maxArgs": 0 } }, "contextMenus": { "remove": { "minArgs": 1, "maxArgs": 1 }, "removeAll": { "minArgs": 0, "maxArgs": 0 }, "update": { "minArgs": 2, "maxArgs": 2 } }, "cookies": { "get": { "minArgs": 1, "maxArgs": 1 }, "getAll": { "minArgs": 1, "maxArgs": 1 }, "getAllCookieStores": { "minArgs": 0, "maxArgs": 0 }, "remove": { "minArgs": 1, "maxArgs": 1 }, "set": { "minArgs": 1, "maxArgs": 1 } }, "devtools": { "inspectedWindow": { "eval": { "minArgs": 1, "maxArgs": 2, "singleCallbackArg": false } }, "panels": { "create": { "minArgs": 3, "maxArgs": 3, "singleCallbackArg": true }, "elements": { "createSidebarPane": { "minArgs": 1, "maxArgs": 1 } } } }, "downloads": { "cancel": { "minArgs": 1, "maxArgs": 1 }, "download": { "minArgs": 1, "maxArgs": 1 }, "erase": { "minArgs": 1, "maxArgs": 1 }, "getFileIcon": { "minArgs": 1, "maxArgs": 2 }, "open": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true }, "pause": { "minArgs": 1, "maxArgs": 1 }, "removeFile": { "minArgs": 1, "maxArgs": 1 }, "resume": { "minArgs": 1, "maxArgs": 1 }, "search": { "minArgs": 1, "maxArgs": 1 }, "show": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true } }, "extension": { "isAllowedFileSchemeAccess": { "minArgs": 0, "maxArgs": 0 }, "isAllowedIncognitoAccess": { "minArgs": 0, "maxArgs": 0 } }, "history": { "addUrl": { "minArgs": 1, "maxArgs": 1 }, "deleteAll": { "minArgs": 0, "maxArgs": 0 }, "deleteRange": { "minArgs": 1, "maxArgs": 1 }, "deleteUrl": { "minArgs": 1, "maxArgs": 1 }, "getVisits": { "minArgs": 1, "maxArgs": 1 }, "search": { "minArgs": 1, "maxArgs": 1 } }, "i18n": { "detectLanguage": { "minArgs": 1, "maxArgs": 1 }, "getAcceptLanguages": { "minArgs": 0, "maxArgs": 0 } }, "identity": { "launchWebAuthFlow": { "minArgs": 1, "maxArgs": 1 } }, "idle": { "queryState": { "minArgs": 1, "maxArgs": 1 } }, "management": { "get": { "minArgs": 1, "maxArgs": 1 }, "getAll": { "minArgs": 0, "maxArgs": 0 }, "getSelf": { "minArgs": 0, "maxArgs": 0 }, "setEnabled": { "minArgs": 2, "maxArgs": 2 }, "uninstallSelf": { "minArgs": 0, "maxArgs": 1 } }, "notifications": { "clear": { "minArgs": 1, "maxArgs": 1 }, "create": { "minArgs": 1, "maxArgs": 2 }, "getAll": { "minArgs": 0, "maxArgs": 0 }, "getPermissionLevel": { "minArgs": 0, "maxArgs": 0 }, "update": { "minArgs": 2, "maxArgs": 2 } }, "pageAction": { "getPopup": { "minArgs": 1, "maxArgs": 1 }, "getTitle": { "minArgs": 1, "maxArgs": 1 }, "hide": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true }, "setIcon": { "minArgs": 1, "maxArgs": 1 }, "setPopup": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true }, "setTitle": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true }, "show": { "minArgs": 1, "maxArgs": 1, "fallbackToNoCallback": true } }, "permissions": { "contains": { "minArgs": 1, "maxArgs": 1 }, "getAll": { "minArgs": 0, "maxArgs": 0 }, "remove": { "minArgs": 1, "maxArgs": 1 }, "request": { "minArgs": 1, "maxArgs": 1 } }, "runtime": { "getBackgroundPage": { "minArgs": 0, "maxArgs": 0 }, "getPlatformInfo": { "minArgs": 0, "maxArgs": 0 }, "openOptionsPage": { "minArgs": 0, "maxArgs": 0 }, "requestUpdateCheck": { "minArgs": 0, "maxArgs": 0 }, "sendMessage": { "minArgs": 1, "maxArgs": 3 }, "sendNativeMessage": { "minArgs": 2, "maxArgs": 2 }, "setUninstallURL": { "minArgs": 1, "maxArgs": 1 } }, "sessions": { "getDevices": { "minArgs": 0, "maxArgs": 1 }, "getRecentlyClosed": { "minArgs": 0, "maxArgs": 1 }, "restore": { "minArgs": 0, "maxArgs": 1 } }, "storage": { "local": { "clear": { "minArgs": 0, "maxArgs": 0 }, "get": { "minArgs": 0, "maxArgs": 1 }, "getBytesInUse": { "minArgs": 0, "maxArgs": 1 }, "remove": { "minArgs": 1, "maxArgs": 1 }, "set": { "minArgs": 1, "maxArgs": 1 } }, "managed": { "get": { "minArgs": 0, "maxArgs": 1 }, "getBytesInUse": { "minArgs": 0, "maxArgs": 1 } }, "sync": { "clear": { "minArgs": 0, "maxArgs": 0 }, "get": { "minArgs": 0, "maxArgs": 1 }, "getBytesInUse": { "minArgs": 0, "maxArgs": 1 }, "remove": { "minArgs": 1, "maxArgs": 1 }, "set": { "minArgs": 1, "maxArgs": 1 } } }, "tabs": { "captureVisibleTab": { "minArgs": 0, "maxArgs": 2 }, "create": { "minArgs": 1, "maxArgs": 1 }, "detectLanguage": { "minArgs": 0, "maxArgs": 1 }, "discard": { "minArgs": 0, "maxArgs": 1 }, "duplicate": { "minArgs": 1, "maxArgs": 1 }, "executeScript": { "minArgs": 1, "maxArgs": 2 }, "get": { "minArgs": 1, "maxArgs": 1 }, "getCurrent": { "minArgs": 0, "maxArgs": 0 }, "getZoom": { "minArgs": 0, "maxArgs": 1 }, "getZoomSettings": { "minArgs": 0, "maxArgs": 1 }, "goBack": { "minArgs": 0, "maxArgs": 1 }, "goForward": { "minArgs": 0, "maxArgs": 1 }, "highlight": { "minArgs": 1, "maxArgs": 1 }, "insertCSS": { "minArgs": 1, "maxArgs": 2 }, "move": { "minArgs": 2, "maxArgs": 2 }, "query": { "minArgs": 1, "maxArgs": 1 }, "reload": { "minArgs": 0, "maxArgs": 2 }, "remove": { "minArgs": 1, "maxArgs": 1 }, "removeCSS": { "minArgs": 1, "maxArgs": 2 }, "sendMessage": { "minArgs": 2, "maxArgs": 3 }, "setZoom": { "minArgs": 1, "maxArgs": 2 }, "setZoomSettings": { "minArgs": 1, "maxArgs": 2 }, "update": { "minArgs": 1, "maxArgs": 2 } }, "topSites": { "get": { "minArgs": 0, "maxArgs": 0 } }, "webNavigation": { "getAllFrames": { "minArgs": 1, "maxArgs": 1 }, "getFrame": { "minArgs": 1, "maxArgs": 1 } }, "webRequest": { "handlerBehaviorChanged": { "minArgs": 0, "maxArgs": 0 } }, "windows": { "create": { "minArgs": 0, "maxArgs": 1 }, "get": { "minArgs": 1, "maxArgs": 2 }, "getAll": { "minArgs": 0, "maxArgs": 1 }, "getCurrent": { "minArgs": 0, "maxArgs": 1 }, "getLastFocused": { "minArgs": 0, "maxArgs": 1 }, "remove": { "minArgs": 1, "maxArgs": 1 }, "update": { "minArgs": 2, "maxArgs": 2 } } }; if (Object.keys(apiMetadata).length === 0) { throw new Error("api-metadata.json has not been included in browser-polyfill"); } class DefaultWeakMap extends WeakMap { constructor(createItem, items = void 0) { super(items); this.createItem = createItem; } get(key) { if (!this.has(key)) { this.set(key, this.createItem(key)); } return super.get(key); } } const isThenable = (value) => { return value && typeof value === "object" && typeof value.then === "function"; }; const makeCallback = (promise, metadata) => { return (...callbackArgs) => { if (extensionAPIs.runtime.lastError) { promise.reject(new Error(extensionAPIs.runtime.lastError.message)); } else if (metadata.singleCallbackArg || callbackArgs.length <= 1 && metadata.singleCallbackArg !== false) { promise.resolve(callbackArgs[0]); } else { promise.resolve(callbackArgs); } }; }; const pluralizeArguments = (numArgs) => numArgs == 1 ? "argument" : "arguments"; const wrapAsyncFunction = (name, metadata) => { return function asyncFunctionWrapper(target, ...args) { if (args.length < metadata.minArgs) { throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`); } if (args.length > metadata.maxArgs) { throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`); } return new Promise((resolve, reject) => { if (metadata.fallbackToNoCallback) { try { target[name](...args, makeCallback({ resolve, reject }, metadata)); } catch (cbError) { console.warn(`${name} API method doesn't seem to support the callback parameter, falling back to call it without a callback: `, cbError); target[name](...args); metadata.fallbackToNoCallback = false; metadata.noCallback = true; resolve(); } } else if (metadata.noCallback) { target[name](...args); resolve(); } else { target[name](...args, makeCallback({ resolve, reject }, metadata)); } }); }; }; const wrapMethod = (target, method, wrapper) => { return new Proxy(method, { apply(targetMethod, thisObj, args) { return wrapper.call(thisObj, target, ...args); } }); }; let hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); const wrapObject = (target, wrappers = {}, metadata = {}) => { let cache = /* @__PURE__ */ Object.create(null); let handlers = { has(proxyTarget2, prop) { return prop in target || prop in cache; }, get(proxyTarget2, prop, receiver) { if (prop in cache) { return cache[prop]; } if (!(prop in target)) { return void 0; } let value = target[prop]; if (typeof value === "function") { if (typeof wrappers[prop] === "function") { value = wrapMethod(target, target[prop], wrappers[prop]); } else if (hasOwnProperty(metadata, prop)) { let wrapper = wrapAsyncFunction(prop, metadata[prop]); value = wrapMethod(target, target[prop], wrapper); } else { value = value.bind(target); } } else if (typeof value === "object" && value !== null && (hasOwnProperty(wrappers, prop) || hasOwnProperty(metadata, prop))) { value = wrapObject(value, wrappers[prop], metadata[prop]); } else if (hasOwnProperty(metadata, "*")) { value = wrapObject(value, wrappers[prop], metadata["*"]); } else { Object.defineProperty(cache, prop, { configurable: true, enumerable: true, get() { return target[prop]; }, set(value2) { target[prop] = value2; } }); return value; } cache[prop] = value; return value; }, set(proxyTarget2, prop, value, receiver) { if (prop in cache) { cache[prop] = value; } else { target[prop] = value; } return true; }, defineProperty(proxyTarget2, prop, desc) { return Reflect.defineProperty(cache, prop, desc); }, deleteProperty(proxyTarget2, prop) { return Reflect.deleteProperty(cache, prop); } }; let proxyTarget = Object.create(target); return new Proxy(proxyTarget, handlers); }; const wrapEvent = (wrapperMap) => ({ addListener(target, listener, ...args) { target.addListener(wrapperMap.get(listener), ...args); }, hasListener(target, listener) { return target.hasListener(wrapperMap.get(listener)); }, removeListener(target, listener) { target.removeListener(wrapperMap.get(listener)); } }); const onRequestFinishedWrappers = new DefaultWeakMap((listener) => { if (typeof listener !== "function") { return listener; } return function onRequestFinished(req) { const wrappedReq = wrapObject( req, {}, { getContent: { minArgs: 0, maxArgs: 0 } } ); listener(wrappedReq); }; }); const onMessageWrappers = new DefaultWeakMap((listener) => { if (typeof listener !== "function") { return listener; } return function onMessage(message, sender, sendResponse) { let didCallSendResponse = false; let wrappedSendResponse; let sendResponsePromise = new Promise((resolve) => { wrappedSendResponse = function(response) { didCallSendResponse = true; resolve(response); }; }); let result; try { result = listener(message, sender, wrappedSendResponse); } catch (err) { result = Promise.reject(err); } const isResultThenable = result !== true && isThenable(result); if (result !== true && !isResultThenable && !didCallSendResponse) { return false; } const sendPromisedResult = (promise) => { promise.then((msg) => { sendResponse(msg); }, (error) => { let message2; if (error && (error instanceof Error || typeof error.message === "string")) { message2 = error.message; } else { message2 = "An unexpected error occurred"; } sendResponse({ __mozWebExtensionPolyfillReject__: true, message: message2 }); }).catch((err) => { console.error("Failed to send onMessage rejected reply", err); }); }; if (isResultThenable) { sendPromisedResult(result); } else { sendPromisedResult(sendResponsePromise); } return true; }; }); const wrappedSendMessageCallback = ({ reject, resolve }, reply) => { if (extensionAPIs.runtime.lastError) { if (extensionAPIs.runtime.lastError.message === CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE) { resolve(); } else { reject(new Error(extensionAPIs.runtime.lastError.message)); } } else if (reply && reply.__mozWebExtensionPolyfillReject__) { reject(new Error(reply.message)); } else { resolve(reply); } }; const wrappedSendMessage = (name, metadata, apiNamespaceObj, ...args) => { if (args.length < metadata.minArgs) { throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`); } if (args.length > metadata.maxArgs) { throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`); } return new Promise((resolve, reject) => { const wrappedCb = wrappedSendMessageCallback.bind(null, { resolve, reject }); args.push(wrappedCb); apiNamespaceObj.sendMessage(...args); }); }; const staticWrappers = { devtools: { network: { onRequestFinished: wrapEvent(onRequestFinishedWrappers) } }, runtime: { onMessage: wrapEvent(onMessageWrappers), onMessageExternal: wrapEvent(onMessageWrappers), sendMessage: wrappedSendMessage.bind(null, "sendMessage", { minArgs: 1, maxArgs: 3 }) }, tabs: { sendMessage: wrappedSendMessage.bind(null, "sendMessage", { minArgs: 2, maxArgs: 3 }) } }; const settingMetadata = { clear: { minArgs: 1, maxArgs: 1 }, get: { minArgs: 1, maxArgs: 1 }, set: { minArgs: 1, maxArgs: 1 } }; apiMetadata.privacy = { network: { "*": settingMetadata }, services: { "*": settingMetadata }, websites: { "*": settingMetadata } }; return wrapObject(extensionAPIs, staticWrappers, apiMetadata); }; module2.exports = wrapAPIs(chrome); } else { module2.exports = globalThis.browser; } }); } }); // src/index.ts var src_exports = {}; __export(src_exports, { defineExtensionMessaging: () => defineExtensionMessaging }); // src/extension.ts var import_webextension_polyfill = __toESM(require_browser_polyfill(), 1); // ../../node_modules/serialize-error/error-constructors.js var list = [ // Native ES errors https://262.ecma-international.org/12.0/#sec-well-known-intrinsic-objects EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, // Built-in errors globalThis.DOMException, // Node-specific errors // https://nodejs.org/api/errors.html globalThis.AssertionError, globalThis.SystemError ].filter(Boolean).map( (constructor) => [constructor.name, constructor] ); var errorConstructors = new Map(list); var error_constructors_default = errorConstructors; // ../../node_modules/serialize-error/index.js var NonError = class extends Error { constructor(message) { super(NonError._prepareSuperMessage(message)); __publicField(this, "name", "NonError"); } static _prepareSuperMessage(message) { try { return JSON.stringify(message); } catch (e) { return String(message); } } }; var commonProperties = [ { property: "name", enumerable: false }, { property: "message", enumerable: false }, { property: "stack", enumerable: false }, { property: "code", enumerable: true }, { property: "cause", enumerable: false } ]; var toJsonWasCalled = /* @__PURE__ */ new WeakSet(); var toJSON = (from) => { toJsonWasCalled.add(from); const json = from.toJSON(); toJsonWasCalled.delete(from); return json; }; var getErrorConstructor = (name) => { var _a; return (_a = error_constructors_default.get(name)) != null ? _a : Error; }; var destroyCircular = ({ from, seen, to, forceEnumerable, maxDepth, depth, useToJSON, serialize }) => { if (!to) { if (Array.isArray(from)) { to = []; } else if (!serialize && isErrorLike(from)) { const Error2 = getErrorConstructor(from.name); to = new Error2(); } else { to = {}; } } seen.push(from); if (depth >= maxDepth) { return to; } if (useToJSON && typeof from.toJSON === "function" && !toJsonWasCalled.has(from)) { return toJSON(from); } const continueDestroyCircular = (value) => destroyCircular({ from: value, seen: [...seen], forceEnumerable, maxDepth, depth, useToJSON, serialize }); for (const [key, value] of Object.entries(from)) { if (value && value instanceof Uint8Array && value.constructor.name === "Buffer") { to[key] = "[object Buffer]"; continue; } if (value !== null && typeof value === "object" && typeof value.pipe === "function") { to[key] = "[object Stream]"; continue; } if (typeof value === "function") { continue; } if (!value || typeof value !== "object") { try { to[key] = value; } catch (e) { } continue; } if (!seen.includes(from[key])) { depth++; to[key] = continueDestroyCircular(from[key]); continue; } to[key] = "[Circular]"; } for (const { property, enumerable } of commonProperties) { if (typeof from[property] !== "undefined" && from[property] !== null) { Object.defineProperty(to, property, { value: isErrorLike(from[property]) ? continueDestroyCircular(from[property]) : from[property], enumerable: forceEnumerable ? true : enumerable, configurable: true, writable: true }); } } return to; }; function serializeError(value, options = {}) { const { maxDepth = Number.POSITIVE_INFINITY, useToJSON = true } = options; if (typeof value === "object" && value !== null) { return destroyCircular({ from: value, seen: [], forceEnumerable: true, maxDepth, depth: 0, useToJSON, serialize: true }); } if (typeof value === "function") { return `[Function: ${value.name || "anonymous"}]`; } return value; } function deserializeError(value, options = {}) { const { maxDepth = Number.POSITIVE_INFINITY } = options; if (value instanceof Error) { return value; } if (isMinimumViableSerializedError(value)) { const Error2 = getErrorConstructor(value.name); return destroyCircular({ from: value, seen: [], to: new Error2(), maxDepth, depth: 0, serialize: false }); } return new NonError(value); } function isErrorLike(value) { return Boolean(value) && typeof value === "object" && "name" in value && "message" in value && "stack" in value; } function isMinimumViableSerializedError(value) { return Boolean(value) && typeof value === "object" && "message" in value && !Array.isArray(value); } // src/generic.ts function defineGenericMessanging(config) { let removeRootListener; let perTypeListeners = {}; function cleanupRootListener() { if (Object.entries(perTypeListeners).length === 0) { removeRootListener == null ? void 0 : removeRootListener(); removeRootListener = void 0; } } let idSeq = Math.floor(Math.random() * 1e4); function getNextId() { return idSeq++; } return { sendMessage(type, data, ...args) { return __async(this, null, function* () { var _a2, _b, _c, _d; const _message = { id: getNextId(), type, data, timestamp: Date.now() }; const message = (_b = yield (_a2 = config.verifyMessageData) == null ? void 0 : _a2.call(config, _message)) != null ? _b : _message; (_c = config.logger) == null ? void 0 : _c.debug(`[messaging] sendMessage {id=${message.id}} \u2500\u1405`, message, ...args); const response = yield config.sendMessage(message, ...args); const { res, err } = response != null ? response : { err: new Error("No response") }; (_d = config.logger) == null ? void 0 : _d.debug(`[messaging] sendMessage {id=${message.id}} \u140A\u2500`, { res, err }); if (err != null) throw deserializeError(err); return res; }); }, onMessage(type, onReceived) { var _a2, _b, _c; if (removeRootListener == null) { (_a2 = config.logger) == null ? void 0 : _a2.debug( `[messaging] "${type}" initialized the message listener for this context` ); removeRootListener = config.addRootListener((message) => { var _a3, _b2; if (typeof message.type != "string" || typeof message.timestamp !== "number") { if (config.breakError) { return; } const err = Error( `[messaging] Unknown message format, must include the 'type' & 'timestamp' fields, received: ${JSON.stringify( message )}` ); (_a3 = config.logger) == null ? void 0 : _a3.error(err); throw err; } (_b2 = config == null ? void 0 : config.logger) == null ? void 0 : _b2.debug("[messaging] Received message", message); const listener = perTypeListeners[message.type]; if (listener == null) return; const res = listener(message); return Promise.resolve(res).then((res2) => { var _a4, _b3; return (_b3 = (_a4 = config.verifyMessageData) == null ? void 0 : _a4.call(config, res2)) != null ? _b3 : res2; }).then((res2) => { var _a4; (_a4 = config == null ? void 0 : config.logger) == null ? void 0 : _a4.debug(`[messaging] onMessage {id=${message.id}} \u2500\u1405`, { res: res2 }); return { res: res2 }; }).catch((err) => { var _a4; (_a4 = config == null ? void 0 : config.logger) == null ? void 0 : _a4.debug(`[messaging] onMessage {id=${message.id}} \u2500\u1405`, { err }); return { err: serializeError(err) }; }); }); } if (perTypeListeners[type] != null) { const err = Error( `[messaging] In this JS context, only one listener can be setup for ${type}` ); (_b = config.logger) == null ? void 0 : _b.error(err); throw err; } perTypeListeners[type] = onReceived; (_c = config.logger) == null ? void 0 : _c.log(`[messaging] Added listener for ${type}`); return () => { delete perTypeListeners[type]; cleanupRootListener(); }; }, removeAllListeners() { Object.keys(perTypeListeners).forEach((type) => { delete perTypeListeners[type]; }); cleanupRootListener(); } }; } // src/extension.ts function defineExtensionMessaging(config) { return defineGenericMessanging(__spreadProps(__spreadValues({}, config), { sendMessage(message, arg) { if (arg == null) { return import_webextension_polyfill.default.runtime.sendMessage(message); } const options = typeof arg === "number" ? { tabId: arg } : arg; return import_webextension_polyfill.default.tabs.sendMessage( options.tabId, message, // Pass frameId if specified options.frameId != null ? { frameId: options.frameId } : void 0 ); }, addRootListener(processMessage) { const listener = (message, sender) => { if (typeof message === "object") return processMessage(__spreadProps(__spreadValues({}, message), { sender })); else return processMessage(message); }; import_webextension_polyfill.default.runtime.onMessage.addListener(listener); return () => import_webextension_polyfill.default.runtime.onMessage.removeListener(listener); } })); } return __toCommonJS(src_exports); })();