@tscircuit/schematic-trace-solver 0.0.174 → 0.0.175

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 (28) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +195 -74
  3. package/lib/solvers/InlineNetLabelSolver/InlineNetLabelSolver.ts +16 -1
  4. package/lib/solvers/InlineNetLabelSolver/restoreReroutesAroundSupersededLabels.ts +174 -0
  5. package/lib/solvers/NetLabelToTraceSolver/NetLabelToTraceSolver.ts +2 -30
  6. package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +9 -0
  7. package/lib/utils/doesPathCoincideWithTraces.ts +17 -4
  8. package/lib/utils/pathIntersectsRenderedLabel.ts +33 -0
  9. package/package.json +1 -1
  10. package/site/bug-reports/bug-report-20260901T055358Z.page.tsx +4 -0
  11. package/site/bug-reports/bug-report-20260901T064117Z.page.tsx +4 -0
  12. package/site/bug-reports/bug-report-20260901T134241Z.page.tsx +4 -0
  13. package/tests/bug-reports/bug-report-20260901T055358Z/__snapshots__/bug-report-20260901T055358Z.snap.svg +676 -0
  14. package/tests/bug-reports/bug-report-20260901T055358Z/bug-report-20260901T055358Z.json +2467 -0
  15. package/tests/bug-reports/bug-report-20260901T055358Z/bug-report-20260901T055358Z.test.ts +59 -0
  16. package/tests/bug-reports/bug-report-20260901T064117Z/__snapshots__/bug-report-20260901T064117Z.snap.svg +134 -0
  17. package/tests/bug-reports/bug-report-20260901T064117Z/bug-report-20260901T064117Z.json +215 -0
  18. package/tests/bug-reports/bug-report-20260901T064117Z/bug-report-20260901T064117Z.test.ts +12 -0
  19. package/tests/bug-reports/bug-report-20260901T134241Z/__snapshots__/bug-report-20260901T134241Z.snap.svg +115 -0
  20. package/tests/bug-reports/bug-report-20260901T134241Z/bug-report-20260901T134241Z.json +359 -0
  21. package/tests/bug-reports/bug-report-20260901T134241Z/bug-report-20260901T134241Z.test.ts +12 -0
  22. package/tests/repros/__snapshots__/repro-trellis-core-gnd-net-label-overlap.snap.svg +134 -0
  23. package/tests/repros/__snapshots__/repro-wireless-mouse-charger-section.snap.svg +164 -0
  24. package/tests/repros/assets/repro-trellis-core-gnd-net-label-overlap.input.json +178 -0
  25. package/tests/repros/assets/repro-wireless-mouse-charger-section.input.json +591 -0
  26. package/tests/repros/repro-trellis-core-gnd-net-label-overlap.test.ts +73 -0
  27. package/tests/repros/repro-wireless-mouse-charger-section.test.ts +16 -0
  28. package/tests/solvers/InlineNetLabelSolver/restore-reroutes-around-superseded-labels.test.ts +186 -0
@@ -0,0 +1,186 @@
1
+ import { expect, test } from "bun:test"
2
+ import type { InlineNetLabelPlacement } from "lib/solvers/InlineNetLabelSolver/InlineNetLabelSolver"
3
+ import { restoreReroutesAroundSupersededLabels } from "lib/solvers/InlineNetLabelSolver/restoreReroutesAroundSupersededLabels"
4
+ import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
5
+ import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
6
+ import type { CompletedTraceReroute } from "lib/solvers/TraceElbowTransitionSimplificationSolver/types"
7
+ import type { InputProblem } from "lib/types/InputProblem"
8
+
9
+ const inputProblem: InputProblem = {
10
+ chips: [],
11
+ directConnections: [],
12
+ netConnections: [],
13
+ availableNetLabelOrientations: {},
14
+ textBoxes: [],
15
+ }
16
+
17
+ const initialPath = [
18
+ { x: 0, y: 0 },
19
+ { x: 4, y: 0 },
20
+ ]
21
+
22
+ const reroutedPath = [
23
+ { x: 0, y: 0 },
24
+ { x: 1.8, y: 0 },
25
+ { x: 1.8, y: 0.5 },
26
+ { x: 2.2, y: 0.5 },
27
+ { x: 2.2, y: 0 },
28
+ { x: 4, y: 0 },
29
+ ]
30
+
31
+ const initialTrace: SolvedTracePath = {
32
+ mspPairId: "ground-trace",
33
+ dcConnNetId: "ground-global",
34
+ globalConnNetId: "ground-global",
35
+ userNetId: "GND",
36
+ pins: [
37
+ { pinId: "ground-pin-1", chipId: "left", x: 0, y: 0 },
38
+ { pinId: "ground-pin-2", chipId: "right", x: 4, y: 0 },
39
+ ],
40
+ tracePath: initialPath,
41
+ mspConnectionPairIds: ["ground-trace"],
42
+ pinIds: ["ground-pin-1", "ground-pin-2"],
43
+ }
44
+
45
+ const supersededLabel: NetLabelPlacement = {
46
+ globalConnNetId: "label-global",
47
+ dcConnNetId: "label-global",
48
+ netId: "CC2",
49
+ mspConnectionPairIds: ["label-host"],
50
+ pinIds: ["label-pin-1", "label-pin-2"],
51
+ orientation: "y+",
52
+ anchorPoint: { x: 2, y: -0.2 },
53
+ center: { x: 2, y: 0 },
54
+ width: 0.2,
55
+ height: 0.4,
56
+ }
57
+
58
+ const clearInlineLabel: InlineNetLabelPlacement = {
59
+ globalConnNetId: "label-global",
60
+ netId: "CC2",
61
+ mspPairId: "label-host",
62
+ pinIds: ["label-pin-1", "label-pin-2"],
63
+ axis: "x",
64
+ anchorPoint: { x: 2, y: -0.5 },
65
+ center: { x: 2, y: -0.6 },
66
+ width: 0.4,
67
+ height: 0.1,
68
+ side: "y-",
69
+ }
70
+
71
+ const completedReroute: CompletedTraceReroute = {
72
+ initialTrace,
73
+ reroutedTracePath: reroutedPath,
74
+ label: supersededLabel,
75
+ detourCount: 0,
76
+ }
77
+
78
+ const makeReroutedTrace = (tracePath = reroutedPath): SolvedTracePath => ({
79
+ ...initialTrace,
80
+ tracePath,
81
+ })
82
+
83
+ const restore = ({
84
+ traces = [makeReroutedTrace()],
85
+ netLabelPlacements = [],
86
+ inlineNetLabelPlacements = [clearInlineLabel],
87
+ }: {
88
+ traces?: SolvedTracePath[]
89
+ netLabelPlacements?: NetLabelPlacement[]
90
+ inlineNetLabelPlacements?: InlineNetLabelPlacement[]
91
+ } = {}) =>
92
+ restoreReroutesAroundSupersededLabels({
93
+ inputProblem,
94
+ traces,
95
+ netLabelPlacements,
96
+ inlineNetLabelPlacements,
97
+ completedReroutes: [completedReroute],
98
+ })
99
+
100
+ test("restores the exact route after its blocking label is superseded", () => {
101
+ const result = restore()
102
+
103
+ expect(result.restoredTraceCount).toBe(1)
104
+ expect(result.traces[0]!.tracePath).toEqual(initialPath)
105
+ })
106
+
107
+ test("keeps the detour when inline conversion did not supersede the label", () => {
108
+ const result = restore({ inlineNetLabelPlacements: [] })
109
+
110
+ expect(result.restoredTraceCount).toBe(0)
111
+ expect(result.traces[0]!.tracePath).toEqual(reroutedPath)
112
+ })
113
+
114
+ test("keeps the detour when the final inline label occupies the old route", () => {
115
+ const result = restore({
116
+ inlineNetLabelPlacements: [
117
+ {
118
+ ...clearInlineLabel,
119
+ anchorPoint: { x: 2, y: 0 },
120
+ center: { x: 2, y: 0 },
121
+ },
122
+ ],
123
+ })
124
+
125
+ expect(result.restoredTraceCount).toBe(0)
126
+ expect(result.traces[0]!.tracePath).toEqual(reroutedPath)
127
+ })
128
+
129
+ test("keeps the detour when another trace crosses the old route", () => {
130
+ const blockingTrace: SolvedTracePath = {
131
+ ...initialTrace,
132
+ mspPairId: "blocking-trace",
133
+ dcConnNetId: "blocking-global",
134
+ globalConnNetId: "blocking-global",
135
+ userNetId: "BLOCKING",
136
+ tracePath: [
137
+ { x: 2, y: -1 },
138
+ { x: 2, y: 1 },
139
+ ],
140
+ }
141
+ const result = restore({ traces: [makeReroutedTrace(), blockingTrace] })
142
+
143
+ expect(result.restoredTraceCount).toBe(0)
144
+ expect(result.traces[0]!.tracePath).toEqual(reroutedPath)
145
+ })
146
+
147
+ test("allows an unchanged pre-existing trace crossing", () => {
148
+ const existingCrossing: SolvedTracePath = {
149
+ ...initialTrace,
150
+ mspPairId: "existing-crossing",
151
+ dcConnNetId: "existing-crossing-global",
152
+ globalConnNetId: "existing-crossing-global",
153
+ userNetId: "EXISTING_CROSSING",
154
+ tracePath: [
155
+ { x: 1, y: -1 },
156
+ { x: 1, y: 1 },
157
+ ],
158
+ }
159
+ const result = restore({ traces: [makeReroutedTrace(), existingCrossing] })
160
+
161
+ expect(result.restoredTraceCount).toBe(1)
162
+ expect(result.traces[0]!.tracePath).toEqual(initialPath)
163
+ })
164
+
165
+ test("keeps the detour when a retained anchored label occupies the old route", () => {
166
+ const retainedLabel: NetLabelPlacement = {
167
+ ...supersededLabel,
168
+ globalConnNetId: "retained-label-global",
169
+ dcConnNetId: "retained-label-global",
170
+ netId: "RETAINED",
171
+ }
172
+ const result = restore({ netLabelPlacements: [retainedLabel] })
173
+
174
+ expect(result.restoredTraceCount).toBe(0)
175
+ expect(result.traces[0]!.tracePath).toEqual(reroutedPath)
176
+ })
177
+
178
+ test("does not overwrite a trace changed after the recorded reroute", () => {
179
+ const changedPath = reroutedPath.map((point) => ({ ...point }))
180
+ changedPath[2]!.y = 0.6
181
+ changedPath[3]!.y = 0.6
182
+ const result = restore({ traces: [makeReroutedTrace(changedPath)] })
183
+
184
+ expect(result.restoredTraceCount).toBe(0)
185
+ expect(result.traces[0]!.tracePath).toEqual(changedPath)
186
+ })