All files / src/app/core/utils meta-reducers.ts

39.58% Statements 19/48
9.52% Branches 2/21
50% Functions 6/12
38.29% Lines 18/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96  68x 68x   68x   68x   68x 20x 64x 3x   61x       68x       54x 54x 811x 46x   765x                                                                                     68x     68x             68x                                
import { Action, ActionReducer, MetaReducer } from '@ngrx/store';
import { isEqual } from 'lodash-es';
import { identity } from 'rxjs';
 
import { logoutUserSuccess } from 'ish-core/store/customer/user';
 
import { omit } from './functions';
 
export function resetOnLogoutMeta<S>(reducer: ActionReducer<S>): ActionReducer<S> {
  return (state: S, action: Action) => {
    if (action.type === logoutUserSuccess.type) {
      return reducer(undefined, action);
    }
    return reducer(state, action);
  };
}
 
export function resetSubStatesOnActionsMeta<S extends object>(
  subStates: (keyof S)[],
  actions: Action[]
): MetaReducer<S, Action> {
  return (reducer): ActionReducer<S> =>
    (state: S, action: Action) => {
      if (actions?.some(a => a.type === action.type)) {
        return reducer(omit(state, ...subStates) as S, action);
      }
      return reducer(state, action);
    };
}
 
function saveMeta<S>(
  storage: Storage,
  baseHref: string,
  prefix: string,
  key: keyof S & string,
  lifeTimeMinutes?: number
): MetaReducer<S, Action> {
  Iif (!key?.startsWith('_')) {
    console.warn('saveMeta:', `store key ${prefix}/${key} is not excluded from universal state transfer.`);
  }
  const item = `${baseHref}-${prefix}-${key}`;
  return (reducer): ActionReducer<S> =>
    (state: S, action: Action) => {
      Iif (typeof window !== 'undefined' && action.type !== '@ngrx/store-devtools/recompute') {
        let incomingState = state;
        Iif (!incomingState?.[key]) {
          const fromStorage = storage.getItem(item);
          Iif (fromStorage) {
            const fromStorageParsed = JSON.parse(fromStorage);
            const timeoutCheck =
              lifeTimeMinutes === undefined ||
              lifeTimeMinutes * 60 * 1000 + fromStorageParsed.sync > new Date().getTime();
            if (timeoutCheck) {
              incomingState = { ...state, [key]: fromStorageParsed.data };
            } else {
              storage.setItem(item, undefined);
            }
          }
        }
        const newState = reducer(incomingState, action);
        Iif (newState?.[key] !== state?.[key] && !isEqual(newState?.[key], state?.[key])) {
          storage.setItem(item, JSON.stringify({ sync: new Date().getTime(), data: newState?.[key] }));
        }
        return newState;
      }
      return reducer(state, action);
    };
}
 
const localStorageSaveMeta = <S>(baseHref: string, prefix: string, key: keyof S & string, lifeTimeMinutes?: number) =>
  saveMeta<S>(localStorage, baseHref, prefix, key, lifeTimeMinutes);
 
const sessionStorageSaveMeta = <S>(baseHref: string, prefix: string, key: keyof S & string) =>
  saveMeta<S>(sessionStorage, baseHref, prefix, key);
 
type DataRetentionPolicyValue = 'session' | number | 'forever';
 
export type DataRetentionPolicy = Record<string, DataRetentionPolicyValue>;
 
export function dataRetentionMeta<S>(
  policy: DataRetentionPolicyValue,
  baseHref: string,
  prefix: string,
  key: keyof S & string
) {
  if (policy === 'session') {
    return sessionStorageSaveMeta<S>(baseHref, prefix, key);
  } else if (policy === 'forever') {
    return localStorageSaveMeta<S>(baseHref, prefix, key);
  } else if (typeof policy === 'number') {
    return localStorageSaveMeta<S>(baseHref, prefix, key, policy);
  } else {
    return identity;
  }
}