@tscircuit/props 0.0.626 → 0.0.628
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 +21 -0
- package/dist/index.d.ts +2958 -2
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/lib/common/implicitBreakoutPointSolver.ts +71 -0
- package/lib/components/group.ts +8 -0
- package/lib/components/pin-header.ts +76 -27
- package/lib/index.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export interface ImplicitBreakoutPoint {
|
|
2
|
+
readonly x: number
|
|
3
|
+
readonly y: number
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface ImplicitBreakoutBounds {
|
|
7
|
+
readonly minX: number
|
|
8
|
+
readonly maxX: number
|
|
9
|
+
readonly minY: number
|
|
10
|
+
readonly maxY: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type ImplicitBreakoutEdge = "left" | "right" | "bottom" | "top"
|
|
14
|
+
|
|
15
|
+
export interface ImplicitBreakoutRegion {
|
|
16
|
+
readonly regionId: string
|
|
17
|
+
readonly bounds: ImplicitBreakoutBounds
|
|
18
|
+
readonly edge: ImplicitBreakoutEdge
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ImplicitBreakoutConnectionEndpoint {
|
|
22
|
+
readonly regionId: string
|
|
23
|
+
readonly position: ImplicitBreakoutPoint
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ImplicitBreakoutConnection {
|
|
27
|
+
readonly connectionId: string
|
|
28
|
+
readonly endpoints: readonly ImplicitBreakoutConnectionEndpoint[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ImplicitBreakoutDifferentialPair {
|
|
32
|
+
readonly type: "differential"
|
|
33
|
+
readonly connections: readonly [
|
|
34
|
+
ImplicitBreakoutConnection,
|
|
35
|
+
ImplicitBreakoutConnection,
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type ImplicitBreakoutConnectionOrDifferentialPair =
|
|
40
|
+
| ImplicitBreakoutConnection
|
|
41
|
+
| ImplicitBreakoutDifferentialPair
|
|
42
|
+
|
|
43
|
+
export interface ImplicitBreakoutBus {
|
|
44
|
+
readonly busId: string
|
|
45
|
+
readonly connectionIds: readonly string[]
|
|
46
|
+
/** Ordered candidate layers that the solver may distribute this bus over. */
|
|
47
|
+
readonly targetLayers?: readonly string[]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ImplicitBreakoutPointSolverInput {
|
|
51
|
+
readonly regions: readonly ImplicitBreakoutRegion[]
|
|
52
|
+
readonly connections: readonly ImplicitBreakoutConnectionOrDifferentialPair[]
|
|
53
|
+
readonly buses: readonly ImplicitBreakoutBus[]
|
|
54
|
+
readonly boundaryPointSpacing: number
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface ImplicitBreakoutSolverPoint extends ImplicitBreakoutPoint {
|
|
58
|
+
readonly regionId: string
|
|
59
|
+
readonly connectionId: string
|
|
60
|
+
readonly layer: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ImplicitBreakoutPointSolverOutput {
|
|
64
|
+
readonly breakoutPoints: readonly ImplicitBreakoutSolverPoint[]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type ImplicitBreakoutPointSolverFn = (
|
|
68
|
+
input: ImplicitBreakoutPointSolverInput,
|
|
69
|
+
) =>
|
|
70
|
+
| ImplicitBreakoutPointSolverOutput
|
|
71
|
+
| Promise<ImplicitBreakoutPointSolverOutput>
|
package/lib/components/group.ts
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from "lib/common/schematicPinStyle"
|
|
34
34
|
import { url } from "lib/common/url"
|
|
35
35
|
import type { Connections } from "lib/utility-types/connections-and-selectors"
|
|
36
|
+
import type { ImplicitBreakoutPointSolverFn } from "lib/common/implicitBreakoutPointSolver"
|
|
36
37
|
|
|
37
38
|
export const layoutConfig = z.object({
|
|
38
39
|
layoutMode: z
|
|
@@ -342,6 +343,8 @@ export interface AutorouterConfig {
|
|
|
342
343
|
| /** @deprecated Use "sequential_trace" */ "sequential-trace"
|
|
343
344
|
local?: boolean
|
|
344
345
|
algorithmFn?: (simpleRouteJson: any) => Promise<any>
|
|
346
|
+
/** Override the solver used to place implicit breakout points. */
|
|
347
|
+
implicitBreakoutPointSolverFn?: ImplicitBreakoutPointSolverFn
|
|
345
348
|
preset?:
|
|
346
349
|
| "sequential_trace"
|
|
347
350
|
| "subcircuit"
|
|
@@ -423,6 +426,11 @@ export const autorouterConfig = z.object({
|
|
|
423
426
|
(v) => typeof v === "function" || v === undefined,
|
|
424
427
|
)
|
|
425
428
|
.optional(),
|
|
429
|
+
implicitBreakoutPointSolverFn: z
|
|
430
|
+
.custom<ImplicitBreakoutPointSolverFn>(
|
|
431
|
+
(value) => typeof value === "function" || value === undefined,
|
|
432
|
+
)
|
|
433
|
+
.optional(),
|
|
426
434
|
preset: z
|
|
427
435
|
.enum([
|
|
428
436
|
"sequential_trace",
|
|
@@ -45,6 +45,27 @@ export interface PinHeaderProps extends CommonComponentProps {
|
|
|
45
45
|
*/
|
|
46
46
|
gender?: "male" | "female" | "unpopulated"
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Mount the header on the top of the board, so it is connected to from
|
|
50
|
+
* above. An alias for `layer: "top"`, which is the default.
|
|
51
|
+
*
|
|
52
|
+
* Which side of the board a part sits on is `layer`, and only `layer`: the
|
|
53
|
+
* 3D model is always drawn top-side and consumers flip it for a bottom-layer
|
|
54
|
+
* component. Prefer these names on a connector, where "which side does the
|
|
55
|
+
* mating connector come from" is the question actually being asked.
|
|
56
|
+
*/
|
|
57
|
+
connectsFromAbove?: boolean
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Mount the header on the underside of the board, so it is connected to from
|
|
61
|
+
* below. An alias for `layer: "bottom"`.
|
|
62
|
+
*
|
|
63
|
+
* Not to be confused with `invert` on a footprint string, which installs a
|
|
64
|
+
* header BACKWARDS on whichever side it is on — long pins through the board
|
|
65
|
+
* rather than short ones.
|
|
66
|
+
*/
|
|
67
|
+
connectsFromBelow?: boolean
|
|
68
|
+
|
|
48
69
|
/**
|
|
49
70
|
* Whether to show pin labels in silkscreen
|
|
50
71
|
*/
|
|
@@ -122,33 +143,61 @@ export interface PinHeaderProps extends CommonComponentProps {
|
|
|
122
143
|
schHeight?: number | string
|
|
123
144
|
}
|
|
124
145
|
|
|
125
|
-
export const pinHeaderProps = commonComponentProps
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
.
|
|
139
|
-
.
|
|
140
|
-
.optional(),
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
export const pinHeaderProps = commonComponentProps
|
|
147
|
+
.extend({
|
|
148
|
+
pinCount: z.number(),
|
|
149
|
+
pitch: distance.optional(),
|
|
150
|
+
schFacingDirection: z.enum(["up", "down", "left", "right"]).optional(),
|
|
151
|
+
gender: z
|
|
152
|
+
.enum(["male", "female", "unpopulated"])
|
|
153
|
+
.optional()
|
|
154
|
+
.default("male"),
|
|
155
|
+
showSilkscreenPinLabels: z.boolean().optional(),
|
|
156
|
+
pcbPinLabels: z.record(z.string(), z.string()).optional(),
|
|
157
|
+
doubleRow: z.boolean().optional(),
|
|
158
|
+
rightAngle: z.boolean().optional(),
|
|
159
|
+
pcbOrientation: pcbOrientationProp.optional(),
|
|
160
|
+
holeDiameter: distance.optional(),
|
|
161
|
+
platedDiameter: distance.optional(),
|
|
162
|
+
pinLabels: z
|
|
163
|
+
.record(z.string(), schematicPinLabel)
|
|
164
|
+
.or(z.array(schematicPinLabel))
|
|
165
|
+
.optional(),
|
|
166
|
+
connections: z
|
|
167
|
+
.custom<Connections>()
|
|
168
|
+
.pipe(z.record(z.string(), connectionTarget))
|
|
169
|
+
.optional(),
|
|
170
|
+
facingDirection: z.enum(["left", "right"]).optional(),
|
|
171
|
+
schPinArrangement: schematicPinArrangement.optional(),
|
|
172
|
+
schPinStyle: schematicPinStyle.optional(),
|
|
173
|
+
schPinSpacing: distance.optional(),
|
|
174
|
+
schWidth: distance.optional(),
|
|
175
|
+
schHeight: distance.optional(),
|
|
176
|
+
connectsFromAbove: z.boolean().optional(),
|
|
177
|
+
connectsFromBelow: z.boolean().optional(),
|
|
178
|
+
})
|
|
179
|
+
// Resolved HERE rather than in each consumer: `layer` is read in dozens of
|
|
180
|
+
// places downstream, and an alias that only some of them understand is worse
|
|
181
|
+
// than no alias. After parsing there is one field to reason about again.
|
|
182
|
+
.superRefine((props, ctx) => {
|
|
183
|
+
if (props.connectsFromAbove && props.connectsFromBelow) {
|
|
184
|
+
ctx.addIssue({
|
|
185
|
+
code: z.ZodIssueCode.custom,
|
|
186
|
+
message:
|
|
187
|
+
"connectsFromAbove and connectsFromBelow are opposites; set at most one",
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
.transform((props) => {
|
|
192
|
+
const layer =
|
|
193
|
+
props.layer ??
|
|
194
|
+
(props.connectsFromBelow
|
|
195
|
+
? ("bottom" as const)
|
|
196
|
+
: props.connectsFromAbove
|
|
197
|
+
? ("top" as const)
|
|
198
|
+
: undefined)
|
|
199
|
+
return layer === undefined ? props : { ...props, layer }
|
|
200
|
+
})
|
|
152
201
|
|
|
153
202
|
type InferredPinHeaderProps = z.input<typeof pinHeaderProps>
|
|
154
203
|
expectTypesMatch<PinHeaderProps, InferredPinHeaderProps>(true)
|
package/lib/index.ts
CHANGED