@tscircuit/core 0.0.430 → 0.0.432

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
@@ -12,7 +12,7 @@ import * as _tscircuit_layout from '@tscircuit/layout';
12
12
  import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
13
13
  import { GraphicsObject } from 'graphics-debug';
14
14
 
15
- declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "InitializePortsFromChildren", "CreateNetsFromProps", "CreateTracesFromProps", "CreateTraceHintsFromProps", "SourceRender", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SchematicComponentRender", "SchematicPrimitiveRender", "SchematicPortRender", "SchematicLayout", "SchematicTraceRender", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbLayout", "PcbComponentSizeCalculation", "PcbBoardAutoSize", "PcbTraceHintRender", "PcbTraceRender", "PcbRouteNetIslands", "PcbDesignRuleChecks", "CadModelRender", "PartsEngineRender"];
15
+ declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "PcbFootprintStringRender", "InitializePortsFromChildren", "CreateNetsFromProps", "CreateTracesFromProps", "CreateTraceHintsFromProps", "SourceRender", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SchematicComponentRender", "SchematicPrimitiveRender", "SchematicPortRender", "SchematicLayout", "SchematicTraceRender", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbLayout", "PcbComponentSizeCalculation", "PcbBoardAutoSize", "PcbTraceHintRender", "PcbTraceRender", "PcbRouteNetIslands", "PcbDesignRuleChecks", "CadModelRender", "PartsEngineRender"];
16
16
  type RenderPhase = (typeof orderedRenderPhases)[number];
17
17
  type RenderPhaseFn<K extends RenderPhase = RenderPhase> = `doInitial${K}` | `update${K}` | `remove${K}`;
18
18
  type RenderPhaseStates = Record<RenderPhase, {
@@ -919,6 +919,7 @@ declare class NormalComponent<ZodProps extends ZodType = any, PortNames extends
919
919
  isPrimitiveContainer: boolean;
920
920
  _asyncSupplierPartNumbers?: SupplierPartNumbers;
921
921
  pcb_missing_footprint_error_id?: string;
922
+ _hasStartedFootprintUrlLoad: boolean;
922
923
  /**
923
924
  * Override this property for component defaults
924
925
  */
@@ -944,6 +945,7 @@ declare class NormalComponent<ZodProps extends ZodType = any, PortNames extends
944
945
  pinCount?: number;
945
946
  }): void;
946
947
  _getImpliedFootprintString(): string | null;
948
+ _isFootprintUrl(s: string): boolean;
947
949
  _addChildrenFromStringFootprint(): void;
948
950
  get portMap(): PortMap<PortNames>;
949
951
  getInstanceForReactElement(element: ReactElement): NormalComponent | null;
@@ -969,6 +971,7 @@ declare class NormalComponent<ZodProps extends ZodType = any, PortNames extends
969
971
  _renderReactSubtree(element: ReactElement): ReactSubtree;
970
972
  doInitialInitializePortsFromChildren(): void;
971
973
  doInitialReactSubtreesRender(): void;
974
+ doInitialPcbFootprintStringRender(): void;
972
975
  _hasExistingPortExactly(port1: Port): boolean;
973
976
  add(componentOrElm: PrimitiveComponent | ReactElement): void;
974
977
  getPortsFromFootprint(opts?: {
package/dist/index.js CHANGED
@@ -76,6 +76,7 @@ import Debug from "debug";
76
76
  var debug = Debug("tscircuit:renderable");
77
77
  var orderedRenderPhases = [
78
78
  "ReactSubtreesRender",
79
+ "PcbFootprintStringRender",
79
80
  "InitializePortsFromChildren",
80
81
  "CreateNetsFromProps",
81
82
  "CreateTracesFromProps",
@@ -2290,7 +2291,8 @@ var SilkscreenText = class extends PrimitiveComponent2 {
2290
2291
  var createPinrowSilkscreenText = ({
2291
2292
  elm,
2292
2293
  pinLabels,
2293
- readableRotation
2294
+ readableRotation,
2295
+ anchorAlignment
2294
2296
  }) => {
2295
2297
  const pinNum = elm.text.replace(/[{}]/g, "").toLowerCase();
2296
2298
  let label = pinNum;
@@ -2301,7 +2303,7 @@ var createPinrowSilkscreenText = ({
2301
2303
  label = pinLabels[pinNum]?.[0] ?? pinNum;
2302
2304
  }
2303
2305
  return new SilkscreenText({
2304
- anchorAlignment: "center",
2306
+ anchorAlignment: anchorAlignment || "center",
2305
2307
  text: label ?? pinNum,
2306
2308
  fontSize: elm.font_size + 0.2,
2307
2309
  pcbX: isNaN(elm.anchor_position.x) ? 0 : elm.anchor_position.x,
@@ -2311,6 +2313,13 @@ var createPinrowSilkscreenText = ({
2311
2313
  };
2312
2314
 
2313
2315
  // lib/utils/createComponentsFromCircuitJson.ts
2316
+ var calculateCcwRotation = (componentRotationStr, elementCcwRotation) => {
2317
+ const componentAngle = parseInt(componentRotationStr || "0", 10);
2318
+ const baseRotation = -componentAngle;
2319
+ const totalRotation = baseRotation + (elementCcwRotation ?? 0);
2320
+ const normalizedRotation = (totalRotation % 360 + 360) % 360;
2321
+ return normalizedRotation;
2322
+ };
2314
2323
  var createComponentsFromCircuitJson = ({
2315
2324
  componentName,
2316
2325
  componentRotation,
@@ -2403,23 +2412,28 @@ var createComponentsFromCircuitJson = ({
2403
2412
  })
2404
2413
  );
2405
2414
  } else if (elm.type === "pcb_silkscreen_text") {
2406
- let readableRotation = componentRotation ? parseInt(componentRotation) : 0;
2407
- const normalizedRotation = (readableRotation % 360 + 360) % 360;
2408
- const isUpsideDown = normalizedRotation > 90 && normalizedRotation <= 270;
2409
- readableRotation = isUpsideDown ? (normalizedRotation + 180) % 360 : normalizedRotation;
2410
- if (footprint.includes("pinrow") && elm.text.includes("PIN") && pinLabels) {
2415
+ const ccwRotation = calculateCcwRotation(
2416
+ componentRotation,
2417
+ elm.ccw_rotation
2418
+ );
2419
+ if (footprint.includes("pinrow") && elm.text.includes("PIN")) {
2411
2420
  components.push(
2412
- createPinrowSilkscreenText({ elm, pinLabels, readableRotation })
2421
+ createPinrowSilkscreenText({
2422
+ elm,
2423
+ pinLabels,
2424
+ readableRotation: ccwRotation,
2425
+ anchorAlignment: elm.anchor_alignment
2426
+ })
2413
2427
  );
2414
- } else if (elm.text === "{REF}") {
2428
+ } else {
2415
2429
  components.push(
2416
2430
  new SilkscreenText({
2417
- anchorAlignment: "center",
2431
+ anchorAlignment: elm.anchor_alignment || "center",
2418
2432
  text: componentName,
2419
2433
  fontSize: elm.font_size + 0.2,
2420
2434
  pcbX: isNaN(elm.anchor_position.x) ? 0 : elm.anchor_position.x,
2421
2435
  pcbY: elm.anchor_position.y,
2422
- pcbRotation: readableRotation ?? 0
2436
+ pcbRotation: ccwRotation ?? 0
2423
2437
  })
2424
2438
  );
2425
2439
  }
@@ -5035,6 +5049,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
5035
5049
  isPrimitiveContainer = true;
5036
5050
  _asyncSupplierPartNumbers;
5037
5051
  pcb_missing_footprint_error_id;
5052
+ _hasStartedFootprintUrlLoad = false;
5038
5053
  /**
5039
5054
  * Override this property for component defaults
5040
5055
  */
@@ -5224,6 +5239,9 @@ var NormalComponent = class extends PrimitiveComponent2 {
5224
5239
  _getImpliedFootprintString() {
5225
5240
  return null;
5226
5241
  }
5242
+ _isFootprintUrl(s) {
5243
+ return s.startsWith("http://") || s.startsWith("https://");
5244
+ }
5227
5245
  _addChildrenFromStringFootprint() {
5228
5246
  const {
5229
5247
  name: componentName,
@@ -5234,6 +5252,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
5234
5252
  footprint ??= this._getImpliedFootprintString?.();
5235
5253
  if (!footprint) return;
5236
5254
  if (typeof footprint === "string") {
5255
+ if (this._isFootprintUrl(footprint)) return;
5237
5256
  const fpSoup = fp.string(footprint).soup();
5238
5257
  const fpComponents = createComponentsFromCircuitJson(
5239
5258
  { componentName, componentRotation, footprint, pinLabels },
@@ -5476,12 +5495,41 @@ var NormalComponent = class extends PrimitiveComponent2 {
5476
5495
  this.initPorts();
5477
5496
  }
5478
5497
  doInitialReactSubtreesRender() {
5479
- if (isReactElement(this.props.footprint)) {
5480
- if (this.reactSubtrees.some((rs) => rs.element === this.props.footprint))
5481
- return;
5482
- const subtree = this._renderReactSubtree(this.props.footprint);
5498
+ }
5499
+ doInitialPcbFootprintStringRender() {
5500
+ let { footprint } = this.props;
5501
+ footprint ??= this._getImpliedFootprintString?.();
5502
+ if (!footprint) return;
5503
+ const {
5504
+ name: componentName,
5505
+ pcbRotation: componentRotation,
5506
+ pinLabels
5507
+ } = this.props;
5508
+ if (typeof footprint === "string" && this._isFootprintUrl(footprint)) {
5509
+ if (this._hasStartedFootprintUrlLoad) return;
5510
+ this._hasStartedFootprintUrlLoad = true;
5511
+ const url = footprint;
5512
+ this._queueAsyncEffect("load-footprint-url", async () => {
5513
+ const res = await fetch(url);
5514
+ const soup = await res.json();
5515
+ const fpComponents = createComponentsFromCircuitJson(
5516
+ { componentName, componentRotation, footprint: url, pinLabels },
5517
+ soup
5518
+ );
5519
+ this.addAll(fpComponents);
5520
+ this._markDirty("InitializePortsFromChildren");
5521
+ });
5522
+ return;
5523
+ }
5524
+ if (isReactElement(footprint)) {
5525
+ if (this.reactSubtrees.some((rs) => rs.element === footprint)) return;
5526
+ const subtree = this._renderReactSubtree(footprint);
5483
5527
  this.reactSubtrees.push(subtree);
5484
5528
  this.add(subtree.component);
5529
+ return;
5530
+ }
5531
+ if (!isValidElement(footprint) && footprint.componentName === "Footprint") {
5532
+ this.add(footprint);
5485
5533
  }
5486
5534
  }
5487
5535
  _hasExistingPortExactly(port1) {
@@ -5525,6 +5573,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
5525
5573
  footprint = this.children.find((c) => c.componentName === "Footprint");
5526
5574
  }
5527
5575
  if (typeof footprint === "string") {
5576
+ if (this._isFootprintUrl(footprint)) return [];
5528
5577
  const fpSoup = fp.string(footprint).soup();
5529
5578
  const newPorts2 = [];
5530
5579
  for (const elm of fpSoup) {
@@ -8656,7 +8705,7 @@ import { identity as identity4 } from "transformation-matrix";
8656
8705
  var package_default = {
8657
8706
  name: "@tscircuit/core",
8658
8707
  type: "module",
8659
- version: "0.0.429",
8708
+ version: "0.0.431",
8660
8709
  types: "dist/index.d.ts",
8661
8710
  main: "dist/index.js",
8662
8711
  module: "dist/index.js",
@@ -8682,14 +8731,15 @@ var package_default = {
8682
8731
  "@tscircuit/capacity-autorouter": "^0.0.67",
8683
8732
  "@tscircuit/checks": "^0.0.46",
8684
8733
  "@tscircuit/circuit-json-util": "^0.0.47",
8685
- "@tscircuit/footprinter": "^0.0.169",
8734
+ "@tscircuit/footprinter": "^0.0.171",
8686
8735
  "@tscircuit/import-snippet": "^0.0.4",
8687
8736
  "@tscircuit/infgrid-ijump-astar": "^0.0.33",
8688
8737
  "@tscircuit/layout": "^0.0.28",
8689
8738
  "@tscircuit/log-soup": "^1.0.2",
8690
8739
  "@tscircuit/math-utils": "^0.0.18",
8691
- "@tscircuit/props": "^0.0.193",
8740
+ "@tscircuit/props": "^0.0.195",
8692
8741
  "@tscircuit/schematic-autolayout": "^0.0.6",
8742
+ "@tscircuit/simple-3d-svg": "^0.0.6",
8693
8743
  "@types/bun": "latest",
8694
8744
  "@types/debug": "^4.1.12",
8695
8745
  "@types/react": "^19.0.1",
@@ -8707,7 +8757,6 @@ var package_default = {
8707
8757
  howfat: "^0.3.8",
8708
8758
  "live-server": "^1.2.2",
8709
8759
  "looks-same": "^9.0.1",
8710
- "@tscircuit/simple-3d-svg": "^0.0.6",
8711
8760
  "pkg-pr-new": "^0.0.37",
8712
8761
  react: "^19.0.0",
8713
8762
  "react-dom": "^19.0.0",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.430",
4
+ "version": "0.0.432",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -27,14 +27,15 @@
27
27
  "@tscircuit/capacity-autorouter": "^0.0.67",
28
28
  "@tscircuit/checks": "^0.0.46",
29
29
  "@tscircuit/circuit-json-util": "^0.0.47",
30
- "@tscircuit/footprinter": "^0.0.169",
30
+ "@tscircuit/footprinter": "^0.0.171",
31
31
  "@tscircuit/import-snippet": "^0.0.4",
32
32
  "@tscircuit/infgrid-ijump-astar": "^0.0.33",
33
33
  "@tscircuit/layout": "^0.0.28",
34
34
  "@tscircuit/log-soup": "^1.0.2",
35
35
  "@tscircuit/math-utils": "^0.0.18",
36
- "@tscircuit/props": "^0.0.193",
36
+ "@tscircuit/props": "^0.0.195",
37
37
  "@tscircuit/schematic-autolayout": "^0.0.6",
38
+ "@tscircuit/simple-3d-svg": "^0.0.6",
38
39
  "@types/bun": "latest",
39
40
  "@types/debug": "^4.1.12",
40
41
  "@types/react": "^19.0.1",
@@ -52,7 +53,6 @@
52
53
  "howfat": "^0.3.8",
53
54
  "live-server": "^1.2.2",
54
55
  "looks-same": "^9.0.1",
55
- "@tscircuit/simple-3d-svg": "^0.0.6",
56
56
  "pkg-pr-new": "^0.0.37",
57
57
  "react": "^19.0.0",
58
58
  "react-dom": "^19.0.0",