text: "use strict";
  
  var _interopRequireWildcard = require("../npm/@babel/runtime/helpers/interopRequireWildcard.js");
  
  var _interopRequireDefault = require("../npm/@babel/runtime/helpers/interopRequireDefault.js");
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.create = create;
  
  var _getIterator2 = _interopRequireDefault(require("../npm/@babel/runtime/core-js/get-iterator.js"));
  
  var _keys = _interopRequireDefault(require("../npm/@babel/runtime/core-js/object/keys.js"));
  
  var _objectSpread2 = _interopRequireDefault(require("../npm/@babel/runtime/helpers/objectSpread.js"));
  
  var _redux = require("../npm/redux/lib/index.js");
  
  var _middleware = _interopRequireDefault(require("../npm/redux-saga/lib/internal/middleware.js"));
  
  var _invariant = _interopRequireDefault(require("../npm/invariant/invariant.js"));
  
  var _checkModel = _interopRequireDefault(require("./checkModel.js"));
  
  var _prefixNamespace = _interopRequireDefault(require("./prefixNamespace.js"));
  
  var _Plugin = _interopRequireWildcard(require("./Plugin.js"));
  
  var _createStore = _interopRequireDefault(require("./createStore.js"));
  
  var _getSaga = _interopRequireDefault(require("./getSaga.js"));
  
  var _getReducer = _interopRequireDefault(require("./getReducer.js"));
  
  var _createPromiseMiddleware = _interopRequireDefault(require("./createPromiseMiddleware.js"));
  
  var _subscription = require("./subscription.js");
  
  var _utils = require("./utils.js");
  
  // Internal model to update global state when do unmodel
  var dvaModel = {
    namespace: '@@dva',
    state: 0,
    reducers: {
      UPDATE: function UPDATE(state) {
        return state + 1;
      }
    }
  };
  /**
   * Create dva-core instance.
   *
   * @param hooksAndOpts
   * @param createOpts
   */
  
  function create() {
    var hooksAndOpts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    var createOpts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    var initialReducer = createOpts.initialReducer,
        _createOpts$setupApp = createOpts.setupApp,
        setupApp = _createOpts$setupApp === undefined ? _utils.noop : _createOpts$setupApp;
    var plugin = new _Plugin.default();
    plugin.use((0, _Plugin.filterHooks)(hooksAndOpts));
    var app = {
      _models: [(0, _prefixNamespace.default)((0, _objectSpread2.default)({}, dvaModel))],
      _store: null,
      _plugin: plugin,
      use: plugin.use.bind(plugin),
      model: model,
      start: start
    };
    return app;
    /**
     * Register model before app is started.
     *
     * @param m {Object} model to register
     */
  
    function model(m) {
      {
        (0, _checkModel.default)(m, app._models);
      }
  
      var prefixedModel = (0, _prefixNamespace.default)((0, _objectSpread2.default)({}, m));
  
      app._models.push(prefixedModel);
  
      return prefixedModel;
    }
    /**
     * Inject model after app is started.
     *
     * @param createReducer
     * @param onError
     * @param unlisteners
     * @param m
     */
  
    function injectModel(createReducer, onError, unlisteners, m) {
      m = model(m);
      var store = app._store;
      store.asyncReducers[m.namespace] = (0, _getReducer.default)(m.reducers, m.state, plugin._handleActions);
      store.replaceReducer(createReducer());
  
      if (m.effects) {
        store.runSaga(app._getSaga(m.effects, m, onError, plugin.get('onEffect')));
      }
  
      if (m.subscriptions) {
        unlisteners[m.namespace] = (0, _subscription.run)(m.subscriptions, m, app, onError);
      }
    }
    /**
     * Unregister model.
     *
     * @param createReducer
     * @param reducers
     * @param unlisteners
     * @param namespace
     *
     * Unexpected key warn problem:
     * https://github.com/reactjs/redux/issues/1636
     */
  
    function unmodel(createReducer, reducers, unlisteners, namespace) {
      var store = app._store; // Delete reducers
  
      delete store.asyncReducers[namespace];
      delete reducers[namespace];
      store.replaceReducer(createReducer());
      store.dispatch({
        type: '@@dva/UPDATE'
      }); // Cancel effects
  
      store.dispatch({
        type: "".concat(namespace, "/@@CANCEL_EFFECTS")
      }); // Unlisten subscrioptions
  
      (0, _subscription.unlisten)(unlisteners, namespace); // Delete model from app._models
  
      app._models = app._models.filter(function (model) {
        return model.namespace !== namespace;
      });
    }
    /**
     * Replace a model if it exsits, if not, add it to app
     * Attention:
     * - Only available after dva.start gets called
     * - Will not check origin m is strict equal to the new one
     * Useful for HMR
     * @param createReducer
     * @param reducers
     * @param unlisteners
     * @param onError
     * @param m
     */
  
    function replaceModel(createReducer, reducers, unlisteners, onError, m) {
      var store = app._store;
      var namespace = m.namespace;
      var oldModelIdx = (0, _utils.findIndex)(app._models, function (model) {
        return model.namespace === namespace;
      });
  
      if (~oldModelIdx) {
        // Cancel effects
        store.dispatch({
          type: "".concat(namespace, "/@@CANCEL_EFFECTS")
        }); // Delete reducers
  
        delete store.asyncReducers[namespace];
        delete reducers[namespace]; // Unlisten subscrioptions
  
        (0, _subscription.unlisten)(unlisteners, namespace); // Delete model from app._models
  
        app._models.splice(oldModelIdx, 1);
      } // add new version model to store
  
  
      app.model(m);
      store.dispatch({
        type: '@@dva/UPDATE'
      });
    }
    /**
     * Start the app.
     *
     * @returns void
     */
  
    function start() {
      // Global error handler
      var onError = function onError(err, extension) {
        if (err) {
          if (typeof err === 'string') err = new Error(err);
  
          err.preventDefault = function () {
            err._dontReject = true;
          };
  
          plugin.apply('onError', function (err) {
            throw new Error(err.stack || err);
          })(err, app._store.dispatch, extension);
        }
      };
  
      var sagaMiddleware = (0, _middleware.default)();
      var promiseMiddleware = (0, _createPromiseMiddleware.default)(app);
      app._getSaga = _getSaga.default.bind(null);
      var sagas = [];
      var reducers = (0, _objectSpread2.default)({}, initialReducer);
      var _iteratorNormalCompletion = true;
      var _didIteratorError = false;
      var _iteratorError = undefined;
  
      try {
        for (var _iterator = (0, _getIterator2.default)(app._models), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
          var m = _step.value;
          reducers[m.namespace] = (0, _getReducer.default)(m.reducers, m.state, plugin._handleActions);
          if (m.effects) sagas.push(app._getSaga(m.effects, m, onError, plugin.get('onEffect')));
        }
      } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion && _iterator.return != null) {
            _iterator.return();
          }
        } finally {
          if (_didIteratorError) {
            throw _iteratorError;
          }
        }
      }
  
      var reducerEnhancer = plugin.get('onReducer');
      var extraReducers = plugin.get('extraReducers');
      (0, _invariant.default)((0, _keys.default)(extraReducers).every(function (key) {
        return !(key in reducers);
      }), "[app.start] extraReducers is conflict with other reducers, reducers list: ".concat((0, _keys.default)(reducers).join(', '))); // Create store
  
      var store = app._store = (0, _createStore.default)({
        // eslint-disable-line
        reducers: createReducer(),
        initialState: hooksAndOpts.initialState || {},
        plugin: plugin,
        createOpts: createOpts,
        sagaMiddleware: sagaMiddleware,
        promiseMiddleware: promiseMiddleware
      }); // Extend store
  
      store.runSaga = sagaMiddleware.run;
      store.asyncReducers = {}; // Execute listeners when state is changed
  
      var listeners = plugin.get('onStateChange');
      var _iteratorNormalCompletion2 = true;
      var _didIteratorError2 = false;
      var _iteratorError2 = undefined;
  
      try {
        var _loop = function _loop() {
          var listener = _step2.value;
          store.subscribe(function () {
            listener(store.getState());
          });
        };
  
        for (var _iterator2 = (0, _getIterator2.default)(listeners), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
          _loop();
        } // Run sagas
      } catch (err) {
        _didIteratorError2 = true;
        _iteratorError2 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
            _iterator2.return();
          }
        } finally {
          if (_didIteratorError2) {
            throw _iteratorError2;
          }
        }
      }
  
      sagas.forEach(sagaMiddleware.run); // Setup app
  
      setupApp(app); // Run subscriptions
  
      var unlisteners = {};
      var _iteratorNormalCompletion3 = true;
      var _didIteratorError3 = false;
      var _iteratorError3 = undefined;
  
      try {
        for (var _iterator3 = (0, _getIterator2.default)(this._models), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
          var _model = _step3.value;
  
          if (_model.subscriptions) {
            unlisteners[_model.namespace] = (0, _subscription.run)(_model.subscriptions, _model, app, onError);
          }
        } // Setup app.model and app.unmodel
      } catch (err) {
        _didIteratorError3 = true;
        _iteratorError3 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
            _iterator3.return();
          }
        } finally {
          if (_didIteratorError3) {
            throw _iteratorError3;
          }
        }
      }
  
      app.model = injectModel.bind(app, createReducer, onError, unlisteners);
      app.unmodel = unmodel.bind(app, createReducer, reducers, unlisteners);
      app.replaceModel = replaceModel.bind(app, createReducer, reducers, unlisteners, onError);
      /**
       * Create global reducer for redux.
       *
       * @returns {Object}
       */
  
      function createReducer() {
        return reducerEnhancer((0, _redux.combineReducers)((0, _objectSpread2.default)({}, reducers, extraReducers, app._store ? app._store.asyncReducers : {})));
      }
    }
  }