import * as tsplus_module_1 from "@effect/core/io/Effect/definition";
import * as tsplus_module_2 from "@effect/core/stm/STM/TxnId";
import * as tsplus_module_3 from "@tsplus/stdlib/data/AtomicReference";
import * as tsplus_module_4 from "@effect/core/stm/STM/State";
import * as tsplus_module_5 from "@effect/core/io/Effect/operations/async";
import * as tsplus_module_6 from "@effect/core/io/Effect/operations/done";
import * as tsplus_module_7 from "@effect/core/io/Effect/operations/failCause";
import * as tsplus_module_8 from "@effect/core/io/Effect/operations/catchAllCause";
import * as tsplus_module_9 from "@effect/core/io/Effect/operations/interruption";
import * as tsplus_module_10 from "@effect/core/io/Effect/operations/suspendSucceedWith";
import * as tsplus_module_11 from "@effect/core/io/Effect/operations/environmentWithEffect";
import { tryCommitAsync, tryCommitSync } from "@effect/core/stm/STM/Journal";
/**
 * @tsplus static ets/STM/Ops atomically
 */

export function atomically(self, __tsplusTrace) {
  return tsplus_module_11.environmentWithEffect(env => tsplus_module_10.suspendSucceedWith((_, fiberId) => {
    const v = tryCommitSync(fiberId, self, env);

    switch (v._tag) {
      case "Done":
        {
          throw new tsplus_module_1.Effect.Error(v.exit, __tsplusTrace);
        }

      case "Suspend":
        {
          const txnId = tsplus_module_2.makeTxnId();
          const state = new tsplus_module_3.AtomicReference(tsplus_module_4.running);

          const io = tsplus_module_5._async(tryCommitAsync(v.journal, fiberId, self, txnId, state, env), __tsplusTrace);

          return tsplus_module_9.uninterruptibleMask(({
            restore
          }) => tsplus_module_8.catchAllCause_(restore(() => io, __tsplusTrace), cause => {
            state.compareAndSet(tsplus_module_4.running, tsplus_module_4.interrupted);
            const currentState = state.get;
            return currentState._tag === "Done" ? tsplus_module_6.done(() => currentState.exit, __tsplusTrace) : tsplus_module_7.failCause(() => cause, __tsplusTrace);
          }, __tsplusTrace), __tsplusTrace);
        }
    }
  }, __tsplusTrace), __tsplusTrace);
}
//# sourceMappingURL=atomically.mjs.map