import { Injectable } from '@angular/core' ; import { Message , MessageFactory , MessageHandler , MessageResponse , MessageType , Subscription , deserializeMessage , testResponse , } from '../../communication' ; const subscriptions = new Set < MessageHandler > ( ) ; let connection ; const post = < T > ( message ) => connection . postMessage ( Object . assign ( { } , message , { tabId : chrome . devtools . inspectedWindow . tabId , } ) ) ; export const reconnect = ( ) : Promise < Response > => { if ( connection ) { return Promise . resolve ( void 0 ) ; } let interval ; const connect = ( resolver ) => { try { connection = chrome . runtime . connect ( ) ; clearInterval ( interval ) ; connection . onMessage . addListener ( ( message , port ) => { deserializeMessage ( message ) ; if ( message . messageType === MessageType . Response ) { const cannotRespond = ( ) => { throw new Error ( 'You cannot respond to a response' ) ; } ; subscriptions . forEach ( handler => handler ( message , cannotRespond ) ) ; } else { let responded = false ; const sendResponse = ( messageResponse ) => { post ( messageResponse ) ; } ; subscriptions . forEach ( handler => { const respond = ( response ) => { sendResponse ( response ) ; responded = true ; } ; handler ( message , respond ) ; } ) ; if ( responded === false ) { sendResponse ( MessageFactory . response ( message , { processed : false } , false ) ) ; } } } ) ; connection . onDisconnect . addListener ( ( ) => connection = null ) ; resolver ( ) ; } catch ( e ) { } } ; return new Promise < Response > ( resolve => { try { connect ( resolve ) ; return ; } catch ( e ) { } interval = setInterval ( ( ) => connect ( resolve ) , 250 ) ; } ) ; } ; export const subscribe = ( handler ) : Subscription => { subscriptions . add ( handler ) ; return { unsubscribe : ( ) => subscriptions . delete ( handler ) } ; } ; export const send = < Response , T > ( message ) : Promise < Response > => { if ( connection == null ) { throw new Error ( 'No connection to send messsage through!' ) ; } return new Promise ( ( resolve , reject ) => { const responseHandler = ( response ) => { if ( testResponse ( message , response ) ) { connection . onMessage . removeListener ( < any > responseHandler ) ; if ( response . error ) { reject ( response . error ) ; } else { resolve ( response . content ) ; } } } ; connection . onMessage . addListener ( responseHandler ) ; post ( message ) ; } ) ; } ; @ Injectable ( ) export class Connection { reconnect ( ) { if ( connection == null ) { return reconnect ( ) ; } return Promise . resolve ( void 0 ) ; } subscribe ( handler ) { return subscribe ( handler ) ; } send < Response , T > ( message ) { return reconnect ( ) . then ( ( ) => < Promise < Response > > send ( message ) ) ; } close ( ) { subscriptions . clear ( ) ; } }