import { v4 } from 'uuid' ; type SavedEventHandlersMap = { [ K in keyof EventHandlerMap ] ? : Array < unknown > ; } ; export class EventBus { private readonly savedEventHandlersMap : SavedEventHandlersMap ; constructor ( ) { this . savedEventHandlersMap = { } ; } public addEventHandler = < Name extends EventName = EventName > ( name , handler ) : void => { let savedEventHandlers = this . savedEventHandlersMap [ name ] ; if ( ! savedEventHandlers ) { savedEventHandlers = [ ] ; } savedEventHandlers . push ( handler ) ; this . savedEventHandlersMap [ name ] = savedEventHandlers ; } ; public removeEventHandler = < Name extends EventName = EventName > ( name , handler ) : void => { const savedEventHandlers = this . savedEventHandlersMap [ name ] ; if ( ! savedEventHandlers ) { return ; } this . savedEventHandlersMap [ name ] = savedEventHandlers . filter ( ( savedEventHandler ) => ( savedEventHandler !== handler ) ) ; } ; public dispatchEvent = < Name extends EventName = EventName > ( name , payload ) : string => { const eventId = payload . eventId || v4 ( ) ; const savedEventHandlers = this . savedEventHandlersMap [ name ] ; if ( ! savedEventHandlers ) { return eventId ; } savedEventHandlers . forEach ( ( element ) => { if ( typeof element !== 'function' ) { return ; } setTimeout ( ( ) => { element ( { ... payload , eventId } ) ; } , 0 ) ; } ) ; return eventId ; } ; }