functionalscript 0.19.0 → 0.21.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/fs/asn.1/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/asn.1/{test.f.js → proof.f.js} +1 -1
- package/fs/asserts/module.f.d.ts +4 -0
- package/fs/asserts/module.f.js +6 -0
- package/fs/base128/proof.f.d.ts +1 -0
- package/fs/base128/{test.f.js → proof.f.js} +1 -1
- package/fs/bnf/data/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/bnf/data/{test.f.js → proof.f.js} +1 -1
- package/fs/bnf/proof.f.d.ts +3 -0
- package/fs/bnf/{test.f.js → proof.f.js} +1 -1
- package/fs/cas/module.f.js +9 -23
- package/fs/cas/proof.f.d.ts +4 -0
- package/fs/cas/proof.f.js +37 -0
- package/fs/cbase32/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/cbase32/{test.f.js → proof.f.js} +1 -1
- package/fs/ci/bun/module.f.js +2 -7
- package/fs/ci/common/module.f.d.ts +2 -1
- package/fs/ci/common/module.f.js +7 -9
- package/fs/ci/config/module.f.d.ts +12 -3
- package/fs/ci/config/module.f.js +24 -4
- package/fs/ci/deno/module.f.js +2 -5
- package/fs/ci/node/module.f.js +14 -9
- package/fs/ci/playwright/module.f.js +5 -8
- package/fs/ci/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/ci/{test.f.js → proof.f.js} +2 -2
- package/fs/ci/rust/module.f.js +3 -9
- package/fs/crypto/hmac/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/crypto/hmac/{test.f.js → proof.f.js} +1 -1
- package/fs/crypto/secp/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/crypto/secp/{test.f.js → proof.f.js} +1 -1
- package/fs/crypto/sha2/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/crypto/sha2/{test.f.js → proof.f.js} +1 -1
- package/fs/crypto/sign/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/crypto/sign/{test.f.js → proof.f.js} +1 -1
- package/fs/dev/module.f.d.ts +28 -5
- package/fs/dev/module.f.js +38 -28
- package/fs/dev/{test.f.d.ts → proof.f.d.ts} +5 -2
- package/fs/dev/{test.f.js → proof.f.js} +26 -2
- package/fs/dev/version/proof.f.d.ts +3 -0
- package/fs/dev/version/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/ast/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/ast/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/parser/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/parser/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/serializer/module.f.d.ts +2 -2
- package/fs/djs/serializer/module.f.js +47 -79
- package/fs/djs/serializer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/serializer/{test.f.js → proof.f.js} +8 -8
- package/fs/djs/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/tokenizer/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/tokenizer-new/module.f.js +1 -1
- package/fs/djs/tokenizer-new/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/tokenizer-new/{test.f.js → proof.f.js} +1 -1
- package/fs/djs/transpiler/module.f.d.ts +15 -0
- package/fs/djs/transpiler/module.f.js +10 -2
- package/fs/djs/transpiler/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/djs/transpiler/{test.f.js → proof.f.js} +1 -1
- package/fs/{dev/tf → emergent-testing}/module.f.d.ts +66 -8
- package/fs/{dev/tf → emergent-testing}/module.f.js +101 -34
- package/fs/{dev/tf → emergent-testing}/module.js +2 -2
- package/fs/{dev/tf/test.f.d.ts → emergent-testing/proof.f.d.ts} +28 -0
- package/fs/{dev/tf/test.f.js → emergent-testing/proof.f.js} +119 -40
- package/fs/emergent-testing/scenarios/async-subtests.fail.d.ts +6 -0
- package/fs/emergent-testing/scenarios/async-subtests.fail.js +9 -0
- package/fs/emergent-testing/scenarios/async-subtests.pass.d.ts +6 -0
- package/fs/emergent-testing/scenarios/async-subtests.pass.js +9 -0
- package/fs/emergent-testing/scenarios/async.fail.d.ts +3 -0
- package/fs/emergent-testing/scenarios/async.fail.js +6 -0
- package/fs/emergent-testing/scenarios/async.pass.d.ts +3 -0
- package/fs/emergent-testing/scenarios/async.pass.js +5 -0
- package/fs/emergent-testing/scenarios/fail.fail.d.ts +3 -0
- package/fs/emergent-testing/scenarios/fail.fail.js +3 -0
- package/fs/emergent-testing/scenarios/return-value.pass.d.ts +3 -0
- package/fs/emergent-testing/scenarios/return-value.pass.js +4 -0
- package/fs/emergent-testing/scenarios/thenable.pass.d.ts +5 -0
- package/fs/emergent-testing/scenarios/thenable.pass.js +11 -0
- package/fs/emergent-testing/scenarios/thenable2.pass.d.ts +5 -0
- package/fs/emergent-testing/scenarios/thenable2.pass.js +3 -0
- package/fs/emergent-testing/scenarios/throw.pass.d.ts +5 -0
- package/fs/{dev/tf/scenarios/throw.pass.f.js → emergent-testing/scenarios/throw.pass.js} +1 -1
- package/fs/fjs/module.f.js +4 -5
- package/fs/fsc/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/fsc/{test.f.js → proof.f.js} +1 -1
- package/fs/fsm/proof.f.d.ts +4 -0
- package/fs/fsm/{test.f.js → proof.f.js} +1 -1
- package/fs/html/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/html/{test.f.js → proof.f.js} +1 -1
- package/fs/io/module.d.ts +1 -1
- package/fs/io/module.f.d.ts +3 -2
- package/fs/io/module.f.js +4 -3
- package/fs/io/module.js +19 -11
- package/fs/js/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/js/tokenizer/{test.f.js → proof.f.js} +1 -1
- package/fs/json/parser/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/json/parser/{test.f.js → proof.f.js} +1 -1
- package/fs/json/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/json/{test.f.js → proof.f.js} +1 -1
- package/fs/json/serializer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/json/serializer/{test.f.js → proof.f.js} +1 -1
- package/fs/json/tokenizer/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/json/tokenizer/{test.f.js → proof.f.js} +1 -1
- package/fs/path/proof.f.d.ts +5 -0
- package/fs/path/{test.f.js → proof.f.js} +4 -3
- package/fs/sul/id/module.f.js +1 -1
- package/fs/sul/id/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/sul/id/{test.f.js → proof.f.js} +2 -2
- package/fs/sul/level/hash/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/sul/level/hash/{test.f.js → proof.f.js} +2 -2
- package/fs/sul/level/literal/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/sul/level/literal/{test.f.js → proof.f.js} +1 -1
- package/fs/sul/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/sul/{test.f.js → proof.f.js} +2 -2
- package/fs/text/ascii/proof.f.d.ts +3 -0
- package/fs/text/ascii/{test.f.js → proof.f.js} +1 -1
- package/fs/text/code_point/module.f.d.ts +28 -0
- package/fs/text/code_point/module.f.js +31 -0
- package/fs/text/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/text/{test.f.js → proof.f.js} +1 -1
- package/fs/text/sgr/proof.f.d.ts +1 -0
- package/fs/text/sgr/{test.f.js → proof.f.js} +1 -1
- package/fs/text/utf16/module.f.js +3 -53
- package/fs/text/utf16/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/text/utf16/{test.f.js → proof.f.js} +1 -1
- package/fs/text/utf8/module.f.js +3 -25
- package/fs/text/utf8/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/text/utf8/{test.f.js → proof.f.js} +1 -1
- package/fs/types/array/module.f.js +2 -5
- package/fs/types/array/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/array/{test.f.js → proof.f.js} +1 -1
- package/fs/types/bigfloat/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/bigfloat/{test.f.js → proof.f.js} +1 -1
- package/fs/types/bigint/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/bigint/{test.f.js → proof.f.js} +1 -1
- package/fs/types/bit_vec/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/bit_vec/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/find/proof.f.d.ts +1 -0
- package/fs/types/btree/find/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/btree/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/remove/proof.f.d.ts +4 -0
- package/fs/types/btree/remove/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/set/proof.f.d.ts +1 -0
- package/fs/types/btree/set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/btree/types/module.f.d.ts +8 -0
- package/fs/types/btree/types/module.f.js +8 -0
- package/fs/types/byte_set/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/byte_set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/effects/module.f.d.ts +17 -0
- package/fs/types/effects/module.f.js +17 -0
- package/fs/types/effects/node/module.f.d.ts +60 -5
- package/fs/types/effects/node/module.f.js +12 -1
- package/fs/types/effects/node/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/effects/node/{test.f.js → proof.f.js} +1 -1
- package/fs/types/effects/node/virtual/module.f.js +2 -1
- package/fs/types/effects/proof.f.d.ts +11 -0
- package/fs/types/effects/proof.f.js +57 -0
- package/fs/types/function/compare/proof.f.d.ts +1 -0
- package/fs/types/function/compare/{test.f.js → proof.f.js} +1 -1
- package/fs/types/function/operator/proof.f.d.ts +12 -0
- package/fs/types/function/operator/{test.f.js → proof.f.js} +11 -10
- package/fs/types/function/proof.f.d.ts +1 -0
- package/fs/types/function/{test.f.js → proof.f.js} +1 -1
- package/fs/types/list/{test.f.d.ts → proof.f.d.ts} +2 -2
- package/fs/types/list/{test.f.js → proof.f.js} +15 -1
- package/fs/types/map/proof.f.d.ts +4 -0
- package/fs/types/map/{test.f.js → proof.f.js} +1 -1
- package/fs/types/monoid/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/monoid/{test.f.js → proof.f.js} +1 -1
- package/fs/types/nibble_set/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/nibble_set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/nominal/proof.f.d.ts +4 -0
- package/fs/types/nominal/{test.f.js → proof.f.js} +1 -1
- package/fs/types/nullable/module.f.d.ts +7 -0
- package/fs/types/nullable/module.f.js +7 -0
- package/fs/types/nullable/proof.f.d.ts +1 -0
- package/fs/types/nullable/{test.f.js → proof.f.js} +20 -3
- package/fs/types/number/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/number/{test.f.js → proof.f.js} +1 -1
- package/fs/types/object/module.f.js +2 -4
- package/fs/types/object/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/object/{test.f.js → proof.f.js} +1 -1
- package/fs/types/ordered_map/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/ordered_map/{test.f.js → proof.f.js} +1 -1
- package/fs/types/patricia_trie/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/patricia_trie/{test.f.js → proof.f.js} +2 -2
- package/fs/types/prime_field/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/prime_field/{test.f.js → proof.f.js} +1 -1
- package/fs/types/range/proof.f.d.ts +1 -0
- package/fs/types/range/{test.f.js → proof.f.js} +1 -1
- package/fs/types/range_map/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/range_map/{test.f.js → proof.f.js} +1 -1
- package/fs/types/result/proof.f.d.ts +5 -0
- package/fs/types/result/{test.f.js → proof.f.js} +18 -2
- package/fs/types/rtti/parse/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/rtti/parse/{test.f.js → proof.f.js} +1 -1
- package/fs/types/rtti/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/rtti/{test.f.js → proof.f.js} +1 -1
- package/fs/types/rtti/ts/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/rtti/ts/{test.f.js → proof.f.js} +1 -1
- package/fs/types/rtti/validate/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/rtti/validate/{test.f.js → proof.f.js} +1 -1
- package/fs/types/sorted_list/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/sorted_list/{test.f.js → proof.f.js} +1 -1
- package/fs/types/sorted_set/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/sorted_set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/string/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/string/{test.f.js → proof.f.js} +1 -1
- package/fs/types/string_set/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/string_set/{test.f.js → proof.f.js} +1 -1
- package/fs/types/ts/module.f.d.ts +0 -1
- package/fs/types/ts/{test.f.d.ts → proof.f.d.ts} +20 -0
- package/fs/types/ts/{test.f.js → proof.f.js} +1 -0
- package/fs/types/uint8array/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/fs/types/uint8array/{test.f.js → proof.f.js} +1 -1
- package/fs/website/proof.f.d.ts +3 -0
- package/fs/website/proof.f.js +9 -0
- package/issues/demo/sample/{test.f.js → proof.f.js} +1 -1
- package/issues/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/issues/{test.f.js → proof.f.js} +1 -1
- package/nanvm-lib/tests/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/nanvm-lib/tests/{test.f.js → proof.f.js} +1 -1
- package/nanvm-lib/tests/vm/{test.f.d.ts → proof.f.d.ts} +1 -2
- package/nanvm-lib/tests/vm/{test.f.js → proof.f.js} +1 -1
- package/package.json +2 -2
- package/fs/base128/test.f.d.ts +0 -2
- package/fs/bnf/test.f.d.ts +0 -4
- package/fs/cas/test.f.d.ts +0 -2
- package/fs/cas/test.f.js +0 -1
- package/fs/dev/tf/scenarios/fail.fail.f.d.ts +0 -1
- package/fs/dev/tf/scenarios/fail.fail.f.js +0 -1
- package/fs/dev/tf/scenarios/return-value.pass.f.d.ts +0 -1
- package/fs/dev/tf/scenarios/return-value.pass.f.js +0 -2
- package/fs/dev/tf/scenarios/throw.pass.f.d.ts +0 -6
- package/fs/dev/version/test.f.d.ts +0 -4
- package/fs/fsm/test.f.d.ts +0 -5
- package/fs/path/test.f.d.ts +0 -3
- package/fs/text/ascii/test.f.d.ts +0 -4
- package/fs/text/sgr/test.f.d.ts +0 -2
- package/fs/types/btree/find/test.f.d.ts +0 -2
- package/fs/types/btree/remove/test.f.d.ts +0 -5
- package/fs/types/btree/set/test.f.d.ts +0 -2
- package/fs/types/function/compare/test.f.d.ts +0 -2
- package/fs/types/function/operator/test.f.d.ts +0 -10
- package/fs/types/function/test.f.d.ts +0 -2
- package/fs/types/map/test.f.d.ts +0 -5
- package/fs/types/nominal/test.f.d.ts +0 -5
- package/fs/types/nullable/test.f.d.ts +0 -2
- package/fs/types/range/test.f.d.ts +0 -2
- package/fs/types/result/test.f.d.ts +0 -2
- /package/fs/{dev/tf → emergent-testing}/all.test.d.ts +0 -0
- /package/fs/{dev/tf → emergent-testing}/all.test.js +0 -0
- /package/fs/{dev/tf → emergent-testing}/module.d.ts +0 -0
- /package/fs/{dev/tf → emergent-testing}/scenarios/all.d.ts +0 -0
- /package/fs/{dev/tf → emergent-testing}/scenarios/all.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const proof: (() => void)[];
|
|
@@ -12,4 +12,12 @@ export type TNode<T> = Leaf1<T> | Leaf2<T> | Branch3<T> | Branch5<T>;
|
|
|
12
12
|
export type Tree<T> = TNode<T> | null;
|
|
13
13
|
export type Branch1<T> = readonly [TNode<T>];
|
|
14
14
|
export type Branch7<T> = readonly [...Branch5<T>, T, TNode<T>];
|
|
15
|
+
/**
|
|
16
|
+
* Demotes a single-child branch root to its only child.
|
|
17
|
+
*
|
|
18
|
+
* After an insert or remove the root may temporarily hold exactly one child
|
|
19
|
+
* (a `Branch1`). In that case the tree is one level taller than necessary;
|
|
20
|
+
* returning the child directly restores the correct height. If the root has
|
|
21
|
+
* more than one child it is returned unchanged.
|
|
22
|
+
*/
|
|
15
23
|
export declare const collapseRoot: <T>(b: Branch1<T> | Branch3<T> | Branch5<T>) => TNode<T>;
|
|
@@ -1 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Demotes a single-child branch root to its only child.
|
|
3
|
+
*
|
|
4
|
+
* After an insert or remove the root may temporarily hold exactly one child
|
|
5
|
+
* (a `Branch1`). In that case the tree is one level taller than necessary;
|
|
6
|
+
* returning the child directly restores the correct height. If the root has
|
|
7
|
+
* more than one child it is returned unchanged.
|
|
8
|
+
*/
|
|
1
9
|
export const collapseRoot = b => b.length === 1 ? b[0] : b;
|
|
@@ -3,7 +3,7 @@ import { every, countdown, map, toArray } from "../list/module.f.js";
|
|
|
3
3
|
import { stringify as jsonStringify } from "../../json/module.f.js";
|
|
4
4
|
import { sort } from "../object/module.f.js";
|
|
5
5
|
const stringify = jsonStringify(sort);
|
|
6
|
-
export
|
|
6
|
+
export const proof = {
|
|
7
7
|
has: [
|
|
8
8
|
() => {
|
|
9
9
|
if (has(0)(empty)) {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
import { type List } from '../list/module.f.ts';
|
|
6
7
|
export type Operation = readonly [string, (..._: readonly never[]) => unknown];
|
|
7
8
|
export type Effect<O extends Operation, T> = {
|
|
8
9
|
value: Value<O, T>;
|
|
@@ -20,6 +21,22 @@ export type Param<O extends Operation> = F<O>[0];
|
|
|
20
21
|
export type Return<O extends Operation> = F<O>[1];
|
|
21
22
|
export declare const do_: <O extends Operation>(cmd: O[0]) => (...param: Param<O>) => Effect<O, Return<O>>;
|
|
22
23
|
export declare const begin: Effect<never, void>;
|
|
24
|
+
/**
|
|
25
|
+
* Sequentially threads a state value through an effect for each item in `items`.
|
|
26
|
+
*
|
|
27
|
+
* Given `f: item => state => Effect<O, state>`, `init: S`, and `items: [x₀, x₁, …]`,
|
|
28
|
+
* builds `f(x₀)(init).step(f(x₁)).step(f(x₂)).…` and yields a single
|
|
29
|
+
* `Effect<O, S>` that produces the final state.
|
|
30
|
+
*
|
|
31
|
+
* Sequential — each step depends on the previous state. Compare to `all`,
|
|
32
|
+
* which fans out independent effects.
|
|
33
|
+
*/
|
|
34
|
+
export declare const foldStep: <O extends Operation, T, S>(f: (item: T) => (state: S) => Effect<O, S>) => (init: S) => (items: List<T>) => Effect<O, S>;
|
|
35
|
+
/**
|
|
36
|
+
* Sequentially runs `f(item)` for each item in `items`, discarding intermediate
|
|
37
|
+
* results. The `void` accumulator sibling of `foldStep`.
|
|
38
|
+
*/
|
|
39
|
+
export declare const forEachStep: <O extends Operation, T>(f: (item: T) => Effect<O, void>) => (items: List<T>) => Effect<O, void>;
|
|
23
40
|
export type ToAsyncOperationMap<O extends Operation> = {
|
|
24
41
|
readonly [K in O[0]]: (...payload: Pr<O, K>[0]) => Promise<Pr<O, K>[1]>;
|
|
25
42
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
import { fold } from "../list/module.f.js";
|
|
6
7
|
export const pure = (v) => ({
|
|
7
8
|
value: [v],
|
|
8
9
|
step: f => f(v)
|
|
@@ -13,3 +14,19 @@ export const doFull = (cmd, param, cont) => ({
|
|
|
13
14
|
});
|
|
14
15
|
export const do_ = (cmd) => (...param) => doFull(cmd, param, pure);
|
|
15
16
|
export const begin = pure(undefined);
|
|
17
|
+
/**
|
|
18
|
+
* Sequentially threads a state value through an effect for each item in `items`.
|
|
19
|
+
*
|
|
20
|
+
* Given `f: item => state => Effect<O, state>`, `init: S`, and `items: [x₀, x₁, …]`,
|
|
21
|
+
* builds `f(x₀)(init).step(f(x₁)).step(f(x₂)).…` and yields a single
|
|
22
|
+
* `Effect<O, S>` that produces the final state.
|
|
23
|
+
*
|
|
24
|
+
* Sequential — each step depends on the previous state. Compare to `all`,
|
|
25
|
+
* which fans out independent effects.
|
|
26
|
+
*/
|
|
27
|
+
export const foldStep = (f) => (init) => (items) => fold(item => acc => acc.step(f(item)))(pure(init))(items);
|
|
28
|
+
/**
|
|
29
|
+
* Sequentially runs `f(item)` for each item in `items`, discarding intermediate
|
|
30
|
+
* results. The `void` accumulator sibling of `foldStep`.
|
|
31
|
+
*/
|
|
32
|
+
export const forEachStep = (f) => (items) => foldStep((item) => () => f(item))(undefined)(items);
|
|
@@ -77,8 +77,15 @@ export type Module = {
|
|
|
77
77
|
};
|
|
78
78
|
export type Import = ['import', (path: string) => IoResult<Module>];
|
|
79
79
|
export declare const import_: Func<Import>;
|
|
80
|
+
/** Named output streams accepted by the `Write` effect. */
|
|
80
81
|
export type WriteConsoles = 'stdout' | 'stderr';
|
|
82
|
+
/**
|
|
83
|
+
* Raw byte write to a named output stream. Encoding-agnostic — callers supply
|
|
84
|
+
* a `Vec`. The Node runner maps each stream name to the appropriate fd and
|
|
85
|
+
* delegates to the OS via `stream.write()` with backpressure handling.
|
|
86
|
+
*/
|
|
81
87
|
export type Write = readonly ['write', (stream: WriteConsoles, data: Vec) => void];
|
|
88
|
+
/** Emits a `Write` effect to the given named stream. */
|
|
82
89
|
export declare const write: Func<Write>;
|
|
83
90
|
export type Console = (s: string) => Effect<Write, void>;
|
|
84
91
|
/** Writes a line to `stdout`. Replaces the retired `Log` effect. */
|
|
@@ -87,12 +94,19 @@ export declare const log: Console;
|
|
|
87
94
|
export declare const error: Console;
|
|
88
95
|
export type Now = readonly ['now', () => number];
|
|
89
96
|
export declare const now: Func<Now>;
|
|
97
|
+
/**
|
|
98
|
+
* The outcome of a `Sandbox` operation.
|
|
99
|
+
*
|
|
100
|
+
* `result` carries either `['ok', value]` or `['error', thrown]`. `duration`
|
|
101
|
+
* is a floating-point millisecond count with up to microsecond precision,
|
|
102
|
+
* matching `performance.now()` directly. Additional fields (allocated memory,
|
|
103
|
+
* max stack depth, coverage) may be added in future without breaking consumers.
|
|
104
|
+
*/
|
|
90
105
|
export type SandboxResult<T> = {
|
|
91
106
|
readonly result: Result<T, unknown>;
|
|
92
107
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* with up to microsecond precision.
|
|
108
|
+
* Elapsed time in milliseconds (microsecond precision via `performance.now()`).
|
|
109
|
+
* The virtual runner returns `0` for deterministic tests.
|
|
96
110
|
*/
|
|
97
111
|
readonly duration: number;
|
|
98
112
|
};
|
|
@@ -116,16 +130,43 @@ export type Sandbox = readonly ['sandbox', <T>(f: () => T) => SandboxResult<T>];
|
|
|
116
130
|
* @see {@link SandboxResult}
|
|
117
131
|
*/
|
|
118
132
|
export declare const sandbox: Func<Sandbox>;
|
|
133
|
+
/**
|
|
134
|
+
* Resolves the return value of a test function inside the effect runner.
|
|
135
|
+
* If `p` is a real `Promise`, it is awaited and rejections propagate as
|
|
136
|
+
* throws. If `p` is any other value it is returned as-is. Plain thenables
|
|
137
|
+
* (objects with a `.then` method that are not `instanceof Promise`) are
|
|
138
|
+
* treated as ordinary values — not awaited. See `fs/dev/tf/README.md`.
|
|
139
|
+
*/
|
|
140
|
+
export type Await = readonly ['await', (p: unknown) => readonly [unknown]];
|
|
141
|
+
export declare const awaitIfPromise: (p: unknown) => Effect<Await, unknown>;
|
|
142
|
+
/**
|
|
143
|
+
* Signature of a framework test-registration function (e.g. `nodeTest.test`,
|
|
144
|
+
* `bunTest.test`, `pwTest`). Returns `Promise<void>` so async sub-tests can
|
|
145
|
+
* be awaited.
|
|
146
|
+
*/
|
|
119
147
|
export type TestFn = (name: string, options: {
|
|
120
148
|
readonly expectFailure: boolean;
|
|
121
149
|
}, fn: (t: TestContext) => Promise<void>) => Promise<void>;
|
|
150
|
+
/**
|
|
151
|
+
* A thin wrapper around a framework's `test` function. Passed through
|
|
152
|
+
* `registerModule` so nested test registration uses the appropriate context
|
|
153
|
+
* (e.g. `inlineContext` on Bun and Playwright, which do not support nested
|
|
154
|
+
* `test()` calls inside a callback).
|
|
155
|
+
*/
|
|
122
156
|
export type TestContext = {
|
|
123
157
|
readonly test: TestFn;
|
|
124
158
|
};
|
|
125
|
-
|
|
159
|
+
/** Effect operation that registers a named test with the active `TestContext`. */
|
|
160
|
+
export type Test = readonly ['test', (ctx: TestContext, name: string, expectFailure: boolean, test: (t: TestContext) => Effect<Test | All | Await, void>) => void];
|
|
126
161
|
export declare const test: Func<Test>;
|
|
127
|
-
export type NodeOp = All | Fetch | Fs | Http | Forever | Import | Now | Sandbox | Write | Test;
|
|
162
|
+
export type NodeOp = All | Await | Fetch | Fs | Http | Forever | Import | Now | Sandbox | Write | Test;
|
|
128
163
|
export type NodeEffect<T> = Effect<NodeOp, T>;
|
|
164
|
+
/**
|
|
165
|
+
* Writes an error line to `stderr` and yields exit code `1`. The canonical
|
|
166
|
+
* "fail with a message" program for a `NodeProgram`. For non-`1` exit codes,
|
|
167
|
+
* compose `error(s).step(() => pure(n))` directly.
|
|
168
|
+
*/
|
|
169
|
+
export declare const errorExit: (s: string) => Effect<NodeOp, number>;
|
|
129
170
|
export type NodeOperationMap = ToAsyncOperationMap<NodeOp>;
|
|
130
171
|
/**
|
|
131
172
|
* The environment variables.
|
|
@@ -133,7 +174,21 @@ export type NodeOperationMap = ToAsyncOperationMap<NodeOp>;
|
|
|
133
174
|
export type Env = {
|
|
134
175
|
readonly [k: string]: string | undefined;
|
|
135
176
|
};
|
|
177
|
+
/** Identifies the JavaScript runtime detected at startup. */
|
|
136
178
|
export type Engine = 'node' | 'bun' | 'playwright';
|
|
179
|
+
/**
|
|
180
|
+
* Runtime options passed to every `NodeProgram`.
|
|
181
|
+
*
|
|
182
|
+
* - `args`: command-line arguments (equivalent to `process.argv.slice(2)`).
|
|
183
|
+
* - `env`: process environment variables.
|
|
184
|
+
* - `std`: TTY flags for `stdout` and `stderr`, known at startup and used by
|
|
185
|
+
* `csiWrite` to decide whether to strip ANSI SGR sequences.
|
|
186
|
+
* - `testContext`: Node `--test` context; used by `register` on Node.
|
|
187
|
+
* - `bunTestContext`: Bun-compatible context that flattens nested tests inline,
|
|
188
|
+
* working around Bun's lack of nested `test()` support.
|
|
189
|
+
* - `playwrightTestContext`: Playwright context using the same inline strategy.
|
|
190
|
+
* - `engine`: runtime detected at startup; controls which context `register` selects.
|
|
191
|
+
*/
|
|
137
192
|
export type NodeProgramOptions = {
|
|
138
193
|
readonly args: readonly string[];
|
|
139
194
|
readonly env: Env;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import { utf8 } from "../../../text/module.f.js";
|
|
11
|
-
import { do_ } from "../module.f.js";
|
|
11
|
+
import { begin, do_, pure } from "../module.f.js";
|
|
12
12
|
const doAll = do_('all');
|
|
13
13
|
/**
|
|
14
14
|
* To run the operation `O` should be known by the runner/engine.
|
|
@@ -31,6 +31,7 @@ export const createServer = do_('createServer');
|
|
|
31
31
|
export const listen = do_('listen');
|
|
32
32
|
export const forever = do_('forever');
|
|
33
33
|
export const import_ = do_('import');
|
|
34
|
+
/** Emits a `Write` effect to the given named stream. */
|
|
34
35
|
export const write = do_('write');
|
|
35
36
|
/**
|
|
36
37
|
* Encodes `s + '\n'` as UTF-8 and emits a `Write` effect to `stream`.
|
|
@@ -61,4 +62,14 @@ export const now = do_('now');
|
|
|
61
62
|
* @see {@link SandboxResult}
|
|
62
63
|
*/
|
|
63
64
|
export const sandbox = do_('sandbox');
|
|
65
|
+
const awaitPromise = do_('await');
|
|
66
|
+
export const awaitIfPromise = (p) => awaitPromise(p).step(([x]) => pure(x));
|
|
64
67
|
export const test = do_('test');
|
|
68
|
+
/**
|
|
69
|
+
* Writes an error line to `stderr` and yields exit code `1`. The canonical
|
|
70
|
+
* "fail with a message" program for a `NodeProgram`. For non-`1` exit codes,
|
|
71
|
+
* compose `error(s).step(() => pure(n))` directly.
|
|
72
|
+
*/
|
|
73
|
+
export const errorExit = (s) => begin
|
|
74
|
+
.step(() => error(s))
|
|
75
|
+
.step(() => pure(1));
|
|
@@ -2,7 +2,7 @@ import { empty, isVec, uint, vec8 } from "../../bit_vec/module.f.js";
|
|
|
2
2
|
import { pure } from "../module.f.js";
|
|
3
3
|
import { fetch, mkdir, now, readdir, readFile, rm, sandbox, writeFile } from "./module.f.js";
|
|
4
4
|
import { emptyState, virtual } from "./virtual/module.f.js";
|
|
5
|
-
export
|
|
5
|
+
export const proof = {
|
|
6
6
|
map: () => {
|
|
7
7
|
let e = readFile('hello').step(([k, v]) => {
|
|
8
8
|
if (k === 'error') {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { assert, todo } from "../../../../
|
|
6
|
+
import { assert, todo } from "../../../../asserts/module.f.js";
|
|
7
7
|
import { parse } from "../../../../path/module.f.js";
|
|
8
8
|
import { utf8ToString } from "../../../../text/module.f.js";
|
|
9
9
|
import { isVec } from "../../../bit_vec/module.f.js";
|
|
@@ -167,6 +167,7 @@ const map = {
|
|
|
167
167
|
// exception in a fixture propagates loudly as a bug in the fixture.
|
|
168
168
|
// See: issues/156-tf-virtual-tests.md
|
|
169
169
|
sandbox: (state, f) => [state, f()],
|
|
170
|
+
await: (state, p) => [state, [p]],
|
|
170
171
|
test: todo,
|
|
171
172
|
write: (state, stream, data) => {
|
|
172
173
|
const s = utf8ToString(data);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { foldStep, forEachStep, pure } from "./module.f.js";
|
|
2
|
+
export const proof = {
|
|
3
|
+
foldStep: {
|
|
4
|
+
empty: () => {
|
|
5
|
+
const e = foldStep((x) => (s) => pure(s + x))(10)([]);
|
|
6
|
+
const { value } = e;
|
|
7
|
+
if (value.length !== 1) {
|
|
8
|
+
throw value;
|
|
9
|
+
}
|
|
10
|
+
if (value[0] !== 10) {
|
|
11
|
+
throw value[0];
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
threadsState: () => {
|
|
15
|
+
const e = foldStep((x) => (s) => pure(s + x))(0)([1, 2, 3, 4]);
|
|
16
|
+
const { value } = e;
|
|
17
|
+
if (value.length !== 1) {
|
|
18
|
+
throw value;
|
|
19
|
+
}
|
|
20
|
+
if (value[0] !== 10) {
|
|
21
|
+
throw value[0];
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
order: () => {
|
|
25
|
+
const e = foldStep((x) => (s) => pure(s + x))('')(['a', 'b', 'c']);
|
|
26
|
+
const { value } = e;
|
|
27
|
+
if (value.length !== 1) {
|
|
28
|
+
throw value;
|
|
29
|
+
}
|
|
30
|
+
if (value[0] !== 'abc') {
|
|
31
|
+
throw value[0];
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
forEachStep: {
|
|
36
|
+
empty: () => {
|
|
37
|
+
const e = forEachStep(() => pure(undefined))([]);
|
|
38
|
+
const { value } = e;
|
|
39
|
+
if (value.length !== 1) {
|
|
40
|
+
throw value;
|
|
41
|
+
}
|
|
42
|
+
if (value[0] !== undefined) {
|
|
43
|
+
throw value[0];
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
runs: () => {
|
|
47
|
+
const e = forEachStep(() => pure(undefined))([1, 2, 3]);
|
|
48
|
+
const { value } = e;
|
|
49
|
+
if (value.length !== 1) {
|
|
50
|
+
throw value;
|
|
51
|
+
}
|
|
52
|
+
if (value[0] !== undefined) {
|
|
53
|
+
throw value[0];
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const proof: () => void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const proof: {
|
|
2
|
+
joinTest: () => void;
|
|
3
|
+
concatTest: () => void;
|
|
4
|
+
logicalNotTest: () => void;
|
|
5
|
+
strictEqualTest: () => void;
|
|
6
|
+
additionTest: () => void;
|
|
7
|
+
minTest: () => void;
|
|
8
|
+
maxTest: () => void;
|
|
9
|
+
incrementTest: () => void;
|
|
10
|
+
foldToScanTest: () => void;
|
|
11
|
+
reduceToScanTest: () => void;
|
|
12
|
+
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { join, concat, logicalNot, strictEqual, addition, min, max, increment, foldToScan, reduceToScan, } from "./module.f.js";
|
|
2
|
-
|
|
2
|
+
const joinTest = () => {
|
|
3
3
|
const result = join(', ')('world')('hello');
|
|
4
4
|
if (result !== 'hello, world') {
|
|
5
5
|
throw result;
|
|
6
6
|
}
|
|
7
7
|
};
|
|
8
|
-
|
|
8
|
+
const concatTest = () => {
|
|
9
9
|
const result = concat('world')('hello');
|
|
10
10
|
if (result !== 'helloworld') {
|
|
11
11
|
throw result;
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
const logicalNotTest = () => {
|
|
15
15
|
if (logicalNot(true) !== false) {
|
|
16
16
|
throw 'expected false';
|
|
17
17
|
}
|
|
@@ -19,7 +19,7 @@ export const logicalNotTest = () => {
|
|
|
19
19
|
throw 'expected true';
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
|
-
|
|
22
|
+
const strictEqualTest = () => {
|
|
23
23
|
if (!strictEqual(1)(1)) {
|
|
24
24
|
throw 'expected true';
|
|
25
25
|
}
|
|
@@ -27,13 +27,13 @@ export const strictEqualTest = () => {
|
|
|
27
27
|
throw 'expected false';
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
|
-
|
|
30
|
+
const additionTest = () => {
|
|
31
31
|
const result = addition(3)(4);
|
|
32
32
|
if (result !== 7) {
|
|
33
33
|
throw result;
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
|
-
|
|
36
|
+
const minTest = () => {
|
|
37
37
|
if (min(3)(5) !== 3) {
|
|
38
38
|
throw 'min(3)(5)';
|
|
39
39
|
}
|
|
@@ -41,7 +41,7 @@ export const minTest = () => {
|
|
|
41
41
|
throw 'min(7)(2)';
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
|
-
|
|
44
|
+
const maxTest = () => {
|
|
45
45
|
if (max(3)(5) !== 5) {
|
|
46
46
|
throw 'max(3)(5)';
|
|
47
47
|
}
|
|
@@ -49,7 +49,7 @@ export const maxTest = () => {
|
|
|
49
49
|
throw 'max(7)(2)';
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
|
-
|
|
52
|
+
const incrementTest = () => {
|
|
53
53
|
if (increment(4) !== 5) {
|
|
54
54
|
throw 'increment(4)';
|
|
55
55
|
}
|
|
@@ -57,7 +57,7 @@ export const incrementTest = () => {
|
|
|
57
57
|
throw 'increment(0)';
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
|
-
|
|
60
|
+
const foldToScanTest = () => {
|
|
61
61
|
const scan = foldToScan(addition)(0);
|
|
62
62
|
const [v1, scan2] = scan(3);
|
|
63
63
|
if (v1 !== 3) {
|
|
@@ -68,7 +68,7 @@ export const foldToScanTest = () => {
|
|
|
68
68
|
throw v2;
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
|
-
|
|
71
|
+
const reduceToScanTest = () => {
|
|
72
72
|
const scan = reduceToScan(addition);
|
|
73
73
|
const [v0, scan2] = scan(10);
|
|
74
74
|
if (v0 !== 10) {
|
|
@@ -79,3 +79,4 @@ export const reduceToScanTest = () => {
|
|
|
79
79
|
throw v1;
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
|
+
export const proof = { joinTest, concatTest, logicalNotTest, strictEqualTest, additionTest, minTest, maxTest, incrementTest, foldToScanTest, reduceToScanTest };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const proof: () => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const
|
|
1
|
+
export declare const proof: {
|
|
2
2
|
stringifyTest: () => void;
|
|
3
3
|
cycle: () => void;
|
|
4
4
|
countdown: () => void;
|
|
@@ -18,5 +18,5 @@ declare const _default: {
|
|
|
18
18
|
strictEqual: (() => void)[];
|
|
19
19
|
isEmpty: (() => void)[];
|
|
20
20
|
length: () => void;
|
|
21
|
+
filterMap: (() => void)[];
|
|
21
22
|
};
|
|
22
|
-
export default _default;
|
|
@@ -321,7 +321,7 @@ const stress = () => ({
|
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
323
|
});
|
|
324
|
-
export
|
|
324
|
+
export const proof = {
|
|
325
325
|
stringifyTest,
|
|
326
326
|
cycle: cycleTest,
|
|
327
327
|
countdown: countdownTest,
|
|
@@ -389,5 +389,19 @@ export default {
|
|
|
389
389
|
throw 6;
|
|
390
390
|
}
|
|
391
391
|
},
|
|
392
|
+
filterMap: [
|
|
393
|
+
() => {
|
|
394
|
+
const result = str(filterMap((x) => x % 2 === 0 ? x * 10 : null)([1, 2, 3, 4, 5]));
|
|
395
|
+
if (result !== '[20,40]') {
|
|
396
|
+
throw result;
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
() => {
|
|
400
|
+
const result = str(filterMap((x) => x > 3 ? x : null)([1, 2, 3]));
|
|
401
|
+
if (result !== '[]') {
|
|
402
|
+
throw result;
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
],
|
|
392
406
|
// stress
|
|
393
407
|
};
|
|
@@ -8,3 +8,10 @@ export type Nullable<T> = T | null;
|
|
|
8
8
|
export declare const map: <T, R>(f: (value: T) => R) => (value: Nullable<T>) => Nullable<R>;
|
|
9
9
|
export declare const match: <T, R>(f: (_: T) => R) => (none: () => R) => (_: Nullable<T>) => Nullable<R>;
|
|
10
10
|
export declare const toOption: <T>(value: Nullable<T>) => Option<T>;
|
|
11
|
+
/**
|
|
12
|
+
* Normalizes a possibly-`undefined` value into the codebase's `null` convention.
|
|
13
|
+
*
|
|
14
|
+
* The boundary rule between JavaScript hosts (which return `undefined` from
|
|
15
|
+
* property/index lookups) and FunctionalScript (which uses `null` for absence).
|
|
16
|
+
*/
|
|
17
|
+
export declare const fromUndefined: <T>(value: T | undefined) => Nullable<T>;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
export const map = f => value => value === null ? null : f(value);
|
|
2
2
|
export const match = f => none => value => value === null ? none() : f(value);
|
|
3
3
|
export const toOption = (value) => value === null ? [] : [value];
|
|
4
|
+
/**
|
|
5
|
+
* Normalizes a possibly-`undefined` value into the codebase's `null` convention.
|
|
6
|
+
*
|
|
7
|
+
* The boundary rule between JavaScript hosts (which return `undefined` from
|
|
8
|
+
* property/index lookups) and FunctionalScript (which uses `null` for absence).
|
|
9
|
+
*/
|
|
10
|
+
export const fromUndefined = (value) => value === undefined ? null : value;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const proof: (() => void)[];
|