import { EventEmitter2 } from 'eventemitter2' ; import logger from './logger' ; import { ActionHandler , FilterHandler , HookContext , InitHandler } from './types' ; export class Emitter { private filterEmitter ; private actionEmitter ; private initEmitter ; constructor ( ) { const emitterOptions = { wildcard : true , verboseMemoryLeak : true , delimiter : '.' , ignoreErrors : true , } ; this . filterEmitter = new EventEmitter2 ( emitterOptions ) ; this . actionEmitter = new EventEmitter2 ( emitterOptions ) ; this . initEmitter = new EventEmitter2 ( emitterOptions ) ; } public async emitFilter < T > ( event , payload , meta , context ) { const events = this . eventsToEmit ( event , meta ) ; const listeners = events . flatMap ( ( event ) => this . filterEmitter . listeners ( event ) ) as FilterHandler [ ] ; let updatedPayload = payload ; for ( const listener of listeners ) { const result = await listener ( updatedPayload , meta , context ) ; if ( result !== undefined ) { updatedPayload = result ; } } return updatedPayload ; } public emitAction ( event , meta , context ) { const events = this . eventsToEmit ( event , meta ) ; for ( const event of events ) { this . actionEmitter . emitAsync ( event , meta , context ) . catch ( ( err ) => { logger . warn ( `An error was thrown while executing action "${ event }"` ) ; logger . warn ( err ) ; } ) ; } } public async emitInit ( event , meta ) { try { await this . initEmitter . emitAsync ( event , meta ) ; } catch ( err ) { logger . warn ( `An error was thrown while executing init "${ event }"` ) ; logger . warn ( err ) ; } } public onFilter ( event , handler ) { this . filterEmitter . on ( event , handler ) ; } public onAction ( event , handler ) { this . actionEmitter . on ( event , handler ) ; } public onInit ( event , handler ) { this . initEmitter . on ( event , handler ) ; } public offFilter ( event , handler ) { this . filterEmitter . off ( event , handler ) ; } public offAction ( event , handler ) { this . actionEmitter . off ( event , handler ) ; } public offInit ( event , handler ) { this . initEmitter . off ( event , handler ) ; } public offAll ( ) { this . filterEmitter . removeAllListeners ( ) ; this . actionEmitter . removeAllListeners ( ) ; this . initEmitter . removeAllListeners ( ) ; } private eventsToEmit ( event , meta ) { if ( event . startsWith ( 'items' ) ) { return [ event , `${ meta . collection }.${ event }` ] ; } return [ event ] ; } } const emitter = new Emitter ( ) ; export default emitter ;