Skip to content

Instantly share code, notes, and snippets.

@lygaret
Last active July 8, 2016 22:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lygaret/889d15d041860a2b128f846e21e36899 to your computer and use it in GitHub Desktop.
Save lygaret/889d15d041860a2b128f846e21e36899 to your computer and use it in GitHub Desktop.
Chrome Extension Helpers

dispatch helpers

createMessageDispatcher creates a message listener which will call a method on the handler argument, based on the contents of the message that's passed from elsewhere. It does this by injecting the (potentially error causing) method into a promise chain, by sticking it inside a custom thenable, which gives us much nicer error handling.

example

const handler = {
  methodA() {
    console.log("called methodA", arguments);
    return 42;
  }
}

createMessageDispatcher("handlerid", handler);

elsewhere...

dispatchExtMessage("handlerid", "methodA", 1, 2, 3).then((resp) => console.log(resp))

// in THIS context
//# { state: "resolved", value: 42 }

// in the OTHER context
//# called method A [1, 2, 3]
export function createMessageDispatcher(identity, handler) {
chrome.runtime.onMessage.addListener((msg, sender, respond) => {
if (!Array.isArray(msg)) { return; }
if (msg[0] === identity) {
var method = msg[1];
var args = msg.slice(2);
var thunk = (res) => res(handler[method].apply(handler, args));
// call the method, but do it via a thunk that's injected into a promise chain
// that way, all errors are handled the same way, and we can use the normal response methods
// this includes non-existant methods, bad arguments, etc.
Promise.resolve({ then: thunk })
.then((value) => ({ state: "resolved", value }))
.catch((error) => ({ state: "rejected", error }))
.then(respond);
return true;
}
});
}
export function dispatchTabMessage(to, method, ...args) {
return new Promise((resolve, reject) => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, [to, method, ...args], (response) => {
if (response === undefined) { return reject(chrome.runtime.lastError); }
if (response.state === "rejected") { return reject(response.error); }
if (response.state === "resolved") { return resolve(response.value); }
console.log("Weird message response:", response);
return reject("Unknown response object.");
});
});
});
}
export function dispatchExtMessage(to, method, ...args) {
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage([to, method, ...args], (response) => {
if (response === undefined) { return reject(chrome.runtime.lastError); }
if (response.state === "rejected") { return reject(response.error); }
if (response.state === "resolved") { return resolve(response.value); }
console.log("Weird message response:", response);
return reject("Unknown response object.");
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment