import { g as GraphBackend, q as SqlTableNames, R as RecordedInstant } from './types-BynPp5kU.js'; /** * One-time offline migration from timestamp-only recorded relations to numeric * revisions. The durable remap table lets applications translate checkpoints * stored outside TypeGraph before deleting the migration metadata. */ type MigrateLegacyRecordedTimeOptions = Readonly<{ backend: GraphBackend; /** Patch selected backend table names; unstated names remain configured. */ tableNames?: Partial | undefined; /** Override the durable legacy-anchor mapping table name. */ mappingTableName?: string | undefined; }>; type MigrateLegacyRecordedTimeResult = Readonly<{ /** `true` when timestamp columns were rewritten during this call. */ migrated: boolean; /** Number of graphs represented in the legacy commit order. */ graphs: number; /** Number of distinct legacy anchors available for remapping. */ anchors: number; /** Physical table retaining the old-anchor → revision mapping. */ mappingTableName: string; }>; type MigrateRecordedAnchorOptions = Readonly<{ backend: Pick; graphId: string; anchor: string; /** Patch selected backend table names; unstated names remain configured. */ tableNames?: Partial | undefined; mappingTableName?: string | undefined; }>; type DeleteLegacyRecordedAnchorMapOptions = Readonly<{ backend: Pick; graphId: string; /** Patch selected backend table names; unstated names remain configured. */ tableNames?: Partial | undefined; mappingTableName?: string | undefined; /** Drop the mapping table when this deletion leaves it empty. */ dropWhenEmpty?: boolean | undefined; }>; /** * Rewrites timestamp-only recorded relations to numeric revisions. * * Run offline before opening a Store with the new schema. The durable mapping * table is retained so external checkpoint stores can call * {@link migrateRecordedAnchor}; delete each graph's rows after its downstream * checkpoints have been rewritten. */ declare function migrateLegacyRecordedTime(options: MigrateLegacyRecordedTimeOptions): Promise; /** Remaps one timestamp-only checkpoint after {@link migrateLegacyRecordedTime}. */ declare function migrateRecordedAnchor(options: MigrateRecordedAnchorOptions): Promise; /** * Deletes one graph's legacy remap rows after downstream checkpoints migrate. * Set `dropWhenEmpty` to remove the migration table after the final graph. */ declare function deleteLegacyRecordedAnchorMap(options: DeleteLegacyRecordedAnchorMapOptions): Promise; /** A relation whose rows carry a validity window this repair can normalize. */ type RepairRelation = "nodes" | "edges" | "recordedNodes" | "recordedEdges"; /** * Which relations one call scans. * * `"live-and-recorded"` is the recommended scope. `"live"` is correct in * exactly two cases: the store captures no history and the `recorded_*` tables * do not exist, or the operator is deliberately preserving the recorded axis as * an audit record of what was stored before the repair — and accepts that * historical `asOfRecorded` reads keep returning the invisible shape. */ type RepairRelationScope = "live" | "live-and-recorded"; /** Inputs for detecting or repairing legacy inverted validity windows. */ type RepairInvertedWindowsOptions = Readonly<{ backend: GraphBackend; /** Omit to sweep every graph in the database. */ graphId?: string | undefined; /** Required: the scope is a decision, not a default. */ relations: RepairRelationScope; /** * `"report"` counts and writes nothing; `"apply"` counts and then normalizes * the rows it counted. */ mode: "report" | "apply"; /** * Patch selected backend table names, exactly as migrate-recorded-time does. * Unstated names continue to come from `backend.tableNames`; see * {@link resolvedTableNames}. */ tableNames?: Partial | undefined; }>; /** Counts and execution guarantees observed by one repair/report call. */ type RepairInvertedWindowsReport = Readonly<{ /** Echoes the scope actually scanned — a count of 0 and "not scanned" are different facts. */ relations: RepairRelationScope; /** * Rows whose stored window is inverted: found in `"report"` mode, repaired in * `"apply"` mode. `undefined` means NOT SCANNED, never "clean". */ counts: Readonly>; /** * Rows whose stored bounds are not canonical ISO and were therefore not * classified. SQLite only in substance: on PostgreSQL the columns are * `timestamptz`, so a scanned relation always reports `0` (never `undefined` * — that value is reserved for "not scanned", on both dialects). * * `"apply"` refuses while any scanned relation reports a non-zero count: * classifying those rows needs a timestamp semantics this repair does not * own, and skipping them silently would be an accepted option ignored. */ nonCanonical: Readonly>; /** * Whether every statement of this call ran in ONE transaction. `false` on a * backend that reports `capabilities.execution.interactiveTransactions === false`, where the call * degrades to per-relation statements. * * Reported by the seam, not inferred from backend object identity: * {@link runOptionallyInTransaction} explicitly tells its callback whether it * opened a transaction. "One snapshot" and "four snapshots" are different * facts about a report, and the report must state which occurred even when a * custom backend passes the same object into its transaction callback. * * When `false`, a `"report"`'s counts may come from different snapshots and a * crash mid-`"apply"` can leave the live axis repaired and the recorded axis * not. Both are survivable the same way: each relation's statement is * idempotent and convergent, so a re-run finishes the job and a later * `"report"` proves it. */ atomic: boolean; }>; /** * Counts — and, in `"apply"` mode, normalizes — rows whose stored validity * window is inverted. * * ```typescript * // Diagnose with the store's backend: `report` reads only, so it runs * // anywhere, including a capture-wrapped or statement-less backend. * const report = await repairInvertedValidityWindows({ * backend: anyBackend, * relations: "live-and-recorded", * mode: "report", * }); * * // Repair with the raw one, while writers are stopped. * await repairInvertedValidityWindows({ * backend: rawBackend, * relations: "live-and-recorded", * mode: "apply", * }); * ``` * * Idempotent and convergent: a second `"apply"` reports zero, because the rows * the first one repaired no longer match the predicate. * * No batching, deliberately. Unlike the recorded-time migration, which rewrites * every row, this statement touches only rows the library mis-stored — an empty * set on a healthy graph. A deployment that reports a count large enough to * worry about should run it per `graphId`. * * @throws ConfigurationError in `"apply"` mode when the backend cannot execute * statements, when the backend is a recorded-capture wrapper, or when any * scanned relation stores non-canonical bounds. A transaction TARGET that * disagrees with the top-level verdict (missing `executeStatement` the * top-level backend has) refuses separately, with I20's * `BUNDLE_PORT_SURFACE_MISMATCH` — the per-bundle port check * `statementExecutionMembers` performs, not a second spelling of this one. */ declare function repairInvertedValidityWindows(options: RepairInvertedWindowsOptions): Promise; export { type DeleteLegacyRecordedAnchorMapOptions as D, type MigrateLegacyRecordedTimeOptions as M, type RepairInvertedWindowsOptions as R, type MigrateLegacyRecordedTimeResult as a, type MigrateRecordedAnchorOptions as b, type RepairInvertedWindowsReport as c, type RepairRelation as d, type RepairRelationScope as e, deleteLegacyRecordedAnchorMap as f, migrateRecordedAnchor as g, migrateLegacyRecordedTime as m, repairInvertedValidityWindows as r };