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,5 +1,5 @@
1
1
  /**
2
- * Node.js effect runner: interprets `Effect<NodeOp, T>` directly against the
2
+ * Node.js effect runner: interprets `Effect<NodeOp, T, E>` directly against the
3
3
  * Node globals and built-in modules (`fs`, `http`, `child_process`, `process`,
4
4
  * `fetch`, …).
5
5
  *
@@ -11,6 +11,11 @@
11
11
  * globals directly instead.
12
12
  *
13
13
  * @module
14
+ *
15
+ * @import { Effect } from '../types.ts'
16
+ * @import { IoResult, Server as EffectServer, Headers, Module, NodeOp, RequestListener as Erl, NodeProgram, NodeProgramOptions, WriteConsoles, TestContext, TestFn, } from './types.ts'
17
+ * @import { Result } from '../../types/result/types.ts'
18
+ * @import { StringMap } from '../../types/object/types.ts'
14
19
  */
15
20
 
16
21
  import http from 'node:http'
@@ -23,30 +28,13 @@ import { once } from 'node:events'
23
28
  import * as testContext from 'node:test'
24
29
 
25
30
  import { concat, normalize, toPosix } from '../../path/module.f.mjs'
26
- /** @import { Effect } from '../types.ts' */
27
31
  import { asyncRun } from '../module.mjs'
28
32
  import { memoryOperationMap } from './memory/module.mjs'
29
- import { usesInlineTestContext } from './module.f.mjs'
30
- /**
31
- * @import {
32
- * Server as EffectServer,
33
- * Headers,
34
- * Module,
35
- * NodeOp,
36
- * RequestListener as Erl,
37
- * NodeProgram,
38
- * NodeProgramOptions,
39
- * WriteConsoles,
40
- * TestContext,
41
- * TestFn,
42
- * } from './types.ts'
43
- */
33
+ import { exitCode, toIoError, usesInlineTestContext } from './module.f.mjs'
44
34
  import { asBase, asNominal } from '../../types/nominal/module.f.mjs'
45
- /** @import { Result } from '../../types/result/types.ts' */
46
- import { error, ok } from '../../types/result/module.f.mjs'
35
+ import { error, ok, unwrap } from '../../types/result/module.f.mjs'
47
36
  import { asyncTryCatch } from '../../types/result/module.mjs'
48
37
  import { fromVec, listToVec, toVec } from '../../types/uint8array/module.f.mjs'
49
- /** @import { StringMap } from '../../types/object/types.ts' */
50
38
  import { maxLengthBytes } from '../../types/bit_vec/module.f.mjs'
51
39
 
52
40
  /** @typedef {{ readonly listen: (port: number) => void }} _Server */
@@ -79,7 +67,23 @@ import { maxLengthBytes } from '../../types/bit_vec/module.f.mjs'
79
67
  */
80
68
  const createServer = http.createServer
81
69
 
82
- /** @typedef {<T>(effect: Effect<NodeOp, T>) => Promise<T>} _EffectToPromise */
70
+ /** @typedef {<T, E>(effect: Effect<NodeOp, T, E>) => Promise<Result<T, E>>} _EffectToPromise */
71
+
72
+ /**
73
+ * Performs host IO, reporting a thrown failure as an {@link IoResult} error.
74
+ *
75
+ * Every filesystem, network, and subprocess handler below goes through it, so
76
+ * the `catch` that turns an exception into effect data — and the normalization
77
+ * that keeps the channel serializable — happens in exactly one place.
78
+ *
79
+ * @template T
80
+ * @param {() => Promise<T>} f
81
+ * @returns {Promise<IoResult<T>>}
82
+ */
83
+ const io = async f => {
84
+ const r = await asyncTryCatch(f)
85
+ return r[0] === 'ok' ? r : error(toIoError(r[1]))
86
+ }
83
87
 
84
88
  /**
85
89
  * @template T
@@ -127,7 +131,7 @@ const sandbox = async f => {
127
131
  p = await p
128
132
  after = performance.now()
129
133
  }
130
- result = ok(/** @type {T} */ (p))
134
+ result = ok(p)
131
135
  } catch (e) {
132
136
  after = performance.now()
133
137
  result = error(e)
@@ -202,7 +206,7 @@ const waitReadableOrEnd = stdin =>
202
206
  const readStdinByte = async () => {
203
207
  const stdin = process.stdin
204
208
  while (true) {
205
- const chunk = /** @type {Uint8Array | null} */ (stdin.read(1))
209
+ const chunk = stdin.read(1)
206
210
  if (chunk !== null) {
207
211
  return chunk[0]
208
212
  }
@@ -222,16 +226,16 @@ const { randomInt } = crypto
222
226
  /** @type {_EffectToPromise} */
223
227
  const runNodeEffect = asyncRun({
224
228
  ...memoryOperationMap(),
225
- all: async (...effects) => await Promise.all(effects.map(runNodeEffect)),
226
- fetch: async url => asyncTryCatch(async () => {
229
+ all: async (...effects) => ok(await Promise.all(effects.map(runNodeEffect))),
230
+ fetch: url => io(async () => {
227
231
  const response = await fetch(url)
228
232
  if (!response.ok) {
229
233
  throw new Error(`Fetch error: ${response.status} ${response.statusText}`)
230
234
  }
231
235
  return toVec(new Uint8Array(await response.arrayBuffer()))
232
236
  }),
233
- mkdir: (path, options) => asyncTryCatch(async () => { await mkdir(path, options) }),
234
- readFile: path => asyncTryCatch(async () => {
237
+ mkdir: (path, options) => io(async () => { await mkdir(path, options) }),
238
+ readFile: path => io(async () => {
235
239
  const fileStats = await stat(path)
236
240
  // if the file is too big, toVec should fail anyway but in this case we don't want to load the file.
237
241
  if (fileStats.size > maxFileSizeBytes) {
@@ -239,7 +243,7 @@ const runNodeEffect = asyncRun({
239
243
  }
240
244
  return toVec(await readFile(path))
241
245
  }),
242
- readdir: (path, r) => asyncTryCatch(async () =>
246
+ readdir: (path, r) => io(async () =>
243
247
  (await readdir(path, { ...r, withFileTypes: true }))
244
248
  .map(v => ({
245
249
  name: v.name,
@@ -247,10 +251,10 @@ const runNodeEffect = asyncRun({
247
251
  isFile: v.isFile()
248
252
  }))
249
253
  ),
250
- writeFile: (path, data) => asyncTryCatch(() => writeFile(path, fromVec(data))),
251
- rm: path => asyncTryCatch(() => rm(path)),
252
- rename: (src, dst) => asyncTryCatch(() => rename(src, dst)),
253
- readBytes: (path, offset, size) => asyncTryCatch(async () => {
254
+ writeFile: (path, data) => io(() => writeFile(path, fromVec(data))),
255
+ rm: path => io(() => rm(path)),
256
+ rename: (src, dst) => io(() => rename(src, dst)),
257
+ readBytes: (path, offset, size) => io(async () => {
254
258
  if (offset < 0) {
255
259
  throw new Error(`Offset ${offset} is negative`)
256
260
  }
@@ -266,13 +270,13 @@ const runNodeEffect = asyncRun({
266
270
  await fh.close()
267
271
  }
268
272
  }),
269
- randomInt: async () => randomInt(randomMax),
270
- access: path => asyncTryCatch(() => access(path)),
271
- createExclusive: path => asyncTryCatch(async () => {
273
+ randomInt: async () => ok(randomInt(randomMax)),
274
+ access: path => io(() => access(path)),
275
+ createExclusive: path => io(async () => {
272
276
  const fh = await open(path, 'wx')
273
277
  await fh.close()
274
278
  }),
275
- writeBytes: (path, offset, data) => asyncTryCatch(async () => {
279
+ writeBytes: (path, offset, data) => io(async () => {
276
280
  const fh = await open(path, 'r+')
277
281
  try {
278
282
  const buffer = fromVec(data)
@@ -287,11 +291,11 @@ const runNodeEffect = asyncRun({
287
291
  await fh.close()
288
292
  }
289
293
  }),
290
- stat: path => asyncTryCatch(async () => ({ size: (await stat(path)).size })),
291
- import: path => asyncTryCatch(() => asyncImport(path)),
294
+ stat: path => io(async () => ({ size: (await stat(path)).size })),
295
+ import: path => io(() => asyncImport(path)),
292
296
  exec: (command, stdin) => new Promise(resolve => {
293
297
  const child = exec(command, (e, stdout, stderr) =>
294
- resolve(e !== null ? /** @type {const} */ (['error', e]) : ok({ stdout, stderr }))
298
+ resolve(e !== null ? error(toIoError(e)) : ok({ stdout, stderr }))
295
299
  )
296
300
  child.stdin?.end(stdin)
297
301
  }),
@@ -301,30 +305,37 @@ const runNodeEffect = asyncRun({
301
305
  const nodeRl = async (req, res) => {
302
306
  const reqBody = await collect(req)
303
307
  const { method, url, headers } = req
304
- const { status, headers: outHeaders, body: outBody } = await runNodeEffect(erl({
308
+ // `RequestListener` answers `Effect<…, ServerResponse, never>`
309
+ // the response frame is where a listener puts its failures — so
310
+ // this unwrap is total.
311
+ const { status, headers: outHeaders, body: outBody } = unwrap(await runNodeEffect(erl({
305
312
  method,
306
313
  url,
307
314
  headers,
308
315
  body: listToVec(reqBody)
309
- }))
316
+ })))
310
317
  res
311
318
  .writeHead(status, outHeaders)
312
319
  .end(fromVec(outBody))
313
320
  }
314
- return /** @satisfies {EffectServer} */ (asNominal(createServer(nodeRl)))
321
+ return ok(/** @satisfies {EffectServer} */ (asNominal(createServer(nodeRl))))
315
322
  },
316
323
  listen: async (server, port) => {
317
324
  const s = /** @type {_Server} */ (asBase(server))
318
325
  s.listen(port)
326
+ return ok(undefined)
319
327
  },
320
328
  forever: () => new Promise(() => {}),
321
- now: async () => now(),
322
- sandbox,
323
- await: awaitPromise,
324
- write: (stream, data) => writeAll(streams[stream], fromVec(data)),
325
- read: readStdinByte,
329
+ now: async () => ok(now()),
330
+ sandbox: async f => ok(await sandbox(f)),
331
+ await: async p => ok(await awaitPromise(p)),
332
+ write: async (stream, data) => ok(await writeAll(streams[stream], fromVec(data))),
333
+ read: async () => ok(await readStdinByte()),
326
334
  test: async (ctx, name, expectFailure, test) =>
327
- ctx.test(name, { expectFailure }, async t => runNodeEffect(test(t))),
335
+ // The body's answer is `ok(undefined)` a `Test` callback absorbs its
336
+ // own failures by panicking, which is the only signal these frameworks
337
+ // read — so it is awaited and discarded rather than returned.
338
+ ok(await ctx.test(name, { expectFailure }, async t => { await runNodeEffect(test(t)) })),
328
339
  })
329
340
 
330
341
  /** @type {TestFn} */
@@ -377,8 +388,8 @@ const options = {
377
388
  * the program's code, use {@link run} instead.
378
389
  * @type {(p: NodeProgram) => Promise<number>}
379
390
  */
380
- export const runEffect = program =>
381
- runNodeEffect(program(options))
391
+ export const runEffect = async program =>
392
+ exitCode(await runNodeEffect(program(options)))
382
393
 
383
394
  /**
384
395
  * CLI entry point: runs a `NodeProgram` via {@link runEffect}, then calls
@@ -1,11 +1,37 @@
1
1
  /**
2
2
  * @import { Vec } from "../../types/bit_vec/types.ts"
3
- * @import { IoResult, ReadFile } from "./types.ts"
4
- * @import { Dir } from "./virtual/types.ts"
3
+ * @import { IoChannel, IoError, IoResult, ReadFile } from "./types.ts"
4
+ * @import { Result } from "../../types/result/types.ts"
5
5
  * @import { List } from "../list/types.ts"
6
6
  * @import { OperationMap } from "../types.ts"
7
7
  */
8
8
  export declare const proof: {
9
+ toIoError: {
10
+ error: () => void;
11
+ withCode: () => void;
12
+ string: () => void;
13
+ null: () => void;
14
+ nonStringCode: () => void;
15
+ noCode: () => void;
16
+ };
17
+ isNotFound: {
18
+ enoent: () => void;
19
+ otherCode: () => void;
20
+ notImplemented: () => void;
21
+ };
22
+ errorMessage: {
23
+ io: () => void;
24
+ notImplemented: () => void;
25
+ };
26
+ errorSummary: {
27
+ io: () => void;
28
+ ioWithoutCode: () => void;
29
+ notImplemented: () => void;
30
+ };
31
+ exitStep: {
32
+ ok: () => void;
33
+ error: () => void;
34
+ };
9
35
  externalTestContext: () => void;
10
36
  map: () => void;
11
37
  fetch: () => void;
@@ -1,15 +1,16 @@
1
1
  /**
2
2
  * @import { Vec } from "../../types/bit_vec/types.ts"
3
- * @import { IoResult, ReadFile } from "./types.ts"
4
- * @import { Dir } from "./virtual/types.ts"
3
+ * @import { IoChannel, IoError, IoResult, ReadFile } from "./types.ts"
4
+ * @import { Result } from "../../types/result/types.ts"
5
5
  * @import { List } from "../list/types.ts"
6
6
  * @import { OperationMap } from "../types.ts"
7
7
  */
8
8
 
9
9
  import { empty, isVec, uint, vec, vec8 } from "../../types/bit_vec/module.f.mjs"
10
10
  import { utf8, utf8ToString } from "../../text/module.f.mjs"
11
- import { match, pure, step } from "../module.f.mjs"
12
- import { both, fetch, mkdir, now, readdir, readFile, readUtf8File, rm, sandbox, writeFile, writeUtf8File, rename, readBytes, randomInt, writeFromStream, usesInlineTestContext, versionLessThan } from "./module.f.mjs"
11
+ import { match } from "../module.f.mjs"
12
+ import { mapStep, step as ioStep } from "../module.f.mjs"
13
+ import { both, errorMessage, errorSummary, exitStep, fetch, ioError, isNotFound, mkdir, now, readdir, readFile, readUtf8File, rm, sandbox, toIoError, writeFile, writeUtf8File, rename, readBytes, randomInt, writeFromStream, usesInlineTestContext, versionLessThan } from "./module.f.mjs"
13
14
  import { create as memCreate, read as memRead, write as memWrite } from "../memory/module.f.mjs"
14
15
  import { empty as listEmpty, nonEmpty as listNonEmpty } from "../list/module.f.mjs"
15
16
  import { emptyState, virtual } from "./virtual/module.f.mjs"
@@ -29,7 +30,115 @@ const readHelloMap = {
29
30
 
30
31
  const readHello = match(readHelloMap)
31
32
 
33
+ /**
34
+ * Asserts that a channel error is a host failure carrying `message`. Every
35
+ * runner reports through the same normalized {@link IoError}, so a proof
36
+ * against the virtual filesystem names the message rather than the shape.
37
+ * @type {(e: IoChannel, message: string) => void}
38
+ */
39
+ const assertIoMessage = (e, message) => {
40
+ assert(e[0] === 'ioError', e)
41
+ assertEq(e[1].message, message)
42
+ }
43
+
44
+ /** Asserts that an operation succeeded with `expected`.
45
+ * @type {<T, E>(r: Result<T, E>, expected: T) => void}
46
+ */
47
+ const assertOk = (r, expected) => {
48
+ assert(r[0] === 'ok', r)
49
+ assertEq(r[1], expected)
50
+ }
51
+
32
52
  export const proof = {
53
+ // The one boundary where a runner's `catch` becomes effect data: whatever
54
+ // was thrown is reduced to a code (when the host attached a string one)
55
+ // and a message.
56
+ toIoError: {
57
+ error: () => {
58
+ assertIoMessage(toIoError(new Error('boom')), 'boom')
59
+ },
60
+ withCode: () => {
61
+ const e = toIoError(Object.assign(new Error('missing'), { code: 'ENOENT' }))
62
+ assert(e[0] === 'ioError', e)
63
+ assertEq(e[1].code, 'ENOENT', e)
64
+ assertEq(e[1].message, 'missing', e)
65
+ },
66
+ // A thrown non-`Error` still normalizes: the value's string form is the
67
+ // message, and there is no code to carry.
68
+ string: () => {
69
+ const e = toIoError('plain')
70
+ assert(e[0] === 'ioError', e)
71
+ assertEq(e[1].code, undefined, e)
72
+ assertEq(e[1].message, 'plain', e)
73
+ },
74
+ null: () => {
75
+ assertIoMessage(toIoError(null), 'null')
76
+ },
77
+ // An object whose `code` is not a string is not an OS error code, so it
78
+ // is dropped rather than carried as one.
79
+ nonStringCode: () => {
80
+ const e = toIoError({ code: 42 })
81
+ assert(e[0] === 'ioError', e)
82
+ assertEq(e[1].code, undefined, e)
83
+ },
84
+ noCode: () => {
85
+ const e = toIoError({})
86
+ assert(e[0] === 'ioError', e)
87
+ assertEq(e[1].code, undefined, e)
88
+ },
89
+ },
90
+ isNotFound: {
91
+ enoent: () => {
92
+ assert(isNotFound(ioError({ code: 'ENOENT', message: 'no such file or directory' })))
93
+ },
94
+ otherCode: () => {
95
+ assert(!isNotFound(ioError({ code: 'EACCES', message: 'permission denied' })))
96
+ },
97
+ // A runner that cannot perform the operation has not looked for the
98
+ // path at all, so a missing handler is never "not found".
99
+ notImplemented: () => {
100
+ assert(!isNotFound(['notImplemented', 'readFile']))
101
+ },
102
+ },
103
+ errorMessage: {
104
+ io: () => {
105
+ assertEq(errorMessage(ioError({ message: 'disk full' })), 'disk full')
106
+ },
107
+ notImplemented: () => {
108
+ assertEq(errorMessage(['notImplemented', 'readFile']), 'operation not implemented: readFile')
109
+ },
110
+ },
111
+ errorSummary: {
112
+ // The distinction that matters: `errorMessage` hands back the host's
113
+ // words, which is where the path lives; `errorSummary` never does.
114
+ io: () => {
115
+ assertEq(errorSummary(ioError({ code: 'ENOENT', message: "no such file or directory, scandir '/home/u/.cas'" })), 'io error: ENOENT')
116
+ },
117
+ ioWithoutCode: () => {
118
+ assertEq(errorSummary(ioError({ message: "cannot read '/home/u/.cas'" })), 'io error')
119
+ },
120
+ notImplemented: () => {
121
+ assertEq(errorSummary(['notImplemented', 'readdir']), 'operation not implemented: readdir')
122
+ },
123
+ },
124
+ exitStep: {
125
+ // The exit-code policy a `NodeProgram` ends with: success is `0`...
126
+ ok: () => {
127
+ const [state, code] = virtual(emptyState)(exitStep(writeFile('hello', vec8(0x2An))))
128
+ assertEq(code[0], 'ok')
129
+ assertEq(code[1], 0)
130
+ assertEq(state.stderr, '')
131
+ },
132
+ // ...and a failure is reported on `stderr` and exits `1`.
133
+ // ...and the code is `[1]` either way, which is what lets a runner
134
+ // read it without asking which branch it came from.
135
+ error: () => {
136
+ const [state, code] = virtual(emptyState)(exitStep(readFile('missing')))
137
+ assertEq(code[0], 'error')
138
+ assertEq(code[1], 1)
139
+ assertEq(state.stderr, 'no such file or directory\n')
140
+ },
141
+ },
33
142
  externalTestContext: () => {
34
143
  assert(usesInlineTestContext('node', 'v22.20.0'))
35
144
  assert(usesInlineTestContext('node', '25.99.99'))
@@ -44,18 +153,15 @@ export const proof = {
44
153
  assert(!versionLessThan('26.1.1', '26.1.1'))
45
154
  },
46
155
  map: () => {
47
- const e = step(
48
- readFile('hello'),
49
- ([k, v]) => {
50
- assert(k !== 'error', v)
51
- return pure(uint(v) * 2n)
52
- })
156
+ const e = mapStep(readFile('hello'), v => uint(v) * 2n)
53
157
  //
54
158
  let r = readHello(e)
55
159
  while (r[0] === 'cont') {
56
160
  r = readHello(r[2](r[1]))
57
161
  }
58
- assertEq(r[1], 0x2An)
162
+ // `done` carries the whole `Result`: an interpreter never separates the
163
+ // channels, so the projection's value is inside the `ok`.
164
+ assertEq(r[1][1], 0x2An)
59
165
  },
60
166
  fetch: () => {
61
167
  const [_, [t, result]] = virtual({
@@ -81,8 +187,11 @@ export const proof = {
81
187
  )
82
188
  assert(t === 'ok', result)
83
189
  const tmp = state.root.tmp
84
- assert(!(typeof tmp !== 'object' || Array.isArray(tmp)), state.root)
85
- const cache = (/** @type {Dir} */ (tmp)).cache
190
+ // `instanceof Array`, not `Array.isArray`: only the former's negative
191
+ // branch removes a `readonly` array from a union, so only it narrows
192
+ // `_Entity` to `Dir`.
193
+ assert(!(typeof tmp !== 'object' || tmp instanceof Array), state.root)
194
+ const cache = tmp.cache
86
195
  assert(!(typeof cache !== 'object' || Array.isArray(cache)), tmp)
87
196
  },
88
197
  nonRec: () => {
@@ -122,7 +231,8 @@ export const proof = {
122
231
  nestedPath: () => {
123
232
  const [_, [t, result]] = virtual(emptyState)(readFile('tmp/cache'))
124
233
  assert(t === 'error', result)
125
- if ((/** @type {{ code?: unknown }} */ (result)).code !== 'ENOENT') { throw result }
234
+ assert(result[0] === 'ioError', result)
235
+ assertEq(result[1].code, 'ENOENT', result)
126
236
  },
127
237
  withinLimit: () => {
128
238
  // Test with a small file well within the 131,072 byte limit
@@ -197,7 +307,7 @@ export const proof = {
197
307
  noSuchDir: () => {
198
308
  const [_, [t, result]] = virtual(emptyState)(readdir('tmp', { recursive: true }))
199
309
  assert(t === 'error', result)
200
- assertEq(result, 'invalid path')
310
+ assertIoMessage(result, 'invalid path')
201
311
  },
202
312
  },
203
313
  writeFile: {
@@ -229,7 +339,7 @@ export const proof = {
229
339
  writeFile('tmp/cache', vec8(0x2An))
230
340
  )
231
341
  assert(t === 'error', result)
232
- assertEq(result, 'invalid file')
342
+ assertIoMessage(result, 'invalid file')
233
343
  assertEq(state.root.tmp, undefined, state.root)
234
344
  },
235
345
  directory: () => {
@@ -242,7 +352,7 @@ export const proof = {
242
352
  writeFile('tmp', vec8(0x2An))
243
353
  )
244
354
  assert(t === 'error', result)
245
- assertEq(result, 'invalid file')
355
+ assertIoMessage(result, 'invalid file')
246
356
  const tmp = state.root.tmp
247
357
  assert(!(tmp === undefined || Array.isArray(tmp)), tmp)
248
358
  },
@@ -272,13 +382,13 @@ export const proof = {
272
382
  })(rm('tmp/cache'))
273
383
  assert(t === 'ok', result)
274
384
  const tmp = state.root.tmp
275
- assert(!(typeof tmp !== 'object' || Array.isArray(tmp)), state.root)
276
- assertEq((/** @type {Dir} */ (tmp)).cache, undefined, tmp)
385
+ assert(!(typeof tmp !== 'object' || tmp instanceof Array), state.root)
386
+ assertEq(tmp.cache, undefined, tmp)
277
387
  },
278
388
  noSuchFile: () => {
279
389
  const [_, [t, result]] = virtual(emptyState)(rm('hello'))
280
390
  assert(t === 'error', result)
281
- assertEq(result, 'no such file')
391
+ assertIoMessage(result, 'no such file')
282
392
  },
283
393
  isDirectory: () => {
284
394
  const [state, [t, result]] = virtual({
@@ -286,18 +396,20 @@ export const proof = {
286
396
  root: { tmp: {} },
287
397
  })(rm('tmp'))
288
398
  assert(t === 'error', result)
289
- assertEq(result, 'invalid path')
399
+ assertIoMessage(result, 'invalid path')
290
400
  assert(state.root.tmp !== undefined, state.root)
291
401
  },
292
402
  },
293
403
  both: () => {
294
- const [_, results] = virtual({
404
+ const [_, both2] = virtual({
295
405
  ...emptyState,
296
406
  root: {
297
407
  a: [vec8(0x2An)],
298
408
  b: [vec8(0x15n)],
299
409
  },
300
410
  })(both(readFile('a'))(readFile('b')))
411
+ assert(both2[0] === 'ok', both2)
412
+ const results = both2[1]
301
413
  assert(results[0][0] === 'ok', results[0])
302
414
  assert(results[1][0] === 'ok', results[1])
303
415
  assertEq(uint(results[0][1]), 0x2An, results[0][1])
@@ -305,41 +417,48 @@ export const proof = {
305
417
  },
306
418
  now: () => {
307
419
  const [_, result] = virtual({ ...emptyState, epochNs: 1_000_000 })(now())
308
- assertEq(result, 1_000_000)
420
+ assertOk(result, 1_000_000)
309
421
  },
310
422
  sandbox: {
311
423
  // Virtual `sandbox` is now a pass-through: the function is expected
312
424
  // to return a `SandboxResult` directly. Fixtures dictate the result
313
425
  // (and `duration`) instead of the runner measuring.
314
426
  ok: () => {
315
- const [_, { result, duration }] = virtual(emptyState)(
316
- sandbox(() => /** @type {never} */ ({ result: ['ok', 42], duration: 0 })))
427
+ const [_, sandboxed] = virtual(emptyState)(
428
+ sandbox(() => ({ result: ['ok', 42], duration: 0 })))
429
+ // Two `Result`s, one inside the other on purpose: the outer one is
430
+ // the operation's own status, the inner one is the sandboxed
431
+ // function's outcome — returned data, not effect status.
432
+ assert(sandboxed[0] === 'ok', sandboxed)
433
+ const { result, duration } = sandboxed[1]
317
434
  assert(result[0] === 'ok', result)
318
435
  assertEq(result[1], 42)
319
436
  assertEq(duration, 0)
320
437
  },
321
438
  error: () => {
322
439
  const err = new Error('fail')
323
- const [_, { result }] = virtual(emptyState)(
324
- sandbox(() => /** @type {never} */ ({ result: ['error', err], duration: 0 })))
440
+ const [_, sandboxed] = virtual(emptyState)(
441
+ sandbox(() => ({ result: ['error', err], duration: 0 })))
442
+ assert(sandboxed[0] === 'ok', sandboxed)
443
+ const { result } = sandboxed[1]
325
444
  assert(result[0] === 'error', result)
326
445
  assertEq(result[1], err)
327
446
  },
328
447
  },
329
448
  memory: {
330
449
  createAndRead: () => {
331
- const effect = step(memCreate(42), key => memRead(key))
450
+ const effect = ioStep(memCreate(42), key => memRead(key))
332
451
  const [_, value] = virtual(emptyState)(effect)
333
- assertEq(value, 42)
452
+ assertOk(value, 42)
334
453
  },
335
454
  createAndWrite: () => {
336
- const effect = step(
455
+ const effect = ioStep(
337
456
  memCreate(1),
338
- key => step(
457
+ key => ioStep(
339
458
  memWrite(key, 99),
340
459
  () => memRead(key)))
341
460
  const [_, value] = virtual(emptyState)(effect)
342
- assertEq(value, 99)
461
+ assertOk(value, 99)
343
462
  },
344
463
  },
345
464
  rename: {
@@ -351,7 +470,7 @@ export const proof = {
351
470
  assert(t === 'ok', result)
352
471
  assertEq(state.root.src, undefined, state.root)
353
472
  assert(Array.isArray(state.root.dst), state.root)
354
- assertEq(uint((/** @type {readonly Vec[]} */ (state.root.dst))[0]), 0x2An, state.root)
473
+ assertEq(uint(state.root.dst[0]), 0x2An, state.root)
355
474
  },
356
475
  nestedRename: () => {
357
476
  const [state, [t, result]] = virtual({
@@ -360,8 +479,8 @@ export const proof = {
360
479
  })(rename('tmp/src', 'tmp/dst'))
361
480
  assert(t === 'ok', result)
362
481
  const tmp = state.root.tmp
363
- assert(!(typeof tmp !== 'object' || Array.isArray(tmp)), state.root)
364
- assertEq((/** @type {Dir} */ (tmp)).src, undefined, tmp)
482
+ assert(!(typeof tmp !== 'object' || tmp instanceof Array), state.root)
483
+ assertEq(tmp.src, undefined, tmp)
365
484
  },
366
485
  dirOverFile: () => {
367
486
  const [state, [t, result]] = virtual({
@@ -408,18 +527,18 @@ export const proof = {
408
527
  randomInt: {
409
528
  increments: () => {
410
529
  const [state1, r1] = virtual(emptyState)(randomInt())
411
- assertEq(r1, 0)
530
+ assertOk(r1, 0)
412
531
  const [state2, r2] = virtual(state1)(randomInt())
413
- assertEq(r2, 1)
532
+ assertOk(r2, 1)
414
533
  const [_, r3] = virtual(state2)(randomInt())
415
- assertEq(r3, 2)
534
+ assertOk(r3, 2)
416
535
  },
417
536
  },
418
537
  writeFromStream: {
419
538
  createExclusiveFails: () => {
420
539
  // The destination already exists, so `createExclusive` fails (EEXIST) and
421
540
  // the error propagates without ever touching `writeBytes`.
422
- /** @type {List<never, IoResult<Vec>>} */
541
+ /** @type {List<never, Vec, IoChannel>} */
423
542
  const chunks = listEmpty()
424
543
  const [state, [t, result]] = virtual({
425
544
  ...emptyState,
@@ -432,13 +551,13 @@ export const proof = {
432
551
  invalidBufferSize: () => {
433
552
  // A chunk whose bit length isn't a multiple of 8 trips the
434
553
  // byte-alignment guard before `writeBytes` is ever called.
435
- /** @type {List<never, IoResult<Vec>>} */
436
- const chunks = listNonEmpty(['ok', vec(4n)(0b1010n)], listEmpty())
554
+ /** @type {List<never, Vec, IoChannel>} */
555
+ const chunks = listNonEmpty(vec(4n)(0b1010n), listEmpty())
437
556
  const [_, [t, result]] = virtual(emptyState)(
438
557
  writeFromStream('hello', chunks)
439
558
  )
440
559
  assert(t === 'error', result)
441
- assertEq(result, 'invalid buffer size')
560
+ assertIoMessage(result, 'invalid buffer size')
442
561
  },
443
562
  },
444
563
  }