@tscircuit/rectdiff 0.0.23 → 0.0.25

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 (47) hide show
  1. package/AGENTS.md +23 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +195 -144
  4. package/lib/RectDiffPipeline.ts +4 -37
  5. package/lib/buildFinalRectDiffVisualization.ts +46 -0
  6. package/lib/solvers/RectDiffSeedingSolver/RectDiffSeedingSolver.ts +23 -48
  7. package/lib/solvers/RectDiffSeedingSolver/computeCandidates3D.ts +21 -12
  8. package/lib/solvers/RectDiffSeedingSolver/computeEdgeCandidates3D.ts +68 -25
  9. package/lib/solvers/RectDiffSeedingSolver/longestFreeSpanAroundZ.ts +1 -1
  10. package/lib/utils/buildOutlineGraphics.ts +39 -0
  11. package/lib/utils/expandRectFromSeed.ts +19 -11
  12. package/lib/utils/isFullyOccupiedAtPoint.ts +2 -2
  13. package/lib/utils/rectdiff-geometry.ts +13 -20
  14. package/package.json +2 -1
  15. package/scripts/benchmark-slow-problem.ts +94 -0
  16. package/test-assets/keyboard4.json +16165 -0
  17. package/tests/solver/__snapshots__/rectDiffGridSolverPipeline.snap.svg +1 -1
  18. package/tests/solver/bugreport01-be84eb/__snapshots__/bugreport01-be84eb.snap.svg +2 -2
  19. package/tests/solver/bugreport02-bc4361/__snapshots__/bugreport02-bc4361.snap.svg +2 -2
  20. package/tests/solver/bugreport03-fe4a17/__snapshots__/bugreport03-fe4a17.snap.svg +1 -1
  21. package/tests/solver/bugreport07-d3f3be/__snapshots__/bugreport07-d3f3be.snap.svg +1 -1
  22. package/tests/solver/bugreport08-e3ec95/__snapshots__/bugreport08-e3ec95.snap.svg +1 -1
  23. package/tests/solver/bugreport09-618e09/__snapshots__/bugreport09-618e09.snap.svg +2 -2
  24. package/tests/solver/bugreport10-71239a/__snapshots__/bugreport10-71239a.snap.svg +2 -2
  25. package/tests/solver/bugreport11-b2de3c/__snapshots__/bugreport11-b2de3c.snap.svg +1 -1
  26. package/tests/solver/bugreport11-b2de3c/bugreport11-b2de3c-clearance-equivalence.test.ts +52 -0
  27. package/tests/solver/bugreport12-35ce1c/__snapshots__/bugreport12-35ce1c.snap.svg +1 -1
  28. package/tests/solver/bugreport13-b9a758/__snapshots__/bugreport13-b9a758.snap.svg +2 -2
  29. package/tests/solver/bugreport16-d95f38/__snapshots__/bugreport16-d95f38.snap.svg +2 -2
  30. package/tests/solver/bugreport19/__snapshots__/bugreport19.snap.svg +1 -1
  31. package/tests/solver/bugreport22-2a75ce/__snapshots__/bugreport22-2a75ce.snap.svg +1 -1
  32. package/tests/solver/bugreport23-LGA15x4/__snapshots__/bugreport23-LGA15x4.snap.svg +1 -1
  33. package/tests/solver/bugreport24-05597c/__snapshots__/bugreport24-05597c.snap.svg +1 -1
  34. package/tests/solver/bugreport26-66b0b2/__snapshots__/bugreport26-66b0b2.snap.svg +2 -2
  35. package/tests/solver/bugreport27-dd3734/__snapshots__/bugreport27-dd3734.snap.svg +2 -2
  36. package/tests/solver/bugreport28-18a9ef/__snapshots__/bugreport28-18a9ef.snap.svg +2 -2
  37. package/tests/solver/bugreport29-7deae8/__snapshots__/bugreport29-7deae8.snap.svg +2 -2
  38. package/tests/solver/bugreport30-2174c8/__snapshots__/bugreport30-2174c8.snap.svg +1 -1
  39. package/tests/solver/bugreport33-213d45/__snapshots__/bugreport33-213d45.snap.svg +2 -2
  40. package/tests/solver/bugreport34-e9dea2/__snapshots__/bugreport34-e9dea2.snap.svg +2 -2
  41. package/tests/solver/bugreport35-191db9/__snapshots__/bugreport35-191db9.snap.svg +2 -2
  42. package/tests/solver/bugreport36-bf8303/__snapshots__/bugreport36-bf8303.snap.svg +1 -1
  43. package/tests/solver/interaction/__snapshots__/interaction.snap.svg +1 -1
  44. package/tests/solver/multi-point/__snapshots__/multi-point.snap.svg +1 -1
  45. package/tests/solver/pcb_trace_id-should-return-root-connection-name/__snapshots__/pcb_trace_id-should-return-root-connection-name.snap.svg +1 -1
  46. package/tests/solver/bugreport11-b2de3c/__snapshots__/bugreport11-b2de3c-clearance.snap.svg +0 -44
  47. package/tests/solver/bugreport11-b2de3c/bugreport11-b2de3c-clearance.test.ts +0 -97
@@ -0,0 +1,94 @@
1
+ import { RectDiffPipeline } from "../lib/RectDiffPipeline"
2
+ import type { SimpleRouteJson } from "../lib/types/srj-types"
3
+
4
+ type BenchmarkInput = {
5
+ simpleRouteJson: SimpleRouteJson
6
+ }
7
+
8
+ const args = Bun.argv.slice(2)
9
+ const filePath = args[0] ?? "test-assets/keyboard4.json"
10
+ const repeatArg = args.find((arg) => arg.startsWith("--repeat="))
11
+ const repeatCount = repeatArg
12
+ ? Number.parseInt(repeatArg.split("=")[1]!, 10)
13
+ : 5
14
+
15
+ const data = JSON.parse(await Bun.file(filePath).text()) as
16
+ | BenchmarkInput
17
+ | BenchmarkInput[]
18
+ const input = Array.isArray(data) ? data[0] : data
19
+
20
+ if (!input?.simpleRouteJson) {
21
+ throw new Error(`Expected ${filePath} to contain { simpleRouteJson } input`)
22
+ }
23
+
24
+ const areaScore = (
25
+ meshNodes: ReturnType<RectDiffPipeline["getOutput"]>["meshNodes"],
26
+ ) =>
27
+ meshNodes.reduce(
28
+ (sum, node) =>
29
+ sum + node.width * node.height * (node.availableZ?.length ?? 1),
30
+ 0,
31
+ )
32
+
33
+ const runs: Array<{
34
+ totalMs: number
35
+ gridMs: number
36
+ gapFillMs: number
37
+ nodeCount: number
38
+ area: number
39
+ }> = []
40
+
41
+ for (let i = 0; i < repeatCount; i++) {
42
+ const solver = new RectDiffPipeline(input)
43
+ const t0 = performance.now()
44
+ solver.solve()
45
+ const t1 = performance.now()
46
+ const meshNodes = solver.getOutput().meshNodes
47
+ const stages = solver.getStageStats()
48
+ runs.push({
49
+ totalMs: t1 - t0,
50
+ gridMs: stages.rectDiffGridSolverPipeline?.timeSpent ?? 0,
51
+ gapFillMs: stages.gapFillSolver?.timeSpent ?? 0,
52
+ nodeCount: meshNodes.length,
53
+ area: areaScore(meshNodes),
54
+ })
55
+ }
56
+
57
+ const mean = (values: number[]) =>
58
+ values.reduce((sum, value) => sum + value, 0) / values.length
59
+
60
+ console.log(
61
+ JSON.stringify(
62
+ {
63
+ filePath,
64
+ repeatCount,
65
+ obstacleCount: input.simpleRouteJson.obstacles?.length ?? 0,
66
+ connectionCount: input.simpleRouteJson.connections?.length ?? 0,
67
+ averages: {
68
+ totalMs: Number.parseFloat(
69
+ mean(runs.map((run) => run.totalMs)).toFixed(2),
70
+ ),
71
+ gridMs: Number.parseFloat(
72
+ mean(runs.map((run) => run.gridMs)).toFixed(2),
73
+ ),
74
+ gapFillMs: Number.parseFloat(
75
+ mean(runs.map((run) => run.gapFillMs)).toFixed(2),
76
+ ),
77
+ nodeCount: Number.parseFloat(
78
+ mean(runs.map((run) => run.nodeCount)).toFixed(2),
79
+ ),
80
+ area: Number.parseFloat(mean(runs.map((run) => run.area)).toFixed(2)),
81
+ },
82
+ runs: runs.map((run, index) => ({
83
+ run: index + 1,
84
+ totalMs: Number.parseFloat(run.totalMs.toFixed(2)),
85
+ gridMs: Number.parseFloat(run.gridMs.toFixed(2)),
86
+ gapFillMs: Number.parseFloat(run.gapFillMs.toFixed(2)),
87
+ nodeCount: run.nodeCount,
88
+ area: Number.parseFloat(run.area.toFixed(2)),
89
+ })),
90
+ },
91
+ null,
92
+ 2,
93
+ ),
94
+ )