1 import { type Middleware, isAction } from 'redux';
3 import { selectRequest } from '@proton/pass/store/selectors';
4 import { getEpoch } from '@proton/pass/utils/time/epoch';
6 import { requestInvalidate } from './actions';
7 import type { RequestState } from './types';
8 import { isActionWithRequest } from './utils';
10 export const requestMiddleware: Middleware<{}, { request: RequestState }> =
11 ({ getState, dispatch }) =>
13 return (action: unknown) => {
14 if (isAction(action)) {
15 if (!isActionWithRequest(action)) return next(action);
17 const { request } = action.meta;
18 const { status, id } = request;
20 if ((status === 'success' && !request.maxAge) || status === 'failure') {
21 /** request data garbage collection : on a request success or failure,
22 * if it not persistent, dispatch an acknowledgment action in order to
23 * clear the request data for this particular request id.*/
24 setTimeout(() => dispatch(requestInvalidate(id)), 500);
27 if (status === 'start') {
28 if (request.revalidate) return next(action);
29 const pending = selectRequest(id)(getState());
31 switch (pending?.status) {
32 case 'start' /* if there is an ongoing `start`, omit this action */:
36 /* if there is a request result with a `maxAge` property,
37 * skip the action if not invalidated */
38 const now = getEpoch();
39 if (pending.maxAge && pending.requestedAt + pending.maxAge > now) return;
40 else return next(action);
42 default: /* if there is no pending request, process it */