@transia/ripple-binary-codec 1.4.6-alpha.9 → 2.5.1

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 (363) hide show
  1. package/dist/binary.d.ts +30 -16
  2. package/dist/binary.js +36 -16
  3. package/dist/binary.js.map +1 -1
  4. package/dist/enums/bytes.d.ts +1 -2
  5. package/dist/enums/bytes.js +3 -2
  6. package/dist/enums/bytes.js.map +1 -1
  7. package/dist/enums/constants.d.ts +1 -0
  8. package/dist/enums/constants.js +6 -5
  9. package/dist/enums/constants.js.map +1 -1
  10. package/dist/enums/definitions.json +1604 -969
  11. package/dist/enums/field.d.ts +1 -2
  12. package/dist/enums/field.js +1 -2
  13. package/dist/enums/field.js.map +1 -1
  14. package/dist/enums/index.d.ts +1 -2
  15. package/dist/enums/index.js +5 -27
  16. package/dist/enums/index.js.map +1 -1
  17. package/dist/enums/src/enums/definitions.json +1606 -971
  18. package/dist/enums/xrpl-definitions-base.d.ts +5 -3
  19. package/dist/enums/xrpl-definitions-base.js +26 -6
  20. package/dist/enums/xrpl-definitions-base.js.map +1 -1
  21. package/dist/enums/xrpl-definitions.d.ts +2 -1
  22. package/dist/enums/xrpl-definitions.js +2 -1
  23. package/dist/enums/xrpl-definitions.js.map +1 -1
  24. package/dist/hash-prefixes.d.ts +1 -2
  25. package/dist/hash-prefixes.js +8 -6
  26. package/dist/hash-prefixes.js.map +1 -1
  27. package/dist/hashes.d.ts +6 -7
  28. package/dist/hashes.js +6 -7
  29. package/dist/hashes.js.map +1 -1
  30. package/dist/index.d.ts +16 -11
  31. package/dist/index.js +53 -58
  32. package/dist/index.js.map +1 -1
  33. package/dist/ledger-hashes.d.ts +1 -2
  34. package/dist/ledger-hashes.js +11 -30
  35. package/dist/ledger-hashes.js.map +1 -1
  36. package/dist/quality.d.ts +3 -4
  37. package/dist/quality.js +10 -8
  38. package/dist/quality.js.map +1 -1
  39. package/dist/serdes/binary-parser.d.ts +2 -3
  40. package/dist/serdes/binary-parser.js +16 -32
  41. package/dist/serdes/binary-parser.js.map +1 -1
  42. package/dist/serdes/binary-serializer.d.ts +7 -8
  43. package/dist/serdes/binary-serializer.js +14 -37
  44. package/dist/serdes/binary-serializer.js.map +1 -1
  45. package/dist/shamap.d.ts +4 -5
  46. package/dist/shamap.js +5 -5
  47. package/dist/shamap.js.map +1 -1
  48. package/dist/src/binary.d.ts +106 -0
  49. package/dist/src/binary.js +154 -0
  50. package/dist/src/binary.js.map +1 -0
  51. package/dist/src/coretypes.d.ts +9 -0
  52. package/dist/src/coretypes.js +48 -0
  53. package/dist/src/coretypes.js.map +1 -0
  54. package/dist/src/enums/bytes.d.ts +25 -0
  55. package/dist/src/enums/bytes.js +65 -0
  56. package/dist/src/enums/bytes.js.map +1 -0
  57. package/dist/src/enums/constants.d.ts +5 -0
  58. package/dist/src/enums/constants.js +9 -0
  59. package/dist/src/enums/constants.js.map +1 -0
  60. package/dist/src/enums/definitions.json +3404 -0
  61. package/dist/src/enums/field.d.ts +28 -0
  62. package/dist/src/enums/field.js +58 -0
  63. package/dist/src/enums/field.js.map +1 -0
  64. package/dist/src/enums/index.d.ts +12 -0
  65. package/dist/src/enums/index.js +31 -0
  66. package/dist/src/enums/index.js.map +1 -0
  67. package/dist/src/enums/utils-renumber.d.ts +101 -0
  68. package/dist/src/enums/utils-renumber.js +127 -0
  69. package/dist/src/enums/utils-renumber.js.map +1 -0
  70. package/dist/src/enums/xrpl-definitions-base.d.ts +47 -0
  71. package/dist/src/enums/xrpl-definitions-base.js +83 -0
  72. package/dist/src/enums/xrpl-definitions-base.js.map +1 -0
  73. package/dist/src/enums/xrpl-definitions.d.ts +22 -0
  74. package/dist/src/enums/xrpl-definitions.js +30 -0
  75. package/dist/src/enums/xrpl-definitions.js.map +1 -0
  76. package/dist/src/hash-prefixes.d.ts +5 -0
  77. package/dist/src/hash-prefixes.js +43 -0
  78. package/dist/src/hash-prefixes.js.map +1 -0
  79. package/dist/src/hashes.d.ts +50 -0
  80. package/dist/src/hashes.js +76 -0
  81. package/dist/src/hashes.js.map +1 -0
  82. package/dist/src/index.d.ts +69 -0
  83. package/dist/src/index.js +134 -0
  84. package/dist/src/index.js.map +1 -0
  85. package/dist/src/ledger-hashes.d.ts +48 -0
  86. package/dist/src/ledger-hashes.js +141 -0
  87. package/dist/src/ledger-hashes.js.map +1 -0
  88. package/dist/src/quality.d.ts +21 -0
  89. package/dist/src/quality.js +42 -0
  90. package/dist/src/quality.js.map +1 -0
  91. package/dist/src/serdes/binary-parser.d.ts +100 -0
  92. package/dist/src/serdes/binary-parser.js +194 -0
  93. package/dist/src/serdes/binary-parser.js.map +1 -0
  94. package/dist/src/serdes/binary-serializer.d.ts +81 -0
  95. package/dist/src/serdes/binary-serializer.js +149 -0
  96. package/dist/src/serdes/binary-serializer.js.map +1 -0
  97. package/dist/src/shamap.d.ts +102 -0
  98. package/dist/src/shamap.js +172 -0
  99. package/dist/src/shamap.js.map +1 -0
  100. package/dist/src/types/account-id.d.ts +37 -0
  101. package/dist/src/types/account-id.js +73 -0
  102. package/dist/src/types/account-id.js.map +1 -0
  103. package/dist/src/types/amount.d.ts +92 -0
  104. package/dist/src/types/amount.js +292 -0
  105. package/dist/src/types/amount.js.map +1 -0
  106. package/dist/src/types/blob.d.ts +25 -0
  107. package/dist/src/types/blob.js +46 -0
  108. package/dist/src/types/blob.js.map +1 -0
  109. package/dist/src/types/currency.d.ts +30 -0
  110. package/dist/src/types/currency.js +131 -0
  111. package/dist/src/types/currency.js.map +1 -0
  112. package/dist/src/types/data.d.ts +104 -0
  113. package/dist/src/types/data.js +387 -0
  114. package/dist/src/types/data.js.map +1 -0
  115. package/dist/src/types/dataType.d.ts +94 -0
  116. package/dist/src/types/dataType.js +145 -0
  117. package/dist/src/types/dataType.js.map +1 -0
  118. package/dist/src/types/hash-128.d.ts +18 -0
  119. package/dist/src/types/hash-128.js +36 -0
  120. package/dist/src/types/hash-128.js.map +1 -0
  121. package/dist/src/types/hash-160.d.ts +12 -0
  122. package/dist/src/types/hash-160.js +23 -0
  123. package/dist/src/types/hash-160.js.map +1 -0
  124. package/dist/src/types/hash-192.d.ts +12 -0
  125. package/dist/src/types/hash-192.js +23 -0
  126. package/dist/src/types/hash-192.js.map +1 -0
  127. package/dist/src/types/hash-256.d.ts +12 -0
  128. package/dist/src/types/hash-256.js +20 -0
  129. package/dist/src/types/hash-256.js.map +1 -0
  130. package/dist/src/types/hash.d.ts +40 -0
  131. package/dist/src/types/hash.js +76 -0
  132. package/dist/src/types/hash.js.map +1 -0
  133. package/dist/src/types/index.d.ts +21 -0
  134. package/dist/src/types/index.js +72 -0
  135. package/dist/src/types/index.js.map +1 -0
  136. package/dist/src/types/issue.d.ts +49 -0
  137. package/dist/src/types/issue.js +107 -0
  138. package/dist/src/types/issue.js.map +1 -0
  139. package/dist/src/types/json.d.ts +169 -0
  140. package/dist/src/types/json.js +529 -0
  141. package/dist/src/types/json.js.map +1 -0
  142. package/dist/src/types/path-set.d.ts +37 -0
  143. package/dist/src/types/path-set.js +236 -0
  144. package/dist/src/types/path-set.js.map +1 -0
  145. package/dist/src/types/serialized-type.d.ts +117 -0
  146. package/dist/src/types/serialized-type.js +242 -0
  147. package/dist/src/types/serialized-type.js.map +1 -0
  148. package/dist/src/types/st-array.d.ts +32 -0
  149. package/dist/src/types/st-array.js +89 -0
  150. package/dist/src/types/st-array.js.map +1 -0
  151. package/dist/src/types/st-number.d.ts +55 -0
  152. package/dist/src/types/st-number.js +212 -0
  153. package/dist/src/types/st-number.js.map +1 -0
  154. package/dist/src/types/st-object.d.ts +33 -0
  155. package/dist/src/types/st-object.js +176 -0
  156. package/dist/src/types/st-object.js.map +1 -0
  157. package/dist/src/types/uint-16.d.ts +26 -0
  158. package/dist/src/types/uint-16.js +49 -0
  159. package/dist/src/types/uint-16.js.map +1 -0
  160. package/dist/src/types/uint-32.d.ts +26 -0
  161. package/dist/src/types/uint-32.js +54 -0
  162. package/dist/src/types/uint-32.js.map +1 -0
  163. package/dist/src/types/uint-64.d.ts +40 -0
  164. package/dist/src/types/uint-64.js +112 -0
  165. package/dist/src/types/uint-64.js.map +1 -0
  166. package/dist/src/types/uint-8.d.ts +26 -0
  167. package/dist/src/types/uint-8.js +50 -0
  168. package/dist/src/types/uint-8.js.map +1 -0
  169. package/dist/src/types/uint.d.ts +29 -0
  170. package/dist/src/types/uint.js +47 -0
  171. package/dist/src/types/uint.js.map +1 -0
  172. package/dist/src/types/vector-256.d.ts +31 -0
  173. package/dist/src/types/vector-256.js +76 -0
  174. package/dist/src/types/vector-256.js.map +1 -0
  175. package/dist/src/types/xchain-bridge.d.ts +45 -0
  176. package/dist/src/types/xchain-bridge.js +105 -0
  177. package/dist/src/types/xchain-bridge.js.map +1 -0
  178. package/dist/src/utils.d.ts +79 -0
  179. package/dist/src/utils.js +181 -0
  180. package/dist/src/utils.js.map +1 -0
  181. package/dist/tsconfig.tsbuildinfo +1 -0
  182. package/dist/types/account-id.d.ts +3 -2
  183. package/dist/types/account-id.js +8 -6
  184. package/dist/types/account-id.js.map +1 -1
  185. package/dist/types/amount.d.ts +33 -9
  186. package/dist/types/amount.js +128 -43
  187. package/dist/types/amount.js.map +1 -1
  188. package/dist/types/blob.d.ts +3 -3
  189. package/dist/types/blob.js +8 -2
  190. package/dist/types/blob.js.map +1 -1
  191. package/dist/types/currency.d.ts +3 -2
  192. package/dist/types/currency.js +17 -13
  193. package/dist/types/currency.js.map +1 -1
  194. package/dist/types/data.d.ts +104 -0
  195. package/dist/types/data.js +387 -0
  196. package/dist/types/data.js.map +1 -0
  197. package/dist/types/dataType.d.ts +94 -0
  198. package/dist/types/dataType.js +145 -0
  199. package/dist/types/dataType.js.map +1 -0
  200. package/dist/types/hash-128.d.ts +3 -2
  201. package/dist/types/hash-128.js +7 -3
  202. package/dist/types/hash-128.js.map +1 -1
  203. package/dist/types/hash-160.d.ts +3 -2
  204. package/dist/types/hash-160.js +5 -2
  205. package/dist/types/hash-160.js.map +1 -1
  206. package/dist/types/hash-192.d.ts +12 -0
  207. package/dist/types/hash-192.js +23 -0
  208. package/dist/types/hash-192.js.map +1 -0
  209. package/dist/types/hash-256.d.ts +3 -2
  210. package/dist/types/hash-256.js +5 -2
  211. package/dist/types/hash-256.js.map +1 -1
  212. package/dist/types/hash.d.ts +2 -3
  213. package/dist/types/hash.js +8 -4
  214. package/dist/types/hash.js.map +1 -1
  215. package/dist/types/index.d.ts +4 -1
  216. package/dist/types/index.js +17 -2
  217. package/dist/types/index.js.map +1 -1
  218. package/dist/types/issue.d.ts +49 -0
  219. package/dist/types/issue.js +107 -0
  220. package/dist/types/issue.js.map +1 -0
  221. package/dist/types/json.d.ts +169 -0
  222. package/dist/types/json.js +529 -0
  223. package/dist/types/json.js.map +1 -0
  224. package/dist/types/path-set.d.ts +2 -1
  225. package/dist/types/path-set.js +15 -12
  226. package/dist/types/path-set.js.map +1 -1
  227. package/dist/types/serialized-type.d.ts +70 -16
  228. package/dist/types/serialized-type.js +153 -8
  229. package/dist/types/serialized-type.js.map +1 -1
  230. package/dist/types/st-array.d.ts +7 -3
  231. package/dist/types/st-array.js +20 -11
  232. package/dist/types/st-array.js.map +1 -1
  233. package/dist/types/st-number.d.ts +55 -0
  234. package/dist/types/st-number.js +212 -0
  235. package/dist/types/st-number.js.map +1 -0
  236. package/dist/types/st-object.d.ts +2 -1
  237. package/dist/types/st-object.js +35 -8
  238. package/dist/types/st-object.js.map +1 -1
  239. package/dist/types/uint-16.d.ts +3 -2
  240. package/dist/types/uint-16.js +10 -5
  241. package/dist/types/uint-16.js.map +1 -1
  242. package/dist/types/uint-32.d.ts +3 -2
  243. package/dist/types/uint-32.js +11 -6
  244. package/dist/types/uint-32.js.map +1 -1
  245. package/dist/types/uint-64.d.ts +8 -7
  246. package/dist/types/uint-64.js +49 -24
  247. package/dist/types/uint-64.js.map +1 -1
  248. package/dist/types/uint-8.d.ts +3 -2
  249. package/dist/types/uint-8.js +11 -5
  250. package/dist/types/uint-8.js.map +1 -1
  251. package/dist/types/uint.d.ts +5 -6
  252. package/dist/types/uint.js +5 -0
  253. package/dist/types/uint.js.map +1 -1
  254. package/dist/types/vector-256.d.ts +3 -3
  255. package/dist/types/vector-256.js +5 -4
  256. package/dist/types/vector-256.js.map +1 -1
  257. package/dist/types/xchain-bridge.d.ts +45 -0
  258. package/dist/types/xchain-bridge.js +105 -0
  259. package/dist/types/xchain-bridge.js.map +1 -0
  260. package/dist/utils.d.ts +79 -0
  261. package/dist/utils.js +181 -0
  262. package/dist/utils.js.map +1 -0
  263. package/package.json +21 -17
  264. package/src/README.md +5 -0
  265. package/src/binary.ts +235 -0
  266. package/src/coretypes.ts +31 -0
  267. package/src/enums/README.md +144 -0
  268. package/src/enums/bytes.ts +80 -0
  269. package/src/enums/constants.ts +5 -0
  270. package/src/enums/definitions.json +3409 -0
  271. package/src/enums/field.ts +84 -0
  272. package/src/enums/index.ts +34 -0
  273. package/src/enums/utils-renumber.ts +134 -0
  274. package/src/enums/xrpl-definitions-base.ts +150 -0
  275. package/src/enums/xrpl-definitions.ts +33 -0
  276. package/src/hash-prefixes.ts +42 -0
  277. package/src/hashes.ts +75 -0
  278. package/src/index.ts +166 -0
  279. package/src/ledger-hashes.ts +191 -0
  280. package/src/quality.ts +38 -0
  281. package/src/serdes/binary-parser.ts +228 -0
  282. package/src/serdes/binary-serializer.ts +166 -0
  283. package/src/shamap.ts +189 -0
  284. package/src/types/account-id.ts +91 -0
  285. package/src/types/amount.ts +366 -0
  286. package/src/types/blob.ts +50 -0
  287. package/src/types/currency.ts +145 -0
  288. package/src/types/data.ts +496 -0
  289. package/src/types/dataType.ts +178 -0
  290. package/src/types/hash-128.ts +38 -0
  291. package/src/types/hash-160.ts +24 -0
  292. package/src/types/hash-192.ts +24 -0
  293. package/src/types/hash-256.ts +20 -0
  294. package/src/types/hash.ts +86 -0
  295. package/src/types/index.ts +74 -0
  296. package/src/types/issue.ts +140 -0
  297. package/src/types/json.ts +641 -0
  298. package/src/types/path-set.ts +294 -0
  299. package/src/types/serialized-type.ts +271 -0
  300. package/src/types/st-array.ts +117 -0
  301. package/src/types/st-number.ts +238 -0
  302. package/src/types/st-object.ts +219 -0
  303. package/src/types/uint-16.ts +58 -0
  304. package/src/types/uint-32.ts +64 -0
  305. package/src/types/uint-64.ts +141 -0
  306. package/src/types/uint-8.ts +57 -0
  307. package/src/types/uint.ts +60 -0
  308. package/src/types/vector-256.ts +83 -0
  309. package/src/types/xchain-bridge.ts +132 -0
  310. package/src/utils.ts +220 -0
  311. package/test/amount.test.js +0 -43
  312. package/test/binary-json.test.js +0 -45
  313. package/test/binary-parser.test.js +0 -396
  314. package/test/binary-serializer.test.js +0 -319
  315. package/test/definitions.test.js +0 -100
  316. package/test/fixtures/account-tx-transactions.db +0 -0
  317. package/test/fixtures/codec-fixtures.json +0 -4466
  318. package/test/fixtures/data-driven-tests.json +0 -2919
  319. package/test/fixtures/delivermin-tx-binary.json +0 -1
  320. package/test/fixtures/delivermin-tx.json +0 -98
  321. package/test/fixtures/deposit-preauth-tx-binary.json +0 -1
  322. package/test/fixtures/deposit-preauth-tx-meta-binary.json +0 -1
  323. package/test/fixtures/deposit-preauth-tx.json +0 -58
  324. package/test/fixtures/escrow-cancel-binary.json +0 -1
  325. package/test/fixtures/escrow-cancel-tx.json +0 -6
  326. package/test/fixtures/escrow-create-binary.json +0 -1
  327. package/test/fixtures/escrow-create-tx.json +0 -10
  328. package/test/fixtures/escrow-finish-binary.json +0 -1
  329. package/test/fixtures/escrow-finish-meta-binary.json +0 -1
  330. package/test/fixtures/escrow-finish-tx.json +0 -95
  331. package/test/fixtures/ledger-full-38129.json +0 -1
  332. package/test/fixtures/ledger-full-40000.json +0 -1
  333. package/test/fixtures/negative-unl.json +0 -12
  334. package/test/fixtures/nf-token.json +0 -547
  335. package/test/fixtures/payment-channel-claim-binary.json +0 -1
  336. package/test/fixtures/payment-channel-claim-tx.json +0 -8
  337. package/test/fixtures/payment-channel-create-binary.json +0 -1
  338. package/test/fixtures/payment-channel-create-tx.json +0 -11
  339. package/test/fixtures/payment-channel-fund-binary.json +0 -1
  340. package/test/fixtures/payment-channel-fund-tx.json +0 -7
  341. package/test/fixtures/remit-binary.json +0 -1
  342. package/test/fixtures/remit-tx.json +0 -39
  343. package/test/fixtures/signerlistset-tx-binary.json +0 -1
  344. package/test/fixtures/signerlistset-tx-meta-binary.json +0 -1
  345. package/test/fixtures/signerlistset-tx.json +0 -94
  346. package/test/fixtures/ticket-create-binary.json +0 -1
  347. package/test/fixtures/ticket-create-tx.json +0 -7
  348. package/test/fixtures/unl-report-binary.json +0 -1
  349. package/test/fixtures/unl-report-meta-binary.json +0 -1
  350. package/test/fixtures/unl-report.json +0 -89
  351. package/test/fixtures/x-codec-fixtures.json +0 -188
  352. package/test/hash.test.js +0 -135
  353. package/test/ledger.test.js +0 -29
  354. package/test/lower-case-hex.test.js +0 -46
  355. package/test/pseudo-transaction.test.js +0 -38
  356. package/test/quality.test.js +0 -15
  357. package/test/shamap.test.js +0 -89
  358. package/test/signing-data-encoding.test.js +0 -213
  359. package/test/tx-encode-decode.test.js +0 -119
  360. package/test/types.test.js +0 -34
  361. package/test/uint.test.js +0 -148
  362. package/test/utils.js +0 -30
  363. package/test/x-address.test.js +0 -181
@@ -0,0 +1,641 @@
1
+ /* eslint-disable max-lines */
2
+ /* eslint-disable complexity */
3
+ import { BinaryParser } from '../serdes/binary-parser'
4
+ import { JsonObject, SerializedType, SerializedTypeID } from './serialized-type'
5
+ import { bytesToHex } from '@transia/isomorphic/utils'
6
+ import { BinarySerializer, BytesList } from '../serdes/binary-serializer'
7
+
8
+ /**
9
+ * STJson: Serialized Type for JSON-like structures (objects or arrays).
10
+ *
11
+ * Supports two modes:
12
+ * - Object: Key-value pairs where keys are VL-encoded strings
13
+ * - Array: Ordered list of values
14
+ *
15
+ * Values are [SType marker][VL-encoded SType serialization].
16
+ * Values can be any SType, including nested STJson.
17
+ *
18
+ * Serialization format: [type_byte][VL_length][data...]
19
+ * - type_byte: 0x00 = Object, 0x01 = Array
20
+ *
21
+ * Depth constraint: Maximum nesting depth of 1 level
22
+ */
23
+ class STJson extends SerializedType {
24
+ private static readonly JsonType = {
25
+ Object: 0x00,
26
+ Array: 0x01,
27
+ }
28
+
29
+ private data: Map<string, SerializedType | null> | (SerializedType | null)[]
30
+ private jsonType: number
31
+ private default_: boolean = false
32
+
33
+ /**
34
+ * Construct STJson from bytes
35
+ * @param bytes - Uint8Array containing serialized JSON
36
+ */
37
+ constructor(bytes: Uint8Array) {
38
+ super(bytes)
39
+ this.data = new Map()
40
+ this.jsonType = STJson.JsonType.Object
41
+ }
42
+
43
+ /**
44
+ * Parse STJson from BinaryParser
45
+ *
46
+ * @param parser - BinaryParser positioned at the start of STJson
47
+ * @returns STJson instance
48
+ */
49
+ static fromParser(parser: BinaryParser): STJson {
50
+ const dataLength = parser.readVariableLengthLength()
51
+
52
+ if (dataLength < 0) {
53
+ throw new Error('Invalid STJson length')
54
+ }
55
+
56
+ if (dataLength === 0) {
57
+ const json = new STJson(new Uint8Array())
58
+ json.data = new Map()
59
+ return json
60
+ }
61
+
62
+ // Read type byte
63
+ const typeByte = parser.read(1)[0]
64
+ const type = typeByte
65
+ const initialBytesLeft = parser.size()
66
+
67
+ if (type === STJson.JsonType.Array) {
68
+ const array: (SerializedType | null)[] = []
69
+ while (
70
+ parser.size() > 0 &&
71
+ initialBytesLeft - parser.size() < dataLength
72
+ ) {
73
+ const valueVL = parser.readVariableLength()
74
+ if (valueVL.length > 0) {
75
+ const valueSit = new BinaryParser(bytesToHex(valueVL))
76
+ const value = STJson.makeValueFromVLWithType(valueSit)
77
+ array.push(value)
78
+ } else {
79
+ array.push(null)
80
+ }
81
+ }
82
+
83
+ const json = new STJson(new Uint8Array())
84
+ json.data = array
85
+ json.jsonType = STJson.JsonType.Array
86
+ return json
87
+ } else {
88
+ // JsonType.Object
89
+ const map = new Map<string, SerializedType | null>()
90
+ while (
91
+ parser.size() > 0 &&
92
+ initialBytesLeft - parser.size() < dataLength
93
+ ) {
94
+ const [key, value] = STJson.parsePair(parser)
95
+ map.set(key, value)
96
+ }
97
+
98
+ const json = new STJson(new Uint8Array())
99
+ json.data = map
100
+ json.jsonType = STJson.JsonType.Object
101
+ return json
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Parse a single key-value pair from the parser
107
+ */
108
+ private static parsePair(
109
+ parser: BinaryParser,
110
+ ): [string, SerializedType | null] {
111
+ const keyVL = parser.readVariableLength()
112
+ const key = new TextDecoder().decode(keyVL)
113
+
114
+ const valueVL = parser.readVariableLength()
115
+ let value: SerializedType | null = null
116
+
117
+ if (valueVL.length > 0) {
118
+ const valueSit = new BinaryParser(bytesToHex(valueVL))
119
+ value = STJson.makeValueFromVLWithType(valueSit)
120
+ }
121
+
122
+ return [key, value]
123
+ }
124
+
125
+ /**
126
+ * Factory for SType value from VL blob (with SType marker)
127
+ */
128
+ private static makeValueFromVLWithType(parser: BinaryParser): SerializedType {
129
+ if (parser.size() === 0) {
130
+ throw new Error('Empty data when parsing STJson value')
131
+ }
132
+
133
+ const typeId = parser.read(1)[0]
134
+
135
+ // Delegate to appropriate type's fromParser
136
+ // This is a placeholder - actual implementation would dispatch to concrete types
137
+ // For now, we create an STJson if type is Object or Array
138
+ if (typeId === STJson.JsonType.Object || typeId === STJson.JsonType.Array) {
139
+ return STJson.fromParser(parser)
140
+ }
141
+
142
+ throw new Error(`Unsupported type ID in STJson: ${typeId}`)
143
+ }
144
+
145
+ /**
146
+ * Check if this is an array type
147
+ */
148
+ isArray(): boolean {
149
+ return this.jsonType === STJson.JsonType.Array
150
+ }
151
+
152
+ /**
153
+ * Check if this is an object type
154
+ */
155
+ isObject(): boolean {
156
+ return this.jsonType === STJson.JsonType.Object
157
+ }
158
+
159
+ /**
160
+ * Get the JSON type
161
+ */
162
+ getType(): number {
163
+ return this.jsonType
164
+ }
165
+
166
+ /**
167
+ * Get nesting depth (0 = no nesting, 1 = one level of nesting)
168
+ */
169
+ getDepth(): number {
170
+ if (this.isArray()) {
171
+ const array = this.data as (SerializedType | null)[]
172
+ for (const value of array) {
173
+ if (value && value instanceof STJson) {
174
+ return 1 + value.getDepth()
175
+ }
176
+ }
177
+ return 0
178
+ } else {
179
+ // isObject()
180
+ const map = this.data as Map<string, SerializedType | null>
181
+ for (const value of map.values()) {
182
+ if (value && value instanceof STJson) {
183
+ return 1 + value.getDepth()
184
+ }
185
+ }
186
+ return 0
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Validate nesting depth (max 1 level)
192
+ */
193
+ private validateDepth(
194
+ value: SerializedType | null,
195
+ currentDepth: number,
196
+ ): void {
197
+ if (!value) {
198
+ return
199
+ }
200
+
201
+ if (!(value instanceof STJson)) {
202
+ return
203
+ }
204
+
205
+ const valueDepth = value.getDepth()
206
+ if (currentDepth + valueDepth > 1) {
207
+ throw new Error('STJson nesting depth exceeds maximum of 1')
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Set a field in an object
213
+ */
214
+ setObjectField(key: string, value: SerializedType | null): void {
215
+ if (!this.isObject()) {
216
+ throw new Error('STJson::setObjectField called on non-object')
217
+ }
218
+ this.validateDepth(value, 0)
219
+ ;(this.data as Map<string, SerializedType | null>).set(key, value)
220
+ }
221
+
222
+ /**
223
+ * Get a field from an object
224
+ */
225
+ getObjectField(key: string): SerializedType | null | undefined {
226
+ if (!this.isObject()) {
227
+ return undefined
228
+ }
229
+ return (this.data as Map<string, SerializedType | null>).get(key)
230
+ }
231
+
232
+ /**
233
+ * Set a nested object field (one level deep)
234
+ */
235
+ setNestedObjectField(
236
+ key: string,
237
+ nestedKey: string,
238
+ value: SerializedType | null,
239
+ ): void {
240
+ if (!this.isObject()) {
241
+ throw new Error('STJson::setNestedObjectField called on non-object')
242
+ }
243
+
244
+ const map = this.data as Map<string, SerializedType | null>
245
+ let nestedObj = map.get(key)
246
+
247
+ if (!nestedObj || !(nestedObj instanceof STJson) || !nestedObj.isObject()) {
248
+ const newNested = new STJson(new Uint8Array())
249
+ ;(newNested as any).data = new Map()
250
+ ;(newNested as any).jsonType = STJson.JsonType.Object
251
+ map.set(key, newNested as SerializedType)
252
+ nestedObj = newNested
253
+ }
254
+
255
+ if (nestedObj instanceof STJson) {
256
+ nestedObj.setObjectField(nestedKey, value)
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Get a nested object field
262
+ */
263
+ getNestedObjectField(
264
+ key: string,
265
+ nestedKey: string,
266
+ ): SerializedType | null | undefined {
267
+ if (!this.isObject()) {
268
+ return undefined
269
+ }
270
+
271
+ const nestedObj = (this.data as Map<string, SerializedType | null>).get(key)
272
+ if (nestedObj instanceof STJson && nestedObj.isObject()) {
273
+ return nestedObj.getObjectField(nestedKey)
274
+ }
275
+ return undefined
276
+ }
277
+
278
+ /**
279
+ * Get the inner data as a Map (for objects)
280
+ */
281
+ getMap(): Map<string, SerializedType | null> {
282
+ if (!this.isObject()) {
283
+ throw new Error('STJson is not an object type')
284
+ }
285
+ return this.data as Map<string, SerializedType | null>
286
+ }
287
+
288
+ /**
289
+ * Get the inner data as an array
290
+ */
291
+ getArray(): (SerializedType | null)[] {
292
+ if (!this.isArray()) {
293
+ throw new Error('STJson is not an array type')
294
+ }
295
+ return this.data as (SerializedType | null)[]
296
+ }
297
+
298
+ /**
299
+ * Push an element to an array
300
+ */
301
+ pushArrayElement(value: SerializedType | null): void {
302
+ if (!this.isArray()) {
303
+ throw new Error('STJson::pushArrayElement called on non-array')
304
+ }
305
+ this.validateDepth(value, 0)
306
+ ;(this.data as (SerializedType | null)[]).push(value)
307
+ }
308
+
309
+ /**
310
+ * Get an array element by index
311
+ */
312
+ getArrayElement(index: number): SerializedType | null | undefined {
313
+ if (!this.isArray()) {
314
+ return undefined
315
+ }
316
+ const array = this.data as (SerializedType | null)[]
317
+ return array[index]
318
+ }
319
+
320
+ /**
321
+ * Set an array element by index
322
+ */
323
+ setArrayElement(index: number, value: SerializedType | null): void {
324
+ if (!this.isArray()) {
325
+ throw new Error('STJson::setArrayElement called on non-array')
326
+ }
327
+ this.validateDepth(value, 0)
328
+
329
+ const array = this.data as (SerializedType | null)[]
330
+ // Auto-resize with nulls if needed
331
+ if (index >= array.length) {
332
+ array.length = index + 1
333
+ array.fill(null)
334
+ }
335
+ array[index] = value
336
+ }
337
+
338
+ /**
339
+ * Set a field within an array element (element must be an object)
340
+ */
341
+ setArrayElementField(
342
+ index: number,
343
+ key: string,
344
+ value: SerializedType | null,
345
+ ): void {
346
+ if (!this.isArray()) {
347
+ throw new Error('STJson::setArrayElementField called on non-array')
348
+ }
349
+
350
+ this.validateDepth(value, 1)
351
+
352
+ const array = this.data as (SerializedType | null)[]
353
+ // Auto-resize with nulls if needed
354
+ if (index >= array.length) {
355
+ array.length = index + 1
356
+ array.fill(null)
357
+ }
358
+
359
+ let element = array[index]
360
+ if (!element || !(element instanceof STJson) || !element.isObject()) {
361
+ const newElement = new STJson(new Uint8Array())
362
+ ;(newElement as any).data = new Map()
363
+ ;(newElement as any).jsonType = STJson.JsonType.Object
364
+ array[index] = newElement as SerializedType
365
+ element = newElement
366
+ }
367
+
368
+ if (element instanceof STJson) {
369
+ element.setObjectField(key, value)
370
+ }
371
+ }
372
+
373
+ /**
374
+ * Get a field within an array element
375
+ */
376
+ getArrayElementField(
377
+ index: number,
378
+ key: string,
379
+ ): SerializedType | null | undefined {
380
+ if (!this.isArray()) {
381
+ return undefined
382
+ }
383
+
384
+ const array = this.data as (SerializedType | null)[]
385
+ if (index >= array.length) {
386
+ return undefined
387
+ }
388
+
389
+ const element = array[index]
390
+ if (element instanceof STJson && element.isObject()) {
391
+ return element.getObjectField(key)
392
+ }
393
+ return undefined
394
+ }
395
+
396
+ /**
397
+ * Get the size of the array
398
+ */
399
+ arraySize(): number {
400
+ if (!this.isArray()) {
401
+ return 0
402
+ }
403
+ return (this.data as (SerializedType | null)[]).length
404
+ }
405
+
406
+ /**
407
+ * Set a nested array element (array stored in object field)
408
+ */
409
+ setNestedArrayElement(
410
+ key: string,
411
+ index: number,
412
+ value: SerializedType | null,
413
+ ): void {
414
+ if (!this.isObject()) {
415
+ throw new Error('STJson::setNestedArrayElement called on non-object')
416
+ }
417
+
418
+ this.validateDepth(value, 1)
419
+
420
+ const map = this.data as Map<string, SerializedType | null>
421
+ let arrayJson = map.get(key)
422
+
423
+ if (!arrayJson || !(arrayJson instanceof STJson) || !arrayJson.isArray()) {
424
+ const newArray = new STJson(new Uint8Array())
425
+ ;(newArray as any).data = []
426
+ ;(newArray as any).jsonType = STJson.JsonType.Array
427
+ map.set(key, newArray as SerializedType)
428
+ arrayJson = newArray
429
+ }
430
+
431
+ if (arrayJson instanceof STJson) {
432
+ arrayJson.setArrayElement(index, value)
433
+ }
434
+ }
435
+
436
+ /**
437
+ * Set a field within a nested array element
438
+ */
439
+ setNestedArrayElementField(
440
+ key: string,
441
+ index: number,
442
+ nestedKey: string,
443
+ value: SerializedType | null,
444
+ ): void {
445
+ if (!this.isObject()) {
446
+ throw new Error('STJson::setNestedArrayElementField called on non-object')
447
+ }
448
+
449
+ this.validateDepth(value, 1)
450
+
451
+ const map = this.data as Map<string, SerializedType | null>
452
+ let arrayJson = map.get(key)
453
+
454
+ if (!arrayJson || !(arrayJson instanceof STJson) || !arrayJson.isArray()) {
455
+ const newArray = new STJson(new Uint8Array())
456
+ ;(newArray as any).data = []
457
+ ;(newArray as any).jsonType = STJson.JsonType.Array
458
+ map.set(key, newArray as SerializedType)
459
+ arrayJson = newArray
460
+ }
461
+
462
+ if (arrayJson instanceof STJson) {
463
+ arrayJson.setArrayElementField(index, nestedKey, value)
464
+ }
465
+ }
466
+
467
+ /**
468
+ * Get a nested array element
469
+ */
470
+ getNestedArrayElement(
471
+ key: string,
472
+ index: number,
473
+ ): SerializedType | null | undefined {
474
+ if (!this.isObject()) {
475
+ return undefined
476
+ }
477
+
478
+ const arrayJson = (this.data as Map<string, SerializedType | null>).get(key)
479
+ if (arrayJson instanceof STJson && arrayJson.isArray()) {
480
+ return arrayJson.getArrayElement(index)
481
+ }
482
+ return undefined
483
+ }
484
+
485
+ /**
486
+ * Get a field within a nested array element
487
+ */
488
+ getNestedArrayElementField(
489
+ key: string,
490
+ index: number,
491
+ nestedKey: string,
492
+ ): SerializedType | null | undefined {
493
+ if (!this.isObject()) {
494
+ return undefined
495
+ }
496
+
497
+ const arrayJson = (this.data as Map<string, SerializedType | null>).get(key)
498
+ if (arrayJson instanceof STJson && arrayJson.isArray()) {
499
+ return arrayJson.getArrayElementField(index, nestedKey)
500
+ }
501
+ return undefined
502
+ }
503
+
504
+ /**
505
+ * Serialize to binary
506
+ */
507
+ add(s: BinarySerializer): void {
508
+ const bytesList = new BytesList()
509
+ const tmp = new BinarySerializer(bytesList)
510
+
511
+ // Add type byte
512
+ tmp.put(new Uint8Array([this.jsonType]))
513
+
514
+ if (this.isArray()) {
515
+ const array = this.data as (SerializedType | null)[]
516
+ for (const value of array) {
517
+ STJson.addVLValue(tmp, value)
518
+ }
519
+ } else {
520
+ // isObject()
521
+ const map = this.data as Map<string, SerializedType | null>
522
+ for (const [key, value] of map.entries()) {
523
+ STJson.addVLKey(tmp, key)
524
+ STJson.addVLValue(tmp, value)
525
+ }
526
+ }
527
+
528
+ const innerBytes = bytesList.toBytes()
529
+ const lengthBytes = BinarySerializer.encodeVariableLength(innerBytes.length)
530
+ s.put(lengthBytes)
531
+ s.put(innerBytes)
532
+ }
533
+
534
+ /**
535
+ * Encode a key as VL
536
+ */
537
+ private static addVLKey(s: BinarySerializer, str: string): void {
538
+ const keyBytes = new TextEncoder().encode(str)
539
+ const lengthBytes = BinarySerializer.encodeVariableLength(keyBytes.length)
540
+ s.put(lengthBytes)
541
+ s.put(keyBytes)
542
+ }
543
+
544
+ /**
545
+ * Encode a value as [SType marker][VL]
546
+ */
547
+ private static addVLValue(
548
+ s: BinarySerializer,
549
+ value: SerializedType | null,
550
+ ): void {
551
+ if (!value) {
552
+ s.put(BinarySerializer.encodeVariableLength(0))
553
+ return
554
+ }
555
+
556
+ const bytesList = new BytesList()
557
+ const tmp = new BinarySerializer(bytesList)
558
+ tmp.put(new Uint8Array([value.getSType()]))
559
+ value.toBytesSink(bytesList)
560
+
561
+ const innerBytes = bytesList.toBytes()
562
+ const lengthBytes = BinarySerializer.encodeVariableLength(innerBytes.length)
563
+ s.put(lengthBytes)
564
+ s.put(innerBytes)
565
+ }
566
+
567
+ /**
568
+ * Convert to JSON representation
569
+ */
570
+ toJSON(): JsonObject | JsonObject[] {
571
+ if (this.isArray()) {
572
+ const array = this.data as (SerializedType | null)[]
573
+ return array.map((item) => (item ? item.toJSON() : null)) as JsonObject[]
574
+ } else {
575
+ // isObject()
576
+ const map = this.data as Map<string, SerializedType | null>
577
+ const result: JsonObject = {}
578
+ for (const [key, value] of map.entries()) {
579
+ result[key] = value ? value.toJSON() : null
580
+ }
581
+ return result as JsonObject
582
+ }
583
+ }
584
+
585
+ /**
586
+ * Compare with another STJson for equivalence
587
+ */
588
+ isEquivalent(t: SerializedType): boolean {
589
+ if (!(t instanceof STJson)) {
590
+ return false
591
+ }
592
+ return bytesToHex(this.bytes) === bytesToHex(t.bytes)
593
+ }
594
+
595
+ /**
596
+ * Check if this is the default value
597
+ */
598
+ isDefault(): boolean {
599
+ return this.default_
600
+ }
601
+
602
+ /**
603
+ * Get blob representation
604
+ */
605
+ toBlob(): Uint8Array {
606
+ const bytesList = new BytesList()
607
+ const s = new BinarySerializer(bytesList)
608
+ this.add(s)
609
+ return bytesList.toBytes()
610
+ }
611
+
612
+ /**
613
+ * Get the size (number of bytes in serialized form)
614
+ */
615
+ size(): number {
616
+ const bytesList = new BytesList()
617
+ const s = new BinarySerializer(bytesList)
618
+ this.add(s)
619
+ return bytesList.getLength()
620
+ }
621
+
622
+ /**
623
+ * Set the value from another STJson
624
+ */
625
+ setValue(v: STJson): void {
626
+ if (!(v instanceof STJson)) {
627
+ throw new Error('setValue: value must be STJson')
628
+ }
629
+ ;(this as any).data = (v as any).data
630
+ ;(this as any).jsonType = (v as any).jsonType
631
+ }
632
+
633
+ /**
634
+ * Get serialized type ID
635
+ */
636
+ getSType(): SerializedTypeID {
637
+ return SerializedTypeID.STI_JSON
638
+ }
639
+ }
640
+
641
+ export { STJson }