import { Iterable, fromJS } from 'immutable';

const defaultArgs = {
  initialState: {}
};

/**
 * Create reducer
 * @description Shorthand function to create a new reducer. By default, always returns the state
 * in case it was not modified by any action.
 * @param {Object} initialState - Initial state of the reducer.
 * @param {Object} actions - Subscribed actions (format: { actionType: fn() } ).
 * @return {Function} Reducer function.
 */
export function createReducer(args = defaultArgs) {
  let { initialState, actions } = args;

  if (!actions) {
    throw Error(`Shorthand reducer should have {actions} property specified, but received: ${actions}.`);
  }

  return (state, action) => {
    /* Duplicate the state for further changes */
    let newState = state || initialState;

    /* Enforce immutable state */
    if (!Iterable.isIterable(newState)) {
      newState = fromJS(newState);
    }

    /* Iterate through each specified action */
    actions.forEach((expectedAction) => {
      const expectedType = expectedAction.type;
      const isRegExp = (expectedType instanceof RegExp);

      /* Determine if dispatched action type is expected */
      const shouldActionPass = isRegExp ? expectedType.test(action.type) : expectedType.includes(action.type);

      /* Mutate the state once dispatched action type is expected */
      if (shouldActionPass) {
        newState = expectedAction.reducer(newState, fromJS(action));
      }
    });

    /* Return a new state */
    return newState;
  };
}

import { Iterable, fromJS } from 'immutable';

const defaultArgs = {
  initialState: {}
};

/**
 * Create reducer
 * @description Shorthand function to create a new reducer. By default, always returns the state
 * in case it was not modified by any action.
 * @param {Object} initialState - Initial state of the reducer.
 * @param {Object} actions - Subscribed actions (format: { actionType: fn() } ).
 * @return {Function} Reducer function.
 */
export function createReducer(args = defaultArgs) {
  let { initialState, actions } = args;

  if (!actions) {
    throw Error(`Shorthand reducer should have {actions} property specified, but received: ${actions}.`);
  }

  return (state, action) => {
    const dispatchedType = action.type;

    /* Duplicate the state for further changes */
    let newState = state || initialState;

    /* Enforce immutable state */
    if (!Iterable.isIterable(newState)) {
      newState = fromJS(newState);
    }

    /* Iterate through each specified action */
    actions.forEach((expectedAction) => {
      const expectedType = expectedAction.type;
      const isRegExp = (expectedType instanceof RegExp);

      /* Determine if dispatched action type is expected */
      const shouldActionPass = isRegExp ? expectedType.test(dispatchedType) : expectedType.includes(dispatchedType);

      /* Mutate the state once dispatched action type is expected */
      if (shouldActionPass) {
        newState = expectedAction.reducer(newState, fromJS(action));
      }
    });

    /* Return a new state */
    return newState;
  };
}

Create reducer: Move dispatched action type into the dedicated variable
Create reducer: Move dispatched action type into the dedicated variable
