@tscircuit/core 0.0.1023 → 0.0.1024

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
@@ -171,9 +171,9 @@ interface IIsolatedCircuit {
171
171
  interface IRootCircuit extends IIsolatedCircuit {
172
172
  }
173
173
 
174
- declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "InflateSubcircuitCircuitJson", "SourceNameDuplicateComponentRemoval", "PcbFootprintStringRender", "InitializePortsFromChildren", "CreateNetsFromProps", "AssignFallbackProps", "CreateTracesFromProps", "CreateTracesFromNetLabels", "CreateTraceHintsFromProps", "SourceGroupRender", "AssignNameToUnnamedComponents", "SourceRender", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SourceDesignRuleChecks", "SimulationRender", "SchematicComponentRender", "SchematicPortRender", "SymbolContainerRender", "SchematicPrimitiveRender", "SchematicSymbolResize", "SchematicComponentSizeCalculation", "SchematicLayout", "SchematicTraceRender", "SchematicReplaceNetLabelsWithSymbols", "PanelBoardLayout", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbComponentSizeCalculation", "PcbComponentAnchorAlignment", "PcbLayout", "PcbBoardAutoSize", "PanelLayout", "PcbTraceHintRender", "PcbManualTraceRender", "PcbTraceRender", "PcbRouteNetIslands", "PcbCopperPourRender", "PcbDesignRuleChecks", "SilkscreenOverlapAdjustment", "CadModelRender", "PartsEngineRender", "SimulationSpiceEngineRender"];
174
+ declare const orderedRenderPhases: readonly ["RenderIsolatedSubcircuits", "ReactSubtreesRender", "InflateSubcircuitCircuitJson", "SourceNameDuplicateComponentRemoval", "PcbFootprintStringRender", "InitializePortsFromChildren", "CreateNetsFromProps", "AssignFallbackProps", "CreateTracesFromProps", "CreateTracesFromNetLabels", "CreateTraceHintsFromProps", "SourceGroupRender", "AssignNameToUnnamedComponents", "SourceRender", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SourceDesignRuleChecks", "SimulationRender", "SchematicComponentRender", "SchematicPortRender", "SymbolContainerRender", "SchematicPrimitiveRender", "SchematicSymbolResize", "SchematicComponentSizeCalculation", "SchematicLayout", "SchematicTraceRender", "SchematicReplaceNetLabelsWithSymbols", "PanelBoardLayout", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbComponentSizeCalculation", "PcbComponentAnchorAlignment", "PcbLayout", "PcbBoardAutoSize", "PanelLayout", "PcbTraceHintRender", "PcbManualTraceRender", "PcbTraceRender", "PcbRouteNetIslands", "PcbCopperPourRender", "PcbDesignRuleChecks", "SilkscreenOverlapAdjustment", "CadModelRender", "PartsEngineRender", "SimulationSpiceEngineRender"];
175
175
  type RenderPhase = (typeof orderedRenderPhases)[number];
176
- declare const renderPhaseIndexMap: Map<"ReactSubtreesRender" | "InflateSubcircuitCircuitJson" | "SourceNameDuplicateComponentRemoval" | "PcbFootprintStringRender" | "InitializePortsFromChildren" | "CreateNetsFromProps" | "AssignFallbackProps" | "CreateTracesFromProps" | "CreateTracesFromNetLabels" | "CreateTraceHintsFromProps" | "SourceGroupRender" | "AssignNameToUnnamedComponents" | "SourceRender" | "SourceParentAttachment" | "PortMatching" | "OptimizeSelectorCache" | "SourceTraceRender" | "SourceAddConnectivityMapKey" | "SourceDesignRuleChecks" | "SimulationRender" | "SchematicComponentRender" | "SchematicPortRender" | "SymbolContainerRender" | "SchematicPrimitiveRender" | "SchematicSymbolResize" | "SchematicComponentSizeCalculation" | "SchematicLayout" | "SchematicTraceRender" | "SchematicReplaceNetLabelsWithSymbols" | "PanelBoardLayout" | "PcbComponentRender" | "PcbPrimitiveRender" | "PcbFootprintLayout" | "PcbPortRender" | "PcbPortAttachment" | "PcbComponentSizeCalculation" | "PcbComponentAnchorAlignment" | "PcbLayout" | "PcbBoardAutoSize" | "PanelLayout" | "PcbTraceHintRender" | "PcbManualTraceRender" | "PcbTraceRender" | "PcbRouteNetIslands" | "PcbCopperPourRender" | "PcbDesignRuleChecks" | "SilkscreenOverlapAdjustment" | "CadModelRender" | "PartsEngineRender" | "SimulationSpiceEngineRender", number>;
176
+ declare const renderPhaseIndexMap: Map<"RenderIsolatedSubcircuits" | "ReactSubtreesRender" | "InflateSubcircuitCircuitJson" | "SourceNameDuplicateComponentRemoval" | "PcbFootprintStringRender" | "InitializePortsFromChildren" | "CreateNetsFromProps" | "AssignFallbackProps" | "CreateTracesFromProps" | "CreateTracesFromNetLabels" | "CreateTraceHintsFromProps" | "SourceGroupRender" | "AssignNameToUnnamedComponents" | "SourceRender" | "SourceParentAttachment" | "PortMatching" | "OptimizeSelectorCache" | "SourceTraceRender" | "SourceAddConnectivityMapKey" | "SourceDesignRuleChecks" | "SimulationRender" | "SchematicComponentRender" | "SchematicPortRender" | "SymbolContainerRender" | "SchematicPrimitiveRender" | "SchematicSymbolResize" | "SchematicComponentSizeCalculation" | "SchematicLayout" | "SchematicTraceRender" | "SchematicReplaceNetLabelsWithSymbols" | "PanelBoardLayout" | "PcbComponentRender" | "PcbPrimitiveRender" | "PcbFootprintLayout" | "PcbPortRender" | "PcbPortAttachment" | "PcbComponentSizeCalculation" | "PcbComponentAnchorAlignment" | "PcbLayout" | "PcbBoardAutoSize" | "PanelLayout" | "PcbTraceHintRender" | "PcbManualTraceRender" | "PcbTraceRender" | "PcbRouteNetIslands" | "PcbCopperPourRender" | "PcbDesignRuleChecks" | "SilkscreenOverlapAdjustment" | "CadModelRender" | "PartsEngineRender" | "SimulationSpiceEngineRender", number>;
177
177
  type RenderPhaseFn<K extends RenderPhase = RenderPhase> = `doInitial${K}` | `update${K}` | `remove${K}`;
178
178
  type RenderPhaseStates = Record<RenderPhase, {
179
179
  initialized: boolean;
@@ -362,7 +362,7 @@ declare class IsolatedCircuit {
362
362
  children: PrimitiveComponent[];
363
363
  db: CircuitJsonUtilObjects;
364
364
  root: IsolatedCircuit | null;
365
- isRoot: boolean;
365
+ isRootCircuit: boolean;
366
366
  private _schematicDisabledOverride;
367
367
  get schematicDisabled(): boolean;
368
368
  set schematicDisabled(value: boolean);
@@ -1653,7 +1653,9 @@ declare class Group<Props extends z.ZodType<any, any, any> = typeof groupProps>
1653
1653
  subcircuit_id: string | null;
1654
1654
  _hasStartedAsyncAutorouting: boolean;
1655
1655
  _isInflatedFromCircuitJson: boolean;
1656
- private _normalComponentNameMap;
1656
+ _isolatedCircuitJson: AnyCircuitElement[] | null;
1657
+ get _isIsolatedSubcircuit(): boolean;
1658
+ _normalComponentNameMap: Map<string, NormalComponent[]> | null;
1657
1659
  /**
1658
1660
  * Returns a cached map of component names to NormalComponent instances within this subcircuit.
1659
1661
  * The map is built lazily on first access and cached for subsequent calls.
@@ -1684,6 +1686,8 @@ declare class Group<Props extends z.ZodType<any, any, any> = typeof groupProps>
1684
1686
  zodProps: Props;
1685
1687
  componentName: string;
1686
1688
  };
1689
+ runRenderPhaseForChildren(phase: RenderPhase): void;
1690
+ doInitialRenderIsolatedSubcircuits(): void;
1687
1691
  doInitialSourceGroupRender(): void;
1688
1692
  doInitialSourceRender(): void;
1689
1693
  doInitialSourceParentAttachment(): void;
@@ -131936,7 +131940,7 @@ declare class VoltageProbe extends PrimitiveComponent<typeof voltageProbeProps>
131936
131940
  declare function resolveStaticFileImport(path: string, platform?: PlatformConfig): Promise<string>;
131937
131941
 
131938
131942
  declare class RootCircuit extends IsolatedCircuit {
131939
- isRoot: boolean;
131943
+ isRootCircuit: boolean;
131940
131944
  constructor({ platform, projectUrl, }?: {
131941
131945
  platform?: PlatformConfig;
131942
131946
  projectUrl?: string;
package/dist/index.js CHANGED
@@ -117,6 +117,7 @@ import { DefaultEventPriority } from "react-reconciler/constants.js";
117
117
  import Debug from "debug";
118
118
  var debug = Debug("tscircuit:renderable");
119
119
  var orderedRenderPhases = [
120
+ "RenderIsolatedSubcircuits",
120
121
  "ReactSubtreesRender",
121
122
  "InflateSubcircuitCircuitJson",
122
123
  "SourceNameDuplicateComponentRemoval",
@@ -172,6 +173,7 @@ var renderPhaseIndexMap = new Map(
172
173
  orderedRenderPhases.map((phase, index) => [phase, index])
173
174
  );
174
175
  var asyncPhaseDependencies = {
176
+ InflateSubcircuitCircuitJson: ["RenderIsolatedSubcircuits"],
175
177
  PcbFootprintLayout: ["PcbFootprintStringRender"],
176
178
  PcbComponentSizeCalculation: ["PcbFootprintStringRender"],
177
179
  PcbLayout: ["PcbFootprintStringRender"],
@@ -951,7 +953,7 @@ var PrimitiveComponent2 = class extends Renderable {
951
953
  * components share the same names) unless you explicitly break out some ports
952
954
  */
953
955
  get isSubcircuit() {
954
- return Boolean(this.props.subcircuit) || this.lowercaseComponentName === "group" && this?.parent?.isRoot;
956
+ return Boolean(this.props.subcircuit) || this.lowercaseComponentName === "group" && this?.parent?.isRootCircuit;
955
957
  }
956
958
  get isGroup() {
957
959
  return this.lowercaseComponentName === "group";
@@ -10283,7 +10285,7 @@ var TscircuitAutorouter = class {
10283
10285
  import {
10284
10286
  distance as distance8
10285
10287
  } from "circuit-json";
10286
- import Debug13 from "debug";
10288
+ import Debug14 from "debug";
10287
10289
  import "zod";
10288
10290
 
10289
10291
  // lib/components/primitive-components/TraceHint.ts
@@ -14649,74 +14651,488 @@ function addPortIdsToTracesAtJumperPads(segments, db) {
14649
14651
  return result;
14650
14652
  }
14651
14653
 
14652
- // lib/components/primitive-components/Group/Group.ts
14653
- var Group6 = class extends NormalComponent3 {
14654
- pcb_group_id = null;
14655
- schematic_group_id = null;
14656
- subcircuit_id = null;
14657
- _hasStartedAsyncAutorouting = false;
14658
- _isInflatedFromCircuitJson = false;
14659
- _normalComponentNameMap = null;
14654
+ // lib/IsolatedCircuit.ts
14655
+ import { su as su5 } from "@tscircuit/circuit-json-util";
14656
+ import Debug13 from "debug";
14657
+ import { isValidElement as isValidElement2 } from "react";
14658
+ import { identity as identity4 } from "transformation-matrix";
14659
+
14660
+ // package.json
14661
+ var package_default = {
14662
+ name: "@tscircuit/core",
14663
+ type: "module",
14664
+ version: "0.0.1023",
14665
+ types: "dist/index.d.ts",
14666
+ main: "dist/index.js",
14667
+ module: "dist/index.js",
14668
+ exports: {
14669
+ ".": {
14670
+ import: "./dist/index.js",
14671
+ types: "./dist/index.d.ts"
14672
+ }
14673
+ },
14674
+ files: [
14675
+ "dist"
14676
+ ],
14677
+ repository: {
14678
+ type: "git",
14679
+ url: "https://github.com/tscircuit/core"
14680
+ },
14681
+ scripts: {
14682
+ build: "tsup-node index.ts --format esm --dts",
14683
+ format: "biome format . --write",
14684
+ "measure-bundle": "howfat -r table .",
14685
+ "pkg-pr-new-release": "bunx pkg-pr-new publish --comment=off --peerDeps",
14686
+ "smoke-test:dist": "bun run scripts/smoke-tests/test-dist-simple-circuit.tsx",
14687
+ "build:benchmarking": "bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist",
14688
+ "build:benchmarking:watch": `chokidar "./{benchmarking,lib}/**/*.{ts,tsx}" -c 'bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist'`,
14689
+ "start:benchmarking": 'concurrently "bun run build:benchmarking:watch" "live-server ./benchmarking-dist"',
14690
+ "generate-test-plan": "bun run scripts/generate-test-plan.ts"
14691
+ },
14692
+ devDependencies: {
14693
+ "@biomejs/biome": "^1.8.3",
14694
+ "@resvg/resvg-js": "^2.6.2",
14695
+ "@tscircuit/alphabet": "0.0.18",
14696
+ "@tscircuit/capacity-autorouter": "^0.0.264",
14697
+ "@tscircuit/checks": "^0.0.88",
14698
+ "@tscircuit/circuit-json-util": "^0.0.77",
14699
+ "@tscircuit/common": "^0.0.20",
14700
+ "@tscircuit/copper-pour-solver": "^0.0.20",
14701
+ "@tscircuit/footprinter": "^0.0.288",
14702
+ "@tscircuit/infgrid-ijump-astar": "^0.0.35",
14703
+ "@tscircuit/log-soup": "^1.0.2",
14704
+ "@tscircuit/matchpack": "^0.0.16",
14705
+ "@tscircuit/math-utils": "^0.0.29",
14706
+ "@tscircuit/miniflex": "^0.0.4",
14707
+ "@tscircuit/ngspice-spice-engine": "^0.0.8",
14708
+ "@tscircuit/props": "^0.0.471",
14709
+ "@tscircuit/schematic-match-adapt": "^0.0.16",
14710
+ "@tscircuit/schematic-trace-solver": "^v0.0.45",
14711
+ "@tscircuit/solver-utils": "^0.0.3",
14712
+ "@tscircuit/soup-util": "^0.0.41",
14713
+ "@types/bun": "^1.2.16",
14714
+ "@types/debug": "^4.1.12",
14715
+ "@types/react": "^19.1.8",
14716
+ "@types/react-dom": "^19.1.6",
14717
+ "@types/react-reconciler": "^0.28.9",
14718
+ "bpc-graph": "^0.0.57",
14719
+ "bun-match-svg": "0.0.12",
14720
+ "calculate-elbow": "^0.0.12",
14721
+ "chokidar-cli": "^3.0.0",
14722
+ "circuit-json": "^0.0.378",
14723
+ "circuit-json-to-bpc": "^0.0.13",
14724
+ "circuit-json-to-connectivity-map": "^0.0.23",
14725
+ "circuit-json-to-gltf": "^0.0.62",
14726
+ "circuit-json-to-simple-3d": "^0.0.9",
14727
+ "circuit-json-to-spice": "^0.0.33",
14728
+ "circuit-to-svg": "^0.0.327",
14729
+ concurrently: "^9.1.2",
14730
+ "connectivity-map": "^1.0.0",
14731
+ debug: "^4.3.6",
14732
+ "eecircuit-engine": "^1.5.6",
14733
+ flatbush: "^4.5.0",
14734
+ "graphics-debug": "^0.0.60",
14735
+ howfat: "^0.3.8",
14736
+ "live-server": "^1.2.2",
14737
+ "looks-same": "^9.0.1",
14738
+ minicssgrid: "^0.0.9",
14739
+ "pkg-pr-new": "^0.0.37",
14740
+ poppygl: "^0.0.16",
14741
+ react: "^19.1.0",
14742
+ "react-dom": "^19.1.0",
14743
+ "schematic-symbols": "^0.0.208",
14744
+ spicey: "^0.0.14",
14745
+ "ts-expect": "^1.3.0",
14746
+ tsup: "^8.2.4"
14747
+ },
14748
+ peerDependencies: {
14749
+ "@tscircuit/capacity-autorouter": "*",
14750
+ "@tscircuit/checks": "*",
14751
+ "@tscircuit/circuit-json-util": "*",
14752
+ "@tscircuit/footprinter": "*",
14753
+ "@tscircuit/infgrid-ijump-astar": "*",
14754
+ "@tscircuit/math-utils": "*",
14755
+ "@tscircuit/props": "*",
14756
+ "@tscircuit/schematic-match-adapt": "*",
14757
+ "circuit-json-to-bpc": "*",
14758
+ "bpc-graph": "*",
14759
+ "@tscircuit/matchpack": "*",
14760
+ "circuit-json": "*",
14761
+ "circuit-json-to-connectivity-map": "*",
14762
+ "schematic-symbols": "*",
14763
+ typescript: "^5.0.0"
14764
+ },
14765
+ dependencies: {
14766
+ "@flatten-js/core": "^1.6.2",
14767
+ "@lume/kiwi": "^0.4.3",
14768
+ "calculate-packing": "0.0.68",
14769
+ "css-select": "5.1.0",
14770
+ "format-si-unit": "^0.0.3",
14771
+ nanoid: "^5.0.7",
14772
+ "performance-now": "^2.1.0",
14773
+ "react-reconciler": "^0.32.0",
14774
+ "svg-path-commander": "^2.1.11",
14775
+ "transformation-matrix": "^2.16.1",
14776
+ zod: "^3.25.67"
14777
+ }
14778
+ };
14779
+
14780
+ // lib/IsolatedCircuit.ts
14781
+ var IsolatedCircuit = class {
14782
+ firstChild = null;
14783
+ children;
14784
+ db;
14785
+ root = null;
14786
+ isRootCircuit = false;
14787
+ _schematicDisabledOverride;
14788
+ get schematicDisabled() {
14789
+ if (this._schematicDisabledOverride !== void 0) {
14790
+ return this._schematicDisabledOverride;
14791
+ }
14792
+ if (this.platform?.schematicDisabled !== void 0) {
14793
+ return this.platform.schematicDisabled;
14794
+ }
14795
+ const board = this._getBoard();
14796
+ return board?._parsedProps?.schematicDisabled ?? false;
14797
+ }
14798
+ set schematicDisabled(value) {
14799
+ this._schematicDisabledOverride = value;
14800
+ }
14801
+ pcbDisabled = false;
14802
+ pcbRoutingDisabled = false;
14803
+ _featureMspSchematicTraceRouting = true;
14660
14804
  /**
14661
- * Returns a cached map of component names to NormalComponent instances within this subcircuit.
14662
- * The map is built lazily on first access and cached for subsequent calls.
14805
+ * The IsolatedCircuit name is usually set by the platform, it's not required but
14806
+ * if supplied can identify the circuit in certain effects, e.g. it is passed
14807
+ * as the display_name parameter for autorouting effects.
14663
14808
  */
14664
- getNormalComponentNameMap() {
14665
- if (this._normalComponentNameMap) {
14666
- return this._normalComponentNameMap;
14667
- }
14668
- const nameMap = /* @__PURE__ */ new Map();
14669
- const collectNamedComponents = (component) => {
14670
- if (component._isNormalComponent && component.name) {
14671
- const componentsWithSameName = nameMap.get(component.name);
14672
- if (componentsWithSameName) {
14673
- componentsWithSameName.push(component);
14674
- } else {
14675
- nameMap.set(component.name, [component]);
14676
- }
14677
- }
14678
- for (const child of component.children) {
14679
- if (!child.isSubcircuit) collectNamedComponents(child);
14680
- }
14681
- };
14682
- for (const child of this.children) {
14683
- if (!child.isSubcircuit) collectNamedComponents(child);
14809
+ name;
14810
+ platform;
14811
+ /**
14812
+ * Optional URL pointing to where this project is hosted or documented.
14813
+ * When provided it is stored in the source_project_metadata.project_url field
14814
+ * of the generated Circuit JSON.
14815
+ */
14816
+ projectUrl;
14817
+ _hasRenderedAtleastOnce = false;
14818
+ _asyncEffectIdsByPhase = /* @__PURE__ */ new Map();
14819
+ _asyncEffectPhaseById = /* @__PURE__ */ new Map();
14820
+ constructor({
14821
+ platform,
14822
+ projectUrl
14823
+ } = {}) {
14824
+ this.children = [];
14825
+ this.db = su5([]);
14826
+ this.platform = platform;
14827
+ this.projectUrl = projectUrl;
14828
+ this.pcbDisabled = platform?.pcbDisabled ?? false;
14829
+ this.root = this;
14830
+ }
14831
+ add(componentOrElm) {
14832
+ let component;
14833
+ if (isValidElement2(componentOrElm)) {
14834
+ component = createInstanceFromReactElement(componentOrElm);
14835
+ } else {
14836
+ component = componentOrElm;
14684
14837
  }
14685
- this._normalComponentNameMap = nameMap;
14686
- return nameMap;
14838
+ this.children.push(component);
14687
14839
  }
14688
- _asyncAutoroutingResult = null;
14689
- get config() {
14690
- return {
14691
- zodProps: groupProps,
14692
- componentName: "Group"
14840
+ setPlatform(platform) {
14841
+ this.platform = {
14842
+ ...this.platform,
14843
+ ...platform
14693
14844
  };
14694
14845
  }
14695
- doInitialSourceGroupRender() {
14696
- const { db } = this.root;
14697
- const hasExplicitName = typeof this._parsedProps.name === "string" && this._parsedProps.name.length > 0;
14698
- const source_group = db.source_group.insert({
14699
- name: this.name,
14700
- is_subcircuit: this.isSubcircuit,
14701
- was_automatically_named: !hasExplicitName
14702
- });
14703
- this.source_group_id = source_group.source_group_id;
14704
- if (this.isSubcircuit) {
14705
- this.subcircuit_id = `subcircuit_${source_group.source_group_id}`;
14706
- db.source_group.update(source_group.source_group_id, {
14707
- subcircuit_id: this.subcircuit_id
14708
- });
14846
+ /**
14847
+ * Get the main board for this Circuit.
14848
+ */
14849
+ _getBoard() {
14850
+ const directBoard = this.children.find((c) => c.componentName === "Board");
14851
+ if (directBoard) {
14852
+ return directBoard;
14709
14853
  }
14854
+ return void 0;
14710
14855
  }
14711
- doInitialSourceRender() {
14712
- const { db } = this.root;
14713
- for (const child of this.children) {
14714
- db.source_component.update(child.source_component_id, {
14715
- source_group_id: this.source_group_id
14716
- });
14856
+ _guessRootComponent() {
14857
+ if (this.firstChild) return;
14858
+ if (this.children.length === 0) {
14859
+ throw new Error(
14860
+ "Not able to guess root component: IsolatedCircuit has no children (use circuit.add(...))"
14861
+ );
14717
14862
  }
14718
- }
14719
- doInitialSourceParentAttachment() {
14863
+ const panels = this.children.filter(
14864
+ (child) => child.lowercaseComponentName === "panel"
14865
+ );
14866
+ if (panels.length > 1) {
14867
+ throw new Error("Only one <panel> is allowed per circuit");
14868
+ }
14869
+ if (panels.length === 1) {
14870
+ if (this.children.length !== 1) {
14871
+ throw new Error("<panel> must be the root element of the circuit");
14872
+ }
14873
+ this.firstChild = panels[0];
14874
+ return;
14875
+ }
14876
+ if (this.children.length === 1 && this.children[0].isGroup) {
14877
+ this.firstChild = this.children[0];
14878
+ return;
14879
+ }
14880
+ const group = new Group6({ subcircuit: true });
14881
+ group.parent = this;
14882
+ group.addAll(this.children);
14883
+ this.children = [group];
14884
+ this.firstChild = group;
14885
+ }
14886
+ render() {
14887
+ if (!this.firstChild) {
14888
+ this._guessRootComponent();
14889
+ }
14890
+ const { firstChild, db } = this;
14891
+ if (!firstChild) throw new Error("IsolatedCircuit has no root component");
14892
+ firstChild.parent = this;
14893
+ firstChild.runRenderCycle();
14894
+ this._hasRenderedAtleastOnce = true;
14895
+ }
14896
+ async renderUntilSettled() {
14897
+ const existing = this.db.source_project_metadata.list()?.[0];
14898
+ if (!existing) {
14899
+ this.db.source_project_metadata.insert({
14900
+ software_used_string: `@tscircuit/core@${this.getCoreVersion()}`,
14901
+ ...this.projectUrl ? { project_url: this.projectUrl } : {}
14902
+ });
14903
+ }
14904
+ this.render();
14905
+ while (this._hasIncompleteAsyncEffects()) {
14906
+ await new Promise((resolve) => setTimeout(resolve, 100));
14907
+ this.render();
14908
+ }
14909
+ this.emit("renderComplete");
14910
+ }
14911
+ _hasIncompleteAsyncEffects() {
14912
+ if (this._asyncEffectPhaseById.size > 0) return true;
14913
+ return this.children.some((child) => child._hasIncompleteAsyncEffects());
14914
+ }
14915
+ _hasIncompleteAsyncEffectsForPhase(phase) {
14916
+ return (this._asyncEffectIdsByPhase.get(phase)?.size ?? 0) > 0;
14917
+ }
14918
+ getCircuitJson() {
14919
+ if (!this._hasRenderedAtleastOnce) this.render();
14920
+ return this.db.toArray();
14921
+ }
14922
+ toJson() {
14923
+ return this.getCircuitJson();
14924
+ }
14925
+ async getSvg(options) {
14926
+ const circuitToSvg = await import("circuit-to-svg").catch((e) => {
14927
+ throw new Error(
14928
+ `To use circuit.getSvg, you must install the "circuit-to-svg" package.
14929
+
14930
+ "${e.message}"`
14931
+ );
14932
+ });
14933
+ if (options.view === "pcb") {
14934
+ return circuitToSvg.convertCircuitJsonToPcbSvg(this.getCircuitJson());
14935
+ }
14936
+ if (options.view === "schematic") {
14937
+ return circuitToSvg.convertCircuitJsonToSchematicSvg(
14938
+ this.getCircuitJson()
14939
+ );
14940
+ }
14941
+ throw new Error(`Invalid view: ${options.view}`);
14942
+ }
14943
+ getCoreVersion() {
14944
+ const [major, minor, patch] = package_default.version.split(".").map(Number);
14945
+ return `${major}.${minor}.${patch + 1}`;
14946
+ }
14947
+ async preview(previewNameOrOpts) {
14948
+ const previewOpts = typeof previewNameOrOpts === "object" ? previewNameOrOpts : { previewName: previewNameOrOpts };
14949
+ throw new Error("project.preview is not yet implemented");
14950
+ }
14951
+ computeSchematicGlobalTransform() {
14952
+ return identity4();
14953
+ }
14954
+ _computePcbGlobalTransformBeforeLayout() {
14955
+ return identity4();
14956
+ }
14957
+ selectAll(selector) {
14958
+ this._guessRootComponent();
14959
+ return this.firstChild?.selectAll(selector) ?? [];
14960
+ }
14961
+ selectOne(selector, opts) {
14962
+ this._guessRootComponent();
14963
+ return this.firstChild?.selectOne(selector, opts) ?? null;
14964
+ }
14965
+ _eventListeners = {};
14966
+ emit(event, ...args) {
14967
+ if (event === "asyncEffect:start") {
14968
+ this._registerAsyncEffectStart(args[0]);
14969
+ } else if (event === "asyncEffect:end") {
14970
+ this._registerAsyncEffectEnd(args[0]);
14971
+ }
14972
+ if (!this._eventListeners[event]) return;
14973
+ for (const listener of this._eventListeners[event]) {
14974
+ listener(...args);
14975
+ }
14976
+ }
14977
+ on(event, listener) {
14978
+ if (!this._eventListeners[event]) {
14979
+ this._eventListeners[event] = [];
14980
+ }
14981
+ this._eventListeners[event].push(listener);
14982
+ }
14983
+ removeListener(event, listener) {
14984
+ if (!this._eventListeners[event]) return;
14985
+ this._eventListeners[event] = this._eventListeners[event].filter(
14986
+ (l) => l !== listener
14987
+ );
14988
+ }
14989
+ enableDebug(debug11) {
14990
+ if (typeof debug11 === "string") {
14991
+ Debug13.enable(debug11);
14992
+ } else if (debug11 === null || debug11 === false) {
14993
+ Debug13.disable();
14994
+ }
14995
+ }
14996
+ getClientOrigin() {
14997
+ if (typeof window !== "undefined" && window.location) {
14998
+ return window.location.origin;
14999
+ }
15000
+ if (typeof self !== "undefined" && self.location) {
15001
+ return self.location.origin;
15002
+ }
15003
+ return "";
15004
+ }
15005
+ _registerAsyncEffectStart(payload) {
15006
+ if (!payload?.asyncEffectId || !payload.phase) return;
15007
+ const { asyncEffectId, phase } = payload;
15008
+ const existingPhase = this._asyncEffectPhaseById.get(asyncEffectId);
15009
+ if (existingPhase && existingPhase !== phase) {
15010
+ this._asyncEffectIdsByPhase.get(existingPhase)?.delete(asyncEffectId);
15011
+ }
15012
+ if (!this._asyncEffectIdsByPhase.has(phase)) {
15013
+ this._asyncEffectIdsByPhase.set(phase, /* @__PURE__ */ new Set());
15014
+ }
15015
+ this._asyncEffectIdsByPhase.get(phase).add(asyncEffectId);
15016
+ this._asyncEffectPhaseById.set(asyncEffectId, phase);
15017
+ }
15018
+ _registerAsyncEffectEnd(payload) {
15019
+ if (!payload?.asyncEffectId) return;
15020
+ const { asyncEffectId } = payload;
15021
+ const phase = this._asyncEffectPhaseById.get(asyncEffectId) ?? payload.phase;
15022
+ if (phase) {
15023
+ const phaseSet = this._asyncEffectIdsByPhase.get(phase);
15024
+ phaseSet?.delete(asyncEffectId);
15025
+ if (phaseSet && phaseSet.size === 0) {
15026
+ this._asyncEffectIdsByPhase.delete(phase);
15027
+ }
15028
+ }
15029
+ this._asyncEffectPhaseById.delete(asyncEffectId);
15030
+ }
15031
+ };
15032
+
15033
+ // lib/components/primitive-components/Group/Group_doInitialRenderIsolatedSubcircuits.ts
15034
+ function Group_doInitialRenderIsolatedSubcircuits(group) {
15035
+ if (!group._isIsolatedSubcircuit) return;
15036
+ if (!group.root) return;
15037
+ const parentRoot = group.root;
15038
+ const isolatedCircuit = new IsolatedCircuit({
15039
+ platform: {
15040
+ ...parentRoot.platform,
15041
+ pcbDisabled: parentRoot.pcbDisabled,
15042
+ schematicDisabled: parentRoot.schematicDisabled
15043
+ }
15044
+ });
15045
+ const childrenSnapshot = [...group.children];
15046
+ for (const child of childrenSnapshot) {
15047
+ isolatedCircuit.add(child);
15048
+ }
15049
+ group._queueAsyncEffect("render-isolated-subcircuit", async () => {
15050
+ await isolatedCircuit.renderUntilSettled();
15051
+ group.children = [];
15052
+ group._normalComponentNameMap = null;
15053
+ group._isolatedCircuitJson = isolatedCircuit.getCircuitJson();
15054
+ });
15055
+ }
15056
+
15057
+ // lib/components/primitive-components/Group/Group.ts
15058
+ var Group6 = class extends NormalComponent3 {
15059
+ pcb_group_id = null;
15060
+ schematic_group_id = null;
15061
+ subcircuit_id = null;
15062
+ _hasStartedAsyncAutorouting = false;
15063
+ _isInflatedFromCircuitJson = false;
15064
+ _isolatedCircuitJson = null;
15065
+ get _isIsolatedSubcircuit() {
15066
+ return Boolean(this._parsedProps._subcircuitCachingEnabled);
15067
+ }
15068
+ _normalComponentNameMap = null;
15069
+ /**
15070
+ * Returns a cached map of component names to NormalComponent instances within this subcircuit.
15071
+ * The map is built lazily on first access and cached for subsequent calls.
15072
+ */
15073
+ getNormalComponentNameMap() {
15074
+ if (this._normalComponentNameMap) {
15075
+ return this._normalComponentNameMap;
15076
+ }
15077
+ const nameMap = /* @__PURE__ */ new Map();
15078
+ const collectNamedComponents = (component) => {
15079
+ if (component._isNormalComponent && component.name) {
15080
+ const componentsWithSameName = nameMap.get(component.name);
15081
+ if (componentsWithSameName) {
15082
+ componentsWithSameName.push(component);
15083
+ } else {
15084
+ nameMap.set(component.name, [component]);
15085
+ }
15086
+ }
15087
+ for (const child of component.children) {
15088
+ if (!child.isSubcircuit) collectNamedComponents(child);
15089
+ }
15090
+ };
15091
+ for (const child of this.children) {
15092
+ if (!child.isSubcircuit) collectNamedComponents(child);
15093
+ }
15094
+ this._normalComponentNameMap = nameMap;
15095
+ return nameMap;
15096
+ }
15097
+ _asyncAutoroutingResult = null;
15098
+ get config() {
15099
+ return {
15100
+ zodProps: groupProps,
15101
+ componentName: "Group"
15102
+ };
15103
+ }
15104
+ runRenderPhaseForChildren(phase) {
15105
+ if (this._isIsolatedSubcircuit && !this._isInflatedFromCircuitJson) return;
15106
+ super.runRenderPhaseForChildren(phase);
15107
+ }
15108
+ doInitialRenderIsolatedSubcircuits() {
15109
+ Group_doInitialRenderIsolatedSubcircuits(this);
15110
+ }
15111
+ doInitialSourceGroupRender() {
15112
+ const { db } = this.root;
15113
+ const hasExplicitName = typeof this._parsedProps.name === "string" && this._parsedProps.name.length > 0;
15114
+ const source_group = db.source_group.insert({
15115
+ name: this.name,
15116
+ is_subcircuit: this.isSubcircuit,
15117
+ was_automatically_named: !hasExplicitName
15118
+ });
15119
+ this.source_group_id = source_group.source_group_id;
15120
+ if (this.isSubcircuit) {
15121
+ this.subcircuit_id = `subcircuit_${source_group.source_group_id}`;
15122
+ db.source_group.update(source_group.source_group_id, {
15123
+ subcircuit_id: this.subcircuit_id
15124
+ });
15125
+ }
15126
+ }
15127
+ doInitialSourceRender() {
15128
+ const { db } = this.root;
15129
+ for (const child of this.children) {
15130
+ db.source_component.update(child.source_component_id, {
15131
+ source_group_id: this.source_group_id
15132
+ });
15133
+ }
15134
+ }
15135
+ doInitialSourceParentAttachment() {
14720
15136
  const { db } = this.root;
14721
15137
  const parentGroup = this.parent?.getGroup?.();
14722
15138
  if (parentGroup?.source_group_id) {
@@ -14880,14 +15296,14 @@ var Group6 = class extends NormalComponent3 {
14880
15296
  return false;
14881
15297
  }
14882
15298
  _hasTracesToRoute() {
14883
- const debug11 = Debug13("tscircuit:core:_hasTracesToRoute");
15299
+ const debug11 = Debug14("tscircuit:core:_hasTracesToRoute");
14884
15300
  const traces = this.selectAll("trace");
14885
15301
  debug11(`[${this.getString()}] has ${traces.length} traces to route`);
14886
15302
  return traces.length > 0;
14887
15303
  }
14888
15304
  async _runEffectMakeHttpAutoroutingRequest() {
14889
15305
  const { db } = this.root;
14890
- const debug11 = Debug13("tscircuit:core:_runEffectMakeHttpAutoroutingRequest");
15306
+ const debug11 = Debug14("tscircuit:core:_runEffectMakeHttpAutoroutingRequest");
14891
15307
  const props = this._parsedProps;
14892
15308
  const autorouterConfig = this._getAutorouterConfig();
14893
15309
  const serverUrl = autorouterConfig.serverUrl;
@@ -15010,7 +15426,7 @@ var Group6 = class extends NormalComponent3 {
15010
15426
  async _runLocalAutorouting() {
15011
15427
  const { db } = this.root;
15012
15428
  const props = this._parsedProps;
15013
- const debug11 = Debug13("tscircuit:core:_runLocalAutorouting");
15429
+ const debug11 = Debug14("tscircuit:core:_runLocalAutorouting");
15014
15430
  debug11(`[${this.getString()}] starting local autorouting`);
15015
15431
  const autorouterConfig = this._getAutorouterConfig();
15016
15432
  const isLaserPrefabPreset = this._isLaserPrefabAutorouter(autorouterConfig);
@@ -15146,7 +15562,7 @@ var Group6 = class extends NormalComponent3 {
15146
15562
  }
15147
15563
  }
15148
15564
  doInitialPcbTraceRender() {
15149
- const debug11 = Debug13("tscircuit:core:doInitialPcbTraceRender");
15565
+ const debug11 = Debug14("tscircuit:core:doInitialPcbTraceRender");
15150
15566
  if (!this.isSubcircuit) return;
15151
15567
  if (this.root?.pcbDisabled) return;
15152
15568
  if (this.getInheritedProperty("routingDisabled")) return;
@@ -15168,7 +15584,7 @@ var Group6 = class extends NormalComponent3 {
15168
15584
  Group_doInitialSchematicTraceRender(this);
15169
15585
  }
15170
15586
  updatePcbTraceRender() {
15171
- const debug11 = Debug13("tscircuit:core:updatePcbTraceRender");
15587
+ const debug11 = Debug14("tscircuit:core:updatePcbTraceRender");
15172
15588
  debug11(`[${this.getString()}] updating...`);
15173
15589
  if (!this.isSubcircuit) return;
15174
15590
  if (this._isInflatedFromCircuitJson) return;
@@ -17078,6 +17494,13 @@ var Subcircuit = class extends Group6 {
17078
17494
  * - Add components to groups in the appropriate hierarchy
17079
17495
  */
17080
17496
  doInitialInflateSubcircuitCircuitJson() {
17497
+ const isolatedJson = this._isolatedCircuitJson;
17498
+ if (isolatedJson) {
17499
+ this._isInflatedFromCircuitJson = true;
17500
+ this._isolatedCircuitJson = null;
17501
+ inflateCircuitJson(this, isolatedJson, []);
17502
+ return;
17503
+ }
17081
17504
  const { circuitJson, children } = this._parsedProps;
17082
17505
  if (circuitJson) {
17083
17506
  this._isInflatedFromCircuitJson = true;
@@ -19449,7 +19872,7 @@ var BreakoutPoint = class extends PrimitiveComponent2 {
19449
19872
  import { netLabelProps } from "@tscircuit/props";
19450
19873
  import {
19451
19874
  applyToPoint as applyToPoint17,
19452
- identity as identity4,
19875
+ identity as identity5,
19453
19876
  translate as translate8
19454
19877
  } from "transformation-matrix";
19455
19878
  import { calculateElbow as calculateElbow2 } from "calculate-elbow";
@@ -19500,7 +19923,7 @@ var NetLabel = class extends PrimitiveComponent2 {
19500
19923
  if (connectedPorts.length > 0) {
19501
19924
  const portPos = connectedPorts[0]._getGlobalSchematicPositionBeforeLayout();
19502
19925
  const parentCenter = applyToPoint17(
19503
- this.parent?.computeSchematicGlobalTransform?.() ?? identity4(),
19926
+ this.parent?.computeSchematicGlobalTransform?.() ?? identity5(),
19504
19927
  { x: 0, y: 0 }
19505
19928
  );
19506
19929
  return translate8(portPos.x - parentCenter.x, portPos.y - parentCenter.y);
@@ -22306,384 +22729,9 @@ var VoltageProbe = class extends PrimitiveComponent2 {
22306
22729
  }
22307
22730
  };
22308
22731
 
22309
- // lib/IsolatedCircuit.ts
22310
- import { su as su5 } from "@tscircuit/circuit-json-util";
22311
- import Debug14 from "debug";
22312
- import { isValidElement as isValidElement2 } from "react";
22313
- import { identity as identity5 } from "transformation-matrix";
22314
-
22315
- // package.json
22316
- var package_default = {
22317
- name: "@tscircuit/core",
22318
- type: "module",
22319
- version: "0.0.1022",
22320
- types: "dist/index.d.ts",
22321
- main: "dist/index.js",
22322
- module: "dist/index.js",
22323
- exports: {
22324
- ".": {
22325
- import: "./dist/index.js",
22326
- types: "./dist/index.d.ts"
22327
- }
22328
- },
22329
- files: [
22330
- "dist"
22331
- ],
22332
- repository: {
22333
- type: "git",
22334
- url: "https://github.com/tscircuit/core"
22335
- },
22336
- scripts: {
22337
- build: "tsup-node index.ts --format esm --dts",
22338
- format: "biome format . --write",
22339
- "measure-bundle": "howfat -r table .",
22340
- "pkg-pr-new-release": "bunx pkg-pr-new publish --comment=off --peerDeps",
22341
- "smoke-test:dist": "bun run scripts/smoke-tests/test-dist-simple-circuit.tsx",
22342
- "build:benchmarking": "bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist",
22343
- "build:benchmarking:watch": `chokidar "./{benchmarking,lib}/**/*.{ts,tsx}" -c 'bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist'`,
22344
- "start:benchmarking": 'concurrently "bun run build:benchmarking:watch" "live-server ./benchmarking-dist"',
22345
- "generate-test-plan": "bun run scripts/generate-test-plan.ts"
22346
- },
22347
- devDependencies: {
22348
- "@biomejs/biome": "^1.8.3",
22349
- "@resvg/resvg-js": "^2.6.2",
22350
- "@tscircuit/alphabet": "0.0.18",
22351
- "@tscircuit/capacity-autorouter": "^0.0.264",
22352
- "@tscircuit/checks": "^0.0.88",
22353
- "@tscircuit/circuit-json-util": "^0.0.77",
22354
- "@tscircuit/common": "^0.0.20",
22355
- "@tscircuit/copper-pour-solver": "^0.0.20",
22356
- "@tscircuit/footprinter": "^0.0.288",
22357
- "@tscircuit/infgrid-ijump-astar": "^0.0.35",
22358
- "@tscircuit/log-soup": "^1.0.2",
22359
- "@tscircuit/matchpack": "^0.0.16",
22360
- "@tscircuit/math-utils": "^0.0.29",
22361
- "@tscircuit/miniflex": "^0.0.4",
22362
- "@tscircuit/ngspice-spice-engine": "^0.0.8",
22363
- "@tscircuit/props": "^0.0.471",
22364
- "@tscircuit/schematic-match-adapt": "^0.0.16",
22365
- "@tscircuit/schematic-trace-solver": "^v0.0.45",
22366
- "@tscircuit/solver-utils": "^0.0.3",
22367
- "@tscircuit/soup-util": "^0.0.41",
22368
- "@types/bun": "^1.2.16",
22369
- "@types/debug": "^4.1.12",
22370
- "@types/react": "^19.1.8",
22371
- "@types/react-dom": "^19.1.6",
22372
- "@types/react-reconciler": "^0.28.9",
22373
- "bpc-graph": "^0.0.57",
22374
- "bun-match-svg": "0.0.12",
22375
- "calculate-elbow": "^0.0.12",
22376
- "chokidar-cli": "^3.0.0",
22377
- "circuit-json": "^0.0.378",
22378
- "circuit-json-to-bpc": "^0.0.13",
22379
- "circuit-json-to-connectivity-map": "^0.0.23",
22380
- "circuit-json-to-gltf": "^0.0.62",
22381
- "circuit-json-to-simple-3d": "^0.0.9",
22382
- "circuit-json-to-spice": "^0.0.33",
22383
- "circuit-to-svg": "^0.0.327",
22384
- concurrently: "^9.1.2",
22385
- "connectivity-map": "^1.0.0",
22386
- debug: "^4.3.6",
22387
- "eecircuit-engine": "^1.5.6",
22388
- flatbush: "^4.5.0",
22389
- "graphics-debug": "^0.0.60",
22390
- howfat: "^0.3.8",
22391
- "live-server": "^1.2.2",
22392
- "looks-same": "^9.0.1",
22393
- minicssgrid: "^0.0.9",
22394
- "pkg-pr-new": "^0.0.37",
22395
- poppygl: "^0.0.16",
22396
- react: "^19.1.0",
22397
- "react-dom": "^19.1.0",
22398
- "schematic-symbols": "^0.0.208",
22399
- spicey: "^0.0.14",
22400
- "ts-expect": "^1.3.0",
22401
- tsup: "^8.2.4"
22402
- },
22403
- peerDependencies: {
22404
- "@tscircuit/capacity-autorouter": "*",
22405
- "@tscircuit/checks": "*",
22406
- "@tscircuit/circuit-json-util": "*",
22407
- "@tscircuit/footprinter": "*",
22408
- "@tscircuit/infgrid-ijump-astar": "*",
22409
- "@tscircuit/math-utils": "*",
22410
- "@tscircuit/props": "*",
22411
- "@tscircuit/schematic-match-adapt": "*",
22412
- "circuit-json-to-bpc": "*",
22413
- "bpc-graph": "*",
22414
- "@tscircuit/matchpack": "*",
22415
- "circuit-json": "*",
22416
- "circuit-json-to-connectivity-map": "*",
22417
- "schematic-symbols": "*",
22418
- typescript: "^5.0.0"
22419
- },
22420
- dependencies: {
22421
- "@flatten-js/core": "^1.6.2",
22422
- "@lume/kiwi": "^0.4.3",
22423
- "calculate-packing": "0.0.68",
22424
- "css-select": "5.1.0",
22425
- "format-si-unit": "^0.0.3",
22426
- nanoid: "^5.0.7",
22427
- "performance-now": "^2.1.0",
22428
- "react-reconciler": "^0.32.0",
22429
- "svg-path-commander": "^2.1.11",
22430
- "transformation-matrix": "^2.16.1",
22431
- zod: "^3.25.67"
22432
- }
22433
- };
22434
-
22435
- // lib/IsolatedCircuit.ts
22436
- var IsolatedCircuit = class {
22437
- firstChild = null;
22438
- children;
22439
- db;
22440
- root = null;
22441
- isRoot = false;
22442
- _schematicDisabledOverride;
22443
- get schematicDisabled() {
22444
- if (this._schematicDisabledOverride !== void 0) {
22445
- return this._schematicDisabledOverride;
22446
- }
22447
- const board = this._getBoard();
22448
- return board?._parsedProps?.schematicDisabled ?? false;
22449
- }
22450
- set schematicDisabled(value) {
22451
- this._schematicDisabledOverride = value;
22452
- }
22453
- pcbDisabled = false;
22454
- pcbRoutingDisabled = false;
22455
- _featureMspSchematicTraceRouting = true;
22456
- /**
22457
- * The IsolatedCircuit name is usually set by the platform, it's not required but
22458
- * if supplied can identify the circuit in certain effects, e.g. it is passed
22459
- * as the display_name parameter for autorouting effects.
22460
- */
22461
- name;
22462
- platform;
22463
- /**
22464
- * Optional URL pointing to where this project is hosted or documented.
22465
- * When provided it is stored in the source_project_metadata.project_url field
22466
- * of the generated Circuit JSON.
22467
- */
22468
- projectUrl;
22469
- _hasRenderedAtleastOnce = false;
22470
- _asyncEffectIdsByPhase = /* @__PURE__ */ new Map();
22471
- _asyncEffectPhaseById = /* @__PURE__ */ new Map();
22472
- constructor({
22473
- platform,
22474
- projectUrl
22475
- } = {}) {
22476
- this.children = [];
22477
- this.db = su5([]);
22478
- this.platform = platform;
22479
- this.projectUrl = projectUrl;
22480
- this.pcbDisabled = platform?.pcbDisabled ?? false;
22481
- }
22482
- add(componentOrElm) {
22483
- let component;
22484
- if (isValidElement2(componentOrElm)) {
22485
- component = createInstanceFromReactElement(componentOrElm);
22486
- } else {
22487
- component = componentOrElm;
22488
- }
22489
- this.children.push(component);
22490
- }
22491
- setPlatform(platform) {
22492
- this.platform = {
22493
- ...this.platform,
22494
- ...platform
22495
- };
22496
- }
22497
- /**
22498
- * Get the main board for this Circuit.
22499
- */
22500
- _getBoard() {
22501
- const directBoard = this.children.find((c) => c.componentName === "Board");
22502
- if (directBoard) {
22503
- return directBoard;
22504
- }
22505
- return void 0;
22506
- }
22507
- _guessRootComponent() {
22508
- if (this.firstChild) return;
22509
- if (this.children.length === 0) {
22510
- throw new Error(
22511
- "Not able to guess root component: IsolatedCircuit has no children (use circuit.add(...))"
22512
- );
22513
- }
22514
- const panels = this.children.filter(
22515
- (child) => child.lowercaseComponentName === "panel"
22516
- );
22517
- if (panels.length > 1) {
22518
- throw new Error("Only one <panel> is allowed per circuit");
22519
- }
22520
- if (panels.length === 1) {
22521
- if (this.children.length !== 1) {
22522
- throw new Error("<panel> must be the root element of the circuit");
22523
- }
22524
- this.firstChild = panels[0];
22525
- return;
22526
- }
22527
- if (this.children.length === 1 && this.children[0].isGroup) {
22528
- this.firstChild = this.children[0];
22529
- return;
22530
- }
22531
- const group = new Group6({ subcircuit: true });
22532
- group.parent = this;
22533
- group.addAll(this.children);
22534
- this.children = [group];
22535
- this.firstChild = group;
22536
- }
22537
- render() {
22538
- if (!this.firstChild) {
22539
- this._guessRootComponent();
22540
- }
22541
- const { firstChild, db } = this;
22542
- if (!firstChild) throw new Error("IsolatedCircuit has no root component");
22543
- firstChild.parent = this;
22544
- firstChild.runRenderCycle();
22545
- this._hasRenderedAtleastOnce = true;
22546
- }
22547
- async renderUntilSettled() {
22548
- const existing = this.db.source_project_metadata.list()?.[0];
22549
- if (!existing) {
22550
- this.db.source_project_metadata.insert({
22551
- software_used_string: `@tscircuit/core@${this.getCoreVersion()}`,
22552
- ...this.projectUrl ? { project_url: this.projectUrl } : {}
22553
- });
22554
- }
22555
- this.render();
22556
- while (this._hasIncompleteAsyncEffects()) {
22557
- await new Promise((resolve) => setTimeout(resolve, 100));
22558
- this.render();
22559
- }
22560
- this.emit("renderComplete");
22561
- }
22562
- _hasIncompleteAsyncEffects() {
22563
- if (this._asyncEffectPhaseById.size > 0) return true;
22564
- return this.children.some((child) => child._hasIncompleteAsyncEffects());
22565
- }
22566
- _hasIncompleteAsyncEffectsForPhase(phase) {
22567
- return (this._asyncEffectIdsByPhase.get(phase)?.size ?? 0) > 0;
22568
- }
22569
- getCircuitJson() {
22570
- if (!this._hasRenderedAtleastOnce) this.render();
22571
- return this.db.toArray();
22572
- }
22573
- toJson() {
22574
- return this.getCircuitJson();
22575
- }
22576
- async getSvg(options) {
22577
- const circuitToSvg = await import("circuit-to-svg").catch((e) => {
22578
- throw new Error(
22579
- `To use circuit.getSvg, you must install the "circuit-to-svg" package.
22580
-
22581
- "${e.message}"`
22582
- );
22583
- });
22584
- if (options.view === "pcb") {
22585
- return circuitToSvg.convertCircuitJsonToPcbSvg(this.getCircuitJson());
22586
- }
22587
- if (options.view === "schematic") {
22588
- return circuitToSvg.convertCircuitJsonToSchematicSvg(
22589
- this.getCircuitJson()
22590
- );
22591
- }
22592
- throw new Error(`Invalid view: ${options.view}`);
22593
- }
22594
- getCoreVersion() {
22595
- const [major, minor, patch] = package_default.version.split(".").map(Number);
22596
- return `${major}.${minor}.${patch + 1}`;
22597
- }
22598
- async preview(previewNameOrOpts) {
22599
- const previewOpts = typeof previewNameOrOpts === "object" ? previewNameOrOpts : { previewName: previewNameOrOpts };
22600
- throw new Error("project.preview is not yet implemented");
22601
- }
22602
- computeSchematicGlobalTransform() {
22603
- return identity5();
22604
- }
22605
- _computePcbGlobalTransformBeforeLayout() {
22606
- return identity5();
22607
- }
22608
- selectAll(selector) {
22609
- this._guessRootComponent();
22610
- return this.firstChild?.selectAll(selector) ?? [];
22611
- }
22612
- selectOne(selector, opts) {
22613
- this._guessRootComponent();
22614
- return this.firstChild?.selectOne(selector, opts) ?? null;
22615
- }
22616
- _eventListeners = {};
22617
- emit(event, ...args) {
22618
- if (event === "asyncEffect:start") {
22619
- this._registerAsyncEffectStart(args[0]);
22620
- } else if (event === "asyncEffect:end") {
22621
- this._registerAsyncEffectEnd(args[0]);
22622
- }
22623
- if (!this._eventListeners[event]) return;
22624
- for (const listener of this._eventListeners[event]) {
22625
- listener(...args);
22626
- }
22627
- }
22628
- on(event, listener) {
22629
- if (!this._eventListeners[event]) {
22630
- this._eventListeners[event] = [];
22631
- }
22632
- this._eventListeners[event].push(listener);
22633
- }
22634
- removeListener(event, listener) {
22635
- if (!this._eventListeners[event]) return;
22636
- this._eventListeners[event] = this._eventListeners[event].filter(
22637
- (l) => l !== listener
22638
- );
22639
- }
22640
- enableDebug(debug11) {
22641
- if (typeof debug11 === "string") {
22642
- Debug14.enable(debug11);
22643
- } else if (debug11 === null || debug11 === false) {
22644
- Debug14.disable();
22645
- }
22646
- }
22647
- getClientOrigin() {
22648
- if (typeof window !== "undefined" && window.location) {
22649
- return window.location.origin;
22650
- }
22651
- if (typeof self !== "undefined" && self.location) {
22652
- return self.location.origin;
22653
- }
22654
- return "";
22655
- }
22656
- _registerAsyncEffectStart(payload) {
22657
- if (!payload?.asyncEffectId || !payload.phase) return;
22658
- const { asyncEffectId, phase } = payload;
22659
- const existingPhase = this._asyncEffectPhaseById.get(asyncEffectId);
22660
- if (existingPhase && existingPhase !== phase) {
22661
- this._asyncEffectIdsByPhase.get(existingPhase)?.delete(asyncEffectId);
22662
- }
22663
- if (!this._asyncEffectIdsByPhase.has(phase)) {
22664
- this._asyncEffectIdsByPhase.set(phase, /* @__PURE__ */ new Set());
22665
- }
22666
- this._asyncEffectIdsByPhase.get(phase).add(asyncEffectId);
22667
- this._asyncEffectPhaseById.set(asyncEffectId, phase);
22668
- }
22669
- _registerAsyncEffectEnd(payload) {
22670
- if (!payload?.asyncEffectId) return;
22671
- const { asyncEffectId } = payload;
22672
- const phase = this._asyncEffectPhaseById.get(asyncEffectId) ?? payload.phase;
22673
- if (phase) {
22674
- const phaseSet = this._asyncEffectIdsByPhase.get(phase);
22675
- phaseSet?.delete(asyncEffectId);
22676
- if (phaseSet && phaseSet.size === 0) {
22677
- this._asyncEffectIdsByPhase.delete(phase);
22678
- }
22679
- }
22680
- this._asyncEffectPhaseById.delete(asyncEffectId);
22681
- }
22682
- };
22683
-
22684
22732
  // lib/RootCircuit.ts
22685
22733
  var RootCircuit = class extends IsolatedCircuit {
22686
- isRoot = true;
22734
+ isRootCircuit = true;
22687
22735
  constructor({
22688
22736
  platform,
22689
22737
  projectUrl
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1023",
4
+ "version": "0.0.1024",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",