import { IterableX } from '../iterablex' ; import { RefCountList } from './_refcountlist' ; import { create } from '../create' ; import { OperatorFunction } from '../../interfaces' ; class PublishedBuffer < T > extends IterableX < T > { private _buffer : RefCountList < T > ; private _source : Iterator < T > ; private _error : any ; private _stopped = false ; constructor ( source ) { super ( ) ; this . _source = source ; this . _buffer = new RefCountList < T > ( 0 ) ; } private * _getIterable ( i ) { try { while ( 1 ) { let hasValue = false ; let current = < T > { } ; if ( i >= this . _buffer . count ) { if ( ! this . _stopped ) { try { const next = this . _source . next ( ) ; hasValue = ! next . done ; if ( hasValue ) { current = next . value ; } } catch ( e ) { this . _error = e ; this . _stopped = true ; } } if ( this . _stopped ) { if ( this . _error ) { throw this . _error ; } else { break ; } } if ( hasValue ) { this . _buffer . push ( current ) ; } } else { hasValue = true ; } if ( hasValue ) { yield this . _buffer . get ( i ) ; } else { break ; } i ++ ; } } finally { this . _buffer . done ( ) ; } } [ Symbol . iterator ] ( ) { this . _buffer . readerCount ++ ; return this . _getIterable ( this . _buffer . count ) [ Symbol . iterator ] ( ) ; } } template TSource returns { OperatorFunction < TSource , TSource > } export function publish < TSource > ( ) ; template TSource template TResult param { ( value : Iterable < TSource > ) => Iterable < TResult > } selector returns { OperatorFunction < TSource , TResult > } export function publish < TSource , TResult > ( selector ? ) ; template TSource template TResult param { ( value : Iterable < TSource > ) => Iterable < TResult > } selector returns { ( OperatorFunction < TSource , TSource | TResult > ) } export function publish < TSource , TResult > ( selector ? ) { return function publishOperatorFunction ( source ) : IterableX < TSource | TResult > { return selector ? create ( ( ) => selector ( publish < TSource > ( ) ( source ) ) [ Symbol . iterator ] ( ) ) : new PublishedBuffer < TSource > ( source [ Symbol . iterator ] ( ) ) ; } ; }