text: 'use strict';
  
  Object.defineProperty(exports, '__esModule', {
    value: true
  });
  Object.defineProperty(exports, 'messageParent', {
    enumerable: true,
    get: function () {
      return _messageParent.default;
    }
  });
  exports.default = void 0;
  
  function _os() {
    const data = require('os');
  
    _os = function () {
      return data;
    };
  
    return data;
  }
  
  var _Farm = _interopRequireDefault(require('./Farm'));
  
  var _WorkerPool = _interopRequireDefault(require('./WorkerPool'));
  
  var _messageParent = _interopRequireDefault(require('./workers/messageParent'));
  
  function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {default: obj};
  }
  
  function _defineProperty(obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      });
    } else {
      obj[key] = value;
    }
    return obj;
  }
  
  function getExposedMethods(workerPath, options) {
    let exposedMethods = options.exposedMethods; // If no methods list is given, try getting it by auto-requiring the module.
  
    if (!exposedMethods) {
      const module = require(workerPath);
  
      exposedMethods = Object.keys(module).filter(
        // @ts-expect-error: no index
        name => typeof module[name] === 'function'
      );
  
      if (typeof module === 'function') {
        exposedMethods = [...exposedMethods, 'default'];
      }
    }
  
    return exposedMethods;
  }
  /**
   * The Jest farm (publicly called "Worker") is a class that allows you to queue
   * methods across multiple child processes, in order to parallelize work. This
   * is done by providing an absolute path to a module that will be loaded on each
   * of the child processes, and bridged to the main process.
   *
   * Bridged methods are specified by using the "exposedMethods" property of the
   * "options" object. This is an array of strings, where each of them corresponds
   * to the exported name in the loaded module.
   *
   * You can also control the amount of workers by using the "numWorkers" property
   * of the "options" object, and the settings passed to fork the process through
   * the "forkOptions" property. The amount of workers defaults to the amount of
   * CPUS minus one.
   *
   * Queueing calls can be done in two ways:
   *   - Standard method: calls will be redirected to the first available worker,
   *     so they will get executed as soon as they can.
   *
   *   - Sticky method: if a "computeWorkerKey" method is provided within the
   *     config, the resulting string of this method will be used as a key.
   *     Every time this key is returned, it is guaranteed that your job will be
   *     processed by the same worker. This is specially useful if your workers
   *     are caching results.
   */
  
  class JestWorker {
    constructor(workerPath, options) {
      var _this$_options$enable,
        _this$_options$forkOp,
        _this$_options$maxRet,
        _this$_options$numWor,
        _this$_options$resour,
        _this$_options$setupA;
  
      _defineProperty(this, '_ending', void 0);
  
      _defineProperty(this, '_farm', void 0);
  
      _defineProperty(this, '_options', void 0);
  
      _defineProperty(this, '_workerPool', void 0);
  
      this._options = {...options};
      this._ending = false;
      const workerPoolOptions = {
        enableWorkerThreads:
          (_this$_options$enable = this._options.enableWorkerThreads) !== null &&
          _this$_options$enable !== void 0
            ? _this$_options$enable
            : false,
        forkOptions:
          (_this$_options$forkOp = this._options.forkOptions) !== null &&
          _this$_options$forkOp !== void 0
            ? _this$_options$forkOp
            : {},
        maxRetries:
          (_this$_options$maxRet = this._options.maxRetries) !== null &&
          _this$_options$maxRet !== void 0
            ? _this$_options$maxRet
            : 3,
        numWorkers:
          (_this$_options$numWor = this._options.numWorkers) !== null &&
          _this$_options$numWor !== void 0
            ? _this$_options$numWor
            : Math.max((0, _os().cpus)().length - 1, 1),
        resourceLimits:
          (_this$_options$resour = this._options.resourceLimits) !== null &&
          _this$_options$resour !== void 0
            ? _this$_options$resour
            : {},
        setupArgs:
          (_this$_options$setupA = this._options.setupArgs) !== null &&
          _this$_options$setupA !== void 0
            ? _this$_options$setupA
            : []
      };
  
      if (this._options.WorkerPool) {
        // @ts-expect-error: constructor target any?
        this._workerPool = new this._options.WorkerPool(
          workerPath,
          workerPoolOptions
        );
      } else {
        this._workerPool = new _WorkerPool.default(workerPath, workerPoolOptions);
      }
  
      this._farm = new _Farm.default(
        workerPoolOptions.numWorkers,
        this._workerPool.send.bind(this._workerPool),
        this._options.computeWorkerKey
      );
  
      this._bindExposedWorkerMethods(workerPath, this._options);
    }
  
    _bindExposedWorkerMethods(workerPath, options) {
      getExposedMethods(workerPath, options).forEach(name => {
        if (name.startsWith('_')) {
          return;
        }
  
        if (this.constructor.prototype.hasOwnProperty(name)) {
          throw new TypeError('Cannot define a method called ' + name);
        } // @ts-expect-error: dynamic extension of the class instance is expected.
  
        this[name] = this._callFunctionWithArgs.bind(this, name);
      });
    }
  
    _callFunctionWithArgs(method, ...args) {
      if (this._ending) {
        throw new Error('Farm is ended, no more calls can be done to it');
      }
  
      return this._farm.doWork(method, ...args);
    }
  
    getStderr() {
      return this._workerPool.getStderr();
    }
  
    getStdout() {
      return this._workerPool.getStdout();
    }
  
    async end() {
      if (this._ending) {
        throw new Error('Farm is ended, no more calls can be done to it');
      }
  
      this._ending = true;
      return this._workerPool.end();
    }
  }
  
  exports.default = JestWorker;
  