functionalscript 0.11.1 → 0.11.3
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/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 +1 -1
- 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 +29 -0
- package/text/sgr/module.f.js +27 -2
- package/types/effects/module.f.d.ts +6 -2
- package/types/effects/module.f.js +1 -0
- package/types/effects/node/module.f.d.ts +15 -5
- package/types/effects/node/module.f.js +6 -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/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
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';
|
|
@@ -15,17 +21,40 @@ export declare const csi: (end: End) => Csi;
|
|
|
15
21
|
* https://en.wikipedia.org/wiki/ANSI_escape_code#SGR
|
|
16
22
|
*/
|
|
17
23
|
export declare const sgr: Csi;
|
|
24
|
+
/** Resets all SGR styles to terminal defaults. */
|
|
18
25
|
export declare const reset: string;
|
|
26
|
+
/** Enables bold/intense text rendering when supported by the terminal. */
|
|
19
27
|
export declare const bold: string;
|
|
28
|
+
/** Applies red foreground color to subsequent text. */
|
|
20
29
|
export declare const fgRed: string;
|
|
30
|
+
/** Applies green foreground color to subsequent text. */
|
|
21
31
|
export declare const fgGreen: string;
|
|
22
32
|
export type Stdout = {
|
|
33
|
+
/** Writes a string to the output stream. */
|
|
23
34
|
readonly write: (s: string) => void;
|
|
24
35
|
};
|
|
36
|
+
/** Stateful writer that updates previously printed text in-place. */
|
|
25
37
|
export type WriteText = (text: string) => WriteText;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a stateful text writer that rewrites the previous value using backspaces.
|
|
40
|
+
*
|
|
41
|
+
* @param stdout - Destination output stream.
|
|
42
|
+
* @returns A recursive writer that replaces prior text on each call.
|
|
43
|
+
*/
|
|
26
44
|
export declare const createConsoleText: (stdout: Stdout) => WriteText;
|
|
27
45
|
export type CsiConsole = (s: string) => void;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a TTY-aware console function.
|
|
48
|
+
*
|
|
49
|
+
* For TTY destinations, ANSI SGR sequences are preserved.
|
|
50
|
+
* For non-TTY destinations, ANSI SGR sequences are stripped.
|
|
51
|
+
*
|
|
52
|
+
* @param io - Runtime IO bindings.
|
|
53
|
+
* @returns A function that targets a writable stream.
|
|
54
|
+
*/
|
|
28
55
|
export declare const console: ({ fs: { writeSync } }: Io) => (w: Writable) => CsiConsole;
|
|
56
|
+
/** Writes to process stdout using a TTY-aware CSI console. */
|
|
29
57
|
export declare const stdio: (io: Io) => CsiConsole;
|
|
58
|
+
/** Writes to process stderr using a TTY-aware CSI console. */
|
|
30
59
|
export declare const stderr: (io: Io) => CsiConsole;
|
|
31
60
|
export {};
|
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
|
/**
|
|
@@ -15,9 +19,13 @@ export const csi = (end) => code => `${begin}${code.toString()}${end}`;
|
|
|
15
19
|
* https://en.wikipedia.org/wiki/ANSI_escape_code#SGR
|
|
16
20
|
*/
|
|
17
21
|
export const sgr = csi('m');
|
|
22
|
+
/** Resets all SGR styles to terminal defaults. */
|
|
18
23
|
export const reset = sgr(0);
|
|
24
|
+
/** Enables bold/intense text rendering when supported by the terminal. */
|
|
19
25
|
export const bold = sgr(1);
|
|
26
|
+
/** Applies red foreground color to subsequent text. */
|
|
20
27
|
export const fgRed = sgr(31);
|
|
28
|
+
/** Applies green foreground color to subsequent text. */
|
|
21
29
|
export const fgGreen = sgr(32);
|
|
22
30
|
const { max } = Math;
|
|
23
31
|
const replace = (old) => (text) => {
|
|
@@ -25,6 +33,12 @@ const replace = (old) => (text) => {
|
|
|
25
33
|
const suffixLength = max(0, len - text.length);
|
|
26
34
|
return backspace.repeat(len) + text + " ".repeat(suffixLength) + backspace.repeat(suffixLength);
|
|
27
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Creates a stateful text writer that rewrites the previous value using backspaces.
|
|
38
|
+
*
|
|
39
|
+
* @param stdout - Destination output stream.
|
|
40
|
+
* @returns A recursive writer that replaces prior text on each call.
|
|
41
|
+
*/
|
|
28
42
|
export const createConsoleText = (stdout) => {
|
|
29
43
|
const f = (old) => (text) => {
|
|
30
44
|
stdout.write(replace(old)(text));
|
|
@@ -32,11 +46,22 @@ export const createConsoleText = (stdout) => {
|
|
|
32
46
|
};
|
|
33
47
|
return f('');
|
|
34
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* Creates a TTY-aware console function.
|
|
51
|
+
*
|
|
52
|
+
* For TTY destinations, ANSI SGR sequences are preserved.
|
|
53
|
+
* For non-TTY destinations, ANSI SGR sequences are stripped.
|
|
54
|
+
*
|
|
55
|
+
* @param io - Runtime IO bindings.
|
|
56
|
+
* @returns A function that targets a writable stream.
|
|
57
|
+
*/
|
|
35
58
|
export const console = ({ fs: { writeSync } }) => (w) => {
|
|
36
59
|
const { isTTY } = w;
|
|
37
60
|
return isTTY
|
|
38
61
|
? (s) => writeSync(w.fd, s + '\n')
|
|
39
62
|
: (s) => writeSync(w.fd, s.replace(/\x1b\[[0-9;]*m/g, '') + '\n');
|
|
40
63
|
};
|
|
64
|
+
/** Writes to process stdout using a TTY-aware CSI console. */
|
|
41
65
|
export const stdio = (io) => console(io)(io.process.stdout);
|
|
66
|
+
/** Writes to process stderr using a TTY-aware CSI console. */
|
|
42
67
|
export const stderr = (io) => console(io)(io.process.stderr);
|
|
@@ -16,10 +16,14 @@ export type DoK<O extends Operation, T, K extends O[0]> = DoKPR<O, T, K, Pr<O, K
|
|
|
16
16
|
export type Do<O extends Operation, T> = DoK<O, T, O[0]>;
|
|
17
17
|
export declare const pure: <T>(v: T) => Effect<never, T>;
|
|
18
18
|
export declare const doFull: <O extends Operation, T, K extends O[0]>(cmd: K, param: Pr<O, K>[0], cont: (input: Pr<O, K>[1]) => Effect<O, T>) => Effect<O, T>;
|
|
19
|
-
export
|
|
19
|
+
export type Param<O extends Operation> = F<O>[0];
|
|
20
|
+
export type Return<O extends Operation> = F<O>[1];
|
|
21
|
+
export declare const do_: <O extends Operation>(cmd: O[0]) => (param: Param<O>) => Effect<O, Return<O>>;
|
|
22
|
+
export declare const doRest: <O extends Operation>(cmd: O[0]) => (...param: Param<O>) => Effect<O, Return<O>>;
|
|
20
23
|
export declare const begin: Effect<never, void>;
|
|
21
24
|
export type ToAsyncOperationMap<O extends Operation> = {
|
|
22
25
|
readonly [K in O[0]]: (payload: Pr<O, K>[0]) => Promise<Pr<O, K>[1]>;
|
|
23
26
|
};
|
|
24
27
|
export type F<O extends Operation> = Pr<O, O[0]>;
|
|
25
|
-
export type Func<O extends Operation> = (_:
|
|
28
|
+
export type Func<O extends Operation> = (_: Param<O>) => Effect<O, Return<O>>;
|
|
29
|
+
export type RestFunc<O extends Operation> = (..._: Param<O>) => Effect<O, Return<O>>;
|
|
@@ -12,4 +12,5 @@ export const doFull = (cmd, param, cont) => ({
|
|
|
12
12
|
step: (f) => doFull(cmd, param, x => cont(x).step(f)),
|
|
13
13
|
});
|
|
14
14
|
export const do_ = (cmd) => (param) => doFull(cmd, param, pure);
|
|
15
|
+
export const doRest = (cmd) => (...param) => do_(cmd)(param);
|
|
15
16
|
export const begin = pure(undefined);
|
|
@@ -1,6 +1,7 @@
|
|
|
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
|
-
import { type Effect, type Func, type Operation, type ToAsyncOperationMap } from '../module.f.ts';
|
|
4
|
+
import { type Effect, type Func, type Operation, type RestFunc, type ToAsyncOperationMap } from '../module.f.ts';
|
|
4
5
|
export type IoResult<T> = Result<T, unknown>;
|
|
5
6
|
export type All = ['all', <T>(_: readonly Effect<never, T>[]) => readonly T[]];
|
|
6
7
|
/**
|
|
@@ -19,7 +20,7 @@ export type MakeDirectoryOptions = {
|
|
|
19
20
|
};
|
|
20
21
|
export type MkdirParam = readonly [string, MakeDirectoryOptions?];
|
|
21
22
|
export type Mkdir = readonly ['mkdir', (_: MkdirParam) => IoResult<void>];
|
|
22
|
-
export declare const mkdir:
|
|
23
|
+
export declare const mkdir: RestFunc<Mkdir>;
|
|
23
24
|
export type ReadFile = readonly ['readFile', (_: string) => IoResult<Vec>];
|
|
24
25
|
export declare const readFile: Func<ReadFile>;
|
|
25
26
|
/**
|
|
@@ -36,17 +37,26 @@ export type ReaddirOptions = {
|
|
|
36
37
|
};
|
|
37
38
|
export type ReaddirParam = readonly [string, ReaddirOptions];
|
|
38
39
|
export type Readdir = readonly ['readdir', (_: ReaddirParam) => IoResult<readonly Dirent[]>];
|
|
39
|
-
export declare const readdir:
|
|
40
|
+
export declare const readdir: RestFunc<Readdir>;
|
|
40
41
|
export type WriteFileParam = readonly [string, Vec];
|
|
41
42
|
export type WriteFile = readonly ['writeFile', (_: WriteFileParam) => IoResult<void>];
|
|
42
|
-
export declare const writeFile:
|
|
43
|
+
export declare const writeFile: RestFunc<WriteFile>;
|
|
43
44
|
export type Fs = Mkdir | ReadFile | Readdir | WriteFile;
|
|
44
45
|
export type Error = ['error', (_: string) => void];
|
|
45
46
|
export declare const error: Func<Error>;
|
|
46
47
|
export type Log = ['log', (_: string) => void];
|
|
47
48
|
export declare const log: Func<Log>;
|
|
48
49
|
export type Console = Log | Error;
|
|
49
|
-
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 declare const listen: RestFunc<Listen>;
|
|
58
|
+
export type Http = CreateServer | Listen;
|
|
59
|
+
export type NodeOp = All | Fetch | Console | Fs | Http;
|
|
50
60
|
export type NodeEffect<T> = Effect<NodeOp, T>;
|
|
51
61
|
export type NodeOperationMap = ToAsyncOperationMap<NodeOp>;
|
|
52
62
|
export type NodeProgram = (argv: readonly string[]) => Effect<NodeOp, number>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { do_ } from "../module.f.js";
|
|
1
|
+
import { doRest, do_ } from "../module.f.js";
|
|
2
2
|
/**
|
|
3
3
|
* To run the operation `O` should be known by the runner/engine.
|
|
4
4
|
* This is the reason why we merge `O` with `All` in the resulted `Effect`.
|
|
@@ -9,9 +9,11 @@ import { do_ } from "../module.f.js";
|
|
|
9
9
|
export const all = (...a) => do_('all')(a);
|
|
10
10
|
export const both = (a) => (b) => all(a, b);
|
|
11
11
|
export const fetch = do_('fetch');
|
|
12
|
-
export const mkdir = (
|
|
12
|
+
export const mkdir = doRest('mkdir');
|
|
13
13
|
export const readFile = do_('readFile');
|
|
14
|
-
export const readdir = (
|
|
15
|
-
export const writeFile = (
|
|
14
|
+
export const readdir = doRest('readdir');
|
|
15
|
+
export const writeFile = doRest('writeFile');
|
|
16
16
|
export const error = do_('error');
|
|
17
17
|
export const log = do_('log');
|
|
18
|
+
export const createServer = do_('createServer');
|
|
19
|
+
export const listen = doRest('listen');
|
|
@@ -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;
|