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,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @import { Object as JsonObject } from '../json/types.ts'
|
|
3
|
+
* @import { LockMap } from './types.ts'
|
|
4
|
+
*/
|
|
5
|
+
|
|
3
6
|
import { assert, assertEq } from '../../asserts/module.f.mjs'
|
|
4
7
|
import { dialect, mediaType, isHash, validate, decodeText, encodeText } from './module.f.mjs'
|
|
5
8
|
|
|
@@ -13,6 +16,11 @@ const alias = /** @type {const} */ ('I')
|
|
|
13
16
|
/** @type {LockMap} */
|
|
14
17
|
const _lockMapAllowsMissingSubjects = {}
|
|
15
18
|
|
|
19
|
+
// A lock map's values are `string | LockMap | undefined` at every depth, so
|
|
20
|
+
// the same value is a legal binding for a direct hash and for a nested scope.
|
|
21
|
+
/** @type {LockMap} */
|
|
22
|
+
const _lockMapNests = { direct: h1, scope: { direct: h2, deeper: { direct: h1 } } }
|
|
23
|
+
|
|
16
24
|
// A shape-valid revision: every required field present (`snapshot` and
|
|
17
25
|
// `generation` included), with `extra` overriding or adding fields per test.
|
|
18
26
|
/** @type {(extra: JsonObject) => JsonObject} */
|
|
@@ -152,6 +160,62 @@ export const proof = {
|
|
|
152
160
|
assertEq(t, 'ok')
|
|
153
161
|
},
|
|
154
162
|
|
|
163
|
+
// A nested map scopes further bindings under a subject — the
|
|
164
|
+
// incompatible-diamond case from the README, where `B` and `C` each
|
|
165
|
+
// pick their own `D`.
|
|
166
|
+
nestedLockAccepted: () => {
|
|
167
|
+
const r = validate(revisionOf({ lock: { B: { B: h1, D: h1 }, C: { C: h2, D: h2 } } }))
|
|
168
|
+
assert(r[0] === 'ok', ['expected ok', r])
|
|
169
|
+
assert(encodeText(r[1]).includes(`"lock":{"B":{"B":"${h1}","D":"${h1}"},"C":{"C":"${h2}","D":"${h2}"}}`))
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// Nesting has no depth limit, and a nested map may be sparse — it need
|
|
173
|
+
// not bind the subject it appears under, or anything at all.
|
|
174
|
+
deeplyNestedLockAccepted: () => {
|
|
175
|
+
const [t] = validate(revisionOf({ lock: { B: { C: { D: { E: h1 } } }, empty: {} } }))
|
|
176
|
+
assertEq(t, 'ok')
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
// A direct value must be a string or a map at every depth: a number
|
|
180
|
+
// nested two levels down fails structural (rtti) validation, exactly
|
|
181
|
+
// as it does at the root.
|
|
182
|
+
malformedNestedLockRejected: () => {
|
|
183
|
+
const [t] = validate(revisionOf({ lock: { B: { D: 1 } } }))
|
|
184
|
+
assertEq(t, 'error')
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// Semantic reference checking recurses too: a non-hash string deep in
|
|
188
|
+
// a nested scope is rejected, and the message names the path to it.
|
|
189
|
+
invalidNestedHashLockRejected: () => {
|
|
190
|
+
const r = validate(revisionOf({ lock: { B: { D: 'https://example.com/x' } } }))
|
|
191
|
+
assert(r[0] === 'error', ['expected error', r])
|
|
192
|
+
assertEq(r[1], 'lock value for B/D is not a valid hash: https://example.com/x')
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
// In place of the map, `lock` may be the hash of a `vnd.fjs.lock`
|
|
196
|
+
// blob holding one — the only position where a string means "where
|
|
197
|
+
// the bindings are" rather than "this dependency's content".
|
|
198
|
+
sharedLockReferenceAccepted: () => {
|
|
199
|
+
const r = validate(revisionOf({ lock: h1 }))
|
|
200
|
+
assert(r[0] === 'ok', ['expected ok', r])
|
|
201
|
+
assertEq(r[1].lock, h1)
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
// A reference is validated as a cbase32 hash and nothing more — the
|
|
205
|
+
// same contract `snapshot` has — so a non-hash one is rejected.
|
|
206
|
+
invalidSharedLockReferenceRejected: () => {
|
|
207
|
+
const r = validate(revisionOf({ lock: 'https://example.com/lock' }))
|
|
208
|
+
assert(r[0] === 'error', ['expected error', r])
|
|
209
|
+
assertEq(r[1], 'lock reference is not a valid hash: https://example.com/lock')
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
// Only the top level is widened: a nested value is still a hash or a
|
|
213
|
+
// map, so nothing about an inline map's meaning changed.
|
|
214
|
+
nestedValueIsStillNotAReference: () => {
|
|
215
|
+
const [t] = validate(revisionOf({ lock: { B: { D: h1 } } }))
|
|
216
|
+
assertEq(t, 'ok')
|
|
217
|
+
},
|
|
218
|
+
|
|
155
219
|
// Wrong dialect tag: structural validation rejects it outright.
|
|
156
220
|
wrongDialectRejected: () => {
|
|
157
221
|
const [t] = validate({ dialect: 'vnd.fjs.other', subject: h1, parents: [], snapshot: h2, generation: 0 })
|
|
@@ -210,6 +274,32 @@ export const proof = {
|
|
|
210
274
|
`{"dialect":"${dialect}","generation":0,"lock":{"10":"${h1}","2":"${h2}"},"parents":[],"snapshot":"${h2}","subject":"${h1}"}`,
|
|
211
275
|
)
|
|
212
276
|
},
|
|
277
|
+
// The one `stringify(sort)` rule already reaches every depth, so a
|
|
278
|
+
// nested lock map needs no serialization special case: its keys sort
|
|
279
|
+
// as strings like every other object's ("10" before "2").
|
|
280
|
+
sortsNestedLockKeys: () => {
|
|
281
|
+
const revision = revisionOf({ lock: { scope: { '2': h2, '10': h1 }, '2': h2, '10': h1 } })
|
|
282
|
+
const decoded = validate(revision)
|
|
283
|
+
assert(decoded[0] === 'ok', ['expected ok', decoded])
|
|
284
|
+
assert(encodeText(decoded[1]).includes(
|
|
285
|
+
`"lock":{"10":"${h1}","2":"${h2}","scope":{"10":"${h1}","2":"${h2}"}}`))
|
|
286
|
+
},
|
|
287
|
+
// Two nested maps differing only in property order converge on one
|
|
288
|
+
// byte sequence, so they address the same CAS blob.
|
|
289
|
+
equivalentNestedLockOrdersConverge: () => {
|
|
290
|
+
const a = validate(revisionOf({ lock: { B: { B: h1, D: h2 }, C: { D: h1 } } }))
|
|
291
|
+
const b = validate(revisionOf({ lock: { C: { D: h1 }, B: { D: h2, B: h1 } } }))
|
|
292
|
+
assert(a[0] === 'ok', ['expected ok', a])
|
|
293
|
+
assert(b[0] === 'ok', ['expected ok', b])
|
|
294
|
+
assertEq(encodeText(a[1]), encodeText(b[1]))
|
|
295
|
+
},
|
|
296
|
+
// A shared-lock reference serializes as the plain string it is — no
|
|
297
|
+
// wrapper, no marker: the two forms are told apart by JSON type.
|
|
298
|
+
serializesSharedLockReferenceAsAString: () => {
|
|
299
|
+
const decoded = validate(revisionOf({ lock: h1 }))
|
|
300
|
+
assert(decoded[0] === 'ok', ['expected ok', decoded])
|
|
301
|
+
assert(encodeText(decoded[1]).includes(`"lock":"${h1}"`))
|
|
302
|
+
},
|
|
213
303
|
preservesArrayOrder: () => {
|
|
214
304
|
const decoded = validate(revisionOf({ parents: [h2, h1] }))
|
|
215
305
|
assert(decoded[0] === 'ok', ['expected ok', decoded])
|
|
@@ -226,3 +316,4 @@ export const proof = {
|
|
|
226
316
|
}
|
|
227
317
|
|
|
228
318
|
void _lockMapAllowsMissingSubjects
|
|
319
|
+
void _lockMapNests
|
|
@@ -1,15 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Type-level API for `fjs/media/revision/module.f.mjs`: `LockMap`,
|
|
3
|
-
* `
|
|
4
|
-
*
|
|
3
|
+
* `LockSchema`, `LockField`, `LockFieldSchema`, `Revision`, and
|
|
4
|
+
* `RevisionError`.
|
|
5
|
+
*
|
|
6
|
+
* `LockMap` is written by hand rather than derived, so that the recursion
|
|
7
|
+
* reads directly, and is then pinned against the module's rtti schema with
|
|
8
|
+
* `Assert<Equal<LockMap, Ts<typeof lock>>>` — the same arrangement the JSON
|
|
9
|
+
* data model uses in [`../json/types.ts`](../json/types.ts). `LockSchema` is
|
|
10
|
+
* the schema side of the same recursion: `lock` cannot infer its own type
|
|
11
|
+
* (a `const` may not reference itself in its own initializer), so it carries
|
|
12
|
+
* this named annotation instead.
|
|
5
13
|
*
|
|
6
14
|
* @module
|
|
7
15
|
*/
|
|
8
16
|
import type { Ts } from '../../types/rtti/ts/types.ts';
|
|
17
|
+
import type { String as RttiString } from '../../types/rtti/types.ts';
|
|
9
18
|
import type { ValidationError } from '../../types/rtti/common/types.ts';
|
|
10
|
-
import type {
|
|
11
|
-
/**
|
|
12
|
-
|
|
19
|
+
import type { revisionSchema } from './module.f.mjs';
|
|
20
|
+
/**
|
|
21
|
+
* A set of subject-to-snapshot bindings supplied to dependency resolvers.
|
|
22
|
+
* A direct string value selects immutable content; a nested map scopes
|
|
23
|
+
* further bindings under that subject (see the README).
|
|
24
|
+
*
|
|
25
|
+
* Spelled inline rather than as `StringMap<string | LockMap>`: a type alias
|
|
26
|
+
* may not reference itself through another alias's instantiation (TS2456).
|
|
27
|
+
*/
|
|
28
|
+
export type LockMap = {
|
|
29
|
+
readonly [subject in string]?: string | LockMap;
|
|
30
|
+
};
|
|
31
|
+
/** The rtti schema type of `lock` — a record of `string | LockSchema`. */
|
|
32
|
+
export type LockSchema = () => readonly ['record', () => readonly ['or', RttiString, LockSchema]];
|
|
33
|
+
/**
|
|
34
|
+
* A revision's `lock` field: the bindings inline as a {@link LockMap}, or the
|
|
35
|
+
* cbase32 hash of a `vnd.fjs.lock` blob (`fjs/media/lock`) holding one to
|
|
36
|
+
* share. Only the top level admits a hash — a string *inside* a map is a
|
|
37
|
+
* dependency's content, unchanged.
|
|
38
|
+
*/
|
|
39
|
+
export type LockField = string | LockMap;
|
|
40
|
+
/** The rtti schema type of `lockField` — a shared-lock reference or a lock map. */
|
|
41
|
+
export type LockFieldSchema = () => readonly ['or', RttiString, LockSchema];
|
|
13
42
|
/** The TypeScript type derived from `revisionSchema` — the single source of truth. */
|
|
14
43
|
export type Revision = Ts<typeof revisionSchema>;
|
|
15
44
|
/** Either a structural validation error or a semantic (hash / generation) error message. */
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Magic-byte MIME type detection.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* One list — `signatures` — declares every recognized magic-byte pattern, and
|
|
5
|
+
* both detectors read it through the same eliminator (`magicStep`): `detect`
|
|
6
|
+
* folds a whole `Vec` and returns a MIME type string or `null`, while
|
|
7
|
+
* `detectStream` folds a read stream one chunk at a time.
|
|
7
8
|
*
|
|
8
|
-
* Beside
|
|
9
|
-
* state machine (length × magic-byte eliminator × UTF-8 validity
|
|
10
|
-
* `{ length, mime_type, type }` by folding a CAS read stream in
|
|
11
|
-
* ever buffering the blob into a single `maxLength`-bounded
|
|
12
|
-
* for the factored design.
|
|
9
|
+
* Beside `detect`, `detectStream` is the **streaming counterpart**: a
|
|
10
|
+
* byte-accepting state machine (length × magic-byte eliminator × UTF-8 validity
|
|
11
|
+
* DFA) that derives `{ length, mime_type, type }` by folding a CAS read stream in
|
|
12
|
+
* O(1) space, without ever buffering the blob into a single `maxLength`-bounded
|
|
13
|
+
* `Vec`. See the README for the factored design.
|
|
13
14
|
*
|
|
14
15
|
* The CAS store is type-agnostic and keeps raw bytes only, so type is never
|
|
15
16
|
* stored; it is recovered on read by sniffing the content. Callers decide what
|
|
@@ -27,21 +28,54 @@
|
|
|
27
28
|
* | `application/zip` | `50 4B 03 04` / `05 06` / `07 08` (`"PK"` entry, empty, or spanned) |
|
|
28
29
|
*
|
|
29
30
|
* WebP is the one signature with a gap: the four-byte little-endian file size
|
|
30
|
-
* sits between the `RIFF` and `WEBP` markers, so
|
|
31
|
-
*
|
|
31
|
+
* sits between the `RIFF` and `WEBP` markers, so its pattern carries four
|
|
32
|
+
* wildcard bytes rather than being one contiguous run.
|
|
32
33
|
*
|
|
33
34
|
* See `./types.ts` for the type-level API.
|
|
34
35
|
*
|
|
35
36
|
* @module
|
|
37
|
+
*
|
|
38
|
+
* @import { Vec } from '../../types/bit_vec/types.ts'
|
|
39
|
+
* @import { Nullable } from '../../types/nullable/types.ts'
|
|
40
|
+
* @import { Operation } from '../../effects/types.ts'
|
|
41
|
+
* @import { List } from '../../effects/list/types.ts'
|
|
42
|
+
* @import { IoChannel, IoResult } from '../../effects/node/types.ts'
|
|
43
|
+
* @import { Effect } from '../../effects/types.ts'
|
|
44
|
+
* @import { DetectMeta, DetectState, _MagicState, _Signature, _Utf8Detect } from './types.ts'
|
|
36
45
|
*/
|
|
37
46
|
import type { Vec } from '../../types/bit_vec/types.ts';
|
|
38
47
|
import type { Nullable } from '../../types/nullable/types.ts';
|
|
39
|
-
import type {
|
|
48
|
+
import type { Operation } from '../../effects/types.ts';
|
|
40
49
|
import type { List } from '../../effects/list/types.ts';
|
|
41
|
-
import type {
|
|
50
|
+
import type { IoChannel } from '../../effects/node/types.ts';
|
|
51
|
+
import type { Effect } from '../../effects/types.ts';
|
|
42
52
|
import type { DetectMeta, DetectState } from './types.ts';
|
|
43
53
|
/**
|
|
44
|
-
* Detects the MIME type of `bytes` from its leading magic-byte signature
|
|
54
|
+
* Detects the MIME type of `bytes` from its leading magic-byte signature, as
|
|
55
|
+
* the magic projection of the streaming detector below — one fold, read two
|
|
56
|
+
* ways, rather than a second copy of it.
|
|
57
|
+
*
|
|
58
|
+
* The two agree because `magicStep` returns a non-`scan` state unchanged, so
|
|
59
|
+
* both absorbing states are its fixed points. `detect`'s old loop stopped at
|
|
60
|
+
* the first one; `push` stops only once the *whole* verdict is settled and may
|
|
61
|
+
* keep folding for the UTF-8 factor after the magic state is `dead` — but a
|
|
62
|
+
* `dead` or `matched` magic cannot move again, so the final magic is the same
|
|
63
|
+
* either way. A signature still in `scan` at the end of the `Vec` — a prefix
|
|
64
|
+
* too short to complete any signature — reads as `null`.
|
|
65
|
+
*
|
|
66
|
+
* Cost follows `push`, which stops only once the whole verdict is settled, not
|
|
67
|
+
* once the magic state is. On a signature match or on non-text bytes that is
|
|
68
|
+
* still an early exit; on valid text it now reads the whole `Vec`, because the
|
|
69
|
+
* shared machine is still tracking the UTF-8 factor this function ignores
|
|
70
|
+
* (measured: 100 KB of ASCII, 1.2 ms before, 82 ms after). That is the same
|
|
71
|
+
* work {@link detectVec} already does on the same bytes, and `Vec` is capped at
|
|
72
|
+
* `maxLength`, so the cost is bounded rather than unbounded — but a caller
|
|
73
|
+
* scanning many large text blobs for signatures alone should know it is paying
|
|
74
|
+
* for the UTF-8 fold too.
|
|
75
|
+
*
|
|
76
|
+
* The bytes come from `u8List`, so a `Vec` whose length is not a whole number of
|
|
77
|
+
* bytes has its trailing partial byte zero-padded — the same reading of a ragged
|
|
78
|
+
* `Vec` the streaming detector already uses.
|
|
45
79
|
*
|
|
46
80
|
* @returns the MIME type string for a recognized format, or `null` when the
|
|
47
81
|
* leading bytes match no known signature (including any `Vec` shorter than
|
|
@@ -87,11 +121,12 @@ export declare const finish: (s: DetectState) => DetectMeta;
|
|
|
87
121
|
export declare const detectVec: (bytes: Vec) => DetectMeta;
|
|
88
122
|
/**
|
|
89
123
|
* Folds a CAS read stream through {@link push} and reads {@link finish} at EOF,
|
|
90
|
-
* deriving `cas_get` metadata without ever materializing the blob. A
|
|
91
|
-
*
|
|
124
|
+
* deriving `cas_get` metadata without ever materializing the blob. A stream that
|
|
125
|
+
* fails carries its failure out as this one's, through `step` rather than
|
|
126
|
+
* through a case in the loop.
|
|
92
127
|
*
|
|
93
128
|
* @template {Operation} O
|
|
94
|
-
* @param {List<O,
|
|
95
|
-
* @returns {Effect<O,
|
|
129
|
+
* @param {List<O, Vec, IoChannel>} stream
|
|
130
|
+
* @returns {Effect<O, DetectMeta, IoChannel>}
|
|
96
131
|
*/
|
|
97
|
-
export declare const detectStream: <O extends Operation>(stream: List<O,
|
|
132
|
+
export declare const detectStream: <O extends Operation>(stream: List<O, Vec, IoChannel>) => Effect<O, DetectMeta, IoChannel>;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Magic-byte MIME type detection.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* One list — `signatures` — declares every recognized magic-byte pattern, and
|
|
5
|
+
* both detectors read it through the same eliminator (`magicStep`): `detect`
|
|
6
|
+
* folds a whole `Vec` and returns a MIME type string or `null`, while
|
|
7
|
+
* `detectStream` folds a read stream one chunk at a time.
|
|
7
8
|
*
|
|
8
|
-
* Beside
|
|
9
|
-
* state machine (length × magic-byte eliminator × UTF-8 validity
|
|
10
|
-
* `{ length, mime_type, type }` by folding a CAS read stream in
|
|
11
|
-
* ever buffering the blob into a single `maxLength`-bounded
|
|
12
|
-
* for the factored design.
|
|
9
|
+
* Beside `detect`, `detectStream` is the **streaming counterpart**: a
|
|
10
|
+
* byte-accepting state machine (length × magic-byte eliminator × UTF-8 validity
|
|
11
|
+
* DFA) that derives `{ length, mime_type, type }` by folding a CAS read stream in
|
|
12
|
+
* O(1) space, without ever buffering the blob into a single `maxLength`-bounded
|
|
13
|
+
* `Vec`. See the README for the factored design.
|
|
13
14
|
*
|
|
14
15
|
* The CAS store is type-agnostic and keeps raw bytes only, so type is never
|
|
15
16
|
* stored; it is recovered on read by sniffing the content. Callers decide what
|
|
@@ -27,107 +28,51 @@
|
|
|
27
28
|
* | `application/zip` | `50 4B 03 04` / `05 06` / `07 08` (`"PK"` entry, empty, or spanned) |
|
|
28
29
|
*
|
|
29
30
|
* WebP is the one signature with a gap: the four-byte little-endian file size
|
|
30
|
-
* sits between the `RIFF` and `WEBP` markers, so
|
|
31
|
-
*
|
|
31
|
+
* sits between the `RIFF` and `WEBP` markers, so its pattern carries four
|
|
32
|
+
* wildcard bytes rather than being one contiguous run.
|
|
32
33
|
*
|
|
33
34
|
* See `./types.ts` for the type-level API.
|
|
34
35
|
*
|
|
35
36
|
* @module
|
|
37
|
+
*
|
|
38
|
+
* @import { Vec } from '../../types/bit_vec/types.ts'
|
|
39
|
+
* @import { Nullable } from '../../types/nullable/types.ts'
|
|
40
|
+
* @import { Operation } from '../../effects/types.ts'
|
|
41
|
+
* @import { List } from '../../effects/list/types.ts'
|
|
42
|
+
* @import { IoChannel, IoResult } from '../../effects/node/types.ts'
|
|
43
|
+
* @import { Effect } from '../../effects/types.ts'
|
|
44
|
+
* @import { DetectMeta, DetectState, _MagicState, _Signature, _Utf8Detect } from './types.ts'
|
|
36
45
|
*/
|
|
37
46
|
|
|
38
|
-
import { msb,
|
|
39
|
-
/** @import { Vec } from '../../types/bit_vec/types.ts' */
|
|
47
|
+
import { msb, length, u8List } from '../../types/bit_vec/module.f.mjs'
|
|
40
48
|
import { iterable } from '../../types/list/module.f.mjs'
|
|
41
|
-
|
|
42
|
-
import { pure, step } from '../../effects/module.f.mjs'
|
|
43
|
-
/** @import { Effect, Operation } from '../../effects/types.ts' */
|
|
44
|
-
/** @import { List } from '../../effects/list/types.ts' */
|
|
45
|
-
/** @import { IoResult } from '../../effects/node/types.ts' */
|
|
46
|
-
import { ok, error } from '../../types/result/module.f.mjs'
|
|
49
|
+
import { pureOk, step as ioStep } from '../../effects/module.f.mjs'
|
|
47
50
|
import { isValidCodePoint, isTextCodePoint } from '../../text/code_point/module.f.mjs'
|
|
48
51
|
import { utf8ByteToCodePointOp } from '../../text/utf8/module.f.mjs'
|
|
49
|
-
/** @import { DetectMeta, DetectState, _MagicState, _Signature, _Utf8Detect } from './types.ts' */
|
|
50
|
-
|
|
51
|
-
const { startsWith, removeFront } = msb
|
|
52
|
-
|
|
53
|
-
// Each signature is written as a hex literal whose leading `1` nibble is a
|
|
54
|
-
// sentinel marking the start of the byte run (so leading zero bytes survive)
|
|
55
|
-
// and fixing the length — see `bit_vec` `fromSentinel`.
|
|
56
|
-
const sig = fromSentinel
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Contiguous magic-byte signatures, checked in order; the first prefix match
|
|
60
|
-
* wins. Ordering is irrelevant here — no signature is a prefix of another.
|
|
61
|
-
*
|
|
62
|
-
* @type {readonly (readonly [Vec, string])[]}
|
|
63
|
-
*/
|
|
64
|
-
const table = [
|
|
65
|
-
[sig(0x1_89_50_4e_47_0d_0a_1a_0an), 'image/png'],
|
|
66
|
-
[sig(0x1_ff_d8_ffn), 'image/jpeg'],
|
|
67
|
-
// Match the full GIF version headers ("GIF87a" / "GIF89a"), not just "GIF8",
|
|
68
|
-
// so opaque bytes that merely start with "GIF8" are not mistyped.
|
|
69
|
-
[sig(0x1_47_49_46_38_37_61n), 'image/gif'],
|
|
70
|
-
[sig(0x1_47_49_46_38_39_61n), 'image/gif'],
|
|
71
|
-
[sig(0x1_25_50_44_46_2dn), 'application/pdf'],
|
|
72
|
-
// ZIP has three "PK" local-header variants: a normal entry, an empty
|
|
73
|
-
// archive (end-of-central-directory only), and a spanned archive.
|
|
74
|
-
[sig(0x1_50_4b_03_04n), 'application/zip'],
|
|
75
|
-
[sig(0x1_50_4b_05_06n), 'application/zip'],
|
|
76
|
-
[sig(0x1_50_4b_07_08n), 'application/zip'],
|
|
77
|
-
]
|
|
78
52
|
|
|
79
|
-
//
|
|
80
|
-
// file size). 12 bytes = 96 bits is the minimum to carry both markers.
|
|
81
|
-
const riff = sig(0x1_52_49_46_46n)
|
|
82
|
-
const webp = sig(0x1_57_45_42_50n)
|
|
83
|
-
|
|
84
|
-
/** @type {(bytes: Vec) => boolean} */
|
|
85
|
-
const isWebp = bytes =>
|
|
86
|
-
length(bytes) >= 96n
|
|
87
|
-
&& startsWith(riff)(bytes)
|
|
88
|
-
&& startsWith(webp)(removeFront(64n)(bytes))
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Detects the MIME type of `bytes` from its leading magic-byte signature.
|
|
92
|
-
*
|
|
93
|
-
* @returns the MIME type string for a recognized format, or `null` when the
|
|
94
|
-
* leading bytes match no known signature (including any `Vec` shorter than
|
|
95
|
-
* the signature it might otherwise match).
|
|
96
|
-
*
|
|
97
|
-
* @type {(bytes: Vec) => Nullable<string>}
|
|
98
|
-
*/
|
|
99
|
-
export const detect = bytes => {
|
|
100
|
-
if (isWebp(bytes)) { return 'image/webp' }
|
|
101
|
-
for (const [s, m] of table) {
|
|
102
|
-
if (startsWith(s)(bytes)) { return m }
|
|
103
|
-
}
|
|
104
|
-
return null
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// ── Streaming detector ────────────────────────────────────────────────────────────
|
|
53
|
+
// ── Magic-byte signatures ─────────────────────────────────────────────────────────
|
|
108
54
|
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
// end-of-stream by `finish`. This lets `cas_get` inspect arbitrarily large blobs
|
|
114
|
-
// (where a single `Vec` would overflow `maxLength`) in O(1) space, since the bulk
|
|
115
|
-
// of a large blob costs only length counting once the verdict is fixed (see
|
|
116
|
-
// `isSettled`: a magic match settles it immediately, a dead magic once utf8 fails).
|
|
55
|
+
// The single declaration of what a signature is: a byte pattern the eliminator can
|
|
56
|
+
// consume one byte at a time, with `null` for a wildcard byte. Both `detect` and
|
|
57
|
+
// the streaming detector below eliminate against this one list, so a signature is
|
|
58
|
+
// added or corrected in exactly one place.
|
|
117
59
|
|
|
118
|
-
// The streaming counterpart of `table`/`isWebp`: the same signatures expressed as
|
|
119
|
-
// byte patterns the eliminator can consume one byte at a time. WebP's gap is the
|
|
120
|
-
// only wildcard run.
|
|
121
60
|
/** @type {readonly _Signature[]} */
|
|
122
61
|
const signatures = [
|
|
123
62
|
{ pattern: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], mime: 'image/png' },
|
|
124
63
|
{ pattern: [0xff, 0xd8, 0xff], mime: 'image/jpeg' },
|
|
64
|
+
// Match the full GIF version headers ("GIF87a" / "GIF89a"), not just "GIF8",
|
|
65
|
+
// so opaque bytes that merely start with "GIF8" are not mistyped.
|
|
125
66
|
{ pattern: [0x47, 0x49, 0x46, 0x38, 0x37, 0x61], mime: 'image/gif' },
|
|
126
67
|
{ pattern: [0x47, 0x49, 0x46, 0x38, 0x39, 0x61], mime: 'image/gif' },
|
|
127
68
|
{ pattern: [0x25, 0x50, 0x44, 0x46, 0x2d], mime: 'application/pdf' },
|
|
69
|
+
// ZIP has three "PK" local-header variants: a normal entry, an empty
|
|
70
|
+
// archive (end-of-central-directory only), and a spanned archive.
|
|
128
71
|
{ pattern: [0x50, 0x4b, 0x03, 0x04], mime: 'application/zip' },
|
|
129
72
|
{ pattern: [0x50, 0x4b, 0x05, 0x06], mime: 'application/zip' },
|
|
130
73
|
{ pattern: [0x50, 0x4b, 0x07, 0x08], mime: 'application/zip' },
|
|
74
|
+
// WebP: "RIFF" at offset 0, "WEBP" at offset 8; the four bytes between are
|
|
75
|
+
// the little-endian file size, matched as wildcards.
|
|
131
76
|
{
|
|
132
77
|
pattern: [0x52, 0x49, 0x46, 0x46, null, null, null, null, 0x57, 0x45, 0x42, 0x50],
|
|
133
78
|
mime: 'image/webp',
|
|
@@ -154,6 +99,52 @@ const magicStep = (m, byte) => {
|
|
|
154
99
|
/** @type {(m: _MagicState) => Nullable<string>} */
|
|
155
100
|
const magicMime = m => m.tag === 'matched' ? m.mime : null
|
|
156
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Detects the MIME type of `bytes` from its leading magic-byte signature, as
|
|
104
|
+
* the magic projection of the streaming detector below — one fold, read two
|
|
105
|
+
* ways, rather than a second copy of it.
|
|
106
|
+
*
|
|
107
|
+
* The two agree because `magicStep` returns a non-`scan` state unchanged, so
|
|
108
|
+
* both absorbing states are its fixed points. `detect`'s old loop stopped at
|
|
109
|
+
* the first one; `push` stops only once the *whole* verdict is settled and may
|
|
110
|
+
* keep folding for the UTF-8 factor after the magic state is `dead` — but a
|
|
111
|
+
* `dead` or `matched` magic cannot move again, so the final magic is the same
|
|
112
|
+
* either way. A signature still in `scan` at the end of the `Vec` — a prefix
|
|
113
|
+
* too short to complete any signature — reads as `null`.
|
|
114
|
+
*
|
|
115
|
+
* Cost follows `push`, which stops only once the whole verdict is settled, not
|
|
116
|
+
* once the magic state is. On a signature match or on non-text bytes that is
|
|
117
|
+
* still an early exit; on valid text it now reads the whole `Vec`, because the
|
|
118
|
+
* shared machine is still tracking the UTF-8 factor this function ignores
|
|
119
|
+
* (measured: 100 KB of ASCII, 1.2 ms before, 82 ms after). That is the same
|
|
120
|
+
* work {@link detectVec} already does on the same bytes, and `Vec` is capped at
|
|
121
|
+
* `maxLength`, so the cost is bounded rather than unbounded — but a caller
|
|
122
|
+
* scanning many large text blobs for signatures alone should know it is paying
|
|
123
|
+
* for the UTF-8 fold too.
|
|
124
|
+
*
|
|
125
|
+
* The bytes come from `u8List`, so a `Vec` whose length is not a whole number of
|
|
126
|
+
* bytes has its trailing partial byte zero-padded — the same reading of a ragged
|
|
127
|
+
* `Vec` the streaming detector already uses.
|
|
128
|
+
*
|
|
129
|
+
* @returns the MIME type string for a recognized format, or `null` when the
|
|
130
|
+
* leading bytes match no known signature (including any `Vec` shorter than
|
|
131
|
+
* the signature it might otherwise match).
|
|
132
|
+
*
|
|
133
|
+
* @type {(bytes: Vec) => Nullable<string>}
|
|
134
|
+
*/
|
|
135
|
+
export const detect = bytes => magicMime(push(detectInit)(bytes).magic)
|
|
136
|
+
|
|
137
|
+
// ── Streaming detector ────────────────────────────────────────────────────────────
|
|
138
|
+
//
|
|
139
|
+
// A byte-accepting state machine that derives the same `{ length, mime_type, type }`
|
|
140
|
+
// metadata as the pure `detect` + UTF-8 path, but **without buffering the blob**.
|
|
141
|
+
// It is the product of three independent folds over the byte stream — length,
|
|
142
|
+
// magic-byte signature elimination, and a UTF-8 validity DFA — read off at
|
|
143
|
+
// end-of-stream by `finish`. This lets `cas_get` inspect arbitrarily large blobs
|
|
144
|
+
// (where a single `Vec` would overflow `maxLength`) in O(1) space, since the bulk
|
|
145
|
+
// of a large blob costs only length counting once the verdict is fixed (see
|
|
146
|
+
// `isSettled`: a magic match settles it immediately, a dead magic once utf8 fails).
|
|
147
|
+
|
|
157
148
|
/** @type {_Utf8Detect} */
|
|
158
149
|
const utf8Init = { st: null, valid: true, text: true }
|
|
159
150
|
|
|
@@ -258,24 +249,23 @@ export const detectVec = bytes => finish(push(detectInit)(bytes))
|
|
|
258
249
|
|
|
259
250
|
/**
|
|
260
251
|
* Folds a CAS read stream through {@link push} and reads {@link finish} at EOF,
|
|
261
|
-
* deriving `cas_get` metadata without ever materializing the blob. A
|
|
262
|
-
*
|
|
252
|
+
* deriving `cas_get` metadata without ever materializing the blob. A stream that
|
|
253
|
+
* fails carries its failure out as this one's, through `step` rather than
|
|
254
|
+
* through a case in the loop.
|
|
263
255
|
*
|
|
264
256
|
* @template {Operation} O
|
|
265
|
-
* @param {List<O,
|
|
266
|
-
* @returns {Effect<O,
|
|
257
|
+
* @param {List<O, Vec, IoChannel>} stream
|
|
258
|
+
* @returns {Effect<O, DetectMeta, IoChannel>}
|
|
267
259
|
*/
|
|
268
260
|
export const detectStream = stream => {
|
|
269
|
-
/** @type {(s: DetectState) => (l: List<O,
|
|
261
|
+
/** @type {(s: DetectState) => (l: List<O, Vec, IoChannel>) => Effect<O, DetectMeta, IoChannel>} */
|
|
270
262
|
const loop = s => l =>
|
|
271
|
-
|
|
263
|
+
ioStep(
|
|
272
264
|
l,
|
|
273
265
|
node => {
|
|
274
|
-
if (node === undefined) { return
|
|
266
|
+
if (node === undefined) { return pureOk(finish(s)) }
|
|
275
267
|
const { first, tail } = node
|
|
276
|
-
|
|
277
|
-
if (t === 'error') { return pure(error(v)) }
|
|
278
|
-
return loop(push(s)(v))(tail)
|
|
268
|
+
return loop(push(s)(first))(tail)
|
|
279
269
|
})
|
|
280
270
|
return loop(detectInit)(stream)
|
|
281
271
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { Vec } from '../../types/bit_vec/types.ts'
|
|
3
|
+
* @import { List } from '../../effects/list/types.ts'
|
|
4
|
+
* @import { IoChannel } from '../../effects/node/types.ts'
|
|
5
|
+
* @import { DetectMeta } from './types.ts'
|
|
6
|
+
*/
|
|
1
7
|
export declare const proof: {
|
|
2
8
|
png: () => void;
|
|
3
9
|
jpeg: () => void;
|
|
@@ -7,11 +13,22 @@ export declare const proof: {
|
|
|
7
13
|
pdf: () => void;
|
|
8
14
|
zip: () => void;
|
|
9
15
|
emptyZip: () => void;
|
|
16
|
+
spannedZip: () => void;
|
|
10
17
|
webp: () => void;
|
|
11
18
|
riffNotWebp: () => void;
|
|
19
|
+
settledMagicIsAFixedPoint: (() => void)[];
|
|
12
20
|
textIsNull: () => void;
|
|
13
21
|
shortIsNull: () => void;
|
|
14
22
|
emptyIsNull: () => void;
|
|
23
|
+
truncated: {
|
|
24
|
+
png: () => void;
|
|
25
|
+
jpeg: () => void;
|
|
26
|
+
gif87a: () => void;
|
|
27
|
+
gif89a: () => void;
|
|
28
|
+
pdf: () => void;
|
|
29
|
+
zip: () => void;
|
|
30
|
+
webp: () => void;
|
|
31
|
+
};
|
|
15
32
|
stream: {
|
|
16
33
|
text: () => void;
|
|
17
34
|
png: () => void;
|