text: var __extends = (this && this.__extends) || (function () {
      var extendStatics = Object.setPrototypeOf ||
          ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
          function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
      return function (d, b) {
          extendStatics(d, b);
          function __() { this.constructor = d; }
          d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
      };
  })();
  var __assign = (this && this.__assign) || Object.assign || function(t) {
      for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
              t[p] = s[p];
      }
      return t;
  };
  import 'whatwg-fetch';
  import { BaseNetworkInterface, printRequest, } from './networkInterface';
  import { QueryBatcher, } from './batching';
  import { assign } from '../util/assign';
  var HTTPBatchedNetworkInterface = (function (_super) {
      __extends(HTTPBatchedNetworkInterface, _super);
      function HTTPBatchedNetworkInterface(uri, batchInterval, fetchOpts) {
          var _this = _super.call(this, uri, fetchOpts) || this;
          if (typeof batchInterval !== 'number') {
              throw new Error("batchInterval must be a number, got " + batchInterval);
          }
          _this.batcher = new QueryBatcher({
              batchInterval: batchInterval,
              batchFetchFunction: _this.batchQuery.bind(_this),
          });
          return _this;
      }
      HTTPBatchedNetworkInterface.prototype.query = function (request) {
          return this.batcher.enqueueRequest(request);
      };
      HTTPBatchedNetworkInterface.prototype.batchQuery = function (requests) {
          var _this = this;
          var options = __assign({}, this._opts);
          var middlewarePromise = this.applyBatchMiddlewares({
              requests: requests,
              options: options,
          });
          return new Promise(function (resolve, reject) {
              middlewarePromise.then(function (batchRequestAndOptions) {
                  return _this.batchedFetchFromRemoteEndpoint(batchRequestAndOptions)
                      .then(function (result) {
                      var httpResponse = result;
                      if (!httpResponse.ok) {
                          return _this.applyBatchAfterwares({ responses: [httpResponse], options: batchRequestAndOptions })
                              .then(function () {
                              var httpError = new Error("Network request failed with status " + httpResponse.status + " - \"" + httpResponse.statusText + "\"");
                              httpError.response = httpResponse;
                              throw httpError;
                          });
                      }
                      return result.json();
                  })
                      .then(function (responses) {
                      if (typeof responses.map !== 'function') {
                          throw new Error('BatchingNetworkInterface: server response is not an array');
                      }
                      _this.applyBatchAfterwares({
                          responses: responses,
                          options: batchRequestAndOptions.options,
                      }).then(function (responseAndOptions) {
                          resolve(responseAndOptions.responses);
                      }).catch(function (error) {
                          reject(error);
                      });
                  });
              }).catch(function (error) {
                  reject(error);
              });
          });
      };
      HTTPBatchedNetworkInterface.prototype.applyBatchMiddlewares = function (_a) {
          var _this = this;
          var requests = _a.requests, options = _a.options;
          return new Promise(function (resolve, reject) {
              var queue = function (funcs, scope) {
                  var next = function () {
                      if (funcs.length > 0) {
                          var f = funcs.shift();
                          if (f) {
                              f.applyBatchMiddleware.apply(scope, [{ requests: requests, options: options }, next]);
                          }
                      }
                      else {
                          resolve({
                              requests: requests,
                              options: options,
                          });
                      }
                  };
                  next();
              };
              queue(_this._middlewares.slice(), _this);
          });
      };
      HTTPBatchedNetworkInterface.prototype.applyBatchAfterwares = function (_a) {
          var _this = this;
          var responses = _a.responses, options = _a.options;
          return new Promise(function (resolve, reject) {
              var responseObject = { responses: responses, options: options };
              var queue = function (funcs, scope) {
                  var next = function () {
                      if (funcs.length > 0) {
                          var f = funcs.shift();
                          if (f) {
                              f.applyBatchAfterware.apply(scope, [responseObject, next]);
                          }
                      }
                      else {
                          resolve(responseObject);
                      }
                  };
                  next();
              };
              queue(_this._afterwares.slice(), _this);
          });
      };
      HTTPBatchedNetworkInterface.prototype.use = function (middlewares) {
          var _this = this;
          middlewares.map(function (middleware) {
              if (typeof middleware.applyBatchMiddleware === 'function') {
                  _this._middlewares.push(middleware);
              }
              else {
                  throw new Error('Batch middleware must implement the applyBatchMiddleware function');
              }
          });
          return this;
      };
      HTTPBatchedNetworkInterface.prototype.useAfter = function (afterwares) {
          var _this = this;
          afterwares.map(function (afterware) {
              if (typeof afterware.applyBatchAfterware === 'function') {
                  _this._afterwares.push(afterware);
              }
              else {
                  throw new Error('Batch afterware must implement the applyBatchAfterware function');
              }
          });
          return this;
      };
      HTTPBatchedNetworkInterface.prototype.batchedFetchFromRemoteEndpoint = function (batchRequestAndOptions) {
          var options = {};
          assign(options, batchRequestAndOptions.options);
          var printedRequests = batchRequestAndOptions.requests.map(function (request) {
              return printRequest(request);
          });
          return fetch(this._uri, __assign({}, this._opts, { body: JSON.stringify(printedRequests), method: 'POST' }, options, { headers: __assign({ Accept: '*/*', 'Content-Type': 'application/json' }, options.headers) }));
      };
      return HTTPBatchedNetworkInterface;
  }(BaseNetworkInterface));
  export { HTTPBatchedNetworkInterface };
  export function createBatchingNetworkInterface(options) {
      if (!options) {
          throw new Error('You must pass an options argument to createNetworkInterface.');
      }
      return new HTTPBatchedNetworkInterface(options.uri, options.batchInterval, options.opts || {});
  }
  //# sourceMappingURL=batchedNetworkInterface.js.map