fixing scripRunner error

pull/1342/head
davidzagi93@gmail.com 3 years ago
parent f018addf13
commit 3826e9c576
  1. 1
      .gitignore
  2. 31
      apps/remix-ide/src/app/panels/terminal.js
  3. 103
      libs/remix-ui/terminal/src/lib/actions/terminalAction.ts
  4. 120
      libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts
  5. 171
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx

1
.gitignore vendored

@ -30,6 +30,7 @@ soljson.js
*.launch
.settings/
*.sublime-workspace
.vscode/
# IDE - VSCode
.vscode/*

@ -69,26 +69,6 @@ class Terminal extends Plugin {
this._INDEX.allMain = []
this._INDEX.commands = {}
this._INDEX.commandsMain = {}
this.registerCommand('html', this._blocksRenderer('html'), { activate: true })
this.registerCommand('log', this._blocksRenderer('log'), { activate: true })
this.registerCommand('info', this._blocksRenderer('info'), { activate: true })
this.registerCommand('warn', this._blocksRenderer('warn'), { activate: true })
this.registerCommand('error', this._blocksRenderer('error'), { activate: true })
this.registerCommand('script', function execute (args, scopedCommands, append) {
var script = String(args[0])
this._shell(script, scopedCommands, function (error, output) {
if (error) scopedCommands.error(error)
else if (output) scopedCommands.log(output)
})
}, { activate: true })
function basicFilter (value, query) { try { return value.indexOf(query) !== -1 } catch (e) { return false } }
this.registerFilter('log', basicFilter)
this.registerFilter('info', basicFilter)
this.registerFilter('warn', basicFilter)
this.registerFilter('error', basicFilter)
this.registerFilter('script', basicFilter)
if (opts.shell) this._shell = opts.shell // ???
register(this)
}
@ -109,12 +89,18 @@ class Terminal extends Plugin {
this.renderComponent()
}
onDeactivation () {
this.off('scriptRunner', 'log')
this.off('scriptRunner', 'info')
this.off('scriptRunner', 'warn')
this.off('scriptRunner', 'error')
}
render () {
return this.element
}
renderComponent () {
ReactDOM.render(
<RemixUiTerminal
event = {this.event}
@ -129,6 +115,7 @@ class Terminal extends Plugin {
command = {this.commands}
version = {this.version}
config = {this.config}
thisState = {this}
/>,
this.element
)
@ -213,6 +200,8 @@ class Terminal extends Plugin {
if (self._commands[name]) throw new Error(`command "${name}" exists already`)
if (typeof command !== 'function') throw new Error(`invalid command: ${command}`)
self._commands[name] = command
console.log({ command })
console.log(self._commands)
self._INDEX.commands[name] = []
self._INDEX.commandsMain[name] = []
self.commands[name] = function _command () {

@ -0,0 +1,103 @@
export const registerCommandAction = (name, command, activate, dispatch) => {
const commands: any = {}
const _commands: any = {}
_commands[name] = command
const data: any = {
// lineLength: props.options.lineLength || 80,
session: [],
activeFilters: { commands: {}, input: '' },
filterFns: {}
}
const _INDEX = {
all: [],
allMain: [],
commands: {},
commandsMain: {}
}
const registerFilter = (commandName, filterFn) => {
data.filterFns[commandName] = filterFn
}
// const _appendItem = (item) => {
// var { el, gidx } = item
// _JOURNAL[gidx] = item
// if (!_jobs.length) {
// requestAnimationFrame(function updateTerminal () {
// _jobs.forEach(el => _view.journal.appendChild(el))
// .scroll2bottom()
// ._jobs = []
// })
// }
// if (data.activeFilters.commands[item.cmd]) _jobs.push(el)
// }
commands[name] = function () {
const args = [...arguments]
const steps = []
const root = { steps, cmd: name, gidx: 0, idx: 0 }
const ITEM = { root, cmd: name }
root.gidx = _INDEX.allMain.push(ITEM) - 1
// root.idx = _INDEX.commandsMain[name].push(ITEM) - 1
let item
function append (cmd, params, el) {
if (cmd) { // subcommand
item = { el, cmd, root }
} else { // command
item = ITEM
item.el = el
cmd = name
}
item.gidx = _INDEX.all.push(item) - 1
item.idx = _INDEX.commands[cmd].push(item) - 1
item.step = steps.push(item) - 1
item.args = params
// _appendItem(item)
console.log({ item }, 'append items')
// self._appendItem(item)
}
var scopedCommands = _scopeCommands(append)
command(args, scopedCommands, el => append(null, args, blockify(el)))
console.log({ args })
}
const help = typeof command.help === 'string' ? command.help : [
'// no help available for:', `terminal.command.${name}`
].join('\n')
commands[name].toString = () => { return help }
commands[name].help = help
data.activeFilters.commands[name] = activate && activate.activate
if (activate.filterFn) {
registerFilter(name, activate.filterFn)
}
dispatch({ type: name, payload: { commands: commands, _commands: _commands, data: data } })
const blockify = (el) => {
return `<div class="px-4 block_2A0YE0" data-id="block_null">${el}</div>`
}
const _scopeCommands = (append) => {
const scopedCommands = {}
Object.keys(commands).forEach(function makeScopedCommand (cmd) {
var command = _commands[cmd]
scopedCommands[cmd] = function _command () {
var args = [...arguments]
console.log({ cmd }, { args }, { blockify })
command(args, scopedCommands, el => append(cmd, args, blockify(el)))
}
})
console.log({ scopedCommands })
return scopedCommands
}
}
export const filterFnAction = (name, filterFn, dispatch) => {
const data: any = {
// session: [],
// activeFilters: { commands: {}, input: '' },
filterFns: {}
}
data.filterFns[name] = filterFn
dispatch({ type: name, payload: { data: data } })
}

@ -0,0 +1,120 @@
export const initialState = {
journalBlocks: {
},
data: {
// lineLength: props.options.lineLength || 80,
session: [],
activeFilters: { commands: {}, input: '' },
filterFns: {}
},
_commandHistory: [],
_commands: {},
commands: {},
_JOURNAL: [],
_jobs: [],
_INDEX: {
},
_INDEXall: [],
_INDEXallMain: [],
_INDEXcommands: {},
_INDEXcommandsMain: {}
}
export const registerCommandReducer = (state, action) => {
switch (action.type) {
case 'html' :
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, { ...action.payload.data })
}
case 'log':
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, { ...action.payload.data })
}
case 'info':
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data)
}
case 'warn':
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data)
}
case 'error':
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data)
}
case 'script':
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data)
}
default :
return { state }
}
}
export const registerFilterReducer = (state, action) => {
switch (action.type) {
case 'log':
console.log({ action }, { state }, 'register Filter')
return {
...state,
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns)
}
case 'info':
console.log({ action }, 'registerFilter')
return {
...state,
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns)
}
case 'warn':
return {
...state,
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns)
}
case 'error':
return {
...state,
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns)
}
case 'script':
return {
...state,
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns)
}
default :
return { state }
}
}
export const addCommandHistoryReducer = (state, action) => {
switch (action.type) {
case 'cmdHistory':
console.log({ action }, { state }, 'cmd history')
return {
...state,
_commandHistory: initialState._commandHistory.unshift(action.payload.script)
}
default :
return { state }
}
}

@ -1,6 +1,10 @@
import React, { useState, useEffect, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line
import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line
import { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line
import { useWindowResize } from 'beautiful-react-hooks'
import { registerCommandAction, filterFnAction } from './actions/terminalAction'
import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer } from './reducers/terminalReducer'
import javascriptserialize from 'javascript-serialize'
import jsbeautify from 'js-beautify'
import './remix-ui-terminal.css'
@ -15,10 +19,10 @@ export interface RemixUiTerminalProps {
options: any
data: any
cmdInterpreter: any
registerCommand: any
command: any
version: any
config: any
thisState: any
// blockRenderHtml: any
// blockRenderLog: any
@ -44,6 +48,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const [separatorYPosition, setSeparatorYPosition] = useState<undefined | number>(undefined)
const [dragging, setDragging] = useState(false)
const [newstate, dispatch] = useReducer(registerCommandReducer, initialState)
const [filterState, filterDispatch] = useReducer(registerFilterReducer, initialState)
const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState)
const [state, setState] = useState({
journalBlocks: {
intro: (
@ -102,16 +110,27 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const inputEl = useRef(null)
// events
useEffect(() => {
// window.addEventListener('resize', function () {
// props.event.trigger('resize', [])
// props.event.trigger('resize', [])
// })
// return () => {
// window.removeEventListener('resize', function () {
// props.event.trigger('resize', [])
// props.event.trigger('resize', [])
// })
// }
registerCommandAction('html', _blocksRenderer('html'), { activate: true }, dispatch)
registerCommandAction('log', _blocksRenderer('log'), { activate: true }, dispatch)
registerCommandAction('info', _blocksRenderer('info'), { activate: true }, dispatch)
registerCommandAction('warn', _blocksRenderer('warn'), { activate: true }, dispatch)
registerCommandAction('error', _blocksRenderer('error'), { activate: true }, dispatch)
registerCommandAction('script', function execute (args, scopedCommands, append) {
var script = String(args[0])
props.thisState._shell(script, scopedCommands, function (error, output) {
if (error) scopedCommands.error(error)
else if (output) scopedCommands.log(output)
})
}, { activate: true }, dispatch)
filterFnAction('log', basicFilter, filterDispatch)
filterFnAction('info', basicFilter, filterDispatch)
filterFnAction('warn', basicFilter, filterDispatch)
filterFnAction('error', basicFilter, filterDispatch)
filterFnAction('script', basicFilter, filterDispatch)
// console.log({ htmlresullt }, { logresult })
// dispatch({ type: 'html', payload: { commands: htmlresullt.commands } })
// dispatch({ type: 'log', payload: { _commands: logresult._commands } })
// registerCommand('log', _blocksRenderer('log'), { activate: true })
}, [])
const placeCaretAtEnd = (el) => {
@ -157,56 +176,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
}
}
// const reattached = (event) => {
// let el = event.currentTarget
// var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30
// if (isBottomed) {
// } else {
// // if (!inserted)
// }
// }
const registerCommand = (name, command, opts) => {
const { _commands, _INDEXcommands, _INDEXallMain, _INDEXcommandsMain, _INDEXall, commands } = state
// TODO if no _commands[name] throw an error
// TODO if typeof command !== 'function' throw error
_commands[name] = command
_INDEXcommands[name] = []
_INDEXallMain[name] = []
// TODO _command function goes here
commands[name] = function _command () {
const steps = []
const args = [...arguments]
const gidx = 0
const idx = 0
const step = 0
const root = { steps, cmd: name, gidx, idx }
const ITEM = { root, cmd: name, el: {} }
root.gidx = _INDEXallMain.push(ITEM) - 1
root.idx = _INDEXcommandsMain[name].push(ITEM) - 1
function append (cmd, params, el) {
let item = { el, cmd, root, gidx, idx, step, args: [...arguments] }
if (cmd) {
item = { el, cmd, root, gidx, idx, step, args }
} else {
// item = ITEM
item.el = el
cmd = name
}
item.gidx = _INDEXall.push(item) - 1
item.idx = _INDEXcommands[cmd].push(item) - 1
item.step = steps.push(item) - 1
item.args = params
_appendItem(item)
}
}
return commands[name]
}
const _appendItem = (item: any) => {
let { _JOURNAL, _jobs, data } = state
@ -259,16 +228,17 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix))
if (isKnownScript) return script
return `
try {
const ret = ${script};
if (ret instanceof Promise) {
ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) })
} else {
console.log(ret)
}
} catch (e) {
console.log(e.message)
}`
try {
const ret = ${script};
if (ret instanceof Promise) {
ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) })
} else {
console.log(ret)
}
} catch (e) {
console.log(e.message)
}
`
}
const handleKeyDown = (event) => {
@ -289,10 +259,16 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
// scroll2botton () function not implemented
props.autoCompletePopup.removeAutoComplete()
} else { // <enter>
console.log('hit enter')
setCmdIndex(-1)
setCmdTemp('')
const script = inputEl.current.innerText.trim()
console.log({ script }, ' script ')
if (script.length) {
cmdHistoryDispatch({ type: 'cmdHistory', payload: { script } })
const result = newstate.commands.script(wrapScript(script))
console.log({ result })
}
// inputEl.current.innerText += '\n'
// if (script.length) {
// // self._cmdHistory.unshift(script)
@ -417,9 +393,58 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
}
}, [leftHeight, setLeftHeight])
/* block contents that gets rendered from scriptRunner */
const _blocksRenderer = (mode) => {
if (mode === 'html') {
return function logger (args) {
console.log({ args })
if (args.length) {
return args[0]
}
}
}
mode = {
log: 'text-info',
info: 'text-info',
warn: 'text-warning',
error: 'text-danger'
}[mode] // defaults
if (mode) {
const filterUndefined = (el) => el !== undefined && el !== null
return function logger (args) {
var types = args.filter(filterUndefined).map(type => type)
var values = javascriptserialize.apply(null, args.filter(filterUndefined)).map(function (val, idx) {
if (typeof args[idx] === 'string') {
const el = document.createElement('div')
el.innerHTML = args[idx].replace(/(\r\n|\n|\r)/gm, '<br>')
val = el.children.length === 0 ? el.firstChild : el
}
if (types[idx] === 'element') val = jsbeautify.html(val)
return val
})
if (values.length) {
console.log({ values })
return `<span class="${mode}" >${values}</span>`
}
}
} else {
throw new Error('mode is not supported')
}
}
function basicFilter (value, query) { try { return value.indexOf(query) !== -1 } catch (e) { return false } }
const registerCommand = (name, command, opts) => {
// setState((prevState) => ({ ...prevState, _commands[name]: command }))
}
/* end of block content that gets rendered from script Runner */
return (
<div style={{ height: '323px' }} className='panel_2A0YE0'>
{console.log({ props })}
{console.log({ newstate })}
<div className="bar_2A0YE0">
{/* ${self._view.dragbar} */}
<div className="dragbarHorizontal" onMouseDown={mousedown}></div>

Loading…
Cancel
Save