text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  var static_1 = require("../static");
  var transport_info_1 = require("./transport/transport-info");
  var transport_1 = require("./transport/transport");
  var func_transport_1 = require("./transport/func-transport");
  /**
   *
   * Denotes different bundle processing modes. A bundle processing mode
   * determines how a bundle reacts to transport dependencies of given
   * `HTMLDocument`:
   *
   */
  var ProcessingMode;
  (function (ProcessingMode) {
      /**
       *
       * In this mode, unresolved dependencies of the document are checked.
       * If they appear in the bundle, they are marked as resolved, and the bundle
       * will be added to the header of the document.
       *
       */
      ProcessingMode[ProcessingMode["ResolveOnly"] = 0] = "ResolveOnly";
      /**
       *
       * In this mode, unresolved dependencies of the document are checked,
       * if they appear in the bundle, they are marked as resolved, otherwise
       * they will be added to the bundle, and the bundle added to the header
       * of the document. Processing in this mode might require the bundle
       * to be reconstructed.
       *
       */
      ProcessingMode[ProcessingMode["ResolveAndCollect"] = 1] = "ResolveAndCollect";
  })(ProcessingMode = exports.ProcessingMode || (exports.ProcessingMode = {}));
  /**
   *
   * Represents a bundle containing bundled code for components that need to be
   * transported and executed on client side. A bundle is mainly denoted
   * by the URL it will be accessible on (from client's perspective) and the
   * server-side imports necessary to construct/reconstruct it.
   *
   */
  var Bundle = /** @class */ (function () {
      /**
       *
       * @param url  the URL on which the bundle will be accessible to clients.
       * @param path the path of the file the bundle is stored on. defaults to the URL.
       *
       */
      function Bundle(url, path) {
          this.url = url;
          /**
           *
           * Whether the bundle should be reconstructed or not.
           *
           */
          this.repack = true;
          this.imports = [];
          this.initImports = [];
          this.path = path || this.url;
      }
      /**
       *
       * @param info
       * @returns `true` if the bundle includes given server-side import.
       *
       */
      Bundle.prototype.includes = function (info) { return this.imports.some(function (i) { return i === info || i.hash === info.hash; }); };
      /**
       *
       * @param info a new server-side import to be added to this bundle.
       * @returns `this` for chaining convenience.
       * @warning This function DOES NOT check whether given import is already part of the bundle or not.
       * Avoid using it directly unless you know what you are doing.
       *
       */
      Bundle.prototype.add = function (info) {
          this.imports.push(info);
          this.repack = true;
          return this;
      };
      Bundle.prototype.collect = function () {
          var _this = this;
          var comps = [];
          for (var _i = 0; _i < arguments.length; _i++) {
              comps[_i] = arguments[_i];
          }
          comps.forEach(function (comp) {
              var info = transport_1.getCompTransportInfo(comp);
              if (info && !_this.includes(info))
                  _this.add(info);
          });
          return comps.length == 0 ? this.process(ProcessingMode.ResolveAndCollect) : this;
      };
      /**
       *
       * @returns a `PostProcessor` that processes given `HTMLDocument` in `ResolveOnly` mode.
       * This means that unresolved dependencies of the given document will be checked, if they
       * are part of the bundle they will be marked as resolved and the bundle will be added to the
       * document's header (via a `<script/>` tag with the bundle's URL).
       *
       */
      Bundle.prototype.resolve = function () { return this.process(ProcessingMode.ResolveOnly); };
      /**
       *
       * @param mode
       * @returns a `PostProcessor` that processes given `HTMLDocument` using given mode.
       * @see Bundle.resolve()
       * @see Bundle.collect()
       *
       */
      Bundle.prototype.process = function (mode) {
          var _this = this;
          var renderer = new static_1.StaticRenderer();
          return function (document) {
              var used = false;
              transport_info_1.fetchInfo(document).forEach(function (info) {
                  if (!info.resolved) {
                      if (_this.includes(info))
                          info.resolved = used = true;
                      else if (mode === ProcessingMode.ResolveAndCollect) {
                          _this.add(info);
                          info.resolved = used = true;
                      }
                  }
              });
              if (used || _this.initImports.length > 0)
                  renderer.render(renderer.create("script", { async: true, defer: true, src: _this.url })).on(document.head);
          };
      };
      /**
       *
       * Will set the client-side renderer used by the bundle to given
       * renderer factory. Useful for using custom client-side renderers.
       *
       * @param factory the factory function to be transported. MUST BE result of `funcTransport()` function.
       * @returns `this` for chaining convenience.
       *
       */
      Bundle.prototype.withRenderer = function (factory) {
          var _rendererImport = func_transport_1.getFuncTransportInfo(factory);
          if (_rendererImport) {
              if (!this.rendererImport || this.rendererImport && this.rendererImport.hash !== _rendererImport.hash) {
                  this.rendererImport = _rendererImport;
                  this.repack = true;
              }
          }
          return this;
      };
      /**
       *
       * Will add the given init-function to initialization functions of this bundle.
       * These functions will be executed when the bundle is loaded on the client-side.
       *
       * @param initFunc the initialization function to be transported. MUST BE result of `funcTransport()` function.
       * @returns `this` for chaining convenience.
       *
       */
      Bundle.prototype.init = function (initFunc) {
          var _import = func_transport_1.getFuncTransportInfo(initFunc);
          if (!this.initImports.some(function (i) { return i.hash === _import.hash; })) {
              this.initImports.push(_import);
              this.repack = true;
          }
          return this;
      };
      return Bundle;
  }());
  exports.Bundle = Bundle;
  //# sourceMappingURL=bundle.js.map