functionalscript 0.45.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 +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/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/module.f.d.mts +0 -41
- package/fjs/types/rtti/validate/module.f.mjs +0 -171
- 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/cas/types.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import type { Vec } from '../types/bit_vec/types.ts';
|
|
7
7
|
import type { Effect, Operation } from '../effects/types.ts';
|
|
8
8
|
import type { List } from '../effects/list/types.ts';
|
|
9
|
-
import type {
|
|
9
|
+
import type { Access, CreateExclusive, IoChannel, Mkdir, Now, RandomInt, ReadBytes, Readdir, Rename, Rm, Stat, WriteBytes } from '../effects/node/types.ts';
|
|
10
10
|
/**
|
|
11
11
|
* The filesystem effects the streaming CAS performs: `read` pulls shards
|
|
12
12
|
* (`ReadBytes`); `list` walks the store (`Access`/`Readdir`); `write` runs the
|
|
@@ -17,18 +17,32 @@ import type { IoResult, Mkdir, Now, RandomInt, ReadBytes, Readdir, Rename, Rm, C
|
|
|
17
17
|
export type FileCasOperation = ReadBytes | Mkdir | Readdir | Access | Rename | Rm | RandomInt | Now | CreateExclusive | WriteBytes | Stat | Now | Readdir | Rm;
|
|
18
18
|
export type Cas<O extends Operation> = {
|
|
19
19
|
/**
|
|
20
|
-
* Streams the content for `hash` out in `<=128 KiB` chunks.
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* Streams the content for `hash` out in `<=128 KiB` chunks.
|
|
21
|
+
*
|
|
22
|
+
* A missing shard or an I/O error **fails the stream** rather than ending
|
|
23
|
+
* it, so it can never be mistaken for end-of-stream. That distinction used
|
|
24
|
+
* to be a rule this comment had to state, with an `ok(chunk)`/`error` item
|
|
25
|
+
* union that every consumer kept apart by hand; it is now the difference
|
|
26
|
+
* between an `error` cell and an `ok(undefined)` one, which nothing can
|
|
27
|
+
* confuse.
|
|
23
28
|
*/
|
|
24
|
-
readonly read: (hash: Vec) => List<O,
|
|
29
|
+
readonly read: (hash: Vec) => List<O, Vec, IoChannel>;
|
|
25
30
|
/**
|
|
26
|
-
* Consumes a chunk stream
|
|
27
|
-
*
|
|
31
|
+
* Consumes a chunk stream, hashing incrementally, and returns the content
|
|
32
|
+
* address. A stream that fails aborts the upload with that failure.
|
|
28
33
|
*/
|
|
29
|
-
readonly write: <O1 extends Operation>(payload: List<O1,
|
|
30
|
-
/**
|
|
31
|
-
|
|
34
|
+
readonly write: <O1 extends Operation>(payload: List<O1, Vec, IoChannel>) => Effect<O | O1, Vec, IoChannel>;
|
|
35
|
+
/**
|
|
36
|
+
* Lists all stored content hashes.
|
|
37
|
+
*
|
|
38
|
+
* Fallible like its siblings: walking the store is IO, and a store that
|
|
39
|
+
* cannot be walked must be distinguishable from one that is empty. An
|
|
40
|
+
* absent store *is* empty and answers `ok([])` — that is the fresh-store
|
|
41
|
+
* case, not a failure — but a directory that exists and cannot be read is
|
|
42
|
+
* an error, and returning it is what lets a caller say so instead of
|
|
43
|
+
* reporting no content.
|
|
44
|
+
*/
|
|
45
|
+
readonly list: () => Effect<O, readonly Vec[], IoChannel>;
|
|
32
46
|
};
|
|
33
47
|
export type FileCas = Cas<FileCasOperation> & {
|
|
34
48
|
url: (v: Vec) => string;
|
|
@@ -18,7 +18,7 @@ export declare const images: {
|
|
|
18
18
|
readonly arm: 'windows-11-arm';
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
-
export declare const functionalscript = /** @type {const} */ "0.
|
|
21
|
+
export declare const functionalscript = /** @type {const} */ "0.45.0";
|
|
22
22
|
export declare const bun = "1.3.14";
|
|
23
23
|
export declare const deno = "2.9.5";
|
|
24
24
|
export declare const node: {
|
|
@@ -28,7 +28,7 @@ export declare const node: {
|
|
|
28
28
|
};
|
|
29
29
|
export declare const nixpkgs: {
|
|
30
30
|
readonly ref: 'nixos-26.05';
|
|
31
|
-
readonly commit: '
|
|
31
|
+
readonly commit: '02e08985a27c65ffd33d434eeb2e660a2e4dc84d';
|
|
32
32
|
};
|
|
33
33
|
export declare const wasmtime = "47.0.3";
|
|
34
34
|
export declare const wasmer = "7.2.1";
|
|
@@ -25,7 +25,7 @@ export const images = /** @type {const} */({
|
|
|
25
25
|
// published FunctionalScript release; do not tie it to package.json's current
|
|
26
26
|
// in-repo version.
|
|
27
27
|
// https://www.npmjs.com/package/functionalscript
|
|
28
|
-
export const functionalscript = /** @type {const} */ '0.
|
|
28
|
+
export const functionalscript = /** @type {const} */ '0.45.0'
|
|
29
29
|
|
|
30
30
|
// https://bun.sh/
|
|
31
31
|
export const bun = '1.3.14'
|
|
@@ -53,7 +53,7 @@ export const node = /** @type {const} */({
|
|
|
53
53
|
// https://channels.nixos.org/nixos-26.05/git-revision
|
|
54
54
|
export const nixpkgs = /** @type {const} */({
|
|
55
55
|
ref: 'nixos-26.05',
|
|
56
|
-
commit: '
|
|
56
|
+
commit: '02e08985a27c65ffd33d434eeb2e660a2e4dc84d',
|
|
57
57
|
})
|
|
58
58
|
|
|
59
59
|
// https://github.com/bytecodealliance/wasmtime/releases
|
package/fjs/ci/module.f.d.mts
CHANGED
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*
|
|
8
|
-
* @import { Effect } from '../effects/types.ts'
|
|
9
8
|
* @import { NodeOp } from '../effects/node/types.ts'
|
|
10
9
|
* @import { Architecture, GitHubAction, Job, Jobs, MetaStep, Os } from './common/types.ts'
|
|
11
10
|
* @import { NixJob } from './nix/types.ts'
|
|
12
11
|
* @import { Setup } from './types.ts'
|
|
12
|
+
* @import { Effect } from '../effects/types.ts'
|
|
13
13
|
*/
|
|
14
|
-
import type { Effect } from '../effects/types.ts';
|
|
15
14
|
import type { NodeOp } from '../effects/node/types.ts';
|
|
16
15
|
import type { Setup } from './types.ts';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export declare const
|
|
16
|
+
import type { Effect } from '../effects/types.ts';
|
|
17
|
+
/** @type {(setup: Setup) => Effect<NodeOp, 0, number>} */
|
|
18
|
+
export declare const ci: (setup: Setup) => Effect<NodeOp, 0, number>;
|
|
19
|
+
export declare const main: () => Effect<NodeOp, 0, number>;
|
package/fjs/ci/module.f.mjs
CHANGED
|
@@ -5,15 +5,16 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*
|
|
8
|
-
* @import { Effect } from '../effects/types.ts'
|
|
9
8
|
* @import { NodeOp } from '../effects/node/types.ts'
|
|
10
9
|
* @import { Architecture, GitHubAction, Job, Jobs, MetaStep, Os } from './common/types.ts'
|
|
11
10
|
* @import { NixJob } from './nix/types.ts'
|
|
12
11
|
* @import { Setup } from './types.ts'
|
|
12
|
+
* @import { Effect } from '../effects/types.ts'
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import {
|
|
16
|
-
import { access, writeUtf8File } from '../effects/node/module.f.mjs'
|
|
15
|
+
import { resultStep } from '../effects/module.f.mjs'
|
|
16
|
+
import { access, exitStep, writeUtf8File } from '../effects/node/module.f.mjs'
|
|
17
|
+
import { step as ioStep } from '../effects/module.f.mjs'
|
|
17
18
|
import { functionalscript, images } from './config/module.f.mjs'
|
|
18
19
|
import {
|
|
19
20
|
architecture,
|
|
@@ -57,8 +58,8 @@ const canonicalJobs = rust => ({
|
|
|
57
58
|
'nix-flakes': nixFlakeJob,
|
|
58
59
|
})
|
|
59
60
|
|
|
60
|
-
/** @type {(setup: Setup) => Effect<NodeOp, number>} */
|
|
61
|
-
export const ci = ({ nodeExtra }) =>
|
|
61
|
+
/** @type {(setup: Setup) => Effect<NodeOp, 0, number>} */
|
|
62
|
+
export const ci = ({ nodeExtra }) => resultStep(
|
|
62
63
|
access('Cargo.toml'),
|
|
63
64
|
result => {
|
|
64
65
|
const rust = result[0] === 'ok'
|
|
@@ -82,8 +83,8 @@ export const ci = ({ nodeExtra }) => step(
|
|
|
82
83
|
const workflowWritten = writeUtf8File(
|
|
83
84
|
'.github/workflows/ci.yml',
|
|
84
85
|
JSON.stringify(gha, null, ' '))
|
|
85
|
-
const flakesWritten =
|
|
86
|
-
return
|
|
86
|
+
const flakesWritten = ioStep(workflowWritten, () => nixFlakes(nixJobs))
|
|
87
|
+
return exitStep(flakesWritten)
|
|
87
88
|
})
|
|
88
89
|
|
|
89
90
|
export const main = () => ci({ nodeExtra: () => [] })
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*
|
|
14
|
+
* @import { IoChannel, Mkdir, WriteFile } from '../../effects/node/types.ts'
|
|
14
15
|
* @import { Effect } from '../../effects/types.ts'
|
|
15
|
-
* @import { Mkdir, WriteFile } from '../../effects/node/types.ts'
|
|
16
16
|
* @import { Expression } from '../../media/nix/types.ts'
|
|
17
17
|
* @import { MetaStep } from '../common/types.ts'
|
|
18
18
|
* @import { NixJob } from './types.ts'
|
|
19
19
|
*/
|
|
20
|
+
import type { IoChannel, Mkdir, WriteFile } from '../../effects/node/types.ts';
|
|
20
21
|
import type { Effect } from '../../effects/types.ts';
|
|
21
|
-
import type { Mkdir, WriteFile } from '../../effects/node/types.ts';
|
|
22
22
|
import type { MetaStep } from '../common/types.ts';
|
|
23
23
|
import type { NixJob } from './types.ts';
|
|
24
24
|
/** Directory owned by this generator. */
|
|
@@ -35,16 +35,18 @@ export declare const generatedDirectory: 'nix/generated';
|
|
|
35
35
|
*/
|
|
36
36
|
export declare const flakeText: (job: NixJob) => string;
|
|
37
37
|
/**
|
|
38
|
-
* Writes one generated flake per job.
|
|
38
|
+
* Writes one generated flake per job, stopping at the first failure.
|
|
39
39
|
*
|
|
40
|
-
* @type {(jobs: readonly NixJob[]) => Effect<Mkdir | WriteFile, void>}
|
|
40
|
+
* @type {(jobs: readonly NixJob[]) => Effect<Mkdir | WriteFile, void, IoChannel>}
|
|
41
41
|
*/
|
|
42
|
-
export declare const nixFlakes: (jobs: readonly NixJob[]) => Effect<Mkdir | WriteFile, void>;
|
|
42
|
+
export declare const nixFlakes: (jobs: readonly NixJob[]) => Effect<Mkdir | WriteFile, void, IoChannel>;
|
|
43
43
|
/** Path a workflow passes to `nix develop`, for the job of the given id. */
|
|
44
|
+
/** @type {(id: string) => string} */
|
|
44
45
|
export declare const flakePath: (id: string) => string;
|
|
45
46
|
/** Installs Nix, with `nix-command` and `flakes` enabled by the action's defaults. */
|
|
46
47
|
export declare const nixInstall: MetaStep;
|
|
47
48
|
/** Runs one command inside a job's generated development shell. */
|
|
49
|
+
/** @type {(id: string, command: string) => string} */
|
|
48
50
|
export declare const nixDevelop: (id: string, command: string) => string;
|
|
49
51
|
/**
|
|
50
52
|
* Runs a migrated job's whole command sequence in one development shell, so the
|
package/fjs/ci/nix/module.f.mjs
CHANGED
|
@@ -11,15 +11,16 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*
|
|
14
|
+
* @import { IoChannel, Mkdir, WriteFile } from '../../effects/node/types.ts'
|
|
14
15
|
* @import { Effect } from '../../effects/types.ts'
|
|
15
|
-
* @import { Mkdir, WriteFile } from '../../effects/node/types.ts'
|
|
16
16
|
* @import { Expression } from '../../media/nix/types.ts'
|
|
17
17
|
* @import { MetaStep } from '../common/types.ts'
|
|
18
18
|
* @import { NixJob } from './types.ts'
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import {
|
|
21
|
+
import { pureOk } from '../../effects/module.f.mjs'
|
|
22
22
|
import { mkdir, writeUtf8File } from '../../effects/node/module.f.mjs'
|
|
23
|
+
import { forEachStep, step } from '../../effects/module.f.mjs'
|
|
23
24
|
import { nixToString } from '../../media/nix/module.f.mjs'
|
|
24
25
|
import { fromUndefined, unwrap as unwrapNullable } from '../../types/nullable/module.f.mjs'
|
|
25
26
|
import { unwrap } from '../../types/result/module.f.mjs'
|
|
@@ -72,33 +73,33 @@ const flake = ({ system, packages, shellHook }) => ['set',
|
|
|
72
73
|
export const flakeText = job =>
|
|
73
74
|
unwrapNullable(fromUndefined(nixToString(flake(job))))
|
|
74
75
|
|
|
75
|
-
/** @type {(job: NixJob) => Effect<Mkdir | WriteFile, void>} */
|
|
76
|
+
/** @type {(job: NixJob) => Effect<Mkdir | WriteFile, void, IoChannel>} */
|
|
76
77
|
const writeFlake = job => {
|
|
77
78
|
const directory = `${generatedDirectory}/${job.id}`
|
|
78
|
-
const created =
|
|
79
|
-
|
|
79
|
+
const created = mkdir(directory, { recursive: true })
|
|
80
|
+
return step(
|
|
80
81
|
created,
|
|
81
82
|
() => writeUtf8File(`${directory}/flake.nix`, flakeText(job)))
|
|
82
|
-
return mapStep(written, unwrap)
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
|
-
* Writes one generated flake per job.
|
|
86
|
+
* Writes one generated flake per job, stopping at the first failure.
|
|
87
87
|
*
|
|
88
|
-
* @type {(jobs: readonly NixJob[]) => Effect<Mkdir | WriteFile, void>}
|
|
88
|
+
* @type {(jobs: readonly NixJob[]) => Effect<Mkdir | WriteFile, void, IoChannel>}
|
|
89
89
|
*/
|
|
90
90
|
export const nixFlakes = jobs =>
|
|
91
|
-
forEachStep(
|
|
91
|
+
forEachStep(pureOk(jobs), writeFlake)
|
|
92
92
|
|
|
93
93
|
/** Path a workflow passes to `nix develop`, for the job of the given id. */
|
|
94
|
-
|
|
94
|
+
/** @type {(id: string) => string} */
|
|
95
|
+
export const flakePath = id => `./${generatedDirectory}/${id}`
|
|
95
96
|
|
|
96
97
|
/** Installs Nix, with `nix-command` and `flakes` enabled by the action's defaults. */
|
|
97
98
|
export const nixInstall = install(uses('cachix/install-nix-action'))
|
|
98
99
|
|
|
99
100
|
/** Runs one command inside a job's generated development shell. */
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
/** @type {(id: string, command: string) => string} */
|
|
102
|
+
export const nixDevelop = (id, command) => `nix develop ${flakePath(id)} --command ${command}`
|
|
102
103
|
|
|
103
104
|
/**
|
|
104
105
|
* Wraps a string so a POSIX shell reproduces it exactly. Single quotes protect
|
package/fjs/ci/nix/proof.f.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { assert, assertEq } from '../../asserts/module.f.mjs'
|
|
10
|
-
import { step } from '../../effects/module.f.mjs'
|
|
10
|
+
import { step as ioStep } from '../../effects/module.f.mjs'
|
|
11
11
|
import { readUtf8File } from '../../effects/node/module.f.mjs'
|
|
12
12
|
import { emptyState, virtual } from '../../effects/node/virtual/module.f.mjs'
|
|
13
13
|
import { nixpkgs } from '../config/module.f.mjs'
|
|
@@ -74,7 +74,7 @@ const shellHookFlake = `{
|
|
|
74
74
|
|
|
75
75
|
/** @type {(jobs: readonly NixJob[], id: string) => string} */
|
|
76
76
|
const generated = (jobs, id) => {
|
|
77
|
-
const written =
|
|
77
|
+
const written = ioStep(
|
|
78
78
|
nixFlakes(jobs),
|
|
79
79
|
() => readUtf8File(`${generatedDirectory}/${id}/flake.nix`))
|
|
80
80
|
const [, [tag, result]] = virtual(emptyState)(written)
|
package/fjs/ci/proof.f.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @import { Dir, State } from '../effects/node/virtual/types.ts'
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { exitCode } from '../effects/node/module.f.mjs'
|
|
6
7
|
import { ci, main } from './module.f.mjs'
|
|
7
8
|
import { functionalscript, node } from './config/module.f.mjs'
|
|
8
9
|
import { nodeNixJobs } from './node/module.f.mjs'
|
|
@@ -39,8 +40,11 @@ const makeState = (/** @type {boolean} */ rust, /** @type {string | undefined} *
|
|
|
39
40
|
/** @type {(dir: Dir, name: string) => Dir} */
|
|
40
41
|
const subDir = (dir, name) => {
|
|
41
42
|
const entity = dir[name]
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
// `Array.isArray` narrows to `any[]`, which `readonly Vec[]` is not assignable
|
|
44
|
+
// to, so its negative branch never removes a `readonly` array from a union.
|
|
45
|
+
// `instanceof Array` does, so this `assert` narrows `entity` to `Dir`.
|
|
46
|
+
assert(typeof entity === 'object' && !(entity instanceof Array), entity)
|
|
47
|
+
return entity
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
/** @type {(dir: Dir, name: string) => string} */
|
|
@@ -66,14 +70,14 @@ const flake = (state, id) =>
|
|
|
66
70
|
/** @type {(rust: boolean, nodeExtra?: (o: Os) => readonly MetaStep[]) => GitHubAction} */
|
|
67
71
|
const run = (rust, nodeExtra = () => []) => {
|
|
68
72
|
const [state, result] = virtual(makeState(rust, undefined))(ci({ nodeExtra }))
|
|
69
|
-
assertEq(result, 0)
|
|
73
|
+
assertEq(exitCode(result), 0)
|
|
70
74
|
return workflow(state)
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
/** @type {(packageJson?: string) => GitHubAction} */
|
|
74
78
|
const runDefault = packageJson => {
|
|
75
79
|
const [state, result] = virtual(makeState(false, packageJson))(main())
|
|
76
|
-
assertEq(result, 0)
|
|
80
|
+
assertEq(exitCode(result), 0)
|
|
77
81
|
return workflow(state)
|
|
78
82
|
}
|
|
79
83
|
|
|
@@ -175,7 +179,7 @@ export const proof = {
|
|
|
175
179
|
},
|
|
176
180
|
nixFlakes: () => {
|
|
177
181
|
const [state, result] = virtual(makeState(false, undefined))(main())
|
|
178
|
-
assertEq(result, 0)
|
|
182
|
+
assertEq(exitCode(result), 0)
|
|
179
183
|
for (const { id, packages } of nodeNixJobs) {
|
|
180
184
|
const [nodePackage] = packages
|
|
181
185
|
assert(
|
package/fjs/cli/module.f.d.mts
CHANGED
|
@@ -5,12 +5,10 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*
|
|
8
|
-
* @import { NodeOp,
|
|
9
|
-
* @import { Effect } from '../effects/types.ts'
|
|
8
|
+
* @import { NodeOp, Program, Write } from '../effects/node/types.ts'
|
|
10
9
|
* @import { Commands } from './types.ts'
|
|
11
10
|
*/
|
|
12
|
-
import type { NodeOp,
|
|
13
|
-
import type { Effect } from '../effects/types.ts';
|
|
11
|
+
import type { NodeOp, Program, Write } from '../effects/node/types.ts';
|
|
14
12
|
import type { Commands } from './types.ts';
|
|
15
|
-
/** @type {<O extends NodeOp>(commands: Commands<O>) =>
|
|
16
|
-
export declare const dispatch: <O extends NodeOp>(commands: Commands<O>) =>
|
|
13
|
+
/** @type {<O extends NodeOp>(commands: Commands<O>) => Program<O | Write>} */
|
|
14
|
+
export declare const dispatch: <O extends NodeOp>(commands: Commands<O>) => Program<O | Write>;
|
package/fjs/cli/module.f.mjs
CHANGED
|
@@ -5,18 +5,16 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*
|
|
8
|
-
* @import { NodeOp,
|
|
9
|
-
* @import { Effect } from '../effects/types.ts'
|
|
8
|
+
* @import { NodeOp, Program, Write } from '../effects/node/types.ts'
|
|
10
9
|
* @import { Commands } from './types.ts'
|
|
11
10
|
*/
|
|
12
11
|
|
|
13
|
-
import { errorExit, log } from '../effects/node/module.f.mjs'
|
|
14
|
-
import { pure, step } from '../effects/module.f.mjs'
|
|
12
|
+
import { errorExit, exitStep, log } from '../effects/node/module.f.mjs'
|
|
15
13
|
import { at, fromEntries } from '../types/object/module.f.mjs'
|
|
16
14
|
|
|
17
15
|
const helpMeta = { names: ['help', 'h', '?'], description: 'Print this help message' }
|
|
18
16
|
|
|
19
|
-
/** @type {<O extends NodeOp>(commands: Commands<O>) =>
|
|
17
|
+
/** @type {<O extends NodeOp>(commands: Commands<O>) => Program<O | Write>} */
|
|
20
18
|
export const dispatch = commands => options => {
|
|
21
19
|
const [cmd, ...rest] = options.args
|
|
22
20
|
const rows = [...commands, helpMeta]
|
|
@@ -38,9 +36,7 @@ export const dispatch = commands => options => {
|
|
|
38
36
|
return dispatch(targetCmd.handler)({ ...options, args: ['help'] })
|
|
39
37
|
}
|
|
40
38
|
}
|
|
41
|
-
return
|
|
42
|
-
log(helpText),
|
|
43
|
-
() => pure(0))
|
|
39
|
+
return exitStep(log(helpText))
|
|
44
40
|
}
|
|
45
41
|
const found = at(cmd)(map)
|
|
46
42
|
if (found === null) {
|
package/fjs/cli/proof.f.mjs
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* @import { Commands } from './types.ts'
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { exitCode } from '../effects/node/module.f.mjs'
|
|
7
|
+
import { pureError, pureOk } from '../effects/module.f.mjs'
|
|
7
8
|
import { defaultNodeProgramOptions, emptyState, virtual } from '../effects/node/virtual/module.f.mjs'
|
|
8
9
|
import { dispatch } from './module.f.mjs'
|
|
9
10
|
import { assert, assertEq } from '../asserts/module.f.mjs'
|
|
@@ -17,7 +18,7 @@ const echoCommands = [
|
|
|
17
18
|
{
|
|
18
19
|
names: ['echo', 'e'],
|
|
19
20
|
description: 'Print the first argument',
|
|
20
|
-
handler: ({ args: [arg = ''] }) =>
|
|
21
|
+
handler: ({ args: [arg = ''] }) => arg.length === 0 ? pureOk(0) : pureError(arg.length),
|
|
21
22
|
},
|
|
22
23
|
]
|
|
23
24
|
|
|
@@ -27,25 +28,25 @@ const run = (/** @type {Commands<NodeOp>} */ commands) => (/** @type {readonly s
|
|
|
27
28
|
export const proof = {
|
|
28
29
|
knownCommand: () => {
|
|
29
30
|
const [, code] = run(echoCommands)(['echo', 'hello'])
|
|
30
|
-
assertEq(code, 5, ['expected length 5', code])
|
|
31
|
+
assertEq(exitCode(code), 5, ['expected length 5', code])
|
|
31
32
|
},
|
|
32
33
|
alias: () => {
|
|
33
34
|
const [, code] = run(echoCommands)(['e', 'hi'])
|
|
34
|
-
assertEq(code, 2, ['expected length 2', code])
|
|
35
|
+
assertEq(exitCode(code), 2, ['expected length 2', code])
|
|
35
36
|
},
|
|
36
37
|
noArgs: () => {
|
|
37
38
|
const [state, code] = run(echoCommands)([])
|
|
38
|
-
assertEq(code, 1, ['expected exit 1', code])
|
|
39
|
+
assertEq(exitCode(code), 1, ['expected exit 1', code])
|
|
39
40
|
assert(state.stderr.length !== 0, 'expected error in stderr')
|
|
40
41
|
},
|
|
41
42
|
unknownCommand: () => {
|
|
42
43
|
const [state, code] = run(echoCommands)(['bogus'])
|
|
43
|
-
assertEq(code, 1, ['expected exit 1', code])
|
|
44
|
+
assertEq(exitCode(code), 1, ['expected exit 1', code])
|
|
44
45
|
assert(state.stderr.length !== 0, 'expected error in stderr')
|
|
45
46
|
},
|
|
46
47
|
help: () => {
|
|
47
48
|
const [state, code] = run(echoCommands)(['help'])
|
|
48
|
-
assertEq(code, 0, ['expected exit 0', code])
|
|
49
|
+
assertEq(exitCode(code), 0, ['expected exit 0', code])
|
|
49
50
|
assert(state.stdout.includes('echo'), 'expected command name in stdout')
|
|
50
51
|
assert(state.stdout.includes('help'), 'expected help entry in stdout')
|
|
51
52
|
},
|
|
@@ -62,7 +63,7 @@ export const proof = {
|
|
|
62
63
|
description: 'Capture args',
|
|
63
64
|
handler: (/** @type {{ args: readonly string[] }} */ { args }) => {
|
|
64
65
|
captured.push(...args)
|
|
65
|
-
return
|
|
66
|
+
return pureOk(0)
|
|
66
67
|
},
|
|
67
68
|
}]
|
|
68
69
|
run(commands)(['grab', 'a', 'b', 'c'])
|
|
@@ -73,7 +74,7 @@ export const proof = {
|
|
|
73
74
|
const inner = [{
|
|
74
75
|
names: ['ping'],
|
|
75
76
|
description: 'Inner ping',
|
|
76
|
-
handler: () =>
|
|
77
|
+
handler: () => pureError(42),
|
|
77
78
|
}]
|
|
78
79
|
/** @type {Commands<NodeOp>} */
|
|
79
80
|
const outer = [{
|
|
@@ -82,14 +83,14 @@ export const proof = {
|
|
|
82
83
|
handler: inner,
|
|
83
84
|
}]
|
|
84
85
|
const [, code] = run(outer)(['sub', 'ping'])
|
|
85
|
-
assertEq(code, 42, ['expected 42', code])
|
|
86
|
+
assertEq(exitCode(code), 42, ['expected 42', code])
|
|
86
87
|
},
|
|
87
88
|
nestedHelp: () => {
|
|
88
89
|
/** @type {Commands<NodeOp>} */
|
|
89
90
|
const inner = [{
|
|
90
91
|
names: ['ping'],
|
|
91
92
|
description: 'Inner ping',
|
|
92
|
-
handler: () =>
|
|
93
|
+
handler: () => pureOk(0),
|
|
93
94
|
}]
|
|
94
95
|
/** @type {Commands<NodeOp>} */
|
|
95
96
|
const outer = [{
|
|
@@ -98,17 +99,17 @@ export const proof = {
|
|
|
98
99
|
handler: inner,
|
|
99
100
|
}]
|
|
100
101
|
const [state, code] = run(outer)(['sub', 'help'])
|
|
101
|
-
assertEq(code, 0, ['expected exit 0', code])
|
|
102
|
+
assertEq(exitCode(code), 0, ['expected exit 0', code])
|
|
102
103
|
assert(state.stdout.includes('ping'), 'expected inner command in help')
|
|
103
104
|
},
|
|
104
105
|
prototypeNameIsUnknownCommand: () => {
|
|
105
106
|
const [state, code] = run(echoCommands)(['toString'])
|
|
106
|
-
assertEq(code, 1, ['expected exit 1 for prototype-name command', code])
|
|
107
|
+
assertEq(exitCode(code), 1, ['expected exit 1 for prototype-name command', code])
|
|
107
108
|
assert(state.stderr.includes('unknown command'), 'expected unknown-command error in stderr')
|
|
108
109
|
},
|
|
109
110
|
helpPrototypeSafe: () => {
|
|
110
111
|
const [state, code] = run(echoCommands)(['help', 'toString'])
|
|
111
|
-
assertEq(code, 0, ['expected exit 0, not a throw', code])
|
|
112
|
+
assertEq(exitCode(code), 0, ['expected exit 0, not a throw', code])
|
|
112
113
|
assert(state.stdout.includes('echo'), 'expected top-level help for unknown target')
|
|
113
114
|
},
|
|
114
115
|
helpWithTarget: () => {
|
|
@@ -116,7 +117,7 @@ export const proof = {
|
|
|
116
117
|
const inner = [{
|
|
117
118
|
names: ['ping'],
|
|
118
119
|
description: 'Inner ping',
|
|
119
|
-
handler: () =>
|
|
120
|
+
handler: () => pureOk(0),
|
|
120
121
|
}]
|
|
121
122
|
/** @type {Commands<NodeOp>} */
|
|
122
123
|
const outer = [{
|
|
@@ -125,7 +126,7 @@ export const proof = {
|
|
|
125
126
|
handler: inner,
|
|
126
127
|
}]
|
|
127
128
|
const [state, code] = run(outer)(['help', 'sub'])
|
|
128
|
-
assertEq(code, 0, ['expected exit 0', code])
|
|
129
|
+
assertEq(exitCode(code), 0, ['expected exit 0', code])
|
|
129
130
|
assert(state.stdout.includes('ping'), 'expected inner command in help')
|
|
130
131
|
assert(!(state.stdout.includes('Subcommand group')), 'expected inner help, not outer')
|
|
131
132
|
},
|
package/fjs/cli/types.d.ts
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import type { NodeOp,
|
|
7
|
-
|
|
8
|
-
type Handler<O extends NodeOp> = (options: NodeProgramOptions) => Effect<O, number>;
|
|
6
|
+
import type { NodeOp, Program } from '../effects/node/types.ts';
|
|
7
|
+
type Handler<O extends NodeOp> = Program<O>;
|
|
9
8
|
export type Command<O extends NodeOp> = {
|
|
10
9
|
readonly names: readonly string[];
|
|
11
10
|
readonly description: string;
|
|
@@ -65,7 +65,7 @@ export type Monoid<T> = {
|
|
|
65
65
|
* has `null`, meaning "longer than `maxLength`".
|
|
66
66
|
*
|
|
67
67
|
* The monoid is carried as a field rather than intersected in, so it stays
|
|
68
|
-
* independently constructed and consumed (`AGENTS.md` §
|
|
68
|
+
* independently constructed and consumed (`fjs/AGENTS.md` §3.2).
|
|
69
69
|
*/
|
|
70
70
|
export type Absorbing<T> = {
|
|
71
71
|
readonly monoid: Monoid<T>;
|
|
@@ -44,8 +44,8 @@ const iPad = vec8(0x36n)
|
|
|
44
44
|
* that takes a message and computes the HMAC.
|
|
45
45
|
*/
|
|
46
46
|
export const hmac = hashFunc => {
|
|
47
|
-
const { blockLength } = hashFunc
|
|
48
|
-
const p = repeat(
|
|
47
|
+
const { blockLength, blockBytes } = hashFunc
|
|
48
|
+
const p = repeat(blockBytes)
|
|
49
49
|
const ip = p(iPad)
|
|
50
50
|
const op = p(oPad)
|
|
51
51
|
const c = computeSync(hashFunc)
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @import { Base, Sha2, State, V16, V8 } from './types.ts'
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { mask } from '../../types/bigint/module.f.mjs'
|
|
14
|
+
import { divUp8, mask } from '../../types/bigint/module.f.mjs'
|
|
15
15
|
import {
|
|
16
16
|
vec,
|
|
17
17
|
length,
|
|
@@ -257,6 +257,8 @@ const base = ({ logBitLen, k, bs0, bs1, ss0, ss1 }) => {
|
|
|
257
257
|
const sha2 = ({ append, end, chunkLength }, hash, hashLength) => ({
|
|
258
258
|
hashLength,
|
|
259
259
|
blockLength: chunkLength,
|
|
260
|
+
hashBytes: divUp8(hashLength),
|
|
261
|
+
blockBytes: divUp8(chunkLength),
|
|
260
262
|
init: {
|
|
261
263
|
hash,
|
|
262
264
|
len: 0n,
|
|
@@ -9,6 +9,19 @@ import { assertEq } from '../../asserts/module.f.mjs'
|
|
|
9
9
|
import { map } from '../../types/list/module.f.mjs'
|
|
10
10
|
import { base32, base64, computeSync, sha224, sha256, sha384, sha512, sha512x224, sha512x256 } from './module.f.mjs'
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Every SHA-2 length is a whole number of bytes, so the rounded-up byte count
|
|
14
|
+
* and the exact division agree — this pins both that identity and the values.
|
|
15
|
+
*
|
|
16
|
+
* @type {(sha2: Sha2) => (hashBytes: bigint, blockBytes: bigint) => void}
|
|
17
|
+
*/
|
|
18
|
+
const checkBytes = ({ hashLength, blockLength, hashBytes, blockBytes }) => (h, b) => {
|
|
19
|
+
assertEq(hashBytes, h)
|
|
20
|
+
assertEq(blockBytes, b)
|
|
21
|
+
assertEq(hashBytes, hashLength >> 3n)
|
|
22
|
+
assertEq(blockBytes, blockLength >> 3n)
|
|
23
|
+
}
|
|
24
|
+
|
|
12
25
|
/** @type {(sha2: Sha2) => (x: bigint) => void} */
|
|
13
26
|
const checkEmpty = ({ init, end, hashLength }) => x => {
|
|
14
27
|
const result = end(init)
|
|
@@ -71,6 +84,17 @@ export const proof = {
|
|
|
71
84
|
sha512x256: () => checkEmpty(sha512x256)(0xc672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967an),
|
|
72
85
|
sha512x224: () => checkEmpty(sha512x224)(0x6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4n),
|
|
73
86
|
},
|
|
87
|
+
// The byte counts consumers read instead of converting bit lengths
|
|
88
|
+
// themselves. Asserted against the bit length each is derived from, not
|
|
89
|
+
// against a hand-written number, so the pairing is what is pinned.
|
|
90
|
+
byteLengths: [
|
|
91
|
+
() => checkBytes(sha224)(28n, 64n),
|
|
92
|
+
() => checkBytes(sha256)(32n, 64n),
|
|
93
|
+
() => checkBytes(sha384)(48n, 128n),
|
|
94
|
+
() => checkBytes(sha512)(64n, 128n),
|
|
95
|
+
() => checkBytes(sha512x224)(28n, 128n),
|
|
96
|
+
() => checkBytes(sha512x256)(32n, 128n),
|
|
97
|
+
],
|
|
74
98
|
utf8: [
|
|
75
99
|
() => {
|
|
76
100
|
const e = 0x730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525n
|
|
@@ -51,6 +51,17 @@ export type Base = {
|
|
|
51
51
|
export type Sha2 = {
|
|
52
52
|
readonly hashLength: bigint;
|
|
53
53
|
readonly blockLength: bigint;
|
|
54
|
+
/**
|
|
55
|
+
* `hashLength` and `blockLength` in whole bytes, rounded up. Consumers
|
|
56
|
+
* that size a byte buffer read these instead of converting: `hmac` and
|
|
57
|
+
* `sign` each used to do it themselves, with two different spellings
|
|
58
|
+
* (`>> 3n` and `divUp8`), leaving a reader to work out per site whether
|
|
59
|
+
* the two roundings agree. They do for every SHA-2 variant, whose lengths
|
|
60
|
+
* are byte multiples — which is exactly why the decision belongs here
|
|
61
|
+
* once rather than at each call site.
|
|
62
|
+
*/
|
|
63
|
+
readonly hashBytes: bigint;
|
|
64
|
+
readonly blockBytes: bigint;
|
|
54
65
|
readonly init: State;
|
|
55
66
|
readonly append: Fold<Vec, State>;
|
|
56
67
|
readonly end: (state: State) => Vec;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { assertNotNullish } from '../../asserts/module.f.mjs'
|
|
15
|
-
import { bitLength,
|
|
15
|
+
import { bitLength, roundUp8 } from '../../types/bigint/module.f.mjs'
|
|
16
16
|
import { empty, length, msb, repeat, unpack, vec, vec8 } from '../../types/bit_vec/module.f.mjs'
|
|
17
17
|
import { hmac } from '../hmac/module.f.mjs'
|
|
18
18
|
import { computeSync } from '../sha2/module.f.mjs'
|
|
@@ -75,7 +75,7 @@ export const computeK =
|
|
|
75
75
|
// step and all subsequent steps, we use the same H function as the
|
|
76
76
|
// one used in step 'a' to process the input message; this choice
|
|
77
77
|
// will be discussed in more detail in Section 3.6.
|
|
78
|
-
const rep = repeat(
|
|
78
|
+
const rep = repeat(hf.hashBytes)
|
|
79
79
|
const v0 = rep(x01)
|
|
80
80
|
// c. Set:
|
|
81
81
|
// K = 0x00 0x00 0x00 ... 0x00
|