functionalscript 0.44.0 → 0.45.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 (453) hide show
  1. package/fjs/asn.1/proof.f.d.mts +5 -0
  2. package/fjs/asn.1/proof.f.mjs +15 -3
  3. package/fjs/asserts/module.f.d.mts +14 -0
  4. package/fjs/asserts/module.f.mjs +20 -0
  5. package/fjs/asserts/proof.f.d.mts +3 -0
  6. package/fjs/asserts/proof.f.mjs +15 -1
  7. package/fjs/basen/base128/proof.f.d.mts +3 -1
  8. package/fjs/basen/base128/proof.f.mjs +3 -1
  9. package/fjs/basen/base64/module.f.mjs +7 -3
  10. package/fjs/basen/base64/proof.f.d.mts +3 -1
  11. package/fjs/basen/base64/proof.f.mjs +7 -4
  12. package/fjs/basen/cbase32/proof.f.d.mts +3 -1
  13. package/fjs/basen/cbase32/proof.f.mjs +3 -1
  14. package/fjs/bnf/data/proof.f.mjs +0 -1
  15. package/fjs/bnf/descent/module.f.d.mts +17 -2
  16. package/fjs/bnf/descent/module.f.mjs +118 -41
  17. package/fjs/bnf/descent/proof.f.d.mts +1 -0
  18. package/fjs/bnf/descent/proof.f.mjs +77 -1
  19. package/fjs/bnf/descent/types.d.ts +12 -4
  20. package/fjs/bnf/ll1/module.f.d.mts +28 -2
  21. package/fjs/bnf/ll1/module.f.mjs +180 -38
  22. package/fjs/bnf/ll1/proof.f.d.mts +2 -0
  23. package/fjs/bnf/ll1/proof.f.mjs +62 -1
  24. package/fjs/bnf/ll1/types.d.ts +14 -8
  25. package/fjs/bnf/module.f.d.mts +15 -6
  26. package/fjs/bnf/module.f.mjs +52 -11
  27. package/fjs/bnf/proof.f.d.mts +2 -0
  28. package/fjs/bnf/proof.f.mjs +79 -3
  29. package/fjs/bnf/token_symbol/module.f.d.mts +4 -3
  30. package/fjs/bnf/token_symbol/module.f.mjs +7 -6
  31. package/fjs/bnf/token_symbol/proof.f.mjs +5 -2
  32. package/fjs/bnf/token_symbol/types.d.ts +2 -2
  33. package/fjs/bnf/types.d.ts +10 -3
  34. package/fjs/cas/cli/proof.f.d.mts +3 -1
  35. package/fjs/cas/cli/proof.f.mjs +3 -1
  36. package/fjs/cas/evo/module.f.d.mts +7 -13
  37. package/fjs/cas/evo/module.f.mjs +103 -96
  38. package/fjs/cas/evo/proof.f.mjs +6 -3
  39. package/fjs/cas/module.f.mjs +96 -109
  40. package/fjs/ci/common/module.f.d.mts +1 -1
  41. package/fjs/ci/common/module.f.mjs +1 -0
  42. package/fjs/ci/config/module.f.d.mts +2 -2
  43. package/fjs/ci/config/module.f.mjs +2 -2
  44. package/fjs/ci/nix/proof.f.d.mts +2 -0
  45. package/fjs/ci/nix/proof.f.mjs +2 -2
  46. package/fjs/ci/proof.f.d.mts +4 -2
  47. package/fjs/ci/proof.f.mjs +4 -3
  48. package/fjs/cli/proof.f.d.mts +4 -2
  49. package/fjs/cli/proof.f.mjs +4 -2
  50. package/fjs/common/monoid/module.f.d.mts +70 -12
  51. package/fjs/common/monoid/module.f.mjs +177 -14
  52. package/fjs/common/monoid/proof.f.d.mts +12 -1
  53. package/fjs/common/monoid/proof.f.mjs +88 -4
  54. package/fjs/common/monoid/types.d.ts +23 -0
  55. package/fjs/crypto/secp/proof.f.d.mts +3 -1
  56. package/fjs/crypto/secp/proof.f.mjs +3 -1
  57. package/fjs/crypto/sha2/proof.f.d.mts +3 -1
  58. package/fjs/crypto/sha2/proof.f.mjs +3 -1
  59. package/fjs/crypto/vdf/module.f.d.mts +23 -4
  60. package/fjs/crypto/vdf/module.f.mjs +6 -4
  61. package/fjs/dev/module.f.d.mts +5 -2
  62. package/fjs/dev/module.f.mjs +5 -4
  63. package/fjs/dev/package_json/module.f.d.mts +7 -0
  64. package/fjs/dev/package_json/module.f.mjs +10 -7
  65. package/fjs/dev/update/module.f.d.mts +3 -0
  66. package/fjs/dev/update/module.f.mjs +3 -2
  67. package/fjs/dev/update/proof.f.d.mts +3 -0
  68. package/fjs/dev/update/proof.f.mjs +1 -2
  69. package/fjs/djs/parser/module.f.d.mts +3 -0
  70. package/fjs/djs/parser/module.f.mjs +18 -0
  71. package/fjs/djs/parser/proof.f.d.mts +3 -0
  72. package/fjs/djs/parser/proof.f.mjs +13 -1
  73. package/fjs/djs/proof.f.d.mts +3 -0
  74. package/fjs/djs/proof.f.mjs +4 -1
  75. package/fjs/djs/serializer/module.f.mjs +5 -4
  76. package/fjs/djs/tokenizer/module.f.mjs +21 -13
  77. package/fjs/djs/tokenizer/proof.f.d.mts +3 -0
  78. package/fjs/djs/tokenizer/proof.f.mjs +14 -2
  79. package/fjs/djs/transpiler/module.f.d.mts +1 -12
  80. package/fjs/djs/transpiler/module.f.mjs +1 -20
  81. package/fjs/djs/transpiler/types.d.ts +25 -0
  82. package/fjs/effects/eff/module.f.d.mts +10 -0
  83. package/fjs/effects/eff/module.f.mjs +4 -2
  84. package/fjs/effects/eff/proof.f.d.mts +3 -0
  85. package/fjs/effects/eff/proof.f.mjs +4 -1
  86. package/fjs/effects/list/module.f.d.mts +10 -2
  87. package/fjs/effects/list/module.f.mjs +4 -2
  88. package/fjs/effects/memory/module.f.d.mts +4 -2
  89. package/fjs/effects/memory/module.f.mjs +4 -3
  90. package/fjs/effects/memory/proof.f.d.mts +4 -0
  91. package/fjs/effects/memory/proof.f.mjs +5 -2
  92. package/fjs/effects/mock/module.f.d.mts +10 -2
  93. package/fjs/effects/mock/module.f.mjs +4 -2
  94. package/fjs/effects/module.d.mts +8 -0
  95. package/fjs/effects/module.f.d.mts +6 -4
  96. package/fjs/effects/module.f.mjs +6 -5
  97. package/fjs/effects/module.mjs +9 -1
  98. package/fjs/effects/node/memory/module.d.mts +3 -0
  99. package/fjs/effects/node/memory/module.mjs +3 -2
  100. package/fjs/effects/node/memory/proof.d.mts +2 -0
  101. package/fjs/effects/node/memory/proof.mjs +2 -1
  102. package/fjs/effects/node/module.d.mts +5 -0
  103. package/fjs/effects/node/module.f.d.mts +17 -12
  104. package/fjs/effects/node/module.f.mjs +6 -12
  105. package/fjs/effects/node/module.mjs +5 -17
  106. package/fjs/effects/node/virtual/module.f.d.mts +6 -3
  107. package/fjs/effects/node/virtual/module.f.mjs +6 -5
  108. package/fjs/effects/node/virtual/proof.f.d.mts +4 -1
  109. package/fjs/effects/node/virtual/proof.f.mjs +13 -1
  110. package/fjs/effects/proof.f.d.mts +3 -0
  111. package/fjs/effects/proof.f.mjs +4 -1
  112. package/fjs/emergent_testing/all.test.d.mts +8 -0
  113. package/fjs/emergent_testing/all.test.mjs +14 -0
  114. package/fjs/emergent_testing/module.f.d.mts +6 -1
  115. package/fjs/emergent_testing/module.f.mjs +40 -66
  116. package/fjs/emergent_testing/proof.f.mjs +5 -5
  117. package/fjs/fsc/bnf.f.d.mts +3 -0
  118. package/fjs/fsc/bnf.f.mjs +4 -1
  119. package/fjs/fsc/json.f.d.mts +3 -0
  120. package/fjs/fsc/json.f.mjs +4 -1
  121. package/fjs/fsc/module.f.d.mts +9 -0
  122. package/fjs/fsc/module.f.mjs +5 -3
  123. package/fjs/fsm/proof.f.d.mts +3 -0
  124. package/fjs/fsm/proof.f.mjs +4 -1
  125. package/fjs/js/tokenizer/module.f.d.mts +7 -0
  126. package/fjs/js/tokenizer/module.f.mjs +19 -55
  127. package/fjs/mcp/module.f.d.mts +36 -1
  128. package/fjs/mcp/module.f.mjs +9 -7
  129. package/fjs/mcp/proof.f.d.mts +11 -1
  130. package/fjs/mcp/proof.f.mjs +11 -18
  131. package/fjs/media/html/module.f.d.mts +12 -0
  132. package/fjs/media/html/module.f.mjs +6 -4
  133. package/fjs/media/html/proof.f.d.mts +3 -0
  134. package/fjs/media/html/proof.f.mjs +4 -1
  135. package/fjs/media/json/parser/module.f.d.mts +1 -1
  136. package/fjs/media/json/parser/module.f.mjs +25 -8
  137. package/fjs/media/json/parser/types.d.ts +5 -0
  138. package/fjs/media/json/rtti/proof.f.d.mts +3 -0
  139. package/fjs/media/json/rtti/proof.f.mjs +3 -3
  140. package/fjs/media/json/schema/module.f.d.mts +61 -27
  141. package/fjs/media/json/schema/module.f.mjs +228 -63
  142. package/fjs/media/json/schema/proof.f.d.mts +41 -0
  143. package/fjs/media/json/schema/proof.f.mjs +219 -7
  144. package/fjs/media/json/serializer/module.f.d.mts +13 -0
  145. package/fjs/media/json/serializer/module.f.mjs +7 -7
  146. package/fjs/media/json/tokenizer/module.f.d.mts +8 -0
  147. package/fjs/media/json/tokenizer/module.f.mjs +24 -5
  148. package/fjs/media/nix/module.f.d.mts +13 -0
  149. package/fjs/media/nix/module.f.mjs +4 -2
  150. package/fjs/media/nix/proof.f.d.mts +3 -0
  151. package/fjs/media/nix/proof.f.mjs +4 -1
  152. package/fjs/media/revision/module.f.d.mts +5 -0
  153. package/fjs/media/revision/module.f.mjs +8 -11
  154. package/fjs/media/revision/proof.f.d.mts +4 -0
  155. package/fjs/media/revision/proof.f.mjs +5 -2
  156. package/fjs/media/type/module.f.d.mts +28 -11
  157. package/fjs/media/type/module.f.mjs +69 -85
  158. package/fjs/media/type/proof.f.d.mts +16 -0
  159. package/fjs/media/type/proof.f.mjs +44 -4
  160. package/fjs/module.d.mts +5 -0
  161. package/fjs/module.f.d.mts +8 -0
  162. package/fjs/module.f.mjs +4 -2
  163. package/fjs/module.mjs +6 -0
  164. package/fjs/path/module.f.d.mts +8 -0
  165. package/fjs/path/module.f.mjs +4 -2
  166. package/fjs/proof.f.d.mts +4 -0
  167. package/fjs/proof.f.mjs +5 -2
  168. package/fjs/protocol/json_rpc/module.f.d.mts +1 -1
  169. package/fjs/protocol/json_rpc/module.f.mjs +7 -4
  170. package/fjs/protocol/json_rpc/proof.f.d.mts +6 -0
  171. package/fjs/protocol/json_rpc/proof.f.mjs +22 -1
  172. package/fjs/protocol/mcp/proof.f.d.mts +4 -0
  173. package/fjs/protocol/mcp/proof.f.mjs +47 -24
  174. package/fjs/protocol/mcp/stdio/module.f.d.mts +2 -4
  175. package/fjs/protocol/mcp/stdio/module.f.mjs +1 -8
  176. package/fjs/protocol/mcp/stdio/proof.f.d.mts +1 -1
  177. package/fjs/protocol/mcp/stdio/proof.f.mjs +1 -1
  178. package/fjs/protocol/mcp/stdio/types.d.ts +14 -0
  179. package/fjs/sul/id/module.f.d.mts +5 -0
  180. package/fjs/sul/id/module.f.mjs +5 -4
  181. package/fjs/sul/level/hash/module.f.d.mts +4 -1
  182. package/fjs/sul/level/hash/module.f.mjs +4 -3
  183. package/fjs/sul/level/hash/proof.f.d.mts +4 -0
  184. package/fjs/sul/level/hash/proof.f.mjs +5 -2
  185. package/fjs/sul/level/literal/module.f.d.mts +4 -1
  186. package/fjs/sul/level/literal/module.f.mjs +4 -3
  187. package/fjs/sul/level/literal/proof.f.d.mts +3 -0
  188. package/fjs/sul/level/literal/proof.f.mjs +4 -1
  189. package/fjs/sul/module.f.d.mts +5 -3
  190. package/fjs/sul/module.f.mjs +5 -4
  191. package/fjs/sul/proof.f.d.mts +4 -0
  192. package/fjs/sul/proof.f.mjs +5 -2
  193. package/fjs/text/ascii/module.f.d.mts +26 -0
  194. package/fjs/text/ascii/module.f.mjs +49 -1
  195. package/fjs/text/ascii/proof.f.d.mts +10 -0
  196. package/fjs/text/ascii/proof.f.mjs +33 -1
  197. package/fjs/text/code_point/module.f.d.mts +21 -3
  198. package/fjs/text/code_point/module.f.mjs +24 -8
  199. package/fjs/text/code_point/proof.f.d.mts +1 -0
  200. package/fjs/text/code_point/proof.f.mjs +28 -0
  201. package/fjs/text/module.f.d.mts +4 -2
  202. package/fjs/text/module.f.mjs +4 -3
  203. package/fjs/text/proof.f.d.mts +3 -0
  204. package/fjs/text/proof.f.mjs +4 -1
  205. package/fjs/text/sgr/module.f.d.mts +4 -1
  206. package/fjs/text/sgr/module.f.mjs +4 -3
  207. package/fjs/text/sgr/proof.f.d.mts +3 -0
  208. package/fjs/text/sgr/proof.f.mjs +4 -1
  209. package/fjs/text/utf16/module.f.d.mts +5 -1
  210. package/fjs/text/utf16/module.f.mjs +31 -33
  211. package/fjs/text/utf16/proof.f.d.mts +3 -1
  212. package/fjs/text/utf16/proof.f.mjs +18 -1
  213. package/fjs/text/utf8/module.f.d.mts +9 -5
  214. package/fjs/text/utf8/module.f.mjs +16 -18
  215. package/fjs/types/array/module.f.d.mts +2 -1
  216. package/fjs/types/array/module.f.mjs +2 -2
  217. package/fjs/types/bigfloat/module.f.d.mts +21 -1
  218. package/fjs/types/bigfloat/module.f.mjs +33 -7
  219. package/fjs/types/bigfloat/proof.f.d.mts +1 -0
  220. package/fjs/types/bigfloat/proof.f.mjs +46 -0
  221. package/fjs/types/bigint/module.f.d.mts +4 -0
  222. package/fjs/types/bigint/module.f.mjs +4 -3
  223. package/fjs/types/bit_vec/module.f.d.mts +10 -14
  224. package/fjs/types/bit_vec/module.f.mjs +61 -71
  225. package/fjs/types/bit_vec/proof.f.d.mts +6 -0
  226. package/fjs/types/bit_vec/proof.f.mjs +29 -3
  227. package/fjs/types/btree/find/module.f.d.mts +5 -1
  228. package/fjs/types/btree/find/module.f.mjs +5 -5
  229. package/fjs/types/btree/find/proof.f.d.mts +5 -1
  230. package/fjs/types/btree/find/proof.f.mjs +5 -3
  231. package/fjs/types/btree/module.f.d.mts +3 -0
  232. package/fjs/types/btree/module.f.mjs +3 -2
  233. package/fjs/types/btree/proof.f.d.mts +5 -1
  234. package/fjs/types/btree/proof.f.mjs +5 -3
  235. package/fjs/types/btree/remove/module.f.d.mts +11 -0
  236. package/fjs/types/btree/remove/module.f.mjs +9 -9
  237. package/fjs/types/btree/remove/proof.f.d.mts +3 -0
  238. package/fjs/types/btree/remove/proof.f.mjs +4 -1
  239. package/fjs/types/btree/set/module.f.d.mts +9 -0
  240. package/fjs/types/btree/set/module.f.mjs +5 -6
  241. package/fjs/types/btree/set/proof.f.d.mts +3 -0
  242. package/fjs/types/btree/set/proof.f.mjs +4 -1
  243. package/fjs/types/btree/types/module.f.d.mts +2 -1
  244. package/fjs/types/btree/types/module.f.mjs +2 -1
  245. package/fjs/types/byte_set/module.f.d.mts +10 -1
  246. package/fjs/types/byte_set/module.f.mjs +5 -3
  247. package/fjs/types/byte_set/proof.f.d.mts +3 -1
  248. package/fjs/types/byte_set/proof.f.mjs +3 -1
  249. package/fjs/types/function/compare/module.f.d.mts +3 -2
  250. package/fjs/types/function/compare/module.f.mjs +3 -2
  251. package/fjs/types/function/module.f.d.mts +8 -1
  252. package/fjs/types/function/module.f.mjs +8 -1
  253. package/fjs/types/function/operator/module.f.d.mts +2 -1
  254. package/fjs/types/function/operator/module.f.mjs +2 -2
  255. package/fjs/types/list/module.f.d.mts +9 -2
  256. package/fjs/types/list/module.f.mjs +5 -3
  257. package/fjs/types/list/proof.f.d.mts +4 -1
  258. package/fjs/types/list/proof.f.mjs +4 -2
  259. package/fjs/types/nibble_set/module.f.d.mts +2 -1
  260. package/fjs/types/nibble_set/module.f.mjs +2 -2
  261. package/fjs/types/nominal/module.f.d.mts +2 -1
  262. package/fjs/types/nominal/module.f.mjs +2 -1
  263. package/fjs/types/nullable/module.f.d.mts +8 -2
  264. package/fjs/types/nullable/module.f.mjs +4 -2
  265. package/fjs/types/number/module.f.d.mts +4 -0
  266. package/fjs/types/number/module.f.mjs +4 -3
  267. package/fjs/types/object/module.f.d.mts +14 -2
  268. package/fjs/types/object/module.f.mjs +15 -6
  269. package/fjs/types/object/proof.f.d.mts +5 -2
  270. package/fjs/types/object/proof.f.mjs +6 -3
  271. package/fjs/types/object/structurally_same/module.f.d.mts +39 -0
  272. package/fjs/types/object/structurally_same/module.f.mjs +59 -0
  273. package/fjs/types/object/structurally_same/proof.f.d.mts +6 -0
  274. package/fjs/types/object/structurally_same/proof.f.mjs +73 -0
  275. package/fjs/types/ordered_map/module.f.d.mts +5 -0
  276. package/fjs/types/ordered_map/module.f.mjs +5 -4
  277. package/fjs/types/ordered_map/proof.f.d.mts +3 -0
  278. package/fjs/types/ordered_map/proof.f.mjs +4 -1
  279. package/fjs/types/patricia_trie/module.f.d.mts +2 -1
  280. package/fjs/types/patricia_trie/module.f.mjs +2 -2
  281. package/fjs/types/patricia_trie/proof.f.d.mts +3 -0
  282. package/fjs/types/patricia_trie/proof.f.mjs +4 -1
  283. package/fjs/types/prime_field/module.f.d.mts +3 -1
  284. package/fjs/types/prime_field/module.f.mjs +3 -2
  285. package/fjs/types/range/module.f.d.mts +2 -1
  286. package/fjs/types/range/module.f.mjs +2 -2
  287. package/fjs/types/range_map/module.f.d.mts +6 -0
  288. package/fjs/types/range_map/module.f.mjs +6 -9
  289. package/fjs/types/range_map/proof.f.d.mts +5 -1
  290. package/fjs/types/range_map/proof.f.mjs +5 -3
  291. package/fjs/types/range_set/module.f.d.mts +5 -0
  292. package/fjs/types/range_set/module.f.mjs +1 -0
  293. package/fjs/types/range_set/proof.f.d.mts +3 -0
  294. package/fjs/types/range_set/proof.f.mjs +4 -1
  295. package/fjs/types/result/module.d.mts +8 -0
  296. package/fjs/types/result/module.f.d.mts +37 -7
  297. package/fjs/types/result/module.f.mjs +38 -8
  298. package/fjs/types/result/module.mjs +9 -1
  299. package/fjs/types/result/proof.f.d.mts +5 -0
  300. package/fjs/types/result/proof.f.mjs +22 -2
  301. package/fjs/types/rtti/common/module.f.d.mts +35 -2
  302. package/fjs/types/rtti/common/module.f.mjs +9 -7
  303. package/fjs/types/rtti/common/proof.f.d.mts +4 -0
  304. package/fjs/types/rtti/common/proof.f.mjs +5 -2
  305. package/fjs/types/rtti/data/module.f.d.mts +120 -0
  306. package/fjs/types/rtti/data/module.f.mjs +1030 -0
  307. package/fjs/types/rtti/data/proof.f.d.mts +75 -0
  308. package/fjs/types/rtti/data/proof.f.mjs +566 -0
  309. package/fjs/types/rtti/data/types.d.ts +83 -0
  310. package/fjs/types/rtti/module.f.d.mts +12 -5
  311. package/fjs/types/rtti/module.f.mjs +7 -5
  312. package/fjs/types/rtti/parse/module.f.d.mts +38 -0
  313. package/fjs/types/rtti/parse/module.f.mjs +9 -7
  314. package/fjs/types/rtti/parse/proof.f.mjs +18 -38
  315. package/fjs/types/rtti/proof.f.d.mts +3 -1
  316. package/fjs/types/rtti/proof.f.mjs +3 -1
  317. package/fjs/types/rtti/ts/module.f.d.mts +68 -9
  318. package/fjs/types/rtti/ts/module.f.mjs +262 -30
  319. package/fjs/types/rtti/ts/proof.f.d.mts +44 -0
  320. package/fjs/types/rtti/ts/proof.f.mjs +152 -4
  321. package/fjs/types/rtti/ts/types.d.ts +11 -0
  322. package/fjs/types/rtti/types.d.ts +40 -0
  323. package/fjs/types/rtti/validate/module.f.d.mts +36 -1
  324. package/fjs/types/rtti/validate/module.f.mjs +6 -4
  325. package/fjs/types/sorted_list/module.f.d.mts +4 -1
  326. package/fjs/types/sorted_list/module.f.mjs +21 -12
  327. package/fjs/types/sorted_list/proof.f.d.mts +3 -1
  328. package/fjs/types/sorted_list/proof.f.mjs +3 -1
  329. package/fjs/types/sorted_set/module.f.d.mts +31 -1
  330. package/fjs/types/sorted_set/module.f.mjs +4 -2
  331. package/fjs/types/sorted_set/proof.f.d.mts +3 -1
  332. package/fjs/types/sorted_set/proof.f.mjs +3 -1
  333. package/fjs/types/string/module.f.d.mts +4 -0
  334. package/fjs/types/string/module.f.mjs +4 -3
  335. package/fjs/types/string_set/module.f.d.mts +3 -1
  336. package/fjs/types/string_set/module.f.mjs +3 -2
  337. package/fjs/types/ts/module.f.d.mts +2 -0
  338. package/fjs/types/ts/module.f.mjs +3 -3
  339. package/fjs/types/ts/proof.f.d.mts +1 -0
  340. package/fjs/types/ts/proof.f.mjs +5 -0
  341. package/fjs/types/ts/types.d.ts +6 -1
  342. package/fjs/types/uint8array/module.f.d.mts +13 -2
  343. package/fjs/types/uint8array/module.f.mjs +20 -15
  344. package/fjs/website/module.f.d.mts +3 -0
  345. package/fjs/website/module.f.mjs +3 -2
  346. package/package.json +3 -3
  347. package/fjs/asn.1/types.js +0 -6
  348. package/fjs/asserts/types.js +0 -6
  349. package/fjs/basen/types.js +0 -6
  350. package/fjs/bnf/data/types.js +0 -6
  351. package/fjs/bnf/descent/types.js +0 -6
  352. package/fjs/bnf/ll1/types.js +0 -6
  353. package/fjs/bnf/token_symbol/types.js +0 -6
  354. package/fjs/bnf/types.js +0 -6
  355. package/fjs/cas/evo/types.js +0 -7
  356. package/fjs/cas/types.js +0 -6
  357. package/fjs/ci/common/types.js +0 -1
  358. package/fjs/ci/nix/types.js +0 -6
  359. package/fjs/ci/types.js +0 -6
  360. package/fjs/cli/types.js +0 -6
  361. package/fjs/common/monoid/types.js +0 -6
  362. package/fjs/crypto/pow/types.js +0 -6
  363. package/fjs/crypto/secp/types.js +0 -6
  364. package/fjs/crypto/sha2/types.js +0 -6
  365. package/fjs/crypto/sign/types.js +0 -6
  366. package/fjs/crypto/vdf/types.js +0 -6
  367. package/fjs/dev/types.js +0 -6
  368. package/fjs/djs/ast/types.js +0 -8
  369. package/fjs/djs/parser/types.js +0 -7
  370. package/fjs/djs/tokenizer/types.js +0 -7
  371. package/fjs/djs/types.js +0 -7
  372. package/fjs/effects/eff/types.js +0 -6
  373. package/fjs/effects/list/types.js +0 -6
  374. package/fjs/effects/memory/types.js +0 -6
  375. package/fjs/effects/mock/types.js +0 -6
  376. package/fjs/effects/node/types.js +0 -6
  377. package/fjs/effects/node/virtual/types.js +0 -7
  378. package/fjs/effects/types.js +0 -6
  379. package/fjs/emergent_testing/all.test.d.ts +0 -1
  380. package/fjs/emergent_testing/all.test.js +0 -5
  381. package/fjs/emergent_testing/scenarios/all.d.ts +0 -1
  382. package/fjs/emergent_testing/scenarios/all.js +0 -1
  383. package/fjs/emergent_testing/scenarios/async-subtests.fail.d.ts +0 -6
  384. package/fjs/emergent_testing/scenarios/async-subtests.fail.js +0 -9
  385. package/fjs/emergent_testing/scenarios/async-subtests.pass.d.ts +0 -6
  386. package/fjs/emergent_testing/scenarios/async-subtests.pass.js +0 -9
  387. package/fjs/emergent_testing/scenarios/async.fail.d.ts +0 -3
  388. package/fjs/emergent_testing/scenarios/async.fail.js +0 -6
  389. package/fjs/emergent_testing/scenarios/async.pass.d.ts +0 -3
  390. package/fjs/emergent_testing/scenarios/async.pass.js +0 -5
  391. package/fjs/emergent_testing/scenarios/fail.fail.d.ts +0 -3
  392. package/fjs/emergent_testing/scenarios/fail.fail.js +0 -3
  393. package/fjs/emergent_testing/scenarios/return-value.pass.d.ts +0 -3
  394. package/fjs/emergent_testing/scenarios/return-value.pass.js +0 -4
  395. package/fjs/emergent_testing/scenarios/thenable.pass.d.ts +0 -5
  396. package/fjs/emergent_testing/scenarios/thenable.pass.js +0 -11
  397. package/fjs/emergent_testing/scenarios/thenable2.pass.d.ts +0 -5
  398. package/fjs/emergent_testing/scenarios/thenable2.pass.js +0 -3
  399. package/fjs/emergent_testing/scenarios/throw.pass.d.ts +0 -5
  400. package/fjs/emergent_testing/scenarios/throw.pass.js +0 -3
  401. package/fjs/emergent_testing/types.js +0 -6
  402. package/fjs/js/tokenizer/types.js +0 -6
  403. package/fjs/media/html/types.js +0 -6
  404. package/fjs/media/json/parser/types.js +0 -6
  405. package/fjs/media/json/tokenizer/types.js +0 -6
  406. package/fjs/media/json/types.js +0 -13
  407. package/fjs/media/nix/types.js +0 -6
  408. package/fjs/media/revision/types.js +0 -8
  409. package/fjs/media/type/types.js +0 -6
  410. package/fjs/media/types.js +0 -7
  411. package/fjs/nanvm/types.js +0 -11
  412. package/fjs/protocol/json_rpc/types.js +0 -8
  413. package/fjs/protocol/mcp/types.js +0 -8
  414. package/fjs/sul/id/types.js +0 -6
  415. package/fjs/sul/level/hash/types.js +0 -6
  416. package/fjs/sul/level/literal/types.js +0 -6
  417. package/fjs/sul/types.js +0 -6
  418. package/fjs/text/sgr/types.js +0 -6
  419. package/fjs/text/types.js +0 -6
  420. package/fjs/text/utf16/types.js +0 -6
  421. package/fjs/text/utf8/types.js +0 -6
  422. package/fjs/types/array/types.js +0 -6
  423. package/fjs/types/bigfloat/types.js +0 -6
  424. package/fjs/types/bigint/types.js +0 -6
  425. package/fjs/types/bit_vec/types.js +0 -6
  426. package/fjs/types/btree/find/types.js +0 -6
  427. package/fjs/types/btree/types/types.js +0 -6
  428. package/fjs/types/byte_set/types.js +0 -6
  429. package/fjs/types/function/compare/types.js +0 -6
  430. package/fjs/types/function/operator/types.js +0 -6
  431. package/fjs/types/function/types.js +0 -6
  432. package/fjs/types/list/types.js +0 -6
  433. package/fjs/types/nibble_set/types.js +0 -6
  434. package/fjs/types/nominal/types.js +0 -6
  435. package/fjs/types/nullable/types.js +0 -6
  436. package/fjs/types/object/types.js +0 -8
  437. package/fjs/types/option/types.js +0 -6
  438. package/fjs/types/ordered_map/types.js +0 -6
  439. package/fjs/types/patricia_trie/types.js +0 -6
  440. package/fjs/types/phantom/types.js +0 -11
  441. package/fjs/types/prime_field/types.js +0 -6
  442. package/fjs/types/range/types.js +0 -6
  443. package/fjs/types/range_map/types.js +0 -6
  444. package/fjs/types/result/types.js +0 -6
  445. package/fjs/types/rtti/common/types.js +0 -1
  446. package/fjs/types/rtti/parse/types.js +0 -1
  447. package/fjs/types/rtti/ts/types.js +0 -1
  448. package/fjs/types/rtti/types.js +0 -1
  449. package/fjs/types/rtti/validate/types.js +0 -1
  450. package/fjs/types/sorted_list/types.js +0 -6
  451. package/fjs/types/sorted_set/types.js +0 -6
  452. package/fjs/types/string_set/types.js +0 -6
  453. package/fjs/types/ts/types.js +0 -8
@@ -2,22 +2,268 @@
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 { at, definedEntries } from '../../object/module.f.mjs'
7
23
  import { primitive, union, printer as tsPrinter } from '../../ts/module.f.mjs'
8
- /** @import { Const, Type } from '../types.ts' */
24
+ import { cmp, toData, unitBit, unknown as top } from '../data/module.f.mjs'
25
+
26
+ const nullBit = unitBit(null)
27
+ const undefinedBit = unitBit(undefined)
28
+ const falseBit = unitBit(false)
29
+ const trueBit = unitBit(true)
30
+ const booleanBits = falseBit | trueBit
9
31
 
10
32
  /**
11
- * Creates a printer that converts an RTTI schema `Type` to its TypeScript type expression as a string.
33
+ * Names that cannot name a TypeScript type alias: the predefined type
34
+ * names (`TS2457`), the ECMAScript reserved words — those reserved only in
35
+ * strict-mode code included, since every module is strict-mode code
36
+ * (`TS1214`) — and the type keywords that fail in the alias-name position.
37
+ */
38
+ const reserved = /** @type {const} */ ([
39
+ // predefined type names
40
+ 'any', 'bigint', 'boolean', 'false', 'never', 'null', 'number', 'object',
41
+ 'string', 'symbol', 'true', 'undefined', 'unknown', 'void',
42
+ // ECMAScript reserved words
43
+ 'await', 'break', 'case', 'catch', 'class', 'const', 'continue',
44
+ 'debugger', 'default', 'delete', 'do', 'else', 'enum', 'export',
45
+ 'extends', 'finally', 'for', 'function', 'if', 'import', 'in',
46
+ 'instanceof', 'new', 'return', 'super', 'switch', 'this', 'throw', 'try',
47
+ 'typeof', 'var', 'while', 'with',
48
+ // reserved in strict-mode code — and every module is strict-mode code
49
+ 'implements', 'interface', 'let', 'package', 'private', 'protected',
50
+ 'public', 'static', 'yield',
51
+ // type-operator keywords, and `intrinsic` (TS2795 outside lib.d.ts)
52
+ 'infer', 'intrinsic', 'keyof', 'readonly', 'unique',
53
+ ])
54
+
55
+ /** @type {(c: string) => boolean} */
56
+ const isIdStart = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c === '_' || c === '$'
57
+
58
+ /** @type {(c: string) => boolean} */
59
+ const isIdPart = c => isIdStart(c) || (c >= '0' && c <= '9')
60
+
61
+ /** Whether `s` can name a TypeScript type alias. */
62
+ /** @type {(s: string) => boolean} */
63
+ const isTypeName = s =>
64
+ s !== ''
65
+ && [...s].every((c, i) => i === 0 ? isIdStart(c) : isIdPart(c))
66
+ && !reserved.some(p => p === s)
67
+
68
+ /**
69
+ * Maps every rule name to a TypeScript type-alias identifier: the name
70
+ * itself when it can be one, else a deterministic generated `T<n>` that
71
+ * collides with no kept name.
12
72
  *
13
- * Mirrors the compile-time `Ts<T>` mapped type at runtime.
14
- * Pass `true` to emit mutable (non-`readonly`) types.
73
+ * @type {(rules: RuleSet) => readonly (readonly [string, string])[]}
74
+ */
75
+ const identifiers = rules => {
76
+ const names = definedEntries(rules).map(([n]) => n)
77
+ const kept = names.filter(isTypeName)
78
+ /** @type {readonly (readonly [string, string])[]} */
79
+ let result = []
80
+ let i = 0
81
+ for (const name of names) {
82
+ if (isTypeName(name)) {
83
+ result = [...result, [name, name]]
84
+ continue
85
+ }
86
+ let id = `T${i}`
87
+ while (kept.some(k => k === id)) {
88
+ ++i
89
+ id = `T${i}`
90
+ }
91
+ ++i
92
+ result = [...result, [name, id]]
93
+ }
94
+ return result
95
+ }
96
+
97
+ /**
98
+ * @typedef {{
99
+ * readonly ts: Printer
100
+ * readonly ids: readonly (readonly [string, string])[]
101
+ * readonly rules: RuleSet
102
+ * }} _Ctx
103
+ */
104
+
105
+ /** @type {(ids: readonly (readonly [string, string])[], name: string) => string | undefined} */
106
+ const idOf = (ids, name) => {
107
+ for (const [k, v] of ids) {
108
+ if (k === name) { return v }
109
+ }
110
+ return undefined
111
+ }
112
+
113
+ /**
114
+ * A reference prints as its definition's identifier; a reference naming a
115
+ * missing definition is malformed data and panics.
15
116
  *
16
- * **Note:** recursive schemas (e.g. `const list = () => ['array', list] as const`)
17
- * will cause infinite recursion. Only acyclic schemas are supported.
117
+ * @type {(ctx: _Ctx) => (n: Node) => string}
118
+ */
119
+ const nodeToTs = ctx => n =>
120
+ typeof n === 'string'
121
+ ? assertNotNullish(idOf(ctx.ids, n), `missing definition: ${n}`)
122
+ : unionToTs(ctx)(n)
123
+
124
+ /**
125
+ * The member expressions of one kind component: nothing when absent, the
126
+ * whole kind when `true`, one expression per member otherwise.
18
127
  *
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`.
128
+ * @template T
129
+ * @param {KindSet<T> | undefined} k
130
+ * @param {string} whole
131
+ * @param {(v: T) => string} item
132
+ * @returns {readonly string[]}
133
+ */
134
+ const kindToTs = (k, whole, item) =>
135
+ k === undefined ? [] :
136
+ k === true ? [whole] :
137
+ k.map(item)
138
+
139
+ /** @type {(bits: number) => readonly string[]} */
140
+ const unitToTs = bits => [
141
+ ...((bits & nullBit) === 0 ? [] : [primitive(null)]),
142
+ ...((bits & undefinedBit) === 0 ? [] : [primitive(undefined)]),
143
+ ...((bits & booleanBits) === booleanBits ? ['boolean']
144
+ : (bits & falseBit) !== 0 ? [primitive(false)]
145
+ : (bits & trueBit) !== 0 ? [primitive(true)]
146
+ : []),
147
+ ]
148
+
149
+ /**
150
+ * A tuple prints its prefix, an array its element type, and a
151
+ * tuple-with-rest combines them with a rest element:
152
+ * `readonly[A,...readonly(R)[]]`.
153
+ *
154
+ * @type {(ctx: _Ctx) => (p: ArraySet) => string}
155
+ */
156
+ const arraySetToTs = ctx => p => {
157
+ const items = p.prefix.map(nodeToTs(ctx))
158
+ const { rest } = p
159
+ if (rest === undefined) { return ctx.ts.tuple(items) }
160
+ const restTs = ctx.ts.array(nodeToTs(ctx)(rest))
161
+ return items.length === 0 ? restTs : ctx.ts.tuple([...items, `...${restTs}`])
162
+ }
163
+
164
+ /**
165
+ * Whether the node's value set admits `undefined` — its unit bit, read
166
+ * through a reference (own-property only) if needed.
167
+ *
168
+ * @type {(ctx: _Ctx) => (n: Node) => boolean}
169
+ */
170
+ const admitsUndefined = ctx => n => {
171
+ const u = typeof n === 'string' ? assertNotNullish(at(n)(ctx.rules)) : n
172
+ return ((u.unit ?? 0) & undefinedBit) !== 0
173
+ }
174
+
175
+ /** @type {(list: readonly string[]) => readonly string[]} */
176
+ const dedup = list => list.filter((s, i) => list.indexOf(s) === i)
177
+
178
+ /**
179
+ * A struct prints its fields — a key whose value set admits `undefined` may
180
+ * also be absent, so it prints optional, mirroring `Ts<>` — and a record
181
+ * prints its value type. A props-with-rest set combines them with an
182
+ * intersection; TypeScript requires an index signature to cover the
183
+ * declared keys too, so the index type widens to the union of the rest and
184
+ * the declared value types — the closest expressible supertype.
185
+ *
186
+ * @type {(ctx: _Ctx) => (p: ObjectSet) => string}
187
+ */
188
+ const objectSetToTs = ctx => p => {
189
+ /** @type {readonly StructField[]} */
190
+ const fields = definedEntries(p.props).map(([k, v]) => {
191
+ const ts = nodeToTs(ctx)(v)
192
+ return admitsUndefined(ctx)(v) ? [k, ts, true] : [k, ts]
193
+ })
194
+ const { rest } = p
195
+ if (rest === undefined) { return ctx.ts.struct(fields) }
196
+ const restTs = ctx.ts.record(union(dedup([...fields.map(([, v]) => v), nodeToTs(ctx)(rest)])))
197
+ return fields.length === 0 ? restTs : `${ctx.ts.struct(fields)}&${restTs}`
198
+ }
199
+
200
+ /** @type {(u: UnionSet) => boolean} */
201
+ const isTop = u => cmp([{}, u])([{}, top]) === 0
202
+
203
+ /** @type {(ctx: _Ctx) => (u: UnionSet) => string} */
204
+ const unionToTs = ctx => u => {
205
+ if (isTop(u)) { return 'unknown' }
206
+ return union([
207
+ ...unitToTs(u.unit ?? 0),
208
+ ...kindToTs(u.number, 'number', primitive),
209
+ ...kindToTs(u.string, 'string', primitive),
210
+ ...kindToTs(u.bigint, 'bigint', primitive),
211
+ ...kindToTs(u.array, ctx.ts.array('unknown'), arraySetToTs(ctx)),
212
+ ...kindToTs(u.object, ctx.ts.record('unknown'), objectSetToTs(ctx)),
213
+ ])
214
+ }
215
+
216
+ /**
217
+ * Renders a serializable RTTI {@link Data} (from `toData`) as TypeScript:
218
+ * the rule definitions as sorted `[identifier, expression]` pairs — render
219
+ * each as `type <identifier> = <expression>` — plus the entry expression,
220
+ * which references those identifiers. A schema with no reference cycles has
221
+ * no definitions and the entry expression stands alone.
222
+ *
223
+ * Rule names come from the data form; one that cannot name a type alias —
224
+ * not an identifier, a predefined type name, an ECMAScript reserved word,
225
+ * or a type-operator keyword — gets a deterministic generated identifier
226
+ * (`T0`, `T1`, …). A reference naming a missing definition panics.
227
+ *
228
+ * @example
229
+ * ```js
230
+ * const list = () => ['array', list]
231
+ * dataToTs()(toData(list))
232
+ * // [[['list', 'readonly(list)[]']], 'list']
233
+ * // i.e. `type list = readonly(list)[]` and the entry expression `list`
234
+ * ```
235
+ *
236
+ * @type {(mut?: true) => (data: Data) => readonly [readonly (readonly [string, string])[], string]}
237
+ */
238
+ export const dataToTs = mut => ([rules, entry]) => {
239
+ /** @type {_Ctx} */
240
+ const ctx = { ts: tsPrinter(mut), ids: identifiers(rules), rules }
241
+ return [
242
+ definedEntries(rules).map(([n, u]) =>
243
+ /** @type {const} */ ([nodeToTs(ctx)(n), unionToTs(ctx)(u)])),
244
+ nodeToTs(ctx)(entry),
245
+ ]
246
+ }
247
+
248
+ /**
249
+ * Creates a printer that converts an RTTI schema `Type` to its TypeScript
250
+ * type expression as a string, through the canonical data form: `toData`
251
+ * first, then {@link dataToTs}.
252
+ *
253
+ * Mirrors the compile-time `Ts<T>` mapped type at runtime, in the data
254
+ * form's canonical order — union members follow its kind order (e.g.
255
+ * `option(number)` prints `'undefined|number'`) and structurally different
256
+ * but equivalent schemas print identically (`or(true, false)` prints
257
+ * `'boolean'`). Pass `true` to emit mutable (non-`readonly`) types.
258
+ *
259
+ * A recursive schema prints as the identifier of its definition — use
260
+ * {@link dataToTs} to also obtain the `type <identifier> = <expression>`
261
+ * definitions the expression references; a schema with no reference cycles
262
+ * needs none.
263
+ *
264
+ * **Note:** the `unknown` schema produces the string `'unknown'`
265
+ * (TypeScript's built-in), whereas `Ts<>` maps it to `DjsUnknown` from
266
+ * `djs/module.f.ts`.
21
267
  *
22
268
  * @example
23
269
  * ```js
@@ -25,12 +271,15 @@ import { primitive, union, printer as tsPrinter } from '../../ts/module.f.mjs'
25
271
  * toTs(boolean) // 'boolean'
26
272
  * toTs(array(number)) // 'readonly(number)[]'
27
273
  * toTs(record(string)) // '{readonly[k in string]?:string}'
28
- * toTs(or(string, number)) // 'string|number'
274
+ * toTs(or(string, number)) // 'number|string'
29
275
  * toTs(42) // '42'
30
276
  * toTs('hello') // '"hello"'
31
277
  * toTs([boolean, number]) // 'readonly[boolean,number]'
32
278
  * toTs({ x: string }) // '{readonly"x":string}'
33
279
  *
280
+ * const list = () => ['array', list]
281
+ * toTs(list) // 'list' — see `dataToTs` for the definition
282
+ *
34
283
  * const toTsMut = printer(true)
35
284
  * toTsMut(array(number)) // '(number)[]'
36
285
  * toTsMut(record(string)) // '{[k in string]?:string}'
@@ -39,26 +288,9 @@ import { primitive, union, printer as tsPrinter } from '../../ts/module.f.mjs'
39
288
  * @type {(mut?: true) => (rtti: Type) => string}
40
289
  */
41
290
  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
- }
291
+ const toTs = dataToTs(mut)
292
+ return rtti => {
293
+ const [, entry] = toTs(toData(rtti))
294
+ return entry
61
295
  }
62
-
63
- return toTs
64
296
  }
@@ -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
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * TypeScript type transformers for RTTI schemas.
3
+ *
4
+ * Each `*Ts` type maps a schema (or schema fragment) to its corresponding TypeScript type.
5
+ * The main entry point is `Ts<T>`.
6
+ *
7
+ * The runtime `toTs` function (`printer` in `./module.f.mjs`) mirrors `Ts<T>` at value
8
+ * level, returning a TypeScript type expression string for a given RTTI schema.
9
+ *
10
+ * @module
11
+ */
1
12
  import type { Tag0, Tag1, Struct, Tuple, Type } from '../types.ts';
2
13
  import type { phantomKey } from '../../phantom/types.ts';
3
14
  import type { StringMap } from '../../object/types.ts';
@@ -1,3 +1,43 @@
1
+ /**
2
+ * Type-level API for runtime type information (RTTI) — a type-safe schema
3
+ * system for describing and converting TypeScript types.
4
+ *
5
+ * ## Core concepts
6
+ *
7
+ * A `Type` is either a `Const` (used directly as its own schema) or a `Thunk`
8
+ * (a zero-argument function returning an `Info` descriptor). Thunks are the
9
+ * primary building block: they enable lazy evaluation and recursive type definitions.
10
+ *
11
+ * ```
12
+ * Type = Const | Thunk
13
+ * Thunk = () => Info
14
+ * Info = ['const', Const] | Info0<Tag0> | Info1<Tag1, Type>
15
+ * ```
16
+ *
17
+ * ## Nullary schemas (no type parameter)
18
+ *
19
+ * `boolean`, `number`, `string`, `bigint`, `unknown` are pre-built `Thunk` values
20
+ * that describe primitive types. Each is a `_Type0<Tag0>` — a thunk returning a
21
+ * single-element tag tuple.
22
+ *
23
+ * ## Unary schemas (one type parameter)
24
+ *
25
+ * `array(t)` and `record(t)` construct `Thunk` values parameterized by an inner
26
+ * `Type`. They return `Type1` thunks wrapping an `Info1` tuple.
27
+ *
28
+ * ## Const schemas
29
+ *
30
+ * Any `Primitive`, `Struct` (plain object), or `Tuple` (readonly array) can be
31
+ * used directly as a schema — it describes exactly the shape of that value.
32
+ * Inside a recursive `Thunk`-based definition, wrap consts with `() => ['const', c]`
33
+ * to keep the schema uniform.
34
+ *
35
+ * ## Converting to TypeScript types
36
+ *
37
+ * See `./ts/module.f.ts` for `Ts<T>` and the `*Ts` transformer types.
38
+ *
39
+ * @module
40
+ */
1
41
  import type { StringMap } from '../object/types.ts';
2
42
  import type { tag0List } from './module.f.mjs';
3
43
  /** A constant schema: a primitive literal, a struct object, or a tuple. */
@@ -1,6 +1,41 @@
1
+ /**
2
+ * Runtime validation of unknown values against RTTI schemas.
3
+ *
4
+ * The main entry point is `validate(rtti)`, which takes a schema `Type` and returns
5
+ * a `Validate<T>` function. When called with an unknown value, it returns a `Result`
6
+ * that is either `['ok', typedValue]` or `['error', { path, message }]`.
7
+ *
8
+ * ## Error path
9
+ *
10
+ * On failure, the error carries a `path` pointing at the offending sub-value:
11
+ * each step is the string property name (for structs/records) or the stringified
12
+ * index (for tuples/arrays). The path is empty when the failure is at the root.
13
+ *
14
+ * ## Dispatch strategy
15
+ *
16
+ * Schema recognition is delegated to `visit` in `../common/module.f.mjs`,
17
+ * which routes each `Type` variant to a handler in the `Visitor` record
18
+ * defined below. `validate` returns the original value on success — no
19
+ * fresh allocation — which is the only behavior that distinguishes it
20
+ * from `parse`.
21
+ *
22
+ * ## Recursion safety
23
+ *
24
+ * For `array` and `record` schemas, the inner item validator is instantiated lazily —
25
+ * only after confirming the container is non-empty. This prevents infinite recursion
26
+ * when validating recursive schemas like `const list = () => ['array', list]`.
27
+ *
28
+ * See `./types.ts` for the `Path`/`Result`/`Validate`/`ValidationError` type-level API.
29
+ *
30
+ * @module
31
+ *
32
+ * @import { Unknown } from '../ts/types.ts'
33
+ * @import { Info1, Struct, Tag1, Tuple, Type } from '../types.ts'
34
+ * @import { StringMap } from '../../object/types.ts'
35
+ * @import { Container, IsContainer, Validate, ValidateE, Visitor } from '../common/types.ts'
36
+ */
1
37
  import type { Type } from '../types.ts';
2
38
  import type { Validate } from '../common/types.ts';
3
- /** @import { Container, IsContainer, Validate, ValidateE, Visitor } from '../common/types.ts' */
4
39
  export { constPrimitiveValidate, prependPath, primitive0Validate, verror, } from '../common/module.f.mjs';
5
40
  /** @type {<T extends Type>(rtti: T) => Validate<T>} */
6
41
  export declare const validate: <T extends Type>(rtti: T) => Validate<T>;