import type { SerializedError } from '@pikku/core/errors'; import type { StepState, WorkflowRunMirror, WorkflowRunWire, WorkflowStatus, WorkflowPlannedStep, WorkflowVersionStatus } from '@pikku/core/workflow'; import type { Kysely } from 'kysely'; import type { KyselyPikkuDB } from './kysely-tables.js'; /** * Kysely-backed `WorkflowRunMirror`. * * Forwards executor writes to the same `workflow_runs` / `workflow_step` / * `workflow_step_history` / `workflow_versions` tables that * `KyselyWorkflowService` uses, so a `KyselyWorkflowRunService` reading * those tables will see runs driven by any executor (Cloudflare Durable * Object, Redis, MongoDB, in-memory) — not just kysely-driven runs. * * Errors thrown here are caught by the executor's `safeMirror` wrapper * and logged, so a mirror outage cannot break a running workflow. */ export declare class KyselyWorkflowMirror implements WorkflowRunMirror { protected db: Kysely; private initialized; constructor(db: Kysely); /** * Create the underlying tables if none of them exist yet. * * Safe to call from either the mirror or `KyselyWorkflowService.init()` — * both apply the same `workflowSchema`, and `requirePikkuSchema` is a no-op * once the tables are there. A database holding only *part* of the schema * throws rather than filling in the rest: something else owns those tables, * and boot is not where that gets reconciled. */ init(): Promise; createRun(runId: string, workflowName: string, input: any, inline: boolean, graphHash: string, wire: WorkflowRunWire, options?: { deterministic?: boolean; plannedSteps?: WorkflowPlannedStep[]; }): Promise; updateRunStatus(id: string, status: WorkflowStatus, output?: any, error?: SerializedError): Promise; insertStepState(runId: string, step: StepState & { stepName: string; rpcName: string | null; data: any; }): Promise; setStepRunning(stepId: string): Promise; setStepScheduled(stepId: string): Promise; setStepResult(stepId: string, result: any): Promise; setStepChildRunId(stepId: string, childRunId: string): Promise; setStepError(stepId: string, error: SerializedError): Promise; createRetryAttempt(failedStepId: string, newStep: StepState & { stepName: string; }): Promise; setBranchTaken(stepId: string, branchKey: string): Promise; updateRunState(runId: string, name: string, value: unknown): Promise; upsertWorkflowVersion(name: string, graphHash: string, graph: any, source: string, status?: WorkflowVersionStatus): Promise; updateWorkflowVersionStatus(name: string, graphHash: string, status: WorkflowVersionStatus): Promise; private updateStepStatus; private insertHistoryRecord; /** * The executor pattern is: `insertStepState` writes a 'pending' history * row, then later transitions UPDATE that latest row in place rather * than appending a new one — except for retry attempts which append. * * We mirror the same shape so `KyselyWorkflowRunService.getRunHistory` * returns the same sequence the executor would have produced. */ private appendOrUpdateLatestHistory; }