136 lines
3.7 KiB
JavaScript
Raw Normal View History

2018-08-27 16:12:28 +01:00
const RunCode = require('./runCode.js');
const EmbarkJS = require('embarkjs');
2018-08-28 11:47:40 +01:00
const IpfsApi = require('ipfs-api');
const Web3 = require('web3');
2018-05-21 17:22:19 -04:00
class CodeRunner {
constructor(options) {
2018-08-28 14:43:52 +01:00
this.config = options.config;
2018-05-21 17:22:19 -04:00
this.plugins = options.plugins;
this.logger = options.logger;
this.events = options.events;
2018-08-08 13:42:45 +01:00
this.ipc = options.ipc;
this.commands = [];
2018-08-24 14:05:19 +01:00
this.runCode = new RunCode();
2018-08-29 10:49:53 +01:00
this.registerIpcEvents();
this.IpcClientListen();
this.registerEvents();
this.registerCommands();
this.registerEmbarkJs();
}
2018-05-23 11:16:56 -04:00
2018-08-29 10:49:53 +01:00
registerIpcEvents() {
if (!this.ipc.isServer()) {
return;
2018-08-08 13:42:45 +01:00
}
2018-08-29 10:49:53 +01:00
this.ipc.on('runcode:getCommands', (_err, callback) => {
let result = {web3Config: this.runCode.getWeb3Config(), commands: this.commands};
callback(null, result);
});
}
2018-08-28 12:16:36 +01:00
2018-08-29 10:49:53 +01:00
IpcClientListen() {
if (!this.ipc.isClient() || !this.ipc.connected) {
return;
2018-08-08 13:42:45 +01:00
}
2018-08-29 10:49:53 +01:00
this.ipc.listenTo('runcode:newCommand', (command) => {
if (command.varName) {
this.events.emit("runcode:register", command.varName, command.code);
} else {
this.events.request("runcode:eval", command.code);
2018-08-08 13:42:45 +01:00
}
2018-08-24 14:05:19 +01:00
});
2018-08-29 10:49:53 +01:00
}
registerEvents() {
this.events.on("runcode:register", this.registerVar.bind(this));
}
2018-08-24 14:05:19 +01:00
2018-08-29 10:49:53 +01:00
registerCommands() {
2018-08-24 14:05:19 +01:00
this.events.setCommandHandler('runcode:getContext', (cb) => {
2018-08-29 10:49:53 +01:00
cb(this.runCode.context);
2018-05-23 11:16:56 -04:00
});
2018-08-29 10:49:53 +01:00
this.events.setCommandHandler('runcode:eval', this.evalCode.bind(this));
}
2018-05-21 17:22:19 -04:00
2018-08-29 10:49:53 +01:00
registerEmbarkJs() {
2018-08-29 11:03:06 +01:00
this.registerVar('IpfsApi', IpfsApi, false);
this.registerVar('Web3', Web3, false);
this.registerVar('EmbarkJS', EmbarkJS, false);
2018-08-29 10:49:53 +01:00
if (this.ipc.connected) {
return;
}
this.events.on('code-generator-ready', () => {
this.events.request('code-generator:embarkjs:provider-code', (code) => {
2018-08-29 11:03:06 +01:00
const func = () => {};
this.evalCode(code, func, true);
this.evalCode(this.getInitProviderCode(), func, true);
2018-08-29 10:49:53 +01:00
});
});
}
2018-08-29 11:03:06 +01:00
registerVar(varName, code, toRecord = true) {
if (this.ipc.isServer() && toRecord) {
2018-08-29 10:49:53 +01:00
this.commands.push({varName, code});
this.ipc.broadcast("runcode:newCommand", {varName, code});
}
this.runCode.registerVar(varName, code);
}
evalCode(code, cb, forConsoleOnly = false) {
if (!cb) {
cb = function() {};
}
const awaitIdx = code.indexOf('await');
if (awaitIdx > -1) {
if (awaitIdx < 2) {
let end = code.length;
if (code[end - 1] === ';') {
end--; // Remove the `;` because we add function calls
2018-08-22 14:09:10 -04:00
}
2018-08-29 10:49:53 +01:00
code = code.substring(5, end); // remove await keyword
} else {
code = `(async function() {${code}})();`;
2018-08-22 11:32:15 -04:00
}
2018-08-29 10:49:53 +01:00
}
let result = this.runCode.doEval(code);
2018-08-24 14:05:19 +01:00
2018-08-29 10:49:53 +01:00
if (forConsoleOnly && this.ipc.isServer()) {
this.commands.push({code});
this.ipc.broadcast("runcode:newCommand", {code});
}
2018-08-24 14:05:19 +01:00
2018-08-29 10:49:53 +01:00
if (result instanceof Promise) {
return result.then((value) => cb(null, value)).catch(cb);
}
2018-08-24 14:05:19 +01:00
2018-08-29 10:49:53 +01:00
cb(null, result);
2018-05-21 17:22:19 -04:00
}
2018-08-08 13:42:45 +01:00
2018-08-29 10:49:53 +01:00
getInitProviderCode() {
const codeTypes = {
'communication': this.config.communicationConfig || {},
'names': this.config.namesystemConfig || {},
'storage': this.config.storageConfig || {}
};
return this.plugins.getPluginsFor('initConsoleCode').reduce((acc, plugin) => {
Object.keys(codeTypes).forEach(codeTypeName => {
(plugin.embarkjs_init_console_code[codeTypeName] || []).forEach(initCode => {
let [block, shouldInit] = initCode;
if (shouldInit.call(plugin, codeTypes[codeTypeName])) {
acc += block;
}
});
});
return acc;
}, '');
}
2018-05-21 17:22:19 -04:00
}
module.exports = CodeRunner;