import { OrmException } from './exceptions.js'; import type { ModelBase } from './model.js'; import { IJunctionDelta, IOrphanDelta, Subject, SubjectSet } from './subject.js'; /** * Raised when the insert order cannot be satisfied because two or more rows reference each * other through non-deferrable foreign keys. */ export declare class OrmCycleException extends OrmException { } /** * A `SubjectSet` in execution order. */ export interface ISortedPlan { /** Insert subjects, every parent before every child that references it. */ Inserts: Subject[]; /** Update subjects, followed by insert subjects carrying deferred foreign keys. */ Updates: Subject[]; Junctions: IJunctionDelta[]; /** Orphan actions, children before parents. */ Orphans: IOrphanDelta[]; } export declare class SubjectSorter { /** * Orders a subject set for execution. * * @param set - output of `SubjectBuilder.build()` * @throws OrmCycleException when a non-self-referencing foreign-key cycle makes the order * unsatisfiable */ sort(set: SubjectSet): ISortedPlan; /** * Kahn's algorithm over the insert subjects, in O(V + E). * * Each subject carries a count of how many not-yet-emitted subjects it must follow, plus the * list of subjects waiting on IT. Emitting a subject decrements its dependents' counters and * moves any that reach zero onto the ready queue, so no pass ever rescans the whole graph. * The previous shape rebuilt the entire dependency map and re-filtered every insert on every * pass — O(V² · E) on a deep chain, which is exactly the shape `deferSelfReferences` exists * to serve ( a self-referencing tree inserted parent-by-parent ). * * Stable: the queue is seeded and refilled in the subjects' own order, so a dependency-free * graph comes out exactly as it went in. */ protected order(inserts: Subject[]): Subject[]; /** * In-degree per remaining subject, and the reverse edges needed to decrement them. * * `pending` counts DISTINCT targets: two foreign keys on one subject pointing at the same * target are one dependency, and counting them twice would leave a counter that never * reaches zero and a spurious cycle report. */ protected buildDegrees(inserts: Subject[], byModel: Map, remaining: Set): { pending: Map; dependents: Map; }; /** * Breaks a cycle by deferring the foreign keys that point at the *same model* — a * self-referencing hierarchy, which is a cycle between models but not between rows. * The row is inserted without the column and a follow-up UPDATE sets it. * * @returns true when at least one foreign key was deferred, i.e. progress is possible */ protected deferSelfReferences(remaining: Set, byModel: Map): boolean; /** * Children before parents, so a DELETE never strands a foreign key. A model that does not * appear in the insert order at all keeps its relative position at the front. */ protected orderOrphans(orphans: IOrphanDelta[], inserts: Subject[]): IOrphanDelta[]; } //# sourceMappingURL=subject-sorter.d.ts.map