@tscircuit/props 0.0.708 → 0.0.709

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.
@@ -1,4 +1,4 @@
1
- import { ms } from "circuit-json"
1
+ import { frequency, length, ms } from "circuit-json"
2
2
  import { expectTypesMatch } from "lib/typecheck"
3
3
  import { z } from "zod"
4
4
  import { ibisPinRunState, type IbisPinRunState } from "lib/common/ibis"
@@ -17,8 +17,119 @@ export interface AnalogTransientSimulationProps
17
17
  timePerStep?: number | string
18
18
  /** Physical pin selectors and per-experiment direction/enable states. Requires spiceEngine="pcb_spice"; rendering only declares the experiment. */
19
19
  ibisPinStates?: Record<string, IbisPinRunState>
20
+ pcbSpiceChannel?: PcbSpiceChannelProps
20
21
  }
21
22
 
23
+ export interface PcbSpiceChannelProps {
24
+ reduction: "routed-copper" | "straightened-stages"
25
+ sections: number
26
+ lanes: Array<{ name: string; from: string; to: string }>
27
+ referencePinRef: string
28
+ passiveComponentRefs?: string[]
29
+ extraction: {
30
+ minimumFrequency: number | string
31
+ maximumFrequency: number | string
32
+ modelFrequency: number | string
33
+ filaments: number
34
+ refinementFilaments: number
35
+ convergenceTolerance: number
36
+ capacitanceTolerance: number
37
+ reciprocityTolerance: number
38
+ dcResistanceTolerance: number
39
+ maxPanelLength: number | string
40
+ groundMeshSize?: number | string
41
+ }
42
+ relativePermittivity?: number
43
+ via?: {
44
+ platingThickness?: number | string
45
+ equivalentWidth?: number | string
46
+ omitThroughViaStubs?: boolean
47
+ }
48
+ straightenedStageProfiles?: Record<
49
+ string,
50
+ {
51
+ spacing: number | string
52
+ relativePermittivity: number
53
+ return: {
54
+ width: number | string
55
+ thickness: number | string
56
+ lengthFactor: number
57
+ centerY: number | string
58
+ centerZ: number | string
59
+ }
60
+ }
61
+ >
62
+ }
63
+
64
+ const positiveLength = length.pipe(z.number().finite().positive())
65
+ const signedLength = length.pipe(z.number().finite())
66
+ const positiveFrequency = frequency.pipe(z.number().finite().positive())
67
+
68
+ export const pcbSpiceChannelProps = z.object({
69
+ reduction: z.enum(["routed-copper", "straightened-stages"]),
70
+ sections: z.number().int().min(1).max(128),
71
+ lanes: z
72
+ .array(
73
+ z.object({
74
+ name: z.string().min(1),
75
+ from: z.string().min(1),
76
+ to: z.string().min(1),
77
+ }),
78
+ )
79
+ .min(1)
80
+ .max(3),
81
+ referencePinRef: z.string().min(1),
82
+ passiveComponentRefs: z.array(z.string().min(1)).optional(),
83
+ extraction: z
84
+ .object({
85
+ minimumFrequency: positiveFrequency,
86
+ maximumFrequency: positiveFrequency,
87
+ modelFrequency: positiveFrequency,
88
+ filaments: z.number().int().positive(),
89
+ refinementFilaments: z.number().int().positive(),
90
+ convergenceTolerance: z.number().finite().positive(),
91
+ capacitanceTolerance: z.number().finite().positive(),
92
+ reciprocityTolerance: z.number().finite().positive(),
93
+ dcResistanceTolerance: z.number().finite().positive(),
94
+ maxPanelLength: positiveLength,
95
+ groundMeshSize: positiveLength.optional(),
96
+ })
97
+ .refine(
98
+ (extraction) => extraction.refinementFilaments > extraction.filaments,
99
+ {
100
+ path: ["refinementFilaments"],
101
+ message: "refinementFilaments must be greater than filaments",
102
+ },
103
+ ),
104
+ relativePermittivity: z.number().finite().positive().optional(),
105
+ via: z
106
+ .object({
107
+ platingThickness: positiveLength.optional(),
108
+ equivalentWidth: positiveLength.optional(),
109
+ omitThroughViaStubs: z.boolean().optional(),
110
+ })
111
+ .optional(),
112
+ straightenedStageProfiles: z
113
+ .record(
114
+ z.object({
115
+ spacing: positiveLength,
116
+ relativePermittivity: z.number().finite().positive(),
117
+ return: z.object({
118
+ width: positiveLength,
119
+ thickness: positiveLength,
120
+ lengthFactor: z.number().finite().positive(),
121
+ centerY: signedLength,
122
+ centerZ: signedLength,
123
+ }),
124
+ }),
125
+ )
126
+ .optional(),
127
+ })
128
+
129
+ expectTypesMatch<PcbSpiceChannelProps, z.input<typeof pcbSpiceChannelProps>>(
130
+ true,
131
+ )
132
+
22
133
  const positiveMilliseconds = ms.refine(
23
134
  (milliseconds) => milliseconds > 0,
24
135
  "Time must be positive",
@@ -30,9 +141,17 @@ export const analogTransientSimulationProps = z
30
141
  duration: positiveMilliseconds.default("10ms"),
31
142
  startTime: ms.default("0ms"),
32
143
  timePerStep: positiveMilliseconds.default("0.01ms"),
144
+ pcbSpiceChannel: pcbSpiceChannelProps.optional(),
33
145
  ibisPinStates: z.record(z.string().min(1), ibisPinRunState).optional(),
34
146
  })
35
147
  .superRefine((simulation, context) => {
148
+ if (simulation.pcbSpiceChannel && simulation.spiceEngine !== "pcb_spice") {
149
+ context.addIssue({
150
+ code: z.ZodIssueCode.custom,
151
+ path: ["pcbSpiceChannel"],
152
+ message: "PCB SPICE channel settings require spiceEngine=pcb_spice",
153
+ })
154
+ }
36
155
  if (simulation.ibisPinStates && simulation.spiceEngine !== "pcb_spice") {
37
156
  context.addIssue({
38
157
  code: z.ZodIssueCode.custom,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/props",
3
- "version": "0.0.708",
3
+ "version": "0.0.709",
4
4
  "description": "Props for tscircuit builtin component types",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",