stylus/content/api.js
2018-10-04 12:46:19 +08:00

56 lines
1.3 KiB
JavaScript

'use strict';
const API = (() => {
const preparing = promisify(chrome.runtime.getBackgroundPage.bind(chrome.runtime))()
.catch(() => 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.__ERROR__) {
throw new Error(result.__ERROR__);
}
return result;
});
}
function promisify(fn) {
return (...args) =>
new Promise((resolve, reject) => {
fn(...args, (...result) => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
return;
}
resolve(
result.length === 0 ? undefined :
result.length === 1 ? result[1] : 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);
}
return BG.API_METHODS[name](...args)
.then(BG.deepCopy);
});
}
})();