functionalscript 0.44.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/fjs/asn.1/module.f.mjs +8 -1
- package/fjs/asn.1/proof.f.d.mts +15 -0
- package/fjs/asn.1/proof.f.mjs +31 -3
- package/fjs/asserts/module.f.d.mts +14 -0
- package/fjs/asserts/module.f.mjs +20 -0
- package/fjs/asserts/proof.f.d.mts +3 -0
- package/fjs/asserts/proof.f.mjs +15 -1
- package/fjs/basen/base128/module.f.mjs +22 -5
- package/fjs/basen/base128/proof.f.d.mts +3 -1
- package/fjs/basen/base128/proof.f.mjs +3 -1
- package/fjs/basen/base64/module.f.mjs +7 -3
- package/fjs/basen/base64/proof.f.d.mts +3 -1
- package/fjs/basen/base64/proof.f.mjs +7 -4
- package/fjs/basen/cbase32/proof.f.d.mts +3 -1
- package/fjs/basen/cbase32/proof.f.mjs +3 -1
- package/fjs/bnf/data/module.f.d.mts +32 -6
- package/fjs/bnf/data/module.f.mjs +112 -7
- package/fjs/bnf/data/proof.f.d.mts +2 -0
- package/fjs/bnf/data/proof.f.mjs +74 -4
- package/fjs/bnf/data/types.d.ts +20 -2
- package/fjs/bnf/descent/module.f.d.mts +34 -5
- package/fjs/bnf/descent/module.f.mjs +176 -54
- package/fjs/bnf/descent/proof.f.d.mts +3 -0
- package/fjs/bnf/descent/proof.f.mjs +189 -27
- package/fjs/bnf/descent/types.d.ts +24 -18
- package/fjs/bnf/ll1/module.f.d.mts +74 -6
- package/fjs/bnf/ll1/module.f.mjs +297 -95
- package/fjs/bnf/ll1/proof.f.d.mts +17 -2
- package/fjs/bnf/ll1/proof.f.mjs +372 -137
- package/fjs/bnf/ll1/types.d.ts +25 -27
- package/fjs/bnf/matcher/module.f.d.mts +66 -0
- package/fjs/bnf/matcher/module.f.mjs +81 -0
- package/fjs/bnf/matcher/proof.f.d.mts +10 -0
- package/fjs/bnf/matcher/proof.f.mjs +79 -0
- package/fjs/bnf/matcher/types.d.ts +54 -0
- package/fjs/bnf/module.f.d.mts +15 -6
- package/fjs/bnf/module.f.mjs +52 -11
- package/fjs/bnf/proof.f.d.mts +2 -0
- package/fjs/bnf/proof.f.mjs +79 -3
- package/fjs/bnf/testlib.f.d.mts +31 -0
- package/fjs/bnf/testlib.f.mjs +80 -0
- package/fjs/bnf/token_symbol/module.f.d.mts +4 -3
- package/fjs/bnf/token_symbol/module.f.mjs +7 -6
- package/fjs/bnf/token_symbol/proof.f.mjs +5 -2
- package/fjs/bnf/token_symbol/types.d.ts +2 -2
- package/fjs/bnf/types.d.ts +10 -3
- package/fjs/cas/cli/module.f.d.mts +1 -1
- package/fjs/cas/cli/module.f.mjs +14 -20
- package/fjs/cas/cli/proof.f.d.mts +4 -4
- package/fjs/cas/cli/proof.f.mjs +47 -34
- package/fjs/cas/evo/module.f.d.mts +71 -31
- package/fjs/cas/evo/module.f.mjs +223 -138
- package/fjs/cas/evo/proof.f.d.mts +10 -1
- package/fjs/cas/evo/proof.f.mjs +311 -226
- package/fjs/cas/evo/types.d.ts +45 -9
- package/fjs/cas/module.f.d.mts +18 -32
- package/fjs/cas/module.f.mjs +164 -176
- package/fjs/cas/proof.f.d.mts +11 -8
- package/fjs/cas/proof.f.mjs +259 -147
- package/fjs/cas/types.d.ts +24 -10
- package/fjs/ci/common/module.f.d.mts +1 -1
- package/fjs/ci/common/module.f.mjs +1 -0
- package/fjs/ci/config/module.f.d.mts +3 -3
- package/fjs/ci/config/module.f.mjs +3 -3
- package/fjs/ci/module.f.d.mts +5 -5
- package/fjs/ci/module.f.mjs +8 -7
- package/fjs/ci/nix/module.f.d.mts +7 -5
- package/fjs/ci/nix/module.f.mjs +13 -12
- package/fjs/ci/nix/proof.f.d.mts +2 -0
- package/fjs/ci/nix/proof.f.mjs +4 -4
- package/fjs/ci/proof.f.d.mts +4 -2
- package/fjs/ci/proof.f.mjs +13 -8
- package/fjs/cli/module.f.d.mts +4 -6
- package/fjs/cli/module.f.mjs +4 -8
- package/fjs/cli/proof.f.d.mts +4 -2
- package/fjs/cli/proof.f.mjs +21 -18
- package/fjs/cli/types.d.ts +2 -3
- package/fjs/common/monoid/module.f.d.mts +70 -12
- package/fjs/common/monoid/module.f.mjs +177 -14
- package/fjs/common/monoid/proof.f.d.mts +12 -1
- package/fjs/common/monoid/proof.f.mjs +88 -4
- package/fjs/common/monoid/types.d.ts +23 -0
- package/fjs/crypto/hmac/module.f.mjs +2 -2
- package/fjs/crypto/secp/proof.f.d.mts +3 -1
- package/fjs/crypto/secp/proof.f.mjs +3 -1
- package/fjs/crypto/sha2/module.f.mjs +3 -1
- package/fjs/crypto/sha2/proof.f.d.mts +4 -1
- package/fjs/crypto/sha2/proof.f.mjs +27 -1
- package/fjs/crypto/sha2/types.d.ts +11 -0
- package/fjs/crypto/sign/module.f.mjs +2 -2
- package/fjs/crypto/vdf/module.f.d.mts +23 -4
- package/fjs/crypto/vdf/module.f.mjs +6 -4
- package/fjs/dev/module.f.d.mts +17 -5
- package/fjs/dev/module.f.mjs +60 -30
- package/fjs/dev/update/module.f.d.mts +11 -3
- package/fjs/dev/update/module.f.mjs +16 -11
- package/fjs/dev/update/proof.f.d.mts +4 -3
- package/fjs/dev/update/proof.f.mjs +11 -7
- package/fjs/djs/module.f.d.mts +13 -5
- package/fjs/djs/module.f.mjs +31 -16
- package/fjs/djs/parser/module.f.d.mts +16 -3
- package/fjs/djs/parser/module.f.mjs +135 -16
- package/fjs/djs/parser/proof.f.d.mts +8 -1
- package/fjs/djs/parser/proof.f.mjs +287 -13
- package/fjs/djs/parser/types.d.ts +7 -1
- package/fjs/djs/proof.f.d.mts +20 -1
- package/fjs/djs/proof.f.mjs +190 -12
- package/fjs/djs/serializer/module.f.d.mts +25 -8
- package/fjs/djs/serializer/module.f.mjs +66 -19
- package/fjs/djs/serializer/proof.f.d.mts +5 -0
- package/fjs/djs/serializer/proof.f.mjs +23 -1
- package/fjs/djs/tokenizer/module.f.d.mts +17 -5
- package/fjs/djs/tokenizer/module.f.mjs +120 -73
- package/fjs/djs/tokenizer/proof.f.d.mts +3 -0
- package/fjs/djs/tokenizer/proof.f.mjs +86 -67
- package/fjs/djs/transpiler/module.f.d.mts +13 -19
- package/fjs/djs/transpiler/module.f.mjs +79 -72
- package/fjs/djs/transpiler/types.d.ts +29 -0
- package/fjs/djs/types.d.ts +7 -1
- package/fjs/effects/list/module.f.d.mts +23 -12
- package/fjs/effects/list/module.f.mjs +16 -12
- package/fjs/effects/list/types.d.ts +27 -7
- package/fjs/effects/memory/module.f.d.mts +6 -3
- package/fjs/effects/memory/module.f.mjs +7 -7
- package/fjs/effects/memory/proof.f.d.mts +4 -0
- package/fjs/effects/memory/proof.f.mjs +18 -9
- package/fjs/effects/memory/types.d.ts +4 -3
- package/fjs/effects/mock/module.f.d.mts +28 -4
- package/fjs/effects/mock/module.f.mjs +39 -5
- package/fjs/effects/mock/types.d.ts +10 -1
- package/fjs/effects/module.d.mts +12 -2
- package/fjs/effects/module.f.d.mts +469 -281
- package/fjs/effects/module.f.mjs +538 -299
- package/fjs/effects/module.mjs +11 -2
- package/fjs/effects/node/memory/module.d.mts +7 -2
- package/fjs/effects/node/memory/module.mjs +9 -5
- package/fjs/effects/node/memory/proof.d.mts +2 -0
- package/fjs/effects/node/memory/proof.mjs +12 -5
- package/fjs/effects/node/module.d.mts +8 -2
- package/fjs/effects/node/module.f.d.mts +183 -43
- package/fjs/effects/node/module.f.mjs +260 -62
- package/fjs/effects/node/module.mjs +61 -50
- package/fjs/effects/node/proof.f.d.mts +28 -2
- package/fjs/effects/node/proof.f.mjs +161 -42
- package/fjs/effects/node/types.d.ts +106 -18
- package/fjs/effects/node/virtual/module.f.d.mts +21 -4
- package/fjs/effects/node/virtual/module.f.mjs +113 -70
- package/fjs/effects/node/virtual/proof.f.d.mts +31 -2
- package/fjs/effects/node/virtual/proof.f.mjs +201 -8
- package/fjs/effects/proof.f.d.mts +69 -34
- package/fjs/effects/proof.f.mjs +413 -130
- package/fjs/effects/types.d.ts +161 -33
- package/fjs/emergent_testing/all.test.d.mts +8 -0
- package/fjs/emergent_testing/all.test.mjs +14 -0
- package/fjs/emergent_testing/module.f.d.mts +22 -10
- package/fjs/emergent_testing/module.f.mjs +119 -85
- package/fjs/emergent_testing/proof.f.d.mts +21 -7
- package/fjs/emergent_testing/proof.f.mjs +169 -35
- package/fjs/emergent_testing/types.d.ts +22 -4
- package/fjs/fsc/bnf.f.d.mts +3 -0
- package/fjs/fsc/bnf.f.mjs +4 -1
- package/fjs/fsc/json.f.d.mts +3 -0
- package/fjs/fsc/json.f.mjs +4 -1
- package/fjs/fsc/module.f.d.mts +9 -0
- package/fjs/fsc/module.f.mjs +5 -3
- package/fjs/fsm/module.f.d.mts +14 -4
- package/fjs/fsm/module.f.mjs +54 -37
- package/fjs/fsm/proof.f.d.mts +5 -0
- package/fjs/fsm/proof.f.mjs +87 -115
- package/fjs/js/keywords/module.f.d.mts +52 -0
- package/fjs/js/keywords/module.f.mjs +72 -0
- package/fjs/{emergent_testing/scenarios/return-value.pass.d.ts → js/keywords/proof.f.d.mts} +1 -1
- package/fjs/js/keywords/proof.f.mjs +13 -0
- package/fjs/js/tokenizer/module.f.d.mts +30 -3
- package/fjs/js/tokenizer/module.f.mjs +161 -211
- package/fjs/js/tokenizer/proof.f.d.mts +1 -0
- package/fjs/js/tokenizer/proof.f.mjs +54 -24
- package/fjs/js/tokenizer/types.d.ts +33 -24
- package/fjs/mcp/cas/module.f.d.mts +1 -6
- package/fjs/mcp/cas/module.f.mjs +55 -51
- package/fjs/mcp/cas/proof.f.d.mts +15 -0
- package/fjs/mcp/cas/proof.f.mjs +174 -0
- package/fjs/mcp/evo/module.f.d.mts +19 -10
- package/fjs/mcp/evo/module.f.mjs +48 -27
- package/fjs/mcp/evo/proof.f.d.mts +6 -1
- package/fjs/mcp/evo/proof.f.mjs +115 -31
- package/fjs/mcp/module.f.d.mts +39 -4
- package/fjs/mcp/module.f.mjs +14 -12
- package/fjs/mcp/proof.f.d.mts +13 -1
- package/fjs/mcp/proof.f.mjs +120 -61
- package/fjs/media/html/module.f.d.mts +12 -0
- package/fjs/media/html/module.f.mjs +7 -5
- package/fjs/media/html/proof.f.d.mts +3 -0
- package/fjs/media/html/proof.f.mjs +4 -1
- package/fjs/media/json/extended/module.f.d.mts +82 -0
- package/fjs/media/json/extended/module.f.mjs +153 -0
- package/fjs/media/json/extended/proof.f.d.mts +42 -0
- package/fjs/media/json/extended/proof.f.mjs +127 -0
- package/fjs/media/json/extended/types.d.ts +23 -0
- package/fjs/media/json/module.f.d.mts +8 -2
- package/fjs/media/json/module.f.mjs +43 -41
- package/fjs/media/json/number/module.f.d.mts +59 -0
- package/fjs/media/json/number/module.f.mjs +136 -0
- package/fjs/media/json/number/proof.f.d.mts +24 -0
- package/fjs/media/json/number/proof.f.mjs +86 -0
- package/fjs/media/json/number/types.d.ts +28 -0
- package/fjs/media/json/parser/module.f.d.mts +25 -13
- package/fjs/media/json/parser/module.f.mjs +133 -72
- package/fjs/media/json/parser/proof.f.d.mts +5 -0
- package/fjs/media/json/parser/proof.f.mjs +31 -1
- package/fjs/media/json/parser/types.d.ts +38 -14
- package/fjs/media/json/rtti/module.f.d.mts +1 -1
- package/fjs/media/json/rtti/module.f.mjs +1 -1
- package/fjs/media/json/rtti/proof.f.d.mts +3 -0
- package/fjs/media/json/rtti/proof.f.mjs +12 -12
- package/fjs/media/json/schema/module.f.d.mts +61 -27
- package/fjs/media/json/schema/module.f.mjs +218 -63
- package/fjs/media/json/schema/proof.f.d.mts +41 -1
- package/fjs/media/json/schema/proof.f.mjs +220 -9
- package/fjs/media/json/serializer/module.f.d.mts +44 -0
- package/fjs/media/json/serializer/module.f.mjs +71 -9
- package/fjs/media/json/tokenizer/module.f.d.mts +8 -0
- package/fjs/media/json/tokenizer/module.f.mjs +31 -8
- package/fjs/media/json/tokenizer/proof.f.d.mts +6 -0
- package/fjs/media/json/tokenizer/proof.f.mjs +62 -21
- package/fjs/media/json/types.d.ts +36 -10
- package/fjs/media/lock/module.f.d.mts +100 -0
- package/fjs/media/lock/module.f.mjs +125 -0
- package/fjs/media/lock/proof.f.d.mts +33 -0
- package/fjs/media/lock/proof.f.mjs +196 -0
- package/fjs/media/lock/types.d.ts +15 -0
- package/fjs/media/module.f.d.mts +6 -5
- package/fjs/media/module.f.mjs +8 -7
- package/fjs/media/nix/module.f.d.mts +13 -0
- package/fjs/media/nix/module.f.mjs +4 -2
- package/fjs/media/nix/proof.f.d.mts +3 -0
- package/fjs/media/nix/proof.f.mjs +4 -1
- package/fjs/media/note/module.f.d.mts +121 -0
- package/fjs/media/note/module.f.mjs +131 -0
- package/fjs/media/note/proof.f.d.mts +29 -0
- package/fjs/media/note/proof.f.mjs +150 -0
- package/fjs/media/note/types.d.ts +10 -0
- package/fjs/media/proof.f.d.mts +4 -1
- package/fjs/media/proof.f.mjs +40 -21
- package/fjs/media/revision/module.f.d.mts +83 -7
- package/fjs/media/revision/module.f.mjs +127 -23
- package/fjs/media/revision/proof.f.d.mts +14 -0
- package/fjs/media/revision/proof.f.mjs +93 -2
- package/fjs/media/revision/types.d.ts +34 -5
- package/fjs/media/type/module.f.d.mts +53 -18
- package/fjs/media/type/module.f.mjs +87 -97
- package/fjs/media/type/proof.f.d.mts +17 -0
- package/fjs/media/type/proof.f.mjs +73 -13
- package/fjs/module.d.mts +5 -0
- package/fjs/module.f.d.mts +8 -0
- package/fjs/module.f.mjs +33 -10
- package/fjs/module.mjs +6 -0
- package/fjs/nanvm/proof.f.mjs +3 -3
- package/fjs/nanvm/rust/module.f.mjs +1 -1
- package/fjs/nanvm/update/module.f.d.mts +4 -4
- package/fjs/nanvm/update/module.f.mjs +8 -9
- package/fjs/nanvm/update/proof.f.mjs +4 -3
- package/fjs/path/module.f.d.mts +8 -0
- package/fjs/path/module.f.mjs +4 -2
- package/fjs/proof.f.d.mts +7 -3
- package/fjs/proof.f.mjs +41 -12
- package/fjs/protocol/json_rpc/module.f.d.mts +3 -3
- package/fjs/protocol/json_rpc/module.f.mjs +10 -7
- package/fjs/protocol/json_rpc/proof.f.d.mts +6 -0
- package/fjs/protocol/json_rpc/proof.f.mjs +26 -5
- package/fjs/protocol/mcp/module.f.d.mts +10 -13
- package/fjs/protocol/mcp/module.f.mjs +74 -58
- package/fjs/protocol/mcp/proof.f.d.mts +16 -3
- package/fjs/protocol/mcp/proof.f.mjs +224 -69
- package/fjs/protocol/mcp/stdio/module.f.d.mts +17 -11
- package/fjs/protocol/mcp/stdio/module.f.mjs +39 -33
- package/fjs/protocol/mcp/stdio/proof.f.d.mts +5 -3
- package/fjs/protocol/mcp/stdio/proof.f.mjs +46 -13
- package/fjs/protocol/mcp/stdio/types.d.ts +14 -0
- package/fjs/protocol/mcp/types.d.ts +17 -6
- package/fjs/sul/id/module.f.d.mts +4 -0
- package/fjs/sul/id/module.f.mjs +6 -6
- package/fjs/sul/level/hash/module.f.d.mts +4 -1
- package/fjs/sul/level/hash/module.f.mjs +6 -4
- package/fjs/sul/level/hash/proof.f.d.mts +4 -0
- package/fjs/sul/level/hash/proof.f.mjs +7 -4
- package/fjs/sul/level/literal/module.f.d.mts +4 -1
- package/fjs/sul/level/literal/module.f.mjs +4 -3
- package/fjs/sul/level/literal/proof.f.d.mts +3 -0
- package/fjs/sul/level/literal/proof.f.mjs +4 -1
- package/fjs/sul/module.f.d.mts +5 -3
- package/fjs/sul/module.f.mjs +23 -17
- package/fjs/sul/proof.f.d.mts +4 -0
- package/fjs/sul/proof.f.mjs +5 -2
- package/fjs/text/ascii/module.f.d.mts +26 -0
- package/fjs/text/ascii/module.f.mjs +49 -1
- package/fjs/text/ascii/proof.f.d.mts +10 -0
- package/fjs/text/ascii/proof.f.mjs +33 -1
- package/fjs/text/code_point/module.f.d.mts +29 -3
- package/fjs/text/code_point/module.f.mjs +32 -9
- package/fjs/text/code_point/proof.f.d.mts +2 -0
- package/fjs/text/code_point/proof.f.mjs +39 -0
- package/fjs/text/module.f.d.mts +4 -2
- package/fjs/text/module.f.mjs +4 -3
- package/fjs/text/proof.f.d.mts +3 -0
- package/fjs/text/proof.f.mjs +4 -1
- package/fjs/text/sgr/module.f.d.mts +6 -5
- package/fjs/text/sgr/module.f.mjs +8 -8
- package/fjs/text/sgr/proof.f.d.mts +3 -0
- package/fjs/text/sgr/proof.f.mjs +4 -1
- package/fjs/text/utf16/module.f.d.mts +5 -1
- package/fjs/text/utf16/module.f.mjs +38 -35
- package/fjs/text/utf16/proof.f.d.mts +3 -1
- package/fjs/text/utf16/proof.f.mjs +19 -2
- package/fjs/text/utf8/module.f.d.mts +9 -5
- package/fjs/text/utf8/module.f.mjs +20 -20
- package/fjs/types/array/module.f.d.mts +2 -1
- package/fjs/types/array/module.f.mjs +16 -4
- package/fjs/types/bigfloat/module.f.d.mts +21 -1
- package/fjs/types/bigfloat/module.f.mjs +33 -7
- package/fjs/types/bigfloat/proof.f.d.mts +1 -0
- package/fjs/types/bigfloat/proof.f.mjs +46 -0
- package/fjs/types/bigint/module.f.d.mts +4 -0
- package/fjs/types/bigint/module.f.mjs +4 -3
- package/fjs/types/bit_vec/module.f.d.mts +10 -16
- package/fjs/types/bit_vec/module.f.mjs +99 -95
- package/fjs/types/bit_vec/proof.f.d.mts +6 -0
- package/fjs/types/bit_vec/proof.f.mjs +31 -5
- package/fjs/types/btree/find/module.f.d.mts +5 -1
- package/fjs/types/btree/find/module.f.mjs +5 -5
- package/fjs/types/btree/find/proof.f.d.mts +5 -1
- package/fjs/types/btree/find/proof.f.mjs +5 -3
- package/fjs/types/btree/module.f.d.mts +3 -0
- package/fjs/types/btree/module.f.mjs +3 -2
- package/fjs/types/btree/proof.f.d.mts +5 -1
- package/fjs/types/btree/proof.f.mjs +5 -3
- package/fjs/types/btree/remove/module.f.d.mts +11 -0
- package/fjs/types/btree/remove/module.f.mjs +10 -10
- package/fjs/types/btree/remove/proof.f.d.mts +3 -0
- package/fjs/types/btree/remove/proof.f.mjs +4 -1
- package/fjs/types/btree/set/module.f.d.mts +9 -0
- package/fjs/types/btree/set/module.f.mjs +14 -17
- package/fjs/types/btree/set/proof.f.d.mts +3 -0
- package/fjs/types/btree/set/proof.f.mjs +16 -1
- package/fjs/types/btree/types/module.f.d.mts +2 -1
- package/fjs/types/btree/types/module.f.mjs +2 -1
- package/fjs/types/byte_set/module.f.d.mts +20 -4
- package/fjs/types/byte_set/module.f.mjs +18 -8
- package/fjs/types/byte_set/proof.f.d.mts +3 -1
- package/fjs/types/byte_set/proof.f.mjs +10 -8
- package/fjs/types/function/compare/module.f.d.mts +3 -2
- package/fjs/types/function/compare/module.f.mjs +13 -5
- package/fjs/types/function/module.f.d.mts +8 -1
- package/fjs/types/function/module.f.mjs +8 -1
- package/fjs/types/function/operator/module.f.d.mts +2 -1
- package/fjs/types/function/operator/module.f.mjs +2 -2
- package/fjs/types/list/module.f.d.mts +10 -3
- package/fjs/types/list/module.f.mjs +6 -4
- package/fjs/types/list/proof.f.d.mts +4 -1
- package/fjs/types/list/proof.f.mjs +4 -2
- package/fjs/types/nibble_set/module.f.d.mts +2 -1
- package/fjs/types/nibble_set/module.f.mjs +2 -2
- package/fjs/types/nominal/module.f.d.mts +2 -1
- package/fjs/types/nominal/module.f.mjs +2 -1
- package/fjs/types/nullable/module.f.d.mts +26 -6
- package/fjs/types/nullable/module.f.mjs +25 -6
- package/fjs/types/nullable/proof.f.d.mts +4 -0
- package/fjs/types/nullable/proof.f.mjs +15 -0
- package/fjs/types/number/module.f.d.mts +4 -0
- package/fjs/types/number/module.f.mjs +4 -3
- package/fjs/types/object/module.f.d.mts +26 -4
- package/fjs/types/object/module.f.mjs +26 -7
- package/fjs/types/object/proof.f.d.mts +5 -2
- package/fjs/types/object/proof.f.mjs +6 -3
- package/fjs/types/object/structurally_same/module.f.d.mts +39 -0
- package/fjs/types/object/structurally_same/module.f.mjs +59 -0
- package/fjs/types/object/structurally_same/proof.f.d.mts +6 -0
- package/fjs/types/object/structurally_same/proof.f.mjs +73 -0
- package/fjs/types/ordered_map/module.f.d.mts +5 -0
- package/fjs/types/ordered_map/module.f.mjs +5 -4
- package/fjs/types/ordered_map/proof.f.d.mts +3 -0
- package/fjs/types/ordered_map/proof.f.mjs +4 -1
- package/fjs/types/patricia_trie/module.f.d.mts +2 -1
- package/fjs/types/patricia_trie/module.f.mjs +27 -12
- package/fjs/types/patricia_trie/proof.f.d.mts +3 -0
- package/fjs/types/patricia_trie/proof.f.mjs +4 -1
- package/fjs/types/prime_field/module.f.d.mts +3 -1
- package/fjs/types/prime_field/module.f.mjs +3 -2
- package/fjs/types/range/module.f.d.mts +2 -1
- package/fjs/types/range/module.f.mjs +2 -2
- package/fjs/types/range_map/module.f.d.mts +6 -0
- package/fjs/types/range_map/module.f.mjs +6 -9
- package/fjs/types/range_map/proof.f.d.mts +5 -1
- package/fjs/types/range_map/proof.f.mjs +5 -3
- package/fjs/types/range_set/module.f.d.mts +5 -0
- package/fjs/types/range_set/module.f.mjs +1 -0
- package/fjs/types/range_set/proof.f.d.mts +3 -0
- package/fjs/types/range_set/proof.f.mjs +4 -1
- package/fjs/types/result/module.d.mts +8 -0
- package/fjs/types/result/module.f.d.mts +37 -7
- package/fjs/types/result/module.f.mjs +38 -8
- package/fjs/types/result/module.mjs +9 -1
- package/fjs/types/result/proof.f.d.mts +5 -0
- package/fjs/types/result/proof.f.mjs +22 -2
- package/fjs/types/rtti/common/module.f.d.mts +44 -14
- package/fjs/types/rtti/common/module.f.mjs +42 -36
- package/fjs/types/rtti/common/proof.f.d.mts +4 -0
- package/fjs/types/rtti/common/proof.f.mjs +10 -7
- package/fjs/types/rtti/data/module.f.d.mts +134 -0
- package/fjs/types/rtti/data/module.f.mjs +1053 -0
- package/fjs/types/rtti/data/proof.f.d.mts +76 -0
- package/fjs/types/rtti/data/proof.f.mjs +589 -0
- package/fjs/types/rtti/data/types.d.ts +83 -0
- package/fjs/types/rtti/module.f.d.mts +12 -5
- package/fjs/types/rtti/module.f.mjs +7 -5
- package/fjs/types/rtti/parse/module.f.d.mts +48 -0
- package/fjs/types/rtti/parse/module.f.mjs +45 -34
- package/fjs/types/rtti/parse/proof.f.d.mts +3 -2
- package/fjs/types/rtti/parse/proof.f.mjs +51 -52
- package/fjs/types/rtti/proof.f.d.mts +3 -1
- package/fjs/types/rtti/proof.f.mjs +6 -2
- package/fjs/types/rtti/ts/module.f.d.mts +68 -9
- package/fjs/types/rtti/ts/module.f.mjs +258 -30
- package/fjs/types/rtti/ts/proof.f.d.mts +44 -0
- package/fjs/types/rtti/ts/proof.f.mjs +152 -4
- package/fjs/types/rtti/ts/types.d.ts +25 -1
- package/fjs/types/rtti/types.d.ts +40 -0
- package/fjs/types/sorted_list/module.f.d.mts +4 -1
- package/fjs/types/sorted_list/module.f.mjs +21 -12
- package/fjs/types/sorted_list/proof.f.d.mts +3 -1
- package/fjs/types/sorted_list/proof.f.mjs +3 -1
- package/fjs/types/sorted_set/module.f.d.mts +49 -1
- package/fjs/types/sorted_set/module.f.mjs +26 -2
- package/fjs/types/sorted_set/proof.f.d.mts +4 -1
- package/fjs/types/sorted_set/proof.f.mjs +19 -2
- package/fjs/types/string/module.f.d.mts +4 -0
- package/fjs/types/string/module.f.mjs +4 -3
- package/fjs/types/string_set/module.f.d.mts +3 -1
- package/fjs/types/string_set/module.f.mjs +3 -2
- package/fjs/types/ts/module.f.d.mts +2 -0
- package/fjs/types/ts/module.f.mjs +3 -3
- package/fjs/types/ts/proof.f.d.mts +1 -0
- package/fjs/types/ts/proof.f.mjs +5 -0
- package/fjs/types/ts/types.d.ts +6 -1
- package/fjs/types/uint8array/module.f.d.mts +13 -2
- package/fjs/types/uint8array/module.f.mjs +20 -15
- package/fjs/website/module.f.d.mts +5 -2
- package/fjs/website/module.f.mjs +6 -8
- package/fjs/website/proof.f.mjs +2 -1
- package/package.json +3 -3
- package/fjs/asn.1/types.js +0 -6
- package/fjs/asserts/types.js +0 -6
- package/fjs/basen/types.js +0 -6
- package/fjs/bnf/data/types.js +0 -6
- package/fjs/bnf/descent/types.js +0 -6
- package/fjs/bnf/ll1/types.js +0 -6
- package/fjs/bnf/token_symbol/types.js +0 -6
- package/fjs/bnf/types.js +0 -6
- package/fjs/cas/evo/types.js +0 -7
- package/fjs/cas/types.js +0 -6
- package/fjs/ci/common/types.js +0 -1
- package/fjs/ci/nix/types.js +0 -6
- package/fjs/ci/types.js +0 -6
- package/fjs/cli/types.js +0 -6
- package/fjs/common/monoid/types.js +0 -6
- package/fjs/crypto/pow/types.js +0 -6
- package/fjs/crypto/secp/types.js +0 -6
- package/fjs/crypto/sha2/types.js +0 -6
- package/fjs/crypto/sign/types.js +0 -6
- package/fjs/crypto/vdf/types.js +0 -6
- package/fjs/dev/package_json/module.f.d.mts +0 -32
- package/fjs/dev/package_json/module.f.mjs +0 -37
- package/fjs/dev/package_json/proof.f.d.mts +0 -6
- package/fjs/dev/package_json/proof.f.mjs +0 -32
- package/fjs/dev/types.js +0 -6
- package/fjs/djs/ast/types.js +0 -8
- package/fjs/djs/parser/types.js +0 -7
- package/fjs/djs/tokenizer/types.js +0 -7
- package/fjs/djs/types.js +0 -7
- package/fjs/effects/eff/module.f.d.mts +0 -10
- package/fjs/effects/eff/module.f.mjs +0 -68
- package/fjs/effects/eff/proof.f.d.mts +0 -12
- package/fjs/effects/eff/proof.f.mjs +0 -66
- package/fjs/effects/eff/types.d.ts +0 -71
- package/fjs/effects/eff/types.js +0 -6
- package/fjs/effects/list/types.js +0 -6
- package/fjs/effects/memory/types.js +0 -6
- package/fjs/effects/mock/types.js +0 -6
- package/fjs/effects/node/types.js +0 -6
- package/fjs/effects/node/virtual/types.js +0 -7
- package/fjs/effects/types.js +0 -6
- package/fjs/emergent_testing/all.test.d.ts +0 -1
- package/fjs/emergent_testing/all.test.js +0 -5
- package/fjs/emergent_testing/scenarios/all.d.ts +0 -1
- package/fjs/emergent_testing/scenarios/all.js +0 -1
- package/fjs/emergent_testing/scenarios/async-subtests.fail.d.ts +0 -6
- package/fjs/emergent_testing/scenarios/async-subtests.fail.js +0 -9
- package/fjs/emergent_testing/scenarios/async-subtests.pass.d.ts +0 -6
- package/fjs/emergent_testing/scenarios/async-subtests.pass.js +0 -9
- package/fjs/emergent_testing/scenarios/async.fail.d.ts +0 -3
- package/fjs/emergent_testing/scenarios/async.fail.js +0 -6
- package/fjs/emergent_testing/scenarios/async.pass.d.ts +0 -3
- package/fjs/emergent_testing/scenarios/async.pass.js +0 -5
- package/fjs/emergent_testing/scenarios/fail.fail.d.ts +0 -3
- package/fjs/emergent_testing/scenarios/fail.fail.js +0 -3
- package/fjs/emergent_testing/scenarios/return-value.pass.js +0 -4
- package/fjs/emergent_testing/scenarios/thenable.pass.d.ts +0 -5
- package/fjs/emergent_testing/scenarios/thenable.pass.js +0 -11
- package/fjs/emergent_testing/scenarios/thenable2.pass.d.ts +0 -5
- package/fjs/emergent_testing/scenarios/thenable2.pass.js +0 -3
- package/fjs/emergent_testing/scenarios/throw.pass.d.ts +0 -5
- package/fjs/emergent_testing/scenarios/throw.pass.js +0 -3
- package/fjs/emergent_testing/types.js +0 -6
- package/fjs/js/tokenizer/types.js +0 -6
- package/fjs/media/html/types.js +0 -6
- package/fjs/media/json/parser/types.js +0 -6
- package/fjs/media/json/tokenizer/types.js +0 -6
- package/fjs/media/json/types.js +0 -13
- package/fjs/media/nix/types.js +0 -6
- package/fjs/media/revision/types.js +0 -8
- package/fjs/media/type/types.js +0 -6
- package/fjs/media/types.js +0 -7
- package/fjs/nanvm/types.js +0 -11
- package/fjs/protocol/json_rpc/types.js +0 -8
- package/fjs/protocol/mcp/types.js +0 -8
- package/fjs/sul/id/types.js +0 -6
- package/fjs/sul/level/hash/types.js +0 -6
- package/fjs/sul/level/literal/types.js +0 -6
- package/fjs/sul/types.js +0 -6
- package/fjs/text/sgr/types.js +0 -6
- package/fjs/text/types.js +0 -6
- package/fjs/text/utf16/types.js +0 -6
- package/fjs/text/utf8/types.js +0 -6
- package/fjs/types/array/types.js +0 -6
- package/fjs/types/bigfloat/types.js +0 -6
- package/fjs/types/bigint/types.js +0 -6
- package/fjs/types/bit_vec/types.js +0 -6
- package/fjs/types/btree/find/types.js +0 -6
- package/fjs/types/btree/types/types.js +0 -6
- package/fjs/types/byte_set/types.js +0 -6
- package/fjs/types/function/compare/types.js +0 -6
- package/fjs/types/function/operator/types.js +0 -6
- package/fjs/types/function/types.js +0 -6
- package/fjs/types/list/types.js +0 -6
- package/fjs/types/nibble_set/types.js +0 -6
- package/fjs/types/nominal/types.js +0 -6
- package/fjs/types/nullable/types.js +0 -6
- package/fjs/types/object/types.js +0 -8
- package/fjs/types/option/types.js +0 -6
- package/fjs/types/ordered_map/types.js +0 -6
- package/fjs/types/patricia_trie/types.js +0 -6
- package/fjs/types/phantom/types.js +0 -11
- package/fjs/types/prime_field/types.js +0 -6
- package/fjs/types/range/types.js +0 -6
- package/fjs/types/range_map/types.js +0 -6
- package/fjs/types/result/types.js +0 -6
- package/fjs/types/rtti/common/types.js +0 -1
- package/fjs/types/rtti/parse/types.js +0 -1
- package/fjs/types/rtti/ts/types.js +0 -1
- package/fjs/types/rtti/types.js +0 -1
- package/fjs/types/rtti/validate/module.f.d.mts +0 -6
- package/fjs/types/rtti/validate/module.f.mjs +0 -169
- package/fjs/types/rtti/validate/proof.f.d.mts +0 -125
- package/fjs/types/rtti/validate/proof.f.mjs +0 -437
- package/fjs/types/rtti/validate/types.d.ts +0 -6
- package/fjs/types/rtti/validate/types.js +0 -1
- package/fjs/types/sorted_list/types.js +0 -6
- package/fjs/types/sorted_set/types.js +0 -6
- package/fjs/types/string_set/types.js +0 -6
- package/fjs/types/ts/types.js +0 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Node.js effect runner: interprets `Effect<NodeOp, T>` directly against the
|
|
2
|
+
* Node.js effect runner: interprets `Effect<NodeOp, T, E>` directly against the
|
|
3
3
|
* Node globals and built-in modules (`fs`, `http`, `child_process`, `process`,
|
|
4
4
|
* `fetch`, …).
|
|
5
5
|
*
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
* globals directly instead.
|
|
12
12
|
*
|
|
13
13
|
* @module
|
|
14
|
+
*
|
|
15
|
+
* @import { Effect } from '../types.ts'
|
|
16
|
+
* @import { IoResult, Server as EffectServer, Headers, Module, NodeOp, RequestListener as Erl, NodeProgram, NodeProgramOptions, WriteConsoles, TestContext, TestFn, } from './types.ts'
|
|
17
|
+
* @import { Result } from '../../types/result/types.ts'
|
|
18
|
+
* @import { StringMap } from '../../types/object/types.ts'
|
|
14
19
|
*/
|
|
15
20
|
|
|
16
21
|
import http from 'node:http'
|
|
@@ -23,30 +28,13 @@ import { once } from 'node:events'
|
|
|
23
28
|
import * as testContext from 'node:test'
|
|
24
29
|
|
|
25
30
|
import { concat, normalize, toPosix } from '../../path/module.f.mjs'
|
|
26
|
-
/** @import { Effect } from '../types.ts' */
|
|
27
31
|
import { asyncRun } from '../module.mjs'
|
|
28
32
|
import { memoryOperationMap } from './memory/module.mjs'
|
|
29
|
-
import { usesInlineTestContext } from './module.f.mjs'
|
|
30
|
-
/**
|
|
31
|
-
* @import {
|
|
32
|
-
* Server as EffectServer,
|
|
33
|
-
* Headers,
|
|
34
|
-
* Module,
|
|
35
|
-
* NodeOp,
|
|
36
|
-
* RequestListener as Erl,
|
|
37
|
-
* NodeProgram,
|
|
38
|
-
* NodeProgramOptions,
|
|
39
|
-
* WriteConsoles,
|
|
40
|
-
* TestContext,
|
|
41
|
-
* TestFn,
|
|
42
|
-
* } from './types.ts'
|
|
43
|
-
*/
|
|
33
|
+
import { exitCode, toIoError, usesInlineTestContext } from './module.f.mjs'
|
|
44
34
|
import { asBase, asNominal } from '../../types/nominal/module.f.mjs'
|
|
45
|
-
|
|
46
|
-
import { error, ok } from '../../types/result/module.f.mjs'
|
|
35
|
+
import { error, ok, unwrap } from '../../types/result/module.f.mjs'
|
|
47
36
|
import { asyncTryCatch } from '../../types/result/module.mjs'
|
|
48
37
|
import { fromVec, listToVec, toVec } from '../../types/uint8array/module.f.mjs'
|
|
49
|
-
/** @import { StringMap } from '../../types/object/types.ts' */
|
|
50
38
|
import { maxLengthBytes } from '../../types/bit_vec/module.f.mjs'
|
|
51
39
|
|
|
52
40
|
/** @typedef {{ readonly listen: (port: number) => void }} _Server */
|
|
@@ -79,7 +67,23 @@ import { maxLengthBytes } from '../../types/bit_vec/module.f.mjs'
|
|
|
79
67
|
*/
|
|
80
68
|
const createServer = http.createServer
|
|
81
69
|
|
|
82
|
-
/** @typedef {<T>(effect: Effect<NodeOp, T>) => Promise<T
|
|
70
|
+
/** @typedef {<T, E>(effect: Effect<NodeOp, T, E>) => Promise<Result<T, E>>} _EffectToPromise */
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Performs host IO, reporting a thrown failure as an {@link IoResult} error.
|
|
74
|
+
*
|
|
75
|
+
* Every filesystem, network, and subprocess handler below goes through it, so
|
|
76
|
+
* the `catch` that turns an exception into effect data — and the normalization
|
|
77
|
+
* that keeps the channel serializable — happens in exactly one place.
|
|
78
|
+
*
|
|
79
|
+
* @template T
|
|
80
|
+
* @param {() => Promise<T>} f
|
|
81
|
+
* @returns {Promise<IoResult<T>>}
|
|
82
|
+
*/
|
|
83
|
+
const io = async f => {
|
|
84
|
+
const r = await asyncTryCatch(f)
|
|
85
|
+
return r[0] === 'ok' ? r : error(toIoError(r[1]))
|
|
86
|
+
}
|
|
83
87
|
|
|
84
88
|
/**
|
|
85
89
|
* @template T
|
|
@@ -127,7 +131,7 @@ const sandbox = async f => {
|
|
|
127
131
|
p = await p
|
|
128
132
|
after = performance.now()
|
|
129
133
|
}
|
|
130
|
-
result = ok(
|
|
134
|
+
result = ok(p)
|
|
131
135
|
} catch (e) {
|
|
132
136
|
after = performance.now()
|
|
133
137
|
result = error(e)
|
|
@@ -202,7 +206,7 @@ const waitReadableOrEnd = stdin =>
|
|
|
202
206
|
const readStdinByte = async () => {
|
|
203
207
|
const stdin = process.stdin
|
|
204
208
|
while (true) {
|
|
205
|
-
const chunk =
|
|
209
|
+
const chunk = stdin.read(1)
|
|
206
210
|
if (chunk !== null) {
|
|
207
211
|
return chunk[0]
|
|
208
212
|
}
|
|
@@ -222,16 +226,16 @@ const { randomInt } = crypto
|
|
|
222
226
|
/** @type {_EffectToPromise} */
|
|
223
227
|
const runNodeEffect = asyncRun({
|
|
224
228
|
...memoryOperationMap(),
|
|
225
|
-
all: async (...effects) => await Promise.all(effects.map(runNodeEffect)),
|
|
226
|
-
fetch:
|
|
229
|
+
all: async (...effects) => ok(await Promise.all(effects.map(runNodeEffect))),
|
|
230
|
+
fetch: url => io(async () => {
|
|
227
231
|
const response = await fetch(url)
|
|
228
232
|
if (!response.ok) {
|
|
229
233
|
throw new Error(`Fetch error: ${response.status} ${response.statusText}`)
|
|
230
234
|
}
|
|
231
235
|
return toVec(new Uint8Array(await response.arrayBuffer()))
|
|
232
236
|
}),
|
|
233
|
-
mkdir: (path, options) =>
|
|
234
|
-
readFile: path =>
|
|
237
|
+
mkdir: (path, options) => io(async () => { await mkdir(path, options) }),
|
|
238
|
+
readFile: path => io(async () => {
|
|
235
239
|
const fileStats = await stat(path)
|
|
236
240
|
// if the file is too big, toVec should fail anyway but in this case we don't want to load the file.
|
|
237
241
|
if (fileStats.size > maxFileSizeBytes) {
|
|
@@ -239,7 +243,7 @@ const runNodeEffect = asyncRun({
|
|
|
239
243
|
}
|
|
240
244
|
return toVec(await readFile(path))
|
|
241
245
|
}),
|
|
242
|
-
readdir: (path, r) =>
|
|
246
|
+
readdir: (path, r) => io(async () =>
|
|
243
247
|
(await readdir(path, { ...r, withFileTypes: true }))
|
|
244
248
|
.map(v => ({
|
|
245
249
|
name: v.name,
|
|
@@ -247,10 +251,10 @@ const runNodeEffect = asyncRun({
|
|
|
247
251
|
isFile: v.isFile()
|
|
248
252
|
}))
|
|
249
253
|
),
|
|
250
|
-
writeFile: (path, data) =>
|
|
251
|
-
rm: path =>
|
|
252
|
-
rename: (src, dst) =>
|
|
253
|
-
readBytes: (path, offset, size) =>
|
|
254
|
+
writeFile: (path, data) => io(() => writeFile(path, fromVec(data))),
|
|
255
|
+
rm: path => io(() => rm(path)),
|
|
256
|
+
rename: (src, dst) => io(() => rename(src, dst)),
|
|
257
|
+
readBytes: (path, offset, size) => io(async () => {
|
|
254
258
|
if (offset < 0) {
|
|
255
259
|
throw new Error(`Offset ${offset} is negative`)
|
|
256
260
|
}
|
|
@@ -266,13 +270,13 @@ const runNodeEffect = asyncRun({
|
|
|
266
270
|
await fh.close()
|
|
267
271
|
}
|
|
268
272
|
}),
|
|
269
|
-
randomInt: async () => randomInt(randomMax),
|
|
270
|
-
access: path =>
|
|
271
|
-
createExclusive: path =>
|
|
273
|
+
randomInt: async () => ok(randomInt(randomMax)),
|
|
274
|
+
access: path => io(() => access(path)),
|
|
275
|
+
createExclusive: path => io(async () => {
|
|
272
276
|
const fh = await open(path, 'wx')
|
|
273
277
|
await fh.close()
|
|
274
278
|
}),
|
|
275
|
-
writeBytes: (path, offset, data) =>
|
|
279
|
+
writeBytes: (path, offset, data) => io(async () => {
|
|
276
280
|
const fh = await open(path, 'r+')
|
|
277
281
|
try {
|
|
278
282
|
const buffer = fromVec(data)
|
|
@@ -287,11 +291,11 @@ const runNodeEffect = asyncRun({
|
|
|
287
291
|
await fh.close()
|
|
288
292
|
}
|
|
289
293
|
}),
|
|
290
|
-
stat: path =>
|
|
291
|
-
import: path =>
|
|
294
|
+
stat: path => io(async () => ({ size: (await stat(path)).size })),
|
|
295
|
+
import: path => io(() => asyncImport(path)),
|
|
292
296
|
exec: (command, stdin) => new Promise(resolve => {
|
|
293
297
|
const child = exec(command, (e, stdout, stderr) =>
|
|
294
|
-
resolve(e !== null ?
|
|
298
|
+
resolve(e !== null ? error(toIoError(e)) : ok({ stdout, stderr }))
|
|
295
299
|
)
|
|
296
300
|
child.stdin?.end(stdin)
|
|
297
301
|
}),
|
|
@@ -301,30 +305,37 @@ const runNodeEffect = asyncRun({
|
|
|
301
305
|
const nodeRl = async (req, res) => {
|
|
302
306
|
const reqBody = await collect(req)
|
|
303
307
|
const { method, url, headers } = req
|
|
304
|
-
|
|
308
|
+
// `RequestListener` answers `Effect<…, ServerResponse, never>` —
|
|
309
|
+
// the response frame is where a listener puts its failures — so
|
|
310
|
+
// this unwrap is total.
|
|
311
|
+
const { status, headers: outHeaders, body: outBody } = unwrap(await runNodeEffect(erl({
|
|
305
312
|
method,
|
|
306
313
|
url,
|
|
307
314
|
headers,
|
|
308
315
|
body: listToVec(reqBody)
|
|
309
|
-
}))
|
|
316
|
+
})))
|
|
310
317
|
res
|
|
311
318
|
.writeHead(status, outHeaders)
|
|
312
319
|
.end(fromVec(outBody))
|
|
313
320
|
}
|
|
314
|
-
return /** @satisfies {EffectServer} */ (asNominal(createServer(nodeRl)))
|
|
321
|
+
return ok(/** @satisfies {EffectServer} */ (asNominal(createServer(nodeRl))))
|
|
315
322
|
},
|
|
316
323
|
listen: async (server, port) => {
|
|
317
324
|
const s = /** @type {_Server} */ (asBase(server))
|
|
318
325
|
s.listen(port)
|
|
326
|
+
return ok(undefined)
|
|
319
327
|
},
|
|
320
328
|
forever: () => new Promise(() => {}),
|
|
321
|
-
now: async () => now(),
|
|
322
|
-
sandbox,
|
|
323
|
-
await: awaitPromise,
|
|
324
|
-
write: (stream, data) => writeAll(streams[stream], fromVec(data)),
|
|
325
|
-
read: readStdinByte,
|
|
329
|
+
now: async () => ok(now()),
|
|
330
|
+
sandbox: async f => ok(await sandbox(f)),
|
|
331
|
+
await: async p => ok(await awaitPromise(p)),
|
|
332
|
+
write: async (stream, data) => ok(await writeAll(streams[stream], fromVec(data))),
|
|
333
|
+
read: async () => ok(await readStdinByte()),
|
|
326
334
|
test: async (ctx, name, expectFailure, test) =>
|
|
327
|
-
|
|
335
|
+
// The body's answer is `ok(undefined)` — a `Test` callback absorbs its
|
|
336
|
+
// own failures by panicking, which is the only signal these frameworks
|
|
337
|
+
// read — so it is awaited and discarded rather than returned.
|
|
338
|
+
ok(await ctx.test(name, { expectFailure }, async t => { await runNodeEffect(test(t)) })),
|
|
328
339
|
})
|
|
329
340
|
|
|
330
341
|
/** @type {TestFn} */
|
|
@@ -377,8 +388,8 @@ const options = {
|
|
|
377
388
|
* the program's code, use {@link run} instead.
|
|
378
389
|
* @type {(p: NodeProgram) => Promise<number>}
|
|
379
390
|
*/
|
|
380
|
-
export const runEffect = program =>
|
|
381
|
-
runNodeEffect(program(options))
|
|
391
|
+
export const runEffect = async program =>
|
|
392
|
+
exitCode(await runNodeEffect(program(options)))
|
|
382
393
|
|
|
383
394
|
/**
|
|
384
395
|
* CLI entry point: runs a `NodeProgram` via {@link runEffect}, then calls
|
|
@@ -1,11 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @import { Vec } from "../../types/bit_vec/types.ts"
|
|
3
|
-
* @import { IoResult, ReadFile } from "./types.ts"
|
|
4
|
-
* @import {
|
|
3
|
+
* @import { IoChannel, IoError, IoResult, ReadFile } from "./types.ts"
|
|
4
|
+
* @import { Result } from "../../types/result/types.ts"
|
|
5
5
|
* @import { List } from "../list/types.ts"
|
|
6
6
|
* @import { OperationMap } from "../types.ts"
|
|
7
7
|
*/
|
|
8
8
|
export declare const proof: {
|
|
9
|
+
toIoError: {
|
|
10
|
+
error: () => void;
|
|
11
|
+
withCode: () => void;
|
|
12
|
+
string: () => void;
|
|
13
|
+
null: () => void;
|
|
14
|
+
nonStringCode: () => void;
|
|
15
|
+
noCode: () => void;
|
|
16
|
+
};
|
|
17
|
+
isNotFound: {
|
|
18
|
+
enoent: () => void;
|
|
19
|
+
otherCode: () => void;
|
|
20
|
+
notImplemented: () => void;
|
|
21
|
+
};
|
|
22
|
+
errorMessage: {
|
|
23
|
+
io: () => void;
|
|
24
|
+
notImplemented: () => void;
|
|
25
|
+
};
|
|
26
|
+
errorSummary: {
|
|
27
|
+
io: () => void;
|
|
28
|
+
ioWithoutCode: () => void;
|
|
29
|
+
notImplemented: () => void;
|
|
30
|
+
};
|
|
31
|
+
exitStep: {
|
|
32
|
+
ok: () => void;
|
|
33
|
+
error: () => void;
|
|
34
|
+
};
|
|
9
35
|
externalTestContext: () => void;
|
|
10
36
|
map: () => void;
|
|
11
37
|
fetch: () => void;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @import { Vec } from "../../types/bit_vec/types.ts"
|
|
3
|
-
* @import { IoResult, ReadFile } from "./types.ts"
|
|
4
|
-
* @import {
|
|
3
|
+
* @import { IoChannel, IoError, IoResult, ReadFile } from "./types.ts"
|
|
4
|
+
* @import { Result } from "../../types/result/types.ts"
|
|
5
5
|
* @import { List } from "../list/types.ts"
|
|
6
6
|
* @import { OperationMap } from "../types.ts"
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { empty, isVec, uint, vec, vec8 } from "../../types/bit_vec/module.f.mjs"
|
|
10
10
|
import { utf8, utf8ToString } from "../../text/module.f.mjs"
|
|
11
|
-
import { match
|
|
12
|
-
import {
|
|
11
|
+
import { match } from "../module.f.mjs"
|
|
12
|
+
import { mapStep, step as ioStep } from "../module.f.mjs"
|
|
13
|
+
import { both, errorMessage, errorSummary, exitStep, fetch, ioError, isNotFound, mkdir, now, readdir, readFile, readUtf8File, rm, sandbox, toIoError, writeFile, writeUtf8File, rename, readBytes, randomInt, writeFromStream, usesInlineTestContext, versionLessThan } from "./module.f.mjs"
|
|
13
14
|
import { create as memCreate, read as memRead, write as memWrite } from "../memory/module.f.mjs"
|
|
14
15
|
import { empty as listEmpty, nonEmpty as listNonEmpty } from "../list/module.f.mjs"
|
|
15
16
|
import { emptyState, virtual } from "./virtual/module.f.mjs"
|
|
@@ -29,7 +30,115 @@ const readHelloMap = {
|
|
|
29
30
|
|
|
30
31
|
const readHello = match(readHelloMap)
|
|
31
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Asserts that a channel error is a host failure carrying `message`. Every
|
|
35
|
+
* runner reports through the same normalized {@link IoError}, so a proof
|
|
36
|
+
* against the virtual filesystem names the message rather than the shape.
|
|
37
|
+
* @type {(e: IoChannel, message: string) => void}
|
|
38
|
+
*/
|
|
39
|
+
const assertIoMessage = (e, message) => {
|
|
40
|
+
assert(e[0] === 'ioError', e)
|
|
41
|
+
assertEq(e[1].message, message)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Asserts that an operation succeeded with `expected`.
|
|
45
|
+
* @type {<T, E>(r: Result<T, E>, expected: T) => void}
|
|
46
|
+
*/
|
|
47
|
+
const assertOk = (r, expected) => {
|
|
48
|
+
assert(r[0] === 'ok', r)
|
|
49
|
+
assertEq(r[1], expected)
|
|
50
|
+
}
|
|
51
|
+
|
|
32
52
|
export const proof = {
|
|
53
|
+
// The one boundary where a runner's `catch` becomes effect data: whatever
|
|
54
|
+
// was thrown is reduced to a code (when the host attached a string one)
|
|
55
|
+
// and a message.
|
|
56
|
+
toIoError: {
|
|
57
|
+
error: () => {
|
|
58
|
+
assertIoMessage(toIoError(new Error('boom')), 'boom')
|
|
59
|
+
},
|
|
60
|
+
withCode: () => {
|
|
61
|
+
const e = toIoError(Object.assign(new Error('missing'), { code: 'ENOENT' }))
|
|
62
|
+
assert(e[0] === 'ioError', e)
|
|
63
|
+
assertEq(e[1].code, 'ENOENT', e)
|
|
64
|
+
assertEq(e[1].message, 'missing', e)
|
|
65
|
+
},
|
|
66
|
+
// A thrown non-`Error` still normalizes: the value's string form is the
|
|
67
|
+
// message, and there is no code to carry.
|
|
68
|
+
string: () => {
|
|
69
|
+
const e = toIoError('plain')
|
|
70
|
+
assert(e[0] === 'ioError', e)
|
|
71
|
+
assertEq(e[1].code, undefined, e)
|
|
72
|
+
assertEq(e[1].message, 'plain', e)
|
|
73
|
+
},
|
|
74
|
+
null: () => {
|
|
75
|
+
assertIoMessage(toIoError(null), 'null')
|
|
76
|
+
},
|
|
77
|
+
// An object whose `code` is not a string is not an OS error code, so it
|
|
78
|
+
// is dropped rather than carried as one.
|
|
79
|
+
nonStringCode: () => {
|
|
80
|
+
const e = toIoError({ code: 42 })
|
|
81
|
+
assert(e[0] === 'ioError', e)
|
|
82
|
+
assertEq(e[1].code, undefined, e)
|
|
83
|
+
},
|
|
84
|
+
noCode: () => {
|
|
85
|
+
const e = toIoError({})
|
|
86
|
+
assert(e[0] === 'ioError', e)
|
|
87
|
+
assertEq(e[1].code, undefined, e)
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
isNotFound: {
|
|
91
|
+
enoent: () => {
|
|
92
|
+
assert(isNotFound(ioError({ code: 'ENOENT', message: 'no such file or directory' })))
|
|
93
|
+
},
|
|
94
|
+
otherCode: () => {
|
|
95
|
+
assert(!isNotFound(ioError({ code: 'EACCES', message: 'permission denied' })))
|
|
96
|
+
},
|
|
97
|
+
// A runner that cannot perform the operation has not looked for the
|
|
98
|
+
// path at all, so a missing handler is never "not found".
|
|
99
|
+
notImplemented: () => {
|
|
100
|
+
assert(!isNotFound(['notImplemented', 'readFile']))
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
errorMessage: {
|
|
104
|
+
io: () => {
|
|
105
|
+
assertEq(errorMessage(ioError({ message: 'disk full' })), 'disk full')
|
|
106
|
+
},
|
|
107
|
+
notImplemented: () => {
|
|
108
|
+
assertEq(errorMessage(['notImplemented', 'readFile']), 'operation not implemented: readFile')
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
errorSummary: {
|
|
112
|
+
// The distinction that matters: `errorMessage` hands back the host's
|
|
113
|
+
// words, which is where the path lives; `errorSummary` never does.
|
|
114
|
+
io: () => {
|
|
115
|
+
assertEq(errorSummary(ioError({ code: 'ENOENT', message: "no such file or directory, scandir '/home/u/.cas'" })), 'io error: ENOENT')
|
|
116
|
+
},
|
|
117
|
+
ioWithoutCode: () => {
|
|
118
|
+
assertEq(errorSummary(ioError({ message: "cannot read '/home/u/.cas'" })), 'io error')
|
|
119
|
+
},
|
|
120
|
+
notImplemented: () => {
|
|
121
|
+
assertEq(errorSummary(['notImplemented', 'readdir']), 'operation not implemented: readdir')
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
exitStep: {
|
|
125
|
+
// The exit-code policy a `NodeProgram` ends with: success is `0`...
|
|
126
|
+
ok: () => {
|
|
127
|
+
const [state, code] = virtual(emptyState)(exitStep(writeFile('hello', vec8(0x2An))))
|
|
128
|
+
assertEq(code[0], 'ok')
|
|
129
|
+
assertEq(code[1], 0)
|
|
130
|
+
assertEq(state.stderr, '')
|
|
131
|
+
},
|
|
132
|
+
// ...and a failure is reported on `stderr` and exits `1`.
|
|
133
|
+
// ...and the code is `[1]` either way, which is what lets a runner
|
|
134
|
+
// read it without asking which branch it came from.
|
|
135
|
+
error: () => {
|
|
136
|
+
const [state, code] = virtual(emptyState)(exitStep(readFile('missing')))
|
|
137
|
+
assertEq(code[0], 'error')
|
|
138
|
+
assertEq(code[1], 1)
|
|
139
|
+
assertEq(state.stderr, 'no such file or directory\n')
|
|
140
|
+
},
|
|
141
|
+
},
|
|
33
142
|
externalTestContext: () => {
|
|
34
143
|
assert(usesInlineTestContext('node', 'v22.20.0'))
|
|
35
144
|
assert(usesInlineTestContext('node', '25.99.99'))
|
|
@@ -44,18 +153,15 @@ export const proof = {
|
|
|
44
153
|
assert(!versionLessThan('26.1.1', '26.1.1'))
|
|
45
154
|
},
|
|
46
155
|
map: () => {
|
|
47
|
-
const e =
|
|
48
|
-
readFile('hello'),
|
|
49
|
-
([k, v]) => {
|
|
50
|
-
assert(k !== 'error', v)
|
|
51
|
-
return pure(uint(v) * 2n)
|
|
52
|
-
})
|
|
156
|
+
const e = mapStep(readFile('hello'), v => uint(v) * 2n)
|
|
53
157
|
//
|
|
54
158
|
let r = readHello(e)
|
|
55
159
|
while (r[0] === 'cont') {
|
|
56
160
|
r = readHello(r[2](r[1]))
|
|
57
161
|
}
|
|
58
|
-
|
|
162
|
+
// `done` carries the whole `Result`: an interpreter never separates the
|
|
163
|
+
// channels, so the projection's value is inside the `ok`.
|
|
164
|
+
assertEq(r[1][1], 0x2An)
|
|
59
165
|
},
|
|
60
166
|
fetch: () => {
|
|
61
167
|
const [_, [t, result]] = virtual({
|
|
@@ -81,8 +187,11 @@ export const proof = {
|
|
|
81
187
|
)
|
|
82
188
|
assert(t === 'ok', result)
|
|
83
189
|
const tmp = state.root.tmp
|
|
84
|
-
|
|
85
|
-
|
|
190
|
+
// `instanceof Array`, not `Array.isArray`: only the former's negative
|
|
191
|
+
// branch removes a `readonly` array from a union, so only it narrows
|
|
192
|
+
// `_Entity` to `Dir`.
|
|
193
|
+
assert(!(typeof tmp !== 'object' || tmp instanceof Array), state.root)
|
|
194
|
+
const cache = tmp.cache
|
|
86
195
|
assert(!(typeof cache !== 'object' || Array.isArray(cache)), tmp)
|
|
87
196
|
},
|
|
88
197
|
nonRec: () => {
|
|
@@ -122,7 +231,8 @@ export const proof = {
|
|
|
122
231
|
nestedPath: () => {
|
|
123
232
|
const [_, [t, result]] = virtual(emptyState)(readFile('tmp/cache'))
|
|
124
233
|
assert(t === 'error', result)
|
|
125
|
-
|
|
234
|
+
assert(result[0] === 'ioError', result)
|
|
235
|
+
assertEq(result[1].code, 'ENOENT', result)
|
|
126
236
|
},
|
|
127
237
|
withinLimit: () => {
|
|
128
238
|
// Test with a small file well within the 131,072 byte limit
|
|
@@ -197,7 +307,7 @@ export const proof = {
|
|
|
197
307
|
noSuchDir: () => {
|
|
198
308
|
const [_, [t, result]] = virtual(emptyState)(readdir('tmp', { recursive: true }))
|
|
199
309
|
assert(t === 'error', result)
|
|
200
|
-
|
|
310
|
+
assertIoMessage(result, 'invalid path')
|
|
201
311
|
},
|
|
202
312
|
},
|
|
203
313
|
writeFile: {
|
|
@@ -229,7 +339,7 @@ export const proof = {
|
|
|
229
339
|
writeFile('tmp/cache', vec8(0x2An))
|
|
230
340
|
)
|
|
231
341
|
assert(t === 'error', result)
|
|
232
|
-
|
|
342
|
+
assertIoMessage(result, 'invalid file')
|
|
233
343
|
assertEq(state.root.tmp, undefined, state.root)
|
|
234
344
|
},
|
|
235
345
|
directory: () => {
|
|
@@ -242,7 +352,7 @@ export const proof = {
|
|
|
242
352
|
writeFile('tmp', vec8(0x2An))
|
|
243
353
|
)
|
|
244
354
|
assert(t === 'error', result)
|
|
245
|
-
|
|
355
|
+
assertIoMessage(result, 'invalid file')
|
|
246
356
|
const tmp = state.root.tmp
|
|
247
357
|
assert(!(tmp === undefined || Array.isArray(tmp)), tmp)
|
|
248
358
|
},
|
|
@@ -272,13 +382,13 @@ export const proof = {
|
|
|
272
382
|
})(rm('tmp/cache'))
|
|
273
383
|
assert(t === 'ok', result)
|
|
274
384
|
const tmp = state.root.tmp
|
|
275
|
-
assert(!(typeof tmp !== 'object' || Array
|
|
276
|
-
assertEq(
|
|
385
|
+
assert(!(typeof tmp !== 'object' || tmp instanceof Array), state.root)
|
|
386
|
+
assertEq(tmp.cache, undefined, tmp)
|
|
277
387
|
},
|
|
278
388
|
noSuchFile: () => {
|
|
279
389
|
const [_, [t, result]] = virtual(emptyState)(rm('hello'))
|
|
280
390
|
assert(t === 'error', result)
|
|
281
|
-
|
|
391
|
+
assertIoMessage(result, 'no such file')
|
|
282
392
|
},
|
|
283
393
|
isDirectory: () => {
|
|
284
394
|
const [state, [t, result]] = virtual({
|
|
@@ -286,18 +396,20 @@ export const proof = {
|
|
|
286
396
|
root: { tmp: {} },
|
|
287
397
|
})(rm('tmp'))
|
|
288
398
|
assert(t === 'error', result)
|
|
289
|
-
|
|
399
|
+
assertIoMessage(result, 'invalid path')
|
|
290
400
|
assert(state.root.tmp !== undefined, state.root)
|
|
291
401
|
},
|
|
292
402
|
},
|
|
293
403
|
both: () => {
|
|
294
|
-
const [_,
|
|
404
|
+
const [_, both2] = virtual({
|
|
295
405
|
...emptyState,
|
|
296
406
|
root: {
|
|
297
407
|
a: [vec8(0x2An)],
|
|
298
408
|
b: [vec8(0x15n)],
|
|
299
409
|
},
|
|
300
410
|
})(both(readFile('a'))(readFile('b')))
|
|
411
|
+
assert(both2[0] === 'ok', both2)
|
|
412
|
+
const results = both2[1]
|
|
301
413
|
assert(results[0][0] === 'ok', results[0])
|
|
302
414
|
assert(results[1][0] === 'ok', results[1])
|
|
303
415
|
assertEq(uint(results[0][1]), 0x2An, results[0][1])
|
|
@@ -305,41 +417,48 @@ export const proof = {
|
|
|
305
417
|
},
|
|
306
418
|
now: () => {
|
|
307
419
|
const [_, result] = virtual({ ...emptyState, epochNs: 1_000_000 })(now())
|
|
308
|
-
|
|
420
|
+
assertOk(result, 1_000_000)
|
|
309
421
|
},
|
|
310
422
|
sandbox: {
|
|
311
423
|
// Virtual `sandbox` is now a pass-through: the function is expected
|
|
312
424
|
// to return a `SandboxResult` directly. Fixtures dictate the result
|
|
313
425
|
// (and `duration`) instead of the runner measuring.
|
|
314
426
|
ok: () => {
|
|
315
|
-
const [_,
|
|
316
|
-
sandbox(() =>
|
|
427
|
+
const [_, sandboxed] = virtual(emptyState)(
|
|
428
|
+
sandbox(() => ({ result: ['ok', 42], duration: 0 })))
|
|
429
|
+
// Two `Result`s, one inside the other on purpose: the outer one is
|
|
430
|
+
// the operation's own status, the inner one is the sandboxed
|
|
431
|
+
// function's outcome — returned data, not effect status.
|
|
432
|
+
assert(sandboxed[0] === 'ok', sandboxed)
|
|
433
|
+
const { result, duration } = sandboxed[1]
|
|
317
434
|
assert(result[0] === 'ok', result)
|
|
318
435
|
assertEq(result[1], 42)
|
|
319
436
|
assertEq(duration, 0)
|
|
320
437
|
},
|
|
321
438
|
error: () => {
|
|
322
439
|
const err = new Error('fail')
|
|
323
|
-
const [_,
|
|
324
|
-
sandbox(() =>
|
|
440
|
+
const [_, sandboxed] = virtual(emptyState)(
|
|
441
|
+
sandbox(() => ({ result: ['error', err], duration: 0 })))
|
|
442
|
+
assert(sandboxed[0] === 'ok', sandboxed)
|
|
443
|
+
const { result } = sandboxed[1]
|
|
325
444
|
assert(result[0] === 'error', result)
|
|
326
445
|
assertEq(result[1], err)
|
|
327
446
|
},
|
|
328
447
|
},
|
|
329
448
|
memory: {
|
|
330
449
|
createAndRead: () => {
|
|
331
|
-
const effect =
|
|
450
|
+
const effect = ioStep(memCreate(42), key => memRead(key))
|
|
332
451
|
const [_, value] = virtual(emptyState)(effect)
|
|
333
|
-
|
|
452
|
+
assertOk(value, 42)
|
|
334
453
|
},
|
|
335
454
|
createAndWrite: () => {
|
|
336
|
-
const effect =
|
|
455
|
+
const effect = ioStep(
|
|
337
456
|
memCreate(1),
|
|
338
|
-
key =>
|
|
457
|
+
key => ioStep(
|
|
339
458
|
memWrite(key, 99),
|
|
340
459
|
() => memRead(key)))
|
|
341
460
|
const [_, value] = virtual(emptyState)(effect)
|
|
342
|
-
|
|
461
|
+
assertOk(value, 99)
|
|
343
462
|
},
|
|
344
463
|
},
|
|
345
464
|
rename: {
|
|
@@ -351,7 +470,7 @@ export const proof = {
|
|
|
351
470
|
assert(t === 'ok', result)
|
|
352
471
|
assertEq(state.root.src, undefined, state.root)
|
|
353
472
|
assert(Array.isArray(state.root.dst), state.root)
|
|
354
|
-
assertEq(uint(
|
|
473
|
+
assertEq(uint(state.root.dst[0]), 0x2An, state.root)
|
|
355
474
|
},
|
|
356
475
|
nestedRename: () => {
|
|
357
476
|
const [state, [t, result]] = virtual({
|
|
@@ -360,8 +479,8 @@ export const proof = {
|
|
|
360
479
|
})(rename('tmp/src', 'tmp/dst'))
|
|
361
480
|
assert(t === 'ok', result)
|
|
362
481
|
const tmp = state.root.tmp
|
|
363
|
-
assert(!(typeof tmp !== 'object' || Array
|
|
364
|
-
assertEq(
|
|
482
|
+
assert(!(typeof tmp !== 'object' || tmp instanceof Array), state.root)
|
|
483
|
+
assertEq(tmp.src, undefined, tmp)
|
|
365
484
|
},
|
|
366
485
|
dirOverFile: () => {
|
|
367
486
|
const [state, [t, result]] = virtual({
|
|
@@ -408,18 +527,18 @@ export const proof = {
|
|
|
408
527
|
randomInt: {
|
|
409
528
|
increments: () => {
|
|
410
529
|
const [state1, r1] = virtual(emptyState)(randomInt())
|
|
411
|
-
|
|
530
|
+
assertOk(r1, 0)
|
|
412
531
|
const [state2, r2] = virtual(state1)(randomInt())
|
|
413
|
-
|
|
532
|
+
assertOk(r2, 1)
|
|
414
533
|
const [_, r3] = virtual(state2)(randomInt())
|
|
415
|
-
|
|
534
|
+
assertOk(r3, 2)
|
|
416
535
|
},
|
|
417
536
|
},
|
|
418
537
|
writeFromStream: {
|
|
419
538
|
createExclusiveFails: () => {
|
|
420
539
|
// The destination already exists, so `createExclusive` fails (EEXIST) and
|
|
421
540
|
// the error propagates without ever touching `writeBytes`.
|
|
422
|
-
/** @type {List<never,
|
|
541
|
+
/** @type {List<never, Vec, IoChannel>} */
|
|
423
542
|
const chunks = listEmpty()
|
|
424
543
|
const [state, [t, result]] = virtual({
|
|
425
544
|
...emptyState,
|
|
@@ -432,13 +551,13 @@ export const proof = {
|
|
|
432
551
|
invalidBufferSize: () => {
|
|
433
552
|
// A chunk whose bit length isn't a multiple of 8 trips the
|
|
434
553
|
// byte-alignment guard before `writeBytes` is ever called.
|
|
435
|
-
/** @type {List<never,
|
|
436
|
-
const chunks = listNonEmpty(
|
|
554
|
+
/** @type {List<never, Vec, IoChannel>} */
|
|
555
|
+
const chunks = listNonEmpty(vec(4n)(0b1010n), listEmpty())
|
|
437
556
|
const [_, [t, result]] = virtual(emptyState)(
|
|
438
557
|
writeFromStream('hello', chunks)
|
|
439
558
|
)
|
|
440
559
|
assert(t === 'error', result)
|
|
441
|
-
|
|
560
|
+
assertIoMessage(result, 'invalid buffer size')
|
|
442
561
|
},
|
|
443
562
|
},
|
|
444
563
|
}
|