@tscircuit/fanout-solver 0.0.14 → 0.0.15

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.
Files changed (2) hide show
  1. package/lib/route-bus.ts +26 -4
  2. package/package.json +2 -1
package/lib/route-bus.ts CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  } from "./geometry"
13
13
  import { getLayerSpan } from "./layer-names"
14
14
  import type {
15
+ Bounds,
15
16
  FanoutDirection,
16
17
  FanoutRoutePlan,
17
18
  Point2D,
@@ -147,6 +148,23 @@ function getConnectionRank(
147
148
  return connectionRank
148
149
  }
149
150
 
151
+ function getRoutableBounds(
152
+ srjBounds: SimpleRouteJson["bounds"],
153
+ sharedBoundary: Bounds,
154
+ ): SimpleRouteJson["bounds"] {
155
+ // Fanout routes must reach the shared boundary and terminate exactly on it.
156
+ // When that boundary sits outside srj.bounds -- which is what
157
+ // fanoutBoundaryPadding does, since it pads the boundary without widening
158
+ // the routing area -- containment has to follow the boundary, or every plan
159
+ // is rejected before its geometry is ever considered.
160
+ return {
161
+ minX: Math.min(srjBounds.minX, sharedBoundary.minX),
162
+ maxX: Math.max(srjBounds.maxX, sharedBoundary.maxX),
163
+ minY: Math.min(srjBounds.minY, sharedBoundary.minY),
164
+ maxY: Math.max(srjBounds.maxY, sharedBoundary.maxY),
165
+ }
166
+ }
167
+
150
168
  function pointIsInsideBounds(
151
169
  point: Point2D,
152
170
  bounds: SimpleRouteJson["bounds"],
@@ -668,15 +686,17 @@ function planIsClear(params: {
668
686
  plan: FanoutRoutePlan
669
687
  otherPlans: FanoutRoutePlan[]
670
688
  srj: SimpleRouteJson
689
+ sharedBoundary: Bounds
671
690
  clearance: number
672
691
  }): boolean {
673
- const { plan, otherPlans, srj, clearance } = params
692
+ const { plan, otherPlans, srj, sharedBoundary, clearance } = params
693
+ const routableBounds = getRoutableBounds(srj.bounds, sharedBoundary)
674
694
  if (
675
- !pointIsInsideBounds(plan.exitPoint, srj.bounds) ||
695
+ !pointIsInsideBounds(plan.exitPoint, routableBounds) ||
676
696
  plan.segments.some(
677
697
  (segment) =>
678
- !pointIsInsideBounds(segment.start, srj.bounds) ||
679
- !pointIsInsideBounds(segment.end, srj.bounds),
698
+ !pointIsInsideBounds(segment.start, routableBounds) ||
699
+ !pointIsInsideBounds(segment.end, routableBounds),
680
700
  )
681
701
  ) {
682
702
  return false
@@ -814,6 +834,7 @@ function routePlaneTerminatedBus(
814
834
  plan,
815
835
  otherPlans: [...acceptedPlans, ...candidatePlans],
816
836
  srj,
837
+ sharedBoundary: bus.sharedBoundary,
817
838
  clearance,
818
839
  })
819
840
  ) {
@@ -913,6 +934,7 @@ export function routeBus(params: RouteBusParams): FanoutRoutePlan[] | null {
913
934
  plan,
914
935
  otherPlans: [...acceptedPlans, ...candidatePlans],
915
936
  srj,
937
+ sharedBoundary: bus.sharedBoundary,
916
938
  clearance,
917
939
  })
918
940
  ) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/fanout-solver",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "description": "BGA fanout solver with coordinated bus-layer escapes for SimpleRouteJson",
5
5
  "module": "lib/index.ts",
6
6
  "type": "module",
@@ -43,6 +43,7 @@
43
43
  "@types/bun": "1.3.14",
44
44
  "@types/react": "19.2.14",
45
45
  "@types/react-dom": "19.2.3",
46
+ "bun-match-svg": "^0.0.15",
46
47
  "circuit-json": "0.0.455",
47
48
  "react": "19.2.8",
48
49
  "react-cosmos": "7.3.0",