functionalscript 0.45.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 (296) 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 +10 -0
  4. package/fjs/asn.1/proof.f.mjs +16 -0
  5. package/fjs/basen/base128/module.f.mjs +22 -5
  6. package/fjs/bnf/data/module.f.d.mts +32 -6
  7. package/fjs/bnf/data/module.f.mjs +112 -7
  8. package/fjs/bnf/data/proof.f.d.mts +2 -0
  9. package/fjs/bnf/data/proof.f.mjs +74 -3
  10. package/fjs/bnf/data/types.d.ts +20 -2
  11. package/fjs/bnf/descent/module.f.d.mts +28 -14
  12. package/fjs/bnf/descent/module.f.mjs +122 -77
  13. package/fjs/bnf/descent/proof.f.d.mts +2 -0
  14. package/fjs/bnf/descent/proof.f.mjs +117 -31
  15. package/fjs/bnf/descent/types.d.ts +12 -14
  16. package/fjs/bnf/ll1/module.f.d.mts +64 -22
  17. package/fjs/bnf/ll1/module.f.mjs +214 -154
  18. package/fjs/bnf/ll1/proof.f.d.mts +15 -2
  19. package/fjs/bnf/ll1/proof.f.mjs +323 -149
  20. package/fjs/bnf/ll1/types.d.ts +16 -24
  21. package/fjs/bnf/matcher/module.f.d.mts +66 -0
  22. package/fjs/bnf/matcher/module.f.mjs +81 -0
  23. package/fjs/bnf/matcher/proof.f.d.mts +10 -0
  24. package/fjs/bnf/matcher/proof.f.mjs +79 -0
  25. package/fjs/bnf/matcher/types.d.ts +54 -0
  26. package/fjs/bnf/testlib.f.d.mts +31 -0
  27. package/fjs/bnf/testlib.f.mjs +80 -0
  28. package/fjs/cas/cli/module.f.d.mts +1 -1
  29. package/fjs/cas/cli/module.f.mjs +14 -20
  30. package/fjs/cas/cli/proof.f.d.mts +1 -3
  31. package/fjs/cas/cli/proof.f.mjs +44 -33
  32. package/fjs/cas/evo/module.f.d.mts +64 -18
  33. package/fjs/cas/evo/module.f.mjs +148 -70
  34. package/fjs/cas/evo/proof.f.d.mts +10 -1
  35. package/fjs/cas/evo/proof.f.mjs +305 -223
  36. package/fjs/cas/evo/types.d.ts +45 -9
  37. package/fjs/cas/module.f.d.mts +18 -32
  38. package/fjs/cas/module.f.mjs +129 -128
  39. package/fjs/cas/proof.f.d.mts +11 -8
  40. package/fjs/cas/proof.f.mjs +259 -147
  41. package/fjs/cas/types.d.ts +24 -10
  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/module.f.d.mts +5 -5
  45. package/fjs/ci/module.f.mjs +8 -7
  46. package/fjs/ci/nix/module.f.d.mts +7 -5
  47. package/fjs/ci/nix/module.f.mjs +13 -12
  48. package/fjs/ci/nix/proof.f.mjs +2 -2
  49. package/fjs/ci/proof.f.mjs +9 -5
  50. package/fjs/cli/module.f.d.mts +4 -6
  51. package/fjs/cli/module.f.mjs +4 -8
  52. package/fjs/cli/proof.f.mjs +17 -16
  53. package/fjs/cli/types.d.ts +2 -3
  54. package/fjs/common/monoid/types.d.ts +1 -1
  55. package/fjs/crypto/hmac/module.f.mjs +2 -2
  56. package/fjs/crypto/sha2/module.f.mjs +3 -1
  57. package/fjs/crypto/sha2/proof.f.d.mts +1 -0
  58. package/fjs/crypto/sha2/proof.f.mjs +24 -0
  59. package/fjs/crypto/sha2/types.d.ts +11 -0
  60. package/fjs/crypto/sign/module.f.mjs +2 -2
  61. package/fjs/dev/module.f.d.mts +13 -4
  62. package/fjs/dev/module.f.mjs +56 -27
  63. package/fjs/dev/update/module.f.d.mts +9 -4
  64. package/fjs/dev/update/module.f.mjs +14 -10
  65. package/fjs/dev/update/proof.f.d.mts +1 -3
  66. package/fjs/dev/update/proof.f.mjs +10 -5
  67. package/fjs/djs/module.f.d.mts +13 -5
  68. package/fjs/djs/module.f.mjs +31 -16
  69. package/fjs/djs/parser/module.f.d.mts +13 -3
  70. package/fjs/djs/parser/module.f.mjs +117 -16
  71. package/fjs/djs/parser/proof.f.d.mts +5 -1
  72. package/fjs/djs/parser/proof.f.mjs +274 -12
  73. package/fjs/djs/parser/types.d.ts +7 -1
  74. package/fjs/djs/proof.f.d.mts +18 -2
  75. package/fjs/djs/proof.f.mjs +187 -12
  76. package/fjs/djs/serializer/module.f.d.mts +25 -8
  77. package/fjs/djs/serializer/module.f.mjs +61 -15
  78. package/fjs/djs/serializer/proof.f.d.mts +5 -0
  79. package/fjs/djs/serializer/proof.f.mjs +23 -1
  80. package/fjs/djs/tokenizer/module.f.d.mts +17 -5
  81. package/fjs/djs/tokenizer/module.f.mjs +99 -60
  82. package/fjs/djs/tokenizer/proof.f.d.mts +1 -1
  83. package/fjs/djs/tokenizer/proof.f.mjs +74 -67
  84. package/fjs/djs/transpiler/module.f.d.mts +12 -7
  85. package/fjs/djs/transpiler/module.f.mjs +82 -56
  86. package/fjs/djs/transpiler/types.d.ts +7 -3
  87. package/fjs/djs/types.d.ts +7 -1
  88. package/fjs/effects/list/module.f.d.mts +14 -11
  89. package/fjs/effects/list/module.f.mjs +13 -11
  90. package/fjs/effects/list/types.d.ts +27 -7
  91. package/fjs/effects/memory/module.f.d.mts +2 -1
  92. package/fjs/effects/memory/module.f.mjs +3 -4
  93. package/fjs/effects/memory/proof.f.mjs +13 -7
  94. package/fjs/effects/memory/types.d.ts +4 -3
  95. package/fjs/effects/mock/module.f.d.mts +20 -4
  96. package/fjs/effects/mock/module.f.mjs +37 -5
  97. package/fjs/effects/mock/types.d.ts +10 -1
  98. package/fjs/effects/module.d.mts +4 -2
  99. package/fjs/effects/module.f.d.mts +466 -280
  100. package/fjs/effects/module.f.mjs +537 -299
  101. package/fjs/effects/module.mjs +2 -1
  102. package/fjs/effects/node/memory/module.d.mts +4 -2
  103. package/fjs/effects/node/memory/module.mjs +6 -3
  104. package/fjs/effects/node/memory/proof.mjs +10 -4
  105. package/fjs/effects/node/module.d.mts +4 -3
  106. package/fjs/effects/node/module.f.d.mts +168 -33
  107. package/fjs/effects/node/module.f.mjs +256 -52
  108. package/fjs/effects/node/module.mjs +57 -34
  109. package/fjs/effects/node/proof.f.d.mts +28 -2
  110. package/fjs/effects/node/proof.f.mjs +161 -42
  111. package/fjs/effects/node/types.d.ts +106 -18
  112. package/fjs/effects/node/virtual/module.f.d.mts +18 -4
  113. package/fjs/effects/node/virtual/module.f.mjs +110 -68
  114. package/fjs/effects/node/virtual/proof.f.d.mts +28 -2
  115. package/fjs/effects/node/virtual/proof.f.mjs +190 -9
  116. package/fjs/effects/proof.f.d.mts +69 -37
  117. package/fjs/effects/proof.f.mjs +410 -130
  118. package/fjs/effects/types.d.ts +161 -33
  119. package/fjs/emergent_testing/module.f.d.mts +19 -12
  120. package/fjs/emergent_testing/module.f.mjs +93 -33
  121. package/fjs/emergent_testing/proof.f.d.mts +21 -7
  122. package/fjs/emergent_testing/proof.f.mjs +166 -32
  123. package/fjs/emergent_testing/types.d.ts +22 -4
  124. package/fjs/fsm/module.f.d.mts +14 -4
  125. package/fjs/fsm/module.f.mjs +54 -37
  126. package/fjs/fsm/proof.f.d.mts +2 -0
  127. package/fjs/fsm/proof.f.mjs +83 -114
  128. package/fjs/js/keywords/module.f.d.mts +52 -0
  129. package/fjs/js/keywords/module.f.mjs +72 -0
  130. package/fjs/js/keywords/proof.f.d.mts +3 -0
  131. package/fjs/js/keywords/proof.f.mjs +13 -0
  132. package/fjs/js/tokenizer/module.f.d.mts +26 -6
  133. package/fjs/js/tokenizer/module.f.mjs +145 -159
  134. package/fjs/js/tokenizer/proof.f.d.mts +1 -0
  135. package/fjs/js/tokenizer/proof.f.mjs +54 -24
  136. package/fjs/js/tokenizer/types.d.ts +33 -24
  137. package/fjs/mcp/cas/module.f.d.mts +1 -6
  138. package/fjs/mcp/cas/module.f.mjs +55 -51
  139. package/fjs/mcp/cas/proof.f.d.mts +15 -0
  140. package/fjs/mcp/cas/proof.f.mjs +174 -0
  141. package/fjs/mcp/evo/module.f.d.mts +19 -10
  142. package/fjs/mcp/evo/module.f.mjs +48 -27
  143. package/fjs/mcp/evo/proof.f.d.mts +6 -1
  144. package/fjs/mcp/evo/proof.f.mjs +115 -31
  145. package/fjs/mcp/module.f.d.mts +4 -4
  146. package/fjs/mcp/module.f.mjs +6 -6
  147. package/fjs/mcp/proof.f.d.mts +5 -3
  148. package/fjs/mcp/proof.f.mjs +112 -46
  149. package/fjs/media/html/module.f.mjs +1 -1
  150. package/fjs/media/json/extended/module.f.d.mts +82 -0
  151. package/fjs/media/json/extended/module.f.mjs +153 -0
  152. package/fjs/media/json/extended/proof.f.d.mts +42 -0
  153. package/fjs/media/json/extended/proof.f.mjs +127 -0
  154. package/fjs/media/json/extended/types.d.ts +23 -0
  155. package/fjs/media/json/module.f.d.mts +8 -2
  156. package/fjs/media/json/module.f.mjs +43 -41
  157. package/fjs/media/json/number/module.f.d.mts +59 -0
  158. package/fjs/media/json/number/module.f.mjs +136 -0
  159. package/fjs/media/json/number/proof.f.d.mts +24 -0
  160. package/fjs/media/json/number/proof.f.mjs +86 -0
  161. package/fjs/media/json/number/types.d.ts +28 -0
  162. package/fjs/media/json/parser/module.f.d.mts +25 -13
  163. package/fjs/media/json/parser/module.f.mjs +114 -70
  164. package/fjs/media/json/parser/proof.f.d.mts +5 -0
  165. package/fjs/media/json/parser/proof.f.mjs +31 -1
  166. package/fjs/media/json/parser/types.d.ts +33 -14
  167. package/fjs/media/json/rtti/module.f.d.mts +1 -1
  168. package/fjs/media/json/rtti/module.f.mjs +1 -1
  169. package/fjs/media/json/rtti/proof.f.mjs +9 -9
  170. package/fjs/media/json/schema/module.f.mjs +3 -13
  171. package/fjs/media/json/schema/proof.f.d.mts +0 -1
  172. package/fjs/media/json/schema/proof.f.mjs +1 -2
  173. package/fjs/media/json/serializer/module.f.d.mts +32 -1
  174. package/fjs/media/json/serializer/module.f.mjs +64 -2
  175. package/fjs/media/json/tokenizer/module.f.mjs +7 -3
  176. package/fjs/media/json/tokenizer/proof.f.d.mts +6 -0
  177. package/fjs/media/json/tokenizer/proof.f.mjs +62 -21
  178. package/fjs/media/json/types.d.ts +36 -10
  179. package/fjs/media/lock/module.f.d.mts +100 -0
  180. package/fjs/media/lock/module.f.mjs +125 -0
  181. package/fjs/media/lock/proof.f.d.mts +33 -0
  182. package/fjs/media/lock/proof.f.mjs +196 -0
  183. package/fjs/media/lock/types.d.ts +15 -0
  184. package/fjs/media/module.f.d.mts +6 -5
  185. package/fjs/media/module.f.mjs +8 -7
  186. package/fjs/media/note/module.f.d.mts +121 -0
  187. package/fjs/media/note/module.f.mjs +131 -0
  188. package/fjs/media/note/proof.f.d.mts +29 -0
  189. package/fjs/media/note/proof.f.mjs +150 -0
  190. package/fjs/media/note/types.d.ts +10 -0
  191. package/fjs/media/proof.f.d.mts +4 -1
  192. package/fjs/media/proof.f.mjs +40 -21
  193. package/fjs/media/revision/module.f.d.mts +78 -7
  194. package/fjs/media/revision/module.f.mjs +119 -12
  195. package/fjs/media/revision/proof.f.d.mts +10 -0
  196. package/fjs/media/revision/proof.f.mjs +88 -0
  197. package/fjs/media/revision/types.d.ts +34 -5
  198. package/fjs/media/type/module.f.d.mts +33 -15
  199. package/fjs/media/type/module.f.mjs +35 -29
  200. package/fjs/media/type/proof.f.d.mts +2 -1
  201. package/fjs/media/type/proof.f.mjs +30 -10
  202. package/fjs/module.f.mjs +29 -8
  203. package/fjs/nanvm/proof.f.mjs +3 -3
  204. package/fjs/nanvm/rust/module.f.mjs +1 -1
  205. package/fjs/nanvm/update/module.f.d.mts +4 -4
  206. package/fjs/nanvm/update/module.f.mjs +8 -9
  207. package/fjs/nanvm/update/proof.f.mjs +4 -3
  208. package/fjs/proof.f.d.mts +3 -3
  209. package/fjs/proof.f.mjs +36 -10
  210. package/fjs/protocol/json_rpc/module.f.d.mts +2 -2
  211. package/fjs/protocol/json_rpc/module.f.mjs +3 -3
  212. package/fjs/protocol/json_rpc/proof.f.mjs +4 -4
  213. package/fjs/protocol/mcp/module.f.d.mts +10 -13
  214. package/fjs/protocol/mcp/module.f.mjs +74 -58
  215. package/fjs/protocol/mcp/proof.f.d.mts +13 -4
  216. package/fjs/protocol/mcp/proof.f.mjs +193 -61
  217. package/fjs/protocol/mcp/stdio/module.f.d.mts +15 -7
  218. package/fjs/protocol/mcp/stdio/module.f.mjs +38 -25
  219. package/fjs/protocol/mcp/stdio/proof.f.d.mts +4 -2
  220. package/fjs/protocol/mcp/stdio/proof.f.mjs +45 -12
  221. package/fjs/protocol/mcp/stdio/types.d.ts +1 -1
  222. package/fjs/protocol/mcp/types.d.ts +17 -6
  223. package/fjs/sul/id/module.f.d.mts +0 -1
  224. package/fjs/sul/id/module.f.mjs +2 -3
  225. package/fjs/sul/level/hash/module.f.mjs +2 -1
  226. package/fjs/sul/level/hash/proof.f.mjs +2 -2
  227. package/fjs/sul/module.f.mjs +18 -13
  228. package/fjs/text/code_point/module.f.d.mts +8 -0
  229. package/fjs/text/code_point/module.f.mjs +8 -1
  230. package/fjs/text/code_point/proof.f.d.mts +1 -0
  231. package/fjs/text/code_point/proof.f.mjs +11 -0
  232. package/fjs/text/sgr/module.f.d.mts +4 -6
  233. package/fjs/text/sgr/module.f.mjs +6 -7
  234. package/fjs/text/utf16/module.f.mjs +7 -2
  235. package/fjs/text/utf16/proof.f.mjs +3 -3
  236. package/fjs/text/utf8/module.f.mjs +4 -2
  237. package/fjs/types/array/module.f.mjs +14 -2
  238. package/fjs/types/bit_vec/module.f.d.mts +0 -2
  239. package/fjs/types/bit_vec/module.f.mjs +46 -32
  240. package/fjs/types/bit_vec/proof.f.mjs +2 -2
  241. package/fjs/types/btree/remove/module.f.mjs +1 -1
  242. package/fjs/types/btree/set/module.f.mjs +9 -11
  243. package/fjs/types/btree/set/proof.f.mjs +12 -0
  244. package/fjs/types/byte_set/module.f.d.mts +11 -4
  245. package/fjs/types/byte_set/module.f.mjs +14 -6
  246. package/fjs/types/byte_set/proof.f.mjs +7 -7
  247. package/fjs/types/function/compare/module.f.mjs +10 -3
  248. package/fjs/types/list/module.f.d.mts +1 -1
  249. package/fjs/types/list/module.f.mjs +1 -1
  250. package/fjs/types/nullable/module.f.d.mts +18 -4
  251. package/fjs/types/nullable/module.f.mjs +21 -4
  252. package/fjs/types/nullable/proof.f.d.mts +4 -0
  253. package/fjs/types/nullable/proof.f.mjs +15 -0
  254. package/fjs/types/object/module.f.d.mts +12 -2
  255. package/fjs/types/object/module.f.mjs +11 -1
  256. package/fjs/types/patricia_trie/module.f.mjs +26 -11
  257. package/fjs/types/result/module.f.d.mts +3 -3
  258. package/fjs/types/result/module.f.mjs +3 -3
  259. package/fjs/types/rtti/common/module.f.d.mts +25 -28
  260. package/fjs/types/rtti/common/module.f.mjs +36 -32
  261. package/fjs/types/rtti/common/proof.f.mjs +5 -5
  262. package/fjs/types/rtti/data/module.f.d.mts +14 -0
  263. package/fjs/types/rtti/data/module.f.mjs +25 -2
  264. package/fjs/types/rtti/data/proof.f.d.mts +1 -0
  265. package/fjs/types/rtti/data/proof.f.mjs +25 -2
  266. package/fjs/types/rtti/parse/module.f.d.mts +24 -14
  267. package/fjs/types/rtti/parse/module.f.mjs +37 -28
  268. package/fjs/types/rtti/parse/proof.f.d.mts +3 -2
  269. package/fjs/types/rtti/parse/proof.f.mjs +33 -14
  270. package/fjs/types/rtti/proof.f.mjs +3 -1
  271. package/fjs/types/rtti/ts/module.f.mjs +13 -17
  272. package/fjs/types/rtti/ts/types.d.ts +14 -1
  273. package/fjs/types/sorted_set/module.f.d.mts +18 -0
  274. package/fjs/types/sorted_set/module.f.mjs +22 -0
  275. package/fjs/types/sorted_set/proof.f.d.mts +1 -0
  276. package/fjs/types/sorted_set/proof.f.mjs +16 -1
  277. package/fjs/types/uint8array/module.f.d.mts +1 -1
  278. package/fjs/types/uint8array/module.f.mjs +1 -1
  279. package/fjs/website/module.f.d.mts +3 -3
  280. package/fjs/website/module.f.mjs +4 -7
  281. package/fjs/website/proof.f.mjs +2 -1
  282. package/package.json +2 -2
  283. package/fjs/dev/package_json/module.f.d.mts +0 -39
  284. package/fjs/dev/package_json/module.f.mjs +0 -40
  285. package/fjs/dev/package_json/proof.f.d.mts +0 -6
  286. package/fjs/dev/package_json/proof.f.mjs +0 -32
  287. package/fjs/effects/eff/module.f.d.mts +0 -20
  288. package/fjs/effects/eff/module.f.mjs +0 -70
  289. package/fjs/effects/eff/proof.f.d.mts +0 -15
  290. package/fjs/effects/eff/proof.f.mjs +0 -69
  291. package/fjs/effects/eff/types.d.ts +0 -71
  292. package/fjs/types/rtti/validate/module.f.d.mts +0 -41
  293. package/fjs/types/rtti/validate/module.f.mjs +0 -171
  294. package/fjs/types/rtti/validate/proof.f.d.mts +0 -125
  295. package/fjs/types/rtti/validate/proof.f.mjs +0 -437
  296. package/fjs/types/rtti/validate/types.d.ts +0 -6
package/fjs/module.f.mjs CHANGED
@@ -11,11 +11,10 @@ import { compile } from './djs/module.f.mjs'
11
11
  import { main as testMain } from './emergent_testing/module.f.mjs'
12
12
  import { commands as casCommands } from './cas/cli/module.f.mjs'
13
13
  import { main as ciMain } from './ci/module.f.mjs'
14
- import { import_ } from './effects/node/module.f.mjs'
14
+ import { errorExit, errorMessage, exitStep, import_ } from './effects/node/module.f.mjs'
15
15
  import { dispatch } from './cli/module.f.mjs'
16
16
  import { casMcpServer } from './mcp/module.f.mjs'
17
- import { pure, step } from './effects/module.f.mjs'
18
- import { unwrap } from './types/result/module.f.mjs'
17
+ import { resultStep } from './effects/module.f.mjs'
19
18
 
20
19
  /** @type {Commands<NodeOp>} */
21
20
  const commands = [
@@ -37,9 +36,17 @@ const commands = [
37
36
  {
38
37
  names: ['mcp', 'm'],
39
38
  description: 'Run an MCP server over stdio exposing the CAS and Evo (subjects/heads) as tools',
40
- handler: ({ home }) => step(
41
- casMcpServer(home),
42
- () => pure(0)),
39
+ // `exitStep`, not `resultStep(…, () => pureOk(0))`: the server's
40
+ // bootstrap can fail, and a continuation that ignores its result would
41
+ // report a server that never started as a clean exit.
42
+ //
43
+ // The types do *not* rule that out. `Program`'s exit code being a
44
+ // `Result` catches the old spelling — `() => pure(0)` hands back a bare
45
+ // number, which no longer fits — but `() => pureOk(0)` still compiles,
46
+ // because discarding a result you were handed is exactly what a
47
+ // continuation is allowed to do. This comment guards a mistake that is
48
+ // still available.
49
+ handler: ({ home }) => exitStep(casMcpServer(home)),
43
50
  },
44
51
  {
45
52
  names: ['ci', 'i'],
@@ -49,11 +56,25 @@ const commands = [
49
56
  {
50
57
  names: ['run', 'r'],
51
58
  description: 'Run a FunctionalScript module as a NodeProgram',
59
+ // Both ways this can fail are the command line, not a defect: the
60
+ // named file may not import, and a module that does import may export
61
+ // no `main`. Neither deserves a stack trace, so both are reported on
62
+ // `stderr` and exit `1` — the same answer an unknown command gets a
63
+ // few lines up, and the same one every other command now gives.
52
64
  handler: options => {
53
65
  const [file, ...args] = options.args
54
- return step(
66
+ return resultStep(
55
67
  import_(file),
56
- x => (/** @type {NodeProgram} */ (unwrap(x).main))({ ...options, args }))
68
+ r => {
69
+ if (r[0] === 'error') {
70
+ return errorExit(`${file}: ${errorMessage(r[1])}`)
71
+ }
72
+ const { main } = r[1]
73
+ if (typeof main !== 'function') {
74
+ return errorExit(`${file}: not a NodeProgram — no exported \`main\` function`)
75
+ }
76
+ return /** @type {NodeProgram} */ (main)({ ...options, args })
77
+ })
57
78
  },
58
79
  },
59
80
  ]
@@ -121,8 +121,8 @@ const eqProof = (() => {
121
121
  })
122
122
  /** @type {(c: EqCase) => readonly[string, () => void]} */
123
123
  const leaf = c => [c.name, () => {
124
- const a = /** @type {any} */(operand(c.a))
125
- const b = /** @type {any} */(operand(c.b))
124
+ const a = operand(c.a)
125
+ const b = operand(c.b)
126
126
  assertEq(a === b, c.eq, [a, c.eq ? '===' : '!==', b])
127
127
  assertEq(b === a, c.eq)
128
128
  }]
@@ -157,7 +157,7 @@ const jsOnly = {
157
157
  },
158
158
  throw: {
159
159
  toStringThrows: () => String({ toString: () => { throw 'Custom error' } }),
160
- toStringNotAFunction: () => String(/** @type {any} */({ toString: 'hello' })),
160
+ toStringNotAFunction: () => String({ toString: 'hello' }),
161
161
  toStringNotPrimitive: () => String({ toString: () => [] }),
162
162
  /** `throws` describes a case's outcome; it is not a value to build. */
163
163
  throwsIsNotAValue: () => value(() => ['throw']),
@@ -78,7 +78,7 @@ export const valueExpr = v => {
78
78
  case 'bigint': { return `bigint_any(${i64Literal(v)})` }
79
79
  }
80
80
  if (Array.isArray(v)) {
81
- const items = /** @type {readonly Value[]} */(v)
81
+ const items = v
82
82
  return items.length === 0
83
83
  ? 'Array::default().to_any()'
84
84
  : `[${items.map(valueExpr).join(', ')}].to_array().to_any()`
@@ -8,16 +8,16 @@
8
8
  *
9
9
  * @module
10
10
  *
11
+ * @import { IoChannel, Mkdir, NodeProgram, WriteFile } from '../../effects/node/types.ts'
11
12
  * @import { Effect } from '../../effects/types.ts'
12
- * @import { Mkdir, NodeProgram, WriteFile } from '../../effects/node/types.ts'
13
13
  */
14
+ import type { IoChannel, Mkdir, NodeProgram, WriteFile } from '../../effects/node/types.ts';
14
15
  import type { Effect } from '../../effects/types.ts';
15
- import type { Mkdir, NodeProgram, WriteFile } from '../../effects/node/types.ts';
16
16
  /**
17
17
  * Regenerates `nanvm-lib/tests/test/generated.rs` from the shared test data.
18
18
  *
19
- * @type {() => Effect<Mkdir | WriteFile, void>}
19
+ * @type {() => Effect<Mkdir | WriteFile, void, IoChannel>}
20
20
  */
21
- export declare const generateRustTests: () => Effect<Mkdir | WriteFile, void>;
21
+ export declare const generateRustTests: () => Effect<Mkdir | WriteFile, void, IoChannel>;
22
22
  /** @type {NodeProgram} */
23
23
  export declare const main: NodeProgram;
@@ -8,26 +8,25 @@
8
8
  *
9
9
  * @module
10
10
  *
11
+ * @import { IoChannel, Mkdir, NodeProgram, WriteFile } from '../../effects/node/types.ts'
11
12
  * @import { Effect } from '../../effects/types.ts'
12
- * @import { Mkdir, NodeProgram, WriteFile } from '../../effects/node/types.ts'
13
13
  */
14
14
 
15
- import { mapStep, step } from '../../effects/module.f.mjs'
16
- import { mkdir, writeUtf8File } from '../../effects/node/module.f.mjs'
17
- import { unwrap } from '../../types/result/module.f.mjs'
15
+
16
+ import { exitStep, mkdir, writeUtf8File } from '../../effects/node/module.f.mjs'
17
+ import { step } from '../../effects/module.f.mjs'
18
18
  import { data } from '../module.f.mjs'
19
19
  import { directory, generate, path } from '../rust/module.f.mjs'
20
20
 
21
21
  /**
22
22
  * Regenerates `nanvm-lib/tests/test/generated.rs` from the shared test data.
23
23
  *
24
- * @type {() => Effect<Mkdir | WriteFile, void>}
24
+ * @type {() => Effect<Mkdir | WriteFile, void, IoChannel>}
25
25
  */
26
26
  export const generateRustTests = () => {
27
- const directoryReady = mapStep(mkdir(directory, { recursive: true }), unwrap)
28
- const written = step(directoryReady, () => writeUtf8File(path, generate(data)))
29
- return mapStep(written, unwrap)
27
+ const directoryReady = mkdir(directory, { recursive: true })
28
+ return step(directoryReady, () => writeUtf8File(path, generate(data)))
30
29
  }
31
30
 
32
31
  /** @type {NodeProgram} */
33
- export const main = () => mapStep(generateRustTests(), () => 0)
32
+ export const main = () => exitStep(generateRustTests())
@@ -4,8 +4,9 @@
4
4
  * @module
5
5
  */
6
6
 
7
+ import { exitCode } from '../../effects/node/module.f.mjs'
7
8
  import { assert, assertEq } from '../../asserts/module.f.mjs'
8
- import { step } from '../../effects/module.f.mjs'
9
+ import { step as ioStep } from '../../effects/module.f.mjs'
9
10
  import { readUtf8File } from '../../effects/node/module.f.mjs'
10
11
  import {
11
12
  defaultNodeProgramOptions,
@@ -20,13 +21,13 @@ export const proof = {
20
21
  generateRustTests: () => {
21
22
  // The target directory does not exist in `emptyState`, so this also
22
23
  // covers the `mkdir` the writer does before the file write.
23
- const written = step(generateRustTests(), () => readUtf8File(path))
24
+ const written = ioStep(generateRustTests(), () => readUtf8File(path))
24
25
  const [, [tag, result]] = virtual(emptyState)(written)
25
26
  assert(tag === 'ok', result)
26
27
  assertEq(result, generate(data))
27
28
  },
28
29
  main: () => {
29
30
  const [, result] = virtual(emptyState)(main(defaultNodeProgramOptions))
30
- assertEq(result, 0)
31
+ assertEq(exitCode(result), 0)
31
32
  },
32
33
  }
package/fjs/proof.f.d.mts CHANGED
@@ -7,7 +7,7 @@ export declare const proof: {
7
7
  compileRequiresArgs: () => void;
8
8
  runModule: () => void;
9
9
  mcp: () => void;
10
- throw: {
11
- runImportError: () => void;
12
- };
10
+ mcpCorruptStore: () => void;
11
+ runImportError: () => void;
12
+ runNotANodeProgram: () => void;
13
13
  };
package/fjs/proof.f.mjs CHANGED
@@ -3,10 +3,12 @@
3
3
  * @import { Dir } from './effects/node/virtual/types.ts'
4
4
  */
5
5
 
6
+ import { exitCode } from './effects/node/module.f.mjs'
6
7
  import { assert, assertEq } from './asserts/module.f.mjs'
7
- import { pure } from './effects/module.f.mjs'
8
+ import { pureError, pureOk } from './effects/module.f.mjs'
8
9
  import { defaultNodeProgramOptions, emptyState, virtual } from './effects/node/virtual/module.f.mjs'
9
10
  import { main } from './module.f.mjs'
11
+ import { vec8 } from './types/bit_vec/module.f.mjs'
10
12
 
11
13
  /** @type {(args: readonly string[]) => NodeProgramOptions} */
12
14
  const makeOptions = args => ({ ...defaultNodeProgramOptions, args })
@@ -14,18 +16,20 @@ const makeOptions = args => ({ ...defaultNodeProgramOptions, args })
14
16
  const run = (/** @type {Dir} */ root) => (/** @type {readonly string[]} */ args) =>
15
17
  virtual({ ...emptyState, root })(main(makeOptions(args)))
16
18
 
19
+ // A program whose exit code is its argument count — non-zero, so it leaves
20
+ // through the error branch like any other failing program.
17
21
  /** @type {NodeProgram} */
18
- const appMain = ({ args }) => pure(args.length)
22
+ const appMain = ({ args }) => args.length === 0 ? pureOk(0) : pureError(args.length)
19
23
 
20
24
  export const proof = {
21
25
  help: () => {
22
26
  const [state, code] = run({})(['help'])
23
- assertEq(code, 0)
27
+ assertEq(exitCode(code), 0)
24
28
  assert(state.stdout.includes('compile'), 'expected command list in stdout')
25
29
  },
26
30
  compileRequiresArgs: () => {
27
31
  const [state, code] = run({})(['compile'])
28
- assertEq(code, 1)
32
+ assertEq(exitCode(code), 1)
29
33
  assert(state.stderr.length !== 0, 'expected error in stderr')
30
34
  },
31
35
  runModule: () => {
@@ -33,7 +37,7 @@ export const proof = {
33
37
  const root = { 'app.f.ts': () => ({ main: appMain }) }
34
38
  const [, code] = run(root)(['run', 'app.f.ts', 'x', 'y'])
35
39
  // `run` strips the command and file name, so `main` sees two arguments
36
- assertEq(code, 2)
40
+ assertEq(exitCode(code), 2)
37
41
  },
38
42
  mcp: () => {
39
43
  // stdin is empty in the virtual environment, so the server sees EOF
@@ -41,11 +45,33 @@ export const proof = {
41
45
  // The store is empty too, so `casMcpServer`'s Evo cache scan
42
46
  // (`initEvo`) also runs and finds nothing.
43
47
  const [, code] = run({})(['mcp'])
44
- assertEq(code, 0)
48
+ assertEq(exitCode(code), 0)
45
49
  },
46
- throw: {
47
- runImportError: () => {
48
- run({})(['run', 'missing.f.ts'])
49
- },
50
+ mcpCorruptStore: () => {
51
+ // The headline new error path, end to end: `.cas` exists but is a
52
+ // file, so `initEvo`'s scan cannot list it. The server never starts,
53
+ // and the failure travels out of the bootstrap to the command's
54
+ // `exitStep` — a message on stderr and exit 1, where it used to be a
55
+ // panic from inside `buildCache`.
56
+ const [state, code] = run({ '.cas': [vec8(0x2An)] })(['mcp'])
57
+ assertEq(exitCode(code), 1)
58
+ assert(state.stderr !== '', ['expected the storage error on stderr', state.stderr])
59
+ },
60
+ // A file that will not import is the user's command line, not a defect:
61
+ // it is reported with the name they typed and exits 1, where it used to
62
+ // panic out of the effect runner.
63
+ runImportError: () => {
64
+ const [state, code] = run({})(['run', 'missing.f.ts'])
65
+ assertEq(exitCode(code), 1)
66
+ assert(state.stderr.startsWith('missing.f.ts: '), state.stderr)
67
+ },
68
+ // The file imports but is not a program. Same answer, different reason —
69
+ // and the reason is the half of it worth saying.
70
+ runNotANodeProgram: () => {
71
+ /** @type {Dir} */
72
+ const root = { 'app.f.ts': () => ({ notMain: 1 }) }
73
+ const [state, code] = run(root)(['run', 'app.f.ts'])
74
+ assertEq(exitCode(code), 1)
75
+ assert(state.stderr.includes('not a NodeProgram'), state.stderr)
50
76
  },
51
77
  }
@@ -2,7 +2,7 @@
2
2
  * JSON-RPC 2.0 envelopes and a pure dispatcher.
3
3
  *
4
4
  * The envelopes are rtti schemas, so one declaration yields both a runtime
5
- * decoder (`validate(request)`) and the static type (`Ts<typeof request>`) — no
5
+ * decoder (`parse(request)`) and the static type (`Ts<typeof request>`) — no
6
6
  * drift between them. The dispatcher is pure: it maps an already-parsed request
7
7
  * value to a response value (or `null` for a notification) and performs no I/O.
8
8
  *
@@ -77,7 +77,7 @@ export declare const response: import("../../types/rtti/types.ts").Or<[{
77
77
  readonly id: import("../../types/rtti/types.ts").Or<[import("../../types/rtti/types.ts")._Type0<"string">, import("../../types/rtti/types.ts")._Type0<"number">, null]>;
78
78
  }]>;
79
79
  /** Decodes an untrusted value as a JSON-RPC request / notification. */
80
- export declare const decodeRequest: import("../../types/rtti/common/types.ts").Validate<{
80
+ export declare const decodeRequest: import("../../types/rtti/parse/types.ts").Parse<{
81
81
  readonly jsonrpc: "2.0";
82
82
  readonly method: import("../../types/rtti/types.ts")._Type0<"string">;
83
83
  readonly params: import("../../types/rtti/types.ts").Or<readonly [() => readonly ['or', typeof import("../../media/json/rtti/module.f.mjs").primitive, typeof import("../../media/json/rtti/module.f.mjs").object, typeof import("../../media/json/rtti/module.f.mjs").array], undefined]>;
@@ -2,7 +2,7 @@
2
2
  * JSON-RPC 2.0 envelopes and a pure dispatcher.
3
3
  *
4
4
  * The envelopes are rtti schemas, so one declaration yields both a runtime
5
- * decoder (`validate(request)`) and the static type (`Ts<typeof request>`) — no
5
+ * decoder (`parse(request)`) and the static type (`Ts<typeof request>`) — no
6
6
  * drift between them. The dispatcher is pure: it maps an already-parsed request
7
7
  * value to a response value (or `null` for a notification) and performs no I/O.
8
8
  *
@@ -20,7 +20,7 @@
20
20
 
21
21
  import { at } from '../../types/object/module.f.mjs'
22
22
  import { number, string, or, option } from '../../types/rtti/module.f.mjs'
23
- import { validate } from '../../types/rtti/validate/module.f.mjs'
23
+ import { parse } from '../../types/rtti/parse/module.f.mjs'
24
24
  import { unknown } from '../../media/json/rtti/module.f.mjs'
25
25
 
26
26
  export const jsonrpc = /** @type {const} */ ('2.0')
@@ -63,7 +63,7 @@ export const errorResponse = /** @type {const} */ ({ jsonrpc, error, id: _id })
63
63
  export const response = or(successResponse, errorResponse)
64
64
 
65
65
  /** Decodes an untrusted value as a JSON-RPC request / notification. */
66
- export const decodeRequest = validate(request)
66
+ export const decodeRequest = parse(request)
67
67
 
68
68
  /**
69
69
  * Builds an `RpcError` with the given `code` and `message` (no `data`).
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { assert, assertEq } from '../../asserts/module.f.mjs'
6
6
  import { ok, error } from '../../types/result/module.f.mjs'
7
- import { validate } from '../../types/rtti/validate/module.f.mjs'
7
+ import { parse } from '../../types/rtti/parse/module.f.mjs'
8
8
  import {
9
9
  error as errorSchema,
10
10
  decodeRequest,
@@ -44,9 +44,9 @@ export const proof = {
44
44
  notObject: () => assert(!isOk(decodeRequest(42))),
45
45
  },
46
46
  error: {
47
- ok: () => assert(isOk(validate(errorSchema)({ code: -1, message: 'x' }))),
48
- withData: () => assert(isOk(validate(errorSchema)({ code: -1, message: 'x', data: [1, 2] }))),
49
- missingMessage: () => assert(!isOk(validate(errorSchema)({ code: -1 }))),
47
+ ok: () => assert(isOk(parse(errorSchema)({ code: -1, message: 'x' }))),
48
+ withData: () => assert(isOk(parse(errorSchema)({ code: -1, message: 'x', data: [1, 2] }))),
49
+ missingMessage: () => assert(!isOk(parse(errorSchema)({ code: -1 }))),
50
50
  },
51
51
  },
52
52
  errors: {
@@ -7,7 +7,7 @@
7
7
  * - `tools/list` — advertise available tools
8
8
  * - `tools/call` — invoke a tool and return text content
9
9
  *
10
- * Each schema is both a runtime decoder (`validate(schema)`) and a static
10
+ * Each schema is both a runtime decoder (`parse(schema)`) and a static
11
11
  * TypeScript type (`Ts<typeof schema>`). Transport framing (stdio) and the
12
12
  * JSON-RPC dispatcher are in `fjs/protocol/json_rpc/module.f.mjs`.
13
13
  *
@@ -15,19 +15,15 @@
15
15
  *
16
16
  * @import { Unknown } from '../../media/json/types.ts'
17
17
  * @import { Ts } from '../../types/rtti/ts/types.ts'
18
- * @import { Operation, Effect } from '../../effects/types.ts'
18
+ * @import { Effect, Operation } from '../../effects/types.ts'
19
19
  * @import { Key, MemOp } from '../../effects/memory/types.ts'
20
20
  * @import { Response, Id, RpcError } from '../json_rpc/types.ts'
21
21
  * @import { Type } from '../../types/rtti/types.ts'
22
- * @import {
23
- * Implementation, ServerCapabilities, InitializeResult, Tool,
24
- * ToolsListParams, ToolsCallResult, McpHandlers, ToolEntry,
25
- * InitializedState, McpSessionState, McpConfig,
26
- * } from './types.ts'
22
+ * @import { Implementation, ServerCapabilities, InitializeResult, Tool, ToolsListParams, ToolsCallResult, McpHandlers, ToolEntry, McpSessionState, McpConfig } from './types.ts'
27
23
  */
28
24
  import type { Unknown } from '../../media/json/types.ts';
29
25
  import type { Ts } from '../../types/rtti/ts/types.ts';
30
- import type { Operation, Effect } from '../../effects/types.ts';
26
+ import type { Effect, Operation } from '../../effects/types.ts';
31
27
  import type { Key, MemOp } from '../../effects/memory/types.ts';
32
28
  import type { Response } from '../json_rpc/types.ts';
33
29
  import type { Type } from '../../types/rtti/types.ts';
@@ -162,10 +158,10 @@ export declare const toolsCallResult: {
162
158
  * @param {string} name - The tool name (used in `tools/call` requests)
163
159
  * @param {string} description - Human-readable description for `tools/list`
164
160
  * @param {T} inputRtti - Runtime type info for input validation
165
- * @param {(args: Ts<T>) => Effect<O, ToolsCallResult>} handle - Handler receiving validated arguments of type `Ts<inputRtti>`
161
+ * @param {(args: Ts<T>) => Effect<O, ToolsCallResult, never>} handle - Handler receiving validated arguments of type `Ts<inputRtti>`
166
162
  * @returns {ToolEntry<O>} A `ToolEntry` ready to be added to a registry
167
163
  */
168
- export declare const toolEntry: <T extends Type, O extends Operation>(name: string, description: string, inputRtti: T, handle: (args: Ts<T>) => Effect<O, ToolsCallResult>) => ToolEntry<O>;
164
+ export declare const toolEntry: <T extends Type, O extends Operation>(name: string, description: string, inputRtti: T, handle: (args: Ts<T>) => Effect<O, ToolsCallResult, never>) => ToolEntry<O>;
169
165
  /**
170
166
  * Helper to create a successful single-text-block tool result.
171
167
  *
@@ -200,12 +196,13 @@ export declare const notInitialized: import("../../types/rtti/ts/types.ts").Stru
200
196
  readonly data: import("../../types/rtti/types.ts").Or<readonly [() => readonly ['or', typeof import("../../media/json/rtti/module.f.mjs").primitive, typeof import("../../media/json/rtti/module.f.mjs").object, typeof import("../../media/json/rtti/module.f.mjs").array], undefined]>;
201
197
  }>;
202
198
  /** Initial session state — always start here. */
199
+ /** @type {McpSessionState} */
203
200
  export declare const uninitializedState: McpSessionState;
204
201
  /**
205
202
  * State-machine step for an MCP session using memory effects.
206
203
  *
207
204
  * Given configuration, handlers, and a memory key holding the session state,
208
- * returns a function `(value) => Effect<MemOp | O, Response | null>`.
205
+ * returns a function `(value) => Effect<MemOp | O, Response | null, never>`.
209
206
  *
210
207
  * Rules:
211
208
  * - `ping` returns an empty success regardless of session state; non-object
@@ -222,6 +219,6 @@ export declare const uninitializedState: McpSessionState;
222
219
  * to the handler; invalid params → -32602.
223
220
  *
224
221
  * @param {McpConfig} config
225
- * @returns {<O extends Operation>(handlers: McpHandlers<O>) => (stateKey: Key<McpSessionState>) => (value: Unknown) => Effect<MemOp | O, Response | null>}
222
+ * @returns {<O extends Operation>(handlers: McpHandlers<O>) => (stateKey: Key<McpSessionState>) => (value: Unknown) => Effect<MemOp | O, Response | null, never>}
226
223
  */
227
- export declare const mcpStep: ({ protocolVersion, capabilities, serverInfo, }: McpConfig) => <O extends Operation>(handlers: McpHandlers<O>) => (stateKey: Key<McpSessionState>) => (value: Unknown) => Effect<MemOp | O, Response | null>;
224
+ export declare const mcpStep: ({ protocolVersion, capabilities, serverInfo, }: McpConfig) => <O extends Operation>(handlers: McpHandlers<O>) => (stateKey: Key<McpSessionState>) => (value: Unknown) => Effect<MemOp | O, Response | null, never>;