import { Observable , Subject } from 'rxjs' ; import { first } from 'rxjs/operators' ; import { Message , MessageType } from 'src/ts/messaging/message' ; import { MessageResponse } from 'src/ts/messaging/message-response' ; import MessageSender = chrome . runtime . MessageSender ; export interface IMessageHandlerArgs < T extends Message = Message , U extends MessageResponse = undefined > { message : T ; sender : MessageSender ; response$ ? : Subject < U > ; } export interface IMessenger { onMessage$ ( messageType , sendResponse ? ) : Observable < IMessageHandlerArgs < Message , MessageResponse > > ; } export abstract class BaseMessenger implements IMessenger { public onMessage$ ( messageType , doSendResponse = false ) { const handlerArgs$ = new Subject < IMessageHandlerArgs < Message , MessageResponse > > ( ) ; if ( doSendResponse ) { const response$ = new Subject < MessageResponse > ( ) ; chrome . runtime . onMessage . addListener ( ( message , sender , sendResponse ) => { if ( message . type === messageType ) { handlerArgs$ . next ( { message , sender , response$ } ) ; response$ . pipe ( first ( ) ) . subscribe ( sendResponse ) ; return true ; } } ) ; } else { chrome . runtime . onMessage . addListener ( ( message , sender ) => { if ( message . type === messageType ) { handlerArgs$ . next ( { message , sender } ) ; } } ) ; } return handlerArgs$ . asObservable ( ) ; } }