"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"];

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _tslib = require("tslib");

var _mobx = require("mobx");

var _cache = _interopRequireWildcard(require("../cache"));

var KEY = Symbol('KEY');

var PromiseMerger = /*#__PURE__*/function () {
  function PromiseMerger(callback, config) {
    var timeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 200;
    (0, _classCallCheck2["default"])(this, PromiseMerger);
    this.timeout = timeout;
    this.promiseMap = new Map();
    this.cache = new _cache["default"]((0, _mobx.toJS)(config));
    this.dataMap = new Map();
    this.callback = callback;
    this.reaction = (0, _cache.refreshCacheOptions)(this.cache);
  }

  (0, _createClass2["default"])(PromiseMerger, [{
    key: "dispose",
    value: function dispose() {
      this.reaction();
    }
  }, {
    key: "add",
    value: function add(code, getBatchKey, args, data) {
      var _this = this;

      var cache = this.cache,
          promiseMap = this.promiseMap,
          dataMap = this.dataMap;
      var item = cache.get(code);

      if (item !== undefined) {
        return Promise.resolve(item);
      }

      if (data) {
        dataMap.set(code, data);
      }

      var batchKey = getBatchKey ? getBatchKey(KEY) : KEY;
      return new Promise(function (resolve, reject) {
        var promiseList = promiseMap.get(batchKey) || new Map();
        promiseMap.set(batchKey, promiseList);
        var promise = promiseList.get(code);

        var resolveCallback = function resolveCallback() {
          resolve(cache.get(code));
        };

        if (promise) {
          promise.resolves.push(resolveCallback);
          promise.rejects.push(reject);
        } else {
          if (_this.waitID) {
            clearTimeout(_this.waitID);
          }

          promise = {
            resolves: [resolveCallback],
            rejects: [reject]
          };
          promiseList.set(code, promise);
          _this.waitID = setTimeout(function () {
            var codeList = Array.from(promiseList.keys());

            if (process.env.LOGGER_LEVEL === 'info') {
              // eslint-disable-next-line no-console
              console.info("batch request: ".concat(codeList));
            }

            _this.callback(codeList, args, codeList.reduce(function (list, $code) {
              var $value = dataMap.get($code);

              if ($value !== undefined) {
                list.push($value);
              }

              return list;
            }, [])).then(function (res) {
              codeList.forEach(function (key) {
                var value = promiseList.get(key);
                promiseList["delete"](key);

                var _ref = value || {},
                    _ref$resolves = _ref.resolves,
                    resolves = _ref$resolves === void 0 ? [] : _ref$resolves;

                if (res) {
                  var _data = res[key];

                  _this.cache.set(key, _data);

                  resolves.forEach(function (r) {
                    return r(_data);
                  });
                } else {
                  resolves.forEach(function (r) {
                    return r();
                  });
                }
              });
            })["catch"](function (error) {
              codeList.forEach(function (key) {
                var value = promiseList.get(key);
                promiseList["delete"](key);

                var _ref2 = value || {},
                    _ref2$rejects = _ref2.rejects,
                    rejects = _ref2$rejects === void 0 ? [] : _ref2$rejects;

                rejects.forEach(function (r) {
                  return r(error);
                });
              });
            });
          }, _this.timeout);
        }
      });
    }
  }]);
  return PromiseMerger;
}();

exports["default"] = PromiseMerger;
(0, _tslib.__decorate)([_mobx.action], PromiseMerger.prototype, "add", null);
//# sourceMappingURL=index.js.map
