export interface Subscription { unsubscribe ( ) : void ; } export interface Callback < Type > { ( type , param ? ) : void ; } function compactArray ( array ) { let n = 0 ; for ( let i = 0 ; i < array . length ; ++ i ) { if ( array [ i ] != null ) array [ n ++ ] = array [ i ] ; } array . length = n ; } export class Subject < Type > { private subscribers = new Array < Callback < Type > | null > ( ) ; private anyRemoved = false ; private nestCount = 0 ; public subscribe ( callback ) { this . subscribers . push ( callback ) ; return { unsubscribe : ( ) => { const i = this . subscribers . indexOf ( callback ) ; if ( i !== - 1 ) { this . subscribers [ i ] = null ; this . anyRemoved = true ; } } , } ; } protected next ( type , param ? ) { ++ this . nestCount ; for ( const s of this . subscribers ) if ( s != null ) s ( type , param ) ; -- this . nestCount ; if ( this . nestCount === 0 && this . anyRemoved ) { compactArray ( this . subscribers ) ; this . anyRemoved = false ; } } }