export function capitalize ( text ) { return text . split ( ' ' ) . map ( word => `${ word [ 0 ] . toUpperCase ( ) }${ word . slice ( 1 ) }` ) . join ( ' ' ) ; } export class AsyncIterator < D > { private awaitingData : D [ ] = [ ] ; private awaitingResolver ? : ( value : D ) => void ; private iteration : number = 0 ; private isDone = false ; constructor ( private maxIterations ? ) { } nextValue ( value ) { if ( this . isDone ) { return ; } if ( this . awaitingResolver ) { this . awaitingResolver ( value ) ; this . awaitingResolver = undefined ; } else { this . awaitingData . push ( value ) ; } } finish ( value ) { if ( this . awaitingResolver ) { this . awaitingResolver ( value ) ; } this . isDone = true ; } makeIterator < T > ( target ) { const self = this ; return Object . assign ( target , { [ Symbol . iterator ] ( ) { return { next : ( ) => { if ( ( self . maxIterations && self . iteration >= self . maxIterations - 1 ) || self . isDone ) { return { done : true , value : Promise . resolve ( undefined ) , } ; } else { self . iteration ++ ; } let value ; if ( self . awaitingResolver ) { throw new Error ( 'Cannot call next on iterator, if previous promise has not yet resolved' ) ; } if ( self . awaitingData . length ) { value = Promise . resolve ( self . awaitingData . shift ( ) ! ) ; } else { value = new Promise ( resolve => { self . awaitingResolver = resolve ; } ) ; } return { done : false , value , } ; } , } ; } , } ) ; } }