@tscircuit/core 0.0.39 → 0.0.41

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
@@ -141,10 +141,10 @@ declare abstract class PrimitiveComponent<ZodProps extends ZodType = any> extend
141
141
  _computePcbGlobalTransformBeforeLayout(): Matrix;
142
142
  getPrimitiveContainer(): PrimitiveComponent | null;
143
143
  /**
144
- * Compute the bounds of this component the circuit json elements associated
145
- * with it.
144
+ * Compute the PCB bounds of this component the circuit json elements
145
+ * associated with it.
146
146
  */
147
- _getCircuitJsonBounds(): {
147
+ _getPcbCircuitJsonBounds(): {
148
148
  center: {
149
149
  x: number;
150
150
  y: number;
@@ -161,7 +161,7 @@ declare abstract class PrimitiveComponent<ZodProps extends ZodType = any> extend
161
161
  /**
162
162
  * Set the position of this component from the layout solver. This method
163
163
  * should operate using CircuitJson associated with this component, like
164
- * _getCircuitJsonBounds it can be called multiple times as different
164
+ * _getPcbCircuitJsonBounds it can be called multiple times as different
165
165
  * parents apply layout to their children.
166
166
  */
167
167
  _setPositionFromLayout(newCenter: {
@@ -512,6 +512,24 @@ declare class Port extends PrimitiveComponent<typeof portProps> {
512
512
  x: number;
513
513
  y: number;
514
514
  };
515
+ _getPcbCircuitJsonBounds(): {
516
+ center: {
517
+ x: number;
518
+ y: number;
519
+ };
520
+ bounds: {
521
+ left: number;
522
+ top: number;
523
+ right: number;
524
+ bottom: number;
525
+ };
526
+ width: number;
527
+ height: number;
528
+ };
529
+ _getGlobalPcbPositionAfterLayout(): {
530
+ x: number;
531
+ y: number;
532
+ };
515
533
  _getGlobalSchematicPositionBeforeLayout(): {
516
534
  x: number;
517
535
  y: number;
@@ -770,7 +788,7 @@ declare class SmtPad extends PrimitiveComponent<typeof smtPadProps> {
770
788
  };
771
789
  doInitialPortMatching(): void;
772
790
  doInitialPcbPrimitiveRender(): void;
773
- _getCircuitJsonBounds(): {
791
+ _getPcbCircuitJsonBounds(): {
774
792
  center: {
775
793
  x: number;
776
794
  y: number;
@@ -3819,7 +3837,7 @@ declare class PlatedHole extends PrimitiveComponent<typeof platedHoleProps> {
3819
3837
  width: number;
3820
3838
  height: number;
3821
3839
  };
3822
- _getCircuitJsonBounds(): {
3840
+ _getPcbCircuitJsonBounds(): {
3823
3841
  center: {
3824
3842
  x: number;
3825
3843
  y: number;
@@ -3985,7 +4003,7 @@ declare class Hole extends PrimitiveComponent<typeof holeProps> {
3985
4003
  height: number;
3986
4004
  };
3987
4005
  doInitialPcbPrimitiveRender(): void;
3988
- _getCircuitJsonBounds(): {
4006
+ _getPcbCircuitJsonBounds(): {
3989
4007
  center: {
3990
4008
  x: number;
3991
4009
  y: number;
package/dist/index.js CHANGED
@@ -274,10 +274,10 @@ var PrimitiveComponent = class extends Renderable {
274
274
  return this.parent?.getPrimitiveContainer?.() ?? null;
275
275
  }
276
276
  /**
277
- * Compute the bounds of this component the circuit json elements associated
278
- * with it.
277
+ * Compute the PCB bounds of this component the circuit json elements
278
+ * associated with it.
279
279
  */
280
- _getCircuitJsonBounds() {
280
+ _getPcbCircuitJsonBounds() {
281
281
  return {
282
282
  center: { x: 0, y: 0 },
283
283
  bounds: { left: 0, top: 0, right: 0, bottom: 0 },
@@ -288,7 +288,7 @@ var PrimitiveComponent = class extends Renderable {
288
288
  /**
289
289
  * Set the position of this component from the layout solver. This method
290
290
  * should operate using CircuitJson associated with this component, like
291
- * _getCircuitJsonBounds it can be called multiple times as different
291
+ * _getPcbCircuitJsonBounds it can be called multiple times as different
292
292
  * parents apply layout to their children.
293
293
  */
294
294
  _setPositionFromLayout(newCenter) {
@@ -529,7 +529,7 @@ var Footprint = class extends PrimitiveComponent {
529
529
  selector,
530
530
  componentSelector,
531
531
  edge,
532
- bounds: component._getCircuitJsonBounds()
532
+ bounds: component._getPcbCircuitJsonBounds()
533
533
  }));
534
534
  if (involvedComponents.some((c) => c.edge)) {
535
535
  throw new Error(
@@ -745,6 +745,22 @@ var Port = class extends PrimitiveComponent {
745
745
  }
746
746
  return matchedPcbElm?._getGlobalPcbPositionBeforeLayout() ?? { x: 0, y: 0 };
747
747
  }
748
+ _getPcbCircuitJsonBounds() {
749
+ if (!this.pcb_port_id) {
750
+ return super._getPcbCircuitJsonBounds();
751
+ }
752
+ const { db } = this.root;
753
+ const pcb_port = db.pcb_port.get(this.pcb_port_id);
754
+ return {
755
+ center: { x: pcb_port.x, y: pcb_port.y },
756
+ bounds: { left: 0, top: 0, right: 0, bottom: 0 },
757
+ width: 0,
758
+ height: 0
759
+ };
760
+ }
761
+ _getGlobalPcbPositionAfterLayout() {
762
+ return this._getPcbCircuitJsonBounds().center;
763
+ }
748
764
  _getGlobalSchematicPositionBeforeLayout() {
749
765
  if (!this.schematicSymbolPortDef) {
750
766
  return applyToPoint2(this.parent.computeSchematicGlobalTransform(), {
@@ -845,11 +861,11 @@ var Port = class extends PrimitiveComponent {
845
861
  );
846
862
  }
847
863
  const pcbMatch = pcbMatches[0];
848
- if ("_getCircuitJsonBounds" in pcbMatch) {
864
+ if ("_getPcbCircuitJsonBounds" in pcbMatch) {
849
865
  const pcb_port = db.pcb_port.insert({
850
866
  pcb_component_id: this.parent?.pcb_component_id,
851
867
  layers: ["top"],
852
- ...pcbMatch._getCircuitJsonBounds().center,
868
+ ...pcbMatch._getPcbCircuitJsonBounds().center,
853
869
  source_port_id: this.source_port_id
854
870
  });
855
871
  this.pcb_port_id = pcb_port.pcb_port_id;
@@ -876,8 +892,10 @@ var Port = class extends PrimitiveComponent {
876
892
  }
877
893
  _setPositionFromLayout(newCenter) {
878
894
  const { db } = this.root;
879
- db.schematic_port.update(this.schematic_port_id, {
880
- center: newCenter
895
+ if (!this.pcb_port_id) return;
896
+ db.pcb_port.update(this.pcb_port_id, {
897
+ x: newCenter.x,
898
+ y: newCenter.y
881
899
  });
882
900
  }
883
901
  };
@@ -1134,7 +1152,7 @@ var SmtPad = class extends PrimitiveComponent {
1134
1152
  this.pcb_smtpad_id = pcb_smtpad.pcb_smtpad_id;
1135
1153
  }
1136
1154
  }
1137
- _getCircuitJsonBounds() {
1155
+ _getPcbCircuitJsonBounds() {
1138
1156
  const { db } = this.root;
1139
1157
  const smtpad = db.pcb_smtpad.get(this.pcb_smtpad_id);
1140
1158
  if (smtpad.shape === "rect") {
@@ -1173,6 +1191,7 @@ var SmtPad = class extends PrimitiveComponent {
1173
1191
  x: newCenter.x,
1174
1192
  y: newCenter.y
1175
1193
  });
1194
+ this.matchedPort?._setPositionFromLayout(newCenter);
1176
1195
  }
1177
1196
  };
1178
1197
 
@@ -1239,7 +1258,7 @@ var PlatedHole = class extends PrimitiveComponent {
1239
1258
  `getPcbSize for shape "${props.shape}" not implemented for ${this.componentName}`
1240
1259
  );
1241
1260
  }
1242
- _getCircuitJsonBounds() {
1261
+ _getPcbCircuitJsonBounds() {
1243
1262
  const { db } = this.root;
1244
1263
  const platedHole = db.pcb_plated_hole.get(this.pcb_plated_hole_id);
1245
1264
  const size = this.getPcbSize();
@@ -1261,10 +1280,11 @@ var PlatedHole = class extends PrimitiveComponent {
1261
1280
  x: newCenter.x,
1262
1281
  y: newCenter.y
1263
1282
  });
1283
+ this.matchedPort?._setPositionFromLayout(newCenter);
1264
1284
  }
1265
1285
  doInitialPortMatching() {
1266
- const parentPorts = (this.parent?.children ?? []).filter(
1267
- (c) => c.componentName === "Port"
1286
+ const parentPorts = this.getPrimitiveContainer()?.selectAll(
1287
+ "port"
1268
1288
  );
1269
1289
  if (!this.props.portHints) {
1270
1290
  return;
@@ -2035,7 +2055,7 @@ function getClosest(point, candidates) {
2035
2055
  // lib/components/primitive-components/Trace.ts
2036
2056
  import "zod";
2037
2057
  var portToObjective = (port) => {
2038
- const portPosition = port._getGlobalPcbPositionBeforeLayout();
2058
+ const portPosition = port._getGlobalPcbPositionAfterLayout();
2039
2059
  return {
2040
2060
  ...portPosition,
2041
2061
  layers: port.getAvailablePcbLayers()
@@ -3034,14 +3054,17 @@ var Constraint2 = class extends PrimitiveComponent {
3034
3054
  const componentsWithSelectors = [];
3035
3055
  const container = this.getPrimitiveContainer();
3036
3056
  function addComponentFromSelector(selector) {
3037
- const component = container.selectOne(selector);
3057
+ const maybeEdge = selector.split(" ").pop();
3058
+ const edge = edgeSpecifiers.includes(maybeEdge) ? maybeEdge : void 0;
3059
+ const componentSelector = edge ? selector.replace(` ${edge}`, "") : selector;
3060
+ const component = container.selectOne(componentSelector, {
3061
+ pcbPrimitive: true
3062
+ });
3038
3063
  if (component) {
3039
- const maybeEdge = selector.split(" ").pop();
3040
- const edge = edgeSpecifiers.includes(maybeEdge) ? maybeEdge : void 0;
3041
3064
  componentsWithSelectors.push({
3042
3065
  selector,
3043
3066
  component,
3044
- componentSelector: edge ? selector.replace(` ${edge}`, "") : selector,
3067
+ componentSelector,
3045
3068
  edge
3046
3069
  });
3047
3070
  }
@@ -3087,7 +3110,7 @@ var Hole = class extends PrimitiveComponent {
3087
3110
  });
3088
3111
  this.pcb_hole_id = inserted_hole.pcb_hole_id;
3089
3112
  }
3090
- _getCircuitJsonBounds() {
3113
+ _getPcbCircuitJsonBounds() {
3091
3114
  const { db } = this.root;
3092
3115
  const hole = db.pcb_hole.get(this.pcb_hole_id);
3093
3116
  const size = this.getPcbSize();
@@ -166,10 +166,10 @@ export abstract class PrimitiveComponent<
166
166
  }
167
167
 
168
168
  /**
169
- * Compute the bounds of this component the circuit json elements associated
170
- * with it.
169
+ * Compute the PCB bounds of this component the circuit json elements
170
+ * associated with it.
171
171
  */
172
- _getCircuitJsonBounds(): {
172
+ _getPcbCircuitJsonBounds(): {
173
173
  center: { x: number; y: number }
174
174
  bounds: { left: number; top: number; right: number; bottom: number }
175
175
  width: number
@@ -186,7 +186,7 @@ export abstract class PrimitiveComponent<
186
186
  /**
187
187
  * Set the position of this component from the layout solver. This method
188
188
  * should operate using CircuitJson associated with this component, like
189
- * _getCircuitJsonBounds it can be called multiple times as different
189
+ * _getPcbCircuitJsonBounds it can be called multiple times as different
190
190
  * parents apply layout to their children.
191
191
  */
192
192
  _setPositionFromLayout(newCenter: { x: number; y: number }) {
@@ -56,15 +56,19 @@ export class Constraint extends PrimitiveComponent<typeof constraintProps> {
56
56
  function addComponentFromSelector(selector: string) {
57
57
  // TODO this selector has to be modified in case it contains a leftedge,
58
58
  // center/topedge/rightedge indicator
59
- const component = container.selectOne(selector)
59
+ const maybeEdge = selector.split(" ").pop() as EdgeSpecifier
60
+ const edge = edgeSpecifiers.includes(maybeEdge) ? maybeEdge : undefined
61
+ const componentSelector = edge
62
+ ? selector.replace(` ${edge}`, "")
63
+ : selector
64
+ const component = container.selectOne(componentSelector, {
65
+ pcbPrimitive: true,
66
+ })
60
67
  if (component) {
61
- const maybeEdge = selector.split(" ").pop() as EdgeSpecifier
62
- const edge = edgeSpecifiers.includes(maybeEdge) ? maybeEdge : undefined
63
-
64
68
  componentsWithSelectors.push({
65
69
  selector,
66
70
  component,
67
- componentSelector: edge ? selector.replace(` ${edge}`, "") : selector,
71
+ componentSelector,
68
72
  edge,
69
73
  })
70
74
  }
@@ -28,7 +28,7 @@ export class Footprint extends PrimitiveComponent<typeof footprintProps> {
28
28
  selector,
29
29
  componentSelector,
30
30
  edge,
31
- bounds: component._getCircuitJsonBounds(),
31
+ bounds: component._getPcbCircuitJsonBounds(),
32
32
  }))
33
33
 
34
34
  if (involvedComponents.some((c) => c.edge)) {
@@ -32,7 +32,7 @@ export class Hole extends PrimitiveComponent<typeof holeProps> {
32
32
  this.pcb_hole_id = inserted_hole.pcb_hole_id!
33
33
  }
34
34
 
35
- _getCircuitJsonBounds(): {
35
+ _getPcbCircuitJsonBounds(): {
36
36
  center: { x: number; y: number }
37
37
  bounds: { left: number; top: number; right: number; bottom: number }
38
38
  width: number
@@ -27,7 +27,7 @@ export class PlatedHole extends PrimitiveComponent<typeof platedHoleProps> {
27
27
  )
28
28
  }
29
29
 
30
- _getCircuitJsonBounds(): {
30
+ _getPcbCircuitJsonBounds(): {
31
31
  center: { x: number; y: number }
32
32
  bounds: { left: number; top: number; right: number; bottom: number }
33
33
  width: number
@@ -56,11 +56,12 @@ export class PlatedHole extends PrimitiveComponent<typeof platedHoleProps> {
56
56
  x: newCenter.x,
57
57
  y: newCenter.y,
58
58
  })
59
+ this.matchedPort?._setPositionFromLayout(newCenter)
59
60
  }
60
61
 
61
62
  doInitialPortMatching(): void {
62
- const parentPorts = (this.parent?.children ?? []).filter(
63
- (c) => c.componentName === "Port",
63
+ const parentPorts = this.getPrimitiveContainer()?.selectAll(
64
+ "port",
64
65
  ) as Port[]
65
66
 
66
67
  if (!this.props.portHints) {
@@ -44,6 +44,24 @@ export class Port extends PrimitiveComponent<typeof portProps> {
44
44
  return matchedPcbElm?._getGlobalPcbPositionBeforeLayout() ?? { x: 0, y: 0 }
45
45
  }
46
46
 
47
+ _getPcbCircuitJsonBounds() {
48
+ if (!this.pcb_port_id) {
49
+ return super._getPcbCircuitJsonBounds()
50
+ }
51
+ const { db } = this.root!
52
+ const pcb_port = db.pcb_port.get(this.pcb_port_id)!
53
+ return {
54
+ center: { x: pcb_port.x, y: pcb_port.y },
55
+ bounds: { left: 0, top: 0, right: 0, bottom: 0 },
56
+ width: 0,
57
+ height: 0,
58
+ }
59
+ }
60
+
61
+ _getGlobalPcbPositionAfterLayout(): { x: number; y: number } {
62
+ return this._getPcbCircuitJsonBounds().center
63
+ }
64
+
47
65
  _getGlobalSchematicPositionBeforeLayout(): { x: number; y: number } {
48
66
  if (!this.schematicSymbolPortDef) {
49
67
  return applyToPoint(this.parent!.computeSchematicGlobalTransform(), {
@@ -168,12 +186,12 @@ export class Port extends PrimitiveComponent<typeof portProps> {
168
186
 
169
187
  const pcbMatch: any = pcbMatches[0]
170
188
 
171
- if ("_getCircuitJsonBounds" in pcbMatch) {
189
+ if ("_getPcbCircuitJsonBounds" in pcbMatch) {
172
190
  const pcb_port = db.pcb_port.insert({
173
191
  pcb_component_id: this.parent?.pcb_component_id!,
174
192
  layers: ["top"],
175
193
 
176
- ...pcbMatch._getCircuitJsonBounds().center,
194
+ ...pcbMatch._getPcbCircuitJsonBounds().center,
177
195
 
178
196
  source_port_id: this.source_port_id!,
179
197
  })
@@ -208,9 +226,11 @@ export class Port extends PrimitiveComponent<typeof portProps> {
208
226
 
209
227
  _setPositionFromLayout(newCenter: { x: number; y: number }): void {
210
228
  const { db } = this.root!
229
+ if (!this.pcb_port_id) return
211
230
 
212
- db.schematic_port.update(this.schematic_port_id!, {
213
- center: newCenter,
231
+ db.pcb_port.update(this.pcb_port_id!, {
232
+ x: newCenter.x,
233
+ y: newCenter.y,
214
234
  })
215
235
  }
216
236
  }
@@ -97,7 +97,7 @@ export class SmtPad extends PrimitiveComponent<typeof smtPadProps> {
97
97
  }
98
98
  }
99
99
 
100
- _getCircuitJsonBounds(): {
100
+ _getPcbCircuitJsonBounds(): {
101
101
  center: { x: number; y: number }
102
102
  bounds: { left: number; top: number; right: number; bottom: number }
103
103
  width: number
@@ -143,5 +143,6 @@ export class SmtPad extends PrimitiveComponent<typeof smtPadProps> {
143
143
  x: newCenter.x,
144
144
  y: newCenter.y,
145
145
  })
146
+ this.matchedPort?._setPositionFromLayout(newCenter)
146
147
  }
147
148
  }
@@ -38,7 +38,7 @@ type PcbRouteObjective =
38
38
  | { layers: string[]; x: number; y: number; via?: boolean }
39
39
 
40
40
  const portToObjective = (port: Port): PcbRouteObjective => {
41
- const portPosition = port._getGlobalPcbPositionBeforeLayout()
41
+ const portPosition = port._getGlobalPcbPositionAfterLayout()
42
42
  return {
43
43
  ...portPosition,
44
44
  layers: port.getAvailablePcbLayers(),
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tscircuit/core",
3
3
  "module": "index.ts",
4
4
  "type": "module",
5
- "version": "0.0.39",
5
+ "version": "0.0.41",
6
6
  "types": "dist/index.d.ts",
7
7
  "main": "dist/index.js",
8
8
  "files": [