functionalscript 0.45.0 → 0.46.1
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 +10 -0
- package/fjs/asn.1/proof.f.mjs +16 -0
- package/fjs/basen/base128/module.f.mjs +22 -5
- 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 -3
- package/fjs/bnf/data/types.d.ts +20 -2
- package/fjs/bnf/descent/module.f.d.mts +28 -14
- package/fjs/bnf/descent/module.f.mjs +122 -77
- package/fjs/bnf/descent/proof.f.d.mts +2 -0
- package/fjs/bnf/descent/proof.f.mjs +117 -31
- package/fjs/bnf/descent/types.d.ts +12 -14
- package/fjs/bnf/ll1/module.f.d.mts +64 -22
- package/fjs/bnf/ll1/module.f.mjs +214 -154
- package/fjs/bnf/ll1/proof.f.d.mts +15 -2
- package/fjs/bnf/ll1/proof.f.mjs +323 -149
- package/fjs/bnf/ll1/types.d.ts +16 -24
- 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/testlib.f.d.mts +31 -0
- package/fjs/bnf/testlib.f.mjs +80 -0
- 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 +1 -3
- package/fjs/cas/cli/proof.f.mjs +44 -33
- package/fjs/cas/evo/module.f.d.mts +64 -18
- package/fjs/cas/evo/module.f.mjs +148 -70
- package/fjs/cas/evo/proof.f.d.mts +10 -1
- package/fjs/cas/evo/proof.f.mjs +305 -223
- package/fjs/cas/evo/types.d.ts +45 -9
- package/fjs/cas/module.f.d.mts +18 -32
- package/fjs/cas/module.f.mjs +129 -128
- 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/config/module.f.d.mts +2 -2
- package/fjs/ci/config/module.f.mjs +2 -2
- 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.mjs +2 -2
- package/fjs/ci/proof.f.mjs +9 -5
- package/fjs/cli/module.f.d.mts +4 -6
- package/fjs/cli/module.f.mjs +4 -8
- package/fjs/cli/proof.f.mjs +17 -16
- package/fjs/cli/types.d.ts +2 -3
- package/fjs/common/monoid/types.d.ts +1 -1
- package/fjs/crypto/hmac/module.f.mjs +2 -2
- package/fjs/crypto/sha2/module.f.mjs +3 -1
- package/fjs/crypto/sha2/proof.f.d.mts +1 -0
- package/fjs/crypto/sha2/proof.f.mjs +24 -0
- package/fjs/crypto/sha2/types.d.ts +11 -0
- package/fjs/crypto/sign/module.f.mjs +2 -2
- package/fjs/dev/module.f.d.mts +13 -4
- package/fjs/dev/module.f.mjs +56 -27
- package/fjs/dev/update/module.f.d.mts +9 -4
- package/fjs/dev/update/module.f.mjs +14 -10
- package/fjs/dev/update/proof.f.d.mts +1 -3
- package/fjs/dev/update/proof.f.mjs +10 -5
- 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 +13 -3
- package/fjs/djs/parser/module.f.mjs +117 -16
- package/fjs/djs/parser/proof.f.d.mts +5 -1
- package/fjs/djs/parser/proof.f.mjs +274 -12
- package/fjs/djs/parser/types.d.ts +7 -1
- package/fjs/djs/proof.f.d.mts +18 -2
- package/fjs/djs/proof.f.mjs +187 -12
- package/fjs/djs/serializer/module.f.d.mts +25 -8
- package/fjs/djs/serializer/module.f.mjs +61 -15
- 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 +99 -60
- package/fjs/djs/tokenizer/proof.f.d.mts +1 -1
- package/fjs/djs/tokenizer/proof.f.mjs +74 -67
- package/fjs/djs/transpiler/module.f.d.mts +12 -7
- package/fjs/djs/transpiler/module.f.mjs +82 -56
- package/fjs/djs/transpiler/types.d.ts +7 -3
- package/fjs/djs/types.d.ts +7 -1
- package/fjs/effects/list/module.f.d.mts +14 -11
- package/fjs/effects/list/module.f.mjs +13 -11
- package/fjs/effects/list/types.d.ts +27 -7
- package/fjs/effects/memory/module.f.d.mts +2 -1
- package/fjs/effects/memory/module.f.mjs +3 -4
- package/fjs/effects/memory/proof.f.mjs +13 -7
- package/fjs/effects/memory/types.d.ts +4 -3
- package/fjs/effects/mock/module.f.d.mts +20 -4
- package/fjs/effects/mock/module.f.mjs +37 -5
- package/fjs/effects/mock/types.d.ts +10 -1
- package/fjs/effects/module.d.mts +4 -2
- package/fjs/effects/module.f.d.mts +466 -280
- package/fjs/effects/module.f.mjs +537 -299
- package/fjs/effects/module.mjs +2 -1
- package/fjs/effects/node/memory/module.d.mts +4 -2
- package/fjs/effects/node/memory/module.mjs +6 -3
- package/fjs/effects/node/memory/proof.mjs +10 -4
- package/fjs/effects/node/module.d.mts +4 -3
- package/fjs/effects/node/module.f.d.mts +168 -33
- package/fjs/effects/node/module.f.mjs +256 -52
- package/fjs/effects/node/module.mjs +57 -34
- 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 +18 -4
- package/fjs/effects/node/virtual/module.f.mjs +110 -68
- package/fjs/effects/node/virtual/proof.f.d.mts +28 -2
- package/fjs/effects/node/virtual/proof.f.mjs +190 -9
- package/fjs/effects/proof.f.d.mts +69 -37
- package/fjs/effects/proof.f.mjs +410 -130
- package/fjs/effects/types.d.ts +161 -33
- package/fjs/emergent_testing/module.f.d.mts +19 -12
- package/fjs/emergent_testing/module.f.mjs +93 -33
- package/fjs/emergent_testing/proof.f.d.mts +21 -7
- package/fjs/emergent_testing/proof.f.mjs +166 -32
- package/fjs/emergent_testing/types.d.ts +22 -4
- package/fjs/fsm/module.f.d.mts +14 -4
- package/fjs/fsm/module.f.mjs +54 -37
- package/fjs/fsm/proof.f.d.mts +2 -0
- package/fjs/fsm/proof.f.mjs +83 -114
- package/fjs/js/keywords/module.f.d.mts +52 -0
- package/fjs/js/keywords/module.f.mjs +72 -0
- package/fjs/js/keywords/proof.f.d.mts +3 -0
- package/fjs/js/keywords/proof.f.mjs +13 -0
- package/fjs/js/tokenizer/module.f.d.mts +26 -6
- package/fjs/js/tokenizer/module.f.mjs +145 -159
- 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 +4 -4
- package/fjs/mcp/module.f.mjs +6 -6
- package/fjs/mcp/proof.f.d.mts +5 -3
- package/fjs/mcp/proof.f.mjs +112 -46
- package/fjs/media/html/module.f.mjs +1 -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 +114 -70
- 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 +33 -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.mjs +9 -9
- package/fjs/media/json/schema/module.f.mjs +3 -13
- package/fjs/media/json/schema/proof.f.d.mts +0 -1
- package/fjs/media/json/schema/proof.f.mjs +1 -2
- package/fjs/media/json/serializer/module.f.d.mts +32 -1
- package/fjs/media/json/serializer/module.f.mjs +64 -2
- package/fjs/media/json/tokenizer/module.f.mjs +7 -3
- 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/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 +78 -7
- package/fjs/media/revision/module.f.mjs +119 -12
- package/fjs/media/revision/proof.f.d.mts +10 -0
- package/fjs/media/revision/proof.f.mjs +88 -0
- package/fjs/media/revision/types.d.ts +34 -5
- package/fjs/media/type/module.f.d.mts +33 -15
- package/fjs/media/type/module.f.mjs +35 -29
- package/fjs/media/type/proof.f.d.mts +2 -1
- package/fjs/media/type/proof.f.mjs +30 -10
- package/fjs/module.f.mjs +29 -8
- 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/proof.f.d.mts +3 -3
- package/fjs/proof.f.mjs +36 -10
- package/fjs/protocol/json_rpc/module.f.d.mts +2 -2
- package/fjs/protocol/json_rpc/module.f.mjs +3 -3
- package/fjs/protocol/json_rpc/proof.f.mjs +4 -4
- 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 +13 -4
- package/fjs/protocol/mcp/proof.f.mjs +193 -61
- package/fjs/protocol/mcp/stdio/module.f.d.mts +15 -7
- package/fjs/protocol/mcp/stdio/module.f.mjs +38 -25
- package/fjs/protocol/mcp/stdio/proof.f.d.mts +4 -2
- package/fjs/protocol/mcp/stdio/proof.f.mjs +45 -12
- package/fjs/protocol/mcp/stdio/types.d.ts +1 -1
- package/fjs/protocol/mcp/types.d.ts +17 -6
- package/fjs/sul/id/module.f.d.mts +0 -1
- package/fjs/sul/id/module.f.mjs +2 -3
- package/fjs/sul/level/hash/module.f.mjs +2 -1
- package/fjs/sul/level/hash/proof.f.mjs +2 -2
- package/fjs/sul/module.f.mjs +18 -13
- package/fjs/text/code_point/module.f.d.mts +8 -0
- package/fjs/text/code_point/module.f.mjs +8 -1
- package/fjs/text/code_point/proof.f.d.mts +1 -0
- package/fjs/text/code_point/proof.f.mjs +11 -0
- package/fjs/text/sgr/module.f.d.mts +4 -6
- package/fjs/text/sgr/module.f.mjs +6 -7
- package/fjs/text/utf16/module.f.mjs +7 -2
- package/fjs/text/utf16/proof.f.mjs +3 -3
- package/fjs/text/utf8/module.f.mjs +4 -2
- package/fjs/types/array/module.f.mjs +14 -2
- package/fjs/types/bit_vec/module.f.d.mts +0 -2
- package/fjs/types/bit_vec/module.f.mjs +46 -32
- package/fjs/types/bit_vec/proof.f.mjs +2 -2
- package/fjs/types/btree/remove/module.f.mjs +1 -1
- package/fjs/types/btree/set/module.f.mjs +9 -11
- package/fjs/types/btree/set/proof.f.mjs +12 -0
- package/fjs/types/byte_set/module.f.d.mts +11 -4
- package/fjs/types/byte_set/module.f.mjs +14 -6
- package/fjs/types/byte_set/proof.f.mjs +7 -7
- package/fjs/types/function/compare/module.f.mjs +10 -3
- package/fjs/types/list/module.f.d.mts +1 -1
- package/fjs/types/list/module.f.mjs +1 -1
- package/fjs/types/nullable/module.f.d.mts +18 -4
- package/fjs/types/nullable/module.f.mjs +21 -4
- package/fjs/types/nullable/proof.f.d.mts +4 -0
- package/fjs/types/nullable/proof.f.mjs +15 -0
- package/fjs/types/object/module.f.d.mts +12 -2
- package/fjs/types/object/module.f.mjs +11 -1
- package/fjs/types/patricia_trie/module.f.mjs +26 -11
- package/fjs/types/result/module.f.d.mts +3 -3
- package/fjs/types/result/module.f.mjs +3 -3
- package/fjs/types/rtti/common/module.f.d.mts +25 -28
- package/fjs/types/rtti/common/module.f.mjs +36 -32
- package/fjs/types/rtti/common/proof.f.mjs +5 -5
- package/fjs/types/rtti/data/module.f.d.mts +14 -0
- package/fjs/types/rtti/data/module.f.mjs +25 -2
- package/fjs/types/rtti/data/proof.f.d.mts +1 -0
- package/fjs/types/rtti/data/proof.f.mjs +25 -2
- package/fjs/types/rtti/parse/module.f.d.mts +24 -14
- package/fjs/types/rtti/parse/module.f.mjs +37 -28
- package/fjs/types/rtti/parse/proof.f.d.mts +3 -2
- package/fjs/types/rtti/parse/proof.f.mjs +33 -14
- package/fjs/types/rtti/proof.f.mjs +3 -1
- package/fjs/types/rtti/ts/module.f.mjs +13 -17
- package/fjs/types/rtti/ts/types.d.ts +14 -1
- package/fjs/types/rtti/validate/module.f.d.mts +81 -19
- package/fjs/types/rtti/validate/module.f.mjs +107 -61
- package/fjs/types/rtti/validate/proof.f.d.mts +13 -10
- package/fjs/types/rtti/validate/proof.f.mjs +186 -197
- package/fjs/types/sorted_set/module.f.d.mts +18 -0
- package/fjs/types/sorted_set/module.f.mjs +22 -0
- package/fjs/types/sorted_set/proof.f.d.mts +1 -0
- package/fjs/types/sorted_set/proof.f.mjs +16 -1
- package/fjs/types/uint8array/module.f.d.mts +1 -1
- package/fjs/types/uint8array/module.f.mjs +1 -1
- package/fjs/website/module.f.d.mts +3 -3
- package/fjs/website/module.f.mjs +4 -7
- package/fjs/website/proof.f.mjs +2 -1
- package/package.json +2 -2
- package/fjs/dev/package_json/module.f.d.mts +0 -39
- package/fjs/dev/package_json/module.f.mjs +0 -40
- package/fjs/dev/package_json/proof.f.d.mts +0 -6
- package/fjs/dev/package_json/proof.f.mjs +0 -32
- package/fjs/effects/eff/module.f.d.mts +0 -20
- package/fjs/effects/eff/module.f.mjs +0 -70
- package/fjs/effects/eff/proof.f.d.mts +0 -15
- package/fjs/effects/eff/proof.f.mjs +0 -69
- package/fjs/effects/eff/types.d.ts +0 -71
- package/fjs/types/rtti/validate/types.d.ts +0 -6
package/fjs/bnf/ll1/types.d.ts
CHANGED
|
@@ -6,43 +6,35 @@
|
|
|
6
6
|
import type { CodePoint } from '../../text/utf16/types.ts';
|
|
7
7
|
import type { RangeMapArray } from '../../types/range_map/types.ts';
|
|
8
8
|
import type { StringMap } from '../../types/object/types.ts';
|
|
9
|
-
import type {
|
|
10
|
-
/**
|
|
9
|
+
import type { Ast } from '../matcher/types.ts';
|
|
10
|
+
/**
|
|
11
|
+
* A rule's dispatch entry: its first set as a range map, and — for a variant
|
|
12
|
+
* that can match empty — the branch a dispatch miss selects.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
11
16
|
export type _DispatchRule = {
|
|
12
|
-
readonly
|
|
17
|
+
readonly empty: _DispatchBranch | undefined;
|
|
13
18
|
readonly rangeMap: _Dispatch;
|
|
14
19
|
};
|
|
15
20
|
/** @internal */
|
|
16
21
|
export type _Dispatch = RangeMapArray<_DispatchResult>;
|
|
17
22
|
/** @internal */
|
|
18
|
-
export type _DispatchResult =
|
|
23
|
+
export type _DispatchResult = _DispatchBranch | null;
|
|
19
24
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
25
|
+
* A branch as dispatch selects it: the name of the rule to invoke — a name
|
|
26
|
+
* into the {@link _DispatchMap} — and the tag its node gets. Only a variant's
|
|
27
|
+
* entries are ever read as branches; every other rule kind consults its range
|
|
28
|
+
* map solely for first-set membership.
|
|
23
29
|
*
|
|
24
30
|
* @internal
|
|
25
31
|
*/
|
|
26
|
-
export type
|
|
32
|
+
export type _DispatchBranch = {
|
|
27
33
|
readonly tag: string | undefined;
|
|
28
|
-
readonly
|
|
34
|
+
readonly name: string;
|
|
29
35
|
};
|
|
30
36
|
/** @internal */
|
|
31
37
|
export type _DispatchMap = StringMap<_DispatchRule>;
|
|
32
|
-
/**
|
|
33
|
-
* Represents a parsed AST rule, consisting of a rule name and its parsed sequence.
|
|
34
|
-
*
|
|
35
|
-
* @internal
|
|
36
|
-
*/
|
|
37
|
-
export type _AstRule = {
|
|
38
|
-
readonly tag: AstTag;
|
|
39
|
-
readonly sequence: AstSequence;
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Represents a parsed AST sequence.
|
|
43
|
-
*/
|
|
44
|
-
export type AstSequence = readonly (_AstRule | CodePoint)[];
|
|
45
|
-
export type AstTag = string | true | undefined;
|
|
46
38
|
/**
|
|
47
39
|
* Represents the remaining input after a match attempt, or `null` if no match is possible.
|
|
48
40
|
*
|
|
@@ -55,7 +47,7 @@ export type Remainder = readonly CodePoint[] | null;
|
|
|
55
47
|
*
|
|
56
48
|
* Represents the result of a match operation, including the parsed AST rule and the remainder of the input.
|
|
57
49
|
*/
|
|
58
|
-
export type MatchResult = readonly [
|
|
50
|
+
export type MatchResult = readonly [Ast<CodePoint>, boolean, Remainder];
|
|
59
51
|
/**
|
|
60
52
|
* LL(1) parser function for matching by rule name.
|
|
61
53
|
*
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layer every BNF matcher backend shares: the {@link Cursor} it matches at,
|
|
3
|
+
* the {@link Ast} it builds, and the constructors that pair them.
|
|
4
|
+
*
|
|
5
|
+
* `fjs/bnf/ll1` and `fjs/bnf/descent` are two machines over one contract, and
|
|
6
|
+
* the contract is what lives here — not the machines. Backtracking, frame
|
|
7
|
+
* shapes, failure reporting and the public result type are each backend's own,
|
|
8
|
+
* and deliberately different; where the input sits, what a consumed symbol
|
|
9
|
+
* contributes to the AST, and how a node is built are not.
|
|
10
|
+
*
|
|
11
|
+
* The three are one module rather than three because they are interdependent:
|
|
12
|
+
* {@link leafAt} produces AST leaves, and {@link mrSuccess} builds AST nodes
|
|
13
|
+
* positioned by a cursor. Splitting them would put one concept behind three
|
|
14
|
+
* imports.
|
|
15
|
+
*
|
|
16
|
+
* See `./types.ts` for the type-level API and `./README.md` for the contract
|
|
17
|
+
* this implements.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*
|
|
21
|
+
* @import { Ast, AstResult, AstSequence, AstTag, Cursor } from './types.ts'
|
|
22
|
+
*/
|
|
23
|
+
import type { AstResult, AstSequence, AstTag, Cursor } from './types.ts';
|
|
24
|
+
/**
|
|
25
|
+
* What consuming the symbol at a cursor contributes to the AST: the leaf
|
|
26
|
+
* itself, and nothing for the synthesized end-of-input symbol — it has no
|
|
27
|
+
* physical source element, so it never reaches an AST.
|
|
28
|
+
*
|
|
29
|
+
* @type {<L>(input: readonly L[], pos: Cursor) => AstSequence<L>}
|
|
30
|
+
*/
|
|
31
|
+
export declare const leafAt: <L>(input: readonly L[], pos: Cursor) => AstSequence<L>;
|
|
32
|
+
/**
|
|
33
|
+
* The semantic symbol a cursor points at: one read out of the physical input,
|
|
34
|
+
* and the synthesized {@link eofSymbol} at its end. Only meaningful where the
|
|
35
|
+
* cursor still has a symbol, `pos <= input.length`.
|
|
36
|
+
*
|
|
37
|
+
* `symbolOf` is the one place backends differ — it is how a leaf yields its
|
|
38
|
+
* symbol, `identity` where the leaf *is* the code point and a destructuring
|
|
39
|
+
* where it carries metadata alongside. Each backend binds its own partial
|
|
40
|
+
* application once at module scope.
|
|
41
|
+
*
|
|
42
|
+
* @type {<L>(symbolOf: (leaf: L) => number) => (input: readonly L[], pos: Cursor) => number}
|
|
43
|
+
*/
|
|
44
|
+
export declare const symbolAt: <L>(symbolOf: (leaf: L) => number) => (input: readonly L[], pos: Cursor) => number;
|
|
45
|
+
/**
|
|
46
|
+
* The public, physical index of a cursor. Consuming the synthesized
|
|
47
|
+
* end-of-input symbol moves the cursor past the physical end, and both cursors
|
|
48
|
+
* report `length`.
|
|
49
|
+
*
|
|
50
|
+
* @type {(length: number) => (pos: Cursor) => number}
|
|
51
|
+
*/
|
|
52
|
+
export declare const physicalIdx: (length: number) => (pos: Cursor) => number;
|
|
53
|
+
export type _Mr<L, P> = (tag: AstTag, sequence: AstSequence<L>, pos: P) => AstResult<L, P>;
|
|
54
|
+
/**
|
|
55
|
+
* A matched node at a position.
|
|
56
|
+
*
|
|
57
|
+
* @type {<L, P>(tag: AstTag, sequence: AstSequence<L>, pos: P) => AstResult<L, P>}
|
|
58
|
+
*/
|
|
59
|
+
export declare const mrSuccess: <L, P>(tag: AstTag, sequence: AstSequence<L>, pos: P) => AstResult<L, P>;
|
|
60
|
+
/**
|
|
61
|
+
* A node that did not match, at the position the caller should resume from —
|
|
62
|
+
* which a backtracking backend rewinds and a predictive one does not.
|
|
63
|
+
*
|
|
64
|
+
* @type {<L, P>(tag: AstTag, sequence: AstSequence<L>, pos: P) => AstResult<L, P>}
|
|
65
|
+
*/
|
|
66
|
+
export declare const mrFail: <L, P>(tag: AstTag, sequence: AstSequence<L>, pos: P) => AstResult<L, P>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layer every BNF matcher backend shares: the {@link Cursor} it matches at,
|
|
3
|
+
* the {@link Ast} it builds, and the constructors that pair them.
|
|
4
|
+
*
|
|
5
|
+
* `fjs/bnf/ll1` and `fjs/bnf/descent` are two machines over one contract, and
|
|
6
|
+
* the contract is what lives here — not the machines. Backtracking, frame
|
|
7
|
+
* shapes, failure reporting and the public result type are each backend's own,
|
|
8
|
+
* and deliberately different; where the input sits, what a consumed symbol
|
|
9
|
+
* contributes to the AST, and how a node is built are not.
|
|
10
|
+
*
|
|
11
|
+
* The three are one module rather than three because they are interdependent:
|
|
12
|
+
* {@link leafAt} produces AST leaves, and {@link mrSuccess} builds AST nodes
|
|
13
|
+
* positioned by a cursor. Splitting them would put one concept behind three
|
|
14
|
+
* imports.
|
|
15
|
+
*
|
|
16
|
+
* See `./types.ts` for the type-level API and `./README.md` for the contract
|
|
17
|
+
* this implements.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*
|
|
21
|
+
* @import { Ast, AstResult, AstSequence, AstTag, Cursor } from './types.ts'
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { eofSymbol } from '../module.f.mjs'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* What consuming the symbol at a cursor contributes to the AST: the leaf
|
|
28
|
+
* itself, and nothing for the synthesized end-of-input symbol — it has no
|
|
29
|
+
* physical source element, so it never reaches an AST.
|
|
30
|
+
*
|
|
31
|
+
* @type {<L>(input: readonly L[], pos: Cursor) => AstSequence<L>}
|
|
32
|
+
*/
|
|
33
|
+
export const leafAt = (input, pos) => pos < input.length ? [input[pos]] : []
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The semantic symbol a cursor points at: one read out of the physical input,
|
|
37
|
+
* and the synthesized {@link eofSymbol} at its end. Only meaningful where the
|
|
38
|
+
* cursor still has a symbol, `pos <= input.length`.
|
|
39
|
+
*
|
|
40
|
+
* `symbolOf` is the one place backends differ — it is how a leaf yields its
|
|
41
|
+
* symbol, `identity` where the leaf *is* the code point and a destructuring
|
|
42
|
+
* where it carries metadata alongside. Each backend binds its own partial
|
|
43
|
+
* application once at module scope.
|
|
44
|
+
*
|
|
45
|
+
* @type {<L>(symbolOf: (leaf: L) => number) => (input: readonly L[], pos: Cursor) => number}
|
|
46
|
+
*/
|
|
47
|
+
export const symbolAt = symbolOf => (input, pos) =>
|
|
48
|
+
pos < input.length ? symbolOf(input[pos]) : eofSymbol
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The public, physical index of a cursor. Consuming the synthesized
|
|
52
|
+
* end-of-input symbol moves the cursor past the physical end, and both cursors
|
|
53
|
+
* report `length`.
|
|
54
|
+
*
|
|
55
|
+
* @type {(length: number) => (pos: Cursor) => number}
|
|
56
|
+
*/
|
|
57
|
+
export const physicalIdx = length => pos => Math.min(pos, length)
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @template L
|
|
61
|
+
* @template P
|
|
62
|
+
* @typedef {(tag: AstTag, sequence: AstSequence<L>, pos: P) => AstResult<L, P>} _Mr
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/** @type {<L, P>(success: boolean) => _Mr<L, P>} */
|
|
66
|
+
const mr = success => (tag, sequence, pos) => ({ ast: { tag, sequence }, success, pos })
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A matched node at a position.
|
|
70
|
+
*
|
|
71
|
+
* @type {<L, P>(tag: AstTag, sequence: AstSequence<L>, pos: P) => AstResult<L, P>}
|
|
72
|
+
*/
|
|
73
|
+
export const mrSuccess = mr(true)
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A node that did not match, at the position the caller should resume from —
|
|
77
|
+
* which a backtracking backend rewinds and a predictive one does not.
|
|
78
|
+
*
|
|
79
|
+
* @type {<L, P>(tag: AstTag, sequence: AstSequence<L>, pos: P) => AstResult<L, P>}
|
|
80
|
+
*/
|
|
81
|
+
export const mrFail = mr(false)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { CodePointMeta } from '../descent/types.ts'
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { assertEq } from '../../asserts/module.f.mjs'
|
|
6
|
+
import { identity } from '../../types/function/module.f.mjs'
|
|
7
|
+
import { eofSymbol } from '../module.f.mjs'
|
|
8
|
+
import { leafAt, mrFail, mrSuccess, physicalIdx, symbolAt } from './module.f.mjs'
|
|
9
|
+
|
|
10
|
+
/** @type {readonly CodePointMeta<string>[]} */
|
|
11
|
+
const withMeta = [[0x41, 'a'], [0x42, 'b']]
|
|
12
|
+
|
|
13
|
+
/** @type {(leaf: CodePointMeta<string>) => number} */
|
|
14
|
+
const metaSymbolOf = ([symbol]) => symbol
|
|
15
|
+
|
|
16
|
+
export const proof = {
|
|
17
|
+
leafAt: [
|
|
18
|
+
() => {
|
|
19
|
+
// Inside the physical input a leaf is contributed whole, whatever a
|
|
20
|
+
// backend chose a leaf to be.
|
|
21
|
+
assertEq(JSON.stringify(leafAt([65, 66], 0)), '[65]')
|
|
22
|
+
assertEq(JSON.stringify(leafAt([65, 66], 1)), '[66]')
|
|
23
|
+
assertEq(JSON.stringify(leafAt(withMeta, 0)), '[[65,"a"]]')
|
|
24
|
+
},
|
|
25
|
+
() => {
|
|
26
|
+
// At and past the physical end there is nothing to contribute: the
|
|
27
|
+
// synthesized end-of-input symbol has no source element, so it never
|
|
28
|
+
// reaches an AST.
|
|
29
|
+
assertEq(JSON.stringify(leafAt([65, 66], 2)), '[]')
|
|
30
|
+
assertEq(JSON.stringify(leafAt([65, 66], 3)), '[]')
|
|
31
|
+
assertEq(JSON.stringify(leafAt([], 0)), '[]')
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
symbolAt: [
|
|
35
|
+
() => {
|
|
36
|
+
// `identity` is the leaf reader of a backend whose leaf *is* the
|
|
37
|
+
// symbol; a pair's reader takes its first half. Same positions, same
|
|
38
|
+
// symbols.
|
|
39
|
+
/** @type {(leaf: number) => number} */
|
|
40
|
+
const symbolOf = identity
|
|
41
|
+
assertEq(symbolAt(symbolOf)([65, 66], 0), 65)
|
|
42
|
+
assertEq(symbolAt(metaSymbolOf)(withMeta, 0), 65)
|
|
43
|
+
assertEq(symbolAt(metaSymbolOf)(withMeta, 1), 66)
|
|
44
|
+
},
|
|
45
|
+
() => {
|
|
46
|
+
// The one synthesized end-of-input symbol sits at the physical end,
|
|
47
|
+
// for either leaf shape.
|
|
48
|
+
/** @type {(leaf: number) => number} */
|
|
49
|
+
const symbolOf = identity
|
|
50
|
+
assertEq(symbolAt(symbolOf)([65, 66], 2), eofSymbol)
|
|
51
|
+
assertEq(symbolAt(metaSymbolOf)(withMeta, 2), eofSymbol)
|
|
52
|
+
assertEq(symbolAt(symbolOf)([], 0), eofSymbol)
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
physicalIdx: () => {
|
|
56
|
+
const physical = physicalIdx(2)
|
|
57
|
+
assertEq(physical(0), 0)
|
|
58
|
+
assertEq(physical(2), 2)
|
|
59
|
+
// Consuming the end-of-input symbol moves the cursor past the physical
|
|
60
|
+
// end, and both cursors report the same public index — which is what
|
|
61
|
+
// keeps a public position physical.
|
|
62
|
+
assertEq(physical(3), 2)
|
|
63
|
+
},
|
|
64
|
+
mrSuccess: () => {
|
|
65
|
+
assertEq(
|
|
66
|
+
JSON.stringify(mrSuccess('some', [65], 1)),
|
|
67
|
+
'{"ast":{"tag":"some","sequence":[65]},"success":true,"pos":1}')
|
|
68
|
+
// The position type is the backend's own: `null` is how a predictive
|
|
69
|
+
// backend says it ran out of input.
|
|
70
|
+
assertEq(
|
|
71
|
+
JSON.stringify(mrSuccess(undefined, [], null)),
|
|
72
|
+
'{"ast":{"sequence":[]},"success":true,"pos":null}')
|
|
73
|
+
},
|
|
74
|
+
mrFail: () => {
|
|
75
|
+
assertEq(
|
|
76
|
+
JSON.stringify(mrFail(true, [], 0)),
|
|
77
|
+
'{"ast":{"tag":true,"sequence":[]},"success":false,"pos":0}')
|
|
78
|
+
},
|
|
79
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-level API for the layer every BNF matcher backend shares: the position
|
|
3
|
+
* it matches at, the AST it builds, and the result that pairs them.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Tag of an AST node: the variant branch that matched, `true` where a rule
|
|
9
|
+
* matched empty input without naming a branch, and `undefined` where the rule
|
|
10
|
+
* is not a choice at all.
|
|
11
|
+
*/
|
|
12
|
+
export type AstTag = string | true | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* An AST over leaves of type `L`. A backend picks `L` for what it keeps of a
|
|
15
|
+
* consumed symbol — the code point alone, or the code point with metadata.
|
|
16
|
+
*/
|
|
17
|
+
export type Ast<L> = {
|
|
18
|
+
readonly tag: AstTag;
|
|
19
|
+
readonly sequence: AstSequence<L>;
|
|
20
|
+
};
|
|
21
|
+
/** The children of an {@link Ast} node: nested nodes and consumed leaves. */
|
|
22
|
+
export type AstSequence<L> = readonly (Ast<L> | L)[];
|
|
23
|
+
/**
|
|
24
|
+
* A match position over input of `length` leaves: `0 .. length` are the
|
|
25
|
+
* physical positions, and `length + 1` is where the one synthesized
|
|
26
|
+
* end-of-input symbol has been consumed.
|
|
27
|
+
*
|
|
28
|
+
* This is the complete cursor `(idx, eofConsumed)` of
|
|
29
|
+
* [the BNF contract](../README.md#logical-eof-in-parser-input) written as one
|
|
30
|
+
* number. `eofConsumed` can only be true at the physical end, so the pair and
|
|
31
|
+
* the extended position hold the same information — and being one number is
|
|
32
|
+
* what makes every ordering a backend needs a plain `<`, because consuming EOF
|
|
33
|
+
* *is* progress even though the public index does not move. A backend that
|
|
34
|
+
* treated it as no progress would loop forever on a repetition over a rule that
|
|
35
|
+
* can match EOF.
|
|
36
|
+
*
|
|
37
|
+
* Public positions are physical, so a cursor is converted back with
|
|
38
|
+
* `physicalIdx` before it leaves a backend.
|
|
39
|
+
*/
|
|
40
|
+
export type Cursor = number;
|
|
41
|
+
/**
|
|
42
|
+
* A matcher's own result: the AST built so far, whether it matched, and where
|
|
43
|
+
* it stopped.
|
|
44
|
+
*
|
|
45
|
+
* `P` is the position type. A backend whose match always has one uses
|
|
46
|
+
* {@link Cursor}; one that also reports running out of input uses
|
|
47
|
+
* `Cursor | null`. Public results are each backend's own type — this is the
|
|
48
|
+
* shape they are built from, not the shape they return.
|
|
49
|
+
*/
|
|
50
|
+
export type AstResult<L, P> = {
|
|
51
|
+
readonly ast: Ast<L>;
|
|
52
|
+
readonly success: boolean;
|
|
53
|
+
readonly pos: P;
|
|
54
|
+
};
|
package/fjs/bnf/testlib.f.d.mts
CHANGED
|
@@ -1,10 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module
|
|
3
3
|
*
|
|
4
|
+
* @import { Ast, AstTag } from './matcher/types.ts'
|
|
4
5
|
* @import { Rule } from './types.ts'
|
|
5
6
|
*/
|
|
7
|
+
import type { Ast } from './matcher/types.ts';
|
|
6
8
|
import type { Rule } from './types.ts';
|
|
7
9
|
/** @type {() => Rule} */
|
|
8
10
|
export declare const classic: () => Rule;
|
|
9
11
|
/** @type {() => Rule} */
|
|
10
12
|
export declare const deterministic: () => Rule;
|
|
13
|
+
export type _Leaf = number | readonly [number, unknown];
|
|
14
|
+
export type _AstNode = Ast<_Leaf>;
|
|
15
|
+
export type _AstChild = _AstNode | _Leaf;
|
|
16
|
+
export type _Parts = {
|
|
17
|
+
readonly parts: readonly string[];
|
|
18
|
+
readonly text: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Renders a matcher AST as one line of `tag(children)`, with the code points a
|
|
22
|
+
* node consumed directly written as one quoted string.
|
|
23
|
+
*
|
|
24
|
+
* A proof that pins a whole AST is checking its *shape*, and raw JSON buries
|
|
25
|
+
* that under `{"tag":…,"sequence":[…]}` and a `[32,null]` per space — several
|
|
26
|
+
* kilobytes for an input a reader can hold in their head. This keeps the two
|
|
27
|
+
* things a repetition changes legible: how deep the nesting goes, and which
|
|
28
|
+
* tags survive. Repeated items are siblings under one node, whereas the
|
|
29
|
+
* right-recursive encoding puts each item one level deeper than the last.
|
|
30
|
+
*
|
|
31
|
+
* @type {(node: _AstNode) => string}
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
*
|
|
35
|
+
* ```ts
|
|
36
|
+
* // three spaces matched by a flat `repeat`, then by right-recursion
|
|
37
|
+
* '(" "(" ") " "(" ") " "(" "))'
|
|
38
|
+
* '" "(" " " "(" " " "(" " *())'
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare const showAst: (node: _AstNode) => string;
|
package/fjs/bnf/testlib.f.mjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module
|
|
3
3
|
*
|
|
4
|
+
* @import { Ast, AstTag } from './matcher/types.ts'
|
|
4
5
|
* @import { Rule } from './types.ts'
|
|
5
6
|
*/
|
|
6
7
|
|
|
8
|
+
import { codePointToString } from '../text/utf16/module.f.mjs'
|
|
7
9
|
import {
|
|
8
10
|
commaJoin0Plus,
|
|
9
11
|
none,
|
|
@@ -194,3 +196,81 @@ export const deterministic = () => {
|
|
|
194
196
|
|
|
195
197
|
return json
|
|
196
198
|
}
|
|
199
|
+
|
|
200
|
+
//
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The leaf of either backend's AST: `bnf/ll1` keeps the code point alone and
|
|
204
|
+
* `bnf/descent` pairs it with metadata, so a renderer that takes both is
|
|
205
|
+
* generic over exactly this.
|
|
206
|
+
*
|
|
207
|
+
* @typedef {number | readonly [number, unknown]} _Leaf
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
/** @typedef {Ast<_Leaf>} _AstNode */
|
|
211
|
+
|
|
212
|
+
/** @typedef {_AstNode | _Leaf} _AstChild */
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @param {_AstChild} child
|
|
216
|
+
* @returns {child is _AstNode}
|
|
217
|
+
*/
|
|
218
|
+
const isAstNode = child => typeof child !== 'number' && !(child instanceof Array)
|
|
219
|
+
|
|
220
|
+
/** @type {(child: _Leaf) => number} */
|
|
221
|
+
const codePointOf = child => typeof child === 'number' ? child : child[0]
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* A tag as `showAst` writes it: a quoted string, `*` for the tagless empty
|
|
225
|
+
* match, and nothing at all for an untagged node. `*` rather than `true`
|
|
226
|
+
* because a branch may itself be named `true` — the JSON grammars have one.
|
|
227
|
+
*
|
|
228
|
+
* @type {(tag: AstTag) => string}
|
|
229
|
+
*/
|
|
230
|
+
const showTag = tag =>
|
|
231
|
+
tag === undefined ? '' : tag === true ? '*' : JSON.stringify(tag)
|
|
232
|
+
|
|
233
|
+
/** @typedef {{ readonly parts: readonly string[], readonly text: string }} _Parts */
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Ends the run of consumed code points being accumulated, if there is one, so
|
|
237
|
+
* that a node's text appears as one quoted string rather than one part per
|
|
238
|
+
* symbol.
|
|
239
|
+
*
|
|
240
|
+
* @type {(acc: _Parts) => readonly string[]}
|
|
241
|
+
*/
|
|
242
|
+
const flushText = acc =>
|
|
243
|
+
acc.text === '' ? acc.parts : [...acc.parts, JSON.stringify(acc.text)]
|
|
244
|
+
|
|
245
|
+
/** @type {(acc: _Parts, child: _AstChild) => _Parts} */
|
|
246
|
+
const addChild = (acc, child) =>
|
|
247
|
+
isAstNode(child)
|
|
248
|
+
? { parts: [...flushText(acc), showAst(child)], text: '' }
|
|
249
|
+
: { parts: acc.parts, text: acc.text + codePointToString(codePointOf(child)) }
|
|
250
|
+
|
|
251
|
+
/** @type {_Parts} */
|
|
252
|
+
const noParts = { parts: [], text: '' }
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Renders a matcher AST as one line of `tag(children)`, with the code points a
|
|
256
|
+
* node consumed directly written as one quoted string.
|
|
257
|
+
*
|
|
258
|
+
* A proof that pins a whole AST is checking its *shape*, and raw JSON buries
|
|
259
|
+
* that under `{"tag":…,"sequence":[…]}` and a `[32,null]` per space — several
|
|
260
|
+
* kilobytes for an input a reader can hold in their head. This keeps the two
|
|
261
|
+
* things a repetition changes legible: how deep the nesting goes, and which
|
|
262
|
+
* tags survive. Repeated items are siblings under one node, whereas the
|
|
263
|
+
* right-recursive encoding puts each item one level deeper than the last.
|
|
264
|
+
*
|
|
265
|
+
* @type {(node: _AstNode) => string}
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
*
|
|
269
|
+
* ```ts
|
|
270
|
+
* // three spaces matched by a flat `repeat`, then by right-recursion
|
|
271
|
+
* '(" "(" ") " "(" ") " "(" "))'
|
|
272
|
+
* '" "(" " " "(" " " "(" " *())'
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
export const showAst = node =>
|
|
276
|
+
`${showTag(node.tag)}(${flushText(node.sequence.reduce(addChild, noParts)).join(' ')})`
|
|
@@ -14,4 +14,4 @@ import type { MemOp } from '../../effects/memory/types.ts';
|
|
|
14
14
|
import type { FileCasOperation } from '../types.ts';
|
|
15
15
|
/** @type {Commands<FileCasOperation | WriteFile | Write | All | MemOp | Read>} */
|
|
16
16
|
export declare const commands: Commands<FileCasOperation | WriteFile | Write | All | MemOp | Read>;
|
|
17
|
-
export declare const main:
|
|
17
|
+
export declare const main: import("../../effects/node/types.ts").Program<All | Read | Write | WriteFile | FileCasOperation | MemOp>;
|
package/fjs/cas/cli/module.f.mjs
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
import { sha256 } from '../../crypto/sha2/module.f.mjs'
|
|
13
13
|
import { cBase32ToVec, vecToCBase32 } from '../../basen/cbase32/module.f.mjs'
|
|
14
|
-
|
|
15
|
-
import { errorExit, log, writeFromStream } from '../../effects/node/module.f.mjs'
|
|
14
|
+
|
|
15
|
+
import { errorExit, exitStep, log, writeFromStream } from '../../effects/node/module.f.mjs'
|
|
16
|
+
import { forEachStep, step as ioStep } from '../../effects/module.f.mjs'
|
|
16
17
|
import { dispatch } from '../../cli/module.f.mjs'
|
|
17
18
|
import { casAddFile, fileCas } from '../module.f.mjs'
|
|
18
19
|
|
|
@@ -26,15 +27,9 @@ export const commands = [
|
|
|
26
27
|
return errorExit("'cas add' expects one parameter")
|
|
27
28
|
}
|
|
28
29
|
const c = fileCas(sha256)(home)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
? pure(1)
|
|
33
|
-
: step(
|
|
34
|
-
log(vecToCBase32(hashResult[1])),
|
|
35
|
-
() => pure(0)
|
|
36
|
-
)
|
|
37
|
-
)
|
|
30
|
+
const added = casAddFile(c)(path)
|
|
31
|
+
const logged = ioStep(added, hash => log(vecToCBase32(hash)))
|
|
32
|
+
return exitStep(logged)
|
|
38
33
|
},
|
|
39
34
|
},
|
|
40
35
|
{
|
|
@@ -50,10 +45,7 @@ export const commands = [
|
|
|
50
45
|
}
|
|
51
46
|
const c = fileCas(sha256)(home)
|
|
52
47
|
const x = c.read(hash)
|
|
53
|
-
return
|
|
54
|
-
writeFromStream(path, x),
|
|
55
|
-
([r, v]) => r === 'error' ? errorExit(`e: ` + String(v)) : pure(0),
|
|
56
|
-
)
|
|
48
|
+
return exitStep(writeFromStream(path, x))
|
|
57
49
|
},
|
|
58
50
|
},
|
|
59
51
|
{
|
|
@@ -61,11 +53,13 @@ export const commands = [
|
|
|
61
53
|
description: 'List all stored content hashes',
|
|
62
54
|
handler: ({ home }) => {
|
|
63
55
|
const c = fileCas(sha256)(home)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
56
|
+
// The fold's `items` is deliberately a raw effect, so a fallible
|
|
57
|
+
// producer composes with `step` ahead of it rather than the fold
|
|
58
|
+
// growing an error channel of its own.
|
|
59
|
+
// `c.list()` feeds the fold directly: the step that used to sit
|
|
60
|
+
// here existed only to unwrap the list so `pure` could wrap it
|
|
61
|
+
// again.
|
|
62
|
+
return exitStep(forEachStep(c.list(), j => log(vecToCBase32(j))))
|
|
69
63
|
},
|
|
70
64
|
},
|
|
71
65
|
]
|
|
@@ -14,7 +14,5 @@ export declare const proof: {
|
|
|
14
14
|
mainListEmptyStore: () => void;
|
|
15
15
|
mainNoCmd: () => void;
|
|
16
16
|
mainUnknownCmd: () => void;
|
|
17
|
-
|
|
18
|
-
mainListCorruptStore: () => readonly [import("../../effects/node/virtual/types.ts").State, number];
|
|
19
|
-
};
|
|
17
|
+
mainListCorruptStore: () => void;
|
|
20
18
|
};
|