<commit_before>
import merge from 'deepmerge';
import {SOCKET_DISPATCH, SOCKET_RECEIVE_ACTION, SOCKET_CONNECT, SOCKET_DISCONNECT} from './constants';

const defaultOptions = {
  actions: [],
};

export default function socketMiddleware(options = defaultOptions) {
  let socket;
  options = merge(defaultOptions, options);

  // Determines wether or not an action should be emitted to the socket server.
  const shouldEmit = action => {
    return socket // We need a socket server
        && !action.emitted // If the action was emitted before, we will not emit it again.
        && options.actions.includes(action.type); // The action type needs to be included
  };

  const setupSocket = (url) => {
    socket = options.resolveSocket(url);

    socket.on(SOCKET_RECEIVE_ACTION, action => {
      store.dispatch({...action, emitted: true});
    });

    socket.on('disconnect', () => {
      store.dispatch({
        type: SOCKET_DISCONNECT,
      });
    });

    socket.on('reconnect', () => {
      store.dispatch({
        type: SOCKET_CONNECT,
      });
    });

    return socket;
  }

  return store => next => action => {
    // We first execute the action locally
    const result = next(action);

    // We want to intercept a couple of actions related to sockets.
    switch (action.type) {
      case SOCKET_CONNECT:
        if (!socket) {
          socket = setupSocket(action.url);
        }
        break;
    }

    // If the action should be emitted we do so.
    if (shouldEmit(action)) {
      socket.emit(SOCKET_DISPATCH, action);
    }

    // Return the result to the next middleware.
    return result;
  };
}<commit_msg>Move socket setup method lower so it has access to the store<commit_after>
import merge from 'deepmerge';
import {SOCKET_DISPATCH, SOCKET_RECEIVE_ACTION, SOCKET_CONNECT, SOCKET_DISCONNECT} from './constants';

const defaultOptions = {
  actions: [],
};

export default function socketMiddleware(options = defaultOptions) {
  let socket;
  options = merge(defaultOptions, options);

  // Determines wether or not an action should be emitted to the socket server.
  const shouldEmit = action => {
    return socket // We need a socket server
        && !action.emitted // If the action was emitted before, we will not emit it again.
        && options.actions.includes(action.type); // The action type needs to be included
  };

  return store => {
    const setupSocket = (url) => {
      socket = options.resolveSocket(url);

      socket.on(SOCKET_RECEIVE_ACTION, action => {
        store.dispatch({...action, emitted: true});
      });

      socket.on('disconnect', () => {
        store.dispatch({
          type: SOCKET_DISCONNECT,
        });
      });

      socket.on('reconnect', () => {
        store.dispatch({
          type: SOCKET_CONNECT,
        });
      });

      return socket;
    }

    return next => action => {
      // We first execute the action locally
      const result = next(action);

      // We want to intercept a couple of actions related to sockets.
      switch (action.type) {
        case SOCKET_CONNECT:
          if (!socket) {
            socket = setupSocket(action.url);
          }
          break;
      }

      // If the action should be emitted we do so.
      if (shouldEmit(action)) {
        socket.emit(SOCKET_DISPATCH, action);
      }

      // Return the result to the next middleware.
      return result;
    };
  }
}
{'fraction_non_alphanumeric': 0.11279953243717125, 'fraction_numerical': 0.0, 'mean_word_length': 2.4471299093655587, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '2310688', 'n_tokens_mistral': 975, 'n_tokens_neox': 969, 'n_words': 300}