author Joel Hernandez <lifenautjoe@gmail.com>
  import { NoelEventConfig } from './interfaces' ; import { NoelEventListener } from './types' ; import { NoelEventListenerManager } from './event-listener-manager' ; import { NoelBufferSizeNotValidError , NoelEventConfigError , NoelEventListenerError , NoelEventReplayNotEnabled } from './errors' ; import NoelImp from './noel' ; import { NoelLogger } from './logger' ; export class NoelEvent { private noel : NoelImp ; private name : string ; private replayEnabled : boolean ; private replayBufferSize : number ; private replayBuffer : Array < any > | null = null ; private listeners : Set < NoelEventListener > | null = null ; private logger : NoelLogger ; private noListenersWarning : boolean ; constructor ( config ) { config = config || { } ; if ( typeof config . name === 'undefined' ) throw new NoelEventConfigError ( 'config.name:string is required' ) ; this . name = config . name ; if ( ! config . noel ) throw new NoelEventConfigError ( 'config.noel:Noel is required' ) ; this . noel = config . noel ; if ( config . logger ) this . setLogger ( config . logger ) ; this . replayBufferSize = config . replayBufferSize || 1 ; const noListenersWarning = typeof config . noListenersWarning === 'boolean' ? config . noListenersWarning : true ; noListenersWarning ? this . enableNoListenersWarning ( ) : this . disableNoListenersWarning ( ) ; this . replayEnabled = typeof config . replay === 'boolean' ? config . replay : false ; } enableReplay ( ) { this . replayEnabled = true ; } disableReplay ( ) { this . replayEnabled = false ; this . replayBuffer = null ; } emit ( ... eventArgs ) { const listeners = this . listeners ; if ( listeners ) { listeners . forEach ( listener => listener ( ... eventArgs ) ) ; } else if ( ! this . replayEnabled && this . noListenersWarning ) { this . logWarn ( `Event "${ this . name }" was emitted but had no listeners.` ) ; } if ( this . replayEnabled ) this . pushEventArgsToReplayBuffer ( eventArgs ) ; } on ( listener ) { if ( typeof listener !== 'function' ) throw new NoelEventListenerError ( 'Given listener is not a function' ) ; const listeners = this . getListeners ( ) ; listeners . add ( listener ) ; return new NoelEventListenerManager ( listener , this , this . noel ) ; } removeListener ( listener ) { const listeners = this . listeners ; if ( ! listeners ) return ; listeners . delete ( listener ) ; } countListeners ( ) { return this . listeners ? this . listeners . size : 0 ; } clearReplayBuffer ( ) { this . replayBuffer = null ; } removeAllListeners ( ) { this . listeners = null ; } setReplayBufferSize ( replayBufferSize ) { if ( ! this . replayEnabled ) throw new NoelEventReplayNotEnabled ( this ) ; if ( replayBufferSize <= 0 ) throw new NoelBufferSizeNotValidError ( 'Replay buffer size needs to be >=1' ) ; this . replayBufferSize = replayBufferSize ; const replayBuffer = this . replayBuffer ; if ( ! replayBuffer ) return ; this . setReplayBuffer ( replayBuffer . slice ( 0 , replayBufferSize ) ) ; } getReplayBufferAmount ( replayBufferAmount ) { if ( ! this . replayEnabled ) throw new NoelEventReplayNotEnabled ( this ) ; const replayBuffer = this . getReplayBuffer ( ) ; return typeof replayBufferAmount === 'undefined' || replayBufferAmount === replayBuffer . length ? replayBuffer : replayBuffer . slice ( 0 , replayBufferAmount ) ; } setLogger ( logger ) { this . logger = logger ; } enableNoListenersWarning ( ) { this . noListenersWarning = true ; } disableNoListenersWarning ( ) { this . noListenersWarning = false ; } getName ( ) { return this . name ; } getLogger ( ) { return this . logger ; } getReplayBufferSize ( ) { return this . replayBufferSize ; } getReplayIsEnabled ( ) { return this . replayEnabled ; } private setReplayBuffer ( replayBuffer ) { this . replayBuffer = replayBuffer ; } private getListeners ( ) { return this . listeners || ( this . listeners = new Set < NoelEventListener > ( ) ) ; } private pushEventArgsToReplayBuffer ( eventArgs ) { const replayBuffer = this . getReplayBuffer ( ) ; replayBuffer . push ( eventArgs ) ; if ( replayBuffer . length > this . replayBufferSize ) replayBuffer . shift ( ) ; } private getReplayBuffer ( ) { return this . replayBuffer || ( this . replayBuffer = [ ] ) ; } private logWarn ( warn ) { this . logger . warn ( warn ) ; } }