Source: server/util/createStoreInstance.js

/* global WP_DEFINE_DEVELOPMENT */
import { createStore, applyMiddleware, compose } from 'redux';
import getStoredState from 'redux-persist/lib/getStoredState';
import thunk from 'redux-thunk';
import { routerMiddleware } from 'react-router-redux';
import promisify from 'es6-promisify';
import checkFSA from '../../app/util/checkFSAMiddleware';
import { asyncAction } from '../../app/util/asyncActionMiddleware';
import enhancedReduxFormMiddleware from '../../app/enhanced-redux-form/enhancedReduxFormMiddleware';
import { getClient } from '../../app/util/raven/raven-client';
import createRavenMiddleware from '../../app/util/raven/middleware';
import seoMiddleware from '../../app/util/seoMiddleware';
import reduxConfig from '../../app/config/redux.configdefinitions';
import * as reduxPersistTransformFilters from '../../app/config/reduxPersistTransformFilters';
import { KEY_PREFIX } from '../../app/data/persistCookieSettings';
import ReduxPersistServerCookieStorage from './ReduxPersistServerCookieStorage';

const getStoredStatePromisified = promisify(getStoredState);

const middleware = [
  createRavenMiddleware(getClient),
  asyncAction,
  thunk,
  enhancedReduxFormMiddleware,
  seoMiddleware,
];
if (WP_DEFINE_DEVELOPMENT) {
  middleware.push(checkFSA);
  // middleware.push(createLogger({
  //   timestamp: false,
  //   colors: {},
  //   stateTransformer: () => null,
  // }));
}

/**
 * Creates store instance on the server
 * @param reducer The main reducer for the store
 * @param cookies {object} Cookies object, used for redux-persist
 * @param cookies.jar {object} The req.cookies object from express
 * @param cookies.set {function} The response.setCookie function from express
 * @param cookies.clear {function} The response.clearCookie function from express
 * @param history The history instance that will be synced with react-router-redux
 * @param authentication {object} This object contains id_token and access_token set up by BE.
 * @returns {Store} A redux Store instance
 */
async function createStoreInstance(reducer, cookies, history, authentication) {
  const additionalEnhancers = [];
  let initialState = {};

  if (reduxConfig.persistKeys.length) {
    const userId = authentication?.userId;
    const userIdString = userId ? `${userId}.` : '';
    const keyPrefix = `${KEY_PREFIX}${userIdString}`;

    const persistConfig = {
      storage: new ReduxPersistServerCookieStorage(cookies),
      transforms: reduxConfig.persistFilters.map(key => reduxPersistTransformFilters[key]),
      whitelist: reduxConfig.persistKeys,
      keyPrefix,
    };

    initialState = await getStoredStatePromisified(persistConfig);
  }

  const store = createStore(
    reducer,
    initialState,
    compose(applyMiddleware(...middleware, routerMiddleware(history)), ...additionalEnhancers),
  );

  return store;
}

export default createStoreInstance;