import omit from 'lodash/omit' ; import { actionTypes } from '../actions' ; import type { Action } from '../../types' ; import type { Command , StatePipette , StateLabware , SessionModule , Mount , Slot , DoorState , SessionStatus , SessionStatusInfo , } from '../types' ; import type { InvalidProtocolFileAction } from '../../protocol/types' ; import type { SessionUpdateAction } from '../actions' ; export interface Request { inProgress : boolean ; error : { message : string ; } | null | undefined ; } export interface SessionState { sessionRequest : Request ; state : SessionStatus ; statusInfo : SessionStatusInfo ; doorState : DoorState ; blocked : boolean ; errors : Array < { timestamp : number ; line : number ; message : string ; } > ; protocolCommands : number [ ] ; protocolCommandsById : { [ id ] : Command ; } ; pipettesByMount : { [ mount in Mount ] ? : StatePipette ; } ; labwareBySlot : { [ slot in Slot ] ? : StateLabware ; } ; modulesBySlot : { [ slot in Slot ] ? : SessionModule ; } ; runRequest : Request ; pauseRequest : Request ; resumeRequest : Request ; cancelRequest : Request ; startTime : number | null | undefined ; apiLevel : [ number , number ] | null ; capabilities : string [ ] ; } const { RUN , RUN_RESPONSE , PAUSE , PAUSE_RESPONSE , RESUME , RESUME_RESPONSE , CANCEL , CANCEL_RESPONSE , } = actionTypes ; const INITIAL_STATE = { sessionRequest : { inProgress : false , error : null } , state : '' , statusInfo : { message : null , changedAt : null , estimatedDuration : null , userMessage : null , } , doorState : null , blocked : false , errors : [ ] , protocolCommands : [ ] , protocolCommandsById : { } , capabilities : [ ] , pipettesByMount : { } , labwareBySlot : { } , modulesBySlot : { } , runRequest : { inProgress : false , error : null } , pauseRequest : { inProgress : false , error : null } , resumeRequest : { inProgress : false , error : null } , cancelRequest : { inProgress : false , error : null } , startTime : null , apiLevel : null , } ; export function sessionReducer ( state = INITIAL_STATE , action ) { switch ( action . type ) { case 'robot:CONNECT_RESPONSE' : { if ( action . payload . error ) return state ; return { ... state , capabilities : action . payload . sessionCapabilities , } ; } case 'robot:DISCONNECT_RESPONSE' : return INITIAL_STATE ; case 'robot:SESSION_UPDATE' : return handleSessionUpdate ( state , action ) ; case 'protocol:UPLOAD' : return handleSessionInProgress ( { ... INITIAL_STATE , capabilities : state . capabilities , } ) ; case 'robot:REFRESH_SESSION' : return handleSessionInProgress ( state ) ; case 'robot:SESSION_RESPONSE' : case 'robot:SESSION_ERROR' : return handleSessionResponse ( state , action ) ; case 'protocol:INVALID_FILE' : return handleInvalidFile ( { ... INITIAL_STATE , capabilities : state . capabilities , } , action ) ; case RUN : return handleRun ( state , action ) ; case RUN_RESPONSE : return handleRunResponse ( state , action ) ; case PAUSE : return handlePause ( state , action ) ; case PAUSE_RESPONSE : return handlePauseResponse ( state , action ) ; case RESUME : return handleResume ( state , action ) ; case RESUME_RESPONSE : return handleResumeResponse ( state , action ) ; case CANCEL : return handleCancel ( state , action ) ; case CANCEL_RESPONSE : return handleCancelResponse ( state , action ) ; } return state ; } function handleSessionUpdate ( state , action ) { const { payload : { state : sessionStateUpdate , startTime , lastCommand } , } = action ; let { protocolCommandsById } = state ; if ( lastCommand ) { const command = { ... protocolCommandsById [ lastCommand . id ] , ... lastCommand , } ; protocolCommandsById = { ... protocolCommandsById , [ lastCommand . id ] : command , } ; } const sessionState = state . state === 'stopped' && sessionStateUpdate === 'error' ? 'stopped' : sessionStateUpdate ; return { ... state , state : sessionState , statusInfo : action . payload . statusInfo , doorState : action . payload . doorState , blocked : action . payload . blocked , startTime , protocolCommandsById , } ; } function handleSessionInProgress ( state ) { return { ... state , startTime : null , sessionRequest : { inProgress : true , error : null } , } ; } function handleSessionResponse ( state , action ) { const { payload } = action ; if ( payload . error ) { return { ... state , sessionRequest : { inProgress : false , error : payload . error } , } ; } const session = omit ( payload , [ 'name' , 'protocolText' ] ) ; return { ... state , sessionRequest : { inProgress : false , error : null } , ... session , } ; } function handleInvalidFile ( state , action ) { return { ... state , sessionRequest : { inProgress : false , error : { message : action . payload . message } , } , } ; } function handleRun ( state , action ) { return { ... state , runRequest : { inProgress : true , error : null } } ; } function handleRunResponse ( state , action ) { const { error , payload } = action ; if ( error ) { return { ... state , runRequest : { inProgress : false , error : payload } } ; } return { ... state , runRequest : { inProgress : false , error : null } } ; } function handlePause ( state , action ) { return { ... state , pauseRequest : { inProgress : true , error : null } } ; } function handlePauseResponse ( state , action ) { const { error , payload } = action ; if ( error ) { return { ... state , pauseRequest : { inProgress : false , error : payload } } ; } return { ... state , pauseRequest : { inProgress : false , error : null } } ; } function handleResume ( state , action ) { return { ... state , resumeRequest : { inProgress : true , error : null } } ; } function handleResumeResponse ( state , action ) { const { error , payload } = action ; if ( error ) { return { ... state , resumeRequest : { inProgress : false , error : payload } } ; } return { ... state , resumeRequest : { inProgress : false , error : null } } ; } function handleCancel ( state , action ) { return { ... state , cancelRequest : { inProgress : true , error : null } } ; } function handleCancelResponse ( state , action ) { const { error , payload } = action ; if ( error ) { return { ... state , cancelRequest : { inProgress : false , error : payload } } ; } return { ... state , cancelRequest : { inProgress : false , error : null } } ; }