@tscircuit/schematic-trace-solver 0.0.178 → 0.0.180

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 (21) hide show
  1. package/dist/index.d.ts +8 -2
  2. package/dist/index.js +109 -4
  3. package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +141 -6
  4. package/lib/solvers/AvailableNetOrientationSolver/traces.ts +36 -0
  5. package/lib/solvers/AvailableNetOrientationSolver/types.ts +1 -0
  6. package/package.json +1 -1
  7. package/site/bug-reports/bug-report-20260902T092101Z.page.tsx +4 -0
  8. package/site/bug-reports/bug-report-20260902T092425Z.page.tsx +4 -0
  9. package/tests/bug-reports/bug-report-20260902T092101Z/__snapshots__/bug-report-20260902T092101Z.snap.svg +117 -0
  10. package/tests/bug-reports/bug-report-20260902T092101Z/bug-report-20260902T092101Z.json +162 -0
  11. package/tests/bug-reports/bug-report-20260902T092101Z/bug-report-20260902T092101Z.test.ts +28 -0
  12. package/tests/bug-reports/bug-report-20260902T092425Z/__snapshots__/bug-report-20260902T092425Z.snap.svg +136 -0
  13. package/tests/bug-reports/bug-report-20260902T092425Z/bug-report-20260902T092425Z.json +238 -0
  14. package/tests/bug-reports/bug-report-20260902T092425Z/bug-report-20260902T092425Z.test.ts +12 -0
  15. package/tests/repros/__snapshots__/repro-hub-usb-sheet.snap.svg +545 -0
  16. package/tests/repros/__snapshots__/repro-pmp11282-isolated-dcdc.snap.svg +10 -10
  17. package/tests/repros/__snapshots__/repro-smartwatch-power-sheet.snap.svg +4 -4
  18. package/tests/repros/assets/repro-hub-usb-sheet.input.json +3967 -0
  19. package/tests/repros/repro-battery-management-bq24073.test.ts +17 -0
  20. package/tests/repros/repro-hub-usb-sheet.test.ts +56 -0
  21. package/tests/repros/repro-smartwatch-power-sheet.test.ts +31 -5
@@ -5,6 +5,8 @@ import type { FacingDirection } from "lib/utils/dir"
5
5
  import "tests/fixtures/matcher"
6
6
  import inputProblem from "./assets/repro-battery-management-bq24073.input.json"
7
7
 
8
+ const EXPECTED_BOTTOM_GROUND_LABEL_X = 1.1
9
+
8
10
  const getPinPair = (pinIds: string[]): [string, string] => {
9
11
  if (pinIds.length !== 2) {
10
12
  throw new Error(`Expected two pin IDs, received ${pinIds.length}`)
@@ -57,6 +59,21 @@ test("repro BatteryManagement_BQ24073 schematic traces", () => {
57
59
  const solver = new SchematicTracePipelineSolver(solverInput)
58
60
  solver.solve()
59
61
 
62
+ const output = solver.netLabelToTraceSolver!.getOutput()
63
+ const groundNetIds = new Set(
64
+ solverInput.netConnections
65
+ .filter((connection) => connection.isGround)
66
+ .map((connection) => connection.netId),
67
+ )
68
+ const bottomGroundLabel = output.netLabelPlacements
69
+ .filter(
70
+ (label) => label.netId !== undefined && groundNetIds.has(label.netId),
71
+ )
72
+ .sort((first, second) => first.anchorPoint.y - second.anchorPoint.y)[0]!
73
+
60
74
  expect(solver.inlineNetLabelSolver!.stats.pushedAnchoredNetLabelCount).toBe(1)
75
+ expect(bottomGroundLabel.anchorPoint.x).toBeCloseTo(
76
+ EXPECTED_BOTTOM_GROUND_LABEL_X,
77
+ )
61
78
  expect(solver).toMatchSolverSnapshot(import.meta.path)
62
79
  })
@@ -0,0 +1,56 @@
1
+ import { expect, test } from "bun:test"
2
+ import { tracePathContainsPoint } from "lib/solvers/RailNetLabelCornerPlacementSolver/geometry"
3
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
4
+ import { isVertical } from "lib/solvers/TraceCleanupSolver/sameNetRailAlignment/geometry"
5
+ import type { InputChip, InputProblem, PinId } from "lib/types/InputProblem"
6
+ import "tests/fixtures/matcher"
7
+ import inputProblemJson from "./assets/repro-hub-usb-sheet.input.json"
8
+
9
+ // Captured from @tsci/mohan-bee.hub 1.0.12 using @tscircuit/core 0.0.1816.
10
+ // Only opaque schematic component IDs were replaced with unique source names.
11
+ test("repro hub USB sheet schematic trace routing", () => {
12
+ const inputProblem: InputProblem = JSON.parse(
13
+ JSON.stringify(inputProblemJson),
14
+ )
15
+ const solver = new SchematicTracePipelineSolver(inputProblem)
16
+
17
+ solver.solve()
18
+
19
+ const output = solver.netLabelToTraceSolver!.getOutput()
20
+ const groundNetIds = new Set(
21
+ inputProblem.netConnections
22
+ .filter((connection) => connection.isGround)
23
+ .map((connection) => connection.netId),
24
+ )
25
+ const pinChipMap = new Map<PinId, InputChip>(
26
+ inputProblem.chips.flatMap((chip) =>
27
+ chip.pins.map((pin) => [pin.pinId, chip] as const),
28
+ ),
29
+ )
30
+ const sameChipGroundLabel = output.netLabelPlacements.find((label) => {
31
+ if (
32
+ label.pinIds.length !== 2 ||
33
+ label.netId === undefined ||
34
+ !groundNetIds.has(label.netId)
35
+ ) {
36
+ return false
37
+ }
38
+ const firstChip = pinChipMap.get(label.pinIds[0]!)
39
+ const secondChip = pinChipMap.get(label.pinIds[1]!)
40
+ return firstChip === secondChip && (firstChip?.pins.length ?? 0) > 2
41
+ })!
42
+ const sameChipGroundHostTrace = output.traces.find((trace) =>
43
+ sameChipGroundLabel.mspConnectionPairIds.includes(trace.mspPairId),
44
+ )!
45
+ const verticalHostPoint = sameChipGroundHostTrace.tracePath.find(
46
+ (point, index, path) => index > 0 && isVertical(path[index - 1]!, point),
47
+ )!
48
+ const tracesAtSameChipGroundLabel = output.traces.filter((trace) =>
49
+ tracePathContainsPoint(trace.tracePath, sameChipGroundLabel.anchorPoint),
50
+ )
51
+
52
+ expect(sameChipGroundLabel.orientation).toBe("y-")
53
+ expect(sameChipGroundLabel.anchorPoint.x).toBeCloseTo(verticalHostPoint.x)
54
+ expect(tracesAtSameChipGroundLabel).toHaveLength(1)
55
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
56
+ })
@@ -1,9 +1,13 @@
1
1
  import { expect, test } from "bun:test"
2
+ import { tracePathContainsPoint } from "lib/solvers/RailNetLabelCornerPlacementSolver/geometry"
2
3
  import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
4
+ import { isVertical } from "lib/solvers/TraceCleanupSolver/sameNetRailAlignment/geometry"
3
5
  import type { InputProblem } from "lib/types/InputProblem"
4
6
  import "tests/fixtures/matcher"
5
7
  import inputProblem from "./assets/repro-smartwatch-power-sheet.input.json"
6
8
 
9
+ const MIN_CONNECTOR_GROUND_RAIL_EXTENSION = 0.2
10
+
7
11
  test("smartwatch power sheet", () => {
8
12
  const solver = new SchematicTracePipelineSolver(
9
13
  inputProblem as unknown as InputProblem,
@@ -17,11 +21,33 @@ test("smartwatch power sheet", () => {
17
21
  "schematic_port_0",
18
22
  "schematic_port_11",
19
23
  ])
20
- const connectorGroundLabels = solver
21
- .netLabelToTraceSolver!.getOutput()
22
- .netLabelPlacements.filter((label) =>
23
- label.pinIds.some((pinId) => connectorGroundPinIds.has(pinId)),
24
- )
24
+ const output = solver.netLabelToTraceSolver!.getOutput()
25
+ const connectorGroundLabels = output.netLabelPlacements.filter((label) =>
26
+ label.pinIds.some((pinId) => connectorGroundPinIds.has(pinId)),
27
+ )
25
28
  expect(connectorGroundLabels).toHaveLength(1)
29
+ const connectorGroundLabel = connectorGroundLabels[0]!
30
+ const connectorGroundPins = inputProblem.chips.flatMap((chip) =>
31
+ chip.pins.filter((pin) => connectorGroundPinIds.has(pin.pinId)),
32
+ )
33
+ const connectorGroundHostTrace = output.traces.find((trace) =>
34
+ connectorGroundLabel.mspConnectionPairIds.includes(trace.mspPairId),
35
+ )!
36
+ const verticalHostPoint = connectorGroundHostTrace.tracePath.find(
37
+ (point, index, path) => index > 0 && isVertical(path[index - 1]!, point),
38
+ )!
39
+ const lowestConnectorGroundPinY = Math.min(
40
+ ...connectorGroundPins.map((pin) => pin.y),
41
+ )
42
+ const tracesAtConnectorGroundLabel = output.traces.filter((trace) =>
43
+ tracePathContainsPoint(trace.tracePath, connectorGroundLabel.anchorPoint),
44
+ )
45
+
46
+ expect(connectorGroundLabel.orientation).toBe("y-")
47
+ expect(connectorGroundLabel.anchorPoint.x).toBeCloseTo(verticalHostPoint.x)
48
+ expect(connectorGroundLabel.anchorPoint.y).toBeCloseTo(
49
+ lowestConnectorGroundPinY - MIN_CONNECTOR_GROUND_RAIL_EXTENSION,
50
+ )
51
+ expect(tracesAtConnectorGroundLabel).toHaveLength(1)
26
52
  expect(solver).toMatchSolverSnapshot(import.meta.path)
27
53
  })