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
@@ -0,0 +1,74 @@
1
+ import { codexValues, invertCodex } from "../tables/codex-utils.js";
2
+ import { IdrDex, IdxBthSigDex, IdxCrtSigDex, IdxSigDex, } from "../tables/indexer.codex.generated.js";
3
+ import { BexDex, CiXAllQB64Dex, CiXDex, CiXFixQB64Dex, CiXVarDex, CiXVarQB2Dex, CiXVarQB64Dex, CiXVarStrmDex, DecDex, DigDex, EscapeDex, LabelDex, MtrDex, NonceDex, NonTransDex, NumDex, PreDex, PreNonDigDex, TagDex, TexDex, } from "../tables/matter.codex.generated.js";
4
+ import { TraitDex } from "../tables/trait.codex.generated.js";
5
+ import { Protocols } from "../tables/versions.js";
6
+ /**
7
+ * Derived readability layer over the generated KERIpy-parity codex objects.
8
+ *
9
+ * Canonical names such as `MtrDex`, `PreDex`, `DigDex`, and `IdrDex` are the
10
+ * primary source of truth. The sets exported here are convenience views for
11
+ * primitive-family validation and TS ergonomics.
12
+ */
13
+ export { BexDex, CiXAllQB64Dex, CiXDex, CiXFixQB64Dex, CiXVarDex, CiXVarQB2Dex, CiXVarQB64Dex, CiXVarStrmDex, DecDex, DigDex, EscapeDex, IdrDex, IdxBthSigDex, IdxCrtSigDex, IdxSigDex, LabelDex, MtrDex, NonceDex, NonTransDex, NumDex, PreDex, PreNonDigDex, TagDex, TexDex, TraitDex, };
14
+ export const BEXTER_CODES = codexValues(BexDex);
15
+ export const TEXTER_CODES = codexValues(TexDex);
16
+ export const DECIMAL_CODES = codexValues(DecDex);
17
+ export const DIGEST_CODES = codexValues(DigDex);
18
+ export const NONCE_CODES = codexValues(NonceDex);
19
+ export const NUMBER_CODES = codexValues(NumDex);
20
+ export const TAG_CODES = codexValues(TagDex);
21
+ export const LABELER_CODES = codexValues(LabelDex);
22
+ export const PREFIX_CODES = codexValues(PreDex);
23
+ export const NON_TRANSFERABLE_PREFIX_CODES = codexValues(NonTransDex);
24
+ export const NON_DIGEST_PREFIX_CODES = codexValues(PreNonDigDex);
25
+ export const ESCAPE_CODES = codexValues(EscapeDex);
26
+ export const CIPHER_X25519_VARIABLE_STREAM_CODES = codexValues(CiXVarStrmDex);
27
+ export const CIPHER_X25519_QB64_VARIABLE_CODES = codexValues(CiXVarQB64Dex);
28
+ export const CIPHER_X25519_FIXED_QB64_CODES = codexValues(CiXFixQB64Dex);
29
+ export const CIPHER_X25519_ALL_QB64_CODES = codexValues(CiXAllQB64Dex);
30
+ export const CIPHER_X25519_ALL_VARIABLE_CODES = codexValues(CiXVarDex);
31
+ export const CIPHER_X25519_QB2_VARIABLE_CODES = codexValues(CiXVarQB2Dex);
32
+ export const CIPHER_X25519_ALL_CODES = codexValues(CiXDex);
33
+ export const INDEXER_CODES = codexValues(IdrDex);
34
+ export const INDEXED_SIG_CODES = codexValues(IdxSigDex);
35
+ export const INDEXED_CURRENT_SIG_CODES = codexValues(IdxCrtSigDex);
36
+ export const INDEXED_BOTH_SIG_CODES = codexValues(IdxBthSigDex);
37
+ export const VERFER_CODES = NON_DIGEST_PREFIX_CODES;
38
+ export const SIGER_CODES = INDEXED_SIG_CODES;
39
+ export const DATER_CODES = new Set([MtrDex.DateTime]);
40
+ export const SEQNER_CODES = new Set([MtrDex.Salt_128]);
41
+ export const ILKER_CODES = new Set([MtrDex.Tag3]);
42
+ export const THOLDER_WEIGHTED_CODES = BEXTER_CODES;
43
+ export const THOLDER_NUMERIC_CODES = NUMBER_CODES;
44
+ export const THOLDER_CODES = new Set([
45
+ ...THOLDER_NUMERIC_CODES,
46
+ ...THOLDER_WEIGHTED_CODES,
47
+ ]);
48
+ export const SIGNER_CODES = new Set([
49
+ MtrDex.Ed25519_Seed,
50
+ MtrDex.ECDSA_256k1_Seed,
51
+ MtrDex.ECDSA_256r1_Seed,
52
+ ]);
53
+ export const SALTER_CODES = new Set([MtrDex.Salt_128]);
54
+ export const ENCRYPTER_CODES = new Set([MtrDex.X25519]);
55
+ export const DECRYPTER_CODES = new Set([MtrDex.X25519_Private]);
56
+ export const CIGAR_CODES = new Set([
57
+ MtrDex.Ed25519_Sig,
58
+ MtrDex.ECDSA_256k1_Sig,
59
+ MtrDex.ECDSA_256r1_Sig,
60
+ MtrDex.Ed448_Sig,
61
+ ]);
62
+ export const TRAIT_TAGS = new Set([
63
+ ...codexValues(TraitDex),
64
+ ]);
65
+ export const VERSER_CODES = new Set([MtrDex.Tag7, MtrDex.Tag10]);
66
+ export const VERSER_PROTOCOLS = new Set(Object.values(Protocols));
67
+ const MATTER_CODEX_NAMES = invertCodex(MtrDex);
68
+ export function matterCodexName(code) {
69
+ return MATTER_CODEX_NAMES.get(code);
70
+ }
71
+ /** KERI attribute-name validator used by Labeler semantic projection. */
72
+ export function isAttLabel(value) {
73
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(value);
74
+ }
@@ -1,12 +1,6 @@
1
1
  import { UnknownCodeError } from "../core/errors.js";
2
- import { CtrDexV2 } from "../tables/counter-codex.js";
2
+ import { COMPACTOR_CODES } from "../tables/counter-groups.js";
3
3
  import { parseMapperBody } from "./mapper.js";
4
- const COMPACTOR_CODES = new Set([
5
- CtrDexV2.MapBodyGroup,
6
- CtrDexV2.BigMapBodyGroup,
7
- CtrDexV2.GenericMapGroup,
8
- CtrDexV2.BigGenericMapGroup,
9
- ]);
10
4
  export function parseCompactor(input, version, cold) {
11
5
  const mapper = parseMapperBody(input, version, cold);
12
6
  if (!COMPACTOR_CODES.has(mapper.code)) {
@@ -1,18 +1,24 @@
1
- import { b64ToInt, codeB2ToB64, codeB64ToB2, nabSextets, sceil, } from "../core/bytes.js";
2
- import { DeserializeError, ShortageError, UnknownCodeError, } from "../core/errors.js";
3
- import { COUNTER_HARDS } from "../tables/counter.tables.generated.js";
1
+ import { b, b64ToInt, codeB2ToB64, codeB64ToB2, intToB64, nabSextets, sceil, } from "../core/bytes.js";
2
+ import { DeserializeError, ShortageError, UnknownCodeError } from "../core/errors.js";
4
3
  import { resolveCounterCodeNameTable, resolveCounterSizeTable, } from "../tables/counter-version-registry.js";
4
+ import { COUNTER_HARDS } from "../tables/counter.tables.generated.js";
5
5
  const COUNTER_BARDS = new Map([...COUNTER_HARDS.entries()].map(([code, hs]) => [
6
- String.fromCharCode(codeB64ToB2(code)[0]) +
7
- String.fromCharCode(codeB64ToB2(code)[1] ?? 0),
6
+ String.fromCharCode(codeB64ToB2(code)[0])
7
+ + String.fromCharCode(codeB64ToB2(code)[1] ?? 0),
8
8
  hs,
9
9
  ]));
10
+ function isCounterData(value) {
11
+ return typeof value === "object" && value !== null
12
+ && "code" in value && "count" in value && "fullSize" in value
13
+ && "fullSizeB2" in value && "qb64" in value && "name" in value
14
+ && "version" in value;
15
+ }
10
16
  function getTables(version) {
11
17
  const sizeTable = resolveCounterSizeTable(version);
12
18
  const nameTable = resolveCounterCodeNameTable(version);
13
19
  return { sizeTable, nameTable };
14
20
  }
15
- export function parseCounterFromText(input, version) {
21
+ function parseCounterFromTextData(input, version) {
16
22
  const txt = String.fromCharCode(...input);
17
23
  if (txt.length === 0) {
18
24
  throw new ShortageError(1, 0);
@@ -27,7 +33,6 @@ export function parseCounterFromText(input, version) {
27
33
  const hard2 = txt.slice(0, 2);
28
34
  const hs = COUNTER_HARDS.get(hard2);
29
35
  if (!hs && txt.length < 4) {
30
- // Counter hard selectors are at most 4 chars in current codex tables.
31
36
  throw new ShortageError(4, txt.length);
32
37
  }
33
38
  if (!hs) {
@@ -46,26 +51,28 @@ export function parseCounterFromText(input, version) {
46
51
  }
47
52
  const count = b64ToInt(txt.slice(sizage.hs, sizage.hs + sizage.ss));
48
53
  const name = nameTable[code] ?? "UnknownCounter";
54
+ const qb64 = txt.slice(0, sizage.fs);
49
55
  return {
50
56
  code,
51
57
  count,
52
58
  fullSize: sizage.fs,
53
59
  fullSizeB2: sceil((sizage.fs * 3) / 4),
54
- qb64: txt.slice(0, sizage.fs),
60
+ qb64,
55
61
  name,
62
+ version,
56
63
  };
57
64
  }
58
- export function parseCounterFromBinary(input, version) {
65
+ function parseCounterFromBinaryData(input, version) {
59
66
  if (input.length < 2) {
60
67
  throw new ShortageError(2, input.length);
61
68
  }
62
69
  const { sizeTable, nameTable } = getTables(version);
63
70
  const firstTwo = nabSextets(input, 2);
64
- const key = String.fromCharCode(firstTwo[0]) +
65
- String.fromCharCode(firstTwo[1] ?? 0);
71
+ const key = String.fromCharCode(firstTwo[0])
72
+ + String.fromCharCode(firstTwo[1] ?? 0);
66
73
  const hs = COUNTER_BARDS.get(key);
67
74
  if (!hs) {
68
- throw new UnknownCodeError(`Unsupported qb2 counter start sextets`);
75
+ throw new UnknownCodeError("Unsupported qb2 counter start sextets");
69
76
  }
70
77
  const bhs = sceil((hs * 3) / 4);
71
78
  if (input.length < bhs) {
@@ -81,7 +88,7 @@ export function parseCounterFromBinary(input, version) {
81
88
  throw new ShortageError(bcs, input.length);
82
89
  }
83
90
  const qb64 = codeB2ToB64(input, sizage.fs);
84
- const count = b64ToInt(qb64.slice(sizage.hs, sizage.fs));
91
+ const count = b64ToInt(qb64.slice(sizage.hs, sizage.hs + sizage.ss));
85
92
  const name = nameTable[code] ?? "UnknownCounter";
86
93
  return {
87
94
  code,
@@ -90,8 +97,191 @@ export function parseCounterFromBinary(input, version) {
90
97
  fullSizeB2: bcs,
91
98
  qb64,
92
99
  name,
100
+ version,
93
101
  };
94
102
  }
103
+ function encodeCounterFromFields(code, count, version) {
104
+ const { sizeTable, nameTable } = getTables(version);
105
+ const sizage = sizeTable.get(code);
106
+ if (!sizage) {
107
+ throw new UnknownCodeError(`Unsupported counter code for version: ${code}`);
108
+ }
109
+ if (!Number.isInteger(count) || count < 0 || count > 64 ** sizage.ss - 1) {
110
+ throw new DeserializeError(`Invalid count=${count} for code=${code}`);
111
+ }
112
+ const qb64 = `${code}${intToB64(count, sizage.ss)}`;
113
+ if (qb64.length !== sizage.fs) {
114
+ throw new DeserializeError(`Encoded counter size mismatch for ${code}: expected=${sizage.fs} got=${qb64.length}`);
115
+ }
116
+ return {
117
+ code,
118
+ count,
119
+ fullSize: sizage.fs,
120
+ fullSizeB2: sceil((sizage.fs * 3) / 4),
121
+ qb64,
122
+ name: nameTable[code] ?? "UnknownCounter",
123
+ version,
124
+ };
125
+ }
126
+ function parseCounterInit(init) {
127
+ const version = init.version ?? { major: 2, minor: 0 };
128
+ if (init.code !== undefined) {
129
+ const count = init.count
130
+ ?? (init.countB64 ? b64ToInt(init.countB64) : 0);
131
+ return encodeCounterFromFields(init.code, count, version);
132
+ }
133
+ if (init.qb64b) {
134
+ return parseCounterFromTextData(init.qb64b, version);
135
+ }
136
+ if (init.qb64) {
137
+ return parseCounterFromTextData(b(init.qb64), version);
138
+ }
139
+ if (init.qb2) {
140
+ return parseCounterFromBinaryData(init.qb2, version);
141
+ }
142
+ throw new DeserializeError("Counter requires code/count or qb64/qb64b/qb2 initialization");
143
+ }
144
+ /**
145
+ * Base CESR counter primitive.
146
+ *
147
+ * KERIpy substance: counters are first-class primitives that frame counted
148
+ * payload groups and carry versioned code-name semantics.
149
+ */
150
+ export class Counter {
151
+ constructor(init) {
152
+ Object.defineProperty(this, "_code", {
153
+ enumerable: true,
154
+ configurable: true,
155
+ writable: true,
156
+ value: void 0
157
+ });
158
+ Object.defineProperty(this, "_count", {
159
+ enumerable: true,
160
+ configurable: true,
161
+ writable: true,
162
+ value: void 0
163
+ });
164
+ Object.defineProperty(this, "_fullSize", {
165
+ enumerable: true,
166
+ configurable: true,
167
+ writable: true,
168
+ value: void 0
169
+ });
170
+ Object.defineProperty(this, "_fullSizeB2", {
171
+ enumerable: true,
172
+ configurable: true,
173
+ writable: true,
174
+ value: void 0
175
+ });
176
+ Object.defineProperty(this, "_qb64", {
177
+ enumerable: true,
178
+ configurable: true,
179
+ writable: true,
180
+ value: void 0
181
+ });
182
+ Object.defineProperty(this, "_name", {
183
+ enumerable: true,
184
+ configurable: true,
185
+ writable: true,
186
+ value: void 0
187
+ });
188
+ Object.defineProperty(this, "_version", {
189
+ enumerable: true,
190
+ configurable: true,
191
+ writable: true,
192
+ value: void 0
193
+ });
194
+ const data = init instanceof Counter
195
+ ? init.toCounterData()
196
+ : isCounterData(init)
197
+ ? init
198
+ : parseCounterInit(init);
199
+ this._code = data.code;
200
+ this._count = data.count;
201
+ this._fullSize = data.fullSize;
202
+ this._fullSizeB2 = data.fullSizeB2;
203
+ this._qb64 = data.qb64;
204
+ this._name = data.name;
205
+ this._version = { ...data.version };
206
+ }
207
+ toCounterData() {
208
+ return {
209
+ code: this._code,
210
+ count: this._count,
211
+ fullSize: this._fullSize,
212
+ fullSizeB2: this._fullSizeB2,
213
+ qb64: this._qb64,
214
+ name: this._name,
215
+ version: { ...this._version },
216
+ };
217
+ }
218
+ get code() {
219
+ return this._code;
220
+ }
221
+ get count() {
222
+ return this._count;
223
+ }
224
+ get fullSize() {
225
+ return this._fullSize;
226
+ }
227
+ get fullSizeB2() {
228
+ return this._fullSizeB2;
229
+ }
230
+ get qb64() {
231
+ return this._qb64;
232
+ }
233
+ get qb64b() {
234
+ return b(this._qb64);
235
+ }
236
+ get qb2() {
237
+ return codeB64ToB2(this._qb64);
238
+ }
239
+ get name() {
240
+ return this._name;
241
+ }
242
+ get version() {
243
+ return { ...this._version };
244
+ }
245
+ equals(other) {
246
+ return this._qb64 === other.qb64;
247
+ }
248
+ toString() {
249
+ return this._qb64;
250
+ }
251
+ }
252
+ /**
253
+ * Parsed counter-group container with raw counted payload and hydrated entries.
254
+ *
255
+ * This is parser-facing structure used for primitive-graph attachment outputs.
256
+ */
257
+ export class CounterGroup extends Counter {
258
+ constructor(counter, raw, items) {
259
+ super(counter);
260
+ Object.defineProperty(this, "raw", {
261
+ enumerable: true,
262
+ configurable: true,
263
+ writable: true,
264
+ value: void 0
265
+ });
266
+ Object.defineProperty(this, "items", {
267
+ enumerable: true,
268
+ configurable: true,
269
+ writable: true,
270
+ value: void 0
271
+ });
272
+ this.raw = raw.slice();
273
+ this.items = items;
274
+ }
275
+ }
276
+ /** Parse counter from text-domain CESR bytes using provided version context. */
277
+ export function parseCounterFromText(input, version) {
278
+ return new Counter(parseCounterFromTextData(input, version));
279
+ }
280
+ /** Parse counter from binary-domain CESR bytes using provided version context. */
281
+ export function parseCounterFromBinary(input, version) {
282
+ return new Counter(parseCounterFromBinaryData(input, version));
283
+ }
284
+ /** Parse counter using domain hint (`txt` or `bny`) and versioned codex tables. */
95
285
  export function parseCounter(input, version, cold) {
96
286
  return cold === "bny"
97
287
  ? parseCounterFromBinary(input, version)
@@ -1,22 +1,37 @@
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";
2
+ import { MATTER_SIZES } from "../tables/matter.tables.generated.js";
3
+ import { DATER_CODES } from "./codex.js";
4
+ import { Matter, parseMatter } from "./matter.js";
5
+ /** Project compact CESR datetime encoding to RFC3339/ISO-8601 text form. */
4
6
  function toIso8601(dts) {
5
7
  return dts.replaceAll("c", ":").replaceAll("d", ".").replaceAll("p", "+");
6
8
  }
7
- export function parseDater(input, cold) {
8
- const matter = parseMatter(input, cold);
9
- const name = MATTER_CODE_NAMES[matter.code];
10
- if (name !== "DateTime") {
11
- throw new UnknownCodeError(`Expected dater DateTime code, got ${matter.code}`);
9
+ /**
10
+ * Datetime primitive for compact RFC3339/ISO-8601 representations.
11
+ *
12
+ * KERIpy substance: `Dater` encodes datetime text by substituting non-base64
13
+ * characters (`:`, `.`, `+`) with base64-safe symbols (`c`, `d`, `p`).
14
+ */
15
+ export class Dater extends Matter {
16
+ constructor(init) {
17
+ const matter = init instanceof Matter ? init : new Matter(init);
18
+ super(matter);
19
+ if (!DATER_CODES.has(this.code)) {
20
+ throw new UnknownCodeError(`Expected dater DateTime code, got ${this.code}`);
21
+ }
22
+ }
23
+ get dts() {
24
+ const sizage = MATTER_SIZES.get(this.code);
25
+ if (!sizage) {
26
+ throw new UnknownCodeError(`Unknown dater code ${this.code}`);
27
+ }
28
+ return this.qb64.slice(sizage.hs);
29
+ }
30
+ get iso8601() {
31
+ return toIso8601(this.dts);
12
32
  }
13
- const dts = new TextDecoder().decode(matter.raw);
14
- return {
15
- code: matter.code,
16
- qb64: matter.qb64,
17
- dts,
18
- iso8601: toIso8601(dts),
19
- fullSize: matter.fullSize,
20
- fullSizeB2: matter.fullSizeB2,
21
- };
33
+ }
34
+ /** Parse and hydrate `Dater` from txt/qb2 bytes. */
35
+ export function parseDater(input, cold) {
36
+ return new Dater(parseMatter(input, cold));
22
37
  }
@@ -0,0 +1,65 @@
1
+ import { concatBytes, decodeB64, encodeB64 } from "../core/bytes.js";
2
+ import { UnknownCodeError } from "../core/errors.js";
3
+ import { MATTER_SIZES } from "../tables/matter.tables.generated.js";
4
+ import { DECIMAL_CODES } from "./codex.js";
5
+ import { Matter, parseMatter } from "./matter.js";
6
+ /** Decode variable-sized decimal payload bytes into decimal-string form. */
7
+ function derawifyDns(raw, code) {
8
+ const sizage = MATTER_SIZES.get(code);
9
+ if (!sizage) {
10
+ throw new UnknownCodeError(`Unknown decimer code ${code}`);
11
+ }
12
+ const body = encodeB64(concatBytes(new Uint8Array(sizage.ls), raw));
13
+ const ws = sizage.ls === 0 && body.startsWith("A") ? 1 : (sizage.ls + 1) % 4;
14
+ return body.slice(ws).replaceAll("p", ".");
15
+ }
16
+ /** Encode decimal-string form into CESR raw bytes for decimal codes. */
17
+ function rawifyDns(dns) {
18
+ const encoded = dns.replaceAll(".", "p");
19
+ const ts = encoded.length % 4;
20
+ const ws = (4 - ts) % 4;
21
+ const ls = (3 - ts) % 3;
22
+ return decodeB64("A".repeat(ws) + encoded).slice(ls);
23
+ }
24
+ /**
25
+ * CESR decimal primitive aligned with KERIpy `Decimer`.
26
+ *
27
+ * Supports hydration from existing qualified material or direct decimal input
28
+ * (`dns`/`decimal`) when raw material is not provided.
29
+ */
30
+ export class Decimer extends Matter {
31
+ constructor(init) {
32
+ if (!(init instanceof Matter)
33
+ && !init.raw
34
+ && !init.qb64
35
+ && !init.qb64b
36
+ && !init.qb2
37
+ && (init.dns !== undefined || init.decimal !== undefined)) {
38
+ const dns = init.dns ?? `${init.decimal}`;
39
+ super({
40
+ ...init,
41
+ raw: rawifyDns(dns),
42
+ code: init.code ?? "4H",
43
+ });
44
+ }
45
+ else {
46
+ const matter = init instanceof Matter ? init : new Matter(init);
47
+ super(matter);
48
+ }
49
+ if (!DECIMAL_CODES.has(this.code)) {
50
+ throw new UnknownCodeError(`Expected decimal code, got ${this.code}`);
51
+ }
52
+ }
53
+ /** Decimal string form (roundtrippable CESR decimal representation). */
54
+ get dns() {
55
+ return derawifyDns(this.raw, this.code);
56
+ }
57
+ /** Convenience numeric projection of `.dns` for consumer-side arithmetic. */
58
+ get decimal() {
59
+ return Number(this.dns);
60
+ }
61
+ }
62
+ /** Parse and hydrate a `Decimer` from txt or qb2 stream bytes. */
63
+ export function parseDecimer(input, cold) {
64
+ return new Decimer(parseMatter(input, cold));
65
+ }
@@ -0,0 +1,18 @@
1
+ import { UnknownCodeError } from "../core/errors.js";
2
+ import { DECRYPTER_CODES } from "./codex.js";
3
+ import { Matter } from "./matter.js";
4
+ /**
5
+ * Private-key decryption primitive for asymmetric envelope payloads.
6
+ *
7
+ * KERIpy substance: decrypter material is private X25519 key material used to
8
+ * recover plaintext from cipher envelopes (often derived from signing seeds).
9
+ */
10
+ export class Decrypter extends Matter {
11
+ constructor(init) {
12
+ const matter = init instanceof Matter ? init : new Matter(init);
13
+ super(matter);
14
+ if (!DECRYPTER_CODES.has(this.code)) {
15
+ throw new UnknownCodeError(`Expected decrypter key code, got ${this.code}`);
16
+ }
17
+ }
18
+ }
@@ -1,22 +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
- function isDigestName(name) {
5
- return name.startsWith("Blake") || name.startsWith("SHA2_") ||
6
- name.startsWith("SHA3_");
2
+ import { DIGEST_CODES, matterCodexName } from "./codex.js";
3
+ import { Matter, parseMatter } from "./matter.js";
4
+ /**
5
+ * Digest primitive family.
6
+ *
7
+ * KERIpy substance: `Diger` encapsulates self-addressing digest material and
8
+ * optionally constrains codes to digest codex membership (`strict=true`).
9
+ */
10
+ export class Diger extends Matter {
11
+ constructor(init, options = {}) {
12
+ const matter = init instanceof Matter ? init : new Matter(init);
13
+ super(matter);
14
+ if ((options.strict ?? true) && !DIGEST_CODES.has(this.code)) {
15
+ throw new UnknownCodeError(`Expected digest code, got ${this.code}`);
16
+ }
17
+ }
18
+ get digest() {
19
+ return this.raw;
20
+ }
21
+ get algorithm() {
22
+ return matterCodexName(this.code) ?? "UnknownDigest";
23
+ }
7
24
  }
25
+ /** Parse and hydrate `Diger` from txt/qb2 bytes. */
8
26
  export function parseDiger(input, cold) {
9
- const matter = parseMatter(input, cold);
10
- const name = MATTER_CODE_NAMES[matter.code] ?? "";
11
- if (!isDigestName(name)) {
12
- throw new UnknownCodeError(`Expected digest code, got ${matter.code}`);
13
- }
14
- return {
15
- code: matter.code,
16
- qb64: matter.qb64,
17
- digest: matter.raw,
18
- algorithm: name,
19
- fullSize: matter.fullSize,
20
- fullSizeB2: matter.fullSizeB2,
21
- };
27
+ return new Diger(parseMatter(input, cold));
22
28
  }
@@ -0,0 +1,19 @@
1
+ import { UnknownCodeError } from "../core/errors.js";
2
+ import { ENCRYPTER_CODES } from "./codex.js";
3
+ import { Matter } from "./matter.js";
4
+ /**
5
+ * Public-key encryption primitive for asymmetric envelope encryption.
6
+ *
7
+ * KERIpy substance: Encrypter uses public key material (typically X25519,
8
+ * optionally derived from verifier keys) to produce ciphertext envelopes.
9
+ * This TS class validates material type; encryption ops live in crypto layers.
10
+ */
11
+ export class Encrypter extends Matter {
12
+ constructor(init) {
13
+ const matter = init instanceof Matter ? init : new Matter(init);
14
+ super(matter);
15
+ if (!ENCRYPTER_CODES.has(this.code)) {
16
+ throw new UnknownCodeError(`Expected encrypter key code, got ${this.code}`);
17
+ }
18
+ }
19
+ }
@@ -1,15 +1,27 @@
1
1
  import { UnknownCodeError } from "../core/errors.js";
2
- import { parseMatter } from "./matter.js";
3
- export function parseIlker(input, cold) {
4
- const matter = parseMatter(input, cold);
5
- if (matter.code !== "X") {
6
- throw new UnknownCodeError(`Expected ilker code X, got ${matter.code}`);
2
+ import { ILKER_CODES } from "./codex.js";
3
+ import { Matter, parseMatter } from "./matter.js";
4
+ import { Tagger } from "./tagger.js";
5
+ /**
6
+ * Message-type primitive (`ilk`) encoded via Tagger compact tag semantics.
7
+ *
8
+ * KERIpy semantics: `Ilker` is restricted to Tag3 (`X`) values that carry
9
+ * compact Base64 ilk identifiers.
10
+ */
11
+ export class Ilker extends Tagger {
12
+ constructor(init) {
13
+ const matter = init instanceof Matter ? init : new Matter(init);
14
+ super(matter);
15
+ if (!ILKER_CODES.has(this.code)) {
16
+ throw new UnknownCodeError(`Expected ilker Tag3 code, got ${this.code}`);
17
+ }
18
+ }
19
+ /** Decoded ilk value (alias of tag payload for this subclass). */
20
+ get ilk() {
21
+ return this.tag;
7
22
  }
8
- return {
9
- code: matter.code,
10
- qb64: matter.qb64,
11
- fullSize: matter.fullSize,
12
- fullSizeB2: matter.fullSizeB2,
13
- ilk: matter.qb64.slice(matter.code.length),
14
- };
23
+ }
24
+ /** Parse and hydrate `Ilker` from txt/qb2 bytes. */
25
+ export function parseIlker(input, cold) {
26
+ return new Ilker(parseMatter(input, cold));
15
27
  }