Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / pass / store / optimistic / selectors / select-is-failed.ts
blob61433cbdfa831dbc67ff19a4ce9ee28d96692b8f
1 import type { Selector } from '@reduxjs/toolkit';
3 import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
5 import type {
6     MaybeOptimisticStateObject,
7     OptimisticReducersMapObject,
8     StateFromOptimisticReducersMapObject,
9     WithOptimisticReducer,
10     WrappedOptimisticState,
11 } from '../types';
12 import { isOptimisticReducer, isOptimisticState } from '../utils/assertions';
13 import { getReducerMapEntries } from '../utils/combine-optimistic-reducers';
14 import getWithoutFailed from '../utils/get-without-failed';
15 import { sanitizeOptimisticReducerMapObject } from '../utils/transformers';
17 export const asIfNotFailed = <T extends {}, M extends OptimisticReducersMapObject<T>>(
18     state: T,
19     reducerMap: M
20 ): StateFromOptimisticReducersMapObject<M> => {
21     const entries = getReducerMapEntries(sanitizeOptimisticReducerMapObject(reducerMap));
23     const stateWithOptimistics = state as MaybeOptimisticStateObject;
24     const newState = {} as any;
26     for (const [name, maybeReducer] of entries) {
27         const subState = stateWithOptimistics[name];
29         if (typeof maybeReducer === 'function') {
30             if (isOptimisticState(subState) && isOptimisticReducer(maybeReducer)) {
31                 newState[name] = getWithoutFailed(subState, maybeReducer);
32             } else {
33                 newState[name] = subState;
34             }
35         } else {
36             newState[name] = asIfNotFailed(subState, maybeReducer);
37         }
38     }
40     return newState;
43 export const asIfNotFailedSubSelector =
44     <T extends {}, Optimistics extends WrappedOptimisticState<T>>(reducer: WithOptimisticReducer<T>) =>
45     (subState: Optimistics) =>
46         getWithoutFailed(subState, reducer);
48 const selectIsFailed =
49     <T extends object>(state: T) =>
50     <M extends OptimisticReducersMapObject<T>>(reducerMap: M) =>
51     (selector: Selector<StateFromOptimisticReducersMapObject<M>>): boolean => {
52         const stateWithoutFailed = selector(asIfNotFailed(state, reducerMap));
53         const stateWithOptimistic = selector(state as StateFromOptimisticReducersMapObject<M>);
55         return !isDeepEqual(stateWithOptimistic, stateWithoutFailed);
56     };
58 export default selectIsFailed;