@tscircuit/core 0.0.280 → 0.0.282

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 +247 -213
  2. package/dist/index.js +123 -63
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -50,7 +50,7 @@ __export(components_exports, {
50
50
  Via: () => Via
51
51
  });
52
52
 
53
- // lib/components/base-components/NormalComponent.ts
53
+ // lib/components/base-components/NormalComponent/NormalComponent.ts
54
54
  import { fp } from "@tscircuit/footprinter";
55
55
  import { point3, rotation } from "circuit-json";
56
56
  import Debug4 from "debug";
@@ -72,7 +72,6 @@ var orderedRenderPhases = [
72
72
  "CreateTraceHintsFromProps",
73
73
  "SourceRender",
74
74
  "SourceParentAttachment",
75
- "PortDiscovery",
76
75
  "PortMatching",
77
76
  "SourceTraceRender",
78
77
  "SourceAddConnectivityMapKey",
@@ -2051,14 +2050,67 @@ var Port = class extends PrimitiveComponent {
2051
2050
  _getGlobalPcbPositionAfterLayout() {
2052
2051
  return this._getPcbCircuitJsonBounds().center;
2053
2052
  }
2053
+ _getPortsInternallyConnectedToThisPort() {
2054
+ const parent = this.parent;
2055
+ if (!parent || !parent._getInternallyConnectedPorts) return [];
2056
+ const internallyConnectedPorts = parent._getInternallyConnectedPorts();
2057
+ for (const ports of internallyConnectedPorts) {
2058
+ if (ports.some((port) => port === this)) {
2059
+ return ports;
2060
+ }
2061
+ }
2062
+ return [];
2063
+ }
2064
+ /**
2065
+ * Return true if this port has a schematic representation and can be rendered
2066
+ * to the schematic.
2067
+ *
2068
+ * Sometimes things like mounting holes don't have a schematic representation
2069
+ * and aren't rendered to the schematic.
2070
+ *
2071
+ * It's common for a schematic symbol to not have a representation for all of
2072
+ * the pins on a footprint, e.g. a pushbutton has 4 pins but is typically
2073
+ * represented by a two-pin symbol. In these cases, it's best to use
2074
+ * internallyConnectedPorts or externallyConnectedPorts to ensure the things
2075
+ * are rendered properly.
2076
+ */
2077
+ _hasSchematicPort() {
2078
+ const symbol = this.parent?.getSchematicSymbol();
2079
+ if (symbol) {
2080
+ if (this.schematicSymbolPortDef) return true;
2081
+ const portsInternallyConnectedToThisPort = this._getPortsInternallyConnectedToThisPort();
2082
+ if (portsInternallyConnectedToThisPort.some((p) => p.schematicSymbolPortDef))
2083
+ return true;
2084
+ return false;
2085
+ }
2086
+ const parentBoxDim = this?.parent?._getSchematicBoxDimensions();
2087
+ if (parentBoxDim && this.props.pinNumber !== void 0) {
2088
+ const localPortPosition = parentBoxDim.getPortPositionByPinNumber(
2089
+ this.props.pinNumber
2090
+ );
2091
+ if (localPortPosition) return true;
2092
+ }
2093
+ return false;
2094
+ }
2054
2095
  _getGlobalSchematicPositionBeforeLayout() {
2055
2096
  const symbol = this.parent?.getSchematicSymbol();
2056
- if (symbol && this.schematicSymbolPortDef) {
2097
+ if (symbol) {
2098
+ let schematicSymbolPortDef = this.schematicSymbolPortDef;
2099
+ if (!schematicSymbolPortDef) {
2100
+ schematicSymbolPortDef = this._getPortsInternallyConnectedToThisPort().find(
2101
+ (p) => p.schematicSymbolPortDef
2102
+ )?.schematicSymbolPortDef ?? null;
2103
+ if (!schematicSymbolPortDef) {
2104
+ throw new Error(
2105
+ `Couldn't find schematicSymbolPortDef for port ${this.getString()}, searched internally connected ports and none had a schematicSymbolPortDef. Why are we trying to get the schematic position of this port?`
2106
+ );
2107
+ }
2108
+ }
2057
2109
  const transform = compose2(
2058
2110
  this.parent.computeSchematicGlobalTransform(),
2059
2111
  translate2(-symbol.center.x, -symbol.center.y)
2060
2112
  );
2061
- return applyToPoint3(transform, this.schematicSymbolPortDef);
2113
+ return applyToPoint3(transform, schematicSymbolPortDef);
2062
2114
  }
2063
2115
  const parentBoxDim = this?.parent?._getSchematicBoxDimensions();
2064
2116
  if (parentBoxDim && this.props.pinNumber !== void 0) {
@@ -2066,14 +2118,18 @@ var Port = class extends PrimitiveComponent {
2066
2118
  this.props.pinNumber
2067
2119
  );
2068
2120
  if (!localPortPosition) {
2069
- return { x: 0, y: 0 };
2121
+ throw new Error(
2122
+ `Couldn't find position for schematic_port for port ${this.getString()} inside of the schematic box`
2123
+ );
2070
2124
  }
2071
2125
  return applyToPoint3(
2072
2126
  this.parent.computeSchematicGlobalTransform(),
2073
2127
  localPortPosition
2074
2128
  );
2075
2129
  }
2076
- return { x: 0, y: 0 };
2130
+ throw new Error(
2131
+ `Couldn't find position for schematic_port for port ${this.getString()}`
2132
+ );
2077
2133
  }
2078
2134
  _getGlobalSchematicPositionAfterLayout() {
2079
2135
  const { db } = this.root;
@@ -2201,6 +2257,7 @@ var Port = class extends PrimitiveComponent {
2201
2257
  const { _parsedProps: props } = this;
2202
2258
  const container = this.getPrimitiveContainer();
2203
2259
  if (!container) return;
2260
+ if (!this._hasSchematicPort()) return;
2204
2261
  const containerCenter = container._getGlobalSchematicPositionBeforeLayout();
2205
2262
  const portCenter = this._getGlobalSchematicPositionBeforeLayout();
2206
2263
  let localPortInfo = null;
@@ -2267,14 +2324,19 @@ var getPinNumberFromLabels = (labels) => {
2267
2324
  if (!pinNumber) return null;
2268
2325
  return Number.parseInt(pinNumber.replace(/^pin/, ""));
2269
2326
  };
2270
- function getPortFromHints(hints) {
2327
+ function getPortFromHints(hints, opts) {
2271
2328
  const pinNumber = getPinNumberFromLabels(hints);
2272
2329
  if (!pinNumber) return null;
2330
+ const aliasesFromHints = hints.filter(
2331
+ (p) => p.toString() !== pinNumber.toString() && p !== `pin${pinNumber}`
2332
+ );
2333
+ const aliases = [
2334
+ ...aliasesFromHints,
2335
+ ...opts?.additionalAliases?.[`pin${pinNumber}`] ?? []
2336
+ ];
2273
2337
  return new Port({
2274
2338
  pinNumber,
2275
- aliases: hints.filter(
2276
- (p) => p.toString() !== pinNumber.toString() && p !== `pin${pinNumber}`
2277
- )
2339
+ aliases
2278
2340
  });
2279
2341
  }
2280
2342
 
@@ -2567,7 +2629,7 @@ var getAllDimensionsForSchematicBox = (params) => {
2567
2629
  };
2568
2630
  };
2569
2631
 
2570
- // lib/components/base-components/NormalComponent.ts
2632
+ // lib/components/base-components/NormalComponent/NormalComponent.ts
2571
2633
  import {
2572
2634
  isValidElement as isReactElement,
2573
2635
  isValidElement
@@ -2799,7 +2861,7 @@ var getNumericSchPinStyle = (pinStyles, pinLabels) => {
2799
2861
  return numericPinStyles;
2800
2862
  };
2801
2863
 
2802
- // lib/components/base-components/NormalComponent.ts
2864
+ // lib/components/base-components/NormalComponent/NormalComponent.ts
2803
2865
  var debug3 = Debug4("tscircuit:core");
2804
2866
  var rotation3 = z5.object({
2805
2867
  x: rotation,
@@ -2812,6 +2874,15 @@ var NormalComponent = class extends PrimitiveComponent {
2812
2874
  isPrimitiveContainer = true;
2813
2875
  _asyncSupplierPartNumbers;
2814
2876
  pcb_missing_footprint_error_id;
2877
+ /**
2878
+ * Override this property for component defaults
2879
+ */
2880
+ get defaultInternallyConnectedPortNames() {
2881
+ return [];
2882
+ }
2883
+ get internallyConnectedPortNames() {
2884
+ return this._parsedProps.internallyConnectedPorts ?? this.defaultInternallyConnectedPortNames;
2885
+ }
2815
2886
  constructor(props) {
2816
2887
  super(props);
2817
2888
  this._addChildrenFromStringFootprint();
@@ -2926,10 +2997,9 @@ var NormalComponent = class extends PrimitiveComponent {
2926
2997
  }
2927
2998
  }
2928
2999
  this.addAll(portsToCreate);
2929
- return;
2930
3000
  }
2931
3001
  if (!this._parsedProps.schPortArrangement) {
2932
- const portsFromFootprint = this.getPortsFromFootprint();
3002
+ const portsFromFootprint = this.getPortsFromFootprint(opts);
2933
3003
  for (const port of portsFromFootprint) {
2934
3004
  if (!portsToCreate.some(
2935
3005
  (p) => p.isMatchingAnyOf(port.getNameAndAliases())
@@ -2938,7 +3008,7 @@ var NormalComponent = class extends PrimitiveComponent {
2938
3008
  }
2939
3009
  }
2940
3010
  }
2941
- for (let pn = 1; pn <= this._getPinCount(); pn++) {
3011
+ for (let pn = 1; pn <= (opts.pinCount ?? this._getPinCount()); pn++) {
2942
3012
  if (!this._parsedProps.schPortArrangement) continue;
2943
3013
  if (portsToCreate.find((p) => p._parsedProps.pinNumber === pn)) continue;
2944
3014
  let explicitlyListedPinNumbersInSchPortArrangement = [
@@ -3054,6 +3124,18 @@ var NormalComponent = class extends PrimitiveComponent {
3054
3124
  _getSchematicSymbolDisplayValue() {
3055
3125
  return void 0;
3056
3126
  }
3127
+ _getInternallyConnectedPorts() {
3128
+ if (this.internallyConnectedPortNames.length === 0) return [];
3129
+ const internallyConnectedPorts = [];
3130
+ for (const netPortNames of this.internallyConnectedPortNames) {
3131
+ const ports = [];
3132
+ for (const portName of netPortNames) {
3133
+ ports.push(this.portMap[portName]);
3134
+ }
3135
+ internallyConnectedPorts.push(ports);
3136
+ }
3137
+ return internallyConnectedPorts;
3138
+ }
3057
3139
  _doInitialSchematicComponentRenderWithSymbol() {
3058
3140
  if (this.root?.schematicDisabled) return;
3059
3141
  const { db } = this.root;
@@ -3241,7 +3323,7 @@ var NormalComponent = class extends PrimitiveComponent {
3241
3323
  }
3242
3324
  super.add(component);
3243
3325
  }
3244
- getPortsFromFootprint() {
3326
+ getPortsFromFootprint(opts) {
3245
3327
  let { footprint } = this.props;
3246
3328
  if (!footprint || isValidElement(footprint)) {
3247
3329
  footprint = this.children.find((c) => c.componentName === "Footprint");
@@ -3251,7 +3333,7 @@ var NormalComponent = class extends PrimitiveComponent {
3251
3333
  const newPorts2 = [];
3252
3334
  for (const elm of fpSoup) {
3253
3335
  if ("port_hints" in elm && elm.port_hints) {
3254
- const newPort = getPortFromHints(elm.port_hints);
3336
+ const newPort = getPortFromHints(elm.port_hints, opts);
3255
3337
  if (!newPort) continue;
3256
3338
  newPort.originDescription = `footprint:string:${footprint}:port_hints[0]:${elm.port_hints[0]}`;
3257
3339
  newPorts2.push(newPort);
@@ -3310,41 +3392,6 @@ var NormalComponent = class extends PrimitiveComponent {
3310
3392
  _createNetsFromProps(propsWithConnections) {
3311
3393
  createNetsFromProps(this, propsWithConnections);
3312
3394
  }
3313
- /**
3314
- * Use data from our props to create ports for this component.
3315
- *
3316
- * Generally, this is done by looking at the schematic and the footprint,
3317
- * reading the pins, making sure there aren't duplicates.
3318
- *
3319
- * Can probably be removed in favor of initPorts()
3320
- *
3321
- */
3322
- doInitialPortDiscovery() {
3323
- const { _parsedProps: props } = this;
3324
- let newPorts = [];
3325
- if (!props.schPortArrangement) {
3326
- newPorts = [
3327
- ...this.getPortsFromFootprint(),
3328
- ...this.getPortsFromSchematicSymbol()
3329
- ];
3330
- }
3331
- const existingPorts = this.children.filter(
3332
- (c) => c.componentName === "Port"
3333
- );
3334
- for (const newPort of newPorts) {
3335
- const existingPort = existingPorts.find(
3336
- (p) => p.isMatchingAnyOf(newPort.getNameAndAliases())
3337
- );
3338
- if (existingPort) {
3339
- if (!existingPort.schematicSymbolPortDef && newPort.schematicSymbolPortDef) {
3340
- existingPort.schematicSymbolPortDef = newPort.schematicSymbolPortDef;
3341
- }
3342
- continue;
3343
- }
3344
- existingPorts.push(newPort);
3345
- this.add(newPort);
3346
- }
3347
- }
3348
3395
  _getPcbCircuitJsonBounds() {
3349
3396
  const { db } = this.root;
3350
3397
  if (!this.pcb_component_id) return super._getPcbCircuitJsonBounds();
@@ -3361,20 +3408,26 @@ var NormalComponent = class extends PrimitiveComponent {
3361
3408
  height: pcb_component.height
3362
3409
  };
3363
3410
  }
3411
+ _getPinCountFromSchematicPortArrangement() {
3412
+ const schPortArrangement = this._getSchematicPortArrangement();
3413
+ if (!schPortArrangement) return 0;
3414
+ const isExplicitPinMapping = isExplicitPinMappingArrangement(schPortArrangement);
3415
+ if (!isExplicitPinMapping) {
3416
+ return (schPortArrangement.leftSize ?? schPortArrangement.leftPinCount ?? 0) + (schPortArrangement.rightSize ?? schPortArrangement.rightPinCount ?? 0) + (schPortArrangement.topSize ?? schPortArrangement.topPinCount ?? 0) + (schPortArrangement.bottomSize ?? schPortArrangement.bottomPinCount ?? 0);
3417
+ }
3418
+ const { leftSide, rightSide, topSide, bottomSide } = schPortArrangement;
3419
+ return Math.max(
3420
+ ...leftSide?.pins ?? [],
3421
+ ...rightSide?.pins ?? [],
3422
+ ...topSide?.pins ?? [],
3423
+ ...bottomSide?.pins ?? []
3424
+ );
3425
+ }
3364
3426
  _getPinCount() {
3365
3427
  const schPortArrangement = this._getSchematicPortArrangement();
3366
3428
  if (schPortArrangement) {
3367
- const isExplicitPinMapping = isExplicitPinMappingArrangement(schPortArrangement);
3368
- if (!isExplicitPinMapping) {
3369
- return (schPortArrangement.leftSize ?? schPortArrangement.leftPinCount ?? 0) + (schPortArrangement.rightSize ?? schPortArrangement.rightPinCount ?? 0) + (schPortArrangement.topSize ?? schPortArrangement.topPinCount ?? 0) + (schPortArrangement.bottomSize ?? schPortArrangement.bottomPinCount ?? 0);
3370
- }
3371
- const { leftSide, rightSide, topSide, bottomSide } = schPortArrangement;
3372
- return Math.max(
3373
- ...leftSide?.pins ?? [],
3374
- ...rightSide?.pins ?? [],
3375
- ...topSide?.pins ?? [],
3376
- ...bottomSide?.pins ?? []
3377
- );
3429
+ const pinCountFromSchematicPortArrangement = this._getPinCountFromSchematicPortArrangement();
3430
+ return pinCountFromSchematicPortArrangement;
3378
3431
  }
3379
3432
  return this.getPortsFromFootprint().length;
3380
3433
  }
@@ -6337,8 +6390,15 @@ var PushButton = class extends NormalComponent {
6337
6390
  sourceFtype: FTYPE.simple_push_button
6338
6391
  };
6339
6392
  }
6393
+ get defaultInternallyConnectedPortNames() {
6394
+ return [
6395
+ ["pin1", "pin4"],
6396
+ ["pin2", "pin3"]
6397
+ ];
6398
+ }
6340
6399
  initPorts() {
6341
6400
  super.initPorts({
6401
+ pinCount: 4,
6342
6402
  additionalAliases: {
6343
6403
  pin1: ["side1"],
6344
6404
  pin3: ["side2"]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.280",
4
+ "version": "0.0.282",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -55,7 +55,7 @@
55
55
  "@tscircuit/footprinter": "^0.0.97",
56
56
  "@tscircuit/infgrid-ijump-astar": "^0.0.33",
57
57
  "@tscircuit/math-utils": "^0.0.9",
58
- "@tscircuit/props": "^0.0.130",
58
+ "@tscircuit/props": "^0.0.134",
59
59
  "@tscircuit/schematic-autolayout": "^0.0.6",
60
60
  "@tscircuit/soup-util": "^0.0.41",
61
61
  "circuit-json": "^0.0.134",