"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.UIROOT_ASPECT_IDS = exports.BundleUiTask = exports.BUNDLE_UI_TASK_NAME = exports.BUNDLE_UI_HASH_FILENAME = exports.BUNDLE_UI_DIR = exports.BUNDLE_UIROOT_DIR = void 0;
function _path() {
  const data = require("path");
  _path = function () {
    return data;
  };
  return data;
}
function _fs() {
  const data = require("fs");
  _fs = function () {
    return data;
  };
  return data;
}
function _ui() {
  const data = require("./ui.aspect");
  _ui = function () {
    return data;
  };
  return data;
}
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const BUNDLE_UI_TASK_NAME = exports.BUNDLE_UI_TASK_NAME = 'BundleUI';
const BUNDLE_UI_DIR = exports.BUNDLE_UI_DIR = 'ui-bundle';
const UIROOT_ASPECT_IDS = exports.UIROOT_ASPECT_IDS = {
  SCOPE: 'teambit.scope/scope',
  WORKSPACE: 'teambit.workspace/workspace'
};
const BUNDLE_UIROOT_DIR = exports.BUNDLE_UIROOT_DIR = {
  [UIROOT_ASPECT_IDS.SCOPE]: 'scope',
  [UIROOT_ASPECT_IDS.WORKSPACE]: 'workspace'
};
const BUNDLE_UI_HASH_FILENAME = exports.BUNDLE_UI_HASH_FILENAME = '.hash';
class BundleUiTask {
  constructor(ui, logger) {
    this.ui = ui;
    this.logger = logger;
    _defineProperty(this, "aspectId", 'teambit.ui-foundation/ui');
    _defineProperty(this, "name", BUNDLE_UI_TASK_NAME);
    _defineProperty(this, "location", 'end');
  }
  async execute(context) {
    const capsule = context.capsuleNetwork.seedersCapsules.find(c => c.component.id.toStringWithoutVersion() === _ui().UIAspect.id);
    if (!capsule) {
      return {
        componentsResults: []
      };
    }
    const uiRootAspectIds = Object.values(UIROOT_ASPECT_IDS);
    try {
      // allSettled, not all: `all` rejects as soon as one root fails, and the `finally` below would
      // then close compilers while the other root is still bundling. Wait for both, then report.
      const outcomes = await Promise.allSettled(uiRootAspectIds.map(async uiRootAspectId => {
        const outputPath = (0, _path().join)(capsule.path, BundleUiTask.getArtifactDirectory(uiRootAspectId));
        this.logger.info(`Generating UI bundle at ${outputPath}...`);
        await this.ui.build(uiRootAspectId, outputPath, {
          deferClose: true
        });
        await this.generateHash(outputPath);
      }));
      const failures = outcomes.flatMap((outcome, index) => outcome.status === 'rejected' ? [{
        uiRootAspectId: uiRootAspectIds[index],
        reason: outcome.reason
      }] : []);
      if (failures.length) {
        // Log every root that failed, not only the one that ends the task. The reason itself is
        // usually rspack's entire stats output - megabytes - so it goes to the log and to `cause`,
        // and the thrown message names the roots, which is what the build pipeline prints.
        failures.forEach(({
          uiRootAspectId,
          reason
        }) => this.logger.error(`Generating UI bundle failed for ${uiRootAspectId}`, reason));
        const error = new Error(`Generating UI bundle failed for ${failures.map(failure => failure.uiRootAspectId).join(', ')}`);
        // not `new Error(msg, { cause })`: this project targets es2015, whose lib has no ErrorOptions
        error.cause = failures[0].reason;
        throw error;
      }
    } finally {
      // Free both UI module graphs before the build moves on. Every remaining task - a preview
      // bundle per env among them - runs in this same process, and holding these two graphs is what
      // pushed it into the OOM killer. `deferClose` above is what leaves them for this call, so a
      // compiler is never closed while the other root is still bundling.
      await this.ui.closeBuildCompilers();
    }
    const artifacts = BundleUiTask.getArtifactDef();
    return {
      componentsResults: [],
      artifacts
    };
  }
  async generateHash(outputPath) {
    const maybeUiRoot = this.ui.getUi();
    if (!maybeUiRoot) throw new Error('no uiRoot found');
    const [, uiRoot] = maybeUiRoot;
    const hash = await this.ui.createBundleUiHash(uiRoot);
    if (!(0, _fs().existsSync)(outputPath)) (0, _fs().mkdirSync)(outputPath);
    (0, _fs().writeFileSync)((0, _path().join)(outputPath, BUNDLE_UI_HASH_FILENAME), hash);
  }
  static getArtifactDirectory(uiRootAspectId) {
    return (0, _path().join)('artifacts', BUNDLE_UI_DIR, BUNDLE_UIROOT_DIR[uiRootAspectId]);
  }
  static getArtifactDef() {
    const scopeRootDir = BundleUiTask.getArtifactDirectory(UIROOT_ASPECT_IDS.SCOPE);
    const workspaceRootDir = BundleUiTask.getArtifactDirectory(UIROOT_ASPECT_IDS.WORKSPACE);
    return [{
      name: `${BUNDLE_UI_DIR}-${BUNDLE_UIROOT_DIR[UIROOT_ASPECT_IDS.SCOPE]}`,
      globPatterns: [`${scopeRootDir}/**`]
    }, {
      name: `${BUNDLE_UI_DIR}-${BUNDLE_UIROOT_DIR[UIROOT_ASPECT_IDS.WORKSPACE]}`,
      globPatterns: [`${workspaceRootDir}/**`]
    }];
  }
}
exports.BundleUiTask = BundleUiTask;

//# sourceMappingURL=bundle-ui.task.js.map