import { Listener , ListenersStore , MessengerType } from './types' ; export const isUndefined = ( val ) : val is undefined => val === undefined ; const isObject = ( val ) : boolean => typeof val === 'object' && val !== null ; function executeListenersX ( data , handlers ) { if ( isUndefined ( data ) || ! isObject ( data ) || ! data . message ) { return ; } const d = data as Message ; Object . keys ( handlers ) . forEach ( id => { const h = handlers [ id ] ; if ( isUndefined ( h ) || isUndefined ( h . listeners [ d . message ] ) ) { return ; } if ( ( isUndefined ( d . messengerName ) && isUndefined ( h . name ) ) || d . messengerName === h . name ) { h . listeners [ d . message ] . forEach ( cb => isUndefined ( d . data ) ? cb ( ) : cb ( ... d . data ) ) ; } } ) ; } function listen ( to , executeListeners ) { if ( to === MessengerType . main ) { figma . ui . onmessage = ( data ) => { executeListeners ( data ) ; } ; } else if ( to === MessengerType . iframe ) { onmessage = event => { const data = event . data . pluginMessage ; executeListeners ( data ) ; } ; } } interface Message { messengerName : string | undefined ; message : string ; data : any [ ] ; } function send ( from , messengerName , message , data ) { const msg = { message , messengerName , data } ; if ( from === MessengerType . main ) { figma . ui . postMessage ( msg ) ; } else if ( from === MessengerType . iframe ) { parent . postMessage ( { pluginMessage : msg } , '*' ) ; } } export function createGlobalMessenger ( type ) { const listenersStore = { } ; const messageHandler = ( data ) => { executeListenersX ( data , listenersStore ) ; } ; listen ( type , messageHandler ) ; return { sendMessage ( messengerName , message , data ) { send ( type , messengerName , message , data ) ; } , addMessengerInstanceToStore ( id , name ? ) { if ( isUndefined ( listenersStore [ id ] ) ) { listenersStore [ id ] = { name , listeners : { } } ; } } , addListener ( id , message , cb ) { const l = listenersStore [ id ] ; if ( isUndefined ( l ) ) { throw Error ( 'Messenger instance not found in listeners store. Call addMessengerInstanceToStore first.' ) ; } if ( isUndefined ( l . listeners [ message ] ) ) { l . listeners [ message ] = [ ] ; } l . listeners [ message ] . push ( cb ) ; } , removeListener ( id , message , cb ? ) { const l = listenersStore [ id ] ; if ( isUndefined ( l ) ) { throw Error ( 'Messenger instance not found in listeners store. Call addMessengerInstanceToStore first.' ) ; } if ( isUndefined ( l . listeners [ message ] ) ) { return ; } if ( ! ! cb ) { l . listeners [ message ] = l . listeners [ message ] . filter ( x => x !== cb ) ; } else { delete l . listeners [ message ] ; } } } ; }