Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / pass / store / request / reducer.ts
blob936c31c3d6ddc4d5ec4f0ec1e4b3422685633566
1 import type { Action, Reducer } from 'redux';
3 import { objectDelete } from '@proton/pass/utils/object/delete';
4 import { partialMerge } from '@proton/pass/utils/object/merge';
5 import { getEpoch } from '@proton/pass/utils/time/epoch';
7 import { requestInvalidate, requestProgress } from './actions';
8 import type { RequestState } from './types';
9 import { isActionWithRequest } from './utils';
11 const requestReducer: Reducer<RequestState> = (state = {}, action: Action) => {
12     if (isActionWithRequest(action)) {
13         const { request } = action.meta;
14         const nextState = { ...state };
16         switch (request.status) {
17             case 'start': {
18                 nextState[request.id] = {
19                     status: 'start',
20                     progress: 0,
21                     data: request.data,
22                 };
24                 return nextState;
25             }
27             case 'progress': {
28                 const ongoing = nextState[request.id];
29                 if (ongoing?.status !== 'start') return state;
30                 nextState[request.id] = { ...ongoing, progress: request.progress };
32                 return nextState;
33             }
35             case 'failure': {
36                 return objectDelete(state, request.id);
37             }
39             case 'success': {
40                 const now = getEpoch();
41                 if (!request.maxAge) return objectDelete(state, request.id);
43                 /** If there was a `maxAge` specified, store the
44                  * resulting payload in the `data` field. This should
45                  * ideally only be used for state not being tracked in
46                  * any other reducer (HOT data) */
47                 nextState[request.id] = {
48                     status: request.status,
49                     maxAge: request.maxAge,
50                     requestedAt: now,
51                     data: (() => {
52                         if ('data' in request) return request.data;
53                         if ('payload' in action) return action.payload;
54                     })(),
55                 };
57                 return nextState;
58             }
59         }
60     }
62     if (requestProgress.match(action) && state[action.payload.requestId]?.status === 'start') {
63         return partialMerge(state, {
64             [action.payload.requestId]: { progress: action.payload.progress },
65         });
66     }
68     if (requestInvalidate.match(action)) return objectDelete(state, action.payload.requestId);
70     return state;
73 export default requestReducer;