import type { PersistedRunSchedulingState, PersistedRunState, RunId, RunPruneCandidate, RunSummary, WorkflowExecutionListingRepository, WorkflowExecutionPruneRepository, WorkflowExecutionRepository, WorkflowId, } from "../types"; import type { RunEventBus } from "./runEvents"; export class EventPublishingWorkflowExecutionRepository implements WorkflowExecutionRepository, WorkflowExecutionListingRepository, WorkflowExecutionPruneRepository { constructor( private readonly inner: WorkflowExecutionRepository, private readonly eventBus: RunEventBus, private readonly now: () => Date = () => new Date(), ) {} async createRun(args: Parameters[0]): Promise { await this.inner.createRun(args); await this.eventBus.publish({ kind: "runCreated", runId: args.runId, workflowId: args.workflowId, parent: args.parent, at: this.now().toISOString(), }); } async load(runId: RunId): Promise { return await this.inner.load(runId); } async loadSchedulingState(runId: RunId): Promise { return await this.inner.loadSchedulingState(runId); } async save(state: PersistedRunState): Promise { await this.inner.save(state); await this.eventBus.publish({ kind: "runSaved", runId: state.runId, workflowId: state.workflowId, parent: state.parent, at: this.now().toISOString(), state, }); } async deleteRun(runId: RunId): Promise { if (!this.inner.deleteRun) return; await this.inner.deleteRun(runId); } async listRuns(args?: Readonly<{ workflowId?: WorkflowId; limit?: number }>): Promise> { const listingRepository = this.inner as unknown as Partial; if (!listingRepository.listRuns) return []; return await listingRepository.listRuns(args); } async listRunsOlderThan( args: Readonly<{ nowIso: string; defaultRetentionSeconds: number; limit?: number }>, ): Promise> { const pruneRepository = this.inner as unknown as Partial; if (!pruneRepository.listRunsOlderThan) return []; return await pruneRepository.listRunsOlderThan(args); } }