/** * `cleo cloud conflicts resolve --keep …` (T12997): settle a recorded * conflict by keeping this store's values, the incoming op's, or a choice * per column. * * Where the merge DROPPED the incoming value, keeping mine writes nothing: * every receiver merges the same ops to the same result, so this store's * value is what the peers hold. Where the merge APPLIED it, every device * converged on theirs, so keeping mine re-asserts the pre-merge value the * conflict recorded (T13624), or is refused when none was recorded; it is * never a silent no-op. Every write a resolution makes is an ORDINARY local * write (a `write` capture frame, actor op `cloud.conflicts.resolve`): it is * captured, sealed and synced like any command's write, and wins by its * fresh HLC. The whole resolution (checks and write) runs in one immediate * transaction, so a peer op applied meanwhile cannot make a check stale. * * A resolution obeys the typed merge rules like any write: it is not a leave * op. Before writing, the would-be op is merged against the row exactly as a * receiver would merge it; when a rule would refuse it (leaving an absorbing * state, lowering a rank, editing a frozen or write-once field, changing an * immutable row), it is refused here too, naming the rule and the command * that may leave it, so the origin and its peers never diverge. * * @module store/sync/apply/resolve-conflict * @task T12997 */ import type { DatabaseSync } from 'node:sqlite'; import type { TableScope } from '@cleocode/contracts'; /** The `actor.op` a resolution's write carries. It is not a leave op of any rule. */ export declare const CONFLICT_RESOLVE_OP = "cloud.conflicts.resolve"; /** Which side to keep: one for every column, or per column (unnamed columns keep mine). */ export type ConflictKeep = 'mine' | 'theirs' | Readonly>; /** What a resolution did. */ export interface ConflictResolution { readonly id: number; /** Columns written (theirs, or mine re-asserted); empty when nothing had to change. */ readonly written: readonly string[]; } /** A resolution this store refuses, with the code and the way forward. */ export declare class ConflictResolveError extends Error { readonly code: 'E_NOT_FOUND' | 'E_VALIDATION' | 'E_INVALID_STATE'; readonly fix: string; constructor(code: 'E_NOT_FOUND' | 'E_VALIDATION' | 'E_INVALID_STATE', message: string, fix: string); } /** * Resolve one open conflict by keeping a side per column, then mark it * resolved, all in one immediate transaction. * * @param db - The store. * @param scope - The store's scope. * @param id - The conflict id. * @param keep - Which side to keep. * @param nowIso - The time. * @returns The columns written. * @throws {ConflictResolveError} When there is no such open conflict, a column * is not the conflict's, a kept value is unknown or cannot be written, or a * typed rule would refuse the write on a receiver. */ export declare function resolveConflictKeeping(db: DatabaseSync, scope: TableScope, id: number, keep: ConflictKeep, nowIso: string): ConflictResolution; //# sourceMappingURL=resolve-conflict.d.ts.map