"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.interruptible = exports.interruptStatus_ = exports.interruptStatus = exports.interruptAs = exports.interrupt = exports.disconnect = exports.checkInterruptible = exports.InterruptStatusRestoreImpl = void 0;
exports.interruptibleMask = interruptibleMask;
exports.onInterruptPolymorphic = exports.onInterrupt = void 0;
exports.onInterruptPolymorphic_ = onInterruptPolymorphic_;
exports.uninterruptibleMask = exports.uninterruptible = exports.onInterrupt_ = void 0;

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

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

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

var tsplus_module_4 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/InterruptStatus/definition"));

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

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

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

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

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

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

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

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

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

var tsplus_module_14 = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/core/io/Cause/definition"));

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

var _primitives = /*#__PURE__*/require("@effect/core/io/Effect/definition/primitives");

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; }

const fileName_1 = "(@effect/core) _src/io/Effect/operations/interruption.ts";
const interruptStatus_ = interruptStatus_1;
exports.interruptStatus_ = interruptStatus_;
const interruptible = interruptible_1;
exports.interruptible = interruptible;
const uninterruptible = uninterruptible_1;
exports.uninterruptible = uninterruptible;
const checkInterruptible = checkInterruptible_1;
exports.checkInterruptible = checkInterruptible;
const uninterruptibleMask = uninterruptibleMask_1;
exports.uninterruptibleMask = uninterruptibleMask;
const disconnect = disconnect_1;
exports.disconnect = disconnect;
const onInterrupt_ = onInterrupt_1;
exports.onInterrupt_ = onInterrupt_;
const interruptAs = interruptAs_1;
exports.interruptAs = interruptAs;

class InterruptStatusRestoreImpl {
  constructor(flag) {
    this.flag = flag;

    this.restore = (effect, __tsplusTrace) => {
      return tsplus_module_1.suspendSucceed(() => interruptStatus_1(effect(), () => this.flag, fileName_1 + ":34:58"), fileName_1 + ":34:33");
    };

    this.force = (effect, __tsplusTrace) => {
      return tsplus_module_1.suspendSucceed(() => this.flag.isUninterruptible ? interruptible_1(disconnect_1(uninterruptible_1(effect(), fileName_1 + ":43:35"), fileName_1 + ":43:48"), fileName_1 + ":43:64") : interruptStatus_1(effect(), () => this.flag, fileName_1 + ":44:35"), fileName_1 + ":41:33");
    };
  }

} // -----------------------------------------------------------------------------
// Operations
// -----------------------------------------------------------------------------

/**
 * Returns an effect that is interrupted by the current fiber
 *
 * @tsplus static ets/Effect/Ops interrupt
 */


exports.InterruptStatusRestoreImpl = InterruptStatusRestoreImpl;
const interrupt = /*#__PURE__*/tsplus_module_3.flatMap_(tsplus_module_2.fiberId, fiberId => interruptAs_1(() => fiberId, fileName_1 + ":58:80"), fileName_1 + ":58:48");
/**
 * Switches the interrupt status for this effect. If `true` is used, then the
 * effect becomes interruptible (the default), while if `false` is used, then
 * the effect becomes uninterruptible. These changes are compositional, so
 * they only affect regions of the effect.
 *
 * @tsplus fluent ets/Effect interruptStatus
 */

exports.interrupt = interrupt;

function interruptStatus_1(self, flag, __tsplusTrace) {
  return new _primitives.IInterruptStatus(self, flag, __tsplusTrace);
}
/**
 * Switches the interrupt status for this effect. If `true` is used, then the
 * effect becomes interruptible (the default), while if `false` is used, then
 * the effect becomes uninterruptible. These changes are compositional, so
 * they only affect regions of the effect.
 *
 * @tsplus static ets/Effect/Aspects interruptStatus
 */


const interruptStatus = (flag, __tsplusTrace) => self => interruptStatus_(self, flag, __tsplusTrace);
/**
 * Returns a new effect that performs the same operations as this effect, but
 * interruptibly, even if composed inside of an uninterruptible region.
 *
 * Note that effects are interruptible by default, so this function only has
 * meaning if used within an uninterruptible region.
 *
 * **WARNING**: This operator "punches holes" into effects, allowing them to be
 * interrupted in unexpected places. Do not use this operator unless you know
 * exactly what you are doing. Instead, you should use `uninterruptibleMask`.
 *
 * @tsplus fluent ets/Effect interruptible
 */


exports.interruptStatus = interruptStatus;

function interruptible_1(self, __tsplusTrace) {
  return interruptStatus_1(self, () => tsplus_module_4.Interruptible, __tsplusTrace);
}
/**
 * Performs this effect uninterruptibly. This will prevent the effect from
 * being terminated externally, but the effect may fail for internal reasons
 * (e.g. an uncaught error) or terminate due to defect.
 *
 * Uninterruptible effects may recover from all failure causes (including
 * interruption of an inner effect that has been made interruptible).
 *
 * @tsplus fluent ets/Effect uninterruptible
 */


function uninterruptible_1(self, __tsplusTrace) {
  return interruptStatus_1(self, () => tsplus_module_4.Uninterruptible, __tsplusTrace);
}
/**
 * Checks the interrupt status, and produces the effect returned by the
 * specified callback.
 *
 * @tsplus static ets/Effect/Ops checkInterruptible
 */


function checkInterruptible_1(f, __tsplusTrace) {
  return new _primitives.ICheckInterrupt(f, __tsplusTrace);
}
/**
 * Makes the effect interruptible, but passes it a restore function that can
 * be used to restore the inherited interruptibility from whatever region the
 * effect is composed into.
 *
 * @tsplus static ets/Effect/Ops interruptibleMask
 */


function interruptibleMask(f, __tsplusTrace) {
  return checkInterruptible_1(flag => interruptible_1(f(new InterruptStatusRestoreImpl(flag)), __tsplusTrace), __tsplusTrace);
}
/**
 * Makes the effect uninterruptible, but passes it a restore function that can
 * be used to restore the inherited interruptibility from whatever region the
 * effect is composed into.
 *
 * @tsplus static ets/Effect/Ops uninterruptibleMask
 */


function uninterruptibleMask_1(f, __tsplusTrace) {
  return checkInterruptible_1(flag => uninterruptible_1(f(new InterruptStatusRestoreImpl(flag)), __tsplusTrace), __tsplusTrace);
}
/**
 * Returns an effect whose interruption will be disconnected from the
 * fiber's own interruption, being performed in the background without
 * slowing down the fiber's interruption.
 *
 * This method is useful to create "fast interrupting" effects. For
 * example, if you call this on a bracketed effect, then even if the
 * effect is "stuck" in acquire or release, its interruption will return
 * immediately, while the acquire / release are performed in the
 * background.
 *
 * See timeout and race for other applications.
 *
 * @tsplus fluent ets/Effect disconnect
 */


function disconnect_1(effect, __tsplusTrace) {
  return uninterruptibleMask_1(({
    restore
  }) => tsplus_module_3.flatMap_(tsplus_module_2.fiberId, id => tsplus_module_3.flatMap_(tsplus_module_6.forkDaemon(restore(() => effect, __tsplusTrace), __tsplusTrace), fiber => onInterrupt_1(restore(() => tsplus_module_7.join(fiber, __tsplusTrace), __tsplusTrace), () => tsplus_module_6.forkDaemon(tsplus_module_5.interruptAsNow_(fiber, id, __tsplusTrace), __tsplusTrace), __tsplusTrace), __tsplusTrace), __tsplusTrace), __tsplusTrace);
}
/**
 * Calls the specified function, and runs the effect it returns, if this
 * effect is interrupted.
 *
 * @tsplus fluent ets/Effect onInterrupt
 */


function onInterrupt_1(self, cleanup, __tsplusTrace) {
  return uninterruptibleMask_1(({
    restore
  }) => tsplus_module_13.foldCauseEffect_(restore(() => self, __tsplusTrace), cause => tsplus_module_8.isInterrupted(cause) ? tsplus_module_11.zipRight_(cleanup(tsplus_module_9.interruptors(cause)), () => tsplus_module_10.failCauseNow(cause, __tsplusTrace), __tsplusTrace) : tsplus_module_10.failCauseNow(cause, __tsplusTrace), tsplus_module_12.succeedNow, __tsplusTrace), __tsplusTrace);
}
/**
 * Calls the specified function, and runs the effect it returns, if this
 * effect is interrupted.
 *
 * @tsplus static ets/Effect/Aspects onInterrupt
 */


const onInterrupt = (cleanup, __tsplusTrace) => self => onInterrupt_(self, cleanup, __tsplusTrace);
/**
 * Calls the specified function, and runs the effect it returns, if this
 * effect is interrupted (allows for expanding error).
 *
 * @tsplus fluent ets/Effect onInterruptPolymorphic
 */


exports.onInterrupt = onInterrupt;

function onInterruptPolymorphic_(self, cleanup, __tsplusTrace) {
  return uninterruptibleMask_1(({
    restore
  }) => tsplus_module_13.foldCauseEffect_(restore(() => self, __tsplusTrace), cause => tsplus_module_8.isInterrupted(cause) ? tsplus_module_13.foldCauseEffect_(cleanup(tsplus_module_9.interruptors(cause)), _ => tsplus_module_10.failCauseNow(_, __tsplusTrace), () => tsplus_module_10.failCauseNow(cause, __tsplusTrace), __tsplusTrace) : tsplus_module_10.failCauseNow(cause, __tsplusTrace), tsplus_module_12.succeedNow, __tsplusTrace), __tsplusTrace);
}
/**
 * Calls the specified function, and runs the effect it returns, if this
 * effect is interrupted (allows for expanding error).
 *
 * @tsplus static ets/Effect/Aspects onInterruptPolymorphic
 */


const onInterruptPolymorphic = (cleanup, __tsplusTrace) => self => onInterruptPolymorphic_(self, cleanup, __tsplusTrace);
/**
 * Returns an effect that is interrupted as if by the specified fiber.
 *
 * @tsplus static ets/Effect/Ops interruptAs
 */


exports.onInterruptPolymorphic = onInterruptPolymorphic;

function interruptAs_1(fiberId, __tsplusTrace) {
  return tsplus_module_15.failCause(() => tsplus_module_14.interrupt(fiberId()), __tsplusTrace);
}
//# sourceMappingURL=interruption.js.map