functionalscript 0.37.0 → 0.39.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 +1 -1
- package/{fs → fjs}/asn.1/proof.f.js +32 -94
- package/fjs/asserts/module.f.d.ts +36 -0
- package/fjs/asserts/module.f.js +39 -0
- package/fjs/asserts/proof.f.d.ts +11 -0
- package/fjs/asserts/proof.f.js +18 -0
- package/{fs → fjs}/base_n/proof.f.js +12 -36
- package/{fs → fjs}/basen/base64/proof.f.d.ts +1 -0
- package/{fs → fjs}/basen/base64/proof.f.js +15 -1
- package/{fs → fjs}/basen/cbase32/proof.f.js +15 -42
- package/fjs/bnf/data/module.f.d.ts +52 -0
- package/{fs → fjs}/bnf/data/module.f.js +53 -3
- package/{fs → fjs}/bnf/data/proof.f.d.ts +1 -0
- package/{fs → fjs}/bnf/data/proof.f.js +54 -19
- package/{fs → fjs}/bnf/descent/module.f.d.ts +4 -14
- package/fjs/bnf/descent/module.f.js +124 -0
- package/{fs → fjs}/bnf/descent/proof.f.d.ts +1 -0
- package/{fs → fjs}/bnf/descent/proof.f.js +55 -24
- package/{fs → fjs}/bnf/ll1/module.f.d.ts +4 -4
- package/{fs → fjs}/bnf/ll1/module.f.js +7 -5
- package/{fs → fjs}/bnf/ll1/proof.f.d.ts +1 -0
- package/{fs → fjs}/bnf/ll1/proof.f.js +27 -10
- package/{fs → fjs}/bnf/module.f.d.ts +19 -5
- package/{fs → fjs}/bnf/module.f.js +10 -11
- package/fjs/bnf/proof.f.js +69 -0
- package/{fs → fjs}/bnf/testlib.f.js +2 -2
- package/fjs/bnf/token_symbol/module.f.d.ts +38 -0
- package/fjs/bnf/token_symbol/module.f.js +48 -0
- package/fjs/bnf/token_symbol/proof.f.d.ts +10 -0
- package/fjs/bnf/token_symbol/proof.f.js +37 -0
- package/{fs → fjs}/cas/cli/module.f.js +6 -9
- package/{fs → fjs}/cas/cli/proof.f.d.ts +4 -1
- package/{fs → fjs}/cas/cli/proof.f.js +29 -66
- package/fjs/cas/evo/mcp/module.f.d.ts +27 -0
- package/fjs/cas/evo/mcp/module.f.js +94 -0
- package/fjs/cas/evo/mcp/proof.f.d.ts +11 -0
- package/fjs/cas/evo/mcp/proof.f.js +126 -0
- package/fjs/cas/evo/module.f.d.ts +202 -0
- package/fjs/cas/evo/module.f.js +421 -0
- package/fjs/cas/evo/proof.f.d.ts +39 -0
- package/fjs/cas/evo/proof.f.js +572 -0
- package/fjs/cas/mcp/module.f.d.ts +49 -0
- package/{fs → fjs}/cas/mcp/module.f.js +61 -81
- package/{fs → fjs}/cas/mcp/proof.f.d.ts +4 -1
- package/{fs → fjs}/cas/mcp/proof.f.js +45 -17
- package/{fs → fjs}/cas/module.f.d.ts +10 -0
- package/{fs → fjs}/cas/module.f.js +89 -36
- package/fjs/cas/proof.f.d.ts +18 -0
- package/fjs/cas/proof.f.js +305 -0
- package/{fs → fjs}/ci/bun/module.f.js +3 -3
- package/{fs → fjs}/ci/common/module.f.d.ts +1 -2
- package/{fs → fjs}/ci/common/module.f.js +1 -5
- package/{fs → fjs}/ci/config/module.f.d.ts +8 -8
- package/{fs → fjs}/ci/config/module.f.js +8 -8
- package/{fs → fjs}/ci/deno/module.f.js +3 -3
- package/{fs → fjs}/ci/module.f.js +3 -4
- package/{fs → fjs}/ci/node/module.f.js +11 -9
- package/{fs → fjs}/ci/proof.f.js +16 -9
- package/{fs → fjs}/ci/rust/module.f.js +9 -1
- package/{fs → fjs}/cli/module.f.js +2 -2
- package/{fs → fjs}/cli/proof.f.js +22 -63
- package/{fs → fjs}/common/monoid/module.f.d.ts +46 -2
- package/fjs/common/monoid/module.f.js +88 -0
- package/fjs/common/monoid/proof.f.d.ts +9 -0
- package/fjs/common/monoid/proof.f.js +48 -0
- package/{fs → fjs}/crypto/hmac/proof.f.js +4 -12
- package/fjs/crypto/pow/proof.f.js +111 -0
- package/{fs → fjs}/crypto/secp/proof.f.js +12 -33
- package/{fs → fjs}/crypto/sha2/proof.f.js +18 -49
- package/{fs → fjs}/crypto/sign/module.f.d.ts +0 -5
- package/{fs → fjs}/crypto/sign/module.f.js +7 -4
- package/{fs → fjs}/crypto/sign/proof.f.js +36 -105
- package/{fs → fjs}/crypto/vdf/proof.f.js +22 -63
- package/{fs → fjs}/dev/module.f.js +25 -25
- package/{fs → fjs}/dev/package_json/proof.f.js +7 -7
- package/{fs → fjs}/dev/proof.f.js +2 -4
- package/{fs → fjs}/djs/ast/proof.f.js +4 -12
- package/{fs → fjs}/djs/module.f.js +5 -8
- package/{fs → fjs}/djs/parser/module.f.d.ts +8 -0
- package/{fs → fjs}/djs/parser/module.f.js +37 -0
- package/{fs → fjs}/djs/parser/proof.f.js +138 -400
- package/{fs → fjs}/djs/proof.f.js +13 -36
- package/{fs → fjs}/djs/serializer/proof.f.js +14 -39
- package/fjs/djs/tokenizer/module.f.d.ts +24 -0
- package/fjs/djs/tokenizer/module.f.js +472 -0
- package/{fs/djs/tokenizer-new → fjs/djs/tokenizer}/proof.f.d.ts +4 -3
- package/{fs/djs/tokenizer-new → fjs/djs/tokenizer}/proof.f.js +446 -445
- package/{fs → fjs}/djs/transpiler/module.f.js +6 -6
- package/{fs → fjs}/djs/transpiler/proof.f.d.ts +3 -0
- package/{fs → fjs}/djs/transpiler/proof.f.js +29 -30
- package/fjs/effects/eff/module.f.d.ts +72 -0
- package/fjs/effects/eff/module.f.js +46 -0
- package/fjs/effects/eff/proof.f.d.ts +11 -0
- package/fjs/effects/eff/proof.f.js +58 -0
- package/{fs → fjs}/effects/list/module.f.d.ts +11 -5
- package/{fs → fjs}/effects/list/module.f.js +2 -1
- package/{fs → fjs}/effects/memory/proof.f.js +15 -29
- package/fjs/effects/module.f.d.ts +388 -0
- package/fjs/effects/module.f.js +288 -0
- package/{fs → fjs}/effects/node/memory/proof.js +7 -13
- package/{fs → fjs}/effects/node/module.d.ts +1 -1
- package/{fs → fjs}/effects/node/module.f.d.ts +2 -2
- package/{fs → fjs}/effects/node/module.f.js +9 -11
- package/{fs → fjs}/effects/node/module.js +3 -3
- package/{fs → fjs}/effects/node/proof.f.d.ts +1 -0
- package/{fs → fjs}/effects/node/proof.f.js +121 -299
- package/{fs → fjs}/effects/node/virtual/proof.f.d.ts +1 -0
- package/{fs → fjs}/effects/node/virtual/proof.f.js +36 -29
- package/fjs/effects/proof.f.d.ts +51 -0
- package/fjs/effects/proof.f.js +178 -0
- package/{fs → fjs}/emergent_testing/module.f.js +55 -39
- package/{fs → fjs}/emergent_testing/proof.f.d.ts +4 -0
- package/{fs → fjs}/emergent_testing/proof.f.js +60 -27
- package/{fs → fjs}/fsc/proof.f.js +12 -34
- package/{fs → fjs}/fsm/proof.f.js +5 -12
- package/{fs → fjs}/mcp/module.f.d.ts +7 -0
- package/{fs → fjs}/mcp/module.f.js +17 -10
- package/{fs → fjs}/mcp/proof.f.js +17 -16
- package/{fs → fjs}/mcp/stdio/module.f.d.ts +4 -4
- package/{fs → fjs}/mcp/stdio/module.f.js +14 -14
- package/{fs → fjs}/media/html/proof.f.js +12 -33
- package/{fs → fjs}/media/json/parser/module.f.d.ts +5 -0
- package/{fs → fjs}/media/json/parser/module.f.js +14 -0
- package/{fs → fjs}/media/json/parser/proof.f.js +39 -114
- package/{fs → fjs}/media/json/rpc/module.f.js +1 -1
- package/{fs → fjs}/media/json/schema/module.f.d.ts +2 -2
- package/{fs → fjs}/media/json/schema/module.f.js +23 -39
- package/{fs → fjs}/media/json/schema/proof.f.js +3 -6
- package/{fs → fjs}/media/json/serializer/proof.f.js +10 -27
- package/{fs → fjs}/media/module.f.d.ts +6 -6
- package/{fs → fjs}/media/module.f.js +3 -4
- package/{fs → fjs}/media/proof.f.js +5 -4
- package/{fs → fjs}/media/revision/module.f.d.ts +31 -4
- package/{fs → fjs}/media/revision/module.f.js +35 -23
- package/{fs → fjs}/media/revision/proof.f.d.ts +10 -8
- package/fjs/media/revision/proof.f.js +140 -0
- package/{fs → fjs}/media/type/module.f.js +2 -2
- package/{fs → fjs}/media/type/proof.f.js +8 -15
- package/{fs → fjs}/module.f.js +5 -9
- package/{fs → fjs}/path/proof.f.js +27 -78
- package/{fs → fjs}/proof.f.js +2 -0
- package/{fs → fjs}/sul/id/proof.f.js +7 -21
- package/{fs → fjs}/sul/level/hash/proof.f.js +5 -5
- package/{fs → fjs}/sul/level/literal/proof.f.js +12 -26
- package/fjs/text/ascii/proof.f.d.ts +6 -0
- package/{fs → fjs}/text/ascii/proof.f.js +4 -14
- package/{fs → fjs}/text/code_point/module.f.js +10 -10
- package/{fs → fjs}/text/proof.f.js +4 -9
- package/{fs → fjs}/text/sgr/proof.f.js +6 -15
- package/{fs → fjs}/text/utf16/module.f.js +1 -1
- package/{fs → fjs}/text/utf16/proof.f.js +23 -66
- package/{fs → fjs}/text/utf8/proof.f.js +56 -125
- package/{fs → fjs}/types/array/proof.f.js +18 -52
- package/fjs/types/bigfloat/proof.f.js +217 -0
- package/{fs → fjs}/types/bigint/module.f.js +4 -3
- package/{fs → fjs}/types/bigint/proof.f.js +49 -145
- package/{fs → fjs}/types/bit_vec/module.f.js +5 -15
- package/{fs → fjs}/types/bit_vec/proof.f.js +72 -214
- package/{fs → fjs}/types/btree/find/proof.f.js +23 -66
- package/{fs → fjs}/types/btree/proof.f.js +5 -12
- package/{fs → fjs}/types/btree/remove/module.f.d.ts +5 -0
- package/{fs → fjs}/types/btree/remove/module.f.js +12 -0
- package/{fs → fjs}/types/btree/remove/proof.f.d.ts +2 -0
- package/{fs → fjs}/types/btree/remove/proof.f.js +83 -230
- package/{fs → fjs}/types/btree/set/module.f.js +5 -2
- package/{fs → fjs}/types/btree/set/proof.f.js +35 -24
- package/{fs → fjs}/types/byte_set/proof.f.js +22 -63
- package/{fs → fjs}/types/function/compare/proof.f.js +13 -36
- package/{fs → fjs}/types/function/operator/proof.f.js +17 -48
- package/{fs → fjs}/types/function/proof.f.js +2 -3
- package/{fs → fjs}/types/list/module.f.d.ts +21 -0
- package/{fs → fjs}/types/list/module.f.js +17 -0
- package/{fs → fjs}/types/list/proof.f.d.ts +1 -0
- package/{fs → fjs}/types/list/proof.f.js +79 -164
- package/{fs → fjs}/types/map/proof.f.js +4 -12
- package/{fs → fjs}/types/nibble_set/proof.f.js +16 -45
- package/{fs → fjs}/types/nominal/proof.f.js +5 -10
- package/fjs/types/nullable/proof.f.js +29 -0
- package/{fs → fjs}/types/number/module.f.js +2 -1
- package/{fs → fjs}/types/number/proof.f.js +9 -24
- package/{fs → fjs}/types/object/proof.f.js +3 -6
- package/{fs → fjs}/types/patricia_trie/proof.f.js +21 -21
- package/{fs → fjs}/types/prime_field/module.f.js +2 -7
- package/{fs → fjs}/types/range/module.f.d.ts +1 -1
- package/fjs/types/range/module.f.js +2 -0
- package/fjs/types/range/proof.f.js +9 -0
- package/{fs → fjs}/types/range_map/proof.f.js +28 -81
- package/{fs → fjs}/types/result/proof.f.d.ts +3 -2
- package/fjs/types/result/proof.f.js +31 -0
- package/{fs → fjs}/types/rtti/common/module.f.d.ts +36 -1
- package/{fs → fjs}/types/rtti/common/module.f.js +44 -0
- package/fjs/types/rtti/common/proof.f.d.ts +8 -0
- package/fjs/types/rtti/common/proof.f.js +51 -0
- package/{fs → fjs}/types/rtti/parse/module.f.js +13 -22
- package/{fs → fjs}/types/rtti/parse/proof.f.js +7 -18
- package/{fs → fjs}/types/rtti/ts/module.f.d.ts +10 -4
- package/{fs → fjs}/types/rtti/validate/module.f.js +8 -29
- package/{fs → fjs}/types/rtti/validate/proof.f.js +4 -9
- package/{fs → fjs}/types/sorted_list/proof.f.js +8 -21
- package/{fs → fjs}/types/sorted_set/proof.f.js +14 -39
- package/{fs → fjs}/types/string/module.f.js +10 -2
- package/fjs/types/string/proof.f.js +77 -0
- package/fjs/types/string_set/proof.f.js +43 -0
- package/{fs → fjs}/types/ts/proof.f.js +15 -42
- package/{fs → fjs}/types/uint8array/module.f.js +7 -7
- package/{fs → fjs}/types/uint8array/proof.f.d.ts +4 -1
- package/{fs → fjs}/types/uint8array/proof.f.js +7 -7
- package/{fs → fjs}/website/module.f.js +2 -3
- package/{fs → fjs}/website/proof.f.js +3 -6
- package/package.json +8 -8
- package/fs/asserts/module.f.d.ts +0 -4
- package/fs/asserts/module.f.js +0 -9
- package/fs/asserts/proof.f.d.ts +0 -8
- package/fs/asserts/proof.f.js +0 -51
- package/fs/bnf/data/module.f.d.ts +0 -30
- package/fs/bnf/descent/module.f.js +0 -119
- package/fs/bnf/proof.f.js +0 -104
- package/fs/cas/mcp/module.f.d.ts +0 -36
- package/fs/cas/proof.f.d.ts +0 -20
- package/fs/cas/proof.f.js +0 -294
- package/fs/common/monoid/module.f.js +0 -44
- package/fs/common/monoid/proof.f.d.ts +0 -4
- package/fs/common/monoid/proof.f.js +0 -27
- package/fs/crypto/pow/proof.f.js +0 -161
- package/fs/djs/tokenizer/module.f.d.ts +0 -12
- package/fs/djs/tokenizer/module.f.js +0 -62
- package/fs/djs/tokenizer/proof.f.d.ts +0 -7
- package/fs/djs/tokenizer/proof.f.js +0 -543
- package/fs/djs/tokenizer-new/module.f.d.ts +0 -3
- package/fs/djs/tokenizer-new/module.f.js +0 -155
- package/fs/effects/module.f.d.ts +0 -106
- package/fs/effects/module.f.js +0 -80
- package/fs/effects/proof.f.d.ts +0 -25
- package/fs/effects/proof.f.js +0 -115
- package/fs/media/revision/proof.f.js +0 -119
- package/fs/text/ascii/proof.f.d.ts +0 -4
- package/fs/types/bigfloat/proof.f.js +0 -348
- package/fs/types/nullable/proof.f.js +0 -50
- package/fs/types/range/module.f.js +0 -2
- package/fs/types/range/proof.f.js +0 -18
- package/fs/types/result/proof.f.js +0 -52
- package/fs/types/string/proof.f.js +0 -118
- package/fs/types/string_set/proof.f.js +0 -82
- /package/{fs → fjs}/asn.1/module.f.d.ts +0 -0
- /package/{fs → fjs}/asn.1/module.f.js +0 -0
- /package/{fs → fjs}/asn.1/proof.f.d.ts +0 -0
- /package/{fs → fjs}/base_n/module.f.d.ts +0 -0
- /package/{fs → fjs}/base_n/module.f.js +0 -0
- /package/{fs → fjs}/base_n/proof.f.d.ts +0 -0
- /package/{fs → fjs}/basen/base128/module.f.d.ts +0 -0
- /package/{fs → fjs}/basen/base128/module.f.js +0 -0
- /package/{fs → fjs}/basen/base128/proof.f.d.ts +0 -0
- /package/{fs → fjs}/basen/base128/proof.f.js +0 -0
- /package/{fs → fjs}/basen/base64/module.f.d.ts +0 -0
- /package/{fs → fjs}/basen/base64/module.f.js +0 -0
- /package/{fs → fjs}/basen/cbase32/module.f.d.ts +0 -0
- /package/{fs → fjs}/basen/cbase32/module.f.js +0 -0
- /package/{fs → fjs}/basen/cbase32/proof.f.d.ts +0 -0
- /package/{fs → fjs}/bnf/proof.f.d.ts +0 -0
- /package/{fs → fjs}/bnf/testlib.f.d.ts +0 -0
- /package/{fs → fjs}/cas/cli/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/bun/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/deno/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/node/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/playwright/module.f.d.ts +0 -0
- /package/{fs → fjs}/ci/playwright/module.f.js +0 -0
- /package/{fs → fjs}/ci/proof.f.d.ts +0 -0
- /package/{fs → fjs}/ci/rust/module.f.d.ts +0 -0
- /package/{fs → fjs}/cli/module.f.d.ts +0 -0
- /package/{fs → fjs}/cli/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/hmac/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/hmac/module.f.js +0 -0
- /package/{fs → fjs}/crypto/hmac/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/pow/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/pow/module.f.js +0 -0
- /package/{fs → fjs}/crypto/pow/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/secp/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/secp/module.f.js +0 -0
- /package/{fs → fjs}/crypto/secp/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/sha2/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/sha2/module.f.js +0 -0
- /package/{fs → fjs}/crypto/sha2/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/sign/proof.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/vdf/module.f.d.ts +0 -0
- /package/{fs → fjs}/crypto/vdf/module.f.js +0 -0
- /package/{fs → fjs}/crypto/vdf/proof.f.d.ts +0 -0
- /package/{fs → fjs}/dev/module.f.d.ts +0 -0
- /package/{fs → fjs}/dev/package_json/module.f.d.ts +0 -0
- /package/{fs → fjs}/dev/package_json/module.f.js +0 -0
- /package/{fs → fjs}/dev/package_json/proof.f.d.ts +0 -0
- /package/{fs → fjs}/dev/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/ast/module.f.d.ts +0 -0
- /package/{fs → fjs}/djs/ast/module.f.js +0 -0
- /package/{fs → fjs}/djs/ast/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/examples/input.f.d.ts +0 -0
- /package/{fs → fjs}/djs/examples/input.f.js +0 -0
- /package/{fs → fjs}/djs/examples/m.f.d.ts +0 -0
- /package/{fs → fjs}/djs/examples/m.f.js +0 -0
- /package/{fs → fjs}/djs/module.f.d.ts +0 -0
- /package/{fs → fjs}/djs/parser/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/serializer/module.f.d.ts +0 -0
- /package/{fs → fjs}/djs/serializer/module.f.js +0 -0
- /package/{fs → fjs}/djs/serializer/proof.f.d.ts +0 -0
- /package/{fs → fjs}/djs/transpiler/module.f.d.ts +0 -0
- /package/{fs → fjs}/effects/memory/module.f.d.ts +0 -0
- /package/{fs → fjs}/effects/memory/module.f.js +0 -0
- /package/{fs → fjs}/effects/memory/proof.f.d.ts +0 -0
- /package/{fs → fjs}/effects/mock/module.f.d.ts +0 -0
- /package/{fs → fjs}/effects/mock/module.f.js +0 -0
- /package/{fs → fjs}/effects/module.d.ts +0 -0
- /package/{fs → fjs}/effects/module.js +0 -0
- /package/{fs → fjs}/effects/node/memory/module.d.ts +0 -0
- /package/{fs → fjs}/effects/node/memory/module.js +0 -0
- /package/{fs → fjs}/effects/node/memory/proof.d.ts +0 -0
- /package/{fs → fjs}/effects/node/virtual/module.f.d.ts +0 -0
- /package/{fs → fjs}/effects/node/virtual/module.f.js +0 -0
- /package/{fs → fjs}/emergent_testing/all.test.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/all.test.js +0 -0
- /package/{fs → fjs}/emergent_testing/example.f.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/example.f.js +0 -0
- /package/{fs → fjs}/emergent_testing/module.f.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/all.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/all.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async-subtests.fail.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async-subtests.fail.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async-subtests.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async-subtests.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async.fail.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async.fail.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/async.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/fail.fail.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/fail.fail.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/return-value.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/return-value.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/thenable.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/thenable.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/thenable2.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/thenable2.pass.js +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/throw.pass.d.ts +0 -0
- /package/{fs → fjs}/emergent_testing/scenarios/throw.pass.js +0 -0
- /package/{fs → fjs}/fsc/bnf.f.d.ts +0 -0
- /package/{fs → fjs}/fsc/bnf.f.js +0 -0
- /package/{fs → fjs}/fsc/json.f.d.ts +0 -0
- /package/{fs → fjs}/fsc/json.f.js +0 -0
- /package/{fs → fjs}/fsc/module.f.d.ts +0 -0
- /package/{fs → fjs}/fsc/module.f.js +0 -0
- /package/{fs → fjs}/fsc/proof.f.d.ts +0 -0
- /package/{fs → fjs}/fsm/module.f.d.ts +0 -0
- /package/{fs → fjs}/fsm/module.f.js +0 -0
- /package/{fs → fjs}/fsm/proof.f.d.ts +0 -0
- /package/{fs → fjs}/js/tokenizer/module.f.d.ts +0 -0
- /package/{fs → fjs}/js/tokenizer/module.f.js +0 -0
- /package/{fs → fjs}/js/tokenizer/proof.f.d.ts +0 -0
- /package/{fs → fjs}/js/tokenizer/proof.f.js +0 -0
- /package/{fs → fjs}/mcp/proof.f.d.ts +0 -0
- /package/{fs → fjs}/mcp/stdio/proof.f.d.ts +0 -0
- /package/{fs → fjs}/mcp/stdio/proof.f.js +0 -0
- /package/{fs → fjs}/media/html/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/html/module.f.js +0 -0
- /package/{fs → fjs}/media/html/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/module.f.js +0 -0
- /package/{fs → fjs}/media/json/parser/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/proof.f.js +0 -0
- /package/{fs → fjs}/media/json/rpc/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/rpc/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/rpc/proof.f.js +0 -0
- /package/{fs → fjs}/media/json/schema/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/serializer/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/serializer/module.f.js +0 -0
- /package/{fs → fjs}/media/json/serializer/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/tokenizer/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/tokenizer/module.f.js +0 -0
- /package/{fs → fjs}/media/json/tokenizer/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/json/tokenizer/proof.f.js +0 -0
- /package/{fs → fjs}/media/proof.f.d.ts +0 -0
- /package/{fs → fjs}/media/type/module.f.d.ts +0 -0
- /package/{fs → fjs}/media/type/proof.f.d.ts +0 -0
- /package/{fs → fjs}/module.d.ts +0 -0
- /package/{fs → fjs}/module.f.d.ts +0 -0
- /package/{fs → fjs}/module.js +0 -0
- /package/{fs → fjs}/path/module.f.d.ts +0 -0
- /package/{fs → fjs}/path/module.f.js +0 -0
- /package/{fs → fjs}/path/proof.f.d.ts +0 -0
- /package/{fs → fjs}/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/id/module.f.d.ts +0 -0
- /package/{fs → fjs}/sul/id/module.f.js +0 -0
- /package/{fs → fjs}/sul/id/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/level/hash/module.f.d.ts +0 -0
- /package/{fs → fjs}/sul/level/hash/module.f.js +0 -0
- /package/{fs → fjs}/sul/level/hash/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/level/literal/module.f.d.ts +0 -0
- /package/{fs → fjs}/sul/level/literal/module.f.js +0 -0
- /package/{fs → fjs}/sul/level/literal/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/module.f.d.ts +0 -0
- /package/{fs → fjs}/sul/module.f.js +0 -0
- /package/{fs → fjs}/sul/proof.f.d.ts +0 -0
- /package/{fs → fjs}/sul/proof.f.js +0 -0
- /package/{fs → fjs}/text/ascii/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/ascii/module.f.js +0 -0
- /package/{fs → fjs}/text/code_point/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/code_point/proof.f.d.ts +0 -0
- /package/{fs → fjs}/text/code_point/proof.f.js +0 -0
- /package/{fs → fjs}/text/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/module.f.js +0 -0
- /package/{fs → fjs}/text/proof.f.d.ts +0 -0
- /package/{fs → fjs}/text/sgr/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/sgr/module.f.js +0 -0
- /package/{fs → fjs}/text/sgr/proof.f.d.ts +0 -0
- /package/{fs → fjs}/text/utf16/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/utf16/proof.f.d.ts +0 -0
- /package/{fs → fjs}/text/utf8/module.f.d.ts +0 -0
- /package/{fs → fjs}/text/utf8/module.f.js +0 -0
- /package/{fs → fjs}/text/utf8/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/array/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/array/module.f.js +0 -0
- /package/{fs → fjs}/types/array/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/bigfloat/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/bigfloat/module.f.js +0 -0
- /package/{fs → fjs}/types/bigfloat/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/bigint/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/bigint/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/bit_vec/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/bit_vec/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/find/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/find/module.f.js +0 -0
- /package/{fs → fjs}/types/btree/find/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/module.f.js +0 -0
- /package/{fs → fjs}/types/btree/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/types/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/btree/types/module.f.js +0 -0
- /package/{fs → fjs}/types/byte_set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/byte_set/module.f.js +0 -0
- /package/{fs → fjs}/types/byte_set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/compare/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/compare/module.f.js +0 -0
- /package/{fs → fjs}/types/function/compare/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/module.f.js +0 -0
- /package/{fs → fjs}/types/function/operator/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/operator/module.f.js +0 -0
- /package/{fs → fjs}/types/function/operator/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/function/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/map/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/map/module.f.js +0 -0
- /package/{fs → fjs}/types/map/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/nibble_set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/nibble_set/module.f.js +0 -0
- /package/{fs → fjs}/types/nibble_set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/nominal/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/nominal/module.f.js +0 -0
- /package/{fs → fjs}/types/nominal/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/nullable/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/nullable/module.f.js +0 -0
- /package/{fs → fjs}/types/nullable/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/number/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/number/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/object/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/object/module.f.js +0 -0
- /package/{fs → fjs}/types/object/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/option/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/option/module.f.js +0 -0
- /package/{fs → fjs}/types/ordered_map/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/ordered_map/module.f.js +0 -0
- /package/{fs → fjs}/types/ordered_map/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/ordered_map/proof.f.js +0 -0
- /package/{fs → fjs}/types/patricia_trie/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/patricia_trie/module.f.js +0 -0
- /package/{fs → fjs}/types/patricia_trie/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/phantom/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/phantom/module.f.js +0 -0
- /package/{fs → fjs}/types/prime_field/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/prime_field/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/prime_field/proof.f.js +0 -0
- /package/{fs → fjs}/types/range/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/range_map/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/range_map/module.f.js +0 -0
- /package/{fs → fjs}/types/range_map/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/result/module.d.ts +0 -0
- /package/{fs → fjs}/types/result/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/result/module.f.js +0 -0
- /package/{fs → fjs}/types/result/module.js +0 -0
- /package/{fs → fjs}/types/rtti/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/module.f.js +0 -0
- /package/{fs → fjs}/types/rtti/parse/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/parse/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/proof.f.js +0 -0
- /package/{fs → fjs}/types/rtti/ts/module.f.js +0 -0
- /package/{fs → fjs}/types/rtti/ts/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/ts/proof.f.js +0 -0
- /package/{fs → fjs}/types/rtti/validate/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/rtti/validate/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/sorted_list/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/sorted_list/module.f.js +0 -0
- /package/{fs → fjs}/types/sorted_list/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/sorted_set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/sorted_set/module.f.js +0 -0
- /package/{fs → fjs}/types/sorted_set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/string/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/string/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/string_set/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/string_set/module.f.js +0 -0
- /package/{fs → fjs}/types/string_set/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/ts/module.f.d.ts +0 -0
- /package/{fs → fjs}/types/ts/module.f.js +0 -0
- /package/{fs → fjs}/types/ts/proof.f.d.ts +0 -0
- /package/{fs → fjs}/types/uint8array/module.f.d.ts +0 -0
- /package/{fs → fjs}/website/module.f.d.ts +0 -0
- /package/{fs → fjs}/website/proof.f.d.ts +0 -0
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ The CAS is also exposed as an [MCP](https://modelcontextprotocol.io/) server so
|
|
|
60
60
|
claude mcp add cas -- npx functionalscript m
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
See [`
|
|
63
|
+
See [`fjs/cas/mcp/README.md`](fjs/cas/mcp/README.md) for details on the `cas_add`, `cas_get`, and `cas_list` tools.
|
|
64
64
|
|
|
65
65
|
## Vision
|
|
66
66
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { empty, isVec, length, msb, uint, unpack, vec, vec8 } from "../types/bit_vec/module.f.js";
|
|
2
2
|
import { asBase } from "../types/nominal/module.f.js";
|
|
3
3
|
import { decodeRaw, decodeInteger, encodeRaw, encodeInteger, integer, encode, decode, constructedSequence, octetString, boolean, constructedSet, encodeObjectIdentifier, decodeObjectIdentifier, } from "./module.f.js";
|
|
4
|
-
import { assertEq } from
|
|
4
|
+
import { assert, assertEq } from '../asserts/module.f.js';
|
|
5
5
|
const { concat, popFront: pop, listToVec } = msb;
|
|
6
6
|
const pop8 = pop(8n);
|
|
7
7
|
const check = (tag, v, rest) => {
|
|
@@ -23,9 +23,7 @@ const integerValueCheck = (i, v) => {
|
|
|
23
23
|
throw `encode: ${asBase(v)}, ${asBase(v0)}`;
|
|
24
24
|
}
|
|
25
25
|
const i0 = decodeInteger(v);
|
|
26
|
-
|
|
27
|
-
throw [i, i0];
|
|
28
|
-
}
|
|
26
|
+
assertEq(i, i0, [i, i0]);
|
|
29
27
|
};
|
|
30
28
|
const ch0 = (r, v, rest) => {
|
|
31
29
|
const [r0, rest0] = decode(concat(v)(rest));
|
|
@@ -51,24 +49,14 @@ export const proof = {
|
|
|
51
49
|
const v = vec8(0x13n);
|
|
52
50
|
const x = encodeRaw([integer, v]);
|
|
53
51
|
const lx = length(x);
|
|
54
|
-
|
|
55
|
-
throw lx;
|
|
56
|
-
}
|
|
52
|
+
assertEq(lx, 24n);
|
|
57
53
|
const [tag, x1] = pop8(x);
|
|
58
|
-
|
|
59
|
-
throw tag;
|
|
60
|
-
}
|
|
54
|
+
assertEq(tag, BigInt(integer));
|
|
61
55
|
const [len, x2] = pop8(x1);
|
|
62
|
-
|
|
63
|
-
throw len;
|
|
64
|
-
}
|
|
56
|
+
assertEq(len, 1n);
|
|
65
57
|
const { length: intLen, uint } = unpack(x2);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
if (uint !== 0x13n) {
|
|
70
|
-
throw uint;
|
|
71
|
-
}
|
|
58
|
+
assertEq(intLen, 8n);
|
|
59
|
+
assertEq(uint, 0x13n);
|
|
72
60
|
},
|
|
73
61
|
encode7F: () => {
|
|
74
62
|
const valueLen = 0x7fn << 3n;
|
|
@@ -76,24 +64,14 @@ export const proof = {
|
|
|
76
64
|
const v = vec(valueLen)(value);
|
|
77
65
|
const x = encodeRaw([integer, v]);
|
|
78
66
|
const lx = length(x);
|
|
79
|
-
|
|
80
|
-
throw lx;
|
|
81
|
-
}
|
|
67
|
+
assertEq(lx, 0x81n << 3n);
|
|
82
68
|
const [tag, x1] = pop8(x);
|
|
83
|
-
|
|
84
|
-
throw tag;
|
|
85
|
-
}
|
|
69
|
+
assertEq(tag, BigInt(integer));
|
|
86
70
|
const [len, x2] = pop8(x1);
|
|
87
|
-
|
|
88
|
-
throw len;
|
|
89
|
-
}
|
|
71
|
+
assertEq(len, 0x7fn);
|
|
90
72
|
const { length: intLen, uint } = unpack(x2);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
if (uint !== value) {
|
|
95
|
-
throw uint;
|
|
96
|
-
}
|
|
73
|
+
assertEq(intLen, valueLen);
|
|
74
|
+
assertEq(uint, value);
|
|
97
75
|
},
|
|
98
76
|
encode80: () => {
|
|
99
77
|
const valueLen = 0x80n << 3n;
|
|
@@ -101,28 +79,16 @@ export const proof = {
|
|
|
101
79
|
const v = vec(valueLen)(value);
|
|
102
80
|
const x = encodeRaw([integer, v]);
|
|
103
81
|
const lx = length(x);
|
|
104
|
-
|
|
105
|
-
throw lx;
|
|
106
|
-
}
|
|
82
|
+
assertEq(lx, 0x83n << 3n);
|
|
107
83
|
const [tag, x1] = pop8(x);
|
|
108
|
-
|
|
109
|
-
throw tag;
|
|
110
|
-
}
|
|
84
|
+
assertEq(tag, BigInt(integer));
|
|
111
85
|
const [lenLen, x2] = pop8(x1);
|
|
112
|
-
|
|
113
|
-
throw lenLen;
|
|
114
|
-
}
|
|
86
|
+
assertEq(lenLen, 0x81n);
|
|
115
87
|
const [len, x3] = pop8(x2);
|
|
116
|
-
|
|
117
|
-
throw len;
|
|
118
|
-
}
|
|
88
|
+
assertEq(len, 0x80n);
|
|
119
89
|
const { length: intLen, uint } = unpack(x3);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
if (uint !== value) {
|
|
124
|
-
throw uint;
|
|
125
|
-
}
|
|
90
|
+
assertEq(intLen, valueLen);
|
|
91
|
+
assertEq(uint, value);
|
|
126
92
|
},
|
|
127
93
|
encodeFF: () => {
|
|
128
94
|
const valueLen = 0xffn << 3n;
|
|
@@ -134,24 +100,14 @@ export const proof = {
|
|
|
134
100
|
throw `lx: ${lx}`;
|
|
135
101
|
}
|
|
136
102
|
const [tag, x1] = pop8(x);
|
|
137
|
-
|
|
138
|
-
throw tag;
|
|
139
|
-
}
|
|
103
|
+
assertEq(tag, BigInt(integer));
|
|
140
104
|
const [lenLen, x2] = pop8(x1);
|
|
141
|
-
|
|
142
|
-
throw lenLen;
|
|
143
|
-
}
|
|
105
|
+
assertEq(lenLen, 0x81n);
|
|
144
106
|
const [len, x3] = pop8(x2);
|
|
145
|
-
|
|
146
|
-
throw len;
|
|
147
|
-
}
|
|
107
|
+
assertEq(len, 0xffn);
|
|
148
108
|
const { length: intLen, uint } = unpack(x3);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
if (uint !== value) {
|
|
153
|
-
throw uint;
|
|
154
|
-
}
|
|
109
|
+
assertEq(intLen, valueLen);
|
|
110
|
+
assertEq(uint, value);
|
|
155
111
|
},
|
|
156
112
|
encode103: () => {
|
|
157
113
|
const valueLen = 0x103n << 3n;
|
|
@@ -163,32 +119,20 @@ export const proof = {
|
|
|
163
119
|
throw `lx: ${lx}`;
|
|
164
120
|
}
|
|
165
121
|
const [tag, x1] = pop8(x);
|
|
166
|
-
|
|
167
|
-
throw tag;
|
|
168
|
-
}
|
|
122
|
+
assertEq(tag, BigInt(integer));
|
|
169
123
|
const [lenLen, x2] = pop8(x1);
|
|
170
|
-
|
|
171
|
-
throw lenLen;
|
|
172
|
-
}
|
|
124
|
+
assertEq(lenLen, 0x82n);
|
|
173
125
|
const [len, x3] = pop(16n)(x2);
|
|
174
|
-
|
|
175
|
-
throw len;
|
|
176
|
-
}
|
|
126
|
+
assertEq(len, 0x103n);
|
|
177
127
|
const { length: intLen, uint } = unpack(x3);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
if (uint !== value) {
|
|
182
|
-
throw uint;
|
|
183
|
-
}
|
|
128
|
+
assertEq(intLen, valueLen);
|
|
129
|
+
assertEq(uint, value);
|
|
184
130
|
},
|
|
185
131
|
ed: [
|
|
186
132
|
() => {
|
|
187
133
|
const tag = integer;
|
|
188
134
|
const v = vec(0x10n)(0x8234n);
|
|
189
|
-
|
|
190
|
-
throw asBase(v).toString(16);
|
|
191
|
-
}
|
|
135
|
+
assertEq(asBase(v), 0x8234n, asBase(v).toString(16));
|
|
192
136
|
check(integer, v, empty);
|
|
193
137
|
},
|
|
194
138
|
{
|
|
@@ -297,16 +241,10 @@ export const proof = {
|
|
|
297
241
|
// bitString (0x03) is not in SupportedRecord, exercises the default case in rawToRecord
|
|
298
242
|
const raw = encodeRaw([0x03n, vec8(0x42n)]);
|
|
299
243
|
const [decoded, rest] = decode(raw);
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
if (rest !== empty) {
|
|
304
|
-
throw 'expected empty rest';
|
|
305
|
-
}
|
|
244
|
+
assert(isVec(decoded), 'expected UnsupportedRecord (Vec)');
|
|
245
|
+
assertEq(rest, empty, 'expected empty rest');
|
|
306
246
|
// Re-encoding an UnsupportedRecord returns it unchanged (it is already the TLV bytes)
|
|
307
|
-
|
|
308
|
-
throw 'encode should round-trip UnsupportedRecord';
|
|
309
|
-
}
|
|
247
|
+
assertEq(encode(decoded), raw, 'encode should round-trip UnsupportedRecord');
|
|
310
248
|
},
|
|
311
249
|
raw: [
|
|
312
250
|
() => {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assertion helpers for runtime checks and compile-time type-level tests.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Marks a code path as unimplemented. Always throws.
|
|
8
|
+
*/
|
|
9
|
+
export declare const todo: () => never;
|
|
10
|
+
/**
|
|
11
|
+
* Throws `msg` (default `'assertion failed'`) if `v` is `false`.
|
|
12
|
+
*
|
|
13
|
+
* Narrows `v` to `true` via `asserts v`, so callers can rely on the
|
|
14
|
+
* condition holding for the rest of the enclosing scope.
|
|
15
|
+
*/
|
|
16
|
+
export declare const assert: (v: boolean, msg?: unknown) => asserts v;
|
|
17
|
+
/**
|
|
18
|
+
* Asserts that `a` and `b` are `===`, throwing `x` (the `[a, b]` pair, plus
|
|
19
|
+
* an optional third element used as an extra message) if they differ.
|
|
20
|
+
*/
|
|
21
|
+
export declare const assertEq: <T>(...x: readonly [T, T, unknown?]) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Compile-time-only check: a type resolves only if it is exactly `true`.
|
|
24
|
+
* Used to assert type-level properties without any runtime cost, e.g.
|
|
25
|
+
* `type _ = Assert<Equal<A, B>>`.
|
|
26
|
+
*/
|
|
27
|
+
export type Assert<T extends true> = T;
|
|
28
|
+
/**
|
|
29
|
+
* Asserts that `a` is neither `null` nor `undefined` and returns it,
|
|
30
|
+
* narrowed to `T`.
|
|
31
|
+
*
|
|
32
|
+
* Use this to chain directly off a call that may return a nullish value,
|
|
33
|
+
* e.g. `const r = assertNotNullish(f(x))`. For a variable that already
|
|
34
|
+
* exists, prefer `assert(a !== null && a !== undefined)` instead.
|
|
35
|
+
*/
|
|
36
|
+
export declare const assertNotNullish: <T>(a: T | null | undefined, msg?: unknown) => T;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assertion helpers for runtime checks and compile-time type-level tests.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Marks a code path as unimplemented. Always throws.
|
|
8
|
+
*/
|
|
9
|
+
export const todo = () => { throw 'not implemented'; };
|
|
10
|
+
/**
|
|
11
|
+
* Throws `msg` (default `'assertion failed'`) if `v` is `false`.
|
|
12
|
+
*
|
|
13
|
+
* Narrows `v` to `true` via `asserts v`, so callers can rely on the
|
|
14
|
+
* condition holding for the rest of the enclosing scope.
|
|
15
|
+
*/
|
|
16
|
+
export const assert = (v, msg = 'assertion failed') => {
|
|
17
|
+
if (!v)
|
|
18
|
+
throw msg;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Asserts that `a` and `b` are `===`, throwing `x` (the `[a, b]` pair, plus
|
|
22
|
+
* an optional third element used as an extra message) if they differ.
|
|
23
|
+
*/
|
|
24
|
+
export const assertEq = (...x) => {
|
|
25
|
+
const [a, b] = x;
|
|
26
|
+
assert(a === b, x);
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Asserts that `a` is neither `null` nor `undefined` and returns it,
|
|
30
|
+
* narrowed to `T`.
|
|
31
|
+
*
|
|
32
|
+
* Use this to chain directly off a call that may return a nullish value,
|
|
33
|
+
* e.g. `const r = assertNotNullish(f(x))`. For a variable that already
|
|
34
|
+
* exists, prefer `assert(a !== null && a !== undefined)` instead.
|
|
35
|
+
*/
|
|
36
|
+
export const assertNotNullish = (a, msg) => {
|
|
37
|
+
assert(a !== null && a !== undefined, msg);
|
|
38
|
+
return a;
|
|
39
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const proof: {
|
|
2
|
+
assertPassesOnTrue: () => void;
|
|
3
|
+
assertEqPassesOnEqual: () => void;
|
|
4
|
+
throw: {
|
|
5
|
+
assertEqThrowsOnUnequal: () => void;
|
|
6
|
+
assertEqThrowsOnUnequal3: () => void;
|
|
7
|
+
assertThrowsDefaultMsg: () => void;
|
|
8
|
+
assertThrowsCustomMsg: () => void;
|
|
9
|
+
todoThrows: () => never;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { assert, assertEq, todo } from './module.f.js';
|
|
2
|
+
export const proof = {
|
|
3
|
+
assertPassesOnTrue: () => {
|
|
4
|
+
assert(true);
|
|
5
|
+
assert(true, 'with message');
|
|
6
|
+
},
|
|
7
|
+
assertEqPassesOnEqual: () => {
|
|
8
|
+
assertEq(1, 1);
|
|
9
|
+
assertEq('x', 'x');
|
|
10
|
+
},
|
|
11
|
+
throw: {
|
|
12
|
+
assertEqThrowsOnUnequal: () => assertEq(1, 2),
|
|
13
|
+
assertEqThrowsOnUnequal3: () => assertEq(1, 2, "message"),
|
|
14
|
+
assertThrowsDefaultMsg: () => assert(false),
|
|
15
|
+
assertThrowsCustomMsg: () => assert(false, 'oops'),
|
|
16
|
+
todoThrows: () => todo(),
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -25,67 +25,43 @@ const bigSampleHex = `f`.repeat(Number(maxLength >> 2n));
|
|
|
25
25
|
export const proof = {
|
|
26
26
|
encodeEmpty: () => {
|
|
27
27
|
const s = hex.vecToString(empty);
|
|
28
|
-
|
|
29
|
-
throw [s];
|
|
30
|
-
}
|
|
28
|
+
assertEq(s, '', [s]);
|
|
31
29
|
},
|
|
32
30
|
encodeAligned: () => {
|
|
33
31
|
// Two 4-bit chunks → two hex digits
|
|
34
32
|
const s = hex.vecToString(vec(8n)(0xa5n));
|
|
35
|
-
|
|
36
|
-
throw [s];
|
|
37
|
-
}
|
|
33
|
+
assertEq(s, 'a5', [s]);
|
|
38
34
|
},
|
|
39
35
|
encodeUnaligned: () => {
|
|
40
36
|
// 6 bits → first 4-bit chunk + a 2-bit tail that popFront pads with
|
|
41
37
|
// trailing zeros (the standard `popFront` behaviour the codec inherits).
|
|
42
38
|
const s = hex.vecToString(vec(6n)(41n));
|
|
43
|
-
|
|
44
|
-
throw [s];
|
|
45
|
-
}
|
|
39
|
+
assertEq(s, 'a4', [s]);
|
|
46
40
|
},
|
|
47
41
|
decodeEmpty: () => {
|
|
48
42
|
const v = hex.stringToVec('');
|
|
49
|
-
|
|
50
|
-
throw [v];
|
|
51
|
-
}
|
|
43
|
+
assertEq(v, empty, [v]);
|
|
52
44
|
},
|
|
53
45
|
decodeRoundTrip: () => {
|
|
54
46
|
const v = hex.stringToVec('ab');
|
|
55
|
-
|
|
56
|
-
throw [v];
|
|
57
|
-
}
|
|
47
|
+
assertEq(v, vec(8n)(0xabn), [v]);
|
|
58
48
|
},
|
|
59
49
|
decodeInvalid: () => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
if (hex.stringToVec('aZ') !== null) {
|
|
64
|
-
throw 'mixed invalid char should return null';
|
|
65
|
-
}
|
|
50
|
+
assertEq(hex.stringToVec('z'), null, 'invalid char should return null');
|
|
51
|
+
assertEq(hex.stringToVec('aZ'), null, 'mixed invalid char should return null');
|
|
66
52
|
},
|
|
67
53
|
normalizeHit: () => {
|
|
68
54
|
// 'A' lowercases to 'a' — same vector as the lowercase input.
|
|
69
55
|
const a = cb32.stringToVec('A');
|
|
70
56
|
const b = cb32.stringToVec('a');
|
|
71
|
-
|
|
72
|
-
throw [a, b];
|
|
73
|
-
}
|
|
57
|
+
assertEq(a, b, [a, b]);
|
|
74
58
|
// Crockford folds: i,l → 1 and o → 0.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (cb32.stringToVec('l') !== cb32.stringToVec('1')) {
|
|
79
|
-
throw 'l→1';
|
|
80
|
-
}
|
|
81
|
-
if (cb32.stringToVec('o') !== cb32.stringToVec('0')) {
|
|
82
|
-
throw 'o→0';
|
|
83
|
-
}
|
|
59
|
+
assertEq(cb32.stringToVec('I'), cb32.stringToVec('1'), 'I→1');
|
|
60
|
+
assertEq(cb32.stringToVec('l'), cb32.stringToVec('1'), 'l→1');
|
|
61
|
+
assertEq(cb32.stringToVec('o'), cb32.stringToVec('0'), 'o→0');
|
|
84
62
|
},
|
|
85
63
|
normalizeMiss: () => {
|
|
86
|
-
|
|
87
|
-
throw 'unknown char should return null';
|
|
88
|
-
}
|
|
64
|
+
assertEq(cb32.stringToVec('u'), null, 'unknown char should return null');
|
|
89
65
|
},
|
|
90
66
|
// Decodes a 1 Mibit hex string. With the O(n log n) `listToVec` builder this
|
|
91
67
|
// runs in well under a second (was ~13 s node / ~43 s bun under the old
|
|
@@ -9,6 +9,7 @@ export declare const proof: {
|
|
|
9
9
|
validPadding: () => void;
|
|
10
10
|
knownVectors: () => void;
|
|
11
11
|
decodeOverflow: () => void;
|
|
12
|
+
decodePaddedTailRejections: () => void;
|
|
12
13
|
encodeAtMaxLengthSucceeds: () => void;
|
|
13
14
|
decodeAtMaxLengthSucceeds: () => void;
|
|
14
15
|
encodeLargeVecIsSlow: () => void;
|
|
@@ -83,6 +83,20 @@ export const proof = {
|
|
|
83
83
|
const oversized = 'A'.repeat(174_764);
|
|
84
84
|
assertEq(decode(oversized), null);
|
|
85
85
|
},
|
|
86
|
+
decodePaddedTailRejections: () => {
|
|
87
|
+
// These all take the padded branch of `decode` (`padChars > 0`,
|
|
88
|
+
// i.e. the `head`/`lastChunk` split), unlike `decodeOverflow` above
|
|
89
|
+
// which takes the unpadded fast path. An invalid character before
|
|
90
|
+
// the final char must be rejected via the `head` decode...
|
|
91
|
+
assertEq(decode('!A=='), null);
|
|
92
|
+
// ...and an invalid final character (the one holding the padding
|
|
93
|
+
// bits) must be rejected via the last-character decode.
|
|
94
|
+
assertEq(decode('A!=='), null);
|
|
95
|
+
// Same as `decodeOverflow`, but with a padded tail so it's the
|
|
96
|
+
// padded branch that measures the result against `maxLength` and
|
|
97
|
+
// rejects it.
|
|
98
|
+
assertEq(decode('A'.repeat(174_764) + '='), null);
|
|
99
|
+
},
|
|
86
100
|
encodeAtMaxLengthSucceeds: () => {
|
|
87
101
|
// A `maxLength`-sized vector's trailing partial 6-bit chunk is
|
|
88
102
|
// left-padded by `vecToString` itself (see `baseN`), so `encode`
|
|
@@ -99,7 +113,7 @@ export const proof = {
|
|
|
99
113
|
check('A'.repeat(174_763) + '=', vec(maxLength)(0n));
|
|
100
114
|
},
|
|
101
115
|
// Regression guard: `encode` used to be quadratic in the input size, not
|
|
102
|
-
// linear. `baseN`'s `vecToString` (`
|
|
116
|
+
// linear. `baseN`'s `vecToString` (`fjs/base_n/module.f.ts`) popped one
|
|
103
117
|
// 6-bit chunk off the front at a time via `popFront`, and each `popFront`
|
|
104
118
|
// re-masked the entire remaining bigint through `vec()`'s `m & ui` —
|
|
105
119
|
// O(remaining length) — so encoding a vector of `n` bits cost O(n²). A
|
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
import { empty, vec } from "../../types/bit_vec/module.f.js";
|
|
2
2
|
import { cBase32ToVec, cBase32ToVec5x, vec5xToCBase32, vecToCBase32 } from "./module.f.js";
|
|
3
|
+
import { assertEq } from '../../asserts/module.f.js';
|
|
3
4
|
const check5x = (s, v) => {
|
|
4
5
|
const sr = vec5xToCBase32(v);
|
|
5
|
-
|
|
6
|
-
throw [sr, s];
|
|
7
|
-
}
|
|
6
|
+
assertEq(sr, s, [sr, s]);
|
|
8
7
|
const vr = cBase32ToVec5x(s);
|
|
9
|
-
|
|
10
|
-
throw [vr, v];
|
|
11
|
-
}
|
|
8
|
+
assertEq(vr, v, [vr, v]);
|
|
12
9
|
//
|
|
13
10
|
check(`${s}g`, v);
|
|
14
11
|
};
|
|
15
12
|
const check = (s, v) => {
|
|
16
13
|
const sr = vecToCBase32(v);
|
|
17
|
-
|
|
18
|
-
throw [sr, s];
|
|
19
|
-
}
|
|
14
|
+
assertEq(sr, s, [sr, s]);
|
|
20
15
|
const vr = cBase32ToVec(s);
|
|
21
|
-
|
|
22
|
-
throw [vr, v];
|
|
23
|
-
}
|
|
16
|
+
assertEq(vr, v, [vr, v]);
|
|
24
17
|
};
|
|
25
18
|
export const proof = {
|
|
26
19
|
roundtrip5x: () => {
|
|
@@ -50,40 +43,20 @@ export const proof = {
|
|
|
50
43
|
unalignedBits: () => {
|
|
51
44
|
const v = vec(1n)(1n);
|
|
52
45
|
const cr = vec5xToCBase32(v);
|
|
53
|
-
|
|
54
|
-
throw ['g', cr];
|
|
55
|
-
}
|
|
46
|
+
assertEq(cr, "g", ['g', cr]);
|
|
56
47
|
},
|
|
57
48
|
caseInsensitive: () => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
if (cBase32ToVec5x("l") !== cBase32ToVec5x("1")) {
|
|
65
|
-
throw 'l maps to 1';
|
|
66
|
-
}
|
|
67
|
-
if (cBase32ToVec5x("o") !== cBase32ToVec5x("0")) {
|
|
68
|
-
throw 'o maps to 0';
|
|
69
|
-
}
|
|
70
|
-
if (cBase32ToVec5x("u") !== null) {
|
|
71
|
-
throw 'should error on invalid character';
|
|
72
|
-
}
|
|
49
|
+
assertEq(cBase32ToVec5x("A"), cBase32ToVec5x("a"), 'case-insensitive expected');
|
|
50
|
+
assertEq(cBase32ToVec5x("I"), cBase32ToVec5x("1"), 'i maps to 1');
|
|
51
|
+
assertEq(cBase32ToVec5x("l"), cBase32ToVec5x("1"), 'l maps to 1');
|
|
52
|
+
assertEq(cBase32ToVec5x("o"), cBase32ToVec5x("0"), 'o maps to 0');
|
|
53
|
+
assertEq(cBase32ToVec5x("u"), null, 'should error on invalid character');
|
|
73
54
|
},
|
|
74
55
|
unterminated: () => {
|
|
75
56
|
// No sentinel `1` bit → invalid; must return null, not loop forever.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
throw 'single zero symbol must be null';
|
|
81
|
-
}
|
|
82
|
-
if (cBase32ToVec("00") !== null) {
|
|
83
|
-
throw 'all-zero symbols must be null';
|
|
84
|
-
}
|
|
85
|
-
if (cBase32ToVec("o") !== null) {
|
|
86
|
-
throw 'o (maps to 0) must be null';
|
|
87
|
-
}
|
|
57
|
+
assertEq(cBase32ToVec(""), null, 'empty must be null');
|
|
58
|
+
assertEq(cBase32ToVec("0"), null, 'single zero symbol must be null');
|
|
59
|
+
assertEq(cBase32ToVec("00"), null, 'all-zero symbols must be null');
|
|
60
|
+
assertEq(cBase32ToVec("o"), null, 'o (maps to 0) must be null');
|
|
88
61
|
}
|
|
89
62
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type Rule as FRule } from '../module.f.ts';
|
|
2
|
+
import { type StringMap } from '../../types/object/module.f.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Encoded terminal range value used by BNF data rules.
|
|
5
|
+
*
|
|
6
|
+
* The same as the functional TerminalRange.
|
|
7
|
+
*/
|
|
8
|
+
export type TerminalRange = number;
|
|
9
|
+
/**
|
|
10
|
+
* Ordered list of grammar rule names.
|
|
11
|
+
*/
|
|
12
|
+
export type Sequence = readonly string[];
|
|
13
|
+
/** A variant of rule names. */
|
|
14
|
+
export type Variant = StringMap<string, string>;
|
|
15
|
+
/**
|
|
16
|
+
* Grammar rule definition.
|
|
17
|
+
*
|
|
18
|
+
* It can be one of:
|
|
19
|
+
* - a tagged variant map,
|
|
20
|
+
* - a sequence of referenced rule names,
|
|
21
|
+
* - an encoded terminal range.
|
|
22
|
+
*/
|
|
23
|
+
export type Rule = Variant | Sequence | TerminalRange;
|
|
24
|
+
/** The full grammar */
|
|
25
|
+
export type RuleSet = Readonly<Record<string, Rule>>;
|
|
26
|
+
/**
|
|
27
|
+
* Whether a rule can match empty input: `undefined` if it never can, `true`
|
|
28
|
+
* if it can with no tag (a nullable sequence), or the tag of the nullable
|
|
29
|
+
* variant branch.
|
|
30
|
+
*/
|
|
31
|
+
export type EmptyTag = string | true | undefined;
|
|
32
|
+
type EmptyTagMap = StringMap<string, EmptyTag>;
|
|
33
|
+
/**
|
|
34
|
+
* Computes, for every rule in the set, whether it can match empty input, by
|
|
35
|
+
* the standard nullable-set fixpoint: a sequence is nullable iff all of its
|
|
36
|
+
* items are (AND semantics), a variant iff at least one branch is (its tag is
|
|
37
|
+
* that branch's). Rules may reference each other cyclically (e.g. a `repeat`
|
|
38
|
+
* rule referring to itself), so this starts every rule as non-nullable and
|
|
39
|
+
* relaxes every rule, one round at a time, until a full round changes
|
|
40
|
+
* nothing. A round only ever grows the nullable set or moves a variant's
|
|
41
|
+
* chosen tag to a later (still-nullable) branch, both bounded, so this always
|
|
42
|
+
* terminates — but a rule's tag can still change for rounds *after* its own
|
|
43
|
+
* nullable/non-nullable status has already settled, while a cyclic
|
|
44
|
+
* dependency's tag catches up, so a fixed round count isn't enough.
|
|
45
|
+
*/
|
|
46
|
+
export declare const emptyTagMap: (ruleSet: RuleSet) => EmptyTagMap;
|
|
47
|
+
/**
|
|
48
|
+
* Converts a functional grammar rule into serializable BNF data and returns
|
|
49
|
+
* the generated rule set with the entry rule identifier.
|
|
50
|
+
*/
|
|
51
|
+
export declare const toData: (fr: FRule) => readonly [RuleSet, string];
|
|
52
|
+
export {};
|
|
@@ -5,15 +5,65 @@
|
|
|
5
5
|
* This module is the pure, parser-agnostic substrate: it defines the
|
|
6
6
|
* {@link RuleSet} data form (`Rule = Variant | Sequence | TerminalRange`) and
|
|
7
7
|
* converts a functional grammar into it. The automaton builders that consume a
|
|
8
|
-
* {@link RuleSet} live in their own sibling modules (`
|
|
9
|
-
* `
|
|
8
|
+
* {@link RuleSet} live in their own sibling modules (`fjs/bnf/ll1`,
|
|
9
|
+
* `fjs/bnf/descent`, …), so the IR stays free of any one parser's machinery.
|
|
10
10
|
*
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
13
|
import { stringToCodePointList } from '../../text/utf16/module.f.js';
|
|
14
14
|
import { map, toArray } from '../../types/list/module.f.js';
|
|
15
15
|
import { oneEncode, } from '../module.f.js';
|
|
16
|
-
import {} from '../../types/object/module.f.js';
|
|
16
|
+
import { definedEntries } from '../../types/object/module.f.js';
|
|
17
|
+
const emptyTagOf = (map) => (rule) => {
|
|
18
|
+
if (typeof rule === 'number') {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
else if (rule instanceof Array) {
|
|
22
|
+
return rule.every(item => map[item] !== undefined) ? true : undefined;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
let tag = undefined;
|
|
26
|
+
for (const [k, item] of definedEntries(rule)) {
|
|
27
|
+
if (map[item] !== undefined) {
|
|
28
|
+
tag = k;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return tag;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const emptyTagStep = (ruleSet) => (map) => {
|
|
35
|
+
let next = map;
|
|
36
|
+
let changed = false;
|
|
37
|
+
for (const name in ruleSet) {
|
|
38
|
+
const tag = emptyTagOf(map)(ruleSet[name]);
|
|
39
|
+
if (tag !== next[name]) {
|
|
40
|
+
changed = true;
|
|
41
|
+
}
|
|
42
|
+
next = { ...next, [name]: tag };
|
|
43
|
+
}
|
|
44
|
+
return [next, changed];
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Computes, for every rule in the set, whether it can match empty input, by
|
|
48
|
+
* the standard nullable-set fixpoint: a sequence is nullable iff all of its
|
|
49
|
+
* items are (AND semantics), a variant iff at least one branch is (its tag is
|
|
50
|
+
* that branch's). Rules may reference each other cyclically (e.g. a `repeat`
|
|
51
|
+
* rule referring to itself), so this starts every rule as non-nullable and
|
|
52
|
+
* relaxes every rule, one round at a time, until a full round changes
|
|
53
|
+
* nothing. A round only ever grows the nullable set or moves a variant's
|
|
54
|
+
* chosen tag to a later (still-nullable) branch, both bounded, so this always
|
|
55
|
+
* terminates — but a rule's tag can still change for rounds *after* its own
|
|
56
|
+
* nullable/non-nullable status has already settled, while a cyclic
|
|
57
|
+
* dependency's tag catches up, so a fixed round count isn't enough.
|
|
58
|
+
*/
|
|
59
|
+
export const emptyTagMap = (ruleSet) => {
|
|
60
|
+
const step = emptyTagStep(ruleSet);
|
|
61
|
+
const relax = (map) => {
|
|
62
|
+
const [next, changed] = step(map);
|
|
63
|
+
return changed ? relax(next) : next;
|
|
64
|
+
};
|
|
65
|
+
return relax({});
|
|
66
|
+
};
|
|
17
67
|
const { entries } = Object;
|
|
18
68
|
const find = (map) => (fr) => {
|
|
19
69
|
for (const [k, v] of entries(map)) {
|