// ets_tracing: off import { combineSeq } from "../Cause/cause.js" import { fold_ } from "../Exit/api.js" import type { Exit } from "../Exit/exit.js" import { chain_, foldCauseM_, halt, result, suspend } from "./core.js" import { done } from "./done.js" import type { Effect } from "./effect.js" import { uninterruptibleMask } from "./interruption.js" /** * Acquires a resource, uses the resource, and then releases the resource. * Neither the acquisition nor the release will be interrupted, and the * resource is guaranteed to be released, so long as the `acquire` effect * succeeds. If `use` fails, then after release, the returned effect will fail * with the same error. * * @ets_data_first bracketExit_ */ export function bracketExit( use: (a: A) => Effect, release: (a: A, e: Exit) => Effect, __trace?: string ) { return (acquire: Effect): Effect => bracketExit_(acquire, use, release, __trace) } /** * Acquires a resource, uses the resource, and then releases the resource. * Neither the acquisition nor the release will be interrupted, and the * resource is guaranteed to be released, so long as the `acquire` effect * succeeds. If `use` fails, then after release, the returned effect will fail * with the same error. */ export function bracketExit_( acquire: Effect, use: (a: A) => Effect, release: (a: A, e: Exit) => Effect, __trace?: string ): Effect { return uninterruptibleMask(({ restore }) => chain_( acquire, (a) => chain_(result(suspend(() => restore(use(a)))), (e) => foldCauseM_( suspend(() => release(a, e)), (cause2) => halt( fold_( e, (_) => combineSeq(_, cause2), (_) => cause2 ) ), (_) => done(e) ) ), __trace ) ) }