import * as Effect from "effect/Effect"; import type { PlanStatusSession } from "./Cli/Cli.ts"; import type { Plan } from "./Plan.ts"; import { State } from "./State/index.ts"; /** * The outcome of syncing a single resource. * * - `unchanged` — the observed cloud state matches the persisted attributes. * - `drifted` — (dry-run only) the cloud state diverged from the persisted * attributes; a non-dry-run sync would repair it. * - `missing` — (dry-run only) the resource no longer exists in the cloud; * a non-dry-run sync would recreate it. * - `repaired` — drift was detected and the resource was reconciled back to * its desired (last-deployed) state. * - `recreated` — the resource was missing from the cloud and was reconciled * from scratch, reusing the persisted instance id so * deterministic physical names converge to the same values. * - `skipped` — the resource was not synced; see `reason` (provider has no * `read`, or the persisted status is not stable). */ export type SyncAction = "unchanged" | "drifted" | "missing" | "repaired" | "recreated" | "skipped"; export interface SyncResourceResult { fqn: string; logicalId: string; resourceType: string; action: SyncAction; /** Why the resource was skipped (only set when `action === "skipped"`). */ reason?: string; /** * The resource's attributes after the sync: the reconciled attributes for * `repaired`/`recreated`, the observed cloud attributes for `drifted`, and * the persisted attributes for `unchanged`. Unset for `missing`/`skipped`. */ attr?: any; } export interface SyncResult { resources: Record; } export interface SyncOptions { /** * Detect and report drift without repairing it. No provider `reconcile` * runs and no state is persisted — resources report `drifted`/`missing` * instead of `repaired`/`recreated`. */ dryRun?: boolean; /** Optional progress session (the CLI passes one; tests usually don't). */ session?: PlanStatusSession; } /** * Reconcile state drift for every resource persisted under `stack`/`stage`. * * Unlike `deploy` (which converges the cloud to a *new* desired state * computed from the stack program), `sync` converges the cloud back to the * *last-deployed* desired state recorded in the state store. It needs no * stack program — only the state store and the resource providers. * * The algorithm, per resource, is observe → compare → converge: * * 1. **Read** — call `provider.read` with the persisted props/attributes to * observe the live cloud state. * 2. **Compare** — deep-compare the observed attributes against the * persisted attributes. Equal ⇒ `unchanged`. * 3. **Reconcile** — on drift, call `provider.reconcile` with the persisted * props as the desired state (`news`) and the *observed* attributes as * `output`, so the provider diffs against reality rather than a stale * snapshot. When the resource is missing entirely, reconcile runs * greenfield (`olds`/`output` undefined) under the *same* instance id so * deterministic physical names regenerate identically. * 4. **Persist** — write the fresh attributes back to the state store. * * Resources are synced concurrently and independently — persisted props are * fully resolved values, so there are no upstream/downstream data edges to * order by. A failure syncing one resource does not interrupt the others; * all failures are aggregated into a single combined cause after every * resource has been attempted. * * Resources that cannot be synced are reported as `skipped` rather than * failing the run: providers without `read` (nothing to observe), and * resources whose persisted status is not stable (`creating`, `updating`, * `replacing`, `replaced`, `deleting`) — those represent an interrupted * deploy and must be recovered by `deploy`, which owns replacement chains * and dependency ordering. Action rows have no cloud state and are ignored. */ export declare const sync: (stack: { name: string; stage: string; }, options?: SyncOptions) => Effect.Effect; export interface SyncPlan { /** Per-resource detection outcome (a dry-run {@link SyncResult}). */ result: SyncResult; /** * The detection outcome projected onto the engine's {@link Plan} shape so * the CLI renders a sync exactly like a deploy plan (ink TUI when * interactive, plain logging otherwise): `drifted` → `update`, `missing` → * `create`, `unchanged`/`skipped` → `noop`. */ plan: Plan; } /** * Run the drift-detection pass (a dry-run {@link sync}) and project the * outcome onto a {@link Plan} for display/approval. The plan is a read-only * view — repair happens by calling {@link sync} (without `dryRun`), which * re-observes the cloud rather than trusting the detection snapshot. */ export declare const plan: (stack: { name: string; stage: string; }) => Effect.Effect; //# sourceMappingURL=Sync.d.ts.map