@tscircuit/props 0.0.696 → 0.0.698
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/README.md +164 -112
- package/dist/index.d.ts +488 -47
- package/dist/index.js +1445 -1327
- package/dist/index.js.map +1 -1
- package/lib/assembly/index.ts +3 -0
- package/lib/assembly/part.ts +4 -0
- package/lib/assembly/printedpart.ts +10 -1
- package/lib/assembly/referencesurface.ts +80 -0
- package/lib/components/pcb-return-current-excitation.ts +110 -0
- package/lib/components/pcb-return-current-simulation.ts +25 -0
- package/lib/index.ts +1 -0
- package/lib/simulation/index.ts +10 -0
- package/package.json +1 -1
package/lib/assembly/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { assemblyCadAssemblyProps } from "./cadassembly"
|
|
|
2
2
|
import { assemblyCableProps } from "./cable"
|
|
3
3
|
import { assemblyDeviceProps } from "./device"
|
|
4
4
|
import { assemblyPartProps } from "./part"
|
|
5
|
+
import { assemblyReferenceSurfaceProps } from "./referencesurface"
|
|
5
6
|
import { assemblyPrintedPartProps } from "./printedpart"
|
|
6
7
|
import { assemblyMotorProps } from "./motor"
|
|
7
8
|
import { assemblyScreenProps } from "./screen"
|
|
@@ -12,6 +13,7 @@ export * from "./cable"
|
|
|
12
13
|
export * from "./device"
|
|
13
14
|
export * from "./motor"
|
|
14
15
|
export * from "./part"
|
|
16
|
+
export * from "./referencesurface"
|
|
15
17
|
export * from "./printedpart"
|
|
16
18
|
export * from "./screen"
|
|
17
19
|
export * from "./subassembly"
|
|
@@ -22,6 +24,7 @@ export const assemblyProps = {
|
|
|
22
24
|
device: assemblyDeviceProps,
|
|
23
25
|
motor: assemblyMotorProps,
|
|
24
26
|
part: assemblyPartProps,
|
|
27
|
+
referencesurface: assemblyReferenceSurfaceProps,
|
|
25
28
|
printedpart: assemblyPrintedPartProps,
|
|
26
29
|
screen: assemblyScreenProps,
|
|
27
30
|
subassembly: assemblySubassemblyProps,
|
package/lib/assembly/part.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type CadModelProp, cadModelProp } from "lib/common/cadModel"
|
|
|
2
2
|
import { url } from "lib/common/url"
|
|
3
3
|
import { expectTypesMatch } from "lib/typecheck"
|
|
4
4
|
import { z } from "zod"
|
|
5
|
+
import type { ReactNode } from "react"
|
|
5
6
|
|
|
6
7
|
/** A generic component of an assembly, with optional CAD geometry. */
|
|
7
8
|
export interface AssemblyPartProps {
|
|
@@ -15,6 +16,8 @@ export interface AssemblyPartProps {
|
|
|
15
16
|
modelUrl?: string
|
|
16
17
|
/** Existing component CAD model formats; mutually exclusive with model and modelUrl. */
|
|
17
18
|
cadModel?: CadModelProp
|
|
19
|
+
/** Reference surfaces defining named mounting frames for this part. */
|
|
20
|
+
children?: ReactNode
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
export const assemblyPartProps = z
|
|
@@ -26,6 +29,7 @@ export const assemblyPartProps = z
|
|
|
26
29
|
.refine((value) => value.trim().length > 0, "modelUrl cannot be empty")
|
|
27
30
|
.optional(),
|
|
28
31
|
cadModel: cadModelProp.optional(),
|
|
32
|
+
children: z.custom<ReactNode>().optional(),
|
|
29
33
|
})
|
|
30
34
|
.refine(
|
|
31
35
|
(part) =>
|
|
@@ -2,7 +2,7 @@ import { type CadModelProp, cadModelProp } from "lib/common/cadModel"
|
|
|
2
2
|
import { url } from "lib/common/url"
|
|
3
3
|
import { distance, type Distance } from "lib/common/distance"
|
|
4
4
|
import { expectTypesMatch } from "lib/typecheck"
|
|
5
|
-
import { isValidElement, type ReactElement } from "react"
|
|
5
|
+
import { isValidElement, type ReactElement, type ReactNode } from "react"
|
|
6
6
|
import { z } from "zod"
|
|
7
7
|
|
|
8
8
|
/** Provide exactly one of jscad, model, modelUrl, or cadModel. */
|
|
@@ -10,6 +10,12 @@ export interface AssemblyPrintedPartProps {
|
|
|
10
10
|
/** Stable identity used by assembly mounting selectors. */
|
|
11
11
|
name: string
|
|
12
12
|
displayName?: string
|
|
13
|
+
/** Color for the rendered printed part. Omit to retain authored materials. */
|
|
14
|
+
color?: string
|
|
15
|
+
/** Printable material classification; omitted when unspecified. */
|
|
16
|
+
material?: "pla" | "petg" | "nylon"
|
|
17
|
+
/** Reference surfaces defining named mounting frames, alongside CAD children. */
|
|
18
|
+
children?: ReactNode
|
|
13
19
|
/** Pure jscad-fiber JSX in right-handed local XYZ, dimensions in millimeters.
|
|
14
20
|
* Named reference rectangles define attachment faces; they add no material.
|
|
15
21
|
* Hooks, async components, and raw kernel geometry are not supported.
|
|
@@ -36,6 +42,9 @@ export const assemblyPrintedPartProps = z
|
|
|
36
42
|
.object({
|
|
37
43
|
name: z.string().trim().min(1),
|
|
38
44
|
displayName: z.string().optional(),
|
|
45
|
+
color: z.string().trim().min(1).optional(),
|
|
46
|
+
material: z.enum(["pla", "petg", "nylon"]).optional(),
|
|
47
|
+
children: z.custom<ReactNode>().optional(),
|
|
39
48
|
jscad: z
|
|
40
49
|
.custom<ReactElement>(isValidElement, "Expected jscad-fiber JSX")
|
|
41
50
|
.optional(),
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type Distance, distance } from "lib/common/distance"
|
|
2
|
+
import { expectTypesMatch } from "lib/typecheck"
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
|
|
5
|
+
/** A named, non-solid mounting frame in the owning part's local, right-handed
|
|
6
|
+
* XYZ (mm). Offsets locate its origin; its normal and tangent are directions.
|
|
7
|
+
*/
|
|
8
|
+
export interface AssemblyReferenceSurfaceProps {
|
|
9
|
+
/** Unique within the part; defaults to "anchor". Use PART.name to mount to it. */
|
|
10
|
+
name?: string
|
|
11
|
+
/** Reference shape; defaults to rect. Does not create solid geometry. */
|
|
12
|
+
shape?: "rect"
|
|
13
|
+
/** Defaults to xy. Positive normals: xy +Z, xz +Y, yz +X. */
|
|
14
|
+
plane?: "xy" | "xz" | "yz"
|
|
15
|
+
/** Outward normal, perpendicular to plane. Defaults: xy z+, xz y+, yz x+.
|
|
16
|
+
* Reversing the normal retains the local X tangent. Replaces positive/negative.
|
|
17
|
+
*/
|
|
18
|
+
normalDirection?: "x+" | "x-" | "y+" | "y-" | "z+" | "z-"
|
|
19
|
+
/** Surface center offsets from the part origin, in mm or unit strings; each defaults to zero. */
|
|
20
|
+
centerXOffset?: Distance
|
|
21
|
+
centerYOffset?: Distance
|
|
22
|
+
centerZOffset?: Distance
|
|
23
|
+
/** Optional rectangular extents along the tangent and its perpendicular.
|
|
24
|
+
* Supply width and height together. Mounting uses the center, not the edges.
|
|
25
|
+
*/
|
|
26
|
+
width?: Distance
|
|
27
|
+
height?: Distance
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const offset = distance.pipe(z.number().finite())
|
|
31
|
+
const extent = distance.pipe(z.number().positive().finite())
|
|
32
|
+
|
|
33
|
+
export const assemblyReferenceSurfaceProps = z
|
|
34
|
+
.object({
|
|
35
|
+
name: z.string().trim().min(1).default("anchor"),
|
|
36
|
+
shape: z.literal("rect").default("rect"),
|
|
37
|
+
plane: z.enum(["xy", "xz", "yz"]).default("xy"),
|
|
38
|
+
normalDirection: z.enum(["x+", "x-", "y+", "y-", "z+", "z-"]).optional(),
|
|
39
|
+
centerXOffset: offset.default(0),
|
|
40
|
+
centerYOffset: offset.default(0),
|
|
41
|
+
centerZOffset: offset.default(0),
|
|
42
|
+
width: extent.optional(),
|
|
43
|
+
height: extent.optional(),
|
|
44
|
+
})
|
|
45
|
+
.refine(
|
|
46
|
+
(surface) =>
|
|
47
|
+
(surface.width === undefined) === (surface.height === undefined),
|
|
48
|
+
{
|
|
49
|
+
message: "Provide width and height together",
|
|
50
|
+
path: ["width"],
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
.superRefine((surface, ctx) => {
|
|
54
|
+
const normalAxis =
|
|
55
|
+
surface.plane === "xy" ? "z" : surface.plane === "xz" ? "y" : "x"
|
|
56
|
+
if (surface.normalDirection && surface.normalDirection[0] !== normalAxis)
|
|
57
|
+
ctx.addIssue({
|
|
58
|
+
code: z.ZodIssueCode.custom,
|
|
59
|
+
path: ["normalDirection"],
|
|
60
|
+
message: `normalDirection must be ${normalAxis}+ or ${normalAxis}- for plane ${surface.plane}`,
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
.transform((surface) => ({
|
|
64
|
+
...surface,
|
|
65
|
+
normalDirection:
|
|
66
|
+
surface.normalDirection ??
|
|
67
|
+
(surface.plane === "xy"
|
|
68
|
+
? ("z+" as const)
|
|
69
|
+
: surface.plane === "xz"
|
|
70
|
+
? ("y+" as const)
|
|
71
|
+
: ("x+" as const)),
|
|
72
|
+
}))
|
|
73
|
+
|
|
74
|
+
export type AssemblyReferenceSurfacePropsInput = z.input<
|
|
75
|
+
typeof assemblyReferenceSurfaceProps
|
|
76
|
+
>
|
|
77
|
+
expectTypesMatch<
|
|
78
|
+
AssemblyReferenceSurfaceProps,
|
|
79
|
+
AssemblyReferenceSurfacePropsInput
|
|
80
|
+
>(true)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { layer_ref, type LayerRefInput } from "circuit-json"
|
|
2
|
+
import { expectTypesMatch } from "lib/typecheck"
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
|
|
5
|
+
/** A signal driver/load pair and its explicit ground return terminals.
|
|
6
|
+
* Selectors resolve inside the containing board/subcircuit. The initial core
|
|
7
|
+
* implementation accepts physical PCB ports/pads, not standalone via contacts.
|
|
8
|
+
* This definition neither connects the selected pins nor runs a simulation.
|
|
9
|
+
*/
|
|
10
|
+
export interface PcbReturnCurrentExcitationProps {
|
|
11
|
+
/** Readable excitation name for diagnostics; not stored on its Circuit JSON record. */
|
|
12
|
+
name?: string
|
|
13
|
+
/** Signal driver port selector, e.g. ".U1 > .OUT". */
|
|
14
|
+
source: string
|
|
15
|
+
/** Signal receiving port selector, e.g. ".U2 > .IN". */
|
|
16
|
+
load: string
|
|
17
|
+
/** Ground net selector, e.g. "net.GND"; its copper and connections must already exist. */
|
|
18
|
+
ground: string
|
|
19
|
+
/** Positive in-phase peak signal current. Numbers are amperes, not RMS; strings use ampere units. */
|
|
20
|
+
current: number | string
|
|
21
|
+
/** Load-side GND port where positive return current enters the return conductor. */
|
|
22
|
+
returnSource: string
|
|
23
|
+
/** Driver-side GND port where positive return current leaves the return conductor. */
|
|
24
|
+
returnSink: string
|
|
25
|
+
/** Positive real source-port resistance. Numbers are ohms; complex impedances are unsupported. */
|
|
26
|
+
sourceImpedance: number | string
|
|
27
|
+
/** Positive real load-port resistance. Numbers are ohms; complex impedances are unsupported. */
|
|
28
|
+
loadImpedance: number | string
|
|
29
|
+
/** Optional trace selector to disambiguate multiple routes between the signal ports. */
|
|
30
|
+
trace?: string
|
|
31
|
+
/** Contact layer for a load-side PCB port spanning multiple copper layers. */
|
|
32
|
+
returnSourceLayer?: LayerRefInput
|
|
33
|
+
/** Contact layer for a driver-side PCB port spanning multiple copper layers. */
|
|
34
|
+
returnSinkLayer?: LayerRefInput
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const selector = z.string().trim().min(1, "Provide a nonempty selector")
|
|
38
|
+
const quantity = "[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?"
|
|
39
|
+
const prefixScale: Record<string, number> = {
|
|
40
|
+
"": 1,
|
|
41
|
+
y: 1e-24,
|
|
42
|
+
z: 1e-21,
|
|
43
|
+
a: 1e-18,
|
|
44
|
+
f: 1e-15,
|
|
45
|
+
p: 1e-12,
|
|
46
|
+
n: 1e-9,
|
|
47
|
+
u: 1e-6,
|
|
48
|
+
µ: 1e-6,
|
|
49
|
+
μ: 1e-6,
|
|
50
|
+
m: 1e-3,
|
|
51
|
+
k: 1e3,
|
|
52
|
+
M: 1e6,
|
|
53
|
+
G: 1e9,
|
|
54
|
+
T: 1e12,
|
|
55
|
+
P: 1e15,
|
|
56
|
+
E: 1e18,
|
|
57
|
+
Z: 1e21,
|
|
58
|
+
Y: 1e24,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Full-string parsing preserves scientific notation and rejects other
|
|
62
|
+
// dimensions. The generic Circuit JSON converters currently do neither.
|
|
63
|
+
function positiveQuantity(unit: string, label: string, example: string) {
|
|
64
|
+
const pattern = new RegExp(
|
|
65
|
+
`^(${quantity})\\s*(?:([yzafpnumkMGTPEZYµμ]?)(?:${unit}))?$`,
|
|
66
|
+
)
|
|
67
|
+
return z
|
|
68
|
+
.union([
|
|
69
|
+
z.number(),
|
|
70
|
+
z
|
|
71
|
+
.string()
|
|
72
|
+
.trim()
|
|
73
|
+
.regex(pattern, `Use ${label} or a unit string, e.g. ${example}`),
|
|
74
|
+
])
|
|
75
|
+
.transform((value) => {
|
|
76
|
+
if (typeof value === "number") return value
|
|
77
|
+
const match = pattern.exec(value)!
|
|
78
|
+
return Number(match[1]) * prefixScale[match[2] ?? ""]!
|
|
79
|
+
})
|
|
80
|
+
.pipe(z.number().finite().positive(`${label} must be greater than zero`))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const positiveCurrent = positiveQuantity("A", "peak amperes", "5mA")
|
|
84
|
+
const positiveResistance = positiveQuantity(
|
|
85
|
+
"ohms?|Ohms?|Ω",
|
|
86
|
+
"real ohms",
|
|
87
|
+
"100ohm",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
export const pcbReturnCurrentExcitationProps = z
|
|
91
|
+
.object({
|
|
92
|
+
name: z.string().trim().min(1).optional(),
|
|
93
|
+
source: selector,
|
|
94
|
+
load: selector,
|
|
95
|
+
ground: selector,
|
|
96
|
+
current: positiveCurrent,
|
|
97
|
+
returnSource: selector,
|
|
98
|
+
returnSink: selector,
|
|
99
|
+
sourceImpedance: positiveResistance,
|
|
100
|
+
loadImpedance: positiveResistance,
|
|
101
|
+
trace: selector.optional(),
|
|
102
|
+
returnSourceLayer: layer_ref.optional(),
|
|
103
|
+
returnSinkLayer: layer_ref.optional(),
|
|
104
|
+
})
|
|
105
|
+
.strict()
|
|
106
|
+
|
|
107
|
+
expectTypesMatch<
|
|
108
|
+
PcbReturnCurrentExcitationProps,
|
|
109
|
+
z.input<typeof pcbReturnCurrentExcitationProps>
|
|
110
|
+
>(true)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { expectTypesMatch } from "lib/typecheck"
|
|
2
|
+
import type { ReactNode } from "react"
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
|
|
5
|
+
/** Defines a pending PCB return-current experiment; rendering does not run it.
|
|
6
|
+
* Frequency, mesh and sampling settings are supplied to the simulation CLI.
|
|
7
|
+
*/
|
|
8
|
+
export interface PcbReturnCurrentSimulationProps {
|
|
9
|
+
/** Stable identity and readable name for the experiment. */
|
|
10
|
+
name?: string
|
|
11
|
+
/** One or more nested simulation.pcbreturncurrentexcitation elements. */
|
|
12
|
+
children?: ReactNode
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const pcbReturnCurrentSimulationProps = z
|
|
16
|
+
.object({
|
|
17
|
+
name: z.string().trim().min(1).optional(),
|
|
18
|
+
children: z.custom<ReactNode>().optional(),
|
|
19
|
+
})
|
|
20
|
+
.strict()
|
|
21
|
+
|
|
22
|
+
expectTypesMatch<
|
|
23
|
+
PcbReturnCurrentSimulationProps,
|
|
24
|
+
z.input<typeof pcbReturnCurrentSimulationProps>
|
|
25
|
+
>(true)
|
package/lib/index.ts
CHANGED
|
@@ -81,6 +81,7 @@ export * from "./components/analogtransientsimulation"
|
|
|
81
81
|
export * from "./components/analogdcoperatingpointsimulation"
|
|
82
82
|
export * from "./components/analogdcsweepsimulation"
|
|
83
83
|
export * from "./components/analogacsweepsimulation"
|
|
84
|
+
export * from "./simulation"
|
|
84
85
|
export * from "./components/analogsweepparameter"
|
|
85
86
|
export * from "./components/autoroutingphase"
|
|
86
87
|
export * from "./components/spicemodel"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { pcbReturnCurrentExcitationProps } from "../components/pcb-return-current-excitation"
|
|
2
|
+
import { pcbReturnCurrentSimulationProps } from "../components/pcb-return-current-simulation"
|
|
3
|
+
|
|
4
|
+
export * from "../components/pcb-return-current-excitation"
|
|
5
|
+
export * from "../components/pcb-return-current-simulation"
|
|
6
|
+
|
|
7
|
+
export const simulationProps = {
|
|
8
|
+
pcbreturncurrentsimulation: pcbReturnCurrentSimulationProps,
|
|
9
|
+
pcbreturncurrentexcitation: pcbReturnCurrentExcitationProps,
|
|
10
|
+
} as const
|