"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports._E = exports._A = exports.DeferredSym = exports.DeferredInternal = exports.Deferred = void 0;

var tsplus_module_1 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Deferred/_internal/DeferredState"));

var tsplus_module_2 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/succeed"));

var tsplus_module_3 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@tsplus/stdlib/data/Either/definition"));

var tsplus_module_4 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/asyncInterrupt"));

var tsplus_module_5 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/intoDeferred"));

var tsplus_module_6 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/die"));

var tsplus_module_7 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/done"));

var tsplus_module_8 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/fail"));

var tsplus_module_9 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/failCause"));

var tsplus_module_10 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/interruption"));

var tsplus_module_11 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/fiberId"));

var tsplus_module_12 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Effect/operations/flatMap"));

var tsplus_module_13 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@tsplus/stdlib/data/Maybe/definition"));

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

var _a;

const fileName_1 = "(@effect/core) _src/io/Deferred/definition.ts";
const DeferredSym = /*#__PURE__*/Symbol.for("@effect/core/io/Deferred");
exports.DeferredSym = DeferredSym;

const _E = /*#__PURE__*/Symbol.for("@effect/core/io/Deferred/E");

exports._E = _E;

const _A = /*#__PURE__*/Symbol.for("@effect/core/io/Deferred/A");

exports._A = _A;
const Deferred = {
  $: {}
};
exports.Deferred = Deferred;

function interruptJoiner(self, joiner, __tsplusTrace) {
  return tsplus_module_2.succeed(() => {
    const state = self.state.get;

    if (state._tag === "Pending") {
      self.state.set(tsplus_module_1.pending(state.joiners.filter(j => j !== joiner)));
    }
  }, __tsplusTrace);
}

class DeferredInternal {
  constructor(state, blockingOn) {
    this.state = state;
    this.blockingOn = blockingOn;
    this[_a] = DeferredSym;
  }
  /**
   * Retrieves the value of the promise, suspending the fiber running the action
   * until the result is available.
   */


  await(__tsplusTrace) {
    return tsplus_module_4.asyncInterruptBlockingOn(k => {
      const state = this.state.get;

      switch (state._tag) {
        case "Done":
          {
            return tsplus_module_3.right(state.value);
          }

        case "Pending":
          {
            this.state.set(tsplus_module_1.pending([k, ...state.joiners]));
            return tsplus_module_3.left(interruptJoiner(this, k, fileName_1 + ":78:45"));
          }
      }
    }, () => this.blockingOn, fileName_1 + ":69:43");
  }
  /**
   * Completes the deferred with the result of the specified effect. If the
   * deferred has already been completed, the method will produce false.
   *
   * Note that `Deferred.completeWith` will be much faster, so consider using
   * that if you do not need to memoize the result of the specified effect.
   */


  complete(effect, __tsplusTrace) {
    return tsplus_module_5.intoDeferred_(effect, () => this, fileName_1 + ":96:31");
  }
  /**
   * Completes the deferred with the result of the specified effect. If the
   * deferred has already been completed, the method will produce false.
   *
   * Note that `Deferred.completeWith` will be much faster, so consider using
   * that if you do not need to memoize the result of the specified effect.
   */


  completeWith(effect, __tsplusTrace) {
    return tsplus_module_2.succeed(() => {
      const state = this.state.get;

      switch (state._tag) {
        case "Done":
          {
            return false;
          }

        case "Pending":
          {
            this.state.set(tsplus_module_1.done(effect));
            state.joiners.forEach(f => {
              f(effect);
            });
            return true;
          }
      }
    }, fileName_1 + ":111:26");
  }
  /**
   * Kills the promise with the specified error, which will be propagated to all
   * fibers waiting on the value of the promise.
   */


  die(defect, __tsplusTrace) {
    return this.completeWith(tsplus_module_6.die(defect, fileName_1 + ":137:40"), fileName_1 + ":137:29");
  }
  /**
   * Exits the deferred with the specified exit, which will be propagated to all
   * fibers waiting on the value of the deferred.
   */


  done(exit, __tsplusTrace) {
    return this.completeWith(tsplus_module_7.done(exit, fileName_1 + ":149:41"), fileName_1 + ":149:29");
  }
  /**
   * Fails the deferred with the specified error, which will be propagated to all
   * fibers waiting on the value of the deferred.
   */


  fail(e, __tsplusTrace) {
    return this.completeWith(tsplus_module_8.fail(e, fileName_1 + ":157:41"), __tsplusTrace);
  }
  /**
   * Fails the deferred with the specified cause, which will be propagated to all
   * fibers waiting on the value of the deferred.
   */


  failCause(cause, __tsplusTrace) {
    return this.completeWith(tsplus_module_9.failCause(cause, fileName_1 + ":169:46"), fileName_1 + ":169:29");
  }
  /**
   * Completes the deferred with interruption. This will interrupt all fibers
   * waiting on the value of the deferred as by the fiber calling this method.
   */


  interrupt(__tsplusTrace) {
    return tsplus_module_12.flatMap_(tsplus_module_11.fiberId, id => this.completeWith(tsplus_module_10.interruptAs(() => id, fileName_1 + ":177:79"), fileName_1 + ":177:60"), fileName_1 + ":177:34");
  }
  /**
   * Completes the deferred with interruption. This will interrupt all fibers
   * waiting on the value of the deferred as by the fiber calling this method.
   */


  interruptAs(fiberId, __tsplusTrace) {
    return this.completeWith(tsplus_module_10.interruptAs(fiberId, fileName_1 + ":189:48"), fileName_1 + ":189:29");
  }
  /**
   * Checks for completion of this `Promise`. Produces true if this promise has
   * already been completed with a value or an error and false otherwise.
   */


  isDone(__tsplusTrace) {
    return tsplus_module_2.succeed(() => this.state.get._tag === "Done", fileName_1 + ":197:26");
  }
  /**
   * Checks for completion of this `Deferred`. Returns the result effect if this
   * deferred has already been completed or a `None` otherwise.
   */


  poll(__tsplusTrace) {
    return tsplus_module_2.succeed(() => {
      const state = this.state.get;

      switch (state._tag) {
        case "Pending":
          {
            return tsplus_module_13.none;
          }

        case "Done":
          {
            return tsplus_module_13.some(state.value);
          }
      }
    }, fileName_1 + ":208:26");
  }
  /**
   * Completes the deferred with the specified value.
   */


  succeed(value, __tsplusTrace) {
    return this.completeWith(tsplus_module_2.succeed(value, fileName_1 + ":229:44"), fileName_1 + ":229:29");
  }
  /**
   * Unsafe version of `done`.
   */


  unsafeDone(effect) {
    const state = this.state.get;

    if (state._tag === "Pending") {
      this.state.set(tsplus_module_1.done(effect));
      Array.from(state.joiners).reverse().forEach(f => {
        f(effect);
      });
    }
  }

}

exports.DeferredInternal = DeferredInternal;
_a = DeferredSym;
//# sourceMappingURL=definition.js.map