@tscircuit/core 0.0.1414 → 0.0.1416

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.
package/dist/index.d.ts CHANGED
@@ -241,9 +241,9 @@ interface IIsolatedCircuit {
241
241
  interface IRootCircuit extends IIsolatedCircuit {
242
242
  }
243
243
 
244
- declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "RenderIsolatedSubcircuits", "InflateSubcircuitCircuitJson", "SourceNameDuplicateComponentRemoval", "PcbFootprintStringRender", "FetchPartFootprint", "ResolveFootprintPinLabels", "InitializePortsFromChildren", "CreateNetsFromProps", "AssignFallbackProps", "CreateTracesFromProps", "CreateTracesFromNetLabels", "CreateTraceHintsFromProps", "CreateAutoplacedBreakoutPoints", "SourceGroupRender", "AssignNameToUnnamedComponents", "SourceRender", "CheckRefDesConvention", "SourceComponentPropertyValidation", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SourceDesignRuleChecks", "SimulationRender", "SchematicComponentRender", "SchematicPortRender", "SymbolContainerRender", "SchematicPrimitiveRender", "SchematicSymbolResize", "SchematicComponentSizeCalculation", "SchematicLayout", "SchematicSectionRender", "SchematicTraceRender", "SchematicSheetRender", "SchematicReplaceNetLabelsWithSymbols", "PanelBoardLayout", "ValidatePcbCoordinates", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbComponentSizeCalculation", "PcbComponentAnchorAlignment", "PcbCalcPlacementResolution", "PcbLayout", "PcbBoardAutoSize", "PanelLayout", "PcbAutoplaceBreakoutPoints", "PcbTraceHintRender", "PcbManualTraceRender", "PcbTraceRender", "PcbRouteNetIslands", "PcbCopperPourRender", "PcbDesignRuleChecks", "SilkscreenOverlapAdjustment", "CadModelRender", "PartsEngineRender", "SupplierFootprintMismatchWarning", "SimulationSpiceEngineRender"];
244
+ declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "RenderIsolatedSubcircuits", "InflateSubcircuitCircuitJson", "SourceNameDuplicateComponentRemoval", "PcbFootprintStringRender", "FetchPartFootprint", "ResolveFootprintPinLabels", "InitializePortsFromChildren", "CreateNetsFromProps", "AssignFallbackProps", "CreateTracesFromProps", "CreateTracesFromNetLabels", "CreateTraceHintsFromProps", "CreateAutoplacedBreakoutPoints", "SourceGroupRender", "AssignNameToUnnamedComponents", "SourceRender", "CheckRefDesConvention", "SourceComponentPropertyValidation", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SourceDesignRuleChecks", "SimulationRender", "SchematicComponentRender", "SchematicPortRender", "SymbolContainerRender", "SchematicPrimitiveRender", "SchematicSymbolResize", "SchematicComponentSizeCalculation", "SchematicLayout", "SchematicSectionRender", "SchematicTraceRender", "SchematicSheetRender", "SchematicReplaceNetLabelsWithSymbols", "PanelBoardLayout", "ValidatePcbCoordinates", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbComponentSizeCalculation", "PcbComponentAnchorAlignment", "PcbCalcPlacementResolution", "PcbLayout", "PcbBoardAutoSize", "PanelLayout", "PcbAutoplaceBreakoutPoints", "PcbTraceHintRender", "PcbManualTraceRender", "PcbPlacementDesignRuleChecks", "PcbTraceRender", "PcbRouteNetIslands", "PcbCopperPourRender", "PcbDesignRuleChecks", "SilkscreenOverlapAdjustment", "CadModelRender", "PartsEngineRender", "SupplierFootprintMismatchWarning", "SimulationSpiceEngineRender"];
245
245
  type RenderPhase = (typeof orderedRenderPhases)[number];
246
- declare const renderPhaseIndexMap: Map<"ReactSubtreesRender" | "RenderIsolatedSubcircuits" | "InflateSubcircuitCircuitJson" | "SourceNameDuplicateComponentRemoval" | "PcbFootprintStringRender" | "FetchPartFootprint" | "ResolveFootprintPinLabels" | "InitializePortsFromChildren" | "CreateNetsFromProps" | "AssignFallbackProps" | "CreateTracesFromProps" | "CreateTracesFromNetLabels" | "CreateTraceHintsFromProps" | "CreateAutoplacedBreakoutPoints" | "SourceGroupRender" | "AssignNameToUnnamedComponents" | "SourceRender" | "CheckRefDesConvention" | "SourceComponentPropertyValidation" | "SourceParentAttachment" | "PortMatching" | "OptimizeSelectorCache" | "SourceTraceRender" | "SourceAddConnectivityMapKey" | "SourceDesignRuleChecks" | "SimulationRender" | "SchematicComponentRender" | "SchematicPortRender" | "SymbolContainerRender" | "SchematicPrimitiveRender" | "SchematicSymbolResize" | "SchematicComponentSizeCalculation" | "SchematicLayout" | "SchematicSectionRender" | "SchematicTraceRender" | "SchematicSheetRender" | "SchematicReplaceNetLabelsWithSymbols" | "PanelBoardLayout" | "ValidatePcbCoordinates" | "PcbComponentRender" | "PcbPrimitiveRender" | "PcbFootprintLayout" | "PcbPortRender" | "PcbPortAttachment" | "PcbComponentSizeCalculation" | "PcbComponentAnchorAlignment" | "PcbCalcPlacementResolution" | "PcbLayout" | "PcbBoardAutoSize" | "PanelLayout" | "PcbAutoplaceBreakoutPoints" | "PcbTraceHintRender" | "PcbManualTraceRender" | "PcbTraceRender" | "PcbRouteNetIslands" | "PcbCopperPourRender" | "PcbDesignRuleChecks" | "SilkscreenOverlapAdjustment" | "CadModelRender" | "PartsEngineRender" | "SupplierFootprintMismatchWarning" | "SimulationSpiceEngineRender", number>;
246
+ declare const renderPhaseIndexMap: Map<"ReactSubtreesRender" | "RenderIsolatedSubcircuits" | "InflateSubcircuitCircuitJson" | "SourceNameDuplicateComponentRemoval" | "PcbFootprintStringRender" | "FetchPartFootprint" | "ResolveFootprintPinLabels" | "InitializePortsFromChildren" | "CreateNetsFromProps" | "AssignFallbackProps" | "CreateTracesFromProps" | "CreateTracesFromNetLabels" | "CreateTraceHintsFromProps" | "CreateAutoplacedBreakoutPoints" | "SourceGroupRender" | "AssignNameToUnnamedComponents" | "SourceRender" | "CheckRefDesConvention" | "SourceComponentPropertyValidation" | "SourceParentAttachment" | "PortMatching" | "OptimizeSelectorCache" | "SourceTraceRender" | "SourceAddConnectivityMapKey" | "SourceDesignRuleChecks" | "SimulationRender" | "SchematicComponentRender" | "SchematicPortRender" | "SymbolContainerRender" | "SchematicPrimitiveRender" | "SchematicSymbolResize" | "SchematicComponentSizeCalculation" | "SchematicLayout" | "SchematicSectionRender" | "SchematicTraceRender" | "SchematicSheetRender" | "SchematicReplaceNetLabelsWithSymbols" | "PanelBoardLayout" | "ValidatePcbCoordinates" | "PcbComponentRender" | "PcbPrimitiveRender" | "PcbFootprintLayout" | "PcbPortRender" | "PcbPortAttachment" | "PcbComponentSizeCalculation" | "PcbComponentAnchorAlignment" | "PcbCalcPlacementResolution" | "PcbLayout" | "PcbBoardAutoSize" | "PanelLayout" | "PcbAutoplaceBreakoutPoints" | "PcbTraceHintRender" | "PcbManualTraceRender" | "PcbPlacementDesignRuleChecks" | "PcbTraceRender" | "PcbRouteNetIslands" | "PcbCopperPourRender" | "PcbDesignRuleChecks" | "SilkscreenOverlapAdjustment" | "CadModelRender" | "PartsEngineRender" | "SupplierFootprintMismatchWarning" | "SimulationSpiceEngineRender", number>;
247
247
  type RenderPhaseFn<K extends RenderPhase = RenderPhase> = `doInitial${K}` | `update${K}` | `remove${K}`;
248
248
  type RenderPhaseStates = Record<RenderPhase, {
249
249
  initialized: boolean;
@@ -2380,6 +2380,7 @@ declare class Group<Props extends z.ZodType<any, any, any> = typeof groupProps>
2380
2380
  schematic_group_id: string | null;
2381
2381
  subcircuit_id: string | null;
2382
2382
  _hasStartedAsyncAutorouting: boolean;
2383
+ _pcbPlacementDrcErrorCount: number | null;
2383
2384
  _isInflatedFromCircuitJson: boolean;
2384
2385
  _isolatedCircuitJson: AnyCircuitElement[] | null;
2385
2386
  get _isIsolatedSubcircuit(): boolean;
@@ -4046,6 +4047,7 @@ declare class Board extends Group<typeof boardProps> implements BoardI, Subcircu
4046
4047
  doInitialPcbComponentRender(): void;
4047
4048
  removePcbComponentRender(): void;
4048
4049
  doInitialPcbDesignRuleChecks(): void;
4050
+ doInitialPcbPlacementDesignRuleChecks(): void;
4049
4051
  updatePcbDesignRuleChecks(): void;
4050
4052
  _emitRenderLifecycleEvent(phase: RenderPhase, startOrEnd: "start" | "end"): void;
4051
4053
  _repositionOnPcb(position: {
package/dist/index.js CHANGED
@@ -373,6 +373,7 @@ var orderedRenderPhases = [
373
373
  "PcbAutoplaceBreakoutPoints",
374
374
  "PcbTraceHintRender",
375
375
  "PcbManualTraceRender",
376
+ "PcbPlacementDesignRuleChecks",
376
377
  "PcbTraceRender",
377
378
  "PcbRouteNetIslands",
378
379
  "PcbCopperPourRender",
@@ -421,6 +422,10 @@ var asyncPhaseDependencies = {
421
422
  "PcbTraceRender",
422
423
  "PcbRouteNetIslands"
423
424
  ],
425
+ PcbPlacementDesignRuleChecks: [
426
+ "PcbFootprintStringRender",
427
+ "FetchPartFootprint"
428
+ ],
424
429
  PcbTraceRender: ["PcbFootprintStringRender", "FetchPartFootprint"],
425
430
  PcbRouteNetIslands: ["PcbFootprintStringRender", "FetchPartFootprint"],
426
431
  PcbDesignRuleChecks: ["PcbFootprintStringRender", "FetchPartFootprint"],
@@ -4056,6 +4061,37 @@ function Trace_doInitialPcbManualTraceRender(trace) {
4056
4061
  import { MultilayerIjump } from "@tscircuit/infgrid-ijump-astar";
4057
4062
  import "circuit-json";
4058
4063
  import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map";
4064
+
4065
+ // lib/utils/autorouting/should-skip-autorouting-because-of-placement-errors.ts
4066
+ var shouldSkipAutoroutingBecauseOfPlacementErrors = ({
4067
+ component,
4068
+ subcircuit
4069
+ }) => {
4070
+ let ancestor = component;
4071
+ let placementErrorCount = 0;
4072
+ while (ancestor) {
4073
+ if ("_pcbPlacementDrcErrorCount" in ancestor && typeof ancestor._pcbPlacementDrcErrorCount === "number") {
4074
+ placementErrorCount = ancestor._pcbPlacementDrcErrorCount;
4075
+ break;
4076
+ }
4077
+ ancestor = ancestor.parent;
4078
+ }
4079
+ if (placementErrorCount === 0) return false;
4080
+ const { db } = component.root;
4081
+ const pcbErrorId = `pcb_autorouting_skipped_placement_errors_${subcircuit.subcircuit_id}`;
4082
+ const errorAlreadyExists = db.pcb_autorouting_error.list().some((error) => error.pcb_error_id === pcbErrorId);
4083
+ if (!errorAlreadyExists) {
4084
+ db.pcb_autorouting_error.insert({
4085
+ pcb_error_id: pcbErrorId,
4086
+ error_type: "pcb_autorouting_error",
4087
+ subcircuit_id: subcircuit.subcircuit_id ?? void 0,
4088
+ message: `Autorouting was skipped because ${placementErrorCount} PCB placement error${placementErrorCount === 1 ? " was" : "s were"} found. Fix the placement errors or set placementDrcChecksDisabled to true to route anyway.`
4089
+ });
4090
+ }
4091
+ return true;
4092
+ };
4093
+
4094
+ // lib/components/primitive-components/Trace/Trace_doInitialPcbTraceRender.ts
4059
4095
  var portToObjective = (port) => {
4060
4096
  const portPosition = port._getGlobalPcbPositionAfterLayout();
4061
4097
  return {
@@ -4121,6 +4157,11 @@ function Trace_doInitialPcbTraceRender(trace) {
4121
4157
  if (!subcircuit._shouldUseTraceByTraceRouting()) {
4122
4158
  return;
4123
4159
  }
4160
+ if (shouldSkipAutoroutingBecauseOfPlacementErrors({
4161
+ component: trace,
4162
+ subcircuit
4163
+ }))
4164
+ return;
4124
4165
  let allPortsFound;
4125
4166
  let ports;
4126
4167
  let portsWithSelectors;
@@ -19031,6 +19072,7 @@ function convertTreeToMatchPackInputProblem(tree, db, group) {
19031
19072
  x: (schematicComponent.size?.width || 1) + marginLeft + marginRight,
19032
19073
  y: (schematicComponent.size?.height || 1) + marginTop + marginBottom
19033
19074
  },
19075
+ isCapacitor: child.sourceComponent.ftype === "simple_capacitor",
19034
19076
  availableRotations,
19035
19077
  ...explicitlyPositioned && {
19036
19078
  fixedPosition: {
@@ -22932,6 +22974,7 @@ var Group5 = class extends NormalComponent3 {
22932
22974
  schematic_group_id = null;
22933
22975
  subcircuit_id = null;
22934
22976
  _hasStartedAsyncAutorouting = false;
22977
+ _pcbPlacementDrcErrorCount = null;
22935
22978
  _isInflatedFromCircuitJson = false;
22936
22979
  _isolatedCircuitJson = null;
22937
22980
  get _isIsolatedSubcircuit() {
@@ -23731,6 +23774,11 @@ var Group5 = class extends NormalComponent3 {
23731
23774
  `[${this.getString()}] no child subcircuits to wait for, initiating async routing`
23732
23775
  );
23733
23776
  if (!this._hasTracesToRoute()) return;
23777
+ if (shouldSkipAutoroutingBecauseOfPlacementErrors({
23778
+ component: this,
23779
+ subcircuit: this
23780
+ }))
23781
+ return;
23734
23782
  this._startAsyncAutorouting();
23735
23783
  }
23736
23784
  doInitialSchematicTraceRender() {
@@ -23744,6 +23792,11 @@ var Group5 = class extends NormalComponent3 {
23744
23792
  if (this._isInflatedFromCircuitJson) return;
23745
23793
  if (this._shouldRouteAsync() && this._hasTracesToRoute() && !this._hasStartedAsyncAutorouting) {
23746
23794
  if (this._areChildSubcircuitsRouted()) {
23795
+ if (shouldSkipAutoroutingBecauseOfPlacementErrors({
23796
+ component: this,
23797
+ subcircuit: this
23798
+ }))
23799
+ return;
23747
23800
  debug12(
23748
23801
  `[${this.getString()}] child subcircuits are now routed, starting async autorouting`
23749
23802
  );
@@ -25356,7 +25409,7 @@ import { identity as identity5 } from "transformation-matrix";
25356
25409
  var package_default = {
25357
25410
  name: "@tscircuit/core",
25358
25411
  type: "module",
25359
- version: "0.0.1413",
25412
+ version: "0.0.1415",
25360
25413
  types: "dist/index.d.ts",
25361
25414
  main: "dist/index.js",
25362
25415
  module: "dist/index.js",
@@ -25401,7 +25454,7 @@ var package_default = {
25401
25454
  "@tscircuit/jlcpcb-manufacturing-specs": "git+https://github.com/tscircuit/jlcpcb-manufacturing-specs#e08af159db01a37db007e33f0a7268d0e4a279a5",
25402
25455
  "@tscircuit/krt-wasm": "^0.1.1",
25403
25456
  "@tscircuit/log-soup": "^1.0.2",
25404
- "@tscircuit/matchpack": "^0.0.31",
25457
+ "@tscircuit/matchpack": "^0.0.33",
25405
25458
  "@tscircuit/math-utils": "^0.0.36",
25406
25459
  "@tscircuit/miniflex": "^0.0.4",
25407
25460
  "@tscircuit/ngspice-spice-engine": "^0.0.19",
@@ -25920,6 +25973,40 @@ function Subcircuit_getSubcircuitPropHash(subcircuit) {
25920
25973
  return computeHash(hashableData);
25921
25974
  }
25922
25975
 
25976
+ // lib/components/normal-components/Board_doInitialPcbPlacementDesignRuleChecks.ts
25977
+ import {
25978
+ checkConnectorAccessibleOrientation,
25979
+ checkPadPadClearance,
25980
+ checkPadTraceClearance,
25981
+ checkPcbComponentOverlap,
25982
+ checkPcbComponentsOutOfBoard,
25983
+ checkViasOffBoard
25984
+ } from "@tscircuit/checks";
25985
+ var Board_doInitialPcbPlacementDesignRuleChecks = (board) => {
25986
+ if (board.root?.pcbDisabled) return;
25987
+ const placementDrcChecksDisabled = board.root?.platform?.placementDrcChecksDisabled ?? board.getInheritedProperty("placementDrcChecksDisabled");
25988
+ const drcChecksDisabled = board.root?.platform?.drcChecksDisabled ?? board.getInheritedProperty("drcChecksDisabled");
25989
+ board._pcbPlacementDrcErrorCount = 0;
25990
+ if (placementDrcChecksDisabled || drcChecksDisabled) return;
25991
+ const { db } = board.root;
25992
+ const existingPlacementErrorCount = db.pcb_placement_error.list().length;
25993
+ const subcircuitCircuitJson = db.subtree({ subcircuit_id: board.subcircuit_id }).toArray();
25994
+ try {
25995
+ const placementCheckResults = [
25996
+ ...checkViasOffBoard(subcircuitCircuitJson),
25997
+ ...checkPcbComponentsOutOfBoard(subcircuitCircuitJson),
25998
+ ...checkPcbComponentOverlap(subcircuitCircuitJson),
25999
+ ...checkPadPadClearance(subcircuitCircuitJson),
26000
+ ...checkPadTraceClearance(subcircuitCircuitJson),
26001
+ ...checkConnectorAccessibleOrientation(subcircuitCircuitJson)
26002
+ ];
26003
+ db.insertAll(placementCheckResults);
26004
+ board._pcbPlacementDrcErrorCount = existingPlacementErrorCount + placementCheckResults.filter((result) => result.type.endsWith("_error")).length;
26005
+ } catch {
26006
+ board._pcbPlacementDrcErrorCount = existingPlacementErrorCount;
26007
+ }
26008
+ };
26009
+
25923
26010
  // lib/components/normal-components/Board.ts
25924
26011
  var MIN_EFFECTIVE_BORDER_RADIUS_MM = 0.01;
25925
26012
  var getRoundedRectOutline = (width, height, radius) => {
@@ -26314,6 +26401,9 @@ var Board = class extends Group5 {
26314
26401
  super.doInitialPcbDesignRuleChecks();
26315
26402
  this.updatePcbDesignRuleChecks();
26316
26403
  }
26404
+ doInitialPcbPlacementDesignRuleChecks() {
26405
+ Board_doInitialPcbPlacementDesignRuleChecks(this);
26406
+ }
26317
26407
  updatePcbDesignRuleChecks() {
26318
26408
  const { db } = this.root;
26319
26409
  const routingDisabled = this.root?.pcbRoutingDisabled || this.getInheritedProperty("routingDisabled");
@@ -26343,8 +26433,15 @@ var Board = class extends Group5 {
26343
26433
  );
26344
26434
  }
26345
26435
  if (shouldRunPlacementChecks) {
26436
+ const existingPlacementDiagnostics = db.toArray();
26346
26437
  checksToRun.push(
26347
- runAllPlacementChecks(circuitJson)
26438
+ runAllPlacementChecks(circuitJson).then(
26439
+ (results) => results.filter(
26440
+ (result) => !existingPlacementDiagnostics.some(
26441
+ (existing) => existing.type === result.type && "message" in existing && existing.message === result.message
26442
+ )
26443
+ )
26444
+ )
26348
26445
  );
26349
26446
  }
26350
26447
  if (shouldRunNetlistChecks) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1414",
4
+ "version": "0.0.1416",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -46,7 +46,7 @@
46
46
  "@tscircuit/jlcpcb-manufacturing-specs": "git+https://github.com/tscircuit/jlcpcb-manufacturing-specs#e08af159db01a37db007e33f0a7268d0e4a279a5",
47
47
  "@tscircuit/krt-wasm": "^0.1.1",
48
48
  "@tscircuit/log-soup": "^1.0.2",
49
- "@tscircuit/matchpack": "^0.0.31",
49
+ "@tscircuit/matchpack": "^0.0.33",
50
50
  "@tscircuit/math-utils": "^0.0.36",
51
51
  "@tscircuit/miniflex": "^0.0.4",
52
52
  "@tscircuit/ngspice-spice-engine": "^0.0.19",