interface EmitterEvents { [ key ] : any ; } class ReadymadeEventTarget extends EventTarget { } class EventDispatcher { public target : Element ; public events : { [ key ] : CustomEvent < any > | Event ; } ; public channels : { [ key ] : BroadcastChannel ; } ; constructor ( context , channelName ? ) { this . target = context ; this . channels = { default : new BroadcastChannel ( 'default' ) } ; if ( channelName ) { this . setChannel ( channelName ) ; } this . events = { } ; } public get ( eventName ) { return this . events [ eventName ] ; } public set ( eventName , ev ) { this . events [ eventName ] = ev ; return this . get ( eventName ) ; } public emit ( ev ) { if ( typeof ev === 'string' ) { ev = this . events [ ev ] ; } this . target . dispatchEvent ( ev ) ; } public broadcast ( ev , name ? ) { if ( typeof ev === 'string' ) { ev = this . events [ ev ] ; } this . target . dispatchEvent ( ev ) ; const evt = { bubbles : ev . bubbles , cancelBubble : ev . cancelBubble , cancelable : ev . cancelable , defaultPrevented : ev . defaultPrevented , detail : ( ev as CustomEvent ) . detail , timeStamp : ev . timeStamp , type : ev . type } ; name ? this . channels [ name ] . postMessage ( evt ) : this . channels . default . postMessage ( evt ) ; } public setChannel ( name ) { this . channels [ name ] = new BroadcastChannel ( name ) ; this . channels [ name ] . onmessage = ev => { for ( const prop in ( this . target as any ) . elementMeta . eventMap ) { if ( prop . includes ( name ) && prop . includes ( ev . data . type ) ) { this . target [ ( this . target as any ) . elementMeta . eventMap [ prop ] . handler ] ( ev . data ) ; } } } ; } public removeChannel ( name ) { this . channels [ name ] . close ( ) ; delete this . channels [ name ] ; } } export { EventDispatcher , ReadymadeEventTarget } ;