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
@@ -1,16 +1,72 @@
1
+ /**
2
+ * Runtime printer mirroring the `Ts<T>` type transformer for RTTI schemas.
3
+ * See `./types.ts` for `Ts<T>` and the `*Ts` transformer types.
4
+ *
5
+ * The printer routes through the serializable RTTI data form
6
+ * (`fjs/types/rtti/data`): `thunk RTTI → toData → dataToTs`. The data form
7
+ * is a finite graph, so recursive schemas — which the thunk graph represents
8
+ * as self-referencing functions with no leaves — terminate: every named rule
9
+ * becomes a TypeScript type-alias definition and every graph edge prints as
10
+ * that alias's identifier. Output is canonical: union members follow the
11
+ * data form's kind order and object keys its sorted order, so structurally
12
+ * different but equivalent schemas print identically.
13
+ *
14
+ * @module
15
+ *
16
+ * @import { Printer, StructField } from '../../ts/types.ts'
17
+ * @import { Type } from '../types.ts'
18
+ * @import { ArraySet, Data, KindSet, Node, ObjectSet, RuleSet, UnionSet } from '../data/types.ts'
19
+ */
20
+ import type { Printer } from '../../ts/types.ts';
1
21
  import type { Type } from '../types.ts';
2
- /** @import { Const, Type } from '../types.ts' */
22
+ import type { Data, RuleSet } from '../data/types.ts';
23
+ export type _Ctx = {
24
+ readonly ts: Printer;
25
+ readonly ids: readonly (readonly [string, string])[];
26
+ readonly rules: RuleSet;
27
+ };
28
+ /**
29
+ * Renders a serializable RTTI {@link Data} (from `toData`) as TypeScript:
30
+ * the rule definitions as sorted `[identifier, expression]` pairs — render
31
+ * each as `type <identifier> = <expression>` — plus the entry expression,
32
+ * which references those identifiers. A schema with no reference cycles has
33
+ * no definitions and the entry expression stands alone.
34
+ *
35
+ * Rule names come from the data form; one that cannot name a type alias —
36
+ * not an identifier, a predefined type name, an ECMAScript reserved word,
37
+ * or a type-operator keyword — gets a deterministic generated identifier
38
+ * (`T0`, `T1`, …). A reference naming a missing definition panics.
39
+ *
40
+ * @example
41
+ * ```js
42
+ * const list = () => ['array', list]
43
+ * dataToTs()(toData(list))
44
+ * // [[['list', 'readonly(list)[]']], 'list']
45
+ * // i.e. `type list = readonly(list)[]` and the entry expression `list`
46
+ * ```
47
+ *
48
+ * @type {(mut?: true) => (data: Data) => readonly [readonly (readonly [string, string])[], string]}
49
+ */
50
+ export declare const dataToTs: (mut?: true) => (data: Data) => readonly [readonly (readonly [string, string])[], string];
3
51
  /**
4
- * Creates a printer that converts an RTTI schema `Type` to its TypeScript type expression as a string.
52
+ * Creates a printer that converts an RTTI schema `Type` to its TypeScript
53
+ * type expression as a string, through the canonical data form: `toData`
54
+ * first, then {@link dataToTs}.
5
55
  *
6
- * Mirrors the compile-time `Ts<T>` mapped type at runtime.
7
- * Pass `true` to emit mutable (non-`readonly`) types.
56
+ * Mirrors the compile-time `Ts<T>` mapped type at runtime, in the data
57
+ * form's canonical order union members follow its kind order (e.g.
58
+ * `option(number)` prints `'undefined|number'`) and structurally different
59
+ * but equivalent schemas print identically (`or(true, false)` prints
60
+ * `'boolean'`). Pass `true` to emit mutable (non-`readonly`) types.
8
61
  *
9
- * **Note:** recursive schemas (e.g. `const list = () => ['array', list] as const`)
10
- * will cause infinite recursion. Only acyclic schemas are supported.
62
+ * A recursive schema prints as the identifier of its definition use
63
+ * {@link dataToTs} to also obtain the `type <identifier> = <expression>`
64
+ * definitions the expression references; a schema with no reference cycles
65
+ * needs none.
11
66
  *
12
- * **Note:** the `unknown` schema produces the string `'unknown'` (TypeScript's built-in),
13
- * whereas `Ts<>` maps it to `DjsUnknown` from `djs/module.f.ts`.
67
+ * **Note:** the `unknown` schema produces the string `'unknown'`
68
+ * (TypeScript's built-in), whereas `Ts<>` maps it to `DjsUnknown` from
69
+ * `djs/module.f.ts`.
14
70
  *
15
71
  * @example
16
72
  * ```js
@@ -18,12 +74,15 @@ import type { Type } from '../types.ts';
18
74
  * toTs(boolean) // 'boolean'
19
75
  * toTs(array(number)) // 'readonly(number)[]'
20
76
  * toTs(record(string)) // '{readonly[k in string]?:string}'
21
- * toTs(or(string, number)) // 'string|number'
77
+ * toTs(or(string, number)) // 'number|string'
22
78
  * toTs(42) // '42'
23
79
  * toTs('hello') // '"hello"'
24
80
  * toTs([boolean, number]) // 'readonly[boolean,number]'
25
81
  * toTs({ x: string }) // '{readonly"x":string}'
26
82
  *
83
+ * const list = () => ['array', list]
84
+ * toTs(list) // 'list' — see `dataToTs` for the definition
85
+ *
27
86
  * const toTsMut = printer(true)
28
87
  * toTsMut(array(number)) // '(number)[]'
29
88
  * toTsMut(record(string)) // '{[k in string]?:string}'
@@ -2,22 +2,264 @@
2
2
  * Runtime printer mirroring the `Ts<T>` type transformer for RTTI schemas.
3
3
  * See `./types.ts` for `Ts<T>` and the `*Ts` transformer types.
4
4
  *
5
+ * The printer routes through the serializable RTTI data form
6
+ * (`fjs/types/rtti/data`): `thunk RTTI → toData → dataToTs`. The data form
7
+ * is a finite graph, so recursive schemas — which the thunk graph represents
8
+ * as self-referencing functions with no leaves — terminate: every named rule
9
+ * becomes a TypeScript type-alias definition and every graph edge prints as
10
+ * that alias's identifier. Output is canonical: union members follow the
11
+ * data form's kind order and object keys its sorted order, so structurally
12
+ * different but equivalent schemas print identically.
13
+ *
5
14
  * @module
15
+ *
16
+ * @import { Printer, StructField } from '../../ts/types.ts'
17
+ * @import { Type } from '../types.ts'
18
+ * @import { ArraySet, Data, KindSet, Node, ObjectSet, RuleSet, UnionSet } from '../data/types.ts'
6
19
  */
20
+
21
+ import { assertNotNullish } from '../../../asserts/module.f.mjs'
22
+ import { reservedWords, strictModeReservedWords } from '../../../js/keywords/module.f.mjs'
23
+ import { at, definedEntries } from '../../object/module.f.mjs'
7
24
  import { primitive, union, printer as tsPrinter } from '../../ts/module.f.mjs'
8
- /** @import { Const, Type } from '../types.ts' */
25
+ import { cmp, toData, unitBit, unknown as top } from '../data/module.f.mjs'
26
+
27
+ const nullBit = unitBit(null)
28
+ const undefinedBit = unitBit(undefined)
29
+ const falseBit = unitBit(false)
30
+ const trueBit = unitBit(true)
31
+ const booleanBits = falseBit | trueBit
9
32
 
10
33
  /**
11
- * Creates a printer that converts an RTTI schema `Type` to its TypeScript type expression as a string.
34
+ * Names that cannot name a TypeScript type alias: the ECMAScript reserved
35
+ * words — from the one source of truth for JavaScript keywords,
36
+ * `fjs/js/keywords`, the strict-mode ones included since every module is
37
+ * strict-mode code (`TS1214`) — plus TypeScript's predefined type names
38
+ * (`TS2457`) and the type keywords that fail in the alias-name position.
39
+ */
40
+ /** @type {readonly string[]} */
41
+ const reserved = [
42
+ ...reservedWords,
43
+ ...strictModeReservedWords,
44
+ // predefined type names
45
+ 'any', 'bigint', 'boolean', 'never', 'number', 'object', 'string',
46
+ 'symbol', 'undefined', 'unknown',
47
+ // type-operator keywords, and `intrinsic` (TS2795 outside lib.d.ts)
48
+ 'infer', 'intrinsic', 'keyof', 'readonly', 'unique',
49
+ ]
50
+
51
+ /** @type {(c: string) => boolean} */
52
+ const isIdStart = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c === '_' || c === '$'
53
+
54
+ /** @type {(c: string) => boolean} */
55
+ const isIdPart = c => isIdStart(c) || (c >= '0' && c <= '9')
56
+
57
+ /** Whether `s` can name a TypeScript type alias. */
58
+ /** @type {(s: string) => boolean} */
59
+ const isTypeName = s =>
60
+ s !== ''
61
+ && [...s].every((c, i) => i === 0 ? isIdStart(c) : isIdPart(c))
62
+ && !reserved.some(p => p === s)
63
+
64
+ /**
65
+ * Maps every rule name to a TypeScript type-alias identifier: the name
66
+ * itself when it can be one, else a deterministic generated `T<n>` that
67
+ * collides with no kept name.
12
68
  *
13
- * Mirrors the compile-time `Ts<T>` mapped type at runtime.
14
- * Pass `true` to emit mutable (non-`readonly`) types.
69
+ * @type {(rules: RuleSet) => readonly (readonly [string, string])[]}
70
+ */
71
+ const identifiers = rules => {
72
+ const names = definedEntries(rules).map(([n]) => n)
73
+ const kept = names.filter(isTypeName)
74
+ /** @type {readonly (readonly [string, string])[]} */
75
+ let result = []
76
+ let i = 0
77
+ for (const name of names) {
78
+ if (isTypeName(name)) {
79
+ result = [...result, [name, name]]
80
+ continue
81
+ }
82
+ let id = `T${i}`
83
+ while (kept.some(k => k === id)) {
84
+ ++i
85
+ id = `T${i}`
86
+ }
87
+ ++i
88
+ result = [...result, [name, id]]
89
+ }
90
+ return result
91
+ }
92
+
93
+ /**
94
+ * @typedef {{
95
+ * readonly ts: Printer
96
+ * readonly ids: readonly (readonly [string, string])[]
97
+ * readonly rules: RuleSet
98
+ * }} _Ctx
99
+ */
100
+
101
+ /** @type {(ids: readonly (readonly [string, string])[], name: string) => string | undefined} */
102
+ const idOf = (ids, name) => {
103
+ for (const [k, v] of ids) {
104
+ if (k === name) { return v }
105
+ }
106
+ return undefined
107
+ }
108
+
109
+ /**
110
+ * A reference prints as its definition's identifier; a reference naming a
111
+ * missing definition is malformed data and panics.
15
112
  *
16
- * **Note:** recursive schemas (e.g. `const list = () => ['array', list] as const`)
17
- * will cause infinite recursion. Only acyclic schemas are supported.
113
+ * @type {(ctx: _Ctx) => (n: Node) => string}
114
+ */
115
+ const nodeToTs = ctx => n =>
116
+ typeof n === 'string'
117
+ ? assertNotNullish(idOf(ctx.ids, n), `missing definition: ${n}`)
118
+ : unionToTs(ctx)(n)
119
+
120
+ /**
121
+ * The member expressions of one kind component: nothing when absent, the
122
+ * whole kind when `true`, one expression per member otherwise.
18
123
  *
19
- * **Note:** the `unknown` schema produces the string `'unknown'` (TypeScript's built-in),
20
- * whereas `Ts<>` maps it to `DjsUnknown` from `djs/module.f.ts`.
124
+ * @template T
125
+ * @param {KindSet<T> | undefined} k
126
+ * @param {string} whole
127
+ * @param {(v: T) => string} item
128
+ * @returns {readonly string[]}
129
+ */
130
+ const kindToTs = (k, whole, item) =>
131
+ k === undefined ? [] :
132
+ k === true ? [whole] :
133
+ k.map(item)
134
+
135
+ /** @type {(bits: number) => readonly string[]} */
136
+ const unitToTs = bits => [
137
+ ...((bits & nullBit) === 0 ? [] : [primitive(null)]),
138
+ ...((bits & undefinedBit) === 0 ? [] : [primitive(undefined)]),
139
+ ...((bits & booleanBits) === booleanBits ? ['boolean']
140
+ : (bits & falseBit) !== 0 ? [primitive(false)]
141
+ : (bits & trueBit) !== 0 ? [primitive(true)]
142
+ : []),
143
+ ]
144
+
145
+ /**
146
+ * A tuple prints its prefix, an array its element type, and a
147
+ * tuple-with-rest combines them with a rest element:
148
+ * `readonly[A,...readonly(R)[]]`.
149
+ *
150
+ * @type {(ctx: _Ctx) => (p: ArraySet) => string}
151
+ */
152
+ const arraySetToTs = ctx => p => {
153
+ const items = p.prefix.map(nodeToTs(ctx))
154
+ const { rest } = p
155
+ if (rest === undefined) { return ctx.ts.tuple(items) }
156
+ const restTs = ctx.ts.array(nodeToTs(ctx)(rest))
157
+ return items.length === 0 ? restTs : ctx.ts.tuple([...items, `...${restTs}`])
158
+ }
159
+
160
+ /**
161
+ * Whether the node's value set admits `undefined` — its unit bit, read
162
+ * through a reference (own-property only) if needed.
163
+ *
164
+ * @type {(ctx: _Ctx) => (n: Node) => boolean}
165
+ */
166
+ const admitsUndefined = ctx => n => {
167
+ const u = typeof n === 'string' ? assertNotNullish(at(n)(ctx.rules)) : n
168
+ return ((u.unit ?? 0) & undefinedBit) !== 0
169
+ }
170
+
171
+ /** @type {(list: readonly string[]) => readonly string[]} */
172
+ const dedup = list => list.filter((s, i) => list.indexOf(s) === i)
173
+
174
+ /**
175
+ * A struct prints its fields — a key whose value set admits `undefined` may
176
+ * also be absent, so it prints optional, mirroring `Ts<>` — and a record
177
+ * prints its value type. A props-with-rest set combines them with an
178
+ * intersection; TypeScript requires an index signature to cover the
179
+ * declared keys too, so the index type widens to the union of the rest and
180
+ * the declared value types — the closest expressible supertype.
181
+ *
182
+ * @type {(ctx: _Ctx) => (p: ObjectSet) => string}
183
+ */
184
+ const objectSetToTs = ctx => p => {
185
+ /** @type {readonly StructField[]} */
186
+ const fields = definedEntries(p.props).map(([k, v]) => {
187
+ const ts = nodeToTs(ctx)(v)
188
+ return admitsUndefined(ctx)(v) ? [k, ts, true] : [k, ts]
189
+ })
190
+ const { rest } = p
191
+ if (rest === undefined) { return ctx.ts.struct(fields) }
192
+ const restTs = ctx.ts.record(union(dedup([...fields.map(([, v]) => v), nodeToTs(ctx)(rest)])))
193
+ return fields.length === 0 ? restTs : `${ctx.ts.struct(fields)}&${restTs}`
194
+ }
195
+
196
+ /** @type {(u: UnionSet) => boolean} */
197
+ const isTop = u => cmp([{}, u])([{}, top]) === 0
198
+
199
+ /** @type {(ctx: _Ctx) => (u: UnionSet) => string} */
200
+ const unionToTs = ctx => u => {
201
+ if (isTop(u)) { return 'unknown' }
202
+ return union([
203
+ ...unitToTs(u.unit ?? 0),
204
+ ...kindToTs(u.number, 'number', primitive),
205
+ ...kindToTs(u.string, 'string', primitive),
206
+ ...kindToTs(u.bigint, 'bigint', primitive),
207
+ ...kindToTs(u.array, ctx.ts.array('unknown'), arraySetToTs(ctx)),
208
+ ...kindToTs(u.object, ctx.ts.record('unknown'), objectSetToTs(ctx)),
209
+ ])
210
+ }
211
+
212
+ /**
213
+ * Renders a serializable RTTI {@link Data} (from `toData`) as TypeScript:
214
+ * the rule definitions as sorted `[identifier, expression]` pairs — render
215
+ * each as `type <identifier> = <expression>` — plus the entry expression,
216
+ * which references those identifiers. A schema with no reference cycles has
217
+ * no definitions and the entry expression stands alone.
218
+ *
219
+ * Rule names come from the data form; one that cannot name a type alias —
220
+ * not an identifier, a predefined type name, an ECMAScript reserved word,
221
+ * or a type-operator keyword — gets a deterministic generated identifier
222
+ * (`T0`, `T1`, …). A reference naming a missing definition panics.
223
+ *
224
+ * @example
225
+ * ```js
226
+ * const list = () => ['array', list]
227
+ * dataToTs()(toData(list))
228
+ * // [[['list', 'readonly(list)[]']], 'list']
229
+ * // i.e. `type list = readonly(list)[]` and the entry expression `list`
230
+ * ```
231
+ *
232
+ * @type {(mut?: true) => (data: Data) => readonly [readonly (readonly [string, string])[], string]}
233
+ */
234
+ export const dataToTs = mut => ([rules, entry]) => {
235
+ /** @type {_Ctx} */
236
+ const ctx = { ts: tsPrinter(mut), ids: identifiers(rules), rules }
237
+ return [
238
+ definedEntries(rules).map(([n, u]) =>
239
+ /** @type {const} */ ([nodeToTs(ctx)(n), unionToTs(ctx)(u)])),
240
+ nodeToTs(ctx)(entry),
241
+ ]
242
+ }
243
+
244
+ /**
245
+ * Creates a printer that converts an RTTI schema `Type` to its TypeScript
246
+ * type expression as a string, through the canonical data form: `toData`
247
+ * first, then {@link dataToTs}.
248
+ *
249
+ * Mirrors the compile-time `Ts<T>` mapped type at runtime, in the data
250
+ * form's canonical order — union members follow its kind order (e.g.
251
+ * `option(number)` prints `'undefined|number'`) and structurally different
252
+ * but equivalent schemas print identically (`or(true, false)` prints
253
+ * `'boolean'`). Pass `true` to emit mutable (non-`readonly`) types.
254
+ *
255
+ * A recursive schema prints as the identifier of its definition — use
256
+ * {@link dataToTs} to also obtain the `type <identifier> = <expression>`
257
+ * definitions the expression references; a schema with no reference cycles
258
+ * needs none.
259
+ *
260
+ * **Note:** the `unknown` schema produces the string `'unknown'`
261
+ * (TypeScript's built-in), whereas `Ts<>` maps it to `DjsUnknown` from
262
+ * `djs/module.f.ts`.
21
263
  *
22
264
  * @example
23
265
  * ```js
@@ -25,12 +267,15 @@ import { primitive, union, printer as tsPrinter } from '../../ts/module.f.mjs'
25
267
  * toTs(boolean) // 'boolean'
26
268
  * toTs(array(number)) // 'readonly(number)[]'
27
269
  * toTs(record(string)) // '{readonly[k in string]?:string}'
28
- * toTs(or(string, number)) // 'string|number'
270
+ * toTs(or(string, number)) // 'number|string'
29
271
  * toTs(42) // '42'
30
272
  * toTs('hello') // '"hello"'
31
273
  * toTs([boolean, number]) // 'readonly[boolean,number]'
32
274
  * toTs({ x: string }) // '{readonly"x":string}'
33
275
  *
276
+ * const list = () => ['array', list]
277
+ * toTs(list) // 'list' — see `dataToTs` for the definition
278
+ *
34
279
  * const toTsMut = printer(true)
35
280
  * toTsMut(array(number)) // '(number)[]'
36
281
  * toTsMut(record(string)) // '{[k in string]?:string}'
@@ -39,26 +284,9 @@ import { primitive, union, printer as tsPrinter } from '../../ts/module.f.mjs'
39
284
  * @type {(mut?: true) => (rtti: Type) => string}
40
285
  */
41
286
  export const printer = mut => {
42
- const { tuple, struct, array, record } = tsPrinter(mut)
43
-
44
- /** @type {(rtti: Const) => string} */
45
- const constToTs = rtti =>
46
- typeof rtti !== 'object' || rtti === null ? primitive(rtti) :
47
- rtti instanceof Array ? tuple(rtti.map(toTs)) :
48
- struct(Object.entries(rtti).map(([k, v]) => [k, toTs(v)]))
49
-
50
- /** @type {(rtti: Type) => string} */
51
- const toTs = rtti => {
52
- if (typeof rtti !== 'function') { return constToTs(rtti) }
53
- const [tag, ...rest] = rtti()
54
- switch (tag) {
55
- case 'const': return constToTs(/** @type {Const} */ (rest[0]))
56
- case 'array': return array(toTs(rest[0]))
57
- case 'record': return record(toTs(rest[0]))
58
- case 'or': return union(rest.map(toTs))
59
- default: return tag // tag0: 'boolean' | 'number' | 'string' | 'bigint' | 'unknown'
60
- }
287
+ const toTs = dataToTs(mut)
288
+ return rtti => {
289
+ const [, entry] = toTs(toData(rtti))
290
+ return entry
61
291
  }
62
-
63
- return toTs
64
292
  }
@@ -1,3 +1,15 @@
1
+ /**
2
+ * @import { Type } from '../types.ts'
3
+ * @import { Data } from '../data/types.ts'
4
+ */
5
+ import { number, string } from '../module.f.mjs';
6
+ export type _List = () => readonly ['array', _List];
7
+ export type _Tree = () => readonly ['or', typeof number, _Forest];
8
+ export type _Forest = () => readonly ['array', _Tree];
9
+ export type _Lock = () => readonly ['record', () => readonly ['or', typeof string, _Lock]];
10
+ export type _StringNamed = () => readonly ['array', _StringNamed];
11
+ export type _T0Named = () => readonly ['array', _T0Named];
12
+ export type _IfNamed = () => readonly ['array', _IfNamed];
1
13
  export declare const proof: {
2
14
  tag0: {
3
15
  boolean: () => void;
@@ -49,6 +61,35 @@ export declare const proof: {
49
61
  };
50
62
  never: () => void;
51
63
  option: () => void;
64
+ normalization: {
65
+ booleanFromConsts: () => void;
66
+ literalAbsorbed: () => void;
67
+ sortedLiterals: () => void;
68
+ sortedBigints: () => void;
69
+ canonicalIdentity: () => void;
70
+ optionalProp: () => void;
71
+ mixedProps: () => void;
72
+ };
73
+ recursion: {
74
+ selfList: () => void;
75
+ mutual: () => void;
76
+ recursiveUnion: () => void;
77
+ mutable: () => void;
78
+ };
79
+ identifiers: {
80
+ emptyName: () => void;
81
+ predefinedName: () => void;
82
+ reservedName: () => void;
83
+ typeOperatorName: () => void;
84
+ strictModeReservedName: () => void;
85
+ generatedCollision: () => void;
86
+ };
87
+ data: {
88
+ tupleWithRest: () => void;
89
+ structWithRest: () => void;
90
+ optionalByReference: () => void;
91
+ wholeKinds: () => void;
92
+ };
52
93
  mut: {
53
94
  array: () => void;
54
95
  nestedArray: () => void;
@@ -56,4 +97,7 @@ export declare const proof: {
56
97
  tuple: () => void;
57
98
  struct: () => void;
58
99
  };
100
+ throw: {
101
+ missingDefinition: () => readonly [readonly (readonly [string, string])[], string];
102
+ };
59
103
  };
@@ -1,20 +1,71 @@
1
- import { printer } from './module.f.mjs'
1
+ /**
2
+ * @import { Type } from '../types.ts'
3
+ * @import { Data } from '../data/types.ts'
4
+ */
5
+
6
+ import { assertEq } from '../../../asserts/module.f.mjs'
7
+ import { toData, unitBit } from '../data/module.f.mjs'
2
8
  import { boolean, number, string, bigint, unknown, array, record, or, option, never } from '../module.f.mjs'
3
- /** @import { Type } from '../types.ts' */
9
+ import { dataToTs, printer } from './module.f.mjs'
4
10
 
5
11
  const toTs = printer()
6
12
  const toTsMut = printer(true)
13
+
7
14
  /** @type {(rtti: Type, expected: string) => void} */
8
15
  const eqMut = (rtti, expected) => {
9
16
  const result = toTsMut(rtti)
10
17
  if (result !== expected) { throw `expected ${JSON.stringify(expected)}, got ${JSON.stringify(result)}` }
11
18
  }
19
+
12
20
  /** @type {(rtti: Type, expected: string) => void} */
13
21
  const eq = (rtti, expected) => {
14
22
  const result = toTs(rtti)
15
23
  if (result !== expected) { throw `expected ${JSON.stringify(expected)}, got ${JSON.stringify(result)}` }
16
24
  }
17
25
 
26
+ /** @type {(data: Data, expected: unknown) => void} */
27
+ const eqData = (data, expected) => {
28
+ const result = JSON.stringify(dataToTs()(data))
29
+ const exp = JSON.stringify(expected)
30
+ assertEq(result, exp, [result, exp])
31
+ }
32
+
33
+ /** A recursive list: `type list = readonly list[]`. */
34
+ /** @typedef {() => readonly ['array', _List]} _List */
35
+ /** @type {_List} */
36
+ const list = () => ['array', list]
37
+
38
+ /** Mutual recursion through a container. */
39
+ /** @typedef {() => readonly ['or', typeof number, _Forest]} _Tree */
40
+ /** @typedef {() => readonly ['array', _Tree]} _Forest */
41
+ /** @type {_Tree} */
42
+ const tree = () => ['or', number, forest]
43
+ /** @type {_Forest} */
44
+ const forest = () => ['array', tree]
45
+
46
+ /** A cycle closing through an anonymous `or` thunk — an empty rule name. */
47
+ /** @typedef {() => readonly ['record', () => readonly ['or', typeof string, _Lock]]} _Lock */
48
+ /** @type {_Lock} */
49
+ const lock = () => ['record', or(string, lock)]
50
+
51
+ /** A recursive rule whose function name is the predefined type name `string`. */
52
+ /** @typedef {() => readonly ['array', _StringNamed]} _StringNamed */
53
+ /** @type {{ readonly string: _StringNamed }} */
54
+ const stringNamedHolder = { string: () => ['array', stringNamedHolder.string] }
55
+ const stringNamed = stringNamedHolder.string
56
+
57
+ /** A recursive rule whose function name is `T0` — the first generated identifier. */
58
+ /** @typedef {() => readonly ['array', _T0Named]} _T0Named */
59
+ /** @type {{ readonly T0: _T0Named }} */
60
+ const t0NamedHolder = { T0: () => ['array', t0NamedHolder.T0] }
61
+ const t0Named = t0NamedHolder.T0
62
+
63
+ /** A recursive rule whose function name is the reserved word `if`. */
64
+ /** @typedef {() => readonly ['array', _IfNamed]} _IfNamed */
65
+ /** @type {{ readonly if: _IfNamed }} */
66
+ const ifNamedHolder = { if: () => ['array', ifNamedHolder.if] }
67
+ const ifNamed = ifNamedHolder.if
68
+
18
69
  export const proof = {
19
70
  tag0: {
20
71
  boolean: () => eq(boolean, 'boolean'),
@@ -47,7 +98,8 @@ export const proof = {
47
98
  bigint: () => eq(7n, '7n'),
48
99
  emptyTuple: () => eq([], 'readonly[]'),
49
100
  tuple: () => eq([12, true], 'readonly[12,true]'),
50
- emptyStruct: () => eq({}, '{}'),
101
+ // an unconstrained struct is the whole object kind
102
+ emptyStruct: () => eq({}, '{readonly[k in string]?:unknown}'),
51
103
  struct: () => eq(
52
104
  { a: number, b: string },
53
105
  '{readonly"a":number,readonly"b":string}',
@@ -77,7 +129,99 @@ export const proof = {
77
129
  mixed: () => eq(or(42, string), '42|string'),
78
130
  },
79
131
  never: () => eq(never, 'never'),
80
- option: () => eq(option(number), 'number|undefined'),
132
+ // union members follow the canonical kind order, `undefined` first
133
+ option: () => eq(option(number), 'undefined|number'),
134
+ normalization: {
135
+ booleanFromConsts: () => eq(or(true, false), 'boolean'),
136
+ literalAbsorbed: () => eq(or(42, number), 'number'),
137
+ sortedLiterals: () => eq(or(2, 1), '1|2'),
138
+ sortedBigints: () => eq(or(2n, 1n), '1n|2n'),
139
+ canonicalIdentity: () => {
140
+ assertEq(toTs(or(string, number)), toTs(or(number, string)))
141
+ },
142
+ // a key admitting `undefined` may be absent — it prints optional
143
+ optionalProp: () => eq({ x: option(string) }, '{readonly"x"?:undefined|string}'),
144
+ mixedProps: () => eq(
145
+ { a: number, b: option(number) },
146
+ '{readonly"a":number,readonly"b"?:undefined|number}'),
147
+ },
148
+ recursion: {
149
+ selfList: () => {
150
+ eq(list, 'list')
151
+ eqData(toData(list), [[['list', 'readonly(list)[]']], 'list'])
152
+ },
153
+ mutual: () => {
154
+ eqData(toData(tree), [[['tree', 'number|readonly(tree)[]']], 'tree'])
155
+ eqData(toData(forest), [[['tree', 'number|readonly(tree)[]']], 'readonly(tree)[]'])
156
+ },
157
+ recursiveUnion: () => {
158
+ eqData(toData(or(number, list)), [[['list', 'readonly(list)[]']], 'number|readonly(list)[]'])
159
+ },
160
+ mutable: () => {
161
+ const [defs, entry] = dataToTs(true)(toData(list))
162
+ assertEq(JSON.stringify([defs, entry]), JSON.stringify([[['list', '(list)[]']], 'list']))
163
+ },
164
+ },
165
+ identifiers: {
166
+ // the empty rule name is not an identifier — generated `T0`
167
+ emptyName: () => {
168
+ eqData(toData(lock), [
169
+ [['T0', 'string|{readonly[k in string]?:T0}']],
170
+ '{readonly[k in string]?:T0}',
171
+ ])
172
+ },
173
+ // a predefined type name cannot name an alias — generated `T0`
174
+ predefinedName: () => {
175
+ eqData(toData(stringNamed), [[['T0', 'readonly(T0)[]']], 'T0'])
176
+ },
177
+ // reserved words cannot name an alias either — generated `T0`
178
+ reservedName: () => {
179
+ eqData(toData(ifNamed), [[['T0', 'readonly(T0)[]']], 'T0'])
180
+ },
181
+ typeOperatorName: () => {
182
+ eqData([{ infer: { array: [{ prefix: [], rest: 'infer' }] } }, 'infer'],
183
+ [[['T0', 'readonly(T0)[]']], 'T0'])
184
+ },
185
+ // reserved only in strict-mode code — but every module is strict
186
+ strictModeReservedName: () => {
187
+ eqData([{ let: { array: [{ prefix: [], rest: 'let' }] } }, 'let'],
188
+ [[['T0', 'readonly(T0)[]']], 'T0'])
189
+ eqData([{ intrinsic: { array: [{ prefix: [], rest: 'intrinsic' }] } }, 'intrinsic'],
190
+ [[['T0', 'readonly(T0)[]']], 'T0'])
191
+ },
192
+ // a generated identifier skips names already kept
193
+ generatedCollision: () => {
194
+ eqData(toData(/** @type {const} */ ([t0Named, lock])), [
195
+ [['T1', 'string|{readonly[k in string]?:T1}'], ['T0', 'readonly(T0)[]']],
196
+ 'readonly[T0,{readonly[k in string]?:T1}]',
197
+ ])
198
+ },
199
+ },
200
+ data: {
201
+ tupleWithRest: () => {
202
+ eqData([{}, { array: [{ prefix: [{ number: true }], rest: { string: true } }] }],
203
+ [[], 'readonly[number,...readonly(string)[]]'])
204
+ },
205
+ structWithRest: () => {
206
+ // the index signature must cover the declared keys too, so the
207
+ // rest type widens to include the declared value types
208
+ eqData([{}, { object: [{ props: { a: { number: true } }, rest: { string: true } }] }],
209
+ [[], '{readonly"a":number}&{readonly[k in string]?:number|string}'])
210
+ eqData([{}, { object: [{ props: { a: { string: true } }, rest: { string: true } }] }],
211
+ [[], '{readonly"a":string}&{readonly[k in string]?:string}'])
212
+ },
213
+ optionalByReference: () => {
214
+ eqData([{ r: { unit: unitBit(null) | unitBit(undefined), number: true } },
215
+ { object: [{ props: { p: 'r' } }] }],
216
+ [[['r', 'null|undefined|number']], '{readonly"p"?:r}'])
217
+ eqData([{ r: { number: true } }, { object: [{ props: { p: 'r' } }] }],
218
+ [[['r', 'number']], '{readonly"p":r}'])
219
+ },
220
+ wholeKinds: () => {
221
+ eqData([{}, { array: true, object: true }],
222
+ [[], 'readonly(unknown)[]|{readonly[k in string]?:unknown}'])
223
+ },
224
+ },
81
225
  mut: {
82
226
  array: () => eqMut(array(number), '(number)[]'),
83
227
  nestedArray: () => eqMut(array(array(boolean)), '((boolean)[])[]'),
@@ -85,4 +229,8 @@ export const proof = {
85
229
  tuple: () => eqMut([12, true], '[12,true]'),
86
230
  struct: () => eqMut({ a: number, b: string }, '{"a":number,"b":string}'),
87
231
  },
232
+ throw: {
233
+ // a dangling reference is malformed data
234
+ missingDefinition: () => dataToTs()([{}, 'nope']),
235
+ },
88
236
  }