functionalscript 0.19.0 → 0.20.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.
- package/fs/asn.1/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/asn.1/{test.f.js → proof.f.js} +1 -1
- package/fs/base128/proof.f.d.ts +1 -0
- package/fs/base128/{test.f.js → proof.f.js} +1 -1
- package/fs/bnf/data/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/bnf/data/{test.f.js → proof.f.js} +1 -1
- package/fs/bnf/proof.f.d.ts +3 -0
- package/fs/bnf/{test.f.js → proof.f.js} +1 -1
- package/fs/cas/module.f.js +2 -12
- package/fs/cas/proof.f.d.ts +1 -0
- package/fs/cas/proof.f.js +1 -0
- package/fs/cbase32/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/cbase32/{test.f.js → proof.f.js} +1 -1
- package/fs/ci/node/module.f.js +12 -7
- package/fs/ci/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/ci/{test.f.js → proof.f.js} +1 -1
- package/fs/crypto/hmac/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/crypto/hmac/{test.f.js → proof.f.js} +1 -1
- package/fs/crypto/secp/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/crypto/secp/{test.f.js → proof.f.js} +1 -1
- package/fs/crypto/sha2/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/crypto/sha2/{test.f.js → proof.f.js} +1 -1
- package/fs/crypto/sign/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/crypto/sign/{test.f.js → proof.f.js} +1 -1
- package/fs/dev/module.f.d.ts +28 -2
- package/fs/dev/module.f.js +38 -22
- package/fs/dev/{test.f.d.ts → proof.f.d.ts} +5 -2
- package/fs/dev/{test.f.js → proof.f.js} +25 -2
- package/fs/dev/tf/module.f.d.ts +63 -5
- package/fs/dev/tf/module.f.js +77 -20
- package/fs/dev/tf/{test.f.d.ts → proof.f.d.ts} +26 -0
- package/fs/dev/tf/{test.f.js → proof.f.js} +76 -34
- package/fs/dev/tf/scenarios/async-subtests.fail.d.ts +4 -0
- package/fs/dev/tf/scenarios/async-subtests.fail.js +7 -0
- package/fs/dev/tf/scenarios/async-subtests.pass.d.ts +4 -0
- package/fs/dev/tf/scenarios/async-subtests.pass.js +7 -0
- package/fs/dev/tf/scenarios/async.fail.d.ts +1 -0
- package/fs/dev/tf/scenarios/async.fail.js +4 -0
- package/fs/dev/tf/scenarios/async.pass.d.ts +1 -0
- package/fs/dev/tf/scenarios/async.pass.js +3 -0
- package/fs/dev/tf/scenarios/thenable.pass.d.ts +3 -0
- package/fs/dev/tf/scenarios/thenable.pass.js +9 -0
- package/fs/dev/tf/scenarios/thenable2.pass.f.d.ts +3 -0
- package/fs/dev/tf/scenarios/thenable2.pass.f.js +3 -0
- package/fs/dev/version/proof.f.d.ts +3 -0
- package/fs/dev/version/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/ast/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/ast/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/parser/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/parser/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/serializer/module.f.d.ts +2 -2
- package/fs/djs/serializer/module.f.js +47 -79
- package/fs/djs/serializer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/serializer/{test.f.js → proof.f.js} +8 -8
- package/fs/djs/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/tokenizer/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/tokenizer-new/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/tokenizer-new/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/transpiler/module.f.d.ts +15 -0
- package/fs/djs/transpiler/module.f.js +10 -2
- package/fs/djs/transpiler/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/transpiler/{test.f.js → proof.f.js} +1 -1
- package/fs/fsc/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/fsc/{test.f.js → proof.f.js} +1 -1
- package/fs/fsm/proof.f.d.ts +4 -0
- package/fs/fsm/{test.f.js → proof.f.js} +1 -1
- package/fs/html/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/html/{test.f.js → proof.f.js} +1 -1
- package/fs/io/module.d.ts +1 -1
- package/fs/io/module.f.d.ts +3 -2
- package/fs/io/module.f.js +4 -3
- package/fs/io/module.js +19 -11
- package/fs/js/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/js/tokenizer/{test.f.js → proof.f.js} +1 -1
- package/fs/json/parser/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/json/parser/{test.f.js → proof.f.js} +1 -1
- package/fs/json/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/json/{test.f.js → proof.f.js} +1 -1
- package/fs/json/serializer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/json/serializer/{test.f.js → proof.f.js} +1 -1
- package/fs/json/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/json/tokenizer/{test.f.js → proof.f.js} +1 -1
- package/fs/path/proof.f.d.ts +5 -0
- package/fs/path/{test.f.js → proof.f.js} +4 -3
- package/fs/sul/id/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/sul/id/{test.f.js → proof.f.js} +1 -1
- package/fs/sul/level/hash/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/sul/level/hash/{test.f.js → proof.f.js} +1 -1
- package/fs/sul/level/literal/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/sul/level/literal/{test.f.js → proof.f.js} +1 -1
- package/fs/sul/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/sul/{test.f.js → proof.f.js} +1 -1
- package/fs/text/ascii/proof.f.d.ts +3 -0
- package/fs/text/ascii/{test.f.js → proof.f.js} +1 -1
- package/fs/text/code_point/module.f.d.ts +28 -0
- package/fs/text/code_point/module.f.js +31 -0
- package/fs/text/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/text/{test.f.js → proof.f.js} +1 -1
- package/fs/text/sgr/proof.f.d.ts +1 -0
- package/fs/text/sgr/{test.f.js → proof.f.js} +1 -1
- package/fs/text/utf16/module.f.js +3 -53
- package/fs/text/utf16/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/text/utf16/{test.f.js → proof.f.js} +1 -1
- package/fs/text/utf8/module.f.js +3 -25
- package/fs/text/utf8/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/text/utf8/{test.f.js → proof.f.js} +1 -1
- package/fs/types/array/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/array/{test.f.js → proof.f.js} +1 -1
- package/fs/types/bigfloat/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/bigfloat/{test.f.js → proof.f.js} +1 -1
- package/fs/types/bigint/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/bigint/{test.f.js → proof.f.js} +1 -1
- package/fs/types/bit_vec/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/bit_vec/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/find/proof.f.d.ts +1 -0
- package/fs/types/btree/find/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/btree/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/remove/proof.f.d.ts +4 -0
- package/fs/types/btree/remove/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/set/proof.f.d.ts +1 -0
- package/fs/types/btree/set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/types/module.f.d.ts +8 -0
- package/fs/types/btree/types/module.f.js +8 -0
- package/fs/types/byte_set/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/byte_set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/effects/module.f.d.ts +17 -0
- package/fs/types/effects/module.f.js +17 -0
- package/fs/types/effects/node/module.f.d.ts +54 -5
- package/fs/types/effects/node/module.f.js +4 -1
- package/fs/types/effects/node/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/effects/node/{test.f.js → proof.f.js} +1 -1
- package/fs/types/effects/node/virtual/module.f.js +1 -0
- package/fs/types/effects/proof.f.d.ts +11 -0
- package/fs/types/effects/proof.f.js +57 -0
- package/fs/types/function/compare/proof.f.d.ts +1 -0
- package/fs/types/function/compare/{test.f.js → proof.f.js} +1 -1
- package/fs/types/function/operator/proof.f.d.ts +12 -0
- package/fs/types/function/operator/{test.f.js → proof.f.js} +11 -10
- package/fs/types/function/proof.f.d.ts +1 -0
- package/fs/types/function/{test.f.js → proof.f.js} +1 -1
- package/fs/types/list/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/list/{test.f.js → proof.f.js} +1 -1
- package/fs/types/map/proof.f.d.ts +4 -0
- package/fs/types/map/{test.f.js → proof.f.js} +1 -1
- package/fs/types/monoid/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/monoid/{test.f.js → proof.f.js} +1 -1
- package/fs/types/nibble_set/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/nibble_set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/nominal/proof.f.d.ts +4 -0
- package/fs/types/nominal/{test.f.js → proof.f.js} +1 -1
- package/fs/types/nullable/proof.f.d.ts +1 -0
- package/fs/types/nullable/{test.f.js → proof.f.js} +1 -1
- package/fs/types/number/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/number/{test.f.js → proof.f.js} +1 -1
- package/fs/types/object/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/object/{test.f.js → proof.f.js} +1 -1
- package/fs/types/ordered_map/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/ordered_map/{test.f.js → proof.f.js} +1 -1
- package/fs/types/patricia_trie/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/patricia_trie/{test.f.js → proof.f.js} +1 -1
- package/fs/types/prime_field/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/prime_field/{test.f.js → proof.f.js} +1 -1
- package/fs/types/range/proof.f.d.ts +1 -0
- package/fs/types/range/{test.f.js → proof.f.js} +1 -1
- package/fs/types/range_map/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/range_map/{test.f.js → proof.f.js} +1 -1
- package/fs/types/result/proof.f.d.ts +5 -0
- package/fs/types/result/{test.f.js → proof.f.js} +18 -2
- package/fs/types/rtti/parse/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/rtti/parse/{test.f.js → proof.f.js} +1 -1
- package/fs/types/rtti/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/rtti/{test.f.js → proof.f.js} +1 -1
- package/fs/types/rtti/ts/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/rtti/ts/{test.f.js → proof.f.js} +1 -1
- package/fs/types/rtti/validate/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/rtti/validate/{test.f.js → proof.f.js} +1 -1
- package/fs/types/sorted_list/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/sorted_list/{test.f.js → proof.f.js} +1 -1
- package/fs/types/sorted_set/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/sorted_set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/string/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/string/{test.f.js → proof.f.js} +1 -1
- package/fs/types/string_set/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/string_set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/ts/{test.f.d.ts → proof.f.d.ts} +20 -0
- package/fs/types/ts/{test.f.js → proof.f.js} +1 -0
- package/fs/types/uint8array/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/uint8array/{test.f.js → proof.f.js} +1 -1
- package/issues/demo/sample/{test.f.js → proof.f.js} +1 -1
- package/issues/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/issues/{test.f.js → proof.f.js} +1 -1
- package/nanvm-lib/tests/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/nanvm-lib/tests/{test.f.js → proof.f.js} +1 -1
- package/nanvm-lib/tests/vm/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/nanvm-lib/tests/vm/{test.f.js → proof.f.js} +1 -1
- package/package.json +2 -2
- package/fs/base128/test.f.d.ts +0 -2
- package/fs/bnf/test.f.d.ts +0 -4
- package/fs/cas/test.f.d.ts +0 -2
- package/fs/cas/test.f.js +0 -1
- package/fs/dev/version/test.f.d.ts +0 -4
- package/fs/fsm/test.f.d.ts +0 -5
- package/fs/path/test.f.d.ts +0 -3
- package/fs/text/ascii/test.f.d.ts +0 -4
- package/fs/text/sgr/test.f.d.ts +0 -2
- package/fs/types/btree/find/test.f.d.ts +0 -2
- package/fs/types/btree/remove/test.f.d.ts +0 -5
- package/fs/types/btree/set/test.f.d.ts +0 -2
- package/fs/types/function/compare/test.f.d.ts +0 -2
- package/fs/types/function/operator/test.f.d.ts +0 -10
- package/fs/types/function/test.f.d.ts +0 -2
- package/fs/types/map/test.f.d.ts +0 -5
- package/fs/types/nominal/test.f.d.ts +0 -5
- package/fs/types/nullable/test.f.d.ts +0 -2
- package/fs/types/range/test.f.d.ts +0 -2
- package/fs/types/result/test.f.d.ts +0 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const proof: () => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const
|
|
1
|
+
export declare const proof: {
|
|
2
2
|
rangeDecode: () => void;
|
|
3
3
|
rangeEncode: () => void;
|
|
4
4
|
toData: (() => void)[];
|
|
@@ -12,4 +12,3 @@ declare const _default: {
|
|
|
12
12
|
repeatParser: (() => void)[];
|
|
13
13
|
example: () => void;
|
|
14
14
|
};
|
|
15
|
-
export default _default;
|
|
@@ -11,7 +11,7 @@ const descentParserCpOnly = (m, name, cp) => {
|
|
|
11
11
|
const cpm = toArray(map(mapCodePoint)(cp));
|
|
12
12
|
return m(name, cpm);
|
|
13
13
|
};
|
|
14
|
-
export
|
|
14
|
+
export const proof = {
|
|
15
15
|
rangeDecode: () => {
|
|
16
16
|
const decoded1 = stringify(sort)(rangeDecode(0x000079_000087));
|
|
17
17
|
if (decoded1 !== '[121,135]') {
|
package/fs/cas/module.f.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { computeSync, sha256 } from "../crypto/sha2/module.f.js";
|
|
7
7
|
import { parse } from "../path/module.f.js";
|
|
8
8
|
import { cBase32ToVec, vecToCBase32 } from "../cbase32/module.f.js";
|
|
9
|
-
import { begin, pure } from "../types/effects/module.f.js";
|
|
9
|
+
import { begin, forEachStep, pure } from "../types/effects/module.f.js";
|
|
10
10
|
import { error, log, mkdir, readdir, readFile, writeFile } from "../types/effects/node/module.f.js";
|
|
11
11
|
import { toOption } from "../types/nullable/module.f.js";
|
|
12
12
|
import { unwrap } from "../types/result/module.f.js";
|
|
@@ -111,17 +111,7 @@ export const main = (args) => {
|
|
|
111
111
|
case 'list': {
|
|
112
112
|
return begin
|
|
113
113
|
.step(() => c.list())
|
|
114
|
-
.step(
|
|
115
|
-
// TODO: make it lazy.
|
|
116
|
-
let i = begin;
|
|
117
|
-
for (const j of v) {
|
|
118
|
-
const prev = i;
|
|
119
|
-
i = begin
|
|
120
|
-
.step(() => prev)
|
|
121
|
-
.step(() => log(vecToCBase32(j)));
|
|
122
|
-
}
|
|
123
|
-
return i;
|
|
124
|
-
})
|
|
114
|
+
.step(forEachStep(j => log(vecToCBase32(j))))
|
|
125
115
|
.step(() => pure(0));
|
|
126
116
|
}
|
|
127
117
|
case undefined: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const proof: () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const proof = () => { };
|
package/fs/ci/node/module.f.js
CHANGED
|
@@ -8,20 +8,25 @@ import { node, tsgo } from "../config/module.f.js";
|
|
|
8
8
|
import { clean, findTgz, install, test, ubuntu } from "../common/module.f.js";
|
|
9
9
|
export const major = (v) => v.split('.')[0];
|
|
10
10
|
const installNode = (version) => ({ uses: 'actions/setup-node@v6', with: { 'node-version': version } });
|
|
11
|
-
|
|
12
|
-
install(installNode(
|
|
11
|
+
const nodeInstall = (v) => [
|
|
12
|
+
install(installNode(v)),
|
|
13
13
|
test({ run: 'npm ci' }),
|
|
14
|
+
];
|
|
15
|
+
export const basicNode = (version) => (extra) => clean([
|
|
16
|
+
...nodeInstall(version),
|
|
14
17
|
...extra,
|
|
15
18
|
]);
|
|
16
|
-
|
|
17
|
-
test({ run: 'npm
|
|
19
|
+
const basicTests = [
|
|
20
|
+
test({ run: 'npm t' }),
|
|
18
21
|
test({ run: 'npm run fst' }),
|
|
22
|
+
];
|
|
23
|
+
export const nodeTests = (version) => (extra) => basicNode(version)([
|
|
24
|
+
...basicTests,
|
|
19
25
|
...extra,
|
|
20
26
|
]);
|
|
21
27
|
const nodeSteps = (v) => [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
test({ run: 'npm t' }),
|
|
28
|
+
...nodeInstall(v),
|
|
29
|
+
...basicTests,
|
|
25
30
|
];
|
|
26
31
|
export const nodeVersions = Object.fromEntries(node.others.map(v => [
|
|
27
32
|
`node${major(v)}`,
|
|
@@ -23,7 +23,7 @@ const run = (rust, nodeExtra = () => []) => {
|
|
|
23
23
|
assert(isVec(file), file);
|
|
24
24
|
return unwrap(parseGitHubAction(jsonParse(utf8ToString(file))));
|
|
25
25
|
};
|
|
26
|
-
export
|
|
26
|
+
export const proof = {
|
|
27
27
|
rust: () => {
|
|
28
28
|
assert(hasRun('cargo')(run(true)), 'expected Rust steps');
|
|
29
29
|
},
|
|
@@ -2,7 +2,7 @@ import { utf8 } from "../../text/module.f.js";
|
|
|
2
2
|
import { uint, vec } from "../../types/bit_vec/module.f.js";
|
|
3
3
|
import { sha256, sha384, sha512 } from "../sha2/module.f.js";
|
|
4
4
|
import { hmac } from "./module.f.js";
|
|
5
|
-
export
|
|
5
|
+
export const proof = {
|
|
6
6
|
example: () => {
|
|
7
7
|
const r = hmac(sha256)(utf8('key'))(utf8('The quick brown fox jumps over the lazy dog'));
|
|
8
8
|
if (r !== vec(256n)(0xf7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8n)) {
|
|
@@ -12,7 +12,7 @@ const checkEmpty = ({ init, end, hashLength }) => (x) => {
|
|
|
12
12
|
// https://en.wikipedia.org/wiki/SHA-2#Test_vectors
|
|
13
13
|
//
|
|
14
14
|
// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Secure-Hashing
|
|
15
|
-
export
|
|
15
|
+
export const proof = {
|
|
16
16
|
base: {
|
|
17
17
|
b32: () => {
|
|
18
18
|
const { fromV8, compress, chunkLength } = base32;
|
package/fs/dev/module.f.d.ts
CHANGED
|
@@ -10,14 +10,40 @@ export declare const todo: () => never;
|
|
|
10
10
|
export declare const assert: (v: boolean, msg?: unknown) => asserts v;
|
|
11
11
|
export declare const assertEq: <T>(a: T, b: T) => void;
|
|
12
12
|
export type Module = {
|
|
13
|
-
readonly
|
|
13
|
+
readonly proof?: unknown;
|
|
14
14
|
readonly [k: string]: unknown;
|
|
15
15
|
};
|
|
16
16
|
export type ModuleMap = {
|
|
17
17
|
readonly [k in string]: Module;
|
|
18
18
|
};
|
|
19
19
|
export declare const env: (io: Io) => (v: string) => string | undefined;
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Returns `true` if the file should be loaded for proof discovery.
|
|
22
|
+
*
|
|
23
|
+
* All FunctionalScript modules (`.f.ts` / `.f.js`) are safe to bulk-load by
|
|
24
|
+
* construction — they have no import side effects. For vanilla TS/JS the
|
|
25
|
+
* load gate stays opt-in by filename: any file ending in `proof.ts`,
|
|
26
|
+
* `proof.js`, `proof.mts`, or `proof.mjs` is included.
|
|
27
|
+
*
|
|
28
|
+
* Whether a loaded module actually _contains_ a proof is determined at
|
|
29
|
+
* runtime by checking for an exported `proof` property.
|
|
30
|
+
*/
|
|
31
|
+
export declare const shouldLoad: (s: string) => boolean;
|
|
32
|
+
/** The effect operations required to discover and load a module map. */
|
|
21
33
|
export type LoadModuleOperations = Access | Import | All | Readdir;
|
|
34
|
+
/**
|
|
35
|
+
* Discovers all source files under `INIT_CWD` (or `.` if unset) that match
|
|
36
|
+
* `predicate`, imports them, and returns a map from relative path to module
|
|
37
|
+
* exports.
|
|
38
|
+
*
|
|
39
|
+
* The `predicate` is propagated into `allFiles` so that non-matching files
|
|
40
|
+
* are excluded before any `import()` is attempted — no wasted I/O.
|
|
41
|
+
* The default matches all JS/TS source files (`.js`, `.ts`, `.mts`, `.mjs`).
|
|
42
|
+
* `loadFile`'s own guards (`.f.js`, `.f.ts`, `shouldLoad`) still apply on
|
|
43
|
+
* top; the predicate only controls which files are discovered.
|
|
44
|
+
*
|
|
45
|
+
* The result is sorted by path key using `string.cmp` so the order is
|
|
46
|
+
* deterministic regardless of filesystem traversal order.
|
|
47
|
+
*/
|
|
22
48
|
export declare const loadModuleMap: (env: Env) => Effect<LoadModuleOperations, ModuleMap>;
|
|
23
49
|
export declare const index4: NodeProgram;
|
package/fs/dev/module.f.js
CHANGED
|
@@ -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";
|
|
@@ -13,14 +14,28 @@ export const assert = (v, msg = 'assertion failed') => {
|
|
|
13
14
|
throw msg;
|
|
14
15
|
};
|
|
15
16
|
export const assertEq = (a, b) => assert(a === b, [a, b]);
|
|
16
|
-
const cmp = ([a], [b]) => a < b ? -1 : a > b ? 1 : 0;
|
|
17
17
|
export const env = ({ process: { env } }) => a => {
|
|
18
18
|
const r = Object.getOwnPropertyDescriptor(env, a);
|
|
19
19
|
return r === undefined ? undefined :
|
|
20
20
|
typeof r.get === 'function' ? r.get() :
|
|
21
21
|
r.value;
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Returns `true` if the file should be loaded for proof discovery.
|
|
25
|
+
*
|
|
26
|
+
* All FunctionalScript modules (`.f.ts` / `.f.js`) are safe to bulk-load by
|
|
27
|
+
* construction — they have no import side effects. For vanilla TS/JS the
|
|
28
|
+
* load gate stays opt-in by filename: any file ending in `proof.ts`,
|
|
29
|
+
* `proof.js`, `proof.mts`, or `proof.mjs` is included.
|
|
30
|
+
*
|
|
31
|
+
* Whether a loaded module actually _contains_ a proof is determined at
|
|
32
|
+
* runtime by checking for an exported `proof` property.
|
|
33
|
+
*/
|
|
34
|
+
export const shouldLoad = (s) => s.endsWith('.f.ts') || s.endsWith('.f.js') ||
|
|
35
|
+
s.endsWith('proof.ts') || s.endsWith('proof.js') ||
|
|
36
|
+
s.endsWith('proof.mts') || s.endsWith('proof.mjs');
|
|
37
|
+
const isSourceFile = (path) => path.endsWith('.js') || path.endsWith('.ts') || path.endsWith('.mts') || path.endsWith('.mjs');
|
|
38
|
+
const allFiles = (s, predicate) => {
|
|
24
39
|
const load = (p) => begin
|
|
25
40
|
.step(() => readdir(p, {}))
|
|
26
41
|
.step(d => {
|
|
@@ -38,7 +53,7 @@ export const allFiles = (s) => {
|
|
|
38
53
|
result = [...result, load(file)];
|
|
39
54
|
continue;
|
|
40
55
|
}
|
|
41
|
-
if (
|
|
56
|
+
if (predicate(file)) {
|
|
42
57
|
result = [...result, pure([file])];
|
|
43
58
|
}
|
|
44
59
|
}
|
|
@@ -47,18 +62,22 @@ export const allFiles = (s) => {
|
|
|
47
62
|
.step(v => pure(v.flat()));
|
|
48
63
|
return load(s);
|
|
49
64
|
};
|
|
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
|
-
};
|
|
65
|
+
const loadFile = (f) => import_(f).step(r => pure([[f, unwrap(r)]]));
|
|
61
66
|
const { fromEntries } = Object;
|
|
67
|
+
/**
|
|
68
|
+
* Discovers all source files under `INIT_CWD` (or `.` if unset) that match
|
|
69
|
+
* `predicate`, imports them, and returns a map from relative path to module
|
|
70
|
+
* exports.
|
|
71
|
+
*
|
|
72
|
+
* The `predicate` is propagated into `allFiles` so that non-matching files
|
|
73
|
+
* are excluded before any `import()` is attempted — no wasted I/O.
|
|
74
|
+
* The default matches all JS/TS source files (`.js`, `.ts`, `.mts`, `.mjs`).
|
|
75
|
+
* `loadFile`'s own guards (`.f.js`, `.f.ts`, `shouldLoad`) still apply on
|
|
76
|
+
* top; the predicate only controls which files are discovered.
|
|
77
|
+
*
|
|
78
|
+
* The result is sorted by path key using `string.cmp` so the order is
|
|
79
|
+
* deterministic regardless of filesystem traversal order.
|
|
80
|
+
*/
|
|
62
81
|
export const loadModuleMap = (env) => {
|
|
63
82
|
const initCwd = env['INIT_CWD'];
|
|
64
83
|
const s = initCwd === undefined ? '.' : `${initCwd.replaceAll('\\', '/')}`;
|
|
@@ -67,24 +86,21 @@ export const loadModuleMap = (env) => {
|
|
|
67
86
|
// we should consider optimize them by ALIQ technique or something similar.
|
|
68
87
|
// For example, we should be able to write it like `allFiles(s).flatMap(loadFile)`,
|
|
69
88
|
// then an effect runner can batch all file loading operations together.
|
|
70
|
-
return allFiles(s)
|
|
89
|
+
return allFiles(s, shouldLoad)
|
|
71
90
|
.step(files => all(...files.map(loadFile)))
|
|
72
91
|
.step(entries => pure(fromEntries(entries
|
|
73
92
|
.flat()
|
|
74
93
|
.map(([k, v]) => [relativize(prefix, k), v])
|
|
75
|
-
.toSorted(
|
|
94
|
+
.toSorted(([a], [b]) => strCmp(a)(b)))));
|
|
76
95
|
};
|
|
77
96
|
const denoJson = './deno.json';
|
|
78
97
|
const parseDenoJson = rttiParse(record(rttiUnknown));
|
|
79
|
-
const index2 =
|
|
80
|
-
.step(() => updateVersion)
|
|
98
|
+
const index2 = updateVersion
|
|
81
99
|
.step(() => readFile(denoJson))
|
|
82
100
|
.step(v => pure(unwrap(parseDenoJson(jsonParse(utf8ToString(unwrap(v)))))));
|
|
83
|
-
const allFiles2aa =
|
|
84
|
-
.step(() => allFiles('.'))
|
|
101
|
+
const allFiles2aa = allFiles('.', v => v.endsWith('/module.f.ts') || v.endsWith('/module.ts'))
|
|
85
102
|
.step(files => {
|
|
86
|
-
const
|
|
87
|
-
const exportsA = list.map(v => [v, `./${v.substring(2)}`]);
|
|
103
|
+
const exportsA = files.map(v => [v, `./${v.substring(2)}`]);
|
|
88
104
|
return pure(Object.fromEntries(exportsA));
|
|
89
105
|
});
|
|
90
106
|
const index3 = both(index2)(allFiles2aa)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
declare const
|
|
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,8 @@
|
|
|
1
|
-
import { todo } from "./module.f.js";
|
|
2
|
-
export
|
|
1
|
+
import { todo, env } from "./module.f.js";
|
|
2
|
+
export const proof = {
|
|
3
|
+
shouldPass: () => ({
|
|
4
|
+
then: () => undefined
|
|
5
|
+
}),
|
|
3
6
|
ctor: () => {
|
|
4
7
|
const c = (() => { })['constructor'];
|
|
5
8
|
const f = c('return 5');
|
|
@@ -52,5 +55,25 @@ export default {
|
|
|
52
55
|
},
|
|
53
56
|
throw: () => {
|
|
54
57
|
todo();
|
|
58
|
+
},
|
|
59
|
+
env: () => {
|
|
60
|
+
const mockIo = { process: { env: { MY_VAR: 'hello' } } };
|
|
61
|
+
// missing key → undefined
|
|
62
|
+
const r1 = env(mockIo)('MISSING');
|
|
63
|
+
if (r1 !== undefined) {
|
|
64
|
+
throw r1;
|
|
65
|
+
}
|
|
66
|
+
// regular value property → returns value
|
|
67
|
+
const r2 = env(mockIo)('MY_VAR');
|
|
68
|
+
if (r2 !== 'hello') {
|
|
69
|
+
throw r2;
|
|
70
|
+
}
|
|
71
|
+
// getter property → calls get()
|
|
72
|
+
const envWithGetter = Object.defineProperty({}, 'GETTER_VAR', { get: () => 'from-getter', enumerable: true, configurable: true });
|
|
73
|
+
const mockIo2 = { process: { env: envWithGetter } };
|
|
74
|
+
const r3 = env(mockIo2)('GETTER_VAR');
|
|
75
|
+
if (r3 !== 'from-getter') {
|
|
76
|
+
throw r3;
|
|
77
|
+
}
|
|
55
78
|
}
|
|
56
79
|
};
|
package/fs/dev/tf/module.f.d.ts
CHANGED
|
@@ -1,13 +1,33 @@
|
|
|
1
|
-
import { type All, type NodeProgram, type NodeProgramOptions, type Program, type Sandbox, type SandboxResult, type Test, type TestContext, type Write } from '../../types/effects/node/module.f.ts';
|
|
1
|
+
import { type All, type Await, type NodeProgram, type NodeProgramOptions, type Program, type Sandbox, type SandboxResult, type Test, type TestContext, type Write } from '../../types/effects/node/module.f.ts';
|
|
2
2
|
import { type Effect, type Operation } from '../../types/effects/module.f.ts';
|
|
3
3
|
import { type LoadModuleOperations, type ModuleMap } from '../module.f.ts';
|
|
4
|
-
|
|
4
|
+
/** A zero-argument test function whose return value may contain sub-tests. */
|
|
5
5
|
export type TestFn = () => unknown;
|
|
6
|
+
/**
|
|
7
|
+
* A leaf test bundled with its throw expectation.
|
|
8
|
+
*
|
|
9
|
+
* `throws: true` means the test is expected to throw; the runner inverts the
|
|
10
|
+
* `sandbox` result so a caught error becomes a pass and a clean return becomes
|
|
11
|
+
* a failure. Using a record instead of a wrapper function avoids a double
|
|
12
|
+
* `sandbox` call and gives accurate per-test timing.
|
|
13
|
+
*/
|
|
6
14
|
export type TestEntry = {
|
|
7
15
|
readonly fn: TestFn;
|
|
8
16
|
readonly throws: boolean;
|
|
9
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Either a leaf `TestEntry` (function + throw flag) or a named sub-tree of
|
|
20
|
+
* `[key, value]` pairs to recurse into. Discriminate with `Array.isArray`.
|
|
21
|
+
*/
|
|
10
22
|
export type TestSet = TestEntry | readonly (readonly [string, unknown])[];
|
|
23
|
+
/**
|
|
24
|
+
* Converts an arbitrary JS value into a `TestSet`.
|
|
25
|
+
*
|
|
26
|
+
* - Zero-argument functions become a `TestEntry`; the `throws` flag is set if
|
|
27
|
+
* `throws` is already `true` or the function's `.name === 'throw'`.
|
|
28
|
+
* - Non-null objects become an array of `[key, value]` pairs to recurse into.
|
|
29
|
+
* - All other values (including functions with parameters) produce an empty array.
|
|
30
|
+
*/
|
|
11
31
|
export declare const parseTestSet: (throws: boolean, x: unknown) => TestSet;
|
|
12
32
|
type TestAndPath = readonly [Path, TestEntry];
|
|
13
33
|
/**
|
|
@@ -30,12 +50,38 @@ export type Reporter<O extends Operation> = {
|
|
|
30
50
|
readonly summary: (pass: number, fail: number, time: number) => Effect<O, void>;
|
|
31
51
|
readonly test: (file: string, path: Path, set: TestEntry) => Effect<O, SandboxResult<unknown>>;
|
|
32
52
|
};
|
|
33
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Registers all tests reachable from module export `v` (keyed by `k`) with
|
|
55
|
+
* the given `TestContext`.
|
|
56
|
+
*
|
|
57
|
+
* Unlike `runModule`, which sandboxes only the leaf function, `registerModule`
|
|
58
|
+
* lets the external framework own scheduling: each registered test callback
|
|
59
|
+
* calls `fn`, then recursively registers any sub-trees returned by the function.
|
|
60
|
+
* This is the correct model for Node `--test`, Bun, and Playwright, where tests
|
|
61
|
+
* must be declared upfront and the framework drives execution.
|
|
62
|
+
*/
|
|
63
|
+
export declare const registerModule: (ctx: TestContext, k: string, v: unknown) => Effect<Test | All | Await, void>;
|
|
64
|
+
/**
|
|
65
|
+
* Runs all test modules in `moduleMap` whose names pass `isTest`, accumulates
|
|
66
|
+
* pass/fail/time via `reporter`, and returns an exit code (0 = all passed,
|
|
67
|
+
* 1 = at least one failure).
|
|
68
|
+
*/
|
|
34
69
|
export declare const runModuleMap: <O extends Operation>(reporter: Reporter<O>) => (moduleMap: ModuleMap) => Effect<O | All, number>;
|
|
70
|
+
/**
|
|
71
|
+
* Discovers all test modules via `loadModuleMap`, then runs them through
|
|
72
|
+
* `runModuleMap`. The composed effect is a `NodeProgram` entry point for the
|
|
73
|
+
* `fjs t` test runner.
|
|
74
|
+
*/
|
|
35
75
|
export declare const testAll: <O extends Operation>(reporter: Reporter<O>) => Program<O | All | LoadModuleOperations>;
|
|
36
|
-
|
|
76
|
+
/**
|
|
77
|
+
* A chain of property-access keys leading to a test location. String entries
|
|
78
|
+
* are object/array keys; `null` marks a function-call boundary (the return
|
|
79
|
+
* value was walked as a sub-tree).
|
|
80
|
+
*/
|
|
37
81
|
export type Path = readonly (string | null)[];
|
|
82
|
+
/** Returns `true` if `s` is a non-negative decimal integer without a leading zero. */
|
|
38
83
|
export declare const isInteger: (s: string) => boolean;
|
|
84
|
+
/** Returns `true` if `s` is a valid JS identifier (ASCII subset: `[A-Za-z_$][A-Za-z0-9_$]*`). */
|
|
39
85
|
export declare const isIdentifier: (s: string) => boolean;
|
|
40
86
|
/**
|
|
41
87
|
* Renders a key chain as a JS property-access expression: identifier keys use
|
|
@@ -46,7 +92,7 @@ export declare const isIdentifier: (s: string) => boolean;
|
|
|
46
92
|
export declare const fmtPath: (path: Path) => string;
|
|
47
93
|
/**
|
|
48
94
|
* Formats a fully-qualified test identifier as a JS-like expression, e.g.
|
|
49
|
-
* `import("./math.
|
|
95
|
+
* `import("./math.proof.f.ts").add()` or `import("./a.proof.f.ts").users[3].name()`.
|
|
50
96
|
* Self-contained per line — suitable for parallel output and as a CLI filter argument.
|
|
51
97
|
*/
|
|
52
98
|
export declare const fmtImport: (file: string, path: Path) => string;
|
|
@@ -63,6 +109,10 @@ export declare const fmtTerm: (path: Path) => string;
|
|
|
63
109
|
* https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions
|
|
64
110
|
*/
|
|
65
111
|
export declare const ghEscape: (s: string) => string;
|
|
112
|
+
/**
|
|
113
|
+
* Default `Reporter.test` implementation: sandboxes `fn` once and inverts the
|
|
114
|
+
* result when `throws` is `true` (caught error → pass, clean return → fail).
|
|
115
|
+
*/
|
|
66
116
|
export declare const defaultTest: (file: string, path: Path, { fn, throws }: TestEntry) => Effect<Sandbox, SandboxResult<unknown>>;
|
|
67
117
|
/**
|
|
68
118
|
* The terminal/GitHub reporter used by `fjs t`. Output goes through
|
|
@@ -72,6 +122,14 @@ export declare const defaultTest: (file: string, path: Path, { fn, throws }: Tes
|
|
|
72
122
|
* GitHub format path can be exercised directly from tests.
|
|
73
123
|
*/
|
|
74
124
|
export declare const defaultReporter: (options: NodeProgramOptions) => Reporter<Write | Sandbox>;
|
|
125
|
+
/** The `fjs t` entry point: runs all tests using `defaultReporter`. */
|
|
75
126
|
export declare const main: NodeProgram;
|
|
127
|
+
/**
|
|
128
|
+
* Entry point for external test frameworks (Node `--test`, Bun, Playwright).
|
|
129
|
+
*
|
|
130
|
+
* Discovers test modules via `loadModuleMap`, then registers each with the
|
|
131
|
+
* framework-appropriate `TestContext` selected from `NodeProgramOptions`
|
|
132
|
+
* based on the detected `engine`.
|
|
133
|
+
*/
|
|
76
134
|
export declare const register: NodeProgram;
|
|
77
135
|
export {};
|