REFACTOR terminal api + build index structure for filtering

pull/1/head
serapath 7 years ago
parent 94ff629749
commit 224eb8b71b
  1. 16
      src/app/execution/txLogger.js
  2. 8
      src/app/panels/editor-panel.js
  3. 140
      src/app/panels/terminal.js

@ -16,11 +16,15 @@ class TxLogger {
constructor (opts = {}) { constructor (opts = {}) {
this.event = new EventManager() this.event = new EventManager()
this.opts = opts this.opts = opts
opts.api.editorpanel.registerLogType('knownTransaction', (data) => { this.logKnownTX = opts.api.editorpanel.registerCommand('knownTransaction', (args, cmds, append) => {
return renderKnownTransaction(this, data) var data = args[0]
var el = renderKnownTransaction(this, data)
append(el)
}) })
opts.api.editorpanel.registerLogType('unknownTransaction', (data) => { this.logUnknownTX = opts.api.editorpanel.registerCommand('unknownTransaction', (args, cmds, append) => {
return renderUnknownTransaction(this, data) var data = args[0]
var el = renderUnknownTransaction(this, data)
append(el)
}) })
opts.api.editorpanel.registerLogType('emptyBlock', (data) => { opts.api.editorpanel.registerLogType('emptyBlock', (data) => {
return renderEmptyBlock(this, data) return renderEmptyBlock(this, data)
@ -43,12 +47,12 @@ function log (self, tx, api) {
if (resolvedTransaction) { if (resolvedTransaction) {
api.parseLogs(tx, resolvedTransaction.contractName, api.compiledContracts(), (error, logs) => { api.parseLogs(tx, resolvedTransaction.contractName, api.compiledContracts(), (error, logs) => {
if (!error) { if (!error) {
api.editorpanel.log({type: 'knownTransaction', value: { tx: tx, resolvedData: resolvedTransaction, logs: logs }}) self.logKnownTX({ tx: tx, resolvedData: resolvedTransaction, logs: logs })
} }
}) })
} else { } else {
// contract unknown - just displaying raw tx. // contract unknown - just displaying raw tx.
api.editorpanel.log({ type: 'unknownTransaction', value: { tx: tx } }) self.logUnknownTX({ tx: tx })
} }
} }

@ -215,13 +215,9 @@ class EditorPanel {
self._adjustLayout('top', self.data._layout.top.offset) self._adjustLayout('top', self.data._layout.top.offset)
return self._view.el return self._view.el
} }
registerLogType (typename, template) { registerCommand (name, command) {
var self = this var self = this
self._components.terminal.registerType(typename, template) return self._components.terminal.registerCommand(name, command)
}
log () {
var self = this
self._components.terminal._output.apply(self._components.terminal, arguments)
} }
_renderTabsbar () { _renderTabsbar () {
var self = this var self = this

@ -91,17 +91,7 @@ var css = csjs`
outline : none; outline : none;
font-family : monospace; font-family : monospace;
} }
.error {
color : red;
}
.info {
color : blue;
}
.log {
color : black;
}
.dragbarHorizontal { .dragbarHorizontal {
position : absolute; position : absolute;
top : 0; top : 0;
@ -201,10 +191,23 @@ class Terminal {
console.log('select', label) console.log('select', label)
}) })
self._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null } self._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null }
self._templates = {} self._commands = {}
self.logger = {} self.commands = {}
;['log', 'info', 'error'].forEach(typename => { self._INDEX = {}
self.registerType(typename, self._blocksRenderer(typename)) self._INDEX.all = []
self._INDEX.allMain = []
self._INDEX.commands = {}
self._INDEX.commandsMain = {}
self.registerCommand('log', self._blocksRenderer('log'))
self.registerCommand('info', self._blocksRenderer('info'))
self.registerCommand('error', self._blocksRenderer('error'))
self.registerCommand('script', function execute (args, scopedCommands, append) {
var script = String(args[0])
scopedCommands.log(`> ${script}`)
self._shell(script, function (error, output) {
if (error) scopedCommands.error(error)
else scopedCommands.log(output)
})
}) })
self._jsSandboxContext = {} self._jsSandboxContext = {}
self._jsSandbox = vm.createContext(self._jsSandboxContext) self._jsSandbox = vm.createContext(self._jsSandboxContext)
@ -253,7 +256,7 @@ class Terminal {
${self._view.term} ${self._view.term}
</div> </div>
` `
self._output(self.data.banner) self.commands.log(self.data.banner)
function throttle (fn, wait) { function throttle (fn, wait) {
var time = Date.now() var time = Date.now()
@ -466,12 +469,17 @@ class Terminal {
editable.focus() editable.focus()
} }
} }
scroll2bottom () {
var self = this
setTimeout(function () {
self._view.term.scrollTop = self._view.term.scrollHeight
}, 0)
}
_blocksRenderer (mode) { _blocksRenderer (mode) {
var self = this var self = this
var modes = { log: true, info: true, error: true } mode = { log: 'black', info: 'blue', error: 'red' }[mode] // defaults
if (modes[mode]) { if (mode) {
return function render () { return function logger (args, scopedCommands, append) {
var args = [].slice.call(arguments)
var types = args.map(type) var types = args.map(type)
var values = javascriptserialize.apply(null, args).map(function (val, idx) { var values = javascriptserialize.apply(null, args).map(function (val, idx) {
if (typeof args[idx] === 'string') val = args[idx] if (typeof args[idx] === 'string') val = args[idx]
@ -480,59 +488,67 @@ class Terminal {
var lines = val.match(new RegExp(pattern, 'g')) var lines = val.match(new RegExp(pattern, 'g'))
return lines.map(str => document.createTextNode(`${str}\n`)) return lines.map(str => document.createTextNode(`${str}\n`))
}) })
return values append(yo`<span style="color: ${mode};">${values}</span>`)
} }
} else { } else {
throw new Error('mode is not supported') throw new Error('mode is not supported')
} }
} }
execute (script) { _scopeCommands (append) {
var self = this var self = this
script = String(script) var scopedCommands = {}
self._output({ type: 'log', value: `> ${script}` }) Object.keys(self.commands).forEach(function makeScopedCommand (cmd) {
self._shell(script, function (error, output) { var command = self._commands[cmd]
if (error) { scopedCommands[cmd] = function _command () {
self._output({ type: 'error', value: error }) var args = arguments
return error command(args, scopedCommands, el => append(cmd, args, el))
} else {
self._output({ type: 'log', value: output })
return output
} }
}) })
return scopedCommands
} }
registerType (typename, template) { registerCommand (name, command) {
var self = this
if (typeof template !== 'function') throw new Error('invalid template')
self._templates[typename] = template
self.logger[typename] = function () {
var args = [...arguments].map(x => ({ type: typename, value: x }))
self._output.apply(self, args)
}
}
_output () {
var self = this var self = this
var args = [...arguments] name = String(name)
self.data.session.push(args) if (self._commands[name]) throw new Error(`command "${name}" exists already`)
args.forEach(function (data) { if (typeof command !== 'function') throw new Error(`invalid command: ${command}`)
if (!data || !data.type) data = { type: 'log', value: data } self._commands[name] = command
var render = self._templates[data.type] self._INDEX.commands[name] = []
var blocks = render(data.value) self._INDEX.commandsMain[name] = []
blocks = [].concat(blocks) self.commands[name] = function _command () {
blocks.forEach(function (block) { var args = [...arguments]
var steps = []
var root = { steps, cmd: name }
var ITEM = { root, cmd: name }
root.gidx = self._INDEX.allMain.push(ITEM) - 1
root.idx = self._INDEX.commandsMain[name].push(ITEM) - 1
function append (cmd, params, el) {
var item
if (cmd) { // subcommand
item = { el, cmd, root }
} else { // command
item = ITEM
item.el = el
cmd = name
}
item.gidx = self._INDEX.all.push(item) - 1
item.idx = self._INDEX.commands[cmd].push(item) - 1
item.step = steps.push(item) - 1
item.args = params
self._view.journal.appendChild(yo` self._view.journal.appendChild(yo`
<div class="${css.block} ${css[data.type] || data.type}"> <div data-gidx=${item.gidx} class=${css.block}>${el}</div>
${block}
</div>
`) `)
self.scroll2bottom() self.scroll2bottom()
}) }
}) var scopedCommands = self._scopeCommands(append)
} command(args, scopedCommands, el => append(null, args, el))
scroll2bottom () { }
var self = this var help = typeof command.help === 'string' ? command.help : [
setTimeout(function () { `// no help available for:`,
self._view.term.scrollTop = self._view.term.scrollHeight `terminal.commands.${name}(...)`
}, 0) ].join('\n')
self.commands[name].toString = _ => { return help }
self.commands[name].help = help
return self.commands[name]
} }
_shell (script, done) { // default shell _shell (script, done) { // default shell
var self = this var self = this
@ -552,7 +568,9 @@ function domTerminalFeatures (self) {
return { return {
web3: executionContext.getProvider() !== 'vm' ? new Web3(executionContext.web3().currentProvider) : null, web3: executionContext.getProvider() !== 'vm' ? new Web3(executionContext.web3().currentProvider) : null,
console: { console: {
log: function () { self._output.apply(self, arguments) } log: function () { self.commands.log.apply(null, arguments) },
info: function () { self.commands.info.apply(null, arguments) },
error: function () { self.commands.error.apply(null, arguments) }
} }
} }
} }

Loading…
Cancel
Save