@tscircuit/core 0.0.16 → 0.0.17
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 +761 -43
- package/dist/index.js +147 -16
- package/lib/Project.ts +29 -0
- package/lib/components/base-components/NormalComponent.ts +16 -0
- package/lib/components/base-components/PrimitiveComponent.ts +3 -0
- package/lib/components/index.ts +2 -0
- package/lib/components/normal-components/Chip.ts +0 -19
- package/lib/components/normal-components/Jumper.ts +101 -0
- package/lib/components/primitive-components/Port.ts +1 -0
- package/lib/components/primitive-components/SilkscreenPath.ts +35 -0
- package/lib/fiber/intrinsic-jsx.ts +1 -0
- package/lib/utils/createComponentsFromSoup.ts +9 -50
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ __export(components_exports, {
|
|
|
12
12
|
Chip: () => Chip,
|
|
13
13
|
Footprint: () => Footprint,
|
|
14
14
|
Group: () => Group,
|
|
15
|
+
Jumper: () => Jumper,
|
|
15
16
|
Led: () => Led,
|
|
16
17
|
Net: () => Net,
|
|
17
18
|
NormalComponent: () => NormalComponent,
|
|
@@ -19,6 +20,7 @@ __export(components_exports, {
|
|
|
19
20
|
PrimitiveComponent: () => PrimitiveComponent,
|
|
20
21
|
Renderable: () => Renderable,
|
|
21
22
|
Resistor: () => Resistor,
|
|
23
|
+
SilkscreenPath: () => SilkscreenPath,
|
|
22
24
|
SmtPad: () => SmtPad,
|
|
23
25
|
Trace: () => Trace,
|
|
24
26
|
TraceHint: () => TraceHint
|
|
@@ -167,6 +169,7 @@ var PrimitiveComponent = class extends Renderable {
|
|
|
167
169
|
_parsedProps;
|
|
168
170
|
componentName = "";
|
|
169
171
|
lowercaseComponentName = "";
|
|
172
|
+
externallyAddedAliases;
|
|
170
173
|
source_group_id = null;
|
|
171
174
|
source_component_id = null;
|
|
172
175
|
schematic_component_id = null;
|
|
@@ -177,6 +180,7 @@ var PrimitiveComponent = class extends Renderable {
|
|
|
177
180
|
this.children = [];
|
|
178
181
|
this.childrenPendingRemoval = [];
|
|
179
182
|
this.props = props ?? {};
|
|
183
|
+
this.externallyAddedAliases = [];
|
|
180
184
|
this._parsedProps = this.config.zodProps.parse(
|
|
181
185
|
props ?? {}
|
|
182
186
|
);
|
|
@@ -466,7 +470,8 @@ var Port = class extends PrimitiveComponent {
|
|
|
466
470
|
/* @__PURE__ */ new Set([
|
|
467
471
|
...props.aliases ?? [],
|
|
468
472
|
props.name,
|
|
469
|
-
...typeof props.pinNumber === "number" ? [`pin${props.pinNumber}`, props.pinNumber.toString()] : []
|
|
473
|
+
...typeof props.pinNumber === "number" ? [`pin${props.pinNumber}`, props.pinNumber.toString()] : [],
|
|
474
|
+
...this.externallyAddedAliases
|
|
470
475
|
])
|
|
471
476
|
);
|
|
472
477
|
}
|
|
@@ -796,6 +801,34 @@ var SmtPad = class extends PrimitiveComponent {
|
|
|
796
801
|
}
|
|
797
802
|
};
|
|
798
803
|
|
|
804
|
+
// lib/components/primitive-components/SilkscreenPath.ts
|
|
805
|
+
import { silkscreenPathProps } from "@tscircuit/props";
|
|
806
|
+
var SilkscreenPath = class extends PrimitiveComponent {
|
|
807
|
+
pcb_silkscreen_path_id = null;
|
|
808
|
+
get config() {
|
|
809
|
+
return {
|
|
810
|
+
zodProps: silkscreenPathProps
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
doInitialPcbPrimitiveRender() {
|
|
814
|
+
const { db } = this.project;
|
|
815
|
+
const { _parsedProps: props } = this;
|
|
816
|
+
const layer = props.layer ?? "top";
|
|
817
|
+
if (layer !== "top" && layer !== "bottom") {
|
|
818
|
+
throw new Error(
|
|
819
|
+
`Invalid layer "${layer}" for SilkscreenPath. Must be "top" or "bottom".`
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
const pcb_silkscreen_path = db.pcb_silkscreen_path.insert({
|
|
823
|
+
pcb_component_id: this.parent?.pcb_component_id,
|
|
824
|
+
layer,
|
|
825
|
+
route: props.route,
|
|
826
|
+
stroke_width: props.strokeWidth ?? 0.1
|
|
827
|
+
});
|
|
828
|
+
this.pcb_silkscreen_path_id = pcb_silkscreen_path.pcb_silkscreen_path_id;
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
|
|
799
832
|
// lib/utils/createComponentsFromSoup.ts
|
|
800
833
|
var createComponentsFromSoup = (soup) => {
|
|
801
834
|
const components = [];
|
|
@@ -823,6 +856,14 @@ var createComponentsFromSoup = (soup) => {
|
|
|
823
856
|
portHints: elm.port_hints
|
|
824
857
|
})
|
|
825
858
|
);
|
|
859
|
+
} else if (elm.type === "pcb_silkscreen_path") {
|
|
860
|
+
components.push(
|
|
861
|
+
new SilkscreenPath({
|
|
862
|
+
layer: elm.layer,
|
|
863
|
+
route: elm.route,
|
|
864
|
+
strokeWidth: elm.stroke_width
|
|
865
|
+
})
|
|
866
|
+
);
|
|
826
867
|
}
|
|
827
868
|
}
|
|
828
869
|
return components;
|
|
@@ -866,6 +907,20 @@ var NormalComponent = class extends PrimitiveComponent {
|
|
|
866
907
|
}
|
|
867
908
|
const portsFromFootprint = this.getPortsFromFootprint();
|
|
868
909
|
this.addAll(portsFromFootprint);
|
|
910
|
+
const pinLabels = this._parsedProps.pinLabels;
|
|
911
|
+
if (pinLabels) {
|
|
912
|
+
for (let [pinNumber, label] of Object.entries(pinLabels)) {
|
|
913
|
+
pinNumber = pinNumber.replace("pin", "");
|
|
914
|
+
const port = this.selectOne(`port[pinNumber='${pinNumber}']`);
|
|
915
|
+
if (!port) {
|
|
916
|
+
throw new Error(
|
|
917
|
+
`Could not find port for pin number ${pinNumber} in chip ${this.getString()}`
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
port.externallyAddedAliases.push(label);
|
|
921
|
+
port.props.name = label;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
869
924
|
}
|
|
870
925
|
_addChildrenFromStringFootprint() {
|
|
871
926
|
const { footprint } = this.props;
|
|
@@ -1902,27 +1957,81 @@ var Chip = class extends NormalComponent {
|
|
|
1902
1957
|
zodProps: chipProps
|
|
1903
1958
|
};
|
|
1904
1959
|
}
|
|
1905
|
-
|
|
1906
|
-
|
|
1960
|
+
doInitialSourceRender() {
|
|
1961
|
+
const { db } = this.project;
|
|
1907
1962
|
const { _parsedProps: props } = this;
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1963
|
+
const source_component = db.source_component.insert({
|
|
1964
|
+
ftype: "simple_chip",
|
|
1965
|
+
name: props.name,
|
|
1966
|
+
manufacturer_part_number: props.manufacturerPartNumber,
|
|
1967
|
+
supplier_part_numbers: props.supplierPartNumbers
|
|
1968
|
+
});
|
|
1969
|
+
this.source_component_id = source_component.source_component_id;
|
|
1970
|
+
}
|
|
1971
|
+
doInitialSchematicComponentRender() {
|
|
1972
|
+
const { db } = this.project;
|
|
1973
|
+
const { _parsedProps: props } = this;
|
|
1974
|
+
const ports = this.children.filter((child) => child instanceof Port);
|
|
1975
|
+
const pinSpacing = props.schPinSpacing ?? 0.2;
|
|
1976
|
+
const dimensions = getAllDimensionsForSchematicBox({
|
|
1977
|
+
schWidth: props.schWidth,
|
|
1978
|
+
schHeight: props.schHeight,
|
|
1979
|
+
schPinSpacing: pinSpacing,
|
|
1980
|
+
schPinStyle: props.schPinStyle,
|
|
1981
|
+
pinCount: ports.length,
|
|
1982
|
+
// @ts-ignore there's a subtley in the definition difference with
|
|
1983
|
+
// leftSide/rightSide/topSide/bottomSide in how the direction is defined
|
|
1984
|
+
// that doesn't really matter
|
|
1985
|
+
schPortArrangement: props.schPortArrangement
|
|
1986
|
+
});
|
|
1987
|
+
this.schematicDimensions = dimensions;
|
|
1988
|
+
const schematic_component2 = db.schematic_component.insert({
|
|
1989
|
+
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
1990
|
+
rotation: props.schRotation ?? 0,
|
|
1991
|
+
size: dimensions.getSize(),
|
|
1992
|
+
port_arrangement: underscorifyPortArrangement(
|
|
1993
|
+
props.schPortArrangement
|
|
1994
|
+
),
|
|
1995
|
+
pin_spacing: pinSpacing,
|
|
1996
|
+
// @ts-ignore soup needs to support distance for pin_styles
|
|
1997
|
+
pin_styles: underscorifyPinStyles(props.schPinStyle),
|
|
1998
|
+
port_labels: props.pinLabels,
|
|
1999
|
+
source_component_id: this.source_component_id
|
|
2000
|
+
});
|
|
2001
|
+
this.schematic_component_id = schematic_component2.schematic_component_id;
|
|
2002
|
+
}
|
|
2003
|
+
doInitialPcbComponentRender() {
|
|
2004
|
+
const { db } = this.project;
|
|
2005
|
+
const { _parsedProps: props } = this;
|
|
2006
|
+
const pcb_component = db.pcb_component.insert({
|
|
2007
|
+
center: { x: props.pcbX ?? 0, y: props.pcbY ?? 0 },
|
|
2008
|
+
width: 2,
|
|
2009
|
+
// Default width, adjust as needed
|
|
2010
|
+
height: 3,
|
|
2011
|
+
// Default height, adjust as needed
|
|
2012
|
+
layer: props.layer ?? "top",
|
|
2013
|
+
rotation: props.pcbRotation ?? 0,
|
|
2014
|
+
source_component_id: this.source_component_id
|
|
2015
|
+
});
|
|
2016
|
+
this.pcb_component_id = pcb_component.pcb_component_id;
|
|
2017
|
+
}
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
// lib/components/normal-components/Jumper.ts
|
|
2021
|
+
import { jumperProps } from "@tscircuit/props";
|
|
2022
|
+
var Jumper = class extends NormalComponent {
|
|
2023
|
+
schematicDimensions = null;
|
|
2024
|
+
get config() {
|
|
2025
|
+
return {
|
|
2026
|
+
zodProps: jumperProps
|
|
2027
|
+
};
|
|
1920
2028
|
}
|
|
1921
2029
|
doInitialSourceRender() {
|
|
1922
2030
|
const { db } = this.project;
|
|
1923
2031
|
const { _parsedProps: props } = this;
|
|
1924
2032
|
const source_component = db.source_component.insert({
|
|
1925
2033
|
ftype: "simple_chip",
|
|
2034
|
+
// TODO unknown or jumper
|
|
1926
2035
|
name: props.name,
|
|
1927
2036
|
manufacturer_part_number: props.manufacturerPartNumber,
|
|
1928
2037
|
supplier_part_numbers: props.supplierPartNumbers
|
|
@@ -1943,7 +2052,10 @@ var Chip = class extends NormalComponent {
|
|
|
1943
2052
|
// @ts-ignore there's a subtley in the definition difference with
|
|
1944
2053
|
// leftSide/rightSide/topSide/bottomSide in how the direction is defined
|
|
1945
2054
|
// that doesn't really matter
|
|
1946
|
-
schPortArrangement:
|
|
2055
|
+
schPortArrangement: {
|
|
2056
|
+
// TODO use schematic direction or schPortArrangement
|
|
2057
|
+
rightSize: ports.length
|
|
2058
|
+
}
|
|
1947
2059
|
});
|
|
1948
2060
|
this.schematicDimensions = dimensions;
|
|
1949
2061
|
const schematic_component2 = db.schematic_component.insert({
|
|
@@ -1986,6 +2098,7 @@ var Project = class {
|
|
|
1986
2098
|
rootComponent = null;
|
|
1987
2099
|
children;
|
|
1988
2100
|
db;
|
|
2101
|
+
_hasRenderedAtleastOnce = false;
|
|
1989
2102
|
constructor() {
|
|
1990
2103
|
this.children = [];
|
|
1991
2104
|
this.db = su([]);
|
|
@@ -2029,13 +2142,29 @@ var Project = class {
|
|
|
2029
2142
|
if (!rootComponent) throw new Error("Project has no root component");
|
|
2030
2143
|
rootComponent.setProject(this);
|
|
2031
2144
|
rootComponent.runRenderCycle();
|
|
2145
|
+
this._hasRenderedAtleastOnce = true;
|
|
2032
2146
|
}
|
|
2033
2147
|
getSoup() {
|
|
2148
|
+
if (!this._hasRenderedAtleastOnce) this.render();
|
|
2034
2149
|
return this.db.toArray();
|
|
2035
2150
|
}
|
|
2036
2151
|
getCircuitJson() {
|
|
2037
2152
|
return this.getSoup();
|
|
2038
2153
|
}
|
|
2154
|
+
async getSvg(options) {
|
|
2155
|
+
const circuitToSvg = await import("circuit-to-svg").catch((e) => {
|
|
2156
|
+
throw new Error(
|
|
2157
|
+
`To use project.getSvg, you must install the "circuit-to-svg" package.
|
|
2158
|
+
|
|
2159
|
+
"${e.message}"`
|
|
2160
|
+
);
|
|
2161
|
+
});
|
|
2162
|
+
return circuitToSvg.circuitJsonToPcbSvg(this.getSoup());
|
|
2163
|
+
}
|
|
2164
|
+
async preview(previewNameOrOpts) {
|
|
2165
|
+
const previewOpts = typeof previewNameOrOpts === "object" ? previewNameOrOpts : { previewName: previewNameOrOpts };
|
|
2166
|
+
throw new Error("project.preview is not yet implemented");
|
|
2167
|
+
}
|
|
2039
2168
|
computeGlobalSchematicTransform() {
|
|
2040
2169
|
return identity5();
|
|
2041
2170
|
}
|
|
@@ -2061,6 +2190,7 @@ export {
|
|
|
2061
2190
|
Chip,
|
|
2062
2191
|
Footprint,
|
|
2063
2192
|
Group,
|
|
2193
|
+
Jumper,
|
|
2064
2194
|
Led,
|
|
2065
2195
|
Net,
|
|
2066
2196
|
NormalComponent,
|
|
@@ -2069,6 +2199,7 @@ export {
|
|
|
2069
2199
|
Project,
|
|
2070
2200
|
Renderable,
|
|
2071
2201
|
Resistor,
|
|
2202
|
+
SilkscreenPath,
|
|
2072
2203
|
SmtPad,
|
|
2073
2204
|
Trace,
|
|
2074
2205
|
TraceHint
|
package/lib/Project.ts
CHANGED
|
@@ -11,6 +11,8 @@ export class Project {
|
|
|
11
11
|
children: PrimitiveComponent[]
|
|
12
12
|
db: SoupUtilObjects
|
|
13
13
|
|
|
14
|
+
_hasRenderedAtleastOnce = false
|
|
15
|
+
|
|
14
16
|
constructor() {
|
|
15
17
|
this.children = []
|
|
16
18
|
this.db = su([])
|
|
@@ -64,9 +66,11 @@ export class Project {
|
|
|
64
66
|
rootComponent.setProject(this)
|
|
65
67
|
|
|
66
68
|
rootComponent.runRenderCycle()
|
|
69
|
+
this._hasRenderedAtleastOnce = true
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
getSoup(): AnySoupElement[] {
|
|
73
|
+
if (!this._hasRenderedAtleastOnce) this.render()
|
|
70
74
|
return this.db.toArray()
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -74,6 +78,31 @@ export class Project {
|
|
|
74
78
|
return this.getSoup()
|
|
75
79
|
}
|
|
76
80
|
|
|
81
|
+
async getSvg(options: { view: "pcb"; layer?: string }): Promise<string> {
|
|
82
|
+
const circuitToSvg = await import("circuit-to-svg").catch((e) => {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`To use project.getSvg, you must install the "circuit-to-svg" package.\n\n"${e.message}"`,
|
|
85
|
+
)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
return circuitToSvg.circuitJsonToPcbSvg(this.getSoup())
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async preview(
|
|
92
|
+
previewNameOrOpts:
|
|
93
|
+
| string
|
|
94
|
+
| {
|
|
95
|
+
previewName: string
|
|
96
|
+
tscircuitApiKey?: string
|
|
97
|
+
},
|
|
98
|
+
) {
|
|
99
|
+
const previewOpts =
|
|
100
|
+
typeof previewNameOrOpts === "object"
|
|
101
|
+
? previewNameOrOpts
|
|
102
|
+
: { previewName: previewNameOrOpts }
|
|
103
|
+
throw new Error("project.preview is not yet implemented")
|
|
104
|
+
}
|
|
105
|
+
|
|
77
106
|
computeGlobalSchematicTransform(): Matrix {
|
|
78
107
|
return identity()
|
|
79
108
|
}
|
|
@@ -87,6 +87,22 @@ export class NormalComponent<
|
|
|
87
87
|
const portsFromFootprint = this.getPortsFromFootprint()
|
|
88
88
|
|
|
89
89
|
this.addAll(portsFromFootprint)
|
|
90
|
+
|
|
91
|
+
const pinLabels: Record<string, string> | undefined =
|
|
92
|
+
this._parsedProps.pinLabels
|
|
93
|
+
if (pinLabels) {
|
|
94
|
+
for (let [pinNumber, label] of Object.entries(pinLabels)) {
|
|
95
|
+
pinNumber = pinNumber.replace("pin", "")
|
|
96
|
+
const port = this.selectOne(`port[pinNumber='${pinNumber}']`)
|
|
97
|
+
if (!port) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`Could not find port for pin number ${pinNumber} in chip ${this.getString()}`,
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
port.externallyAddedAliases.push(label)
|
|
103
|
+
port.props.name = label
|
|
104
|
+
}
|
|
105
|
+
}
|
|
90
106
|
}
|
|
91
107
|
|
|
92
108
|
_addChildrenFromStringFootprint() {
|
|
@@ -46,6 +46,8 @@ export abstract class PrimitiveComponent<
|
|
|
46
46
|
componentName = ""
|
|
47
47
|
lowercaseComponentName = ""
|
|
48
48
|
|
|
49
|
+
externallyAddedAliases: string[]
|
|
50
|
+
|
|
49
51
|
source_group_id: string | null = null
|
|
50
52
|
source_component_id: string | null = null
|
|
51
53
|
schematic_component_id: string | null = null
|
|
@@ -57,6 +59,7 @@ export abstract class PrimitiveComponent<
|
|
|
57
59
|
this.children = []
|
|
58
60
|
this.childrenPendingRemoval = []
|
|
59
61
|
this.props = props ?? {}
|
|
62
|
+
this.externallyAddedAliases = []
|
|
60
63
|
this._parsedProps = this.config.zodProps.parse(
|
|
61
64
|
props ?? {},
|
|
62
65
|
) as z.infer<ZodProps>
|
package/lib/components/index.ts
CHANGED
|
@@ -13,3 +13,5 @@ export { Trace } from "./primitive-components/Trace"
|
|
|
13
13
|
export { TraceHint } from "./primitive-components/TraceHint"
|
|
14
14
|
export { Group } from "./primitive-components/Group"
|
|
15
15
|
export { Chip } from "./normal-components/Chip"
|
|
16
|
+
export { Jumper } from "./normal-components/Jumper"
|
|
17
|
+
export { SilkscreenPath } from "./primitive-components/SilkscreenPath"
|
|
@@ -21,25 +21,6 @@ export class Chip<PinLabels extends string = never> extends NormalComponent<
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
initPorts() {
|
|
25
|
-
super.initPorts()
|
|
26
|
-
|
|
27
|
-
const { _parsedProps: props } = this
|
|
28
|
-
|
|
29
|
-
if (props.pinLabels) {
|
|
30
|
-
for (const [pinNumber, label] of Object.entries(props.pinLabels)) {
|
|
31
|
-
const port = this.selectOne(`port[pinNumber='${pinNumber}']`)
|
|
32
|
-
if (!port) {
|
|
33
|
-
throw new Error(
|
|
34
|
-
`Could not find port for pin number ${pinNumber} in chip ${this.getString()}`,
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
port.props.aliases.push(port.props.name)
|
|
38
|
-
port.props.name = label
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
24
|
doInitialSourceRender(): void {
|
|
44
25
|
const { db } = this.project!
|
|
45
26
|
const { _parsedProps: props } = this
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { NormalComponent } from "lib/components/base-components/NormalComponent"
|
|
2
|
+
import { jumperProps } from "@tscircuit/props"
|
|
3
|
+
import { Port } from "../primitive-components/Port"
|
|
4
|
+
import type { BaseSymbolName } from "lib/utils/constants"
|
|
5
|
+
import {
|
|
6
|
+
getAllDimensionsForSchematicBox,
|
|
7
|
+
type SchematicBoxDimensions,
|
|
8
|
+
} from "lib/utils/schematic/getAllDimensionsForSchematicBox"
|
|
9
|
+
import { underscorifyPortArrangement } from "lib/soup/underscorifyPortArrangement"
|
|
10
|
+
import { underscorifyPinStyles } from "lib/soup/underscorifyPinStyles"
|
|
11
|
+
|
|
12
|
+
export class Jumper<PinLabels extends string = never> extends NormalComponent<
|
|
13
|
+
typeof jumperProps,
|
|
14
|
+
PinLabels
|
|
15
|
+
> {
|
|
16
|
+
schematicDimensions: SchematicBoxDimensions | null = null
|
|
17
|
+
|
|
18
|
+
get config() {
|
|
19
|
+
return {
|
|
20
|
+
zodProps: jumperProps,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
doInitialSourceRender(): void {
|
|
25
|
+
const { db } = this.project!
|
|
26
|
+
const { _parsedProps: props } = this
|
|
27
|
+
|
|
28
|
+
const source_component = db.source_component.insert({
|
|
29
|
+
ftype: "simple_chip", // TODO unknown or jumper
|
|
30
|
+
name: props.name,
|
|
31
|
+
manufacturer_part_number: props.manufacturerPartNumber,
|
|
32
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
this.source_component_id = source_component.source_component_id!
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
doInitialSchematicComponentRender() {
|
|
39
|
+
const { db } = this.project!
|
|
40
|
+
const { _parsedProps: props } = this
|
|
41
|
+
|
|
42
|
+
const ports = this.children.filter((child) => child instanceof Port)
|
|
43
|
+
|
|
44
|
+
const pinSpacing = props.schPinSpacing ?? 0.2
|
|
45
|
+
|
|
46
|
+
const dimensions = getAllDimensionsForSchematicBox({
|
|
47
|
+
schWidth: props.schWidth,
|
|
48
|
+
schHeight: props.schHeight,
|
|
49
|
+
schPinSpacing: pinSpacing,
|
|
50
|
+
schPinStyle: props.schPinStyle,
|
|
51
|
+
|
|
52
|
+
pinCount: ports.length,
|
|
53
|
+
|
|
54
|
+
// @ts-ignore there's a subtley in the definition difference with
|
|
55
|
+
// leftSide/rightSide/topSide/bottomSide in how the direction is defined
|
|
56
|
+
// that doesn't really matter
|
|
57
|
+
schPortArrangement: {
|
|
58
|
+
// TODO use schematic direction or schPortArrangement
|
|
59
|
+
rightSize: ports.length,
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
this.schematicDimensions = dimensions
|
|
63
|
+
|
|
64
|
+
const schematic_component = db.schematic_component.insert({
|
|
65
|
+
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
66
|
+
rotation: props.schRotation ?? 0,
|
|
67
|
+
size: dimensions.getSize(),
|
|
68
|
+
|
|
69
|
+
port_arrangement: underscorifyPortArrangement(
|
|
70
|
+
props.schPortArrangement as any,
|
|
71
|
+
),
|
|
72
|
+
|
|
73
|
+
pin_spacing: pinSpacing,
|
|
74
|
+
|
|
75
|
+
// @ts-ignore soup needs to support distance for pin_styles
|
|
76
|
+
pin_styles: underscorifyPinStyles(props.schPinStyle),
|
|
77
|
+
|
|
78
|
+
port_labels: props.pinLabels,
|
|
79
|
+
|
|
80
|
+
source_component_id: this.source_component_id!,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
this.schematic_component_id = schematic_component.schematic_component_id
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
doInitialPcbComponentRender() {
|
|
87
|
+
const { db } = this.project!
|
|
88
|
+
const { _parsedProps: props } = this
|
|
89
|
+
|
|
90
|
+
const pcb_component = db.pcb_component.insert({
|
|
91
|
+
center: { x: props.pcbX ?? 0, y: props.pcbY ?? 0 },
|
|
92
|
+
width: 2, // Default width, adjust as needed
|
|
93
|
+
height: 3, // Default height, adjust as needed
|
|
94
|
+
layer: props.layer ?? "top",
|
|
95
|
+
rotation: props.pcbRotation ?? 0,
|
|
96
|
+
source_component_id: this.source_component_id!,
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
this.pcb_component_id = pcb_component.pcb_component_id
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { silkscreenPathProps } from "@tscircuit/props"
|
|
2
|
+
import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
|
|
3
|
+
|
|
4
|
+
export class SilkscreenPath extends PrimitiveComponent<
|
|
5
|
+
typeof silkscreenPathProps
|
|
6
|
+
> {
|
|
7
|
+
pcb_silkscreen_path_id: string | null = null
|
|
8
|
+
|
|
9
|
+
get config() {
|
|
10
|
+
return {
|
|
11
|
+
zodProps: silkscreenPathProps,
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
doInitialPcbPrimitiveRender(): void {
|
|
16
|
+
const { db } = this.project!
|
|
17
|
+
const { _parsedProps: props } = this
|
|
18
|
+
|
|
19
|
+
const layer = props.layer ?? "top"
|
|
20
|
+
if (layer !== "top" && layer !== "bottom") {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`Invalid layer "${layer}" for SilkscreenPath. Must be "top" or "bottom".`,
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const pcb_silkscreen_path = db.pcb_silkscreen_path.insert({
|
|
27
|
+
pcb_component_id: this.parent?.pcb_component_id!,
|
|
28
|
+
layer,
|
|
29
|
+
route: props.route,
|
|
30
|
+
stroke_width: props.strokeWidth ?? 0.1,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
this.pcb_silkscreen_path_id = pcb_silkscreen_path.pcb_silkscreen_path_id
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AnySoupElement } from "@tscircuit/soup"
|
|
2
2
|
import type { PrimitiveComponent } from "../components/base-components/PrimitiveComponent"
|
|
3
3
|
import { SmtPad } from "lib/components/primitive-components/SmtPad"
|
|
4
|
+
import { SilkscreenPath } from "lib/components/primitive-components/SilkscreenPath"
|
|
4
5
|
|
|
5
6
|
export const createComponentsFromSoup = (
|
|
6
7
|
soup: AnySoupElement[],
|
|
@@ -30,57 +31,15 @@ export const createComponentsFromSoup = (
|
|
|
30
31
|
portHints: elm.port_hints,
|
|
31
32
|
}),
|
|
32
33
|
)
|
|
34
|
+
} else if (elm.type === "pcb_silkscreen_path") {
|
|
35
|
+
components.push(
|
|
36
|
+
new SilkscreenPath({
|
|
37
|
+
layer: elm.layer,
|
|
38
|
+
route: elm.route,
|
|
39
|
+
strokeWidth: elm.stroke_width,
|
|
40
|
+
}),
|
|
41
|
+
)
|
|
33
42
|
}
|
|
34
43
|
}
|
|
35
44
|
return components
|
|
36
|
-
// if (elm.type === "pcb_smtpad") {
|
|
37
|
-
// this.add("smtpad", (pb) => pb.setProps(elm))
|
|
38
|
-
// } else if (elm.type === "pcb_plated_hole") {
|
|
39
|
-
// this.add("platedhole", (pb) => pb.setProps(elm))
|
|
40
|
-
// } else if (elm.type === "pcb_hole") {
|
|
41
|
-
// this.add("hole", (pb) => pb.setProps(elm))
|
|
42
|
-
// } else if (elm.type === "pcb_silkscreen_circle") {
|
|
43
|
-
// this.add("silkscreencircle", (pb) =>
|
|
44
|
-
// pb.setProps({
|
|
45
|
-
// ...elm,
|
|
46
|
-
// pcbX: elm.center.x,
|
|
47
|
-
// pcbY: elm.center.y,
|
|
48
|
-
// })
|
|
49
|
-
// )
|
|
50
|
-
// } else if (elm.type === "pcb_silkscreen_line") {
|
|
51
|
-
// this.add("silkscreenline", (pb) =>
|
|
52
|
-
// pb.setProps({
|
|
53
|
-
// ...elm,
|
|
54
|
-
// strokeWidth: elm.stroke_width,
|
|
55
|
-
// })
|
|
56
|
-
// )
|
|
57
|
-
// } else if (elm.type === "pcb_silkscreen_path") {
|
|
58
|
-
// this.add("silkscreenpath", (pb) =>
|
|
59
|
-
// pb.setProps({
|
|
60
|
-
// ...elm,
|
|
61
|
-
// strokeWidth: elm.stroke_width,
|
|
62
|
-
// })
|
|
63
|
-
// )
|
|
64
|
-
// } else if (elm.type === "pcb_silkscreen_rect") {
|
|
65
|
-
// this.add("silkscreenrect", (pb) =>
|
|
66
|
-
// pb.setProps({
|
|
67
|
-
// ...elm,
|
|
68
|
-
// pcbX: elm.center.x,
|
|
69
|
-
// pcbY: elm.center.y,
|
|
70
|
-
// // TODO silkscreen rect isFilled, isOutline etc.
|
|
71
|
-
// })
|
|
72
|
-
// )
|
|
73
|
-
// } else if (elm.type === "pcb_fabrication_note_path") {
|
|
74
|
-
// this.add("fabricationnotepath", (pb) => pb.setProps(elm))
|
|
75
|
-
// } else if (elm.type === "pcb_fabrication_note_text") {
|
|
76
|
-
// this.add("fabricationnotetext", (pb) =>
|
|
77
|
-
// pb.setProps({
|
|
78
|
-
// ...elm,
|
|
79
|
-
// pcbX: elm.anchor_position.x,
|
|
80
|
-
// pcbY: elm.anchor_position.y,
|
|
81
|
-
// anchorAlignment: elm.anchor_alignment,
|
|
82
|
-
// fontSize: elm.font_size,
|
|
83
|
-
// })
|
|
84
|
-
// )
|
|
85
|
-
// }
|
|
86
45
|
}
|
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.
|
|
5
|
+
"version": "0.0.17",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"files": [
|
|
@@ -16,11 +16,13 @@
|
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@biomejs/biome": "^1.8.3",
|
|
19
|
+
"@tscircuit/layout": "^0.0.27",
|
|
19
20
|
"@tscircuit/log-soup": "^1.0.2",
|
|
20
21
|
"@types/bun": "latest",
|
|
21
22
|
"@types/react": "^18.3.3",
|
|
22
23
|
"@types/react-reconciler": "^0.28.8",
|
|
23
|
-
"
|
|
24
|
+
"bun-match-svg": "0.0.2",
|
|
25
|
+
"circuit-to-svg": "^0.0.13",
|
|
24
26
|
"howfat": "^0.3.8",
|
|
25
27
|
"looks-same": "^9.0.1",
|
|
26
28
|
"tsup": "^8.2.4"
|
|
@@ -30,7 +32,7 @@
|
|
|
30
32
|
},
|
|
31
33
|
"dependencies": {
|
|
32
34
|
"@tscircuit/infgrid-ijump-astar": "0.0.5",
|
|
33
|
-
"@tscircuit/props": "^0.0.
|
|
35
|
+
"@tscircuit/props": "^0.0.49",
|
|
34
36
|
"@tscircuit/soup": "^0.0.58",
|
|
35
37
|
"@tscircuit/soup-util": "0.0.18",
|
|
36
38
|
"footprinter": "^0.0.44",
|