/** Storage reads used by System_State reconciliation. */ import { type EffectStatus } from "../../../contracts/domain/model/constants.js"; import type { SqlExecutor, SqlStorageAdapter } from "../../../contracts/storage/sql.js"; /** Canonical field row used to assemble the desired System_State projection. */ export interface ReconciliationDesiredSystemStateRow { readonly entityId: string; readonly rowBindingId: string; readonly anchorReference: string; readonly entityRevision: number; readonly fieldName: string; readonly normalizedValue: string; readonly ownership: string; } /** Confirmed visible state used by reconciliation baseline planning. */ export interface ReconciliationVisibleState { readonly confirmedVisibleRevision: number | null; readonly confirmedSnapshotHash: string | null; } /** Latest effect used by reconciliation baseline planning. */ export interface ReconciliationLatestEffect { readonly streamSequence: number | null; readonly expectedVisibleRevision: number | null; readonly expectedVisibleHash: string | null; readonly status: EffectStatus; readonly payloadJson: string | null; } /** Read set used to plan one correction without exposing SQL row names. */ export interface ReconciliationCorrectionState { readonly latestEffect: ReconciliationLatestEffect | undefined; readonly visibleState: ReconciliationVisibleState | undefined; } /** * Canonical rows that should be visible in System_State, ordered for keyset * pagination. This is the single implementation of the desired-state query: * the sync-engine reconciliation scanner imports it instead of carrying its * own copy, so the projection shape can only change in one place. */ export declare const READ_DESIRED_SYSTEM_STATE_SQL = "\n SELECT\n entity.entity_id AS entity_id,\n binding.row_binding_id AS row_binding_id,\n binding.anchor_reference AS anchor_reference,\n entity.entity_revision AS entity_revision,\n field.field_name AS field_name,\n field.normalized_value AS normalized_value,\n field.ownership AS ownership\n FROM entity_state AS entity\n JOIN row_binding AS binding\n ON binding.entity_id = entity.entity_id\n AND binding.logical_sheet_id = ?\n AND binding.state = 'active'\n JOIN entity_field_state AS field\n ON field.entity_id = entity.entity_id\n WHERE entity.status = 'active'\n ORDER BY entity.entity_id, field.field_name\n"; /** * Maximum flat rows read per scan chunk. Still bounds the single-table * binding pages; the entity-batched desired/canonical pages below are * bounded by `RECONCILIATION_SCAN_ENTITY_PAGE_SIZE` instead. */ export declare const RECONCILIATION_SCAN_CHUNK_SIZE = 1000; /** * Maximum entities per entity-batched scan chunk. One chunk holds whole * entities only (fields × bindings), so scan memory stays flat while the * per-page cost stays bounded: the entity page is an `entity_state` primary * key range scan, field fetches are `entity_field_state` PK prefix seeks, * and binding fetches are `row_binding_entity_idx` covering seeks — no * temp-b-tree sort anywhere (verified with EXPLAIN QUERY PLAN). */ export declare const RECONCILIATION_SCAN_ENTITY_PAGE_SIZE = 250; /** Keyset cursor for a paged desired-state chunk: the last entity already seen. */ export interface ReconciliationDesiredChunkCursor { readonly entityId: string; } /** One active entity in primary key order. */ export interface ReconciliationPagedEntity { readonly entityId: string; readonly entityRevision: number; } /** * Pages active entities in primary key order (range scan, no sort). Shared * driver for the entity-batched scan readers: every page holds whole * entities, so chunk boundaries never split an entity's rows and the * cursor (`last entity paged`) can neither skip nor repeat rows. */ export declare function readActiveEntityPageWithSql(sql: SqlExecutor, afterEntityId: string | undefined, limit: number): Promise; /** One entity's active bindings for a sheet. */ export interface ReconciliationEntityBinding { readonly rowBindingId: string; readonly anchorReference: string; } /** * One entity's active bindings (covering seek on `row_binding_entity_idx`, * no sort). Entities without an active binding yield no rows, exactly like * the inner join of the full queries. */ export declare function readEntityBindingsWithSql(sql: SqlExecutor, logicalSheetId: string, entityId: string): Promise; /** One entity's fields in primary key order (prefix seek, no sort). */ export interface ReconciliationEntityField { readonly fieldName: string; readonly normalizedValue: string; readonly ownership: string; } /** * One entity's fields, optionally ownership-filtered. PK prefix seek, no * sort; `ownership` narrows to the user-owned projection subset. */ export declare function readEntityFieldsWithSql(sql: SqlExecutor, entityId: string, ownership: "user" | undefined): Promise; /** One entity-batched chunk: whole entities as flat rows plus progress. */ export interface ReconciliationDesiredEntityChunk { readonly rows: readonly ReconciliationDesiredSystemStateRow[]; /** Entities paged (including binding-less ones) — the termination signal. */ readonly entityCount: number; /** Last entity paged — the next cursor (absent only when empty). */ readonly lastEntityId: string | undefined; } /** * Reads one bounded chunk of whole entities as flat canonical rows, in the * same global `(entity_id, field_name)` order as the full query. Pass no * cursor for the first chunk, then `{ entityId }` of the last entity paged * as the next cursor; an empty chunk (or `entityCount < limit`) ends the * scan. Only `limit` entities (with their fields × bindings) are ever * materialized per call, so scan memory is O(chunk) at bounded per-page * cost — unlike a flat cross-table keyset, whose row-value predicate over * joined tables forces SQLite to materialize and sort the whole join per * page. Multi-binding entities emit one row per (binding, field) with the * smallest `row_binding_id` first, so grouping stays deterministic. */ export declare function readReconciliationDesiredSystemStateChunkWithSql(sql: SqlExecutor, logicalSheetId: string, after: ReconciliationDesiredChunkCursor | undefined, limit?: number): Promise; /** Reads the canonical rows that should be visible in System_State. */ export declare function readReconciliationDesiredSystemStateWithSql(sql: SqlExecutor, logicalSheetId: string): Promise; /** Reads the canonical rows that should be visible in System_State. */ export declare function readReconciliationDesiredSystemStateWithAdapter(storage: SqlStorageAdapter, logicalSheetId: string): Promise; /** Reads confirmed visible state for one reconciliation row. */ export declare function readReconciliationVisibleStateWithSql(sql: SqlExecutor, physicalSheetId: string, rowBindingId: string): Promise; /** Reads the latest outbox effect for one reconciliation target. */ export declare function readReconciliationLatestEffectWithSql(sql: SqlExecutor, logicalSheetId: string, entityId: string): Promise; /** Reads the latest effect and visible baseline in one adapter-owned context. */ export declare function readReconciliationCorrectionStateWithAdapter(storage: SqlStorageAdapter, input: { readonly logicalSheetId: string; readonly physicalSheetId: string; readonly entityId: string; readonly rowBindingId: string; }): Promise; //# sourceMappingURL=reconciliationSql.d.ts.map