"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ensuring_ = exports.ensuring = void 0;
// ets_tracing: off
const cause_1 = require("../Cause/cause");
const core_1 = require("./core");
const interruption_1 = require("./interruption");
/**
 * Returns an effect that, if this effect _starts_ execution, then the
 * specified `finalizer` is guaranteed to begin execution, whether this effect
 * succeeds, fails, or is interrupted.
 *
 * For use cases that need access to the effect's result, see onExit.
 *
 * Finalizers offer very powerful guarantees, but they are low-level, and
 * should generally not be used for releasing resources. For higher-level
 * logic built on `ensuring`, see `bracket`.
 *
 * @ets_data_first ensuring_
 */
function ensuring(finalizer, __trace) {
    return (effect) => ensuring_(effect, finalizer, __trace);
}
exports.ensuring = ensuring;
/**
 * Returns an effect that, if this effect _starts_ execution, then the
 * specified `finalizer` is guaranteed to begin execution, whether this effect
 * succeeds, fails, or is interrupted.
 *
 * For use cases that need access to the effect's result, see onExit.
 *
 * Finalizers offer very powerful guarantees, but they are low-level, and
 * should generally not be used for releasing resources. For higher-level
 * logic built on `ensuring`, see `bracket`.
 */
function ensuring_(effect, finalizer, __trace) {
    return (0, interruption_1.uninterruptibleMask)(({ restore }) => (0, core_1.foldCauseM_)(restore(effect), (cause1) => (0, core_1.foldCauseM_)(finalizer, (cause2) => (0, core_1.halt)((0, cause_1.then)(cause1, cause2)), (_) => (0, core_1.halt)(cause1)), (value) => (0, core_1.foldCauseM_)(finalizer, (cause1) => (0, core_1.halt)(cause1), (_) => (0, core_1.succeed)(value)), __trace));
}
exports.ensuring_ = ensuring_;
//# sourceMappingURL=ensuring.js.map