seveibar/usb-reseter

A tscircuit package created by seveibar.

Version
1.1.4
License
unset
Stars
0

index.circuit.tsx

PCBPCB preview for index.circuit.tsx
SchematicSchematic preview for index.circuit.tsx
import unitLayout from "./lib/usb-reseter-layout.json"
import { machiningForBoard, panel, panelId, tooling } from "./lib/panel-layout"

const boards = [
  { name: "A", x: -24.1, y: 21.1 },
  { name: "B", x: 24.1, y: 21.1 },
  { name: "C", x: -24.1, y: -21.1 },
  { name: "D", x: 24.1, y: -21.1 },
]

const localIds = new Set(unitLayout.flatMap((element) =>
  [element[`${element.type}_id`], element.subcircuit_id].filter(Boolean),
))

// Translate the approved single-board geometry without asking the router
// to regenerate any copper in the context of the other three boards.
function copyValue(value: unknown, name: string, dx: number, dy: number): unknown {
  if (typeof value === "string" && localIds.has(value)) return `${name}_${value}`
  if (Array.isArray(value)) return value.map((item) => copyValue(item, name, dx, dy))
  if (value === null || typeof value !== "object") return value

  const record = value as Record<string, unknown>
  const copy = Object.fromEntries(Object.entries(record).map(([key, item]) =>
    [key, copyValue(item, name, dx, dy)],
  ))
  if (typeof record.x === "number" && typeof record.y === "number") {
    copy.x = record.x + dx
    copy.y = record.y + dy
  }
  return copy
}

function copyBoard({ name, x, y }: typeof boards[number]) {
  return unitLayout.flatMap((element) => {
    // Show the common schematic once. Every unit keeps its own source netlist.
    if (element.type.startsWith("schematic_") && name !== "A") return []
    const isPcb = element.type.startsWith("pcb_")
    const copy = copyValue(element, name, isPcb ? x : 0, isPcb ? y : 0) as Record<string, unknown>
    if (isPcb) copy.pcb_panel_id = panelId
    if (element.type === "cad_component") {
      copy.position = copyValue(element.position, name, x, y)
    }
    if (element.type === "source_component") copy.name = `${element.name}-${name}`
    if (element.type === "source_group") copy.name = name
    return [copy]
  })
}

export const circuitJson = [
  panel,
  ...boards.flatMap(copyBoard),
  ...boards.flatMap(({ name, x, y }) => machiningForBoard(name, x, y)),
  ...tooling,
]