import { Message , MessageResponse , Subscription , checkSource , deserializeMessage } from './message' ; import { MessageFactory } from './message-factory' ; import { MessageType } from './message-type' ; import { deserialize , serialize } from '../utils/serialize' ; export interface DispatchHandler { < T , Response > ( message ) : Response ; } const subscriptions = new Set < DispatchHandler > ( ) ; const dispatchers = new Set < DispatchHandler > ( ) ; export const browserSubscribeDispatch = ( handler ) : Subscription => { dispatchers . add ( handler ) ; return { unsubscribe : ( ) => dispatchers . delete ( handler ) } ; } ; export const browserSubscribe = ( handler ) : Subscription => { subscriptions . add ( handler ) ; return { unsubscribe : ( ) => subscriptions . delete ( handler ) } ; } ; export const browserSubscribeOnce = ( messageType , handler ) => { const messageHandler = < T > ( message ) => { if ( message . messageType === messageType ) { try { deserializeMessage ( message ) ; return handler ( message ) ; } finally { subscription . unsubscribe ( ) ; } } } ; const subscription = browserSubscribe ( < DispatchHandler > messageHandler ) ; } ; export const browserSubscribeResponse = ( messageId , handler ) => { const messageHandler = < T > ( response ) => { if ( response . messageType === MessageType . Response && response . messageResponseId === messageId ) { try { deserializeMessage ( response ) ; return handler ( response ) ; } finally { subscription . unsubscribe ( ) ; } } } ; const subscription = browserSubscribe ( < DispatchHandler > messageHandler ) ; } ; export const browserUnsubscribe = ( handler ) => subscriptions . delete ( handler ) ; export const messageJumpContext = < T > ( message ) => { try { window . postMessage ( message , '*' ) ; } catch ( e ) { const msg = JSON . parse ( JSON . stringify ( message ) ) ; window . postMessage ( msg , '*' ) ; } } ; export const browserDispatch = < T > ( message ) => { if ( checkSource ( message ) === false ) { return ; } if ( message . messageType === MessageType . DispatchWrapper ) { dispatchers . forEach ( handler => handler ( message ) ) ; } else if ( message . messageType !== MessageType . Response ) { let dispatchResult ; subscriptions . forEach ( handler => { if ( dispatchResult == null ) { dispatchResult = handler ( message ) ; } else { handler ( message ) ; } } ) ; if ( dispatchResult !== undefined ) { const response = MessageFactory . dispatchWrapper ( MessageFactory . response ( message , dispatchResult , false ) ) ; messageJumpContext ( response ) ; } } else { subscriptions . forEach ( handler => handler ( message ) ) ; } } ; window . addEventListener ( 'message' , ( event ) => { if ( event . source === window ) { browserDispatch ( event . data ) ; } } , false ) ;