@tscircuit/schematic-trace-solver 0.0.96 → 0.0.98

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 (45) hide show
  1. package/dist/index.d.ts +9 -0
  2. package/dist/index.js +986 -479
  3. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/SchematicTraceSingleLineSolver2.ts +55 -14
  4. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/collisions.ts +31 -0
  5. package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +45 -1
  6. package/lib/solvers/TraceCleanupSolver/TraceCleanupSolver.ts +55 -13
  7. package/lib/solvers/TraceCleanupSolver/alignSameNetRails.ts +66 -0
  8. package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/evaluateRailGroup.ts +124 -0
  9. package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/geometry.ts +108 -0
  10. package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/getComponentSideRailSegments.ts +121 -0
  11. package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/getRailGroups.ts +114 -0
  12. package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/moveRailSegments.ts +27 -0
  13. package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/preservesLabelAnchors.ts +30 -0
  14. package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/scoreRailAlignment.ts +67 -0
  15. package/lib/solvers/TraceCleanupSolver/sameNetRailAlignment/types.ts +34 -0
  16. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/SingleOverlapSolver/SingleOverlapSolver.ts +1 -60
  17. package/lib/utils/doesPathCoincideWithTraces.ts +61 -0
  18. package/package.json +1 -1
  19. package/tests/bug-reports/bug-report-20260706T220324Z/__snapshots__/bug-report-20260706T220324Z.snap.svg +1 -1
  20. package/tests/bug-reports/bug-report-20260707T141025Z/__snapshots__/bug-report-20260707T141025Z.snap.svg +1 -1
  21. package/tests/examples/__snapshots__/example02.snap.svg +1 -1
  22. package/tests/examples/__snapshots__/example14.snap.svg +1 -1
  23. package/tests/examples/__snapshots__/example18.snap.svg +1 -1
  24. package/tests/examples/__snapshots__/example46.snap.svg +1 -1
  25. package/tests/repros/__snapshots__/repro-cc2340r5.snap.svg +1 -1
  26. package/tests/repros/__snapshots__/repro-rp2040-gamepad-trace-alignment.snap.svg +178 -0
  27. package/tests/repros/__snapshots__/repro-rp2040-zero-crystal-fallback-netlabels.snap.svg +54 -0
  28. package/tests/repros/__snapshots__/repro130-bq27441-fuel-gauge-trace-through-c1.snap.svg +1 -1
  29. package/tests/repros/assets/repro-rp2040-gamepad-trace-alignment.input.json +237 -0
  30. package/tests/repros/assets/repro-rp2040-zero-crystal-fallback-netlabels.input.json +121 -0
  31. package/tests/repros/repro-rp2040-gamepad-trace-alignment.test.ts +38 -0
  32. package/tests/repros/repro-rp2040-zero-crystal-fallback-netlabels.test.ts +16 -0
  33. package/tests/solvers/SchematicTraceSingleLineSolver2/segment-intersects-rect-interior.test.ts +15 -0
  34. package/tests/solvers/SchematicTraceSingleLineSolver2/segment-overlaps-rect-boundary-boundary.test.ts +18 -0
  35. package/tests/solvers/SchematicTraceSingleLineSolver2/segment-overlaps-rect-boundary-interior.test.ts +18 -0
  36. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-component-scope.test.ts +38 -0
  37. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-eligible-traces.test.ts +28 -0
  38. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-horizontal.test.ts +62 -0
  39. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-label-anchor.test.ts +36 -0
  40. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-label-junction.test.ts +42 -0
  41. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-obstacle.test.ts +28 -0
  42. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-pipeline-label-connector.test.ts +52 -0
  43. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-vertical.test.ts +25 -0
  44. package/tests/solvers/TraceCleanupSolver/alignSameNetRails-visible-length.test.ts +40 -0
  45. package/tests/solvers/TraceCleanupSolver/fixtures/alignSameNetRails.ts +89 -0
@@ -0,0 +1,28 @@
1
+ import { expect, test } from "bun:test"
2
+ import {
3
+ align,
4
+ getVerticalRailTraces,
5
+ verticalProblem,
6
+ } from "./fixtures/alignSameNetRails"
7
+
8
+ test("does not align through an obstacle", () => {
9
+ const traces = getVerticalRailTraces()
10
+ const result = align(traces, {
11
+ inputProblem: {
12
+ ...verticalProblem,
13
+ chips: [
14
+ ...verticalProblem.chips,
15
+ {
16
+ chipId: "barrier",
17
+ center: { x: -2.5, y: 0 },
18
+ width: 0.4,
19
+ height: 0.4,
20
+ pins: [],
21
+ },
22
+ ],
23
+ },
24
+ })
25
+
26
+ expect(result.alignedRailGroupCount).toBe(0)
27
+ expect(result.traces).toEqual(traces)
28
+ })
@@ -0,0 +1,52 @@
1
+ import { expect, test } from "bun:test"
2
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
3
+ import type { InputProblem } from "lib/types/InputProblem"
4
+
5
+ test("pipeline does not stretch a real loop toward a generated label connector", () => {
6
+ const inputProblem: InputProblem = {
7
+ chips: [
8
+ {
9
+ chipId: "U3",
10
+ center: { x: 0, y: 0 },
11
+ width: 2.8,
12
+ height: 1.4,
13
+ pins: [
14
+ { pinId: "U3.3", x: 1.4, y: -0.3 },
15
+ { pinId: "U3.7", x: 1.4, y: -0.5 },
16
+ ],
17
+ },
18
+ ],
19
+ directConnections: [],
20
+ netConnections: [
21
+ {
22
+ netId: "V3_3",
23
+ pinIds: ["U3.3", "U3.7"],
24
+ netLabelWidth: 0.42,
25
+ netLabelHeight: 0.6,
26
+ },
27
+ ],
28
+ textBoxes: [],
29
+ availableNetLabelOrientations: { V3_3: ["y+"] },
30
+ maxMspPairDistance: 2.4,
31
+ }
32
+ const solver = new SchematicTracePipelineSolver(inputProblem)
33
+
34
+ solver.solve()
35
+
36
+ const traces = solver.traceCleanupSolver2!.getOutput().traces
37
+ const realTrace = traces.find((trace) => trace.mspPairId === "U3.3-U3.7")!
38
+ const labelConnector = traces.find((trace) =>
39
+ trace.mspPairId.startsWith("available-net-orientation-"),
40
+ )!
41
+ expect(realTrace.tracePath).toEqual([
42
+ { x: 1.4, y: -0.3 },
43
+ { x: 1.5999999999999999, y: -0.3 },
44
+ { x: 1.5999999999999999, y: -0.5 },
45
+ { x: 1.4, y: -0.5 },
46
+ ])
47
+ expect(labelConnector.mspPairId).toBe("available-net-orientation-0-V3_3")
48
+ expect(solver.traceCleanupSolver2!.stats).toMatchObject({
49
+ alignedRailGroupCount: 0,
50
+ alignedTraceCount: 0,
51
+ })
52
+ })
@@ -0,0 +1,25 @@
1
+ import { expect, test } from "bun:test"
2
+ import { align, getVerticalRailTraces } from "./fixtures/alignSameNetRails"
3
+
4
+ test("aligns same-net rails on one component side", () => {
5
+ const result = align(getVerticalRailTraces())
6
+
7
+ expect(result).toMatchObject({
8
+ alignedRailGroupCount: 1,
9
+ alignedTraceCount: 1,
10
+ })
11
+ expect(result.traces.map((trace) => trace.tracePath)).toEqual([
12
+ [
13
+ { x: -1, y: 2 },
14
+ { x: -2, y: 2 },
15
+ { x: -2, y: 0 },
16
+ { x: -1, y: 0 },
17
+ ],
18
+ [
19
+ { x: -1, y: 0 },
20
+ { x: -2, y: 0 },
21
+ { x: -2, y: -2 },
22
+ { x: -1, y: -2 },
23
+ ],
24
+ ])
25
+ })
@@ -0,0 +1,40 @@
1
+ import { expect, test } from "bun:test"
2
+ import {
3
+ align,
4
+ createTrace,
5
+ getVerticalPin,
6
+ getVerticalRailTraces,
7
+ verticalProblem,
8
+ } from "./fixtures/alignSameNetRails"
9
+
10
+ test("keeps the baseline when alignment would only lengthen visible geometry", () => {
11
+ const traces = getVerticalRailTraces()
12
+ traces[1] = createTrace(
13
+ "lower",
14
+ [
15
+ { x: -1, y: 0 },
16
+ { x: -10, y: 0 },
17
+ { x: -10, y: -2 },
18
+ { x: -1, y: -2 },
19
+ ],
20
+ [getVerticalPin("U1.2"), getVerticalPin("U1.3")],
21
+ )
22
+ const result = align(traces, {
23
+ inputProblem: {
24
+ ...verticalProblem,
25
+ chips: [
26
+ ...verticalProblem.chips,
27
+ {
28
+ chipId: "blocks-short-candidate",
29
+ center: { x: -2, y: -1 },
30
+ width: 0.2,
31
+ height: 0.4,
32
+ pins: [],
33
+ },
34
+ ],
35
+ },
36
+ })
37
+
38
+ expect(result.alignedRailGroupCount).toBe(0)
39
+ expect(result.traces).toEqual(traces)
40
+ })
@@ -0,0 +1,89 @@
1
+ import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
2
+ import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
3
+ import { alignSameNetRails } from "lib/solvers/TraceCleanupSolver/alignSameNetRails"
4
+ import type { InputPin, InputProblem } from "lib/types/InputProblem"
5
+
6
+ export const verticalProblem: InputProblem = {
7
+ chips: [
8
+ {
9
+ chipId: "U1",
10
+ center: { x: 0, y: 0 },
11
+ width: 2,
12
+ height: 6,
13
+ pins: [
14
+ { pinId: "U1.1", x: -1, y: 2, _facingDirection: "x-" },
15
+ { pinId: "U1.2", x: -1, y: 0, _facingDirection: "x-" },
16
+ { pinId: "U1.3", x: -1, y: -2, _facingDirection: "x-" },
17
+ ],
18
+ },
19
+ ],
20
+ directConnections: [],
21
+ netConnections: [],
22
+ textBoxes: [],
23
+ availableNetLabelOrientations: {},
24
+ }
25
+
26
+ export const getVerticalPin = (
27
+ pinId: string,
28
+ ): InputPin & { chipId: string } => {
29
+ const inputPin = verticalProblem.chips[0]!.pins.find(
30
+ (candidate) => candidate.pinId === pinId,
31
+ )!
32
+ return { ...inputPin, chipId: "U1" }
33
+ }
34
+
35
+ export const createTrace = (
36
+ mspPairId: string,
37
+ tracePath: Array<{ x: number; y: number }>,
38
+ pins: SolvedTracePath["pins"],
39
+ globalConnNetId = "power-net",
40
+ ): SolvedTracePath => ({
41
+ mspPairId,
42
+ globalConnNetId,
43
+ dcConnNetId: mspPairId,
44
+ userNetId: "POWER",
45
+ pins,
46
+ tracePath,
47
+ mspConnectionPairIds: [mspPairId],
48
+ pinIds: pins.map((item) => item.pinId),
49
+ })
50
+
51
+ export const getVerticalRailTraces = () => [
52
+ createTrace(
53
+ "upper",
54
+ [
55
+ { x: -1, y: 2 },
56
+ { x: -2, y: 2 },
57
+ { x: -2, y: 0 },
58
+ { x: -1, y: 0 },
59
+ ],
60
+ [getVerticalPin("U1.1"), getVerticalPin("U1.2")],
61
+ ),
62
+ createTrace(
63
+ "lower",
64
+ [
65
+ { x: -1, y: 0 },
66
+ { x: -3, y: 0 },
67
+ { x: -3, y: -2 },
68
+ { x: -1, y: -2 },
69
+ ],
70
+ [getVerticalPin("U1.2"), getVerticalPin("U1.3")],
71
+ ),
72
+ ]
73
+
74
+ export const align = (
75
+ traces: SolvedTracePath[],
76
+ options: {
77
+ inputProblem?: InputProblem
78
+ netLabelPlacements?: NetLabelPlacement[]
79
+ eligibleTraceIds?: ReadonlySet<string>
80
+ } = {},
81
+ ) =>
82
+ alignSameNetRails({
83
+ inputProblem: options.inputProblem ?? verticalProblem,
84
+ traces,
85
+ netLabelPlacements: options.netLabelPlacements ?? [],
86
+ eligibleTraceIds:
87
+ options.eligibleTraceIds ??
88
+ new Set(traces.map((trace) => trace.mspPairId)),
89
+ })