/** * Structural safety for capture (journal spec §2.3a rules 1, 3, 5 and 7; H4 * T12754, B T12775, NEW-8 T12786, N3 T12759). * * - {@link withSyncTriggersSuspended}: the rule-1 bracket. The capture * triggers are dropped, `fn` runs its DDL or data rewrite, and the triggers * are regenerated for the new schema, all in ONE transaction the bracket * opens and commits itself. A second connection's write waits on the * bracket's write lock and is captured by the reinstalled triggers. A body * that rebuilds tables declares them, and the bracket applies rule 2 (A, * T12774): foreign keys off before BEGIN, a foreign_key_check that refuses * only new violations before COMMIT, and the FK mode restored after. * - {@link touchSet}: the tables a rewrite can change, generated rather than * hand-written: the written tables, their FK-action children (CASCADE, * SET NULL, SET DEFAULT on delete; CASCADE on update), and every table a * trigger on any of those writes, to a fixed point. * - {@link markSuspect} / {@link withSuspectAccounting}: a rewriter whose * writes are not captured (triggers dropped, a lineage carry-forward, an * import) marks every sync-set table of its touch set `suspect:` in * `_sync_meta`; the sealer runs the repair diff over them before sealing * anything else (§4.4, S3). Only when the store has the sync schema. * * @task T12754 * @module store/sync/structural */ import type { DatabaseSync } from 'node:sqlite'; import type { TableScope } from '@cleocode/contracts'; /** A bracket whose `fn` committed or rolled back the bracket's transaction. */ export declare class BracketTransactionError extends Error { readonly code = "E_SYNC_BRACKET_TXN"; constructor(message: string); } /** A bracketed rebuild that would leave foreign-key violations it did not find. */ export declare class BracketForeignKeyError extends Error { readonly violations: readonly string[]; readonly code = "E_SYNC_BRACKET_FK_VIOLATION"; constructor(violations: readonly string[]); } /** Options of {@link withSyncTriggersSuspended}. */ export interface SyncSuspensionOptions { /** * The tables `fn` rebuilds (create a copy, copy the rows, DROP the original, * RENAME the copy), named as they are after the rebuild. Inside a * transaction `PRAGMA foreign_keys` is a no-op, so without this a rebuild's * DROP would cascade-delete child rows, uncaptured (§2.3a rule 2, A T12774). * When non-empty, the bracket turns foreign keys off BEFORE its BEGIN, * snapshots the violations of these tables and their FK children, refuses * only violations the snapshot did not hold, and restores the FK mode after. */ readonly rebuilds?: readonly string[]; } /** * Run `fn` with the capture triggers dropped, in one transaction this * bracket opens and commits (§2.3a rule 1). The triggers are reinstalled for * the schema `fn` leaves, before COMMIT. When capture is off, `fn` still runs * in the bracket's transaction and nothing is dropped. * * @param db - The store handle; must not be inside a transaction. * @param scope - The store's scope (selects the capture triggers to reinstall). * @param fn - The DDL or data rewrite. Must not end the transaction. * @param options - {@link SyncSuspensionOptions}: declare rebuilt tables. * @throws {BracketTransactionError} When called inside a transaction, or when * `fn` ends the bracket's transaction. * @throws {BracketForeignKeyError} When a declared rebuild leaves new FK violations. * @throws {ForeignKeysNotRestoredError} When the FK mode could not be restored. */ export declare function withSyncTriggersSuspended(db: DatabaseSync, scope: TableScope, fn: () => T, options?: SyncSuspensionOptions): T; /** * The touch set of a rewrite of `tables` (NEW-8): the tables themselves, their * FK-action children, and every table a trigger on any member writes, * repeated to a fixed point. Only existing tables are returned. */ export declare function touchSet(db: DatabaseSync, tables: readonly string[]): string[]; /** * Mark every sync-set table among `tables` `suspect:` in `_sync_meta`. A no-op * on a store without the sync schema. * * @returns The tables marked. */ export declare function markSuspect(db: DatabaseSync, scope: TableScope, tables: readonly string[]): string[]; /** The tables currently marked suspect. Read-only. */ export declare function suspectTables(db: DatabaseSync): string[]; /** * Run a rewriter whose writes may be uncaptured, and mark its generated touch * set suspect when `total_changes()` moved (rule 3). */ export declare function withSuspectAccounting(db: DatabaseSync, scope: TableScope, tables: readonly string[], fn: () => T): { result: T; suspect: string[]; }; //# sourceMappingURL=structural.d.ts.map