cesr-ts 0.3.0 → 0.4.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.
Files changed (192) hide show
  1. package/README.md +6 -1
  2. package/esm/src/annotate/annotator.js +4 -7
  3. package/esm/src/annotate/comments.js +1 -1
  4. package/esm/src/annotate/render.js +66 -75
  5. package/esm/src/core/bytes.js +47 -0
  6. package/esm/src/core/cbor.js +122 -0
  7. package/esm/src/core/errors.js +13 -0
  8. package/esm/src/core/parser-attachment-collector.js +1 -2
  9. package/esm/src/core/parser-engine.js +7 -7
  10. package/esm/src/core/parser-frame-parser.js +14 -20
  11. package/esm/src/index.js +59 -33
  12. package/esm/src/parser/attachment-parser.js +1 -1
  13. package/esm/src/parser/group-dispatch.js +27 -41
  14. package/esm/src/primitives/aggor.js +74 -31
  15. package/esm/src/primitives/bexter.js +60 -16
  16. package/esm/src/primitives/blinder.js +27 -20
  17. package/esm/src/primitives/cigar.js +25 -15
  18. package/esm/src/primitives/cipher.js +18 -0
  19. package/esm/src/primitives/codex.js +74 -0
  20. package/esm/src/primitives/compactor.js +1 -7
  21. package/esm/src/primitives/counter.js +203 -13
  22. package/esm/src/primitives/dater.js +31 -16
  23. package/esm/src/primitives/decimer.js +65 -0
  24. package/esm/src/primitives/decrypter.js +18 -0
  25. package/esm/src/primitives/diger.js +24 -18
  26. package/esm/src/primitives/encrypter.js +19 -0
  27. package/esm/src/primitives/ilker.js +24 -12
  28. package/esm/src/primitives/indexer.js +199 -7
  29. package/esm/src/primitives/labeler.js +74 -24
  30. package/esm/src/primitives/mapper.js +14 -35
  31. package/esm/src/primitives/matter.js +160 -6
  32. package/esm/src/primitives/mediar.js +27 -18
  33. package/esm/src/primitives/noncer.js +33 -15
  34. package/esm/src/primitives/number.js +28 -27
  35. package/esm/src/primitives/pather.js +30 -18
  36. package/esm/src/primitives/prefixer.js +23 -20
  37. package/esm/src/primitives/primitive.js +9 -0
  38. package/esm/src/primitives/registry.js +3 -3
  39. package/esm/src/primitives/saider.js +24 -18
  40. package/esm/src/primitives/salter.js +22 -0
  41. package/esm/src/primitives/sealer.js +27 -32
  42. package/esm/src/primitives/seqner.js +28 -19
  43. package/esm/src/primitives/siger.js +29 -0
  44. package/esm/src/primitives/signer.js +23 -0
  45. package/esm/src/primitives/structor.js +104 -0
  46. package/esm/src/primitives/tagger.js +44 -0
  47. package/esm/src/primitives/texter.js +24 -15
  48. package/esm/src/primitives/tholder.js +27 -24
  49. package/esm/src/primitives/traitor.js +23 -16
  50. package/esm/src/primitives/unknown.js +89 -0
  51. package/esm/src/primitives/verfer.js +25 -25
  52. package/esm/src/primitives/verser.js +54 -23
  53. package/esm/src/serder/serder.js +190 -10
  54. package/esm/src/serder/serdery.js +2 -2
  55. package/esm/src/tables/codex-utils.js +9 -0
  56. package/esm/src/tables/counter-codex.js +1 -1
  57. package/esm/src/tables/counter-groups.js +46 -0
  58. package/esm/src/tables/counter-version-registry.js +1 -1
  59. package/esm/src/tables/indexer.codex.generated.js +64 -0
  60. package/esm/src/tables/indexer.tables.generated.js +72 -0
  61. package/esm/src/tables/matter.codex.generated.js +399 -0
  62. package/esm/src/tables/matter.tables.generated.js +112 -0
  63. package/esm/src/tables/trait.codex.generated.js +10 -0
  64. package/esm/src/version.js +2 -2
  65. package/package.json +1 -1
  66. package/types/src/adapters/async-iterable.d.ts +1 -1
  67. package/types/src/adapters/async-iterable.d.ts.map +1 -1
  68. package/types/src/adapters/effection.d.ts +1 -1
  69. package/types/src/adapters/effection.d.ts.map +1 -1
  70. package/types/src/annotate/annotator.d.ts.map +1 -1
  71. package/types/src/annotate/comments.d.ts.map +1 -1
  72. package/types/src/annotate/render.d.ts.map +1 -1
  73. package/types/src/bench/parser-benchmark.d.ts.map +1 -1
  74. package/types/src/core/bytes.d.ts +22 -0
  75. package/types/src/core/bytes.d.ts.map +1 -1
  76. package/types/src/core/cbor.d.ts +30 -0
  77. package/types/src/core/cbor.d.ts.map +1 -0
  78. package/types/src/core/errors.d.ts +13 -0
  79. package/types/src/core/errors.d.ts.map +1 -1
  80. package/types/src/core/parser-attachment-collector.d.ts.map +1 -1
  81. package/types/src/core/parser-engine.d.ts +1 -1
  82. package/types/src/core/parser-engine.d.ts.map +1 -1
  83. package/types/src/core/parser-frame-parser.d.ts +1 -1
  84. package/types/src/core/parser-frame-parser.d.ts.map +1 -1
  85. package/types/src/core/types.d.ts +7 -36
  86. package/types/src/core/types.d.ts.map +1 -1
  87. package/types/src/index.d.ts +59 -33
  88. package/types/src/index.d.ts.map +1 -1
  89. package/types/src/parser/attachment-fallback-policy.d.ts.map +1 -1
  90. package/types/src/parser/attachment-parser.d.ts.map +1 -1
  91. package/types/src/parser/group-dispatch.d.ts +2 -2
  92. package/types/src/parser/group-dispatch.d.ts.map +1 -1
  93. package/types/src/primitives/aggor.d.ts +34 -8
  94. package/types/src/primitives/aggor.d.ts.map +1 -1
  95. package/types/src/primitives/bexter.d.ts +28 -6
  96. package/types/src/primitives/bexter.d.ts.map +1 -1
  97. package/types/src/primitives/blinder.d.ts +16 -8
  98. package/types/src/primitives/blinder.d.ts.map +1 -1
  99. package/types/src/primitives/cigar.d.ts +12 -7
  100. package/types/src/primitives/cigar.d.ts.map +1 -1
  101. package/types/src/primitives/cipher.d.ts +11 -0
  102. package/types/src/primitives/cipher.d.ts.map +1 -0
  103. package/types/src/primitives/codex.d.ts +54 -0
  104. package/types/src/primitives/codex.d.ts.map +1 -0
  105. package/types/src/primitives/compactor.d.ts.map +1 -1
  106. package/types/src/primitives/counter.d.ts +63 -2
  107. package/types/src/primitives/counter.d.ts.map +1 -1
  108. package/types/src/primitives/dater.d.ts +12 -7
  109. package/types/src/primitives/dater.d.ts.map +1 -1
  110. package/types/src/primitives/decimer.d.ts +23 -0
  111. package/types/src/primitives/decimer.d.ts.map +1 -0
  112. package/types/src/primitives/decrypter.d.ts +11 -0
  113. package/types/src/primitives/decrypter.d.ts.map +1 -0
  114. package/types/src/primitives/diger.d.ts +16 -7
  115. package/types/src/primitives/diger.d.ts.map +1 -1
  116. package/types/src/primitives/encrypter.d.ts +12 -0
  117. package/types/src/primitives/encrypter.d.ts.map +1 -0
  118. package/types/src/primitives/ilker.d.ts +13 -6
  119. package/types/src/primitives/ilker.d.ts.map +1 -1
  120. package/types/src/primitives/indexer.d.ts +52 -1
  121. package/types/src/primitives/indexer.d.ts.map +1 -1
  122. package/types/src/primitives/labeler.d.ts +28 -11
  123. package/types/src/primitives/labeler.d.ts.map +1 -1
  124. package/types/src/primitives/mapper.d.ts +4 -6
  125. package/types/src/primitives/mapper.d.ts.map +1 -1
  126. package/types/src/primitives/matter.d.ts +44 -1
  127. package/types/src/primitives/matter.d.ts.map +1 -1
  128. package/types/src/primitives/mediar.d.ts +16 -8
  129. package/types/src/primitives/mediar.d.ts.map +1 -1
  130. package/types/src/primitives/noncer.d.ts +20 -6
  131. package/types/src/primitives/noncer.d.ts.map +1 -1
  132. package/types/src/primitives/number.d.ts +12 -7
  133. package/types/src/primitives/number.d.ts.map +1 -1
  134. package/types/src/primitives/pather.d.ts +12 -6
  135. package/types/src/primitives/pather.d.ts.map +1 -1
  136. package/types/src/primitives/prefixer.d.ts +12 -6
  137. package/types/src/primitives/prefixer.d.ts.map +1 -1
  138. package/types/src/primitives/primitive.d.ts +25 -0
  139. package/types/src/primitives/primitive.d.ts.map +1 -0
  140. package/types/src/primitives/registry.d.ts.map +1 -1
  141. package/types/src/primitives/saider.d.ts +12 -7
  142. package/types/src/primitives/saider.d.ts.map +1 -1
  143. package/types/src/primitives/salter.d.ts +13 -0
  144. package/types/src/primitives/salter.d.ts.map +1 -0
  145. package/types/src/primitives/sealer.d.ts +16 -8
  146. package/types/src/primitives/sealer.d.ts.map +1 -1
  147. package/types/src/primitives/seqner.d.ts +12 -7
  148. package/types/src/primitives/seqner.d.ts.map +1 -1
  149. package/types/src/primitives/siger.d.ts +16 -0
  150. package/types/src/primitives/siger.d.ts.map +1 -0
  151. package/types/src/primitives/signer.d.ts +14 -0
  152. package/types/src/primitives/signer.d.ts.map +1 -0
  153. package/types/src/primitives/structor.d.ts +44 -0
  154. package/types/src/primitives/structor.d.ts.map +1 -0
  155. package/types/src/primitives/tagger.d.ts +17 -0
  156. package/types/src/primitives/tagger.d.ts.map +1 -0
  157. package/types/src/primitives/texter.d.ts +11 -6
  158. package/types/src/primitives/texter.d.ts.map +1 -1
  159. package/types/src/primitives/tholder.d.ts +11 -6
  160. package/types/src/primitives/tholder.d.ts.map +1 -1
  161. package/types/src/primitives/traitor.d.ts +13 -6
  162. package/types/src/primitives/traitor.d.ts.map +1 -1
  163. package/types/src/primitives/unknown.d.ts +31 -0
  164. package/types/src/primitives/unknown.d.ts.map +1 -0
  165. package/types/src/primitives/verfer.d.ts +12 -7
  166. package/types/src/primitives/verfer.d.ts.map +1 -1
  167. package/types/src/primitives/verser.d.ts +18 -8
  168. package/types/src/primitives/verser.d.ts.map +1 -1
  169. package/types/src/serder/serder.d.ts +69 -3
  170. package/types/src/serder/serder.d.ts.map +1 -1
  171. package/types/src/serder/serdery.d.ts.map +1 -1
  172. package/types/src/tables/codex-utils.d.ts +4 -0
  173. package/types/src/tables/codex-utils.d.ts.map +1 -0
  174. package/types/src/tables/counter-codex.d.ts.map +1 -1
  175. package/types/src/tables/counter-groups.d.ts +8 -0
  176. package/types/src/tables/counter-groups.d.ts.map +1 -0
  177. package/types/src/tables/indexer.codex.generated.d.ts +127 -0
  178. package/types/src/tables/indexer.codex.generated.d.ts.map +1 -0
  179. package/types/src/tables/indexer.tables.generated.d.ts +46 -0
  180. package/types/src/tables/indexer.tables.generated.d.ts.map +1 -0
  181. package/types/src/tables/matter.codex.generated.d.ts +797 -0
  182. package/types/src/tables/matter.codex.generated.d.ts.map +1 -0
  183. package/types/src/tables/matter.tables.generated.d.ts +112 -0
  184. package/types/src/tables/matter.tables.generated.d.ts.map +1 -1
  185. package/types/src/tables/table-types.d.ts +7 -0
  186. package/types/src/tables/table-types.d.ts.map +1 -1
  187. package/types/src/tables/trait.codex.generated.d.ts +19 -0
  188. package/types/src/tables/trait.codex.generated.d.ts.map +1 -0
  189. package/types/src/version.d.ts +2 -2
  190. package/esm/src/tables/indexer.tables.js +0 -30
  191. package/types/src/tables/indexer.tables.d.ts +0 -12
  192. package/types/src/tables/indexer.tables.d.ts.map +0 -1
package/esm/src/index.js CHANGED
@@ -1,50 +1,76 @@
1
- export * from "./core/types.js";
1
+ export * from "./adapters/async-iterable.js";
2
+ export * from "./adapters/effection.js";
3
+ export * from "./annotate/annotator.js";
4
+ export * from "./annotate/comments.js";
5
+ export * from "./annotate/denot.js";
6
+ export * from "./annotate/render.js";
7
+ export * from "./annotate/types.js";
8
+ export * from "./bench/parser-benchmark.js";
9
+ export * from "./core/bytes.js";
10
+ export * from "./core/cbor.js";
2
11
  export * from "./core/errors.js";
3
12
  export * from "./core/parser-engine.js";
4
13
  export * from "./core/parser-policy.js";
5
14
  export * from "./core/recovery-diagnostics.js";
15
+ export * from "./core/types.js";
6
16
  export * from "./parser/cold-start.js";
7
17
  export * from "./parser/group-dispatch.js";
8
- export * from "./serder/smell.js";
9
- export * from "./serder/serder.js";
10
- export * from "./serder/serdery.js";
11
- export * from "./primitives/matter.js";
18
+ export * from "./primitives/aggor.js";
19
+ export * from "./primitives/bexter.js";
20
+ export * from "./primitives/blinder.js";
21
+ export * from "./primitives/cigar.js";
22
+ export * from "./primitives/cipher.js";
23
+ export * from "./primitives/codex.js";
24
+ export * from "./primitives/compactor.js";
12
25
  export * from "./primitives/counter.js";
13
- export * from "./primitives/indexer.js";
14
- export * from "./primitives/verser.js";
26
+ export * from "./primitives/dater.js";
27
+ export * from "./primitives/decimer.js";
28
+ export * from "./primitives/decrypter.js";
29
+ export * from "./primitives/diger.js";
30
+ export * from "./primitives/encrypter.js";
15
31
  export * from "./primitives/ilker.js";
32
+ export * from "./primitives/indexer.js";
16
33
  export * from "./primitives/labeler.js";
17
- export * from "./primitives/texter.js";
18
- export * from "./primitives/bexter.js";
19
- export * from "./primitives/pather.js";
20
34
  export * from "./primitives/mapper.js";
35
+ export * from "./primitives/matter.js";
36
+ export * from "./primitives/mediar.js";
37
+ export * from "./primitives/noncer.js";
21
38
  export * from "./primitives/number.js";
22
- export * from "./primitives/seqner.js";
23
- export * from "./primitives/dater.js";
24
- export * from "./primitives/diger.js";
39
+ export * from "./primitives/pather.js";
25
40
  export * from "./primitives/prefixer.js";
26
- export * from "./primitives/noncer.js";
41
+ export * from "./primitives/primitive.js";
42
+ export * from "./primitives/registry.js";
27
43
  export * from "./primitives/saider.js";
28
- export * from "./primitives/cigar.js";
29
- export * from "./primitives/verfer.js";
30
- export * from "./primitives/traitor.js";
31
- export * from "./primitives/tholder.js";
44
+ export * from "./primitives/salter.js";
32
45
  export * from "./primitives/sealer.js";
33
- export * from "./primitives/blinder.js";
34
- export * from "./primitives/mediar.js";
35
- export * from "./primitives/compactor.js";
36
- export * from "./primitives/aggor.js";
37
- export * from "./primitives/registry.js";
38
- export * from "./adapters/async-iterable.js";
39
- export * from "./adapters/effection.js";
46
+ export * from "./primitives/seqner.js";
47
+ export * from "./primitives/siger.js";
48
+ export * from "./primitives/signer.js";
49
+ export * from "./primitives/structor.js";
50
+ export * from "./primitives/tagger.js";
51
+ export * from "./primitives/texter.js";
52
+ export * from "./primitives/tholder.js";
53
+ export * from "./primitives/traitor.js";
54
+ export * from "./primitives/unknown.js";
55
+ export * from "./primitives/verfer.js";
56
+ export * from "./primitives/verser.js";
40
57
  export * from "./router/router-stub.js";
41
- export * from "./tables/versions.js";
42
- export * from "./tables/table-types.js";
58
+ export * from "./serder/serder.js";
59
+ export * from "./serder/serdery.js";
60
+ export * from "./serder/smell.js";
61
+ export * from "./tables/codex-utils.js";
43
62
  export * from "./tables/counter-codex.js";
63
+ export * from "./tables/counter-groups.js";
44
64
  export * from "./tables/counter-version-registry.js";
45
- export * from "./annotate/types.js";
46
- export * from "./annotate/comments.js";
47
- export * from "./annotate/render.js";
48
- export * from "./annotate/annotator.js";
49
- export * from "./annotate/denot.js";
50
- export * from "./bench/parser-benchmark.js";
65
+ export * from "./tables/indexer.codex.generated.js";
66
+ export * from "./tables/indexer.tables.generated.js";
67
+ export * from "./tables/matter.codex.generated.js";
68
+ export * from "./tables/matter.tables.generated.js";
69
+ export * from "./tables/table-types.js";
70
+ export * from "./tables/trait.codex.generated.js";
71
+ export * from "./tables/versions.js";
72
+ export { bytesHex } from "./core/bytes.js";
73
+ export { bytesEqual } from "./core/bytes.js";
74
+ export { toBytes } from "./core/bytes.js";
75
+ export { t } from "./core/bytes.js";
76
+ export { b } from "./core/bytes.js";
@@ -1,4 +1,4 @@
1
- import { parseAttachmentDispatchCompat, } from "./group-dispatch.js";
1
+ import { parseAttachmentDispatchCompat } from "./group-dispatch.js";
2
2
  export function parseAttachmentGroup(input, version, domain, options = {}) {
3
3
  return parseAttachmentDispatchCompat(input, version, domain, options);
4
4
  }
@@ -1,24 +1,16 @@
1
- import { parseCounter } from "../primitives/counter.js";
2
- import { parseMatter } from "../primitives/matter.js";
1
+ import { b, b64ToInt, intToB64 } from "../core/bytes.js";
2
+ import { GroupSizeError, ShortageError, UnknownCodeError } from "../core/errors.js";
3
+ import { composeRecoveryDiagnosticObserver, } from "../core/recovery-diagnostics.js";
4
+ import { CounterGroup, parseCounter } from "../primitives/counter.js";
3
5
  import { parseIndexer } from "../primitives/indexer.js";
4
- import { GroupSizeError, ShortageError, UnknownCodeError, } from "../core/errors.js";
6
+ import { parseMatter } from "../primitives/matter.js";
7
+ import { UnknownPrimitive } from "../primitives/unknown.js";
5
8
  import { CtrDexV1, CtrDexV2 } from "../tables/counter-codex.js";
6
9
  import { resolveVersionedRegistryValue, } from "../tables/counter-version-registry.js";
7
- import { b64ToInt, intToB64 } from "../core/bytes.js";
8
- import { composeRecoveryDiagnosticObserver, } from "../core/recovery-diagnostics.js";
9
10
  import { createAttachmentVersionFallbackPolicy, } from "./attachment-fallback-policy.js";
10
- export { createAttachmentVersionFallbackPolicy, } from "./attachment-fallback-policy.js";
11
- function qb64Item(qb64, opaque = false) {
12
- return { kind: "qb64", qb64, opaque };
13
- }
14
- function qb2Item(qb2, opaque = false) {
15
- return { kind: "qb2", qb2, opaque };
16
- }
11
+ export { createAttachmentVersionFallbackPolicy } from "./attachment-fallback-policy.js";
17
12
  function tupleItem(items) {
18
- return { kind: "tuple", items };
19
- }
20
- function nestedGroupItem(code, name, count) {
21
- return { kind: "group", code, name, count };
13
+ return items;
22
14
  }
23
15
  /** Normalize unknown throwables to an `Error` for diagnostic emission. */
24
16
  function asError(error) {
@@ -352,7 +344,7 @@ function parseTuple(input, kinds, domain) {
352
344
  const part = kind === "indexer"
353
345
  ? parseIndexer(input.slice(offset), domain)
354
346
  : parseMatter(input.slice(offset), domain);
355
- items.push(qb64Item(part.qb64));
347
+ items.push(part);
356
348
  offset += primitiveSize(part, domain);
357
349
  }
358
350
  return { items, consumed: offset };
@@ -369,16 +361,16 @@ function parseRepeated(input, count, kinds, domain) {
369
361
  return { items, consumed: offset };
370
362
  }
371
363
  /** Split opaque counted payload into domain units (quadlets for text, triplets for binary). */
372
- function splitOpaqueUnits(payload, domain, expectedCount, opaque = false) {
364
+ function splitOpaqueUnits(payload, domain, expectedCount) {
373
365
  if (domain === "bny") {
374
366
  const count = expectedCount ?? Math.floor(payload.length / 3);
375
- return Array.from({ length: count }, (_v, i) => qb2Item(payload.slice(i * 3, i * 3 + 3), opaque));
367
+ return Array.from({ length: count }, (_v, i) => UnknownPrimitive.fromPayload(payload.slice(i * 3, i * 3 + 3), domain));
376
368
  }
377
369
  const text = String.fromCharCode(...payload);
378
370
  if (expectedCount !== undefined) {
379
- return Array.from({ length: expectedCount }, (_v, i) => qb64Item(text.slice(i * 4, i * 4 + 4), opaque));
371
+ return Array.from({ length: expectedCount }, (_v, i) => UnknownPrimitive.fromPayload(b(text.slice(i * 4, i * 4 + 4)), domain));
380
372
  }
381
- return (text.match(/.{1,4}/g) ?? []).map((token) => qb64Item(token, opaque));
373
+ return (text.match(/.{1,4}/g) ?? []).map((token) => UnknownPrimitive.fromPayload(b(token), domain));
382
374
  }
383
375
  /** Parse nested siger-list group headed by a version-appropriate siger counter. */
384
376
  function parseSigerList(input, version, domain) {
@@ -391,7 +383,7 @@ function parseSigerList(input, version, domain) {
391
383
  let offset = counterHeaderSize(counter, domain);
392
384
  for (let i = 0; i < counter.count; i++) {
393
385
  const part = parseIndexer(input.slice(offset), domain);
394
- items.push(qb64Item(part.qb64));
386
+ items.push(part);
395
387
  offset += primitiveSize(part, domain);
396
388
  }
397
389
  return { items, consumed: offset };
@@ -432,7 +424,7 @@ function parseQuadletGroup(input, counter, version, wrapperCodes, domain, contex
432
424
  // Allow mixed-version nested groups inside wrapper payloads.
433
425
  // Some real-world streams wrap v2 groups inside v1 wrappers.
434
426
  payload.slice(offset), nestedVersion, domain, context);
435
- items.push(nestedGroupItem(nested.group.code, nested.group.name, nested.group.count));
427
+ items.push(nested.group);
436
428
  if (nested.consumed === 0) {
437
429
  throw new GroupSizeError("Nested attachment parser consumed zero bytes");
438
430
  }
@@ -440,8 +432,8 @@ function parseQuadletGroup(input, counter, version, wrapperCodes, domain, contex
440
432
  }
441
433
  catch (error) {
442
434
  const normalized = asError(error);
443
- if (normalized instanceof ShortageError ||
444
- normalized instanceof GroupSizeError) {
435
+ if (normalized instanceof ShortageError
436
+ || normalized instanceof GroupSizeError) {
445
437
  throw normalized;
446
438
  }
447
439
  if (!context.versionFallbackPolicy.shouldPreserveWrapperRemainder(normalized)) {
@@ -449,7 +441,7 @@ function parseQuadletGroup(input, counter, version, wrapperCodes, domain, contex
449
441
  }
450
442
  // Intentional recovery point: keep unread wrapper tail as opaque units.
451
443
  const remainder = payload.slice(offset);
452
- const opaque = splitOpaqueUnits(remainder, domain, undefined, true);
444
+ const opaque = splitOpaqueUnits(remainder, domain);
453
445
  context.recoveryDiagnosticObserver?.({
454
446
  type: "wrapper-opaque-tail-preserved",
455
447
  version: nestedVersion,
@@ -519,8 +511,8 @@ function sadPathSigParser(input, counter, version, domain, context) {
519
511
  const sigGroup = parseAttachmentDispatchCompat(input.slice(offset), version, domain, context);
520
512
  offset += sigGroup.consumed;
521
513
  items.push(tupleItem([
522
- qb64Item(path.qb64),
523
- nestedGroupItem(sigGroup.group.code, sigGroup.group.name, sigGroup.group.count),
514
+ path,
515
+ sigGroup.group,
524
516
  ]));
525
517
  }
526
518
  return { items, consumed: offset };
@@ -531,15 +523,15 @@ function sadPathSigGroupParser(input, counter, version, domain, context) {
531
523
  let offset = counterHeaderSize(counter, domain);
532
524
  const root = parseMatter(input.slice(offset), domain);
533
525
  offset += primitiveSize(root, domain);
534
- items.push(qb64Item(root.qb64));
526
+ items.push(root);
535
527
  for (let i = 0; i < counter.count; i++) {
536
528
  const path = parseMatter(input.slice(offset), domain);
537
529
  offset += primitiveSize(path, domain);
538
530
  const sigGroup = parseAttachmentDispatchCompat(input.slice(offset), version, domain, context);
539
531
  offset += sigGroup.consumed;
540
532
  items.push(tupleItem([
541
- qb64Item(path.qb64),
542
- nestedGroupItem(sigGroup.group.code, sigGroup.group.name, sigGroup.group.count),
533
+ path,
534
+ sigGroup.group,
543
535
  ]));
544
536
  }
545
537
  return { items, consumed: offset };
@@ -547,7 +539,7 @@ function sadPathSigGroupParser(input, counter, version, domain, context) {
547
539
  /** Genus-version groups carry only the counter token itself as semantic payload. */
548
540
  function genusVersionParser(_input, counter, _version, domain, _context) {
549
541
  return {
550
- items: [qb64Item(counter.qb64)],
542
+ items: [counter],
551
543
  consumed: counterHeaderSize(counter, domain),
552
544
  };
553
545
  }
@@ -648,13 +640,7 @@ function parseAttachmentDispatchWithVersion(input, version, domain, context) {
648
640
  throw new GroupSizeError(`Parsed beyond input boundary for ${counter.code}`);
649
641
  }
650
642
  return {
651
- group: {
652
- code: counter.code,
653
- name: counter.name,
654
- count: counter.count,
655
- raw: input.slice(0, parsed.consumed),
656
- items: parsed.items,
657
- },
643
+ group: new CounterGroup(counter, input.slice(0, parsed.consumed), parsed.items),
658
644
  consumed: parsed.consumed,
659
645
  };
660
646
  }
@@ -702,8 +688,8 @@ function parseAttachmentDispatchWithPolicy(input, version, domain, context) {
702
688
  * `options.versionFallbackPolicy`.
703
689
  */
704
690
  export function parseAttachmentDispatchCompat(input, version, domain, options = {}) {
705
- const versionFallbackPolicy = options.versionFallbackPolicy ??
706
- createAttachmentVersionFallbackPolicy({
691
+ const versionFallbackPolicy = options.versionFallbackPolicy
692
+ ?? createAttachmentVersionFallbackPolicy({
707
693
  mode: options.mode,
708
694
  });
709
695
  const recoveryDiagnosticObserver = composeRecoveryDiagnosticObserver({
@@ -1,41 +1,84 @@
1
1
  import { UnknownCodeError } from "../core/errors.js";
2
- import { CtrDexV2 } from "../tables/counter-codex.js";
3
- import { parseAttachmentDispatch } from "../parser/group-dispatch.js";
2
+ import { AGGOR_CODES, AGGOR_LIST_CODES, AGGOR_MAP_CODES } from "../tables/counter-groups.js";
4
3
  import { parseCompactor } from "./compactor.js";
5
4
  import { parseCounter } from "./counter.js";
6
- const AGGOR_LIST_CODES = new Set([
7
- CtrDexV2.GenericGroup,
8
- CtrDexV2.BigGenericGroup,
9
- CtrDexV2.GenericListGroup,
10
- CtrDexV2.BigGenericListGroup,
11
- ]);
12
- const AGGOR_MAP_CODES = new Set([
13
- CtrDexV2.MapBodyGroup,
14
- CtrDexV2.BigMapBodyGroup,
15
- CtrDexV2.GenericMapGroup,
16
- CtrDexV2.BigGenericMapGroup,
17
- ]);
5
+ import { parseStructor, Structor } from "./structor.js";
6
+ /** True when counter code belongs to aggregate-list group families. */
7
+ export function isAggorListCode(code) {
8
+ return AGGOR_LIST_CODES.has(code);
9
+ }
10
+ /** True when counter code belongs to aggregate-map group families. */
11
+ export function isAggorMapCode(code) {
12
+ return AGGOR_MAP_CODES.has(code);
13
+ }
14
+ /** True when counter code belongs to any aggregate list/map family. */
15
+ export function isAggorCode(code) {
16
+ return AGGOR_CODES.has(code);
17
+ }
18
+ /**
19
+ * Aggregate list/map structor primitive.
20
+ *
21
+ * KERIpy substance: `Aggor` represents counted aggregate list/map payload
22
+ * groups and exposes either tuple/list items or semantic map fields.
23
+ */
24
+ export class Aggor extends Structor {
25
+ constructor(init) {
26
+ const payload = init instanceof Structor
27
+ ? { structor: init }
28
+ : "structor" in init
29
+ ? init
30
+ : {
31
+ structor: new Structor(init),
32
+ };
33
+ super(payload.structor);
34
+ Object.defineProperty(this, "kind", {
35
+ enumerable: true,
36
+ configurable: true,
37
+ writable: true,
38
+ value: void 0
39
+ });
40
+ Object.defineProperty(this, "mapFields", {
41
+ enumerable: true,
42
+ configurable: true,
43
+ writable: true,
44
+ value: void 0
45
+ });
46
+ if (!isAggorCode(this.code)) {
47
+ throw new UnknownCodeError(`Expected aggregate list/map group code, got ${this.code}`);
48
+ }
49
+ this.kind = isAggorMapCode(this.code) ? "map" : "list";
50
+ this.mapFields = payload.mapFields;
51
+ }
52
+ /** Tuple/list payload items for aggregate-list families. */
53
+ get listItems() {
54
+ return this.kind === "list" ? this.items : undefined;
55
+ }
56
+ /** Hydrate from an already parsed counter-group node. */
57
+ static fromGroup(group, sourceDomain = "txt") {
58
+ return new Aggor({ structor: Structor.fromGroup(group, sourceDomain) });
59
+ }
60
+ }
61
+ /**
62
+ * Parse aggregate attachment groups as list/map semantic containers.
63
+ *
64
+ * KERIpy substance: aggregate counters can represent generic lists or map-body
65
+ * structures; this helper normalizes both into one discriminated result.
66
+ */
18
67
  export function parseAggor(input, version, cold) {
19
68
  const counter = parseCounter(input, version, cold);
20
- if (AGGOR_MAP_CODES.has(counter.code)) {
69
+ if (!isAggorCode(counter.code)) {
70
+ throw new UnknownCodeError(`Expected aggregate list/map group code, got ${counter.code}`);
71
+ }
72
+ const structor = parseStructor(input, version, cold, new Set([counter.code]), "aggregate list/map");
73
+ if (isAggorMapCode(structor.code)) {
21
74
  const map = parseCompactor(input, version, cold);
22
- return {
23
- code: map.code,
24
- count: map.count,
25
- kind: "map",
75
+ return new Aggor({
76
+ structor,
26
77
  mapFields: map.fields,
27
- consumed: cold === "bny" ? map.totalSizeB2 : map.totalSize,
28
- };
78
+ });
29
79
  }
30
- if (AGGOR_LIST_CODES.has(counter.code)) {
31
- const parsed = parseAttachmentDispatch(input, version, cold);
32
- return {
33
- code: parsed.group.code,
34
- count: parsed.group.count,
35
- kind: "list",
36
- listItems: parsed.group.items,
37
- consumed: parsed.consumed,
38
- };
80
+ if (isAggorListCode(structor.code)) {
81
+ return new Aggor(structor);
39
82
  }
40
- throw new UnknownCodeError(`Expected aggregate list/map group code, got ${counter.code}`);
83
+ throw new UnknownCodeError(`Expected aggregate list/map group code, got ${structor.code}`);
41
84
  }
@@ -1,20 +1,64 @@
1
+ import { decodeB64, encodeB64 } from "../core/bytes.js";
1
2
  import { UnknownCodeError } from "../core/errors.js";
2
- import { parseMatter } from "./matter.js";
3
- import { MATTER_CODE_NAMES } from "../tables/matter.tables.generated.js";
4
- function isBexterCode(code) {
5
- const name = MATTER_CODE_NAMES[code] ?? "";
6
- return name.startsWith("StrB64_") || name.startsWith("StrB64_Big_");
3
+ import { MATTER_SIZES } from "../tables/matter.tables.generated.js";
4
+ import { BEXTER_CODES } from "./codex.js";
5
+ import { Matter, parseMatter } from "./matter.js";
6
+ /** Resolve lead-byte width (`ls`) used by StrB64 code family conversions. */
7
+ function getLeadSize(code) {
8
+ const sizage = MATTER_SIZES.get(code);
9
+ if (!sizage) {
10
+ throw new UnknownCodeError(`Unknown bexter code ${code}`);
11
+ }
12
+ return sizage.ls;
7
13
  }
8
- export function parseBexter(input, cold) {
9
- const matter = parseMatter(input, cold);
10
- if (!isBexterCode(matter.code)) {
11
- throw new UnknownCodeError(`Expected bexter strb64 code, got ${matter.code}`);
14
+ /** True when code belongs to KERIpy `BextCodex`/StrB64 family. */
15
+ export function isBexterCode(code) {
16
+ return BEXTER_CODES.has(code);
17
+ }
18
+ /**
19
+ * CESR Base64-text primitive (`bext`) with compact StrB64 encoding.
20
+ *
21
+ * KERIpy correspondence:
22
+ * - mirrors the `Bexter`/StrB64 family contract: payload text is already
23
+ * restricted to Base64 URL-safe characters, so the qualified form can be more
24
+ * compact than generic UTF-8 text primitives
25
+ *
26
+ * Invariant:
27
+ * - `code` must belong to the StrB64/Bexter codex family
28
+ */
29
+ export class Bexter extends Matter {
30
+ /** Convert bext text into CESR raw payload bytes. */
31
+ static rawify(bext) {
32
+ const ts = bext.length % 4;
33
+ const ws = (4 - ts) % 4;
34
+ const ls = (3 - ts) % 3;
35
+ return decodeB64("A".repeat(ws) + bext).slice(ls);
36
+ }
37
+ /** Decode CESR raw payload bytes back into bext text. */
38
+ static derawify(raw, code) {
39
+ const ls = getLeadSize(code);
40
+ const bext = encodeB64(new Uint8Array([...new Uint8Array(ls), ...raw]));
41
+ const ws = ls === 0 && bext.startsWith("A") ? 1 : (ls + 1) % 4;
42
+ return bext.slice(ws);
12
43
  }
13
- return {
14
- code: matter.code,
15
- qb64: matter.qb64,
16
- bext: new TextDecoder().decode(matter.raw),
17
- fullSize: matter.fullSize,
18
- fullSizeB2: matter.fullSizeB2,
19
- };
44
+ constructor(init) {
45
+ const matter = init instanceof Matter ? init : new Matter(init);
46
+ super(matter);
47
+ if (!isBexterCode(this.code)) {
48
+ throw new UnknownCodeError(`Expected bexter strb64 code, got ${this.code}`);
49
+ }
50
+ }
51
+ /** Base64 text payload value without CESR code prefix. */
52
+ get bext() {
53
+ return Bexter.derawify(this.raw, this.code);
54
+ }
55
+ }
56
+ /**
57
+ * Parse and hydrate a `Bexter` from txt/qb2 bytes.
58
+ *
59
+ * Boundary contract: parser chooses domain from `cold`, while this constructor
60
+ * enforces codex membership and exposes semantic `bext` accessors.
61
+ */
62
+ export function parseBexter(input, cold) {
63
+ return new Bexter(parseMatter(input, cold));
20
64
  }
@@ -1,23 +1,30 @@
1
1
  import { UnknownCodeError } from "../core/errors.js";
2
- import { CtrDexV2 } from "../tables/counter-codex.js";
3
- import { parseAttachmentDispatch } from "../parser/group-dispatch.js";
4
- const BLINDER_CODES = new Set([
5
- CtrDexV2.BlindedStateQuadruples,
6
- CtrDexV2.BigBlindedStateQuadruples,
7
- CtrDexV2.BoundStateSextuples,
8
- CtrDexV2.BigBoundStateSextuples,
9
- ]);
10
- export function parseBlinder(input, version, cold) {
11
- const parsed = parseAttachmentDispatch(input, version, cold);
12
- if (!BLINDER_CODES.has(parsed.group.code)) {
13
- throw new UnknownCodeError(`Expected blinder group code, got ${parsed.group.code}`);
2
+ import { BLINDER_CODES } from "../tables/counter-groups.js";
3
+ import { parseStructor, Structor } from "./structor.js";
4
+ /** True when counter code belongs to blinded/bound state tuple families. */
5
+ export function isBlinderCode(code) {
6
+ return BLINDER_CODES.has(code);
7
+ }
8
+ /**
9
+ * Blinded-state structor primitive.
10
+ *
11
+ * KERIpy substance: `Blinder` materializes blinded/bound state tuple groups
12
+ * used for blindable ACDC/TEL state disclosures.
13
+ */
14
+ export class Blinder extends Structor {
15
+ constructor(init) {
16
+ const structor = init instanceof Structor ? init : new Structor(init);
17
+ super(structor);
18
+ if (!isBlinderCode(this.code)) {
19
+ throw new UnknownCodeError(`Expected blinder group code, got ${this.code}`);
20
+ }
21
+ }
22
+ /** Hydrate a `Blinder` from an already parsed counter-group node. */
23
+ static fromGroup(group, sourceDomain = "txt") {
24
+ return new Blinder({ group, sourceDomain });
14
25
  }
15
- return {
16
- code: parsed.group.code,
17
- name: parsed.group.name,
18
- count: parsed.group.count,
19
- items: parsed.group.items,
20
- raw: parsed.group.raw,
21
- consumed: parsed.consumed,
22
- };
26
+ }
27
+ /** Parse and validate blinded-state attachment groups. */
28
+ export function parseBlinder(input, version, cold) {
29
+ return new Blinder(parseStructor(input, version, cold, BLINDER_CODES, "blinder"));
23
30
  }
@@ -1,18 +1,28 @@
1
1
  import { UnknownCodeError } from "../core/errors.js";
2
- import { parseMatter } from "./matter.js";
3
- import { MATTER_CODE_NAMES } from "../tables/matter.tables.generated.js";
4
- export function parseCigar(input, cold) {
5
- const matter = parseMatter(input, cold);
6
- const name = MATTER_CODE_NAMES[matter.code] ?? "";
7
- if (!name.endsWith("_Sig")) {
8
- throw new UnknownCodeError(`Expected non-indexed signature code, got ${matter.code}`);
2
+ import { CIGAR_CODES, matterCodexName } from "./codex.js";
3
+ import { Matter, parseMatter } from "./matter.js";
4
+ /**
5
+ * Non-indexed signature primitive.
6
+ *
7
+ * KERIpy substance: `Cigar` wraps detached signature material where code
8
+ * determines signature suite and payload holds raw signature bytes.
9
+ */
10
+ export class Cigar extends Matter {
11
+ constructor(init) {
12
+ const matter = init instanceof Matter ? init : new Matter(init);
13
+ super(matter);
14
+ if (!CIGAR_CODES.has(this.code)) {
15
+ throw new UnknownCodeError(`Expected non-indexed signature code, got ${this.code}`);
16
+ }
17
+ }
18
+ get sig() {
19
+ return this.raw;
20
+ }
21
+ get algorithm() {
22
+ return matterCodexName(this.code) ?? "UnknownSig";
9
23
  }
10
- return {
11
- code: matter.code,
12
- qb64: matter.qb64,
13
- sig: matter.raw,
14
- algorithm: name,
15
- fullSize: matter.fullSize,
16
- fullSizeB2: matter.fullSizeB2,
17
- };
24
+ }
25
+ /** Parse and hydrate `Cigar` from txt/qb2 bytes. */
26
+ export function parseCigar(input, cold) {
27
+ return new Cigar(parseMatter(input, cold));
18
28
  }
@@ -0,0 +1,18 @@
1
+ import { UnknownCodeError } from "../core/errors.js";
2
+ import { CIPHER_X25519_ALL_CODES } from "./codex.js";
3
+ import { Matter } from "./matter.js";
4
+ /**
5
+ * Ciphertext primitive for encrypted secret payloads.
6
+ *
7
+ * KERIpy substance: cipher material carries encrypted seed/salt-like plaintext
8
+ * while code determines ciphertext family/size semantics.
9
+ */
10
+ export class Cipher extends Matter {
11
+ constructor(init) {
12
+ const matter = init instanceof Matter ? init : new Matter(init);
13
+ super(matter);
14
+ if (!CIPHER_X25519_ALL_CODES.has(this.code)) {
15
+ throw new UnknownCodeError(`Expected cipher code, got ${this.code}`);
16
+ }
17
+ }
18
+ }