import { ofType } from 'redux-observable' ; import { filter , map , switchMap , ignoreElements } from 'rxjs/operators' ; import { parseISO , differenceInSeconds } from 'date-fns' ; import { GET , PUT , fetchRobotApi } from '../../robot-api' ; import { withRobotHost } from '../../robot-api/operators' ; import * as Constants from '../constants' ; import type { Action , Epic } from '../../types' ; import type { RobotApiRequestOptions } from '../../robot-api/types' ; import type { ConnectAction , LegacyConnectAction } from '../../robot/actions' ; const SYNC_THRESHOLD_SEC = 60 ; const mapActionToFetchRequest = ( action ) : RobotApiRequestOptions => { return { method : GET , path : Constants . SYSTEM_TIME_PATH } ; } ; const createUpdateRequest = ( date ) : RobotApiRequestOptions => { return { method : PUT , path : Constants . SYSTEM_TIME_PATH , body : { data : { systemTime : date . toISOString ( ) , } , } , } ; } ; export const syncTimeOnConnectEpic = ( action$ , state$ ) => { return action$ . pipe ( ofType < Action , LegacyConnectAction | ConnectAction > ( 'robot:LEGACY_CONNECT' , 'robot:CONNECT' ) , withRobotHost ( state$ , action => action . payload . name ) , switchMap ( ( [ action , state , robot ] ) => { const fetchSystemTimeReq = mapActionToFetchRequest ( action ) ; return fetchRobotApi ( robot , fetchSystemTimeReq ) . pipe ( filter ( response => response . ok ) , map ( response => response . body . data . systemTime ) , filter ( systemTimeString => { const systemTime = parseISO ( systemTimeString ) ; const drift = differenceInSeconds ( systemTime , new Date ( ) ) ; return Math . abs ( drift ) > SYNC_THRESHOLD_SEC ; } ) , switchMap ( ( ) => { const updateSystemTimeReq = createUpdateRequest ( new Date ( ) ) ; return fetchRobotApi ( robot , updateSystemTimeReq ) ; } ) ) ; } ) , ignoreElements ( ) ) ; } ;