functionalscript 0.19.0 → 0.21.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 (256) hide show
  1. package/fs/asn.1/{test.f.d.ts → proof.f.d.ts} +1 -2
  2. package/fs/asn.1/{test.f.js → proof.f.js} +1 -1
  3. package/fs/asserts/module.f.d.ts +4 -0
  4. package/fs/asserts/module.f.js +6 -0
  5. package/fs/base128/proof.f.d.ts +1 -0
  6. package/fs/base128/{test.f.js → proof.f.js} +1 -1
  7. package/fs/bnf/data/{test.f.d.ts → proof.f.d.ts} +1 -2
  8. package/fs/bnf/data/{test.f.js → proof.f.js} +1 -1
  9. package/fs/bnf/proof.f.d.ts +3 -0
  10. package/fs/bnf/{test.f.js → proof.f.js} +1 -1
  11. package/fs/cas/module.f.js +9 -23
  12. package/fs/cas/proof.f.d.ts +4 -0
  13. package/fs/cas/proof.f.js +37 -0
  14. package/fs/cbase32/{test.f.d.ts → proof.f.d.ts} +1 -2
  15. package/fs/cbase32/{test.f.js → proof.f.js} +1 -1
  16. package/fs/ci/bun/module.f.js +2 -7
  17. package/fs/ci/common/module.f.d.ts +2 -1
  18. package/fs/ci/common/module.f.js +7 -9
  19. package/fs/ci/config/module.f.d.ts +12 -3
  20. package/fs/ci/config/module.f.js +24 -4
  21. package/fs/ci/deno/module.f.js +2 -5
  22. package/fs/ci/node/module.f.js +14 -9
  23. package/fs/ci/playwright/module.f.js +5 -8
  24. package/fs/ci/{test.f.d.ts → proof.f.d.ts} +1 -2
  25. package/fs/ci/{test.f.js → proof.f.js} +2 -2
  26. package/fs/ci/rust/module.f.js +3 -9
  27. package/fs/crypto/hmac/{test.f.d.ts → proof.f.d.ts} +1 -2
  28. package/fs/crypto/hmac/{test.f.js → proof.f.js} +1 -1
  29. package/fs/crypto/secp/{test.f.d.ts → proof.f.d.ts} +1 -2
  30. package/fs/crypto/secp/{test.f.js → proof.f.js} +1 -1
  31. package/fs/crypto/sha2/{test.f.d.ts → proof.f.d.ts} +1 -2
  32. package/fs/crypto/sha2/{test.f.js → proof.f.js} +1 -1
  33. package/fs/crypto/sign/{test.f.d.ts → proof.f.d.ts} +1 -2
  34. package/fs/crypto/sign/{test.f.js → proof.f.js} +1 -1
  35. package/fs/dev/module.f.d.ts +28 -5
  36. package/fs/dev/module.f.js +38 -28
  37. package/fs/dev/{test.f.d.ts → proof.f.d.ts} +5 -2
  38. package/fs/dev/{test.f.js → proof.f.js} +26 -2
  39. package/fs/dev/version/proof.f.d.ts +3 -0
  40. package/fs/dev/version/{test.f.js → proof.f.js} +1 -1
  41. package/fs/djs/ast/{test.f.d.ts → proof.f.d.ts} +1 -2
  42. package/fs/djs/ast/{test.f.js → proof.f.js} +1 -1
  43. package/fs/djs/parser/{test.f.d.ts → proof.f.d.ts} +1 -2
  44. package/fs/djs/parser/{test.f.js → proof.f.js} +1 -1
  45. package/fs/djs/{test.f.d.ts → proof.f.d.ts} +1 -2
  46. package/fs/djs/{test.f.js → proof.f.js} +1 -1
  47. package/fs/djs/serializer/module.f.d.ts +2 -2
  48. package/fs/djs/serializer/module.f.js +47 -79
  49. package/fs/djs/serializer/{test.f.d.ts → proof.f.d.ts} +1 -2
  50. package/fs/djs/serializer/{test.f.js → proof.f.js} +8 -8
  51. package/fs/djs/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
  52. package/fs/djs/tokenizer/{test.f.js → proof.f.js} +1 -1
  53. package/fs/djs/tokenizer-new/module.f.js +1 -1
  54. package/fs/djs/tokenizer-new/{test.f.d.ts → proof.f.d.ts} +1 -2
  55. package/fs/djs/tokenizer-new/{test.f.js → proof.f.js} +1 -1
  56. package/fs/djs/transpiler/module.f.d.ts +15 -0
  57. package/fs/djs/transpiler/module.f.js +10 -2
  58. package/fs/djs/transpiler/{test.f.d.ts → proof.f.d.ts} +1 -2
  59. package/fs/djs/transpiler/{test.f.js → proof.f.js} +1 -1
  60. package/fs/{dev/tf → emergent-testing}/module.f.d.ts +66 -8
  61. package/fs/{dev/tf → emergent-testing}/module.f.js +101 -34
  62. package/fs/{dev/tf → emergent-testing}/module.js +2 -2
  63. package/fs/{dev/tf/test.f.d.ts → emergent-testing/proof.f.d.ts} +28 -0
  64. package/fs/{dev/tf/test.f.js → emergent-testing/proof.f.js} +119 -40
  65. package/fs/emergent-testing/scenarios/async-subtests.fail.d.ts +6 -0
  66. package/fs/emergent-testing/scenarios/async-subtests.fail.js +9 -0
  67. package/fs/emergent-testing/scenarios/async-subtests.pass.d.ts +6 -0
  68. package/fs/emergent-testing/scenarios/async-subtests.pass.js +9 -0
  69. package/fs/emergent-testing/scenarios/async.fail.d.ts +3 -0
  70. package/fs/emergent-testing/scenarios/async.fail.js +6 -0
  71. package/fs/emergent-testing/scenarios/async.pass.d.ts +3 -0
  72. package/fs/emergent-testing/scenarios/async.pass.js +5 -0
  73. package/fs/emergent-testing/scenarios/fail.fail.d.ts +3 -0
  74. package/fs/emergent-testing/scenarios/fail.fail.js +3 -0
  75. package/fs/emergent-testing/scenarios/return-value.pass.d.ts +3 -0
  76. package/fs/emergent-testing/scenarios/return-value.pass.js +4 -0
  77. package/fs/emergent-testing/scenarios/thenable.pass.d.ts +5 -0
  78. package/fs/emergent-testing/scenarios/thenable.pass.js +11 -0
  79. package/fs/emergent-testing/scenarios/thenable2.pass.d.ts +5 -0
  80. package/fs/emergent-testing/scenarios/thenable2.pass.js +3 -0
  81. package/fs/emergent-testing/scenarios/throw.pass.d.ts +5 -0
  82. package/fs/{dev/tf/scenarios/throw.pass.f.js → emergent-testing/scenarios/throw.pass.js} +1 -1
  83. package/fs/fjs/module.f.js +4 -5
  84. package/fs/fsc/{test.f.d.ts → proof.f.d.ts} +1 -2
  85. package/fs/fsc/{test.f.js → proof.f.js} +1 -1
  86. package/fs/fsm/proof.f.d.ts +4 -0
  87. package/fs/fsm/{test.f.js → proof.f.js} +1 -1
  88. package/fs/html/{test.f.d.ts → proof.f.d.ts} +1 -2
  89. package/fs/html/{test.f.js → proof.f.js} +1 -1
  90. package/fs/io/module.d.ts +1 -1
  91. package/fs/io/module.f.d.ts +3 -2
  92. package/fs/io/module.f.js +4 -3
  93. package/fs/io/module.js +19 -11
  94. package/fs/js/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
  95. package/fs/js/tokenizer/{test.f.js → proof.f.js} +1 -1
  96. package/fs/json/parser/{test.f.d.ts → proof.f.d.ts} +1 -2
  97. package/fs/json/parser/{test.f.js → proof.f.js} +1 -1
  98. package/fs/json/{test.f.d.ts → proof.f.d.ts} +1 -2
  99. package/fs/json/{test.f.js → proof.f.js} +1 -1
  100. package/fs/json/serializer/{test.f.d.ts → proof.f.d.ts} +1 -2
  101. package/fs/json/serializer/{test.f.js → proof.f.js} +1 -1
  102. package/fs/json/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
  103. package/fs/json/tokenizer/{test.f.js → proof.f.js} +1 -1
  104. package/fs/path/proof.f.d.ts +5 -0
  105. package/fs/path/{test.f.js → proof.f.js} +4 -3
  106. package/fs/sul/id/module.f.js +1 -1
  107. package/fs/sul/id/{test.f.d.ts → proof.f.d.ts} +1 -2
  108. package/fs/sul/id/{test.f.js → proof.f.js} +2 -2
  109. package/fs/sul/level/hash/{test.f.d.ts → proof.f.d.ts} +1 -2
  110. package/fs/sul/level/hash/{test.f.js → proof.f.js} +2 -2
  111. package/fs/sul/level/literal/{test.f.d.ts → proof.f.d.ts} +1 -2
  112. package/fs/sul/level/literal/{test.f.js → proof.f.js} +1 -1
  113. package/fs/sul/{test.f.d.ts → proof.f.d.ts} +1 -2
  114. package/fs/sul/{test.f.js → proof.f.js} +2 -2
  115. package/fs/text/ascii/proof.f.d.ts +3 -0
  116. package/fs/text/ascii/{test.f.js → proof.f.js} +1 -1
  117. package/fs/text/code_point/module.f.d.ts +28 -0
  118. package/fs/text/code_point/module.f.js +31 -0
  119. package/fs/text/{test.f.d.ts → proof.f.d.ts} +1 -2
  120. package/fs/text/{test.f.js → proof.f.js} +1 -1
  121. package/fs/text/sgr/proof.f.d.ts +1 -0
  122. package/fs/text/sgr/{test.f.js → proof.f.js} +1 -1
  123. package/fs/text/utf16/module.f.js +3 -53
  124. package/fs/text/utf16/{test.f.d.ts → proof.f.d.ts} +1 -2
  125. package/fs/text/utf16/{test.f.js → proof.f.js} +1 -1
  126. package/fs/text/utf8/module.f.js +3 -25
  127. package/fs/text/utf8/{test.f.d.ts → proof.f.d.ts} +1 -2
  128. package/fs/text/utf8/{test.f.js → proof.f.js} +1 -1
  129. package/fs/types/array/module.f.js +2 -5
  130. package/fs/types/array/{test.f.d.ts → proof.f.d.ts} +1 -2
  131. package/fs/types/array/{test.f.js → proof.f.js} +1 -1
  132. package/fs/types/bigfloat/{test.f.d.ts → proof.f.d.ts} +1 -2
  133. package/fs/types/bigfloat/{test.f.js → proof.f.js} +1 -1
  134. package/fs/types/bigint/{test.f.d.ts → proof.f.d.ts} +1 -2
  135. package/fs/types/bigint/{test.f.js → proof.f.js} +1 -1
  136. package/fs/types/bit_vec/{test.f.d.ts → proof.f.d.ts} +1 -2
  137. package/fs/types/bit_vec/{test.f.js → proof.f.js} +1 -1
  138. package/fs/types/btree/find/proof.f.d.ts +1 -0
  139. package/fs/types/btree/find/{test.f.js → proof.f.js} +1 -1
  140. package/fs/types/btree/{test.f.d.ts → proof.f.d.ts} +1 -2
  141. package/fs/types/btree/{test.f.js → proof.f.js} +1 -1
  142. package/fs/types/btree/remove/proof.f.d.ts +4 -0
  143. package/fs/types/btree/remove/{test.f.js → proof.f.js} +1 -1
  144. package/fs/types/btree/set/proof.f.d.ts +1 -0
  145. package/fs/types/btree/set/{test.f.js → proof.f.js} +1 -1
  146. package/fs/types/btree/types/module.f.d.ts +8 -0
  147. package/fs/types/btree/types/module.f.js +8 -0
  148. package/fs/types/byte_set/{test.f.d.ts → proof.f.d.ts} +1 -2
  149. package/fs/types/byte_set/{test.f.js → proof.f.js} +1 -1
  150. package/fs/types/effects/module.f.d.ts +17 -0
  151. package/fs/types/effects/module.f.js +17 -0
  152. package/fs/types/effects/node/module.f.d.ts +60 -5
  153. package/fs/types/effects/node/module.f.js +12 -1
  154. package/fs/types/effects/node/{test.f.d.ts → proof.f.d.ts} +1 -2
  155. package/fs/types/effects/node/{test.f.js → proof.f.js} +1 -1
  156. package/fs/types/effects/node/virtual/module.f.js +2 -1
  157. package/fs/types/effects/proof.f.d.ts +11 -0
  158. package/fs/types/effects/proof.f.js +57 -0
  159. package/fs/types/function/compare/proof.f.d.ts +1 -0
  160. package/fs/types/function/compare/{test.f.js → proof.f.js} +1 -1
  161. package/fs/types/function/operator/proof.f.d.ts +12 -0
  162. package/fs/types/function/operator/{test.f.js → proof.f.js} +11 -10
  163. package/fs/types/function/proof.f.d.ts +1 -0
  164. package/fs/types/function/{test.f.js → proof.f.js} +1 -1
  165. package/fs/types/list/{test.f.d.ts → proof.f.d.ts} +2 -2
  166. package/fs/types/list/{test.f.js → proof.f.js} +15 -1
  167. package/fs/types/map/proof.f.d.ts +4 -0
  168. package/fs/types/map/{test.f.js → proof.f.js} +1 -1
  169. package/fs/types/monoid/{test.f.d.ts → proof.f.d.ts} +1 -2
  170. package/fs/types/monoid/{test.f.js → proof.f.js} +1 -1
  171. package/fs/types/nibble_set/{test.f.d.ts → proof.f.d.ts} +1 -2
  172. package/fs/types/nibble_set/{test.f.js → proof.f.js} +1 -1
  173. package/fs/types/nominal/proof.f.d.ts +4 -0
  174. package/fs/types/nominal/{test.f.js → proof.f.js} +1 -1
  175. package/fs/types/nullable/module.f.d.ts +7 -0
  176. package/fs/types/nullable/module.f.js +7 -0
  177. package/fs/types/nullable/proof.f.d.ts +1 -0
  178. package/fs/types/nullable/{test.f.js → proof.f.js} +20 -3
  179. package/fs/types/number/{test.f.d.ts → proof.f.d.ts} +1 -2
  180. package/fs/types/number/{test.f.js → proof.f.js} +1 -1
  181. package/fs/types/object/module.f.js +2 -4
  182. package/fs/types/object/{test.f.d.ts → proof.f.d.ts} +1 -2
  183. package/fs/types/object/{test.f.js → proof.f.js} +1 -1
  184. package/fs/types/ordered_map/{test.f.d.ts → proof.f.d.ts} +1 -2
  185. package/fs/types/ordered_map/{test.f.js → proof.f.js} +1 -1
  186. package/fs/types/patricia_trie/{test.f.d.ts → proof.f.d.ts} +1 -2
  187. package/fs/types/patricia_trie/{test.f.js → proof.f.js} +2 -2
  188. package/fs/types/prime_field/{test.f.d.ts → proof.f.d.ts} +1 -2
  189. package/fs/types/prime_field/{test.f.js → proof.f.js} +1 -1
  190. package/fs/types/range/proof.f.d.ts +1 -0
  191. package/fs/types/range/{test.f.js → proof.f.js} +1 -1
  192. package/fs/types/range_map/{test.f.d.ts → proof.f.d.ts} +1 -2
  193. package/fs/types/range_map/{test.f.js → proof.f.js} +1 -1
  194. package/fs/types/result/proof.f.d.ts +5 -0
  195. package/fs/types/result/{test.f.js → proof.f.js} +18 -2
  196. package/fs/types/rtti/parse/{test.f.d.ts → proof.f.d.ts} +1 -2
  197. package/fs/types/rtti/parse/{test.f.js → proof.f.js} +1 -1
  198. package/fs/types/rtti/{test.f.d.ts → proof.f.d.ts} +1 -2
  199. package/fs/types/rtti/{test.f.js → proof.f.js} +1 -1
  200. package/fs/types/rtti/ts/{test.f.d.ts → proof.f.d.ts} +1 -2
  201. package/fs/types/rtti/ts/{test.f.js → proof.f.js} +1 -1
  202. package/fs/types/rtti/validate/{test.f.d.ts → proof.f.d.ts} +1 -2
  203. package/fs/types/rtti/validate/{test.f.js → proof.f.js} +1 -1
  204. package/fs/types/sorted_list/{test.f.d.ts → proof.f.d.ts} +1 -2
  205. package/fs/types/sorted_list/{test.f.js → proof.f.js} +1 -1
  206. package/fs/types/sorted_set/{test.f.d.ts → proof.f.d.ts} +1 -2
  207. package/fs/types/sorted_set/{test.f.js → proof.f.js} +1 -1
  208. package/fs/types/string/{test.f.d.ts → proof.f.d.ts} +1 -2
  209. package/fs/types/string/{test.f.js → proof.f.js} +1 -1
  210. package/fs/types/string_set/{test.f.d.ts → proof.f.d.ts} +1 -2
  211. package/fs/types/string_set/{test.f.js → proof.f.js} +1 -1
  212. package/fs/types/ts/module.f.d.ts +0 -1
  213. package/fs/types/ts/{test.f.d.ts → proof.f.d.ts} +20 -0
  214. package/fs/types/ts/{test.f.js → proof.f.js} +1 -0
  215. package/fs/types/uint8array/{test.f.d.ts → proof.f.d.ts} +1 -2
  216. package/fs/types/uint8array/{test.f.js → proof.f.js} +1 -1
  217. package/fs/website/proof.f.d.ts +3 -0
  218. package/fs/website/proof.f.js +9 -0
  219. package/issues/demo/sample/{test.f.js → proof.f.js} +1 -1
  220. package/issues/{test.f.d.ts → proof.f.d.ts} +1 -2
  221. package/issues/{test.f.js → proof.f.js} +1 -1
  222. package/nanvm-lib/tests/{test.f.d.ts → proof.f.d.ts} +1 -2
  223. package/nanvm-lib/tests/{test.f.js → proof.f.js} +1 -1
  224. package/nanvm-lib/tests/vm/{test.f.d.ts → proof.f.d.ts} +1 -2
  225. package/nanvm-lib/tests/vm/{test.f.js → proof.f.js} +1 -1
  226. package/package.json +2 -2
  227. package/fs/base128/test.f.d.ts +0 -2
  228. package/fs/bnf/test.f.d.ts +0 -4
  229. package/fs/cas/test.f.d.ts +0 -2
  230. package/fs/cas/test.f.js +0 -1
  231. package/fs/dev/tf/scenarios/fail.fail.f.d.ts +0 -1
  232. package/fs/dev/tf/scenarios/fail.fail.f.js +0 -1
  233. package/fs/dev/tf/scenarios/return-value.pass.f.d.ts +0 -1
  234. package/fs/dev/tf/scenarios/return-value.pass.f.js +0 -2
  235. package/fs/dev/tf/scenarios/throw.pass.f.d.ts +0 -6
  236. package/fs/dev/version/test.f.d.ts +0 -4
  237. package/fs/fsm/test.f.d.ts +0 -5
  238. package/fs/path/test.f.d.ts +0 -3
  239. package/fs/text/ascii/test.f.d.ts +0 -4
  240. package/fs/text/sgr/test.f.d.ts +0 -2
  241. package/fs/types/btree/find/test.f.d.ts +0 -2
  242. package/fs/types/btree/remove/test.f.d.ts +0 -5
  243. package/fs/types/btree/set/test.f.d.ts +0 -2
  244. package/fs/types/function/compare/test.f.d.ts +0 -2
  245. package/fs/types/function/operator/test.f.d.ts +0 -10
  246. package/fs/types/function/test.f.d.ts +0 -2
  247. package/fs/types/map/test.f.d.ts +0 -5
  248. package/fs/types/nominal/test.f.d.ts +0 -5
  249. package/fs/types/nullable/test.f.d.ts +0 -2
  250. package/fs/types/range/test.f.d.ts +0 -2
  251. package/fs/types/result/test.f.d.ts +0 -2
  252. /package/fs/{dev/tf → emergent-testing}/all.test.d.ts +0 -0
  253. /package/fs/{dev/tf → emergent-testing}/all.test.js +0 -0
  254. /package/fs/{dev/tf → emergent-testing}/module.d.ts +0 -0
  255. /package/fs/{dev/tf → emergent-testing}/scenarios/all.d.ts +0 -0
  256. /package/fs/{dev/tf → emergent-testing}/scenarios/all.js +0 -0
@@ -1,5 +1,6 @@
1
1
  import { updateVersion } from "./version/module.f.js";
2
2
  import { access, all, both, import_, readdir, readFile, writeFile } from "../types/effects/node/module.f.js";
3
+ import { cmp as strCmp } from "../types/string/module.f.js";
3
4
  import { utf8, utf8ToString } from "../text/module.f.js";
4
5
  import { unwrap } from "../types/result/module.f.js";
5
6
  import { begin, pure } from "../types/effects/module.f.js";
@@ -7,20 +8,28 @@ import { parse as jsonParse } from "../json/module.f.js";
7
8
  import { record, unknown as rttiUnknown } from "../types/rtti/module.f.js";
8
9
  import { parse as rttiParse } from "../types/rtti/parse/module.f.js";
9
10
  import { relativize } from "../path/module.f.js";
10
- export const todo = () => { throw 'not implemented'; };
11
- export const assert = (v, msg = 'assertion failed') => {
12
- if (!v)
13
- throw msg;
14
- };
15
- export const assertEq = (a, b) => assert(a === b, [a, b]);
16
- const cmp = ([a], [b]) => a < b ? -1 : a > b ? 1 : 0;
17
11
  export const env = ({ process: { env } }) => a => {
18
12
  const r = Object.getOwnPropertyDescriptor(env, a);
19
13
  return r === undefined ? undefined :
20
14
  typeof r.get === 'function' ? r.get() :
21
15
  r.value;
22
16
  };
23
- export const allFiles = (s) => {
17
+ /**
18
+ * Returns `true` if the file should be loaded for proof discovery.
19
+ *
20
+ * All FunctionalScript modules (`.f.ts` / `.f.js`) are safe to bulk-load by
21
+ * construction — they have no import side effects. For vanilla TS/JS the
22
+ * load gate stays opt-in by filename: any file ending in `proof.ts`,
23
+ * `proof.js`, `proof.mts`, or `proof.mjs` is included.
24
+ *
25
+ * Whether a loaded module actually _contains_ a proof is determined at
26
+ * runtime by checking for an exported `proof` property.
27
+ */
28
+ export const shouldLoad = (s) => s.endsWith('.f.ts') || s.endsWith('.f.js') ||
29
+ s.endsWith('proof.ts') || s.endsWith('proof.js') ||
30
+ s.endsWith('proof.mts') || s.endsWith('proof.mjs');
31
+ const isSourceFile = (path) => path.endsWith('.js') || path.endsWith('.ts') || path.endsWith('.mts') || path.endsWith('.mjs');
32
+ const allFiles = (s, predicate) => {
24
33
  const load = (p) => begin
25
34
  .step(() => readdir(p, {}))
26
35
  .step(d => {
@@ -38,7 +47,7 @@ export const allFiles = (s) => {
38
47
  result = [...result, load(file)];
39
48
  continue;
40
49
  }
41
- if (name.endsWith('.js') || name.endsWith('.ts')) {
50
+ if (predicate(file)) {
42
51
  result = [...result, pure([file])];
43
52
  }
44
53
  }
@@ -47,18 +56,22 @@ export const allFiles = (s) => {
47
56
  .step(v => pure(v.flat()));
48
57
  return load(s);
49
58
  };
50
- const loadFile = (f) => {
51
- const doImport = import_(f).step(r => pure([[f, unwrap(r)]]));
52
- if (f.endsWith('.f.js')) {
53
- return doImport;
54
- }
55
- if (f.endsWith('.f.ts')) {
56
- return access(f.substring(0, f.length - 3) + '.js')
57
- .step(r => r[0] === 'ok' ? pure([]) : doImport);
58
- }
59
- return pure([]);
60
- };
59
+ const loadFile = (f) => import_(f).step(r => pure([[f, unwrap(r)]]));
61
60
  const { fromEntries } = Object;
61
+ /**
62
+ * Discovers all source files under `INIT_CWD` (or `.` if unset) that match
63
+ * `predicate`, imports them, and returns a map from relative path to module
64
+ * exports.
65
+ *
66
+ * The `predicate` is propagated into `allFiles` so that non-matching files
67
+ * are excluded before any `import()` is attempted — no wasted I/O.
68
+ * The default matches all JS/TS source files (`.js`, `.ts`, `.mts`, `.mjs`).
69
+ * `loadFile`'s own guards (`.f.js`, `.f.ts`, `shouldLoad`) still apply on
70
+ * top; the predicate only controls which files are discovered.
71
+ *
72
+ * The result is sorted by path key using `string.cmp` so the order is
73
+ * deterministic regardless of filesystem traversal order.
74
+ */
62
75
  export const loadModuleMap = (env) => {
63
76
  const initCwd = env['INIT_CWD'];
64
77
  const s = initCwd === undefined ? '.' : `${initCwd.replaceAll('\\', '/')}`;
@@ -67,24 +80,21 @@ export const loadModuleMap = (env) => {
67
80
  // we should consider optimize them by ALIQ technique or something similar.
68
81
  // For example, we should be able to write it like `allFiles(s).flatMap(loadFile)`,
69
82
  // then an effect runner can batch all file loading operations together.
70
- return allFiles(s)
83
+ return allFiles(s, shouldLoad)
71
84
  .step(files => all(...files.map(loadFile)))
72
85
  .step(entries => pure(fromEntries(entries
73
86
  .flat()
74
87
  .map(([k, v]) => [relativize(prefix, k), v])
75
- .toSorted(cmp))));
88
+ .toSorted(([a], [b]) => strCmp(a)(b)))));
76
89
  };
77
90
  const denoJson = './deno.json';
78
91
  const parseDenoJson = rttiParse(record(rttiUnknown));
79
- const index2 = begin
80
- .step(() => updateVersion)
92
+ const index2 = updateVersion
81
93
  .step(() => readFile(denoJson))
82
94
  .step(v => pure(unwrap(parseDenoJson(jsonParse(utf8ToString(unwrap(v)))))));
83
- const allFiles2aa = begin
84
- .step(() => allFiles('.'))
95
+ const allFiles2aa = allFiles('.', v => v.endsWith('/module.f.ts') || v.endsWith('/module.ts'))
85
96
  .step(files => {
86
- const list = files.filter(v => v.endsWith('/module.f.ts') || v.endsWith('/module.ts'));
87
- const exportsA = list.map(v => [v, `./${v.substring(2)}`]);
97
+ const exportsA = files.map(v => [v, `./${v.substring(2)}`]);
88
98
  return pure(Object.fromEntries(exportsA));
89
99
  });
90
100
  const index3 = both(index2)(allFiles2aa)
@@ -1,4 +1,7 @@
1
- declare const _default: {
1
+ export declare const proof: {
2
+ shouldPass: () => {
3
+ then: () => undefined;
4
+ };
2
5
  ctor: () => void;
3
6
  ctorEmpty: () => void;
4
7
  ctorUndefined: () => void;
@@ -6,5 +9,5 @@ declare const _default: {
6
9
  properties: () => void;
7
10
  getOwnPropertyDescriptor: () => void;
8
11
  throw: () => void;
12
+ env: () => void;
9
13
  };
10
- export default _default;
@@ -1,5 +1,9 @@
1
- import { todo } from "./module.f.js";
2
- export default {
1
+ import { todo } from "../asserts/module.f.js";
2
+ import { env } from "./module.f.js";
3
+ export const proof = {
4
+ shouldPass: () => ({
5
+ then: () => undefined
6
+ }),
3
7
  ctor: () => {
4
8
  const c = (() => { })['constructor'];
5
9
  const f = c('return 5');
@@ -52,5 +56,25 @@ export default {
52
56
  },
53
57
  throw: () => {
54
58
  todo();
59
+ },
60
+ env: () => {
61
+ const mockIo = { process: { env: { MY_VAR: 'hello' } } };
62
+ // missing key → undefined
63
+ const r1 = env(mockIo)('MISSING');
64
+ if (r1 !== undefined) {
65
+ throw r1;
66
+ }
67
+ // regular value property → returns value
68
+ const r2 = env(mockIo)('MY_VAR');
69
+ if (r2 !== 'hello') {
70
+ throw r2;
71
+ }
72
+ // getter property → calls get()
73
+ const envWithGetter = Object.defineProperty({}, 'GETTER_VAR', { get: () => 'from-getter', enumerable: true, configurable: true });
74
+ const mockIo2 = { process: { env: envWithGetter } };
75
+ const r3 = env(mockIo2)('GETTER_VAR');
76
+ if (r3 !== 'from-getter') {
77
+ throw r3;
78
+ }
55
79
  }
56
80
  };
@@ -0,0 +1,3 @@
1
+ export declare const proof: {
2
+ new: () => void;
3
+ };
@@ -77,7 +77,7 @@ const e = '{\n' +
77
77
  ' "typescript": "^4.7.4"\n' +
78
78
  ' }\n' +
79
79
  '}';
80
- export default {
80
+ export const proof = {
81
81
  new: () => {
82
82
  const w = (name) => {
83
83
  const fn = `${name}.json`;
@@ -1,8 +1,7 @@
1
- declare const _default: {
1
+ export declare const proof: {
2
2
  test: () => void;
3
3
  testCref: () => void;
4
4
  testAref: () => void;
5
5
  testArray: () => void;
6
6
  testObj: () => void;
7
7
  };
8
- export default _default;
@@ -1,7 +1,7 @@
1
1
  import { sort } from "../../types/object/module.f.js";
2
2
  import { run } from "./module.f.js";
3
3
  import { stringifyAsTree } from "../serializer/module.f.js";
4
- export default {
4
+ export const proof = {
5
5
  test: () => {
6
6
  const djs = run([1])([]);
7
7
  const result = stringifyAsTree(sort)(djs);
@@ -1,4 +1,4 @@
1
- declare const _default: {
1
+ export declare const proof: {
2
2
  valid: (() => void)[];
3
3
  invalid: (() => void)[];
4
4
  errorMetadata: (() => void)[];
@@ -11,4 +11,3 @@ declare const _default: {
11
11
  invalidWithArgs: (() => void)[];
12
12
  comments: (() => void)[];
13
13
  };
14
- export default _default;
@@ -7,7 +7,7 @@ import { stringifyAsTree } from "../serializer/module.f.js";
7
7
  import { stringify } from "../../json/module.f.js";
8
8
  const tokenizeString = s => toArray(tokenize(stringToList(s))(''));
9
9
  const stringifyDjsModule = stringifyAsTree(sort);
10
- export default {
10
+ export const proof = {
11
11
  valid: [
12
12
  () => {
13
13
  const tokenList = tokenizeString('export default null');
@@ -1,4 +1,4 @@
1
- declare const _default: {
1
+ export declare const proof: {
2
2
  tooFewArgs: {
3
3
  noArgs: () => void;
4
4
  oneArg: () => void;
@@ -8,4 +8,3 @@ declare const _default: {
8
8
  fileNotFound: () => void;
9
9
  parseError: () => void;
10
10
  };
11
- export default _default;
@@ -9,7 +9,7 @@ const readOutput = (root, path) => {
9
9
  }
10
10
  return utf8ToString(file);
11
11
  };
12
- export default {
12
+ export const proof = {
13
13
  tooFewArgs: {
14
14
  noArgs: () => {
15
15
  const [state, code] = virtual(emptyState)(compile([]));
@@ -7,11 +7,11 @@ import type { Unknown } from '../module.f.ts';
7
7
  import type { Entry as ObjectEntry } from '../../types/object/module.f.ts';
8
8
  import { type List } from '../../types/list/module.f.ts';
9
9
  export declare const undefinedSerialize: string[];
10
- type RefCounter = [number, number, boolean];
10
+ type RefCounter = readonly [number, number];
11
11
  type Entry = ObjectEntry<Unknown>;
12
12
  type Entries = List<Entry>;
13
13
  type MapEntries = (entries: Entries) => Entries;
14
- type Refs = Map<Unknown, RefCounter>;
14
+ type Refs = ReadonlyMap<Unknown, RefCounter>;
15
15
  export declare const serializeWithoutConst: (mapEntries: MapEntries) => (value: Unknown) => List<string>;
16
16
  export declare const stringify: (sort: MapEntries) => (djs: Unknown) => string;
17
17
  export declare const stringifyAsTree: (mapEntries: MapEntries) => (value: Unknown) => string;
@@ -7,88 +7,47 @@ import { serialize as bigintSerialize } from "../../types/bigint/module.f.js";
7
7
  import { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize, boolSerialize } from "../../json/serializer/module.f.js";
8
8
  const colon = [':'];
9
9
  export const undefinedSerialize = ['undefined'];
10
- const getConstantsOp = djs => state => {
11
- switch (typeof djs) {
12
- case 'boolean': {
13
- return state;
14
- }
15
- case 'number':
16
- case 'string':
17
- case 'bigint': {
18
- return getConstantSelf(djs)(state);
19
- }
20
- default: {
21
- if (djs === null) {
22
- return state;
23
- }
24
- if (djs === undefined) {
25
- return state;
26
- }
27
- if (djs instanceof Array) {
28
- return getConstantSelf(djs)(fold(getConstantsOp)(state)(djs));
29
- }
30
- return getConstantSelf(djs)(fold(getConstantsOp)(state)(map(entryValue)(entries(djs))));
10
+ const getConstants = refs => {
11
+ const checkSelf = djs => state => {
12
+ const refCounter = refs.get(djs);
13
+ if (refCounter !== undefined && refCounter[1] > 1 && !state.added.has(djs)) {
14
+ return {
15
+ added: new Set([...state.added, djs]),
16
+ consts: { head: state.consts, tail: [djs] }
17
+ };
31
18
  }
32
- }
33
- };
34
- const getConstantSelf = djs => state => {
35
- const refs = state.refs;
36
- const refCounter = refs.get(djs);
37
- if (refCounter !== undefined && refCounter[1] > 1 && !refCounter[2]) {
38
- refCounter[2] = true;
39
- refs.set(djs, refCounter);
40
- return { refs, consts: { head: state.consts, tail: [djs] } };
41
- }
42
- return state;
43
- };
44
- const getConstants = djs => refs => {
45
- return getConstantsOp(djs)(refs);
46
- };
47
- const entryValue = kv => kv[1];
48
- export const serializeWithoutConst = sort => {
49
- const propertySerialize = ([k, v]) => flat([
50
- stringSerialize(k),
51
- colon,
52
- f(v)
53
- ]);
54
- const mapPropertySerialize = map(propertySerialize);
55
- const objectSerialize = fn(entries)
56
- .map(sort)
57
- .map(mapPropertySerialize)
58
- .map(objectWrap)
59
- .result;
60
- const f = value => {
61
- switch (typeof value) {
19
+ return state;
20
+ };
21
+ const op = djs => state => {
22
+ switch (typeof djs) {
62
23
  case 'boolean': {
63
- return boolSerialize(value);
64
- }
65
- case 'number': {
66
- return numberSerialize(value);
67
- }
68
- case 'string': {
69
- return stringSerialize(value);
24
+ return state;
70
25
  }
26
+ case 'number':
27
+ case 'string':
71
28
  case 'bigint': {
72
- return [bigintSerialize(value)];
29
+ return checkSelf(djs)(state);
73
30
  }
74
31
  default: {
75
- if (value === null) {
76
- return nullSerialize;
32
+ if (djs === null) {
33
+ return state;
77
34
  }
78
- if (value === undefined) {
79
- return undefinedSerialize;
35
+ if (djs === undefined) {
36
+ return state;
80
37
  }
81
- if (value instanceof Array) {
82
- return arraySerialize(value);
38
+ if (djs instanceof Array) {
39
+ return checkSelf(djs)(fold(op)(state)(djs));
83
40
  }
84
- return objectSerialize(value);
41
+ return checkSelf(djs)(fold(op)(state)(map(entryValue)(entries(djs))));
85
42
  }
86
43
  }
87
44
  };
88
- const arraySerialize = compose(map(f))(arrayWrap);
89
- return f;
45
+ const init = { added: new Set(), consts: [] };
46
+ return djs => op(djs)(init).consts;
90
47
  };
91
- const serializeWithConst = sort => refs => root => {
48
+ const entryValue = kv => kv[1];
49
+ const noRef = () => null;
50
+ const buildSerialize = refLookup => sort => {
92
51
  const propertySerialize = ([k, v]) => flat([
93
52
  stringSerialize(k),
94
53
  colon,
@@ -101,11 +60,9 @@ const serializeWithConst = sort => refs => root => {
101
60
  .map(objectWrap)
102
61
  .result;
103
62
  const f = value => {
104
- if (value !== root) {
105
- const refCounter = refs.get(value);
106
- if (refCounter !== undefined && refCounter[1] > 1) {
107
- return [`c${refCounter[0]}`];
108
- }
63
+ const ref = refLookup(value);
64
+ if (ref !== null) {
65
+ return ref;
109
66
  }
110
67
  switch (typeof value) {
111
68
  case 'boolean': {
@@ -137,6 +94,17 @@ const serializeWithConst = sort => refs => root => {
137
94
  const arraySerialize = compose(map(f))(arrayWrap);
138
95
  return f;
139
96
  };
97
+ export const serializeWithoutConst = buildSerialize(noRef);
98
+ const serializeWithConst = sort => refs => root => buildSerialize(value => {
99
+ if (value === root) {
100
+ return null;
101
+ }
102
+ const refCounter = refs.get(value);
103
+ if (refCounter !== undefined && refCounter[1] > 1) {
104
+ return [`c${refCounter[0]}`];
105
+ }
106
+ return null;
107
+ })(sort);
140
108
  const countRefsOp = djs => refs => {
141
109
  switch (typeof djs) {
142
110
  case 'boolean':
@@ -167,14 +135,14 @@ const countRefsOp = djs => refs => {
167
135
  };
168
136
  const addRef = djs => refs => {
169
137
  const refCounter = refs.get(djs);
170
- if (refCounter === undefined) {
171
- return refs.set(djs, [refs.size, 1, false]);
172
- }
173
- return refs.set(djs, [refCounter[0], refCounter[1] + 1, false]);
138
+ const newCounter = refCounter === undefined
139
+ ? [refs.size, 1]
140
+ : [refCounter[0], refCounter[1] + 1];
141
+ return new Map([...refs, [djs, newCounter]]);
174
142
  };
175
143
  export const stringify = sort => djs => {
176
144
  const refs = countRefs(djs);
177
- const consts = getConstants(djs)({ refs, consts: [] }).consts;
145
+ const consts = getConstants(refs)(djs);
178
146
  const constSerialize = entry => {
179
147
  const refCounter = refs.get(entry);
180
148
  if (refCounter === undefined) {
@@ -1,4 +1,4 @@
1
- declare const _default: {
1
+ export declare const proof: {
2
2
  stringify: ({
3
3
  testPrimitives: () => void;
4
4
  testArray: () => void;
@@ -22,4 +22,3 @@ declare const _default: {
22
22
  stringify: () => void;
23
23
  })[];
24
24
  };
25
- export default _default;
@@ -2,7 +2,7 @@ import { countRefs, stringify, stringifyAsTree } from "./module.f.js";
2
2
  import { sort } from "../../types/object/module.f.js";
3
3
  import { identity } from "../../types/function/module.f.js";
4
4
  import { setProperty } from "../../json/module.f.js";
5
- export default {
5
+ export const proof = {
6
6
  stringify: [
7
7
  {
8
8
  testPrimitives: () => {
@@ -12,15 +12,15 @@ export default {
12
12
  throw refs.size;
13
13
  }
14
14
  const refsBigInt = stringifyAsTree(sort)(refs.get(3n));
15
- if (refsBigInt !== '[0,1,false]') {
15
+ if (refsBigInt !== '[0,1]') {
16
16
  throw refsBigInt;
17
17
  }
18
18
  const refsString = stringifyAsTree(sort)(refs.get("str"));
19
- if (refsString !== '[1,1,false]') {
19
+ if (refsString !== '[1,1]') {
20
20
  throw refsString;
21
21
  }
22
22
  const refsRoot = stringifyAsTree(sort)(refs.get(djs));
23
- if (refsRoot !== '[2,1,false]') {
23
+ if (refsRoot !== '[2,1]') {
24
24
  throw refsRoot;
25
25
  }
26
26
  if (refs.get(null) !== undefined) {
@@ -35,11 +35,11 @@ export default {
35
35
  throw refs.size;
36
36
  }
37
37
  const refsArray = stringifyAsTree(sort)(refs.get(array));
38
- if (refsArray !== '[0,3,false]') {
38
+ if (refsArray !== '[0,3]') {
39
39
  throw refsArray;
40
40
  }
41
41
  const refsRoot = stringifyAsTree(sort)(refs.get(djs));
42
- if (refsRoot !== '[1,1,false]') {
42
+ if (refsRoot !== '[1,1]') {
43
43
  throw refsRoot;
44
44
  }
45
45
  },
@@ -51,11 +51,11 @@ export default {
51
51
  throw refs.size;
52
52
  }
53
53
  const refsObj = stringifyAsTree(sort)(refs.get(obj));
54
- if (refsObj !== '[0,2,false]') {
54
+ if (refsObj !== '[0,2]') {
55
55
  throw refsObj;
56
56
  }
57
57
  const refsRoot = stringifyAsTree(sort)(refs.get(djs));
58
- if (refsRoot !== '[1,1,false]') {
58
+ if (refsRoot !== '[1,1]') {
59
59
  throw refsRoot;
60
60
  }
61
61
  },
@@ -1,8 +1,7 @@
1
- declare const _default: {
1
+ export declare const proof: {
2
2
  djs: (() => void)[];
3
3
  id: (() => void)[];
4
4
  keywords: (() => void)[];
5
5
  comments: (() => void)[];
6
6
  metadata: (() => void)[];
7
7
  };
8
- export default _default;
@@ -7,7 +7,7 @@ const tokenizeString = s => toArray(map(withoutMetada)(tokenize(stringToList(s))
7
7
  const tokenizeStringWithMetadata = s => toArray(tokenize(stringToList(s))(''));
8
8
  const stringify = stringifyAsTree(sort);
9
9
  const withoutMetada = tokenWithMetada => { return tokenWithMetada.token; };
10
- export default {
10
+ export const proof = {
11
11
  djs: [
12
12
  () => {
13
13
  const result = stringify(tokenizeString(''));
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { descentParser } from "../../bnf/data/module.f.js";
7
7
  import { eof, join0Plus, max, none, not, notSet, oneEncode, option, range, remove, repeat, repeat0Plus, repeat1Plus, set, unicodeRange } from "../../bnf/module.f.js";
8
- import { todo } from "../../dev/module.f.js";
8
+ import { todo } from "../../asserts/module.f.js";
9
9
  export const parse = (input) => {
10
10
  const m = descentParser(jsGrammar());
11
11
  return todo();
@@ -1,6 +1,5 @@
1
- declare const _default: {
1
+ export declare const proof: {
2
2
  isValid: (() => void)[];
3
3
  tokenizer: (() => void)[];
4
4
  djs: (() => void)[];
5
5
  };
6
- export default _default;
@@ -108,7 +108,7 @@ const getTokensFromAstRule = ast => {
108
108
  return [token];
109
109
  return { first: token, tail: getTokensFromAstSequence(ast.sequence) };
110
110
  };
111
- export default {
111
+ export const proof = {
112
112
  isValid: [() => {
113
113
  const m = descentParser(jsGrammar());
114
114
  const expect = (s, expected) => {
@@ -10,12 +10,27 @@ import { type OrderedMap } from '../../types/ordered_map/module.f.ts';
10
10
  import { type ParseError } from '../parser/module.f.ts';
11
11
  import { type Effect } from '../../types/effects/module.f.ts';
12
12
  import { type ReadFile } from '../../types/effects/node/module.f.ts';
13
+ /**
14
+ * State threaded through the recursive transpilation of a DJS module graph.
15
+ *
16
+ * - `complete`: modules that have been fully parsed and evaluated, keyed by path.
17
+ * - `stack`: import chain currently being resolved (used to detect circular dependencies).
18
+ * - `error`: the first parse error encountered, or `null` while everything is clean.
19
+ */
13
20
  export type ParseContext = {
14
21
  readonly complete: OrderedMap<djsResult>;
15
22
  readonly stack: List<string>;
16
23
  readonly error: ParseError | null;
17
24
  };
25
+ /** The evaluated DJS value produced for one successfully transpiled module. */
18
26
  export type djsResult = {
19
27
  djs: Unknown;
20
28
  };
29
+ /**
30
+ * Transpiles a DJS module graph rooted at `path` into a single `Unknown` value.
31
+ *
32
+ * Reads each file via the `ReadFile` effect, resolves imports recursively, and
33
+ * evaluates the AST. Returns `['ok', value]` on success, or `['error', ParseError]`
34
+ * on a parse failure or circular dependency.
35
+ */
21
36
  export declare const transpile: (path: string) => Effect<ReadFile, Result<Unknown, ParseError>>;
@@ -12,7 +12,7 @@ import { stringToList } from "../../text/utf16/module.f.js";
12
12
  import { concat as pathConcat } from "../../path/module.f.js";
13
13
  import { parseFromTokens } from "../parser/module.f.js";
14
14
  import { run } from "../ast/module.f.js";
15
- import { pure } from "../../types/effects/module.f.js";
15
+ import { foldStep, pure } from "../../types/effects/module.f.js";
16
16
  import { readFile } from "../../types/effects/node/module.f.js";
17
17
  import { utf8ToString } from "../../text/module.f.js";
18
18
  const mapDjs = context => path => {
@@ -35,7 +35,8 @@ const transpileWithImports = path => parseModuleResult => context => {
35
35
  const pathsCombine = listMap(pathConcat(dir))(parseModuleResult[1][0]);
36
36
  const pathsArray = toArray(pathsCombine);
37
37
  const contextWithStack = { ...context, stack: { first: path, tail: context.stack } };
38
- return pathsArray.reduce((acc, p) => acc.step(ctx => foldNextModuleOp(p)(ctx)), pure(contextWithStack)).step(contextWithImports => {
38
+ return foldStep(foldNextModuleOp)(contextWithStack)(pathsArray)
39
+ .step(contextWithImports => {
39
40
  if (contextWithImports.error !== null) {
40
41
  return pure(contextWithImports);
41
42
  }
@@ -62,6 +63,13 @@ const foldNextModuleOp = path => context => {
62
63
  }
63
64
  return parseModule(path).step(parseModuleResult => transpileWithImports(path)(parseModuleResult)(context));
64
65
  };
66
+ /**
67
+ * Transpiles a DJS module graph rooted at `path` into a single `Unknown` value.
68
+ *
69
+ * Reads each file via the `ReadFile` effect, resolves imports recursively, and
70
+ * evaluates the AST. Returns `['ok', value]` on success, or `['error', ParseError]`
71
+ * on a parse failure or circular dependency.
72
+ */
65
73
  export const transpile = path => foldNextModuleOp(path)({ stack: null, complete: null, error: null }).step((context) => {
66
74
  if (context.error !== null) {
67
75
  return pure(error(context.error));
@@ -1,8 +1,7 @@
1
- declare const _default: {
1
+ export declare const proof: {
2
2
  parse: () => void;
3
3
  parseWithSubModule: () => void;
4
4
  parseWithSubModules: () => void;
5
5
  parseWithFileNotFoundError: () => void;
6
6
  parseWithCycleError: () => void;
7
7
  };
8
- export default _default;
@@ -7,7 +7,7 @@ const run = (root) => (path) => {
7
7
  const [_, result] = virtual({ ...emptyState, root })(transpile(path));
8
8
  return result;
9
9
  };
10
- export default {
10
+ export const proof = {
11
11
  parse: () => {
12
12
  const result = run({ a: utf8('export default 1') })('a');
13
13
  if (result[0] === 'error') {