functionalscript 0.45.0 → 0.46.1

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/rtti/validate/module.f.d.mts +81 -19
  274. package/fjs/types/rtti/validate/module.f.mjs +107 -61
  275. package/fjs/types/rtti/validate/proof.f.d.mts +13 -10
  276. package/fjs/types/rtti/validate/proof.f.mjs +186 -197
  277. package/fjs/types/sorted_set/module.f.d.mts +18 -0
  278. package/fjs/types/sorted_set/module.f.mjs +22 -0
  279. package/fjs/types/sorted_set/proof.f.d.mts +1 -0
  280. package/fjs/types/sorted_set/proof.f.mjs +16 -1
  281. package/fjs/types/uint8array/module.f.d.mts +1 -1
  282. package/fjs/types/uint8array/module.f.mjs +1 -1
  283. package/fjs/website/module.f.d.mts +3 -3
  284. package/fjs/website/module.f.mjs +4 -7
  285. package/fjs/website/proof.f.mjs +2 -1
  286. package/package.json +2 -2
  287. package/fjs/dev/package_json/module.f.d.mts +0 -39
  288. package/fjs/dev/package_json/module.f.mjs +0 -40
  289. package/fjs/dev/package_json/proof.f.d.mts +0 -6
  290. package/fjs/dev/package_json/proof.f.mjs +0 -32
  291. package/fjs/effects/eff/module.f.d.mts +0 -20
  292. package/fjs/effects/eff/module.f.mjs +0 -70
  293. package/fjs/effects/eff/proof.f.d.mts +0 -15
  294. package/fjs/effects/eff/proof.f.mjs +0 -69
  295. package/fjs/effects/eff/types.d.ts +0 -71
  296. package/fjs/types/rtti/validate/types.d.ts +0 -6
@@ -1,13 +1,64 @@
1
1
  /**
2
- * @import { Dir, JsModule } from './types.ts'
2
+ * @import { Dir } from './types.ts'
3
+ * @import { NodeOp } from '../types.ts'
4
+ * @import { Effect } from '../../types.ts'
5
+ * @import { IoChannel } from '../types.ts'
3
6
  */
4
7
 
5
8
  import { assert, assertEq } from '../../../asserts/module.f.mjs'
6
- import { access, awaitIfPromise, fetch, rm, writeFile, readFile, readdir, import_, rename, readBytes, writeBytes, stat } from '../module.f.mjs'
7
- import { maxLengthBytes, vec, vec8 } from '../../../types/bit_vec/module.f.mjs'
9
+ import { access, awaitIfPromise, exec, fetch, log, rm, writeFile, readFile, readdir, import_, rename, readBytes, writeBytes, stat, createExclusive } from '../module.f.mjs'
10
+ import { empty, length, maxLengthBytes, vec, vec8 } from '../../../types/bit_vec/module.f.mjs'
8
11
  import { emptyState, virtual } from './module.f.mjs'
12
+ import { do_ } from '../../module.f.mjs'
13
+ import { catchStep } from '../../module.f.mjs'
14
+
15
+ /**
16
+ * Asserts that a channel error is a host failure carrying `message` — the
17
+ * normalized shape every runner reports, virtual and Node alike.
18
+ * @type {(e: IoChannel, message: string) => void}
19
+ */
20
+ const assertIoMessage = (e, message) => {
21
+ assert(e[0] === 'ioError', e)
22
+ assertEq(e[1].message, message)
23
+ }
9
24
 
10
25
  export const proof = {
26
+ // The two ways a command can have no handler here, which are not the same
27
+ // failure and must not answer alike.
28
+ unimplemented: {
29
+ // `exec` is a `NodeOp` this runner deliberately lacks — an in-memory
30
+ // filesystem has no subprocesses. It used to be a `todo` handler that
31
+ // threw; the program now gets its control back and can decide.
32
+ declaredButAbsent: () => {
33
+ const [, result] = virtual(emptyState)(exec('ls'))
34
+ assert(result[0] === 'error', result)
35
+ assertEq(result[1][0], 'notImplemented', result[1])
36
+ assertEq(result[1][1], 'exec', result[1])
37
+ },
38
+ // What the whole stage is for: the program receives control back and
39
+ // chooses. `exec` is unavailable here, so this one falls back to
40
+ // writing a note instead of dying, and the run completes normally.
41
+ programChoosesAFallback: () => {
42
+ const e = catchStep(exec('ls'), () => log('exec unavailable'))
43
+ const [state, result] = virtual(emptyState)(e)
44
+ assert(result[0] === 'ok', result)
45
+ assertEq(state.stdout, 'exec unavailable\n')
46
+ },
47
+ // A `command` that is not a `NodeOp` at all is a malformed node: the
48
+ // type said it was one, so something built it from data that was never
49
+ // checked. That stays a panic — collapsing it into `notImplemented`
50
+ // would turn a probable bug into a routine outcome.
51
+ throw: {
52
+ undeclaredCommand: () => {
53
+ // `do_` cannot build this from a well-typed call — that is the
54
+ // point: only a node assembled outside the type system reaches
55
+ // an interpreter with a command like this.
56
+ const bogus = /** @type {Effect<NodeOp, never, never>} */ (
57
+ /** @type {any} */ (do_)('nope')())
58
+ virtual(emptyState)(bogus)
59
+ },
60
+ },
61
+ },
11
62
  rm: {
12
63
  success: () => {
13
64
  /** @type {Dir} */
@@ -19,7 +70,10 @@ export const proof = {
19
70
  const [, result] = virtual(emptyState)(rm('notexist.txt'))
20
71
  assert(result[0] === 'error')
21
72
  },
22
- isDirectory: () => {
73
+ onDirectory: () => {
74
+ // `operation`'s wrapper descends into 'mydir' (a plain object),
75
+ // so rmOp itself runs with an empty remaining path and rejects
76
+ // via its `path.length !== 1` guard, not a directory-specific one.
23
77
  /** @type {Dir} */
24
78
  const inner = {}
25
79
  /** @type {Dir} */
@@ -41,7 +95,7 @@ export const proof = {
41
95
  // `!Array.isArray(file)` branch of writeFileOp: the entry exists but is
42
96
  // neither undefined nor an array.
43
97
  /** @type {Dir} */
44
- const root = { 'a.f.ts': /** @type {JsModule} */ (() => ({})) }
98
+ const root = { 'a.f.ts': () => ({}) }
45
99
  const [, result] = virtual({ ...emptyState, root })(writeFile('a.f.ts', vec8(0x42n)))
46
100
  assert(result[0] === 'error')
47
101
  },
@@ -83,7 +137,8 @@ export const proof = {
83
137
  awaitNonPromise: () => {
84
138
  // a non-promise value passes through the virtual `await` handler as-is
85
139
  const [, result] = virtual(emptyState)(awaitIfPromise(42))
86
- assertEq(result, 42)
140
+ assert(result[0] === 'ok', result)
141
+ assertEq(result[1], 42)
87
142
  },
88
143
  fetchNotFound: () => {
89
144
  // covers the `result === undefined` branch of the `fetch` handler
@@ -107,9 +162,135 @@ export const proof = {
107
162
  readFileOnJsModule: () => {
108
163
  // readFile on a JsModule path covers typeof file === 'function' branch
109
164
  /** @type {Dir} */
110
- const root = { 'a.f.ts': /** @type {JsModule} */ (() => ({})) }
165
+ const root = { 'a.f.ts': () => ({}) }
111
166
  virtual({ ...emptyState, root })(readFile('a.f.ts'))
112
167
  },
168
+ readBytesOnJsModule: () => {
169
+ // readBytes on a JsModule path covers typeof file === 'function' branch
170
+ /** @type {Dir} */
171
+ const root = { 'a.f.ts': () => ({}) }
172
+ virtual({ ...emptyState, root })(readBytes('a.f.ts', 0, 1))
173
+ },
174
+ },
175
+ readFileSkipsEmptyChunk: () => {
176
+ // A file stored with a zero-length chunk ahead of real data: readFile's
177
+ // loop must skip it (`chunkLen === 0n`) rather than concatenating it.
178
+ /** @type {Dir} */
179
+ const root = { 'f': [empty, vec8(0x42n)] }
180
+ const [, result] = virtual({ ...emptyState, root })(readFile('f'))
181
+ assert(result[0] === 'ok', result)
182
+ assertEq(length(result[1]), 8n)
183
+ },
184
+ readdirSkipsUndefinedEntry: () => {
185
+ // `Dir`'s index signature is optional (`{[name]?: _Entity}`), so an
186
+ // entry can legitimately be present with value `undefined` (e.g. after
187
+ // a rename leaves a stale key in some future refactor). readdir's loop
188
+ // must skip such entries rather than reporting them.
189
+ /** @type {Dir} */
190
+ const root = { 'd': { 'a': undefined, 'b': [vec8(0x42n)] } }
191
+ const [, result] = virtual({ ...emptyState, root })(readdir('d', {}))
192
+ assert(result[0] === 'ok', result)
193
+ assertEq(result[1].length, 1)
194
+ },
195
+ renameEmptySrc: () => {
196
+ // rename('', dst): src parses to the root path itself.
197
+ const [, result] = virtual(emptyState)(rename('', 'dst'))
198
+ assert(result[0] === 'error')
199
+ assertIoMessage(result[1], 'cannot extract root')
200
+ },
201
+ renameSrcThroughFile: () => {
202
+ // rename('a/b', dst) where 'a' is a file, not a directory: the
203
+ // intermediate segment can't be descended into.
204
+ /** @type {Dir} */
205
+ const root = { 'a': [vec8(0x42n)] }
206
+ const [, result] = virtual({ ...emptyState, root })(rename('a/b', 'dst'))
207
+ assert(result[0] === 'error')
208
+ },
209
+ renameSrcThreeLevelsMissing: () => {
210
+ // rename('a/b/c', dst) where 'a/b' exists but 'c' doesn't: the error
211
+ // from the deepest extractEntity call propagates through two levels
212
+ // of recursion.
213
+ /** @type {Dir} */
214
+ const root = { 'a': { 'b': {} } }
215
+ const [, result] = virtual({ ...emptyState, root })(rename('a/b/c', 'dst'))
216
+ assert(result[0] === 'error')
217
+ },
218
+ renameDstMissingIntermediate: () => {
219
+ // rename(src, 'missingdir/x'): the destination's parent doesn't exist.
220
+ /** @type {Dir} */
221
+ const root = { 'src': [vec8(0x42n)] }
222
+ const [, result] = virtual({ ...emptyState, root })(rename('src', 'missingdir/x'))
223
+ assert(result[0] === 'error')
224
+ },
225
+ renameDstThroughFile: () => {
226
+ // rename(src, 'blocker/x') where 'blocker' is a file, not a directory.
227
+ /** @type {Dir} */
228
+ const root = { 'src': [vec8(0x42n)], 'blocker': [vec8(0x1n)] }
229
+ const [, result] = virtual({ ...emptyState, root })(rename('src', 'blocker/x'))
230
+ assert(result[0] === 'error')
231
+ assertIoMessage(result[1], 'not a directory')
232
+ },
233
+ renameDstNestedError: () => {
234
+ // rename(src, 'a/b/c') where 'a/b' is a file: insertEntityAt's error
235
+ // one level down propagates through the outer recursive call.
236
+ /** @type {Dir} */
237
+ const root = { 'src': [vec8(0x1n)], 'a': { 'b': [vec8(0x2n)] } }
238
+ const [, result] = virtual({ ...emptyState, root })(rename('src', 'a/b/c'))
239
+ assert(result[0] === 'error')
240
+ assertIoMessage(result[1], 'not a directory')
241
+ },
242
+ createExclusiveNestedMissing: () => {
243
+ // createExclusive('a/b') where 'a' doesn't exist: the operation
244
+ // wrapper falls through with the full remaining path. Start from a
245
+ // non-empty root and check it survives untouched, so a mutant that
246
+ // returns the right error tag alongside a wiped dir would be caught.
247
+ /** @type {Dir} */
248
+ const root = { keep: [vec8(0x1n)] }
249
+ const [state, result] = virtual({ ...emptyState, root })(createExclusive('a/b'))
250
+ assert(result[0] === 'error')
251
+ assertEq(Object.keys(state.root).length, 1)
252
+ },
253
+ writeBytesNestedMissing: () => {
254
+ // writeBytes('a/b', ...) where 'a' doesn't exist. Non-empty root, as above.
255
+ /** @type {Dir} */
256
+ const root = { keep: [vec8(0x1n)] }
257
+ const [state, result] = virtual({ ...emptyState, root })(writeBytes('a/b', 0, vec8(0x1n)))
258
+ assert(result[0] === 'error')
259
+ assertEq(Object.keys(state.root).length, 1)
260
+ },
261
+ writeBytesMissingFile: () => {
262
+ // writeBytes on a path that doesn't exist at all: writeBytes never
263
+ // creates. Non-empty root, as above.
264
+ /** @type {Dir} */
265
+ const root = { keep: [vec8(0x1n)] }
266
+ const [state, result] = virtual({ ...emptyState, root })(writeBytes('missing', 0, vec8(0x1n)))
267
+ assert(result[0] === 'error')
268
+ assertEq(Object.keys(state.root).length, 1)
269
+ },
270
+ writeBytesOnJsModule: () => {
271
+ // writeBytes on a JsModule entry covers the `!Array.isArray(file)`
272
+ // branch (unlike readFile/readBytes, writeBytes has no separate throw
273
+ // for JsModule, so this is the reachable way to hit "not a file").
274
+ /** @type {Dir} */
275
+ const root = { 'a.f.ts': () => ({}) }
276
+ const [, result] = virtual({ ...emptyState, root })(writeBytes('a.f.ts', 0, vec8(0x1n)))
277
+ assert(result[0] === 'error')
278
+ },
279
+ writeBytesNegativeOffset: () => {
280
+ /** @type {Dir} */
281
+ const root = { 'file': [vec8(0x1n)] }
282
+ const [, result] = virtual({ ...emptyState, root })(writeBytes('file', -1, vec8(0x2n)))
283
+ assert(result[0] === 'error')
284
+ assertIoMessage(result[1], 'Offset -1 is invalid')
285
+ },
286
+ statNestedMissing: () => {
287
+ // stat('a/b') where 'a' doesn't exist.
288
+ const [, result] = virtual(emptyState)(stat('a/b'))
289
+ assert(result[0] === 'error')
290
+ },
291
+ statMissingFile: () => {
292
+ const [, result] = virtual(emptyState)(stat('missing'))
293
+ assert(result[0] === 'error')
113
294
  },
114
295
  renameSamePath: () => {
115
296
  // rename('a', 'a') should succeed as a no-op, not reject
@@ -219,10 +400,10 @@ export const proof = {
219
400
  // stat on a JsModule entry (neither an array nor a descendable
220
401
  // directory) covers the !Array.isArray(file) branch of statOp.
221
402
  /** @type {Dir} */
222
- const root = { 'a.f.ts': /** @type {JsModule} */ (() => ({})) }
403
+ const root = { 'a.f.ts': () => ({}) }
223
404
  const [, result] = virtual({ ...emptyState, root })(stat('a.f.ts'))
224
405
  assert(result[0] === 'error')
225
- assertEq(result[1], `'a.f.ts' is not a file`)
406
+ assertIoMessage(result[1], `'a.f.ts' is not a file`)
226
407
  },
227
408
  largeFileReadBytes: () => {
228
409
  // A file stored as two 128 KiB chunks is larger than maxLengthBytes.
@@ -1,42 +1,22 @@
1
1
  /**
2
- * @import { Effect, Operation, OperationMap } from './types.ts'
2
+ * @import { Effect, Func, Operation } from './types.ts'
3
+ * @import { Result } from '../types/result/types.ts'
3
4
  */
4
- import type { Effect, Operation } from './types.ts';
5
- /**
6
- * Asserts that `e` yields `expected` without performing a command. Exported so
7
- * `eff/proof.f.ts` shares this definition instead of repeating it.
8
- *
9
- * Not `assertEq(runPure(e), [expected])`: `assertEq` compares with `===`, so a
10
- * freshly allocated `[expected]` is never equal to the returned option. Assert
11
- * the option's shape first, then compare the value inside it.
12
- * @template {Operation} O
13
- * @template T
14
- * @param {Effect<O, T>} e
15
- * @param {T} expected
16
- */
17
- export declare const assertPure: <O extends Operation, T>(e: Effect<O, T>, expected: T) => void;
18
- export type _AddOp = readonly ['add', (a: number, b: number) => number];
19
- export type _AnyOp = readonly [string, (a: number) => number];
5
+ import type { Result } from '../types/result/types.ts';
6
+ export type _AddOp = readonly ['add', (a: number, b: number) => Result<number, string>];
7
+ export type _AnyOp = readonly [string, (a: number) => Result<number, string>];
8
+ export type _DivOp = readonly ['div', (a: number, b: number) => Result<number, string>];
9
+ export type _NegOp = readonly ['neg', (a: number) => Result<number, string>];
10
+ export type _Op = _DivOp | _NegOp;
20
11
  export declare const proof: {
21
- foldStep: {
22
- empty: () => void;
23
- threadsState: () => void;
24
- order: () => void;
25
- };
26
- forEachStep: {
27
- empty: () => void;
28
- runs: () => void;
29
- };
30
- okStep: {
12
+ runPure: {
31
13
  ok: () => void;
32
14
  error: () => void;
33
- };
34
- runPure: {
35
- pure: () => void;
36
15
  pureNull: () => void;
37
16
  do_: () => void;
38
17
  };
39
18
  doNode: () => void;
19
+ failedCommandResumes: () => void;
40
20
  match: {
41
21
  done: () => void;
42
22
  cont: () => void;
@@ -46,20 +26,72 @@ export declare const proof: {
46
26
  toStringCommand: () => void;
47
27
  };
48
28
  };
29
+ partialMatch: {
30
+ implemented: () => void;
31
+ declined: () => void;
32
+ throw: {
33
+ unknownCommand: () => void;
34
+ };
35
+ };
36
+ pureOk: () => void;
37
+ pureError: () => void;
49
38
  step: {
50
- pure: () => void;
39
+ ok: () => void;
40
+ propagates: () => void;
41
+ errorTupleIsUnchanged: () => void;
51
42
  chain: () => void;
52
43
  overDo: () => void;
44
+ overFailedDo: () => void;
45
+ joinsOperations: () => void;
46
+ mixedErrorsOk: () => void;
47
+ mixedErrorsFirst: () => void;
48
+ mixedErrorsSecond: () => void;
53
49
  };
54
- mapStep: {
55
- pure: () => void;
56
- constant: () => void;
50
+ catchStep: {
51
+ recovers: () => void;
52
+ preservesOk: () => void;
53
+ overFailedDo: () => void;
54
+ unionsSuccess: () => void;
55
+ };
56
+ resultStep: {
57
+ ok: () => void;
58
+ error: () => void;
57
59
  overDo: () => void;
58
60
  };
59
61
  historyStep: {
60
- pure: () => void;
61
- overDo: () => void;
62
62
  chain: () => void;
63
- fReceivesWholeHistory: () => void;
63
+ carriesValues: () => void;
64
+ propagates: () => void;
65
+ propagatesFromHead: () => void;
66
+ overDo: () => void;
67
+ };
68
+ foldStep: {
69
+ empty: () => void;
70
+ threadsState: () => void;
71
+ shortCircuits: () => void;
72
+ };
73
+ forEachStep: {
74
+ empty: () => void;
75
+ runs: () => void;
76
+ stopsAtTheFirstError: () => void;
77
+ };
78
+ unwrapStep: {
79
+ ok: () => void;
80
+ throw: {
81
+ error: () => void;
82
+ };
83
+ };
84
+ mapStep: {
85
+ ok: () => void;
86
+ error: () => void;
87
+ overDo: () => void;
88
+ };
89
+ resultMapStep: {
90
+ ok: () => void;
91
+ error: () => void;
92
+ absorbs: () => void;
93
+ rejects: () => void;
94
+ overDo: () => void;
95
+ overFailedDo: () => void;
64
96
  };
65
97
  };