Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions lib/shared/circuit-json-to-footprinter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { AnyCircuitElement } from "circuit-json"
import {
circuitJsonToFootprinter as circuitJsonToFootprinterWithBundledTypes,
type CircuitJsonToFootprinterOptions,
type FootprinterDiscoveryResult,
circuitJsonToFootprinter as circuitJsonToFootprinterWithBundledTypes,
} from "circuit-json-to-footprinter"

export type { FootprinterDiscoveryCandidate } from "circuit-json-to-footprinter"
Expand All @@ -12,7 +12,7 @@ type CircuitJsonToFootprinter = (
options?: CircuitJsonToFootprinterOptions,
) => FootprinterDiscoveryResult

// circuit-json-to-footprinter@0.0.15 bundles an older circuit-json type.
// Keep that compatibility detail isolated at this dependency boundary.
// circuit-json-to-footprinter bundles its own circuit-json version, which can
// differ from the CLI peer version. Keep that type drift isolated here.
export const circuitJsonToFootprinter =
circuitJsonToFootprinterWithBundledTypes as CircuitJsonToFootprinter
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"circuit-json-to-bom-csv": "^0.0.7",
"circuit-json-to-connectivity-map": "^0.0.25",
"circuit-json-to-fdm-component-box": "^0.0.2",
"circuit-json-to-footprinter": "^0.0.15",
"circuit-json-to-footprinter": "^0.0.46",
"circuit-json-to-gerber": "^0.0.94",
"circuit-json-to-kicad": "0.0.157",
"circuit-json-to-pnp-csv": "^0.0.9",
Expand Down
8 changes: 8 additions & 0 deletions scripts/bun-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,18 @@ if (!success) {
process.exit(1)
}

const manifoldWasmSourcePath = Bun.resolveSync(
"@tscircuit/manifold-2d/manifold.wasm",
import.meta.dir,
)
const manifoldWasm = Bun.file(manifoldWasmSourcePath)
await Bun.write("./dist/cli/manifold.wasm", manifoldWasm)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

circuit-json-to-footprinter@0.0.46 introduces @tscircuit/manifold-2d for footprint geometry operations.

The CLI bundles this dependency into dist/cli/main.js. In Node.js, Manifold loads manifold.wasm relative to that bundled JS file, but Bun does not automatically copy the WASM asset into dist.

As a result, the globally installed CLI crashed during startup because it expected:

dist/cli/manifold.wasm

Copying the package-exported WASM file next to main.js preserves Manifold's runtime loading contract. Only dist/cli needs the asset because the other generated bundles do not include the Manifold loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think this is necessary

for (const output of outputs) {
console.log(
`${basename(output.path)} ${(output.size / 1024 / 1024).toFixed(2)} MB`,
)
}
console.log(`manifold.wasm ${(manifoldWasm.size / 1024 / 1024).toFixed(2)} MB`)

export {}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 40 additions & 3 deletions tests/lib/import/convert-imported-footprint-to-footprinter.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import "bun-match-svg"
import { expect, test } from "bun:test"
import { rm, symlink, writeFile } from "node:fs/promises"
import path from "node:path"
import { fp } from "@tscircuit/footprinter"
import type {
AnyCircuitElement,
PcbPort,
PcbSmtPad,
SourcePort,
} from "circuit-json"
import { rm, symlink, writeFile } from "node:fs/promises"
import path from "node:path"
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
import { convertImportedFootprintToFootprinter } from "lib/import/footprinter/convert-imported-footprint-to-footprinter"
import { generateCircuitJson } from "lib/shared/generate-circuit-json"
import { temporaryDirectory } from "tempy"
Expand Down Expand Up @@ -93,6 +95,41 @@ export const TestChip = () => (
}
})

test("compacts C2871569 while preserving its 4x4 thermal-via array", () => {
const circuitJson = fp
.string(
"qfn64_thermalpad6.3mmx6.3mm_thermalvias4x4_thermalviapitch1mm_thermalviaid0.3048mm_thermalviaod0.6096mm_pillpads_h9.67mm_pw0.28mm_pl0.66mm",
)
.circuitJson() as AnyCircuitElement[]
const exactTsx =
"<chip footprint={<footprint><smtpad /><via /></footprint>} />"

const result = convertImportedFootprintToFootprinter({
circuitJson,
sourceHints: ["C2871569", "QFN-64"],
tsx: exactTsx,
})

expect(result.mode).toBe("footprinter")
expect(result.candidate?.footprinterString).toContain("_thermalvias4x4")
expect(result.candidate?.footprinterString).toContain("_thermalviapitch1mm")
expect(result.candidate?.footprinterString).toContain("_thermalviaid0.3048mm")
expect(result.candidate?.footprinterString).toContain("_thermalviaod0.6096mm")
expect(result.candidate?.holeIntersectionOverUnion).toBeGreaterThan(0.99)
expect(result.tsx).not.toContain("footprint={<footprint>")

const recoveredCircuitJson = fp
.string(result.candidate!.footprinterString)
.circuitJson()
expect(
recoveredCircuitJson.filter((element) => element.type === "pcb_via"),
).toHaveLength(16)
expect(convertCircuitJsonToPcbSvg(recoveredCircuitJson)).toMatchSvgSnapshot(
import.meta.path,
"C2871569-thermal-vias",
)
})

test("keeps the exact footprint when copper IoU is at or below 98%", () => {
const circuitJson = fp
.string("res_p1.3mm_pw0.55mm_ph0.7mm")
Expand All @@ -101,7 +138,7 @@ test("keeps the exact footprint when copper IoU is at or below 98%", () => {
if (!firstPad || firstPad.type !== "pcb_smtpad") {
throw new Error("Expected an SMT pad")
}
firstPad.shape = "circle"
Object.assign(firstPad, { radius: 0.1, shape: "circle" as const })
const exactTsx = "<chip footprint={<footprint><smtpad /></footprint>} />"

const result = convertImportedFootprintToFootprinter({
Expand Down
Loading