import type * as d from '../../declarations' ; import { emitBuildLog , emitBuildResults , emitBuildStatus , logDisabled , logReload , logWarn } from '../client' ; export const initClientWebSocket = ( win , config ) => { let clientWs ; let reconnectTmrId ; let reconnectAttempts = 0 ; let requestBuildResultsTmrId ; let hasGottenBuildResults = false ; let buildResultsRequests = 0 ; function onOpen ( this ) { if ( reconnectAttempts > 0 ) { emitBuildStatus ( win , 'pending' ) ; } if ( ! hasGottenBuildResults ) { requestBuildResultsTmrId = setInterval ( ( ) => { buildResultsRequests ++ ; if ( ! hasGottenBuildResults && this . readyState === WebSocket . OPEN && buildResultsRequests < 500 ) { const msg = { requestBuildResults : true , } ; this . send ( JSON . stringify ( msg ) ) ; } else { clearInterval ( requestBuildResultsTmrId ) ; } } , REQUEST_BUILD_RESULTS_INTERVAL_MS ) ; } clearTimeout ( reconnectTmrId ) ; } function onError ( ) { queueReconnect ( ) ; } function onClose ( event ) { emitBuildStatus ( win , 'disabled' ) ; if ( event . code > NORMAL_CLOSURE_CODE ) { logWarn ( `Dev Server` , `web socket closed: ${ event . code } ${ event . reason }` ) ; } else { logDisabled ( `Dev Server` , `Disconnected, attempting to reconnect...` ) ; } queueReconnect ( ) ; } function onMessage ( event ) { const msg = JSON . parse ( event . data ) ; if ( reconnectAttempts > 0 ) { if ( msg . isActivelyBuilding ) { return ; } if ( msg . buildResults ) { logReload ( `Reconnected to dev server` ) ; hasGottenBuildResults = true ; buildResultsRequests = 0 ; clearInterval ( requestBuildResultsTmrId ) ; if ( win [ 's-build-id' ] !== msg . buildResults . buildId ) { win . location . reload ( true ) ; } win [ 's-build-id' ] = msg . buildResults . buildId ; return ; } } if ( msg . buildLog ) { if ( msg . buildLog . progress < 1 ) { emitBuildStatus ( win , 'pending' ) ; } emitBuildLog ( win , msg . buildLog ) ; return ; } if ( msg . buildResults ) { hasGottenBuildResults = true ; buildResultsRequests = 0 ; clearInterval ( requestBuildResultsTmrId ) ; emitBuildStatus ( win , 'default' ) ; emitBuildResults ( win , msg . buildResults ) ; return ; } } function connect ( ) { clearTimeout ( reconnectTmrId ) ; clientWs = new win . WebSocket ( config . socketUrl , [ 'xmpp' ] ) ; clientWs . addEventListener ( 'open' , onOpen ) ; clientWs . addEventListener ( 'error' , onError ) ; clientWs . addEventListener ( 'close' , onClose ) ; clientWs . addEventListener ( 'message' , onMessage ) ; } function queueReconnect ( ) { hasGottenBuildResults = false ; if ( clientWs ) { if ( clientWs . readyState === WebSocket . OPEN || clientWs . readyState === WebSocket . CONNECTING ) { clientWs . close ( NORMAL_CLOSURE_CODE ) ; } clientWs . removeEventListener ( 'open' , onOpen ) ; clientWs . removeEventListener ( 'error' , onError ) ; clientWs . removeEventListener ( 'close' , onClose ) ; clientWs . removeEventListener ( 'message' , onMessage ) ; clientWs = null ; } clearTimeout ( reconnectTmrId ) ; if ( reconnectAttempts >= RECONNECT_ATTEMPTS ) { logWarn ( `Dev Server` , `Canceling reconnect attempts` ) ; } else { reconnectAttempts ++ ; reconnectTmrId = setTimeout ( connect , RECONNECT_RETRY_MS ) ; emitBuildStatus ( win , 'disabled' ) ; } } connect ( ) ; } ; const RECONNECT_ATTEMPTS = 1000 ; const RECONNECT_RETRY_MS = 2500 ; const NORMAL_CLOSURE_CODE = 1000 ; const REQUEST_BUILD_RESULTS_INTERVAL_MS = 500 ;