import type { JsonValue } from "@sixb/core" import { isObjectActionDefinition } from "@sixb/core" import type { ActionEditCommitResult } from "@sixb/core/internal/actions" import { reportActionPhaseFailure } from "@sixb/core/internal/error-reporting" import type { ActionRunRecord } from "@sixb/core/storage" import { toActionRunFailure, translateActionPhaseError } from "../normalize" import { type BasePhaseContext, requireObjectSubject, toActionRuntimeFacade } from "./context" import type { LoadedObjectTarget, PhaseExecutionBase, UpdateActiveRun } from "./types" export async function runEffectsPhase( input: PhaseExecutionBase & { readonly run: ActionRunRecord readonly baseContext: BasePhaseContext readonly objectTarget: LoadedObjectTarget | null readonly writeback: JsonValue | undefined readonly commit: ActionEditCommitResult readonly updateActiveRun: UpdateActiveRun } ): Promise { if (!input.action.phases.effects) { return input.run } let run = await input.runtime.actionRunsStorage.enterPhase({ projectId: input.runtime.id, id: input.run.id, phase: "effects", }) input.updateActiveRun(run) try { if (isObjectActionDefinition(input.action)) { const effects = input.action.phases.effects await effects({ ...input.baseContext, subject: requireObjectSubject(input.run.subject, { actionId: input.action.id, runId: input.run.id, }), sixb: toActionRuntimeFacade(input.runtime), writeback: input.writeback, commit: input.commit, }) } else { const effects = input.action.phases.effects await effects({ ...input.baseContext, sixb: toActionRuntimeFacade(input.runtime), writeback: input.writeback, commit: input.commit, }) } } catch (error) { const completedAt = new Date() const phaseError = translateActionPhaseError(error, "effects", { actionId: input.action.id, runId: input.run.id, signal: input.signal, }) const failure = toActionRunFailure(phaseError, "effects", { actionId: input.action.id, runId: input.run.id, at: completedAt, }) run = await input.runtime.actionRunsStorage.recordEffects({ projectId: input.runtime.id, id: input.run.id, status: "failed", completedAt, error: failure, }) input.updateActiveRun(run) reportActionPhaseFailure(input.runtime.errorReporterHost, error, { projectId: input.runtime.id, actionId: input.action.id, runId: input.run.id, phase: "effects", failure, }) return run } run = await input.runtime.actionRunsStorage.recordEffects({ projectId: input.runtime.id, id: input.run.id, status: "succeeded", }) input.updateActiveRun(run) return run }