import * as Constants from './Constants' ; import { Runtime } from './Runtime' ; import { CommandInterface } from './Commands' ; class ExecuteCommand { public id : number ; public command : string ; public constructor ( id , cmd ) { this . id = id ; this . command = cmd ; } public callback ( output ) { } } ; class SingleLineOutputCommand extends ExecuteCommand { private cb : ( output : string ) => void ; public constructor ( id , cmd , cb ) { super ( id , cmd ) ; this . cb = cb ; } public callback ( output ) { this . cb ( output ) ; } } ; class MultilineOutputCommand extends ExecuteCommand { private cb : ( output : string [ ] ) => void ; public constructor ( id , cmd , cb ) { super ( id , cmd ) ; this . cb = cb ; } public callback ( output ) { this . cb ( output . split ( '\n' ) ) ; } } ; export class CommandList implements CommandInterface { private static readonly SYNC = `${ Constants . MODULE_NAME }::cl` ; private _recording = new Array < ExecuteCommand > ( ) ; private _executing = new Array < ExecuteCommand > ( ) ; private _id = 0 ; private close ( ) { this . _executing = this . _recording ; this . _recording = new Array < ExecuteCommand > ( ) ; } public process ( output ) { const lines = output . split ( CommandList . SYNC ) ; const cl = this . _executing ; const N = Math . min ( cl . length , lines . length ) ; for ( let i = 0 ; i !== N ; ++ i ) { cl [ i ] . callback ( lines [ i ] ) ; } } public constructor ( id ) { this . _id = id ; } public record ( command ) { command . id = this . _recording . length ; this . _recording . push ( command ) ; } public evaluateAsLine ( expression , callback ) { this . record ( new SingleLineOutputCommand ( 0 , expression , callback ) ) ; } public evaluate ( expression , callback ) { this . record ( new MultilineOutputCommand ( 0 , expression , callback ) ) ; } public execute ( expression ) { this . record ( new ExecuteCommand ( 0 , expression ) ) ; } public executeCommandList ( runtime , callback ) { this . close ( ) ; const cmds = this . commands ( ) ; runtime . evaluateAsLine ( cmds , ( output ) => { this . process ( output ) ; callback ( this ) ; } ) ; } public commands ( ) { let cmds = '' ; this . _executing . forEach ( cmd => cmds += `${ cmd . command }\n${ Runtime . echo ( CommandList . SYNC ) }` ) ; return cmds ; } public empty ( ) { return this . _recording . length === 0 ; } public id ( ) { return this . _id ; } }