import { Stream } from './Stream' ; import { Message } from './message' ; type callbackFunction = ( text : string ) => void ; export class Shell { private textDecoder = new TextDecoder ( ) ; private textEncoder = new TextEncoder ( ) ; private messageListener : ( ( message : Message ) => void ) [ ] = [ ] ; private closed = false ; constructor ( readonly stream , readonly callbackFunction ? ) { this . loopRead ( ) ; } private async loopRead ( ) { try { let message ; do { message = await this . stream . read ( ) ; if ( message . header . cmd === 'WRTE' ) { this . stream . write ( 'OKAY' ) ; const data = this . textDecoder . decode ( message . data ! ) ; if ( this . callbackFunction ) { this . callbackFunction ( data ) ; } } for ( const listener of this . messageListener ) { listener ( message ) ; } } while ( ! this . closed ) ; } catch ( e ) { console . error ( 'loopRead crashed' , e ) ; } this . stream . client . unregisterStream ( this . stream ) ; } private waitForMessage ( cmd ) { return new Promise < Message > ( resolve => { const callback = ( message ) : void => { if ( message . header . cmd === cmd ) { const pos = this . messageListener . indexOf ( callback ) ; this . messageListener . splice ( pos , 1 ) ; resolve ( message ) ; } } ; this . messageListener . push ( callback ) ; } ) ; } async write ( command ) { const data = this . textEncoder . encode ( command ) ; await this . stream . write ( 'WRTE' , new DataView ( data . buffer ) ) ; await this . waitForMessage ( 'OKAY' ) ; } async close ( ) { this . closed = true ; await this . write ( 'CLSE' ) ; } }