<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import createSagaMiddleware, { takeEvery, takeLatest } from 'redux-saga';
import { hashHistory, Router } from 'react-router';
import { syncHistoryWithStore, routerReducer as routing } from 'react-router-redux';
import { handleActions } from 'redux-actions';
import { fork } from 'redux-saga/effects';
import window from 'global/window';
import { is, check, warn } from './utils';
import { use, apply, get } from './plugin';

function dva(opts = {}) {
  use(opts);

  let _routes = null;
  const _models = [];
  const app = {
    model,
    router,
    start,
    use,
    store: null
  };
  return app;

  function model(model) {
    check(model.namespace, is.notUndef, 'Namespace must be defined with model.');
    check(model.namespace, namespace => namespace !== 'routing', 'Namespace should not be routing.');
    _models.push(model);
  }

  function router(routes) {
    check(routes, is.func, 'Routes must be function.');
    _routes = routes;
  }

  // Usage:
  // app.start();
  // app.start(container);
  // app.start(container, opts);
  // app.start(opts);
  function start(container, opts = {}) {
    // If no container supplied, return jsx element.
    if (arguments.length === 0
      || (arguments.length === 1 && is.object(container))) {
      opts = container || {};
      container = null;
    } else {
      check(container, is.element, 'Container must be DOMElement.');
    }
    check(_routes, is.notUndef, 'Routes is not defined.');

    // Handle onError.
    const onError = apply('onError', function(err) {
      throw new Error(err.stack || err);
    });
    const onErrorWrapper = (err) => {
      if (err) {
        if (is.string(err)) err = new Error(err);
        onError(err);
      }
    };

    // Get sagas and reducers from model.
    let sagas = {};
    let reducers = {
      routing
    };
    _models.forEach(model => {
      if (is.array(model.reducers)) {
        const [ _reducers, enhancer ] = model.reducers;
        reducers[model.namespace] = enhancer(handleActions(_reducers || {}, model.state));
      } else {
        reducers[model.namespace] = handleActions(model.reducers || {}, model.state);
      }
      sagas = { ...sagas, ...model.effects };
    });

    // Support external reducers.
    const extraReducers = get('extraReducers');
    check(extraReducers, extraReducers => {
      for (let k in extraReducers) {
        if (k in reducers) return false;
      }
      return true;
    }, 'extraReducers should not be conflict with namespace in model.');
    reducers = { ...reducers, ...extraReducers };

    // Create store.
    const extraMiddlewares = get('onAction');
    const sagaMiddleware = createSagaMiddleware();
    const enhancer = compose(
      applyMiddleware.apply(null, [ sagaMiddleware, ...(extraMiddlewares || []) ]),
      window.devToolsExtension ? window.devToolsExtension() : f => f
    );
    const initialState = opts.initialState || {};
    const store = app.store = createStore(
      combineReducers(reducers), initialState, enhancer
    );

    // Handle onStateChange.
    const listeners = get('onStateChange');
    for (const listener of listeners) {
      store.subscribe(listener);
    }

    // Sync history.
    // Use try catch because it don't work in test.
    let history;
    try {
      history = syncHistoryWithStore(opts.history || hashHistory, store);
    } catch (e) { /*eslint-disable no-empty*/ }

    // Start saga.
    sagaMiddleware.run(rootSaga);<commit_msg>add routerMiddleware from react-router-redux, so we can use actions like push, go, ...<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import createSagaMiddleware, { takeEvery, takeLatest } from 'redux-saga';
import { hashHistory, Router } from 'react-router';
import { routerMiddleware, syncHistoryWithStore, routerReducer as routing } from 'react-router-redux';
import { handleActions } from 'redux-actions';
import { fork } from 'redux-saga/effects';
import window from 'global/window';
import { is, check, warn } from './utils';
import { use, apply, get } from './plugin';

function dva(opts = {}) {
  use(opts);

  let _routes = null;
  const _models = [];
  const app = {
    model,
    router,
    start,
    use,
    store: null
  };
  return app;

  function model(model) {
    check(model.namespace, is.notUndef, 'Namespace must be defined with model.');
    check(model.namespace, namespace => namespace !== 'routing', 'Namespace should not be routing.');
    _models.push(model);
  }

  function router(routes) {
    check(routes, is.func, 'Routes must be function.');
    _routes = routes;
  }

  // Usage:
  // app.start();
  // app.start(container);
  // app.start(container, opts);
  // app.start(opts);
  function start(container, opts = {}) {
    // If no container supplied, return jsx element.
    if (arguments.length === 0
      || (arguments.length === 1 && is.object(container))) {
      opts = container || {};
      container = null;
    } else {
      check(container, is.element, 'Container must be DOMElement.');
    }
    check(_routes, is.notUndef, 'Routes is not defined.');

    // Handle onError.
    const onError = apply('onError', function(err) {
      throw new Error(err.stack || err);
    });
    const onErrorWrapper = (err) => {
      if (err) {
        if (is.string(err)) err = new Error(err);
        onError(err);
      }
    };

    // Get sagas and reducers from model.
    let sagas = {};
    let reducers = {
      routing
    };
    _models.forEach(model => {
      if (is.array(model.reducers)) {
        const [ _reducers, enhancer ] = model.reducers;
        reducers[model.namespace] = enhancer(handleActions(_reducers || {}, model.state));
      } else {
        reducers[model.namespace] = handleActions(model.reducers || {}, model.state);
      }
      sagas = { ...sagas, ...model.effects };
    });

    // Support external reducers.
    const extraReducers = get('extraReducers');
    check(extraReducers, extraReducers => {
      for (let k in extraReducers) {
        if (k in reducers) return false;
      }
      return true;
    }, 'extraReducers should not be conflict with namespace in model.');
    reducers = { ...reducers, ...extraReducers };

    // Sync history.
    // Use try catch because it don't work in test.
    let history;
    try {
      history = syncHistoryWithStore(opts.history || hashHistory, store);
    } catch (e) { /*eslint-disable no-empty*/ }

    // Create store.
    const extraMiddlewares = get('onAction');
    const sagaMiddleware = createSagaMiddleware();
    const enhancer = compose(
      applyMiddleware.apply(null, [ routerMiddleware(history), sagaMiddleware, ...(extraMiddlewares || []) ]),
      window.devToolsExtension ? window.devToolsExtension() : f => f
    );
    const initialState = opts.initialState || {};
    const store = app.store = createStore(
      combineReducers(reducers), initialState, enhancer
    );

    // Handle onStateChange.
    const listeners = get('onStateChange');
    for (const listener of listeners) {
      store.subscribe(listener);
    }

    // Start saga.
    sagaMiddleware.run(rootSaga);
{'fraction_non_alphanumeric': 0.1399785061794734, 'fraction_numerical': 0.0005373455131649651, 'mean_word_length': 2.885699373695198, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, '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': '3250208', 'n_tokens_mistral': 2266, 'n_tokens_neox': 2234, 'n_words': 601}