functionalscript 0.44.0 → 0.46.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 (571) hide show
  1. package/README.md +5 -3
  2. package/fjs/asn.1/module.f.mjs +8 -1
  3. package/fjs/asn.1/proof.f.d.mts +15 -0
  4. package/fjs/asn.1/proof.f.mjs +31 -3
  5. package/fjs/asserts/module.f.d.mts +14 -0
  6. package/fjs/asserts/module.f.mjs +20 -0
  7. package/fjs/asserts/proof.f.d.mts +3 -0
  8. package/fjs/asserts/proof.f.mjs +15 -1
  9. package/fjs/basen/base128/module.f.mjs +22 -5
  10. package/fjs/basen/base128/proof.f.d.mts +3 -1
  11. package/fjs/basen/base128/proof.f.mjs +3 -1
  12. package/fjs/basen/base64/module.f.mjs +7 -3
  13. package/fjs/basen/base64/proof.f.d.mts +3 -1
  14. package/fjs/basen/base64/proof.f.mjs +7 -4
  15. package/fjs/basen/cbase32/proof.f.d.mts +3 -1
  16. package/fjs/basen/cbase32/proof.f.mjs +3 -1
  17. package/fjs/bnf/data/module.f.d.mts +32 -6
  18. package/fjs/bnf/data/module.f.mjs +112 -7
  19. package/fjs/bnf/data/proof.f.d.mts +2 -0
  20. package/fjs/bnf/data/proof.f.mjs +74 -4
  21. package/fjs/bnf/data/types.d.ts +20 -2
  22. package/fjs/bnf/descent/module.f.d.mts +34 -5
  23. package/fjs/bnf/descent/module.f.mjs +176 -54
  24. package/fjs/bnf/descent/proof.f.d.mts +3 -0
  25. package/fjs/bnf/descent/proof.f.mjs +189 -27
  26. package/fjs/bnf/descent/types.d.ts +24 -18
  27. package/fjs/bnf/ll1/module.f.d.mts +74 -6
  28. package/fjs/bnf/ll1/module.f.mjs +297 -95
  29. package/fjs/bnf/ll1/proof.f.d.mts +17 -2
  30. package/fjs/bnf/ll1/proof.f.mjs +372 -137
  31. package/fjs/bnf/ll1/types.d.ts +25 -27
  32. package/fjs/bnf/matcher/module.f.d.mts +66 -0
  33. package/fjs/bnf/matcher/module.f.mjs +81 -0
  34. package/fjs/bnf/matcher/proof.f.d.mts +10 -0
  35. package/fjs/bnf/matcher/proof.f.mjs +79 -0
  36. package/fjs/bnf/matcher/types.d.ts +54 -0
  37. package/fjs/bnf/module.f.d.mts +15 -6
  38. package/fjs/bnf/module.f.mjs +52 -11
  39. package/fjs/bnf/proof.f.d.mts +2 -0
  40. package/fjs/bnf/proof.f.mjs +79 -3
  41. package/fjs/bnf/testlib.f.d.mts +31 -0
  42. package/fjs/bnf/testlib.f.mjs +80 -0
  43. package/fjs/bnf/token_symbol/module.f.d.mts +4 -3
  44. package/fjs/bnf/token_symbol/module.f.mjs +7 -6
  45. package/fjs/bnf/token_symbol/proof.f.mjs +5 -2
  46. package/fjs/bnf/token_symbol/types.d.ts +2 -2
  47. package/fjs/bnf/types.d.ts +10 -3
  48. package/fjs/cas/cli/module.f.d.mts +1 -1
  49. package/fjs/cas/cli/module.f.mjs +14 -20
  50. package/fjs/cas/cli/proof.f.d.mts +4 -4
  51. package/fjs/cas/cli/proof.f.mjs +47 -34
  52. package/fjs/cas/evo/module.f.d.mts +71 -31
  53. package/fjs/cas/evo/module.f.mjs +223 -138
  54. package/fjs/cas/evo/proof.f.d.mts +10 -1
  55. package/fjs/cas/evo/proof.f.mjs +311 -226
  56. package/fjs/cas/evo/types.d.ts +45 -9
  57. package/fjs/cas/module.f.d.mts +18 -32
  58. package/fjs/cas/module.f.mjs +164 -176
  59. package/fjs/cas/proof.f.d.mts +11 -8
  60. package/fjs/cas/proof.f.mjs +259 -147
  61. package/fjs/cas/types.d.ts +24 -10
  62. package/fjs/ci/common/module.f.d.mts +1 -1
  63. package/fjs/ci/common/module.f.mjs +1 -0
  64. package/fjs/ci/config/module.f.d.mts +3 -3
  65. package/fjs/ci/config/module.f.mjs +3 -3
  66. package/fjs/ci/module.f.d.mts +5 -5
  67. package/fjs/ci/module.f.mjs +8 -7
  68. package/fjs/ci/nix/module.f.d.mts +7 -5
  69. package/fjs/ci/nix/module.f.mjs +13 -12
  70. package/fjs/ci/nix/proof.f.d.mts +2 -0
  71. package/fjs/ci/nix/proof.f.mjs +4 -4
  72. package/fjs/ci/proof.f.d.mts +4 -2
  73. package/fjs/ci/proof.f.mjs +13 -8
  74. package/fjs/cli/module.f.d.mts +4 -6
  75. package/fjs/cli/module.f.mjs +4 -8
  76. package/fjs/cli/proof.f.d.mts +4 -2
  77. package/fjs/cli/proof.f.mjs +21 -18
  78. package/fjs/cli/types.d.ts +2 -3
  79. package/fjs/common/monoid/module.f.d.mts +70 -12
  80. package/fjs/common/monoid/module.f.mjs +177 -14
  81. package/fjs/common/monoid/proof.f.d.mts +12 -1
  82. package/fjs/common/monoid/proof.f.mjs +88 -4
  83. package/fjs/common/monoid/types.d.ts +23 -0
  84. package/fjs/crypto/hmac/module.f.mjs +2 -2
  85. package/fjs/crypto/secp/proof.f.d.mts +3 -1
  86. package/fjs/crypto/secp/proof.f.mjs +3 -1
  87. package/fjs/crypto/sha2/module.f.mjs +3 -1
  88. package/fjs/crypto/sha2/proof.f.d.mts +4 -1
  89. package/fjs/crypto/sha2/proof.f.mjs +27 -1
  90. package/fjs/crypto/sha2/types.d.ts +11 -0
  91. package/fjs/crypto/sign/module.f.mjs +2 -2
  92. package/fjs/crypto/vdf/module.f.d.mts +23 -4
  93. package/fjs/crypto/vdf/module.f.mjs +6 -4
  94. package/fjs/dev/module.f.d.mts +17 -5
  95. package/fjs/dev/module.f.mjs +60 -30
  96. package/fjs/dev/update/module.f.d.mts +11 -3
  97. package/fjs/dev/update/module.f.mjs +16 -11
  98. package/fjs/dev/update/proof.f.d.mts +4 -3
  99. package/fjs/dev/update/proof.f.mjs +11 -7
  100. package/fjs/djs/module.f.d.mts +13 -5
  101. package/fjs/djs/module.f.mjs +31 -16
  102. package/fjs/djs/parser/module.f.d.mts +16 -3
  103. package/fjs/djs/parser/module.f.mjs +135 -16
  104. package/fjs/djs/parser/proof.f.d.mts +8 -1
  105. package/fjs/djs/parser/proof.f.mjs +287 -13
  106. package/fjs/djs/parser/types.d.ts +7 -1
  107. package/fjs/djs/proof.f.d.mts +20 -1
  108. package/fjs/djs/proof.f.mjs +190 -12
  109. package/fjs/djs/serializer/module.f.d.mts +25 -8
  110. package/fjs/djs/serializer/module.f.mjs +66 -19
  111. package/fjs/djs/serializer/proof.f.d.mts +5 -0
  112. package/fjs/djs/serializer/proof.f.mjs +23 -1
  113. package/fjs/djs/tokenizer/module.f.d.mts +17 -5
  114. package/fjs/djs/tokenizer/module.f.mjs +120 -73
  115. package/fjs/djs/tokenizer/proof.f.d.mts +3 -0
  116. package/fjs/djs/tokenizer/proof.f.mjs +86 -67
  117. package/fjs/djs/transpiler/module.f.d.mts +13 -19
  118. package/fjs/djs/transpiler/module.f.mjs +79 -72
  119. package/fjs/djs/transpiler/types.d.ts +29 -0
  120. package/fjs/djs/types.d.ts +7 -1
  121. package/fjs/effects/list/module.f.d.mts +23 -12
  122. package/fjs/effects/list/module.f.mjs +16 -12
  123. package/fjs/effects/list/types.d.ts +27 -7
  124. package/fjs/effects/memory/module.f.d.mts +6 -3
  125. package/fjs/effects/memory/module.f.mjs +7 -7
  126. package/fjs/effects/memory/proof.f.d.mts +4 -0
  127. package/fjs/effects/memory/proof.f.mjs +18 -9
  128. package/fjs/effects/memory/types.d.ts +4 -3
  129. package/fjs/effects/mock/module.f.d.mts +28 -4
  130. package/fjs/effects/mock/module.f.mjs +39 -5
  131. package/fjs/effects/mock/types.d.ts +10 -1
  132. package/fjs/effects/module.d.mts +12 -2
  133. package/fjs/effects/module.f.d.mts +469 -281
  134. package/fjs/effects/module.f.mjs +538 -299
  135. package/fjs/effects/module.mjs +11 -2
  136. package/fjs/effects/node/memory/module.d.mts +7 -2
  137. package/fjs/effects/node/memory/module.mjs +9 -5
  138. package/fjs/effects/node/memory/proof.d.mts +2 -0
  139. package/fjs/effects/node/memory/proof.mjs +12 -5
  140. package/fjs/effects/node/module.d.mts +8 -2
  141. package/fjs/effects/node/module.f.d.mts +183 -43
  142. package/fjs/effects/node/module.f.mjs +260 -62
  143. package/fjs/effects/node/module.mjs +61 -50
  144. package/fjs/effects/node/proof.f.d.mts +28 -2
  145. package/fjs/effects/node/proof.f.mjs +161 -42
  146. package/fjs/effects/node/types.d.ts +106 -18
  147. package/fjs/effects/node/virtual/module.f.d.mts +21 -4
  148. package/fjs/effects/node/virtual/module.f.mjs +113 -70
  149. package/fjs/effects/node/virtual/proof.f.d.mts +31 -2
  150. package/fjs/effects/node/virtual/proof.f.mjs +201 -8
  151. package/fjs/effects/proof.f.d.mts +69 -34
  152. package/fjs/effects/proof.f.mjs +413 -130
  153. package/fjs/effects/types.d.ts +161 -33
  154. package/fjs/emergent_testing/all.test.d.mts +8 -0
  155. package/fjs/emergent_testing/all.test.mjs +14 -0
  156. package/fjs/emergent_testing/module.f.d.mts +22 -10
  157. package/fjs/emergent_testing/module.f.mjs +119 -85
  158. package/fjs/emergent_testing/proof.f.d.mts +21 -7
  159. package/fjs/emergent_testing/proof.f.mjs +169 -35
  160. package/fjs/emergent_testing/types.d.ts +22 -4
  161. package/fjs/fsc/bnf.f.d.mts +3 -0
  162. package/fjs/fsc/bnf.f.mjs +4 -1
  163. package/fjs/fsc/json.f.d.mts +3 -0
  164. package/fjs/fsc/json.f.mjs +4 -1
  165. package/fjs/fsc/module.f.d.mts +9 -0
  166. package/fjs/fsc/module.f.mjs +5 -3
  167. package/fjs/fsm/module.f.d.mts +14 -4
  168. package/fjs/fsm/module.f.mjs +54 -37
  169. package/fjs/fsm/proof.f.d.mts +5 -0
  170. package/fjs/fsm/proof.f.mjs +87 -115
  171. package/fjs/js/keywords/module.f.d.mts +52 -0
  172. package/fjs/js/keywords/module.f.mjs +72 -0
  173. package/fjs/{emergent_testing/scenarios/return-value.pass.d.ts → js/keywords/proof.f.d.mts} +1 -1
  174. package/fjs/js/keywords/proof.f.mjs +13 -0
  175. package/fjs/js/tokenizer/module.f.d.mts +30 -3
  176. package/fjs/js/tokenizer/module.f.mjs +161 -211
  177. package/fjs/js/tokenizer/proof.f.d.mts +1 -0
  178. package/fjs/js/tokenizer/proof.f.mjs +54 -24
  179. package/fjs/js/tokenizer/types.d.ts +33 -24
  180. package/fjs/mcp/cas/module.f.d.mts +1 -6
  181. package/fjs/mcp/cas/module.f.mjs +55 -51
  182. package/fjs/mcp/cas/proof.f.d.mts +15 -0
  183. package/fjs/mcp/cas/proof.f.mjs +174 -0
  184. package/fjs/mcp/evo/module.f.d.mts +19 -10
  185. package/fjs/mcp/evo/module.f.mjs +48 -27
  186. package/fjs/mcp/evo/proof.f.d.mts +6 -1
  187. package/fjs/mcp/evo/proof.f.mjs +115 -31
  188. package/fjs/mcp/module.f.d.mts +39 -4
  189. package/fjs/mcp/module.f.mjs +14 -12
  190. package/fjs/mcp/proof.f.d.mts +13 -1
  191. package/fjs/mcp/proof.f.mjs +120 -61
  192. package/fjs/media/html/module.f.d.mts +12 -0
  193. package/fjs/media/html/module.f.mjs +7 -5
  194. package/fjs/media/html/proof.f.d.mts +3 -0
  195. package/fjs/media/html/proof.f.mjs +4 -1
  196. package/fjs/media/json/extended/module.f.d.mts +82 -0
  197. package/fjs/media/json/extended/module.f.mjs +153 -0
  198. package/fjs/media/json/extended/proof.f.d.mts +42 -0
  199. package/fjs/media/json/extended/proof.f.mjs +127 -0
  200. package/fjs/media/json/extended/types.d.ts +23 -0
  201. package/fjs/media/json/module.f.d.mts +8 -2
  202. package/fjs/media/json/module.f.mjs +43 -41
  203. package/fjs/media/json/number/module.f.d.mts +59 -0
  204. package/fjs/media/json/number/module.f.mjs +136 -0
  205. package/fjs/media/json/number/proof.f.d.mts +24 -0
  206. package/fjs/media/json/number/proof.f.mjs +86 -0
  207. package/fjs/media/json/number/types.d.ts +28 -0
  208. package/fjs/media/json/parser/module.f.d.mts +25 -13
  209. package/fjs/media/json/parser/module.f.mjs +133 -72
  210. package/fjs/media/json/parser/proof.f.d.mts +5 -0
  211. package/fjs/media/json/parser/proof.f.mjs +31 -1
  212. package/fjs/media/json/parser/types.d.ts +38 -14
  213. package/fjs/media/json/rtti/module.f.d.mts +1 -1
  214. package/fjs/media/json/rtti/module.f.mjs +1 -1
  215. package/fjs/media/json/rtti/proof.f.d.mts +3 -0
  216. package/fjs/media/json/rtti/proof.f.mjs +12 -12
  217. package/fjs/media/json/schema/module.f.d.mts +61 -27
  218. package/fjs/media/json/schema/module.f.mjs +218 -63
  219. package/fjs/media/json/schema/proof.f.d.mts +41 -1
  220. package/fjs/media/json/schema/proof.f.mjs +220 -9
  221. package/fjs/media/json/serializer/module.f.d.mts +44 -0
  222. package/fjs/media/json/serializer/module.f.mjs +71 -9
  223. package/fjs/media/json/tokenizer/module.f.d.mts +8 -0
  224. package/fjs/media/json/tokenizer/module.f.mjs +31 -8
  225. package/fjs/media/json/tokenizer/proof.f.d.mts +6 -0
  226. package/fjs/media/json/tokenizer/proof.f.mjs +62 -21
  227. package/fjs/media/json/types.d.ts +36 -10
  228. package/fjs/media/lock/module.f.d.mts +100 -0
  229. package/fjs/media/lock/module.f.mjs +125 -0
  230. package/fjs/media/lock/proof.f.d.mts +33 -0
  231. package/fjs/media/lock/proof.f.mjs +196 -0
  232. package/fjs/media/lock/types.d.ts +15 -0
  233. package/fjs/media/module.f.d.mts +6 -5
  234. package/fjs/media/module.f.mjs +8 -7
  235. package/fjs/media/nix/module.f.d.mts +13 -0
  236. package/fjs/media/nix/module.f.mjs +4 -2
  237. package/fjs/media/nix/proof.f.d.mts +3 -0
  238. package/fjs/media/nix/proof.f.mjs +4 -1
  239. package/fjs/media/note/module.f.d.mts +121 -0
  240. package/fjs/media/note/module.f.mjs +131 -0
  241. package/fjs/media/note/proof.f.d.mts +29 -0
  242. package/fjs/media/note/proof.f.mjs +150 -0
  243. package/fjs/media/note/types.d.ts +10 -0
  244. package/fjs/media/proof.f.d.mts +4 -1
  245. package/fjs/media/proof.f.mjs +40 -21
  246. package/fjs/media/revision/module.f.d.mts +83 -7
  247. package/fjs/media/revision/module.f.mjs +127 -23
  248. package/fjs/media/revision/proof.f.d.mts +14 -0
  249. package/fjs/media/revision/proof.f.mjs +93 -2
  250. package/fjs/media/revision/types.d.ts +34 -5
  251. package/fjs/media/type/module.f.d.mts +53 -18
  252. package/fjs/media/type/module.f.mjs +87 -97
  253. package/fjs/media/type/proof.f.d.mts +17 -0
  254. package/fjs/media/type/proof.f.mjs +73 -13
  255. package/fjs/module.d.mts +5 -0
  256. package/fjs/module.f.d.mts +8 -0
  257. package/fjs/module.f.mjs +33 -10
  258. package/fjs/module.mjs +6 -0
  259. package/fjs/nanvm/proof.f.mjs +3 -3
  260. package/fjs/nanvm/rust/module.f.mjs +1 -1
  261. package/fjs/nanvm/update/module.f.d.mts +4 -4
  262. package/fjs/nanvm/update/module.f.mjs +8 -9
  263. package/fjs/nanvm/update/proof.f.mjs +4 -3
  264. package/fjs/path/module.f.d.mts +8 -0
  265. package/fjs/path/module.f.mjs +4 -2
  266. package/fjs/proof.f.d.mts +7 -3
  267. package/fjs/proof.f.mjs +41 -12
  268. package/fjs/protocol/json_rpc/module.f.d.mts +3 -3
  269. package/fjs/protocol/json_rpc/module.f.mjs +10 -7
  270. package/fjs/protocol/json_rpc/proof.f.d.mts +6 -0
  271. package/fjs/protocol/json_rpc/proof.f.mjs +26 -5
  272. package/fjs/protocol/mcp/module.f.d.mts +10 -13
  273. package/fjs/protocol/mcp/module.f.mjs +74 -58
  274. package/fjs/protocol/mcp/proof.f.d.mts +16 -3
  275. package/fjs/protocol/mcp/proof.f.mjs +224 -69
  276. package/fjs/protocol/mcp/stdio/module.f.d.mts +17 -11
  277. package/fjs/protocol/mcp/stdio/module.f.mjs +39 -33
  278. package/fjs/protocol/mcp/stdio/proof.f.d.mts +5 -3
  279. package/fjs/protocol/mcp/stdio/proof.f.mjs +46 -13
  280. package/fjs/protocol/mcp/stdio/types.d.ts +14 -0
  281. package/fjs/protocol/mcp/types.d.ts +17 -6
  282. package/fjs/sul/id/module.f.d.mts +4 -0
  283. package/fjs/sul/id/module.f.mjs +6 -6
  284. package/fjs/sul/level/hash/module.f.d.mts +4 -1
  285. package/fjs/sul/level/hash/module.f.mjs +6 -4
  286. package/fjs/sul/level/hash/proof.f.d.mts +4 -0
  287. package/fjs/sul/level/hash/proof.f.mjs +7 -4
  288. package/fjs/sul/level/literal/module.f.d.mts +4 -1
  289. package/fjs/sul/level/literal/module.f.mjs +4 -3
  290. package/fjs/sul/level/literal/proof.f.d.mts +3 -0
  291. package/fjs/sul/level/literal/proof.f.mjs +4 -1
  292. package/fjs/sul/module.f.d.mts +5 -3
  293. package/fjs/sul/module.f.mjs +23 -17
  294. package/fjs/sul/proof.f.d.mts +4 -0
  295. package/fjs/sul/proof.f.mjs +5 -2
  296. package/fjs/text/ascii/module.f.d.mts +26 -0
  297. package/fjs/text/ascii/module.f.mjs +49 -1
  298. package/fjs/text/ascii/proof.f.d.mts +10 -0
  299. package/fjs/text/ascii/proof.f.mjs +33 -1
  300. package/fjs/text/code_point/module.f.d.mts +29 -3
  301. package/fjs/text/code_point/module.f.mjs +32 -9
  302. package/fjs/text/code_point/proof.f.d.mts +2 -0
  303. package/fjs/text/code_point/proof.f.mjs +39 -0
  304. package/fjs/text/module.f.d.mts +4 -2
  305. package/fjs/text/module.f.mjs +4 -3
  306. package/fjs/text/proof.f.d.mts +3 -0
  307. package/fjs/text/proof.f.mjs +4 -1
  308. package/fjs/text/sgr/module.f.d.mts +6 -5
  309. package/fjs/text/sgr/module.f.mjs +8 -8
  310. package/fjs/text/sgr/proof.f.d.mts +3 -0
  311. package/fjs/text/sgr/proof.f.mjs +4 -1
  312. package/fjs/text/utf16/module.f.d.mts +5 -1
  313. package/fjs/text/utf16/module.f.mjs +38 -35
  314. package/fjs/text/utf16/proof.f.d.mts +3 -1
  315. package/fjs/text/utf16/proof.f.mjs +19 -2
  316. package/fjs/text/utf8/module.f.d.mts +9 -5
  317. package/fjs/text/utf8/module.f.mjs +20 -20
  318. package/fjs/types/array/module.f.d.mts +2 -1
  319. package/fjs/types/array/module.f.mjs +16 -4
  320. package/fjs/types/bigfloat/module.f.d.mts +21 -1
  321. package/fjs/types/bigfloat/module.f.mjs +33 -7
  322. package/fjs/types/bigfloat/proof.f.d.mts +1 -0
  323. package/fjs/types/bigfloat/proof.f.mjs +46 -0
  324. package/fjs/types/bigint/module.f.d.mts +4 -0
  325. package/fjs/types/bigint/module.f.mjs +4 -3
  326. package/fjs/types/bit_vec/module.f.d.mts +10 -16
  327. package/fjs/types/bit_vec/module.f.mjs +99 -95
  328. package/fjs/types/bit_vec/proof.f.d.mts +6 -0
  329. package/fjs/types/bit_vec/proof.f.mjs +31 -5
  330. package/fjs/types/btree/find/module.f.d.mts +5 -1
  331. package/fjs/types/btree/find/module.f.mjs +5 -5
  332. package/fjs/types/btree/find/proof.f.d.mts +5 -1
  333. package/fjs/types/btree/find/proof.f.mjs +5 -3
  334. package/fjs/types/btree/module.f.d.mts +3 -0
  335. package/fjs/types/btree/module.f.mjs +3 -2
  336. package/fjs/types/btree/proof.f.d.mts +5 -1
  337. package/fjs/types/btree/proof.f.mjs +5 -3
  338. package/fjs/types/btree/remove/module.f.d.mts +11 -0
  339. package/fjs/types/btree/remove/module.f.mjs +10 -10
  340. package/fjs/types/btree/remove/proof.f.d.mts +3 -0
  341. package/fjs/types/btree/remove/proof.f.mjs +4 -1
  342. package/fjs/types/btree/set/module.f.d.mts +9 -0
  343. package/fjs/types/btree/set/module.f.mjs +14 -17
  344. package/fjs/types/btree/set/proof.f.d.mts +3 -0
  345. package/fjs/types/btree/set/proof.f.mjs +16 -1
  346. package/fjs/types/btree/types/module.f.d.mts +2 -1
  347. package/fjs/types/btree/types/module.f.mjs +2 -1
  348. package/fjs/types/byte_set/module.f.d.mts +20 -4
  349. package/fjs/types/byte_set/module.f.mjs +18 -8
  350. package/fjs/types/byte_set/proof.f.d.mts +3 -1
  351. package/fjs/types/byte_set/proof.f.mjs +10 -8
  352. package/fjs/types/function/compare/module.f.d.mts +3 -2
  353. package/fjs/types/function/compare/module.f.mjs +13 -5
  354. package/fjs/types/function/module.f.d.mts +8 -1
  355. package/fjs/types/function/module.f.mjs +8 -1
  356. package/fjs/types/function/operator/module.f.d.mts +2 -1
  357. package/fjs/types/function/operator/module.f.mjs +2 -2
  358. package/fjs/types/list/module.f.d.mts +10 -3
  359. package/fjs/types/list/module.f.mjs +6 -4
  360. package/fjs/types/list/proof.f.d.mts +4 -1
  361. package/fjs/types/list/proof.f.mjs +4 -2
  362. package/fjs/types/nibble_set/module.f.d.mts +2 -1
  363. package/fjs/types/nibble_set/module.f.mjs +2 -2
  364. package/fjs/types/nominal/module.f.d.mts +2 -1
  365. package/fjs/types/nominal/module.f.mjs +2 -1
  366. package/fjs/types/nullable/module.f.d.mts +26 -6
  367. package/fjs/types/nullable/module.f.mjs +25 -6
  368. package/fjs/types/nullable/proof.f.d.mts +4 -0
  369. package/fjs/types/nullable/proof.f.mjs +15 -0
  370. package/fjs/types/number/module.f.d.mts +4 -0
  371. package/fjs/types/number/module.f.mjs +4 -3
  372. package/fjs/types/object/module.f.d.mts +26 -4
  373. package/fjs/types/object/module.f.mjs +26 -7
  374. package/fjs/types/object/proof.f.d.mts +5 -2
  375. package/fjs/types/object/proof.f.mjs +6 -3
  376. package/fjs/types/object/structurally_same/module.f.d.mts +39 -0
  377. package/fjs/types/object/structurally_same/module.f.mjs +59 -0
  378. package/fjs/types/object/structurally_same/proof.f.d.mts +6 -0
  379. package/fjs/types/object/structurally_same/proof.f.mjs +73 -0
  380. package/fjs/types/ordered_map/module.f.d.mts +5 -0
  381. package/fjs/types/ordered_map/module.f.mjs +5 -4
  382. package/fjs/types/ordered_map/proof.f.d.mts +3 -0
  383. package/fjs/types/ordered_map/proof.f.mjs +4 -1
  384. package/fjs/types/patricia_trie/module.f.d.mts +2 -1
  385. package/fjs/types/patricia_trie/module.f.mjs +27 -12
  386. package/fjs/types/patricia_trie/proof.f.d.mts +3 -0
  387. package/fjs/types/patricia_trie/proof.f.mjs +4 -1
  388. package/fjs/types/prime_field/module.f.d.mts +3 -1
  389. package/fjs/types/prime_field/module.f.mjs +3 -2
  390. package/fjs/types/range/module.f.d.mts +2 -1
  391. package/fjs/types/range/module.f.mjs +2 -2
  392. package/fjs/types/range_map/module.f.d.mts +6 -0
  393. package/fjs/types/range_map/module.f.mjs +6 -9
  394. package/fjs/types/range_map/proof.f.d.mts +5 -1
  395. package/fjs/types/range_map/proof.f.mjs +5 -3
  396. package/fjs/types/range_set/module.f.d.mts +5 -0
  397. package/fjs/types/range_set/module.f.mjs +1 -0
  398. package/fjs/types/range_set/proof.f.d.mts +3 -0
  399. package/fjs/types/range_set/proof.f.mjs +4 -1
  400. package/fjs/types/result/module.d.mts +8 -0
  401. package/fjs/types/result/module.f.d.mts +37 -7
  402. package/fjs/types/result/module.f.mjs +38 -8
  403. package/fjs/types/result/module.mjs +9 -1
  404. package/fjs/types/result/proof.f.d.mts +5 -0
  405. package/fjs/types/result/proof.f.mjs +22 -2
  406. package/fjs/types/rtti/common/module.f.d.mts +44 -14
  407. package/fjs/types/rtti/common/module.f.mjs +42 -36
  408. package/fjs/types/rtti/common/proof.f.d.mts +4 -0
  409. package/fjs/types/rtti/common/proof.f.mjs +10 -7
  410. package/fjs/types/rtti/data/module.f.d.mts +134 -0
  411. package/fjs/types/rtti/data/module.f.mjs +1053 -0
  412. package/fjs/types/rtti/data/proof.f.d.mts +76 -0
  413. package/fjs/types/rtti/data/proof.f.mjs +589 -0
  414. package/fjs/types/rtti/data/types.d.ts +83 -0
  415. package/fjs/types/rtti/module.f.d.mts +12 -5
  416. package/fjs/types/rtti/module.f.mjs +7 -5
  417. package/fjs/types/rtti/parse/module.f.d.mts +48 -0
  418. package/fjs/types/rtti/parse/module.f.mjs +45 -34
  419. package/fjs/types/rtti/parse/proof.f.d.mts +3 -2
  420. package/fjs/types/rtti/parse/proof.f.mjs +51 -52
  421. package/fjs/types/rtti/proof.f.d.mts +3 -1
  422. package/fjs/types/rtti/proof.f.mjs +6 -2
  423. package/fjs/types/rtti/ts/module.f.d.mts +68 -9
  424. package/fjs/types/rtti/ts/module.f.mjs +258 -30
  425. package/fjs/types/rtti/ts/proof.f.d.mts +44 -0
  426. package/fjs/types/rtti/ts/proof.f.mjs +152 -4
  427. package/fjs/types/rtti/ts/types.d.ts +25 -1
  428. package/fjs/types/rtti/types.d.ts +40 -0
  429. package/fjs/types/sorted_list/module.f.d.mts +4 -1
  430. package/fjs/types/sorted_list/module.f.mjs +21 -12
  431. package/fjs/types/sorted_list/proof.f.d.mts +3 -1
  432. package/fjs/types/sorted_list/proof.f.mjs +3 -1
  433. package/fjs/types/sorted_set/module.f.d.mts +49 -1
  434. package/fjs/types/sorted_set/module.f.mjs +26 -2
  435. package/fjs/types/sorted_set/proof.f.d.mts +4 -1
  436. package/fjs/types/sorted_set/proof.f.mjs +19 -2
  437. package/fjs/types/string/module.f.d.mts +4 -0
  438. package/fjs/types/string/module.f.mjs +4 -3
  439. package/fjs/types/string_set/module.f.d.mts +3 -1
  440. package/fjs/types/string_set/module.f.mjs +3 -2
  441. package/fjs/types/ts/module.f.d.mts +2 -0
  442. package/fjs/types/ts/module.f.mjs +3 -3
  443. package/fjs/types/ts/proof.f.d.mts +1 -0
  444. package/fjs/types/ts/proof.f.mjs +5 -0
  445. package/fjs/types/ts/types.d.ts +6 -1
  446. package/fjs/types/uint8array/module.f.d.mts +13 -2
  447. package/fjs/types/uint8array/module.f.mjs +20 -15
  448. package/fjs/website/module.f.d.mts +5 -2
  449. package/fjs/website/module.f.mjs +6 -8
  450. package/fjs/website/proof.f.mjs +2 -1
  451. package/package.json +3 -3
  452. package/fjs/asn.1/types.js +0 -6
  453. package/fjs/asserts/types.js +0 -6
  454. package/fjs/basen/types.js +0 -6
  455. package/fjs/bnf/data/types.js +0 -6
  456. package/fjs/bnf/descent/types.js +0 -6
  457. package/fjs/bnf/ll1/types.js +0 -6
  458. package/fjs/bnf/token_symbol/types.js +0 -6
  459. package/fjs/bnf/types.js +0 -6
  460. package/fjs/cas/evo/types.js +0 -7
  461. package/fjs/cas/types.js +0 -6
  462. package/fjs/ci/common/types.js +0 -1
  463. package/fjs/ci/nix/types.js +0 -6
  464. package/fjs/ci/types.js +0 -6
  465. package/fjs/cli/types.js +0 -6
  466. package/fjs/common/monoid/types.js +0 -6
  467. package/fjs/crypto/pow/types.js +0 -6
  468. package/fjs/crypto/secp/types.js +0 -6
  469. package/fjs/crypto/sha2/types.js +0 -6
  470. package/fjs/crypto/sign/types.js +0 -6
  471. package/fjs/crypto/vdf/types.js +0 -6
  472. package/fjs/dev/package_json/module.f.d.mts +0 -32
  473. package/fjs/dev/package_json/module.f.mjs +0 -37
  474. package/fjs/dev/package_json/proof.f.d.mts +0 -6
  475. package/fjs/dev/package_json/proof.f.mjs +0 -32
  476. package/fjs/dev/types.js +0 -6
  477. package/fjs/djs/ast/types.js +0 -8
  478. package/fjs/djs/parser/types.js +0 -7
  479. package/fjs/djs/tokenizer/types.js +0 -7
  480. package/fjs/djs/types.js +0 -7
  481. package/fjs/effects/eff/module.f.d.mts +0 -10
  482. package/fjs/effects/eff/module.f.mjs +0 -68
  483. package/fjs/effects/eff/proof.f.d.mts +0 -12
  484. package/fjs/effects/eff/proof.f.mjs +0 -66
  485. package/fjs/effects/eff/types.d.ts +0 -71
  486. package/fjs/effects/eff/types.js +0 -6
  487. package/fjs/effects/list/types.js +0 -6
  488. package/fjs/effects/memory/types.js +0 -6
  489. package/fjs/effects/mock/types.js +0 -6
  490. package/fjs/effects/node/types.js +0 -6
  491. package/fjs/effects/node/virtual/types.js +0 -7
  492. package/fjs/effects/types.js +0 -6
  493. package/fjs/emergent_testing/all.test.d.ts +0 -1
  494. package/fjs/emergent_testing/all.test.js +0 -5
  495. package/fjs/emergent_testing/scenarios/all.d.ts +0 -1
  496. package/fjs/emergent_testing/scenarios/all.js +0 -1
  497. package/fjs/emergent_testing/scenarios/async-subtests.fail.d.ts +0 -6
  498. package/fjs/emergent_testing/scenarios/async-subtests.fail.js +0 -9
  499. package/fjs/emergent_testing/scenarios/async-subtests.pass.d.ts +0 -6
  500. package/fjs/emergent_testing/scenarios/async-subtests.pass.js +0 -9
  501. package/fjs/emergent_testing/scenarios/async.fail.d.ts +0 -3
  502. package/fjs/emergent_testing/scenarios/async.fail.js +0 -6
  503. package/fjs/emergent_testing/scenarios/async.pass.d.ts +0 -3
  504. package/fjs/emergent_testing/scenarios/async.pass.js +0 -5
  505. package/fjs/emergent_testing/scenarios/fail.fail.d.ts +0 -3
  506. package/fjs/emergent_testing/scenarios/fail.fail.js +0 -3
  507. package/fjs/emergent_testing/scenarios/return-value.pass.js +0 -4
  508. package/fjs/emergent_testing/scenarios/thenable.pass.d.ts +0 -5
  509. package/fjs/emergent_testing/scenarios/thenable.pass.js +0 -11
  510. package/fjs/emergent_testing/scenarios/thenable2.pass.d.ts +0 -5
  511. package/fjs/emergent_testing/scenarios/thenable2.pass.js +0 -3
  512. package/fjs/emergent_testing/scenarios/throw.pass.d.ts +0 -5
  513. package/fjs/emergent_testing/scenarios/throw.pass.js +0 -3
  514. package/fjs/emergent_testing/types.js +0 -6
  515. package/fjs/js/tokenizer/types.js +0 -6
  516. package/fjs/media/html/types.js +0 -6
  517. package/fjs/media/json/parser/types.js +0 -6
  518. package/fjs/media/json/tokenizer/types.js +0 -6
  519. package/fjs/media/json/types.js +0 -13
  520. package/fjs/media/nix/types.js +0 -6
  521. package/fjs/media/revision/types.js +0 -8
  522. package/fjs/media/type/types.js +0 -6
  523. package/fjs/media/types.js +0 -7
  524. package/fjs/nanvm/types.js +0 -11
  525. package/fjs/protocol/json_rpc/types.js +0 -8
  526. package/fjs/protocol/mcp/types.js +0 -8
  527. package/fjs/sul/id/types.js +0 -6
  528. package/fjs/sul/level/hash/types.js +0 -6
  529. package/fjs/sul/level/literal/types.js +0 -6
  530. package/fjs/sul/types.js +0 -6
  531. package/fjs/text/sgr/types.js +0 -6
  532. package/fjs/text/types.js +0 -6
  533. package/fjs/text/utf16/types.js +0 -6
  534. package/fjs/text/utf8/types.js +0 -6
  535. package/fjs/types/array/types.js +0 -6
  536. package/fjs/types/bigfloat/types.js +0 -6
  537. package/fjs/types/bigint/types.js +0 -6
  538. package/fjs/types/bit_vec/types.js +0 -6
  539. package/fjs/types/btree/find/types.js +0 -6
  540. package/fjs/types/btree/types/types.js +0 -6
  541. package/fjs/types/byte_set/types.js +0 -6
  542. package/fjs/types/function/compare/types.js +0 -6
  543. package/fjs/types/function/operator/types.js +0 -6
  544. package/fjs/types/function/types.js +0 -6
  545. package/fjs/types/list/types.js +0 -6
  546. package/fjs/types/nibble_set/types.js +0 -6
  547. package/fjs/types/nominal/types.js +0 -6
  548. package/fjs/types/nullable/types.js +0 -6
  549. package/fjs/types/object/types.js +0 -8
  550. package/fjs/types/option/types.js +0 -6
  551. package/fjs/types/ordered_map/types.js +0 -6
  552. package/fjs/types/patricia_trie/types.js +0 -6
  553. package/fjs/types/phantom/types.js +0 -11
  554. package/fjs/types/prime_field/types.js +0 -6
  555. package/fjs/types/range/types.js +0 -6
  556. package/fjs/types/range_map/types.js +0 -6
  557. package/fjs/types/result/types.js +0 -6
  558. package/fjs/types/rtti/common/types.js +0 -1
  559. package/fjs/types/rtti/parse/types.js +0 -1
  560. package/fjs/types/rtti/ts/types.js +0 -1
  561. package/fjs/types/rtti/types.js +0 -1
  562. package/fjs/types/rtti/validate/module.f.d.mts +0 -6
  563. package/fjs/types/rtti/validate/module.f.mjs +0 -169
  564. package/fjs/types/rtti/validate/proof.f.d.mts +0 -125
  565. package/fjs/types/rtti/validate/proof.f.mjs +0 -437
  566. package/fjs/types/rtti/validate/types.d.ts +0 -6
  567. package/fjs/types/rtti/validate/types.js +0 -1
  568. package/fjs/types/sorted_list/types.js +0 -6
  569. package/fjs/types/sorted_set/types.js +0 -6
  570. package/fjs/types/string_set/types.js +0 -6
  571. package/fjs/types/ts/types.js +0 -8
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @import { Unknown } from './types.ts'
3
+ */
4
+ export declare const proof: {
5
+ bigint: {
6
+ positive: () => void;
7
+ negative: () => void;
8
+ zero: () => void;
9
+ beyondSafeInteger: () => void;
10
+ oversized: () => void;
11
+ };
12
+ number: {
13
+ negativeZero: () => void;
14
+ fraction: () => void;
15
+ wholeFraction: () => void;
16
+ exponent: () => void;
17
+ capitalExponent: () => void;
18
+ negativeExponent: () => void;
19
+ underflow: () => void;
20
+ exponentSpelling: () => void;
21
+ };
22
+ overflow: {
23
+ exponent: () => void;
24
+ negativeExponent: () => void;
25
+ unboundedExponent: () => void;
26
+ malformed: () => void;
27
+ };
28
+ containers: {
29
+ array: () => void;
30
+ object: () => void;
31
+ undefinedProperty: () => void;
32
+ };
33
+ nonFinite: {
34
+ nan: () => void;
35
+ infinity: () => void;
36
+ negativeInfinity: () => void;
37
+ };
38
+ serialize: {
39
+ oneToOne: () => void;
40
+ largeBigintHasNoExponent: () => void;
41
+ };
42
+ };
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @import { Unknown } from './types.ts'
3
+ */
4
+
5
+ import { parse, stringify as extendedStringify } from './module.f.mjs'
6
+ import { sort } from '../../../types/object/module.f.mjs'
7
+ import { unwrap } from '../../../types/result/module.f.mjs'
8
+ import { assert, assertEq, assertStructurallySame } from '../../../asserts/module.f.mjs'
9
+
10
+ const stringify = extendedStringify(sort)
11
+
12
+ /**
13
+ * The runtime type a token parses to, and the text that value serializes back
14
+ * to — the two halves of the extended codec's round trip.
15
+ *
16
+ * @type {(text: string) => readonly [string, string]}
17
+ */
18
+ const parsed = text => {
19
+ const value = unwrap(parse(text))
20
+ return [typeof value, stringify(value)]
21
+ }
22
+
23
+ /** @type {(text: string) => Unknown} */
24
+ const parseValue = text => unwrap(parse(text))
25
+
26
+ /** @type {(text: string) => string} */
27
+ const parseError = text => {
28
+ const [tag, message] = parse(text)
29
+ assertEq(tag, 'error')
30
+ return `${message}`
31
+ }
32
+
33
+ // Long enough that `Number` of it is `Infinity` and `10 ** exponent` is not a
34
+ // computation anyone can afford.
35
+ const hugeExp = '99999999999999999999'
36
+
37
+ export const proof = {
38
+ // bare integer syntax is `bigint`, whatever the magnitude
39
+ bigint: {
40
+ positive: () => assertStructurallySame(parsed('123'), ['bigint', '123']),
41
+ negative: () => assertStructurallySame(parsed('-123'), ['bigint', '-123']),
42
+ zero: () => assertStructurallySame(parsed('0'), ['bigint', '0']),
43
+ // beyond `Number.MAX_SAFE_INTEGER`, so a materializer that went
44
+ // through `number` first would round here
45
+ beyondSafeInteger: () => {
46
+ assertEq(parseValue('12345678901234567890123'), 12345678901234567890123n)
47
+ assertEq(parseValue('-12345678901234567890123'), -12345678901234567890123n)
48
+ },
49
+ // an integer of a size no `number` can even approximate
50
+ oversized: () => {
51
+ const digits = `1${'0'.repeat(2000)}`
52
+ assertStructurallySame(parsed(digits), ['bigint', digits])
53
+ assertEq(parseValue(digits), 10n ** 2000n)
54
+ },
55
+ },
56
+ // `.`/`e`/`E` means `number`, even when the value is a whole number
57
+ number: {
58
+ negativeZero: () => {
59
+ assertStructurallySame(parsed('-0'), ['number', '-0'])
60
+ // the sign is the whole point: `bigint` has no negative zero
61
+ assert(Object.is(parseValue('-0'), -0))
62
+ },
63
+ fraction: () => assertStructurallySame(parsed('1.5'), ['number', '1.5']),
64
+ wholeFraction: () => assertStructurallySame(parsed('1.0'), ['number', '1.0']),
65
+ exponent: () => assertStructurallySame(parsed('1e3'), ['number', '1000.0']),
66
+ capitalExponent: () => assertStructurallySame(parsed('1E3'), ['number', '1000.0']),
67
+ negativeExponent: () => assertStructurallySame(parsed('1e-3'), ['number', '0.001']),
68
+ // ordinary `number` rounding is not an error: an exponent below the
69
+ // range is zero, as it is everywhere else in JavaScript
70
+ underflow: () => assertStructurallySame(parsed('1e-400'), ['number', '0.0']),
71
+ // a `number` big enough to spell itself with an exponent keeps that
72
+ // spelling — appending `.0` to it would not even be valid JSON
73
+ exponentSpelling: () => assertStructurallySame(parsed('1e21'), ['number', '1e+21']),
74
+ },
75
+ // a valid token the extended domain cannot represent is an ordinary
76
+ // parse error, never `Infinity` and never a throw
77
+ overflow: {
78
+ exponent: () => assertEq(
79
+ parseError('1e400'),
80
+ 'number is out of the finite range: 1e400'),
81
+ negativeExponent: () => assertEq(
82
+ parseError('-1e400'),
83
+ 'number is out of the finite range: -1e400'),
84
+ // exponent text far beyond `number` precision: the tokenizer keeps
85
+ // every digit, and the policy rejects the token rather than losing them
86
+ unboundedExponent: () => assertEq(
87
+ parseError(`1e${hugeExp}`),
88
+ `number is out of the finite range: 1e${hugeExp}`),
89
+ // malformed input is still an ordinary error
90
+ malformed: () => assertEq(parseError('{'), 'unexpected end'),
91
+ },
92
+ containers: {
93
+ array: () => assertEq(
94
+ stringify(parseValue('[1,2.0,-0,"x",true,false,null]')),
95
+ '[1,2.0,-0,"x",true,false,null]'),
96
+ object: () => assertEq(
97
+ stringify(parseValue('{"b":[1e2],"a":{"c":-7}}')),
98
+ '{"a":{"c":-7},"b":[100.0]}'),
99
+ // a missing property is not a leaf
100
+ undefinedProperty: () => assertEq(stringify({ a: 1n, b: undefined }), '{"a":1}'),
101
+ },
102
+ // programmatic values: JSON has no syntax for these, so the serializer
103
+ // spells them `null` — the same choice `JSON.stringify` makes
104
+ nonFinite: {
105
+ nan: () => assertEq(stringify(NaN), 'null'),
106
+ infinity: () => assertEq(stringify(Infinity), 'null'),
107
+ negativeInfinity: () => assertEq(stringify(-Infinity), 'null'),
108
+ },
109
+ // the spellings that keep `number` and `bigint` apart across a round trip
110
+ serialize: {
111
+ oneToOne: () => {
112
+ assertEq(stringify(0n), '0')
113
+ assertEq(stringify(0), '0.0')
114
+ assertEq(stringify(-0), '-0')
115
+ assertEq(stringify(3n), '3')
116
+ assertEq(stringify(3), '3.0')
117
+ assertEq(stringify(1.5), '1.5')
118
+ },
119
+ // a bigint is never shortened to exponent notation, however large:
120
+ // that syntax would parse back as a `number`
121
+ largeBigintHasNoExponent: () => {
122
+ const text = stringify(10n ** 30n)
123
+ assertEq(text, `1${'0'.repeat(30)}`)
124
+ assertStructurallySame(parsed(text), ['bigint', text])
125
+ },
126
+ },
127
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * TypeScript counterparts of the extended JSON data model: ordinary JSON's
3
+ * containers with `bigint` added to the primitive leaf set.
4
+ *
5
+ * This is a runtime representation, not a new syntax: an extended value's
6
+ * serialized form is ordinary valid JSON text, with no `123n` literal, tagged
7
+ * object, or quoted-integer convention.
8
+ *
9
+ * @module
10
+ */
11
+ import type { Primitive as JsonPrimitive, Tree, TreeObject, TreeArray, TreeMapEntries } from '../types.ts';
12
+ /**
13
+ * `null | boolean | string | number | bigint`.
14
+ *
15
+ * `bigint` carries JSON's bare integer syntax exactly, whatever its
16
+ * magnitude; `number` carries decimal and exponent syntax, and the one bare
17
+ * integer that `bigint` cannot represent — negative zero.
18
+ */
19
+ export type Primitive = JsonPrimitive | bigint;
20
+ export type Unknown = Tree<Primitive>;
21
+ export type Object = TreeObject<Primitive>;
22
+ export type Array = TreeArray<Primitive>;
23
+ export type _MapEntries = TreeMapEntries<Primitive>;
@@ -9,11 +9,17 @@
9
9
  * [`./types.ts`](./types.ts), and the rtti schemas they are pinned against in
10
10
  * [`./rtti/module.f.mjs`](./rtti/module.f.mjs).
11
11
  *
12
+ * This is the standard, bigint-free codec: numbers are JavaScript `number`s.
13
+ * [`./extended/module.f.mjs`](./extended/module.f.mjs) is the sibling codec
14
+ * that keeps JSON's bare integer syntax as `bigint`. Both are numeric policies
15
+ * over the same tokenizer and the same structural parser — see
16
+ * [`./README.md`](./README.md).
17
+ *
12
18
  * @module
13
19
  *
14
- * @import { StringMap } from '../../types/object/types.ts'
15
20
  * @import { Result } from '../../types/result/types.ts'
16
- * @import { _MapEntries, Object, Unknown, } from './types.ts'
21
+ * @import { _MapEntries, Primitive, Unknown, } from './types.ts'
22
+ * @import { NumberPolicy } from './parser/types.ts'
17
23
  * @import { List } from '../../types/list/types.ts'
18
24
  */
19
25
  import type { Result } from '../../types/result/types.ts';
@@ -9,22 +9,29 @@
9
9
  * [`./types.ts`](./types.ts), and the rtti schemas they are pinned against in
10
10
  * [`./rtti/module.f.mjs`](./rtti/module.f.mjs).
11
11
  *
12
+ * This is the standard, bigint-free codec: numbers are JavaScript `number`s.
13
+ * [`./extended/module.f.mjs`](./extended/module.f.mjs) is the sibling codec
14
+ * that keeps JSON's bare integer syntax as `bigint`. Both are numeric policies
15
+ * over the same tokenizer and the same structural parser — see
16
+ * [`./README.md`](./README.md).
17
+ *
12
18
  * @module
13
19
  *
14
- * @import { StringMap } from '../../types/object/types.ts'
15
20
  * @import { Result } from '../../types/result/types.ts'
16
- * @import { _MapEntries, Object, Unknown, } from './types.ts'
21
+ * @import { _MapEntries, Primitive, Unknown, } from './types.ts'
22
+ * @import { NumberPolicy } from './parser/types.ts'
17
23
  * @import { List } from '../../types/list/types.ts'
18
24
  */
19
25
 
20
- import { next, flat, map } from '../../types/list/module.f.mjs'
26
+ import { next } from '../../types/list/module.f.mjs'
21
27
  import { concat } from '../../types/string/module.f.mjs'
22
28
  import { stringToList } from '../../text/utf16/module.f.mjs'
23
29
  import { parse as parseTokens } from './parser/module.f.mjs'
24
30
  import { tokenize } from './tokenizer/module.f.mjs'
25
- import { at, definedEntries } from '../../types/object/module.f.mjs'
26
- import { compose, fn } from '../../types/function/module.f.mjs'
27
- import { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize, boolSerialize } from './serializer/module.f.mjs'
31
+ import { at } from '../../types/object/module.f.mjs'
32
+ import { compose } from '../../types/function/module.f.mjs'
33
+ import { ok } from '../../types/result/module.f.mjs'
34
+ import { treeSerialize, stringSerialize, numberSerialize, nullSerialize, boolSerialize } from './serializer/module.f.mjs'
28
35
 
29
36
  // ── JSON utilities ────────────────────────────────────────────────────────────
30
37
 
@@ -43,42 +50,23 @@ export const setProperty = value => {
43
50
  return f
44
51
  }
45
52
 
46
- const colon = [':']
47
-
48
- /** @type {(cmd: StringMap<Unknown>) => readonly (readonly [string, Unknown])[]} */
49
- const df = definedEntries
53
+ /**
54
+ * The standard codec's leaf spelling. The containers around it are
55
+ * `treeSerialize`'s, shared with every other JSON codec.
56
+ *
57
+ * @type {(value: Primitive) => List<string>}
58
+ */
59
+ const primitiveSerialize = value => {
60
+ switch (typeof value) {
61
+ case 'boolean': { return boolSerialize(value) }
62
+ case 'number': { return numberSerialize(value) }
63
+ case 'string': { return stringSerialize(value) }
64
+ default: { return nullSerialize }
65
+ }
66
+ }
50
67
 
51
68
  /** @type {(mapEntries: _MapEntries) => (value: Unknown) => List<string>} */
52
- export const serialize = sort => {
53
- /** @type {(kv: readonly[string, Unknown]) => List<string>} */
54
- const propertySerialize = ([k, v]) => flat([
55
- stringSerialize(k),
56
- colon,
57
- f(v)
58
- ])
59
- const mapPropertySerialize = map(propertySerialize)
60
- /** @type {(object: Object) => List<string>} */
61
- const objectSerialize = fn(df)
62
- .map(sort)
63
- .map(mapPropertySerialize)
64
- .map(objectWrap)
65
- .result
66
- /** @type {(value: Unknown) => List<string>} */
67
- const f = value => {
68
- switch (typeof value) {
69
- case 'boolean': { return boolSerialize(value) }
70
- case 'number': { return numberSerialize(value) }
71
- case 'string': { return stringSerialize(value) }
72
- default: {
73
- if (value === null) { return nullSerialize }
74
- if (value instanceof Array) { return arraySerialize(value) }
75
- return objectSerialize(value)
76
- }
77
- }
78
- }
79
- const arraySerialize = compose(map(f))(arrayWrap)
80
- return f
81
- }
69
+ export const serialize = treeSerialize(primitiveSerialize)
82
70
 
83
71
  /**
84
72
  * The standard `JSON.stringify` rules determined by
@@ -89,6 +77,20 @@ export const serialize = sort => {
89
77
  */
90
78
  export const stringify = sort => compose(serialize(sort))(concat)
91
79
 
80
+ /**
81
+ * The standard codec's numeric policy: every JSON number token becomes a
82
+ * JavaScript `number`, read from the token's own lexeme.
83
+ *
84
+ * It is total — no valid JSON number is rejected — so a magnitude outside the
85
+ * finite `number` range materializes the way JavaScript itself reads that
86
+ * text (`1e400` is `Infinity`, `1e-400` is `0`). The bigint-free domain has
87
+ * nothing more exact to offer; the extended codec keeps such distinctions,
88
+ * from the same token, without this one having to.
89
+ *
90
+ * @type {NumberPolicy<number>}
91
+ */
92
+ const numberPolicy = token => ok(parseFloat(token.value))
93
+
92
94
  /**
93
95
  * Parses `text` as JSON with this module's own pure tokenizer and parser,
94
96
  * reporting failure as a `Result` rather than throwing: malformed input is
@@ -101,4 +103,4 @@ export const stringify = sort => compose(serialize(sort))(concat)
101
103
  *
102
104
  * @type {(text: string) => Result<Unknown, string>}
103
105
  */
104
- export const parse = text => parseTokens(tokenize(stringToList(text)))
106
+ export const parse = text => parseTokens(numberPolicy)(tokenize(stringToList(text)))
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Bounded lexical analysis of a JSON number token.
3
+ *
4
+ * `NumberToken.value` is the canonical lossless numeric source, and these
5
+ * helpers read it **without narrowing it first**: every operation here costs
6
+ * at most the length of the token, so a valid JSON number is classified
7
+ * correctly whatever its magnitude. In particular no helper builds a
8
+ * coefficient bigint, converts an arbitrary exponent to `number`, or evaluates
9
+ * a power such as `10 ** exponent`.
10
+ *
11
+ * That matters for schema-directed consumers, which have to decide questions
12
+ * such as "is this token an integer?" *before* a materializer rounds the value
13
+ * into `number`: `1.00000000000000001` and `1` are the same `number` but
14
+ * different tokens.
15
+ *
16
+ * @module
17
+ *
18
+ * @import { Sign } from '../../../types/function/compare/types.ts'
19
+ * @import { NumberLexeme } from './types.ts'
20
+ */
21
+ import type { NumberLexeme } from './types.ts';
22
+ /**
23
+ * Splits a JSON number token into its lexical parts.
24
+ *
25
+ * The token is grammar-validated by the tokenizer —
26
+ * `-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?` — so this is a split, not a
27
+ * validation.
28
+ *
29
+ * @type {(value: string) => NumberLexeme}
30
+ */
31
+ export declare const numberLexeme: (value: string) => NumberLexeme;
32
+ /**
33
+ * Whether the lexeme is bare integer syntax: no `.` and no `e` / `E`.
34
+ *
35
+ * The distinction is lexical, not mathematical — `1e3` is not bare integer
36
+ * syntax even though its value is the integer `1000`.
37
+ *
38
+ * @type {(lexeme: NumberLexeme) => boolean}
39
+ */
40
+ export declare const isBareInteger: (lexeme: NumberLexeme) => boolean;
41
+ /**
42
+ * Whether the lexeme spells a mathematical integer.
43
+ *
44
+ * This is the exact question, not the lexical one: `1e3` and `1.00` are
45
+ * integral while `1.5` is not. It stays bounded by the token's length.
46
+ *
47
+ * The value is `coefficient × 10 ** (exponent - fractionDigits)`, so it is an
48
+ * integer exactly when the exponent shifts the decimal point no further right
49
+ * than the coefficient's own trailing zeros allow. Both sides of that
50
+ * comparison — the fraction-digit count and the trailing-zero count — are
51
+ * bounded by the token, so the exponent only ever has to be compared against a
52
+ * small number.
53
+ *
54
+ * A zero coefficient is the simple case: zero is integral for any exponent, so
55
+ * the exponent is not examined at all.
56
+ *
57
+ * @type {(lexeme: NumberLexeme) => boolean}
58
+ */
59
+ export declare const isIntegral: (lexeme: NumberLexeme) => boolean;
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Bounded lexical analysis of a JSON number token.
3
+ *
4
+ * `NumberToken.value` is the canonical lossless numeric source, and these
5
+ * helpers read it **without narrowing it first**: every operation here costs
6
+ * at most the length of the token, so a valid JSON number is classified
7
+ * correctly whatever its magnitude. In particular no helper builds a
8
+ * coefficient bigint, converts an arbitrary exponent to `number`, or evaluates
9
+ * a power such as `10 ** exponent`.
10
+ *
11
+ * That matters for schema-directed consumers, which have to decide questions
12
+ * such as "is this token an integer?" *before* a materializer rounds the value
13
+ * into `number`: `1.00000000000000001` and `1` are the same `number` but
14
+ * different tokens.
15
+ *
16
+ * @module
17
+ *
18
+ * @import { Sign } from '../../../types/function/compare/types.ts'
19
+ * @import { NumberLexeme } from './types.ts'
20
+ */
21
+
22
+ import { cmp } from '../../../types/function/compare/module.f.mjs'
23
+
24
+ /**
25
+ * Splits a JSON number token into its lexical parts.
26
+ *
27
+ * The token is grammar-validated by the tokenizer —
28
+ * `-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?` — so this is a split, not a
29
+ * validation.
30
+ *
31
+ * @type {(value: string) => NumberLexeme}
32
+ */
33
+ export const numberLexeme = value => {
34
+ const sign = value.startsWith('-') ? '-' : ''
35
+ const unsigned = value.slice(sign.length)
36
+ // at most one of 'e'/'E' can occur, so whichever `indexOf` finds is it
37
+ const lowerE = unsigned.indexOf('e')
38
+ const eIndex = lowerE < 0 ? unsigned.indexOf('E') : lowerE
39
+ const coefficient = eIndex < 0 ? unsigned : unsigned.slice(0, eIndex)
40
+ const expText = eIndex < 0 ? '' : unsigned.slice(eIndex + 1)
41
+ const dotIndex = coefficient.indexOf('.')
42
+ const int = dotIndex < 0 ? coefficient : coefficient.slice(0, dotIndex)
43
+ const frac = dotIndex < 0 ? '' : coefficient.slice(dotIndex + 1)
44
+ const expSign = expText.startsWith('-')
45
+ ? '-'
46
+ : expText.startsWith('+') ? '+' : ''
47
+ return { sign, int, frac, expSign, exp: expText.slice(expSign.length) }
48
+ }
49
+
50
+ /**
51
+ * Whether the lexeme is bare integer syntax: no `.` and no `e` / `E`.
52
+ *
53
+ * The distinction is lexical, not mathematical — `1e3` is not bare integer
54
+ * syntax even though its value is the integer `1000`.
55
+ *
56
+ * @type {(lexeme: NumberLexeme) => boolean}
57
+ */
58
+ export const isBareInteger = ({ frac, exp }) => frac === '' && exp === ''
59
+
60
+ /** @type {(digits: string) => string} */
61
+ const stripLeadingZeros = digits => {
62
+ let i = 0
63
+ while (i < digits.length && digits[i] === '0') { i += 1 }
64
+ return digits.slice(i)
65
+ }
66
+
67
+ /** @type {(digits: string) => number} */
68
+ const trailingZeroCount = digits => {
69
+ let n = 0
70
+ while (n < digits.length && digits[digits.length - 1 - n] === '0') { n += 1 }
71
+ return n
72
+ }
73
+
74
+ /**
75
+ * Compares arbitrarily long non-negative digit text against an ordinary
76
+ * non-negative integer, in the length of that text.
77
+ *
78
+ * Leading zeros are dropped, so equal-length digit strings compare
79
+ * numerically as strings and unequal lengths are decided by length alone.
80
+ * `bound` therefore never has to be turned into digit text long enough to
81
+ * match `digits`, and `digits` never has to become a number.
82
+ *
83
+ * @type {(digits: string) => (bound: number) => Sign}
84
+ */
85
+ const compareDigits = digits => bound => {
86
+ const a = stripLeadingZeros(digits)
87
+ const b = stripLeadingZeros(`${bound}`)
88
+ const byLength = cmp(a.length)(b.length)
89
+ return byLength === 0 ? cmp(a)(b) : byLength
90
+ }
91
+
92
+ /**
93
+ * Whether the lexeme's exponent is at least `bound`, an ordinary integer
94
+ * small enough to have come from the token's own length.
95
+ *
96
+ * The exponent itself is never converted: its sign decides which side of the
97
+ * comparison can already be answered, and only its digit text is compared —
98
+ * so `1e-99999999999999999999` is settled by looking at the sign and a length,
99
+ * not by representing that exponent.
100
+ *
101
+ * @type {(lexeme: NumberLexeme) => (bound: number) => boolean}
102
+ */
103
+ const exponentAtLeast = ({ expSign, exp }) => bound =>
104
+ expSign === '-'
105
+ // a negative exponent reaches `bound` only if `bound` is not positive
106
+ // and the exponent's magnitude stays within `-bound`
107
+ ? bound <= 0 && compareDigits(exp)(-bound) <= 0
108
+ // a non-negative exponent (`''` — an absent exponent — included, since
109
+ // its digit text is then empty and compares as zero) always reaches a
110
+ // non-positive `bound`
111
+ : bound <= 0 || compareDigits(exp)(bound) >= 0
112
+
113
+ /**
114
+ * Whether the lexeme spells a mathematical integer.
115
+ *
116
+ * This is the exact question, not the lexical one: `1e3` and `1.00` are
117
+ * integral while `1.5` is not. It stays bounded by the token's length.
118
+ *
119
+ * The value is `coefficient × 10 ** (exponent - fractionDigits)`, so it is an
120
+ * integer exactly when the exponent shifts the decimal point no further right
121
+ * than the coefficient's own trailing zeros allow. Both sides of that
122
+ * comparison — the fraction-digit count and the trailing-zero count — are
123
+ * bounded by the token, so the exponent only ever has to be compared against a
124
+ * small number.
125
+ *
126
+ * A zero coefficient is the simple case: zero is integral for any exponent, so
127
+ * the exponent is not examined at all.
128
+ *
129
+ * @type {(lexeme: NumberLexeme) => boolean}
130
+ */
131
+ export const isIntegral = lexeme => {
132
+ const { int, frac } = lexeme
133
+ const coefficient = `${int}${frac}`
134
+ const zeros = trailingZeroCount(coefficient)
135
+ return zeros === coefficient.length || exponentAtLeast(lexeme)(frac.length - zeros)
136
+ }
@@ -0,0 +1,24 @@
1
+ export declare const proof: {
2
+ numberLexeme: {
3
+ int: () => void;
4
+ negative: () => void;
5
+ fraction: () => void;
6
+ exponent: () => void;
7
+ capitalExponent: () => void;
8
+ plusExponent: () => void;
9
+ minusExponent: () => void;
10
+ unbounded: () => void;
11
+ };
12
+ isBareInteger: {
13
+ int: () => void;
14
+ zero: () => void;
15
+ fraction: () => void;
16
+ exponent: () => void;
17
+ };
18
+ isIntegral: {
19
+ zero: (() => void)[];
20
+ plain: (() => void)[];
21
+ exponent: (() => void)[];
22
+ unbounded: (() => void)[];
23
+ };
24
+ };
@@ -0,0 +1,86 @@
1
+ import { isBareInteger, isIntegral, numberLexeme } from './module.f.mjs'
2
+ import { assert, assertStructurallySame } from '../../../asserts/module.f.mjs'
3
+
4
+ /** @type {(value: string) => boolean} */
5
+ const integral = value => isIntegral(numberLexeme(value))
6
+
7
+ /** @type {(value: string) => boolean} */
8
+ const bareInteger = value => isBareInteger(numberLexeme(value))
9
+
10
+ // An exponent long enough that representing it as a `number` loses digits and
11
+ // `10 ** exponent` is not a computation anyone can afford. Every check below
12
+ // that uses it must be decided by the token's shape alone.
13
+ const hugeExp = '99999999999999999999'
14
+
15
+ export const proof = {
16
+ numberLexeme: {
17
+ int: () => assertStructurallySame(
18
+ numberLexeme('123'),
19
+ { sign: '', int: '123', frac: '', expSign: '', exp: '' }),
20
+ negative: () => assertStructurallySame(
21
+ numberLexeme('-123'),
22
+ { sign: '-', int: '123', frac: '', expSign: '', exp: '' }),
23
+ fraction: () => assertStructurallySame(
24
+ numberLexeme('-0.125'),
25
+ { sign: '-', int: '0', frac: '125', expSign: '', exp: '' }),
26
+ exponent: () => assertStructurallySame(
27
+ numberLexeme('1e10'),
28
+ { sign: '', int: '1', frac: '', expSign: '', exp: '10' }),
29
+ capitalExponent: () => assertStructurallySame(
30
+ numberLexeme('1.5E10'),
31
+ { sign: '', int: '1', frac: '5', expSign: '', exp: '10' }),
32
+ plusExponent: () => assertStructurallySame(
33
+ numberLexeme('1e+10'),
34
+ { sign: '', int: '1', frac: '', expSign: '+', exp: '10' }),
35
+ minusExponent: () => assertStructurallySame(
36
+ numberLexeme('1e-10'),
37
+ { sign: '', int: '1', frac: '', expSign: '-', exp: '10' }),
38
+ // nothing is narrowed, so an unrepresentable exponent is just text
39
+ unbounded: () => assertStructurallySame(
40
+ numberLexeme(`-1.5e-${hugeExp}`),
41
+ { sign: '-', int: '1', frac: '5', expSign: '-', exp: hugeExp }),
42
+ },
43
+ // bare integer syntax: no `.` and no `e`/`E`, whatever the value is
44
+ isBareInteger: {
45
+ int: () => assert(bareInteger('-1230')),
46
+ zero: () => assert(bareInteger('-0')),
47
+ fraction: () => assert(!bareInteger('1.0')),
48
+ exponent: () => assert(!bareInteger('1e3')),
49
+ },
50
+ isIntegral: {
51
+ // a zero coefficient is integral at any exponent, and is decided
52
+ // without looking at the exponent at all
53
+ zero: [
54
+ () => assert(integral('0')),
55
+ () => assert(integral('-0.000')),
56
+ () => assert(integral(`0.0e-${hugeExp}`)),
57
+ ],
58
+ plain: [
59
+ () => assert(integral('123')),
60
+ () => assert(integral('1.00')),
61
+ () => assert(!integral('1.5')),
62
+ () => assert(!integral('1.50')),
63
+ ],
64
+ // the exponent moves the point; only the coefficient's own trailing
65
+ // zeros can absorb a move to the right
66
+ exponent: [
67
+ () => assert(integral('1e3')),
68
+ () => assert(integral('1.5e1')),
69
+ () => assert(integral('1.5e2')),
70
+ () => assert(integral('150e-1')),
71
+ () => assert(!integral('1.5e-1')),
72
+ () => assert(!integral('15e-2')),
73
+ () => assert(!integral('1.55e1')),
74
+ () => assert(!integral('1.0000000000001e5')),
75
+ // leading zeros in the exponent are not extra magnitude
76
+ () => assert(integral('1.5e001')),
77
+ ],
78
+ // decided from lengths and a sign, never by representing the exponent
79
+ unbounded: [
80
+ () => assert(integral(`1e${hugeExp}`)),
81
+ () => assert(integral(`1.5e${hugeExp}`)),
82
+ () => assert(!integral(`1e-${hugeExp}`)),
83
+ () => assert(!integral(`1.5e-${hugeExp}`)),
84
+ ],
85
+ },
86
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Types for the lexical view of a JSON number token.
3
+ *
4
+ * @module
5
+ */
6
+ /**
7
+ * The parts of a JSON number lexeme, each kept as text.
8
+ *
9
+ * Nothing here is narrowed to a runtime numeric type, so a lexeme describes
10
+ * every syntactically valid JSON number — including coefficients larger than
11
+ * the runtime can build as a `bigint` and exponents beyond `number` precision.
12
+ *
13
+ * The empty string means "absent" for both optional parts, which is
14
+ * unambiguous: JSON requires at least one digit after `.` and at least one
15
+ * exponent digit, so a present part is never empty.
16
+ */
17
+ export type NumberLexeme = {
18
+ /** `'-'` for a negative number, `''` otherwise. */
19
+ readonly sign: '' | '-';
20
+ /** The integer digits; always at least one digit. */
21
+ readonly int: string;
22
+ /** The fraction digits, or `''` when the lexeme has no `.`. */
23
+ readonly frac: string;
24
+ /** The exponent sign as written, or `''` when it is omitted. */
25
+ readonly expSign: '' | '+' | '-';
26
+ /** The exponent digits, or `''` when the lexeme has no `e` / `E`. */
27
+ readonly exp: string;
28
+ };