@tscircuit/core 0.0.2016 → 0.0.2017

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 (2) hide show
  1. package/dist/index.js +398 -372
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -17594,16 +17594,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
17594
17594
  }
17595
17595
  };
17596
17596
 
17597
- // lib/components/normal-components/Board.ts
17598
- import {
17599
- dedupePcbDrcErrors as dedupePcbDrcErrors2,
17600
- consolidatePcbOverlapErrors as consolidatePcbOverlapErrors2,
17601
- runAllNetlistChecks,
17602
- runAllPinSpecificationChecks,
17603
- runAllPlacementChecks as runAllPlacementChecks2,
17604
- runAllRoutingChecks as runAllRoutingChecks2,
17605
- runAllSchematicChecks
17606
- } from "@tscircuit/checks";
17597
+ // lib/components/normal-components/Board/Board.ts
17607
17598
  import { getBoundsFromPoints as getBoundsFromPoints10 } from "@tscircuit/math-utils";
17608
17599
  import { boardProps } from "@tscircuit/props";
17609
17600
  import { compose as compose16, translate as translate16 } from "transformation-matrix";
@@ -64570,7 +64561,7 @@ function Group_getRoutingPhasePlans(group) {
64570
64561
  var package_default = {
64571
64562
  name: "@tscircuit/core",
64572
64563
  type: "module",
64573
- version: "0.0.2015",
64564
+ version: "0.0.2016",
64574
64565
  types: "dist/index.d.ts",
64575
64566
  main: "dist/index.js",
64576
64567
  module: "dist/index.js",
@@ -64641,7 +64632,7 @@ var package_default = {
64641
64632
  "bun-match-svg": "0.0.12",
64642
64633
  "calculate-elbow": "^0.0.12",
64643
64634
  "chokidar-cli": "^3.0.0",
64644
- "circuit-json": "^0.0.506",
64635
+ "circuit-json": "^0.0.507",
64645
64636
  "circuit-json-to-bpc": "^0.0.13",
64646
64637
  "circuit-json-to-connectivity-map": "^0.0.30",
64647
64638
  "circuit-json-to-gltf": "^0.0.133",
@@ -64705,7 +64696,7 @@ var package_default = {
64705
64696
  overrides: {
64706
64697
  "@tscircuit/circuit-json-util": "^0.0.116",
64707
64698
  "@tscircuit/props": "^0.0.670",
64708
- "circuit-json": "^0.0.506"
64699
+ "circuit-json": "^0.0.507"
64709
64700
  }
64710
64701
  };
64711
64702
 
@@ -68993,248 +68984,6 @@ var inflateCircuitJson = (target, circuitJson, children) => {
68993
68984
  inflateStandalonePcbPrimitives(inflationCtx);
68994
68985
  };
68995
68986
 
68996
- // lib/components/primitive-components/DrcCheck.ts
68997
- import {
68998
- drcCheckProps
68999
- } from "@tscircuit/props";
69000
- import { any_circuit_element } from "circuit-json";
69001
- var isSelectionResultPort = (connectable) => {
69002
- if (!connectable || typeof connectable !== "object") return false;
69003
- const maybePort = connectable;
69004
- return typeof maybePort.getSourcePort === "function";
69005
- };
69006
- var isSelectionResultNet = (connectable) => {
69007
- if (!connectable || typeof connectable !== "object") return false;
69008
- const maybeNet = connectable;
69009
- return typeof maybeNet.getSourceNet === "function";
69010
- };
69011
- var isSelectionResultComponent = (connectable) => {
69012
- if (!connectable || typeof connectable !== "object") return false;
69013
- const maybeComponent = connectable;
69014
- return typeof maybeComponent.getPorts === "function";
69015
- };
69016
- var isCircuitJsonElement = (connectable) => {
69017
- if (!connectable || typeof connectable !== "object") return false;
69018
- const maybeCircuitJsonElement = connectable;
69019
- return typeof maybeCircuitJsonElement.type === "string";
69020
- };
69021
- var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
69022
- var SelectionResultPortImpl = class {
69023
- constructor(port) {
69024
- this.port = port;
69025
- }
69026
- port;
69027
- getPcbPort() {
69028
- const pcbPortId = this.port.pcb_port_id;
69029
- if (!pcbPortId) return null;
69030
- return this.port.root?.db.pcb_port.get(pcbPortId) ?? null;
69031
- }
69032
- getSourcePort() {
69033
- const sourcePortId = this.port.source_port_id;
69034
- if (!sourcePortId) return null;
69035
- return this.port.root?.db.source_port.get(sourcePortId) ?? null;
69036
- }
69037
- };
69038
- var SelectionResultNetImpl = class {
69039
- constructor(net) {
69040
- this.net = net;
69041
- }
69042
- net;
69043
- getSourceNet() {
69044
- const sourceNetId = this.net.source_net_id;
69045
- if (!sourceNetId) return null;
69046
- return this.net.root?.db.source_net.get(sourceNetId) ?? null;
69047
- }
69048
- };
69049
- var SelectionResultComponentImpl = class {
69050
- constructor(component) {
69051
- this.component = component;
69052
- }
69053
- component;
69054
- getPort(name) {
69055
- const port = this.component.selectOne(`port.${name}`, { type: "port" }) ?? this.component.selectOne(`.${name}`, { type: "port" });
69056
- if (!port) return null;
69057
- return new SelectionResultPortImpl(port);
69058
- }
69059
- getPorts() {
69060
- return this.component.selectAll("port").map((port) => new SelectionResultPortImpl(port));
69061
- }
69062
- getPcbComponent() {
69063
- const pcbComponentId = this.component.pcb_component_id;
69064
- if (!pcbComponentId) return null;
69065
- return this.component.root?.db.pcb_component.get(pcbComponentId) ?? null;
69066
- }
69067
- getSourceComponent() {
69068
- const sourceComponentId = this.component.source_component_id;
69069
- if (!sourceComponentId) return null;
69070
- return this.component.root?.db.source_component.get(sourceComponentId) ?? null;
69071
- }
69072
- };
69073
- var DrcCheck = class extends PrimitiveComponent2 {
69074
- get config() {
69075
- return {
69076
- componentName: "DrcCheck",
69077
- zodProps: drcCheckProps
69078
- };
69079
- }
69080
- constructor(props) {
69081
- super(props);
69082
- }
69083
- async runCustomDrcCheck(circuitJson) {
69084
- const result = await this._parsedProps.checkFn(
69085
- this.createCustomDrcCheckContext(circuitJson)
69086
- );
69087
- let diagnostics = [];
69088
- if (Array.isArray(result)) {
69089
- diagnostics = result;
69090
- } else if (result) {
69091
- diagnostics = [result];
69092
- }
69093
- return diagnostics.map(
69094
- (diagnostic, index) => this.createCircuitJsonDiagnostic(diagnostic, index)
69095
- ).filter((diagnostic) => !!diagnostic);
69096
- }
69097
- createCustomDrcCheckContext(circuitJson) {
69098
- return {
69099
- select: this.selectCustomDrcElement.bind(
69100
- this
69101
- ),
69102
- selectAll: this.selectAllCustomDrcElements.bind(
69103
- this
69104
- ),
69105
- isConnected: (a, b) => this.isConnected(a, b, circuitJson),
69106
- isPulledUp: (a) => this.isConnected(a, "net.VCC", circuitJson) || this.isConnected(a, "net.VDD", circuitJson) || this.getResistanceBetween(a, "net.VCC", circuitJson) !== null || this.getResistanceBetween(a, "net.VDD", circuitJson) !== null,
69107
- isPulledDown: (a) => this.isConnected(a, "net.GND", circuitJson) || this.getResistanceBetween(a, "net.GND", circuitJson) !== null,
69108
- getResistanceBetween: (a, b) => this.getResistanceBetween(a, b, circuitJson)
69109
- };
69110
- }
69111
- selectCustomDrcElement(selector) {
69112
- return this.wrapSelectionResult(this.getSubcircuit().selectOne(selector));
69113
- }
69114
- selectAllCustomDrcElements(selector) {
69115
- const selectionResults = [];
69116
- for (const component of this.getSubcircuit().selectAll(selector)) {
69117
- const selectionResult = this.wrapSelectionResult(component);
69118
- if (selectionResult) selectionResults.push(selectionResult);
69119
- }
69120
- return selectionResults;
69121
- }
69122
- wrapSelectionResult(component) {
69123
- if (!component) return null;
69124
- if (component instanceof Port) return new SelectionResultPortImpl(component);
69125
- if (component instanceof Net) return new SelectionResultNetImpl(component);
69126
- return new SelectionResultComponentImpl(component);
69127
- }
69128
- createCircuitJsonDiagnostic(diagnostic, index) {
69129
- const diagnosticRecord = diagnostic;
69130
- let diagnosticType = "source_component_misconfigured_error";
69131
- if (typeof diagnosticRecord.error_type === "string") {
69132
- diagnosticType = diagnosticRecord.error_type;
69133
- } else if (typeof diagnosticRecord.warning_type === "string") {
69134
- diagnosticType = diagnosticRecord.warning_type;
69135
- }
69136
- const diagnosticWithCircuitJsonDefaults = {
69137
- ...diagnostic
69138
- };
69139
- if (typeof diagnosticRecord.type === "string") {
69140
- diagnosticWithCircuitJsonDefaults.type = diagnosticRecord.type;
69141
- } else {
69142
- diagnosticWithCircuitJsonDefaults.type = diagnosticType;
69143
- }
69144
- if (typeof diagnosticRecord.warning_type !== "string") {
69145
- if (typeof diagnosticRecord.error_type === "string") {
69146
- diagnosticWithCircuitJsonDefaults.error_type = diagnosticRecord.error_type;
69147
- } else {
69148
- diagnosticWithCircuitJsonDefaults.error_type = diagnosticType;
69149
- }
69150
- }
69151
- const diagnosticIdField = `${diagnosticType}_id`;
69152
- if (diagnosticRecord[diagnosticIdField]) {
69153
- diagnosticWithCircuitJsonDefaults[diagnosticIdField] = diagnosticRecord[diagnosticIdField];
69154
- } else {
69155
- diagnosticWithCircuitJsonDefaults[diagnosticIdField] = `${diagnosticType}_${this._renderId}_${index}`;
69156
- }
69157
- return any_circuit_element.parse(diagnosticWithCircuitJsonDefaults);
69158
- }
69159
- isConnected(a, b, circuitJson) {
69160
- const aKeys = this.getConnectivityKeys(a, circuitJson);
69161
- const bKeys = this.getConnectivityKeys(b, circuitJson);
69162
- return aKeys.some((key) => bKeys.includes(key));
69163
- }
69164
- getResistanceBetween(a, b, circuitJson) {
69165
- if (this.isConnected(a, b, circuitJson)) return 0;
69166
- const aKeys = this.getConnectivityKeys(a, circuitJson);
69167
- const bKeys = this.getConnectivityKeys(b, circuitJson);
69168
- if (aKeys.length === 0 || bKeys.length === 0) return null;
69169
- const sourceResistors = circuitJson.filter(
69170
- (elm) => elm.type === "source_component" && elm.ftype === "simple_resistor"
69171
- );
69172
- const root = this.root;
69173
- if (!root) return null;
69174
- for (const resistor of sourceResistors) {
69175
- const resistorPorts = root.db.source_port.list({
69176
- source_component_id: resistor.source_component_id
69177
- });
69178
- if (resistorPorts.length !== 2) continue;
69179
- const resistorKeys = resistorPorts.map(
69180
- (port) => port.subcircuit_connectivity_map_key
69181
- );
69182
- const connectsA = resistorKeys.some((key) => key && aKeys.includes(key));
69183
- const connectsB = resistorKeys.some((key) => key && bKeys.includes(key));
69184
- if (connectsA && connectsB) return resistor.resistance;
69185
- }
69186
- return null;
69187
- }
69188
- getConnectivityKeys(connectable, circuitJson) {
69189
- if (!connectable) return [];
69190
- if (typeof connectable === "string") {
69191
- const selected = this.selectCustomDrcElement(connectable);
69192
- if (selected) return this.getConnectivityKeys(selected, circuitJson);
69193
- return [];
69194
- }
69195
- if (isSelectionResultPort(connectable)) {
69196
- return [
69197
- connectable.getSourcePort()?.subcircuit_connectivity_map_key
69198
- ].filter(isNonEmptyString);
69199
- }
69200
- if (isSelectionResultNet(connectable)) {
69201
- return [
69202
- connectable.getSourceNet()?.subcircuit_connectivity_map_key
69203
- ].filter(isNonEmptyString);
69204
- }
69205
- if (isSelectionResultComponent(connectable)) {
69206
- return connectable.getPorts().flatMap((port) => this.getConnectivityKeys(port, circuitJson));
69207
- }
69208
- if (isCircuitJsonElement(connectable)) {
69209
- return this.getCircuitJsonElementConnectivityKeys(
69210
- connectable,
69211
- circuitJson
69212
- );
69213
- }
69214
- return [];
69215
- }
69216
- getCircuitJsonElementConnectivityKeys(element, circuitJson) {
69217
- if (!element) return [];
69218
- if (element.type === "source_port") {
69219
- return [element.subcircuit_connectivity_map_key].filter(isNonEmptyString);
69220
- }
69221
- if (element.type === "source_net") {
69222
- return [element.subcircuit_connectivity_map_key].filter(isNonEmptyString);
69223
- }
69224
- if (element.type === "pcb_port") {
69225
- return this.getConnectivityKeys(element.source_port_id, circuitJson);
69226
- }
69227
- if (element.type === "source_component") {
69228
- const root = this.root;
69229
- if (!root) return [];
69230
- return root.db.source_port.list({
69231
- source_component_id: element.source_component_id
69232
- }).map((port) => port.subcircuit_connectivity_map_key).filter(isNonEmptyString);
69233
- }
69234
- return [];
69235
- }
69236
- };
69237
-
69238
68987
  // lib/utils/circuit-json/create-circuit-json-database.ts
69239
68988
  import * as circuitJsonUtil from "@tscircuit/circuit-json-util";
69240
68989
  function createCircuitJsonDatabase() {
@@ -69714,6 +69463,149 @@ function Subcircuit_getSubcircuitPropHash(subcircuit) {
69714
69463
  return computeHash(hashableData);
69715
69464
  }
69716
69465
 
69466
+ // lib/components/normal-components/Board/Board_updatePcbDesignRuleChecks.ts
69467
+ import {
69468
+ dedupePcbDrcErrors as dedupePcbDrcErrors2,
69469
+ consolidatePcbOverlapErrors,
69470
+ runAllNetlistChecks,
69471
+ runAllPinSpecificationChecks,
69472
+ runAllPlacementChecks,
69473
+ runAllRoutingChecks as runAllRoutingChecks2,
69474
+ runAllSchematicChecks
69475
+ } from "@tscircuit/checks";
69476
+ var Board_updatePcbDesignRuleChecks = (board) => {
69477
+ const { db } = board.root;
69478
+ const routingDisabled = board.root?.pcbRoutingDisabled || board.getInheritedProperty("routingDisabled");
69479
+ const pcbDisabled = board.root?.pcbDisabled;
69480
+ const schematicDisabled = board.root?.schematicDisabled;
69481
+ const drcChecksDisabled = board.root?.platform?.drcChecksDisabled ?? board.getInheritedProperty("drcChecksDisabled");
69482
+ if (drcChecksDisabled) {
69483
+ board._drcChecksComplete = true;
69484
+ return;
69485
+ }
69486
+ const netlistDrcChecksDisabled = board.root?.platform?.netlistDrcChecksDisabled ?? board.getInheritedProperty("netlistDrcChecksDisabled");
69487
+ const pinSpecificationDrcChecksDisabled = board.getInheritedProperty(
69488
+ "pinSpecificationDrcChecksDisabled"
69489
+ );
69490
+ const placementDrcChecksDisabled = board.root?.platform?.placementDrcChecksDisabled ?? board.getInheritedProperty("placementDrcChecksDisabled");
69491
+ const routingDrcChecksDisabled = board.root?.platform?.routingDrcChecksDisabled ?? board.getInheritedProperty("routingDrcChecksDisabled");
69492
+ const shouldRunNetlistChecks = !drcChecksDisabled && !netlistDrcChecksDisabled;
69493
+ const shouldRunPinSpecificationChecks = !drcChecksDisabled && !pinSpecificationDrcChecksDisabled;
69494
+ const shouldRunSchematicChecks = !drcChecksDisabled && !schematicDisabled;
69495
+ const shouldRunPlacementChecks = !drcChecksDisabled && !pcbDisabled && !placementDrcChecksDisabled;
69496
+ const shouldRunRoutingChecks = !drcChecksDisabled && !pcbDisabled && !routingDisabled && !routingDrcChecksDisabled;
69497
+ const fabricatorEngine = board.root?.platform?.fabricatorEngine;
69498
+ const fabricatorPreset = board._parsedProps.fabricatorPreset;
69499
+ const shouldRunFabricatorChecks = !drcChecksDisabled && !pcbDisabled && !!fabricatorEngine && !!fabricatorPreset;
69500
+ if ((shouldRunRoutingChecks || shouldRunFabricatorChecks) && board._hasIncompleteAsyncEffectsInSubtreeForPhase("PcbTraceRender"))
69501
+ return;
69502
+ const hasTracesToRoute = board._hasTracesToRoute();
69503
+ if ((shouldRunRoutingChecks || shouldRunFabricatorChecks) && hasTracesToRoute && !board._areChildSubcircuitsRouted())
69504
+ return;
69505
+ if (board._drcChecksComplete || board._drcChecksInProgress) return;
69506
+ const runDrcChecks = async (circuitJson) => {
69507
+ const checksToRun = [];
69508
+ const queueCheck = (checkName, check) => {
69509
+ checksToRun.push(
69510
+ Promise.resolve().then(check).catch((error) => {
69511
+ const cause = error instanceof Error ? error.message : String(error);
69512
+ db.source_runtime_error.insert({
69513
+ error_type: "source_runtime_error",
69514
+ phase_name: "PcbDesignRuleChecks",
69515
+ message: `DRC could not complete (${checkName}): ${cause}`
69516
+ });
69517
+ return [];
69518
+ })
69519
+ );
69520
+ };
69521
+ const pcbBoardId = board.pcb_board_id;
69522
+ if (shouldRunFabricatorChecks && fabricatorEngine && fabricatorPreset && pcbBoardId) {
69523
+ queueCheck(
69524
+ "fabricator",
69525
+ () => fabricatorEngine.runDrcChecks({
69526
+ circuitJson,
69527
+ fabricatorPreset,
69528
+ pcbBoardId
69529
+ })
69530
+ );
69531
+ }
69532
+ if (shouldRunRoutingChecks) {
69533
+ queueCheck(
69534
+ "routing",
69535
+ () => runAllRoutingChecks2(circuitJson).then(
69536
+ (results) => results.filter(
69537
+ (result) => !board._isExpectedCastellatedHoleDrcError(result)
69538
+ )
69539
+ )
69540
+ );
69541
+ }
69542
+ if (shouldRunPlacementChecks) {
69543
+ const existingPlacementDiagnostics = db.toArray();
69544
+ queueCheck(
69545
+ "placement",
69546
+ () => runAllPlacementChecks(circuitJson, {
69547
+ consolidateOverlaps: false
69548
+ }).then(
69549
+ (results) => consolidatePcbOverlapErrors(
69550
+ circuitJson,
69551
+ results.filter(
69552
+ (result) => !board._isExpectedCastellatedHoleDrcError(result)
69553
+ )
69554
+ ).filter(
69555
+ (result) => !existingPlacementDiagnostics.some(
69556
+ (existing) => existing.type === result.type && "message" in existing && existing.message === result.message
69557
+ )
69558
+ )
69559
+ )
69560
+ );
69561
+ }
69562
+ if (shouldRunNetlistChecks) {
69563
+ queueCheck(
69564
+ "netlist",
69565
+ () => runAllNetlistChecks(circuitJson)
69566
+ );
69567
+ }
69568
+ if (shouldRunPinSpecificationChecks) {
69569
+ queueCheck(
69570
+ "pin_specification",
69571
+ () => runAllPinSpecificationChecks(circuitJson)
69572
+ );
69573
+ }
69574
+ if (shouldRunSchematicChecks) {
69575
+ queueCheck(
69576
+ "schematic",
69577
+ () => runAllSchematicChecks(circuitJson)
69578
+ );
69579
+ }
69580
+ if (!drcChecksDisabled) {
69581
+ for (const drcCheck of board.selectAll("drccheck")) {
69582
+ queueCheck(
69583
+ drcCheck.getString(),
69584
+ () => drcCheck.runCustomDrcCheck(circuitJson)
69585
+ );
69586
+ }
69587
+ }
69588
+ const checkResults = await Promise.all(checksToRun);
69589
+ db.insertAll(
69590
+ consolidatePcbOverlapErrors(
69591
+ circuitJson,
69592
+ dedupePcbDrcErrors2(checkResults.flat())
69593
+ )
69594
+ );
69595
+ };
69596
+ const subcircuit = db.subtree({ subcircuit_id: board.subcircuit_id });
69597
+ const subcircuitCircuitJson = subcircuit.toArray();
69598
+ board._drcChecksInProgress = true;
69599
+ board._queueAsyncEffect("board:drc-checks", async () => {
69600
+ try {
69601
+ await runDrcChecks(subcircuitCircuitJson);
69602
+ board._drcChecksComplete = true;
69603
+ } finally {
69604
+ board._drcChecksInProgress = false;
69605
+ }
69606
+ });
69607
+ };
69608
+
69717
69609
  // lib/utils/copper-pour-connectivity/find-floating-copper.ts
69718
69610
  import {
69719
69611
  getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson5
@@ -69912,7 +69804,7 @@ var findFloatingCopper = (circuitJson, generatedStitchingViaIds = /* @__PURE__ *
69912
69804
  return { floatingPourIds, floatingViaIds };
69913
69805
  };
69914
69806
 
69915
- // lib/components/normal-components/Board_doInitialPcbCopperPourCleanup.ts
69807
+ // lib/components/normal-components/Board/Board_doInitialPcbCopperPourCleanup.ts
69916
69808
  var Board_doInitialPcbCopperPourCleanup = (board) => {
69917
69809
  if (!board.root || board.root.pcbDisabled) return;
69918
69810
  const { db } = board.root;
@@ -69944,10 +69836,10 @@ var Board_doInitialPcbCopperPourCleanup = (board) => {
69944
69836
  }
69945
69837
  };
69946
69838
 
69947
- // lib/components/normal-components/Board_doInitialPcbPlacementDesignRuleChecks.ts
69839
+ // lib/components/normal-components/Board/Board_doInitialPcbPlacementDesignRuleChecks.ts
69948
69840
  import {
69949
- consolidatePcbOverlapErrors,
69950
- runAllPlacementChecks
69841
+ consolidatePcbOverlapErrors as consolidatePcbOverlapErrors2,
69842
+ runAllPlacementChecks as runAllPlacementChecks2
69951
69843
  } from "@tscircuit/checks";
69952
69844
  var resetPcbTraceRenderInSubtree = (renderable) => {
69953
69845
  if (renderable._pcbTraceRenderWaitingForPlacementChecks) {
@@ -69976,11 +69868,11 @@ var Board_doInitialPcbPlacementDesignRuleChecks = (board) => {
69976
69868
  board._pcbPlacementDrcChecksPending = true;
69977
69869
  board._queueAsyncEffect("board:pre-route-placement-checks", async () => {
69978
69870
  try {
69979
- const placementCheckResults = await runAllPlacementChecks(
69871
+ const placementCheckResults = await runAllPlacementChecks2(
69980
69872
  subcircuitCircuitJson,
69981
69873
  { consolidateOverlaps: false }
69982
69874
  );
69983
- const relevantPlacementCheckResults = consolidatePcbOverlapErrors(
69875
+ const relevantPlacementCheckResults = consolidatePcbOverlapErrors2(
69984
69876
  subcircuitCircuitJson,
69985
69877
  placementCheckResults.filter(
69986
69878
  (result) => !board._isExpectedCastellatedHoleDrcError(result)
@@ -70004,7 +69896,7 @@ var Board_doInitialPcbPlacementDesignRuleChecks = (board) => {
70004
69896
  });
70005
69897
  };
70006
69898
 
70007
- // lib/components/normal-components/board-castellated-hole.ts
69899
+ // lib/components/normal-components/Board/board-castellated-hole.ts
70008
69900
  import {
70009
69901
  distance as distance17
70010
69902
  } from "circuit-json";
@@ -70127,7 +70019,7 @@ var BoardCastellatedHole = class _BoardCastellatedHole extends PlatedHole {
70127
70019
  }
70128
70020
  };
70129
70021
 
70130
- // lib/components/normal-components/Board.ts
70022
+ // lib/components/normal-components/Board/Board.ts
70131
70023
  var MIN_EFFECTIVE_BORDER_RADIUS_MM = 0.01;
70132
70024
  var DEFAULT_VIA_PAD_DIAMETER_OVER_HOLE_DIAMETER_MM = 0.15;
70133
70025
  var getRoundedRectOutline = (width, height, radius) => {
@@ -70561,115 +70453,7 @@ var Board = class extends Group5 {
70561
70453
  Board_doInitialPcbCopperPourCleanup(this);
70562
70454
  }
70563
70455
  updatePcbDesignRuleChecks() {
70564
- const { db } = this.root;
70565
- const routingDisabled = this.root?.pcbRoutingDisabled || this.getInheritedProperty("routingDisabled");
70566
- const pcbDisabled = this.root?.pcbDisabled;
70567
- const schematicDisabled = this.root?.schematicDisabled;
70568
- const drcChecksDisabled = this.root?.platform?.drcChecksDisabled ?? this.getInheritedProperty("drcChecksDisabled");
70569
- if (drcChecksDisabled) {
70570
- this._drcChecksComplete = true;
70571
- return;
70572
- }
70573
- const netlistDrcChecksDisabled = this.root?.platform?.netlistDrcChecksDisabled ?? this.getInheritedProperty("netlistDrcChecksDisabled");
70574
- const pinSpecificationDrcChecksDisabled = this.getInheritedProperty(
70575
- "pinSpecificationDrcChecksDisabled"
70576
- );
70577
- const placementDrcChecksDisabled = this.root?.platform?.placementDrcChecksDisabled ?? this.getInheritedProperty("placementDrcChecksDisabled");
70578
- const routingDrcChecksDisabled = this.root?.platform?.routingDrcChecksDisabled ?? this.getInheritedProperty("routingDrcChecksDisabled");
70579
- const shouldRunNetlistChecks = !drcChecksDisabled && !netlistDrcChecksDisabled;
70580
- const shouldRunPinSpecificationChecks = !drcChecksDisabled && !pinSpecificationDrcChecksDisabled;
70581
- const shouldRunSchematicChecks = !drcChecksDisabled && !schematicDisabled;
70582
- const shouldRunPlacementChecks = !drcChecksDisabled && !pcbDisabled && !placementDrcChecksDisabled;
70583
- const shouldRunRoutingChecks = !drcChecksDisabled && !pcbDisabled && !routingDisabled && !routingDrcChecksDisabled;
70584
- const fabricatorEngine = this.root?.platform?.fabricatorEngine;
70585
- const fabricatorPreset = this._parsedProps.fabricatorPreset;
70586
- const shouldRunFabricatorChecks = !drcChecksDisabled && !pcbDisabled && !!fabricatorEngine && !!fabricatorPreset;
70587
- if ((shouldRunRoutingChecks || shouldRunFabricatorChecks) && this._hasIncompleteAsyncEffectsInSubtreeForPhase("PcbTraceRender"))
70588
- return;
70589
- const hasTracesToRoute = this._hasTracesToRoute();
70590
- if ((shouldRunRoutingChecks || shouldRunFabricatorChecks) && hasTracesToRoute && !this._areChildSubcircuitsRouted())
70591
- return;
70592
- if (this._drcChecksComplete || this._drcChecksInProgress) return;
70593
- const runDrcChecks = async (circuitJson) => {
70594
- const checksToRun = [];
70595
- if (shouldRunFabricatorChecks && fabricatorEngine && fabricatorPreset && this.pcb_board_id) {
70596
- checksToRun.push(
70597
- Promise.resolve(
70598
- fabricatorEngine.runDrcChecks({
70599
- circuitJson,
70600
- fabricatorPreset,
70601
- pcbBoardId: this.pcb_board_id
70602
- })
70603
- )
70604
- );
70605
- }
70606
- if (shouldRunRoutingChecks) {
70607
- checksToRun.push(
70608
- runAllRoutingChecks2(circuitJson).then(
70609
- (results) => results.filter(
70610
- (result) => !this._isExpectedCastellatedHoleDrcError(result)
70611
- )
70612
- )
70613
- );
70614
- }
70615
- if (shouldRunPlacementChecks) {
70616
- const existingPlacementDiagnostics = db.toArray();
70617
- checksToRun.push(
70618
- runAllPlacementChecks2(circuitJson, {
70619
- consolidateOverlaps: false
70620
- }).then(
70621
- (results) => consolidatePcbOverlapErrors2(
70622
- circuitJson,
70623
- results.filter(
70624
- (result) => !this._isExpectedCastellatedHoleDrcError(result)
70625
- )
70626
- ).filter(
70627
- (result) => !existingPlacementDiagnostics.some(
70628
- (existing) => existing.type === result.type && "message" in existing && existing.message === result.message
70629
- )
70630
- )
70631
- )
70632
- );
70633
- }
70634
- if (shouldRunNetlistChecks) {
70635
- checksToRun.push(
70636
- runAllNetlistChecks(circuitJson)
70637
- );
70638
- }
70639
- if (shouldRunPinSpecificationChecks) {
70640
- checksToRun.push(
70641
- runAllPinSpecificationChecks(circuitJson)
70642
- );
70643
- }
70644
- if (shouldRunSchematicChecks) {
70645
- checksToRun.push(
70646
- runAllSchematicChecks(circuitJson)
70647
- );
70648
- }
70649
- if (!drcChecksDisabled) {
70650
- for (const drcCheck of this.selectAll("drccheck")) {
70651
- checksToRun.push(drcCheck.runCustomDrcCheck(circuitJson));
70652
- }
70653
- }
70654
- const checkResults = await Promise.all(checksToRun);
70655
- db.insertAll(
70656
- consolidatePcbOverlapErrors2(
70657
- circuitJson,
70658
- dedupePcbDrcErrors2(checkResults.flat())
70659
- )
70660
- );
70661
- };
70662
- const subcircuit = db.subtree({ subcircuit_id: this.subcircuit_id });
70663
- const subcircuitCircuitJson = subcircuit.toArray();
70664
- this._drcChecksInProgress = true;
70665
- this._queueAsyncEffect("board:drc-checks", async () => {
70666
- try {
70667
- await runDrcChecks(subcircuitCircuitJson);
70668
- this._drcChecksComplete = true;
70669
- } finally {
70670
- this._drcChecksInProgress = false;
70671
- }
70672
- });
70456
+ Board_updatePcbDesignRuleChecks(this);
70673
70457
  }
70674
70458
  runRenderPhaseForChildren(phase) {
70675
70459
  this.root?.emit("board:renderPhaseStarted", {
@@ -73056,6 +72840,248 @@ var Constraint3 = class extends PrimitiveComponent2 {
73056
72840
  }
73057
72841
  };
73058
72842
 
72843
+ // lib/components/primitive-components/DrcCheck.ts
72844
+ import {
72845
+ drcCheckProps
72846
+ } from "@tscircuit/props";
72847
+ import { any_circuit_element } from "circuit-json";
72848
+ var isSelectionResultPort = (connectable) => {
72849
+ if (!connectable || typeof connectable !== "object") return false;
72850
+ const maybePort = connectable;
72851
+ return typeof maybePort.getSourcePort === "function";
72852
+ };
72853
+ var isSelectionResultNet = (connectable) => {
72854
+ if (!connectable || typeof connectable !== "object") return false;
72855
+ const maybeNet = connectable;
72856
+ return typeof maybeNet.getSourceNet === "function";
72857
+ };
72858
+ var isSelectionResultComponent = (connectable) => {
72859
+ if (!connectable || typeof connectable !== "object") return false;
72860
+ const maybeComponent = connectable;
72861
+ return typeof maybeComponent.getPorts === "function";
72862
+ };
72863
+ var isCircuitJsonElement = (connectable) => {
72864
+ if (!connectable || typeof connectable !== "object") return false;
72865
+ const maybeCircuitJsonElement = connectable;
72866
+ return typeof maybeCircuitJsonElement.type === "string";
72867
+ };
72868
+ var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
72869
+ var SelectionResultPortImpl = class {
72870
+ constructor(port) {
72871
+ this.port = port;
72872
+ }
72873
+ port;
72874
+ getPcbPort() {
72875
+ const pcbPortId = this.port.pcb_port_id;
72876
+ if (!pcbPortId) return null;
72877
+ return this.port.root?.db.pcb_port.get(pcbPortId) ?? null;
72878
+ }
72879
+ getSourcePort() {
72880
+ const sourcePortId = this.port.source_port_id;
72881
+ if (!sourcePortId) return null;
72882
+ return this.port.root?.db.source_port.get(sourcePortId) ?? null;
72883
+ }
72884
+ };
72885
+ var SelectionResultNetImpl = class {
72886
+ constructor(net) {
72887
+ this.net = net;
72888
+ }
72889
+ net;
72890
+ getSourceNet() {
72891
+ const sourceNetId = this.net.source_net_id;
72892
+ if (!sourceNetId) return null;
72893
+ return this.net.root?.db.source_net.get(sourceNetId) ?? null;
72894
+ }
72895
+ };
72896
+ var SelectionResultComponentImpl = class {
72897
+ constructor(component) {
72898
+ this.component = component;
72899
+ }
72900
+ component;
72901
+ getPort(name) {
72902
+ const port = this.component.selectOne(`port.${name}`, { type: "port" }) ?? this.component.selectOne(`.${name}`, { type: "port" });
72903
+ if (!port) return null;
72904
+ return new SelectionResultPortImpl(port);
72905
+ }
72906
+ getPorts() {
72907
+ return this.component.selectAll("port").map((port) => new SelectionResultPortImpl(port));
72908
+ }
72909
+ getPcbComponent() {
72910
+ const pcbComponentId = this.component.pcb_component_id;
72911
+ if (!pcbComponentId) return null;
72912
+ return this.component.root?.db.pcb_component.get(pcbComponentId) ?? null;
72913
+ }
72914
+ getSourceComponent() {
72915
+ const sourceComponentId = this.component.source_component_id;
72916
+ if (!sourceComponentId) return null;
72917
+ return this.component.root?.db.source_component.get(sourceComponentId) ?? null;
72918
+ }
72919
+ };
72920
+ var DrcCheck = class extends PrimitiveComponent2 {
72921
+ get config() {
72922
+ return {
72923
+ componentName: "DrcCheck",
72924
+ zodProps: drcCheckProps
72925
+ };
72926
+ }
72927
+ constructor(props) {
72928
+ super(props);
72929
+ }
72930
+ async runCustomDrcCheck(circuitJson) {
72931
+ const result = await this._parsedProps.checkFn(
72932
+ this.createCustomDrcCheckContext(circuitJson)
72933
+ );
72934
+ let diagnostics = [];
72935
+ if (Array.isArray(result)) {
72936
+ diagnostics = result;
72937
+ } else if (result) {
72938
+ diagnostics = [result];
72939
+ }
72940
+ return diagnostics.map(
72941
+ (diagnostic, index) => this.createCircuitJsonDiagnostic(diagnostic, index)
72942
+ ).filter((diagnostic) => !!diagnostic);
72943
+ }
72944
+ createCustomDrcCheckContext(circuitJson) {
72945
+ return {
72946
+ select: this.selectCustomDrcElement.bind(
72947
+ this
72948
+ ),
72949
+ selectAll: this.selectAllCustomDrcElements.bind(
72950
+ this
72951
+ ),
72952
+ isConnected: (a, b) => this.isConnected(a, b, circuitJson),
72953
+ isPulledUp: (a) => this.isConnected(a, "net.VCC", circuitJson) || this.isConnected(a, "net.VDD", circuitJson) || this.getResistanceBetween(a, "net.VCC", circuitJson) !== null || this.getResistanceBetween(a, "net.VDD", circuitJson) !== null,
72954
+ isPulledDown: (a) => this.isConnected(a, "net.GND", circuitJson) || this.getResistanceBetween(a, "net.GND", circuitJson) !== null,
72955
+ getResistanceBetween: (a, b) => this.getResistanceBetween(a, b, circuitJson)
72956
+ };
72957
+ }
72958
+ selectCustomDrcElement(selector) {
72959
+ return this.wrapSelectionResult(this.getSubcircuit().selectOne(selector));
72960
+ }
72961
+ selectAllCustomDrcElements(selector) {
72962
+ const selectionResults = [];
72963
+ for (const component of this.getSubcircuit().selectAll(selector)) {
72964
+ const selectionResult = this.wrapSelectionResult(component);
72965
+ if (selectionResult) selectionResults.push(selectionResult);
72966
+ }
72967
+ return selectionResults;
72968
+ }
72969
+ wrapSelectionResult(component) {
72970
+ if (!component) return null;
72971
+ if (component instanceof Port) return new SelectionResultPortImpl(component);
72972
+ if (component instanceof Net) return new SelectionResultNetImpl(component);
72973
+ return new SelectionResultComponentImpl(component);
72974
+ }
72975
+ createCircuitJsonDiagnostic(diagnostic, index) {
72976
+ const diagnosticRecord = diagnostic;
72977
+ let diagnosticType = "source_component_misconfigured_error";
72978
+ if (typeof diagnosticRecord.error_type === "string") {
72979
+ diagnosticType = diagnosticRecord.error_type;
72980
+ } else if (typeof diagnosticRecord.warning_type === "string") {
72981
+ diagnosticType = diagnosticRecord.warning_type;
72982
+ }
72983
+ const diagnosticWithCircuitJsonDefaults = {
72984
+ ...diagnostic
72985
+ };
72986
+ if (typeof diagnosticRecord.type === "string") {
72987
+ diagnosticWithCircuitJsonDefaults.type = diagnosticRecord.type;
72988
+ } else {
72989
+ diagnosticWithCircuitJsonDefaults.type = diagnosticType;
72990
+ }
72991
+ if (typeof diagnosticRecord.warning_type !== "string") {
72992
+ if (typeof diagnosticRecord.error_type === "string") {
72993
+ diagnosticWithCircuitJsonDefaults.error_type = diagnosticRecord.error_type;
72994
+ } else {
72995
+ diagnosticWithCircuitJsonDefaults.error_type = diagnosticType;
72996
+ }
72997
+ }
72998
+ const diagnosticIdField = `${diagnosticType}_id`;
72999
+ if (diagnosticRecord[diagnosticIdField]) {
73000
+ diagnosticWithCircuitJsonDefaults[diagnosticIdField] = diagnosticRecord[diagnosticIdField];
73001
+ } else {
73002
+ diagnosticWithCircuitJsonDefaults[diagnosticIdField] = `${diagnosticType}_${this._renderId}_${index}`;
73003
+ }
73004
+ return any_circuit_element.parse(diagnosticWithCircuitJsonDefaults);
73005
+ }
73006
+ isConnected(a, b, circuitJson) {
73007
+ const aKeys = this.getConnectivityKeys(a, circuitJson);
73008
+ const bKeys = this.getConnectivityKeys(b, circuitJson);
73009
+ return aKeys.some((key) => bKeys.includes(key));
73010
+ }
73011
+ getResistanceBetween(a, b, circuitJson) {
73012
+ if (this.isConnected(a, b, circuitJson)) return 0;
73013
+ const aKeys = this.getConnectivityKeys(a, circuitJson);
73014
+ const bKeys = this.getConnectivityKeys(b, circuitJson);
73015
+ if (aKeys.length === 0 || bKeys.length === 0) return null;
73016
+ const sourceResistors = circuitJson.filter(
73017
+ (elm) => elm.type === "source_component" && elm.ftype === "simple_resistor"
73018
+ );
73019
+ const root = this.root;
73020
+ if (!root) return null;
73021
+ for (const resistor of sourceResistors) {
73022
+ const resistorPorts = root.db.source_port.list({
73023
+ source_component_id: resistor.source_component_id
73024
+ });
73025
+ if (resistorPorts.length !== 2) continue;
73026
+ const resistorKeys = resistorPorts.map(
73027
+ (port) => port.subcircuit_connectivity_map_key
73028
+ );
73029
+ const connectsA = resistorKeys.some((key) => key && aKeys.includes(key));
73030
+ const connectsB = resistorKeys.some((key) => key && bKeys.includes(key));
73031
+ if (connectsA && connectsB) return resistor.resistance;
73032
+ }
73033
+ return null;
73034
+ }
73035
+ getConnectivityKeys(connectable, circuitJson) {
73036
+ if (!connectable) return [];
73037
+ if (typeof connectable === "string") {
73038
+ const selected = this.selectCustomDrcElement(connectable);
73039
+ if (selected) return this.getConnectivityKeys(selected, circuitJson);
73040
+ return [];
73041
+ }
73042
+ if (isSelectionResultPort(connectable)) {
73043
+ return [
73044
+ connectable.getSourcePort()?.subcircuit_connectivity_map_key
73045
+ ].filter(isNonEmptyString);
73046
+ }
73047
+ if (isSelectionResultNet(connectable)) {
73048
+ return [
73049
+ connectable.getSourceNet()?.subcircuit_connectivity_map_key
73050
+ ].filter(isNonEmptyString);
73051
+ }
73052
+ if (isSelectionResultComponent(connectable)) {
73053
+ return connectable.getPorts().flatMap((port) => this.getConnectivityKeys(port, circuitJson));
73054
+ }
73055
+ if (isCircuitJsonElement(connectable)) {
73056
+ return this.getCircuitJsonElementConnectivityKeys(
73057
+ connectable,
73058
+ circuitJson
73059
+ );
73060
+ }
73061
+ return [];
73062
+ }
73063
+ getCircuitJsonElementConnectivityKeys(element, circuitJson) {
73064
+ if (!element) return [];
73065
+ if (element.type === "source_port") {
73066
+ return [element.subcircuit_connectivity_map_key].filter(isNonEmptyString);
73067
+ }
73068
+ if (element.type === "source_net") {
73069
+ return [element.subcircuit_connectivity_map_key].filter(isNonEmptyString);
73070
+ }
73071
+ if (element.type === "pcb_port") {
73072
+ return this.getConnectivityKeys(element.source_port_id, circuitJson);
73073
+ }
73074
+ if (element.type === "source_component") {
73075
+ const root = this.root;
73076
+ if (!root) return [];
73077
+ return root.db.source_port.list({
73078
+ source_component_id: element.source_component_id
73079
+ }).map((port) => port.subcircuit_connectivity_map_key).filter(isNonEmptyString);
73080
+ }
73081
+ return [];
73082
+ }
73083
+ };
73084
+
73059
73085
  // lib/components/primitive-components/AutoroutingPhase.ts
73060
73086
  import { autoroutingPhaseProps } from "@tscircuit/props";
73061
73087
  var AutoroutingPhase = class extends PrimitiveComponent2 {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.2016",
4
+ "version": "0.0.2017",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -72,7 +72,7 @@
72
72
  "bun-match-svg": "0.0.12",
73
73
  "calculate-elbow": "^0.0.12",
74
74
  "chokidar-cli": "^3.0.0",
75
- "circuit-json": "^0.0.506",
75
+ "circuit-json": "^0.0.507",
76
76
  "circuit-json-to-bpc": "^0.0.13",
77
77
  "circuit-json-to-connectivity-map": "^0.0.30",
78
78
  "circuit-json-to-gltf": "^0.0.133",
@@ -136,6 +136,6 @@
136
136
  "overrides": {
137
137
  "@tscircuit/circuit-json-util": "^0.0.116",
138
138
  "@tscircuit/props": "^0.0.670",
139
- "circuit-json": "^0.0.506"
139
+ "circuit-json": "^0.0.507"
140
140
  }
141
141
  }