import { find } from 'lodash' ; import { actions } from './actions' ; import { HostStatus } from '../host' ; import { ForwardingStatus , thunks as forwardThunks } from '../forward' ; import { FORWARD_REASON_AUTOSTART , FORWARD_REASON_AUTORETRY } from './constants' ; import { Dispatch , State } from '../types/redux' ; import { thunks } from './thunks' ; const getHostStatus = ( state , id ) : HostStatus | null => { const host = find ( state . hosts , { id } ) ; return ! host ? null : host . state . status ; } ; const getForwardingStatus = ( state , id , fwdId ) : ForwardingStatus | null => { const forwarding = find ( state . forwardings , { id , fwdId } ) ; return ! forwarding ? null : forwarding . state . status ; } ; const getForwardReason = ( state , id , fwdId ) : string | null => { const forwarding = find ( state . forwardings , { id , fwdId } ) ; return ! forwarding ? null : forwarding . state . reason ; } ; const getAutostart = ( state , id , fwdId ) : boolean | null => { const autoforward = find ( state . autoforwards , { id , fwdId } ) ; return ! autoforward ? null : autoforward . config . start ; } ; const getAutoretry = ( state , id , fwdId ) : boolean | null => { const autoforward = find ( state . autoforwards , { id , fwdId } ) ; return ! autoforward ? null : autoforward . config . retry ; } ; const hasActiveAutoretry = ( state , id , fwdId ) : boolean => { const autoforward = find ( state . autoforwards , { id , fwdId } ) ; return ! autoforward ? false : ( autoforward . state . autoretryId !== null ) ; } ; const includes = < T > ( array , x ) : boolean => x === null ? false : array . includes ( x ) ; const autoStartForwardings = ( prevState , state , dispatch ) => { state . autoforwards . map ( x => ( { id : x . id , fwdId : x . fwdId } ) ) . filter ( ( { id } ) => getHostStatus ( prevState , id ) !== 'connected' ) . filter ( ( { id } ) => getHostStatus ( state , id ) === 'connected' ) . filter ( ( { id , fwdId } ) => getAutostart ( state , id , fwdId ) ) . forEach ( ( { id , fwdId } ) => { dispatch ( forwardThunks . forwardingConnect ( id , fwdId , FORWARD_REASON_AUTOSTART ) ) ; } ) ; } ; const autoRetryForwardings = ( prevState , state , dispatch ) => { state . autoforwards . map ( x => ( { id : x . id , fwdId : x . fwdId } ) ) . filter ( ( { id , fwdId } ) => getAutoretry ( state , id , fwdId ) ) . filter ( ( { id , fwdId } ) => ! includes ( [ 'error' ] , getForwardingStatus ( prevState , id , fwdId ) ) ) . filter ( ( { id , fwdId } ) => includes ( [ 'error' ] , getForwardingStatus ( state , id , fwdId ) ) ) . forEach ( ( { id , fwdId } ) => { dispatch ( thunks . autoretrySpawn ( id , fwdId ) ) ; } ) ; } ; const cancelAutoforwards = ( prevState , state , dispatch ) => { state . autoforwards . map ( x => ( { id : x . id , fwdId : x . fwdId } ) ) . filter ( ( { id , fwdId } ) => getForwardingStatus ( prevState , id , fwdId ) !== 'connected' ) . filter ( ( { id , fwdId } ) => getForwardingStatus ( state , id , fwdId ) === 'connected' ) . filter ( ( { id , fwdId } ) => hasActiveAutoretry ( state , id , fwdId ) ) . forEach ( ( { id , fwdId } ) => { dispatch ( actions . autoforwardCancel ( id , fwdId ) ) ; } ) ; state . autoforwards . map ( x => ( { id : x . id , fwdId : x . fwdId } ) ) . filter ( ( { id , fwdId } ) => getForwardingStatus ( prevState , id , fwdId ) !== 'connecting' ) . filter ( ( { id , fwdId } ) => getForwardingStatus ( state , id , fwdId ) === 'connecting' ) . filter ( ( { id , fwdId } ) => getForwardReason ( state , id , fwdId ) !== FORWARD_REASON_AUTOSTART && getForwardReason ( state , id , fwdId ) !== FORWARD_REASON_AUTORETRY ) . filter ( ( { id , fwdId } ) => hasActiveAutoretry ( state , id , fwdId ) ) . forEach ( ( { id , fwdId } ) => { dispatch ( actions . autoforwardCancel ( id , fwdId ) ) ; } ) ; state . autoforwards . map ( x => ( { id : x . id , fwdId : x . fwdId } ) ) . filter ( ( { id , fwdId } ) => getForwardingStatus ( prevState , id , fwdId ) !== 'disconnecting' ) . filter ( ( { id , fwdId } ) => getForwardingStatus ( state , id , fwdId ) === 'disconnecting' ) . filter ( ( { id , fwdId } ) => getForwardReason ( state , id , fwdId ) !== FORWARD_REASON_AUTOSTART && getForwardReason ( state , id , fwdId ) !== FORWARD_REASON_AUTORETRY ) . filter ( ( { id , fwdId } ) => hasActiveAutoretry ( state , id , fwdId ) ) . forEach ( ( { id , fwdId } ) => { dispatch ( actions . autoforwardCancel ( id , fwdId ) ) ; } ) ; } ; export const onStateChange = ( prevState , state , dispatch ) => { autoStartForwardings ( prevState , state , dispatch ) ; autoRetryForwardings ( prevState , state , dispatch ) ; cancelAutoforwards ( prevState , state , dispatch ) ; } ;