@crazyhappyone/auto-graph 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -434,7 +434,7 @@ interface ConstraintSolverInput {
434
434
  direction: DiagramDirection;
435
435
  overlapSpacing?: number;
436
436
  minSiblingGap?: number;
437
- distributeContainedChildren?: boolean;
437
+ distributeContainedChildren?: boolean | "spread";
438
438
  boxes: ReadonlyMap<string, Box>;
439
439
  nodes: readonly NormalizedNode[];
440
440
  groups: readonly NormalizedGroup[];
@@ -448,6 +448,19 @@ interface ConstraintSolverResult {
448
448
 
449
449
  declare function applyLayoutConstraints(input: ConstraintSolverInput): ConstraintSolverResult;
450
450
 
451
+ interface QualityMetric {
452
+ readonly kind: QualityMetricKind;
453
+ readonly value: number;
454
+ readonly label: string;
455
+ }
456
+ type QualityMetricKind = "node-overlap" | "edge-crossing" | "bend-count" | "route-backtrack" | "label-collision";
457
+ interface QualityReport {
458
+ readonly metrics: QualityMetric[];
459
+ /** Aggregate score 0–100 (higher = better). */
460
+ readonly score: number;
461
+ readonly diagnostics: Diagnostic[];
462
+ }
463
+
451
464
  type DiagramStage = "intent" | "normalized" | "coordinated";
452
465
  type DiagramMetadata = JsonObject;
453
466
  interface IntentDiagram {
@@ -499,6 +512,7 @@ interface CoordinatedDiagram {
499
512
  bounds: Box;
500
513
  frame?: CoordinatedFrame;
501
514
  metadata?: DiagramMetadata;
515
+ qualityReport?: QualityReport;
502
516
  }
503
517
 
504
518
  type DslDiagnosticLayer = "parse" | "validate" | "solve" | "export" | "io";
@@ -568,6 +582,8 @@ interface ExportResult {
568
582
  }
569
583
  interface ExportOptions {
570
584
  title?: string;
585
+ /** Padding around diagram bounds for viewport metadata, in pixels. */
586
+ viewportPadding?: number;
571
587
  }
572
588
 
573
589
  declare function resolveOutputFormat(cliFormat?: string, dslFormat?: DslOutputFormat): {
@@ -597,6 +613,11 @@ declare function boxCenter(box: Box): Point;
597
613
  declare function expandBox(box: Box, margin: number | Insets): Box;
598
614
  declare function unionBoxes(boxes: readonly Box[]): Box;
599
615
  declare function intersectsAabb(a: Box, b: Box): boolean;
616
+ /**
617
+ * Area of overlap between two boxes, in square pixels.
618
+ * Returns 0 when the boxes do not intersect.
619
+ */
620
+ declare function overlapArea(first: Box, second: Box): number;
600
621
 
601
622
  interface LabelFitOptions {
602
623
  font: TextStyleOptions;
@@ -648,12 +669,27 @@ interface ShapeGeometry {
648
669
  declare function computeShapeGeometry(input: ShapeGeometryInput): ShapeGeometry;
649
670
  declare function getEdgePort(geometry: ShapeGeometry, toward: Point, preferredAnchor?: AnchorName): Point;
650
671
 
672
+ interface BoxSpatialIndexEntry {
673
+ id: string;
674
+ box: Box;
675
+ }
676
+ interface BoxSpatialIndex {
677
+ cellSize: number;
678
+ entries: ReadonlyMap<string, Box>;
679
+ cells: ReadonlyMap<string, readonly string[]>;
680
+ }
681
+ declare function createBoxSpatialIndex(entries: Iterable<BoxSpatialIndexEntry>, cellSize?: number): BoxSpatialIndex;
682
+ declare function queryBoxSpatialIndex(index: BoxSpatialIndex, box: Box): BoxSpatialIndexEntry[];
683
+ declare function querySegmentSpatialIndex(index: BoxSpatialIndex, start: Point, end: Point): BoxSpatialIndexEntry[];
684
+ declare function expandBoxForQuery(box: Box, margin: number): Box;
685
+
651
686
  interface DagreLayoutOptions {
652
687
  nodesep: number;
653
688
  ranksep: number;
654
689
  edgesep: number;
655
690
  marginx: number;
656
691
  marginy: number;
692
+ componentGap: number;
657
693
  ranker: "network-simplex" | "tight-tree" | "longest-path";
658
694
  }
659
695
  interface DagreLayoutNode {
@@ -677,6 +713,7 @@ interface InitialLayoutResult {
677
713
  }
678
714
 
679
715
  declare function runDagreInitialLayout(input: DagreLayoutInput): InitialLayoutResult;
716
+ declare function runComponentAwareDagreInitialLayout(input: DagreLayoutInput): InitialLayoutResult;
680
717
 
681
718
  type RouteKind = "orthogonal" | "straight" | "obstacle-avoiding";
682
719
  interface RouteEdgeInput {
@@ -688,6 +725,8 @@ interface RouteEdgeInput {
688
725
  targetAnchor?: AnchorName;
689
726
  obstacles?: readonly Box[];
690
727
  hardObstacles?: readonly Box[];
728
+ obstacleIndex?: BoxSpatialIndex;
729
+ hardObstacleIndex?: BoxSpatialIndex;
691
730
  /** Maximum greedy rerouting iterations (default 5). */
692
731
  maxRoutingAttempts?: number;
693
732
  }
@@ -709,16 +748,21 @@ type CanonicalJson = null | boolean | number | string | CanonicalJson[] | {
709
748
  declare function canonicalize(value: unknown, options?: CanonicalizeOptions): CanonicalJson;
710
749
  declare function stringifyCanonical(value: unknown, precision?: number): string;
711
750
 
751
+ type InitialLayoutMode = "dagre" | "positions";
712
752
  interface SolveDiagramOptions {
753
+ /** Selects the seed coordinates before constraints, routing, and export. */
754
+ initialLayout?: InitialLayoutMode;
713
755
  routeKind?: RouteKind;
714
756
  obstacleMargin?: number | Insets;
757
+ /** When true, compute quality score after solving (Issue #54, 方案 E). */
758
+ qualityScore?: boolean;
715
759
  /** Extra horizontal/vertical clearance reserved around nodes for edge corridors. */
716
760
  routingGutter?: number;
717
761
  overlapSpacing?: number;
718
762
  minLaneGutter?: number;
719
763
  prefitLabelSize?: boolean;
720
764
  minSiblingGap?: number;
721
- distributeContainedChildren?: boolean;
765
+ distributeContainedChildren?: boolean | "spread";
722
766
  pageBounds?: {
723
767
  width: number;
724
768
  height: number;
@@ -753,5 +797,73 @@ declare function solveDiagram(diagram: NormalizedDiagram, options?: SolveDiagram
753
797
  * @see SolveDiagramOptions.prefitLabelSize
754
798
  */
755
799
  declare function solveDiagramSafe(diagram: NormalizedDiagram, options?: SolveDiagramOptions): CoordinatedDiagram;
800
+ /**
801
+ * Build the default layout pipeline. Currently wraps `solveDiagram` in
802
+ * a single mega-phase so custom callers can replace individual phases
803
+ * (e.g. "initial-layout", "route-edges") without touching the rest.
804
+ *
805
+ * Individual phases will be extracted from the mega-phase in follow-up
806
+ * PRs for 方案 A (recursive layout) and 方案 B (corner-graph A*).
807
+ */
808
+ declare function createDefaultPipeline(): LayoutPipeline;
809
+
810
+ /** Shared mutable state flowing through every pipeline phase. */
811
+ interface LayoutState {
812
+ diagram: NormalizedDiagram;
813
+ options: SolveDiagramOptions;
814
+ nodes: NormalizedNode[];
815
+ edges: NormalizedEdge[];
816
+ groups: NormalizedGroup[];
817
+ swimlanes: Swimlane[];
818
+ constraints: Constraint[];
819
+ boxes: Map<string, Box>;
820
+ locks: Map<string, LayoutLock>;
821
+ nodeGeometry: Map<string, ShapeGeometry>;
822
+ coordinatedNodes: CoordinatedNode[];
823
+ coordinatedEdges: CoordinatedEdge[];
824
+ coordinatedGroups: CoordinatedGroup[];
825
+ coordinatedMatrices: CoordinatedMatrixBlock[];
826
+ coordinatedTables: CoordinatedTableBlock[];
827
+ coordinatedEvidencePanels: CoordinatedEvidencePanel[];
828
+ frame?: CoordinatedFrame;
829
+ baseTextAnnotations: SolvedTextAnnotation[];
830
+ edgeTextAnnotations: SolvedTextAnnotation[];
831
+ contentBounds: Box;
832
+ bounds: Box;
833
+ degraded: boolean;
834
+ diagnostics: Diagnostic[];
835
+ qualityReport?: QualityReport;
836
+ phaseTrace: PhaseTraceEntry[];
837
+ }
838
+ interface PhaseTraceEntry {
839
+ phase: string;
840
+ durationMs: number;
841
+ diagnosticsAdded: number;
842
+ }
843
+ /** A single pipeline phase — mutates `state` in-place. */
844
+ interface LayoutPhase {
845
+ readonly name: string;
846
+ run(state: LayoutState): void;
847
+ }
848
+
849
+ /**
850
+ * Pluggable layout pipeline (Issue #54, 方案 D).
851
+ *
852
+ * Phases run sequentially, each mutating the shared LayoutState.
853
+ * Custom pipelines are built with the fluent builder API:
854
+ *
855
+ * new LayoutPipeline()
856
+ * .addPhase(myPhase)
857
+ * .addBefore("apply-constraints", prePhase)
858
+ * .run(diagram, options);
859
+ */
860
+ declare class LayoutPipeline {
861
+ private phases;
862
+ addPhase(phase: LayoutPhase): this;
863
+ addBefore(refName: string, phase: LayoutPhase): this;
864
+ addAfter(refName: string, phase: LayoutPhase): this;
865
+ replacePhase(name: string, phase: LayoutPhase): this;
866
+ run(state: LayoutState): void;
867
+ }
756
868
 
757
- export { type AlignConstraint, type AlignmentAxis, type AnchorName, type AnchorPoint, type Arrowhead, type Box, type CanonicalJson, type CanonicalizeOptions, type Constraint, type ConstraintBase, type ConstraintSolverInput, type ConstraintSolverResult, type ConstraintTarget, type ConstraintTargetKind, type ContainerGeometry, type ContainerGeometryInput, type ContainmentConstraint, type CoordinatedDiagram, type CoordinatedEdge, type CoordinatedEvidencePanel, type CoordinatedFrame, type CoordinatedGroup, type CoordinatedMatrixBlock, type CoordinatedNode, type CoordinatedPort, type CoordinatedTableBlock, DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, type DagreLayoutEdge, type DagreLayoutInput, type DagreLayoutNode, type DagreLayoutOptions, type DefaultTextMeasurerOptions, DeterministicTextMeasurer, type Diagnostic, type DiagnosticPathSegment, type DiagnosticSeverity, type DiagramDirection, type DiagramFrame, type DiagramMetadata, type DiagramStage, type DistributeConstraint, type DistributionAxis, type DslDiagnostic, type DslDiagnosticLayer, type DslOutputFormat, type EdgeArrowhead, type EdgeEndpoint, type EdgeStrokeStyle, type EvidenceCell, type EvidencePanel, type EvidencePanelItem, type EvidencePanelKind, type EvidenceTextLayout, type ExactPositionConstraint, type ExportFormat, type ExportOptions, type ExportResult, type InitialLayoutResult, type Insets, type IntentDiagram, type IntentEdge, type IntentGroup, type IntentNode, type JsonObject, type JsonPrimitive, type JsonValue, type Label, type LabelFitOptions, LabelFitter, type LabelLayout, type LabelLineLayout, type LayoutLock, type LayoutLockSource, type MatrixBlock, type NodeBase, type NodeCompartments, type NodePort, type NodeShape, type NormalizeDiagramDslOptions, type NormalizeDiagramDslResult, type NormalizedDiagram, type NormalizedEdge, type NormalizedGroup, type NormalizedNode, type ParseDiagramDslOptions, type ParseDiagramDslResult, type ParsedEdgeShorthand, type Point, type PortKind, type PortShiftingOptions, type PortSide, type PreparedText, PretextTextMeasurer, type RelativePositionConstraint, type RelativePositionRelation, type RenderDiagramDslOptions, type RenderDiagramDslResult, type RouteEdgeInput, type RouteEdgeResult, type RouteKind, type ShapeGeometry, type ShapeGeometryInput, type Size, type SolveDiagramOptions, type SolvedTextAnnotation, type Swimlane, type SwimlaneLane, type SwimlaneLayout, type SwimlaneOrientation, type TableBlock, type TableColumn, type TableRow, type TextCursor, type TextLayout, type TextLayoutLine, type TextMeasurementBackend, type TextMeasurer, type TextStyleOptions, type TextSurfaceKind, type VisualStyle, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createDefaultTextMeasurer, expandBox, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, parseDiagramDsl, parseEdgeShorthand, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runDagreInitialLayout, simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
869
+ export { type AlignConstraint, type AlignmentAxis, type AnchorName, type AnchorPoint, type Arrowhead, type Box, type BoxSpatialIndex, type BoxSpatialIndexEntry, type CanonicalJson, type CanonicalizeOptions, type Constraint, type ConstraintBase, type ConstraintSolverInput, type ConstraintSolverResult, type ConstraintTarget, type ConstraintTargetKind, type ContainerGeometry, type ContainerGeometryInput, type ContainmentConstraint, type CoordinatedDiagram, type CoordinatedEdge, type CoordinatedEvidencePanel, type CoordinatedFrame, type CoordinatedGroup, type CoordinatedMatrixBlock, type CoordinatedNode, type CoordinatedPort, type CoordinatedTableBlock, DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, type DagreLayoutEdge, type DagreLayoutInput, type DagreLayoutNode, type DagreLayoutOptions, type DefaultTextMeasurerOptions, DeterministicTextMeasurer, type Diagnostic, type DiagnosticPathSegment, type DiagnosticSeverity, type DiagramDirection, type DiagramFrame, type DiagramMetadata, type DiagramStage, type DistributeConstraint, type DistributionAxis, type DslDiagnostic, type DslDiagnosticLayer, type DslOutputFormat, type EdgeArrowhead, type EdgeEndpoint, type EdgeStrokeStyle, type EvidenceCell, type EvidencePanel, type EvidencePanelItem, type EvidencePanelKind, type EvidenceTextLayout, type ExactPositionConstraint, type ExportFormat, type ExportOptions, type ExportResult, type InitialLayoutMode, type InitialLayoutResult, type Insets, type IntentDiagram, type IntentEdge, type IntentGroup, type IntentNode, type JsonObject, type JsonPrimitive, type JsonValue, type Label, type LabelFitOptions, LabelFitter, type LabelLayout, type LabelLineLayout, type LayoutLock, type LayoutLockSource, type LayoutPhase, LayoutPipeline, type LayoutState, type MatrixBlock, type NodeBase, type NodeCompartments, type NodePort, type NodeShape, type NormalizeDiagramDslOptions, type NormalizeDiagramDslResult, type NormalizedDiagram, type NormalizedEdge, type NormalizedGroup, type NormalizedNode, type ParseDiagramDslOptions, type ParseDiagramDslResult, type ParsedEdgeShorthand, type PhaseTraceEntry, type Point, type PortKind, type PortShiftingOptions, type PortSide, type PreparedText, PretextTextMeasurer, type RelativePositionConstraint, type RelativePositionRelation, type RenderDiagramDslOptions, type RenderDiagramDslResult, type RouteEdgeInput, type RouteEdgeResult, type RouteKind, type ShapeGeometry, type ShapeGeometryInput, type Size, type SolveDiagramOptions, type SolvedTextAnnotation, type Swimlane, type SwimlaneLane, type SwimlaneLayout, type SwimlaneOrientation, type TableBlock, type TableColumn, type TableRow, type TextCursor, type TextLayout, type TextLayoutLine, type TextMeasurementBackend, type TextMeasurer, type TextStyleOptions, type TextSurfaceKind, type VisualStyle, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createBoxSpatialIndex, createDefaultPipeline, createDefaultTextMeasurer, expandBox, expandBoxForQuery, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, overlapArea, parseDiagramDsl, parseEdgeShorthand, queryBoxSpatialIndex, querySegmentSpatialIndex, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runComponentAwareDagreInitialLayout, runDagreInitialLayout, simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
package/dist/index.d.ts CHANGED
@@ -434,7 +434,7 @@ interface ConstraintSolverInput {
434
434
  direction: DiagramDirection;
435
435
  overlapSpacing?: number;
436
436
  minSiblingGap?: number;
437
- distributeContainedChildren?: boolean;
437
+ distributeContainedChildren?: boolean | "spread";
438
438
  boxes: ReadonlyMap<string, Box>;
439
439
  nodes: readonly NormalizedNode[];
440
440
  groups: readonly NormalizedGroup[];
@@ -448,6 +448,19 @@ interface ConstraintSolverResult {
448
448
 
449
449
  declare function applyLayoutConstraints(input: ConstraintSolverInput): ConstraintSolverResult;
450
450
 
451
+ interface QualityMetric {
452
+ readonly kind: QualityMetricKind;
453
+ readonly value: number;
454
+ readonly label: string;
455
+ }
456
+ type QualityMetricKind = "node-overlap" | "edge-crossing" | "bend-count" | "route-backtrack" | "label-collision";
457
+ interface QualityReport {
458
+ readonly metrics: QualityMetric[];
459
+ /** Aggregate score 0–100 (higher = better). */
460
+ readonly score: number;
461
+ readonly diagnostics: Diagnostic[];
462
+ }
463
+
451
464
  type DiagramStage = "intent" | "normalized" | "coordinated";
452
465
  type DiagramMetadata = JsonObject;
453
466
  interface IntentDiagram {
@@ -499,6 +512,7 @@ interface CoordinatedDiagram {
499
512
  bounds: Box;
500
513
  frame?: CoordinatedFrame;
501
514
  metadata?: DiagramMetadata;
515
+ qualityReport?: QualityReport;
502
516
  }
503
517
 
504
518
  type DslDiagnosticLayer = "parse" | "validate" | "solve" | "export" | "io";
@@ -568,6 +582,8 @@ interface ExportResult {
568
582
  }
569
583
  interface ExportOptions {
570
584
  title?: string;
585
+ /** Padding around diagram bounds for viewport metadata, in pixels. */
586
+ viewportPadding?: number;
571
587
  }
572
588
 
573
589
  declare function resolveOutputFormat(cliFormat?: string, dslFormat?: DslOutputFormat): {
@@ -597,6 +613,11 @@ declare function boxCenter(box: Box): Point;
597
613
  declare function expandBox(box: Box, margin: number | Insets): Box;
598
614
  declare function unionBoxes(boxes: readonly Box[]): Box;
599
615
  declare function intersectsAabb(a: Box, b: Box): boolean;
616
+ /**
617
+ * Area of overlap between two boxes, in square pixels.
618
+ * Returns 0 when the boxes do not intersect.
619
+ */
620
+ declare function overlapArea(first: Box, second: Box): number;
600
621
 
601
622
  interface LabelFitOptions {
602
623
  font: TextStyleOptions;
@@ -648,12 +669,27 @@ interface ShapeGeometry {
648
669
  declare function computeShapeGeometry(input: ShapeGeometryInput): ShapeGeometry;
649
670
  declare function getEdgePort(geometry: ShapeGeometry, toward: Point, preferredAnchor?: AnchorName): Point;
650
671
 
672
+ interface BoxSpatialIndexEntry {
673
+ id: string;
674
+ box: Box;
675
+ }
676
+ interface BoxSpatialIndex {
677
+ cellSize: number;
678
+ entries: ReadonlyMap<string, Box>;
679
+ cells: ReadonlyMap<string, readonly string[]>;
680
+ }
681
+ declare function createBoxSpatialIndex(entries: Iterable<BoxSpatialIndexEntry>, cellSize?: number): BoxSpatialIndex;
682
+ declare function queryBoxSpatialIndex(index: BoxSpatialIndex, box: Box): BoxSpatialIndexEntry[];
683
+ declare function querySegmentSpatialIndex(index: BoxSpatialIndex, start: Point, end: Point): BoxSpatialIndexEntry[];
684
+ declare function expandBoxForQuery(box: Box, margin: number): Box;
685
+
651
686
  interface DagreLayoutOptions {
652
687
  nodesep: number;
653
688
  ranksep: number;
654
689
  edgesep: number;
655
690
  marginx: number;
656
691
  marginy: number;
692
+ componentGap: number;
657
693
  ranker: "network-simplex" | "tight-tree" | "longest-path";
658
694
  }
659
695
  interface DagreLayoutNode {
@@ -677,6 +713,7 @@ interface InitialLayoutResult {
677
713
  }
678
714
 
679
715
  declare function runDagreInitialLayout(input: DagreLayoutInput): InitialLayoutResult;
716
+ declare function runComponentAwareDagreInitialLayout(input: DagreLayoutInput): InitialLayoutResult;
680
717
 
681
718
  type RouteKind = "orthogonal" | "straight" | "obstacle-avoiding";
682
719
  interface RouteEdgeInput {
@@ -688,6 +725,8 @@ interface RouteEdgeInput {
688
725
  targetAnchor?: AnchorName;
689
726
  obstacles?: readonly Box[];
690
727
  hardObstacles?: readonly Box[];
728
+ obstacleIndex?: BoxSpatialIndex;
729
+ hardObstacleIndex?: BoxSpatialIndex;
691
730
  /** Maximum greedy rerouting iterations (default 5). */
692
731
  maxRoutingAttempts?: number;
693
732
  }
@@ -709,16 +748,21 @@ type CanonicalJson = null | boolean | number | string | CanonicalJson[] | {
709
748
  declare function canonicalize(value: unknown, options?: CanonicalizeOptions): CanonicalJson;
710
749
  declare function stringifyCanonical(value: unknown, precision?: number): string;
711
750
 
751
+ type InitialLayoutMode = "dagre" | "positions";
712
752
  interface SolveDiagramOptions {
753
+ /** Selects the seed coordinates before constraints, routing, and export. */
754
+ initialLayout?: InitialLayoutMode;
713
755
  routeKind?: RouteKind;
714
756
  obstacleMargin?: number | Insets;
757
+ /** When true, compute quality score after solving (Issue #54, 方案 E). */
758
+ qualityScore?: boolean;
715
759
  /** Extra horizontal/vertical clearance reserved around nodes for edge corridors. */
716
760
  routingGutter?: number;
717
761
  overlapSpacing?: number;
718
762
  minLaneGutter?: number;
719
763
  prefitLabelSize?: boolean;
720
764
  minSiblingGap?: number;
721
- distributeContainedChildren?: boolean;
765
+ distributeContainedChildren?: boolean | "spread";
722
766
  pageBounds?: {
723
767
  width: number;
724
768
  height: number;
@@ -753,5 +797,73 @@ declare function solveDiagram(diagram: NormalizedDiagram, options?: SolveDiagram
753
797
  * @see SolveDiagramOptions.prefitLabelSize
754
798
  */
755
799
  declare function solveDiagramSafe(diagram: NormalizedDiagram, options?: SolveDiagramOptions): CoordinatedDiagram;
800
+ /**
801
+ * Build the default layout pipeline. Currently wraps `solveDiagram` in
802
+ * a single mega-phase so custom callers can replace individual phases
803
+ * (e.g. "initial-layout", "route-edges") without touching the rest.
804
+ *
805
+ * Individual phases will be extracted from the mega-phase in follow-up
806
+ * PRs for 方案 A (recursive layout) and 方案 B (corner-graph A*).
807
+ */
808
+ declare function createDefaultPipeline(): LayoutPipeline;
809
+
810
+ /** Shared mutable state flowing through every pipeline phase. */
811
+ interface LayoutState {
812
+ diagram: NormalizedDiagram;
813
+ options: SolveDiagramOptions;
814
+ nodes: NormalizedNode[];
815
+ edges: NormalizedEdge[];
816
+ groups: NormalizedGroup[];
817
+ swimlanes: Swimlane[];
818
+ constraints: Constraint[];
819
+ boxes: Map<string, Box>;
820
+ locks: Map<string, LayoutLock>;
821
+ nodeGeometry: Map<string, ShapeGeometry>;
822
+ coordinatedNodes: CoordinatedNode[];
823
+ coordinatedEdges: CoordinatedEdge[];
824
+ coordinatedGroups: CoordinatedGroup[];
825
+ coordinatedMatrices: CoordinatedMatrixBlock[];
826
+ coordinatedTables: CoordinatedTableBlock[];
827
+ coordinatedEvidencePanels: CoordinatedEvidencePanel[];
828
+ frame?: CoordinatedFrame;
829
+ baseTextAnnotations: SolvedTextAnnotation[];
830
+ edgeTextAnnotations: SolvedTextAnnotation[];
831
+ contentBounds: Box;
832
+ bounds: Box;
833
+ degraded: boolean;
834
+ diagnostics: Diagnostic[];
835
+ qualityReport?: QualityReport;
836
+ phaseTrace: PhaseTraceEntry[];
837
+ }
838
+ interface PhaseTraceEntry {
839
+ phase: string;
840
+ durationMs: number;
841
+ diagnosticsAdded: number;
842
+ }
843
+ /** A single pipeline phase — mutates `state` in-place. */
844
+ interface LayoutPhase {
845
+ readonly name: string;
846
+ run(state: LayoutState): void;
847
+ }
848
+
849
+ /**
850
+ * Pluggable layout pipeline (Issue #54, 方案 D).
851
+ *
852
+ * Phases run sequentially, each mutating the shared LayoutState.
853
+ * Custom pipelines are built with the fluent builder API:
854
+ *
855
+ * new LayoutPipeline()
856
+ * .addPhase(myPhase)
857
+ * .addBefore("apply-constraints", prePhase)
858
+ * .run(diagram, options);
859
+ */
860
+ declare class LayoutPipeline {
861
+ private phases;
862
+ addPhase(phase: LayoutPhase): this;
863
+ addBefore(refName: string, phase: LayoutPhase): this;
864
+ addAfter(refName: string, phase: LayoutPhase): this;
865
+ replacePhase(name: string, phase: LayoutPhase): this;
866
+ run(state: LayoutState): void;
867
+ }
756
868
 
757
- export { type AlignConstraint, type AlignmentAxis, type AnchorName, type AnchorPoint, type Arrowhead, type Box, type CanonicalJson, type CanonicalizeOptions, type Constraint, type ConstraintBase, type ConstraintSolverInput, type ConstraintSolverResult, type ConstraintTarget, type ConstraintTargetKind, type ContainerGeometry, type ContainerGeometryInput, type ContainmentConstraint, type CoordinatedDiagram, type CoordinatedEdge, type CoordinatedEvidencePanel, type CoordinatedFrame, type CoordinatedGroup, type CoordinatedMatrixBlock, type CoordinatedNode, type CoordinatedPort, type CoordinatedTableBlock, DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, type DagreLayoutEdge, type DagreLayoutInput, type DagreLayoutNode, type DagreLayoutOptions, type DefaultTextMeasurerOptions, DeterministicTextMeasurer, type Diagnostic, type DiagnosticPathSegment, type DiagnosticSeverity, type DiagramDirection, type DiagramFrame, type DiagramMetadata, type DiagramStage, type DistributeConstraint, type DistributionAxis, type DslDiagnostic, type DslDiagnosticLayer, type DslOutputFormat, type EdgeArrowhead, type EdgeEndpoint, type EdgeStrokeStyle, type EvidenceCell, type EvidencePanel, type EvidencePanelItem, type EvidencePanelKind, type EvidenceTextLayout, type ExactPositionConstraint, type ExportFormat, type ExportOptions, type ExportResult, type InitialLayoutResult, type Insets, type IntentDiagram, type IntentEdge, type IntentGroup, type IntentNode, type JsonObject, type JsonPrimitive, type JsonValue, type Label, type LabelFitOptions, LabelFitter, type LabelLayout, type LabelLineLayout, type LayoutLock, type LayoutLockSource, type MatrixBlock, type NodeBase, type NodeCompartments, type NodePort, type NodeShape, type NormalizeDiagramDslOptions, type NormalizeDiagramDslResult, type NormalizedDiagram, type NormalizedEdge, type NormalizedGroup, type NormalizedNode, type ParseDiagramDslOptions, type ParseDiagramDslResult, type ParsedEdgeShorthand, type Point, type PortKind, type PortShiftingOptions, type PortSide, type PreparedText, PretextTextMeasurer, type RelativePositionConstraint, type RelativePositionRelation, type RenderDiagramDslOptions, type RenderDiagramDslResult, type RouteEdgeInput, type RouteEdgeResult, type RouteKind, type ShapeGeometry, type ShapeGeometryInput, type Size, type SolveDiagramOptions, type SolvedTextAnnotation, type Swimlane, type SwimlaneLane, type SwimlaneLayout, type SwimlaneOrientation, type TableBlock, type TableColumn, type TableRow, type TextCursor, type TextLayout, type TextLayoutLine, type TextMeasurementBackend, type TextMeasurer, type TextStyleOptions, type TextSurfaceKind, type VisualStyle, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createDefaultTextMeasurer, expandBox, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, parseDiagramDsl, parseEdgeShorthand, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runDagreInitialLayout, simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
869
+ export { type AlignConstraint, type AlignmentAxis, type AnchorName, type AnchorPoint, type Arrowhead, type Box, type BoxSpatialIndex, type BoxSpatialIndexEntry, type CanonicalJson, type CanonicalizeOptions, type Constraint, type ConstraintBase, type ConstraintSolverInput, type ConstraintSolverResult, type ConstraintTarget, type ConstraintTargetKind, type ContainerGeometry, type ContainerGeometryInput, type ContainmentConstraint, type CoordinatedDiagram, type CoordinatedEdge, type CoordinatedEvidencePanel, type CoordinatedFrame, type CoordinatedGroup, type CoordinatedMatrixBlock, type CoordinatedNode, type CoordinatedPort, type CoordinatedTableBlock, DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, type DagreLayoutEdge, type DagreLayoutInput, type DagreLayoutNode, type DagreLayoutOptions, type DefaultTextMeasurerOptions, DeterministicTextMeasurer, type Diagnostic, type DiagnosticPathSegment, type DiagnosticSeverity, type DiagramDirection, type DiagramFrame, type DiagramMetadata, type DiagramStage, type DistributeConstraint, type DistributionAxis, type DslDiagnostic, type DslDiagnosticLayer, type DslOutputFormat, type EdgeArrowhead, type EdgeEndpoint, type EdgeStrokeStyle, type EvidenceCell, type EvidencePanel, type EvidencePanelItem, type EvidencePanelKind, type EvidenceTextLayout, type ExactPositionConstraint, type ExportFormat, type ExportOptions, type ExportResult, type InitialLayoutMode, type InitialLayoutResult, type Insets, type IntentDiagram, type IntentEdge, type IntentGroup, type IntentNode, type JsonObject, type JsonPrimitive, type JsonValue, type Label, type LabelFitOptions, LabelFitter, type LabelLayout, type LabelLineLayout, type LayoutLock, type LayoutLockSource, type LayoutPhase, LayoutPipeline, type LayoutState, type MatrixBlock, type NodeBase, type NodeCompartments, type NodePort, type NodeShape, type NormalizeDiagramDslOptions, type NormalizeDiagramDslResult, type NormalizedDiagram, type NormalizedEdge, type NormalizedGroup, type NormalizedNode, type ParseDiagramDslOptions, type ParseDiagramDslResult, type ParsedEdgeShorthand, type PhaseTraceEntry, type Point, type PortKind, type PortShiftingOptions, type PortSide, type PreparedText, PretextTextMeasurer, type RelativePositionConstraint, type RelativePositionRelation, type RenderDiagramDslOptions, type RenderDiagramDslResult, type RouteEdgeInput, type RouteEdgeResult, type RouteKind, type ShapeGeometry, type ShapeGeometryInput, type Size, type SolveDiagramOptions, type SolvedTextAnnotation, type Swimlane, type SwimlaneLane, type SwimlaneLayout, type SwimlaneOrientation, type TableBlock, type TableColumn, type TableRow, type TextCursor, type TextLayout, type TextLayoutLine, type TextMeasurementBackend, type TextMeasurer, type TextStyleOptions, type TextSurfaceKind, type VisualStyle, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createBoxSpatialIndex, createDefaultPipeline, createDefaultTextMeasurer, expandBox, expandBoxForQuery, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, overlapArea, parseDiagramDsl, parseEdgeShorthand, queryBoxSpatialIndex, querySegmentSpatialIndex, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runComponentAwareDagreInitialLayout, runDagreInitialLayout, simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };