import { createLogger } from "../logger/index.js";
const logger = createLogger("shared").child({ component: "commands" });
async function flushPendingChangesGuard(em, label) {
  let pendingCount = -1;
  try {
    const uow = typeof em.getUnitOfWork === "function" ? em.getUnitOfWork() : void 0;
    if (uow && typeof uow.computeChangeSets === "function" && typeof uow.getChangeSets === "function") {
      uow.computeChangeSets();
      pendingCount = uow.getChangeSets().length;
    }
  } catch {
    pendingCount = -1;
  }
  if (pendingCount > 0) {
    await em.flush();
    if (process.env.NODE_ENV !== "production") {
      logger.warn("withAtomicFlush: pending change-sets remained at the commit boundary and were flushed defensively \u2014 a phase mutated a managed entity after its flush boundary; split the mutation and any dependent read/sync into separate phases", { label: label ?? null, pendingCount });
    }
  }
}
async function withAtomicFlush(em, phases, options) {
  if (phases.length === 0) return;
  const runPhasesAndFlush = async () => {
    for (const phase of phases) {
      await phase();
      await em.flush();
    }
    await flushPendingChangesGuard(em, options?.label);
  };
  if (!options?.transaction) {
    await runPhasesAndFlush();
    return;
  }
  const isInTransaction = em.isInTransaction;
  if (typeof isInTransaction === "function" && isInTransaction.call(em)) {
    await runPhasesAndFlush();
    return;
  }
  await em.begin(options.isolationLevel ? { isolationLevel: options.isolationLevel } : void 0);
  try {
    await runPhasesAndFlush();
    await em.commit();
  } catch (err) {
    try {
      await em.rollback();
    } catch {
    }
    throw err;
  }
}
export {
  withAtomicFlush
};
//# sourceMappingURL=flush.js.map
