Skip to content

Commit

Permalink
feat(@embark/cli): repl support inside dashboard
Browse files Browse the repository at this point in the history
Closes #768
  • Loading branch information
lastmjs authored and 0x-r4bbit committed Nov 27, 2018
1 parent 1d5e33e commit cbb9c1c
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 234 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
"subdir": "0.0.3",
"swarm-api": "0.1.2",
"tar": "3.2.1",
"term.js": "0.0.7",
"toposort": "1.0.7",
"underscore": "1.9.1",
"url-loader": "1.1.2",
Expand Down
4 changes: 0 additions & 4 deletions src/cmd/dashboard/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ class Dashboard {
(ws, _req) => {
let dashboardState = {contractsState: [], environment: "", status: "", availableServices: []};

// TODO: doesn't feel quite right, should be refactored into a shared
// dashboard state
self.events.request('setDashboardState');

self.events.on('contractsState', (contracts) => {
Expand All @@ -60,8 +58,6 @@ class Dashboard {
this.events.on('status', monitor.setStatus.bind(monitor));
this.events.on('servicesState', monitor.availableServices.bind(monitor));

this.events.setCommandHandler("console:command", monitor.executeCmd.bind(monitor));

this.logger.info('========================'.bold.green);
this.logger.info((__('Welcome to Embark') + ' ' + this.version).yellow.bold);
this.logger.info('========================'.bold.green);
Expand Down
161 changes: 62 additions & 99 deletions src/cmd/dashboard/monitor.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
let blessed = require("neo-blessed");
let CommandHistory = require('./command_history.js');
const REPL = require('./repl.js');
const stream = require('stream');

class Monitor {
constructor(_options) {
let options = _options || {};
this.env = options.env;
this.console = options.console;
this.history = new CommandHistory();
this.events = options.events;

this.color = options.color || "green";
this.minimal = options.minimal || false;

Expand All @@ -23,7 +22,7 @@ class Monitor {
this.layoutLog();
this.layoutStatus();
this.layoutModules();
this.layoutCmd();
this.layoutTerminal();

this.screen.key(["C-c"], function () {
process.exit(0);
Expand All @@ -36,7 +35,29 @@ class Monitor {
this.status.setContent(this.env.green);

this.screen.render();
this.input.focus();

this.terminalReadableStream = new stream.Readable({
read() {}
});

const logText = this.logText;
const terminal = this.terminal;
const terminalWritableStream = new stream.Writable({
write(chunk, encoding, next) {
terminal.write(chunk.toString());
next();
}
});

const repl = new REPL({
events: this.events,
env: this.env,
inputStream: this.terminalReadableStream,
outputStream: terminalWritableStream,
logText: this.logText
}).start(() => {
this.terminal.focus();
});
}

availableServices(_services) {
Expand Down Expand Up @@ -89,7 +110,7 @@ class Monitor {
width: "100%",
height: "55%",
left: "0%",
top: "42%",
top: "40%",
border: {
type: "line"
},
Expand Down Expand Up @@ -127,7 +148,7 @@ class Monitor {
tags: true,
padding: 1,
width: "75%",
height: "42%",
height: "40%",
left: "0%",
top: "0",
border: {
Expand Down Expand Up @@ -209,7 +230,7 @@ class Monitor {

this.wrapper = blessed.layout({
width: "25%",
height: "42%",
height: "40%",
top: "0%",
left: "75%",
layout: "grid"
Expand Down Expand Up @@ -261,11 +282,9 @@ class Monitor {
parent: this.wrapper,
label: __("Available Services"),
tags: true,
padding: this.minimal ? {
left: 1
} : 1,
padding: 1,
width: "100%",
height: "60%",
height: "70%",
valign: "top",
border: {
type: "line"
Expand All @@ -287,97 +306,41 @@ class Monitor {
this.screen.append(this.wrapper);
}

layoutCmd() {
this.consoleBox = blessed.box({
label: __('Console'),
tags: true,
padding: 0,
width: '100%',
height: '6%',
left: '0%',
top: '95%',
border: {
type: 'line'
},
style: {
fg: 'black',
border: {
fg: this.color
layoutTerminal() {
this.terminal = blessed.terminal({
parent: this.screen,
cursor: 'block',
cursorBlink: true,
padding: 0,
width: '100%',
height: 3,
left: 0,
top: '100%-3',
border: 'line',
style: {
fg: 'default',
bg: 'default',
focus: {
border: {
fg: 'green'
}
}
},
scrollable: false,
handler: (data) => {
this.terminalReadableStream.push(data);
}
}
});
});

this.input = blessed.textbox({
parent: this.consoleBox,
name: 'input',
input: true,
keys: false,
top: 0,
left: 1,
height: '50%',
width: '100%-2',
inputOnFocus: true,
style: {
fg: 'green',
bg: 'black',
focus: {
bg: 'black',
fg: 'green'
}
}
});

let self = this;

this.input.key(["C-c"], function () {
self.events.emit('exit');
process.exit(0);
});
this.terminal.key('C-c', () => {
this.terminal.kill();
return screen.destroy();
});

this.input.key(["C-w"], function () {
self.input.clearValue();
self.input.focus();
});

this.input.key(["up"], function () {
let cmd = self.history.getPreviousCommand();
self.input.setValue(cmd);
self.input.focus();
});

this.input.key(["down"], function () {
let cmd = self.history.getNextCommand();
self.input.setValue(cmd);
self.input.focus();
});

this.input.on('submit', this.submitCmd.bind(this));

this.screen.append(this.consoleBox);
}

submitCmd(cmd) {
if (cmd !== '') {
this.history.addCommand(cmd);
this.executeCmd(cmd);
}
this.input.clearValue();
this.input.focus();
}

executeCmd(cmd, cb) {
this.logText.log('console> '.bold.green + cmd);
this.events.request('console:executeCmd', cmd, (err, result) => {
let message = err || result;
if (message) {
this.logText.log(message);
}
if (cb) {
cb(message);
}
});
this.terminal.on('click', () => {
this.terminal.focus();
});
}

}

module.exports = Monitor;
15 changes: 13 additions & 2 deletions src/cmd/dashboard/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,25 @@ class REPL {
constructor(options) {
this.events = options.events;
this.env = options.env;
this.inputStream = options.inputStream || process.stdin;
this.outputStream = options.outputStream || process.stdout;
this.logText = options.logText;
}

enhancedEval(cmd, context, filename, callback) {
this.events.request('console:executeCmd', cmd.trim(), function (err, message) {
callback(err, message || ''); // This way, we don't print undefined
callback(err, message === undefined ? '' : message); // This way, we don't print undefined
});
}

enhancedWriter(output) {
if ((typeof output) === "string") {
if (this.logText) this.logText.log(output);
return output;
} else {
const inspectedOutput = util.inspect(output, {colors: true});
if (this.logText) this.logText.log(inspectedOutput);
return inspectedOutput;
}
return util.inspect(output, {colors: true});
}
Expand All @@ -26,7 +34,10 @@ class REPL {
prompt: "Embark (" + this.env + ") > ",
useGlobal: true,
eval: this.enhancedEval.bind(this),
writer: this.enhancedWriter.bind(this)
writer: this.enhancedWriter.bind(this),
input: this.inputStream,
output: this.outputStream,
terminal: true
});

this.events.request('console:history', (err, history) => {
Expand Down
Loading

0 comments on commit cbb9c1c

Please sign in to comment.