@tscircuit/fanout-solver 0.0.36 → 0.0.37

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/lib/types.ts CHANGED
@@ -124,9 +124,14 @@ export interface FanoutBusSpec extends SimpleRouteBus {
124
124
  * connection's electrical endpoint in SimpleRouteJson.
125
125
  *
126
126
  * A caller coordinating two fanouts can pass the paired fanout's selected
127
- * exit here so both sides aim toward the same track.
127
+ * exit here so both sides aim toward the same track. When every target also
128
+ * includes a layer, the solver may use the bus's other allowed layer as an
129
+ * internal crossover channel, then return every exit to one common bus layer
130
+ * in the supplied target order.
128
131
  */
129
- connectionExitTargets?: Readonly<Record<string, Point2D>>
132
+ connectionExitTargets?: Readonly<
133
+ Record<string, Point2D & { readonly layer?: string }>
134
+ >
130
135
  /**
131
136
  * Defaults to `{ type: "boundary" }`.
132
137
  *
@@ -279,7 +284,9 @@ export interface PreparedConnection {
279
284
  sourceObstacle: Obstacle
280
285
  targetPoint: ConnectionPoint
281
286
  /** Preferred downstream point used to choose the boundary exit track. */
282
- exitTargetPoint?: Point2D
287
+ exitTargetPoint?: Point2D & { readonly layer?: string }
288
+ /** Whether the caller supplied the layered handoff metadata needed to coordinate winding. */
289
+ hasExplicitLayeredExitTarget?: boolean
283
290
  }
284
291
 
285
292
  export interface PreparedBus {
@@ -292,6 +299,8 @@ export interface PreparedBus {
292
299
  cornerBandConnectionCount?: number
293
300
  /** Layers to which this bus is allowed to escape. */
294
301
  allowedLayers?: readonly string[]
302
+ /** Bus layers that also survive the solver-wide escape-layer restriction. */
303
+ routableEscapeLayers?: readonly string[]
295
304
  termination: FanoutBusTermination
296
305
  connections: PreparedConnection[]
297
306
  componentId: string
@@ -341,6 +350,8 @@ export interface FanoutRoutePlan {
341
350
  trace: SimplifiedPcbTrace
342
351
  segments: RoutedSegment[]
343
352
  via?: RoutedVia
353
+ /** Additional layer transitions used by an explicit winding channel. */
354
+ additionalVias?: RoutedVia[]
344
355
  /** Optional capacitor-side dogbone reserved and emitted with a plane escape. */
345
356
  planeEndpointTrace?: SimplifiedPcbTrace
346
357
  planeEndpointSegments?: RoutedSegment[]
@@ -44,9 +44,11 @@ function getPlanSegments(plan: FanoutRoutePlan): RoutedSegment[] {
44
44
  }
45
45
 
46
46
  function getPlanVias(plan: FanoutRoutePlan) {
47
- return [plan.via, plan.planeEndpointVia].filter(
48
- (via): via is NonNullable<FanoutRoutePlan["via"]> => Boolean(via),
49
- )
47
+ return [
48
+ plan.via,
49
+ ...(plan.additionalVias ?? []),
50
+ plan.planeEndpointVia,
51
+ ].filter((via): via is NonNullable<FanoutRoutePlan["via"]> => Boolean(via))
50
52
  }
51
53
 
52
54
  function connectionPointsMatch(
@@ -341,13 +343,13 @@ function validatePlanStructure(params: {
341
343
  plan,
342
344
  )
343
345
  }
344
- if (
345
- previous.layer !== current.layer &&
346
- (!plan.via ||
347
- !pointsMatch(previous.end, plan.via.center) ||
348
- !plan.via.spanLayers.includes(previous.layer) ||
349
- !plan.via.spanLayers.includes(current.layer))
350
- ) {
346
+ const transitionVia = getPlanVias(plan).find(
347
+ (via) =>
348
+ pointsMatch(previous.end, via.center) &&
349
+ via.spanLayers.includes(previous.layer) &&
350
+ via.spanLayers.includes(current.layer),
351
+ )
352
+ if (previous.layer !== current.layer && !transitionVia) {
351
353
  addIssue(
352
354
  issues,
353
355
  "disconnected-trace",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/fanout-solver",
3
- "version": "0.0.36",
3
+ "version": "0.0.37",
4
4
  "description": "BGA fanout solver with coordinated bus-layer escapes for SimpleRouteJson",
5
5
  "module": "lib/index.ts",
6
6
  "type": "module",