/** * Fenced canonical field commits for the SQLite-authoritative prototype. * * The writer applies every accepted field CAS and any resulting outbox rows in * one SQLite savepoint. A stale field or lost fence rolls back the complete * row-level commit, so a partially accepted event cannot leak a partial state. */ import { ROW_OPERATIONS } from "../../../contracts/domain/model/constants.js"; import type { FieldOwnership } from "../../../contracts/domain/model/constants.js"; import type { Applicability, Presence } from "../../../contracts/state/types.js"; import type { NormalizedCell } from "../../../contracts/encoding/types.js"; import type { FencingContext } from "@hikoutei/ikisaki"; import { type NewEffect } from "@hikoutei/ikisaki"; import type { SqlExecutor, SqlStorageAdapter } from "../../../contracts/storage/sql.js"; /** Runtime values returned by the canonical commit writer. */ export declare const CANONICAL_COMMIT_RESULT_KINDS: { readonly APPLIED: "applied"; readonly STALE: "stale"; readonly FENCED_OUT: "fenced_out"; readonly INVALID: "invalid"; }; /** Runtime values describing which canonical target became stale. */ export declare const CANONICAL_COMMIT_STALE_TARGETS: { readonly ENTITY: "entity"; readonly FIELD: "field"; }; /** Closed set of canonical stale-target kinds. */ export type CanonicalCommitStaleTarget = (typeof CANONICAL_COMMIT_STALE_TARGETS)[keyof typeof CANONICAL_COMMIT_STALE_TARGETS]; /** A field value the writer should insert or compare-and-set. */ export type CanonicalEffectsFactory = (sql: SqlExecutor, result: Extract) => Promise; export interface CanonicalFieldWrite { readonly fieldName: string; readonly value: NormalizedCell; /** Inserts have no prior revision; updates carry the revision used by CAS. */ readonly expectedFieldRevision: Applicability; readonly ownership: FieldOwnership; } /** Shared canonical commit fields used by every row operation. */ interface CanonicalCommitBase { readonly entityId: string; /** Snapshot hash is absent when the caller has no accepted snapshot evidence. */ readonly acceptedSnapshotHash: Presence; /** Effects are inserted in this same savepoint as the canonical mutation. */ readonly effects: readonly NewEffect[]; /** * Optional transaction-local effect planner. It is evaluated after the * canonical CAS so payloads can include fields committed by another writer * that touched a different field before this transaction began. */ readonly effectsFactory?: CanonicalEffectsFactory; } /** An insert prepared from one core evaluation result. */ export interface CanonicalInsertCommitInput extends CanonicalCommitBase { readonly kind: typeof ROW_OPERATIONS.INSERT; readonly fields: readonly CanonicalFieldWrite[]; } /** A field-level update prepared from one core evaluation result. */ export interface CanonicalUpdateCommitInput extends CanonicalCommitBase { readonly kind: typeof ROW_OPERATIONS.UPDATE; readonly fields: readonly CanonicalFieldWrite[]; } /** An insert or field-level update prepared from one core evaluation result. */ export type CanonicalFieldCommitInput = CanonicalInsertCommitInput | CanonicalUpdateCommitInput; /** A confirmed delete that turns an active canonical entity into a tombstone. */ export interface CanonicalDeleteCommitInput extends CanonicalCommitBase { readonly kind: typeof ROW_OPERATIONS.DELETE; /** Entity revision observed with the explicit delete evidence. */ readonly expectedEntityRevision: number; } /** * An internal create that resurrects an exact tombstoned canonical identity. * * Unlike an observation insert, every field is CAS-updated to its new * normalized value with `field_revision + 1` and the entity flips from * `tombstoned` to `active` with `entity_revision + 1`. This operation is not * part of the public/inbound `ROW_OPERATIONS` set. */ export interface CanonicalReactivateCommitInput extends CanonicalCommitBase { readonly kind: typeof CANONICAL_REACTIVATE_OPERATION; /** Current tombstoned field revisions used by each field CAS. */ readonly fields: readonly CanonicalFieldWrite[]; /** Tombstoned entity revision observed before reactivation. */ readonly expectedEntityRevision: number; } /** A row-level canonical mutation prepared from one core evaluation result. */ export type CanonicalCommitInput = CanonicalFieldCommitInput | CanonicalDeleteCommitInput | CanonicalReactivateCommitInput; /** Internal canonical reactivation operation tag (not part of public ROW_OPERATIONS). */ export declare const CANONICAL_REACTIVATE_OPERATION: "reactivate"; /** Observable result of a fenced canonical commit attempt. */ export type CanonicalCommitResult = { readonly kind: typeof CANONICAL_COMMIT_RESULT_KINDS.APPLIED; readonly entityRevision: number; readonly fieldRevisions: ReadonlyMap; } | { readonly kind: typeof CANONICAL_COMMIT_RESULT_KINDS.STALE; readonly target: CanonicalCommitStaleTarget; readonly fieldName: Applicability; } | { readonly kind: typeof CANONICAL_COMMIT_RESULT_KINDS.FENCED_OUT; } | { readonly kind: typeof CANONICAL_COMMIT_RESULT_KINDS.INVALID; readonly reason: string; }; /** * Commits canonical state and outbox effects inside an already-active async * SQL transaction. * * Call it from the same adapter transaction as the user entity mutation so a * database error cannot persist one side without the other. */ export declare function commitCanonicalChangesWithSql(sql: SqlExecutor, fence: FencingContext, input: CanonicalCommitInput): Promise; /** Commits canonical state in one adapter-owned transaction. */ export declare function commitCanonicalChangesWithAdapter(storage: SqlStorageAdapter, fence: FencingContext, input: CanonicalCommitInput): Promise; export {}; //# sourceMappingURL=canonicalCommit.d.ts.map