getSliceFromStorage

mail@pastecode.io avatar
unknown
typescript
24 days ago
3.5 kB
2
Indexable
Never
import {
  TConfig,
  TDefaultServer,
  TReducers,
  TSelectors
} from '../../types/config.type';
import { decryptStorageData } from '../cryptography/decrypt-storage-data.util';
import { defaultSliceValue } from '../other/default-slice-value.util';
import { generateSliceStorageKey } from '../other/generate-slice-storage-key.util';
import { getSaltKeyFromStorage } from '../cryptography/get-salt-key-from-storage.util';
import { schemaValidation } from '../slice-schema-validation/schema-validation.util';
import { ensureExistAllRequiredKeysInStorage } from '../other/ensure-exist-all-required-keys-in-storage.util';
import { errorMessages } from '../../constants/error-messages.constant';
import { errorTemplate } from '../other/error-template.utli';
import { isAvailableCsr } from '../other/is-available-csr.util';
import { isConfigSsr } from '../other/is-config-ssr.util';

export function getSliceFromStorage<
  GSlice,
  GDefaultServer extends TDefaultServer<GSlice>,
  GSelectors extends TSelectors<GSlice>,
  GReducers extends TReducers<GSlice>
>(params: {
  config: TConfig<GSlice, GDefaultServer, GSelectors, GReducers>;
}): GSlice {
  // default slice value client
  const defaultSliceValueClient = defaultSliceValue({
    config: params.config,
    type: 'client'
  });

  // storage key
  const storageKey = generateSliceStorageKey({
    key: params.config.key
  });

  // default is `default-client value` (update after get slice value from storage)
  let returnValue = (() => {
    if (
      isConfigSsr({
        config: params.config
      })
    ) {
      return defaultSliceValue({
        config: params.config,
        type: 'server'
      });
    } else {
      // `is-config-ssr` is `false` and application is server-side ===> throw error
      if (!isAvailableCsr()) {
        errorTemplate({
          msg: errorMessages.defaultServer.required,
          key: params.config.key
        });
      }
      // `is-config-ssr` is `false` and application is client-side ===> return slice value from storage
      return getSliceFromStorage({
        config: params.config
      });
    }
  })();

  // ensure exist all required keys in storage
  if (isAvailableCsr()) {
    ensureExistAllRequiredKeysInStorage({
      config: params.config
    });
  }

  // get slice value from storageand update `returnValue`
  if (isAvailableCsr()) {
    const storageValue: string | null = localStorage.getItem(storageKey);
    if (storageValue) {
      try {
        // set storagevalue to `returnValue` (if data encrypted ? decrypt : JSON.parse)
        returnValue = (
          params.config.encrypt
            ? decryptStorageData({
                data: storageValue,
                saltKey: getSaltKeyFromStorage()
              })
            : JSON.parse(storageValue)
        ) as GSlice;
        // validate storage value with schema
        schemaValidation({
          data: returnValue,
          config: params.config
        });
      } catch (error: any) {
        // schema validation fail || JSON.parse fail || decrypt fail ===> set `defaultSliceValueClient` to `returnValue` | remove slice key from storage
        localStorage.removeItem(
          generateSliceStorageKey({
            key: params.config.key
          })
        );
        returnValue = defaultSliceValueClient;
      }
    }
  }

  return returnValue;
}
Leave a Comment