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

77.08% Statements 37/48
64.28% Branches 18/28
91.66% Functions 11/12
76.59% Lines 36/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  74x 74x   74x   74x   74x 20x 67x 3x   64x       74x       99x 99x 1770x 3x   1767x                     2x     2x 2x 2x 11x 11x 11x 2x 2x                       11x 11x 5x   11x           74x 2x   74x             74x           2x   2x   2x 2x          
import { Action, ActionReducer, MetaReducer } from '@ngrx/store';
import { isEqual } from 'lodash-es';
import { identity } from 'rxjs';
 
import { resetUserData } 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 === resetUserData.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 ssr state transfer.`);
  }
  const item = `${baseHref}-${prefix}-${key}`;
  return (reducer): ActionReducer<S> =>
    (state: S, action: Action) => {
      Eif (typeof window !== 'undefined' && action.type !== '@ngrx/store-devtools/recompute') {
        let incomingState = state;
        if (!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);
        if (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 = 'forever' | 'session' | number;
 
export type DataRetentionPolicy = Record<string, DataRetentionPolicyValue>;
 
export function dataRetentionMeta<S>(
  policy: DataRetentionPolicyValue,
  baseHref: string,
  prefix: string,
  key: keyof S & string
) {
  Iif (policy === 'session') {
    return sessionStorageSaveMeta<S>(baseHref, prefix, key);
  } else Iif (policy === 'forever') {
    return localStorageSaveMeta<S>(baseHref, prefix, key);
  } else if (typeof policy === 'number') {
    return localStorageSaveMeta<S>(baseHref, prefix, key, policy);
  } else E{
    return identity;
  }
}