@grayhaven/nerve 0.1.0 → 0.2.0
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 +172 -10
- package/dist/index.js +72 -16
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,15 @@ import { Schema } from 'effect';
|
|
|
12
12
|
*/
|
|
13
13
|
type Units = "mm" | "in";
|
|
14
14
|
type ConnectorGender = "plug" | "receptacle" | "hermaphroditic";
|
|
15
|
+
/** Datasheet/source provenance and verification state (PRD §30, §38). */
|
|
16
|
+
interface PartProvenance {
|
|
17
|
+
readonly source?: string;
|
|
18
|
+
readonly datasheet?: string;
|
|
19
|
+
/** "verified" requires a review pass; library seed data is "inspired-by". */
|
|
20
|
+
readonly verification: "unverified" | "inspired-by" | "verified";
|
|
21
|
+
/** ISO date of last verification. */
|
|
22
|
+
readonly lastVerified?: string;
|
|
23
|
+
}
|
|
15
24
|
/**
|
|
16
25
|
* Component master data for a connector housing (PRD §9.2, §30).
|
|
17
26
|
* Instances reference a part; parts live in libraries such as
|
|
@@ -32,10 +41,19 @@ interface ConnectorPart {
|
|
|
32
41
|
readonly matingMpn?: string;
|
|
33
42
|
readonly compatibleTerminals?: ReadonlyArray<string>;
|
|
34
43
|
readonly compatibleSeals?: ReadonlyArray<string>;
|
|
44
|
+
readonly compatibleBackshells?: ReadonlyArray<string>;
|
|
35
45
|
readonly wireGaugeRange?: {
|
|
36
46
|
readonly min: string;
|
|
37
47
|
readonly max: string;
|
|
38
48
|
};
|
|
49
|
+
/** Environmentally sealed housing: every populated cavity needs a seal. */
|
|
50
|
+
readonly sealed?: boolean;
|
|
51
|
+
readonly currentLimitA?: number;
|
|
52
|
+
readonly voltageLimitV?: number;
|
|
53
|
+
readonly crimpTool?: string;
|
|
54
|
+
readonly insertionTool?: string;
|
|
55
|
+
readonly extractionTool?: string;
|
|
56
|
+
readonly provenance?: PartProvenance;
|
|
39
57
|
}
|
|
40
58
|
/** A reference to a specific pin/cavity on a connector instance. */
|
|
41
59
|
interface PinRef {
|
|
@@ -58,6 +76,10 @@ interface ConnectorInstance {
|
|
|
58
76
|
readonly ref: string;
|
|
59
77
|
readonly part: ConnectorPart;
|
|
60
78
|
readonly pins: Readonly<Record<string, string>>;
|
|
79
|
+
/** Terminal MPN per pin (PRD §30). */
|
|
80
|
+
readonly terminals: Readonly<Record<string, string>>;
|
|
81
|
+
/** Seal MPN per pin. */
|
|
82
|
+
readonly seals: Readonly<Record<string, string>>;
|
|
61
83
|
/** Build a `PinRef` for a pin on this connector. */
|
|
62
84
|
pin(pin: string | number): PinRef;
|
|
63
85
|
}
|
|
@@ -183,9 +205,16 @@ interface HarnessDesign {
|
|
|
183
205
|
* diagnostics instead of throwing mid-definition.
|
|
184
206
|
*/
|
|
185
207
|
|
|
186
|
-
/**
|
|
208
|
+
/**
|
|
209
|
+
* Per-pin part assignment: a map of pin → MPN, or a single MPN applied to
|
|
210
|
+
* every assigned pin (the common case — one terminal type per housing).
|
|
211
|
+
*/
|
|
212
|
+
type PinPartAssignment = string | Readonly<Record<string | number, string>>;
|
|
213
|
+
/** Place a connector in the harness: `connector("J1", MolexMicroFit["43025-0800"], { pins: {...}, terminals: "43030-0007" })`. */
|
|
187
214
|
declare const connector: (ref: string, part: ConnectorPart, opts: {
|
|
188
215
|
readonly pins: PinAssignments;
|
|
216
|
+
readonly terminals?: PinPartAssignment;
|
|
217
|
+
readonly seals?: PinPartAssignment;
|
|
189
218
|
}) => ConnectorInstance;
|
|
190
219
|
/** Anything a wire can terminate on: a pin ref, a splice (def or ref). */
|
|
191
220
|
type EndpointInput = PinRef | SpliceDef | {
|
|
@@ -270,9 +299,21 @@ declare const Hir: Schema.Struct<{
|
|
|
270
299
|
min: typeof Schema.String;
|
|
271
300
|
max: typeof Schema.String;
|
|
272
301
|
}>>;
|
|
302
|
+
sealed: Schema.optional<typeof Schema.Boolean>;
|
|
303
|
+
compatibleTerminals: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
304
|
+
compatibleSeals: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
305
|
+
crimpTool: Schema.optional<typeof Schema.String>;
|
|
306
|
+
provenance: Schema.optional<Schema.Struct<{
|
|
307
|
+
source: Schema.optional<typeof Schema.String>;
|
|
308
|
+
datasheet: Schema.optional<typeof Schema.String>;
|
|
309
|
+
verification: Schema.Literal<["unverified", "inspired-by", "verified"]>;
|
|
310
|
+
lastVerified: Schema.optional<typeof Schema.String>;
|
|
311
|
+
}>>;
|
|
273
312
|
pins: Schema.Array$<Schema.Struct<{
|
|
274
313
|
pin: typeof Schema.String;
|
|
275
314
|
signal: Schema.optional<typeof Schema.String>;
|
|
315
|
+
terminal: Schema.optional<typeof Schema.String>;
|
|
316
|
+
seal: Schema.optional<typeof Schema.String>;
|
|
276
317
|
}>>;
|
|
277
318
|
}>>;
|
|
278
319
|
wires: Schema.Array$<Schema.Struct<{
|
|
@@ -379,9 +420,21 @@ declare const HirConnector: Schema.Struct<{
|
|
|
379
420
|
min: typeof Schema.String;
|
|
380
421
|
max: typeof Schema.String;
|
|
381
422
|
}>>;
|
|
423
|
+
sealed: Schema.optional<typeof Schema.Boolean>;
|
|
424
|
+
compatibleTerminals: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
425
|
+
compatibleSeals: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
426
|
+
crimpTool: Schema.optional<typeof Schema.String>;
|
|
427
|
+
provenance: Schema.optional<Schema.Struct<{
|
|
428
|
+
source: Schema.optional<typeof Schema.String>;
|
|
429
|
+
datasheet: Schema.optional<typeof Schema.String>;
|
|
430
|
+
verification: Schema.Literal<["unverified", "inspired-by", "verified"]>;
|
|
431
|
+
lastVerified: Schema.optional<typeof Schema.String>;
|
|
432
|
+
}>>;
|
|
382
433
|
pins: Schema.Array$<Schema.Struct<{
|
|
383
434
|
pin: typeof Schema.String;
|
|
384
435
|
signal: Schema.optional<typeof Schema.String>;
|
|
436
|
+
terminal: Schema.optional<typeof Schema.String>;
|
|
437
|
+
seal: Schema.optional<typeof Schema.String>;
|
|
385
438
|
}>>;
|
|
386
439
|
}>;
|
|
387
440
|
type HirConnector = Schema.Schema.Type<typeof HirConnector>;
|
|
@@ -537,8 +590,8 @@ declare const decodeHir: (u: unknown, overrideOptions?: effect_SchemaAST.ParseOp
|
|
|
537
590
|
}[];
|
|
538
591
|
readonly schemaVersion: "0.1.0";
|
|
539
592
|
readonly connectors: readonly {
|
|
540
|
-
readonly ref: string;
|
|
541
593
|
readonly mpn: string;
|
|
594
|
+
readonly ref: string;
|
|
542
595
|
readonly manufacturer?: string | undefined;
|
|
543
596
|
readonly family?: string | undefined;
|
|
544
597
|
readonly description?: string | undefined;
|
|
@@ -548,9 +601,21 @@ declare const decodeHir: (u: unknown, overrideOptions?: effect_SchemaAST.ParseOp
|
|
|
548
601
|
readonly min: string;
|
|
549
602
|
readonly max: string;
|
|
550
603
|
} | undefined;
|
|
604
|
+
readonly sealed?: boolean | undefined;
|
|
605
|
+
readonly compatibleTerminals?: readonly string[] | undefined;
|
|
606
|
+
readonly compatibleSeals?: readonly string[] | undefined;
|
|
607
|
+
readonly crimpTool?: string | undefined;
|
|
608
|
+
readonly provenance?: {
|
|
609
|
+
readonly source?: string | undefined;
|
|
610
|
+
readonly datasheet?: string | undefined;
|
|
611
|
+
readonly verification: "unverified" | "inspired-by" | "verified";
|
|
612
|
+
readonly lastVerified?: string | undefined;
|
|
613
|
+
} | undefined;
|
|
551
614
|
readonly pins: readonly {
|
|
552
615
|
readonly pin: string;
|
|
553
616
|
readonly signal?: string | undefined;
|
|
617
|
+
readonly terminal?: string | undefined;
|
|
618
|
+
readonly seal?: string | undefined;
|
|
554
619
|
}[];
|
|
555
620
|
}[];
|
|
556
621
|
readonly cables: readonly {
|
|
@@ -591,8 +656,8 @@ declare const decodeHir: (u: unknown, overrideOptions?: effect_SchemaAST.ParseOp
|
|
|
591
656
|
readonly quantity?: number | undefined;
|
|
592
657
|
}[];
|
|
593
658
|
readonly bom: readonly {
|
|
594
|
-
readonly quantity: number;
|
|
595
659
|
readonly mpn: string;
|
|
660
|
+
readonly quantity: number;
|
|
596
661
|
readonly manufacturer?: string | undefined;
|
|
597
662
|
readonly description?: string | undefined;
|
|
598
663
|
readonly notes?: string | undefined;
|
|
@@ -655,8 +720,8 @@ declare const decodeHirEffect: (u: unknown, overrideOptions?: effect_SchemaAST.P
|
|
|
655
720
|
}[];
|
|
656
721
|
readonly schemaVersion: "0.1.0";
|
|
657
722
|
readonly connectors: readonly {
|
|
658
|
-
readonly ref: string;
|
|
659
723
|
readonly mpn: string;
|
|
724
|
+
readonly ref: string;
|
|
660
725
|
readonly manufacturer?: string | undefined;
|
|
661
726
|
readonly family?: string | undefined;
|
|
662
727
|
readonly description?: string | undefined;
|
|
@@ -666,9 +731,21 @@ declare const decodeHirEffect: (u: unknown, overrideOptions?: effect_SchemaAST.P
|
|
|
666
731
|
readonly min: string;
|
|
667
732
|
readonly max: string;
|
|
668
733
|
} | undefined;
|
|
734
|
+
readonly sealed?: boolean | undefined;
|
|
735
|
+
readonly compatibleTerminals?: readonly string[] | undefined;
|
|
736
|
+
readonly compatibleSeals?: readonly string[] | undefined;
|
|
737
|
+
readonly crimpTool?: string | undefined;
|
|
738
|
+
readonly provenance?: {
|
|
739
|
+
readonly source?: string | undefined;
|
|
740
|
+
readonly datasheet?: string | undefined;
|
|
741
|
+
readonly verification: "unverified" | "inspired-by" | "verified";
|
|
742
|
+
readonly lastVerified?: string | undefined;
|
|
743
|
+
} | undefined;
|
|
669
744
|
readonly pins: readonly {
|
|
670
745
|
readonly pin: string;
|
|
671
746
|
readonly signal?: string | undefined;
|
|
747
|
+
readonly terminal?: string | undefined;
|
|
748
|
+
readonly seal?: string | undefined;
|
|
672
749
|
}[];
|
|
673
750
|
}[];
|
|
674
751
|
readonly cables: readonly {
|
|
@@ -709,8 +786,8 @@ declare const decodeHirEffect: (u: unknown, overrideOptions?: effect_SchemaAST.P
|
|
|
709
786
|
readonly quantity?: number | undefined;
|
|
710
787
|
}[];
|
|
711
788
|
readonly bom: readonly {
|
|
712
|
-
readonly quantity: number;
|
|
713
789
|
readonly mpn: string;
|
|
790
|
+
readonly quantity: number;
|
|
714
791
|
readonly manufacturer?: string | undefined;
|
|
715
792
|
readonly description?: string | undefined;
|
|
716
793
|
readonly notes?: string | undefined;
|
|
@@ -773,8 +850,8 @@ declare const encodeHir: (a: {
|
|
|
773
850
|
}[];
|
|
774
851
|
readonly schemaVersion: "0.1.0";
|
|
775
852
|
readonly connectors: readonly {
|
|
776
|
-
readonly ref: string;
|
|
777
853
|
readonly mpn: string;
|
|
854
|
+
readonly ref: string;
|
|
778
855
|
readonly manufacturer?: string | undefined;
|
|
779
856
|
readonly family?: string | undefined;
|
|
780
857
|
readonly description?: string | undefined;
|
|
@@ -784,9 +861,21 @@ declare const encodeHir: (a: {
|
|
|
784
861
|
readonly min: string;
|
|
785
862
|
readonly max: string;
|
|
786
863
|
} | undefined;
|
|
864
|
+
readonly sealed?: boolean | undefined;
|
|
865
|
+
readonly compatibleTerminals?: readonly string[] | undefined;
|
|
866
|
+
readonly compatibleSeals?: readonly string[] | undefined;
|
|
867
|
+
readonly crimpTool?: string | undefined;
|
|
868
|
+
readonly provenance?: {
|
|
869
|
+
readonly source?: string | undefined;
|
|
870
|
+
readonly datasheet?: string | undefined;
|
|
871
|
+
readonly verification: "unverified" | "inspired-by" | "verified";
|
|
872
|
+
readonly lastVerified?: string | undefined;
|
|
873
|
+
} | undefined;
|
|
787
874
|
readonly pins: readonly {
|
|
788
875
|
readonly pin: string;
|
|
789
876
|
readonly signal?: string | undefined;
|
|
877
|
+
readonly terminal?: string | undefined;
|
|
878
|
+
readonly seal?: string | undefined;
|
|
790
879
|
}[];
|
|
791
880
|
}[];
|
|
792
881
|
readonly cables: readonly {
|
|
@@ -827,8 +916,8 @@ declare const encodeHir: (a: {
|
|
|
827
916
|
readonly quantity?: number | undefined;
|
|
828
917
|
}[];
|
|
829
918
|
readonly bom: readonly {
|
|
830
|
-
readonly quantity: number;
|
|
831
919
|
readonly mpn: string;
|
|
920
|
+
readonly quantity: number;
|
|
832
921
|
readonly manufacturer?: string | undefined;
|
|
833
922
|
readonly description?: string | undefined;
|
|
834
923
|
readonly notes?: string | undefined;
|
|
@@ -889,12 +978,14 @@ declare const encodeHir: (a: {
|
|
|
889
978
|
}[];
|
|
890
979
|
readonly schemaVersion: "0.1.0";
|
|
891
980
|
readonly connectors: readonly {
|
|
892
|
-
readonly ref: string;
|
|
893
981
|
readonly mpn: string;
|
|
982
|
+
readonly ref: string;
|
|
894
983
|
readonly pinCount: number;
|
|
895
984
|
readonly pins: readonly {
|
|
896
985
|
readonly pin: string;
|
|
897
986
|
readonly signal?: string | undefined;
|
|
987
|
+
readonly terminal?: string | undefined;
|
|
988
|
+
readonly seal?: string | undefined;
|
|
898
989
|
}[];
|
|
899
990
|
readonly manufacturer?: string | undefined;
|
|
900
991
|
readonly family?: string | undefined;
|
|
@@ -904,6 +995,16 @@ declare const encodeHir: (a: {
|
|
|
904
995
|
readonly min: string;
|
|
905
996
|
readonly max: string;
|
|
906
997
|
} | undefined;
|
|
998
|
+
readonly sealed?: boolean | undefined;
|
|
999
|
+
readonly compatibleTerminals?: readonly string[] | undefined;
|
|
1000
|
+
readonly compatibleSeals?: readonly string[] | undefined;
|
|
1001
|
+
readonly crimpTool?: string | undefined;
|
|
1002
|
+
readonly provenance?: {
|
|
1003
|
+
readonly verification: "unverified" | "inspired-by" | "verified";
|
|
1004
|
+
readonly source?: string | undefined;
|
|
1005
|
+
readonly datasheet?: string | undefined;
|
|
1006
|
+
readonly lastVerified?: string | undefined;
|
|
1007
|
+
} | undefined;
|
|
907
1008
|
}[];
|
|
908
1009
|
readonly cables: readonly {
|
|
909
1010
|
readonly id: string;
|
|
@@ -943,8 +1044,8 @@ declare const encodeHir: (a: {
|
|
|
943
1044
|
readonly quantity?: number | undefined;
|
|
944
1045
|
}[];
|
|
945
1046
|
readonly bom: readonly {
|
|
946
|
-
readonly quantity: number;
|
|
947
1047
|
readonly mpn: string;
|
|
1048
|
+
readonly quantity: number;
|
|
948
1049
|
readonly unitOfMeasure: string;
|
|
949
1050
|
readonly usedBy: readonly string[];
|
|
950
1051
|
readonly manufacturer?: string | undefined;
|
|
@@ -1052,11 +1153,47 @@ declare const runRules: (hir: Hir, rules: ReadonlyArray<Rule>, config?: RuleConf
|
|
|
1052
1153
|
* ```
|
|
1053
1154
|
*/
|
|
1054
1155
|
|
|
1156
|
+
/** Lifecycle risk per PRD §29 supplier/lifecycle fields. */
|
|
1157
|
+
type PartLifecycle = "active" | "nrnd" | "obsolete";
|
|
1158
|
+
interface PartCost {
|
|
1159
|
+
readonly unitCost: number;
|
|
1160
|
+
readonly supplier?: string;
|
|
1161
|
+
readonly leadTimeDays?: number;
|
|
1162
|
+
readonly lifecycle?: PartLifecycle;
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Cost and quote model (PRD §29). Prices are organization data, not design
|
|
1166
|
+
* data — they live in config (or a future part-data provider, §42), never
|
|
1167
|
+
* in the HIR.
|
|
1168
|
+
*/
|
|
1169
|
+
interface CostModel {
|
|
1170
|
+
readonly currency?: string;
|
|
1171
|
+
readonly laborRatePerHour: number;
|
|
1172
|
+
/** Fraction of material lost to scrap, e.g. 0.05. */
|
|
1173
|
+
readonly scrapFactor?: number;
|
|
1174
|
+
/** First-pass yield, e.g. 0.97 — per-unit cost divides by this. */
|
|
1175
|
+
readonly yield?: number;
|
|
1176
|
+
/** Days at/above which a part is flagged long-lead. Default 60. */
|
|
1177
|
+
readonly longLeadThresholdDays?: number;
|
|
1178
|
+
/** Part costs by MPN (connectors, terminals, seals, splice parts...). */
|
|
1179
|
+
readonly parts?: Readonly<Record<string, PartCost>>;
|
|
1180
|
+
/** Wire cost per meter by gauge, e.g. { "18AWG": 0.22 }. */
|
|
1181
|
+
readonly wireCostPerMeter?: Readonly<Record<string, number>>;
|
|
1182
|
+
readonly defaultWireCostPerMeter?: number;
|
|
1183
|
+
readonly sleeveCostPerMeter?: number;
|
|
1184
|
+
readonly labelUnitCost?: number;
|
|
1185
|
+
readonly spliceUnitCost?: number;
|
|
1186
|
+
/** Fallback for parts with no entry; also flags the line as unpriced. */
|
|
1187
|
+
readonly defaultPartCost?: number;
|
|
1188
|
+
}
|
|
1055
1189
|
interface NerveConfig {
|
|
1056
1190
|
readonly units?: Units;
|
|
1057
1191
|
readonly defaultWireTolerance?: number;
|
|
1058
1192
|
readonly outputDir?: string;
|
|
1059
1193
|
readonly rules?: RuleConfig;
|
|
1194
|
+
readonly costing?: CostModel;
|
|
1195
|
+
/** Plugin module paths (relative to the harness file) — rule packs etc. (PRD §40). */
|
|
1196
|
+
readonly plugins?: ReadonlyArray<string>;
|
|
1060
1197
|
readonly exports?: {
|
|
1061
1198
|
readonly csv?: boolean;
|
|
1062
1199
|
readonly svg?: boolean;
|
|
@@ -1101,6 +1238,31 @@ interface VariantOptions {
|
|
|
1101
1238
|
/** Derive a variant: `variant(base, { id: "...-long", wires: { override: { W1: { length: 800 } } } })`. */
|
|
1102
1239
|
declare const variant: (base: HarnessDesign, opts: VariantOptions) => HarnessDesign;
|
|
1103
1240
|
|
|
1241
|
+
/**
|
|
1242
|
+
* Plugin SDK (PRD §40).
|
|
1243
|
+
*
|
|
1244
|
+
* Typed extension boundary. The contract:
|
|
1245
|
+
* - plugins declare which HIR schema versions they support — the compiler
|
|
1246
|
+
* refuses mismatches with a diagnostic instead of undefined behavior,
|
|
1247
|
+
* - plugin rules report through the standard typed diagnostic channel,
|
|
1248
|
+
* - plugins MUST NOT mutate the HIR (rules receive it read-only),
|
|
1249
|
+
* - plugins are plain modules, executable locally and in CI.
|
|
1250
|
+
*
|
|
1251
|
+
* First plugin surface: rule packs (the §38 standards-pack vehicle).
|
|
1252
|
+
* Importers/exporters/renderers join as their host seams stabilize.
|
|
1253
|
+
*/
|
|
1254
|
+
|
|
1255
|
+
interface NervePlugin {
|
|
1256
|
+
readonly name: string;
|
|
1257
|
+
readonly version?: string;
|
|
1258
|
+
/** HIR schema versions this plugin understands. */
|
|
1259
|
+
readonly hirSchemaVersions: ReadonlyArray<string>;
|
|
1260
|
+
readonly rules?: ReadonlyArray<Rule>;
|
|
1261
|
+
}
|
|
1262
|
+
/** Identity helper for typed plugin modules: `export default definePlugin({...})`. */
|
|
1263
|
+
declare const definePlugin: (plugin: NervePlugin) => NervePlugin;
|
|
1264
|
+
declare const isNervePlugin: (value: unknown) => value is NervePlugin;
|
|
1265
|
+
|
|
1104
1266
|
/**
|
|
1105
1267
|
* Revision diff (PRD §21, DoD #9).
|
|
1106
1268
|
*
|
|
@@ -1146,4 +1308,4 @@ declare const isEmptyDiff: (d: HirDiff) => boolean;
|
|
|
1146
1308
|
/** Human-readable diff (git-diff-flavored prefixes). */
|
|
1147
1309
|
declare const formatDiff: (d: HirDiff) => string;
|
|
1148
1310
|
|
|
1149
|
-
export { type BranchDef, type BranchProps, type CableDef, type CableProps, Codes, type CompileResult, type ConnectorGender, type ConnectorInstance, type ConnectorPart, type Diagnostic, DiagnosticSeverity, type EndpointInput, type EntityChange, type FieldChange, HIR_SCHEMA_VERSION, type HarnessDesign, type HarnessProps, Hir, HirBomItem, HirBranch, HirCable, HirConnector, type HirDiff, HirEndpoint, HirLabel, HirPinRef, HirSplice, HirSpliceRef, HirWire, type LabelDef, type LabelProps, type NerveConfig, type PinAssignments, type PinRef, type PinoutChange, type Rule, type RuleConfig, type RuleContext, type RuleOptions, type RuleReport, type SectionDiff, type SpliceDef, type SpliceProps, type SpliceRef, type Units, type VariantOptions, type WireDef, type WireEndpoint, type WireProps, branch, cable, compileDesign, connector, decodeHir, decodeHirEffect, defineConfig, diffHir, encodeHir, endpointLabel, formatDiff, harness, hasErrors, isEmptyDiff, isPinEndpoint, label, refs, rule, runRules, splice, variant, wire };
|
|
1311
|
+
export { type BranchDef, type BranchProps, type CableDef, type CableProps, Codes, type CompileResult, type ConnectorGender, type ConnectorInstance, type ConnectorPart, type CostModel, type Diagnostic, DiagnosticSeverity, type EndpointInput, type EntityChange, type FieldChange, HIR_SCHEMA_VERSION, type HarnessDesign, type HarnessProps, Hir, HirBomItem, HirBranch, HirCable, HirConnector, type HirDiff, HirEndpoint, HirLabel, HirPinRef, HirSplice, HirSpliceRef, HirWire, type LabelDef, type LabelProps, type NerveConfig, type NervePlugin, type PartCost, type PartLifecycle, type PartProvenance, type PinAssignments, type PinPartAssignment, type PinRef, type PinoutChange, type Rule, type RuleConfig, type RuleContext, type RuleOptions, type RuleReport, type SectionDiff, type SpliceDef, type SpliceProps, type SpliceRef, type Units, type VariantOptions, type WireDef, type WireEndpoint, type WireProps, branch, cable, compileDesign, connector, decodeHir, decodeHirEffect, defineConfig, definePlugin, diffHir, encodeHir, endpointLabel, formatDiff, harness, hasErrors, isEmptyDiff, isNervePlugin, isPinEndpoint, label, refs, rule, runRules, splice, variant, wire };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
// src/dsl.ts
|
|
2
2
|
var toRef = (target) => typeof target === "string" ? target : target.ref;
|
|
3
|
+
var expandPinParts = (assignment, pins) => {
|
|
4
|
+
if (assignment === void 0) return {};
|
|
5
|
+
if (typeof assignment === "string") {
|
|
6
|
+
return Object.fromEntries(Object.keys(pins).map((pin) => [pin, assignment]));
|
|
7
|
+
}
|
|
8
|
+
return Object.fromEntries(
|
|
9
|
+
Object.entries(assignment).map(([pin, mpn]) => [String(pin), mpn])
|
|
10
|
+
);
|
|
11
|
+
};
|
|
3
12
|
var connector = (ref, part, opts) => {
|
|
4
13
|
const pins = {};
|
|
5
14
|
for (const [pin, signal] of Object.entries(opts.pins)) {
|
|
@@ -10,6 +19,8 @@ var connector = (ref, part, opts) => {
|
|
|
10
19
|
ref,
|
|
11
20
|
part,
|
|
12
21
|
pins,
|
|
22
|
+
terminals: expandPinParts(opts.terminals, pins),
|
|
23
|
+
seals: expandPinParts(opts.seals, pins),
|
|
13
24
|
pin: (pin) => ({
|
|
14
25
|
kind: "pin-ref",
|
|
15
26
|
connector: ref,
|
|
@@ -107,7 +118,15 @@ var HirSpliceRef = Schema.Struct({
|
|
|
107
118
|
var HirEndpoint = Schema.Union(HirPinRef, HirSpliceRef);
|
|
108
119
|
var HirPin = Schema.Struct({
|
|
109
120
|
pin: Schema.String,
|
|
110
|
-
signal: Schema.optional(Schema.String)
|
|
121
|
+
signal: Schema.optional(Schema.String),
|
|
122
|
+
terminal: Schema.optional(Schema.String),
|
|
123
|
+
seal: Schema.optional(Schema.String)
|
|
124
|
+
});
|
|
125
|
+
var HirProvenance = Schema.Struct({
|
|
126
|
+
source: Schema.optional(Schema.String),
|
|
127
|
+
datasheet: Schema.optional(Schema.String),
|
|
128
|
+
verification: Schema.Literal("unverified", "inspired-by", "verified"),
|
|
129
|
+
lastVerified: Schema.optional(Schema.String)
|
|
111
130
|
});
|
|
112
131
|
var HirConnector = Schema.Struct({
|
|
113
132
|
ref: Schema.String,
|
|
@@ -120,6 +139,11 @@ var HirConnector = Schema.Struct({
|
|
|
120
139
|
wireGaugeRange: Schema.optional(
|
|
121
140
|
Schema.Struct({ min: Schema.String, max: Schema.String })
|
|
122
141
|
),
|
|
142
|
+
sealed: Schema.optional(Schema.Boolean),
|
|
143
|
+
compatibleTerminals: Schema.optional(Schema.Array(Schema.String)),
|
|
144
|
+
compatibleSeals: Schema.optional(Schema.Array(Schema.String)),
|
|
145
|
+
crimpTool: Schema.optional(Schema.String),
|
|
146
|
+
provenance: Schema.optional(HirProvenance),
|
|
123
147
|
pins: Schema.Array(HirPin)
|
|
124
148
|
});
|
|
125
149
|
var HirWire = Schema.Struct({
|
|
@@ -278,7 +302,19 @@ var compileDesign = (design) => {
|
|
|
278
302
|
gender: c.part.gender,
|
|
279
303
|
pinCount: c.part.pinCount,
|
|
280
304
|
wireGaugeRange: c.part.wireGaugeRange ? { min: c.part.wireGaugeRange.min, max: c.part.wireGaugeRange.max } : void 0,
|
|
281
|
-
|
|
305
|
+
sealed: c.part.sealed,
|
|
306
|
+
compatibleTerminals: c.part.compatibleTerminals ? [...c.part.compatibleTerminals] : void 0,
|
|
307
|
+
compatibleSeals: c.part.compatibleSeals ? [...c.part.compatibleSeals] : void 0,
|
|
308
|
+
crimpTool: c.part.crimpTool,
|
|
309
|
+
provenance: c.part.provenance ? { ...c.part.provenance } : void 0,
|
|
310
|
+
pins: Object.entries(c.pins).sort(([a], [b]) => comparePins(a, b)).map(
|
|
311
|
+
([pin, signal]) => compact({
|
|
312
|
+
pin,
|
|
313
|
+
signal,
|
|
314
|
+
terminal: c.terminals[pin],
|
|
315
|
+
seal: c.seals[pin]
|
|
316
|
+
})
|
|
317
|
+
)
|
|
282
318
|
})
|
|
283
319
|
);
|
|
284
320
|
const pinExists = (connectorRef, pin) => {
|
|
@@ -524,25 +560,39 @@ var compileDesign = (design) => {
|
|
|
524
560
|
}
|
|
525
561
|
labels.sort((a, b) => compareStrings(a.id, b.id));
|
|
526
562
|
const bomByMpn = /* @__PURE__ */ new Map();
|
|
527
|
-
|
|
528
|
-
const existing = bomByMpn.get(
|
|
563
|
+
const bomAdd = (mpn, category, usedBy, extra = {}) => {
|
|
564
|
+
const existing = bomByMpn.get(mpn);
|
|
529
565
|
if (existing) {
|
|
530
|
-
existing.
|
|
566
|
+
existing.qty += 1;
|
|
567
|
+
existing.usedBy.push(usedBy);
|
|
531
568
|
} else {
|
|
532
|
-
bomByMpn.set(
|
|
533
|
-
item: compact({
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
description: c.part.description,
|
|
537
|
-
category: "connector",
|
|
538
|
-
quantity: 0,
|
|
539
|
-
unitOfMeasure: "ea"
|
|
540
|
-
}),
|
|
541
|
-
usedBy: [refs.connector(c.ref)]
|
|
569
|
+
bomByMpn.set(mpn, {
|
|
570
|
+
item: compact({ mpn, category, unitOfMeasure: "ea", ...extra }),
|
|
571
|
+
usedBy: [usedBy],
|
|
572
|
+
qty: 1
|
|
542
573
|
});
|
|
543
574
|
}
|
|
575
|
+
};
|
|
576
|
+
for (const c of [...connectorByRef.values()].sort((a, b) => compareStrings(a.ref, b.ref))) {
|
|
577
|
+
bomAdd(c.part.mpn, "connector", refs.connector(c.ref), {
|
|
578
|
+
manufacturer: c.part.manufacturer,
|
|
579
|
+
description: c.part.description
|
|
580
|
+
});
|
|
581
|
+
for (const [pin, terminal] of Object.entries(c.terminals).sort(
|
|
582
|
+
([a], [b]) => comparePins(a, b)
|
|
583
|
+
)) {
|
|
584
|
+
bomAdd(terminal, "terminal", refs.pin(c.ref, pin));
|
|
585
|
+
}
|
|
586
|
+
for (const [pin, seal] of Object.entries(c.seals).sort(
|
|
587
|
+
([a], [b]) => comparePins(a, b)
|
|
588
|
+
)) {
|
|
589
|
+
bomAdd(seal, "seal", refs.pin(c.ref, pin));
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
for (const s of splices) {
|
|
593
|
+
if (s.part !== void 0) bomAdd(s.part, "splice", refs.splice(s.id));
|
|
544
594
|
}
|
|
545
|
-
const bom = [...bomByMpn.values()].map(({ item, usedBy }) => ({ ...item, quantity:
|
|
595
|
+
const bom = [...bomByMpn.values()].map(({ item, usedBy, qty }) => ({ ...item, quantity: qty, usedBy })).sort((a, b) => compareStrings(a.mpn, b.mpn));
|
|
546
596
|
diagnostics.sort(
|
|
547
597
|
(a, b) => compareStrings(a.target ?? "", b.target ?? "") || compareStrings(a.code, b.code) || compareStrings(a.message, b.message)
|
|
548
598
|
);
|
|
@@ -603,6 +653,10 @@ var variant = (base, opts) => ({
|
|
|
603
653
|
cables: apply(base.cables, opts.cables)
|
|
604
654
|
});
|
|
605
655
|
|
|
656
|
+
// src/plugin.ts
|
|
657
|
+
var definePlugin = (plugin) => plugin;
|
|
658
|
+
var isNervePlugin = (value) => typeof value === "object" && value !== null && typeof value.name === "string" && Array.isArray(value.hirSchemaVersions);
|
|
659
|
+
|
|
606
660
|
// src/diff.ts
|
|
607
661
|
var show = (v) => v === void 0 ? "(none)" : typeof v === "string" ? v : JSON.stringify(v);
|
|
608
662
|
var fieldChanges = (a, b, fields) => {
|
|
@@ -781,6 +835,7 @@ export {
|
|
|
781
835
|
decodeHir,
|
|
782
836
|
decodeHirEffect,
|
|
783
837
|
defineConfig,
|
|
838
|
+
definePlugin,
|
|
784
839
|
diffHir,
|
|
785
840
|
encodeHir,
|
|
786
841
|
endpointLabel,
|
|
@@ -788,6 +843,7 @@ export {
|
|
|
788
843
|
harness,
|
|
789
844
|
hasErrors,
|
|
790
845
|
isEmptyDiff,
|
|
846
|
+
isNervePlugin,
|
|
791
847
|
isPinEndpoint,
|
|
792
848
|
label,
|
|
793
849
|
refs,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grayhaven/nerve",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Grayhaven Nerve core: domain model, DSL builders, HIR types and schema, compiler interface, validation primitives.",
|
|
6
6
|
"exports": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"typescript": "^5.8.3",
|
|
17
17
|
"vitest": "^3.2.4",
|
|
18
|
-
"@grayhaven/nerve-rules": "0.
|
|
18
|
+
"@grayhaven/nerve-rules": "0.2.0"
|
|
19
19
|
},
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"files": [
|