import { defer } from './utils' ; export interface IConsole { log ( msg ) : void ; error ( msg ) : void ; } export interface ConsoleFactory { create ( ) : IConsole ; done ( c ) : void ; } class SerializedConsoleImpl implements IConsole { private _activeOutput = false ; private _outputBuffer : { type : 'stderr' | 'stdout' ; line : string ; } [ ] = [ ] ; public finished = defer < void > ( ) ; constructor ( private _console ) { } activeOutput ( ) { this . _activeOutput = true ; this . _outputBuffer . forEach ( line => { if ( line . type === 'stdout' ) this . _console . log ( line . line ) ; else this . _console . error ( line . line ) ; } ) ; this . _outputBuffer = [ ] ; } log ( msg ) { if ( this . _activeOutput ) this . _console . log ( msg ) ; else this . _outputBuffer . push ( { type : 'stdout' , line : msg } ) ; } error ( msg ) { if ( this . _activeOutput ) this . _console . error ( msg ) ; else this . _outputBuffer . push ( { type : 'stderr' , line : msg } ) ; } } export class SerializedConsole implements ConsoleFactory { private _active : SerializedConsoleImpl | undefined ; private _list : SerializedConsoleImpl [ ] = [ ] ; constructor ( private _console ) { } private _start ( c ) { this . _active = c ; this . _active . activeOutput ( ) ; this . _active . finished . promise . then ( ( ) => { this . _active = undefined ; let next = this . _list . shift ( ) ; if ( next ) { this . _start ( next ) ; } } ) ; } create ( ) { let c = new SerializedConsoleImpl ( this . _console ) ; if ( ! this . _active ) { this . _start ( c ) ; } else { this . _list . push ( c ) ; } return c ; } done ( c ) { ; ( c as SerializedConsoleImpl ) . finished . resolve ( ) ; } } export class DefaultConsole implements ConsoleFactory { create ( ) { return console ; } done ( c ) { } }