author Santo Pfingsten
 *  see https import { browser , Runtime } from "webextension-polyfill-ts" ; export type Callback = ( params : any , sender : Runtime . MessageSender ) => any ; type CallbacksMap = { [ s ] : Callback [ ] ; } ; let callbacksMap = null ; export interface ReceiverHandle { destroy ( ) : void ; } function getCallbacksList ( name ) { if ( callbacksMap === null ) { callbacksMap = { } ; browser . runtime . onMessage . addListener ( ( request , sender ) => { if ( callbacksMap ) { const callbacks = callbacksMap [ request . action ] ; callbacks && callbacks . forEach ( ( cb ) => cb ( request . params , sender ) ) ; } } ) ; } const callbacks = callbacksMap [ name ] ; if ( callbacks ) return callbacks ; return callbacksMap [ name ] = [ ] ; } const noop = ( ) => undefined ; export const messageUtil = { send ( name , params ? , callback ? ) { const data = { action : name , params } ; const promise = browser . runtime . sendMessage ( data ) ; if ( callback ) promise . then ( callback ) ; promise . catch ( noop ) ; } , sendSelf ( name , params ) { if ( callbacksMap ) { const callbacks = callbacksMap [ name ] ; callbacks && callbacks . forEach ( ( cb ) => cb ( params , { } ) ) ; } } , receive ( name , callback ) { const callbacks = getCallbacksList ( name ) ; callbacks . push ( callback ) ; return { destroy ( ) { const index = callbacks . indexOf ( callback ) ; if ( index !== - 1 ) callbacks . splice ( index , 1 ) ; } } ; } , clearCallbacksMap ( ) { callbacksMap = null ; } } ;