47 lines
1.2 KiB
JavaScript
47 lines
1.2 KiB
JavaScript
/* global promisify */
|
|
'use strict';
|
|
|
|
const API = (() => {
|
|
const preparing = chrome.runtime.getBackgroundPage ?
|
|
promisify(chrome.runtime.getBackgroundPage.bind(chrome.runtime))()
|
|
.catch(() => null) :
|
|
Promise.resolve(null);
|
|
const runtimeSendMessage = promisify(chrome.runtime.sendMessage.bind(chrome.runtime));
|
|
return new Proxy(() => {}, {
|
|
get: (target, name) =>
|
|
(...args) => invokeBG(name, args),
|
|
});
|
|
|
|
function sendMessage(msg) {
|
|
return runtimeSendMessage(msg)
|
|
.then(result => {
|
|
if (result && result.__ERROR__) {
|
|
throw new Error(result.__ERROR__);
|
|
}
|
|
return result;
|
|
});
|
|
}
|
|
|
|
function invokeBG(name, args) {
|
|
return preparing.then(BG => {
|
|
if (!BG) {
|
|
return sendMessage({
|
|
method: 'invokeAPI',
|
|
name,
|
|
args
|
|
});
|
|
}
|
|
// FIXME: why deep-copying input/output?
|
|
if (BG !== window) {
|
|
args = BG.deepCopy(args);
|
|
}
|
|
const fn = BG.API_METHODS[name];
|
|
if (!fn) {
|
|
throw new Error(`unknown API method: ${name}`);
|
|
}
|
|
return Promise.resolve(fn(...args))
|
|
.then(BG.deepCopy);
|
|
});
|
|
}
|
|
})();
|