@codama/spec 1.6.0-rc.3 → 1.6.0-rc.4

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.
Files changed (96) hide show
  1. package/dist/api.browser.cjs +76 -26
  2. package/dist/api.browser.cjs.map +1 -1
  3. package/dist/api.browser.mjs +74 -26
  4. package/dist/api.browser.mjs.map +1 -1
  5. package/dist/api.node.cjs +76 -26
  6. package/dist/api.node.cjs.map +1 -1
  7. package/dist/api.node.mjs +74 -26
  8. package/dist/api.node.mjs.map +1 -1
  9. package/dist/api.react-native.mjs +74 -26
  10. package/dist/api.react-native.mjs.map +1 -1
  11. package/dist/index.browser.cjs +644 -437
  12. package/dist/index.browser.cjs.map +1 -1
  13. package/dist/index.browser.mjs +644 -437
  14. package/dist/index.browser.mjs.map +1 -1
  15. package/dist/index.node.cjs +644 -437
  16. package/dist/index.node.cjs.map +1 -1
  17. package/dist/index.node.mjs +644 -437
  18. package/dist/index.node.mjs.map +1 -1
  19. package/dist/index.react-native.mjs +644 -437
  20. package/dist/index.react-native.mjs.map +1 -1
  21. package/dist/types/api/attribute.d.ts +2 -2
  22. package/dist/types/api/attribute.d.ts.map +1 -1
  23. package/dist/types/api/defineCategory.d.ts +19 -0
  24. package/dist/types/api/defineCategory.d.ts.map +1 -0
  25. package/dist/types/api/defineEnumeration.d.ts +2 -2
  26. package/dist/types/api/defineEnumeration.d.ts.map +1 -1
  27. package/dist/types/api/defineNestedUnion.d.ts +29 -0
  28. package/dist/types/api/defineNestedUnion.d.ts.map +1 -0
  29. package/dist/types/api/defineNode.d.ts +2 -2
  30. package/dist/types/api/defineNode.d.ts.map +1 -1
  31. package/dist/types/api/defineUnion.d.ts +1 -1
  32. package/dist/types/api/defineUnion.d.ts.map +1 -1
  33. package/dist/types/api/index.d.ts +6 -4
  34. package/dist/types/api/index.d.ts.map +1 -1
  35. package/dist/types/api/primitives.d.ts +8 -4
  36. package/dist/types/api/primitives.d.ts.map +1 -1
  37. package/dist/types/api/public.d.ts +1 -1
  38. package/dist/types/api/public.d.ts.map +1 -1
  39. package/dist/types/api/types.d.ts +67 -22
  40. package/dist/types/api/types.d.ts.map +1 -1
  41. package/dist/types/api/validate.d.ts +4 -5
  42. package/dist/types/api/validate.d.ts.map +1 -1
  43. package/dist/types/v1/enumerations.d.ts.map +1 -1
  44. package/dist/types/v1/index.d.ts.map +1 -1
  45. package/dist/types/v1/nestedUnions.d.ts +9 -0
  46. package/dist/types/v1/nestedUnions.d.ts.map +1 -0
  47. package/dist/types/v1/nodes/AccountNode.d.ts.map +1 -1
  48. package/dist/types/v1/nodes/EventNode.d.ts.map +1 -1
  49. package/dist/types/v1/nodes/InstructionAccountNode.d.ts.map +1 -1
  50. package/dist/types/v1/nodes/InstructionByteDeltaNode.d.ts.map +1 -1
  51. package/dist/types/v1/nodes/InstructionNode.d.ts.map +1 -1
  52. package/dist/types/v1/nodes/InstructionRemainingAccountsNode.d.ts.map +1 -1
  53. package/dist/types/v1/nodes/InstructionStatusNode.d.ts.map +1 -1
  54. package/dist/types/v1/nodes/PdaNode.d.ts.map +1 -1
  55. package/dist/types/v1/nodes/ProgramNode.d.ts.map +1 -1
  56. package/dist/types/v1/nodes/RootNode.d.ts.map +1 -1
  57. package/dist/types/v1/nodes/contextualValueNodes/ConditionalValueNode.d.ts.map +1 -1
  58. package/dist/types/v1/nodes/contextualValueNodes/ContextualValueNode.d.ts.map +1 -1
  59. package/dist/types/v1/nodes/contextualValueNodes/ResolverValueNode.d.ts.map +1 -1
  60. package/dist/types/v1/nodes/linkNodes/InstructionAccountLinkNode.d.ts.map +1 -1
  61. package/dist/types/v1/nodes/linkNodes/InstructionArgumentLinkNode.d.ts.map +1 -1
  62. package/dist/types/v1/nodes/linkNodes/InstructionLinkNode.d.ts.map +1 -1
  63. package/dist/types/v1/nodes/typeNodes/AmountTypeNode.d.ts.map +1 -1
  64. package/dist/types/v1/nodes/typeNodes/ArrayTypeNode.d.ts.map +1 -1
  65. package/dist/types/v1/nodes/typeNodes/BytesTypeNode.d.ts.map +1 -1
  66. package/dist/types/v1/nodes/typeNodes/DateTimeTypeNode.d.ts.map +1 -1
  67. package/dist/types/v1/nodes/typeNodes/EnumEmptyVariantTypeNode.d.ts.map +1 -1
  68. package/dist/types/v1/nodes/typeNodes/EnumStructVariantTypeNode.d.ts.map +1 -1
  69. package/dist/types/v1/nodes/typeNodes/EnumTupleVariantTypeNode.d.ts.map +1 -1
  70. package/dist/types/v1/nodes/typeNodes/HiddenPrefixTypeNode.d.ts.map +1 -1
  71. package/dist/types/v1/nodes/typeNodes/HiddenSuffixTypeNode.d.ts.map +1 -1
  72. package/dist/types/v1/nodes/typeNodes/MapTypeNode.d.ts.map +1 -1
  73. package/dist/types/v1/nodes/typeNodes/OptionTypeNode.d.ts.map +1 -1
  74. package/dist/types/v1/nodes/typeNodes/PostOffsetTypeNode.d.ts.map +1 -1
  75. package/dist/types/v1/nodes/typeNodes/PreOffsetTypeNode.d.ts.map +1 -1
  76. package/dist/types/v1/nodes/typeNodes/RemainderOptionTypeNode.d.ts.map +1 -1
  77. package/dist/types/v1/nodes/typeNodes/SentinelTypeNode.d.ts.map +1 -1
  78. package/dist/types/v1/nodes/typeNodes/SetTypeNode.d.ts.map +1 -1
  79. package/dist/types/v1/nodes/typeNodes/StringTypeNode.d.ts.map +1 -1
  80. package/dist/types/v1/nodes/typeNodes/StructTypeNode.d.ts.map +1 -1
  81. package/dist/types/v1/nodes/typeNodes/ZeroableOptionTypeNode.d.ts.map +1 -1
  82. package/dist/types/v1/nodes/valueNodes/EnumValueNode.d.ts.map +1 -1
  83. package/dist/types/v1/nodes/valueNodes/NumberValueNode.d.ts.map +1 -1
  84. package/dist/v1.browser.cjs +644 -437
  85. package/dist/v1.browser.cjs.map +1 -1
  86. package/dist/v1.browser.mjs +644 -437
  87. package/dist/v1.browser.mjs.map +1 -1
  88. package/dist/v1.node.cjs +644 -437
  89. package/dist/v1.node.cjs.map +1 -1
  90. package/dist/v1.node.mjs +644 -437
  91. package/dist/v1.node.mjs.map +1 -1
  92. package/dist/v1.react-native.mjs +644 -437
  93. package/dist/v1.react-native.mjs.map +1 -1
  94. package/package.json +1 -1
  95. package/dist/types/v1/nestedTypeNodeWrappers.d.ts +0 -10
  96. package/dist/types/v1/nestedTypeNodeWrappers.d.ts.map +0 -1
@@ -6,7 +6,7 @@ function attribute(name, type, options = {}) {
6
6
  name,
7
7
  type,
8
8
  ...options.optional ? { optional: true } : {},
9
- ...options.docs !== void 0 ? { docs: options.docs } : {}
9
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
10
10
  });
11
11
  }
12
12
  function optionalAttribute(name, type, options = {}) {
@@ -21,11 +21,23 @@ function tuple(...items) {
21
21
  return Object.freeze({ kind: "tuple", items: Object.freeze([...items]) });
22
22
  }
23
23
 
24
+ // src/api/defineCategory.ts
25
+ function defineCategory(name, options = {}) {
26
+ return Object.freeze({
27
+ name,
28
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
29
+ nodes: Object.freeze([...options.nodes ?? []]),
30
+ unions: Object.freeze([...options.unions ?? []]),
31
+ enumerations: Object.freeze([...options.enumerations ?? []]),
32
+ nestedUnions: Object.freeze([...options.nestedUnions ?? []])
33
+ });
34
+ }
35
+
24
36
  // src/api/defineEnumeration.ts
25
37
  function variant(name, options = {}) {
26
38
  return Object.freeze({
27
39
  name,
28
- ...options.docs !== void 0 ? { docs: options.docs } : {}
40
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
29
41
  });
30
42
  }
31
43
  function defineEnumeration(name, options) {
@@ -42,7 +54,17 @@ function defineEnumeration(name, options) {
42
54
  return Object.freeze({
43
55
  name,
44
56
  variants: Object.freeze([...options.variants]),
45
- ...options.docs !== void 0 ? { docs: options.docs } : {}
57
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
58
+ });
59
+ }
60
+
61
+ // src/api/defineNestedUnion.ts
62
+ function defineNestedUnion(name, options) {
63
+ return Object.freeze({
64
+ name,
65
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
66
+ base: options.base,
67
+ wrappers: Object.freeze([...options.wrappers])
46
68
  });
47
69
  }
48
70
 
@@ -50,7 +72,7 @@ function defineEnumeration(name, options) {
50
72
  function defineNode(kind, options) {
51
73
  return Object.freeze({
52
74
  kind,
53
- ...options.docs !== void 0 ? { docs: options.docs } : {},
75
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
54
76
  attributes: Object.freeze([...options.attributes]),
55
77
  examples: Object.freeze([...options.examples ?? []])
56
78
  });
@@ -62,7 +84,7 @@ function defineUnion(name, options) {
62
84
  return Object.freeze({
63
85
  name,
64
86
  members: Object.freeze(normalised),
65
- ...options.docs !== void 0 ? { docs: options.docs } : {}
87
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
66
88
  });
67
89
  }
68
90
  function normaliseMember(input) {
@@ -131,8 +153,8 @@ function node(name) {
131
153
  function union(name) {
132
154
  return Object.freeze({ kind: "union", name });
133
155
  }
134
- function nestedTypeNode(name) {
135
- return Object.freeze({ kind: "nestedTypeNode", name });
156
+ function nestedUnion(alias, name) {
157
+ return Object.freeze({ kind: "nestedUnion", alias, name });
136
158
  }
137
159
 
138
160
  // src/api/semanticAliases.ts
@@ -152,23 +174,41 @@ function docs() {
152
174
  // src/api/validate.ts
153
175
  function validate(spec) {
154
176
  const errors = [];
155
- const nodeKinds = new Set(spec.nodes.map((n) => n.kind));
156
- const unionNames = new Set(spec.unions.map((u) => u.name));
157
- const enumerationNames = new Set(spec.enumerations.map((e) => e.name));
158
- const wrappers = new Set(spec.nestedTypeNodeWrappers);
177
+ const allNodes = [];
178
+ const allUnions = [];
179
+ const allEnumerations = [];
180
+ const allNestedUnions = [];
181
+ for (const c of spec.categories) {
182
+ allNodes.push(...c.nodes);
183
+ allUnions.push(...c.unions);
184
+ allEnumerations.push(...c.enumerations);
185
+ allNestedUnions.push(...c.nestedUnions);
186
+ }
187
+ const nodeKinds = new Set(allNodes.map((n) => n.kind));
188
+ const unionNames = new Set(allUnions.map((u) => u.name));
189
+ const enumerationNames = new Set(allEnumerations.map((e) => e.name));
190
+ const nestedUnionNames = new Set(allNestedUnions.map((nu) => nu.name));
159
191
  const registrations = /* @__PURE__ */ new Map();
160
192
  const record = (name, kind) => {
161
193
  const list = registrations.get(name);
162
194
  if (list) list.push(kind);
163
195
  else registrations.set(name, [kind]);
164
196
  };
165
- for (const n of spec.nodes) record(n.kind, "node");
166
- for (const u of spec.unions) record(u.name, "union");
167
- for (const e of spec.enumerations) record(e.name, "enumeration");
197
+ for (const n of allNodes) record(n.kind, "node");
198
+ for (const u of allUnions) record(u.name, "union");
199
+ for (const e of allEnumerations) record(e.name, "enumeration");
200
+ for (const nu of allNestedUnions) record(nu.name, "nestedUnion");
168
201
  for (const [name, kinds] of registrations) {
169
202
  if (kinds.length > 1) errors.push(formatCollisionError(name, kinds));
170
203
  }
171
- for (const n of spec.nodes) {
204
+ const seenCategories = /* @__PURE__ */ new Set();
205
+ for (const c of spec.categories) {
206
+ if (seenCategories.has(c.name)) {
207
+ errors.push(`Category "${c.name}" is declared more than once.`);
208
+ }
209
+ seenCategories.add(c.name);
210
+ }
211
+ for (const n of allNodes) {
172
212
  if (!/^[a-z][A-Za-z0-9]*Node$/.test(n.kind)) {
173
213
  errors.push(`Node kind "${n.kind}" does not match the camelCase ...Node naming convention.`);
174
214
  }
@@ -180,11 +220,11 @@ function validate(spec) {
180
220
  seenAttrs.add(a.name);
181
221
  walkTypeExpr(
182
222
  a.type,
183
- (expr) => checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames)
223
+ (expr) => checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames)
184
224
  );
185
225
  }
186
226
  }
187
- for (const u of spec.unions) {
227
+ for (const u of allUnions) {
188
228
  if (u.members.length === 0) {
189
229
  errors.push(`Union "${u.name}" has no members.`);
190
230
  }
@@ -203,9 +243,14 @@ function validate(spec) {
203
243
  }
204
244
  }
205
245
  }
206
- for (const wrapper of wrappers) {
207
- if (!nodeKinds.has(wrapper)) {
208
- errors.push(`Nested-type-node wrapper "${wrapper}" is not a defined node.`);
246
+ for (const nu of allNestedUnions) {
247
+ if (nu.wrappers.length === 0) {
248
+ errors.push(`Nested union "${nu.name}" has no wrappers.`);
249
+ }
250
+ for (const w of nu.wrappers) {
251
+ if (!nodeKinds.has(w)) {
252
+ errors.push(`Nested union "${nu.name}" wrapper "${w}" is not a defined node.`);
253
+ }
209
254
  }
210
255
  }
211
256
  return errors;
@@ -214,7 +259,7 @@ function formatCollisionError(name, kinds) {
214
259
  const counts = /* @__PURE__ */ new Map();
215
260
  for (const k of kinds) counts.set(k, (counts.get(k) ?? 0) + 1);
216
261
  const breakdown = [...counts.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([k, n]) => `${n} ${k}${n > 1 ? "s" : ""}`).join(", ");
217
- return `Name "${name}" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, and enumerations.`;
262
+ return `Name "${name}" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, enumerations, and nested unions.`;
218
263
  }
219
264
  function walkTypeExpr(expr, visit) {
220
265
  visit(expr);
@@ -224,7 +269,7 @@ function walkTypeExpr(expr, visit) {
224
269
  for (const item of expr.items) walkTypeExpr(item, visit);
225
270
  }
226
271
  }
227
- function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enumerationNames) {
272
+ function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames) {
228
273
  const where = `Node "${nodeKind}", attribute "${attrName}":`;
229
274
  switch (expr.kind) {
230
275
  case "node":
@@ -242,9 +287,12 @@ function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enume
242
287
  errors.push(`${where} references undefined enumeration "${expr.name}".`);
243
288
  }
244
289
  break;
245
- case "nestedTypeNode":
290
+ case "nestedUnion":
246
291
  if (!nodeKinds.has(expr.name)) {
247
- errors.push(`${where} nestedTypeNode references undefined node "${expr.name}".`);
292
+ errors.push(`${where} nestedUnion references undefined node "${expr.name}".`);
293
+ }
294
+ if (!nestedUnionNames.has(expr.alias)) {
295
+ errors.push(`${where} nestedUnion references undefined alias "${expr.alias}".`);
248
296
  }
249
297
  break;
250
298
  }
@@ -252,7 +300,7 @@ function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enume
252
300
  function isChildAttribute(type) {
253
301
  switch (type.kind) {
254
302
  case "node":
255
- case "nestedTypeNode":
303
+ case "nestedUnion":
256
304
  case "union":
257
305
  return true;
258
306
  case "array":
@@ -271,7 +319,9 @@ exports.byteOffset = byteOffset;
271
319
  exports.byteSize = byteSize;
272
320
  exports.codamaVersion = codamaVersion;
273
321
  exports.count = count;
322
+ exports.defineCategory = defineCategory;
274
323
  exports.defineEnumeration = defineEnumeration;
324
+ exports.defineNestedUnion = defineNestedUnion;
275
325
  exports.defineNode = defineNode;
276
326
  exports.defineUnion = defineUnion;
277
327
  exports.docs = docs;
@@ -286,7 +336,7 @@ exports.i8 = i8;
286
336
  exports.isChildAttribute = isChildAttribute;
287
337
  exports.literal = literal;
288
338
  exports.literalUnion = literalUnion;
289
- exports.nestedTypeNode = nestedTypeNode;
339
+ exports.nestedUnion = nestedUnion;
290
340
  exports.node = node;
291
341
  exports.optionalAttribute = optionalAttribute;
292
342
  exports.string = string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/attribute.ts","../src/api/compounds.ts","../src/api/defineEnumeration.ts","../src/api/defineNode.ts","../src/api/defineUnion.ts","../src/api/primitives.ts","../src/api/semanticAliases.ts","../src/api/validate.ts"],"names":[],"mappings":"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","file":"api.browser.cjs","sourcesContent":["/**\n * Attribute factories — produce frozen `AttributeSpec` values directly.\n *\n * Every attribute of a node MUST be constructed via one of these helpers.\n * The returned value IS the encoded form; `defineNode` consumes them as-is.\n */\n\nimport type { AttributeSpec, TypeExpr } from './types';\n\nexport interface AttributeOptions {\n /** Free-form prose description for codegen / docs. */\n readonly docs?: string;\n /** When `true`, the attribute may be absent in encoded values. */\n readonly optional?: boolean;\n}\n\n/**\n * Declare an attribute. The default is a required attribute; pass\n * `{ optional: true }` (or use `optionalAttribute`) to mark it optional.\n */\nexport function attribute(name: string, type: TypeExpr, options: AttributeOptions = {}): AttributeSpec {\n return Object.freeze({\n name,\n type,\n ...(options.optional ? { optional: true as const } : {}),\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n });\n}\n\n/**\n * Sugar for `attribute(name, type, { optional: true, ...rest })` — the most\n * common attribute shape after required ones.\n */\nexport function optionalAttribute(\n name: string,\n type: TypeExpr,\n options: Omit<AttributeOptions, 'optional'> = {},\n): AttributeSpec {\n return attribute(name, type, { ...options, optional: true });\n}\n","/**\n * Compound type-expression constructors — wrap or combine other type\n * expressions. Returned values are frozen.\n *\n * Optionality is intentionally NOT a compound: it's an attribute-level\n * concern, expressed via `optionalAttribute(...)` or\n * `attribute(..., { optional: true })`.\n */\n\nimport type { TypeExpr } from './types';\n\n/** An array (homogeneous list) of `inner`. */\nexport function array(inner: TypeExpr): TypeExpr {\n return Object.freeze({ kind: 'array' as const, of: inner });\n}\n\n/**\n * A heterogeneous fixed-length tuple. Each positional slot has its own type.\n *\n * Tuples use `items` (plural) rather than `of` to signal cardinality > 1.\n */\nexport function tuple(...items: TypeExpr[]): TypeExpr {\n return Object.freeze({ kind: 'tuple' as const, items: Object.freeze([...items]) });\n}\n","/**\n * `defineEnumeration(name, options)` — declares a named enumeration.\n *\n * Codegen emits a string-literal union (TS), a real `enum` (Rust), a class\n * (Python), etc., according to each language's idiom. Per-variant docs are\n * carried through to language-native member documentation.\n */\n\nimport type { EnumerationSpec, EnumerationVariantSpec } from './types';\n\nexport interface VariantOptions {\n readonly docs?: string;\n}\n\n/** Construct a single enumeration variant. */\nexport function variant(name: string, options: VariantOptions = {}): EnumerationVariantSpec {\n return Object.freeze({\n name,\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n });\n}\n\nexport interface DefineEnumerationOptions {\n readonly docs?: string;\n readonly variants: readonly EnumerationVariantSpec[];\n}\n\nexport function defineEnumeration(name: string, options: DefineEnumerationOptions): EnumerationSpec {\n if (options.variants.length === 0) {\n throw new Error(`defineEnumeration(\"${name}\"): variants must be non-empty`);\n }\n const seen = new Set<string>();\n for (const v of options.variants) {\n if (seen.has(v.name)) {\n throw new Error(`defineEnumeration(\"${name}\"): duplicate variant \"${v.name}\"`);\n }\n seen.add(v.name);\n }\n return Object.freeze({\n name,\n variants: Object.freeze([...options.variants]),\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n });\n}\n","/**\n * `defineNode(kind, options)` — declares a single Codama node.\n *\n * The `kind` string is the discriminator value. By convention it ends in\n * `Node` and uses camelCase (e.g. `accountNode`, `arrayTypeNode`).\n *\n * `attributes` is an ordered array of values produced by `attribute(...)` or\n * `optionalAttribute(...)`. Order is preserved in the encoded spec and, by\n * extension, in generated code. The `kind: literal(<kind>)` discriminator\n * is implicit and is NOT declared by authors.\n *\n * The data-vs-children distinction is derived at codegen time from each\n * attribute's type tree (see `isChildAttribute` in `validate.ts`); the\n * meta-model itself just stores a flat list.\n */\n\nimport type { AttributeSpec, NodeSpec } from './types';\n\nexport interface DefineNodeOptions {\n /** Free-form prose description for codegen / docs. */\n readonly docs?: string;\n /**\n * Attributes of the node, in declaration order. Construct each entry\n * via `attribute(...)` or `optionalAttribute(...)`.\n */\n readonly attributes: readonly AttributeSpec[];\n /** Free-form examples (shape defined per spec major version). */\n readonly examples?: readonly unknown[];\n}\n\nexport function defineNode(kind: string, options: DefineNodeOptions): NodeSpec {\n return Object.freeze({\n kind,\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n attributes: Object.freeze([...options.attributes]),\n examples: Object.freeze([...(options.examples ?? [])]),\n });\n}\n","/**\n * `defineUnion(name, options)` — declares a named union of nodes.\n *\n * Members can be:\n * - a node kind string (e.g. `'arrayTypeNode'`), or\n * - a `node(...)` / `union(...)` reference (a `TypeExpr` produced by\n * `primitives.ts`).\n *\n * Nested unions are preserved structurally in the encoded spec rather than\n * flattened. This serves two purposes:\n * - DRY authoring (`union('StandaloneTypeNode')` instead of repeating 23\n * kind names).\n * - A signal to the Rust codegen to emit `From`/`Into` trait impls between\n * the parent union and each nested union.\n */\n\nimport type { TypeExpr, UnionMember, UnionSpec } from './types';\n\nexport type UnionMemberInput = TypeExpr | string;\n\nexport interface DefineUnionOptions {\n readonly docs?: string;\n readonly members: readonly UnionMemberInput[];\n}\n\nexport function defineUnion(name: string, options: DefineUnionOptions): UnionSpec {\n const normalised: UnionMember[] = options.members.map(normaliseMember);\n return Object.freeze({\n name,\n members: Object.freeze(normalised),\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n });\n}\n\nfunction normaliseMember(input: UnionMemberInput): UnionMember {\n if (typeof input === 'string') {\n // Bare strings are treated as node kinds (the most common case).\n return Object.freeze({ kind: 'node' as const, name: input });\n }\n if (input.kind === 'node') return Object.freeze({ kind: 'node' as const, name: input.name });\n if (input.kind === 'union') return Object.freeze({ kind: 'union' as const, name: input.name });\n throw new Error(\n `defineUnion: members must be node kind strings, node(...) or union(...) references; got ${JSON.stringify(input)}`,\n );\n}\n","/**\n * Type-expression primitives — the leaves of any attribute's type tree.\n *\n * Each function returns a frozen `TypeExpr` value. The encoded spec stores\n * those objects verbatim; codegen targets read them and emit native types.\n */\n\nimport type { FloatWidth, IntegerWidth, LiteralValue, StringConstraint, TypeExpr } from './types';\n\n// Strings.\n\n/** Plain UTF-8 string. */\nexport function string(): TypeExpr {\n return Object.freeze({ kind: 'string' as const });\n}\n\n/**\n * A string that must be a valid IDL identifier (stored canonically in\n * camelCase). Renderers may convert to other casings at output time.\n */\nexport function stringIdentifier(): TypeExpr {\n return Object.freeze({ kind: 'string' as const, constraint: 'identifier' as const });\n}\n\n/** A string that must be a valid version (e.g. `\"1.6.0\"`). */\nexport function stringVersion(): TypeExpr {\n return Object.freeze({ kind: 'string' as const, constraint: 'version' as const });\n}\n\n/**\n * The version string of the surrounding Codama spec. Treat as a brand on\n * top of `stringVersion()` — the value is always pinned to the spec\n * version of the IDL document. Codegen targets typically emit a literal\n * type or a constant.\n */\nexport function codamaVersion(): TypeExpr {\n return Object.freeze({ kind: 'codamaVersion' as const });\n}\n\n// Integers (explicit bit widths — no machine-dependent usize/isize).\n\nconst integer = (width: IntegerWidth): TypeExpr => Object.freeze({ kind: 'integer' as const, width });\n\nexport const u8 = (): TypeExpr => integer('u8');\nexport const u16 = (): TypeExpr => integer('u16');\nexport const u32 = (): TypeExpr => integer('u32');\nexport const u64 = (): TypeExpr => integer('u64');\nexport const u128 = (): TypeExpr => integer('u128');\nexport const i8 = (): TypeExpr => integer('i8');\nexport const i16 = (): TypeExpr => integer('i16');\nexport const i32 = (): TypeExpr => integer('i32');\nexport const i64 = (): TypeExpr => integer('i64');\nexport const i128 = (): TypeExpr => integer('i128');\n\n// Floats.\n\nconst float = (width: FloatWidth): TypeExpr => Object.freeze({ kind: 'float' as const, width });\n\nexport const f32 = (): TypeExpr => float('f32');\nexport const f64 = (): TypeExpr => float('f64');\n\n// Booleans and literals.\n\nexport function boolean(): TypeExpr {\n return Object.freeze({ kind: 'boolean' as const });\n}\n\n/** A single fixed value of a primitive type. */\nexport function literal(value: LiteralValue): TypeExpr {\n return Object.freeze({ kind: 'literal' as const, value });\n}\n\n/**\n * A heterogeneous union of literal values — for sum types like\n * `boolean | 'either'` that don't fit a string-only enumeration.\n *\n * Codegen targets render this as the appropriate language idiom (a literal\n * union in TS, a tagged enum with custom serde in Rust, etc.).\n */\nexport function literalUnion(...values: LiteralValue[]): TypeExpr {\n if (values.length === 0) {\n throw new Error('literalUnion: at least one value required');\n }\n const seen = new Set<LiteralValue>();\n for (const v of values) {\n if (seen.has(v)) {\n throw new Error(`literalUnion: duplicate value ${JSON.stringify(v)}`);\n }\n seen.add(v);\n }\n return Object.freeze({ kind: 'literalUnion' as const, values: Object.freeze([...values]) });\n}\n\n// Named references.\n\n/** Reference to a named enumeration declared via `defineEnumeration`. */\nexport function enumeration(name: string): TypeExpr {\n return Object.freeze({ kind: 'enumeration' as const, name });\n}\n\n/** Reference to a named node declared via `defineNode`. */\nexport function node(name: string): TypeExpr {\n return Object.freeze({ kind: 'node' as const, name });\n}\n\n/** Reference to a named union declared via `defineUnion`. */\nexport function union(name: string): TypeExpr {\n return Object.freeze({ kind: 'union' as const, name });\n}\n\n/**\n * Reference to a named node, with implicit `NestedTypeNode<…>` wrapping.\n * The list of recognised wrapper nodes is supplied per spec major version;\n * see `v1/nestedTypeNodeWrappers.ts`.\n */\nexport function nestedTypeNode(name: string): TypeExpr {\n return Object.freeze({ kind: 'nestedTypeNode' as const, name });\n}\n\n// Re-exports for type ergonomics.\nexport type { FloatWidth, IntegerWidth, LiteralValue, StringConstraint, TypeExpr };\n","/**\n * Author-side semantic aliases.\n *\n * Most aliases desugar at call time so the encoded spec only ever shows\n * the underlying primitive (e.g. `{ kind: \"integer\", width: \"u64\" }` for\n * both `u64()` and `byteSize()`). Each language's codegen may further\n * specialise rendering for these widths (e.g. Rust may render `u64` as\n * `usize` for byte-size fields if it wants). Those are codegen policies\n * — not spec content.\n *\n * `docs()` is the exception: it returns its own `'docs'` `TypeExpr` kind\n * so the documentation intent survives in the encoded spec rather than\n * collapsing to `array(string())`.\n */\n\nimport { i64, u32, u64 } from './primitives';\nimport type { TypeExpr } from './types';\n\n/** Number of bytes; non-negative. Encoded as `u64`. */\nexport function byteSize(): TypeExpr {\n return u64();\n}\n\n/** Signed byte offset. Encoded as `i64`. */\nexport function byteOffset(): TypeExpr {\n return i64();\n}\n\n/** Count of items in a collection; non-negative. Encoded as `u32`. */\nexport function count(): TypeExpr {\n return u32();\n}\n\n/**\n * Documentation for a node — semantically a list of paragraph strings,\n * but rendered per language at codegen time (e.g. `Array<string>` in\n * TypeScript, `Vec<String>` in Rust). Returns its own `'docs'` kind so\n * the intent isn't lost in the encoded spec.\n */\nexport function docs(): TypeExpr {\n return Object.freeze({ kind: 'docs' as const });\n}\n","/**\n * Self-consistency validation for an assembled spec.\n *\n * Returns an array of human-readable error strings. An empty array means\n * the spec is internally coherent — every reference resolves, no duplicate\n * names, naming conventions hold.\n */\n\nimport type { Spec, TypeExpr } from './types';\n\ntype RegistryKind = 'enumeration' | 'node' | 'union';\n\nexport function validate(spec: Spec): string[] {\n const errors: string[] = [];\n\n const nodeKinds = new Set(spec.nodes.map(n => n.kind));\n const unionNames = new Set(spec.unions.map(u => u.name));\n const enumerationNames = new Set(spec.enumerations.map(e => e.name));\n const wrappers = new Set(spec.nestedTypeNodeWrappers);\n\n // Single-pass name-collision check. Detects both within-kind duplicates\n // (\"two nodes called `accountNode`\") and cross-kind collisions (\"there's\n // a node and a union both called `TypeNode`\") in one report per\n // offending name.\n const registrations = new Map<string, RegistryKind[]>();\n const record = (name: string, kind: RegistryKind): void => {\n const list = registrations.get(name);\n if (list) list.push(kind);\n else registrations.set(name, [kind]);\n };\n for (const n of spec.nodes) record(n.kind, 'node');\n for (const u of spec.unions) record(u.name, 'union');\n for (const e of spec.enumerations) record(e.name, 'enumeration');\n\n for (const [name, kinds] of registrations) {\n if (kinds.length > 1) errors.push(formatCollisionError(name, kinds));\n }\n\n // Per-node validation.\n for (const n of spec.nodes) {\n if (!/^[a-z][A-Za-z0-9]*Node$/.test(n.kind)) {\n errors.push(`Node kind \"${n.kind}\" does not match the camelCase ...Node naming convention.`);\n }\n const seenAttrs = new Set<string>();\n for (const a of n.attributes) {\n if (seenAttrs.has(a.name)) {\n errors.push(`Node \"${n.kind}\" declares attribute \"${a.name}\" more than once.`);\n }\n seenAttrs.add(a.name);\n walkTypeExpr(a.type, expr =>\n checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames),\n );\n }\n }\n\n // Union member resolution.\n for (const u of spec.unions) {\n if (u.members.length === 0) {\n errors.push(`Union \"${u.name}\" has no members.`);\n }\n const seenMembers = new Set<string>();\n for (const m of u.members) {\n const key = `${m.kind}:${m.name}`;\n if (seenMembers.has(key)) {\n errors.push(`Union \"${u.name}\" lists member ${key} more than once.`);\n }\n seenMembers.add(key);\n if (m.kind === 'node' && !nodeKinds.has(m.name)) {\n errors.push(`Union \"${u.name}\" references undefined node \"${m.name}\".`);\n }\n if (m.kind === 'union' && !unionNames.has(m.name)) {\n errors.push(`Union \"${u.name}\" references undefined union \"${m.name}\".`);\n }\n }\n }\n\n // nestedTypeNode wrapper sanity.\n for (const wrapper of wrappers) {\n if (!nodeKinds.has(wrapper)) {\n errors.push(`Nested-type-node wrapper \"${wrapper}\" is not a defined node.`);\n }\n }\n\n return errors;\n}\n\nfunction formatCollisionError(name: string, kinds: RegistryKind[]): string {\n const counts = new Map<RegistryKind, number>();\n for (const k of kinds) counts.set(k, (counts.get(k) ?? 0) + 1);\n const breakdown = [...counts.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([k, n]) => `${n} ${k}${n > 1 ? 's' : ''}`)\n .join(', ');\n return `Name \"${name}\" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, and enumerations.`;\n}\n\nfunction walkTypeExpr(expr: TypeExpr, visit: (expr: TypeExpr) => void): void {\n visit(expr);\n if (expr.kind === 'array') {\n walkTypeExpr(expr.of, visit);\n } else if (expr.kind === 'tuple') {\n for (const item of expr.items) walkTypeExpr(item, visit);\n }\n}\n\nfunction checkRef(\n expr: TypeExpr,\n nodeKind: string,\n attrName: string,\n errors: string[],\n nodeKinds: Set<string>,\n unionNames: Set<string>,\n enumerationNames: Set<string>,\n): void {\n const where = `Node \"${nodeKind}\", attribute \"${attrName}\":`;\n switch (expr.kind) {\n case 'node':\n if (!nodeKinds.has(expr.name)) {\n errors.push(`${where} references undefined node \"${expr.name}\".`);\n }\n break;\n case 'union':\n if (!unionNames.has(expr.name)) {\n errors.push(`${where} references undefined union \"${expr.name}\".`);\n }\n break;\n case 'enumeration':\n if (!enumerationNames.has(expr.name)) {\n errors.push(`${where} references undefined enumeration \"${expr.name}\".`);\n }\n break;\n case 'nestedTypeNode':\n if (!nodeKinds.has(expr.name)) {\n errors.push(`${where} nestedTypeNode references undefined node \"${expr.name}\".`);\n }\n break;\n default:\n break;\n }\n}\n\n/**\n * Child-detection helper used by codegen, docs, and visitor-table\n * generators.\n *\n * A \"child\" attribute is one whose value contains another node. Specifically,\n * any attribute whose type tree includes a `node`, `nestedTypeNode`, or\n * `union` is treated as a child. Optionality (the `optional` flag on the\n * attribute itself) is orthogonal to this classification.\n */\nexport function isChildAttribute(type: TypeExpr): boolean {\n switch (type.kind) {\n case 'node':\n case 'nestedTypeNode':\n case 'union':\n return true;\n case 'array':\n return isChildAttribute(type.of);\n case 'tuple':\n return type.items.some(isChildAttribute);\n default:\n return false;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/api/attribute.ts","../src/api/compounds.ts","../src/api/defineCategory.ts","../src/api/defineEnumeration.ts","../src/api/defineNestedUnion.ts","../src/api/defineNode.ts","../src/api/defineUnion.ts","../src/api/primitives.ts","../src/api/semanticAliases.ts","../src/api/validate.ts"],"names":[],"mappings":"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","file":"api.browser.cjs","sourcesContent":["/**\n * Attribute factories — produce frozen `AttributeSpec` values directly.\n *\n * Every attribute of a node MUST be constructed via one of these helpers.\n * The returned value IS the encoded form; `defineNode` consumes them as-is.\n */\n\nimport type { AttributeSpec, TypeExpr } from './types';\n\nexport interface AttributeOptions {\n /** Free-form prose paragraphs describing this attribute. */\n readonly docs?: readonly string[];\n /** When `true`, the attribute may be absent in encoded values. */\n readonly optional?: boolean;\n}\n\n/**\n * Declare an attribute. The default is a required attribute; pass\n * `{ optional: true }` (or use `optionalAttribute`) to mark it optional.\n */\nexport function attribute(name: string, type: TypeExpr, options: AttributeOptions = {}): AttributeSpec {\n return Object.freeze({\n name,\n type,\n ...(options.optional ? { optional: true as const } : {}),\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n });\n}\n\n/**\n * Sugar for `attribute(name, type, { optional: true, ...rest })` — the most\n * common attribute shape after required ones.\n */\nexport function optionalAttribute(\n name: string,\n type: TypeExpr,\n options: Omit<AttributeOptions, 'optional'> = {},\n): AttributeSpec {\n return attribute(name, type, { ...options, optional: true });\n}\n","/**\n * Compound type-expression constructors — wrap or combine other type\n * expressions. Returned values are frozen.\n *\n * Optionality is intentionally NOT a compound: it's an attribute-level\n * concern, expressed via `optionalAttribute(...)` or\n * `attribute(..., { optional: true })`.\n */\n\nimport type { TypeExpr } from './types';\n\n/** An array (homogeneous list) of `inner`. */\nexport function array(inner: TypeExpr): TypeExpr {\n return Object.freeze({ kind: 'array' as const, of: inner });\n}\n\n/**\n * A heterogeneous fixed-length tuple. Each positional slot has its own type.\n *\n * Tuples use `items` (plural) rather than `of` to signal cardinality > 1.\n */\nexport function tuple(...items: TypeExpr[]): TypeExpr {\n return Object.freeze({ kind: 'tuple' as const, items: Object.freeze([...items]) });\n}\n","/**\n * `defineCategory(name, options)` — group a coherent set of nodes,\n * unions, enumerations, and nested unions under a single name.\n *\n * Categories double as a filing hint for codegen targets that organise\n * output by category (e.g. the TypeScript node-types generator emits\n * each category into its own subdirectory). Category names are arbitrary\n * strings; the spec doesn't constrain them.\n */\n\nimport type { CategorySpec, EnumerationSpec, NestedUnionSpec, NodeSpec, UnionSpec } from './types';\n\nexport interface DefineCategoryOptions {\n readonly docs?: readonly string[];\n readonly nodes?: readonly NodeSpec[];\n readonly unions?: readonly UnionSpec[];\n readonly enumerations?: readonly EnumerationSpec[];\n readonly nestedUnions?: readonly NestedUnionSpec[];\n}\n\nexport function defineCategory(name: string, options: DefineCategoryOptions = {}): CategorySpec {\n return Object.freeze({\n name,\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n nodes: Object.freeze([...(options.nodes ?? [])]),\n unions: Object.freeze([...(options.unions ?? [])]),\n enumerations: Object.freeze([...(options.enumerations ?? [])]),\n nestedUnions: Object.freeze([...(options.nestedUnions ?? [])]),\n });\n}\n","/**\n * `defineEnumeration(name, options)` — declares a named enumeration.\n *\n * Codegen emits a string-literal union (TS), a real `enum` (Rust), a class\n * (Python), etc., according to each language's idiom. Per-variant docs are\n * carried through to language-native member documentation.\n */\n\nimport type { EnumerationSpec, EnumerationVariantSpec } from './types';\n\nexport interface VariantOptions {\n readonly docs?: readonly string[];\n}\n\n/** Construct a single enumeration variant. */\nexport function variant(name: string, options: VariantOptions = {}): EnumerationVariantSpec {\n return Object.freeze({\n name,\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n });\n}\n\nexport interface DefineEnumerationOptions {\n readonly docs?: readonly string[];\n readonly variants: readonly EnumerationVariantSpec[];\n}\n\nexport function defineEnumeration(name: string, options: DefineEnumerationOptions): EnumerationSpec {\n if (options.variants.length === 0) {\n throw new Error(`defineEnumeration(\"${name}\"): variants must be non-empty`);\n }\n const seen = new Set<string>();\n for (const v of options.variants) {\n if (seen.has(v.name)) {\n throw new Error(`defineEnumeration(\"${name}\"): duplicate variant \"${v.name}\"`);\n }\n seen.add(v.name);\n }\n return Object.freeze({\n name,\n variants: Object.freeze([...options.variants]),\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n });\n}\n","/**\n * `defineNestedUnion(name, options)` — declares a recursive type alias,\n * e.g. `NestedTypeNode<T>`.\n *\n * Codegen renders one alternative per wrapper kind, plus the base case:\n *\n * ```ts\n * type Alias<T extends Base> = Wrapper1<Alias<T>> | Wrapper2<Alias<T>> | … | T;\n * ```\n *\n * Use the `nestedUnion(alias, innerKind)` `TypeExpr` helper to reference\n * an instance of this alias from an attribute.\n */\n\nimport type { NestedUnionSpec, TypeExpr } from './types';\n\nexport interface DefineNestedUnionOptions {\n readonly docs?: readonly string[];\n /**\n * The base type the recursion bottoms out in. Codegen renders this\n * as the alias's type-parameter constraint and as the final union arm.\n */\n readonly base: TypeExpr;\n /**\n * Node kinds that act as wrappers in the recursion. Each must be a\n * node whose attribute structure can wrap another `NestedUnion<T>`.\n */\n readonly wrappers: readonly string[];\n}\n\nexport function defineNestedUnion(name: string, options: DefineNestedUnionOptions): NestedUnionSpec {\n return Object.freeze({\n name,\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n base: options.base,\n wrappers: Object.freeze([...options.wrappers]),\n });\n}\n","/**\n * `defineNode(kind, options)` — declares a single Codama node.\n *\n * The `kind` string is the discriminator value. By convention it ends in\n * `Node` and uses camelCase (e.g. `accountNode`, `arrayTypeNode`).\n *\n * `attributes` is an ordered array of values produced by `attribute(...)` or\n * `optionalAttribute(...)`. Order is preserved in the encoded spec and, by\n * extension, in generated code. The `kind: literal(<kind>)` discriminator\n * is implicit and is NOT declared by authors.\n *\n * The data-vs-children distinction is derived at codegen time from each\n * attribute's type tree (see `isChildAttribute` in `validate.ts`); the\n * meta-model itself just stores a flat list.\n */\n\nimport type { AttributeSpec, NodeSpec } from './types';\n\nexport interface DefineNodeOptions {\n /** Free-form prose paragraphs describing this node. */\n readonly docs?: readonly string[];\n /**\n * Attributes of the node, in declaration order. Construct each entry\n * via `attribute(...)` or `optionalAttribute(...)`.\n */\n readonly attributes: readonly AttributeSpec[];\n /** Free-form examples (shape defined per spec major version). */\n readonly examples?: readonly unknown[];\n}\n\nexport function defineNode(kind: string, options: DefineNodeOptions): NodeSpec {\n return Object.freeze({\n kind,\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n attributes: Object.freeze([...options.attributes]),\n examples: Object.freeze([...(options.examples ?? [])]),\n });\n}\n","/**\n * `defineUnion(name, options)` — declares a named union of nodes.\n *\n * Members can be:\n * - a node kind string (e.g. `'arrayTypeNode'`), or\n * - a `node(...)` / `union(...)` reference (a `TypeExpr` produced by\n * `primitives.ts`).\n *\n * Nested unions are preserved structurally in the encoded spec rather than\n * flattened. This serves two purposes:\n * - DRY authoring (`union('StandaloneTypeNode')` instead of repeating 23\n * kind names).\n * - A signal to the Rust codegen to emit `From`/`Into` trait impls between\n * the parent union and each nested union.\n */\n\nimport type { TypeExpr, UnionMember, UnionSpec } from './types';\n\nexport type UnionMemberInput = TypeExpr | string;\n\nexport interface DefineUnionOptions {\n readonly docs?: readonly string[];\n readonly members: readonly UnionMemberInput[];\n}\n\nexport function defineUnion(name: string, options: DefineUnionOptions): UnionSpec {\n const normalised: UnionMember[] = options.members.map(normaliseMember);\n return Object.freeze({\n name,\n members: Object.freeze(normalised),\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n });\n}\n\nfunction normaliseMember(input: UnionMemberInput): UnionMember {\n if (typeof input === 'string') {\n // Bare strings are treated as node kinds (the most common case).\n return Object.freeze({ kind: 'node' as const, name: input });\n }\n if (input.kind === 'node') return Object.freeze({ kind: 'node' as const, name: input.name });\n if (input.kind === 'union') return Object.freeze({ kind: 'union' as const, name: input.name });\n throw new Error(\n `defineUnion: members must be node kind strings, node(...) or union(...) references; got ${JSON.stringify(input)}`,\n );\n}\n","/**\n * Type-expression primitives — the leaves of any attribute's type tree.\n *\n * Each function returns a frozen `TypeExpr` value. The encoded spec stores\n * those objects verbatim; codegen targets read them and emit native types.\n */\n\nimport type { FloatWidth, IntegerWidth, LiteralValue, StringConstraint, TypeExpr } from './types';\n\n// Strings.\n\n/** Plain UTF-8 string. */\nexport function string(): TypeExpr {\n return Object.freeze({ kind: 'string' as const });\n}\n\n/**\n * A string that must be a valid IDL identifier (stored canonically in\n * camelCase). Renderers may convert to other casings at output time.\n */\nexport function stringIdentifier(): TypeExpr {\n return Object.freeze({ kind: 'string' as const, constraint: 'identifier' as const });\n}\n\n/** A string that must be a valid version (e.g. `\"1.6.0\"`). */\nexport function stringVersion(): TypeExpr {\n return Object.freeze({ kind: 'string' as const, constraint: 'version' as const });\n}\n\n/**\n * The version string of the surrounding Codama spec. Treat as a brand on\n * top of `stringVersion()` — the value is always pinned to the spec\n * version of the IDL document. Codegen targets typically emit a literal\n * type or a constant.\n */\nexport function codamaVersion(): TypeExpr {\n return Object.freeze({ kind: 'codamaVersion' as const });\n}\n\n// Integers (explicit bit widths — no machine-dependent usize/isize).\n\nconst integer = (width: IntegerWidth): TypeExpr => Object.freeze({ kind: 'integer' as const, width });\n\nexport const u8 = (): TypeExpr => integer('u8');\nexport const u16 = (): TypeExpr => integer('u16');\nexport const u32 = (): TypeExpr => integer('u32');\nexport const u64 = (): TypeExpr => integer('u64');\nexport const u128 = (): TypeExpr => integer('u128');\nexport const i8 = (): TypeExpr => integer('i8');\nexport const i16 = (): TypeExpr => integer('i16');\nexport const i32 = (): TypeExpr => integer('i32');\nexport const i64 = (): TypeExpr => integer('i64');\nexport const i128 = (): TypeExpr => integer('i128');\n\n// Floats.\n\nconst float = (width: FloatWidth): TypeExpr => Object.freeze({ kind: 'float' as const, width });\n\nexport const f32 = (): TypeExpr => float('f32');\nexport const f64 = (): TypeExpr => float('f64');\n\n// Booleans and literals.\n\nexport function boolean(): TypeExpr {\n return Object.freeze({ kind: 'boolean' as const });\n}\n\n/** A single fixed value of a primitive type. */\nexport function literal(value: LiteralValue): TypeExpr {\n return Object.freeze({ kind: 'literal' as const, value });\n}\n\n/**\n * A heterogeneous union of literal values — for sum types like\n * `boolean | 'either'` that don't fit a string-only enumeration.\n *\n * Codegen targets render this as the appropriate language idiom (a literal\n * union in TS, a tagged enum with custom serde in Rust, etc.).\n */\nexport function literalUnion(...values: LiteralValue[]): TypeExpr {\n if (values.length === 0) {\n throw new Error('literalUnion: at least one value required');\n }\n const seen = new Set<LiteralValue>();\n for (const v of values) {\n if (seen.has(v)) {\n throw new Error(`literalUnion: duplicate value ${JSON.stringify(v)}`);\n }\n seen.add(v);\n }\n return Object.freeze({ kind: 'literalUnion' as const, values: Object.freeze([...values]) });\n}\n\n// Named references.\n\n/** Reference to a named enumeration declared via `defineEnumeration`. */\nexport function enumeration(name: string): TypeExpr {\n return Object.freeze({ kind: 'enumeration' as const, name });\n}\n\n/** Reference to a named node declared via `defineNode`. */\nexport function node(name: string): TypeExpr {\n return Object.freeze({ kind: 'node' as const, name });\n}\n\n/** Reference to a named union declared via `defineUnion`. */\nexport function union(name: string): TypeExpr {\n return Object.freeze({ kind: 'union' as const, name });\n}\n\n/**\n * Reference to a named node, wrapped by a named recursive `NestedUnion`\n * alias. `alias` selects which `NestedUnion` declared via\n * `defineNestedUnion` the wrapping uses (e.g. `'NestedTypeNode'`); `name`\n * is the inner node kind.\n *\n * Renderers emit `<alias><<innerInterface>>` and an import for the alias\n * file.\n */\nexport function nestedUnion(alias: string, name: string): TypeExpr {\n return Object.freeze({ kind: 'nestedUnion' as const, alias, name });\n}\n\n// Re-exports for type ergonomics.\nexport type { FloatWidth, IntegerWidth, LiteralValue, StringConstraint, TypeExpr };\n","/**\n * Author-side semantic aliases.\n *\n * Most aliases desugar at call time so the encoded spec only ever shows\n * the underlying primitive (e.g. `{ kind: \"integer\", width: \"u64\" }` for\n * both `u64()` and `byteSize()`). Each language's codegen may further\n * specialise rendering for these widths (e.g. Rust may render `u64` as\n * `usize` for byte-size fields if it wants). Those are codegen policies\n * — not spec content.\n *\n * `docs()` is the exception: it returns its own `'docs'` `TypeExpr` kind\n * so the documentation intent survives in the encoded spec rather than\n * collapsing to `array(string())`.\n */\n\nimport { i64, u32, u64 } from './primitives';\nimport type { TypeExpr } from './types';\n\n/** Number of bytes; non-negative. Encoded as `u64`. */\nexport function byteSize(): TypeExpr {\n return u64();\n}\n\n/** Signed byte offset. Encoded as `i64`. */\nexport function byteOffset(): TypeExpr {\n return i64();\n}\n\n/** Count of items in a collection; non-negative. Encoded as `u32`. */\nexport function count(): TypeExpr {\n return u32();\n}\n\n/**\n * Documentation for a node — semantically a list of paragraph strings,\n * but rendered per language at codegen time (e.g. `Array<string>` in\n * TypeScript, `Vec<String>` in Rust). Returns its own `'docs'` kind so\n * the intent isn't lost in the encoded spec.\n */\nexport function docs(): TypeExpr {\n return Object.freeze({ kind: 'docs' as const });\n}\n","/**\n * Self-consistency validation for an assembled spec.\n *\n * Returns an array of human-readable error strings. An empty array means\n * the spec is internally coherent — every reference resolves, no\n * duplicate names, naming conventions hold.\n */\n\nimport type { EnumerationSpec, NestedUnionSpec, NodeSpec, Spec, TypeExpr, UnionSpec } from './types';\n\ntype RegistryKind = 'enumeration' | 'nestedUnion' | 'node' | 'union';\n\nexport function validate(spec: Spec): string[] {\n const errors: string[] = [];\n\n const allNodes: NodeSpec[] = [];\n const allUnions: UnionSpec[] = [];\n const allEnumerations: EnumerationSpec[] = [];\n const allNestedUnions: NestedUnionSpec[] = [];\n for (const c of spec.categories) {\n allNodes.push(...c.nodes);\n allUnions.push(...c.unions);\n allEnumerations.push(...c.enumerations);\n allNestedUnions.push(...c.nestedUnions);\n }\n\n const nodeKinds = new Set(allNodes.map(n => n.kind));\n const unionNames = new Set(allUnions.map(u => u.name));\n const enumerationNames = new Set(allEnumerations.map(e => e.name));\n const nestedUnionNames = new Set(allNestedUnions.map(nu => nu.name));\n\n // Single-pass name-collision check across nodes, unions, enumerations,\n // and nested unions. One error per offending name.\n const registrations = new Map<string, RegistryKind[]>();\n const record = (name: string, kind: RegistryKind): void => {\n const list = registrations.get(name);\n if (list) list.push(kind);\n else registrations.set(name, [kind]);\n };\n for (const n of allNodes) record(n.kind, 'node');\n for (const u of allUnions) record(u.name, 'union');\n for (const e of allEnumerations) record(e.name, 'enumeration');\n for (const nu of allNestedUnions) record(nu.name, 'nestedUnion');\n\n for (const [name, kinds] of registrations) {\n if (kinds.length > 1) errors.push(formatCollisionError(name, kinds));\n }\n\n // Duplicate category names.\n const seenCategories = new Set<string>();\n for (const c of spec.categories) {\n if (seenCategories.has(c.name)) {\n errors.push(`Category \"${c.name}\" is declared more than once.`);\n }\n seenCategories.add(c.name);\n }\n\n // Per-node validation.\n for (const n of allNodes) {\n if (!/^[a-z][A-Za-z0-9]*Node$/.test(n.kind)) {\n errors.push(`Node kind \"${n.kind}\" does not match the camelCase ...Node naming convention.`);\n }\n const seenAttrs = new Set<string>();\n for (const a of n.attributes) {\n if (seenAttrs.has(a.name)) {\n errors.push(`Node \"${n.kind}\" declares attribute \"${a.name}\" more than once.`);\n }\n seenAttrs.add(a.name);\n walkTypeExpr(a.type, expr =>\n checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames),\n );\n }\n }\n\n // Union member resolution.\n for (const u of allUnions) {\n if (u.members.length === 0) {\n errors.push(`Union \"${u.name}\" has no members.`);\n }\n const seenMembers = new Set<string>();\n for (const m of u.members) {\n const key = `${m.kind}:${m.name}`;\n if (seenMembers.has(key)) {\n errors.push(`Union \"${u.name}\" lists member ${key} more than once.`);\n }\n seenMembers.add(key);\n if (m.kind === 'node' && !nodeKinds.has(m.name)) {\n errors.push(`Union \"${u.name}\" references undefined node \"${m.name}\".`);\n }\n if (m.kind === 'union' && !unionNames.has(m.name)) {\n errors.push(`Union \"${u.name}\" references undefined union \"${m.name}\".`);\n }\n }\n }\n\n // Nested-union wrapper sanity.\n for (const nu of allNestedUnions) {\n if (nu.wrappers.length === 0) {\n errors.push(`Nested union \"${nu.name}\" has no wrappers.`);\n }\n for (const w of nu.wrappers) {\n if (!nodeKinds.has(w)) {\n errors.push(`Nested union \"${nu.name}\" wrapper \"${w}\" is not a defined node.`);\n }\n }\n }\n\n return errors;\n}\n\nfunction formatCollisionError(name: string, kinds: RegistryKind[]): string {\n const counts = new Map<RegistryKind, number>();\n for (const k of kinds) counts.set(k, (counts.get(k) ?? 0) + 1);\n const breakdown = [...counts.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([k, n]) => `${n} ${k}${n > 1 ? 's' : ''}`)\n .join(', ');\n return `Name \"${name}\" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, enumerations, and nested unions.`;\n}\n\nfunction walkTypeExpr(expr: TypeExpr, visit: (expr: TypeExpr) => void): void {\n visit(expr);\n if (expr.kind === 'array') {\n walkTypeExpr(expr.of, visit);\n } else if (expr.kind === 'tuple') {\n for (const item of expr.items) walkTypeExpr(item, visit);\n }\n}\n\nfunction checkRef(\n expr: TypeExpr,\n nodeKind: string,\n attrName: string,\n errors: string[],\n nodeKinds: Set<string>,\n unionNames: Set<string>,\n enumerationNames: Set<string>,\n nestedUnionNames: Set<string>,\n): void {\n const where = `Node \"${nodeKind}\", attribute \"${attrName}\":`;\n switch (expr.kind) {\n case 'node':\n if (!nodeKinds.has(expr.name)) {\n errors.push(`${where} references undefined node \"${expr.name}\".`);\n }\n break;\n case 'union':\n if (!unionNames.has(expr.name)) {\n errors.push(`${where} references undefined union \"${expr.name}\".`);\n }\n break;\n case 'enumeration':\n if (!enumerationNames.has(expr.name)) {\n errors.push(`${where} references undefined enumeration \"${expr.name}\".`);\n }\n break;\n case 'nestedUnion':\n if (!nodeKinds.has(expr.name)) {\n errors.push(`${where} nestedUnion references undefined node \"${expr.name}\".`);\n }\n if (!nestedUnionNames.has(expr.alias)) {\n errors.push(`${where} nestedUnion references undefined alias \"${expr.alias}\".`);\n }\n break;\n default:\n break;\n }\n}\n\n/**\n * Discriminator helper used by codegen, docs, and visitor-table generators.\n *\n * A \"child\" attribute is one whose value contains another node. Specifically,\n * any attribute whose type tree includes a `node`, `nestedUnion`, or\n * `union` is treated as a child. Optionality (the `optional` flag on the\n * attribute itself) is orthogonal to this classification.\n */\nexport function isChildAttribute(type: TypeExpr): boolean {\n switch (type.kind) {\n case 'node':\n case 'nestedUnion':\n case 'union':\n return true;\n case 'array':\n return isChildAttribute(type.of);\n case 'tuple':\n return type.items.some(isChildAttribute);\n default:\n return false;\n }\n}\n"]}
@@ -4,7 +4,7 @@ function attribute(name, type, options = {}) {
4
4
  name,
5
5
  type,
6
6
  ...options.optional ? { optional: true } : {},
7
- ...options.docs !== void 0 ? { docs: options.docs } : {}
7
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
8
8
  });
9
9
  }
10
10
  function optionalAttribute(name, type, options = {}) {
@@ -19,11 +19,23 @@ function tuple(...items) {
19
19
  return Object.freeze({ kind: "tuple", items: Object.freeze([...items]) });
20
20
  }
21
21
 
22
+ // src/api/defineCategory.ts
23
+ function defineCategory(name, options = {}) {
24
+ return Object.freeze({
25
+ name,
26
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
27
+ nodes: Object.freeze([...options.nodes ?? []]),
28
+ unions: Object.freeze([...options.unions ?? []]),
29
+ enumerations: Object.freeze([...options.enumerations ?? []]),
30
+ nestedUnions: Object.freeze([...options.nestedUnions ?? []])
31
+ });
32
+ }
33
+
22
34
  // src/api/defineEnumeration.ts
23
35
  function variant(name, options = {}) {
24
36
  return Object.freeze({
25
37
  name,
26
- ...options.docs !== void 0 ? { docs: options.docs } : {}
38
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
27
39
  });
28
40
  }
29
41
  function defineEnumeration(name, options) {
@@ -40,7 +52,17 @@ function defineEnumeration(name, options) {
40
52
  return Object.freeze({
41
53
  name,
42
54
  variants: Object.freeze([...options.variants]),
43
- ...options.docs !== void 0 ? { docs: options.docs } : {}
55
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
56
+ });
57
+ }
58
+
59
+ // src/api/defineNestedUnion.ts
60
+ function defineNestedUnion(name, options) {
61
+ return Object.freeze({
62
+ name,
63
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
64
+ base: options.base,
65
+ wrappers: Object.freeze([...options.wrappers])
44
66
  });
45
67
  }
46
68
 
@@ -48,7 +70,7 @@ function defineEnumeration(name, options) {
48
70
  function defineNode(kind, options) {
49
71
  return Object.freeze({
50
72
  kind,
51
- ...options.docs !== void 0 ? { docs: options.docs } : {},
73
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
52
74
  attributes: Object.freeze([...options.attributes]),
53
75
  examples: Object.freeze([...options.examples ?? []])
54
76
  });
@@ -60,7 +82,7 @@ function defineUnion(name, options) {
60
82
  return Object.freeze({
61
83
  name,
62
84
  members: Object.freeze(normalised),
63
- ...options.docs !== void 0 ? { docs: options.docs } : {}
85
+ ...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
64
86
  });
65
87
  }
66
88
  function normaliseMember(input) {
@@ -129,8 +151,8 @@ function node(name) {
129
151
  function union(name) {
130
152
  return Object.freeze({ kind: "union", name });
131
153
  }
132
- function nestedTypeNode(name) {
133
- return Object.freeze({ kind: "nestedTypeNode", name });
154
+ function nestedUnion(alias, name) {
155
+ return Object.freeze({ kind: "nestedUnion", alias, name });
134
156
  }
135
157
 
136
158
  // src/api/semanticAliases.ts
@@ -150,23 +172,41 @@ function docs() {
150
172
  // src/api/validate.ts
151
173
  function validate(spec) {
152
174
  const errors = [];
153
- const nodeKinds = new Set(spec.nodes.map((n) => n.kind));
154
- const unionNames = new Set(spec.unions.map((u) => u.name));
155
- const enumerationNames = new Set(spec.enumerations.map((e) => e.name));
156
- const wrappers = new Set(spec.nestedTypeNodeWrappers);
175
+ const allNodes = [];
176
+ const allUnions = [];
177
+ const allEnumerations = [];
178
+ const allNestedUnions = [];
179
+ for (const c of spec.categories) {
180
+ allNodes.push(...c.nodes);
181
+ allUnions.push(...c.unions);
182
+ allEnumerations.push(...c.enumerations);
183
+ allNestedUnions.push(...c.nestedUnions);
184
+ }
185
+ const nodeKinds = new Set(allNodes.map((n) => n.kind));
186
+ const unionNames = new Set(allUnions.map((u) => u.name));
187
+ const enumerationNames = new Set(allEnumerations.map((e) => e.name));
188
+ const nestedUnionNames = new Set(allNestedUnions.map((nu) => nu.name));
157
189
  const registrations = /* @__PURE__ */ new Map();
158
190
  const record = (name, kind) => {
159
191
  const list = registrations.get(name);
160
192
  if (list) list.push(kind);
161
193
  else registrations.set(name, [kind]);
162
194
  };
163
- for (const n of spec.nodes) record(n.kind, "node");
164
- for (const u of spec.unions) record(u.name, "union");
165
- for (const e of spec.enumerations) record(e.name, "enumeration");
195
+ for (const n of allNodes) record(n.kind, "node");
196
+ for (const u of allUnions) record(u.name, "union");
197
+ for (const e of allEnumerations) record(e.name, "enumeration");
198
+ for (const nu of allNestedUnions) record(nu.name, "nestedUnion");
166
199
  for (const [name, kinds] of registrations) {
167
200
  if (kinds.length > 1) errors.push(formatCollisionError(name, kinds));
168
201
  }
169
- for (const n of spec.nodes) {
202
+ const seenCategories = /* @__PURE__ */ new Set();
203
+ for (const c of spec.categories) {
204
+ if (seenCategories.has(c.name)) {
205
+ errors.push(`Category "${c.name}" is declared more than once.`);
206
+ }
207
+ seenCategories.add(c.name);
208
+ }
209
+ for (const n of allNodes) {
170
210
  if (!/^[a-z][A-Za-z0-9]*Node$/.test(n.kind)) {
171
211
  errors.push(`Node kind "${n.kind}" does not match the camelCase ...Node naming convention.`);
172
212
  }
@@ -178,11 +218,11 @@ function validate(spec) {
178
218
  seenAttrs.add(a.name);
179
219
  walkTypeExpr(
180
220
  a.type,
181
- (expr) => checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames)
221
+ (expr) => checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames)
182
222
  );
183
223
  }
184
224
  }
185
- for (const u of spec.unions) {
225
+ for (const u of allUnions) {
186
226
  if (u.members.length === 0) {
187
227
  errors.push(`Union "${u.name}" has no members.`);
188
228
  }
@@ -201,9 +241,14 @@ function validate(spec) {
201
241
  }
202
242
  }
203
243
  }
204
- for (const wrapper of wrappers) {
205
- if (!nodeKinds.has(wrapper)) {
206
- errors.push(`Nested-type-node wrapper "${wrapper}" is not a defined node.`);
244
+ for (const nu of allNestedUnions) {
245
+ if (nu.wrappers.length === 0) {
246
+ errors.push(`Nested union "${nu.name}" has no wrappers.`);
247
+ }
248
+ for (const w of nu.wrappers) {
249
+ if (!nodeKinds.has(w)) {
250
+ errors.push(`Nested union "${nu.name}" wrapper "${w}" is not a defined node.`);
251
+ }
207
252
  }
208
253
  }
209
254
  return errors;
@@ -212,7 +257,7 @@ function formatCollisionError(name, kinds) {
212
257
  const counts = /* @__PURE__ */ new Map();
213
258
  for (const k of kinds) counts.set(k, (counts.get(k) ?? 0) + 1);
214
259
  const breakdown = [...counts.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([k, n]) => `${n} ${k}${n > 1 ? "s" : ""}`).join(", ");
215
- return `Name "${name}" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, and enumerations.`;
260
+ return `Name "${name}" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, enumerations, and nested unions.`;
216
261
  }
217
262
  function walkTypeExpr(expr, visit) {
218
263
  visit(expr);
@@ -222,7 +267,7 @@ function walkTypeExpr(expr, visit) {
222
267
  for (const item of expr.items) walkTypeExpr(item, visit);
223
268
  }
224
269
  }
225
- function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enumerationNames) {
270
+ function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames) {
226
271
  const where = `Node "${nodeKind}", attribute "${attrName}":`;
227
272
  switch (expr.kind) {
228
273
  case "node":
@@ -240,9 +285,12 @@ function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enume
240
285
  errors.push(`${where} references undefined enumeration "${expr.name}".`);
241
286
  }
242
287
  break;
243
- case "nestedTypeNode":
288
+ case "nestedUnion":
244
289
  if (!nodeKinds.has(expr.name)) {
245
- errors.push(`${where} nestedTypeNode references undefined node "${expr.name}".`);
290
+ errors.push(`${where} nestedUnion references undefined node "${expr.name}".`);
291
+ }
292
+ if (!nestedUnionNames.has(expr.alias)) {
293
+ errors.push(`${where} nestedUnion references undefined alias "${expr.alias}".`);
246
294
  }
247
295
  break;
248
296
  }
@@ -250,7 +298,7 @@ function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enume
250
298
  function isChildAttribute(type) {
251
299
  switch (type.kind) {
252
300
  case "node":
253
- case "nestedTypeNode":
301
+ case "nestedUnion":
254
302
  case "union":
255
303
  return true;
256
304
  case "array":
@@ -262,6 +310,6 @@ function isChildAttribute(type) {
262
310
  }
263
311
  }
264
312
 
265
- export { array, attribute, boolean, byteOffset, byteSize, codamaVersion, count, defineEnumeration, defineNode, defineUnion, docs, enumeration, f32, f64, i128, i16, i32, i64, i8, isChildAttribute, literal, literalUnion, nestedTypeNode, node, optionalAttribute, string, stringIdentifier, stringVersion, tuple, u128, u16, u32, u64, u8, union, validate, variant };
313
+ export { array, attribute, boolean, byteOffset, byteSize, codamaVersion, count, defineCategory, defineEnumeration, defineNestedUnion, defineNode, defineUnion, docs, enumeration, f32, f64, i128, i16, i32, i64, i8, isChildAttribute, literal, literalUnion, nestedUnion, node, optionalAttribute, string, stringIdentifier, stringVersion, tuple, u128, u16, u32, u64, u8, union, validate, variant };
266
314
  //# sourceMappingURL=api.browser.mjs.map
267
315
  //# sourceMappingURL=api.browser.mjs.map