@tscircuit/core 0.0.331 → 0.0.333

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 (3) hide show
  1. package/dist/index.d.ts +27 -10
  2. package/dist/index.js +524 -211
  3. package/package.json +3 -2
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _tscircuit_props from '@tscircuit/props';
2
- import { subcircuitGroupProps, traceProps, SupplierPartNumbers, SchematicPortArrangement, groupProps, AutorouterConfig, boardProps, capacitorProps, chipProps, diodeProps, jumperProps, ledProps, powerSourceProps, resistorProps, constraintProps, fabricationNotePathProps, fabricationNoteTextProps, footprintProps, subcircuitProps, holeProps, pcbKeepoutProps, netAliasProps, platedHoleProps, silkscreenCircleProps, silkscreenPathProps, silkscreenRectProps, silkscreenTextProps, silkscreenLineProps, smtPadProps, traceHintProps, viaProps, batteryProps, pinHeaderProps, resonatorProps, inductorProps, potentiometerProps, pushButtonProps, crystalProps, transistorProps, mosfetProps, switchProps, CapacitorProps, ChipProps, ResistorProps, ManualEditEvent, manual_edits_file } from '@tscircuit/props';
2
+ import { subcircuitGroupProps, AutorouterConfig, traceProps, SupplierPartNumbers, SchematicPortArrangement, groupProps, boardProps, capacitorProps, chipProps, diodeProps, jumperProps, ledProps, powerSourceProps, resistorProps, constraintProps, fabricationNotePathProps, fabricationNoteTextProps, footprintProps, subcircuitProps, holeProps, pcbKeepoutProps, netAliasProps, platedHoleProps, silkscreenCircleProps, silkscreenPathProps, silkscreenRectProps, silkscreenTextProps, silkscreenLineProps, smtPadProps, traceHintProps, viaProps, batteryProps, pinHeaderProps, resonatorProps, inductorProps, potentiometerProps, pushButtonProps, crystalProps, transistorProps, mosfetProps, switchProps, CapacitorProps, ChipProps, ResistorProps, ManualEditEvent, manual_edits_file } from '@tscircuit/props';
3
3
  import React, { ReactElement, DetailedHTMLProps, SVGProps } from 'react';
4
4
  export { createElement } from 'react';
5
5
  import * as zod from 'zod';
@@ -9,6 +9,7 @@ import { PcbTraceError, PcbPlacementError, PcbManualEditConflictError, LayerRef,
9
9
  import { Matrix } from 'transformation-matrix';
10
10
  import { SoupUtilObjects } from '@tscircuit/soup-util';
11
11
  import * as _tscircuit_layout from '@tscircuit/layout';
12
+ import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
12
13
 
13
14
  declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "InitializePortsFromChildren", "CreateNetsFromProps", "CreateTracesFromProps", "CreateTraceHintsFromProps", "SourceRender", "SourceParentAttachment", "PortMatching", "SourceTraceRender", "SourceAddConnectivityMapKey", "SchematicComponentRender", "SchematicPortRender", "SchematicLayout", "SchematicTraceRender", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbLayout", "PcbComponentSizeCalculation", "PcbBoardAutoSize", "PcbTraceRender", "PcbTraceHintRender", "PcbRouteNetIslands", "CadModelRender", "PartsEngineRender"];
14
15
  type RenderPhase = (typeof orderedRenderPhases)[number];
@@ -103,7 +104,7 @@ interface SchematicBoxDimensions {
103
104
  };
104
105
  }
105
106
 
106
- type RootCircuitEventName = "asyncEffect:start" | "asyncEffect:end" | "renderable:renderLifecycle:anyEvent" | `renderable:renderLifecycle:${RenderPhase}:start` | `renderable:renderLifecycle:${RenderPhase}:end` | "external:evalError";
107
+ type RootCircuitEventName = "asyncEffect:start" | "asyncEffect:end" | "renderable:renderLifecycle:anyEvent" | `renderable:renderLifecycle:${RenderPhase}:start` | `renderable:renderLifecycle:${RenderPhase}:end` | "external:evalError" | "autorouting:start" | "autorouting:end" | "autorouting:progress" | "renderComplete";
107
108
  declare class RootCircuit {
108
109
  firstChild: PrimitiveComponent | null;
109
110
  children: PrimitiveComponent[];
@@ -169,6 +170,7 @@ declare const Circuit: typeof RootCircuit;
169
170
  interface ISubcircuit extends PrimitiveComponent {
170
171
  _shouldUseTraceByTraceRouting(): boolean;
171
172
  _parsedProps: z.infer<typeof subcircuitGroupProps>;
173
+ _getAutorouterConfig(): AutorouterConfig;
172
174
  subcircuit_id: string | null;
173
175
  }
174
176
 
@@ -391,6 +393,7 @@ declare class Net extends PrimitiveComponent<typeof netProps> {
391
393
  };
392
394
  getPortSelector(): string;
393
395
  doInitialSourceRender(): void;
396
+ doInitialSourceParentAttachment(): void;
394
397
  /**
395
398
  * Get all ports connected to this net.
396
399
  *
@@ -412,6 +415,8 @@ declare class Net extends PrimitiveComponent<typeof netProps> {
412
415
  * Sometimes this phase doesn't find any net islands if the autorouter did
413
416
  * a good job and connected the islands. In some sense this is a "backup"
414
417
  * routing phase for autorouters that don't care about connecting nets.
418
+ *
419
+ * This should only run if the autorouter is sequential-trace
415
420
  */
416
421
  doInitialPcbRouteNetIslands(): void;
417
422
  renderError(message: Parameters<typeof PrimitiveComponent.prototype.renderError>[0]): void;
@@ -903,6 +908,7 @@ declare class NormalComponent<ZodProps extends ZodType = any, PortNames extends
903
908
  type SimplifiedPcbTrace = {
904
909
  type: "pcb_trace";
905
910
  pcb_trace_id: string;
911
+ connection_name?: string;
906
912
  route: Array<{
907
913
  route_type: "wire";
908
914
  x: number;
@@ -966,12 +972,15 @@ declare class Group<Props extends z.ZodType<any, any, any> = typeof groupProps>
966
972
  doInitialSourceParentAttachment(): void;
967
973
  doInitialPcbComponentRender(): void;
968
974
  doInitialCreateTraceHintsFromProps(): void;
969
- _getSimpleRouteJsonFromPcbTraces(): SimpleRouteJson;
970
975
  doInitialSourceAddConnectivityMapKey(): void;
971
976
  _areChildSubcircuitsRouted(): boolean;
972
977
  _shouldRouteAsync(): boolean;
973
978
  _hasTracesToRoute(): boolean;
974
979
  _runEffectMakeHttpAutoroutingRequest(): Promise<void>;
980
+ /**
981
+ * Run local autorouting using the CapacityMeshAutorouter
982
+ */
983
+ _runLocalCapacityMeshAutorouting(): Promise<void>;
975
984
  _startAsyncAutorouting(): void;
976
985
  doInitialPcbTraceRender(): void;
977
986
  updatePcbTraceRender(): void;
@@ -10715,10 +10724,15 @@ declare const applyEditEventsToManualEditsFile: ({ circuitJson, editEvents, manu
10715
10724
  /**
10716
10725
  * This function can only be called in the PcbTraceRender phase or later
10717
10726
  */
10718
- declare const getSimpleRouteJsonFromCircuitJson: ({ circuitJson, minTraceWidth, }: {
10719
- circuitJson: AnyCircuitElement[];
10727
+ declare const getSimpleRouteJsonFromCircuitJson: ({ db, circuitJson, subcircuit_id, minTraceWidth, }: {
10728
+ db?: SoupUtilObjects;
10729
+ circuitJson?: AnyCircuitElement[];
10730
+ subcircuit_id?: string | null;
10720
10731
  minTraceWidth?: number;
10721
- }) => SimpleRouteJson;
10732
+ }) => {
10733
+ simpleRouteJson: SimpleRouteJson;
10734
+ connMap: ConnectivityMap;
10735
+ };
10722
10736
 
10723
10737
  type RenderEvent = {
10724
10738
  type: string;
@@ -10737,7 +10751,7 @@ declare const getPhaseTimingsFromRenderEvents: (renderEvents: RenderEvent[]) =>
10737
10751
  type Nums16 = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12" | "13" | "14" | "15" | "16";
10738
10752
  type Nums40 = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12" | "13" | "14" | "15" | "16" | "17" | "18" | "19" | "20" | "21" | "22" | "23" | "24" | "25" | "26" | "27" | "28" | "29" | "30" | "31" | "32" | "33" | "34" | "35" | "36" | "37" | "38" | "39" | "40";
10739
10753
  type PinNumbers100 = "pin1" | "pin2" | "pin3" | "pin4" | "pin5" | "pin6" | "pin7" | "pin8" | "pin9" | "pin10" | "pin11" | "pin12" | "pin13" | "pin14" | "pin15" | "pin16" | "pin17" | "pin18" | "pin19" | "pin20" | "pin21" | "pin22" | "pin23" | "pin24" | "pin25" | "pin26" | "pin27" | "pin28" | "pin29" | "pin30" | "pin31" | "pin32" | "pin33" | "pin34" | "pin35" | "pin36" | "pin37" | "pin38" | "pin39" | "pin40" | "pin41" | "pin42" | "pin43" | "pin44" | "pin45" | "pin46" | "pin47" | "pin48" | "pin49" | "pin50" | "pin51" | "pin52" | "pin53" | "pin54" | "pin55" | "pin56" | "pin57" | "pin58" | "pin59" | "pin60" | "pin61" | "pin62" | "pin63" | "pin64" | "pin65" | "pin66" | "pin67" | "pin68" | "pin69" | "pin70" | "pin71" | "pin72" | "pin73" | "pin74" | "pin75" | "pin76" | "pin77" | "pin78" | "pin79" | "pin80" | "pin81" | "pin82" | "pin83" | "pin84" | "pin85" | "pin86" | "pin87" | "pin88" | "pin89" | "pin90" | "pin91" | "pin92" | "pin93" | "pin94" | "pin95" | "pin96" | "pin97" | "pin98" | "pin99" | "pin100";
10740
- type CommonPinNames = "pos" | "neg" | "V5" | "V3_3" | "VCC" | "VDD" | "GND" | `D${Nums40}` | `GP${Nums40}` | `GPIO${Nums40}` | "DP" | "DN" | "VIN" | "VOUT" | "VREF" | "VIN" | "VOUT" | "VREF" | "VIN" | "VOUT" | "VREF" | "OUT" | "DISCH" | "EN" | "IN" | "CLK" | "DATA" | "THRES" | "TRIG" | "RESET" | `A${Nums40}` | `B${Nums40}` | PinNumbers100;
10754
+ type CommonPinNames = "pos" | "neg" | "V5" | "V3_3" | "PWR" | "VCC" | "VDD" | "GND" | `D${Nums40}` | `GP${Nums40}` | `GPIO${Nums40}` | "DP" | "DN" | "VIN" | "VOUT" | "VREF" | "VIN" | "VOUT" | "VREF" | "VIN" | "VOUT" | "VREF" | "OUT" | "DISCH" | "EN" | "IN" | "CLK" | "DATA" | "THRES" | "TRIG" | "RESET" | `A${Nums40}` | `B${Nums40}` | PinNumbers100;
10741
10755
  type TransistorPinNames = "base" | "collector" | "emitter";
10742
10756
 
10743
10757
  type NonPolarizedSel = Record<`R${Nums40}`, {
@@ -10762,12 +10776,15 @@ type PolarizedSel = Record<`C${Nums40}` | `L${Nums40}` | `LED${Nums40}` | `D${Nu
10762
10776
  pos: string;
10763
10777
  neg: string;
10764
10778
  }>;
10779
+ type CommonNetNames = "VCC" | "GND" | "VDD" | "PWR" | "V5" | "V3_3";
10765
10780
  type TransistorSel = Record<`Q${Nums40}`, Record<TransistorPinNames, string>>;
10766
- type JumperSel = Record<`J${Nums40}`, Record<PinNumbers100, string>>;
10781
+ type JumperSel = Record<`J${Nums40}`, Record<PinNumbers100 | CommonPinNames, string>>;
10767
10782
  type ChipSel = Record<`U${Nums40}`, Record<CommonPinNames, string>>;
10768
- type NetSel = Record<"net", Record<"VCC" | "GND" | "VDD", string>>;
10783
+ type NetSel = Record<"net", Record<CommonNetNames, string>>;
10769
10784
  type ConnectionSel = Record<`CN${Nums40}`, Record<CommonPinNames, string>>;
10770
- type Sel = NonPolarizedSel & PolarizedSel & TransistorSel & JumperSel & ChipSel & SwSel & NetSel & ConnectionSel;
10785
+ type SubcircuitSel = Record<"subcircuit", Record<`S${Nums40}`, SelWithoutSubcircuit>>;
10786
+ type SelWithoutSubcircuit = NonPolarizedSel & PolarizedSel & TransistorSel & JumperSel & ChipSel & SwSel & NetSel & ConnectionSel;
10787
+ type Sel = SubcircuitSel & SelWithoutSubcircuit;
10771
10788
  declare const sel: Sel;
10772
10789
 
10773
10790
  interface TscircuitElements {
package/dist/index.js CHANGED
@@ -1192,6 +1192,14 @@ var Net = class extends PrimitiveComponent {
1192
1192
  });
1193
1193
  this.source_net_id = net.source_net_id;
1194
1194
  }
1195
+ doInitialSourceParentAttachment() {
1196
+ const subcircuit = this.getSubcircuit();
1197
+ if (!subcircuit) return;
1198
+ const { db } = this.root;
1199
+ db.source_net.update(this.source_net_id, {
1200
+ subcircuit_id: subcircuit.subcircuit_id
1201
+ });
1202
+ }
1195
1203
  /**
1196
1204
  * Get all ports connected to this net.
1197
1205
  *
@@ -1235,10 +1243,14 @@ var Net = class extends PrimitiveComponent {
1235
1243
  * Sometimes this phase doesn't find any net islands if the autorouter did
1236
1244
  * a good job and connected the islands. In some sense this is a "backup"
1237
1245
  * routing phase for autorouters that don't care about connecting nets.
1246
+ *
1247
+ * This should only run if the autorouter is sequential-trace
1238
1248
  */
1239
1249
  doInitialPcbRouteNetIslands() {
1240
1250
  if (this.root?.pcbDisabled) return;
1241
1251
  if (this.getSubcircuit()._parsedProps.routingDisabled) return;
1252
+ if (this.getSubcircuit()._getAutorouterConfig().groupMode !== "sequential-trace")
1253
+ return;
1242
1254
  const { db } = this.root;
1243
1255
  const { _parsedProps: props } = this;
1244
1256
  const traces = this._getAllDirectlyConnectedTraces().filter(
@@ -1335,8 +1347,12 @@ var Net = class extends PrimitiveComponent {
1335
1347
  var createNetsFromProps = (component, props) => {
1336
1348
  for (const prop of props) {
1337
1349
  if (typeof prop === "string" && prop.startsWith("net.")) {
1338
- if (!component.getSubcircuit().selectOne(prop)) {
1339
- component.getSubcircuit().add(new Net({ name: prop.split("net.")[1] }));
1350
+ const subcircuit = component.getSubcircuit();
1351
+ if (!subcircuit.selectOne(prop)) {
1352
+ const net = new Net({
1353
+ name: prop.split("net.")[1]
1354
+ });
1355
+ subcircuit.add(net);
1340
1356
  }
1341
1357
  }
1342
1358
  }
@@ -2284,7 +2300,8 @@ var Port = class extends PrimitiveComponent {
2284
2300
  );
2285
2301
  }
2286
2302
  db.source_port.update(this.source_port_id, {
2287
- source_component_id: this.parent?.source_component_id
2303
+ source_component_id: this.parent?.source_component_id,
2304
+ subcircuit_id: this.getSubcircuit()?.subcircuit_id
2288
2305
  });
2289
2306
  this.source_component_id = this.parent?.source_component_id;
2290
2307
  }
@@ -2967,6 +2984,7 @@ var DirectLineRouter = class {
2967
2984
  const trace = {
2968
2985
  type: "pcb_trace",
2969
2986
  pcb_trace_id: "",
2987
+ connection_name: connection.name,
2970
2988
  route: [
2971
2989
  {
2972
2990
  route_type: "wire",
@@ -4689,7 +4707,6 @@ var NormalComponent = class extends PrimitiveComponent {
4689
4707
  if (symbol) {
4690
4708
  const schematic_component2 = db.schematic_component.insert({
4691
4709
  center,
4692
- rotation: props.schRotation ?? 0,
4693
4710
  size: symbol.size,
4694
4711
  source_component_id: this.source_component_id,
4695
4712
  symbol_name,
@@ -5133,64 +5150,156 @@ import {
5133
5150
  groupProps
5134
5151
  } from "@tscircuit/props";
5135
5152
  import * as SAL from "@tscircuit/schematic-autolayout";
5136
- import "circuit-json";
5137
- import { ConnectivityMap } from "circuit-json-to-connectivity-map";
5138
- import Debug5 from "debug";
5139
5153
 
5140
- // lib/utils/autorouting/getSimpleRouteJsonFromTracesAndDb.ts
5141
- import { getObstaclesFromSoup as getObstaclesFromSoup2 } from "@tscircuit/infgrid-ijump-astar";
5142
- var getSimpleRouteJsonFromTracesAndDb = ({
5143
- db,
5144
- traces,
5145
- minTraceWidth = 0.1
5146
- }) => {
5147
- const obstacles = getObstaclesFromSoup2([
5148
- ...db.pcb_component.list(),
5149
- ...db.pcb_smtpad.list(),
5150
- ...db.pcb_plated_hole.list()
5151
- ]);
5152
- const allPoints = obstacles.flatMap((o) => [
5153
- {
5154
- x: o.center.x - o.width / 2,
5155
- y: o.center.y - o.height / 2
5156
- },
5157
- {
5158
- x: o.center.x + o.width / 2,
5159
- y: o.center.y + o.height / 2
5160
- }
5161
- ]);
5162
- const bounds = {
5163
- minX: Math.min(...allPoints.map((p) => p.x)) - 1,
5164
- maxX: Math.max(...allPoints.map((p) => p.x)) + 1,
5165
- minY: Math.min(...allPoints.map((p) => p.y)) - 1,
5166
- maxY: Math.max(...allPoints.map((p) => p.y)) + 1
5167
- };
5168
- const connections = traces.map((trace) => {
5169
- const connectedPorts = trace._findConnectedPorts();
5170
- if (!connectedPorts.allPortsFound || connectedPorts.ports.length < 2)
5171
- return null;
5172
- return {
5173
- name: trace.source_trace_id ?? "",
5174
- pointsToConnect: connectedPorts.ports.map((port) => {
5175
- const pos = port._getGlobalPcbPositionBeforeLayout();
5176
- return {
5177
- x: pos.x,
5178
- y: pos.y,
5179
- layer: port.getAvailablePcbLayers()[0] ?? "top"
5180
- };
5181
- })
5182
- };
5183
- }).filter((c) => c !== null);
5184
- return {
5185
- bounds,
5186
- obstacles: [],
5187
- connections,
5188
- layerCount: 2,
5189
- minTraceWidth
5154
+ // lib/utils/autorouting/CapacityMeshAutorouter.ts
5155
+ import { CapacityMeshSolver } from "@tscircuit/capacity-autorouter";
5156
+ var CapacityMeshAutorouter = class {
5157
+ input;
5158
+ isRouting = false;
5159
+ solver;
5160
+ eventHandlers = {
5161
+ complete: [],
5162
+ error: [],
5163
+ progress: []
5190
5164
  };
5165
+ cycleCount = 0;
5166
+ stepDelay;
5167
+ timeoutId;
5168
+ constructor(input, options = {}) {
5169
+ this.input = input;
5170
+ const { capacityDepth, targetMinCapacity, stepDelay = 0 } = options;
5171
+ this.solver = new CapacityMeshSolver(input, {
5172
+ capacityDepth,
5173
+ targetMinCapacity
5174
+ });
5175
+ this.stepDelay = stepDelay;
5176
+ }
5177
+ /**
5178
+ * Start the autorouting process asynchronously
5179
+ * This will emit progress events during routing and a complete event when done
5180
+ */
5181
+ start() {
5182
+ if (this.isRouting) return;
5183
+ this.isRouting = true;
5184
+ this.cycleCount = 0;
5185
+ this.runCycleAndQueueNextCycle();
5186
+ }
5187
+ /**
5188
+ * Execute the next routing step and schedule the following one if needed
5189
+ */
5190
+ runCycleAndQueueNextCycle() {
5191
+ if (!this.isRouting) return;
5192
+ try {
5193
+ if (this.solver.solved || this.solver.failed) {
5194
+ if (this.solver.failed) {
5195
+ this.emitEvent({
5196
+ type: "error",
5197
+ error: new Error(this.solver.error || "Routing failed")
5198
+ });
5199
+ } else {
5200
+ this.emitEvent({
5201
+ type: "complete",
5202
+ traces: this.solver.getOutputSimpleRouteJson().traces || []
5203
+ });
5204
+ }
5205
+ this.isRouting = false;
5206
+ return;
5207
+ }
5208
+ const startTime = performance.now();
5209
+ const startIterations = this.solver.iterations;
5210
+ while (performance.now() - startTime < 10 && !this.solver.failed && !this.solver.solved) {
5211
+ this.solver.step();
5212
+ }
5213
+ this.cycleCount++;
5214
+ const debugGraphics = this.solver.activeSolver?.visualize() || void 0;
5215
+ const progress = this.solver.progress;
5216
+ this.emitEvent({
5217
+ type: "progress",
5218
+ steps: this.cycleCount,
5219
+ progress,
5220
+ phase: this.solver.getCurrentPhase(),
5221
+ debugGraphics
5222
+ });
5223
+ if (this.stepDelay > 0) {
5224
+ this.timeoutId = setTimeout(
5225
+ () => this.runCycleAndQueueNextCycle(),
5226
+ this.stepDelay
5227
+ );
5228
+ } else {
5229
+ this.timeoutId = setTimeout(
5230
+ () => this.runCycleAndQueueNextCycle(),
5231
+ 0
5232
+ );
5233
+ }
5234
+ } catch (error) {
5235
+ this.emitEvent({
5236
+ type: "error",
5237
+ error: error instanceof Error ? error : new Error(String(error))
5238
+ });
5239
+ this.isRouting = false;
5240
+ }
5241
+ }
5242
+ /**
5243
+ * Stop the routing process if it's in progress
5244
+ */
5245
+ stop() {
5246
+ if (!this.isRouting) return;
5247
+ this.isRouting = false;
5248
+ if (this.timeoutId !== void 0) {
5249
+ clearTimeout(this.timeoutId);
5250
+ this.timeoutId = void 0;
5251
+ }
5252
+ }
5253
+ on(event, callback) {
5254
+ if (event === "complete") {
5255
+ this.eventHandlers.complete.push(
5256
+ callback
5257
+ );
5258
+ } else if (event === "error") {
5259
+ this.eventHandlers.error.push(
5260
+ callback
5261
+ );
5262
+ } else if (event === "progress") {
5263
+ this.eventHandlers.progress.push(
5264
+ callback
5265
+ );
5266
+ }
5267
+ }
5268
+ /**
5269
+ * Emit an event to all registered handlers
5270
+ */
5271
+ emitEvent(event) {
5272
+ if (event.type === "complete") {
5273
+ for (const handler of this.eventHandlers.complete) {
5274
+ handler(event);
5275
+ }
5276
+ } else if (event.type === "error") {
5277
+ for (const handler of this.eventHandlers.error) {
5278
+ handler(event);
5279
+ }
5280
+ } else if (event.type === "progress") {
5281
+ for (const handler of this.eventHandlers.progress) {
5282
+ handler(event);
5283
+ }
5284
+ }
5285
+ }
5286
+ /**
5287
+ * Solve the routing problem synchronously
5288
+ * @returns Array of routed traces
5289
+ */
5290
+ solveSync() {
5291
+ this.solver.solve();
5292
+ if (this.solver.failed) {
5293
+ throw new Error(this.solver.error || "Routing failed");
5294
+ }
5295
+ return this.solver.getOutputSimpleRouteJson().traces || [];
5296
+ }
5191
5297
  };
5192
5298
 
5193
5299
  // lib/components/primitive-components/Group/Group.ts
5300
+ import "circuit-json";
5301
+ import { ConnectivityMap as ConnectivityMap2 } from "circuit-json-to-connectivity-map";
5302
+ import Debug5 from "debug";
5194
5303
  import "zod";
5195
5304
 
5196
5305
  // lib/components/primitive-components/TraceHint.ts
@@ -5254,6 +5363,220 @@ var TraceHint = class extends PrimitiveComponent {
5254
5363
  }
5255
5364
  };
5256
5365
 
5366
+ // lib/utils/edit-events/apply-edit-events-to-manual-edits-file.ts
5367
+ import "zod";
5368
+ import { su } from "@tscircuit/soup-util";
5369
+ var applyEditEventsToManualEditsFile = ({
5370
+ circuitJson,
5371
+ editEvents,
5372
+ manualEditsFile
5373
+ }) => {
5374
+ const updatedManualEditsFile = {
5375
+ ...manualEditsFile,
5376
+ schematic_placements: [...manualEditsFile.schematic_placements ?? []]
5377
+ };
5378
+ for (const editEvent of editEvents) {
5379
+ if (editEvent.edit_event_type === "edit_schematic_component_location") {
5380
+ const { schematic_component_id, new_center } = editEvent;
5381
+ const schematic_component2 = su(circuitJson).schematic_component.get(
5382
+ schematic_component_id
5383
+ );
5384
+ if (!schematic_component2) continue;
5385
+ const source_component = su(circuitJson).source_component.get(
5386
+ schematic_component2.source_component_id
5387
+ );
5388
+ if (!source_component) continue;
5389
+ const existingPlacementIndex = updatedManualEditsFile.schematic_placements?.findIndex(
5390
+ (p) => p.selector === source_component.name
5391
+ );
5392
+ const newPlacement = {
5393
+ selector: source_component.name,
5394
+ center: new_center,
5395
+ relative_to: "group_center"
5396
+ };
5397
+ if (existingPlacementIndex >= 0) {
5398
+ updatedManualEditsFile.schematic_placements[existingPlacementIndex] = newPlacement;
5399
+ } else {
5400
+ updatedManualEditsFile.schematic_placements.push(newPlacement);
5401
+ }
5402
+ }
5403
+ }
5404
+ return updatedManualEditsFile;
5405
+ };
5406
+
5407
+ // lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts
5408
+ import { getObstaclesFromSoup as getObstaclesFromSoup2 } from "@tscircuit/infgrid-ijump-astar";
5409
+ import { su as su2 } from "@tscircuit/soup-util";
5410
+ import {
5411
+ getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson2
5412
+ } from "circuit-json-to-connectivity-map";
5413
+
5414
+ // lib/utils/autorouting/getAncestorSubcircuitIds.ts
5415
+ var getDescendantSubcircuitIds = (db, root_subcircuit_id) => {
5416
+ const groups = db.source_group.list();
5417
+ const result = [];
5418
+ const findDescendants = (parentId) => {
5419
+ const children = groups.filter(
5420
+ (group) => group.parent_subcircuit_id === parentId
5421
+ );
5422
+ for (const child of children) {
5423
+ if (child.subcircuit_id) {
5424
+ result.push(child.subcircuit_id);
5425
+ findDescendants(child.subcircuit_id);
5426
+ }
5427
+ }
5428
+ };
5429
+ findDescendants(root_subcircuit_id);
5430
+ return result;
5431
+ };
5432
+
5433
+ // lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts
5434
+ var getSimpleRouteJsonFromCircuitJson = ({
5435
+ db,
5436
+ circuitJson,
5437
+ subcircuit_id,
5438
+ minTraceWidth = 0.1
5439
+ }) => {
5440
+ if (!db && circuitJson) {
5441
+ db = su2(circuitJson);
5442
+ }
5443
+ if (!db) {
5444
+ throw new Error("db or circuitJson is required");
5445
+ }
5446
+ const relevantSubcircuitIds = subcircuit_id ? /* @__PURE__ */ new Set([subcircuit_id]) : null;
5447
+ if (subcircuit_id) {
5448
+ const descendantSubcircuitIds = getDescendantSubcircuitIds(
5449
+ db,
5450
+ subcircuit_id
5451
+ );
5452
+ for (const id of descendantSubcircuitIds) {
5453
+ relevantSubcircuitIds.add(id);
5454
+ }
5455
+ }
5456
+ const subcircuitElements = (circuitJson ?? db.toArray()).filter(
5457
+ (e) => !subcircuit_id || "subcircuit_id" in e && relevantSubcircuitIds.has(e.subcircuit_id)
5458
+ );
5459
+ const board = db.pcb_board.list()[0];
5460
+ db = su2(subcircuitElements);
5461
+ const connMap = getFullConnectivityMapFromCircuitJson2(subcircuitElements);
5462
+ const obstacles = getObstaclesFromSoup2(
5463
+ [
5464
+ ...db.pcb_component.list(),
5465
+ ...db.pcb_smtpad.list(),
5466
+ ...db.pcb_plated_hole.list()
5467
+ ].filter(
5468
+ (e) => !subcircuit_id || relevantSubcircuitIds?.has(e.subcircuit_id)
5469
+ ),
5470
+ connMap
5471
+ );
5472
+ const allPoints = obstacles.flatMap((o) => [
5473
+ {
5474
+ x: o.center.x - o.width / 2,
5475
+ y: o.center.y - o.height / 2
5476
+ },
5477
+ {
5478
+ x: o.center.x + o.width / 2,
5479
+ y: o.center.y + o.height / 2
5480
+ }
5481
+ ]);
5482
+ let bounds;
5483
+ if (board) {
5484
+ bounds = {
5485
+ minX: board.center.x - board.width / 2,
5486
+ maxX: board.center.x + board.width / 2,
5487
+ minY: board.center.y - board.height / 2,
5488
+ maxY: board.center.y + board.height / 2
5489
+ };
5490
+ } else {
5491
+ bounds = {
5492
+ minX: Math.min(...allPoints.map((p) => p.x)) - 1,
5493
+ maxX: Math.max(...allPoints.map((p) => p.x)) + 1,
5494
+ minY: Math.min(...allPoints.map((p) => p.y)) - 1,
5495
+ maxY: Math.max(...allPoints.map((p) => p.y)) + 1
5496
+ };
5497
+ }
5498
+ const directTraceConnections = db.source_trace.list().map((trace) => {
5499
+ const connectedPorts = trace.connected_source_port_ids.map((id) => {
5500
+ const source_port = db.source_port.get(id);
5501
+ const pcb_port = db.pcb_port.getWhere({ source_port_id: id });
5502
+ return {
5503
+ ...source_port,
5504
+ ...pcb_port
5505
+ };
5506
+ });
5507
+ if (connectedPorts.length < 2) return null;
5508
+ return {
5509
+ name: connMap.getNetConnectedToId(trace.source_trace_id) ?? trace.source_trace_id ?? "",
5510
+ source_trace_id: trace.source_trace_id,
5511
+ pointsToConnect: connectedPorts.map((port) => {
5512
+ return {
5513
+ x: port.x,
5514
+ y: port.y,
5515
+ layer: port.layers?.[0] ?? "top"
5516
+ };
5517
+ })
5518
+ };
5519
+ }).filter((c) => c !== null);
5520
+ const source_nets = db.source_net.list().filter(
5521
+ (e) => !subcircuit_id || relevantSubcircuitIds?.has(e.subcircuit_id)
5522
+ );
5523
+ const connectionsFromNets = [];
5524
+ for (const net of source_nets) {
5525
+ const connectedSourceTraces = db.source_trace.list().filter((st) => st.connected_source_net_ids?.includes(net.source_net_id));
5526
+ connectionsFromNets.push({
5527
+ name: connMap.getNetConnectedToId(net.source_net_id) ?? net.source_net_id,
5528
+ pointsToConnect: connectedSourceTraces.flatMap((st) => {
5529
+ const pcb_ports = db.pcb_port.list().filter(
5530
+ (p) => st.connected_source_port_ids.includes(p.source_port_id)
5531
+ );
5532
+ return pcb_ports.map((p) => ({
5533
+ x: p.x,
5534
+ y: p.y,
5535
+ layer: p.layers?.[0] ?? "top",
5536
+ pcb_port_id: p.pcb_port_id
5537
+ }));
5538
+ })
5539
+ });
5540
+ }
5541
+ return {
5542
+ simpleRouteJson: {
5543
+ bounds,
5544
+ obstacles,
5545
+ connections: [...directTraceConnections, ...connectionsFromNets],
5546
+ // TODO add traces so that we don't run into things routed by another
5547
+ // subcircuit
5548
+ layerCount: 2,
5549
+ minTraceWidth
5550
+ },
5551
+ connMap
5552
+ };
5553
+ };
5554
+
5555
+ // lib/utils/render-events/getPhaseTimingsFromRenderEvents.ts
5556
+ var getPhaseTimingsFromRenderEvents = (renderEvents) => {
5557
+ const phaseTimings = {};
5558
+ if (!renderEvents) return phaseTimings;
5559
+ for (const renderPhase of orderedRenderPhases) {
5560
+ phaseTimings[renderPhase] = 0;
5561
+ }
5562
+ const startEvents = /* @__PURE__ */ new Map();
5563
+ for (const event of renderEvents) {
5564
+ const [, , phase, eventType] = event.type.split(":");
5565
+ if (eventType === "start") {
5566
+ startEvents.set(`${phase}:${event.renderId}`, event);
5567
+ continue;
5568
+ }
5569
+ if (eventType === "end") {
5570
+ const startEvent = startEvents.get(`${phase}:${event.renderId}`);
5571
+ if (startEvent) {
5572
+ const duration = event.createdAt - startEvent.createdAt;
5573
+ phaseTimings[phase] = (phaseTimings[phase] || 0) + duration;
5574
+ }
5575
+ }
5576
+ }
5577
+ return phaseTimings;
5578
+ };
5579
+
5257
5580
  // lib/components/primitive-components/Group/Group.ts
5258
5581
  var Group = class extends NormalComponent {
5259
5582
  pcb_group_id = null;
@@ -5319,20 +5642,11 @@ var Group = class extends NormalComponent {
5319
5642
  );
5320
5643
  }
5321
5644
  }
5322
- _getSimpleRouteJsonFromPcbTraces() {
5323
- const traces = this.selectAll("trace");
5324
- const { db } = this.root;
5325
- return getSimpleRouteJsonFromTracesAndDb({
5326
- db,
5327
- traces,
5328
- minTraceWidth: this._parsedProps.minTraceWidth ?? 0.1
5329
- });
5330
- }
5331
5645
  doInitialSourceAddConnectivityMapKey() {
5332
5646
  if (!this.isSubcircuit) return;
5333
5647
  const { db } = this.root;
5334
5648
  const traces = this.selectAll("trace");
5335
- const connMap = new ConnectivityMap({});
5649
+ const connMap = new ConnectivityMap2({});
5336
5650
  connMap.addConnections(
5337
5651
  traces.map((t) => {
5338
5652
  const source_trace = db.source_trace.get(
@@ -5370,9 +5684,10 @@ var Group = class extends NormalComponent {
5370
5684
  }
5371
5685
  _shouldRouteAsync() {
5372
5686
  const autorouter = this._getAutorouterConfig();
5373
- if (autorouter.local) return false;
5374
5687
  if (autorouter.groupMode === "sequential-trace") return false;
5375
- return true;
5688
+ if (autorouter.local && autorouter.groupMode === "subcircuit") return true;
5689
+ if (!autorouter.local) return true;
5690
+ return false;
5376
5691
  }
5377
5692
  _hasTracesToRoute() {
5378
5693
  const debug4 = Debug5("tscircuit:core:_hasTracesToRoute");
@@ -5403,7 +5718,11 @@ var Group = class extends NormalComponent {
5403
5718
  {
5404
5719
  method: "POST",
5405
5720
  body: JSON.stringify({
5406
- input_simple_route_json: this._getSimpleRouteJsonFromPcbTraces(),
5721
+ input_simple_route_json: getSimpleRouteJsonFromCircuitJson({
5722
+ db,
5723
+ minTraceWidth: this.props.autorouter?.minTraceWidth ?? 0.15,
5724
+ subcircuit_id: this.subcircuit_id
5725
+ }).simpleRouteJson,
5407
5726
  subcircuit_id: this.subcircuit_id
5408
5727
  }),
5409
5728
  headers: { "Content-Type": "application/json" }
@@ -5481,12 +5800,80 @@ var Group = class extends NormalComponent {
5481
5800
  await new Promise((resolve) => setTimeout(resolve, 100));
5482
5801
  }
5483
5802
  }
5803
+ /**
5804
+ * Run local autorouting using the CapacityMeshAutorouter
5805
+ */
5806
+ async _runLocalCapacityMeshAutorouting() {
5807
+ const { db } = this.root;
5808
+ const debug4 = Debug5("tscircuit:core:_runLocalCapacityMeshAutorouting");
5809
+ debug4(`[${this.getString()}] starting local capacity mesh autorouting`);
5810
+ const { simpleRouteJson, connMap } = getSimpleRouteJsonFromCircuitJson({
5811
+ db,
5812
+ minTraceWidth: this.props.autorouter?.minTraceWidth ?? 0.15,
5813
+ subcircuit_id: this.subcircuit_id
5814
+ });
5815
+ this.root?.emit("autorouting:start", {
5816
+ subcircuit_id: this.subcircuit_id,
5817
+ componentDisplayName: this.getString(),
5818
+ simpleRouteJson
5819
+ });
5820
+ const autorouter = new CapacityMeshAutorouter(simpleRouteJson, {
5821
+ // Optional configuration parameters
5822
+ capacityDepth: this.props.autorouter?.capacityDepth,
5823
+ targetMinCapacity: this.props.autorouter?.targetMinCapacity
5824
+ });
5825
+ const routingPromise = new Promise(
5826
+ (resolve, reject) => {
5827
+ autorouter.on("complete", (event) => {
5828
+ debug4(`[${this.getString()}] local autorouting complete`);
5829
+ resolve(event.traces);
5830
+ });
5831
+ autorouter.on("error", (event) => {
5832
+ debug4(
5833
+ `[${this.getString()}] local autorouting error: ${event.error.message}`
5834
+ );
5835
+ reject(event.error);
5836
+ });
5837
+ }
5838
+ );
5839
+ autorouter.on("progress", (event) => {
5840
+ this.root?.emit("autorouting:progress", {
5841
+ subcircuit_id: this.subcircuit_id,
5842
+ componentDisplayName: this.getString(),
5843
+ ...event
5844
+ });
5845
+ });
5846
+ autorouter.start();
5847
+ try {
5848
+ const traces = await routingPromise;
5849
+ this._asyncAutoroutingResult = {
5850
+ output_pcb_traces: traces
5851
+ };
5852
+ this._markDirty("PcbTraceRender");
5853
+ } catch (error) {
5854
+ const { db: db2 } = this.root;
5855
+ db2.pcb_autorouting_error.insert({
5856
+ pcb_error_id: `local_${this.subcircuit_id}`,
5857
+ message: error instanceof Error ? error.message : String(error)
5858
+ });
5859
+ throw error;
5860
+ } finally {
5861
+ autorouter.stop();
5862
+ }
5863
+ }
5484
5864
  _startAsyncAutorouting() {
5485
5865
  this._hasStartedAsyncAutorouting = true;
5486
- this._queueAsyncEffect(
5487
- "make-http-autorouting-request",
5488
- async () => this._runEffectMakeHttpAutoroutingRequest()
5489
- );
5866
+ if (this._getAutorouterConfig().local) {
5867
+ this._queueAsyncEffect(
5868
+ "capacity-mesh-autorouting",
5869
+ async () => this._runLocalCapacityMeshAutorouting()
5870
+ );
5871
+ } else {
5872
+ this._queueAsyncEffect(
5873
+ "make-http-autorouting-request",
5874
+ async () => this._runEffectMakeHttpAutoroutingRequest()
5875
+ );
5876
+ }
5490
5877
  }
5491
5878
  doInitialPcbTraceRender() {
5492
5879
  const debug4 = Debug5("tscircuit:core:doInitialPcbTraceRender");
@@ -5508,6 +5895,7 @@ var Group = class extends NormalComponent {
5508
5895
  }
5509
5896
  updatePcbTraceRender() {
5510
5897
  const debug4 = Debug5("tscircuit:core:updatePcbTraceRender");
5898
+ debug4(`[${this.getString()}] updating...`);
5511
5899
  if (!this.isSubcircuit) return;
5512
5900
  if (this._shouldRouteAsync() && this._hasTracesToRoute() && !this._hasStartedAsyncAutorouting) {
5513
5901
  if (this._areChildSubcircuitsRouted()) {
@@ -5522,10 +5910,16 @@ var Group = class extends NormalComponent {
5522
5910
  if (this._shouldUseTraceByTraceRouting()) return;
5523
5911
  const { db } = this.root;
5524
5912
  if (this._asyncAutoroutingResult.output_simple_route_json) {
5913
+ debug4(
5914
+ `[${this.getString()}] updating PCB traces from simple route json (${this._asyncAutoroutingResult.output_simple_route_json.traces?.length} traces)`
5915
+ );
5525
5916
  this._updatePcbTraceRenderFromSimpleRouteJson();
5526
5917
  return;
5527
5918
  }
5528
5919
  if (this._asyncAutoroutingResult.output_pcb_traces) {
5920
+ debug4(
5921
+ `[${this.getString()}] updating PCB traces from ${this._asyncAutoroutingResult.output_pcb_traces.length} traces`
5922
+ );
5529
5923
  this._updatePcbTraceRenderFromPcbTraces();
5530
5924
  return;
5531
5925
  }
@@ -5534,9 +5928,9 @@ var Group = class extends NormalComponent {
5534
5928
  const { db } = this.root;
5535
5929
  const { traces: routedTraces } = this._asyncAutoroutingResult.output_simple_route_json;
5536
5930
  if (!routedTraces) return;
5537
- const circuitTraces = this.selectAll("trace");
5538
5931
  for (const routedTrace of routedTraces) {
5539
5932
  const pcb_trace = db.pcb_trace.insert({
5933
+ subcircuit_id: this.subcircuit_id,
5540
5934
  route: routedTrace.route
5541
5935
  // source_trace_id: circuitTrace.source_trace_id!,
5542
5936
  });
@@ -5550,6 +5944,22 @@ var Group = class extends NormalComponent {
5550
5944
  pcb_trace.subcircuit_id = this.subcircuit_id;
5551
5945
  db.pcb_trace.insert(pcb_trace);
5552
5946
  }
5947
+ for (const pcb_trace of output_pcb_traces) {
5948
+ for (const point of pcb_trace.route) {
5949
+ if (point.route_type === "via") {
5950
+ db.pcb_via.insert({
5951
+ pcb_trace_id: pcb_trace.pcb_trace_id,
5952
+ x: point.x,
5953
+ y: point.y,
5954
+ hole_diameter: 0.3,
5955
+ outer_diameter: 0.6,
5956
+ layers: [point.from_layer, point.to_layer],
5957
+ from_layer: point.from_layer,
5958
+ to_layer: point.to_layer
5959
+ });
5960
+ }
5961
+ }
5962
+ }
5553
5963
  }
5554
5964
  doInitialSchematicLayout() {
5555
5965
  if (!this.isSubcircuit) return;
@@ -5581,7 +5991,7 @@ var Group = class extends NormalComponent {
5581
5991
  const defaults = {
5582
5992
  serverUrl: "https://registry-api.tscircuit.com",
5583
5993
  serverMode: "job",
5584
- serverCacheEnabled: false
5994
+ serverCacheEnabled: true
5585
5995
  };
5586
5996
  const autorouter = this._parsedProps.autorouter ?? this.getInheritedProperty("autorouter");
5587
5997
  if (typeof autorouter === "object") {
@@ -5593,13 +6003,27 @@ var Group = class extends NormalComponent {
5593
6003
  }
5594
6004
  if (autorouter === "auto-local")
5595
6005
  return {
5596
- local: true
6006
+ local: true,
6007
+ groupMode: "subcircuit"
5597
6008
  };
5598
6009
  if (autorouter === "sequential-trace")
5599
6010
  return {
5600
6011
  local: true,
5601
6012
  groupMode: "sequential-trace"
5602
6013
  };
6014
+ if (autorouter === "subcircuit")
6015
+ return {
6016
+ local: true,
6017
+ groupMode: "subcircuit"
6018
+ };
6019
+ if (autorouter === "auto-cloud")
6020
+ return {
6021
+ local: false,
6022
+ groupMode: "subcircuit",
6023
+ serverUrl: defaults.serverUrl,
6024
+ serverMode: defaults.serverMode,
6025
+ serverCacheEnabled: true
6026
+ };
5603
6027
  return {
5604
6028
  local: true,
5605
6029
  groupMode: "sequential-trace"
@@ -6457,7 +6881,9 @@ var PinHeader = class extends NormalComponent {
6457
6881
  new Port({
6458
6882
  name: `pin${i}`,
6459
6883
  pinNumber: i,
6460
- aliases: []
6884
+ aliases: [this._parsedProps.pinLabels?.[i - 1]].filter(
6885
+ Boolean
6886
+ )
6461
6887
  })
6462
6888
  );
6463
6889
  }
@@ -6778,7 +7204,7 @@ var Switch = class extends NormalComponent {
6778
7204
  };
6779
7205
 
6780
7206
  // lib/RootCircuit.ts
6781
- import { su } from "@tscircuit/soup-util";
7207
+ import { su as su3 } from "@tscircuit/soup-util";
6782
7208
  import { isValidElement as isValidElement2 } from "react";
6783
7209
  import { identity as identity4 } from "transformation-matrix";
6784
7210
  var RootCircuit = class {
@@ -6799,7 +7225,7 @@ var RootCircuit = class {
6799
7225
  _hasRenderedAtleastOnce = false;
6800
7226
  constructor() {
6801
7227
  this.children = [];
6802
- this.db = su([]);
7228
+ this.db = su3([]);
6803
7229
  this.root = this;
6804
7230
  }
6805
7231
  add(componentOrElm) {
@@ -6857,6 +7283,7 @@ var RootCircuit = class {
6857
7283
  await new Promise((resolve) => setTimeout(resolve, 100));
6858
7284
  this.render();
6859
7285
  }
7286
+ this.emit("renderComplete");
6860
7287
  }
6861
7288
  _hasIncompleteAsyncEffects() {
6862
7289
  return this.children.some((child) => {
@@ -7043,137 +7470,6 @@ var useResistor = createUseComponent(
7043
7470
  resistorPins2
7044
7471
  );
7045
7472
 
7046
- // lib/utils/edit-events/apply-edit-events-to-manual-edits-file.ts
7047
- import "zod";
7048
- import { su as su2 } from "@tscircuit/soup-util";
7049
- var applyEditEventsToManualEditsFile = ({
7050
- circuitJson,
7051
- editEvents,
7052
- manualEditsFile
7053
- }) => {
7054
- const updatedManualEditsFile = {
7055
- ...manualEditsFile,
7056
- schematic_placements: [...manualEditsFile.schematic_placements ?? []]
7057
- };
7058
- for (const editEvent of editEvents) {
7059
- if (editEvent.edit_event_type === "edit_schematic_component_location") {
7060
- const { schematic_component_id, new_center } = editEvent;
7061
- const schematic_component2 = su2(circuitJson).schematic_component.get(
7062
- schematic_component_id
7063
- );
7064
- if (!schematic_component2) continue;
7065
- const source_component = su2(circuitJson).source_component.get(
7066
- schematic_component2.source_component_id
7067
- );
7068
- if (!source_component) continue;
7069
- const existingPlacementIndex = updatedManualEditsFile.schematic_placements?.findIndex(
7070
- (p) => p.selector === source_component.name
7071
- );
7072
- const newPlacement = {
7073
- selector: source_component.name,
7074
- center: new_center,
7075
- relative_to: "group_center"
7076
- };
7077
- if (existingPlacementIndex >= 0) {
7078
- updatedManualEditsFile.schematic_placements[existingPlacementIndex] = newPlacement;
7079
- } else {
7080
- updatedManualEditsFile.schematic_placements.push(newPlacement);
7081
- }
7082
- }
7083
- }
7084
- return updatedManualEditsFile;
7085
- };
7086
-
7087
- // lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts
7088
- import { getObstaclesFromSoup as getObstaclesFromSoup3 } from "@tscircuit/infgrid-ijump-astar";
7089
- import { su as su3 } from "@tscircuit/soup-util";
7090
- import { getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson2 } from "circuit-json-to-connectivity-map";
7091
- var getSimpleRouteJsonFromCircuitJson = ({
7092
- circuitJson,
7093
- minTraceWidth = 0.1
7094
- }) => {
7095
- const db = su3(circuitJson);
7096
- const connMap = getFullConnectivityMapFromCircuitJson2(circuitJson);
7097
- const obstacles = getObstaclesFromSoup3(
7098
- [
7099
- ...db.pcb_component.list(),
7100
- ...db.pcb_smtpad.list(),
7101
- ...db.pcb_plated_hole.list()
7102
- ],
7103
- connMap
7104
- );
7105
- const allPoints = obstacles.flatMap((o) => [
7106
- {
7107
- x: o.center.x - o.width / 2,
7108
- y: o.center.y - o.height / 2
7109
- },
7110
- {
7111
- x: o.center.x + o.width / 2,
7112
- y: o.center.y + o.height / 2
7113
- }
7114
- ]);
7115
- const bounds = {
7116
- minX: Math.min(...allPoints.map((p) => p.x)) - 1,
7117
- maxX: Math.max(...allPoints.map((p) => p.x)) + 1,
7118
- minY: Math.min(...allPoints.map((p) => p.y)) - 1,
7119
- maxY: Math.max(...allPoints.map((p) => p.y)) + 1
7120
- };
7121
- const connections = db.source_trace.list().map((trace) => {
7122
- const connectedPorts = trace.connected_source_port_ids.map((id) => {
7123
- const source_port = db.source_port.get(id);
7124
- const pcb_port = db.pcb_port.getWhere({ source_port_id: id });
7125
- return {
7126
- ...source_port,
7127
- ...pcb_port
7128
- };
7129
- });
7130
- if (connectedPorts.length < 2) return null;
7131
- return {
7132
- name: connMap.getNetConnectedToId(trace.source_trace_id) ?? trace.source_trace_id ?? "",
7133
- source_trace_id: trace.source_trace_id,
7134
- pointsToConnect: connectedPorts.map((port) => {
7135
- return {
7136
- x: port.x,
7137
- y: port.y,
7138
- layer: port.layers?.[0] ?? "top"
7139
- };
7140
- })
7141
- };
7142
- }).filter((c) => c !== null);
7143
- return {
7144
- bounds,
7145
- obstacles,
7146
- connections,
7147
- layerCount: 2,
7148
- minTraceWidth
7149
- };
7150
- };
7151
-
7152
- // lib/utils/render-events/getPhaseTimingsFromRenderEvents.ts
7153
- var getPhaseTimingsFromRenderEvents = (renderEvents) => {
7154
- const phaseTimings = {};
7155
- if (!renderEvents) return phaseTimings;
7156
- for (const renderPhase of orderedRenderPhases) {
7157
- phaseTimings[renderPhase] = 0;
7158
- }
7159
- const startEvents = /* @__PURE__ */ new Map();
7160
- for (const event of renderEvents) {
7161
- const [, , phase, eventType] = event.type.split(":");
7162
- if (eventType === "start") {
7163
- startEvents.set(`${phase}:${event.renderId}`, event);
7164
- continue;
7165
- }
7166
- if (eventType === "end") {
7167
- const startEvent = startEvents.get(`${phase}:${event.renderId}`);
7168
- if (startEvent) {
7169
- const duration = event.createdAt - startEvent.createdAt;
7170
- phaseTimings[phase] = (phaseTimings[phase] || 0) + duration;
7171
- }
7172
- }
7173
- }
7174
- return phaseTimings;
7175
- };
7176
-
7177
7473
  // lib/sel/sel.ts
7178
7474
  var sel = new Proxy(
7179
7475
  {},
@@ -7186,6 +7482,23 @@ var sel = new Proxy(
7186
7482
  if (prop1 === "net") {
7187
7483
  return `net.${prop2}`;
7188
7484
  }
7485
+ if (prop1 === "subcircuit") {
7486
+ return new Proxy(
7487
+ {},
7488
+ {
7489
+ get: (_3, prop3) => {
7490
+ return new Proxy(
7491
+ {},
7492
+ {
7493
+ get: (_4, prop4) => {
7494
+ return `subcircuit.${prop2} > .${prop3} > .${prop4}`;
7495
+ }
7496
+ }
7497
+ );
7498
+ }
7499
+ }
7500
+ );
7501
+ }
7189
7502
  return `.${prop1} > .${prop2}`;
7190
7503
  }
7191
7504
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.331",
4
+ "version": "0.0.333",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -53,12 +53,13 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@lume/kiwi": "^0.4.3",
56
+ "@tscircuit/capacity-autorouter": "^0.0.12",
56
57
  "@tscircuit/infgrid-ijump-astar": "^0.0.33",
57
58
  "@tscircuit/math-utils": "^0.0.9",
58
59
  "@tscircuit/props": "^0.0.152",
59
60
  "@tscircuit/schematic-autolayout": "^0.0.6",
60
61
  "@tscircuit/soup-util": "^0.0.41",
61
- "circuit-json": "^0.0.142",
62
+ "circuit-json": "^0.0.144",
62
63
  "circuit-json-to-connectivity-map": "^0.0.17",
63
64
  "format-si-unit": "^0.0.3",
64
65
  "nanoid": "^5.0.7",