functionalscript 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/fs/cas/module.f.js +9 -17
- package/fs/ci/config/module.f.d.ts +1 -1
- package/fs/ci/config/module.f.js +1 -1
- package/fs/ci/deno/module.f.js +1 -1
- package/fs/ci/module.f.js +39 -19
- package/fs/ci/proof.f.d.ts +9 -0
- package/fs/ci/proof.f.js +58 -6
- package/fs/dev/module.f.d.ts +6 -2
- package/fs/dev/module.f.js +3 -28
- package/fs/dev/package_json/module.f.d.ts +16 -0
- package/fs/dev/package_json/module.f.js +21 -0
- package/fs/dev/package_json/proof.f.d.ts +5 -0
- package/fs/dev/package_json/proof.f.js +23 -0
- package/fs/djs/tokenizer-new/proof.f.d.ts +4 -0
- package/fs/djs/tokenizer-new/proof.f.js +167 -122
- package/fs/effects/module.f.d.ts +0 -1
- package/fs/effects/module.f.js +0 -1
- package/fs/effects/node/module.f.js +2 -4
- package/package.json +6 -7
- package/fs/dev/index/module.f.d.ts +0 -1
- package/fs/dev/index/module.f.js +0 -8
- package/fs/dev/version/module.f.d.ts +0 -3
- package/fs/dev/version/module.f.js +0 -27
- package/fs/dev/version/proof.f.d.ts +0 -3
- package/fs/dev/version/proof.f.js +0 -100
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# FunctionalScript
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/functionalscript)
|
|
4
|
-
[](https://jsr.io/@functionalscript/functionalscript)
|
|
5
4
|
|
|
6
5
|
FunctionalScript is a safe, purely functional programming language and a strict subset of
|
|
7
6
|
[ECMAScript](https://en.wikipedia.org/wiki/ECMAScript)/[JavaScript](https://en.wikipedia.org/wiki/JavaScript). It's inspired by
|
package/fs/cas/module.f.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
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
|
-
import {
|
|
9
|
+
import { forEachStep, pure } from "../effects/module.f.js";
|
|
10
10
|
import { errorExit, log, mkdir, readdir, readFile, writeFile } from "../effects/node/module.f.js";
|
|
11
11
|
import { dispatch } from "../cli/module.f.js";
|
|
12
12
|
import { toOption } from "../types/nullable/module.f.js";
|
|
@@ -25,23 +25,20 @@ const toPath = (key) => {
|
|
|
25
25
|
* Creates a filesystem-backed key/value store under the provided root path.
|
|
26
26
|
*/
|
|
27
27
|
export const fileKvStore = (path) => ({
|
|
28
|
-
read: (key) =>
|
|
29
|
-
.step(() => readFile(toPath(key)))
|
|
28
|
+
read: (key) => readFile(toPath(key))
|
|
30
29
|
.step(([status, data]) => pure(status === 'error' ? undefined : data)),
|
|
31
30
|
write: (key, value) => {
|
|
32
31
|
const p = toPath(key);
|
|
33
32
|
const parts = parse(p);
|
|
34
33
|
const dir = `${path}/${parts.slice(0, -1).join('/')}`;
|
|
35
34
|
// TODO: error handling
|
|
36
|
-
return
|
|
37
|
-
.step(() => mkdir(dir, { recursive: true }))
|
|
35
|
+
return mkdir(dir, { recursive: true })
|
|
38
36
|
.step(() => writeFile(`${path}/${p}`, value))
|
|
39
37
|
.step(() => pure(undefined));
|
|
40
38
|
},
|
|
41
39
|
list: () =>
|
|
42
40
|
// TODO: remove unwrap
|
|
43
|
-
|
|
44
|
-
.step(() => readdir('.cas', { recursive: true }))
|
|
41
|
+
readdir('.cas', { recursive: true })
|
|
45
42
|
.step(r => pure(unwrap(r).flatMap(({ name, parentPath, isFile }) => toOption(isFile
|
|
46
43
|
? cBase32ToVec(parentPath.substring(prefix.length).replaceAll('/', '') + name)
|
|
47
44
|
: null)))),
|
|
@@ -55,8 +52,7 @@ export const cas = (sha2) => {
|
|
|
55
52
|
read,
|
|
56
53
|
write: (value) => {
|
|
57
54
|
const hash = compute([value]);
|
|
58
|
-
return
|
|
59
|
-
.step(() => write(hash, value))
|
|
55
|
+
return write(hash, value)
|
|
60
56
|
.step(() => pure(hash));
|
|
61
57
|
},
|
|
62
58
|
list,
|
|
@@ -72,8 +68,7 @@ export const main = (options) => {
|
|
|
72
68
|
if (path === undefined || rest.length !== 0) {
|
|
73
69
|
return errorExit("'cas add' expects one parameter");
|
|
74
70
|
}
|
|
75
|
-
return
|
|
76
|
-
.step(() => readFile(path))
|
|
71
|
+
return readFile(path)
|
|
77
72
|
.step(v => c.write(unwrap(v)))
|
|
78
73
|
.step(hash => log(vecToCBase32(hash)))
|
|
79
74
|
.step(() => pure(0));
|
|
@@ -90,13 +85,11 @@ export const main = (options) => {
|
|
|
90
85
|
if (hash === null) {
|
|
91
86
|
return errorExit(`invalid hash format: ${hashCBase32}`);
|
|
92
87
|
}
|
|
93
|
-
return
|
|
94
|
-
.step(() => c.read(hash))
|
|
88
|
+
return c.read(hash)
|
|
95
89
|
.step(v => {
|
|
96
90
|
const result = v === undefined
|
|
97
91
|
? errorExit(`no such hash: ${hashCBase32}`)
|
|
98
|
-
:
|
|
99
|
-
.step(() => writeFile(path, v))
|
|
92
|
+
: writeFile(path, v)
|
|
100
93
|
.step(() => pure(0));
|
|
101
94
|
return result;
|
|
102
95
|
});
|
|
@@ -105,8 +98,7 @@ export const main = (options) => {
|
|
|
105
98
|
{
|
|
106
99
|
names: ['list'],
|
|
107
100
|
description: 'List all stored content hashes',
|
|
108
|
-
handler: () =>
|
|
109
|
-
.step(() => c.list())
|
|
101
|
+
handler: () => c.list()
|
|
110
102
|
.step(forEachStep(j => log(vecToCBase32(j))))
|
|
111
103
|
.step(() => pure(0)),
|
|
112
104
|
},
|
|
@@ -28,7 +28,7 @@ export declare const node: {
|
|
|
28
28
|
};
|
|
29
29
|
export declare const wasmtime = "45.0.0";
|
|
30
30
|
export declare const wasmer = "7.1.0";
|
|
31
|
-
export declare const tsgo = "7.0.0-dev.
|
|
31
|
+
export declare const tsgo = "7.0.0-dev.20260606.1";
|
|
32
32
|
export declare const actions: {
|
|
33
33
|
readonly 'actions/checkout': "v6";
|
|
34
34
|
readonly 'actions/setup-node': "v6";
|
package/fs/ci/config/module.f.js
CHANGED
|
@@ -36,7 +36,7 @@ export const wasmtime = '45.0.0';
|
|
|
36
36
|
// https://github.com/wasmerio/wasmer/releases
|
|
37
37
|
export const wasmer = '7.1.0';
|
|
38
38
|
// https://www.npmjs.com/package/@typescript/native-preview?activeTab=versions
|
|
39
|
-
export const tsgo = '7.0.0-dev.
|
|
39
|
+
export const tsgo = '7.0.0-dev.20260606.1';
|
|
40
40
|
// GitHub Action versions used by CI step builders. The key is the action
|
|
41
41
|
// `owner/name`; call sites compose the full ref as
|
|
42
42
|
// `` `${name}@${actions[name]}` ``.
|
package/fs/ci/deno/module.f.js
CHANGED
|
@@ -8,7 +8,7 @@ import { deno } from "../config/module.f.js";
|
|
|
8
8
|
import { clean, install, test, uses } from "../common/module.f.js";
|
|
9
9
|
export const denoSteps = (extra) => clean([
|
|
10
10
|
install(uses('denoland/setup-deno', { 'deno-version': deno })),
|
|
11
|
-
test({ run: 'deno install' }),
|
|
11
|
+
test({ run: 'deno install --frozen' }),
|
|
12
12
|
test({ run: 'deno task test' }),
|
|
13
13
|
...extra,
|
|
14
14
|
]);
|
package/fs/ci/module.f.js
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { utf8 } from "../text/module.f.js";
|
|
6
|
+
import { utf8, utf8ToString } from "../text/module.f.js";
|
|
7
|
+
import { validatePackageJsonText } from "../dev/package_json/module.f.js";
|
|
7
8
|
import { pure } from "../effects/module.f.js";
|
|
8
|
-
import { access, writeFile } from "../effects/node/module.f.js";
|
|
9
|
+
import { access, readFile, writeFile } from "../effects/node/module.f.js";
|
|
9
10
|
import { images } from "./config/module.f.js";
|
|
10
11
|
import { architecture, findTgz, os, test, toSteps } from "./common/module.f.js";
|
|
11
12
|
import { rustSteps } from "./rust/module.f.js";
|
|
@@ -24,6 +25,20 @@ const job = (rust, nodeExtra, denoExtra, bunExtra) => (o) => (a) => {
|
|
|
24
25
|
];
|
|
25
26
|
return [id, { 'runs-on': image, steps: toSteps(result) }];
|
|
26
27
|
};
|
|
28
|
+
const functionalscriptPackageName = 'functionalscript';
|
|
29
|
+
const fallbackPackageInfo = {
|
|
30
|
+
name: functionalscriptPackageName,
|
|
31
|
+
functionalscript: false,
|
|
32
|
+
};
|
|
33
|
+
const packageInfoFromPackageJson = ({ name }) => name !== undefined
|
|
34
|
+
? { name, functionalscript: name === functionalscriptPackageName }
|
|
35
|
+
: fallbackPackageInfo;
|
|
36
|
+
const packageInfoFromText = (text) => {
|
|
37
|
+
const result = validatePackageJsonText(text);
|
|
38
|
+
return result[0] === 'ok' ? packageInfoFromPackageJson(result[1]) : fallbackPackageInfo;
|
|
39
|
+
};
|
|
40
|
+
const readPackageInfo = readFile('package.json')
|
|
41
|
+
.step(result => pure(result[0] === 'ok' ? packageInfoFromText(utf8ToString(result[1])) : fallbackPackageInfo));
|
|
27
42
|
export const ci = ({ nodeExtra, denoExtra, bunExtra }) => access('Cargo.toml').step(result => {
|
|
28
43
|
const rust = result[0] === 'ok';
|
|
29
44
|
const jobs = {
|
|
@@ -42,21 +57,26 @@ export const ci = ({ nodeExtra, denoExtra, bunExtra }) => access('Cargo.toml').s
|
|
|
42
57
|
return writeFile('.github/workflows/ci.yml', utf8(JSON.stringify(gha, null, ' ')))
|
|
43
58
|
.step(() => pure(0));
|
|
44
59
|
});
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
const demoCompile = [
|
|
61
|
+
test({ run: 'fjs compile issues/demo/data/tree.json _tree.f.js' }),
|
|
62
|
+
test({ run: 'fjs t' }),
|
|
63
|
+
];
|
|
64
|
+
const denoDemoCompile = [
|
|
65
|
+
test({ run: 'deno task fjs compile issues/demo/data/tree.json _tree.f.js' }),
|
|
66
|
+
test({ run: 'deno task fjs t' }),
|
|
67
|
+
];
|
|
68
|
+
const bunDemoCompile = [
|
|
69
|
+
test({ run: 'bun ./fs/fjs/module.ts t' }),
|
|
70
|
+
];
|
|
71
|
+
const defaultNodeExtra = ({ name, functionalscript }) => (o) => [
|
|
72
|
+
test({ run: 'npm pack' }),
|
|
73
|
+
test({ run: `npm install -g ${findTgz(o)}` }),
|
|
74
|
+
...(functionalscript ? demoCompile : []),
|
|
75
|
+
test({ run: `npm uninstall ${name} -g` }),
|
|
76
|
+
];
|
|
77
|
+
const defaultEffect = (info) => ci({
|
|
78
|
+
nodeExtra: defaultNodeExtra(info),
|
|
79
|
+
denoExtra: info.functionalscript ? [...denoDemoCompile] : [],
|
|
80
|
+
bunExtra: info.functionalscript ? bunDemoCompile : [],
|
|
61
81
|
});
|
|
62
|
-
export const main = () => defaultEffect;
|
|
82
|
+
export const main = () => readPackageInfo.step(defaultEffect);
|
package/fs/ci/proof.f.d.ts
CHANGED
|
@@ -5,4 +5,13 @@ export declare const proof: {
|
|
|
5
5
|
allOs: () => void;
|
|
6
6
|
osSpecific: () => void;
|
|
7
7
|
};
|
|
8
|
+
defaultSetup: {
|
|
9
|
+
functionalscriptDemo: () => void;
|
|
10
|
+
otherPackageNoDemo: () => void;
|
|
11
|
+
uninstallPackageName: () => void;
|
|
12
|
+
malformedPackageJsonFallback: () => void;
|
|
13
|
+
missingPackageJsonFallback: () => void;
|
|
14
|
+
missingNameFallback: () => void;
|
|
15
|
+
nonObjectFallback: () => void;
|
|
16
|
+
};
|
|
8
17
|
};
|
package/fs/ci/proof.f.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ci } from "./module.f.js";
|
|
2
|
-
import { utf8ToString } from "../text/module.f.js";
|
|
1
|
+
import { ci, main } from "./module.f.js";
|
|
2
|
+
import { utf8, utf8ToString } from "../text/module.f.js";
|
|
3
3
|
import { empty as emptyVec, isVec } from "../types/bit_vec/module.f.js";
|
|
4
4
|
import { test, parseGitHubAction } from "./common/module.f.js";
|
|
5
5
|
import { assert } from "../asserts/module.f.js";
|
|
@@ -8,16 +8,15 @@ import { parse as jsonParse } from "../json/module.f.js";
|
|
|
8
8
|
import { unwrap } from "../types/result/module.f.js";
|
|
9
9
|
const hasRun = (cmd) => (gha) => Object.values(gha.jobs).some(job => job.steps.some(step => step.run?.includes(cmd)));
|
|
10
10
|
const hasRunInJob = (jobId, cmd) => (gha) => gha.jobs[jobId]?.steps.some(step => step.run?.includes(cmd)) ?? false;
|
|
11
|
-
const makeState = (rust) => ({
|
|
11
|
+
const makeState = (rust, packageJson) => ({
|
|
12
12
|
...emptyState,
|
|
13
13
|
root: {
|
|
14
14
|
'.github': { workflows: {} },
|
|
15
|
+
...(packageJson !== undefined ? { 'package.json': utf8(packageJson) } : {}),
|
|
15
16
|
...(rust ? { 'Cargo.toml': emptyVec } : {}),
|
|
16
17
|
},
|
|
17
18
|
});
|
|
18
|
-
const
|
|
19
|
-
const [state, result] = virtual(makeState(rust))(ci({ nodeExtra, denoExtra: [], bunExtra: [] }));
|
|
20
|
-
assert(result === 0, result);
|
|
19
|
+
const workflow = (state) => {
|
|
21
20
|
const dotGithub = state.root['.github'];
|
|
22
21
|
assert(typeof dotGithub === 'object', dotGithub);
|
|
23
22
|
const workflows = dotGithub['workflows'];
|
|
@@ -26,6 +25,16 @@ const run = (rust, nodeExtra = () => []) => {
|
|
|
26
25
|
assert(isVec(file), file);
|
|
27
26
|
return unwrap(parseGitHubAction(jsonParse(utf8ToString(file))));
|
|
28
27
|
};
|
|
28
|
+
const run = (rust, nodeExtra = () => []) => {
|
|
29
|
+
const [state, result] = virtual(makeState(rust))(ci({ nodeExtra, denoExtra: [], bunExtra: [] }));
|
|
30
|
+
assert(result === 0, result);
|
|
31
|
+
return workflow(state);
|
|
32
|
+
};
|
|
33
|
+
const runDefault = (packageJson) => {
|
|
34
|
+
const [state, result] = virtual(makeState(false, packageJson))(main());
|
|
35
|
+
assert(result === 0, result);
|
|
36
|
+
return workflow(state);
|
|
37
|
+
};
|
|
29
38
|
export const proof = {
|
|
30
39
|
rust: () => {
|
|
31
40
|
assert(hasRun('cargo')(run(true)), 'expected Rust steps');
|
|
@@ -52,4 +61,47 @@ export const proof = {
|
|
|
52
61
|
}
|
|
53
62
|
},
|
|
54
63
|
},
|
|
64
|
+
defaultSetup: {
|
|
65
|
+
functionalscriptDemo: () => {
|
|
66
|
+
const gha = runDefault('{"name":"functionalscript"}');
|
|
67
|
+
assert(hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'expected fjs demo compile');
|
|
68
|
+
assert(hasRun('fjs t')(gha), 'expected fjs self-test');
|
|
69
|
+
assert(hasRun('deno task fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'expected deno demo compile');
|
|
70
|
+
assert(hasRun('deno task fjs t')(gha), 'expected deno self-test');
|
|
71
|
+
assert(hasRun('bun ./fs/fjs/module.ts t')(gha), 'expected bun self-test');
|
|
72
|
+
},
|
|
73
|
+
otherPackageNoDemo: () => {
|
|
74
|
+
const gha = runDefault('{"name":"other-package"}');
|
|
75
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
76
|
+
assert(!hasRun('fjs t')(gha), 'unexpected fjs self-test');
|
|
77
|
+
assert(!hasRun('deno task fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected deno demo compile');
|
|
78
|
+
assert(!hasRun('deno task fjs t')(gha), 'unexpected deno self-test');
|
|
79
|
+
assert(!hasRun('bun ./fs/fjs/module.ts t')(gha), 'unexpected bun self-test');
|
|
80
|
+
},
|
|
81
|
+
uninstallPackageName: () => {
|
|
82
|
+
const gha = runDefault('{"name":"other-package"}');
|
|
83
|
+
assert(hasRun('npm uninstall other-package -g')(gha), 'expected package-specific uninstall');
|
|
84
|
+
assert(!hasRun('npm uninstall functionalscript -g')(gha), 'unexpected functionalscript uninstall');
|
|
85
|
+
},
|
|
86
|
+
malformedPackageJsonFallback: () => {
|
|
87
|
+
const gha = runDefault('{');
|
|
88
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
89
|
+
assert(hasRun('npm uninstall functionalscript -g')(gha), 'expected fallback uninstall');
|
|
90
|
+
},
|
|
91
|
+
missingPackageJsonFallback: () => {
|
|
92
|
+
const gha = runDefault();
|
|
93
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
94
|
+
assert(hasRun('npm uninstall functionalscript -g')(gha), 'expected fallback uninstall');
|
|
95
|
+
},
|
|
96
|
+
missingNameFallback: () => {
|
|
97
|
+
const gha = runDefault('{"version":"1.0.0"}');
|
|
98
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
99
|
+
assert(hasRun('npm uninstall functionalscript -g')(gha), 'expected fallback uninstall');
|
|
100
|
+
},
|
|
101
|
+
nonObjectFallback: () => {
|
|
102
|
+
const gha = runDefault('[]');
|
|
103
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
104
|
+
assert(hasRun('npm uninstall functionalscript -g')(gha), 'expected fallback uninstall');
|
|
105
|
+
},
|
|
106
|
+
},
|
|
55
107
|
};
|
package/fs/dev/module.f.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Development utilities for indexing modules and loading FunctionalScript files.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { type Access, type All, type Env, type Import, type Readdir } from '../effects/node/module.f.ts';
|
|
2
7
|
import { type Effect } from '../effects/module.f.ts';
|
|
3
8
|
export type Module = {
|
|
4
9
|
readonly proof?: unknown;
|
|
@@ -36,4 +41,3 @@ export type LoadModuleOperations = Access | Import | All | Readdir;
|
|
|
36
41
|
* deterministic regardless of filesystem traversal order.
|
|
37
42
|
*/
|
|
38
43
|
export declare const loadModuleMap: (env: Env) => Effect<LoadModuleOperations, ModuleMap>;
|
|
39
|
-
export declare const index4: NodeProgram;
|
package/fs/dev/module.f.js
CHANGED
|
@@ -3,15 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import { all, both, import_, readdir, readFile, writeFile } from "../effects/node/module.f.js";
|
|
6
|
+
import { all, import_, readdir } from "../effects/node/module.f.js";
|
|
8
7
|
import { cmp as strCmp } from "../types/string/module.f.js";
|
|
9
|
-
import { utf8, utf8ToString } from "../text/module.f.js";
|
|
10
8
|
import { unwrap } from "../types/result/module.f.js";
|
|
11
|
-
import {
|
|
12
|
-
import { parse as jsonParse } from "../json/module.f.js";
|
|
13
|
-
import { record, unknown as rttiUnknown } from "../types/rtti/module.f.js";
|
|
14
|
-
import { parse as rttiParse } from "../types/rtti/parse/module.f.js";
|
|
9
|
+
import { pure } from "../effects/module.f.js";
|
|
15
10
|
import { relativize, toPosix } from "../path/module.f.js";
|
|
16
11
|
/**
|
|
17
12
|
* Returns `true` if the file should be loaded for proof discovery.
|
|
@@ -29,8 +24,7 @@ export const shouldLoad = (s) => s.endsWith('.f.ts') || s.endsWith('.f.js') ||
|
|
|
29
24
|
s.endsWith('proof.mts') || s.endsWith('proof.mjs');
|
|
30
25
|
const isSourceFile = (path) => path.endsWith('.js') || path.endsWith('.ts') || path.endsWith('.mts') || path.endsWith('.mjs');
|
|
31
26
|
const allFiles = (s, predicate) => {
|
|
32
|
-
const load = (p) =>
|
|
33
|
-
.step(() => readdir(p, {}))
|
|
27
|
+
const load = (p) => readdir(p, {})
|
|
34
28
|
.step(d => {
|
|
35
29
|
let result = [];
|
|
36
30
|
for (const i of unwrap(d)) {
|
|
@@ -86,22 +80,3 @@ export const loadModuleMap = (env) => {
|
|
|
86
80
|
.map(([k, v]) => [relativize(prefix, k), v])
|
|
87
81
|
.toSorted(([a], [b]) => strCmp(a)(b)))));
|
|
88
82
|
};
|
|
89
|
-
const denoJson = './deno.json';
|
|
90
|
-
const parseDenoJson = rttiParse(record(rttiUnknown));
|
|
91
|
-
const index2 = updateVersion
|
|
92
|
-
.step(() => readFile(denoJson))
|
|
93
|
-
.step(v => pure(unwrap(parseDenoJson(jsonParse(utf8ToString(unwrap(v)))))));
|
|
94
|
-
const allFiles2aa = allFiles('.', v => v.endsWith('/module.f.ts') ||
|
|
95
|
-
v.endsWith('/module.ts') ||
|
|
96
|
-
v.endsWith('/all.test.ts'))
|
|
97
|
-
.step(files => {
|
|
98
|
-
const exportsA = files.map(v => [v, `./${v.substring(2)}`]);
|
|
99
|
-
return pure(Object.fromEntries(exportsA));
|
|
100
|
-
});
|
|
101
|
-
const index3 = both(index2)(allFiles2aa)
|
|
102
|
-
.step(([jsr_json, exports]) => {
|
|
103
|
-
const json = JSON.stringify({ ...jsr_json, exports }, null, 2);
|
|
104
|
-
return writeFile(denoJson, utf8(json));
|
|
105
|
-
})
|
|
106
|
-
.step(() => pure(0));
|
|
107
|
-
export const index4 = () => index3;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ValidationError } from '../../types/rtti/validate/module.f.ts';
|
|
2
|
+
import type { Ts } from '../../types/rtti/ts/module.f.ts';
|
|
3
|
+
import { type Result } from '../../types/result/module.f.ts';
|
|
4
|
+
export declare const packageJsonSchema: {
|
|
5
|
+
readonly name: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").String, undefined]>;
|
|
6
|
+
readonly version: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").String, undefined]>;
|
|
7
|
+
readonly scripts: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").Type1<"record", import("../../types/rtti/module.f.ts").String>, undefined]>;
|
|
8
|
+
};
|
|
9
|
+
export type PackageJson = Ts<typeof packageJsonSchema>;
|
|
10
|
+
export type JsonTextError = string | ValidationError;
|
|
11
|
+
export declare const validatePackageJson: import("../../types/rtti/common/module.f.ts").Validate<{
|
|
12
|
+
readonly name: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").String, undefined]>;
|
|
13
|
+
readonly version: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").String, undefined]>;
|
|
14
|
+
readonly scripts: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").Type1<"record", import("../../types/rtti/module.f.ts").String>, undefined]>;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const validatePackageJsonText: (text: string) => Result<PackageJson, JsonTextError>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { parse as jsonParse } from "../../json/parser/module.f.js";
|
|
2
|
+
import { tokenize as jsonTokenize } from "../../json/tokenizer/module.f.js";
|
|
3
|
+
import { stringToList } from "../../text/utf16/module.f.js";
|
|
4
|
+
import { option, record, string } from "../../types/rtti/module.f.js";
|
|
5
|
+
import { validate as rttiValidate } from "../../types/rtti/validate/module.f.js";
|
|
6
|
+
import { error, ok } from "../../types/result/module.f.js";
|
|
7
|
+
export const packageJsonSchema = {
|
|
8
|
+
name: option(string),
|
|
9
|
+
version: option(string),
|
|
10
|
+
scripts: option(record(string)),
|
|
11
|
+
};
|
|
12
|
+
export const validatePackageJson = rttiValidate(packageJsonSchema);
|
|
13
|
+
const parseJsonText = (text) => jsonParse(jsonTokenize(stringToList(text)));
|
|
14
|
+
export const validatePackageJsonText = (text) => {
|
|
15
|
+
const [t, v] = parseJsonText(text);
|
|
16
|
+
if (t === 'error') {
|
|
17
|
+
return error(v);
|
|
18
|
+
}
|
|
19
|
+
const [t2, v2] = validatePackageJson(v);
|
|
20
|
+
return t2 === 'ok' ? ok(v2) : error(v2);
|
|
21
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { assert } from "../../asserts/module.f.js";
|
|
2
|
+
import { unwrap } from "../../types/result/module.f.js";
|
|
3
|
+
import { validatePackageJson, validatePackageJsonText, } from "./module.f.js";
|
|
4
|
+
export const proof = {
|
|
5
|
+
parseMetadata: () => {
|
|
6
|
+
const result = unwrap(validatePackageJsonText('{"name":"x","version":"1.0.0","scripts":{"test":"node test.js"}}'));
|
|
7
|
+
assert(result.name === 'x', result);
|
|
8
|
+
assert(result.version === '1.0.0', result);
|
|
9
|
+
assert(result.scripts?.test === 'node test.js', result);
|
|
10
|
+
},
|
|
11
|
+
malformedJson: () => {
|
|
12
|
+
const result = validatePackageJsonText('{');
|
|
13
|
+
assert(result[0] === 'error', result);
|
|
14
|
+
},
|
|
15
|
+
validatePreservesOriginalObject: () => {
|
|
16
|
+
const object = { name: 'x', version: '1.0.0', private: true };
|
|
17
|
+
const metadata = unwrap(validatePackageJson(object));
|
|
18
|
+
assert(metadata.name === 'x', metadata);
|
|
19
|
+
assert(metadata.version === '1.0.0', metadata);
|
|
20
|
+
assert(Object.is(metadata, object), metadata);
|
|
21
|
+
assert(object.private === true, object);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { descentParser } from "../../bnf/data/module.f.js";
|
|
2
|
+
import { backspace, ht, lf, ff, cr, quotationMark, solidus, reverseSolidus, digitRange, digit0, latinCapitalLetterA, latinSmallLetterA, latinSmallLetterB, latinSmallLetterF, latinSmallLetterN, latinSmallLetterR, latinSmallLetterT, latinSmallLetterU, range, } from "../../text/ascii/module.f.js";
|
|
2
3
|
import { stringToCodePointList } from "../../text/utf16/module.f.js";
|
|
4
|
+
import { contains } from "../../types/range/module.f.js";
|
|
3
5
|
import { concat, filter, flat, flatMap, map, stateScan, toArray } from "../../types/list/module.f.js";
|
|
4
|
-
import { jsGrammar } from "./module.f.js";
|
|
6
|
+
import { jsGrammar, parse } from "./module.f.js";
|
|
5
7
|
const mapCodePoint = (cp) => [cp, undefined];
|
|
6
8
|
const descentParserCpOnly = (m, name, cp) => {
|
|
7
9
|
const cpm = toArray(map(mapCodePoint)(cp));
|
|
@@ -45,16 +47,21 @@ const scanFunc = (input, state) => {
|
|
|
45
47
|
}
|
|
46
48
|
return [null, [state[0], concat(state[1])([input])]];
|
|
47
49
|
};
|
|
50
|
+
// All operator tag strings produced by the grammar's operator rule
|
|
51
|
+
const operatorTags = new Set([
|
|
52
|
+
'.', '=>', '===', '==', '=', '!==', '!=', '!',
|
|
53
|
+
'>>>=', '>>>', '>>=', '>>', '>=', '>',
|
|
54
|
+
'<<<=', '<<<', '<<=', '<<', '<=', '<',
|
|
55
|
+
'+=', '++', '+', '-=', '--', '-',
|
|
56
|
+
'**=', '**', '*=', '*', '/=', '%=', '%',
|
|
57
|
+
'&&=', '&&', '&=', '&', '||=', '||', '|=', '|',
|
|
58
|
+
'^=', '^', '~', '??=', '??', '?.', '?',
|
|
59
|
+
'[', ']', '{', '}', '(', ')', ',', ':'
|
|
60
|
+
]);
|
|
48
61
|
const filterFunc = tk => {
|
|
49
62
|
if (typeof tk === 'number')
|
|
50
63
|
return true;
|
|
51
64
|
switch (tk) {
|
|
52
|
-
case '{':
|
|
53
|
-
case '}':
|
|
54
|
-
case '[':
|
|
55
|
-
case ']':
|
|
56
|
-
case ':':
|
|
57
|
-
case ',':
|
|
58
65
|
case 'number':
|
|
59
66
|
case 'string':
|
|
60
67
|
case '\n':
|
|
@@ -63,18 +70,40 @@ const filterFunc = tk => {
|
|
|
63
70
|
case '\t':
|
|
64
71
|
return true;
|
|
65
72
|
default:
|
|
66
|
-
return
|
|
73
|
+
return operatorTags.has(tk);
|
|
67
74
|
}
|
|
68
75
|
};
|
|
76
|
+
const rangeCapitalAF = range('AF');
|
|
77
|
+
const stringDecodeScan = (cp, state) => {
|
|
78
|
+
switch (state.kind) {
|
|
79
|
+
case 'escape':
|
|
80
|
+
switch (cp) {
|
|
81
|
+
case quotationMark: return [[quotationMark], { kind: 'normal' }]; // \" → "
|
|
82
|
+
case reverseSolidus: return [[reverseSolidus], { kind: 'normal' }]; // \\ → \
|
|
83
|
+
case solidus: return [[solidus], { kind: 'normal' }]; // \/ → /
|
|
84
|
+
case latinSmallLetterB: return [[backspace], { kind: 'normal' }]; // \b → backspace (BS)
|
|
85
|
+
case latinSmallLetterF: return [[ff], { kind: 'normal' }]; // \f → form feed (FF)
|
|
86
|
+
case latinSmallLetterN: return [[lf], { kind: 'normal' }]; // \n → line feed (LF)
|
|
87
|
+
case latinSmallLetterR: return [[cr], { kind: 'normal' }]; // \r → carriage return (CR)
|
|
88
|
+
case latinSmallLetterT: return [[ht], { kind: 'normal' }]; // \t → horizontal tab (HT)
|
|
89
|
+
case latinSmallLetterU: return [null, { kind: 'unicode', acc: 0, count: 0 }]; // \u → start 4 hex digits
|
|
90
|
+
default: return [[cp], { kind: 'normal' }];
|
|
91
|
+
}
|
|
92
|
+
case 'unicode': {
|
|
93
|
+
// convert hex digit char to its numeric value: '0'-'9', 'A'-'F', 'a'-'f'
|
|
94
|
+
const digit = contains(digitRange)(cp) ? cp - digit0
|
|
95
|
+
: contains(rangeCapitalAF)(cp) ? cp - (latinCapitalLetterA - 10)
|
|
96
|
+
: cp - (latinSmallLetterA - 10);
|
|
97
|
+
const acc = (state.acc << 4) | digit;
|
|
98
|
+
return state.count === 3 ? [[acc], { kind: 'normal' }] : [null, { kind: 'unicode', acc, count: state.count + 1 }];
|
|
99
|
+
}
|
|
100
|
+
default:
|
|
101
|
+
return cp === reverseSolidus ? [null, { kind: 'escape' }] : [[cp], { kind: 'normal' }];
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const decodeJsonString = codePoints => String.fromCodePoint(...toArray(flat(stateScan(stringDecodeScan)({ kind: 'normal' })(codePoints.slice(1, -1)))));
|
|
69
105
|
const toJsToken = tk => {
|
|
70
106
|
switch (tk[0]) {
|
|
71
|
-
case '{':
|
|
72
|
-
case '}':
|
|
73
|
-
case '[':
|
|
74
|
-
case ']':
|
|
75
|
-
case ':':
|
|
76
|
-
case ',':
|
|
77
|
-
return { kind: tk[0] };
|
|
78
107
|
case '\n':
|
|
79
108
|
case '\r':
|
|
80
109
|
return { kind: 'nl' };
|
|
@@ -82,9 +111,9 @@ const toJsToken = tk => {
|
|
|
82
111
|
case '\t':
|
|
83
112
|
return { kind: 'ws' };
|
|
84
113
|
case 'string':
|
|
85
|
-
return { kind: 'string', value:
|
|
114
|
+
return { kind: 'string', value: decodeJsonString(tk[1]) };
|
|
86
115
|
default:
|
|
87
|
-
return
|
|
116
|
+
return { kind: tk[0] };
|
|
88
117
|
}
|
|
89
118
|
};
|
|
90
119
|
const getTokensFromAstRuleOrCodePoint = value => {
|
|
@@ -385,18 +414,24 @@ export const proof = {
|
|
|
385
414
|
throw result;
|
|
386
415
|
}
|
|
387
416
|
},
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
417
|
+
() => {
|
|
418
|
+
const result = tokenizeString('"\\\\"');
|
|
419
|
+
if (result !== '[{"kind":"string","value":"\\\\"},{"kind":"eof"}]') {
|
|
420
|
+
throw result;
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
() => {
|
|
424
|
+
const result = tokenizeString('"\\""');
|
|
425
|
+
if (result !== '[{"kind":"string","value":"\\""},{"kind":"eof"}]') {
|
|
426
|
+
throw result;
|
|
427
|
+
}
|
|
428
|
+
},
|
|
429
|
+
() => {
|
|
430
|
+
const result = tokenizeString('"\\/"');
|
|
431
|
+
if (result !== '[{"kind":"string","value":"/"},{"kind":"eof"}]') {
|
|
432
|
+
throw result;
|
|
433
|
+
}
|
|
434
|
+
},
|
|
400
435
|
() => {
|
|
401
436
|
const result = tokenizeString('"\\x"');
|
|
402
437
|
if (result !== 'error') {
|
|
@@ -421,18 +456,24 @@ export const proof = {
|
|
|
421
456
|
throw result;
|
|
422
457
|
}
|
|
423
458
|
},
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
459
|
+
() => {
|
|
460
|
+
const result = tokenizeString('"\\b\\f\\n\\r\\t"');
|
|
461
|
+
if (result !== '[{"kind":"string","value":"\\b\\f\\n\\r\\t"},{"kind":"eof"}]') {
|
|
462
|
+
throw result;
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
() => {
|
|
466
|
+
const result = tokenizeString('"\\u1234"');
|
|
467
|
+
if (result !== '[{"kind":"string","value":"ሴ"},{"kind":"eof"}]') {
|
|
468
|
+
throw result;
|
|
469
|
+
}
|
|
470
|
+
},
|
|
471
|
+
() => {
|
|
472
|
+
const result = tokenizeString('"\\uaBcDEeFf"');
|
|
473
|
+
if (result !== '[{"kind":"string","value":"ꯍEeFf"},{"kind":"eof"}]') {
|
|
474
|
+
throw result;
|
|
475
|
+
}
|
|
476
|
+
},
|
|
436
477
|
() => {
|
|
437
478
|
const result = tokenizeString('"\\uEeFg"');
|
|
438
479
|
if (result !== 'error') {
|
|
@@ -612,87 +653,88 @@ export const proof = {
|
|
|
612
653
|
// if (result !== 'error') { throw result }
|
|
613
654
|
// },
|
|
614
655
|
],
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
656
|
+
operators: [
|
|
657
|
+
() => {
|
|
658
|
+
const result = tokenizeString('=');
|
|
659
|
+
if (result !== '[{"kind":"="},{"kind":"eof"}]') {
|
|
660
|
+
throw result;
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
// () => {
|
|
664
|
+
// const result = tokenizeString('=a')
|
|
665
|
+
// if (result !== '[{"kind":"="},{"kind":"id","value":"a"},{"kind":"eof"}]') { throw result }
|
|
666
|
+
// },
|
|
667
|
+
// () => {
|
|
668
|
+
// const result = tokenizeString('-')
|
|
669
|
+
// if (result !== '[{"kind":"-"},{"kind":"eof"}]') { throw result }
|
|
670
|
+
// },
|
|
671
|
+
// () => {
|
|
672
|
+
// const result = tokenizeString('1*2')
|
|
673
|
+
// if (result !== '[{"bf":[1n,0],"kind":"number","value":"1"},{"kind":"*"},{"bf":[2n,0],"kind":"number","value":"2"},{"kind":"eof"}]') { throw result }
|
|
674
|
+
// },
|
|
675
|
+
// () => {
|
|
676
|
+
// const result = tokenizeString('( )')
|
|
677
|
+
// if (result !== '[{"kind":"("},{"kind":"ws"},{"kind":")"},{"kind":"eof"}]') { throw result }
|
|
678
|
+
// },
|
|
679
|
+
// () => {
|
|
680
|
+
// const result = tokenizeString('== != === !== > >= < <=')
|
|
681
|
+
// if (result !== '[{"kind":"=="},{"kind":"ws"},{"kind":"!="},{"kind":"ws"},{"kind":"==="},{"kind":"ws"},{"kind":"!=="},{"kind":"ws"},{"kind":">"},{"kind":"ws"},{"kind":">="},{"kind":"ws"},{"kind":"<"},{"kind":"ws"},{"kind":"<="},{"kind":"eof"}]') { throw result }
|
|
682
|
+
// },
|
|
683
|
+
// () => {
|
|
684
|
+
// const result = tokenizeString('+ - * / % ++ -- **')
|
|
685
|
+
// if (result !== '[{"kind":"+"},{"kind":"ws"},{"kind":"-"},{"kind":"ws"},{"kind":"*"},{"kind":"ws"},{"kind":"/"},{"kind":"ws"},{"kind":"%"},{"kind":"ws"},{"kind":"++"},{"kind":"ws"},{"kind":"--"},{"kind":"ws"},{"kind":"**"},{"kind":"eof"}]') { throw result }
|
|
686
|
+
// },
|
|
687
|
+
// () => {
|
|
688
|
+
// const result = tokenizeString('= += -= *= /= %= **=')
|
|
689
|
+
// if (result !== '[{"kind":"="},{"kind":"ws"},{"kind":"+="},{"kind":"ws"},{"kind":"-="},{"kind":"ws"},{"kind":"*="},{"kind":"ws"},{"kind":"/="},{"kind":"ws"},{"kind":"%="},{"kind":"ws"},{"kind":"**="},{"kind":"eof"}]') { throw result }
|
|
690
|
+
// },
|
|
691
|
+
// () => {
|
|
692
|
+
// const result = tokenizeString('& | ^ ~ << >> >>>')
|
|
693
|
+
// if (result !== '[{"kind":"&"},{"kind":"ws"},{"kind":"|"},{"kind":"ws"},{"kind":"^"},{"kind":"ws"},{"kind":"~"},{"kind":"ws"},{"kind":"<<"},{"kind":"ws"},{"kind":">>"},{"kind":"ws"},{"kind":">>>"},{"kind":"eof"}]') { throw result }
|
|
694
|
+
// },
|
|
695
|
+
// () => {
|
|
696
|
+
// const result = tokenizeString('&= |= ^= <<= >>= >>>=')
|
|
697
|
+
// if (result !== '[{"kind":"&="},{"kind":"ws"},{"kind":"|="},{"kind":"ws"},{"kind":"^="},{"kind":"ws"},{"kind":"<<="},{"kind":"ws"},{"kind":">>="},{"kind":"ws"},{"kind":">>>="},{"kind":"eof"}]') { throw result }
|
|
698
|
+
// },
|
|
699
|
+
// () => {
|
|
700
|
+
// const result = tokenizeString('&& || ! ??')
|
|
701
|
+
// if (result !== '[{"kind":"&&"},{"kind":"ws"},{"kind":"||"},{"kind":"ws"},{"kind":"!"},{"kind":"ws"},{"kind":"??"},{"kind":"eof"}]') { throw result }
|
|
702
|
+
// },
|
|
703
|
+
// () => {
|
|
704
|
+
// const result = tokenizeString('&&= ||= ??=')
|
|
705
|
+
// if (result !== '[{"kind":"&&="},{"kind":"ws"},{"kind":"||="},{"kind":"ws"},{"kind":"??="},{"kind":"eof"}]') { throw result }
|
|
706
|
+
// },
|
|
707
|
+
// () => {
|
|
708
|
+
// const result = tokenizeString('? ?. . =>')
|
|
709
|
+
// if (result !== '[{"kind":"?"},{"kind":"ws"},{"kind":"?."},{"kind":"ws"},{"kind":"."},{"kind":"ws"},{"kind":"=>"},{"kind":"eof"}]') { throw result }
|
|
710
|
+
// },
|
|
711
|
+
// ],
|
|
712
|
+
// ws: [
|
|
713
|
+
// () => {
|
|
714
|
+
// const result = tokenizeString(' ')
|
|
715
|
+
// if (result !== '[{"kind":"ws"},{"kind":"eof"}]') { throw result }
|
|
716
|
+
// },
|
|
717
|
+
// () => {
|
|
718
|
+
// const result = tokenizeString('\t')
|
|
719
|
+
// if (result !== '[{"kind":"ws"},{"kind":"eof"}]') { throw result }
|
|
720
|
+
// },
|
|
721
|
+
// () => {
|
|
722
|
+
// const result = tokenizeString(' \t')
|
|
723
|
+
// if (result !== '[{"kind":"ws"},{"kind":"eof"}]') { throw result }
|
|
724
|
+
// },
|
|
725
|
+
// () => {
|
|
726
|
+
// const result = tokenizeString('\n')
|
|
727
|
+
// if (result !== '[{"kind":"nl"},{"kind":"eof"}]') { throw result }
|
|
728
|
+
// },
|
|
729
|
+
// () => {
|
|
730
|
+
// const result = tokenizeString('\r')
|
|
731
|
+
// if (result !== '[{"kind":"nl"},{"kind":"eof"}]') { throw result }
|
|
732
|
+
// },
|
|
733
|
+
// () => {
|
|
734
|
+
// const result = tokenizeString(' \t\n\r ')
|
|
735
|
+
// if (result !== '[{"kind":"nl"},{"kind":"eof"}]') { throw result }
|
|
736
|
+
// },
|
|
737
|
+
],
|
|
696
738
|
// id: [
|
|
697
739
|
// () => {
|
|
698
740
|
// const result = tokenizeString('err')
|
|
@@ -909,6 +951,9 @@ export const proof = {
|
|
|
909
951
|
// if (result !== '[{"kind":"yield"},{"kind":"eof"}]') { throw result }
|
|
910
952
|
// },
|
|
911
953
|
// ],
|
|
954
|
+
throw: {
|
|
955
|
+
parse: () => { parse(''); }
|
|
956
|
+
},
|
|
912
957
|
// comments: [
|
|
913
958
|
// () => {
|
|
914
959
|
// const result = tokenizeString('//singleline comment')
|
package/fs/effects/module.f.d.ts
CHANGED
|
@@ -20,7 +20,6 @@ export declare const doFull: <O extends Operation, T, K extends O[0]>(cmd: K, pa
|
|
|
20
20
|
export type Param<O extends Operation> = F<O>[0];
|
|
21
21
|
export type Return<O extends Operation> = F<O>[1];
|
|
22
22
|
export declare const do_: <O extends Operation>(cmd: O[0]) => (...param: Param<O>) => Effect<O, Return<O>>;
|
|
23
|
-
export declare const begin: Effect<never, void>;
|
|
24
23
|
/**
|
|
25
24
|
* Sequentially threads a state value through an effect for each item in `items`.
|
|
26
25
|
*
|
package/fs/effects/module.f.js
CHANGED
|
@@ -13,7 +13,6 @@ export const doFull = (cmd, param, cont) => ({
|
|
|
13
13
|
step: (f) => doFull(cmd, param, x => cont(x).step(f)),
|
|
14
14
|
});
|
|
15
15
|
export const do_ = (cmd) => (...param) => doFull(cmd, param, pure);
|
|
16
|
-
export const begin = pure(undefined);
|
|
17
16
|
/**
|
|
18
17
|
* Sequentially threads a state value through an effect for each item in `items`.
|
|
19
18
|
*
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import { utf8 } from "../../text/module.f.js";
|
|
11
|
-
import {
|
|
11
|
+
import { 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.
|
|
@@ -70,6 +70,4 @@ export const test = do_('test');
|
|
|
70
70
|
* "fail with a message" program for a `NodeProgram`. For non-`1` exit codes,
|
|
71
71
|
* compose `error(s).step(() => pure(n))` directly.
|
|
72
72
|
*/
|
|
73
|
-
export const errorExit = (s) =>
|
|
74
|
-
.step(() => error(s))
|
|
75
|
-
.step(() => pure(1));
|
|
73
|
+
export const errorExit = (s) => error(s).step(() => pure(1));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -11,10 +11,9 @@
|
|
|
11
11
|
"prepack": "tsc --NoEmit false",
|
|
12
12
|
"test": "tsc && node ./fs/fjs/module.ts t",
|
|
13
13
|
"cov": "node --test --experimental-test-coverage --test-coverage-include=**/module.f.ts",
|
|
14
|
-
"index": "node ./fs/fjs/module.ts r ./fs/dev/index/module.f.ts",
|
|
15
14
|
"start": "node ./fs/fjs/module.ts",
|
|
16
15
|
"ci-update": "node ./fs/fjs/module.ts ci",
|
|
17
|
-
"update": "npm
|
|
16
|
+
"update": "npx npm-check-updates -u && npm install && deno install && npm run ci-update",
|
|
18
17
|
"index-html": "node ./fs/fjs/module.ts r ./fs/website/module.f.ts",
|
|
19
18
|
"website": "npm run prepack &&npm run index-html"
|
|
20
19
|
},
|
|
@@ -44,8 +43,8 @@
|
|
|
44
43
|
},
|
|
45
44
|
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
46
45
|
"devDependencies": {
|
|
47
|
-
"@playwright/test": "1",
|
|
48
|
-
"@types/node": "
|
|
49
|
-
"typescript": "
|
|
46
|
+
"@playwright/test": "1.60.0",
|
|
47
|
+
"@types/node": "25.9.2",
|
|
48
|
+
"typescript": "6.0.3"
|
|
50
49
|
}
|
|
51
|
-
}
|
|
50
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const main: import("../../effects/node/module.f.ts").NodeProgram;
|
package/fs/dev/index/module.f.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Version management helpers for updating project package versions.
|
|
3
|
-
*
|
|
4
|
-
* @module
|
|
5
|
-
*/
|
|
6
|
-
import { utf8, utf8ToString } from "../../text/module.f.js";
|
|
7
|
-
import { begin, pure } from "../../effects/module.f.js";
|
|
8
|
-
import { all, readFile, writeFile } from "../../effects/node/module.f.js";
|
|
9
|
-
import { unwrap } from "../../types/result/module.f.js";
|
|
10
|
-
const { stringify, parse } = JSON;
|
|
11
|
-
const jsonFile = (jsonFile) => `${jsonFile}.json`;
|
|
12
|
-
const readJson = (name) => begin
|
|
13
|
-
.step(() => readFile(jsonFile(name)))
|
|
14
|
-
.step(v => pure(parse(utf8ToString(unwrap(v)))));
|
|
15
|
-
const writeVersion = (version) => (name) => begin
|
|
16
|
-
.step(() => readJson(name))
|
|
17
|
-
.step(json => writeFile(jsonFile(name), utf8(stringify({
|
|
18
|
-
...json,
|
|
19
|
-
version,
|
|
20
|
-
}, null, 2))));
|
|
21
|
-
export const updateVersion = begin
|
|
22
|
-
.step(() => readJson('package'))
|
|
23
|
-
.step(p => {
|
|
24
|
-
const w = writeVersion(p.version);
|
|
25
|
-
return all(w('package'), w('deno'));
|
|
26
|
-
})
|
|
27
|
-
.step(() => pure(0));
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { utf8, utf8ToString } from "../../text/module.f.js";
|
|
2
|
-
import { isVec } from "../../types/bit_vec/module.f.js";
|
|
3
|
-
import { all, writeFile } from "../../effects/node/module.f.js";
|
|
4
|
-
import { emptyState, virtual } from "../../effects/node/virtual/module.f.js";
|
|
5
|
-
import { updateVersion } from "./module.f.js";
|
|
6
|
-
const version = '0.3.0';
|
|
7
|
-
const x = {
|
|
8
|
-
'package.json': {
|
|
9
|
-
"name": "functionalscript",
|
|
10
|
-
version,
|
|
11
|
-
"description": "FunctionalScript is a functional subset of JavaScript",
|
|
12
|
-
"main": "module.f.cjs",
|
|
13
|
-
"scripts": {
|
|
14
|
-
"tsc": "tsc",
|
|
15
|
-
"test": "tsc && npm run test-only",
|
|
16
|
-
"version": "node ./nodejs/version/main.cjs",
|
|
17
|
-
"test-only": "node --trace-uncaught ./test.f.cjs"
|
|
18
|
-
},
|
|
19
|
-
"repository": {
|
|
20
|
-
"type": "git",
|
|
21
|
-
"url": "git+https://github.com/functionalscript/functionalscript.git"
|
|
22
|
-
},
|
|
23
|
-
"author": "NatFoam",
|
|
24
|
-
"license": "MIT",
|
|
25
|
-
"keywords": [
|
|
26
|
-
"lambda",
|
|
27
|
-
"functional-programming",
|
|
28
|
-
"closure",
|
|
29
|
-
"pure-functional",
|
|
30
|
-
"typescript",
|
|
31
|
-
"programming-language",
|
|
32
|
-
"lazy-evaluation"
|
|
33
|
-
],
|
|
34
|
-
"bugs": {
|
|
35
|
-
"url": "https://github.com/functionalscript/functionalscript/issues"
|
|
36
|
-
},
|
|
37
|
-
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
38
|
-
"devDependencies": {
|
|
39
|
-
"@types/node": "^18.6.2",
|
|
40
|
-
"typescript": "^4.7.4"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"deno.json": {}
|
|
44
|
-
};
|
|
45
|
-
const e = '{\n' +
|
|
46
|
-
' "name": "functionalscript",\n' +
|
|
47
|
-
` "version": "${version}",\n` +
|
|
48
|
-
' "description": "FunctionalScript is a functional subset of JavaScript",\n' +
|
|
49
|
-
' "main": "module.f.cjs",\n' +
|
|
50
|
-
' "scripts": {\n' +
|
|
51
|
-
' "tsc": "tsc",\n' +
|
|
52
|
-
' "test": "tsc && npm run test-only",\n' +
|
|
53
|
-
' "version": "node ./nodejs/version/main.cjs",\n' +
|
|
54
|
-
' "test-only": "node --trace-uncaught ./test.f.cjs"\n' +
|
|
55
|
-
' },\n' +
|
|
56
|
-
' "repository": {\n' +
|
|
57
|
-
' "type": "git",\n' +
|
|
58
|
-
' "url": "git+https://github.com/functionalscript/functionalscript.git"\n' +
|
|
59
|
-
' },\n' +
|
|
60
|
-
' "author": "NatFoam",\n' +
|
|
61
|
-
' "license": "MIT",\n' +
|
|
62
|
-
' "keywords": [\n' +
|
|
63
|
-
' "lambda",\n' +
|
|
64
|
-
' "functional-programming",\n' +
|
|
65
|
-
' "closure",\n' +
|
|
66
|
-
' "pure-functional",\n' +
|
|
67
|
-
' "typescript",\n' +
|
|
68
|
-
' "programming-language",\n' +
|
|
69
|
-
' "lazy-evaluation"\n' +
|
|
70
|
-
' ],\n' +
|
|
71
|
-
' "bugs": {\n' +
|
|
72
|
-
' "url": "https://github.com/functionalscript/functionalscript/issues"\n' +
|
|
73
|
-
' },\n' +
|
|
74
|
-
' "homepage": "https://github.com/functionalscript/functionalscript#readme",\n' +
|
|
75
|
-
' "devDependencies": {\n' +
|
|
76
|
-
' "@types/node": "^18.6.2",\n' +
|
|
77
|
-
' "typescript": "^4.7.4"\n' +
|
|
78
|
-
' }\n' +
|
|
79
|
-
'}';
|
|
80
|
-
export const proof = {
|
|
81
|
-
new: () => {
|
|
82
|
-
const w = (name) => {
|
|
83
|
-
const fn = `${name}.json`;
|
|
84
|
-
return writeFile(fn, utf8(JSON.stringify(x[fn])));
|
|
85
|
-
};
|
|
86
|
-
const [state] = virtual(emptyState)(all(w('package'), w('deno')));
|
|
87
|
-
const [newState, result] = virtual(state)(updateVersion);
|
|
88
|
-
if (result !== 0) {
|
|
89
|
-
throw result;
|
|
90
|
-
}
|
|
91
|
-
const vec = newState.root['package.json'];
|
|
92
|
-
if (!isVec(vec)) {
|
|
93
|
-
throw vec;
|
|
94
|
-
}
|
|
95
|
-
const n = utf8ToString(vec);
|
|
96
|
-
if (n !== e) {
|
|
97
|
-
throw [n, e];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|