functionalscript 0.23.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fs/asserts/proof.f.d.ts +8 -0
- package/fs/asserts/proof.f.js +51 -0
- package/fs/bnf/data/proof.f.js +7 -17
- package/fs/bnf/module.f.d.ts +10 -0
- package/fs/bnf/module.f.js +10 -0
- package/fs/bnf/testlib.f.js +4 -9
- package/fs/cas/module.f.d.ts +2 -2
- package/fs/cas/module.f.js +2 -2
- package/fs/cas/proof.f.js +3 -3
- package/fs/ci/common/module.f.d.ts +2 -0
- package/fs/ci/common/module.f.js +4 -1
- package/fs/ci/config/module.f.d.ts +2 -2
- package/fs/ci/config/module.f.js +2 -2
- package/fs/ci/module.f.d.ts +3 -4
- package/fs/ci/module.f.js +10 -8
- package/fs/ci/node/module.f.js +4 -2
- package/fs/ci/proof.f.js +9 -6
- package/fs/crypto/sha2/module.f.js +32 -36
- package/fs/crypto/vdf/module.f.d.ts +21 -0
- package/fs/crypto/vdf/module.f.js +57 -0
- package/fs/crypto/vdf/proof.f.d.ts +32 -0
- package/fs/crypto/vdf/proof.f.js +135 -0
- package/fs/dev/module.f.d.ts +2 -9
- package/fs/dev/module.f.js +10 -9
- package/fs/dev/proof.f.d.ts +0 -1
- package/fs/dev/proof.f.js +0 -21
- package/fs/dev/version/module.f.d.ts +2 -2
- package/fs/dev/version/module.f.js +2 -2
- package/fs/dev/version/proof.f.js +2 -2
- package/fs/djs/module.f.d.ts +2 -2
- package/fs/djs/module.f.js +2 -2
- package/fs/djs/parser/module.f.d.ts +0 -2
- package/fs/djs/proof.f.js +1 -1
- package/fs/djs/transpiler/module.f.d.ts +2 -2
- package/fs/djs/transpiler/module.f.js +2 -2
- package/fs/djs/transpiler/proof.f.js +1 -1
- package/fs/{types/effects → effects}/module.f.d.ts +1 -1
- package/fs/{types/effects → effects}/module.f.js +1 -1
- package/fs/{io → effects/node}/module.d.ts +5 -12
- package/fs/{types/effects → effects}/node/module.f.d.ts +3 -3
- package/fs/{types/effects → effects}/node/module.f.js +1 -1
- package/fs/{io → effects/node}/module.js +96 -12
- package/fs/{types/effects → effects}/node/proof.f.js +1 -1
- package/fs/{types/effects → effects}/node/virtual/module.f.d.ts +1 -1
- package/fs/{types/effects → effects}/node/virtual/module.f.js +5 -5
- package/fs/emergent_testing/all.test.d.ts +1 -1
- package/fs/emergent_testing/all.test.js +3 -2
- package/fs/emergent_testing/module.f.d.ts +2 -2
- package/fs/emergent_testing/module.f.js +2 -2
- package/fs/emergent_testing/proof.f.js +4 -4
- package/fs/emergent_testing/scenarios/all.d.ts +1 -1
- package/fs/emergent_testing/scenarios/all.js +1 -1
- package/fs/fjs/module.f.d.ts +1 -1
- package/fs/fjs/module.f.js +1 -1
- package/fs/fjs/module.js +2 -2
- package/fs/json/module.f.d.ts +25 -9
- package/fs/json/module.f.js +25 -3
- package/fs/json/rpc/module.f.d.ts +109 -0
- package/fs/json/rpc/module.f.js +84 -0
- package/fs/json/rpc/proof.f.d.ts +35 -0
- package/fs/json/rpc/proof.f.js +68 -0
- package/fs/json/schema/module.f.d.ts +76 -0
- package/fs/json/schema/module.f.js +112 -0
- package/fs/json/schema/proof.f.d.ts +33 -0
- package/fs/json/schema/proof.f.js +71 -0
- package/fs/mcp/module.f.d.ts +88 -0
- package/fs/mcp/module.f.js +69 -0
- package/fs/sul/level/literal/proof.f.d.ts +1 -0
- package/fs/sul/level/literal/proof.f.js +6 -0
- package/fs/text/sgr/module.f.d.ts +2 -17
- package/fs/text/sgr/module.f.js +4 -19
- package/fs/types/array/module.f.d.ts +7 -0
- package/fs/types/array/module.f.js +7 -0
- package/fs/types/prime_field/module.f.d.ts +8 -0
- package/fs/types/prime_field/module.f.js +37 -5
- package/fs/types/prime_field/proof.f.d.ts +3 -0
- package/fs/types/prime_field/proof.f.js +27 -2
- package/fs/types/rtti/parse/module.f.d.ts +28 -0
- package/fs/types/rtti/parse/module.f.js +35 -5
- package/fs/types/rtti/ts/module.f.d.ts +46 -3
- package/fs/types/rtti/validate/module.f.js +5 -0
- package/fs/website/module.f.d.ts +2 -2
- package/fs/website/module.f.js +2 -2
- package/package.json +3 -3
- package/fs/emergent_testing/module.d.ts +0 -1
- package/fs/emergent_testing/module.js +0 -4
- package/fs/io/module.f.d.ts +0 -134
- package/fs/io/module.f.js +0 -113
- /package/fs/{types/effects → effects}/mock/module.f.d.ts +0 -0
- /package/fs/{types/effects → effects}/mock/module.f.js +0 -0
- /package/fs/{types/effects → effects}/module.d.ts +0 -0
- /package/fs/{types/effects → effects}/module.js +0 -0
- /package/fs/{types/effects → effects}/node/proof.f.d.ts +0 -0
- /package/fs/{types/effects → effects}/proof.f.d.ts +0 -0
- /package/fs/{types/effects → effects}/proof.f.js +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const proof: {
|
|
2
|
+
tag0: {
|
|
3
|
+
boolean: () => void;
|
|
4
|
+
number: () => void;
|
|
5
|
+
string: () => void;
|
|
6
|
+
bigint: () => void;
|
|
7
|
+
unknown: () => void;
|
|
8
|
+
};
|
|
9
|
+
const: {
|
|
10
|
+
null: () => void;
|
|
11
|
+
true: () => void;
|
|
12
|
+
false: () => void;
|
|
13
|
+
number: () => void;
|
|
14
|
+
string: () => void;
|
|
15
|
+
undefined: () => void;
|
|
16
|
+
bigint: () => void;
|
|
17
|
+
};
|
|
18
|
+
array: () => void;
|
|
19
|
+
record: () => void;
|
|
20
|
+
or: () => void;
|
|
21
|
+
tuple: () => void;
|
|
22
|
+
struct: {
|
|
23
|
+
allRequired: () => void;
|
|
24
|
+
withOptional: () => void;
|
|
25
|
+
allOptional: () => void;
|
|
26
|
+
empty: () => void;
|
|
27
|
+
};
|
|
28
|
+
nested: {
|
|
29
|
+
arrayOfRecords: () => void;
|
|
30
|
+
orWithConst: () => void;
|
|
31
|
+
structWithOr: () => void;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { boolean, number, string, bigint, unknown, array, record, or, option } from "../../types/rtti/module.f.js";
|
|
2
|
+
import { stringify } from "../module.f.js";
|
|
3
|
+
import { toJsonSchema } from "./module.f.js";
|
|
4
|
+
const serialize = (v) => stringify(e => e)(v);
|
|
5
|
+
const eq = (rtti, expected) => () => {
|
|
6
|
+
const result = serialize(toJsonSchema(rtti));
|
|
7
|
+
const exp = serialize(expected);
|
|
8
|
+
if (result !== exp) {
|
|
9
|
+
throw [result, exp];
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export const proof = {
|
|
13
|
+
tag0: {
|
|
14
|
+
boolean: eq(boolean, { type: 'boolean' }),
|
|
15
|
+
number: eq(number, { type: 'number' }),
|
|
16
|
+
string: eq(string, { type: 'string' }),
|
|
17
|
+
bigint: eq(bigint, { type: 'integer' }),
|
|
18
|
+
unknown: eq(unknown, {}),
|
|
19
|
+
},
|
|
20
|
+
const: {
|
|
21
|
+
null: eq(null, { const: null }),
|
|
22
|
+
true: eq(true, { const: true }),
|
|
23
|
+
false: eq(false, { const: false }),
|
|
24
|
+
number: eq(42, { const: 42 }),
|
|
25
|
+
string: eq('hello', { const: 'hello' }),
|
|
26
|
+
undefined: eq(undefined, { not: {} }),
|
|
27
|
+
bigint: eq(7n, { const: 7 }),
|
|
28
|
+
},
|
|
29
|
+
array: eq(array(number), { type: 'array', items: { type: 'number' } }),
|
|
30
|
+
record: eq(record(string), { type: 'object', additionalProperties: { type: 'string' } }),
|
|
31
|
+
or: eq(or(string, number), { anyOf: [{ type: 'string' }, { type: 'number' }] }),
|
|
32
|
+
tuple: eq([number, string], {
|
|
33
|
+
type: 'array',
|
|
34
|
+
prefixItems: [{ type: 'number' }, { type: 'string' }],
|
|
35
|
+
items: false,
|
|
36
|
+
}),
|
|
37
|
+
struct: {
|
|
38
|
+
allRequired: eq({ x: number, y: string }, {
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: { x: { type: 'number' }, y: { type: 'string' } },
|
|
41
|
+
required: ['x', 'y'],
|
|
42
|
+
}),
|
|
43
|
+
withOptional: eq({ x: number, y: option(string) }, {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: { x: { type: 'number' }, y: { type: 'string' } },
|
|
46
|
+
required: ['x'],
|
|
47
|
+
}),
|
|
48
|
+
allOptional: eq({ x: option(number) }, {
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: { x: { type: 'number' } },
|
|
51
|
+
}),
|
|
52
|
+
empty: eq({}, { type: 'object', properties: {} }),
|
|
53
|
+
},
|
|
54
|
+
nested: {
|
|
55
|
+
arrayOfRecords: eq(array(record(boolean)), {
|
|
56
|
+
type: 'array',
|
|
57
|
+
items: { type: 'object', additionalProperties: { type: 'boolean' } },
|
|
58
|
+
}),
|
|
59
|
+
orWithConst: eq(or(null, string, 42), {
|
|
60
|
+
anyOf: [{ const: null }, { type: 'string' }, { const: 42 }],
|
|
61
|
+
}),
|
|
62
|
+
structWithOr: eq({ id: or(string, number), name: option(string) }, {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
id: { anyOf: [{ type: 'string' }, { type: 'number' }] },
|
|
66
|
+
name: { type: 'string' },
|
|
67
|
+
},
|
|
68
|
+
required: ['id'],
|
|
69
|
+
}),
|
|
70
|
+
},
|
|
71
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type Unknown } from '../json/module.f.ts';
|
|
2
|
+
import type { Ts } from '../types/rtti/ts/module.f.ts';
|
|
3
|
+
import type { Operation, Effect } from '../effects/module.f.ts';
|
|
4
|
+
import type { Response } from '../json/rpc/module.f.ts';
|
|
5
|
+
/** Name + version pair sent in `initialize` requests and responses. */
|
|
6
|
+
export declare const implementation: {
|
|
7
|
+
readonly name: import("../types/rtti/module.f.ts").String;
|
|
8
|
+
readonly version: import("../types/rtti/module.f.ts").String;
|
|
9
|
+
};
|
|
10
|
+
export type Implementation = Ts<typeof implementation>;
|
|
11
|
+
/** Server capabilities advertised in the `initialize` response. */
|
|
12
|
+
export declare const serverCapabilities: {
|
|
13
|
+
readonly tools: import("../types/rtti/module.f.ts").Or<readonly [{
|
|
14
|
+
readonly listChanged: import("../types/rtti/module.f.ts").Or<readonly [import("../types/rtti/module.f.ts").Boolean, undefined]>;
|
|
15
|
+
}, undefined]>;
|
|
16
|
+
};
|
|
17
|
+
export type ServerCapabilities = Ts<typeof serverCapabilities>;
|
|
18
|
+
/** Params for the `initialize` request. */
|
|
19
|
+
export declare const initializeParams: {
|
|
20
|
+
readonly protocolVersion: import("../types/rtti/module.f.ts").String;
|
|
21
|
+
readonly capabilities: () => readonly ["or", import("../types/rtti/module.f.ts").Or<[null, import("../types/rtti/module.f.ts").Boolean, import("../types/rtti/module.f.ts").Number, import("../types/rtti/module.f.ts").String]>, import("../types/rtti/module.f.ts").Type1<"record", /*elided*/ any>, import("../types/rtti/module.f.ts").Type1<"array", /*elided*/ any>];
|
|
22
|
+
readonly clientInfo: {
|
|
23
|
+
readonly name: import("../types/rtti/module.f.ts").String;
|
|
24
|
+
readonly version: import("../types/rtti/module.f.ts").String;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export type InitializeParams = Ts<typeof initializeParams>;
|
|
28
|
+
/** Result for the `initialize` request. */
|
|
29
|
+
export declare const initializeResult: {
|
|
30
|
+
readonly protocolVersion: import("../types/rtti/module.f.ts").String;
|
|
31
|
+
readonly capabilities: {
|
|
32
|
+
readonly tools: import("../types/rtti/module.f.ts").Or<readonly [{
|
|
33
|
+
readonly listChanged: import("../types/rtti/module.f.ts").Or<readonly [import("../types/rtti/module.f.ts").Boolean, undefined]>;
|
|
34
|
+
}, undefined]>;
|
|
35
|
+
};
|
|
36
|
+
readonly serverInfo: {
|
|
37
|
+
readonly name: import("../types/rtti/module.f.ts").String;
|
|
38
|
+
readonly version: import("../types/rtti/module.f.ts").String;
|
|
39
|
+
};
|
|
40
|
+
readonly instructions: import("../types/rtti/module.f.ts").Or<readonly [import("../types/rtti/module.f.ts").String, undefined]>;
|
|
41
|
+
};
|
|
42
|
+
export type InitializeResult = Ts<typeof initializeResult>;
|
|
43
|
+
/** Plain-text content item returned by a tool call. */
|
|
44
|
+
export declare const textContent: {
|
|
45
|
+
readonly type: "text";
|
|
46
|
+
readonly text: import("../types/rtti/module.f.ts").String;
|
|
47
|
+
};
|
|
48
|
+
export type TextContent = Ts<typeof textContent>;
|
|
49
|
+
/**
|
|
50
|
+
* A tool descriptor returned by `tools/list`.
|
|
51
|
+
* `inputSchema` is a JSON Schema object — use `toJsonSchema` to derive it from
|
|
52
|
+
* an rtti schema.
|
|
53
|
+
*/
|
|
54
|
+
export declare const tool: {
|
|
55
|
+
readonly name: import("../types/rtti/module.f.ts").String;
|
|
56
|
+
readonly description: import("../types/rtti/module.f.ts").Or<readonly [import("../types/rtti/module.f.ts").String, undefined]>;
|
|
57
|
+
readonly inputSchema: () => readonly ["or", import("../types/rtti/module.f.ts").Or<[null, import("../types/rtti/module.f.ts").Boolean, import("../types/rtti/module.f.ts").Number, import("../types/rtti/module.f.ts").String]>, import("../types/rtti/module.f.ts").Type1<"record", /*elided*/ any>, import("../types/rtti/module.f.ts").Type1<"array", /*elided*/ any>];
|
|
58
|
+
};
|
|
59
|
+
export type Tool = Ts<typeof tool>;
|
|
60
|
+
export declare const toolsListResult: {
|
|
61
|
+
readonly tools: import("../types/rtti/module.f.ts").Type1<"array", {
|
|
62
|
+
readonly name: import("../types/rtti/module.f.ts").String;
|
|
63
|
+
readonly description: import("../types/rtti/module.f.ts").Or<readonly [import("../types/rtti/module.f.ts").String, undefined]>;
|
|
64
|
+
readonly inputSchema: () => readonly ["or", import("../types/rtti/module.f.ts").Or<[null, import("../types/rtti/module.f.ts").Boolean, import("../types/rtti/module.f.ts").Number, import("../types/rtti/module.f.ts").String]>, import("../types/rtti/module.f.ts").Type1<"record", /*elided*/ any>, import("../types/rtti/module.f.ts").Type1<"array", /*elided*/ any>];
|
|
65
|
+
}>;
|
|
66
|
+
readonly nextCursor: import("../types/rtti/module.f.ts").Or<readonly [import("../types/rtti/module.f.ts").String, undefined]>;
|
|
67
|
+
};
|
|
68
|
+
export type ToolsListResult = Ts<typeof toolsListResult>;
|
|
69
|
+
export declare const toolsCallParams: {
|
|
70
|
+
readonly name: import("../types/rtti/module.f.ts").String;
|
|
71
|
+
readonly arguments: import("../types/rtti/module.f.ts").Or<readonly [import("../types/rtti/module.f.ts").Type1<"record", () => readonly ["or", import("../types/rtti/module.f.ts").Or<[null, import("../types/rtti/module.f.ts").Boolean, import("../types/rtti/module.f.ts").Number, import("../types/rtti/module.f.ts").String]>, import("../types/rtti/module.f.ts").Type1<"record", /*elided*/ any>, import("../types/rtti/module.f.ts").Type1<"array", /*elided*/ any>]>, undefined]>;
|
|
72
|
+
};
|
|
73
|
+
export type ToolsCallParams = Ts<typeof toolsCallParams>;
|
|
74
|
+
export declare const toolsCallResult: {
|
|
75
|
+
readonly content: import("../types/rtti/module.f.ts").Type1<"array", {
|
|
76
|
+
readonly type: "text";
|
|
77
|
+
readonly text: import("../types/rtti/module.f.ts").String;
|
|
78
|
+
}>;
|
|
79
|
+
readonly isError: import("../types/rtti/module.f.ts").Or<readonly [import("../types/rtti/module.f.ts").Boolean, undefined]>;
|
|
80
|
+
};
|
|
81
|
+
export type ToolsCallResult = Ts<typeof toolsCallResult>;
|
|
82
|
+
/** Per-method handlers for a hello-world MCP tool server. */
|
|
83
|
+
export type McpHandlers<O extends Operation> = {
|
|
84
|
+
readonly toolsList: () => Effect<O, ToolsListResult>;
|
|
85
|
+
readonly toolsCall: (params: ToolsCallParams) => Effect<O, ToolsCallResult>;
|
|
86
|
+
};
|
|
87
|
+
/** Top-level handler: maps a raw JSON value to a JSON-RPC response (or `null` for notifications). */
|
|
88
|
+
export type Handle<O extends Operation> = (value: Unknown) => Effect<O, Response | null>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP (Model Context Protocol) message schemas — minimal subset for a
|
|
3
|
+
* hello-world tool server.
|
|
4
|
+
*
|
|
5
|
+
* Covers the three exchanges a minimal server must handle:
|
|
6
|
+
* - `initialize` / `notifications/initialized` lifecycle
|
|
7
|
+
* - `tools/list` — advertise available tools
|
|
8
|
+
* - `tools/call` — invoke a tool and return text content
|
|
9
|
+
*
|
|
10
|
+
* Each schema is both a runtime decoder (`validate(schema)`) and a static
|
|
11
|
+
* TypeScript type (`Ts<typeof schema>`). Transport framing (stdio) and the
|
|
12
|
+
* JSON-RPC dispatcher are in `fs/json/rpc/module.f.ts`.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { boolean, string, option, array, record } from "../types/rtti/module.f.js";
|
|
17
|
+
import { unknown } from "../json/module.f.js";
|
|
18
|
+
// ── Shared ─────────────────────────────────────────────────────────────────────
|
|
19
|
+
/** Name + version pair sent in `initialize` requests and responses. */
|
|
20
|
+
export const implementation = {
|
|
21
|
+
name: string,
|
|
22
|
+
version: string,
|
|
23
|
+
};
|
|
24
|
+
// ── Capabilities ───────────────────────────────────────────────────────────────
|
|
25
|
+
const toolsCapability = { listChanged: option(boolean) };
|
|
26
|
+
/** Server capabilities advertised in the `initialize` response. */
|
|
27
|
+
export const serverCapabilities = {
|
|
28
|
+
tools: option(toolsCapability),
|
|
29
|
+
};
|
|
30
|
+
// ── Lifecycle ──────────────────────────────────────────────────────────────────
|
|
31
|
+
/** Params for the `initialize` request. */
|
|
32
|
+
export const initializeParams = {
|
|
33
|
+
protocolVersion: string,
|
|
34
|
+
capabilities: unknown,
|
|
35
|
+
clientInfo: implementation,
|
|
36
|
+
};
|
|
37
|
+
/** Result for the `initialize` request. */
|
|
38
|
+
export const initializeResult = {
|
|
39
|
+
protocolVersion: string,
|
|
40
|
+
capabilities: serverCapabilities,
|
|
41
|
+
serverInfo: implementation,
|
|
42
|
+
instructions: option(string),
|
|
43
|
+
};
|
|
44
|
+
// ── Content ────────────────────────────────────────────────────────────────────
|
|
45
|
+
/** Plain-text content item returned by a tool call. */
|
|
46
|
+
export const textContent = { type: 'text', text: string };
|
|
47
|
+
// ── Tools ──────────────────────────────────────────────────────────────────────
|
|
48
|
+
/**
|
|
49
|
+
* A tool descriptor returned by `tools/list`.
|
|
50
|
+
* `inputSchema` is a JSON Schema object — use `toJsonSchema` to derive it from
|
|
51
|
+
* an rtti schema.
|
|
52
|
+
*/
|
|
53
|
+
export const tool = {
|
|
54
|
+
name: string,
|
|
55
|
+
description: option(string),
|
|
56
|
+
inputSchema: unknown,
|
|
57
|
+
};
|
|
58
|
+
export const toolsListResult = {
|
|
59
|
+
tools: array(tool),
|
|
60
|
+
nextCursor: option(string),
|
|
61
|
+
};
|
|
62
|
+
export const toolsCallParams = {
|
|
63
|
+
name: string,
|
|
64
|
+
arguments: option(record(unknown)),
|
|
65
|
+
};
|
|
66
|
+
export const toolsCallResult = {
|
|
67
|
+
content: array(textContent),
|
|
68
|
+
isError: option(boolean),
|
|
69
|
+
};
|
|
@@ -686,6 +686,12 @@ export const proof = {
|
|
|
686
686
|
w(0x10000000000000000000000000000000000n, vec(0x008n)(255n));
|
|
687
687
|
}
|
|
688
688
|
},
|
|
689
|
+
wordToString: () => {
|
|
690
|
+
const result = wordToString([0n, 1n, 0xabn]);
|
|
691
|
+
if (result !== '0,1,ab') {
|
|
692
|
+
throw result;
|
|
693
|
+
}
|
|
694
|
+
},
|
|
689
695
|
pipeline: () => {
|
|
690
696
|
// 4 L1 [0,0] words → 2 L2 [0,0] words → L3 [0,0] word → symbol 0
|
|
691
697
|
// First 7 zero bits accumulate without emitting
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
import type
|
|
8
|
-
import { type
|
|
9
|
-
import { type Effect } from '../../types/effects/module.f.ts';
|
|
7
|
+
import { type Write, type WriteConsoles, type NodeProgramOptions } from '../../effects/node/module.f.ts';
|
|
8
|
+
import { type Effect } from '../../effects/module.f.ts';
|
|
10
9
|
export declare const backspace: string;
|
|
11
10
|
type End = 'm';
|
|
12
11
|
type Csi = (code: number | string) => string;
|
|
@@ -45,20 +44,6 @@ export type WriteText = (text: string) => WriteText;
|
|
|
45
44
|
*/
|
|
46
45
|
export declare const createConsoleText: (stdout: Stdout) => WriteText;
|
|
47
46
|
export type CsiConsole = (s: string) => void;
|
|
48
|
-
/**
|
|
49
|
-
* Creates a TTY-aware console function. Appends `\n` to each string before writing.
|
|
50
|
-
*
|
|
51
|
-
* For TTY destinations, ANSI SGR sequences are preserved.
|
|
52
|
-
* For non-TTY destinations, ANSI SGR sequences are stripped.
|
|
53
|
-
*
|
|
54
|
-
* @param io - Runtime IO bindings.
|
|
55
|
-
* @returns A function that targets a writable stream.
|
|
56
|
-
*/
|
|
57
|
-
export declare const console: ({ fs: { writeSync } }: Io) => (w: Writable) => CsiConsole;
|
|
58
|
-
/** Writes to process stdout using a TTY-aware CSI console. */
|
|
59
|
-
export declare const stdio: (io: Io) => CsiConsole;
|
|
60
|
-
/** Writes to process stderr using a TTY-aware CSI console. */
|
|
61
|
-
export declare const stderr: (io: Io) => CsiConsole;
|
|
62
47
|
/**
|
|
63
48
|
* Effect-based TTY-aware write. Strips ANSI SGR sequences when the target
|
|
64
49
|
* stream is not a TTY, then encodes to UTF-8 and emits a `Write` effect.
|
package/fs/text/sgr/module.f.js
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// C0 control codes
|
|
8
|
+
// https://en.wikipedia.org/wiki/ANSI_escape_code#C0_control_codes
|
|
9
|
+
import { write } from "../../effects/node/module.f.js";
|
|
10
|
+
import {} from "../../effects/module.f.js";
|
|
9
11
|
import { utf8 } from "../module.f.js";
|
|
10
12
|
export const backspace = '\x08';
|
|
11
13
|
const begin = '\x1b[';
|
|
@@ -50,23 +52,6 @@ export const createConsoleText = (stdout) => {
|
|
|
50
52
|
return f('');
|
|
51
53
|
};
|
|
52
54
|
const str = (isTTY) => (s) => isTTY ? s : s.replace(/\x1b\[[0-9;]*m/g, '');
|
|
53
|
-
/**
|
|
54
|
-
* Creates a TTY-aware console function. Appends `\n` to each string before writing.
|
|
55
|
-
*
|
|
56
|
-
* For TTY destinations, ANSI SGR sequences are preserved.
|
|
57
|
-
* For non-TTY destinations, ANSI SGR sequences are stripped.
|
|
58
|
-
*
|
|
59
|
-
* @param io - Runtime IO bindings.
|
|
60
|
-
* @returns A function that targets a writable stream.
|
|
61
|
-
*/
|
|
62
|
-
export const console = ({ fs: { writeSync } }) => (w) => {
|
|
63
|
-
const toStr = str(w.isTTY);
|
|
64
|
-
return (s) => writeSync(w.fd, toStr(s) + '\n');
|
|
65
|
-
};
|
|
66
|
-
/** Writes to process stdout using a TTY-aware CSI console. */
|
|
67
|
-
export const stdio = (io) => console(io)(io.process.stdout);
|
|
68
|
-
/** Writes to process stderr using a TTY-aware CSI console. */
|
|
69
|
-
export const stderr = (io) => console(io)(io.process.stderr);
|
|
70
55
|
/**
|
|
71
56
|
* Effect-based TTY-aware write. Strips ANSI SGR sequences when the target
|
|
72
57
|
* stream is not a TTY, then encodes to UTF-8 and emits a `Write` effect.
|
|
@@ -7,6 +7,13 @@ export declare const isArray: (value: unknown) => value is readonly unknown[];
|
|
|
7
7
|
export type Array1<T> = readonly [T];
|
|
8
8
|
export type Index1 = 0;
|
|
9
9
|
export type Array2<T> = readonly [T, T];
|
|
10
|
+
/**
|
|
11
|
+
* Currently, TypeScript can't narrow the type of `readonly T[]` to `Array2<T>`
|
|
12
|
+
* only by checking `a.length === 2`, so we need a user-defined type guard.
|
|
13
|
+
*
|
|
14
|
+
* @param a An array of unknown length.
|
|
15
|
+
* @returns True if `a` has length 2, and `a` is narrowed to `Array2<T>` in that case.
|
|
16
|
+
*/
|
|
10
17
|
export declare const isArray2: <T>(a: readonly T[]) => a is Array2<T>;
|
|
11
18
|
export type Tuple2<T0, T1> = readonly [T0, T1];
|
|
12
19
|
export type Index2 = 0 | 1;
|
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { fromUndefined, map } from "../nullable/module.f.js";
|
|
7
7
|
export const isArray = (value) => value instanceof Array;
|
|
8
|
+
/**
|
|
9
|
+
* Currently, TypeScript can't narrow the type of `readonly T[]` to `Array2<T>`
|
|
10
|
+
* only by checking `a.length === 2`, so we need a user-defined type guard.
|
|
11
|
+
*
|
|
12
|
+
* @param a An array of unknown length.
|
|
13
|
+
* @returns True if `a` has length 2, and `a` is narrowed to `Array2<T>` in that case.
|
|
14
|
+
*/
|
|
8
15
|
export const isArray2 = (a) => a.length === 2;
|
|
9
16
|
const uncheckTail = (a) => a.slice(1);
|
|
10
17
|
const uncheckHead = (a) => a.slice(0, -1);
|
|
@@ -24,6 +24,10 @@ export type PrimeField = {
|
|
|
24
24
|
readonly pow: Reduce;
|
|
25
25
|
readonly pow2: Unary;
|
|
26
26
|
readonly pow3: Unary;
|
|
27
|
+
/** Reduces an arbitrary `bigint` into `[0, p)`. */
|
|
28
|
+
readonly reduce: Unary;
|
|
29
|
+
/** Euler criterion: `true` when `x` is a quadratic residue mod `p`. */
|
|
30
|
+
readonly quadRes: (x: bigint) => boolean;
|
|
27
31
|
};
|
|
28
32
|
/**
|
|
29
33
|
* Creates a prime field with the specified prime modulus and associated operations.
|
|
@@ -46,3 +50,7 @@ export declare const prime_field: (p: bigint) => PrimeField;
|
|
|
46
50
|
* ```
|
|
47
51
|
*/
|
|
48
52
|
export declare const sqrt: ({ p, pow, pow2 }: PrimeField) => (a: bigint) => bigint | null;
|
|
53
|
+
/**
|
|
54
|
+
* Modular square root mod `p` (`p ≡ 3 (mod 4)`); uses {@link PrimeField.neg} when `x` is not a residue.
|
|
55
|
+
*/
|
|
56
|
+
export declare const modSqrt: (field: PrimeField) => Unary;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { repeat } from "../monoid/module.f.js";
|
|
2
|
+
import { assert } from "../../asserts/module.f.js";
|
|
2
3
|
/**
|
|
3
4
|
* Creates a prime field with the specified prime modulus and associated operations.
|
|
4
5
|
*
|
|
@@ -33,23 +34,32 @@ export const prime_field = (p) => {
|
|
|
33
34
|
const middle = p >> 1n;
|
|
34
35
|
const pow2 = a => mul(a)(a);
|
|
35
36
|
const pow = repeat({ identity: 1n, operation: mul });
|
|
37
|
+
const add = a => b => {
|
|
38
|
+
const r = a + b;
|
|
39
|
+
return r < p ? r : r - p;
|
|
40
|
+
};
|
|
41
|
+
const reduce = x => {
|
|
42
|
+
const r = x % p;
|
|
43
|
+
return r < 0n ? add(p)(r) : r;
|
|
44
|
+
};
|
|
45
|
+
const half = (p - 1n) / 2n;
|
|
46
|
+
const quadRes = (x) => pow(half)(reduce(x)) === 1n;
|
|
36
47
|
return {
|
|
37
48
|
p,
|
|
38
49
|
middle,
|
|
39
50
|
max: p - 1n,
|
|
40
51
|
neg: a => a === 0n ? 0n : p - a,
|
|
41
52
|
sub,
|
|
42
|
-
add
|
|
43
|
-
const r = a + b;
|
|
44
|
-
return r < p ? r : r - p;
|
|
45
|
-
},
|
|
53
|
+
add,
|
|
46
54
|
abs: a => middle < a ? p - a : a,
|
|
47
55
|
mul,
|
|
48
56
|
reciprocal,
|
|
49
57
|
div: a => b => mul(a)(reciprocal(b)),
|
|
50
58
|
pow,
|
|
51
59
|
pow2,
|
|
52
|
-
pow3: a => mul(a)(pow2(a))
|
|
60
|
+
pow3: a => mul(a)(pow2(a)),
|
|
61
|
+
reduce,
|
|
62
|
+
quadRes,
|
|
53
63
|
};
|
|
54
64
|
};
|
|
55
65
|
/**
|
|
@@ -76,3 +86,25 @@ export const sqrt = ({ p, pow, pow2 }) => {
|
|
|
76
86
|
return pow2(result) === a ? result : null;
|
|
77
87
|
};
|
|
78
88
|
};
|
|
89
|
+
/**
|
|
90
|
+
* Modular square root mod `p` (`p ≡ 3 (mod 4)`); uses {@link PrimeField.neg} when `x` is not a residue.
|
|
91
|
+
*/
|
|
92
|
+
export const modSqrt = (field) => {
|
|
93
|
+
const { neg, reduce } = field;
|
|
94
|
+
const sqrt_p = sqrt(field);
|
|
95
|
+
return x => {
|
|
96
|
+
const v = reduce(x);
|
|
97
|
+
const r = sqrt_p(v);
|
|
98
|
+
if (r !== null) {
|
|
99
|
+
return r;
|
|
100
|
+
}
|
|
101
|
+
// For a prime `p ≡ 3 (mod 4)`, `−1` is a non-residue, so exactly one of
|
|
102
|
+
// `±v` is a quadratic residue: if `v` has no root, `neg(v)` must — hence
|
|
103
|
+
// `s` is non-null. `sqrt` already enforces `p ≡ 3 (mod 4)`, but primality
|
|
104
|
+
// is never checked, so the only way to reach `s === null` is a *composite*
|
|
105
|
+
// modulus (where the residue argument breaks).
|
|
106
|
+
const s = sqrt_p(neg(v));
|
|
107
|
+
assert(s !== null, 'modSqrt');
|
|
108
|
+
return s;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { prime_field, sqrt } from "./module.f.js";
|
|
1
|
+
import { modSqrt, prime_field, sqrt } from "./module.f.js";
|
|
2
2
|
export const proof = {
|
|
3
3
|
prime_field_test: () => {
|
|
4
4
|
const p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
|
|
@@ -143,7 +143,32 @@ export const proof = {
|
|
|
143
143
|
}
|
|
144
144
|
test(f.middle);
|
|
145
145
|
test(f.max);
|
|
146
|
-
}
|
|
146
|
+
},
|
|
147
|
+
reduce: () => {
|
|
148
|
+
if (f.reduce(13n) !== 13n) {
|
|
149
|
+
throw f.reduce(13n);
|
|
150
|
+
}
|
|
151
|
+
if (f.reduce(-1n) !== p - 1n) {
|
|
152
|
+
throw [f.reduce(-1n), p - 1n];
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
quadRes: () => {
|
|
156
|
+
if (!f.quadRes(1n)) {
|
|
157
|
+
throw 1n;
|
|
158
|
+
}
|
|
159
|
+
if (f.quadRes(3n)) {
|
|
160
|
+
throw 3n;
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
modSqrt: () => {
|
|
164
|
+
const root = modSqrt(f);
|
|
165
|
+
if (root(4n) !== 2n) {
|
|
166
|
+
throw root(4n);
|
|
167
|
+
}
|
|
168
|
+
if (f.pow2(root(2n)) !== 2n) {
|
|
169
|
+
throw root(2n);
|
|
170
|
+
}
|
|
171
|
+
},
|
|
147
172
|
};
|
|
148
173
|
}
|
|
149
174
|
};
|
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime deserialization of unknown values against RTTI schemas.
|
|
3
|
+
*
|
|
4
|
+
* The main entry point is `parse(rtti)`, which takes a schema `Type` and returns
|
|
5
|
+
* a `Parse<T>` function. When called with an unknown value, it returns a `Result`
|
|
6
|
+
* that is either `['ok', newValue]` or `['error', { path, message }]`.
|
|
7
|
+
*
|
|
8
|
+
* Unlike `validate`, which checks an existing value in-place and returns it
|
|
9
|
+
* unchanged on success, `parse` always returns a freshly constructed value that
|
|
10
|
+
* contains only the fields/elements declared by the schema. This makes both
|
|
11
|
+
* structs and tuples effectively closed at runtime, matching the TypeScript
|
|
12
|
+
* type produced by `Ts<T>`:
|
|
13
|
+
*
|
|
14
|
+
* - Tuples: the result has exactly the schema's length; extra elements are dropped.
|
|
15
|
+
* - Structs: the result contains only the schema's keys; extra properties are dropped.
|
|
16
|
+
* - Arrays/records: every element/value is itself parsed, so a fresh container is
|
|
17
|
+
* always returned even if the inner type is a primitive.
|
|
18
|
+
*
|
|
19
|
+
* This also provides forward compatibility with extended serialization formats:
|
|
20
|
+
* a schema-based parser keeps working when newer versions of the format add
|
|
21
|
+
* extra fields or tuple elements.
|
|
22
|
+
*
|
|
23
|
+
* The error shape, path bookkeeping, primitive checks, and schema
|
|
24
|
+
* recognition (`visit`) are shared with `validate` through
|
|
25
|
+
* `../common/module.f.ts`; only container construction differs.
|
|
26
|
+
*
|
|
27
|
+
* @module
|
|
28
|
+
*/
|
|
1
29
|
import { type Type } from '../module.f.ts';
|
|
2
30
|
import { type Result as CommonValidateResult, type Validate } from '../common/module.f.ts';
|
|
3
31
|
export { type Path, type ValidationError } from '../common/module.f.ts';
|
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime deserialization of unknown values against RTTI schemas.
|
|
3
|
+
*
|
|
4
|
+
* The main entry point is `parse(rtti)`, which takes a schema `Type` and returns
|
|
5
|
+
* a `Parse<T>` function. When called with an unknown value, it returns a `Result`
|
|
6
|
+
* that is either `['ok', newValue]` or `['error', { path, message }]`.
|
|
7
|
+
*
|
|
8
|
+
* Unlike `validate`, which checks an existing value in-place and returns it
|
|
9
|
+
* unchanged on success, `parse` always returns a freshly constructed value that
|
|
10
|
+
* contains only the fields/elements declared by the schema. This makes both
|
|
11
|
+
* structs and tuples effectively closed at runtime, matching the TypeScript
|
|
12
|
+
* type produced by `Ts<T>`:
|
|
13
|
+
*
|
|
14
|
+
* - Tuples: the result has exactly the schema's length; extra elements are dropped.
|
|
15
|
+
* - Structs: the result contains only the schema's keys; extra properties are dropped.
|
|
16
|
+
* - Arrays/records: every element/value is itself parsed, so a fresh container is
|
|
17
|
+
* always returned even if the inner type is a primitive.
|
|
18
|
+
*
|
|
19
|
+
* This also provides forward compatibility with extended serialization formats:
|
|
20
|
+
* a schema-based parser keeps working when newer versions of the format add
|
|
21
|
+
* extra fields or tuple elements.
|
|
22
|
+
*
|
|
23
|
+
* The error shape, path bookkeeping, primitive checks, and schema
|
|
24
|
+
* recognition (`visit`) are shared with `validate` through
|
|
25
|
+
* `../common/module.f.ts`; only container construction differs.
|
|
26
|
+
*
|
|
27
|
+
* @module
|
|
28
|
+
*/
|
|
1
29
|
import {} from "../module.f.js";
|
|
2
30
|
import { ok } from "../../result/module.f.js";
|
|
3
31
|
import {} from "../../object/module.f.js";
|
|
@@ -31,9 +59,9 @@ const containerParse = (isContainer, rebuild) => (item) => value => {
|
|
|
31
59
|
const itemParse = parse(item);
|
|
32
60
|
const results = e.map(([k, v]) => [k, itemParse(v)]);
|
|
33
61
|
const err = keyedFirstError(results);
|
|
34
|
-
return
|
|
62
|
+
return err === null
|
|
35
63
|
? ok(rebuild(okEntries(results)))
|
|
36
|
-
: prependPath(err[0], err[1])
|
|
64
|
+
: prependPath(err[0], err[1]);
|
|
37
65
|
};
|
|
38
66
|
const arrayParse = containerParse(isArray, arrayRebuild);
|
|
39
67
|
const recordParse = containerParse(isObject, recordRebuild);
|
|
@@ -49,14 +77,16 @@ const constContainerParse = (isContainer, getItem, rebuild) => (rtti) => value =
|
|
|
49
77
|
}
|
|
50
78
|
const results = entries(rtti).map(([k, t]) => [k, parse(t)(getItem(value, k))]);
|
|
51
79
|
const err = keyedFirstError(results);
|
|
52
|
-
return
|
|
80
|
+
return err === null
|
|
53
81
|
? ok(rebuild(okEntries(results)))
|
|
54
|
-
: prependPath(err[0], err[1])
|
|
82
|
+
: prependPath(err[0], err[1]);
|
|
55
83
|
};
|
|
56
84
|
const tupleParse = constContainerParse(isArray, (value, k) => value[Number(k)], arrayRebuild);
|
|
57
85
|
const structParse = constContainerParse(isObject, (value, k) => value[k], recordRebuild);
|
|
58
86
|
const findFirst = find(verror('no match'))((k) => k[0] === 'ok');
|
|
59
|
-
const orParse = (rtti) =>
|
|
87
|
+
const orParse = (rtti) =>
|
|
88
|
+
// `parse(t)` where t: Type forces Ts<Type> evaluation → TS2589; cast keeps result as any.
|
|
89
|
+
value => findFirst(listMap(t => parse(t)(value))(rtti));
|
|
60
90
|
/**
|
|
61
91
|
* Creates a parser function for the given RTTI schema.
|
|
62
92
|
*
|