@tscircuit/core 0.0.19 → 0.0.20

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
@@ -6,10 +6,10 @@ import { ReactElement } from 'react';
6
6
  import { Matrix } from 'transformation-matrix';
7
7
  import { SchSymbol, BaseSymbolName } from 'schematic-symbols';
8
8
  import * as Props from '@tscircuit/props';
9
- import { boardProps, footprintProps, smtPadProps, resistorProps, ledProps, traceProps, traceHintProps, groupProps, chipProps, jumperProps, silkscreenPathProps, platedHoleProps } from '@tscircuit/props';
9
+ import { boardProps, footprintProps, smtPadProps, resistorProps, ledProps, capacitorProps, traceProps, traceHintProps, groupProps, chipProps, jumperProps, silkscreenPathProps, platedHoleProps } from '@tscircuit/props';
10
10
  import * as _tscircuit_layout from '@tscircuit/layout';
11
11
 
12
- declare class Project {
12
+ declare class Circuit {
13
13
  rootComponent: PrimitiveComponent | null;
14
14
  children: PrimitiveComponent[];
15
15
  db: SoupUtilObjects;
@@ -31,10 +31,13 @@ declare class Project {
31
31
  computeGlobalSchematicTransform(): Matrix;
32
32
  computeGlobalPcbTransform(): Matrix;
33
33
  selectAll(selector: string): PrimitiveComponent[];
34
- selectOne(selector: string): PrimitiveComponent | null;
34
+ selectOne(selector: string, opts: {
35
+ type?: "component" | "port";
36
+ }): PrimitiveComponent | null;
35
37
  }
38
+ declare const Project: typeof Circuit;
36
39
 
37
- declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "SourceRender", "SourceParentAttachment", "PortDiscovery", "PortMatching", "SourceTraceRender", "SchematicComponentRender", "SchematicLayout", "SchematicPortRender", "SchematicTraceRender", "PcbComponentRender", "PcbPortRender", "PcbPrimitiveRender", "PcbParentAttachment", "PcbLayout", "PcbTraceRender", "CadModelRender", "PcbAnalysis"];
40
+ declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "CreateTracesFromProps", "SourceRender", "SourceParentAttachment", "PortDiscovery", "PortMatching", "SourceTraceRender", "SchematicComponentRender", "SchematicLayout", "SchematicPortRender", "SchematicTraceRender", "PcbComponentRender", "PcbPortRender", "PcbPrimitiveRender", "PcbParentAttachment", "PcbLayout", "PcbTraceRender", "CadModelRender", "PcbAnalysis"];
38
41
  type RenderPhase = (typeof orderedRenderPhases)[number];
39
42
  type RenderPhaseFn<K extends RenderPhase = RenderPhase> = `doInitial${K}` | `update${K}` | `remove${K}`;
40
43
  type RenderPhaseStates = Record<RenderPhase, {
@@ -89,19 +92,26 @@ declare abstract class PrimitiveComponent<ZodProps extends ZodType = any> extend
89
92
  children: PrimitiveComponent[];
90
93
  childrenPendingRemoval: PrimitiveComponent[];
91
94
  get config(): BaseComponentConfig;
92
- project: Project | null;
95
+ project: Circuit | null;
93
96
  props: z.input<ZodProps>;
94
97
  _parsedProps: z.infer<ZodProps>;
95
98
  componentName: string;
96
99
  lowercaseComponentName: string;
97
100
  externallyAddedAliases: string[];
101
+ /**
102
+ * An opaque group is a self-contained subcircuit. All the selectors inside
103
+ * an opaque group are relative to the group. You can have multiple opaque
104
+ * groups and their selectors will not interact with each other (even if the
105
+ * components share the same names) unless you explicitly break out some ports
106
+ */
107
+ get isOpaqueGroup(): boolean;
98
108
  source_group_id: string | null;
99
109
  source_component_id: string | null;
100
110
  schematic_component_id: string | null;
101
111
  pcb_component_id: string | null;
102
112
  cad_component_id: string | null;
103
113
  constructor(props: z.input<ZodProps>);
104
- setProject(project: Project): void;
114
+ setProject(project: Circuit): void;
105
115
  setProps(props: Partial<z.input<ZodProps>>): void;
106
116
  /**
107
117
  * Computes a transformation matrix from the props of this component for PCB
@@ -145,10 +155,13 @@ declare abstract class PrimitiveComponent<ZodProps extends ZodType = any> extend
145
155
  add(component: PrimitiveComponent): void;
146
156
  addAll(components: PrimitiveComponent[]): void;
147
157
  remove(component: PrimitiveComponent): void;
158
+ getOpaqueGroupSelector(): string;
159
+ getFullPathSelector(): string;
148
160
  getNameAndAliases(): string[];
149
161
  isMatchingNameOrAlias(name: string): boolean;
150
162
  isMatchingAnyOf(aliases: Array<string | number>): boolean;
151
163
  doesSelectorMatch(selector: string): boolean;
164
+ getOpaqueGroup(): PrimitiveComponent;
152
165
  selectAll(selector: string): PrimitiveComponent[];
153
166
  selectOne(selector: string, options?: {
154
167
  type?: string;
@@ -287,6 +300,7 @@ declare class NormalComponent<ZodProps extends ZodType = any, PortNames extends
287
300
 
288
301
  declare class Board extends NormalComponent<typeof boardProps> {
289
302
  pcb_board_id: string | null;
303
+ get isOpaqueGroup(): boolean;
290
304
  get config(): {
291
305
  zodProps: z.ZodObject<{
292
306
  width: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>>;
@@ -428,33 +442,33 @@ type PolarizedPassivePorts = PassivePorts | "anode" | "cathode" | "pos" | "neg";
428
442
  declare class Resistor extends NormalComponent<typeof resistorProps, PassivePorts> {
429
443
  get config(): {
430
444
  schematicSymbolName: BaseSymbolName;
431
- zodProps: zod.ZodObject<zod.objectUtil.extendShape<zod.objectUtil.extendShape<zod.objectUtil.extendShape<{
432
- pcbX: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
433
- pcbY: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
434
- pcbRotation: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
435
- schX: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
436
- schY: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
437
- schRotation: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
438
- layer: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>, zod.ZodObject<{
439
- name: zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>;
440
- }, "strip", zod.ZodTypeAny, {
445
+ zodProps: z.ZodObject<z.objectUtil.extendShape<z.objectUtil.extendShape<z.objectUtil.extendShape<{
446
+ pcbX: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>>;
447
+ pcbY: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>>;
448
+ pcbRotation: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>>;
449
+ schX: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>>;
450
+ schY: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>>;
451
+ schRotation: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>>;
452
+ layer: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>, z.ZodObject<{
453
+ name: z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>;
454
+ }, "strip", z.ZodTypeAny, {
441
455
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
442
456
  }, {
443
457
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
444
458
  }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
445
459
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
446
460
  }>>;
447
- footprint: zod.ZodOptional<zod.ZodType<Props.Footprint, zod.ZodTypeDef, Props.Footprint>>;
461
+ footprint: z.ZodOptional<z.ZodType<Props.Footprint, z.ZodTypeDef, Props.Footprint>>;
448
462
  }, {
449
- supplierPartNumbers: zod.ZodOptional<zod.ZodRecord<zod.ZodEnum<["jlcpcb", "macrofab", "pcbway", "digikey", "mouser", "lcsc"]>, zod.ZodArray<zod.ZodString, "many">>>;
463
+ supplierPartNumbers: z.ZodOptional<z.ZodRecord<z.ZodEnum<["jlcpcb", "macrofab", "pcbway", "digikey", "mouser", "lcsc"]>, z.ZodArray<z.ZodString, "many">>>;
450
464
  }>, {
451
- name: zod.ZodString;
452
- cadModel: zod.ZodOptional<zod.ZodUnion<[zod.ZodString, zod.ZodObject<zod.objectUtil.extendShape<{
453
- rotationOffset: zod.ZodOptional<zod.ZodUnion<[zod.ZodNumber, zod.ZodObject<{
454
- x: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
455
- y: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
456
- z: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
457
- }, "strip", zod.ZodTypeAny, {
465
+ name: z.ZodString;
466
+ cadModel: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodObject<z.objectUtil.extendShape<{
467
+ rotationOffset: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
468
+ x: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
469
+ y: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
470
+ z: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
471
+ }, "strip", z.ZodTypeAny, {
458
472
  x: string | number;
459
473
  y: string | number;
460
474
  z: string | number;
@@ -463,11 +477,11 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
463
477
  y: string | number;
464
478
  z: string | number;
465
479
  }>]>>;
466
- positionOffset: zod.ZodOptional<zod.ZodObject<{
467
- x: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
468
- y: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
469
- z: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
470
- }, "strip", zod.ZodTypeAny, {
480
+ positionOffset: z.ZodOptional<z.ZodObject<{
481
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
482
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
483
+ z: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
484
+ }, "strip", z.ZodTypeAny, {
471
485
  x: number;
472
486
  y: number;
473
487
  z: number;
@@ -476,11 +490,11 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
476
490
  y: string | number;
477
491
  z: string | number;
478
492
  }>>;
479
- size: zod.ZodOptional<zod.ZodObject<{
480
- x: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
481
- y: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
482
- z: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
483
- }, "strip", zod.ZodTypeAny, {
493
+ size: z.ZodOptional<z.ZodObject<{
494
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
495
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
496
+ z: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
497
+ }, "strip", z.ZodTypeAny, {
484
498
  x: number;
485
499
  y: number;
486
500
  z: number;
@@ -490,8 +504,8 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
490
504
  z: string | number;
491
505
  }>>;
492
506
  }, {
493
- stlUrl: zod.ZodString;
494
- }>, "strip", zod.ZodTypeAny, {
507
+ stlUrl: z.ZodString;
508
+ }>, "strip", z.ZodTypeAny, {
495
509
  stlUrl: string;
496
510
  rotationOffset?: number | {
497
511
  x: string | number;
@@ -525,12 +539,12 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
525
539
  y: string | number;
526
540
  z: string | number;
527
541
  } | undefined;
528
- }>, zod.ZodObject<zod.objectUtil.extendShape<{
529
- rotationOffset: zod.ZodOptional<zod.ZodUnion<[zod.ZodNumber, zod.ZodObject<{
530
- x: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
531
- y: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
532
- z: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
533
- }, "strip", zod.ZodTypeAny, {
542
+ }>, z.ZodObject<z.objectUtil.extendShape<{
543
+ rotationOffset: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
544
+ x: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
545
+ y: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
546
+ z: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
547
+ }, "strip", z.ZodTypeAny, {
534
548
  x: string | number;
535
549
  y: string | number;
536
550
  z: string | number;
@@ -539,11 +553,11 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
539
553
  y: string | number;
540
554
  z: string | number;
541
555
  }>]>>;
542
- positionOffset: zod.ZodOptional<zod.ZodObject<{
543
- x: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
544
- y: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
545
- z: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
546
- }, "strip", zod.ZodTypeAny, {
556
+ positionOffset: z.ZodOptional<z.ZodObject<{
557
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
558
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
559
+ z: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
560
+ }, "strip", z.ZodTypeAny, {
547
561
  x: number;
548
562
  y: number;
549
563
  z: number;
@@ -552,11 +566,11 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
552
566
  y: string | number;
553
567
  z: string | number;
554
568
  }>>;
555
- size: zod.ZodOptional<zod.ZodObject<{
556
- x: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
557
- y: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
558
- z: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
559
- }, "strip", zod.ZodTypeAny, {
569
+ size: z.ZodOptional<z.ZodObject<{
570
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
571
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
572
+ z: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
573
+ }, "strip", z.ZodTypeAny, {
560
574
  x: number;
561
575
  y: number;
562
576
  z: number;
@@ -566,9 +580,9 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
566
580
  z: string | number;
567
581
  }>>;
568
582
  }, {
569
- objUrl: zod.ZodString;
570
- mtlUrl: zod.ZodOptional<zod.ZodString>;
571
- }>, "strip", zod.ZodTypeAny, {
583
+ objUrl: z.ZodString;
584
+ mtlUrl: z.ZodOptional<z.ZodString>;
585
+ }>, "strip", z.ZodTypeAny, {
572
586
  objUrl: string;
573
587
  rotationOffset?: number | {
574
588
  x: string | number;
@@ -604,12 +618,12 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
604
618
  z: string | number;
605
619
  } | undefined;
606
620
  mtlUrl?: string | undefined;
607
- }>, zod.ZodObject<zod.objectUtil.extendShape<{
608
- rotationOffset: zod.ZodOptional<zod.ZodUnion<[zod.ZodNumber, zod.ZodObject<{
609
- x: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
610
- y: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
611
- z: zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>;
612
- }, "strip", zod.ZodTypeAny, {
621
+ }>, z.ZodObject<z.objectUtil.extendShape<{
622
+ rotationOffset: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
623
+ x: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
624
+ y: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
625
+ z: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
626
+ }, "strip", z.ZodTypeAny, {
613
627
  x: string | number;
614
628
  y: string | number;
615
629
  z: string | number;
@@ -618,11 +632,11 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
618
632
  y: string | number;
619
633
  z: string | number;
620
634
  }>]>>;
621
- positionOffset: zod.ZodOptional<zod.ZodObject<{
622
- x: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
623
- y: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
624
- z: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
625
- }, "strip", zod.ZodTypeAny, {
635
+ positionOffset: z.ZodOptional<z.ZodObject<{
636
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
637
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
638
+ z: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
639
+ }, "strip", z.ZodTypeAny, {
626
640
  x: number;
627
641
  y: number;
628
642
  z: number;
@@ -631,11 +645,11 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
631
645
  y: string | number;
632
646
  z: string | number;
633
647
  }>>;
634
- size: zod.ZodOptional<zod.ZodObject<{
635
- x: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
636
- y: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
637
- z: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
638
- }, "strip", zod.ZodTypeAny, {
648
+ size: z.ZodOptional<z.ZodObject<{
649
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
650
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
651
+ z: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
652
+ }, "strip", z.ZodTypeAny, {
639
653
  x: number;
640
654
  y: number;
641
655
  z: number;
@@ -645,8 +659,8 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
645
659
  z: string | number;
646
660
  }>>;
647
661
  }, {
648
- jscad: zod.ZodRecord<zod.ZodString, zod.ZodAny>;
649
- }>, "strip", zod.ZodTypeAny, {
662
+ jscad: z.ZodRecord<z.ZodString, z.ZodAny>;
663
+ }>, "strip", z.ZodTypeAny, {
650
664
  jscad: Record<string, any>;
651
665
  rotationOffset?: number | {
652
666
  x: string | number;
@@ -681,15 +695,15 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
681
695
  z: string | number;
682
696
  } | undefined;
683
697
  }>]>>;
684
- children: zod.ZodOptional<zod.ZodAny>;
685
- symbolName: zod.ZodOptional<zod.ZodString>;
698
+ children: z.ZodOptional<z.ZodAny>;
699
+ symbolName: z.ZodOptional<z.ZodString>;
686
700
  }>, {
687
- resistance: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
688
- pullupFor: zod.ZodOptional<zod.ZodString>;
689
- pullupTo: zod.ZodOptional<zod.ZodString>;
690
- pulldownFor: zod.ZodOptional<zod.ZodString>;
691
- pulldownTo: zod.ZodOptional<zod.ZodString>;
692
- }>, "strip", zod.ZodTypeAny, {
701
+ resistance: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
702
+ pullupFor: z.ZodOptional<z.ZodString>;
703
+ pullupTo: z.ZodOptional<z.ZodString>;
704
+ pulldownFor: z.ZodOptional<z.ZodString>;
705
+ pulldownTo: z.ZodOptional<z.ZodString>;
706
+ }>, "strip", z.ZodTypeAny, {
693
707
  name: string;
694
708
  resistance: number;
695
709
  pcbX?: number | undefined;
@@ -838,6 +852,7 @@ declare class Resistor extends NormalComponent<typeof resistorProps, PassivePort
838
852
  };
839
853
  pin1: Port;
840
854
  pin2: Port;
855
+ doInitialCreateTracesFromProps(): void;
841
856
  doInitialSourceRender(): void;
842
857
  }
843
858
 
@@ -1249,7 +1264,7 @@ declare class Led extends NormalComponent<typeof ledProps, PolarizedPassivePorts
1249
1264
  }
1250
1265
 
1251
1266
  type PortNames = "1" | "2" | "pin1" | "pin2" | "left" | "right" | "anode" | "cathode";
1252
- declare class Capacitor extends NormalComponent<typeof ledProps, PortNames> {
1267
+ declare class Capacitor extends NormalComponent<typeof capacitorProps, PortNames> {
1253
1268
  get config(): {
1254
1269
  zodProps: zod.ZodObject<zod.objectUtil.extendShape<zod.objectUtil.extendShape<zod.objectUtil.extendShape<{
1255
1270
  pcbX: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
@@ -1647,6 +1662,10 @@ declare class Capacitor extends NormalComponent<typeof ledProps, PortNames> {
1647
1662
  }>;
1648
1663
  sourceFtype: "simple_capacitor";
1649
1664
  };
1665
+ pin1: Port;
1666
+ pin2: Port;
1667
+ doInitialCreateTracesFromProps(): void;
1668
+ doInitialSourceRender(): void;
1650
1669
  }
1651
1670
 
1652
1671
  declare const netProps: z.ZodObject<{
@@ -3340,4 +3359,4 @@ declare global {
3340
3359
  }
3341
3360
  }
3342
3361
 
3343
- export { Board, Capacitor, Chip, Footprint, Group, type IRenderable, Jumper, Led, Net, NormalComponent, PlatedHole, Port, PrimitiveComponent, Project, Renderable, Resistor, SilkscreenPath, SmtPad, Trace, TraceHint };
3362
+ export { Board, Capacitor, Chip, Circuit, Footprint, Group, type IRenderable, Jumper, Led, Net, NormalComponent, PlatedHole, Port, PrimitiveComponent, Project, Renderable, Resistor, SilkscreenPath, SmtPad, Trace, TraceHint };
package/dist/index.js CHANGED
@@ -37,6 +37,7 @@ import "react";
37
37
  var orderedRenderPhases = [
38
38
  "ReactSubtreesRender",
39
39
  // probably going to be removed b/c subtrees should render instantly
40
+ "CreateTracesFromProps",
40
41
  "SourceRender",
41
42
  "SourceParentAttachment",
42
43
  "PortDiscovery",
@@ -172,6 +173,16 @@ var PrimitiveComponent = class extends Renderable {
172
173
  componentName = "";
173
174
  lowercaseComponentName = "";
174
175
  externallyAddedAliases;
176
+ /**
177
+ * An opaque group is a self-contained subcircuit. All the selectors inside
178
+ * an opaque group are relative to the group. You can have multiple opaque
179
+ * groups and their selectors will not interact with each other (even if the
180
+ * components share the same names) unless you explicitly break out some ports
181
+ */
182
+ get isOpaqueGroup() {
183
+ return Boolean(this.props.opaque) || // Implied opaque group for top-level group
184
+ this.lowercaseComponentName === "group" && this?.parent?.props?.name === "$root";
185
+ }
175
186
  source_group_id = null;
176
187
  source_component_id = null;
177
188
  schematic_component_id = null;
@@ -294,6 +305,20 @@ var PrimitiveComponent = class extends Renderable {
294
305
  this.childrenPendingRemoval.push(component);
295
306
  component.shouldBeRemoved = true;
296
307
  }
308
+ getOpaqueGroupSelector() {
309
+ const name = this._parsedProps.name;
310
+ const endPart = name ? `${this.lowercaseComponentName}.${name}` : this.lowercaseComponentName;
311
+ if (!this.parent) return endPart;
312
+ if (this.parent.isOpaqueGroup) return endPart;
313
+ return `${this.parent.getOpaqueGroupSelector()} > ${endPart}`;
314
+ }
315
+ getFullPathSelector() {
316
+ const name = this._parsedProps.name;
317
+ const endPart = name ? `${this.lowercaseComponentName}.${name}` : this.lowercaseComponentName;
318
+ const parentSelector = this.parent?.getFullPathSelector?.();
319
+ if (!parentSelector) return endPart;
320
+ return `${parentSelector} > ${endPart}`;
321
+ }
297
322
  getNameAndAliases() {
298
323
  return [
299
324
  this._parsedProps.name,
@@ -322,6 +347,13 @@ var PrimitiveComponent = class extends Renderable {
322
347
  return true;
323
348
  return false;
324
349
  }
350
+ getOpaqueGroup() {
351
+ if (this.isOpaqueGroup) return this;
352
+ const group = this.parent?.getOpaqueGroup();
353
+ if (!group)
354
+ throw new Error("Component is not inside an opaque group (no board?)");
355
+ return group;
356
+ }
325
357
  selectAll(selector) {
326
358
  const parts = selector.trim().split(/\s+/);
327
359
  let results = [this];
@@ -1210,6 +1242,9 @@ import { boardProps } from "@tscircuit/props";
1210
1242
  import { identity as identity3 } from "transformation-matrix";
1211
1243
  var Board = class extends NormalComponent {
1212
1244
  pcb_board_id = null;
1245
+ get isOpaqueGroup() {
1246
+ return true;
1247
+ }
1213
1248
  get config() {
1214
1249
  return {
1215
1250
  zodProps: boardProps
@@ -1241,82 +1276,7 @@ var Board = class extends NormalComponent {
1241
1276
 
1242
1277
  // lib/components/normal-components/Resistor.ts
1243
1278
  import { resistorProps } from "@tscircuit/props";
1244
- var Resistor = class extends NormalComponent {
1245
- get config() {
1246
- return {
1247
- schematicSymbolName: "boxresistor",
1248
- zodProps: resistorProps,
1249
- sourceFtype: "simple_resistor"
1250
- };
1251
- }
1252
- pin1 = this.portMap.pin1;
1253
- pin2 = this.portMap.pin2;
1254
- doInitialSourceRender() {
1255
- const { db } = this.project;
1256
- const { _parsedProps: props } = this;
1257
- const source_component = db.source_component.insert({
1258
- ftype: "simple_resistor",
1259
- name: props.name,
1260
- // @ts-ignore
1261
- manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
1262
- supplier_part_numbers: props.supplierPartNumbers,
1263
- resistance: props.resistance
1264
- });
1265
- this.source_component_id = source_component.source_component_id;
1266
- }
1267
- };
1268
-
1269
- // lib/components/normal-components/Led.ts
1270
- import { ledProps } from "@tscircuit/props";
1271
- var Led = class extends NormalComponent {
1272
- get config() {
1273
- return {
1274
- schematicSymbolName: "led",
1275
- zodProps: ledProps,
1276
- sourceFtype: "simple_diode"
1277
- };
1278
- }
1279
- pos = this.portMap.pin1;
1280
- pin1 = this.portMap.pin1;
1281
- anode = this.portMap.pin1;
1282
- neg = this.portMap.pin2;
1283
- pin2 = this.portMap.pin2;
1284
- cathode = this.portMap.pin2;
1285
- };
1286
-
1287
- // lib/components/normal-components/Capacitor.ts
1288
- import { ledProps as ledProps2 } from "@tscircuit/props";
1289
-
1290
- // lib/utils/constants.ts
1291
- var stringProxy = new Proxy(
1292
- {},
1293
- {
1294
- get: (target, prop) => prop
1295
- }
1296
- );
1297
- var FTYPE = stringProxy;
1298
-
1299
- // lib/components/normal-components/Capacitor.ts
1300
- var Capacitor = class extends NormalComponent {
1301
- get config() {
1302
- return {
1303
- // schematicSymbolName: BASE_SYMBOLS.capacitor,
1304
- zodProps: ledProps2,
1305
- sourceFtype: FTYPE.simple_capacitor
1306
- };
1307
- }
1308
- };
1309
-
1310
- // lib/components/primitive-components/Net.ts
1311
- import { z as z4 } from "zod";
1312
- var netProps = z4.object({
1313
- name: z4.string()
1314
- });
1315
- var Net = class extends PrimitiveComponent {
1316
- getPortSelector() {
1317
- return `net.${this.props.name}`;
1318
- }
1319
- };
1279
+ import "zod";
1320
1280
 
1321
1281
  // lib/components/primitive-components/Trace.ts
1322
1282
  import { traceProps } from "@tscircuit/props";
@@ -1495,18 +1455,20 @@ var Trace = class extends PrimitiveComponent {
1495
1455
  const portSelectors = this.getTracePortPathSelectors();
1496
1456
  const ports = portSelectors.map((selector) => ({
1497
1457
  selector,
1498
- port: parent.selectOne(selector, { type: "port" })
1458
+ port: this.getOpaqueGroup().selectOne(selector, { type: "port" }) ?? null
1499
1459
  }));
1500
1460
  for (const { selector, port } of ports) {
1501
1461
  if (!port) {
1502
1462
  const parentSelector = selector.replace(/\>.*$/, "");
1503
- const targetComponent = parent.selectOne(parentSelector);
1463
+ const targetComponent = this.getOpaqueGroup().selectOne(parentSelector);
1504
1464
  if (!targetComponent) {
1505
1465
  this.renderError(`Could not find port for selector "${selector}"`);
1506
1466
  } else {
1507
1467
  this.renderError(
1508
1468
  `Could not find port for selector "${selector}"
1509
- searched component ${targetComponent.getString()}, which has ports:${targetComponent.children.filter((c) => c.componentName === "Port").map((c) => ` ${c.getString()}`).join("\n")}`
1469
+ searched component ${targetComponent.getString()}, which has ports: ${targetComponent.children.filter((c) => c.componentName === "Port").map(
1470
+ (c) => `${c.getString()}(${c.getNameAndAliases().join(",")})`
1471
+ ).join(" & ")}`
1510
1472
  );
1511
1473
  }
1512
1474
  }
@@ -1558,6 +1520,12 @@ searched component ${targetComponent.getString()}, which has ports:${targetCompo
1558
1520
  if (pcbRouteHints.length === 0) {
1559
1521
  const { solution } = autoroute(pcbElements.concat([source_trace]));
1560
1522
  const inputPcbTrace = solution[0];
1523
+ if (!inputPcbTrace) {
1524
+ console.log(
1525
+ `Failed to find route ffrom ${ports[0].port} to ${ports[1].port} render error!`
1526
+ );
1527
+ return;
1528
+ }
1561
1529
  const pcb_trace2 = db.pcb_trace.insert(inputPcbTrace);
1562
1530
  this.pcb_trace_id = pcb_trace2.pcb_trace_id;
1563
1531
  return;
@@ -1692,6 +1660,131 @@ searched component ${targetComponent.getString()}, which has ports:${targetCompo
1692
1660
  }
1693
1661
  };
1694
1662
 
1663
+ // lib/components/normal-components/Resistor.ts
1664
+ var Resistor = class extends NormalComponent {
1665
+ get config() {
1666
+ return {
1667
+ schematicSymbolName: "boxresistor",
1668
+ zodProps: resistorProps,
1669
+ sourceFtype: "simple_resistor"
1670
+ };
1671
+ }
1672
+ pin1 = this.portMap.pin1;
1673
+ pin2 = this.portMap.pin2;
1674
+ doInitialCreateTracesFromProps() {
1675
+ if (this.props.pullupFor && this.props.pullupTo) {
1676
+ this.add(
1677
+ new Trace({
1678
+ from: `${this.getOpaqueGroupSelector()} > port.1`,
1679
+ to: this.props.pullupFor
1680
+ })
1681
+ );
1682
+ this.add(
1683
+ new Trace({
1684
+ from: `${this.getOpaqueGroupSelector()} > port.2`,
1685
+ to: this.props.pullupTo
1686
+ })
1687
+ );
1688
+ }
1689
+ }
1690
+ doInitialSourceRender() {
1691
+ const { db } = this.project;
1692
+ const { _parsedProps: props } = this;
1693
+ const source_component = db.source_component.insert({
1694
+ ftype: "simple_resistor",
1695
+ name: props.name,
1696
+ // @ts-ignore
1697
+ manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
1698
+ supplier_part_numbers: props.supplierPartNumbers,
1699
+ resistance: props.resistance
1700
+ });
1701
+ this.source_component_id = source_component.source_component_id;
1702
+ }
1703
+ };
1704
+
1705
+ // lib/components/normal-components/Led.ts
1706
+ import { ledProps } from "@tscircuit/props";
1707
+ var Led = class extends NormalComponent {
1708
+ get config() {
1709
+ return {
1710
+ schematicSymbolName: "led",
1711
+ zodProps: ledProps,
1712
+ sourceFtype: "simple_diode"
1713
+ };
1714
+ }
1715
+ pos = this.portMap.pin1;
1716
+ pin1 = this.portMap.pin1;
1717
+ anode = this.portMap.pin1;
1718
+ neg = this.portMap.pin2;
1719
+ pin2 = this.portMap.pin2;
1720
+ cathode = this.portMap.pin2;
1721
+ };
1722
+
1723
+ // lib/components/normal-components/Capacitor.ts
1724
+ import { ledProps as ledProps2 } from "@tscircuit/props";
1725
+
1726
+ // lib/utils/constants.ts
1727
+ var stringProxy = new Proxy(
1728
+ {},
1729
+ {
1730
+ get: (target, prop) => prop
1731
+ }
1732
+ );
1733
+ var FTYPE = stringProxy;
1734
+
1735
+ // lib/components/normal-components/Capacitor.ts
1736
+ var Capacitor = class extends NormalComponent {
1737
+ get config() {
1738
+ return {
1739
+ // schematicSymbolName: BASE_SYMBOLS.capacitor,
1740
+ zodProps: ledProps2,
1741
+ sourceFtype: FTYPE.simple_capacitor
1742
+ };
1743
+ }
1744
+ pin1 = this.portMap.pin1;
1745
+ pin2 = this.portMap.pin2;
1746
+ doInitialCreateTracesFromProps() {
1747
+ if (this.props.decouplingFor && this.props.decouplingTo) {
1748
+ this.add(
1749
+ new Trace({
1750
+ from: `${this.getOpaqueGroupSelector()} > port.1`,
1751
+ to: this.props.decouplingFor
1752
+ })
1753
+ );
1754
+ this.add(
1755
+ new Trace({
1756
+ from: `${this.getOpaqueGroupSelector()} > port.2`,
1757
+ to: this.props.decouplingTo
1758
+ })
1759
+ );
1760
+ }
1761
+ }
1762
+ doInitialSourceRender() {
1763
+ const { db } = this.project;
1764
+ const { _parsedProps: props } = this;
1765
+ const source_component = db.source_component.insert({
1766
+ ftype: "simple_capacitor",
1767
+ name: props.name,
1768
+ // @ts-ignore
1769
+ manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
1770
+ supplier_part_numbers: props.supplierPartNumbers,
1771
+ capacitance: props.capacitance
1772
+ });
1773
+ this.source_component_id = source_component.source_component_id;
1774
+ }
1775
+ };
1776
+
1777
+ // lib/components/primitive-components/Net.ts
1778
+ import { z as z5 } from "zod";
1779
+ var netProps = z5.object({
1780
+ name: z5.string()
1781
+ });
1782
+ var Net = class extends PrimitiveComponent {
1783
+ getPortSelector() {
1784
+ return `net.${this.props.name}`;
1785
+ }
1786
+ };
1787
+
1695
1788
  // lib/components/primitive-components/TraceHint.ts
1696
1789
  import "@tscircuit/props";
1697
1790
  import { applyToPoint as applyToPoint4 } from "transformation-matrix";
@@ -2176,7 +2269,7 @@ var Jumper = class extends NormalComponent {
2176
2269
  import { su } from "@tscircuit/soup-util";
2177
2270
  import { isValidElement as isValidElement2 } from "react";
2178
2271
  import { identity as identity5 } from "transformation-matrix";
2179
- var Project = class {
2272
+ var Circuit = class {
2180
2273
  rootComponent = null;
2181
2274
  children;
2182
2275
  db;
@@ -2256,10 +2349,11 @@ var Project = class {
2256
2349
  selectAll(selector) {
2257
2350
  return this.rootComponent?.selectAll(selector) ?? [];
2258
2351
  }
2259
- selectOne(selector) {
2260
- return this.rootComponent?.selectOne(selector) ?? null;
2352
+ selectOne(selector, opts) {
2353
+ return this.rootComponent?.selectOne(selector, opts) ?? null;
2261
2354
  }
2262
2355
  };
2356
+ var Project = Circuit;
2263
2357
 
2264
2358
  // lib/register-catalogue.ts
2265
2359
  extendCatalogue(components_exports);
@@ -2270,6 +2364,7 @@ export {
2270
2364
  Board,
2271
2365
  Capacitor,
2272
2366
  Chip,
2367
+ Circuit,
2273
2368
  Footprint,
2274
2369
  Group,
2275
2370
  Jumper,
package/lib/Project.ts CHANGED
@@ -6,7 +6,7 @@ import { isValidElement, type ReactElement } from "react"
6
6
  import { createInstanceFromReactElement } from "./fiber/create-instance-from-react-element"
7
7
  import { identity, type Matrix } from "transformation-matrix"
8
8
 
9
- export class Project {
9
+ export class Circuit {
10
10
  rootComponent: PrimitiveComponent | null = null
11
11
  children: PrimitiveComponent[]
12
12
  db: SoupUtilObjects
@@ -115,7 +115,12 @@ export class Project {
115
115
  return this.rootComponent?.selectAll(selector) ?? []
116
116
  }
117
117
 
118
- selectOne(selector: string): PrimitiveComponent | null {
119
- return this.rootComponent?.selectOne(selector) ?? null
118
+ selectOne(
119
+ selector: string,
120
+ opts: { type?: "component" | "port" },
121
+ ): PrimitiveComponent | null {
122
+ return this.rootComponent?.selectOne(selector, opts) ?? null
120
123
  }
121
124
  }
125
+
126
+ export const Project = Circuit
@@ -1,5 +1,5 @@
1
1
  import type { AnySoupElement, AnySourceComponent } from "@tscircuit/soup"
2
- import type { Project } from "../../Project"
2
+ import type { Circuit } from "../../Project"
3
3
  import type { ZodType } from "zod"
4
4
  import { z } from "zod"
5
5
  import { symbols, type SchSymbol, type BaseSymbolName } from "schematic-symbols"
@@ -40,7 +40,7 @@ export abstract class PrimitiveComponent<
40
40
  }
41
41
  }
42
42
 
43
- project: Project | null = null
43
+ project: Circuit | null = null
44
44
  props: z.input<ZodProps>
45
45
  _parsedProps: z.infer<ZodProps>
46
46
 
@@ -49,6 +49,21 @@ export abstract class PrimitiveComponent<
49
49
 
50
50
  externallyAddedAliases: string[]
51
51
 
52
+ /**
53
+ * An opaque group is a self-contained subcircuit. All the selectors inside
54
+ * an opaque group are relative to the group. You can have multiple opaque
55
+ * groups and their selectors will not interact with each other (even if the
56
+ * components share the same names) unless you explicitly break out some ports
57
+ */
58
+ get isOpaqueGroup() {
59
+ return (
60
+ Boolean(this.props.opaque) ||
61
+ // Implied opaque group for top-level group
62
+ (this.lowercaseComponentName === "group" &&
63
+ this?.parent?.props?.name === "$root")
64
+ )
65
+ }
66
+
52
67
  source_group_id: string | null = null
53
68
  source_component_id: string | null = null
54
69
  schematic_component_id: string | null = null
@@ -70,7 +85,7 @@ export abstract class PrimitiveComponent<
70
85
  }
71
86
  }
72
87
 
73
- setProject(project: Project) {
88
+ setProject(project: Circuit) {
74
89
  this.project = project
75
90
  for (const c of this.children) {
76
91
  c.setProject(project)
@@ -197,6 +212,27 @@ export abstract class PrimitiveComponent<
197
212
  component.shouldBeRemoved = true
198
213
  }
199
214
 
215
+ getOpaqueGroupSelector(): string {
216
+ const name = this._parsedProps.name
217
+ const endPart = name
218
+ ? `${this.lowercaseComponentName}.${name}`
219
+ : this.lowercaseComponentName
220
+
221
+ if (!this.parent) return endPart
222
+ if (this.parent.isOpaqueGroup) return endPart
223
+ return `${this.parent.getOpaqueGroupSelector()} > ${endPart}`
224
+ }
225
+
226
+ getFullPathSelector(): string {
227
+ const name = this._parsedProps.name
228
+ const endPart = name
229
+ ? `${this.lowercaseComponentName}.${name}`
230
+ : this.lowercaseComponentName
231
+ const parentSelector = this.parent?.getFullPathSelector?.()
232
+ if (!parentSelector) return endPart
233
+ return `${parentSelector} > ${endPart}`
234
+ }
235
+
200
236
  getNameAndAliases(): string[] {
201
237
  return [
202
238
  this._parsedProps.name,
@@ -230,6 +266,14 @@ export abstract class PrimitiveComponent<
230
266
  return false
231
267
  }
232
268
 
269
+ getOpaqueGroup(): PrimitiveComponent {
270
+ if (this.isOpaqueGroup) return this
271
+ const group = this.parent?.getOpaqueGroup()
272
+ if (!group)
273
+ throw new Error("Component is not inside an opaque group (no board?)")
274
+ return group
275
+ }
276
+
233
277
  selectAll(selector: string): PrimitiveComponent[] {
234
278
  const parts = selector.trim().split(/\s+/)
235
279
  let results: PrimitiveComponent[] = [this]
@@ -3,6 +3,7 @@ import { Component, createElement, type ReactElement } from "react"
3
3
 
4
4
  export const orderedRenderPhases = [
5
5
  "ReactSubtreesRender", // probably going to be removed b/c subtrees should render instantly
6
+ "CreateTracesFromProps",
6
7
  "SourceRender",
7
8
  "SourceParentAttachment",
8
9
  "PortDiscovery", // probably going to be removed b/c port discovery can always be done on prop change
@@ -6,6 +6,10 @@ import { identity, type Matrix } from "transformation-matrix"
6
6
  export class Board extends NormalComponent<typeof boardProps> {
7
7
  pcb_board_id: string | null = null
8
8
 
9
+ get isOpaqueGroup() {
10
+ return true
11
+ }
12
+
9
13
  get config() {
10
14
  return {
11
15
  zodProps: boardProps,
@@ -1,7 +1,8 @@
1
- import { ledProps } from "@tscircuit/props"
2
- import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
1
+ import { capacitorProps, ledProps } from "@tscircuit/props"
3
2
  import { FTYPE, SYMBOL } from "lib/utils/constants"
4
3
  import { NormalComponent } from "../base-components/NormalComponent"
4
+ import type { capacitance, SourceSimpleCapacitorInput } from "@tscircuit/soup"
5
+ import { Trace } from "../primitive-components/Trace"
5
6
 
6
7
  type PortNames =
7
8
  | "1"
@@ -13,7 +14,10 @@ type PortNames =
13
14
  | "anode"
14
15
  | "cathode"
15
16
 
16
- export class Capacitor extends NormalComponent<typeof ledProps, PortNames> {
17
+ export class Capacitor extends NormalComponent<
18
+ typeof capacitorProps,
19
+ PortNames
20
+ > {
17
21
  get config() {
18
22
  return {
19
23
  // schematicSymbolName: BASE_SYMBOLS.capacitor,
@@ -21,4 +25,39 @@ export class Capacitor extends NormalComponent<typeof ledProps, PortNames> {
21
25
  sourceFtype: FTYPE.simple_capacitor,
22
26
  }
23
27
  }
28
+
29
+ pin1 = this.portMap.pin1
30
+ pin2 = this.portMap.pin2
31
+
32
+ doInitialCreateTracesFromProps() {
33
+ if (this.props.decouplingFor && this.props.decouplingTo) {
34
+ this.add(
35
+ new Trace({
36
+ from: `${this.getOpaqueGroupSelector()} > port.1`,
37
+ to: this.props.decouplingFor,
38
+ }),
39
+ )
40
+ this.add(
41
+ new Trace({
42
+ from: `${this.getOpaqueGroupSelector()} > port.2`,
43
+ to: this.props.decouplingTo,
44
+ }),
45
+ )
46
+ }
47
+ }
48
+
49
+ doInitialSourceRender() {
50
+ const { db } = this.project!
51
+ const { _parsedProps: props } = this
52
+ const source_component = db.source_component.insert({
53
+ ftype: "simple_capacitor",
54
+ name: props.name,
55
+ // @ts-ignore
56
+ manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
57
+ supplier_part_numbers: props.supplierPartNumbers,
58
+
59
+ capacitance: props.capacitance,
60
+ } as SourceSimpleCapacitorInput)
61
+ this.source_component_id = source_component.source_component_id
62
+ }
24
63
  }
@@ -2,6 +2,8 @@ import { resistorProps } from "@tscircuit/props"
2
2
  import type { PassivePorts, Ftype, BaseSymbolName } from "lib/utils/constants"
3
3
  import { NormalComponent } from "../base-components/NormalComponent"
4
4
  import type { SourceSimpleResistorInput } from "@tscircuit/soup"
5
+ import { z } from "zod"
6
+ import { Trace } from "../primitive-components/Trace"
5
7
 
6
8
  export class Resistor extends NormalComponent<
7
9
  typeof resistorProps,
@@ -18,6 +20,22 @@ export class Resistor extends NormalComponent<
18
20
  pin1 = this.portMap.pin1
19
21
  pin2 = this.portMap.pin2
20
22
 
23
+ doInitialCreateTracesFromProps() {
24
+ if (this.props.pullupFor && this.props.pullupTo) {
25
+ this.add(
26
+ new Trace({
27
+ from: `${this.getOpaqueGroupSelector()} > port.1`,
28
+ to: this.props.pullupFor,
29
+ }),
30
+ )
31
+ this.add(
32
+ new Trace({
33
+ from: `${this.getOpaqueGroupSelector()} > port.2`,
34
+ to: this.props.pullupTo,
35
+ }),
36
+ )
37
+ }
38
+ }
21
39
  doInitialSourceRender() {
22
40
  const { db } = this.project!
23
41
  const { _parsedProps: props } = this
@@ -79,21 +79,25 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
79
79
 
80
80
  const ports = portSelectors.map((selector) => ({
81
81
  selector,
82
- port: parent.selectOne(selector, { type: "port" }) as Port,
82
+ port:
83
+ (this.getOpaqueGroup().selectOne(selector, { type: "port" }) as Port) ??
84
+ null,
83
85
  }))
84
86
 
85
87
  for (const { selector, port } of ports) {
86
88
  if (!port) {
87
89
  const parentSelector = selector.replace(/\>.*$/, "")
88
- const targetComponent = parent.selectOne(parentSelector)
90
+ const targetComponent = this.getOpaqueGroup().selectOne(parentSelector)
89
91
  if (!targetComponent) {
90
92
  this.renderError(`Could not find port for selector "${selector}"`)
91
93
  } else {
92
94
  this.renderError(
93
- `Could not find port for selector "${selector}"\nsearched component ${targetComponent.getString()}, which has ports:${targetComponent.children
95
+ `Could not find port for selector "${selector}"\nsearched component ${targetComponent.getString()}, which has ports: ${targetComponent.children
94
96
  .filter((c) => c.componentName === "Port")
95
- .map((c) => ` ${c.getString()}`)
96
- .join("\n")}`,
97
+ .map(
98
+ (c) => `${c.getString()}(${c.getNameAndAliases().join(",")})`,
99
+ )
100
+ .join(" & ")}`,
97
101
  )
98
102
  }
99
103
  }
@@ -173,6 +177,14 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
173
177
  const { solution } = autoroute(pcbElements.concat([source_trace]))
174
178
  // TODO for some reason, the solution gets duplicated inside ijump-astar
175
179
  const inputPcbTrace = solution[0]
180
+
181
+ if (!inputPcbTrace) {
182
+ // TODO render error indicating we could not find a route
183
+ console.log(
184
+ `Failed to find route ffrom ${ports[0].port} to ${ports[1].port} render error!`,
185
+ )
186
+ return
187
+ }
176
188
  const pcb_trace = db.pcb_trace.insert(inputPcbTrace as any)
177
189
 
178
190
  this.pcb_trace_id = pcb_trace.pcb_trace_id
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.19",
5
+ "version": "0.0.20",
6
6
  "types": "dist/index.d.ts",
7
7
  "main": "dist/index.js",
8
8
  "files": [