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.
Files changed (178) hide show
  1. package/fjs/basen/cbase32/module.f.mjs +18 -10
  2. package/fjs/basen/cbase32/proof.f.d.mts +3 -0
  3. package/fjs/basen/cbase32/proof.f.mjs +24 -2
  4. package/fjs/basen/proof.f.mjs +8 -16
  5. package/fjs/bnf/ll1/proof.f.d.mts +2 -0
  6. package/fjs/bnf/ll1/proof.f.mjs +33 -18
  7. package/fjs/bnf/module.f.d.mts +2 -2
  8. package/fjs/bnf/module.f.mjs +2 -2
  9. package/fjs/cas/proof.f.mjs +4 -26
  10. package/fjs/ci/common/module.f.mjs +6 -0
  11. package/fjs/ci/config/module.f.d.mts +7 -7
  12. package/fjs/ci/config/module.f.mjs +7 -7
  13. package/fjs/cli/module.f.mjs +14 -10
  14. package/fjs/crypto/vdf/module.f.d.mts +0 -1
  15. package/fjs/crypto/vdf/module.f.mjs +3 -14
  16. package/fjs/dev/module.f.mjs +10 -20
  17. package/fjs/djs/parser/module.f.d.mts +101 -53
  18. package/fjs/djs/parser/module.f.mjs +732 -525
  19. package/fjs/djs/parser/proof.f.d.mts +6 -0
  20. package/fjs/djs/parser/proof.f.mjs +315 -11
  21. package/fjs/djs/parser/types.d.ts +29 -2
  22. package/fjs/djs/tokenizer/module.f.mjs +122 -105
  23. package/fjs/djs/tokenizer/proof.f.mjs +17 -0
  24. package/fjs/djs/transpiler/module.f.mjs +4 -5
  25. package/fjs/djs/transpiler/proof.f.d.mts +2 -0
  26. package/fjs/djs/transpiler/proof.f.mjs +25 -0
  27. package/fjs/edag/amnesia/module.f.d.mts +20 -0
  28. package/fjs/edag/amnesia/module.f.mjs +303 -0
  29. package/fjs/edag/amnesia/proof.f.d.mts +79 -0
  30. package/fjs/edag/amnesia/proof.f.mjs +573 -0
  31. package/fjs/edag/amnesia/types.d.ts +15 -0
  32. package/fjs/edag/module.f.d.mts +410 -0
  33. package/fjs/edag/module.f.mjs +559 -0
  34. package/fjs/edag/proof.f.d.mts +116 -0
  35. package/fjs/edag/proof.f.mjs +686 -0
  36. package/fjs/edag/types.d.ts +55 -0
  37. package/fjs/effects/node/memory/module.d.mts +37 -3
  38. package/fjs/effects/node/memory/module.mjs +38 -4
  39. package/fjs/effects/node/memory/proof.d.mts +5 -2
  40. package/fjs/effects/node/memory/proof.mjs +36 -6
  41. package/fjs/effects/node/module.d.mts +9 -1
  42. package/fjs/effects/node/module.f.d.mts +39 -0
  43. package/fjs/effects/node/module.f.mjs +46 -0
  44. package/fjs/effects/node/module.mjs +234 -32
  45. package/fjs/effects/node/types.d.ts +28 -2
  46. package/fjs/effects/node/virtual/module.f.d.mts +19 -10
  47. package/fjs/effects/node/virtual/module.f.mjs +246 -32
  48. package/fjs/effects/node/virtual/proof.f.d.mts +17 -2
  49. package/fjs/effects/node/virtual/proof.f.mjs +232 -8
  50. package/fjs/effects/node/virtual/types.d.ts +57 -1
  51. package/fjs/emergent_testing/browser/proof.d.mts +55 -0
  52. package/fjs/emergent_testing/browser/proof.mjs +352 -0
  53. package/fjs/emergent_testing/browser/species.proof.d.mts +4 -0
  54. package/fjs/emergent_testing/browser/species.proof.mjs +45 -0
  55. package/fjs/emergent_testing/browser.d.mts +79 -0
  56. package/fjs/emergent_testing/browser.mjs +432 -0
  57. package/fjs/emergent_testing/proof.f.d.mts +1 -1
  58. package/fjs/emergent_testing/proof.f.mjs +2 -2
  59. package/fjs/js/string_escape/module.f.d.mts +47 -0
  60. package/fjs/js/string_escape/module.f.mjs +95 -0
  61. package/fjs/js/string_escape/proof.f.d.mts +8 -0
  62. package/fjs/js/string_escape/proof.f.mjs +68 -0
  63. package/fjs/js/tokenizer/module.f.mjs +14 -12
  64. package/fjs/mcp/cas/module.f.d.mts +1 -7
  65. package/fjs/mcp/cas/module.f.mjs +24 -15
  66. package/fjs/mcp/evo/module.f.mjs +9 -24
  67. package/fjs/mcp/module.f.d.mts +3 -1
  68. package/fjs/mcp/module.f.mjs +4 -2
  69. package/fjs/media/json/rtti/module.f.d.mts +2 -2
  70. package/fjs/media/json/rtti/module.f.mjs +1 -1
  71. package/fjs/media/json/schema/module.f.d.mts +15 -5
  72. package/fjs/media/json/schema/module.f.mjs +42 -15
  73. package/fjs/media/json/schema/proof.f.d.mts +10 -1
  74. package/fjs/media/json/schema/proof.f.mjs +88 -16
  75. package/fjs/media/json/serializer/module.f.mjs +14 -26
  76. package/fjs/media/json/types.d.ts +1 -1
  77. package/fjs/media/lock/module.f.d.mts +8 -3
  78. package/fjs/media/lock/module.f.mjs +9 -3
  79. package/fjs/media/lock/proof.f.d.mts +1 -1
  80. package/fjs/media/lock/proof.f.mjs +2 -2
  81. package/fjs/media/lock/types.d.ts +1 -3
  82. package/fjs/media/module.f.d.mts +20 -13
  83. package/fjs/media/module.f.mjs +29 -16
  84. package/fjs/media/note/module.f.d.mts +14 -7
  85. package/fjs/media/note/module.f.mjs +14 -7
  86. package/fjs/media/note/proof.f.mjs +1 -1
  87. package/fjs/media/proof.f.mjs +5 -5
  88. package/fjs/media/revision/module.f.d.mts +8 -2
  89. package/fjs/media/revision/module.f.mjs +9 -3
  90. package/fjs/media/revision/proof.f.mjs +1 -1
  91. package/fjs/media/revision/types.d.ts +1 -1
  92. package/fjs/media/type/module.f.d.mts +20 -0
  93. package/fjs/media/type/module.f.mjs +74 -0
  94. package/fjs/media/type/proof.f.d.mts +5 -0
  95. package/fjs/media/type/proof.f.mjs +24 -1
  96. package/fjs/module.f.mjs +6 -0
  97. package/fjs/path/module.f.d.mts +60 -3
  98. package/fjs/path/module.f.mjs +138 -14
  99. package/fjs/path/proof.f.d.mts +3 -0
  100. package/fjs/path/proof.f.mjs +298 -2
  101. package/fjs/protocol/json_rpc/module.f.d.mts +65 -28
  102. package/fjs/protocol/json_rpc/module.f.mjs +49 -13
  103. package/fjs/protocol/json_rpc/proof.f.d.mts +4 -0
  104. package/fjs/protocol/json_rpc/proof.f.mjs +29 -0
  105. package/fjs/protocol/json_rpc/types.d.ts +12 -2
  106. package/fjs/protocol/mcp/module.f.d.mts +89 -54
  107. package/fjs/protocol/mcp/module.f.mjs +110 -56
  108. package/fjs/protocol/mcp/proof.f.d.mts +13 -0
  109. package/fjs/protocol/mcp/proof.f.mjs +107 -7
  110. package/fjs/protocol/mcp/stdio/module.f.mjs +3 -4
  111. package/fjs/protocol/mcp/stdio/proof.f.mjs +2 -2
  112. package/fjs/protocol/mcp/types.d.ts +14 -2
  113. package/fjs/text/utf8/module.f.mjs +27 -1
  114. package/fjs/text/utf8/proof.f.mjs +37 -0
  115. package/fjs/types/array/module.f.mjs +18 -11
  116. package/fjs/types/array/proof.f.mjs +27 -1
  117. package/fjs/types/bigfloat/module.f.d.mts +48 -9
  118. package/fjs/types/bigfloat/module.f.mjs +147 -59
  119. package/fjs/types/bigfloat/proof.f.d.mts +2 -0
  120. package/fjs/types/bigfloat/proof.f.mjs +136 -4
  121. package/fjs/types/bigfloat/types.d.ts +17 -0
  122. package/fjs/types/function/module.f.d.mts +11 -2
  123. package/fjs/types/function/module.f.mjs +20 -2
  124. package/fjs/types/function/proof.f.mjs +5 -1
  125. package/fjs/types/phantom/types.d.ts +21 -0
  126. package/fjs/types/result/module.f.d.mts +4 -4
  127. package/fjs/types/result/module.f.mjs +2 -2
  128. package/fjs/types/result/proof.f.d.mts +6 -2
  129. package/fjs/types/result/proof.f.mjs +17 -1
  130. package/fjs/types/rtti/common/module.f.d.mts +78 -5
  131. package/fjs/types/rtti/common/module.f.mjs +168 -3
  132. package/fjs/types/rtti/common/proof.f.d.mts +14 -0
  133. package/fjs/types/rtti/common/proof.f.mjs +61 -2
  134. package/fjs/types/rtti/common/types.d.ts +23 -1
  135. package/fjs/types/rtti/data/module.f.d.mts +57 -1
  136. package/fjs/types/rtti/data/module.f.mjs +241 -47
  137. package/fjs/types/rtti/data/proof.f.d.mts +10 -0
  138. package/fjs/types/rtti/data/proof.f.mjs +272 -39
  139. package/fjs/types/rtti/data/types.d.ts +14 -7
  140. package/fjs/types/rtti/host.proof.d.mts +33 -0
  141. package/fjs/types/rtti/host.proof.mjs +170 -0
  142. package/fjs/types/rtti/module.f.d.mts +51 -6
  143. package/fjs/types/rtti/module.f.mjs +50 -3
  144. package/fjs/types/rtti/parse/module.f.d.mts +31 -24
  145. package/fjs/types/rtti/parse/module.f.mjs +197 -59
  146. package/fjs/types/rtti/parse/proof.f.d.mts +37 -2
  147. package/fjs/types/rtti/parse/proof.f.mjs +171 -47
  148. package/fjs/types/rtti/proof.f.d.mts +6 -0
  149. package/fjs/types/rtti/proof.f.mjs +42 -1
  150. package/fjs/types/rtti/ts/module.f.d.mts +9 -3
  151. package/fjs/types/rtti/ts/module.f.mjs +68 -15
  152. package/fjs/types/rtti/ts/proof.f.d.mts +42 -2
  153. package/fjs/types/rtti/ts/proof.f.mjs +139 -6
  154. package/fjs/types/rtti/ts/types.d.ts +164 -16
  155. package/fjs/types/rtti/types.d.ts +31 -3
  156. package/fjs/types/rtti/validate/module.f.d.mts +120 -0
  157. package/fjs/types/rtti/validate/module.f.mjs +351 -0
  158. package/fjs/types/rtti/validate/proof.f.d.mts +154 -0
  159. package/fjs/types/rtti/validate/proof.f.mjs +781 -0
  160. package/fjs/types/ts/types.d.ts +4 -0
  161. package/fjs/web/module.f.d.mts +115 -0
  162. package/fjs/web/module.f.mjs +581 -0
  163. package/fjs/web/proof.f.d.mts +39 -0
  164. package/fjs/web/proof.f.mjs +413 -0
  165. package/fjs/web/types.d.ts +39 -0
  166. package/fjs/website/browser-prepare.d.mts +5 -0
  167. package/fjs/website/browser-prepare.mjs +115 -0
  168. package/fjs/website/browser-source.d.mts +37 -0
  169. package/fjs/website/browser-source.mjs +202 -0
  170. package/fjs/website/browser-source.proof.d.mts +31 -0
  171. package/fjs/website/browser-source.proof.mjs +162 -0
  172. package/fjs/website/browser.d.mts +5 -0
  173. package/fjs/website/browser.mjs +8 -0
  174. package/fjs/website/module.f.d.mts +3 -3
  175. package/fjs/website/module.f.mjs +62 -9
  176. package/fjs/website/proof.f.d.mts +4 -0
  177. package/fjs/website/proof.f.mjs +18 -3
  178. package/package.json +2 -3
@@ -0,0 +1,559 @@
1
+ /**
2
+ * @module
3
+ *
4
+ * @import { Assert } from '../asserts/types.ts'
5
+ * @import { Check, Check3 } from '../types/rtti/ts/types.ts'
6
+ * @import {
7
+ * Array,
8
+ * Exp,
9
+ * Primitive,
10
+ * Property,
11
+ * NumberCast,
12
+ * Object,
13
+ * PropertyLambda,
14
+ * OptionLambda,
15
+ * OptionPropertyLambda,
16
+ * Call,
17
+ * Dot,
18
+ * OptionDot,
19
+ * OptionCall,
20
+ * Comma,
21
+ * Op2Id,
22
+ * Op2,
23
+ * Op1Id,
24
+ * Op1,
25
+ * Op0Id,
26
+ * Op0,
27
+ * Spread,
28
+ * Items,
29
+ * Properties,
30
+ * Exps,
31
+ * } from './types.ts'
32
+ * @import { Phantom } from '../types/phantom/types.ts'
33
+ */
34
+
35
+ import {
36
+ bigint,
37
+ boolean,
38
+ number,
39
+ or,
40
+ string,
41
+ array as rttiArray,
42
+ } from "../types/rtti/module.f.mjs";
43
+
44
+ /**
45
+ * Every tuple here is closed — the members it declares and nothing else, which
46
+ * is what a bare `Tuple` says ("Structs and tuples are closed" in
47
+ * `../types/rtti/README.md`). That is load-bearing rather than incidental: the
48
+ * chain grammar below claims each JS chain has exactly one spelling, and an
49
+ * `open` tuple would let any node carry a trailing element nothing reads,
50
+ * splitting one function into unboundedly many graphs. So do **not** wrap any
51
+ * of these in `open`. No operand of any node is optional either: a chain step
52
+ * that does no further work carries an explicit `null` continuation, never a
53
+ * missing position.
54
+ *
55
+ * Do not call `parse(exp)` or rely on `validate(exp)` rejecting cycles
56
+ * without reading `../types/rtti/todo/identity-aware-parse.md` first —
57
+ * neither is identity-aware, and that TODO covers why and what's missing.
58
+ */
59
+
60
+ // Exp
61
+
62
+ /**
63
+ * Written out explicitly, not `@type {const}`: that can't apply to the
64
+ * arrow function itself (TS1355, literals only), and applied to just the
65
+ * returned array it still can't resolve the cycle back through `array`/
66
+ * `object`/`op0`/... to `exp` — declaration emit elides it to `any`.
67
+ *
68
+ * @type {() => readonly['or',
69
+ * typeof primitive,
70
+ * typeof array,
71
+ * typeof object,
72
+ * typeof dot,
73
+ * typeof call,
74
+ * typeof optionDot,
75
+ * typeof optionCall,
76
+ * typeof comma,
77
+ * typeof op2,
78
+ * typeof op1,
79
+ * typeof op0,
80
+ * ]}
81
+ */
82
+ const _exp = () => (['or',
83
+ primitive,
84
+ array,
85
+ object,
86
+ dot,
87
+ call,
88
+ optionDot,
89
+ optionCall,
90
+ comma,
91
+ op2,
92
+ op1,
93
+ op0,
94
+ ])
95
+
96
+ /** @type {Phantom<typeof _exp, Exp>} */
97
+ export const exp = _exp
98
+
99
+ /** @typedef {Assert<Check3<Exp, typeof _exp, typeof exp>>} _ExpAssert */
100
+
101
+ // Primitive
102
+
103
+ /**
104
+ * Bare constant values — no tag, no operands, not an operation node at all.
105
+ * `undefined` is deliberately not among them: its EDAG representation,
106
+ * `['undefined']`, *is* a tagged operation node (so a bare `undefined` stays
107
+ * distinguishable from a missing tuple position), which puts it in the
108
+ * `op0`/`op1`/`op2` grouping below by the same arity rule as every other
109
+ * operation, not here.
110
+ */
111
+ export const primitive = or(null, boolean, number, string, bigint)
112
+
113
+ /** @typedef {Assert<Check<Primitive, typeof primitive>>} _Primitive */
114
+
115
+ // Exps
116
+
117
+ export const exps = rttiArray(exp)
118
+
119
+ /** @typedef {Assert<Check<Exps, typeof exps>>} _Exps */
120
+
121
+ // Spread
122
+
123
+ /**
124
+ * ```js
125
+ * [...exp] // as an array item, through `items` — see `array`
126
+ * {...exp} // as an object property, through `properties` — see `object`
127
+ * ```
128
+ *
129
+ * Not a top-level `Exp`: `spread` only appears as an `items`/`properties`
130
+ * alternative, never as an operand an operation node can hold directly.
131
+ */
132
+ export const spread = /** @type {const} */ (['...', exp])
133
+
134
+ /** @typedef {Assert<Check<Spread, typeof spread>>} _Spread */
135
+
136
+ // Items
137
+
138
+ /** An array element: a plain `exp`, or a `spread` splicing another array in. */
139
+ export const items = or(exp, spread)
140
+
141
+ /** @typedef {Assert<Check<Items, typeof items>>} _Items */
142
+
143
+ // Array
144
+
145
+ /**
146
+ * ```js
147
+ * [exp0, exp1]
148
+ * [exp0, ...exp1]
149
+ * ```
150
+ */
151
+ export const array = /** @type {const} */ (['[]', rttiArray(items)])
152
+
153
+ /** @typedef {Assert<Check<Array, typeof array>>} _Array */
154
+
155
+ // Property
156
+
157
+ /**
158
+ * A structural operand of `object`, not an independently evaluated EDAG
159
+ * node: nothing ever evaluates a descriptor as a value, so whether one is
160
+ * shared by reference or written twice with equal content is unobservable,
161
+ * and conforming VMs may legally differ on it. Only the `key` and `value`
162
+ * operands are real nodes, their identities shared normally.
163
+ *
164
+ * The key stays `exp`, not narrowed to a string constant, and its evaluated
165
+ * value is coerced via JS `ToPropertyKey` when the property is defined —
166
+ * see `../../todo/edag-stage1-discussion.md` subject 4.
167
+ */
168
+ export const property = /** @type {const} */ ([':', exp, exp])
169
+
170
+ /** @typedef {Assert<Check<Property, typeof property>>} _Property */
171
+
172
+ // Properties
173
+
174
+ /** An object entry: a plain `property`, or a `spread` splicing another object in. */
175
+ export const properties = or(property, spread)
176
+
177
+ /** @typedef {Assert<Check<Properties, typeof properties>>} _Properties */
178
+
179
+ // Object — same nesting as `array` above, one position further in
180
+
181
+ /**
182
+ * ```js
183
+ * {
184
+ * a: exp0,
185
+ * "a": exp1,
186
+ * [exp2]: exp3,
187
+ * ...exp4,
188
+ * }
189
+ * ```
190
+ *
191
+ * The entries are an ordered sequence, applied as if in written order —
192
+ * never sorted or deduplicated: order is observable (enumeration,
193
+ * overwrites), and duplicate keys are allowed with the later entry winning,
194
+ * which is also required once computed keys are admitted, since key
195
+ * equality may not be decidable at validation time.
196
+ *
197
+ * `__proto__` is a data key, never a prototype assignment: an entry whose
198
+ * key evaluates to `__proto__` defines an ordinary own property, and a
199
+ * printer must spell it computed — `{ ["__proto__"]: value }`, the only
200
+ * object-literal form that reproduces it; the identifier and string
201
+ * spellings assign a prototype instead and lose the property. See "the
202
+ * `__proto__` key" in `../../spec/README.md`.
203
+ */
204
+ export const object = /** @type {const} */ (['{}', rttiArray(properties)])
205
+
206
+ /** @typedef {Assert<Check<Object, typeof object>>} _Object */
207
+
208
+ // Number
209
+
210
+ /**
211
+ * ```js
212
+ * Number(exp)
213
+ * ```
214
+ */
215
+ export const numberCast = /** @type {const} */ (['Number', exp])
216
+
217
+ /**
218
+ * @typedef {Assert<Check<NumberCast, typeof numberCast>>} _NumberCast
219
+ */
220
+
221
+ // Index
222
+
223
+ /**
224
+ * A property/index operand: a plain `string` or `number` key, or a `Number`
225
+ * cast around a computed `exp` (`arr[i]`, where `i` is itself an expression).
226
+ *
227
+ * Every naming position in the chain nodes below uses this rather than a bare
228
+ * `exp` — `.`, `?.`, and the `|.` step. Widening them to `exp` was weighed and
229
+ * rejected: `exp` and `index` overlap (`['Number', e]` is both a `numberCast`
230
+ * and an `op1`), so the wider spelling would buy a second reading of every
231
+ * computed key without buying any expression a `Number` cast cannot already
232
+ * name.
233
+ *
234
+ * Does not exclude `'constructor'`/`'__proto__'` — TODO, see
235
+ * `../types/rtti/todo/excluded-string-values.md`.
236
+ */
237
+ export const index = or(numberCast, string, number)
238
+
239
+ // Chain lambdas
240
+
241
+ // A JS member chain carries two bits of hidden control flow that no value
242
+ // carries: **P**, a receiver handed from a property access to a following
243
+ // call, and **O**, a short-circuit region opened by an optional operator.
244
+ // Neither bit live is the definition of a node boundary, so the three states
245
+ // in which a chain can continue are exactly three lambda types — the fourth
246
+ // cell of the table is an ordinary `Exp`:
247
+ //
248
+ // ```text
249
+ // outside an option inside an option
250
+ // receiver live propertyLambda optionPropertyLambda
251
+ // value only (an exp) optionLambda
252
+ // ```
253
+ //
254
+ // A lambda is **not** an `exp`: it reads the chain's current value implicitly,
255
+ // so it has no operand to hold one, and it cannot be lifted out as a shared
256
+ // computation node — `['|.', 'b', null]` means nothing on its own, only as
257
+ // the continuation of some chain node. That is the standing cost of this
258
+ // shape: the receiver a step consumes cannot be shared, substituted, or
259
+ // hashed.
260
+ //
261
+ // Four steps, each a transition on the two bits:
262
+ //
263
+ // ```text
264
+ // |. sets P, keeps O a property access produces a receiver
265
+ // |() clears P, keeps O a call consumes it
266
+ // |?.() clears P, sets O a call consumes it and opens a region
267
+ // |!() clears P, clears O a call consumes it and closes the region
268
+ // ```
269
+ //
270
+ // Every tag carries the `|` prefix, and that is a correctness requirement
271
+ // rather than a readability one. Unprefixed, `['()', f, null]` would be
272
+ // simultaneously a well-formed `call` — call `f` with `null` as its arguments
273
+ // — and a well-formed `optionLambda` — call the chain's value with `f` as its
274
+ // arguments, and stop. The two readings have the same length, so closedness
275
+ // cannot separate them; only disjoint vocabularies can.
276
+ //
277
+ // A production exists in a state exactly when moving that step into a nested
278
+ // node would be **observable**, which is why the same step appears in one
279
+ // state and not another. The sharpest case is `|.`: it is in
280
+ // `optionPropertyLambda` and not in `propertyLambda`, though it wastes a
281
+ // receiver either way — the difference is that O is live in one, and a region
282
+ // does not let a step leave. That single asymmetry is what makes `(a?.b).c`
283
+ // throw where `a?.b.c` does not.
284
+
285
+ /**
286
+ * The continuation of a step that produced a plain value **inside** an open
287
+ * region — what `?.()` owns, and what a call step hands on.
288
+ *
289
+ * `|()` stays in the region because the region has to cover the call:
290
+ * `a?.(...b)(...c)` skips the second call too. `|.` stays for the same
291
+ * reason, and hands on a receiver. Neither `|?.()` nor `|!()` is here: with P
292
+ * dead there is nothing for a guard or a close to protect that a nested node
293
+ * would not protect equally, so admitting them would only add a second
294
+ * spelling.
295
+ *
296
+ * @type {() => readonly['or',
297
+ * null,
298
+ * readonly['|()', typeof exp, typeof optionLambda],
299
+ * readonly['|.', typeof index, typeof optionPropertyLambda],
300
+ * ]}
301
+ */
302
+ const _optionLambda = () => (['or',
303
+ null,
304
+ /** @type {const} */ (['|()', exp, optionLambda]),
305
+ /** @type {const} */ (['|.', index, optionPropertyLambda]),
306
+ ])
307
+
308
+ /** @type {Phantom<typeof _optionLambda, OptionLambda>} */
309
+ export const optionLambda = _optionLambda
310
+
311
+ /**
312
+ * @typedef {Assert<Check3<OptionLambda, typeof _optionLambda, typeof optionLambda>>} _OptionLambda
313
+ */
314
+
315
+ /**
316
+ * The continuation of a property step **inside** an open region — both bits
317
+ * live, so this is the state with every production.
318
+ *
319
+ * Its three call forms are a complete taxonomy of how a call can relate to
320
+ * the region around it, and there is no fourth:
321
+ *
322
+ * ```js
323
+ * a?.b(...c) // ['?.', a, 'b', ['|()', c, null]] inherits the guard
324
+ * a?.b?.(...c) // ['?.', a, 'b', ['|?.()', c, null]] adds its own
325
+ * (a?.b)(...c) // ['?.', a, 'b', ['|!()', c, null]] escapes it
326
+ * ```
327
+ *
328
+ * `|!()` is the one step a short-circuit does not skip: the parentheses ended
329
+ * the region, so the `undefined` it produced is what gets called. `|!` pairs
330
+ * only with `()` because only a call consumes a receiver — a close-then-access
331
+ * `|!.` would just be a `dot` over the whole node, which nesting already
332
+ * spells.
333
+ *
334
+ * @type {() => readonly['or',
335
+ * null,
336
+ * readonly['|()', typeof exp, typeof optionLambda],
337
+ * readonly['|.', typeof index, typeof optionPropertyLambda],
338
+ * readonly['|?.()', typeof exp, typeof optionLambda],
339
+ * readonly['|!()', typeof exp, null],
340
+ * ]}
341
+ */
342
+ const _optionPropertyLambda = () => (['or',
343
+ null,
344
+ /** @type {const} */ (['|()', exp, optionLambda]),
345
+ /** @type {const} */ (['|.', index, optionPropertyLambda]),
346
+ /** @type {const} */ (['|?.()', exp, optionLambda]),
347
+ /** @type {const} */ (['|!()', exp, null]),
348
+ ])
349
+
350
+ /** @type {Phantom<typeof _optionPropertyLambda, OptionPropertyLambda>} */
351
+ export const optionPropertyLambda = _optionPropertyLambda
352
+
353
+ /**
354
+ * @typedef {Assert<Check3<OptionPropertyLambda, typeof _optionPropertyLambda, typeof optionPropertyLambda>>} _OptionPropertyLambda
355
+ */
356
+
357
+ /**
358
+ * The continuation of a `dot` — a receiver is live and no region is open.
359
+ *
360
+ * Only the two call steps are here, because only a call can use a receiver.
361
+ * `|()` is terminal: with the receiver spent and no region to be inside, what
362
+ * follows an `a.b(...c)` is an ordinary expression over an ordinary value, so
363
+ * it nests. `|?.()` continues, since it opens a region that then owns the
364
+ * rest of the chain. There is no `|.` production, which is what gives a plain
365
+ * property path exactly one spelling: `a.b.c` is nested `dot`s and nothing
366
+ * else.
367
+ *
368
+ * The terminal's third operand is a literal `null`, not the absence of one.
369
+ * Uniform arity is what keeps closedness able to tell it from `['|()', c, k]`:
370
+ * were the terminal two elements long, a continuation handed to a
371
+ * `propertyLambda` slot would be read as the terminal with the rest silently
372
+ * dropped.
373
+ */
374
+ export const propertyLambda = or(
375
+ null,
376
+ /** @type {const} */ (['|()', exp, null]),
377
+ /** @type {const} */ (['|?.()', exp, optionLambda]),
378
+ )
379
+
380
+ /**
381
+ * @typedef {Assert<Check<PropertyLambda, typeof propertyLambda>>} _PropertyLambda
382
+ */
383
+
384
+ // Call
385
+
386
+ /**
387
+ * ```js
388
+ * exp0(...exp1)
389
+ * ```
390
+ *
391
+ * A call with **no** receiver and no region: the callee is an ordinary
392
+ * expression, so a chain never reaches this node — `a.b(...c)` is a `dot`
393
+ * whose continuation is the call, and `(0, a.b)(...c)` is this node over a
394
+ * complete `dot`. The two differ, which is why the distinction is structural.
395
+ *
396
+ * The last operand is one node evaluating to the complete argument array,
397
+ * not a literal operand list: `f(a, b)` is `['()', f, ['[]', [a, b]]]`,
398
+ * while spread `f(...xs)` is `['()', f, xs]`.
399
+ */
400
+ export const call = /** @type {const} */ (['()', exp, exp])
401
+
402
+ /** @typedef {Assert<Check<Call, typeof call>>} _Call */
403
+
404
+ // Dot
405
+
406
+ /**
407
+ * ```js
408
+ * exp0.k // ['.', exp0, 'k', null]
409
+ * exp0[exp1] // ['.', exp0, ['Number', exp1], null]
410
+ * exp0.k(...exp2) // ['.', exp0, 'k', ['|()', exp2, null]]
411
+ * exp0.k?.(...exp2) // ['.', exp0, 'k', ['|?.()', exp2, null]]
412
+ * ```
413
+ *
414
+ * The naming operand is an `index`, not an `exp`, so a computed key is spelled
415
+ * `['Number', exp]`: `['.', a, ['args'], null]` does not validate.
416
+ *
417
+ * Property access, owning whatever the receiver it produces is used for. The
418
+ * `null` continuation is the plain read — the receiver is dropped, as JS
419
+ * drops it — and the two call continuations are the only things that can use
420
+ * it.
421
+ */
422
+ export const dot = /** @type {const} */ (['.', exp, index, propertyLambda])
423
+
424
+ /** @typedef {Assert<Check<Dot, typeof dot>>} _Dot */
425
+
426
+ // Option Dot
427
+
428
+ /**
429
+ * ```js
430
+ * exp0?.k // ['?.', exp0, 'k', null]
431
+ * exp0?.[exp1] // ['?.', exp0, ['Number', exp1], null]
432
+ * exp0?.k.m // ['?.', exp0, 'k', ['|.', 'm', null]]
433
+ * (exp0?.k)(...exp2) // ['?.', exp0, 'k', ['|!()', exp2, null]]
434
+ * ```
435
+ *
436
+ * Optional property access, owning the rest of its optional region. If `exp0`
437
+ * is nullish the region short-circuits: neither the `index` nor any step of
438
+ * the continuation is evaluated — in particular `a?.[k]` does not evaluate
439
+ * `k` — and the node's value is `undefined`, unless the continuation reaches
440
+ * a `|!()`, which the parentheses put *outside* the region and which
441
+ * therefore calls that `undefined`.
442
+ *
443
+ * Where the region ends is the grouping: `a?.b.c` is one node,
444
+ * `['?.', a, 'b', ['|.', 'c', null]]`, while `(a?.b).c` is a `dot` over a
445
+ * complete `['?.', a, 'b', null]` — and throws when `a` is nullish, as JS
446
+ * does.
447
+ */
448
+ export const optionDot = /** @type {const} */ (['?.', exp, index, optionPropertyLambda])
449
+
450
+ /** @typedef {Assert<Check<OptionDot, typeof optionDot>>} _OptionDot */
451
+
452
+ // Option Call
453
+
454
+ /**
455
+ * ```js
456
+ * exp0?.(...exp1) // ['?.()', exp0, exp1, null]
457
+ * exp0?.(...exp1).k // ['?.()', exp0, exp1, ['|.', 'k', null]]
458
+ * ```
459
+ *
460
+ * Optional call, owning the rest of its optional region the way `?.` does.
461
+ * The callee is an ordinary expression, so this node never carries a receiver
462
+ * — `a.b?.(...c)` is a `dot` with a `|?.()` continuation, not this. If `exp0`
463
+ * is nullish the arguments are not evaluated and the region short-circuits.
464
+ */
465
+ export const optionCall = /** @type {const} */ (['?.()', exp, exp, optionLambda])
466
+
467
+ /** @typedef {Assert<Check<OptionCall, typeof optionCall>>} _OptionCall */
468
+
469
+ // Comma
470
+
471
+ /**
472
+ * ```js
473
+ * (exp0, exp1, exp2)
474
+ * ```
475
+ *
476
+ * Establishes all of its operands and takes the value of the last one; the
477
+ * earlier operands exist for their throw-potential only. The shape is a
478
+ * known-incomplete placeholder — it cannot yet say "at least two operands,
479
+ * last is the result, each pre-result operand a true root (not reachable
480
+ * from another operand of the same `,`)". A single-operand `,` is the
481
+ * identity and a reachable operand a redundant anchor — both non-canonical,
482
+ * each splitting one function into two hashes. See the header of
483
+ * `./proof.f.mjs`.
484
+ */
485
+ export const comma = /** @type {const} */ ([',', exps])
486
+
487
+ /**
488
+ * @typedef {Assert<Check<Comma, typeof comma>>} _Comma
489
+ */
490
+
491
+ // No-Args Operations
492
+
493
+ /**
494
+ * `op0`/`op1`/`op2` group operation nodes by their `exp`-operand count —
495
+ * zero, one, or two — not by any semantic category. `undefined`/`args`/
496
+ * `frame` all take zero `exp` operands after the tag, so all three are
497
+ * `op0`, regardless of what each individually means: the `undefined` value,
498
+ * the arguments array, and the captured-consts frame — the way `args` is
499
+ * for the arguments.
500
+ */
501
+ export const op0Id = or('undefined', 'args', 'frame')
502
+
503
+ /** @typedef {Assert<Check<Op0Id, typeof op0Id>>} _Op0Id */
504
+
505
+ export const op0 = /** @type {const} */ ([op0Id])
506
+
507
+ /** @typedef {Assert<Check<Op0, typeof op0>>} _Op0 */
508
+
509
+ // Unary Operations
510
+
511
+ /**
512
+ * `String`/`Number` are casts, `neg` is arithmetic negation (a word tag —
513
+ * `-` is binary subtraction), `!` is logical and `~` bitwise not.
514
+ */
515
+ export const op1Id = or('String', 'Number', 'neg', '!', '~')
516
+
517
+ /** @typedef {Assert<Check<Op1Id, typeof op1Id>>} _Op1Id */
518
+
519
+ export const op1 = /** @type {const} */ ([op1Id, exp])
520
+
521
+ /** @typedef {Assert<Check<Op1, typeof op1>>} _Op1 */
522
+
523
+ // Binary Operations
524
+
525
+ /**
526
+ * `=>` builds a function from a frame and a body: the frame operand is one
527
+ * node evaluated in the enclosing scope, while the body is the inner
528
+ * function's graph — deferred, never established when the closure is built,
529
+ * only on each call, against that function's own `args`/`frame`. Calling one
530
+ * is not here: `()` is `['()', exp, exp]` and so *is* binary in operand
531
+ * count, but it is a chain node rather than an operation — the whole point of
532
+ * the chain vocabulary is that a call's receiver comes from the node holding
533
+ * it, which no `op2` id has anywhere to put. `own` is exactly
534
+ * `Object.getOwnPropertyDescriptor(object, key)?.value` — no
535
+ * getter invocation, no prototype chain — where the key operand must
536
+ * evaluate to a string: a runtime-value constraint the shape-only schema
537
+ * cannot express — a computed key's value is only known at execution, so
538
+ * upholding it falls to the executor (`ownJs` in `./proof.f.mjs`; the
539
+ * Operations table in `../../todo/edag-stage1-discussion.md`). The rest
540
+ * are the JS comparison,
541
+ * arithmetic, bitwise, and logical operators they name — with `&&`/`||`/`??`
542
+ * short-circuiting exactly as in JS: their right operand is conditional,
543
+ * never established eagerly. All this laziness is positional, not nodal —
544
+ * the same node referenced from an eager position elsewhere is still
545
+ * evaluated there.
546
+ */
547
+ export const op2Id = or(
548
+ '=>', 'own',
549
+ '===', '!==', '>', '>=', '<', '<=',
550
+ '+', '-', '*', '/', '%', '**',
551
+ '&', '|', '^', '<<', '>>', '>>>',
552
+ '&&', '||', '??'
553
+ )
554
+
555
+ /** @typedef {Assert<Check<Op2Id, typeof op2Id>>} _Op2Id */
556
+
557
+ export const op2 = /** @type {const} */ ([op2Id, exp, exp])
558
+
559
+ /** @typedef {Assert<Check<Op2, typeof op2>>} _Op2 */
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Runtime behavior of the edag `exp` schema — one section per node kind, plus
3
+ * a value nested through several kinds to exercise the mutual recursion.
4
+ * Exception: `comma` has no section of its own — its shape (`[',', exps]`) is
5
+ * a known-incomplete placeholder pending a redesign that can express "at
6
+ * least two operands, last is the result, each pre-result operand a true
7
+ * root" (a single-operand `,` is the identity, a reachable operand a
8
+ * redundant anchor — both non-canonical), not a settled node to pin. The
9
+ * `exps` section does validate `,`-tagged values, but only to reach `exps`,
10
+ * which `comma` is now the sole route to; it pins the operand array's
11
+ * element schema, and claims nothing about what a `,` means.
12
+ *
13
+ * @import { ValidationError } from '../types/rtti/common/types.ts'
14
+ * @import { Unknown } from '../types/rtti/ts/types.ts'
15
+ * @import { StringMap } from '../types/object/types.ts'
16
+ */
17
+ export declare const proof: {
18
+ primitive: {
19
+ ok: () => void;
20
+ error: () => void;
21
+ };
22
+ array: {
23
+ ok: () => void;
24
+ error: () => void;
25
+ };
26
+ object: {
27
+ ok: () => void;
28
+ error: () => void;
29
+ };
30
+ exps: {
31
+ ok: () => void;
32
+ singleExpIsError: () => void;
33
+ error: () => void;
34
+ };
35
+ closed: {
36
+ extraTailIsError: () => void;
37
+ };
38
+ dot: {
39
+ ok: () => void;
40
+ missingIndexIsError: () => void;
41
+ missingTailIsError: () => void;
42
+ error: () => void;
43
+ };
44
+ lambdas: {
45
+ propertyLambda: () => void;
46
+ optionLambda: () => void;
47
+ optionPropertyLambda: () => void;
48
+ operandSchemas: () => void;
49
+ notAnExp: () => void;
50
+ tagsAreDisjoint: () => void;
51
+ terminalsAreExplicit: () => void;
52
+ missingTailIsError: () => void;
53
+ unknownOpIsRejected: () => void;
54
+ };
55
+ call: {
56
+ ok: () => void;
57
+ missingTailIsError: () => void;
58
+ lambdasShapeIsError: () => void;
59
+ };
60
+ optionDot: {
61
+ ok: () => void;
62
+ error: () => void;
63
+ missingTailIsError: () => void;
64
+ };
65
+ optionCall: {
66
+ ok: () => void;
67
+ missingTailIsError: () => void;
68
+ error: () => void;
69
+ };
70
+ chains: {
71
+ receiver: () => void;
72
+ propertyPath: () => void;
73
+ optionalRegion: () => void;
74
+ callsAgainstTheRegion: () => void;
75
+ skippedOperands: () => void;
76
+ };
77
+ unspellable: {
78
+ optionalPropertyStep: () => void;
79
+ callTerminatesPropertyLambda: () => void;
80
+ closeWithoutReceiver: () => void;
81
+ guardedStepAfterCall: () => void;
82
+ };
83
+ op0: {
84
+ ok: () => void;
85
+ error: () => void;
86
+ unknownIdIsRejected: () => void;
87
+ };
88
+ op1: {
89
+ ok: () => void;
90
+ missingTailIsError: () => void;
91
+ error: () => void;
92
+ unknownIdIsRejected: () => void;
93
+ ownJs: () => void;
94
+ };
95
+ op2: {
96
+ ok: () => void;
97
+ missingTailIsError: () => void;
98
+ error: () => void;
99
+ unknownIdIsRejected: () => void;
100
+ };
101
+ chainsJs: {
102
+ receiver: () => void;
103
+ shortCircuit: () => void;
104
+ grouping: () => void;
105
+ desugaredOptional: () => void;
106
+ throw: {
107
+ detachedReceiver: () => number | undefined;
108
+ desugaredOptional: () => any;
109
+ groupedOptional: () => any;
110
+ evaluatedIndex: () => number;
111
+ evaluatedArgument: () => number | undefined;
112
+ groupedOptionalCallOfCall: () => any;
113
+ };
114
+ };
115
+ nested: () => void;
116
+ };