@tscircuit/schematic-trace-solver 0.0.114 → 0.0.116

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 (27) hide show
  1. package/dist/index.d.ts +22 -9
  2. package/dist/index.js +248 -3
  3. package/lib/solvers/SameNetJunctionAlignmentSolver/SameNetJunctionAlignmentSolver.ts +71 -0
  4. package/lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts +223 -0
  5. package/lib/solvers/SameNetJunctionAlignmentSolver/pathIntersectsAnyNetLabel.ts +22 -0
  6. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/SchematicTraceSingleLineSolver2.ts +9 -9
  7. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect.ts +25 -9
  8. package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +17 -0
  9. package/package.json +2 -2
  10. package/site/bug-reports/bug-report-20260730T061837Z.page.tsx +4 -0
  11. package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +1 -1
  12. package/tests/bug-reports/bug-report-20260728T144234Z/__snapshots__/bug-report-20260728T144234Z.snap.svg +1 -1
  13. package/tests/bug-reports/bug-report-20260728T144234Z/bug-report-20260728T144234Z.test.ts +6 -0
  14. package/tests/bug-reports/bug-report-20260730T061837Z/__snapshots__/bug-report-20260730T061837Z.snap.svg +123 -0
  15. package/tests/bug-reports/bug-report-20260730T061837Z/bug-report-20260730T061837Z.json +614 -0
  16. package/tests/bug-reports/bug-report-20260730T061837Z/bug-report-20260730T061837Z.test.ts +34 -0
  17. package/tests/repros/__snapshots__/board-15984-same-net-junction.snap.svg +110 -0
  18. package/tests/repros/__snapshots__/repro-type-c-16pin-self-connection.snap.svg +54 -0
  19. package/tests/repros/__snapshots__/repro-type-c-16pin-to-resistor.snap.svg +56 -0
  20. package/tests/repros/__snapshots__/repro48-555-timer-vcc-rail-label.snap.svg +87 -0
  21. package/tests/repros/assets/board-15984-schematic-trace-input.json +518 -0
  22. package/tests/repros/assets/repro48-555-timer-vcc-rail-label.input.json +276 -0
  23. package/tests/repros/board-15984-same-net-junction.test.ts +30 -0
  24. package/tests/repros/repro-type-c-16pin-self-connection.test.ts +97 -0
  25. package/tests/repros/repro-type-c-16pin-to-resistor.test.ts +120 -0
  26. package/tests/repros/repro48-555-timer-vcc-rail-label.test.ts +23 -0
  27. package/tests/solvers/SchematicTraceSingleLineSolver2/text-box-obstacle-gap.test.ts +43 -0
@@ -123,16 +123,16 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
123
123
  })
124
124
  this.textObstacles = new Set(this.obstacles.filter(isTextBoxObstacle))
125
125
  const endpointChipIds = new Set(this.pins.map((pin) => pin.chipId))
126
+ // Same-chip routes also need these obstacles so they can escape around
127
+ // attached text after a narrow chip-to-text channel is closed.
126
128
  this.endpointTextObstacles = new Set(
127
- endpointChipIds.size > 1
128
- ? this.obstacles
129
- .filter(isTextBoxObstacle)
130
- .filter(
131
- (obstacle) =>
132
- obstacle.textBox.chipId !== undefined &&
133
- endpointChipIds.has(obstacle.textBox.chipId),
134
- )
135
- : [],
129
+ this.obstacles
130
+ .filter(isTextBoxObstacle)
131
+ .filter(
132
+ (obstacle) =>
133
+ obstacle.textBox.chipId !== undefined &&
134
+ endpointChipIds.has(obstacle.textBox.chipId),
135
+ ),
136
136
  )
137
137
 
138
138
  const [pin1, pin2] = this.pins
@@ -1,20 +1,21 @@
1
+ import { boundsDistance, type Bounds } from "@tscircuit/math-utils"
1
2
  import { getInputChipBounds } from "lib/solvers/GuidelinesSolver/getInputChipBounds"
2
3
  import type { InputChip, InputProblem } from "lib/types/InputProblem"
3
4
  import { getTextBoxBounds, type RectPadding } from "lib/utils/textBoxBounds"
4
5
 
5
- export type RectBounds = {
6
- minX: number
7
- minY: number
8
- maxX: number
9
- maxY: number
10
- }
6
+ // Component text is normally placed 0.04 units from its chip. A trace
7
+ // centerline can fit mathematically, but its rendered stroke cannot usefully
8
+ // occupy that channel.
9
+ const MIN_ROUTABLE_OBSTACLE_GAP = 0.05
10
+
11
+ export type { Bounds as RectBounds } from "@tscircuit/math-utils"
11
12
 
12
- export type ChipObstacleRect = RectBounds & {
13
+ export type ChipObstacleRect = Bounds & {
13
14
  kind: "chip"
14
15
  chipId: string
15
16
  }
16
17
 
17
- export type TextBoxObstacleRect = RectBounds & {
18
+ export type TextBoxObstacleRect = Bounds & {
18
19
  kind: "text_box"
19
20
  textBox: NonNullable<InputProblem["textBoxes"]>[number]
20
21
  }
@@ -36,7 +37,22 @@ export const getObstacleRects = (
36
37
  ): ObstacleRect[] => {
37
38
  const chipRects = problem.chips.map(chipToRect)
38
39
  const textBoxRects = (problem.textBoxes ?? []).map((textBox) => {
39
- const b = getTextBoxBounds(textBox, opts.textBoxPadding)
40
+ const textBounds = getTextBoxBounds(textBox, opts.textBoxPadding)
41
+ const attachedChipBounds = chipRects.find(
42
+ (chip) => chip.chipId === textBox.chipId,
43
+ )
44
+ const gap = attachedChipBounds
45
+ ? boundsDistance(textBounds, attachedChipBounds)
46
+ : Number.POSITIVE_INFINITY
47
+ const b =
48
+ attachedChipBounds && gap > 0 && gap < MIN_ROUTABLE_OBSTACLE_GAP
49
+ ? {
50
+ minX: Math.min(textBounds.minX, attachedChipBounds.maxX),
51
+ maxX: Math.max(textBounds.maxX, attachedChipBounds.minX),
52
+ minY: Math.min(textBounds.minY, attachedChipBounds.maxY),
53
+ maxY: Math.max(textBounds.maxY, attachedChipBounds.minY),
54
+ }
55
+ : textBounds
40
56
  return {
41
57
  kind: "text_box" as const,
42
58
  textBox,
@@ -28,6 +28,7 @@ import { TraceAnchoredNetLabelOverlapSolver } from "../TraceAnchoredNetLabelOver
28
28
  import { NetLabelTraceCollisionSolver } from "../NetLabelTraceCollisionSolver/NetLabelTraceCollisionSolver"
29
29
  import { NetLabelNetLabelCollisionSolver } from "../NetLabelNetLabelCollisionSolver/NetLabelNetLabelCollisionSolver"
30
30
  import { UnroutedTraceRecoverySolver } from "../UnroutedTraceRecoverySolver/UnroutedTraceRecoverySolver"
31
+ import { SameNetJunctionAlignmentSolver } from "../SameNetJunctionAlignmentSolver/SameNetJunctionAlignmentSolver"
31
32
 
32
33
  type PipelineStep<T extends new (...args: any[]) => BaseSolver> = {
33
34
  solverName: string
@@ -86,6 +87,7 @@ export class SchematicTracePipelineSolver extends BaseSolver {
86
87
  netLabelTraceCollisionSolver?: NetLabelTraceCollisionSolver
87
88
  traceCleanupSolver2?: TraceCleanupSolver
88
89
  netLabelNetLabelCollisionSolver?: NetLabelNetLabelCollisionSolver
90
+ sameNetJunctionAlignmentSolver?: SameNetJunctionAlignmentSolver
89
91
 
90
92
  startTimeOfPhase: Record<string, number>
91
93
  endTimeOfPhase: Record<string, number>
@@ -402,6 +404,21 @@ export class SchematicTracePipelineSolver extends BaseSolver {
402
404
  },
403
405
  ],
404
406
  ),
407
+ definePipelineStep(
408
+ "sameNetJunctionAlignmentSolver",
409
+ SameNetJunctionAlignmentSolver,
410
+ (instance) => {
411
+ const collisionOutput =
412
+ instance.netLabelNetLabelCollisionSolver!.getOutput()
413
+ return [
414
+ {
415
+ inputProblem: instance.inputProblem,
416
+ traces: instance.netLabelNetLabelCollisionSolver!.traces,
417
+ netLabelPlacements: collisionOutput.netLabelPlacements,
418
+ },
419
+ ]
420
+ },
421
+ ),
405
422
  ]
406
423
 
407
424
  constructor(inputProblem: InputProblem, opts?: Options) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/schematic-trace-solver",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.114",
4
+ "version": "0.0.116",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "cosmos",
@@ -13,7 +13,7 @@
13
13
  "devDependencies": {
14
14
  "@biomejs/biome": "^2.2.2",
15
15
  "@react-hook/resize-observer": "^2.0.2",
16
- "@tscircuit/math-utils": "^0.0.19",
16
+ "@tscircuit/math-utils": "^0.0.36",
17
17
  "@types/bun": "^1.2.21",
18
18
  "bun-match-svg": "^0.0.13",
19
19
  "calculate-elbow": "^0.0.12",
@@ -0,0 +1,4 @@
1
+ import { PipelineDebugger } from "site/components/PipelineDebugger"
2
+ import inputProblem from "../../tests/bug-reports/bug-report-20260730T061837Z/bug-report-20260730T061837Z.json"
3
+
4
+ export default () => <PipelineDebugger inputProblem={inputProblem as any} />