<commit_before>import {
  success,
  error,
  abort,
  isSuccessAction,
  isResponseAction,
  getRequestActionFromResponse,
} from '../actions';
import operationsReducer from './operations-reducer';
import defaultConfig from './default-config';

// to support libraries like redux-act and redux-actions
const normalizeActionType = actionType =>
  typeof actionType === 'function' ? actionType.toString() : actionType;

const operationConfigHasRequestKey = config =>
  typeof config !== 'boolean' && !!config.getRequestKey;

const getInitialState = ({
  getDefaultData,
  multiple,
  operations,
  handleOperationsState,
}) => ({
  data: getDefaultData(multiple),
  pending: 0,
  error: null,
  operations:
    handleOperationsState && operations
      ? Object.entries(operations)
          .filter(o => !o.local)
          .reduce(
            (prev, [k, v]) => ({
              ...prev,
              [k]: operationConfigHasRequestKey(v)
                ? {}
                : { error: null, pending: 0 },
            }),
            {},
          )
      : null,
});

const getDataUpdaterForSuccess = (reducerConfig, operationConfig) => {
  if (operationConfig === true || operationConfig.updateData === true) {
    return reducerConfig.updateData || reducerConfig.getData;
  } else if (typeof operationConfig === 'function') {
    return operationConfig;
  } else if (
    typeof operationConfig !== 'boolean' &&
    typeof operationConfig.updateData === 'function'
  ) {
    return operationConfig.updateData;
  }

  return null;
};

const requestOperationReducer = (state, action, config) => {
  const operationConfig = config.operations[action.type];

  return {
    ...state,
    data: operationConfig.updateDataOptimistic
      ? operationConfig.updateDataOptimistic(state, action, config)
      : state.data,
  };
};

const responseOperationReducer = (state, action, config) => {
  const requestAction = getRequestActionFromResponse(action);
  const operationConfig = config.operations[requestAction.type];

  if (isSuccessAction(action)) {
    const dataUpdater = getDataUpdaterForSuccess(config, operationConfig);

    return {
      ...state,
      data: dataUpdater ? dataUpdater(state, action, config) : state.data,
    };
  }

  // error or abort case
  return {
    ...state,
    data: operationConfig.revertData
      ? operationConfig.revertData(state, action, config)
      : state.data,
  };
};

export default localConfig => {
  const config = { ...defaultConfig, ...localConfig };
  const normalizedActionType = normalizeActionType(config.actionType);
  const shouldActionBeReset =
    typeof config.resetOn === 'function'
      ? config.resetOn
      : action => config.resetOn.map(normalizeActionType).includes(action.type);<commit_msg>Optimized requests reducer by not creating shallow copies of state in some cases<commit_after>import {
  success,
  error,
  abort,
  isSuccessAction,
  isResponseAction,
  getRequestActionFromResponse,
} from '../actions';
import operationsReducer from './operations-reducer';
import defaultConfig from './default-config';

// to support libraries like redux-act and redux-actions
const normalizeActionType = actionType =>
  typeof actionType === 'function' ? actionType.toString() : actionType;

const operationConfigHasRequestKey = config =>
  typeof config !== 'boolean' && !!config.getRequestKey;

const getInitialState = ({
  getDefaultData,
  multiple,
  operations,
  handleOperationsState,
}) => ({
  data: getDefaultData(multiple),
  pending: 0,
  error: null,
  operations:
    handleOperationsState && operations
      ? Object.entries(operations)
          .filter(o => !o.local)
          .reduce(
            (prev, [k, v]) => ({
              ...prev,
              [k]: operationConfigHasRequestKey(v)
                ? {}
                : { error: null, pending: 0 },
            }),
            {},
          )
      : null,
});

const getDataUpdaterForSuccess = (reducerConfig, operationConfig) => {
  if (operationConfig === true || operationConfig.updateData === true) {
    return reducerConfig.updateData || reducerConfig.getData;
  } else if (typeof operationConfig === 'function') {
    return operationConfig;
  } else if (
    typeof operationConfig !== 'boolean' &&
    typeof operationConfig.updateData === 'function'
  ) {
    return operationConfig.updateData;
  }

  return null;
};

const requestOperationReducer = (state, action, config) => {
  const operationConfig = config.operations[action.type];

  if (operationConfig.updateDataOptimistic) {
    return {
      ...state,
      data: operationConfig.updateDataOptimistic(state, action, config),
    };
  }

  return state;
};

const responseOperationReducer = (state, action, config) => {
  const requestAction = getRequestActionFromResponse(action);
  const operationConfig = config.operations[requestAction.type];

  if (isSuccessAction(action)) {
    const dataUpdater = getDataUpdaterForSuccess(config, operationConfig);

    return dataUpdater
      ? {
          ...state,
          data: dataUpdater ? dataUpdater(state, action, config) : state.data,
        }
      : state;
  }

  // error or abort case
  return operationConfig.revertData
    ? {
        ...state,
        data: operationConfig.revertData(state, action, config),
      }
    : state;
};

export default localConfig => {
  const config = { ...defaultConfig, ...localConfig };
  const normalizedActionType = normalizeActionType(config.actionType);
  const shouldActionBeReset =
    typeof config.resetOn === 'function'
      ? config.resetOn
      : action => config.resetOn.map(normalizeActionType).includes(action.type);
{'fraction_non_alphanumeric': 0.11984422021596743, 'fraction_numerical': 0.0007080899274207824, 'mean_word_length': 3.2038690476190474, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4891394', 'n_tokens_mistral': 1570, 'n_tokens_neox': 1559, 'n_words': 357}