/** * The change journal's own schema, applied lazily. * * The DDL lives in `packages/core/migrations/sync-journal//migration.sql`, * one folder per migration, like the drizzle lineages. It is NOT a drizzle * lineage: it runs when a `sync.*` flag is first enabled on a store, or when * `cleo project link` binds the project store to a replica * (`ensureProjectReplica`, device contract §3.7) with every flag still off * ({@link ensureSyncSchema}). A store that is neither synced nor linked never * gains a table or a journal row. (Do not edit migration.sql comments: their * hash is recorded per store.) Applied folders are recorded in * `_sync_meta` under `schema:` with the sha256 of the folder's SQL, * never in `__drizzle_migrations`. A folder whose SQL changed after it was * applied is refused with {@link SyncSchemaHashDriftError}, never skipped. * * @task T12342 * @module store/sync/schema */ import type { DatabaseSync } from 'node:sqlite'; /** The migrations sub-directory that holds the sync schema. */ export declare const SYNC_SCHEMA_SET = "sync-journal"; /** * `_sync_meta` key prefix of a stream's genesis cut (§2.11 §10): S4 records * `${GENESIS_CUT_KEY_PREFIX}` when it cuts genesis for that stream. * The repair diff reads it to know the stream has started (T13217), so both * sides name the key through this constant, never a hand-typed string. */ export declare const GENESIS_CUT_KEY_PREFIX = "genesis_cut:"; /** One sync schema folder. */ export interface SyncSchemaFolder { readonly name: string; readonly sql: string; /** sha256 of `sql`, hex. */ readonly hash: string; } /** * An applied sync schema folder whose SQL no longer matches what was applied * (in the spirit of `E_MIGRATION_HASH_DRIFT`). Editing an applied folder is * never correct: add a new folder instead. */ export declare class SyncSchemaHashDriftError extends Error { readonly folder: string; readonly applied: string; readonly current: string; readonly code = "E_SYNC_SCHEMA_HASH_DRIFT"; constructor(folder: string, applied: string, current: string); } /** Whether a table exists in the `main` schema. Read-only. */ export declare function hasTable(db: DatabaseSync, table: string): boolean; /** Marker key recording that the one-time audit secret scrub ran (T13857). */ export declare const AUDIT_SCRUB_MARKER = "audit_secret_scrub_v1"; /** * The local-only table holding {@link AUDIT_SCRUB_MARKER}: * `tasks_row_identity_meta` on a project store, `_sync_meta` where that is * absent (a global store that has run sync). `null` when neither exists. */ export declare function auditScrubMarkerTable(db: DatabaseSync): string | null; /** Whether the one-time audit scrub still has to run on this store. Read-only. */ export declare function auditScrubPending(db: DatabaseSync): boolean; /** The local-only alias table (sync-journal folder `20261010150000_t13397-uid-alias`). */ export declare const UID_ALIAS_JOURNAL_TABLE = "_sync_uid_alias"; /** One reference boundary per (table, old uid, origin) (sync-journal folder `20261010160000_t13399-rekey-follow`). */ export declare const UID_REF_ALIAS_JOURNAL_TABLE = "_sync_uid_ref_alias"; /** * Whether `uid` is the old uid of a re-key this replica owes or made an * announcement of (T13399): the stream carried it (the origin's insert and * K), so the sealer never drops the announcement as a re-key of a uid no * replica knew. * * @param db - The store. * @param table - The table. * @param uid - The uid. */ export declare function isAnnouncedOldUid(db: DatabaseSync, table: string, uid: string): boolean; /** * Whether a K this replica is sealing is an announcement (`markAliasPlaced` in uid-alias.ts): * the re-key it names was already applied here from another replica, so it * moves nothing and only draws this replica's reference boundary. * * @param db - The store. * @param table - The K's table. * @param oldUid - The K's uid. * @param oldBfp - The K's old birth fingerprint. * @param newUid - The K's new uid. */ export declare function isAnnouncedRekey(db: DatabaseSync, table: string, oldUid: string, oldBfp: string, newUid: string): boolean; /** The sync schema folders, oldest first. */ export declare function syncSchemaFolders(root?: string): SyncSchemaFolder[]; /** * The schema folders already applied to this store, with the sha256 each was * applied with. Read-only: a store with no `_sync_meta` has none. */ export declare function appliedSyncSchemaHashes(db: DatabaseSync): Map; /** The names of the schema folders already applied to this store. Read-only. */ export declare function appliedSyncSchema(db: DatabaseSync): string[]; /** * Apply every sync schema folder this store has not applied yet, in one * transaction (a savepoint when the caller already holds one). * * The applied set is read again INSIDE the transaction, under the write * lock, so two processes enabling a flag at once apply each folder once. * * @param db - The store handle. * @param options - `root` overrides the schema folder (tests); `now` stamps * the journal rows; `beforeLock` runs between the unlocked pre-check and * taking the lock (a test seam for the two-process race). * @returns The folders applied by this call. * @throws {SyncSchemaHashDriftError} When an applied folder's SQL changed. */ export declare function ensureSyncSchema(db: DatabaseSync, options?: { root?: string; now?: Date; beforeLock?: () => void; }): string[]; /** * Re-run every APPLIED sync schema folder's SQL (`CREATE … IF NOT EXISTS`, * and `ADD COLUMN` only where the column is missing) when one of the sync * tables is missing: a store whose `_sync_capture` was dropped with capture * triggers still present fails every captured write, and the journal * already says the folder ran (§2.3a rule 9). A store with every table * present is left untouched. * * @returns Whether anything was re-run. */ export declare function healSyncSchema(db: DatabaseSync, expected: readonly string[], options?: { root?: string; }): boolean; //# sourceMappingURL=schema.d.ts.map