functionalscript 0.20.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/asserts/module.f.d.ts +4 -0
- package/fs/asserts/module.f.js +6 -0
- package/fs/cas/module.f.js +7 -11
- package/fs/cas/proof.f.d.ts +4 -1
- package/fs/cas/proof.f.js +37 -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 +2 -2
- package/fs/ci/playwright/module.f.js +5 -8
- package/fs/ci/proof.f.js +1 -1
- package/fs/ci/rust/module.f.js +3 -9
- package/fs/dev/module.f.d.ts +0 -3
- package/fs/dev/module.f.js +0 -6
- package/fs/dev/proof.f.js +2 -1
- package/fs/djs/tokenizer-new/module.f.js +1 -1
- package/fs/{dev/tf → emergent-testing}/module.f.d.ts +5 -5
- package/fs/{dev/tf → emergent-testing}/module.f.js +34 -24
- package/fs/{dev/tf → emergent-testing}/module.js +2 -2
- package/fs/{dev/tf → emergent-testing}/proof.f.d.ts +2 -0
- package/fs/{dev/tf → emergent-testing}/proof.f.js +44 -7
- 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/{dev/tf → emergent-testing}/scenarios/thenable.pass.js +5 -3
- 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/sul/id/module.f.js +1 -1
- package/fs/sul/id/proof.f.js +1 -1
- package/fs/sul/level/hash/proof.f.js +1 -1
- package/fs/sul/proof.f.js +1 -1
- package/fs/types/array/module.f.js +2 -5
- package/fs/types/effects/node/module.f.d.ts +6 -0
- package/fs/types/effects/node/module.f.js +9 -1
- package/fs/types/effects/node/virtual/module.f.js +1 -1
- package/fs/types/list/proof.f.d.ts +1 -0
- package/fs/types/list/proof.f.js +14 -0
- 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.js +19 -2
- package/fs/types/object/module.f.js +2 -4
- package/fs/types/patricia_trie/proof.f.js +1 -1
- package/fs/types/ts/module.f.d.ts +0 -1
- package/fs/website/proof.f.d.ts +3 -0
- package/fs/website/proof.f.js +9 -0
- package/package.json +1 -1
- package/fs/dev/tf/scenarios/async-subtests.fail.d.ts +0 -4
- package/fs/dev/tf/scenarios/async-subtests.fail.js +0 -7
- package/fs/dev/tf/scenarios/async-subtests.pass.d.ts +0 -4
- package/fs/dev/tf/scenarios/async-subtests.pass.js +0 -7
- package/fs/dev/tf/scenarios/async.fail.d.ts +0 -1
- package/fs/dev/tf/scenarios/async.fail.js +0 -4
- package/fs/dev/tf/scenarios/async.pass.d.ts +0 -1
- package/fs/dev/tf/scenarios/async.pass.js +0 -3
- 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/thenable.pass.d.ts +0 -3
- package/fs/dev/tf/scenarios/thenable2.pass.f.d.ts +0 -3
- package/fs/dev/tf/scenarios/thenable2.pass.f.js +0 -3
- package/fs/dev/tf/scenarios/throw.pass.f.d.ts +0 -6
- /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
package/fs/cas/module.f.js
CHANGED
|
@@ -7,7 +7,7 @@ import { computeSync, sha256 } from "../crypto/sha2/module.f.js";
|
|
|
7
7
|
import { parse } from "../path/module.f.js";
|
|
8
8
|
import { cBase32ToVec, vecToCBase32 } from "../cbase32/module.f.js";
|
|
9
9
|
import { begin, forEachStep, pure } from "../types/effects/module.f.js";
|
|
10
|
-
import {
|
|
10
|
+
import { errorExit, log, mkdir, readdir, readFile, writeFile } from "../types/effects/node/module.f.js";
|
|
11
11
|
import { toOption } from "../types/nullable/module.f.js";
|
|
12
12
|
import { unwrap } from "../types/result/module.f.js";
|
|
13
13
|
const o = { withFileTypes: true };
|
|
@@ -61,10 +61,6 @@ export const cas = (sha2) => {
|
|
|
61
61
|
list,
|
|
62
62
|
});
|
|
63
63
|
};
|
|
64
|
-
/** Prints an error message and returns exit code `1`. */
|
|
65
|
-
const e = (s) => begin
|
|
66
|
-
.step(() => error(s))
|
|
67
|
-
.step(() => pure(1));
|
|
68
64
|
/**
|
|
69
65
|
* Runs the CAS CLI.
|
|
70
66
|
*
|
|
@@ -79,7 +75,7 @@ export const main = (args) => {
|
|
|
79
75
|
switch (cmd) {
|
|
80
76
|
case 'add': {
|
|
81
77
|
if (options.length !== 1) {
|
|
82
|
-
return
|
|
78
|
+
return errorExit("'cas add' expects one parameter");
|
|
83
79
|
}
|
|
84
80
|
const [path] = options;
|
|
85
81
|
return begin
|
|
@@ -90,18 +86,18 @@ export const main = (args) => {
|
|
|
90
86
|
}
|
|
91
87
|
case 'get': {
|
|
92
88
|
if (options.length !== 2) {
|
|
93
|
-
return
|
|
89
|
+
return errorExit("'cas get' expects two parameters");
|
|
94
90
|
}
|
|
95
91
|
const [hashCBase32, path] = options;
|
|
96
92
|
const hash = cBase32ToVec(hashCBase32);
|
|
97
93
|
if (hash === null) {
|
|
98
|
-
return
|
|
94
|
+
return errorExit(`invalid hash format: ${hashCBase32}`);
|
|
99
95
|
}
|
|
100
96
|
return begin
|
|
101
97
|
.step(() => c.read(hash))
|
|
102
98
|
.step(v => {
|
|
103
99
|
const result = v === undefined
|
|
104
|
-
?
|
|
100
|
+
? errorExit(`no such hash: ${hashCBase32}`)
|
|
105
101
|
: begin
|
|
106
102
|
.step(() => writeFile(path, v))
|
|
107
103
|
.step(() => pure(0));
|
|
@@ -115,9 +111,9 @@ export const main = (args) => {
|
|
|
115
111
|
.step(() => pure(0));
|
|
116
112
|
}
|
|
117
113
|
case undefined: {
|
|
118
|
-
return
|
|
114
|
+
return errorExit('Error: CAS command requires subcommand');
|
|
119
115
|
}
|
|
120
116
|
default:
|
|
121
|
-
return
|
|
117
|
+
return errorExit(`Error: Unknown CAS subcommand "${args[0]}"`);
|
|
122
118
|
}
|
|
123
119
|
};
|
package/fs/cas/proof.f.d.ts
CHANGED
package/fs/cas/proof.f.js
CHANGED
|
@@ -1 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
import { cas } from "./module.f.js";
|
|
2
|
+
import { sha256 } from "../crypto/sha2/module.f.js";
|
|
3
|
+
import { empty, length } from "../types/bit_vec/module.f.js";
|
|
4
|
+
import { pure } from "../types/effects/module.f.js";
|
|
5
|
+
import { run } from "../types/effects/mock/module.f.js";
|
|
6
|
+
export const proof = {
|
|
7
|
+
casWrite: () => {
|
|
8
|
+
const store = {
|
|
9
|
+
read: (_key) => pure(undefined),
|
|
10
|
+
write: (_key, _value) => pure(undefined),
|
|
11
|
+
list: () => pure([]),
|
|
12
|
+
};
|
|
13
|
+
const c = cas(sha256)(store);
|
|
14
|
+
const [, hash] = run({})(undefined)(c.write(empty));
|
|
15
|
+
// sha256 of empty input produces a 256-bit hash
|
|
16
|
+
if (length(hash) !== 256n) {
|
|
17
|
+
throw ['expected 256-bit hash', length(hash)];
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
casReadPassthrough: () => {
|
|
21
|
+
const stored = empty;
|
|
22
|
+
const store = {
|
|
23
|
+
read: (_key) => pure(stored),
|
|
24
|
+
write: (_key, _value) => pure(undefined),
|
|
25
|
+
list: () => pure([stored]),
|
|
26
|
+
};
|
|
27
|
+
const c = cas(sha256)(store);
|
|
28
|
+
const [, readResult] = run({})(undefined)(c.read(empty));
|
|
29
|
+
if (readResult !== stored) {
|
|
30
|
+
throw ['read should pass through', readResult];
|
|
31
|
+
}
|
|
32
|
+
const [, listResult] = run({})(undefined)(c.list());
|
|
33
|
+
if (listResult.length !== 1) {
|
|
34
|
+
throw ['list should pass through', listResult];
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
};
|
package/fs/ci/bun/module.f.js
CHANGED
|
@@ -5,17 +5,12 @@
|
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
import { bun } from "../config/module.f.js";
|
|
8
|
-
import { clean, install, test } from "../common/module.f.js";
|
|
8
|
+
import { clean, install, test, uses } from "../common/module.f.js";
|
|
9
9
|
const installOnWindowsArm = ({ def, name, path }) => (v) => (a) => install(v === 'windows' && a === 'arm'
|
|
10
10
|
? { run: `irm ${path}/install.ps1 | iex; "$env:USERPROFILE\\.${name}\\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append` }
|
|
11
11
|
: def);
|
|
12
12
|
const installBun = installOnWindowsArm({
|
|
13
|
-
def: {
|
|
14
|
-
uses: 'oven-sh/setup-bun@v2',
|
|
15
|
-
with: {
|
|
16
|
-
'bun-version': bun
|
|
17
|
-
},
|
|
18
|
-
},
|
|
13
|
+
def: uses('oven-sh/setup-bun', { 'bun-version': bun }),
|
|
19
14
|
name: 'bun',
|
|
20
15
|
path: 'bun.sh',
|
|
21
16
|
});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
|
-
import { images } from '../config/module.f.ts';
|
|
8
|
+
import { actions, images } from '../config/module.f.ts';
|
|
9
9
|
import { type Ts } from '../../types/rtti/ts/module.f.ts';
|
|
10
10
|
export declare const os: readonly ["ubuntu", "macos", "windows"];
|
|
11
11
|
export type Os = typeof os[number];
|
|
@@ -76,6 +76,7 @@ export type MetaStep = {
|
|
|
76
76
|
readonly type: 'apt-get';
|
|
77
77
|
readonly package: string;
|
|
78
78
|
};
|
|
79
|
+
export declare const uses: (name: keyof typeof actions, w?: Record<string, string>) => Step;
|
|
79
80
|
export declare const install: (step: Step) => MetaStep;
|
|
80
81
|
export declare const test: (step: Step) => MetaStep;
|
|
81
82
|
export declare const clean: (steps: readonly MetaStep[]) => readonly MetaStep[];
|
package/fs/ci/common/module.f.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { actions, images } from "../config/module.f.js";
|
|
9
9
|
import { option, array, record, string } from "../../types/rtti/module.f.js";
|
|
10
10
|
import {} from "../../types/rtti/ts/module.f.js";
|
|
11
11
|
import { parse as rttiParse } from "../../types/rtti/parse/module.f.js";
|
|
@@ -27,6 +27,10 @@ export const gitHubActionSchema = {
|
|
|
27
27
|
jobs: jobsSchema
|
|
28
28
|
};
|
|
29
29
|
export const parseGitHubAction = rttiParse(gitHubActionSchema);
|
|
30
|
+
export const uses = (name, w) => ({
|
|
31
|
+
uses: `${name}@${actions[name]}`,
|
|
32
|
+
...(w === undefined ? {} : { with: w })
|
|
33
|
+
});
|
|
30
34
|
export const install = (step) => ({ type: 'install', step });
|
|
31
35
|
export const test = (step) => ({ type: 'test', step });
|
|
32
36
|
export const clean = (steps) => [
|
|
@@ -40,15 +44,9 @@ export const toSteps = (m) => {
|
|
|
40
44
|
const targets = m.flatMap(v => v.type === 'rust' && v.target !== undefined ? [v.target] : []).join(',');
|
|
41
45
|
return [
|
|
42
46
|
...(aptGet !== '' ? [{ run: `sudo apt-get update && sudo apt-get install -y ${aptGet}` }] : []),
|
|
43
|
-
...(needRust ? [{
|
|
44
|
-
uses: `dtolnay/rust-toolchain@${rust}`,
|
|
45
|
-
with: {
|
|
46
|
-
components: 'rustfmt,clippy',
|
|
47
|
-
targets
|
|
48
|
-
}
|
|
49
|
-
}] : []),
|
|
47
|
+
...(needRust ? [uses('dtolnay/rust-toolchain', { components: 'rustfmt,clippy', targets })] : []),
|
|
50
48
|
...filter('install'),
|
|
51
|
-
|
|
49
|
+
uses('actions/checkout'),
|
|
52
50
|
...filter('test'),
|
|
53
51
|
];
|
|
54
52
|
};
|
|
@@ -22,11 +22,20 @@ export declare const images: {
|
|
|
22
22
|
export declare const bun = "1.3.14";
|
|
23
23
|
export declare const deno = "2.8.1";
|
|
24
24
|
export declare const playwright = "1.60.0";
|
|
25
|
-
export declare const rust = "1.95.0";
|
|
26
25
|
export declare const node: {
|
|
27
|
-
readonly default: "26.
|
|
26
|
+
readonly default: "26.3.0";
|
|
28
27
|
readonly others: readonly ["24.16.0"];
|
|
29
28
|
};
|
|
30
29
|
export declare const wasmtime = "45.0.0";
|
|
31
30
|
export declare const wasmer = "7.1.0";
|
|
32
|
-
export declare const tsgo = "7.0.0-dev.
|
|
31
|
+
export declare const tsgo = "7.0.0-dev.20260601.1";
|
|
32
|
+
export declare const actions: {
|
|
33
|
+
readonly 'actions/checkout': "v6";
|
|
34
|
+
readonly 'actions/setup-node': "v6";
|
|
35
|
+
readonly 'actions/cache': "v5";
|
|
36
|
+
readonly 'denoland/setup-deno': "v2";
|
|
37
|
+
readonly 'oven-sh/setup-bun': "v2";
|
|
38
|
+
readonly 'bytecodealliance/actions/wasmtime/setup': "v1";
|
|
39
|
+
readonly 'wasmerio/setup-wasmer': "v3.1";
|
|
40
|
+
readonly 'dtolnay/rust-toolchain': "1.95.0";
|
|
41
|
+
};
|
package/fs/ci/config/module.f.js
CHANGED
|
@@ -26,11 +26,9 @@ export const bun = '1.3.14';
|
|
|
26
26
|
export const deno = '2.8.1';
|
|
27
27
|
// https://www.npmjs.com/package/playwright
|
|
28
28
|
export const playwright = '1.60.0';
|
|
29
|
-
// https://rust-lang.org/
|
|
30
|
-
export const rust = '1.95.0';
|
|
31
29
|
// https://nodejs.org/en/download
|
|
32
30
|
export const node = {
|
|
33
|
-
default: '26.
|
|
31
|
+
default: '26.3.0',
|
|
34
32
|
others: ['24.16.0'],
|
|
35
33
|
};
|
|
36
34
|
// https://github.com/bytecodealliance/wasmtime/releases
|
|
@@ -38,4 +36,26 @@ export const wasmtime = '45.0.0';
|
|
|
38
36
|
// https://github.com/wasmerio/wasmer/releases
|
|
39
37
|
export const wasmer = '7.1.0';
|
|
40
38
|
// https://www.npmjs.com/package/@typescript/native-preview?activeTab=versions
|
|
41
|
-
export const tsgo = '7.0.0-dev.
|
|
39
|
+
export const tsgo = '7.0.0-dev.20260601.1';
|
|
40
|
+
// GitHub Action versions used by CI step builders. The key is the action
|
|
41
|
+
// `owner/name`; call sites compose the full ref as
|
|
42
|
+
// `` `${name}@${actions[name]}` ``.
|
|
43
|
+
// Note: dtolnay/rust-toolchain value is a Rust version, not an action version.
|
|
44
|
+
export const actions = {
|
|
45
|
+
// https://github.com/marketplace/actions/checkout
|
|
46
|
+
'actions/checkout': 'v6',
|
|
47
|
+
// https://github.com/marketplace/actions/setup-node-js-environment
|
|
48
|
+
'actions/setup-node': 'v6',
|
|
49
|
+
// https://github.com/marketplace/actions/cache
|
|
50
|
+
'actions/cache': 'v5',
|
|
51
|
+
// https://github.com/marketplace/actions/setup-deno
|
|
52
|
+
'denoland/setup-deno': 'v2',
|
|
53
|
+
// https://github.com/marketplace/actions/setup-bun
|
|
54
|
+
'oven-sh/setup-bun': 'v2',
|
|
55
|
+
// https://github.com/bytecodealliance/actions
|
|
56
|
+
'bytecodealliance/actions/wasmtime/setup': 'v1',
|
|
57
|
+
// https://github.com/wasmerio/setup-wasmer
|
|
58
|
+
'wasmerio/setup-wasmer': 'v3.1',
|
|
59
|
+
// https://rust-lang.org/ - value is Rust version, not action version
|
|
60
|
+
'dtolnay/rust-toolchain': '1.95.0',
|
|
61
|
+
};
|
package/fs/ci/deno/module.f.js
CHANGED
|
@@ -5,12 +5,9 @@
|
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
import { deno } from "../config/module.f.js";
|
|
8
|
-
import { clean, install, test } from "../common/module.f.js";
|
|
8
|
+
import { clean, install, test, uses } from "../common/module.f.js";
|
|
9
9
|
export const denoSteps = (extra) => clean([
|
|
10
|
-
install({
|
|
11
|
-
uses: 'denoland/setup-deno@v2',
|
|
12
|
-
with: { 'deno-version': deno },
|
|
13
|
-
}),
|
|
10
|
+
install(uses('denoland/setup-deno', { 'deno-version': deno })),
|
|
14
11
|
test({ run: 'deno install' }),
|
|
15
12
|
test({ run: 'deno task test' }),
|
|
16
13
|
...extra,
|
package/fs/ci/node/module.f.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
import { node, tsgo } from "../config/module.f.js";
|
|
8
|
-
import { clean, findTgz, install, test, ubuntu } from "../common/module.f.js";
|
|
8
|
+
import { clean, findTgz, install, test, ubuntu, uses } from "../common/module.f.js";
|
|
9
9
|
export const major = (v) => v.split('.')[0];
|
|
10
|
-
const installNode = (version) => (
|
|
10
|
+
const installNode = (version) => uses('actions/setup-node', { 'node-version': version });
|
|
11
11
|
const nodeInstall = (v) => [
|
|
12
12
|
install(installNode(v)),
|
|
13
13
|
test({ run: 'npm ci' }),
|
|
@@ -5,19 +5,16 @@
|
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
import { images, node, playwright } from "../config/module.f.js";
|
|
8
|
-
import { install, test, toSteps } from "../common/module.f.js";
|
|
8
|
+
import { install, test, toSteps, uses } from "../common/module.f.js";
|
|
9
9
|
import { basicNode } from "../node/module.f.js";
|
|
10
10
|
const playwrightImage = images.ubuntu.intel;
|
|
11
11
|
export const playwrightJob = {
|
|
12
12
|
'runs-on': playwrightImage,
|
|
13
13
|
steps: toSteps(basicNode(node.default)([
|
|
14
|
-
install({
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
key: `${playwrightImage}-playwright-${playwright}`,
|
|
19
|
-
},
|
|
20
|
-
}),
|
|
14
|
+
install(uses('actions/cache', {
|
|
15
|
+
path: '~/.cache/ms-playwright',
|
|
16
|
+
key: `${playwrightImage}-playwright-${playwright}`,
|
|
17
|
+
})),
|
|
21
18
|
install({ run: `npm install -g playwright@${playwright}` }),
|
|
22
19
|
install({ run: 'playwright install-deps' }),
|
|
23
20
|
install({ run: 'playwright install' }),
|
package/fs/ci/proof.f.js
CHANGED
|
@@ -2,7 +2,7 @@ import { ci } from "./module.f.js";
|
|
|
2
2
|
import { utf8ToString } from "../text/module.f.js";
|
|
3
3
|
import { isVec } from "../types/bit_vec/module.f.js";
|
|
4
4
|
import { test, parseGitHubAction } from "./common/module.f.js";
|
|
5
|
-
import { assert } from "../
|
|
5
|
+
import { assert } from "../asserts/module.f.js";
|
|
6
6
|
import { emptyState, virtual } from "../types/effects/node/virtual/module.f.js";
|
|
7
7
|
import { parse as jsonParse } from "../json/module.f.js";
|
|
8
8
|
import { unwrap } from "../types/result/module.f.js";
|
package/fs/ci/rust/module.f.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
8
|
import { wasmer, wasmtime } from "../config/module.f.js";
|
|
9
|
-
import { install, test } from "../common/module.f.js";
|
|
9
|
+
import { install, test, uses } from "../common/module.f.js";
|
|
10
10
|
const cargoTest = (target, config) => {
|
|
11
11
|
const to = target ? ` --target ${target}` : '';
|
|
12
12
|
const co = config ? ` --config ${config}` : '';
|
|
@@ -40,14 +40,8 @@ export const rustSteps = (v, a) => [
|
|
|
40
40
|
test({ run: 'cargo fmt -- --check' }),
|
|
41
41
|
test({ run: 'cargo clippy -- -D warnings' }),
|
|
42
42
|
...cargoTest(),
|
|
43
|
-
install({
|
|
44
|
-
|
|
45
|
-
with: { version: wasmtime }
|
|
46
|
-
}),
|
|
47
|
-
install({
|
|
48
|
-
uses: 'wasmerio/setup-wasmer@v3.1',
|
|
49
|
-
with: { version: `v${wasmer}` },
|
|
50
|
-
}),
|
|
43
|
+
install(uses('bytecodealliance/actions/wasmtime/setup', { version: wasmtime })),
|
|
44
|
+
install(uses('wasmerio/setup-wasmer', { version: `v${wasmer}` })),
|
|
51
45
|
...wasmTarget('wasm32-wasip1'),
|
|
52
46
|
...wasmTarget('wasm32-wasip2'),
|
|
53
47
|
...wasmTarget('wasm32-unknown-unknown'),
|
package/fs/dev/module.f.d.ts
CHANGED
|
@@ -6,9 +6,6 @@
|
|
|
6
6
|
import type { Io } from '../io/module.f.ts';
|
|
7
7
|
import { type Access, type All, type Env, type Import, type NodeProgram, type Readdir } from '../types/effects/node/module.f.ts';
|
|
8
8
|
import { type Effect } from '../types/effects/module.f.ts';
|
|
9
|
-
export declare const todo: () => never;
|
|
10
|
-
export declare const assert: (v: boolean, msg?: unknown) => asserts v;
|
|
11
|
-
export declare const assertEq: <T>(a: T, b: T) => void;
|
|
12
9
|
export type Module = {
|
|
13
10
|
readonly proof?: unknown;
|
|
14
11
|
readonly [k: string]: unknown;
|
package/fs/dev/module.f.js
CHANGED
|
@@ -8,12 +8,6 @@ import { parse as jsonParse } from "../json/module.f.js";
|
|
|
8
8
|
import { record, unknown as rttiUnknown } from "../types/rtti/module.f.js";
|
|
9
9
|
import { parse as rttiParse } from "../types/rtti/parse/module.f.js";
|
|
10
10
|
import { relativize } from "../path/module.f.js";
|
|
11
|
-
export const todo = () => { throw 'not implemented'; };
|
|
12
|
-
export const assert = (v, msg = 'assertion failed') => {
|
|
13
|
-
if (!v)
|
|
14
|
-
throw msg;
|
|
15
|
-
};
|
|
16
|
-
export const assertEq = (a, b) => assert(a === b, [a, b]);
|
|
17
11
|
export const env = ({ process: { env } }) => a => {
|
|
18
12
|
const r = Object.getOwnPropertyDescriptor(env, a);
|
|
19
13
|
return r === undefined ? undefined :
|
package/fs/dev/proof.f.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { descentParser } from "../../bnf/data/module.f.js";
|
|
7
7
|
import { eof, join0Plus, max, none, not, notSet, oneEncode, option, range, remove, repeat, repeat0Plus, repeat1Plus, set, unicodeRange } from "../../bnf/module.f.js";
|
|
8
|
-
import { todo } from "../../
|
|
8
|
+
import { todo } from "../../asserts/module.f.js";
|
|
9
9
|
export const parse = (input) => {
|
|
10
10
|
const m = descentParser(jsGrammar());
|
|
11
11
|
return todo();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type All, type Await, type NodeProgram, type NodeProgramOptions, type Program, type Sandbox, type SandboxResult, type Test, type TestContext, type Write } from '
|
|
2
|
-
import { type Effect, type Operation } from '
|
|
3
|
-
import { type LoadModuleOperations, type ModuleMap } from '../module.f.ts';
|
|
1
|
+
import { type All, type Await, type NodeProgram, type NodeProgramOptions, type Program, type Sandbox, type SandboxResult, type Test, type TestContext, type Write } from '../types/effects/node/module.f.ts';
|
|
2
|
+
import { type Effect, type Operation } from '../types/effects/module.f.ts';
|
|
3
|
+
import { type LoadModuleOperations, type ModuleMap } from '../dev/module.f.ts';
|
|
4
4
|
/** A zero-argument test function whose return value may contain sub-tests. */
|
|
5
5
|
export type TestFn = () => unknown;
|
|
6
6
|
/**
|
|
@@ -46,7 +46,7 @@ export declare const collectTests: (path: Path, throws: boolean, v: unknown) =>
|
|
|
46
46
|
* contained `inner`.
|
|
47
47
|
*/
|
|
48
48
|
export type Reporter<O extends Operation> = {
|
|
49
|
-
readonly result: (file: string, path: Path, r: SandboxResult<unknown
|
|
49
|
+
readonly result: (file: string, path: Path, r: SandboxResult<unknown>, throws: boolean) => Effect<O, void>;
|
|
50
50
|
readonly summary: (pass: number, fail: number, time: number) => Effect<O, void>;
|
|
51
51
|
readonly test: (file: string, path: Path, set: TestEntry) => Effect<O, SandboxResult<unknown>>;
|
|
52
52
|
};
|
|
@@ -60,7 +60,7 @@ export type Reporter<O extends Operation> = {
|
|
|
60
60
|
* This is the correct model for Node `--test`, Bun, and Playwright, where tests
|
|
61
61
|
* must be declared upfront and the framework drives execution.
|
|
62
62
|
*/
|
|
63
|
-
export declare const registerModule: (ctx: TestContext, k: string, v: unknown) => Effect<Test | All | Await, void>;
|
|
63
|
+
export declare const registerModule: (ctx: TestContext, k: string, v: unknown, star: string) => Effect<Test | All | Await, void>;
|
|
64
64
|
/**
|
|
65
65
|
* Runs all test modules in `moduleMap` whose names pass `isTest`, accumulates
|
|
66
66
|
* pass/fail/time via `reporter`, and returns an exit code (0 = all passed,
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
|
-
import { reset, fgGreen, fgRed, bold, csiWrite } from "
|
|
14
|
-
import { all, awaitIfPromise, sandbox, test } from "
|
|
15
|
-
import { pure } from "
|
|
16
|
-
import { loadModuleMap, shouldLoad } from "../module.f.js";
|
|
17
|
-
import { invert } from "
|
|
13
|
+
import { reset, fgGreen, fgRed, bold, csiWrite } from "../text/sgr/module.f.js";
|
|
14
|
+
import { all, awaitIfPromise, sandbox, test } from "../types/effects/node/module.f.js";
|
|
15
|
+
import { pure } from "../types/effects/module.f.js";
|
|
16
|
+
import { loadModuleMap, shouldLoad } from "../dev/module.f.js";
|
|
17
|
+
import { invert } from "../types/result/module.f.js";
|
|
18
18
|
const addPass = (delta) => (ts) => ({ ...ts, time: ts.time + delta, pass: ts.pass + 1 });
|
|
19
19
|
const addFail = (delta) => (ts) => ({ ...ts, time: ts.time + delta, fail: ts.fail + 1 });
|
|
20
20
|
const timeFormat = (a) => {
|
|
@@ -75,18 +75,26 @@ export const collectTests = (path, throws, v) => {
|
|
|
75
75
|
* This is the correct model for Node `--test`, Bun, and Playwright, where tests
|
|
76
76
|
* must be declared upfront and the framework drives execution.
|
|
77
77
|
*/
|
|
78
|
-
export const registerModule = (ctx, k, v) => {
|
|
79
|
-
const registerOne = (ctx, [path, { fn, throws }]) =>
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
78
|
+
export const registerModule = (ctx, k, v, star) => {
|
|
79
|
+
const registerOne = (ctx, [path, { fn, throws }]) => {
|
|
80
|
+
// ' *' (non-empty only for Bun/Playwright) signals that all sub-tests run
|
|
81
|
+
// inline inside this single registration. Not appended to throw-tests since
|
|
82
|
+
// those never produce sub-tests. The path already contains '.throw' when a
|
|
83
|
+
// test is expected to throw, so no extra suffix is needed.
|
|
84
|
+
const base = fmtImport(k, path);
|
|
85
|
+
const name = throws ? base : `${base}${star}`;
|
|
86
|
+
return test(ctx, name, throws, (t) => awaitIfPromise(fn())
|
|
87
|
+
.step(resolved => {
|
|
88
|
+
if (throws) {
|
|
89
|
+
return pure(undefined);
|
|
90
|
+
}
|
|
91
|
+
const sub = collectTests([...path, null], false, resolved);
|
|
92
|
+
if (sub.length === 0) {
|
|
93
|
+
return pure(undefined);
|
|
94
|
+
}
|
|
95
|
+
return all(...sub.map(e => registerOne(t, e))).step(() => pure(undefined));
|
|
96
|
+
}));
|
|
97
|
+
};
|
|
90
98
|
const tests = collectTests([], false, v);
|
|
91
99
|
if (tests.length === 0) {
|
|
92
100
|
return pure(undefined);
|
|
@@ -99,7 +107,7 @@ const runModule = ({ result, test }) => (k, v) => (ts) => {
|
|
|
99
107
|
const one = ([testPath, set]) => test(k, testPath, set)
|
|
100
108
|
.step(sr => {
|
|
101
109
|
const { result: [s, r], duration } = sr;
|
|
102
|
-
return result(k, testPath, sr)
|
|
110
|
+
return result(k, testPath, sr, set.throws)
|
|
103
111
|
.step(() => {
|
|
104
112
|
if (s === 'ok') {
|
|
105
113
|
if (set.throws) {
|
|
@@ -146,13 +154,13 @@ export const testAll = (reporter) => options => loadModuleMap(options.env).step(
|
|
|
146
154
|
* Registers all modules in `moduleMap` that export a `proof` property with
|
|
147
155
|
* `ctx`. Delegates to `registerModule` for each matching entry.
|
|
148
156
|
*/
|
|
149
|
-
const registerModuleMap = (ctx) => (moduleMap) => {
|
|
157
|
+
const registerModuleMap = (ctx, star) => (moduleMap) => {
|
|
150
158
|
const modules = entries(moduleMap)
|
|
151
159
|
.flatMap(([k, v]) => v.proof !== undefined ? [[k, v.proof]] : []);
|
|
152
160
|
if (modules.length === 0) {
|
|
153
161
|
return pure(undefined);
|
|
154
162
|
}
|
|
155
|
-
return all(...modules.map(([k, v]) => registerModule(ctx, k, v))).step(() => pure(undefined));
|
|
163
|
+
return all(...modules.map(([k, v]) => registerModule(ctx, k, v, star))).step(() => pure(undefined));
|
|
156
164
|
};
|
|
157
165
|
const isAlpha = (c) => (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c === '_' || c === '$';
|
|
158
166
|
const isDigit = (c) => c >= '0' && c <= '9';
|
|
@@ -227,8 +235,8 @@ export const defaultReporter = (options) => {
|
|
|
227
235
|
const isGitHub = options.env['GITHUB_ACTION'] !== undefined;
|
|
228
236
|
return {
|
|
229
237
|
// https://github.com/OndraM/ci-detector/blob/main/src/Ci/GitHubActions.php
|
|
230
|
-
result: (file, path, { result: [s, v], duration }) => s === 'ok'
|
|
231
|
-
? csiLog(fmtResultLine(file, path, fgGreen, 'ok', duration))
|
|
238
|
+
result: (file, path, { result: [s, v], duration }, throws) => s === 'ok'
|
|
239
|
+
? csiLog(fmtResultLine(file, path, fgGreen, 'ok', duration) + (throws ? ' # EXPECTED TO THROW' : ''))
|
|
232
240
|
: isGitHub
|
|
233
241
|
? csiError(`::error file=${file},line=1,title=${ghEscape(fmtImport(file, path))}::${ghEscape(String(v))}`)
|
|
234
242
|
: csiError(fmtResultLine(file, path, fgRed, 'error', duration))
|
|
@@ -251,9 +259,11 @@ export const main = options => testAll(defaultReporter(options))(options);
|
|
|
251
259
|
* based on the detected `engine`.
|
|
252
260
|
*/
|
|
253
261
|
export const register = o => {
|
|
254
|
-
const
|
|
262
|
+
const star = o.engine === 'bun' || o.engine === 'playwright' ? ' ...' : '';
|
|
263
|
+
const ctx = o.engine === 'bun' ? o.bunTestContext :
|
|
255
264
|
o.engine === 'playwright' ? o.playwrightTestContext :
|
|
256
|
-
o.testContext
|
|
265
|
+
o.testContext;
|
|
266
|
+
const r = registerModuleMap(ctx, star);
|
|
257
267
|
return loadModuleMap(o.env)
|
|
258
268
|
.step(r)
|
|
259
269
|
.step(() => pure(0));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { io } from "
|
|
1
|
+
import { io } from "../io/module.js";
|
|
2
2
|
import { register } from "./module.f.js";
|
|
3
|
-
import { runProgram } from "
|
|
3
|
+
import { runProgram } from "../io/module.f.js";
|
|
4
4
|
export const run = () => runProgram(io)([])(register);
|
|
@@ -12,6 +12,7 @@ export declare const namedExports: () => void;
|
|
|
12
12
|
export declare const defaultReporterOutput: () => void;
|
|
13
13
|
export declare const defaultReporterFailOutput: () => void;
|
|
14
14
|
export declare const githubReporterOutput: () => void;
|
|
15
|
+
export declare const registerSuffixes: () => void;
|
|
15
16
|
export declare const helpers: {
|
|
16
17
|
isInteger: () => void;
|
|
17
18
|
isIdentifier: () => void;
|
|
@@ -36,6 +37,7 @@ export declare const proof: {
|
|
|
36
37
|
defaultReporterOutput: () => void;
|
|
37
38
|
defaultReporterFailOutput: () => void;
|
|
38
39
|
githubReporterOutput: () => void;
|
|
40
|
+
registerSuffixes: () => void;
|
|
39
41
|
helpers: {
|
|
40
42
|
isInteger: () => void;
|
|
41
43
|
isIdentifier: () => void;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { pure } from "
|
|
2
|
-
import { emptyState } from "
|
|
3
|
-
import { virtual } from "
|
|
4
|
-
import { assert, assertEq, todo } from "../module.f.js";
|
|
5
|
-
import { testAll, defaultReporter, fmtPath, fmtTerm, fmtImport, ghEscape, isInteger, isIdentifier, defaultTest, } from "./module.f.js";
|
|
6
|
-
import {
|
|
1
|
+
import { pure } from "../types/effects/module.f.js";
|
|
2
|
+
import { emptyState } from "../types/effects/node/virtual/module.f.js";
|
|
3
|
+
import { virtual } from "../types/effects/node/virtual/module.f.js";
|
|
4
|
+
import { assert, assertEq, todo } from "../asserts/module.f.js";
|
|
5
|
+
import { testAll, defaultReporter, fmtPath, fmtTerm, fmtImport, ghEscape, isInteger, isIdentifier, registerModule, defaultTest, } from "./module.f.js";
|
|
6
|
+
import { run as mockRun } from "../types/effects/mock/module.f.js";
|
|
7
|
+
import { shouldLoad } from "../dev/module.f.js";
|
|
7
8
|
const makeReporter = () => {
|
|
8
9
|
const events = [];
|
|
9
10
|
const reporter = {
|
|
10
|
-
result: (file, path, r) => { events.push(['result', file, [...path], r]); return pure(undefined); },
|
|
11
|
+
result: (file, path, r, _throws) => { events.push(['result', file, [...path], r]); return pure(undefined); },
|
|
11
12
|
summary: (pass, fail, time) => { events.push(['summary', pass, fail, time]); return pure(undefined); },
|
|
12
13
|
test: defaultTest,
|
|
13
14
|
};
|
|
@@ -215,6 +216,41 @@ export const githubReporterOutput = () => {
|
|
|
215
216
|
assertEq(exit, 1);
|
|
216
217
|
assertEq(stderr, '::error file=./s.proof.f.ts,line=1,title=import("./s.proof.f.ts").proof["a%3Ab%2Cc%25d"]()::oops\n');
|
|
217
218
|
};
|
|
219
|
+
// registerModule appends ' ...' for inline runners (Bun/Playwright).
|
|
220
|
+
// Uses a minimal synchronous mock for the Test/All/Await effect operations.
|
|
221
|
+
export const registerSuffixes = () => {
|
|
222
|
+
let runner;
|
|
223
|
+
const noopCtx = { test: (_n, _o, _f) => Promise.resolve() };
|
|
224
|
+
const makeRunner = () => mockRun({
|
|
225
|
+
test: (s, _ctx, name, _xf, _fn) => [[...s, name], undefined],
|
|
226
|
+
all: (s, ...effects) => {
|
|
227
|
+
let st = s;
|
|
228
|
+
const rs = [];
|
|
229
|
+
for (const e of effects) {
|
|
230
|
+
const [ns, r] = runner(st)(e);
|
|
231
|
+
st = ns;
|
|
232
|
+
rs.push(r);
|
|
233
|
+
}
|
|
234
|
+
return [st, rs];
|
|
235
|
+
},
|
|
236
|
+
await: (s, p) => [s, [p]],
|
|
237
|
+
});
|
|
238
|
+
runner = makeRunner();
|
|
239
|
+
const proof = {
|
|
240
|
+
ok: () => { },
|
|
241
|
+
throw: { a: () => { throw 'expected'; } },
|
|
242
|
+
};
|
|
243
|
+
// Node (star = ''): no suffixes
|
|
244
|
+
const [nodeNames] = runner([])(registerModule(noopCtx, './a.f.ts', proof, ''));
|
|
245
|
+
assertEq(nodeNames.length, 2);
|
|
246
|
+
assertEq(nodeNames[0], 'import("./a.f.ts").proof.ok()');
|
|
247
|
+
assertEq(nodeNames[1], 'import("./a.f.ts").proof.throw.a()');
|
|
248
|
+
// Bun/Playwright (star = ' ...'): ... on normal tests, path shows throw for throw-tests
|
|
249
|
+
const [inlineNames] = runner([])(registerModule(noopCtx, './a.f.ts', proof, ' ...'));
|
|
250
|
+
assertEq(inlineNames.length, 2);
|
|
251
|
+
assertEq(inlineNames[0], 'import("./a.f.ts").proof.ok() ...');
|
|
252
|
+
assertEq(inlineNames[1], 'import("./a.f.ts").proof.throw.a()');
|
|
253
|
+
};
|
|
218
254
|
// direct unit tests for the pure path-format helpers
|
|
219
255
|
export const helpers = {
|
|
220
256
|
isInteger: () => {
|
|
@@ -297,5 +333,6 @@ export const proof = {
|
|
|
297
333
|
defaultReporterOutput,
|
|
298
334
|
defaultReporterFailOutput,
|
|
299
335
|
githubReporterOutput,
|
|
336
|
+
registerSuffixes,
|
|
300
337
|
helpers
|
|
301
338
|
};
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
// must exit 0: the thenable object is walked as a sub-tree whose only key
|
|
5
5
|
// `then` is a function with parameters, so no leaf tests are found and the
|
|
6
6
|
// test trivially passes.
|
|
7
|
-
export const
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export const proof = {
|
|
8
|
+
thenableResolves: () => ({
|
|
9
|
+
then(resolve) { resolve(undefined); }
|
|
10
|
+
})
|
|
11
|
+
};
|
package/fs/fjs/module.f.js
CHANGED
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { compile } from "../djs/module.f.js";
|
|
7
|
-
import { main as testMain } from "../
|
|
7
|
+
import { main as testMain } from "../emergent-testing/module.f.js";
|
|
8
8
|
import { main as casMain } from "../cas/module.f.js";
|
|
9
|
-
import { import_,
|
|
10
|
-
import { pure } from "../types/effects/module.f.js";
|
|
9
|
+
import { import_, errorExit } from "../types/effects/node/module.f.js";
|
|
11
10
|
export const main = options => {
|
|
12
11
|
const [command, ...rest] = options.args;
|
|
13
12
|
switch (command) {
|
|
@@ -31,8 +30,8 @@ export const main = options => {
|
|
|
31
30
|
});
|
|
32
31
|
}
|
|
33
32
|
case undefined:
|
|
34
|
-
return
|
|
33
|
+
return errorExit('Error: command is required');
|
|
35
34
|
default:
|
|
36
|
-
return
|
|
35
|
+
return errorExit(`Error: Unknown command "${command}"`);
|
|
37
36
|
}
|
|
38
37
|
};
|
package/fs/sul/id/module.f.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { toArray } from "../../types/list/module.f.js";
|
|
9
9
|
import { length, msb, uint, uintChunkList, unpack, vec } from "../../types/bit_vec/module.f.js";
|
|
10
|
-
import { assertEq } from "../../
|
|
10
|
+
import { assertEq } from "../../asserts/module.f.js";
|
|
11
11
|
import { utf8 } from "../../text/module.f.js";
|
|
12
12
|
import { secp256r1 } from "../../crypto/secp/module.f.js";
|
|
13
13
|
import { base32 } from "../../crypto/sha2/module.f.js";
|
package/fs/sul/id/proof.f.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assert, assertEq } from "../../
|
|
1
|
+
import { assert, assertEq } from "../../asserts/module.f.js";
|
|
2
2
|
import { mask } from "../../types/bigint/module.f.js";
|
|
3
3
|
import { vec } from "../../types/bit_vec/module.f.js";
|
|
4
4
|
import { compress, hashId, isHash, isRaw, level3Id, rawId } from "./module.f.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assert, assertEq } from "../../../
|
|
1
|
+
import { assert, assertEq } from "../../../asserts/module.f.js";
|
|
2
2
|
import { compress, level3Id } from "../../id/module.f.js";
|
|
3
3
|
import { emptyEncodeState, encode } from "./module.f.js";
|
|
4
4
|
const add = (l, r, m, isSymbol, s) => [...s, [l, r, m, isSymbol]];
|
package/fs/sul/proof.f.js
CHANGED
|
@@ -3,15 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { map } from "../nullable/module.f.js";
|
|
6
|
+
import { fromUndefined, map } from "../nullable/module.f.js";
|
|
7
7
|
export const isArray = (value) => value instanceof Array;
|
|
8
8
|
export const isArray2 = (a) => a.length === 2;
|
|
9
9
|
const uncheckTail = (a) => a.slice(1);
|
|
10
10
|
const uncheckHead = (a) => a.slice(0, -1);
|
|
11
|
-
export const at = (i) => (a) =>
|
|
12
|
-
const r = a[i];
|
|
13
|
-
return r === undefined ? null : r;
|
|
14
|
-
};
|
|
11
|
+
export const at = (i) => (a) => fromUndefined(a[i]);
|
|
15
12
|
export const first = at(0);
|
|
16
13
|
export const last = (a) => at(a.length - 1)(a);
|
|
17
14
|
export const tail = (a) => a.length === 0 ? null : uncheckTail(a);
|
|
@@ -161,6 +161,12 @@ export type Test = readonly ['test', (ctx: TestContext, name: string, expectFail
|
|
|
161
161
|
export declare const test: Func<Test>;
|
|
162
162
|
export type NodeOp = All | Await | Fetch | Fs | Http | Forever | Import | Now | Sandbox | Write | Test;
|
|
163
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>;
|
|
164
170
|
export type NodeOperationMap = ToAsyncOperationMap<NodeOp>;
|
|
165
171
|
/**
|
|
166
172
|
* The environment variables.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import { utf8 } from "../../../text/module.f.js";
|
|
11
|
-
import { do_, pure } 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.
|
|
@@ -65,3 +65,11 @@ export const sandbox = do_('sandbox');
|
|
|
65
65
|
const awaitPromise = do_('await');
|
|
66
66
|
export const awaitIfPromise = (p) => awaitPromise(p).step(([x]) => pure(x));
|
|
67
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));
|
|
@@ -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";
|
package/fs/types/list/proof.f.js
CHANGED
|
@@ -389,5 +389,19 @@ export const proof = {
|
|
|
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;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { map, match, toOption } from "./module.f.js";
|
|
1
|
+
import { fromUndefined, map, match, toOption } from "./module.f.js";
|
|
2
2
|
export const proof = [
|
|
3
3
|
() => {
|
|
4
4
|
const optionSq = map((v) => v * v);
|
|
@@ -29,5 +29,22 @@ export const proof = [
|
|
|
29
29
|
if (double(null) !== -1) {
|
|
30
30
|
throw double(null);
|
|
31
31
|
}
|
|
32
|
-
}
|
|
32
|
+
},
|
|
33
|
+
() => {
|
|
34
|
+
if (fromUndefined(undefined) !== null) {
|
|
35
|
+
throw 0;
|
|
36
|
+
}
|
|
37
|
+
if (fromUndefined(5) !== 5) {
|
|
38
|
+
throw 1;
|
|
39
|
+
}
|
|
40
|
+
if (fromUndefined(0) !== 0) {
|
|
41
|
+
throw 2;
|
|
42
|
+
}
|
|
43
|
+
if (fromUndefined(null) !== null) {
|
|
44
|
+
throw 3;
|
|
45
|
+
}
|
|
46
|
+
if (fromUndefined('') !== '') {
|
|
47
|
+
throw 4;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
33
50
|
];
|
|
@@ -7,12 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { isArray } from "../array/module.f.js";
|
|
9
9
|
import { iterable } from "../list/module.f.js";
|
|
10
|
+
import { fromUndefined, map } from "../nullable/module.f.js";
|
|
10
11
|
import { entries as mapEntries, fromEntries as mapFromEntries } from "../ordered_map/module.f.js";
|
|
11
12
|
const { getOwnPropertyDescriptor, fromEntries: objectFromEntries } = Object;
|
|
12
|
-
export const at = name => object =>
|
|
13
|
-
const r = getOwnPropertyDescriptor(object, name);
|
|
14
|
-
return r === undefined ? null : r.value;
|
|
15
|
-
};
|
|
13
|
+
export const at = name => object => map((d) => d.value)(fromUndefined(getOwnPropertyDescriptor(object, name)));
|
|
16
14
|
export const sort = e => mapEntries(mapFromEntries(e));
|
|
17
15
|
export const fromEntries = e => objectFromEntries(iterable(e));
|
|
18
16
|
export const fromMap = m => fromEntries(mapEntries(m));
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
8
|
export type Equal<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false;
|
|
9
|
-
export type Assert<T extends true> = T;
|
|
10
9
|
/** Functions for emitting TypeScript type expression strings. */
|
|
11
10
|
export type Printer = {
|
|
12
11
|
/** Emits a tuple type: `readonly[A, B]` or `[A, B]` when mutable. */
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const sleep_fail: () => Promise<never>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const sleep: () => Promise<void>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const failing: () => never;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const failing = () => { throw 'intentional failure'; };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const outer: () => unknown;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|