import { find , some } from 'lodash' ; import { actions } from './actions' ; import { HostStatus , thunks as hostThunks } from '../host' ; import { CONNECT_REASON_AUTOSTART , CONNECT_REASON_AUTORETRY } from './constants' ; import { Dispatch , State } from '../types/redux' ; import { thunks } from './thunks' ; const getStatus = ( state , id ) : HostStatus | null => { const host = find ( state . hosts , { id } ) ; return ! host ? null : host . state . status ; } ; const getConnectReason = ( state , id ) : string | null => { const host = find ( state . hosts , { id } ) ; return ! host ? null : host . state . reason ; } ; const getAutostart = ( state , id ) : boolean | null => { const autoconnect = find ( state . autoconnects , { id } ) ; return ! autoconnect ? null : autoconnect . config . start ; } ; const getAutoretry = ( state , id ) : boolean | null => { const autoconnect = find ( state . autoconnects , { id } ) ; return ! autoconnect ? null : autoconnect . config . retry ; } ; const autoconnectExist = ( state , id ) : boolean => some ( state . autoconnects , { id } ) ; const hasActiveAutoretry = ( state , id ) : boolean => { const autoconnect = find ( state . autoconnects , { id } ) ; return ! autoconnect ? false : ( autoconnect . state . autoretryId !== null ) ; } ; const includes = < T > ( array , x ) : boolean => x === null ? false : array . includes ( x ) ; const autoStartHosts = ( prevState , state , dispatch ) => { state . autoconnects . map ( x => x . id ) . filter ( id => ! autoconnectExist ( prevState , id ) ) . filter ( id => autoconnectExist ( state , id ) ) . filter ( id => getAutostart ( state , id ) ) . forEach ( ( id ) => { dispatch ( hostThunks . hostConnect ( id , CONNECT_REASON_AUTOSTART ) ) ; } ) ; } ; const autoRetryHosts = ( prevState , state , dispatch ) => { state . autoconnects . map ( x => x . id ) . filter ( id => getAutoretry ( state , id ) ) . filter ( id => ! includes ( [ 'error' ] , getStatus ( prevState , id ) ) ) . filter ( id => includes ( [ 'error' ] , getStatus ( state , id ) ) ) . forEach ( ( id ) => { dispatch ( thunks . autoretrySpawn ( id ) ) ; } ) ; } ; const cancelAutoconnects = ( prevState , state , dispatch ) => { state . autoconnects . map ( x => x . id ) . filter ( id => getStatus ( prevState , id ) !== 'connected' ) . filter ( id => getStatus ( state , id ) === 'connected' ) . filter ( id => hasActiveAutoretry ( state , id ) ) . forEach ( ( id ) => { dispatch ( actions . autoconnectCancel ( id ) ) ; } ) ; state . autoconnects . map ( x => x . id ) . filter ( id => getStatus ( prevState , id ) !== 'connecting' ) . filter ( id => getStatus ( state , id ) === 'connecting' ) . filter ( id => getConnectReason ( state , id ) !== CONNECT_REASON_AUTOSTART && getConnectReason ( state , id ) !== CONNECT_REASON_AUTORETRY ) . filter ( id => hasActiveAutoretry ( state , id ) ) . forEach ( ( id ) => { dispatch ( actions . autoconnectCancel ( id ) ) ; } ) ; state . autoconnects . map ( x => x . id ) . filter ( id => getStatus ( prevState , id ) !== 'disconnecting' ) . filter ( id => getStatus ( state , id ) === 'disconnecting' ) . filter ( id => getConnectReason ( state , id ) !== CONNECT_REASON_AUTOSTART && getConnectReason ( state , id ) !== CONNECT_REASON_AUTORETRY ) . filter ( id => hasActiveAutoretry ( state , id ) ) . forEach ( ( id ) => { dispatch ( actions . autoconnectCancel ( id ) ) ; } ) ; } ; export const onStateChange = ( prevState , state , dispatch ) => { autoStartHosts ( prevState , state , dispatch ) ; autoRetryHosts ( prevState , state , dispatch ) ; cancelAutoconnects ( prevState , state , dispatch ) ; } ;