functionalscript 0.22.0 → 0.24.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/module.f.js +2 -1
- package/fs/cas/module.f.d.ts +2 -2
- package/fs/cas/module.f.js +2 -2
- package/fs/cas/proof.f.d.ts +9 -0
- package/fs/cas/proof.f.js +98 -4
- package/fs/ci/config/module.f.d.ts +2 -2
- package/fs/ci/config/module.f.js +2 -2
- package/fs/ci/module.f.d.ts +2 -2
- package/fs/ci/module.f.js +2 -2
- package/fs/ci/proof.f.js +1 -1
- package/fs/crypto/pow/module.f.d.ts +37 -0
- package/fs/crypto/pow/module.f.js +72 -0
- package/fs/crypto/pow/proof.f.d.ts +33 -0
- package/fs/crypto/pow/proof.f.js +161 -0
- package/fs/dev/module.f.d.ts +2 -9
- package/fs/dev/module.f.js +12 -11
- package/fs/dev/proof.f.d.ts +0 -1
- package/fs/dev/proof.f.js +0 -21
- package/fs/dev/version/module.f.d.ts +2 -2
- package/fs/dev/version/module.f.js +2 -2
- package/fs/dev/version/proof.f.js +2 -2
- package/fs/djs/module.f.d.ts +2 -2
- package/fs/djs/module.f.js +2 -2
- package/fs/djs/parser/module.f.d.ts +0 -2
- package/fs/djs/proof.f.js +1 -1
- package/fs/djs/transpiler/module.f.d.ts +2 -2
- package/fs/djs/transpiler/module.f.js +2 -2
- package/fs/djs/transpiler/proof.f.js +1 -1
- package/fs/{types/effects → effects}/module.f.d.ts +1 -1
- package/fs/{types/effects → effects}/module.f.js +1 -1
- package/fs/effects/node/module.d.ts +20 -0
- package/fs/{types/effects → effects}/node/module.f.d.ts +3 -3
- package/fs/{types/effects → effects}/node/module.f.js +1 -1
- package/fs/effects/node/module.js +231 -0
- package/fs/{types/effects → effects}/node/proof.f.js +1 -1
- package/fs/{types/effects → effects}/node/virtual/module.f.d.ts +1 -1
- package/fs/{types/effects → effects}/node/virtual/module.f.js +5 -5
- package/fs/emergent_testing/all.test.js +3 -2
- package/fs/emergent_testing/example.f.d.ts +13 -0
- package/fs/emergent_testing/example.f.js +31 -0
- package/fs/emergent_testing/module.f.d.ts +2 -2
- package/fs/emergent_testing/module.f.js +2 -2
- package/fs/emergent_testing/proof.f.js +4 -4
- package/fs/emergent_testing/scenarios/all.d.ts +1 -1
- package/fs/emergent_testing/scenarios/all.js +1 -3
- package/fs/fjs/module.f.d.ts +1 -1
- package/fs/fjs/module.f.js +1 -1
- package/fs/fjs/module.js +2 -2
- package/fs/path/module.f.d.ts +4 -0
- package/fs/path/module.f.js +5 -1
- package/fs/path/proof.f.d.ts +1 -0
- package/fs/path/proof.f.js +28 -2
- package/fs/text/sgr/module.f.d.ts +2 -17
- package/fs/text/sgr/module.f.js +4 -19
- package/fs/types/bigint/module.f.d.ts +0 -15
- package/fs/types/bigint/module.f.js +0 -15
- package/fs/types/bigint/proof.f.js +2 -1
- package/fs/types/bit_vec/module.f.js +2 -2
- package/fs/types/function/compare/module.f.d.ts +12 -0
- package/fs/types/function/compare/module.f.js +12 -0
- package/fs/types/function/compare/proof.f.js +31 -1
- package/fs/types/function/operator/module.f.d.ts +0 -2
- package/fs/types/function/operator/module.f.js +0 -2
- package/fs/types/function/operator/proof.f.d.ts +0 -2
- package/fs/types/function/operator/proof.f.js +2 -18
- package/fs/types/number/module.f.js +4 -4
- package/fs/website/module.f.d.ts +2 -2
- package/fs/website/module.f.js +2 -2
- package/package.json +1 -1
- package/fs/emergent_testing/module.d.ts +0 -1
- package/fs/emergent_testing/module.js +0 -4
- package/fs/io/module.d.ts +0 -9
- package/fs/io/module.f.d.ts +0 -134
- package/fs/io/module.f.js +0 -113
- package/fs/io/module.js +0 -132
- /package/fs/{types/effects → effects}/mock/module.f.d.ts +0 -0
- /package/fs/{types/effects → effects}/mock/module.f.js +0 -0
- /package/fs/{types/effects → effects}/module.d.ts +0 -0
- /package/fs/{types/effects → effects}/module.js +0 -0
- /package/fs/{types/effects → effects}/node/proof.f.d.ts +0 -0
- /package/fs/{types/effects → effects}/proof.f.d.ts +0 -0
- /package/fs/{types/effects → effects}/proof.f.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { utf8, utf8ToString } from "../../text/module.f.js";
|
|
2
2
|
import { isVec } from "../../types/bit_vec/module.f.js";
|
|
3
|
-
import { all, writeFile } from "../../
|
|
4
|
-
import { emptyState, virtual } from "../../
|
|
3
|
+
import { all, writeFile } from "../../effects/node/module.f.js";
|
|
4
|
+
import { emptyState, virtual } from "../../effects/node/virtual/module.f.js";
|
|
5
5
|
import { updateVersion } from "./module.f.js";
|
|
6
6
|
const version = '0.3.0';
|
|
7
7
|
const x = {
|
package/fs/djs/module.f.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import type { Primitive as JsonPrimitive } from '../json/module.f.ts';
|
|
7
|
-
import { type Effect } from '../
|
|
8
|
-
import { type WriteFile, type ReadFile, type Write } from '../
|
|
7
|
+
import { type Effect } from '../effects/module.f.ts';
|
|
8
|
+
import { type WriteFile, type ReadFile, type Write } from '../effects/node/module.f.ts';
|
|
9
9
|
export type Object = {
|
|
10
10
|
readonly [k in string]: Unknown;
|
|
11
11
|
};
|
package/fs/djs/module.f.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { transpile } from "./transpiler/module.f.js";
|
|
2
2
|
import { stringify, stringifyAsTree } from "./serializer/module.f.js";
|
|
3
3
|
import { sort } from "../types/object/module.f.js";
|
|
4
|
-
import { pure } from "../
|
|
5
|
-
import { writeFile, error, } from "../
|
|
4
|
+
import { pure } from "../effects/module.f.js";
|
|
5
|
+
import { writeFile, error, } from "../effects/node/module.f.js";
|
|
6
6
|
import { utf8 } from "../text/module.f.js";
|
|
7
7
|
export const compile = args => {
|
|
8
8
|
if (args.length < 2) {
|
|
@@ -7,11 +7,9 @@ import { type Result } from '../../types/result/module.f.ts';
|
|
|
7
7
|
import { type List } from '../../types/list/module.f.ts';
|
|
8
8
|
import type { DjsTokenWithMetadata } from '../tokenizer/module.f.ts';
|
|
9
9
|
import { type OrderedMap } from '../../types/ordered_map/module.f.ts';
|
|
10
|
-
import type { Fs } from '../../io/module.f.ts';
|
|
11
10
|
import type { AstModule } from '../ast/module.f.ts';
|
|
12
11
|
import type { TokenMetadata } from '../../js/tokenizer/module.f.ts';
|
|
13
12
|
export type ParseContext = {
|
|
14
|
-
readonly fs: Fs;
|
|
15
13
|
readonly complete: OrderedMap<Result<AstModule, string>>;
|
|
16
14
|
readonly stack: List<string>;
|
|
17
15
|
};
|
package/fs/djs/proof.f.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { compile } from "./module.f.js";
|
|
2
|
-
import { virtual, emptyState } from "../
|
|
2
|
+
import { virtual, emptyState } from "../effects/node/virtual/module.f.js";
|
|
3
3
|
import { isVec } from "../types/bit_vec/module.f.js";
|
|
4
4
|
import { utf8, utf8ToString } from "../text/module.f.js";
|
|
5
5
|
const readOutput = (root, path) => {
|
|
@@ -8,8 +8,8 @@ import { type Result } from '../../types/result/module.f.ts';
|
|
|
8
8
|
import { type List } from '../../types/list/module.f.ts';
|
|
9
9
|
import { type OrderedMap } from '../../types/ordered_map/module.f.ts';
|
|
10
10
|
import { type ParseError } from '../parser/module.f.ts';
|
|
11
|
-
import { type Effect } from '../../
|
|
12
|
-
import { type ReadFile } from '../../
|
|
11
|
+
import { type Effect } from '../../effects/module.f.ts';
|
|
12
|
+
import { type ReadFile } from '../../effects/node/module.f.ts';
|
|
13
13
|
/**
|
|
14
14
|
* State threaded through the recursive transpilation of a DJS module graph.
|
|
15
15
|
*
|
|
@@ -12,8 +12,8 @@ import { stringToList } from "../../text/utf16/module.f.js";
|
|
|
12
12
|
import { concat as pathConcat } from "../../path/module.f.js";
|
|
13
13
|
import { parseFromTokens } from "../parser/module.f.js";
|
|
14
14
|
import { run } from "../ast/module.f.js";
|
|
15
|
-
import { foldStep, pure } from "../../
|
|
16
|
-
import { readFile } from "../../
|
|
15
|
+
import { foldStep, pure } from "../../effects/module.f.js";
|
|
16
|
+
import { readFile } from "../../effects/node/module.f.js";
|
|
17
17
|
import { utf8ToString } from "../../text/module.f.js";
|
|
18
18
|
const mapDjs = context => path => {
|
|
19
19
|
const res = at(path)(context.complete);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { sort } from "../../types/object/module.f.js";
|
|
2
2
|
import { transpile } from "./module.f.js";
|
|
3
3
|
import { stringifyAsTree } from "../serializer/module.f.js";
|
|
4
|
-
import { virtual, emptyState } from "../../
|
|
4
|
+
import { virtual, emptyState } from "../../effects/node/virtual/module.f.js";
|
|
5
5
|
import { utf8 } from "../../text/module.f.js";
|
|
6
6
|
const run = (root) => (path) => {
|
|
7
7
|
const [_, result] = virtual({ ...emptyState, root })(transpile(path));
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { type List } from '../list/module.f.ts';
|
|
6
|
+
import { type List } from '../types/list/module.f.ts';
|
|
7
7
|
export type Operation = readonly [string, (..._: readonly never[]) => unknown];
|
|
8
8
|
export type Effect<O extends Operation, T> = {
|
|
9
9
|
value: Value<O, T>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type NodeProgram } from './module.f.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Runs a `NodeProgram` against the real Node `io` and process arguments,
|
|
4
|
+
* resolving to its exit code **without** terminating the process.
|
|
5
|
+
*
|
|
6
|
+
* Use this when the caller must stay alive afterwards — e.g. when proofs are
|
|
7
|
+
* registered under an external test runner (Node `--test`, Bun, Playwright)
|
|
8
|
+
* that owns the process lifecycle. For a standalone CLI entry point that should
|
|
9
|
+
* exit with the program's code, use {@link run} instead.
|
|
10
|
+
*/
|
|
11
|
+
export declare const runEffect: (p: NodeProgram) => Promise<number>;
|
|
12
|
+
/**
|
|
13
|
+
* CLI entry point: runs a `NodeProgram` via {@link runEffect}, then calls
|
|
14
|
+
* `process.exit` with its exit code. The `Promise<never>` return type reflects
|
|
15
|
+
* that control never returns to the caller — the process terminates.
|
|
16
|
+
*
|
|
17
|
+
* A `bin` script can simply
|
|
18
|
+
* `import { run } from '.../fs/effects/node/module.js'; await run(main)`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const run: (p: NodeProgram) => Promise<never>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Vec } from '../../bit_vec/module.f.ts';
|
|
2
|
-
import type { Nominal } from '../../nominal/module.f.ts';
|
|
3
|
-
import type { Result } from '../../result/module.f.ts';
|
|
1
|
+
import type { Vec } from '../../types/bit_vec/module.f.ts';
|
|
2
|
+
import type { Nominal } from '../../types/nominal/module.f.ts';
|
|
3
|
+
import type { Result } from '../../types/result/module.f.ts';
|
|
4
4
|
import { type Effect, type Func, type Operation, type ToAsyncOperationMap } from '../module.f.ts';
|
|
5
5
|
export type IoResult<T> = Result<T, unknown>;
|
|
6
6
|
export type All = ['all', <T>(...effects: Effect<never, T>[]) => readonly T[]];
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import http from 'node:http';
|
|
10
|
+
import childProcess from 'node:child_process';
|
|
11
|
+
import fs from 'node:fs';
|
|
12
|
+
import process from 'node:process';
|
|
13
|
+
import { once } from 'node:events';
|
|
14
|
+
import * as testContext from 'node:test';
|
|
15
|
+
import { concat } from "../../path/module.f.js";
|
|
16
|
+
import { normalize } from "../../path/module.f.js";
|
|
17
|
+
import {} from "../module.f.js";
|
|
18
|
+
import { asyncRun } from "../module.js";
|
|
19
|
+
import {} from "./module.f.js";
|
|
20
|
+
import { asBase, asNominal } from "../../types/nominal/module.f.js";
|
|
21
|
+
import { error, ok } from "../../types/result/module.f.js";
|
|
22
|
+
import { fromVec, listToVec, toVec } from "../../types/uint8array/module.f.js";
|
|
23
|
+
const tc = async (f) => {
|
|
24
|
+
try {
|
|
25
|
+
return ok(await f());
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
return error(e);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const collect = async (v) => {
|
|
32
|
+
let result = [];
|
|
33
|
+
for await (const a of v) {
|
|
34
|
+
result = [...result, a];
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
const fromIo = ({ fs: { promises: { mkdir, readFile, readdir, writeFile, rm, access } }, fetch, http: { createServer }, childProcess, asyncImport, now: ioNow, sandbox, write, await: awaitPromise, }) => {
|
|
39
|
+
const result = asyncRun({
|
|
40
|
+
all: async (...effects) => await Promise.all(effects.map(result)),
|
|
41
|
+
fetch: async (url) => tc(async () => {
|
|
42
|
+
const response = await fetch(url);
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(`Fetch error: ${response.status} ${response.statusText}`);
|
|
45
|
+
}
|
|
46
|
+
return toVec(new Uint8Array(await response.arrayBuffer()));
|
|
47
|
+
}),
|
|
48
|
+
mkdir: (...p) => tc(async () => { await mkdir(...p); }),
|
|
49
|
+
readFile: path => tc(async () => toVec(await readFile(path))),
|
|
50
|
+
readdir: (path, r) => tc(async () => (await readdir(path, { ...r, withFileTypes: true }))
|
|
51
|
+
.map(v => ({
|
|
52
|
+
name: v.name,
|
|
53
|
+
parentPath: normalize(v.parentPath),
|
|
54
|
+
isFile: v.isFile()
|
|
55
|
+
}))),
|
|
56
|
+
writeFile: (path, data) => tc(() => writeFile(path, fromVec(data))),
|
|
57
|
+
rm: path => tc(() => rm(path)),
|
|
58
|
+
access: path => tc(() => access(path)),
|
|
59
|
+
import: path => tc(() => asyncImport(path)),
|
|
60
|
+
exec: (command, stdin) => new Promise(resolve => {
|
|
61
|
+
const child = childProcess.exec(command, (e, stdout, stderr) => resolve(e !== null ? ['error', e] : ok({ stdout, stderr })));
|
|
62
|
+
child.stdin?.end(stdin);
|
|
63
|
+
}),
|
|
64
|
+
createServer: async (requestListener) => {
|
|
65
|
+
const erl = requestListener;
|
|
66
|
+
const nodeRl = async (req, res) => {
|
|
67
|
+
const reqBody = await collect(req);
|
|
68
|
+
const { method, url, headers } = req;
|
|
69
|
+
const { status, headers: outHeaders, body: outBody } = await result(erl({
|
|
70
|
+
method,
|
|
71
|
+
url,
|
|
72
|
+
headers,
|
|
73
|
+
body: listToVec(reqBody)
|
|
74
|
+
}));
|
|
75
|
+
res
|
|
76
|
+
.writeHead(status, outHeaders)
|
|
77
|
+
.end(fromVec(outBody));
|
|
78
|
+
};
|
|
79
|
+
const server = asNominal(createServer(nodeRl));
|
|
80
|
+
return server;
|
|
81
|
+
},
|
|
82
|
+
listen: async (server, port) => {
|
|
83
|
+
const s = asBase(server);
|
|
84
|
+
s.listen(port);
|
|
85
|
+
},
|
|
86
|
+
forever: () => new Promise(() => { }),
|
|
87
|
+
now: async () => ioNow(),
|
|
88
|
+
sandbox,
|
|
89
|
+
await: awaitPromise,
|
|
90
|
+
write,
|
|
91
|
+
test: async (ctx, name, expectFailure, test) => ctx.test(name, { expectFailure }, async (t) => result(test(t))),
|
|
92
|
+
});
|
|
93
|
+
return result;
|
|
94
|
+
};
|
|
95
|
+
const runProgram = (io) => {
|
|
96
|
+
const { process: { env, stdout, stderr }, testContext, bunTestContext, playwrightTestContext, engine } = io;
|
|
97
|
+
const std = { stdout, stderr };
|
|
98
|
+
const f = fromIo(io);
|
|
99
|
+
return args => {
|
|
100
|
+
const options = { args, env, std, testContext, bunTestContext, playwrightTestContext, engine };
|
|
101
|
+
return program => f(program(options));
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
const isPlaywright = 'PLAYWRIGHT_TEST' in (process?.env ?? {});
|
|
105
|
+
const pwTest = isPlaywright
|
|
106
|
+
? (await import('@playwright/test')).test
|
|
107
|
+
: undefined;
|
|
108
|
+
const inlineTest = async (name, { expectFailure }, fn) => {
|
|
109
|
+
if (expectFailure) {
|
|
110
|
+
try {
|
|
111
|
+
await fn(inlineContext);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
throw new Error(`expected to throw: ${name}`);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
await fn(inlineContext);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const inlineContext = { test: inlineTest };
|
|
123
|
+
const wrapInlineTest = (register) => ({
|
|
124
|
+
test: (name, opts, fn) => register(name, () => inlineTest(name, opts, fn))
|
|
125
|
+
});
|
|
126
|
+
const bunTestContext = wrapInlineTest(testContext.test);
|
|
127
|
+
const playwrightTestContext = wrapInlineTest(pwTest);
|
|
128
|
+
const prefix = 'file:///';
|
|
129
|
+
const { now } = Date;
|
|
130
|
+
/** Maps `WriteConsoles` names to the corresponding Node.js writable streams. */
|
|
131
|
+
const streams = {
|
|
132
|
+
stdout: process.stdout,
|
|
133
|
+
stderr: process.stderr,
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Writes `data` to `stream` respecting Node.js backpressure.
|
|
137
|
+
*
|
|
138
|
+
* `stream.write()` returns `false` when the internal buffer is full; the data
|
|
139
|
+
* is already buffered at that point (no retry needed) but the caller must not
|
|
140
|
+
* issue more writes until the `'drain'` event fires. Waiting here throttles the
|
|
141
|
+
* producer to the speed of the OS consumer, preventing unbounded memory growth
|
|
142
|
+
* when many large messages arrive faster than they can be flushed.
|
|
143
|
+
*
|
|
144
|
+
* When the buffer is not full `write()` returns `true` and we return
|
|
145
|
+
* immediately, so large computations with occasional prints never stall.
|
|
146
|
+
*
|
|
147
|
+
* @see {@link https://nodejs.org/api/stream.html#writablewritechunk}
|
|
148
|
+
*/
|
|
149
|
+
const writeAll = async (stream, data) => {
|
|
150
|
+
if (!stream.write(data)) {
|
|
151
|
+
await once(stream, 'drain');
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const asyncImport = (v) => import(__rewriteRelativeImportExtension(v));
|
|
155
|
+
const tryCatch = f => {
|
|
156
|
+
try {
|
|
157
|
+
return ok(f());
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
return error(e);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const awaitPromise = async (p) => [p instanceof Promise ? await p : p];
|
|
164
|
+
const io = {
|
|
165
|
+
console,
|
|
166
|
+
fs,
|
|
167
|
+
process,
|
|
168
|
+
asyncImport: (v) => {
|
|
169
|
+
const s0 = v.includes(':') || v.startsWith('/') ? v : concat(process.cwd())(v);
|
|
170
|
+
const s1 = s0.startsWith(prefix) ? s0 : `${prefix}${s0}`;
|
|
171
|
+
return asyncImport(s1);
|
|
172
|
+
},
|
|
173
|
+
performance,
|
|
174
|
+
fetch,
|
|
175
|
+
tryCatch,
|
|
176
|
+
asyncTryCatch: async (f) => {
|
|
177
|
+
try {
|
|
178
|
+
return ok(await f());
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
return error(e);
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
http,
|
|
185
|
+
childProcess,
|
|
186
|
+
now,
|
|
187
|
+
sandbox: async (f) => {
|
|
188
|
+
let result;
|
|
189
|
+
let after;
|
|
190
|
+
const before = performance.now();
|
|
191
|
+
try {
|
|
192
|
+
let p = f();
|
|
193
|
+
after = performance.now();
|
|
194
|
+
if (p instanceof Promise) {
|
|
195
|
+
p = await p;
|
|
196
|
+
after = performance.now();
|
|
197
|
+
}
|
|
198
|
+
result = ok(p);
|
|
199
|
+
}
|
|
200
|
+
catch (e) {
|
|
201
|
+
after = performance.now();
|
|
202
|
+
result = error(e);
|
|
203
|
+
}
|
|
204
|
+
return { result, duration: after - before };
|
|
205
|
+
},
|
|
206
|
+
write: (stream, data) => writeAll(streams[stream], fromVec(data)),
|
|
207
|
+
await: awaitPromise,
|
|
208
|
+
testContext,
|
|
209
|
+
bunTestContext,
|
|
210
|
+
playwrightTestContext,
|
|
211
|
+
engine: isPlaywright ? 'playwright' : 'Bun' in globalThis ? 'bun' : 'node',
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* Runs a `NodeProgram` against the real Node `io` and process arguments,
|
|
215
|
+
* resolving to its exit code **without** terminating the process.
|
|
216
|
+
*
|
|
217
|
+
* Use this when the caller must stay alive afterwards — e.g. when proofs are
|
|
218
|
+
* registered under an external test runner (Node `--test`, Bun, Playwright)
|
|
219
|
+
* that owns the process lifecycle. For a standalone CLI entry point that should
|
|
220
|
+
* exit with the program's code, use {@link run} instead.
|
|
221
|
+
*/
|
|
222
|
+
export const runEffect = runProgram(io)(io.process.argv.slice(2));
|
|
223
|
+
/**
|
|
224
|
+
* CLI entry point: runs a `NodeProgram` via {@link runEffect}, then calls
|
|
225
|
+
* `process.exit` with its exit code. The `Promise<never>` return type reflects
|
|
226
|
+
* that control never returns to the caller — the process terminates.
|
|
227
|
+
*
|
|
228
|
+
* A `bin` script can simply
|
|
229
|
+
* `import { run } from '.../fs/effects/node/module.js'; await run(main)`.
|
|
230
|
+
*/
|
|
231
|
+
export const run = async (p) => process.exit(await runEffect(p));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { empty, isVec, uint, vec8 } from "../../bit_vec/module.f.js";
|
|
1
|
+
import { empty, isVec, uint, vec8 } from "../../types/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";
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import { parse } from "
|
|
8
|
-
import { utf8ToString } from "
|
|
9
|
-
import { isVec } from "../../../bit_vec/module.f.js";
|
|
10
|
-
import { error, ok } from "../../../result/module.f.js";
|
|
6
|
+
import { todo } from "../../../asserts/module.f.js";
|
|
7
|
+
import { parse } from "../../../path/module.f.js";
|
|
8
|
+
import { utf8ToString } from "../../../text/module.f.js";
|
|
9
|
+
import { isVec } from "../../../types/bit_vec/module.f.js";
|
|
10
|
+
import { error, ok } from "../../../types/result/module.f.js";
|
|
11
11
|
import { run } from "../../mock/module.f.js";
|
|
12
12
|
export const emptyState = {
|
|
13
13
|
stdout: '',
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const add: (a: number, b: number) => number;
|
|
2
|
+
export declare const mul: (a: number, b: number) => number;
|
|
3
|
+
export declare const sqr: (a: number) => number;
|
|
4
|
+
export declare const todo: () => never;
|
|
5
|
+
export declare const proof: {
|
|
6
|
+
addTest: () => void;
|
|
7
|
+
mulTest: (() => void)[];
|
|
8
|
+
throw: {
|
|
9
|
+
todo: () => never;
|
|
10
|
+
divByZero: () => bigint;
|
|
11
|
+
};
|
|
12
|
+
generateSqrTests: () => (() => void)[];
|
|
13
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const add = (a, b) => a + b;
|
|
2
|
+
export const mul = (a, b) => a * b;
|
|
3
|
+
export const sqr = (a) => mul(a, a);
|
|
4
|
+
export const todo = () => { throw "not implemented"; };
|
|
5
|
+
const checkMul = (a, b, r) => {
|
|
6
|
+
if (mul(a, b) !== r) {
|
|
7
|
+
throw `mul(${a}, ${b}) !== ${r}`;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
export const proof = {
|
|
11
|
+
addTest: () => {
|
|
12
|
+
if (add(2, 2) !== 4) {
|
|
13
|
+
throw "something wrong with the math";
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
mulTest: [
|
|
17
|
+
() => checkMul(2, 3, 6),
|
|
18
|
+
() => checkMul(22, 34, 748),
|
|
19
|
+
() => checkMul(-2, 3, -6),
|
|
20
|
+
() => checkMul(-2, -3, 6),
|
|
21
|
+
],
|
|
22
|
+
throw: {
|
|
23
|
+
todo,
|
|
24
|
+
divByZero: () => 5n / 0n,
|
|
25
|
+
},
|
|
26
|
+
generateSqrTests: () => [1, 2, 3, 5].map(a => () => {
|
|
27
|
+
if (sqr(a) !== a * a) {
|
|
28
|
+
throw `sqr(${a})`;
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
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 '../
|
|
1
|
+
import { type All, type Await, type NodeProgram, type NodeProgramOptions, type Program, type Sandbox, type SandboxResult, type Test, type TestContext, type Write } from '../effects/node/module.f.ts';
|
|
2
|
+
import { type Effect, type Operation } from '../effects/module.f.ts';
|
|
3
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;
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
13
|
import { reset, fgGreen, fgRed, bold, csiWrite } from "../text/sgr/module.f.js";
|
|
14
|
-
import { all, awaitIfPromise, sandbox, test } from "../
|
|
15
|
-
import { pure } from "../
|
|
14
|
+
import { all, awaitIfPromise, sandbox, test } from "../effects/node/module.f.js";
|
|
15
|
+
import { pure } from "../effects/module.f.js";
|
|
16
16
|
import { loadModuleMap, shouldLoad } from "../dev/module.f.js";
|
|
17
17
|
import { invert } from "../types/result/module.f.js";
|
|
18
18
|
const addPass = (delta) => (ts) => ({ ...ts, time: ts.time + delta, pass: ts.pass + 1 });
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { pure } from "../
|
|
2
|
-
import { emptyState } from "../
|
|
3
|
-
import { virtual } from "../
|
|
1
|
+
import { pure } from "../effects/module.f.js";
|
|
2
|
+
import { emptyState } from "../effects/node/virtual/module.f.js";
|
|
3
|
+
import { virtual } from "../effects/node/virtual/module.f.js";
|
|
4
4
|
import { assert, assertEq, todo } from "../asserts/module.f.js";
|
|
5
5
|
import { testAll, defaultReporter, fmtPath, fmtTerm, fmtImport, ghEscape, isInteger, isIdentifier, registerModule, defaultTest, } from "./module.f.js";
|
|
6
|
-
import { run as mockRun } from "../
|
|
6
|
+
import { run as mockRun } from "../effects/mock/module.f.js";
|
|
7
7
|
import { shouldLoad } from "../dev/module.f.js";
|
|
8
8
|
const makeReporter = () => {
|
|
9
9
|
const events = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import '../all.test.ts';
|
package/fs/fjs/module.f.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type NodeProgram } from '../
|
|
1
|
+
import { type NodeProgram } from '../effects/node/module.f.ts';
|
|
2
2
|
export declare const main: NodeProgram;
|
package/fs/fjs/module.f.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { compile } from "../djs/module.f.js";
|
|
7
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_, errorExit } from "../
|
|
9
|
+
import { import_, errorExit } from "../effects/node/module.f.js";
|
|
10
10
|
export const main = options => {
|
|
11
11
|
const [command, ...rest] = options.args;
|
|
12
12
|
switch (command) {
|
package/fs/fjs/module.js
CHANGED
package/fs/path/module.f.d.ts
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import type { Reduce, Unary } from '../types/function/operator/module.f.ts';
|
|
7
|
+
/**
|
|
8
|
+
* Converts Windows separators (`\`) to POSIX separators (`/`).
|
|
9
|
+
*/
|
|
10
|
+
export declare const toPosix: (path: string) => string;
|
|
7
11
|
/**
|
|
8
12
|
* Splits a path into normalized segments.
|
|
9
13
|
*
|
package/fs/path/module.f.js
CHANGED
|
@@ -21,6 +21,10 @@ const foldNormalizeOp = input => state => {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Converts Windows separators (`\`) to POSIX separators (`/`).
|
|
26
|
+
*/
|
|
27
|
+
export const toPosix = (path) => path.replaceAll('\\', '/');
|
|
24
28
|
/**
|
|
25
29
|
* Splits a path into normalized segments.
|
|
26
30
|
*
|
|
@@ -29,7 +33,7 @@ const foldNormalizeOp = input => state => {
|
|
|
29
33
|
* separators are converted to POSIX separators.
|
|
30
34
|
*/
|
|
31
35
|
export const parse = (path) => {
|
|
32
|
-
const split = path
|
|
36
|
+
const split = toPosix(path).split('/');
|
|
33
37
|
return toArray(fold(foldNormalizeOp)([])(split));
|
|
34
38
|
};
|
|
35
39
|
/**
|
package/fs/path/proof.f.d.ts
CHANGED
package/fs/path/proof.f.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { concat, normalize, relativize } from "./module.f.js";
|
|
1
|
+
import { concat, normalize, relativize, toPosix } from "./module.f.js";
|
|
2
2
|
const normalizeTest = [
|
|
3
3
|
() => {
|
|
4
4
|
const norm = normalize("dir/file.json");
|
|
@@ -65,4 +65,30 @@ const relativizeTest = [
|
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
];
|
|
68
|
-
|
|
68
|
+
const toPosixTest = [
|
|
69
|
+
() => {
|
|
70
|
+
const p = toPosix('a\\b\\c');
|
|
71
|
+
if (p !== 'a/b/c') {
|
|
72
|
+
throw p;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
() => {
|
|
76
|
+
const p = toPosix('a/b/c');
|
|
77
|
+
if (p !== 'a/b/c') {
|
|
78
|
+
throw p;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
() => {
|
|
82
|
+
const p = toPosix('C:\\Users\\x');
|
|
83
|
+
if (p !== 'C:/Users/x') {
|
|
84
|
+
throw p;
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
() => {
|
|
88
|
+
const p = toPosix('');
|
|
89
|
+
if (p !== '') {
|
|
90
|
+
throw p;
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
export const proof = { normalizeTest, concatTest, relativizeTest, toPosixTest };
|