import { pull } from 'lodash' ; import { IEndpoint , Msg } from '../types' ; function swap < T > ( items , index1 , index2 ) { if ( index1 === index2 ) return ; let item1 = items [ index1 ] ; let item2 = items [ index2 ] ; if ( item1 !== null ) items [ index2 ] = item1 ; if ( item2 !== null ) items [ index1 ] = item2 ; } export default class Distribution { endpoints : IEndpoint [ ] = [ ] ; matching = 0 ; active = 0 ; attach ( endpoint ) { this . endpoints . push ( endpoint ) ; swap ( this . endpoints , this . active , this . endpoints . length - 1 ) ; this . active ++ ; } match ( endpoint ) { const index = this . endpoints . indexOf ( endpoint ) ; if ( index < this . matching ) return ; if ( index >= this . active ) return ; swap ( this . endpoints , index , this . matching ) ; this . matching ++ ; } unmatch ( ) { this . matching = 0 ; } terminated ( endpoint ) { if ( this . endpoints . indexOf ( endpoint ) < this . matching ) this . matching -- ; if ( this . endpoints . indexOf ( endpoint ) < this . active ) this . active -- ; pull ( this . endpoints , endpoint ) ; } activated ( endpoint ) { swap ( this . endpoints , this . endpoints . indexOf ( endpoint ) , this . active ) ; this . active ++ ; } sendToAll ( msg ) { this . matching = this . active ; this . sendToMatching ( msg ) ; } sendToMatching ( msg ) { if ( this . matching === 0 ) return ; for ( let i = 0 ; i < this . matching ; i ++ ) { if ( ! this . write ( this . endpoints [ i ] , msg ) ) -- i ; } } write ( endpoint , msg ) { if ( ! endpoint . send ( msg ) ) { swap ( this . endpoints , this . endpoints . indexOf ( endpoint ) , this . matching - 1 ) ; this . matching -- ; swap ( this . endpoints , this . endpoints . indexOf ( endpoint ) , this . active - 1 ) ; this . active -- ; return false ; } return true ; } }