functionalscript 0.46.0 → 0.47.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/fjs/basen/cbase32/module.f.mjs +18 -10
- package/fjs/basen/cbase32/proof.f.d.mts +3 -0
- package/fjs/basen/cbase32/proof.f.mjs +24 -2
- package/fjs/basen/proof.f.mjs +8 -16
- package/fjs/bnf/ll1/proof.f.d.mts +2 -0
- package/fjs/bnf/ll1/proof.f.mjs +33 -18
- package/fjs/bnf/module.f.d.mts +2 -2
- package/fjs/bnf/module.f.mjs +2 -2
- package/fjs/cas/proof.f.mjs +4 -26
- package/fjs/ci/common/module.f.mjs +6 -0
- package/fjs/ci/config/module.f.d.mts +7 -7
- package/fjs/ci/config/module.f.mjs +7 -7
- package/fjs/cli/module.f.mjs +14 -10
- package/fjs/crypto/vdf/module.f.d.mts +0 -1
- package/fjs/crypto/vdf/module.f.mjs +3 -14
- package/fjs/dev/module.f.mjs +10 -20
- package/fjs/djs/parser/module.f.d.mts +101 -53
- package/fjs/djs/parser/module.f.mjs +732 -525
- package/fjs/djs/parser/proof.f.d.mts +6 -0
- package/fjs/djs/parser/proof.f.mjs +315 -11
- package/fjs/djs/parser/types.d.ts +29 -2
- package/fjs/djs/tokenizer/module.f.mjs +122 -105
- package/fjs/djs/tokenizer/proof.f.mjs +17 -0
- package/fjs/djs/transpiler/module.f.mjs +4 -5
- package/fjs/djs/transpiler/proof.f.d.mts +2 -0
- package/fjs/djs/transpiler/proof.f.mjs +25 -0
- package/fjs/edag/amnesia/module.f.d.mts +20 -0
- package/fjs/edag/amnesia/module.f.mjs +303 -0
- package/fjs/edag/amnesia/proof.f.d.mts +79 -0
- package/fjs/edag/amnesia/proof.f.mjs +573 -0
- package/fjs/edag/amnesia/types.d.ts +15 -0
- package/fjs/edag/module.f.d.mts +410 -0
- package/fjs/edag/module.f.mjs +559 -0
- package/fjs/edag/proof.f.d.mts +116 -0
- package/fjs/edag/proof.f.mjs +686 -0
- package/fjs/edag/types.d.ts +55 -0
- package/fjs/effects/node/memory/module.d.mts +37 -3
- package/fjs/effects/node/memory/module.mjs +38 -4
- package/fjs/effects/node/memory/proof.d.mts +5 -2
- package/fjs/effects/node/memory/proof.mjs +36 -6
- package/fjs/effects/node/module.d.mts +9 -1
- package/fjs/effects/node/module.f.d.mts +39 -0
- package/fjs/effects/node/module.f.mjs +46 -0
- package/fjs/effects/node/module.mjs +234 -32
- package/fjs/effects/node/types.d.ts +28 -2
- package/fjs/effects/node/virtual/module.f.d.mts +19 -10
- package/fjs/effects/node/virtual/module.f.mjs +246 -32
- package/fjs/effects/node/virtual/proof.f.d.mts +17 -2
- package/fjs/effects/node/virtual/proof.f.mjs +232 -8
- package/fjs/effects/node/virtual/types.d.ts +57 -1
- package/fjs/emergent_testing/browser/proof.d.mts +55 -0
- package/fjs/emergent_testing/browser/proof.mjs +352 -0
- package/fjs/emergent_testing/browser/species.proof.d.mts +4 -0
- package/fjs/emergent_testing/browser/species.proof.mjs +45 -0
- package/fjs/emergent_testing/browser.d.mts +79 -0
- package/fjs/emergent_testing/browser.mjs +432 -0
- package/fjs/emergent_testing/proof.f.d.mts +1 -1
- package/fjs/emergent_testing/proof.f.mjs +2 -2
- package/fjs/js/string_escape/module.f.d.mts +47 -0
- package/fjs/js/string_escape/module.f.mjs +95 -0
- package/fjs/js/string_escape/proof.f.d.mts +8 -0
- package/fjs/js/string_escape/proof.f.mjs +68 -0
- package/fjs/js/tokenizer/module.f.mjs +14 -12
- package/fjs/mcp/cas/module.f.d.mts +1 -7
- package/fjs/mcp/cas/module.f.mjs +24 -15
- package/fjs/mcp/evo/module.f.mjs +9 -24
- package/fjs/mcp/module.f.d.mts +3 -1
- package/fjs/mcp/module.f.mjs +4 -2
- package/fjs/media/json/rtti/module.f.d.mts +2 -2
- package/fjs/media/json/rtti/module.f.mjs +1 -1
- package/fjs/media/json/schema/module.f.d.mts +15 -5
- package/fjs/media/json/schema/module.f.mjs +42 -15
- package/fjs/media/json/schema/proof.f.d.mts +10 -1
- package/fjs/media/json/schema/proof.f.mjs +88 -16
- package/fjs/media/json/serializer/module.f.mjs +14 -26
- package/fjs/media/json/types.d.ts +1 -1
- package/fjs/media/lock/module.f.d.mts +8 -3
- package/fjs/media/lock/module.f.mjs +9 -3
- package/fjs/media/lock/proof.f.d.mts +1 -1
- package/fjs/media/lock/proof.f.mjs +2 -2
- package/fjs/media/lock/types.d.ts +1 -3
- package/fjs/media/module.f.d.mts +20 -13
- package/fjs/media/module.f.mjs +29 -16
- package/fjs/media/note/module.f.d.mts +14 -7
- package/fjs/media/note/module.f.mjs +14 -7
- package/fjs/media/note/proof.f.mjs +1 -1
- package/fjs/media/proof.f.mjs +5 -5
- package/fjs/media/revision/module.f.d.mts +8 -2
- package/fjs/media/revision/module.f.mjs +9 -3
- package/fjs/media/revision/proof.f.mjs +1 -1
- package/fjs/media/revision/types.d.ts +1 -1
- package/fjs/media/type/module.f.d.mts +20 -0
- package/fjs/media/type/module.f.mjs +74 -0
- package/fjs/media/type/proof.f.d.mts +5 -0
- package/fjs/media/type/proof.f.mjs +24 -1
- package/fjs/module.f.mjs +6 -0
- package/fjs/path/module.f.d.mts +60 -3
- package/fjs/path/module.f.mjs +138 -14
- package/fjs/path/proof.f.d.mts +3 -0
- package/fjs/path/proof.f.mjs +298 -2
- package/fjs/protocol/json_rpc/module.f.d.mts +65 -28
- package/fjs/protocol/json_rpc/module.f.mjs +49 -13
- package/fjs/protocol/json_rpc/proof.f.d.mts +4 -0
- package/fjs/protocol/json_rpc/proof.f.mjs +29 -0
- package/fjs/protocol/json_rpc/types.d.ts +12 -2
- package/fjs/protocol/mcp/module.f.d.mts +89 -54
- package/fjs/protocol/mcp/module.f.mjs +110 -56
- package/fjs/protocol/mcp/proof.f.d.mts +13 -0
- package/fjs/protocol/mcp/proof.f.mjs +107 -7
- package/fjs/protocol/mcp/stdio/module.f.mjs +3 -4
- package/fjs/protocol/mcp/stdio/proof.f.mjs +2 -2
- package/fjs/protocol/mcp/types.d.ts +14 -2
- package/fjs/text/utf8/module.f.mjs +27 -1
- package/fjs/text/utf8/proof.f.mjs +37 -0
- package/fjs/types/array/module.f.mjs +18 -11
- package/fjs/types/array/proof.f.mjs +27 -1
- package/fjs/types/bigfloat/module.f.d.mts +48 -9
- package/fjs/types/bigfloat/module.f.mjs +147 -59
- package/fjs/types/bigfloat/proof.f.d.mts +2 -0
- package/fjs/types/bigfloat/proof.f.mjs +136 -4
- package/fjs/types/bigfloat/types.d.ts +17 -0
- package/fjs/types/function/module.f.d.mts +11 -2
- package/fjs/types/function/module.f.mjs +20 -2
- package/fjs/types/function/proof.f.mjs +5 -1
- package/fjs/types/phantom/types.d.ts +21 -0
- package/fjs/types/result/module.f.d.mts +4 -4
- package/fjs/types/result/module.f.mjs +2 -2
- package/fjs/types/result/proof.f.d.mts +6 -2
- package/fjs/types/result/proof.f.mjs +17 -1
- package/fjs/types/rtti/common/module.f.d.mts +78 -5
- package/fjs/types/rtti/common/module.f.mjs +168 -3
- package/fjs/types/rtti/common/proof.f.d.mts +14 -0
- package/fjs/types/rtti/common/proof.f.mjs +61 -2
- package/fjs/types/rtti/common/types.d.ts +23 -1
- package/fjs/types/rtti/data/module.f.d.mts +57 -1
- package/fjs/types/rtti/data/module.f.mjs +241 -47
- package/fjs/types/rtti/data/proof.f.d.mts +10 -0
- package/fjs/types/rtti/data/proof.f.mjs +272 -39
- package/fjs/types/rtti/data/types.d.ts +14 -7
- package/fjs/types/rtti/host.proof.d.mts +33 -0
- package/fjs/types/rtti/host.proof.mjs +170 -0
- package/fjs/types/rtti/module.f.d.mts +51 -6
- package/fjs/types/rtti/module.f.mjs +50 -3
- package/fjs/types/rtti/parse/module.f.d.mts +31 -24
- package/fjs/types/rtti/parse/module.f.mjs +197 -59
- package/fjs/types/rtti/parse/proof.f.d.mts +37 -2
- package/fjs/types/rtti/parse/proof.f.mjs +171 -47
- package/fjs/types/rtti/proof.f.d.mts +6 -0
- package/fjs/types/rtti/proof.f.mjs +42 -1
- package/fjs/types/rtti/ts/module.f.d.mts +9 -3
- package/fjs/types/rtti/ts/module.f.mjs +68 -15
- package/fjs/types/rtti/ts/proof.f.d.mts +42 -2
- package/fjs/types/rtti/ts/proof.f.mjs +139 -6
- package/fjs/types/rtti/ts/types.d.ts +164 -16
- package/fjs/types/rtti/types.d.ts +31 -3
- package/fjs/types/rtti/validate/module.f.d.mts +120 -0
- package/fjs/types/rtti/validate/module.f.mjs +351 -0
- package/fjs/types/rtti/validate/proof.f.d.mts +154 -0
- package/fjs/types/rtti/validate/proof.f.mjs +781 -0
- package/fjs/types/ts/types.d.ts +4 -0
- package/fjs/web/module.f.d.mts +115 -0
- package/fjs/web/module.f.mjs +581 -0
- package/fjs/web/proof.f.d.mts +39 -0
- package/fjs/web/proof.f.mjs +413 -0
- package/fjs/web/types.d.ts +39 -0
- package/fjs/website/browser-prepare.d.mts +5 -0
- package/fjs/website/browser-prepare.mjs +115 -0
- package/fjs/website/browser-source.d.mts +37 -0
- package/fjs/website/browser-source.mjs +202 -0
- package/fjs/website/browser-source.proof.d.mts +31 -0
- package/fjs/website/browser-source.proof.mjs +162 -0
- package/fjs/website/browser.d.mts +5 -0
- package/fjs/website/browser.mjs +8 -0
- package/fjs/website/module.f.d.mts +3 -3
- package/fjs/website/module.f.mjs +62 -9
- package/fjs/website/proof.f.d.mts +4 -0
- package/fjs/website/proof.f.mjs +18 -3
- package/package.json +2 -3
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-level API for `fjs/edag/module.f.mjs`: `Exp`, the union of every EDAG
|
|
3
|
+
* node kind — see the union immediately below for the current list, rather
|
|
4
|
+
* than enumerating it here too, where it silently drifts stale as nodes are
|
|
5
|
+
* added — each pinned against its rtti schema in the sibling module with
|
|
6
|
+
* `Assert<Check<..., typeof ...>>`. Every tuple here is closed on both sides:
|
|
7
|
+
* none of the schemas says `open`, so these types are exact rather than the
|
|
8
|
+
* approximation `TupleTs` in `../types/rtti/ts/types.ts` describes.
|
|
9
|
+
*/
|
|
10
|
+
export type Exp = Primitive | Array | Object | Dot | Call | OptionDot | OptionCall | Comma | Op2 | Op1 | Op0;
|
|
11
|
+
/**
|
|
12
|
+
* Bare constant values, not operation nodes — `undefined` is deliberately
|
|
13
|
+
* excluded, since `['undefined']` is a tagged `Op0` operation, not a bare
|
|
14
|
+
* value; see `primitive` in `module.f.mjs`.
|
|
15
|
+
*/
|
|
16
|
+
export type Primitive = null | boolean | number | string | bigint;
|
|
17
|
+
export type Exps = readonly Exp[];
|
|
18
|
+
export type Spread = readonly ['...', Exp];
|
|
19
|
+
export type Items = Exp | Spread;
|
|
20
|
+
export type Array = readonly ['[]', readonly Items[]];
|
|
21
|
+
export type Property = readonly [':', Exp, Exp];
|
|
22
|
+
export type Properties = Property | Spread;
|
|
23
|
+
export type Object = readonly ['{}', readonly Properties[]];
|
|
24
|
+
export type NumberCast = readonly ['Number', Exp];
|
|
25
|
+
export type Index = number | NumberCast | string;
|
|
26
|
+
/**
|
|
27
|
+
* The continuation of a `Dot`: a receiver is live, no region is open.
|
|
28
|
+
*
|
|
29
|
+
* Only a call can be here — a property step would waste the receiver with no
|
|
30
|
+
* region to keep it in, so `a.b.c` nests `Dot`s instead.
|
|
31
|
+
*/
|
|
32
|
+
export type PropertyLambda = null | readonly ['|()', Exp, null] | readonly ['|?.()', Exp, OptionLambda];
|
|
33
|
+
/**
|
|
34
|
+
* The continuation of a step that produced a plain value inside an open
|
|
35
|
+
* region: `OptionCall`'s, and every call step that stays in its region.
|
|
36
|
+
*/
|
|
37
|
+
export type OptionLambda = null | readonly ['|()', Exp, OptionLambda] | readonly ['|.', Index, OptionPropertyLambda];
|
|
38
|
+
/**
|
|
39
|
+
* The continuation of a property step inside an open region: both bits live,
|
|
40
|
+
* so this is the state with every production — the three ways a call can
|
|
41
|
+
* relate to the region it sits in, plus the property step the region keeps
|
|
42
|
+
* from leaving.
|
|
43
|
+
*/
|
|
44
|
+
export type OptionPropertyLambda = null | readonly ['|()', Exp, OptionLambda] | readonly ['|.', Index, OptionPropertyLambda] | readonly ['|?.()', Exp, OptionLambda] | readonly ['|!()', Exp, null];
|
|
45
|
+
export type Call = readonly ['()', Exp, Exp];
|
|
46
|
+
export type Dot = readonly ['.', Exp, Index, PropertyLambda];
|
|
47
|
+
export type OptionDot = readonly ['?.', Exp, Index, OptionPropertyLambda];
|
|
48
|
+
export type OptionCall = readonly ['?.()', Exp, Exp, OptionLambda];
|
|
49
|
+
export type Comma = readonly [',', Exps];
|
|
50
|
+
export type Op0Id = 'undefined' | 'args' | 'frame';
|
|
51
|
+
export type Op0 = readonly [Op0Id];
|
|
52
|
+
export type Op1Id = 'String' | 'Number' | 'neg' | '!' | '~';
|
|
53
|
+
export type Op1 = readonly [Op1Id, Exp];
|
|
54
|
+
export type Op2Id = '=>' | 'own' | '===' | '!==' | '>' | '>=' | '<' | '<=' | '+' | '-' | '*' | '/' | '%' | '**' | '&' | '|' | '^' | '<<' | '>>' | '>>>' | '&&' | '||' | '??';
|
|
55
|
+
export type Op2 = readonly [Op2Id, Exp, Exp];
|
|
@@ -22,8 +22,42 @@ export type Uuid = () => string;
|
|
|
22
22
|
* @type {(uuid?: Uuid) => MemoryOperationMap}
|
|
23
23
|
*/
|
|
24
24
|
export declare const memoryOperationMap: (uuid?: Uuid) => MemoryOperationMap;
|
|
25
|
+
export type MemoryRun = <T, E>(effect: Effect<MemOp, T, E>) => Promise<Result<T, E>>;
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
-
* @
|
|
27
|
+
* An {@link asyncRun} runner over {@link MemOp}: an effect in, its `Result` out.
|
|
28
|
+
* @typedef {<T, E>(effect: Effect<MemOp, T, E>) => Promise<Result<T, E>>} MemoryRun
|
|
28
29
|
*/
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Creates a runner owning a fresh memory store. Every effect passed to the
|
|
32
|
+
* *same* runner shares that store; a new runner starts empty.
|
|
33
|
+
*
|
|
34
|
+
* **The `MemoryRun` annotation is what types the `asyncRun` call.** `asyncRun`
|
|
35
|
+
* takes a `ToAsyncOperationMap<O>`, a mapped type keyed on `O[0]`, and
|
|
36
|
+
* TypeScript cannot infer `O` back out of one — only a homomorphic
|
|
37
|
+
* `{[K in keyof T]: …}` is reversed. Left to argument inference `O` falls back
|
|
38
|
+
* to its `Operation` constraint, whose payloads and outputs are `never`, and no
|
|
39
|
+
* real map is assignable to that; the call site then needs a cast. Annotating
|
|
40
|
+
* the result instead lets `O` be inferred from the return type, which is what
|
|
41
|
+
* gives the call a real `O` to check the argument against.
|
|
42
|
+
*
|
|
43
|
+
* **What that check is worth here is narrow, so it is worth stating exactly.**
|
|
44
|
+
* Each handler is already checked against `MemOp` by
|
|
45
|
+
* {@link memoryOperationMap}'s own annotation, and was before this call was
|
|
46
|
+
* written — a drifted handler is reported there, at the factory, either way.
|
|
47
|
+
* What the runner adds is agreement between the *declared map type* and
|
|
48
|
+
* `MemOp`: give `MemoryOperationMap` a narrower operation set and this line
|
|
49
|
+
* reports the missing handler, where an unchecked call site would leave it to
|
|
50
|
+
* whoever spreads the map next. The wider hazard — a cast stripping the
|
|
51
|
+
* contextual type from an object *literal*, so no handler is checked at all —
|
|
52
|
+
* is `runNodeEffect`'s (`../module.mjs`), which passes a literal; this call
|
|
53
|
+
* passes an already-annotated result.
|
|
54
|
+
* @type {(uuid?: Uuid) => MemoryRun}
|
|
55
|
+
*/
|
|
56
|
+
export declare const memoryRun: (uuid?: Uuid) => MemoryRun;
|
|
57
|
+
/**
|
|
58
|
+
* Runs a memory-only effect using a fresh memory store — a store per call, so
|
|
59
|
+
* nothing written by one `run` is visible to the next. Use {@link memoryRun}
|
|
60
|
+
* to keep one.
|
|
61
|
+
* @type {MemoryRun}
|
|
62
|
+
*/
|
|
63
|
+
export declare const run: MemoryRun;
|
|
@@ -56,8 +56,42 @@ export const memoryOperationMap = (uuid = randomUUID) => {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
60
|
-
* @
|
|
59
|
+
* An {@link asyncRun} runner over {@link MemOp}: an effect in, its `Result` out.
|
|
60
|
+
* @typedef {<T, E>(effect: Effect<MemOp, T, E>) => Promise<Result<T, E>>} MemoryRun
|
|
61
61
|
*/
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Creates a runner owning a fresh memory store. Every effect passed to the
|
|
65
|
+
* *same* runner shares that store; a new runner starts empty.
|
|
66
|
+
*
|
|
67
|
+
* **The `MemoryRun` annotation is what types the `asyncRun` call.** `asyncRun`
|
|
68
|
+
* takes a `ToAsyncOperationMap<O>`, a mapped type keyed on `O[0]`, and
|
|
69
|
+
* TypeScript cannot infer `O` back out of one — only a homomorphic
|
|
70
|
+
* `{[K in keyof T]: …}` is reversed. Left to argument inference `O` falls back
|
|
71
|
+
* to its `Operation` constraint, whose payloads and outputs are `never`, and no
|
|
72
|
+
* real map is assignable to that; the call site then needs a cast. Annotating
|
|
73
|
+
* the result instead lets `O` be inferred from the return type, which is what
|
|
74
|
+
* gives the call a real `O` to check the argument against.
|
|
75
|
+
*
|
|
76
|
+
* **What that check is worth here is narrow, so it is worth stating exactly.**
|
|
77
|
+
* Each handler is already checked against `MemOp` by
|
|
78
|
+
* {@link memoryOperationMap}'s own annotation, and was before this call was
|
|
79
|
+
* written — a drifted handler is reported there, at the factory, either way.
|
|
80
|
+
* What the runner adds is agreement between the *declared map type* and
|
|
81
|
+
* `MemOp`: give `MemoryOperationMap` a narrower operation set and this line
|
|
82
|
+
* reports the missing handler, where an unchecked call site would leave it to
|
|
83
|
+
* whoever spreads the map next. The wider hazard — a cast stripping the
|
|
84
|
+
* contextual type from an object *literal*, so no handler is checked at all —
|
|
85
|
+
* is `runNodeEffect`'s (`../module.mjs`), which passes a literal; this call
|
|
86
|
+
* passes an already-annotated result.
|
|
87
|
+
* @type {(uuid?: Uuid) => MemoryRun}
|
|
88
|
+
*/
|
|
89
|
+
export const memoryRun = (uuid = randomUUID) => asyncRun(memoryOperationMap(uuid))
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Runs a memory-only effect using a fresh memory store — a store per call, so
|
|
93
|
+
* nothing written by one `run` is visible to the next. Use {@link memoryRun}
|
|
94
|
+
* to keep one.
|
|
95
|
+
* @type {MemoryRun}
|
|
96
|
+
*/
|
|
97
|
+
export const run = effect => memoryRun()(effect)
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*
|
|
6
|
-
* @import { Key
|
|
6
|
+
* @import { Key } from '../../memory/types.ts'
|
|
7
|
+
* @import { Uuid } from './module.mjs'
|
|
7
8
|
*/
|
|
8
9
|
export declare const proof: {
|
|
9
10
|
nodeInterpreter: () => Promise<void>;
|
|
10
|
-
|
|
11
|
+
reusedRunnerPersists: () => Promise<void>;
|
|
12
|
+
runnersDoNotShareStore: () => Promise<void>;
|
|
13
|
+
runIsPerCall: () => Promise<void>;
|
|
11
14
|
missingKeyThrows: () => Promise<void>;
|
|
12
15
|
};
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*
|
|
6
|
-
* @import { Key
|
|
6
|
+
* @import { Key } from '../../memory/types.ts'
|
|
7
|
+
* @import { Uuid } from './module.mjs'
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
import { asyncRun } from '../../module.mjs'
|
|
10
10
|
import { errorSummary } from '../module.f.mjs'
|
|
11
11
|
import {
|
|
12
|
-
asNominal,
|
|
12
|
+
asBase, asNominal,
|
|
13
13
|
create, read, write,
|
|
14
14
|
} from '../../memory/module.f.mjs'
|
|
15
|
-
import {
|
|
15
|
+
import { memoryRun, run } from './module.mjs'
|
|
16
16
|
import { assert, assertEq } from '../../../asserts/module.f.mjs'
|
|
17
17
|
import { unwrap } from "../../../types/result/module.f.mjs"
|
|
18
18
|
import { step, unwrapStep } from '../../module.f.mjs'
|
|
@@ -28,8 +28,8 @@ export const proof = {
|
|
|
28
28
|
assert(r[0] === 'ok', r)
|
|
29
29
|
assertEq(r[1], 2)
|
|
30
30
|
},
|
|
31
|
-
|
|
32
|
-
const runner =
|
|
31
|
+
reusedRunnerPersists: async () => {
|
|
32
|
+
const runner = memoryRun()
|
|
33
33
|
// `unwrapStep` empties the channel, so what the runner hands back is
|
|
34
34
|
// an `ok` and these unwraps are total.
|
|
35
35
|
const key = unwrap(await runner(unwrapStep(create(1), errorSummary)))
|
|
@@ -37,6 +37,36 @@ export const proof = {
|
|
|
37
37
|
const result = unwrap(await runner(unwrapStep(read(key), errorSummary)))
|
|
38
38
|
assertEq(result, 2)
|
|
39
39
|
},
|
|
40
|
+
runnersDoNotShareStore: async () => {
|
|
41
|
+
// Both runners mint the *same* key id, so the id cannot be what tells
|
|
42
|
+
// them apart — only store ownership can. A store shared between
|
|
43
|
+
// runners (module-level rather than per call) passes every other proof
|
|
44
|
+
// here; this is the one that fails it.
|
|
45
|
+
/** @type {Uuid} */
|
|
46
|
+
const uuid = () => 'fixed'
|
|
47
|
+
const a = memoryRun(uuid)
|
|
48
|
+
const b = memoryRun(uuid)
|
|
49
|
+
const key = unwrap(await a(unwrapStep(create(1), errorSummary)))
|
|
50
|
+
const result = await b(read(key)).then(
|
|
51
|
+
() => undefined,
|
|
52
|
+
error => error,
|
|
53
|
+
)
|
|
54
|
+
assert(result instanceof Error, result)
|
|
55
|
+
assertEq(result.message, 'memory key not found: fixed', result)
|
|
56
|
+
},
|
|
57
|
+
runIsPerCall: async () => {
|
|
58
|
+
// `run` builds a runner per call, so the store the first call wrote to
|
|
59
|
+
// is gone by the second. One runner shared across every `run` — the
|
|
60
|
+
// other half of the store-ownership mutant — passes every other proof
|
|
61
|
+
// here, including `runnersDoNotShareStore`.
|
|
62
|
+
const key = unwrap(await run(unwrapStep(create(1), errorSummary)))
|
|
63
|
+
const result = await run(read(key)).then(
|
|
64
|
+
() => undefined,
|
|
65
|
+
error => error,
|
|
66
|
+
)
|
|
67
|
+
assert(result instanceof Error, result)
|
|
68
|
+
assertEq(result.message, `memory key not found: ${asBase(key)}`, result)
|
|
69
|
+
},
|
|
40
70
|
missingKeyThrows: async () => {
|
|
41
71
|
/** @type {Key<number>} */
|
|
42
72
|
const key = asNominal('missing')
|
|
@@ -16,13 +16,20 @@
|
|
|
16
16
|
* @import { IoResult, Server as EffectServer, Headers, Module, NodeOp, RequestListener as Erl, NodeProgram, NodeProgramOptions, WriteConsoles, TestContext, TestFn, } from './types.ts'
|
|
17
17
|
* @import { Result } from '../../types/result/types.ts'
|
|
18
18
|
* @import { StringMap } from '../../types/object/types.ts'
|
|
19
|
+
* @import { Nullable } from '../../types/nullable/types.ts'
|
|
19
20
|
*/
|
|
20
21
|
import type { Effect } from '../types.ts';
|
|
21
22
|
import type { Headers, NodeOp, NodeProgram } from './types.ts';
|
|
22
23
|
import type { Result } from '../../types/result/types.ts';
|
|
23
24
|
import type { StringMap } from '../../types/object/types.ts';
|
|
25
|
+
export type _Socket = {
|
|
26
|
+
readonly end: (data: string) => void;
|
|
27
|
+
};
|
|
24
28
|
export type _Server = {
|
|
25
|
-
readonly listen: (port: number) => void;
|
|
29
|
+
readonly listen: (port: number, host: string) => void;
|
|
30
|
+
readonly once: (event: string, f: (e: unknown) => void) => void;
|
|
31
|
+
on(event: string, f: (req: unknown, socket: _Socket) => void): void;
|
|
32
|
+
readonly removeListener: (event: string, f: (e: unknown) => void) => void;
|
|
26
33
|
};
|
|
27
34
|
export type _Readable = AsyncIterable<Uint8Array>;
|
|
28
35
|
export type _IncomingMessage = _Readable & {
|
|
@@ -33,6 +40,7 @@ export type _IncomingMessage = _Readable & {
|
|
|
33
40
|
export type _ServerResponse = {
|
|
34
41
|
readonly writeHead: (status: number, headers: StringMap<string>) => _ServerResponse;
|
|
35
42
|
readonly end: (body: Uint8Array) => void;
|
|
43
|
+
readonly headersSent: boolean;
|
|
36
44
|
};
|
|
37
45
|
export type _RequestListener = (req: _IncomingMessage, res: _ServerResponse) => Promise<void>;
|
|
38
46
|
export type _EffectToPromise = <T, E>(effect: Effect<NodeOp, T, E>) => Promise<Result<T, E>>;
|
|
@@ -29,6 +29,45 @@ import type { All, Access, Await, Console, CreateExclusive, CreateServer, Engine
|
|
|
29
29
|
* @type {(info: IoErrorInfo) => IoError}
|
|
30
30
|
*/
|
|
31
31
|
export declare const ioError: (info: IoErrorInfo) => IoError;
|
|
32
|
+
/**
|
|
33
|
+
* The host a {@link Listen} refuses.
|
|
34
|
+
*
|
|
35
|
+
* Node treats `''` exactly as it treats an omitted argument and binds the
|
|
36
|
+
* unspecified address — measured on Linux with Node 22.22.2, where
|
|
37
|
+
* `listen(0, '')` reports `0.0.0.0`, and on Darwin with Node 23.11.0, where it
|
|
38
|
+
* reports `::`. **Which** unspecified address is the platform's business; that
|
|
39
|
+
* it is one of them is universal. `Listen` takes the host precisely so that
|
|
40
|
+
* an address is stated rather than inherited, and a missing configuration value
|
|
41
|
+
* arriving as `''` inherits the widest one there is. Every runner refuses it, so
|
|
42
|
+
* a program proven against the virtual one binds where the Node one binds.
|
|
43
|
+
*
|
|
44
|
+
* @type {string}
|
|
45
|
+
*/
|
|
46
|
+
export declare const emptyHost: string;
|
|
47
|
+
/**
|
|
48
|
+
* Node's own code for an argument it rejects, reported here for a value Node
|
|
49
|
+
* itself accepts: a caller reading `IoError.code` should not have to learn a
|
|
50
|
+
* second vocabulary for a refusal that is the runner's own.
|
|
51
|
+
*
|
|
52
|
+
* @type {string}
|
|
53
|
+
*/
|
|
54
|
+
export declare const emptyHostCode: string;
|
|
55
|
+
/** Node's message shape for {@link emptyHostCode} — `The argument '<name>'
|
|
56
|
+
* <reason>. Received <value>`.
|
|
57
|
+
*
|
|
58
|
+
* @type {string}
|
|
59
|
+
*/
|
|
60
|
+
export declare const emptyHostMessage: string;
|
|
61
|
+
/**
|
|
62
|
+
* The failure a runner reports for {@link emptyHost}.
|
|
63
|
+
*
|
|
64
|
+
* The virtual runner answers with this value and the Node runner throws an
|
|
65
|
+
* `Error` carrying the same two literals, which is what keeps the two from
|
|
66
|
+
* drifting apart on a refusal neither inherits from Node.
|
|
67
|
+
*
|
|
68
|
+
* @type {IoError}
|
|
69
|
+
*/
|
|
70
|
+
export declare const emptyHostError: IoError;
|
|
32
71
|
/**
|
|
33
72
|
* Normalizes a **thrown** value into an {@link IoError}: the OS error code when
|
|
34
73
|
* the host attached a string one, and a message that is the `Error`'s own or
|
|
@@ -37,6 +37,52 @@ import {
|
|
|
37
37
|
*/
|
|
38
38
|
export const ioError = info => ['ioError', info]
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* The host a {@link Listen} refuses.
|
|
42
|
+
*
|
|
43
|
+
* Node treats `''` exactly as it treats an omitted argument and binds the
|
|
44
|
+
* unspecified address — measured on Linux with Node 22.22.2, where
|
|
45
|
+
* `listen(0, '')` reports `0.0.0.0`, and on Darwin with Node 23.11.0, where it
|
|
46
|
+
* reports `::`. **Which** unspecified address is the platform's business; that
|
|
47
|
+
* it is one of them is universal. `Listen` takes the host precisely so that
|
|
48
|
+
* an address is stated rather than inherited, and a missing configuration value
|
|
49
|
+
* arriving as `''` inherits the widest one there is. Every runner refuses it, so
|
|
50
|
+
* a program proven against the virtual one binds where the Node one binds.
|
|
51
|
+
*
|
|
52
|
+
* @type {string}
|
|
53
|
+
*/
|
|
54
|
+
export const emptyHost = ''
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Node's own code for an argument it rejects, reported here for a value Node
|
|
58
|
+
* itself accepts: a caller reading `IoError.code` should not have to learn a
|
|
59
|
+
* second vocabulary for a refusal that is the runner's own.
|
|
60
|
+
*
|
|
61
|
+
* @type {string}
|
|
62
|
+
*/
|
|
63
|
+
export const emptyHostCode = 'ERR_INVALID_ARG_VALUE'
|
|
64
|
+
|
|
65
|
+
/** Node's message shape for {@link emptyHostCode} — `The argument '<name>'
|
|
66
|
+
* <reason>. Received <value>`.
|
|
67
|
+
*
|
|
68
|
+
* @type {string}
|
|
69
|
+
*/
|
|
70
|
+
export const emptyHostMessage = `The argument 'host' must not be empty. Received ''`
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The failure a runner reports for {@link emptyHost}.
|
|
74
|
+
*
|
|
75
|
+
* The virtual runner answers with this value and the Node runner throws an
|
|
76
|
+
* `Error` carrying the same two literals, which is what keeps the two from
|
|
77
|
+
* drifting apart on a refusal neither inherits from Node.
|
|
78
|
+
*
|
|
79
|
+
* @type {IoError}
|
|
80
|
+
*/
|
|
81
|
+
export const emptyHostError = ioError({
|
|
82
|
+
code: emptyHostCode,
|
|
83
|
+
message: emptyHostMessage,
|
|
84
|
+
})
|
|
85
|
+
|
|
40
86
|
/**
|
|
41
87
|
* Normalizes a **thrown** value into an {@link IoError}: the OS error code when
|
|
42
88
|
* the host attached a string one, and a message that is the `Error`'s own or
|