functionalscript 0.11.0 → 0.11.2
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/cas/module.f.d.ts +21 -0
- package/cas/module.f.js +16 -0
- package/crypto/sha2/module.f.d.ts +10 -0
- package/crypto/sha2/module.f.js +8 -0
- package/crypto/sign/module.f.d.ts +15 -0
- package/crypto/sign/module.f.js +15 -0
- package/dev/index/module.f.d.ts +2 -0
- package/dev/index/module.f.js +2 -0
- package/dev/module.f.d.ts +2 -3
- package/dev/module.f.js +8 -35
- package/html/module.f.d.ts +18 -0
- package/html/module.f.js +12 -0
- package/io/module.f.d.ts +9 -2
- package/io/module.f.js +12 -3
- package/io/module.js +2 -0
- package/io/virtual/module.f.js +4 -0
- package/json/parser/module.f.d.ts +6 -0
- package/json/parser/module.f.js +6 -0
- package/json/serializer/module.f.d.ts +12 -0
- package/json/serializer/module.f.js +12 -0
- package/json/tokenizer/module.f.d.ts +7 -0
- package/json/tokenizer/module.f.js +7 -0
- package/package.json +2 -2
- package/path/module.f.d.ts +13 -0
- package/path/module.f.js +13 -0
- package/text/ascii/module.f.d.ts +7 -0
- package/text/ascii/module.f.js +7 -0
- package/text/sgr/module.f.d.ts +6 -0
- package/text/sgr/module.f.js +6 -2
- package/types/effects/module.f.js +0 -65
- package/types/effects/node/module.f.d.ts +11 -1
- package/types/effects/node/module.f.js +3 -4
- package/types/effects/node/virtual/module.f.js +3 -1
- package/types/nominal/module.f.d.ts +12 -0
- package/types/nominal/module.f.js +11 -2
- package/dev/index/module.d.ts +0 -1
- package/dev/index/module.js +0 -3
package/cas/module.f.d.ts
CHANGED
|
@@ -8,16 +8,37 @@ import type { Vec } from "../types/bit_vec/module.f.ts";
|
|
|
8
8
|
import { type Effect, type Operation } from "../types/effects/module.f.ts";
|
|
9
9
|
import { type Fs, type NodeOp } from "../types/effects/node/module.f.ts";
|
|
10
10
|
export type KvStore<O extends Operation> = {
|
|
11
|
+
/** Reads a value by key; returns `undefined` when the key does not exist. */
|
|
11
12
|
readonly read: (key: Vec) => Effect<O, Vec | undefined>;
|
|
13
|
+
/** Writes a key/value pair to the underlying storage. */
|
|
12
14
|
readonly write: (key: Vec, value: Vec) => Effect<O, void>;
|
|
15
|
+
/** Lists all keys available in the store. */
|
|
13
16
|
readonly list: () => Effect<O, readonly Vec[]>;
|
|
14
17
|
};
|
|
18
|
+
/** A key/value tuple where index `0` is the key and index `1` is the value. */
|
|
15
19
|
export type Kv = readonly [Vec, Vec];
|
|
20
|
+
/**
|
|
21
|
+
* Creates a filesystem-backed key/value store under the provided root path.
|
|
22
|
+
*/
|
|
16
23
|
export declare const fileKvStore: (path: string) => KvStore<Fs>;
|
|
17
24
|
export type Cas<O extends Operation> = {
|
|
25
|
+
/** Reads content by hash; returns `undefined` when not found. */
|
|
18
26
|
readonly read: (key: Vec) => Effect<O, Vec | undefined>;
|
|
27
|
+
/** Stores content and returns its computed hash. */
|
|
19
28
|
readonly write: (value: Vec) => Effect<O, Vec>;
|
|
29
|
+
/** Lists all stored content hashes. */
|
|
20
30
|
readonly list: () => Effect<O, readonly Vec[]>;
|
|
21
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* Builds a content-addressable storage facade from a SHA-2 implementation.
|
|
34
|
+
*/
|
|
22
35
|
export declare const cas: (sha2: Sha2) => <O extends Operation>(_: KvStore<O>) => Cas<O>;
|
|
36
|
+
/**
|
|
37
|
+
* Runs the CAS CLI.
|
|
38
|
+
*
|
|
39
|
+
* Supported subcommands:
|
|
40
|
+
* - `add <path>`: stores file content and prints the hash.
|
|
41
|
+
* - `get <hash> <path>`: restores content by hash into a file.
|
|
42
|
+
* - `list`: prints all known hashes.
|
|
43
|
+
*/
|
|
23
44
|
export declare const main: (args: readonly string[]) => Effect<NodeOp, number>;
|
package/cas/module.f.js
CHANGED
|
@@ -13,12 +13,16 @@ import { unwrap } from "../types/result/module.f.js";
|
|
|
13
13
|
const o = { withFileTypes: true };
|
|
14
14
|
const split = (s) => [s.substring(0, 2), s.substring(2)];
|
|
15
15
|
const prefix = '.cas';
|
|
16
|
+
/** Converts a content key to its sharded relative CAS file path. */
|
|
16
17
|
const toPath = (key) => {
|
|
17
18
|
const s = vecToCBase32(key);
|
|
18
19
|
const [a, bc] = split(s);
|
|
19
20
|
const [b, c] = split(bc);
|
|
20
21
|
return `${prefix}/${a}/${b}/${c}`;
|
|
21
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Creates a filesystem-backed key/value store under the provided root path.
|
|
25
|
+
*/
|
|
22
26
|
export const fileKvStore = (path) => ({
|
|
23
27
|
read: (key) => begin
|
|
24
28
|
.step(() => readFile(toPath(key)))
|
|
@@ -41,6 +45,9 @@ export const fileKvStore = (path) => ({
|
|
|
41
45
|
? cBase32ToVec(parentPath.substring(prefix.length).replaceAll('/', '') + name)
|
|
42
46
|
: null)))),
|
|
43
47
|
});
|
|
48
|
+
/**
|
|
49
|
+
* Builds a content-addressable storage facade from a SHA-2 implementation.
|
|
50
|
+
*/
|
|
44
51
|
export const cas = (sha2) => {
|
|
45
52
|
const compute = computeSync(sha2);
|
|
46
53
|
return ({ read, write, list }) => ({
|
|
@@ -54,9 +61,18 @@ export const cas = (sha2) => {
|
|
|
54
61
|
list,
|
|
55
62
|
});
|
|
56
63
|
};
|
|
64
|
+
/** Prints an error message and returns exit code `1`. */
|
|
57
65
|
const e = (s) => begin
|
|
58
66
|
.step(() => error(s))
|
|
59
67
|
.step(() => pure(1));
|
|
68
|
+
/**
|
|
69
|
+
* Runs the CAS CLI.
|
|
70
|
+
*
|
|
71
|
+
* Supported subcommands:
|
|
72
|
+
* - `add <path>`: stores file content and prints the hash.
|
|
73
|
+
* - `get <hash> <path>`: restores content by hash into a file.
|
|
74
|
+
* - `list`: prints all known hashes.
|
|
75
|
+
*/
|
|
60
76
|
export const main = (args) => {
|
|
61
77
|
const c = cas(sha256)(fileKvStore('.'));
|
|
62
78
|
const [cmd, ...options] = args;
|
|
@@ -7,7 +7,9 @@ import type { Array16, Array8 } from '../../types/array/module.f.ts';
|
|
|
7
7
|
import { type Vec } from '../../types/bit_vec/module.f.ts';
|
|
8
8
|
import type { Fold } from '../../types/function/operator/module.f.ts';
|
|
9
9
|
import { type List } from '../../types/list/module.f.ts';
|
|
10
|
+
/** 8-word SHA-2 state vector. */
|
|
10
11
|
export type V8 = Array8<bigint>;
|
|
12
|
+
/** 16-word SHA-2 message schedule chunk. */
|
|
11
13
|
export type V16 = Array16<bigint>;
|
|
12
14
|
/**
|
|
13
15
|
* Type definition for the state of the SHA-2 algorithm.
|
|
@@ -75,8 +77,16 @@ export type Sha2 = {
|
|
|
75
77
|
*/
|
|
76
78
|
readonly end: (state: State) => Vec;
|
|
77
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Computes a SHA-2 hash from a list of message chunks.
|
|
82
|
+
*
|
|
83
|
+
* @param sha2 A SHA-2 algorithm configuration.
|
|
84
|
+
* @returns A function that hashes the full list of chunks.
|
|
85
|
+
*/
|
|
78
86
|
export declare const computeSync: ({ append, init, end }: Sha2) => (list: List<Vec>) => Vec;
|
|
87
|
+
/** 32-bit SHA-2 base configuration shared by SHA-224 and SHA-256. */
|
|
79
88
|
export declare const base32: Base;
|
|
89
|
+
/** 64-bit SHA-2 base configuration shared by SHA-384, SHA-512, SHA-512/224 and SHA-512/256. */
|
|
80
90
|
export declare const base64: Base;
|
|
81
91
|
/** SHA-256 */
|
|
82
92
|
export declare const sha256: Sha2;
|
package/crypto/sha2/module.f.js
CHANGED
|
@@ -167,10 +167,17 @@ const sha2 = ({ append, end, chunkLength }, hash, hashLength) => ({
|
|
|
167
167
|
append,
|
|
168
168
|
end: end(hashLength),
|
|
169
169
|
});
|
|
170
|
+
/**
|
|
171
|
+
* Computes a SHA-2 hash from a list of message chunks.
|
|
172
|
+
*
|
|
173
|
+
* @param sha2 A SHA-2 algorithm configuration.
|
|
174
|
+
* @returns A function that hashes the full list of chunks.
|
|
175
|
+
*/
|
|
170
176
|
export const computeSync = ({ append, init, end }) => {
|
|
171
177
|
const f = fold(append)(init);
|
|
172
178
|
return (list) => end(f(list));
|
|
173
179
|
};
|
|
180
|
+
/** 32-bit SHA-2 base configuration shared by SHA-224 and SHA-256. */
|
|
174
181
|
export const base32 = base({
|
|
175
182
|
logBitLen: 5n,
|
|
176
183
|
k: [
|
|
@@ -196,6 +203,7 @@ export const base32 = base({
|
|
|
196
203
|
ss0: [7n, 18n, 3n],
|
|
197
204
|
ss1: [17n, 19n, 10n],
|
|
198
205
|
});
|
|
206
|
+
/** 64-bit SHA-2 base configuration shared by SHA-384, SHA-512, SHA-512/224 and SHA-512/256. */
|
|
199
207
|
export const base64 = base({
|
|
200
208
|
logBitLen: 6n,
|
|
201
209
|
k: [
|
|
@@ -14,10 +14,25 @@ export type All = {
|
|
|
14
14
|
readonly int2octets: (x: bigint) => Vec;
|
|
15
15
|
readonly bits2octets: (b: Vec) => Vec;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Builds RFC6979 helper conversions for a subgroup order.
|
|
19
|
+
*
|
|
20
|
+
* @param q - Subgroup order.
|
|
21
|
+
* @returns Conversion helpers used by deterministic nonce generation.
|
|
22
|
+
*/
|
|
17
23
|
export declare const all: (q: bigint) => All;
|
|
24
|
+
/**
|
|
25
|
+
* Builds RFC6979 helper conversions from curve parameters.
|
|
26
|
+
*/
|
|
18
27
|
export declare const fromCurve: (c: Curve) => All;
|
|
19
28
|
export declare const concat: (...x: readonly Vec[]) => Vec;
|
|
29
|
+
/**
|
|
30
|
+
* Computes deterministic ECDSA nonce `k` as described by RFC6979.
|
|
31
|
+
*/
|
|
20
32
|
export declare const computeK: (_: All) => (_: Sha2) => (x: bigint) => (m: Vec) => bigint;
|
|
21
33
|
type Signature = Array2<bigint>;
|
|
34
|
+
/**
|
|
35
|
+
* Signs a message bit vector and returns an ECDSA `(r, s)` signature pair.
|
|
36
|
+
*/
|
|
22
37
|
export declare const sign: (c: Curve) => (hf: Sha2) => (x: bigint) => (m: Vec) => Signature;
|
|
23
38
|
export {};
|
package/crypto/sign/module.f.js
CHANGED
|
@@ -5,6 +5,12 @@ import { computeSync } from "../sha2/module.f.js";
|
|
|
5
5
|
// qlen to rlen
|
|
6
6
|
const roundUp8 = roundUp(8n);
|
|
7
7
|
const divUp8 = divUp(8n);
|
|
8
|
+
/**
|
|
9
|
+
* Builds RFC6979 helper conversions for a subgroup order.
|
|
10
|
+
*
|
|
11
|
+
* @param q - Subgroup order.
|
|
12
|
+
* @returns Conversion helpers used by deterministic nonce generation.
|
|
13
|
+
*/
|
|
8
14
|
export const all = (q) => {
|
|
9
15
|
const qlen = bitLength(q);
|
|
10
16
|
const bits2int = (b) => {
|
|
@@ -22,11 +28,17 @@ export const all = (q) => {
|
|
|
22
28
|
bits2octets: b => int2octets(bits2int(b) % q),
|
|
23
29
|
};
|
|
24
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Builds RFC6979 helper conversions from curve parameters.
|
|
33
|
+
*/
|
|
25
34
|
export const fromCurve = (c) => all(c.nf.p);
|
|
26
35
|
const x01 = vec8(0x01n);
|
|
27
36
|
const x00 = vec8(0x00n);
|
|
28
37
|
const ltov = listToVec(msb);
|
|
29
38
|
export const concat = (...x) => ltov(x);
|
|
39
|
+
/**
|
|
40
|
+
* Computes deterministic ECDSA nonce `k` as described by RFC6979.
|
|
41
|
+
*/
|
|
30
42
|
export const computeK = ({ q, bits2int, qlen, int2octets, bits2octets }) => hf => {
|
|
31
43
|
// TODO: Look at https://www.rfc-editor.org/rfc/rfc6979#section-3.3 to reformulate
|
|
32
44
|
// it using `HMAC_DRBG`.
|
|
@@ -96,6 +108,9 @@ export const computeK = ({ q, bits2int, qlen, int2octets, bits2octets }) => hf =
|
|
|
96
108
|
}
|
|
97
109
|
};
|
|
98
110
|
};
|
|
111
|
+
/**
|
|
112
|
+
* Signs a message bit vector and returns an ECDSA `(r, s)` signature pair.
|
|
113
|
+
*/
|
|
99
114
|
export const sign = (c) => (hf) => (x) => (m) => {
|
|
100
115
|
// 2.4 Signature Generation
|
|
101
116
|
const { nf: { p: q, div }, g } = c;
|
package/dev/module.f.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { type Io } from '../io/module.f.ts';
|
|
7
|
-
import { type All, type Readdir } from '../types/effects/node/module.f.ts';
|
|
7
|
+
import { type All, type NodeProgram, type Readdir } from '../types/effects/node/module.f.ts';
|
|
8
8
|
import { type Effect } from '../types/effects/module.f.ts';
|
|
9
9
|
export declare const todo: () => never;
|
|
10
10
|
export type Module = {
|
|
@@ -15,6 +15,5 @@ export type ModuleMap = {
|
|
|
15
15
|
};
|
|
16
16
|
export declare const env: (io: Io) => (v: string) => string | undefined;
|
|
17
17
|
export declare const allFiles2: (s: string) => Effect<Readdir | All, readonly string[]>;
|
|
18
|
-
export declare const allFiles: (io: Io) => (s: string) => Promise<readonly string[]>;
|
|
19
18
|
export declare const loadModuleMap: (io: Io) => Promise<ModuleMap>;
|
|
20
|
-
export declare const
|
|
19
|
+
export declare const index4: NodeProgram;
|
package/dev/module.f.js
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { fromIo } from "../io/module.f.js";
|
|
7
7
|
import { updateVersion } from "./version/module.f.js";
|
|
8
|
-
import {
|
|
9
|
-
import { all, readdir, readFile, writeFile } from "../types/effects/node/module.f.js";
|
|
8
|
+
import { all, both, readdir, readFile, writeFile } from "../types/effects/node/module.f.js";
|
|
10
9
|
import { utf8, utf8ToString } from "../text/module.f.js";
|
|
11
10
|
import { unwrap } from "../types/result/module.f.js";
|
|
12
11
|
import { begin, pure } from "../types/effects/module.f.js";
|
|
@@ -45,31 +44,7 @@ export const allFiles2 = (s) => {
|
|
|
45
44
|
.step(v => pure(v.flat()));
|
|
46
45
|
return load(s);
|
|
47
46
|
};
|
|
48
|
-
|
|
49
|
-
const { fs: { promises: { readdir } } } = io;
|
|
50
|
-
const load = async (p) => {
|
|
51
|
-
let result = [];
|
|
52
|
-
for (const i of await readdir(p, { withFileTypes: true })) {
|
|
53
|
-
const { name } = i;
|
|
54
|
-
if (name.startsWith('.')) {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
const file = `${p}/${name}`;
|
|
58
|
-
if (i.isDirectory()) {
|
|
59
|
-
if (name === 'node_modules') {
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
result = [...result, ...await load(file)];
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (name.endsWith('.js') || name.endsWith('.ts')) {
|
|
66
|
-
result = [...result, file];
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return result;
|
|
70
|
-
};
|
|
71
|
-
return load(s);
|
|
72
|
-
};
|
|
47
|
+
const allFiles = (io) => (s) => fromIo(io)(allFiles2(s));
|
|
73
48
|
export const loadModuleMap = async (io) => {
|
|
74
49
|
const { fs: { existsSync }, asyncImport } = io;
|
|
75
50
|
let map = [];
|
|
@@ -89,19 +64,17 @@ const index2 = begin
|
|
|
89
64
|
.step(() => updateVersion)
|
|
90
65
|
.step(() => readFile(denoJson))
|
|
91
66
|
.step(v => pure(JSON.parse(utf8ToString(unwrap(v)))));
|
|
92
|
-
const
|
|
67
|
+
const allFiles2aa = begin
|
|
93
68
|
.step(() => allFiles2('.'))
|
|
94
69
|
.step(files => {
|
|
95
|
-
// console.log(files)
|
|
96
70
|
const list = files.filter(v => v.endsWith('/module.f.ts') || v.endsWith('/module.ts'));
|
|
97
71
|
const exportsA = list.map(v => [v, `./${v.substring(2)}`]);
|
|
98
|
-
|
|
72
|
+
return pure(Object.fromEntries(exportsA));
|
|
73
|
+
});
|
|
74
|
+
const index3 = both(index2)(allFiles2aa)
|
|
75
|
+
.step(([jsr_json, exports]) => {
|
|
99
76
|
const json = JSON.stringify({ ...jsr_json, exports }, null, 2);
|
|
100
77
|
return writeFile(denoJson, utf8(json));
|
|
101
78
|
})
|
|
102
79
|
.step(() => pure(0));
|
|
103
|
-
export const
|
|
104
|
-
const runner = fromIo(io);
|
|
105
|
-
const jsr_json = await runner(index2);
|
|
106
|
-
return await runner(allFiles2a(jsr_json));
|
|
107
|
-
};
|
|
80
|
+
export const index4 = () => index3;
|
package/html/module.f.d.ts
CHANGED
|
@@ -2,12 +2,30 @@ import { type List } from '../types/list/module.f.ts';
|
|
|
2
2
|
type Tag = string;
|
|
3
3
|
type Element1 = readonly [Tag, ...Node[]];
|
|
4
4
|
type Element2 = readonly [Tag, Attributes, ...Node[]];
|
|
5
|
+
/**
|
|
6
|
+
* A FunctionalScript representation of an HTML element.
|
|
7
|
+
*
|
|
8
|
+
* - `[tag, ...children]` for elements without attributes.
|
|
9
|
+
* - `[tag, attributes, ...children]` for elements with attributes.
|
|
10
|
+
*/
|
|
5
11
|
export type Element = Element1 | Element2;
|
|
6
12
|
type Attributes = {
|
|
7
13
|
readonly [k in string]: string;
|
|
8
14
|
};
|
|
9
15
|
export type Node = Element | string;
|
|
16
|
+
/**
|
|
17
|
+
* Converts a FunctionalScript element into a list of HTML string chunks.
|
|
18
|
+
*
|
|
19
|
+
* Chunks are returned instead of a single string to support composition with
|
|
20
|
+
* other list/string helpers in this codebase.
|
|
21
|
+
*/
|
|
10
22
|
export declare const element: (e: Element) => List<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Builds a complete HTML document by prepending `<!DOCTYPE html>`.
|
|
25
|
+
*/
|
|
11
26
|
export declare const html: (_: Element) => List<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Renders an HTML element tree to a final string.
|
|
29
|
+
*/
|
|
12
30
|
export declare const htmlToString: (_: Element) => string;
|
|
13
31
|
export {};
|
package/html/module.f.js
CHANGED
|
@@ -62,6 +62,12 @@ const parseElement = (e) => {
|
|
|
62
62
|
[tag, item1, list] :
|
|
63
63
|
[tag, {}, [item1, ...list]];
|
|
64
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* Converts a FunctionalScript element into a list of HTML string chunks.
|
|
67
|
+
*
|
|
68
|
+
* Chunks are returned instead of a single string to support composition with
|
|
69
|
+
* other list/string helpers in this codebase.
|
|
70
|
+
*/
|
|
65
71
|
export const element = (e) => {
|
|
66
72
|
const [tag, a, n] = parseElement(e);
|
|
67
73
|
const open = flat([[`<`, tag], attributes(a), [`>`]]);
|
|
@@ -70,5 +76,11 @@ export const element = (e) => {
|
|
|
70
76
|
}
|
|
71
77
|
return flat([open, rawText.includes(tag) ? [rawMap(n)] : nodes(n), ['</', tag, '>']]);
|
|
72
78
|
};
|
|
79
|
+
/**
|
|
80
|
+
* Builds a complete HTML document by prepending `<!DOCTYPE html>`.
|
|
81
|
+
*/
|
|
73
82
|
export const html = compose(element)(listConcat(['<!DOCTYPE html>']));
|
|
83
|
+
/**
|
|
84
|
+
* Renders an HTML element tree to a final string.
|
|
85
|
+
*/
|
|
74
86
|
export const htmlToString = compose(html)(stringConcat);
|
package/io/module.f.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Effect } from '../types/effects/module.f.ts';
|
|
2
|
-
import type { NodeOp } from '../types/effects/node/module.f.ts';
|
|
2
|
+
import type { NodeOp, RequestListener } from '../types/effects/node/module.f.ts';
|
|
3
3
|
import { type Result } from '../types/result/module.f.ts';
|
|
4
4
|
/**
|
|
5
5
|
* Represents a directory entry (file or directory) in the filesystem
|
|
@@ -79,6 +79,12 @@ export type Process = {
|
|
|
79
79
|
readonly stderr: Writable;
|
|
80
80
|
};
|
|
81
81
|
export type TryCatch = <T>(f: () => T) => Result<T, unknown>;
|
|
82
|
+
export type Server = {
|
|
83
|
+
readonly listen: (port: number) => void;
|
|
84
|
+
};
|
|
85
|
+
export type Https = {
|
|
86
|
+
readonly createServer: (_: RequestListener) => Server;
|
|
87
|
+
};
|
|
82
88
|
/**
|
|
83
89
|
* Core IO operations interface providing access to system resources
|
|
84
90
|
*/
|
|
@@ -91,6 +97,7 @@ export type Io = {
|
|
|
91
97
|
readonly fetch: (url: string) => Promise<Response>;
|
|
92
98
|
readonly tryCatch: TryCatch;
|
|
93
99
|
readonly asyncTryCatch: <T>(f: () => Promise<T>) => Promise<Result<T, unknown>>;
|
|
100
|
+
readonly https: Https;
|
|
94
101
|
};
|
|
95
102
|
/**
|
|
96
103
|
* The environment variables.
|
|
@@ -106,4 +113,4 @@ export type Run = (f: App) => Promise<never>;
|
|
|
106
113
|
*/
|
|
107
114
|
export declare const run: (io: Io) => Run;
|
|
108
115
|
export type EffectToPromise = <T>(effect: Effect<NodeOp, T>) => Promise<T>;
|
|
109
|
-
export declare const fromIo: ({ console: { error, log }, fs: { promises: { mkdir, readFile, readdir, writeFile } }, fetch, }: Io) => EffectToPromise;
|
|
116
|
+
export declare const fromIo: ({ console: { error, log }, fs: { promises: { mkdir, readFile, readdir, writeFile } }, fetch, https: { createServer }, }: Io) => EffectToPromise;
|
package/io/module.f.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { todo } from "../dev/module.f.js";
|
|
2
2
|
import { normalize } from "../path/module.f.js";
|
|
3
|
-
import {
|
|
3
|
+
import {} from "../types/effects/module.f.js";
|
|
4
4
|
import { asyncRun } from "../types/effects/module.js";
|
|
5
|
+
import { asBase, asNominal } from "../types/nominal/module.f.js";
|
|
5
6
|
import { error, ok } from "../types/result/module.f.js";
|
|
6
7
|
import { fromVec, toVec } from "../types/uint8array/module.f.js";
|
|
7
8
|
/**
|
|
@@ -28,9 +29,9 @@ const tc = async (f) => {
|
|
|
28
29
|
return error(e);
|
|
29
30
|
}
|
|
30
31
|
};
|
|
31
|
-
export const fromIo = ({ console: { error, log }, fs: { promises: { mkdir, readFile, readdir, writeFile } }, fetch, }) => {
|
|
32
|
+
export const fromIo = ({ console: { error, log }, fs: { promises: { mkdir, readFile, readdir, writeFile } }, fetch, https: { createServer }, }) => {
|
|
32
33
|
const result = asyncRun({
|
|
33
|
-
all: async (effects) => await Promise.all(effects.map(
|
|
34
|
+
all: async (effects) => await Promise.all(effects.map(result)),
|
|
34
35
|
error: async (message) => error(message),
|
|
35
36
|
log: async (message) => log(message),
|
|
36
37
|
fetch: async (url) => tc(async () => {
|
|
@@ -45,6 +46,14 @@ export const fromIo = ({ console: { error, log }, fs: { promises: { mkdir, readF
|
|
|
45
46
|
readdir: ([path, r]) => tc(async () => (await readdir(path, { ...r, withFileTypes: true }))
|
|
46
47
|
.map(v => ({ name: v.name, parentPath: normalize(v.parentPath), isFile: v.isFile() }))),
|
|
47
48
|
writeFile: ([path, data]) => tc(() => writeFile(path, fromVec(data))),
|
|
49
|
+
createServer: async (requestListener) => {
|
|
50
|
+
const server = asNominal(createServer(requestListener));
|
|
51
|
+
return server;
|
|
52
|
+
},
|
|
53
|
+
listen: async ([server, port]) => {
|
|
54
|
+
const s = asBase(server);
|
|
55
|
+
s.listen(port);
|
|
56
|
+
},
|
|
48
57
|
});
|
|
49
58
|
return result;
|
|
50
59
|
};
|
package/io/module.js
CHANGED
|
@@ -6,6 +6,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
6
6
|
}
|
|
7
7
|
return path;
|
|
8
8
|
};
|
|
9
|
+
import https from 'node:https';
|
|
9
10
|
import { fromIo, run } from "./module.f.js";
|
|
10
11
|
import fs from 'node:fs';
|
|
11
12
|
import process from "node:process";
|
|
@@ -39,6 +40,7 @@ export const io = {
|
|
|
39
40
|
return error(e);
|
|
40
41
|
}
|
|
41
42
|
},
|
|
43
|
+
https
|
|
42
44
|
};
|
|
43
45
|
export const legacyRun = run(io);
|
|
44
46
|
export const ioRun = (io) => {
|
package/io/virtual/module.f.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { at } from "../../types/ordered_map/module.f.js";
|
|
2
|
+
import { todo } from "../../dev/module.f.js";
|
|
2
3
|
export const createVirtualIo = (files) => ({
|
|
3
4
|
console: {
|
|
4
5
|
log: (..._d) => { },
|
|
@@ -33,4 +34,7 @@ export const createVirtualIo = (files) => ({
|
|
|
33
34
|
fetch: () => Promise.reject(),
|
|
34
35
|
tryCatch: f => ['ok', f()],
|
|
35
36
|
asyncTryCatch: async (f) => ['ok', await f()],
|
|
37
|
+
https: {
|
|
38
|
+
createServer: todo
|
|
39
|
+
}
|
|
36
40
|
});
|
|
@@ -7,4 +7,10 @@ import { type Result } from '../../types/result/module.f.ts';
|
|
|
7
7
|
import { type List } from '../../types/list/module.f.ts';
|
|
8
8
|
import { type JsonToken } from '../tokenizer/module.f.ts';
|
|
9
9
|
import { type Unknown } from '../module.f.ts';
|
|
10
|
+
/**
|
|
11
|
+
* Parses a list of JSON tokens into a JSON-compatible value.
|
|
12
|
+
*
|
|
13
|
+
* Returns `ok` with the parsed value on success, or `error` with a message
|
|
14
|
+
* when the token sequence is invalid or incomplete.
|
|
15
|
+
*/
|
|
10
16
|
export declare const parse: (tokenList: List<JsonToken>) => Result<Unknown, string>;
|
package/json/parser/module.f.js
CHANGED
|
@@ -156,6 +156,12 @@ const foldOp = token => state => {
|
|
|
156
156
|
case '{,': return parseObjectCommaOp(token)(state);
|
|
157
157
|
}
|
|
158
158
|
};
|
|
159
|
+
/**
|
|
160
|
+
* Parses a list of JSON tokens into a JSON-compatible value.
|
|
161
|
+
*
|
|
162
|
+
* Returns `ok` with the parsed value on success, or `error` with a message
|
|
163
|
+
* when the token sequence is invalid or incomplete.
|
|
164
|
+
*/
|
|
159
165
|
export const parse = tokenList => {
|
|
160
166
|
const state = fold(foldOp)({ status: '', top: null, stack: null })(tokenList);
|
|
161
167
|
switch (state.status) {
|
|
@@ -4,9 +4,21 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { type List } from '../../types/list/module.f.ts';
|
|
7
|
+
/**
|
|
8
|
+
* Serializes a string as a JSON string literal.
|
|
9
|
+
*/
|
|
7
10
|
export declare const stringSerialize: (_: string) => List<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Serializes a number as a JSON number literal.
|
|
13
|
+
*/
|
|
8
14
|
export declare const numberSerialize: (_: number) => List<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Shared serialized representation for `null`.
|
|
17
|
+
*/
|
|
9
18
|
export declare const nullSerialize: string[];
|
|
10
19
|
export declare const boolSerialize: (_: boolean) => List<string>;
|
|
11
20
|
export declare const objectWrap: (input: List<List<string>>) => List<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Wraps serialized entries into a JSON array.
|
|
23
|
+
*/
|
|
12
24
|
export declare const arrayWrap: (input: List<List<string>>) => List<string>;
|
|
@@ -7,8 +7,17 @@ import { flat, reduce, empty } from "../../types/list/module.f.js";
|
|
|
7
7
|
import {} from "../../types/object/module.f.js";
|
|
8
8
|
import {} from "../../types/function/operator/module.f.js";
|
|
9
9
|
const jsonStringify = JSON.stringify;
|
|
10
|
+
/**
|
|
11
|
+
* Serializes a string as a JSON string literal.
|
|
12
|
+
*/
|
|
10
13
|
export const stringSerialize = input => [jsonStringify(input)];
|
|
14
|
+
/**
|
|
15
|
+
* Serializes a number as a JSON number literal.
|
|
16
|
+
*/
|
|
11
17
|
export const numberSerialize = input => [jsonStringify(input)];
|
|
18
|
+
/**
|
|
19
|
+
* Shared serialized representation for `null`.
|
|
20
|
+
*/
|
|
12
21
|
export const nullSerialize = ['null'];
|
|
13
22
|
const trueSerialize = ['true'];
|
|
14
23
|
const falseSerialize = ['false'];
|
|
@@ -22,4 +31,7 @@ const wrap = open => close => {
|
|
|
22
31
|
return input => flat([seqOpen, join(input), seqClose]);
|
|
23
32
|
};
|
|
24
33
|
export const objectWrap = wrap('{')('}');
|
|
34
|
+
/**
|
|
35
|
+
* Wraps serialized entries into a JSON array.
|
|
36
|
+
*/
|
|
25
37
|
export const arrayWrap = wrap('[')(']');
|
|
@@ -5,4 +5,11 @@ export type JsonToken = {
|
|
|
5
5
|
} | {
|
|
6
6
|
readonly kind: '{' | '}' | ':' | ',' | '[' | ']';
|
|
7
7
|
} | StringToken | NumberToken | ErrorToken | EofToken;
|
|
8
|
+
/**
|
|
9
|
+
* Converts a stream of UTF-8 bytes into JSON tokens.
|
|
10
|
+
*
|
|
11
|
+
* The tokenizer accepts only JSON-compatible JavaScript tokens, ignores
|
|
12
|
+
* whitespace/newline tokens, and reports invalid token sequences as
|
|
13
|
+
* `{ kind: 'error' }` tokens.
|
|
14
|
+
*/
|
|
8
15
|
export declare const tokenize: (input: List<number>) => List<JsonToken>;
|
|
@@ -50,6 +50,13 @@ const scanToken = state => input => {
|
|
|
50
50
|
default: return parseDefaultState(input);
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* Converts a stream of UTF-8 bytes into JSON tokens.
|
|
55
|
+
*
|
|
56
|
+
* The tokenizer accepts only JSON-compatible JavaScript tokens, ignores
|
|
57
|
+
* whitespace/newline tokens, and reports invalid token sequences as
|
|
58
|
+
* `{ kind: 'error' }` tokens.
|
|
59
|
+
*/
|
|
53
60
|
export const tokenize = (input) => {
|
|
54
61
|
const jsTokens = jsTokenize(input)('');
|
|
55
62
|
return flat(stateScan(scanToken)({ kind: 'def' })(concat(jsTokens)([null])));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"prepack": "tsc --NoEmit false",
|
|
12
12
|
"test20": "npm run prepack && node --test",
|
|
13
13
|
"test": "tsc && node --test --experimental-strip-types --experimental-test-coverage --test-coverage-include=**/module.f.ts",
|
|
14
|
-
"index": "node ./dev/index/module.ts",
|
|
14
|
+
"index": "node ./fjs/module.ts r ./dev/index/module.f.ts",
|
|
15
15
|
"fst": "node ./fjs/module.ts t",
|
|
16
16
|
"fjs": "node ./fjs/module.ts",
|
|
17
17
|
"ci-update": "node ./fjs/module.ts r ./ci/module.f.ts",
|
package/path/module.f.d.ts
CHANGED
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import type { Reduce, Unary } from "../types/function/operator/module.f.ts";
|
|
7
|
+
/**
|
|
8
|
+
* Splits a path into normalized segments.
|
|
9
|
+
*
|
|
10
|
+
* Empty (`""`) and current-directory (`"."`) segments are removed, parent-directory
|
|
11
|
+
* (`".."`) segments collapse the previous segment when possible, and Windows
|
|
12
|
+
* separators are converted to POSIX separators.
|
|
13
|
+
*/
|
|
7
14
|
export declare const parse: (path: string) => readonly string[];
|
|
15
|
+
/**
|
|
16
|
+
* Normalizes a path string by parsing and rejoining it with POSIX separators.
|
|
17
|
+
*/
|
|
8
18
|
export declare const normalize: Unary<string, string>;
|
|
19
|
+
/**
|
|
20
|
+
* Concatenates two path fragments and returns a normalized path.
|
|
21
|
+
*/
|
|
9
22
|
export declare const concat: Reduce<string>;
|
package/path/module.f.js
CHANGED
|
@@ -21,14 +21,27 @@ const foldNormalizeOp = input => state => {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Splits a path into normalized segments.
|
|
26
|
+
*
|
|
27
|
+
* Empty (`""`) and current-directory (`"."`) segments are removed, parent-directory
|
|
28
|
+
* (`".."`) segments collapse the previous segment when possible, and Windows
|
|
29
|
+
* separators are converted to POSIX separators.
|
|
30
|
+
*/
|
|
24
31
|
export const parse = (path) => {
|
|
25
32
|
const split = path.replaceAll('\\', '/').split('/');
|
|
26
33
|
return toArray(fold(foldNormalizeOp)([])(split));
|
|
27
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Normalizes a path string by parsing and rejoining it with POSIX separators.
|
|
37
|
+
*/
|
|
28
38
|
export const normalize = path => {
|
|
29
39
|
const foldResult = parse(path);
|
|
30
40
|
return join('/')(foldResult);
|
|
31
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Concatenates two path fragments and returns a normalized path.
|
|
44
|
+
*/
|
|
32
45
|
export const concat = a => b => {
|
|
33
46
|
const s = stringConcat([a, '/', b]);
|
|
34
47
|
return normalize(s);
|
package/text/ascii/module.f.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides ASCII code point constants and helpers for creating numeric code points and inclusive ranges.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
1
6
|
import type { Range } from '../../types/range/module.f.ts';
|
|
7
|
+
/** Returns the code point value of the first character in a string. */
|
|
2
8
|
export declare const one: (s: string) => number;
|
|
9
|
+
/** Returns an inclusive code point range from the first two characters in a string. */
|
|
3
10
|
export declare const range: (s: string) => Range;
|
|
4
11
|
/** 0x08 */
|
|
5
12
|
export declare const backspace: number;
|
package/text/ascii/module.f.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides ASCII code point constants and helpers for creating numeric code points and inclusive ranges.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
1
6
|
const at = (s) => (i) => {
|
|
2
7
|
const r = s.codePointAt(i);
|
|
3
8
|
if (r === void 0) {
|
|
@@ -5,7 +10,9 @@ const at = (s) => (i) => {
|
|
|
5
10
|
}
|
|
6
11
|
return r;
|
|
7
12
|
};
|
|
13
|
+
/** Returns the code point value of the first character in a string. */
|
|
8
14
|
export const one = (s) => at(s)(0);
|
|
15
|
+
/** Returns an inclusive code point range from the first two characters in a string. */
|
|
9
16
|
export const range = (s) => {
|
|
10
17
|
const f = at(s);
|
|
11
18
|
const f0 = f(0);
|
package/text/sgr/module.f.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ANSI Control Sequence Introducer (CSI) and Select Graphic Rendition (SGR)
|
|
3
|
+
* helpers for writing formatted terminal output and TTY-aware console streams.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
1
7
|
import type { Io, Writable } from "../../io/module.f.ts";
|
|
2
8
|
export declare const backspace: string;
|
|
3
9
|
type End = 'm';
|
package/text/sgr/module.f.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* ANSI Control Sequence Introducer (CSI) and Select Graphic Rendition (SGR)
|
|
3
|
+
* helpers for writing formatted terminal output and TTY-aware console streams.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
3
7
|
export const backspace = '\x08';
|
|
4
8
|
const begin = '\x1b[';
|
|
5
9
|
/**
|
|
@@ -13,68 +13,3 @@ export const doFull = (cmd, param, cont) => ({
|
|
|
13
13
|
});
|
|
14
14
|
export const do_ = (cmd) => (param) => doFull(cmd, param, pure);
|
|
15
15
|
export const begin = pure(undefined);
|
|
16
|
-
//----------------------------------------------------------------------
|
|
17
|
-
/*
|
|
18
|
-
export type Operations = {
|
|
19
|
-
readonly [command in string]: readonly [input: unknown, output: unknown]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type Effect<O extends Operations, T> = Pure<O, T> | Do<O, T>
|
|
23
|
-
|
|
24
|
-
export type Pure<O, T> = readonly [T]
|
|
25
|
-
|
|
26
|
-
export type One<O extends Operations, T, K extends keyof O & string> =
|
|
27
|
-
readonly [K, O[K][0], (input: O[K][1]) => Effect<O, T>]
|
|
28
|
-
|
|
29
|
-
export type Do<O extends Operations, T> = { readonly [K in keyof O & string]: One<O, T, K> }[keyof O & string]
|
|
30
|
-
|
|
31
|
-
export const pure = <O extends Operations, T>(value: T): Pure<O, T> => [value]
|
|
32
|
-
|
|
33
|
-
const doFull = <O extends Operations, K extends keyof O & string, T>(
|
|
34
|
-
cmd: K,
|
|
35
|
-
payload: O[K][0],
|
|
36
|
-
cont: (input: O[K][1]) => Effect<O, T>
|
|
37
|
-
): Do<O, T> =>
|
|
38
|
-
[cmd, payload, cont]
|
|
39
|
-
|
|
40
|
-
export const do_ = <O extends Operations, K extends keyof O & string>(
|
|
41
|
-
cmd: K,
|
|
42
|
-
payload: O[K][0]
|
|
43
|
-
): Do<O, O[K][1]> =>
|
|
44
|
-
doFull(cmd, payload, pure)
|
|
45
|
-
|
|
46
|
-
export type ToAsyncOperationMap<O extends Operations> = {
|
|
47
|
-
readonly [K in keyof O]: (payload: O[K][0]) => Promise<O[K][1]>
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export const step =
|
|
51
|
-
<O extends Operations, T>(e: Effect<O, T>) =>
|
|
52
|
-
<O1 extends Operations, R>(f: (_: T) => Effect<O1, R>): Effect<O | O1, R> =>
|
|
53
|
-
{
|
|
54
|
-
if (e.length === 1) {
|
|
55
|
-
const [value] = e
|
|
56
|
-
return f(value)
|
|
57
|
-
}
|
|
58
|
-
const [cmd, payload, cont] = e
|
|
59
|
-
return doFull(cmd, payload, x => step(cont(x))(f))
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export const map =
|
|
63
|
-
<O extends Operations, T>(e: Effect<O, T>) =>
|
|
64
|
-
<R>(f: (_: T) => R): Effect<O, R> =>
|
|
65
|
-
step(e)(x => pure(f(x)))
|
|
66
|
-
|
|
67
|
-
export type Fluent<O extends Operations, T> = {
|
|
68
|
-
readonly effect: Effect<O, T>
|
|
69
|
-
readonly step: <O1 extends Operations, R>(f: (_: T) => Effect<O1, R>) => Fluent<O | O1, R>
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const wrap = <O extends Operations, T>(effect: Effect<O, T>): Fluent<O, T> => ({
|
|
73
|
-
effect,
|
|
74
|
-
step: x => wrap(step(effect)(x)),
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
export const fluent: Fluent<{}, void> = wrap(pure(undefined))
|
|
78
|
-
|
|
79
|
-
const empty: Effect<{}, readonly never[]> = pure([])
|
|
80
|
-
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Vec } from '../../bit_vec/module.f.ts';
|
|
2
|
+
import type { Nominal } from '../../nominal/module.f.ts';
|
|
2
3
|
import type { Result } from '../../result/module.f.ts';
|
|
3
4
|
import { type Effect, type Func, type Operation, type ToAsyncOperationMap } from '../module.f.ts';
|
|
4
5
|
export type IoResult<T> = Result<T, unknown>;
|
|
@@ -11,6 +12,7 @@ export type All = ['all', <T>(_: readonly Effect<never, T>[]) => readonly T[]];
|
|
|
11
12
|
* @returns
|
|
12
13
|
*/
|
|
13
14
|
export declare const all: <O extends Operation, T>(...a: readonly Effect<O, T>[]) => Effect<O | All, readonly T[]>;
|
|
15
|
+
export declare const both: <O0 extends Operation, T0>(a: Effect<O0, T0>) => <O1 extends Operation, T1>(b: Effect<O1, T1>) => Effect<O0 | O1 | All, readonly [T0, T1]>;
|
|
14
16
|
export type Fetch = ['fetch', (_: string) => IoResult<Vec>];
|
|
15
17
|
export declare const fetch: Func<Fetch>;
|
|
16
18
|
export type MakeDirectoryOptions = {
|
|
@@ -45,7 +47,15 @@ export declare const error: Func<Error>;
|
|
|
45
47
|
export type Log = ['log', (_: string) => void];
|
|
46
48
|
export declare const log: Func<Log>;
|
|
47
49
|
export type Console = Log | Error;
|
|
48
|
-
export type
|
|
50
|
+
export type Server = Nominal<'server', `160855c4f69310fece3273c1853ac32de43dee1eb41bf59d821917f8eebe9272`, unknown>;
|
|
51
|
+
export type IncomingMessage = {};
|
|
52
|
+
export type ServerResponse = {};
|
|
53
|
+
export type RequestListener = (_: IncomingMessage) => ServerResponse;
|
|
54
|
+
export type CreateServer = ['createServer', (_: RequestListener) => Server];
|
|
55
|
+
export declare const createServer: Func<CreateServer>;
|
|
56
|
+
export type Listen = ['listen', (_: readonly [Server, number]) => void];
|
|
57
|
+
export type Http = CreateServer | Listen;
|
|
58
|
+
export type NodeOp = All | Fetch | Console | Fs | Http;
|
|
49
59
|
export type NodeEffect<T> = Effect<NodeOp, T>;
|
|
50
60
|
export type NodeOperationMap = ToAsyncOperationMap<NodeOp>;
|
|
51
61
|
export type NodeProgram = (argv: readonly string[]) => Effect<NodeOp, number>;
|
|
@@ -6,10 +6,8 @@ import { do_ } from "../module.f.js";
|
|
|
6
6
|
* @param a
|
|
7
7
|
* @returns
|
|
8
8
|
*/
|
|
9
|
-
export const all = (...a) =>
|
|
10
|
-
|
|
11
|
-
return result;
|
|
12
|
-
};
|
|
9
|
+
export const all = (...a) => do_('all')(a);
|
|
10
|
+
export const both = (a) => (b) => all(a, b);
|
|
13
11
|
export const fetch = do_('fetch');
|
|
14
12
|
export const mkdir = (...p) => do_('mkdir')(p);
|
|
15
13
|
export const readFile = do_('readFile');
|
|
@@ -17,3 +15,4 @@ export const readdir = (...p) => do_('readdir')(p);
|
|
|
17
15
|
export const writeFile = (...p) => do_('writeFile')(p);
|
|
18
16
|
export const error = do_('error');
|
|
19
17
|
export const log = do_('log');
|
|
18
|
+
export const createServer = do_('createServer');
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
import { todo } from "../../../../dev/module.f.js";
|
|
6
7
|
import { parse } from "../../../../path/module.f.js";
|
|
7
8
|
import { isVec } from "../../../bit_vec/module.f.js";
|
|
8
9
|
import { error, ok } from "../../../result/module.f.js";
|
|
9
10
|
import { run } from "../../mock/module.f.js";
|
|
10
|
-
import { pure } from "../../module.f.js";
|
|
11
11
|
export const emptyState = {
|
|
12
12
|
stdout: '',
|
|
13
13
|
stderr: '',
|
|
@@ -115,5 +115,7 @@ const map = {
|
|
|
115
115
|
readFile,
|
|
116
116
|
readdir: (state, [path, { recursive }]) => readdir(path, recursive === true)(state, path),
|
|
117
117
|
writeFile: (state, [path, payload]) => writeFile(payload)(state, path),
|
|
118
|
+
createServer: todo,
|
|
119
|
+
listen: todo,
|
|
118
120
|
};
|
|
119
121
|
export const virtual = run(map);
|
|
@@ -3,8 +3,20 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* Nominal type.
|
|
8
|
+
*
|
|
9
|
+
* It doesn't allow `===` between different nominal types.
|
|
10
|
+
* It doesn't allow `<`, `>`, `<=`, `>=` comparisons at all.
|
|
11
|
+
*/
|
|
6
12
|
export type Nominal<N extends string, R extends string, B> = symbol & {
|
|
7
13
|
[k in N]: readonly [R, B];
|
|
8
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* note: It should compiles into `identity` and no-ops at runtime.
|
|
17
|
+
*/
|
|
9
18
|
export declare const asNominal: <N extends string, R extends string, B>(b: B) => Nominal<N, R, B>;
|
|
19
|
+
/**
|
|
20
|
+
* note: It should compiles into `identity` and no-ops at runtime.
|
|
21
|
+
*/
|
|
10
22
|
export declare const asBase: <T extends string, R extends string, B>(n: Nominal<T, R, B>) => B;
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Nominal typing helpers for branded TypeScript types.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* note: It should compiles into `identity` and no-ops at runtime.
|
|
8
|
+
*/
|
|
2
9
|
export const asNominal = (b) => b;
|
|
3
|
-
|
|
10
|
+
/**
|
|
11
|
+
* note: It should compiles into `identity` and no-ops at runtime.
|
|
12
|
+
*/
|
|
4
13
|
export const asBase = (n) => n;
|
package/dev/index/module.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dev/index/module.js
DELETED