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
@@ -4,11 +4,32 @@
4
4
  *
5
5
  * @module
6
6
  */
7
- import type { Operation, Effect } from '../../effects/types.ts';
7
+ import type { Effect, NotImplemented, Operation } from '../../effects/types.ts';
8
8
  import type { MemOp } from '../../effects/memory/types.ts';
9
- import type { Result } from '../../types/result/types.ts';
10
9
  import type { StringMap } from '../../types/object/types.ts';
11
- import type { LockMap } from '../../media/revision/types.ts';
10
+ import type { LockField } from '../../media/revision/types.ts';
11
+ /**
12
+ * A revision was rejected on its own terms: a parent that does not resolve, a
13
+ * hash that is not cBase32, a blob that holds something other than a
14
+ * `vnd.fjs.revision`, a store that would not take the write.
15
+ *
16
+ * A tagged tuple rather than a bare `string` so it joins {@link NotImplemented}
17
+ * and `IoError` as a discriminated union rather than a structural one — a
18
+ * renderer switches on the tag it already switches on, instead of testing
19
+ * `typeof`.
20
+ */
21
+ export type EvoError = readonly ['evoError', string];
22
+ /**
23
+ * The error channel of the Evo API: the revision was rejected, or the runner
24
+ * could not dispatch an operation.
25
+ *
26
+ * Host IO failures do **not** appear here as `IoError`. A store that cannot be
27
+ * read or written is reported as an {@link EvoError} whose message says so,
28
+ * because from this API's outside a blob that cannot be delivered and a blob
29
+ * that is not a revision are the same answer — "no revision at that hash" —
30
+ * and the caller has the same recourse to both.
31
+ */
32
+ export type EvoChannel = EvoError | NotImplemented;
12
33
  /** A cBase32 content hash, as accepted/returned by `Cas<O>`. */
13
34
  export type Hash = string;
14
35
  /** The identity of a mutable object whose revisions are being evolved. */
@@ -38,6 +59,12 @@ export type Subject = string;
38
59
  * - `generation` — input: **ignored**, {@link computeGeneration} derives the
39
60
  * authoritative value from the parents; output: always present. It exists as
40
61
  * an input field only so a read value round-trips into `add` as-is.
62
+ * - `lock` — the format's own field, so it is an inline map or the hash of a
63
+ * `vnd.fjs.lock` blob (`fjs/media/lock`) holding one. Both directions
64
+ * validate and canonicalize every hash it names — the reference itself, or
65
+ * each direct value at every depth of a map. Following a reference is not
66
+ * done here: evo stores and reads revisions, it does not resolve
67
+ * dependencies.
41
68
  *
42
69
  * Relaxing what the format requires is the point, not an oversight. The stored
43
70
  * `vnd.fjs.revision` blob requires `subject`, `snapshot` and `generation`, and
@@ -58,7 +85,7 @@ export type RevisionData = {
58
85
  readonly subject?: Subject | undefined;
59
86
  readonly archived?: true | undefined;
60
87
  readonly generation?: number | undefined;
61
- readonly lock?: LockMap | undefined;
88
+ readonly lock?: LockField | undefined;
62
89
  };
63
90
  /**
64
91
  * Per-subject bookkeeping: every revision hash seen for the subject, every
@@ -94,11 +121,20 @@ export type Evo<O extends Operation> = {
94
121
  * adding it later is a compatible extension of this parameter, while
95
122
  * removing it would not be.
96
123
  */
97
- readonly list: (archived?: true) => Effect<MemOp, readonly Subject[]>;
124
+ readonly list: (archived?: true) => Effect<MemOp, readonly Subject[], NotImplemented>;
98
125
  /** Returns the current head hashes of `subject` (empty if unknown). */
99
- readonly head: (subject: Subject) => Effect<MemOp, readonly Hash[]>;
100
- /** Adds a new head; see {@link addRevision}. */
101
- readonly add: (input: RevisionData) => Effect<O | MemOp, Result<Hash, string>>;
126
+ readonly head: (subject: Subject) => Effect<MemOp, readonly Hash[], NotImplemented>;
127
+ /**
128
+ * Adds a new head; see {@link addRevision}.
129
+ *
130
+ * A rejected revision and an undispatchable operation are both failures and
131
+ * share the channel, as {@link EvoChannel}'s two cases. They stay tellable
132
+ * apart — that is what the tags are for, and a caller that renders them
133
+ * differently switches on one — but they do not need separate *layers* to
134
+ * be told apart, and giving them separate layers costs every intermediate
135
+ * step a hand-written short-circuit that `step` would otherwise do.
136
+ */
137
+ readonly add: (input: RevisionData) => Effect<O | MemOp, Hash, EvoChannel>;
102
138
  /**
103
139
  * The revision at `hash`, decoded, validated, and canonicalized; see
104
140
  * {@link readRevision}. Served from the store today, so the `MemOp` in the
@@ -107,5 +143,5 @@ export type Evo<O extends Operation> = {
107
143
  * operations read, which must not become a breaking change to this type
108
144
  * when it happens.
109
145
  */
110
- readonly revision: (hash: Hash) => Effect<O | MemOp, Result<RevisionData, string>>;
146
+ readonly revision: (hash: Hash) => Effect<O | MemOp, RevisionData, EvoChannel>;
111
147
  };
@@ -5,24 +5,19 @@
5
5
  *
6
6
  * @import { Sha2, State as Sha2State } from '../crypto/sha2/types.ts'
7
7
  * @import { Vec } from '../types/bit_vec/types.ts'
8
- * @import { Effect, Operation } from '../effects/types.ts'
9
- * @import {
10
- * IoResult,
11
- * Now,
12
- * RandomInt,
13
- * ReadBytes,
14
- * Readdir,
15
- * Rm,
16
- * } from '../effects/node/types.ts'
8
+ * @import { Operation } from '../effects/types.ts'
9
+ * @import { Effect, NotImplemented } from '../effects/types.ts'
10
+ * @import { IoChannel, Now, RandomInt, ReadBytes, Readdir, Rm } from '../effects/node/types.ts'
17
11
  * @import { List } from '../effects/list/types.ts'
18
12
  * @import { Cas, FileCas, FileCasOperation } from './types.ts'
19
13
  */
20
14
  import type { Sha2 } from '../crypto/sha2/types.ts';
21
15
  import type { Vec } from '../types/bit_vec/types.ts';
22
- import type { Effect, Operation } from '../effects/types.ts';
23
- import type { IoResult, ReadBytes } from '../effects/node/types.ts';
16
+ import type { Operation } from '../effects/types.ts';
17
+ import type { Effect } from '../effects/types.ts';
18
+ import type { IoChannel, ReadBytes } from '../effects/node/types.ts';
24
19
  import type { List } from '../effects/list/types.ts';
25
- import type { Cas, FileCas, FileCasOperation } from './types.ts';
20
+ import type { Cas, FileCas } from './types.ts';
26
21
  /** Converts a content key to its sharded relative CAS file path.
27
22
  *
28
23
  * @type {(key: Vec) => string}
@@ -31,17 +26,16 @@ export declare const toPath: (key: Vec) => string;
31
26
  /**
32
27
  * Drains a `Cas<O>.read` chunk stream into a single `Vec`. Used by any caller
33
28
  * that needs the whole blob at once (an MCP `content: true` fetch, an Evo
34
- * revision decode): the chunk stream is concatenated and an error item is
35
- * surfaced as the result. A single `Vec` cannot exceed `maxLength` bits;
36
- * concatenating past it would overflow the runtime's `bigint` constraint, so
37
- * that case is surfaced as an error item too, rather than crashing the
38
- * process.
29
+ * revision decode): the chunk stream is concatenated, and a stream that fails
30
+ * fails this. A single `Vec` cannot exceed `maxLength` bits; concatenating past
31
+ * it would overflow the runtime's `bigint` constraint, so that case fails here
32
+ * too rather than crashing the process.
39
33
  *
40
34
  * @template {Operation} O
41
- * @param {List<O, IoResult<Vec>>} stream
42
- * @returns {Effect<O, IoResult<Vec>>}
35
+ * @param {List<O, Vec, IoChannel>} stream
36
+ * @returns {Effect<O, Vec, IoChannel>}
43
37
  */
44
- export declare const collectRead: <O extends Operation>(stream: List<O, IoResult<Vec>>) => Effect<O, IoResult<Vec>>;
38
+ export declare const collectRead: <O extends Operation>(stream: List<O, Vec, IoChannel>) => Effect<O, Vec, IoChannel>;
45
39
  /**
46
40
  * Builds a content-addressable storage facade from a SHA-2 implementation.
47
41
  *
@@ -50,19 +44,11 @@ export declare const collectRead: <O extends Operation>(stream: List<O, IoResult
50
44
  export declare const fileCas: (sha2: Sha2) => (path: string) => FileCas;
51
45
  /**
52
46
  * Streams the file at `path` through `cas.write`, returning the content hash.
53
- * Both the CLI `cas add` and the MCP `add` delegate to this; the MCP layer
54
- * additionally deletes the source file on success.
47
+ * Its one consumer is the CLI's `cas add`; the MCP `cas_add` tool takes inline
48
+ * content and calls `write` itself, so it does not come through here.
55
49
  *
56
50
  * @template {Operation} O
57
51
  * @param {Cas<O>} cas
58
- * @returns {(path: string) => Effect<O | ReadBytes, IoResult<Vec>>}
52
+ * @returns {(path: string) => Effect<O | ReadBytes, Vec, IoChannel>}
59
53
  */
60
- export declare const casAddFile: <O extends Operation>(cas: Cas<O>) => (path: string) => Effect<O | ReadBytes, IoResult<Vec>>;
61
- /**
62
- * Upload pipeline: streams `fileName` from `~/cas_upload/` through `casAddFile`,
63
- * then deletes the source on success. On failure the source is left in place so
64
- * the upload can be retried; `write` already cleans up its own partial staging file.
65
- *
66
- * @type {(home: string) => (fileName: string) => Effect<FileCasOperation, IoResult<Vec>>}
67
- */
68
- export declare const casUpload: (home: string) => (fileName: string) => Effect<FileCasOperation, IoResult<Vec>>;
54
+ export declare const casAddFile: <O extends Operation>(cas: Cas<O>) => (path: string) => Effect<O | ReadBytes, Vec, IoChannel>;
@@ -5,28 +5,33 @@
5
5
  *
6
6
  * @import { Sha2, State as Sha2State } from '../crypto/sha2/types.ts'
7
7
  * @import { Vec } from '../types/bit_vec/types.ts'
8
- * @import { Effect, Operation } from '../effects/types.ts'
9
- * @import {
10
- * IoResult,
11
- * Now,
12
- * RandomInt,
13
- * ReadBytes,
14
- * Readdir,
15
- * Rm,
16
- * } from '../effects/node/types.ts'
8
+ * @import { Operation } from '../effects/types.ts'
9
+ * @import { Effect, NotImplemented } from '../effects/types.ts'
10
+ * @import { IoChannel, Now, RandomInt, ReadBytes, Readdir, Rm } from '../effects/node/types.ts'
17
11
  * @import { List } from '../effects/list/types.ts'
18
12
  * @import { Cas, FileCas, FileCasOperation } from './types.ts'
19
13
  */
20
14
 
21
- import { sha256 } from '../crypto/sha2/module.f.mjs'
22
15
  import { join, normalize, parse } from '../path/module.f.mjs'
23
16
  import { empty, length, maxLength, maxLengthBytes, msb, vec } from '../types/bit_vec/module.f.mjs'
24
17
  import { cBase32ToVec, vecToCBase32 } from '../basen/cbase32/module.f.mjs'
25
- import { foldStep, forEachStep, history, historyStep, okStep, pure, step } from '../effects/module.f.mjs'
26
- import { eff } from '../effects/eff/module.f.mjs'
18
+ import {
19
+ catchStep,
20
+ foldStep,
21
+ forEachStep,
22
+ history,
23
+ historyStep,
24
+ mapStep as ioMapStep,
25
+ pureError,
26
+ pureOk,
27
+ resultMapStep,
28
+ resultStep,
29
+ step as ioStep,
30
+ } from '../effects/module.f.mjs'
27
31
  import {
28
32
  access,
29
33
  createExclusive,
34
+ ioError,
30
35
  isNotFound,
31
36
  mkdir,
32
37
  now,
@@ -39,7 +44,7 @@ import {
39
44
  writeBytes,
40
45
  } from '../effects/node/module.f.mjs'
41
46
  import { toOption } from '../types/nullable/module.f.mjs'
42
- import { error, ok, unwrap } from '../types/result/module.f.mjs'
47
+ import { error, ok } from '../types/result/module.f.mjs'
43
48
  import { splitAt } from '../types/string/module.f.mjs'
44
49
  import { nonEmpty, empty as elEmpty } from '../effects/list/module.f.mjs'
45
50
 
@@ -61,31 +66,26 @@ export const toPath = key => {
61
66
  /**
62
67
  * Drains a `Cas<O>.read` chunk stream into a single `Vec`. Used by any caller
63
68
  * that needs the whole blob at once (an MCP `content: true` fetch, an Evo
64
- * revision decode): the chunk stream is concatenated and an error item is
65
- * surfaced as the result. A single `Vec` cannot exceed `maxLength` bits;
66
- * concatenating past it would overflow the runtime's `bigint` constraint, so
67
- * that case is surfaced as an error item too, rather than crashing the
68
- * process.
69
+ * revision decode): the chunk stream is concatenated, and a stream that fails
70
+ * fails this. A single `Vec` cannot exceed `maxLength` bits; concatenating past
71
+ * it would overflow the runtime's `bigint` constraint, so that case fails here
72
+ * too rather than crashing the process.
69
73
  *
70
74
  * @template {Operation} O
71
- * @param {List<O, IoResult<Vec>>} stream
72
- * @returns {Effect<O, IoResult<Vec>>}
75
+ * @param {List<O, Vec, IoChannel>} stream
76
+ * @returns {Effect<O, Vec, IoChannel>}
73
77
  */
74
78
  export const collectRead = stream => {
75
- /** @type {(acc: Vec) => (s: List<O, IoResult<Vec>>) => Effect<O, IoResult<Vec>>} */
79
+ /** @type {(acc: Vec) => (s: List<O, Vec, IoChannel>) => Effect<O, Vec, IoChannel>} */
76
80
  const loop = acc => s =>
77
- eff(s)
78
- .step((/** @type {*} */ node) => {
79
- if (node === undefined) { return pure(ok(acc)) }
80
- const { first, tail } = node
81
- const [t, v] = first
82
- if (t === 'error') { return pure(first) }
83
- if (length(acc) + length(v) > maxLength) {
84
- return pure(error(`cas blob exceeds maximum vector length of ${maxLength} bits`))
85
- }
86
- return loop(msb.concat(acc)(v))(tail)
87
- })
88
- .value
81
+ ioStep(s, node => {
82
+ if (node === undefined) { return pureOk(acc) }
83
+ const { first, tail } = node
84
+ if (length(acc) + length(first) > maxLength) {
85
+ return pureError(ioError({ message: `cas blob exceeds maximum vector length of ${maxLength} bits` }))
86
+ }
87
+ return loop(msb.concat(acc)(first))(tail)
88
+ })
89
89
  return loop(empty)(stream)
90
90
  }
91
91
 
@@ -129,25 +129,34 @@ const deadlineOf = name => Number(name.slice(0, name.indexOf('-')))
129
129
  * still-live lease is left alone; the fencing rename keeps even a misjudged
130
130
  * reclaim fail-safe (worst case: that upload restarts).
131
131
  *
132
- * @template {Now | Readdir | Rm} O
133
- * @param {string} stageDir
134
- * @returns {Effect<O, void>}
132
+ * The error channel is `never`, and that is the claim this function makes: it
133
+ * catches every failure it can produce, so an upload composing it cannot fail
134
+ * because of a sweep.
135
+ *
136
+ * @type {(stageDir: string) => Effect<Now | Readdir | Rm, void, never>}
135
137
  */
136
- const gcStage = stageDir =>
137
- eff(now())
138
- .step(() => readdir(stageDir, {}))
139
- .step(([k, v], t) => {
140
- if (k === 'error') { return pure(undefined) }
141
- const expired = v.flatMap(d =>
138
+ const gcStage = stageDir => {
139
+ // The `readdir` result and the `now()` timestamp are both needed by the last
140
+ // link, so the timestamp is carried forward in a history rather than closed
141
+ // over by a nested continuation.
142
+ const listed = historyStep(
143
+ history(now()),
144
+ () => readdir(stageDir, {}))
145
+ const swept = ioStep(
146
+ listed,
147
+ ([dirents, t]) => {
148
+ const expired = dirents.flatMap(d =>
142
149
  d.isFile && deadlineOf(d.name) < t ? [d.name] : [])
150
+ // Each `rm` recovers on its own, so one undeletable file does not
151
+ // stop the sweep at the file before it.
143
152
  return forEachStep(
144
- pure(expired),
145
- name =>
146
- eff(rm(join(stageDir, name)))
147
- .step(() => pure(undefined))
148
- .value)
153
+ pureOk(expired),
154
+ name => catchStep(rm(join(stageDir, name)), () => pureOk(undefined)))
149
155
  })
150
- .value
156
+ // A fresh store has no `_stage/` yet, and a sweep that cannot run must not
157
+ // fail the upload it is piggy-backed on.
158
+ return catchStep(swept, () => pureOk(undefined))
159
+ }
151
160
 
152
161
  // Lock-free staging upload (plan/staging-lease.md): stream each chunk straight
153
162
  // to a `_stage/<deadline>-<rand>` file via `writeBytes` while folding it into the
@@ -162,83 +171,86 @@ const gcStage = stageDir =>
162
171
  * @param {Sha2} sha2
163
172
  * @param {string} path
164
173
  * @param {string} stageDir
165
- * @param {List<O1, IoResult<Vec>>} payload
166
- * @returns {Effect<O1 | FileCasOperation, IoResult<Vec>>}
174
+ * @param {List<O1, Vec, IoChannel>} payload
175
+ * @returns {Effect<O1 | FileCasOperation, Vec, IoChannel>}
167
176
  */
168
177
  const writeImpl = (sha2, path, stageDir, payload) => {
169
178
  // Publish the finished staging file to its content-addressed shard. The three
170
179
  // filesystem steps run best-effort with their results ignored; success is decided
171
180
  // afterward by observing the target's size (see staging-lease.md "Publish ignores
172
181
  // results and checks the end state").
173
- /** @type {(state: Sha2State, offset: number, curPath: string) => Effect<FileCasOperation, IoResult<Vec>>} */
182
+ /** @type {(state: Sha2State, offset: number, curPath: string) => Effect<FileCasOperation, Vec, IoChannel>} */
174
183
  const publish = (state, offset, curPath) => {
175
184
  const hash = sha2.end(state)
176
185
  const rel = toPath(hash)
177
186
  const dst = join(path, rel)
178
187
  const dstDir = join(path, ...parse(rel).slice(0, -1))
179
- return eff(mkdir(dstDir, { recursive: true }))
180
- .step(() => rename(curPath, dst))
181
- .step(() => rm(curPath))
182
- .step(() => stat(dst))
183
- .step(st => pure(st[0] === 'ok' && st[1].size === offset ? ok(hash) : error('publish size mismatch')))
184
- .value
188
+ // `resultStep` throughout, and that is the "ignores results" above
189
+ // written in the type: each link runs whatever the previous one
190
+ // answered, and only the closing `stat` decides the outcome.
191
+ const created = resultStep(mkdir(dstDir, { recursive: true }), () => rename(curPath, dst))
192
+ const removed = resultStep(created, () => rm(curPath))
193
+ const stated = resultStep(removed, () => stat(dst))
194
+ return resultMapStep(
195
+ stated,
196
+ st => st[0] === 'ok' && st[1].size === offset ? ok(hash) : error(ioError({ message: 'publish size mismatch' })))
185
197
  }
186
198
  // Any streaming error fails closed: delete the partial file, return the error.
187
- /** @type {(curPath: string, e: unknown) => Effect<FileCasOperation, IoResult<Vec>>} */
199
+ /** @type {(curPath: string, e: IoChannel) => Effect<FileCasOperation, Vec, IoChannel>} */
188
200
  const fail = (curPath, e) =>
189
- eff(rm(curPath))
190
- .step(() => pure(error(e)))
191
- .value
192
- return eff(gcStage(stageDir)).step(() =>
193
- eff(random256).step(rnd => {
194
- const rndStr = vecToCBase32(rnd)
195
- /** @type {(state: Sha2State, offset: number, curPath: string) => (stream: List<O1, IoResult<Vec>>) => Effect<O1 | FileCasOperation, IoResult<Vec>>} */
196
- const loop = (state, offset, curPath) =>
197
- stream =>
198
- eff(stream)
199
- .step((node) => {
200
- if (node === undefined) {
201
- return publish(state, offset, curPath)
202
- }
203
- const { first, tail } = node
204
- if (first[0] === 'error') {
205
- return fail(curPath, first[1])
206
- }
207
- const chunk = first[1]
208
- return eff(writeBytes(curPath, offset, chunk))
209
- .step(wb => {
210
- if (wb[0] === 'error') { return fail(curPath, wb[1]) }
211
- const newState = sha2.append(chunk)(state)
212
- const newOffset = offset + Number(length(chunk) / 8n)
213
- // Renew the lease: rename to a fresh deadline (keeps `delta` constant).
214
- // The new path is still needed after the rename, to recurse with,
215
- // so the rename captures it rather than closing over it.
216
- const nextPath = step(
217
- now(),
218
- t => pure(join(stageDir, stageName(t + leaseDelta, rndStr))))
219
- const renamed = historyStep(
220
- history(nextPath),
221
- next => rename(curPath, next))
222
- return step(
223
- renamed,
224
- ([[rt, v], next]) =>
225
- rt === 'error'
226
- ? fail(curPath, v)
227
- : loop(newState, newOffset, next)(tail))
228
- })
229
- .value
230
- })
231
- .value
232
- return eff(mkdir(stageDir, { recursive: true }))
233
- .step(() => now())
234
- .step(t0 => {
235
- const path0 = join(stageDir, stageName(t0 + leaseDelta, rndStr))
236
- return eff(createExclusive(path0))
237
- .step(okStep(() => loop(sha2.init, 0, path0)(payload)))
238
- .value
201
+ // The cleanup's own outcome is discarded on purpose: `e` is what the
202
+ // caller needs to hear, and a failed `rm` has no better answer.
203
+ resultMapStep(rm(curPath), () => error(e))
204
+ const rndEffect = ioStep(gcStage(stageDir), () => random256)
205
+ return ioStep(rndEffect, rnd => {
206
+ const rndStr = vecToCBase32(rnd)
207
+ /** @type {(state: Sha2State, offset: number, curPath: string) => (stream: List<O1, Vec, IoChannel>) => Effect<O1 | FileCasOperation, Vec, IoChannel>} */
208
+ const loop = (state, offset, curPath) =>
209
+ stream =>
210
+ // `resultStep`, not `step`: a stream that fails must still be
211
+ // cleaned up after, so this handles the failure rather than
212
+ // letting it propagate past the partial file.
213
+ resultStep(stream, r => {
214
+ if (r[0] === 'error') {
215
+ return fail(curPath, r[1])
216
+ }
217
+ const node = r[1]
218
+ if (node === undefined) {
219
+ return publish(state, offset, curPath)
220
+ }
221
+ const { first: chunk, tail } = node
222
+ // Both branches matter: a failed write is cleaned up after,
223
+ // rather than propagated with the partial file left behind.
224
+ return resultStep(writeBytes(curPath, offset, chunk), wb => {
225
+ if (wb[0] === 'error') { return fail(curPath, wb[1]) }
226
+ const newState = sha2.append(chunk)(state)
227
+ const newOffset = offset + Number(length(chunk) / 8n)
228
+ // Renew the lease: rename to a fresh deadline (keeps `delta` constant).
229
+ // The new path is still needed after the rename, to recurse with,
230
+ // so the rename captures it rather than closing over it.
231
+ const nextPath = ioMapStep(
232
+ now(),
233
+ t => join(stageDir, stageName(t + leaseDelta, rndStr)))
234
+ const renamed = historyStep(
235
+ history(nextPath),
236
+ next => rename(curPath, next))
237
+ return resultStep(
238
+ renamed,
239
+ r => {
240
+ if (r[0] === 'error') { return fail(curPath, r[1]) }
241
+ const [, next] = r[1]
242
+ return loop(newState, newOffset, next)(tail)
243
+ })
244
+ })
239
245
  })
240
- .value
241
- }).value).value
246
+ const started = ioStep(mkdir(stageDir, { recursive: true }), () => now())
247
+ return ioStep(started, t0 => {
248
+ const path0 = join(stageDir, stageName(t0 + leaseDelta, rndStr))
249
+ return ioStep(
250
+ createExclusive(path0),
251
+ () => loop(sha2.init, 0, path0)(payload))
252
+ })
253
+ })
242
254
  }
243
255
 
244
256
  /**
@@ -253,44 +265,41 @@ export const fileCas = sha2 => path => {
253
265
  return {
254
266
  read: hash => {
255
267
  const p = join(path, toPath(hash))
256
- /** @type {(offset: number) => List<FileCasOperation, IoResult<Vec>>} */
268
+ /** @type {(offset: number) => List<FileCasOperation, Vec, IoChannel>} */
257
269
  const loop = offset =>
258
- eff(readBytes(p, offset, chunkBytes))
259
- .step(/** @type {(result: IoResult<Vec>) => List<FileCasOperation, IoResult<Vec>>} */ (result) => {
260
- const [t, v] = result
261
- // A missing shard or read error is an explicit error item, never EOF.
262
- if (t === 'error') {
263
- return nonEmpty(result, elEmpty())
264
- }
265
- // End the stream only on an empty read; every non-empty read — including a
266
- // final short (`< CHUNK_BYTES`) chunk — is emitted as an `ok` item.
267
- return length(v) === 0n
268
- ? elEmpty()
269
- : nonEmpty(ok(v), loop(offset + chunkBytes))
270
- })
271
- .value
270
+ // A missing shard or read error fails the stream, and `step`
271
+ // propagates it the cell's own failure can never be mistaken
272
+ // for the `undefined` that ends one.
273
+ ioStep(
274
+ readBytes(p, offset, chunkBytes),
275
+ // End the stream only on an empty read; every non-empty read — including a
276
+ // final short (`< CHUNK_BYTES`) chunk — is emitted as a cell.
277
+ chunk => length(chunk) === 0n
278
+ ? elEmpty()
279
+ : nonEmpty(chunk, loop(offset + chunkBytes)))
272
280
  return loop(0)
273
281
  },
274
282
  write: payload => writeImpl(sha2, path, stageDir, payload),
275
283
  list: () =>
276
284
  // A fresh store has no `.cas` directory yet. Treat *only* that case as an
277
- // empty store, mirroring how `read` maps a missing shard to an error item.
285
+ // empty store, mirroring how `read` fails a stream on a missing shard.
278
286
  // A `.cas` that exists but cannot be read (permissions, corruption) is a
279
287
  // genuine storage error and is surfaced, not masked as "no hashes".
280
- eff(access(storePrefix))
281
- .step(a => {
282
- if (a[0] === 'error') {
283
- if (isNotFound(a[1])) { return pure(/** @type {readonly Vec[]} */ ([])) }
284
- throw a[1]
285
- }
286
- return eff(readdir(storePrefix, { recursive: true }))
287
- .step(r => pure(unwrap(r).flatMap(({ name, parentPath, isFile }) =>
288
+ //
289
+ // `resultStep` because both branches genuinely matter: the absent
290
+ // store is a success answering `ok([])`, and every other failure is
291
+ // the caller's to see. It used to `throw` here, which is what the
292
+ // paragraph above always meant by "surfaced" but could not say
293
+ // while the return type had no error channel to say it in.
294
+ resultStep(access(storePrefix), a =>
295
+ a[0] === 'error'
296
+ ? isNotFound(a[1]) ? pureOk([]) : pureError(a[1])
297
+ : ioMapStep(
298
+ readdir(storePrefix, { recursive: true }),
299
+ r => r.flatMap(({ name, parentPath, isFile }) =>
288
300
  toOption(isFile
289
301
  ? cBase32ToVec(normalize(parentPath).substring(normalizedStorePrefix.length).replaceAll('/', '') + name)
290
- : null))))
291
- .value
292
- })
293
- .value,
302
+ : null)))),
294
303
  url: hash =>
295
304
  join(path, toPath(hash))
296
305
  }
@@ -298,46 +307,41 @@ export const fileCas = sha2 => path => {
298
307
 
299
308
  /** 256-bit random `Vec` built from 8 sequential `randomInt` (32-bit) calls.
300
309
  *
301
- * @type {Effect<RandomInt, Vec>}
310
+ * @type {Effect<RandomInt, Vec, NotImplemented>}
302
311
  */
303
312
  const random256 =
304
313
  foldStep(
305
- pure([0, 1, 2, 3, 4, 5, 6, 7]),
314
+ pureOk([0, 1, 2, 3, 4, 5, 6, 7]),
306
315
  empty,
307
316
  () => (/** @type {Vec} */ acc) =>
308
- eff(randomInt())
309
- .step(r => pure(msb.concat(acc)(vec(32n)(BigInt(r)))))
310
- .value)
317
+ ioMapStep(randomInt(), r => msb.concat(acc)(vec(32n)(BigInt(r)))))
311
318
 
312
- /** Streams any file at `filePath` in `<=128 KiB` chunks as a `ListEffect` of `ok` items.
319
+ /** Streams any file at `filePath` in `<=128 KiB` chunks.
320
+ *
321
+ * A failed read fails the stream. It used to be yielded as an error *item*
322
+ * followed by an explicit empty tail — a tail no consumer would ever pull.
313
323
  *
314
- * @type {(filePath: string) => List<ReadBytes, IoResult<Vec>>}
324
+ * @type {(filePath: string) => List<ReadBytes, Vec, IoChannel>}
315
325
  */
316
326
  const streamFile = filePath => {
317
- /** @type {(offset: number) => List<ReadBytes, IoResult<Vec>>} */
327
+ /** @type {(offset: number) => List<ReadBytes, Vec, IoChannel>} */
318
328
  const loop = offset =>
319
- eff(readBytes(filePath, offset, chunkBytes))
320
- .step(/** @type {(result: IoResult<Vec>) => List<ReadBytes, IoResult<Vec>>} */ (result) => {
321
- if (result[0] === 'error') {
322
- return nonEmpty(result, elEmpty())
323
- }
324
- const chunk = result[1]
325
- return length(chunk) === 0n
326
- ? elEmpty()
327
- : nonEmpty(ok(chunk), loop(offset + chunkBytes))
328
- })
329
- .value
329
+ ioStep(
330
+ readBytes(filePath, offset, chunkBytes),
331
+ chunk => length(chunk) === 0n
332
+ ? elEmpty()
333
+ : nonEmpty(chunk, loop(offset + chunkBytes)))
330
334
  return loop(0)
331
335
  }
332
336
 
333
337
  /**
334
338
  * Streams the file at `path` through `cas.write`, returning the content hash.
335
- * Both the CLI `cas add` and the MCP `add` delegate to this; the MCP layer
336
- * additionally deletes the source file on success.
339
+ * Its one consumer is the CLI's `cas add`; the MCP `cas_add` tool takes inline
340
+ * content and calls `write` itself, so it does not come through here.
337
341
  *
338
342
  * @template {Operation} O
339
343
  * @param {Cas<O>} cas
340
- * @returns {(path: string) => Effect<O | ReadBytes, IoResult<Vec>>}
344
+ * @returns {(path: string) => Effect<O | ReadBytes, Vec, IoChannel>}
341
345
  */
342
346
  export const casAddFile = cas => path =>
343
347
  // streamFile produces only ReadBytes effects. TypeScript can't prove ListEffect<ReadBytes,T>
@@ -345,19 +349,3 @@ export const casAddFile = cas => path =>
345
349
  // caller passes a Cas<O> where ReadBytes ⊆ O (e.g. FileCasOperation).
346
350
  cas.write(streamFile(path))
347
351
 
348
- /**
349
- * Upload pipeline: streams `fileName` from `~/cas_upload/` through `casAddFile`,
350
- * then deletes the source on success. On failure the source is left in place so
351
- * the upload can be retried; `write` already cleans up its own partial staging file.
352
- *
353
- * @type {(home: string) => (fileName: string) => Effect<FileCasOperation, IoResult<Vec>>}
354
- */
355
- export const casUpload = home => fileName => {
356
- const src = join(home, 'cas_upload', fileName)
357
- const c = fileCas(sha256)(home)
358
- return eff(casAddFile(c)(src))
359
- .step(okStep(/** @type {(v: Vec) => Effect<Rm, IoResult<Vec>>} */ (v => eff(rm(src))
360
- .step(() => pure(ok(v)))
361
- .value)))
362
- .value
363
- }