webext-typed-messages
Version:
Better WebExtension sendMessage API
84 lines (83 loc) • 2.55 kB
JavaScript
/**
* Sends a runtime message to your registered handlers.
*
* Call {@link addRuntimeMessageListener} to register your handlers.
*
* @see {@link chrome.runtime.sendMessage}
*/
export function sendRuntimeMessage(type, ...params) {
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage({ type, params }, (response) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError.message));
}
else {
resolve(response);
}
});
});
}
/**
* Sends a message to the content script in the specified tab.
*
* The content script should call {@link addTabMessageListener} to receive the message.
*
* @see {@link chrome.tabs.sendMessage}
*/
export function sendTabMessage(tabId, type, ...params) {
return new Promise((resolve, reject) => {
chrome.tabs.sendMessage(tabId, { type, params }, (response) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError.message));
}
else {
resolve(response);
}
});
});
}
/**
* Registers listeners for runtime messages.
*
* Should be called in the background script.
*
* @see {@link chrome.runtime.onMessage}
*/
export function addRuntimeMessageListener(listenerMap) {
const messageListener = getMessageListener(listenerMap);
chrome.runtime.onMessage.addListener(messageListener);
return function removeMessageListener() {
chrome.runtime.onMessage.removeListener(messageListener);
};
}
/**
* Registers listeners for tab messages.
*
* Should be called in the content script.
*
* @see {@link chrome.runtime.onMessage}
*/
export function addTabMessageListener(listenerMap) {
const messageListener = getMessageListener(listenerMap);
chrome.runtime.onMessage.addListener(messageListener);
return function removeMessageListener() {
chrome.runtime.onMessage.removeListener(messageListener);
};
}
function getMessageListener(listenerMap) {
return function messageListener(message, sender, sendResponse) {
handleMessage(listenerMap, message, sendResponse);
return true;
};
}
async function handleMessage(listenerMap, message, sendResponse) {
const listener = listenerMap[message.type];
try {
const result = await listener?.(...message.params);
sendResponse(result);
}
catch (error) {
sendResponse(undefined);
throw error;
}
}