text: 'use strict';
  
  exports.__esModule = true;
  
  var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  
  var _react = require('react');
  
  var _react2 = _interopRequireDefault(_react);
  
  function shallowEqual(a, b) {
    var ka = 0;
    var kb = 0;
    for (var key in a) {
      if (a.hasOwnProperty(key) && a[key] !== b[key]) return false;
      ka++;
    }
    for (var key in b) {
      if (b.hasOwnProperty(key)) kb++;
    }return ka === kb;
  }
  
  var AsyncProps = _react2['default'].createClass({
    displayName: 'AsyncProps',
  
    statics: {
      createElement: function createElement(Component, state) {
        return Component.loadProps ? _react2['default'].createElement(AsyncProps, { Component: Component, routing: state }) : _react2['default'].createElement(Component, state);
      }
    },
  
    getInitialState: function getInitialState() {
      return {
        propsAreLoading: false,
        propsAreLoadingLong: false,
        asyncProps: null,
        previousRoutingState: null
      };
    },
  
    componentDidMount: function componentDidMount() {
      this.load(this.props);
    },
  
    componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
      var _this = this;
  
      var needToLoad = !shallowEqual(nextProps.routing.routeParams, this.props.routing.routeParams);
  
      if (needToLoad) {
        var routerTransitioned = nextProps.routing.location !== this.props.routing.location;
        var keepPreviousRoutingState = this.state.propsAreLoadingLong && routerTransitioned;
  
        if (keepPreviousRoutingState) {
          this.load(nextProps);
        } else {
          this.setState({
            previousRoutingState: this.props.routing
          }, function () {
            return _this.load(nextProps);
          });
        }
      }
    },
  
    /*
     * Could make this method much better, right now AsyncProps doesn't render its
     * children until it fetches data, causing a "waterfall" effect, when instead
     * it could look at the branch of components from it down to the end and load
     * up the props for all of them in parallel, waterfall will do for now...
     */
    load: function load(props) {
      var _this2 = this;
  
      var lastLoadTime = this._lastLoadTime = Date.now();
      var params = props.routing.params;
      var Component = this.props.Component;
  
      this.setState({ propsAreLoading: true }, function () {
        var longLoadTimer = setTimeout(function () {
          _this2.setState({ propsAreLoadingLong: true });
        }, 300);
  
        // TODO: handle `error`s
        Component.loadProps(params, function (error, asyncProps) {
          clearTimeout(longLoadTimer);
  
          // if the router transitions between now and when the callback runs we will
          // ignore it to prevent setting state w/ the wrong data (earlier calls to
          // load that call back later than later calls to load)
          if (_this2._lastLoadTime !== lastLoadTime || !_this2.isMounted()) return;
  
          _this2.setState({
            propsAreLoading: false,
            propsAreLoadingLong: false,
            asyncProps: asyncProps,
            previousRoutingState: null
          });
        });
      });
    },
  
    render: function render() {
      var _this3 = this;
  
      var Component = this.props.Component;
      var _state = this.state;
      var asyncProps = _state.asyncProps;
      var propsAreLoading = _state.propsAreLoading;
      var propsAreLoadingLong = _state.propsAreLoadingLong;
  
      var routing = this.state.previousRoutingState || this.props.routing;
  
      if (this.state.asyncProps === null) return Component.Loader ? _react2['default'].createElement(Component.Loader, routing) : null;
  
      return _react2['default'].createElement(Component, _extends({
        onPropsDidChange: function () {
          return _this3.load(_this3.props);
        },
        propsAreLoading: propsAreLoading,
        propsAreLoadingLong: propsAreLoadingLong
      }, routing, asyncProps));
    }
  });
  
  exports['default'] = AsyncProps;
  module.exports = exports['default'];