import { isString , isInstanceOf } from './util' ; interface Listeners { [ key ] : Function [ ] ; } private function param { string } name param { Function } listener param { Listeners } listeners function _addEventListener ( name , listener , listeners ) { listeners [ name ] = listeners [ name ] || [ ] ; listeners [ name ] . push ( listener ) ; } private function param { string } name param { Function } listener param { Listeners } listeners function _removeEventListener ( name , listener , listeners ) { if ( listeners && listeners [ name ] ) { const index = listeners [ name ] . indexOf ( listener ) ; if ( index !== - 1 ) { listeners [ name ] . splice ( index , 1 ) ; } } } class param { string } name param { any } data export class IEvent { public readonly name : string ; public target : any ; public data : any ; constructor ( name , data ) { this . data = data || null ; this . name = name ; } } class extends IEvent param { Error } error param { any } data export class IErrorEvent extends IEvent { public readonly error : Error ; constructor ( error , data ? ) { super ( 'error' , { error , data } ) ; this . error = error ; } } class export class IEventEmitter { private readonly property default private readonly _listeners : Listeners = { } ; public method param { string } name param { Function } listener return public on ( name , listener ) { _addEventListener ( name , listener , this . _listeners ) ; return this ; } public method param { string } name param { Function } listener return public off ( name , listener ) { _removeEventListener ( name , listener , this . _listeners ) ; return this ; } public method param { string | IEvent } event return public fire ( event , data ? ) { if ( isInstanceOf ( event , IErrorEvent ) ) { console . error ( ( event as IErrorEvent ) . error ) ; return this ; } const ev = isString ( event ) ? new IEvent ( < string > event , data || { } ) : < IEvent > event ; const name = ev . name ; if ( this . _listens ( name ) ) { ev . target = this ; const handlers = this . _listeners [ name ] ? [ ... this . _listeners [ name ] ] : [ ] ; for ( const fn of handlers ) { fn . call ( this , ev ) ; } } return this ; } private method param { string } name return private _listens ( name ) { return this . _listeners [ name ] && this . _listeners [ name ] . length > 0 ; } } const iEventEmitter = new IEventEmitter ( ) ; export function addEventListener ( event , callback ) { iEventEmitter . on ( event , callback ) ; } export function activateEvent ( event , data = { } ) { iEventEmitter . fire ( event , data ) ; } export function removeEventListener ( event , callback ) { iEventEmitter . off ( event , callback ) ; } export const EVENTS = { LOGIN_STATE_CHANGED : 'loginStateChanged' , LOGIN_STATE_EXPIRED : 'loginStateExpire' , LOGIN_TYPE_CHANGED : 'loginTypeChanged' , ANONYMOUS_CONVERTED : 'anonymousConverted' , ACCESS_TOKEN_REFRESHD : 'refreshAccessToken' } ;