Files
UT-Registration-Plus/src/lib/chrome-extension-toolkit/messaging/createMessenger.ts
Diego Perez a537d17a2f feat: inline chrome-extension-toolkit (#744)
* feat(build): inline chrome-extension-toolkit

fix: tsconfig

docs: add chrome-extension-toolkit README.md

chore: update imports

fix: stores

fix: chrome-extension-toolkit ForegroundMessenger

fix: calendarBackgroundHandler

fix: format and lint

fix: path alias

fix: add jsdom env and fix imports

Co-authored-by: Sriram Hariharan <sghsri@gmail.com>

* build: vite storybook config crx toolkit line

---------

Co-authored-by: Sriram Hariharan <sghsri@gmail.com>
Co-authored-by: Derek <derex1987@gmail.com>
2026-02-11 00:50:27 -06:00

95 lines
3.8 KiB
TypeScript

import type { Message, MessageData, MessageResponse } from '../types';
import { MessageEndpoint } from '../types';
/**
* An object that can be used to send messages to the background script.
*/ export type BackgroundMessenger<M> = {
[K in keyof M]: MessageData<M, K> extends undefined
? () => Promise<MessageResponse<M, K>>
: (data: MessageData<M, K>) => Promise<MessageResponse<M, K>>;
};
/**
* Where the foreground message is being sent to specifically (which tab or frame)
*/
type ForegroundMessageOptions =
| {
tabId: number;
frameId?: number;
}
| {
tabId: 'ALL' | 'ACTIVE_TAB';
};
/**
* an object that can be used to send messages to the foreground (tabs OR extension pages (popup, options, etc.))
*/
export type ForegroundMessenger<M> = {
[K in keyof M]: MessageData<M, K> extends undefined
? (options: ForegroundMessageOptions) => Promise<MessageResponse<M, K>>
: (data: MessageData<M, K>, options: ForegroundMessageOptions) => Promise<MessageResponse<M, K>>;
};
/**
* A wrapper for chrome extension messaging with a type-safe API.
* @type To which context the messages are sent.
* @returns A proxy object that can be used to send messages to the foreground (tabs or extension pages (popup, options, etc.))
*/
export function createMessenger<M>(destination: 'foreground'): ForegroundMessenger<M>;
/**
* A wrapper for chrome extension messaging with a type-safe API.
* @param type To which context the messages are sent.
* @returns A proxy object that can be used to send messages to the background script.
*/
export function createMessenger<M>(destination: 'background'): BackgroundMessenger<M>;
/**
* A wrapper for chrome extension messaging with a type-safe API.
* @param destination To which context the messages are sent.
* @returns A proxy object that can be used to send messages to the background script.
*/
export function createMessenger<M>(destination: 'background' | 'foreground') {
let to: MessageEndpoint = MessageEndpoint.BACKGROUND;
let from: MessageEndpoint = MessageEndpoint.FOREGROUND;
if (destination === 'foreground') {
to = MessageEndpoint.FOREGROUND;
from = MessageEndpoint.BACKGROUND;
}
const sender = new Proxy({} as any, {
get(target, prop) {
const name = prop as keyof M;
return async (data: MessageData<M, any>, options?: ForegroundMessageOptions) => {
const message: Message<M> = {
name,
data,
from,
to,
};
if (to === MessageEndpoint.FOREGROUND && options) {
// for messages sent to the tabs, we want to send to the tabs using chrome.tabs.sendMessage,
const { tabId } = options;
if (typeof tabId === 'number') {
return chrome.tabs.sendMessage(tabId, message, { frameId: options.frameId });
}
if (tabId === 'ACTIVE_TAB') {
const tab = (await chrome.tabs.query({ active: true, currentWindow: true }))[0];
if (tab && tab.id) {
return chrome.tabs.sendMessage(tab.id, message);
}
}
if (tabId === 'ALL') {
const tabs = (await chrome.tabs.query({})).filter(tab => tab.id !== undefined && tab.url);
return Promise.any([
...tabs.map(tab => chrome.tabs.sendMessage(tab.id!, message)),
chrome.runtime.sendMessage(message),
]);
}
}
return chrome.runtime.sendMessage(message);
};
},
});
return sender;
}