aontu 0.53.0 → 0.54.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/dist/aontu.d.ts +3 -2
- package/dist/aontu.js +36 -7
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +426 -7
- package/dist/cli.js.map +1 -1
- package/dist/ctx.d.ts +5 -0
- package/dist/ctx.js +1 -0
- package/dist/ctx.js.map +1 -1
- package/dist/diff.js.map +1 -1
- package/dist/err.js +7 -1
- package/dist/err.js.map +1 -1
- package/dist/graph.d.ts +2 -5
- package/dist/graph.js +83 -46
- package/dist/graph.js.map +1 -1
- package/dist/hcanon.js +9 -10
- package/dist/hcanon.js.map +1 -1
- package/dist/hints.js +90 -26
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.js +34 -0
- package/dist/jsonschema.js.map +1 -1
- package/dist/lang.js +593 -191
- package/dist/lang.js.map +1 -1
- package/dist/lsp.d.ts +1 -1
- package/dist/lsp.js +86 -6
- package/dist/lsp.js.map +1 -1
- package/dist/mcp.js +133 -6
- package/dist/mcp.js.map +1 -1
- package/dist/mod-tool.js +42 -8
- package/dist/mod-tool.js.map +1 -1
- package/dist/mod.d.ts +4 -0
- package/dist/mod.js +97 -2
- package/dist/mod.js.map +1 -1
- package/dist/patch.d.ts +5 -0
- package/dist/patch.js +25 -25
- package/dist/patch.js.map +1 -1
- package/dist/provenance.d.ts +1 -0
- package/dist/provenance.js +2 -1
- package/dist/provenance.js.map +1 -1
- package/dist/query.js.map +1 -1
- package/dist/reach.d.ts +1 -0
- package/dist/reach.js +49 -21
- package/dist/reach.js.map +1 -1
- package/dist/relation.d.ts +4 -0
- package/dist/relation.js +125 -200
- package/dist/relation.js.map +1 -1
- package/dist/sig.d.ts +25 -0
- package/dist/sig.js +277 -0
- package/dist/sig.js.map +1 -0
- package/dist/sigdecl.d.ts +2 -0
- package/dist/sigdecl.js +11 -0
- package/dist/sigdecl.js.map +1 -0
- package/dist/siggate.d.ts +4 -0
- package/dist/siggate.js +90 -0
- package/dist/siggate.js.map +1 -0
- package/dist/std.js +72 -16
- package/dist/std.js.map +1 -1
- package/dist/subsume.js +57 -10
- package/dist/subsume.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/unify.d.ts +2 -2
- package/dist/unify.js +93 -114
- package/dist/unify.js.map +1 -1
- package/dist/utility.d.ts +1 -2
- package/dist/utility.js +7 -61
- package/dist/utility.js.map +1 -1
- package/dist/val/AggFuncVal.d.ts +12 -1
- package/dist/val/AggFuncVal.js +165 -3
- package/dist/val/AggFuncVal.js.map +1 -1
- package/dist/val/BagVal.d.ts +2 -0
- package/dist/val/BagVal.js +56 -8
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/ConstraintVal.js +33 -5
- package/dist/val/ConstraintVal.js.map +1 -1
- package/dist/val/ContainerKindVal.d.ts +35 -0
- package/dist/val/ContainerKindVal.js +99 -0
- package/dist/val/ContainerKindVal.js.map +1 -0
- package/dist/val/CopyFuncVal.js +0 -7
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/DisjunctVal.d.ts +1 -2
- package/dist/val/DisjunctVal.js +146 -39
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/ExpectVal.js +37 -2
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FuncBaseVal.d.ts +1 -0
- package/dist/val/FuncBaseVal.js +19 -8
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/GraphAtomVal.d.ts +39 -0
- package/dist/val/GraphAtomVal.js +184 -0
- package/dist/val/GraphAtomVal.js.map +1 -0
- package/dist/val/JunctionVal.js +22 -5
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/ListVal.js +27 -34
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/MapVal.d.ts +1 -0
- package/dist/val/MapVal.js +82 -35
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/PathFuncVal.d.ts +2 -2
- package/dist/val/PathFuncVal.js +75 -16
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PathVal.d.ts +25 -0
- package/dist/val/PathVal.js +150 -0
- package/dist/val/PathVal.js.map +1 -0
- package/dist/val/PlusOpVal.d.ts +2 -1
- package/dist/val/PlusOpVal.js +50 -35
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefVal.d.ts +2 -0
- package/dist/val/PrefVal.js +159 -32
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RecurseVal.d.ts +19 -0
- package/dist/val/RecurseVal.js +217 -0
- package/dist/val/RecurseVal.js.map +1 -0
- package/dist/val/RefVal.d.ts +2 -1
- package/dist/val/RefVal.js +105 -72
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.d.ts +30 -7
- package/dist/val/ReferFuncVal.js +395 -94
- package/dist/val/ReferFuncVal.js.map +1 -1
- package/dist/val/ScalarKindVal.d.ts +4 -2
- package/dist/val/ScalarKindVal.js +12 -1
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/SuperFuncVal.d.ts +4 -2
- package/dist/val/SuperFuncVal.js +118 -14
- package/dist/val/SuperFuncVal.js.map +1 -1
- package/dist/val/TopVal.d.ts +1 -1
- package/dist/val/Val.d.ts +2 -3
- package/dist/val/Val.js +39 -20
- package/dist/val/Val.js.map +1 -1
- package/dist/val/arith.js +4 -1
- package/dist/val/arith.js.map +1 -1
- package/dist/vet.js +27 -1
- package/dist/vet.js.map +1 -1
- package/dist/view.d.ts +85 -0
- package/dist/view.js +1948 -0
- package/dist/view.js.map +1 -0
- package/grammar/aontu.gbnf +18 -10
- package/grammar/aontu.lark +15 -10
- package/grammar/aontu.tmLanguage.json +184 -0
- package/package.json +10 -3
- package/skill/grammar-card.md +1 -2
- package/src/aontu.ts +37 -7
- package/src/cli.ts +472 -7
- package/src/ctx.ts +20 -0
- package/src/diff.ts +4 -2
- package/src/err.ts +8 -1
- package/src/graph.ts +125 -75
- package/src/hcanon.ts +9 -11
- package/src/hints.ts +108 -29
- package/src/jsonschema.ts +41 -0
- package/src/lang.ts +642 -203
- package/src/lsp.ts +75 -6
- package/src/mcp.ts +143 -6
- package/src/mod-tool.ts +48 -9
- package/src/mod.ts +110 -1
- package/src/patch.ts +31 -27
- package/src/provenance.ts +8 -1
- package/src/query.ts +4 -2
- package/src/reach.ts +52 -23
- package/src/relation.ts +139 -236
- package/src/sig.ts +345 -0
- package/src/sigdecl.ts +11 -0
- package/src/siggate.ts +144 -0
- package/src/std.ts +74 -16
- package/src/subsume.ts +59 -10
- package/src/unify.ts +102 -125
- package/src/utility.ts +7 -67
- package/src/val/AggFuncVal.ts +231 -4
- package/src/val/BagVal.ts +58 -9
- package/src/val/ConstraintVal.ts +34 -5
- package/src/val/ContainerKindVal.ts +158 -0
- package/src/val/CopyFuncVal.ts +0 -7
- package/src/val/DisjunctVal.ts +152 -40
- package/src/val/ExpectVal.ts +39 -4
- package/src/val/FuncBaseVal.ts +21 -8
- package/src/val/GraphAtomVal.ts +264 -0
- package/src/val/JunctionVal.ts +23 -6
- package/src/val/ListVal.ts +30 -37
- package/src/val/MapVal.ts +87 -39
- package/src/val/PathFuncVal.ts +107 -19
- package/src/val/PathVal.ts +221 -0
- package/src/val/PlusOpVal.ts +56 -37
- package/src/val/PrefVal.ts +186 -38
- package/src/val/RecurseVal.ts +285 -0
- package/src/val/RefVal.ts +105 -83
- package/src/val/ReferFuncVal.ts +445 -100
- package/src/val/ScalarKindVal.ts +12 -0
- package/src/val/SuperFuncVal.ts +137 -13
- package/src/val/TopVal.ts +1 -1
- package/src/val/Val.ts +44 -35
- package/src/val/arith.ts +4 -1
- package/src/vet.ts +36 -3
- package/src/view.ts +2563 -0
- package/dist/val/IdFuncVal.d.ts +0 -13
- package/dist/val/IdFuncVal.js +0 -54
- package/dist/val/IdFuncVal.js.map +0 -1
- package/src/val/IdFuncVal.ts +0 -91
package/src/val/ScalarKindVal.ts
CHANGED
|
@@ -64,6 +64,15 @@ class BigDecimal { }
|
|
|
64
64
|
// A ScalarKind for null.
|
|
65
65
|
class Null { }
|
|
66
66
|
|
|
67
|
+
// A ScalarKind for tree addresses (docs/design/PATHS.0.md): the value
|
|
68
|
+
// a `path(p)` call captures. Sits UNDER string -- an address is a
|
|
69
|
+
// string with more structure, so string-kinded schemas over address
|
|
70
|
+
// fields keep admitting -- while staying a distinct leaf, so a plain
|
|
71
|
+
// string literal and a path value refuse each other exactly as the
|
|
72
|
+
// number tower's leaves do. Reached only by the `path()` builtin, as
|
|
73
|
+
// the exact numeric leaves are reached only by `0d`.
|
|
74
|
+
class Path { }
|
|
75
|
+
|
|
67
76
|
|
|
68
77
|
// The immediate lattice parent of each kind marker. A marker absent from
|
|
69
78
|
// this table sits directly under top (string, boolean, null -- and
|
|
@@ -75,6 +84,7 @@ const KIND_PARENT = new Map<any, any>([
|
|
|
75
84
|
[Float, Number],
|
|
76
85
|
[BigInteger, Number],
|
|
77
86
|
[BigDecimal, Number],
|
|
87
|
+
[Path, String],
|
|
78
88
|
])
|
|
79
89
|
|
|
80
90
|
|
|
@@ -107,6 +117,7 @@ type ScalarConstructor =
|
|
|
107
117
|
(typeof BigInteger) |
|
|
108
118
|
(typeof BigDecimal) |
|
|
109
119
|
(typeof Null) |
|
|
120
|
+
(typeof Path) |
|
|
110
121
|
(typeof Integer.constructor)
|
|
111
122
|
|
|
112
123
|
|
|
@@ -216,6 +227,7 @@ export {
|
|
|
216
227
|
Float,
|
|
217
228
|
Integer,
|
|
218
229
|
Null,
|
|
230
|
+
Path,
|
|
219
231
|
ScalarConstructor,
|
|
220
232
|
ScalarKindVal,
|
|
221
233
|
kindParent,
|
package/src/val/SuperFuncVal.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
/* Copyright (c) 2021-2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
// THE IMMEDIATE PARENT TYPE (docs/design/SUPER.0.md): super(x) answers
|
|
5
|
+
// the type one step above its argument, structurally. The lattice
|
|
6
|
+
// primitive Val.superior() stays what it always was -- the preference
|
|
7
|
+
// override gate and query's kind lift -- and answers here only for the
|
|
8
|
+
// forms it already served (scalars, kinds, top). Everything structural
|
|
9
|
+
// is this file's walk: maps and lists lift child by child, preferences
|
|
10
|
+
// unwrap, disjunctions distribute, constraints answer the kind they
|
|
11
|
+
// constrain, and a recursion residual stays a symbolic call -- the
|
|
12
|
+
// finite spelling of a lift that is itself recursive.
|
|
13
|
+
|
|
4
14
|
import type {
|
|
5
15
|
Val,
|
|
6
16
|
ValSpec,
|
|
@@ -12,6 +22,11 @@ import {
|
|
|
12
22
|
|
|
13
23
|
|
|
14
24
|
import { FuncBaseVal } from './FuncBaseVal'
|
|
25
|
+
import { MapVal } from './MapVal'
|
|
26
|
+
import { ListVal } from './ListVal'
|
|
27
|
+
import { DisjunctVal } from './DisjunctVal'
|
|
28
|
+
import { ScalarKindVal } from './ScalarKindVal'
|
|
29
|
+
import { top } from './top'
|
|
15
30
|
|
|
16
31
|
|
|
17
32
|
class SuperFuncVal extends FuncBaseVal {
|
|
@@ -34,26 +49,135 @@ class SuperFuncVal extends FuncBaseVal {
|
|
|
34
49
|
}
|
|
35
50
|
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
// A DIRECT residual rides the residuate path rather than resolving:
|
|
53
|
+
// the pending call IS the answer (SUPER.0.md, the phase boundary),
|
|
54
|
+
// printing as written and refusing at generation exactly as an
|
|
55
|
+
// unexpanded recursion does. Residuals met DURING descent are minted
|
|
56
|
+
// as pending child calls by superOf below; only the top-level
|
|
57
|
+
// argument needs the defer, or resolve would re-mint the same call
|
|
58
|
+
// inside one pass forever.
|
|
59
|
+
deferResolve(_ctx: AontuContext, args?: Val[]): boolean {
|
|
60
|
+
return true === (args?.[0] as any)?.isRecurse
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
resolve(ctx: AontuContext, args: Val[]) {
|
|
65
|
+
// One argument, always a Val: funcArity pins super at [1,1]
|
|
66
|
+
// before any resolve, and the parser builds arguments as Vals --
|
|
67
|
+
// a guarded fallback here is dead code under ADR-002.
|
|
68
|
+
return this.place(superOf(ctx, args[0]))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
// superOf answers the immediate parent type of a RESOLVED value (the
|
|
75
|
+
// caller drives arguments before resolve fires, so pending forms --
|
|
76
|
+
// held conjuncts, unresolved references, holes -- never arrive).
|
|
77
|
+
function superOf(ctx: AontuContext, v: any): Val {
|
|
78
|
+
// The residual's lift is itself recursive, so the finite answer is
|
|
79
|
+
// the symbolic call (SUPER.0.md): a fresh pending super() holding a
|
|
80
|
+
// clone of the residual, standing wherever the residual stood --
|
|
81
|
+
// the `next?` slot of a lifted recursive body prints
|
|
82
|
+
// `super($.Node)` and drops under an optional key at generation.
|
|
83
|
+
if (true === v.isRecurse) {
|
|
84
|
+
const call = new SuperFuncVal({ peg: [v.clone(ctx)] }, ctx)
|
|
85
|
+
return v.place(call)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Maps and lists lift child by child. Shape is carried, not lifted:
|
|
89
|
+
// key optionality and closedness describe the container, and the
|
|
90
|
+
// spread template lifts so the result admits at the lifted level
|
|
91
|
+
// for future keys exactly as the original admitted at its own.
|
|
92
|
+
// A fresh bag (ADR-005 instantiation): type/hide marks are not
|
|
93
|
+
// copied -- the lift of a hidden definition is output.
|
|
94
|
+
if (true === v.isMap) {
|
|
95
|
+
const peg: Record<string, Val> = {}
|
|
96
|
+
for (const k of Object.keys(v.peg)) {
|
|
97
|
+
peg[k] = superOf(ctx, v.peg[k])
|
|
98
|
+
}
|
|
99
|
+
const out: any = new MapVal({ peg }, ctx)
|
|
100
|
+
out.optionalKeys = [...v.optionalKeys]
|
|
101
|
+
out.closed = v.closed
|
|
102
|
+
if (null != v.spread?.cj) {
|
|
103
|
+
out.spread.cj = superOf(ctx, v.spread.cj)
|
|
104
|
+
}
|
|
105
|
+
return v.place(out)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (true === v.isList) {
|
|
109
|
+
const peg: Val[] = v.peg.map((e: Val) => superOf(ctx, e))
|
|
110
|
+
const out: any = new ListVal({ peg }, ctx)
|
|
111
|
+
out.closed = v.closed
|
|
112
|
+
if (null != v.spread?.cj) {
|
|
113
|
+
out.spread.cj = superOf(ctx, v.spread.cj)
|
|
114
|
+
}
|
|
115
|
+
return v.place(out)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// The parent TYPE of a soft value is the parent of the value --
|
|
119
|
+
// softness does not survive typing. Deliberately NOT superpeg,
|
|
120
|
+
// whose top-for-a-kind answer is override-gate semantics.
|
|
121
|
+
if (true === v.isPref) {
|
|
122
|
+
return superOf(ctx, v.peg)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// A choice lifts arm by arm: super(1|2) is integer, super(1|"a") is
|
|
126
|
+
// integer|string. An arm whose lift is top absorbs the whole answer
|
|
127
|
+
// -- a disjunct carrying top says nothing -- and duplicate lifts
|
|
128
|
+
// collapse so the common case answers as the one kind it is.
|
|
129
|
+
if (true === v.isDisjunct) {
|
|
130
|
+
const arms: Val[] = []
|
|
131
|
+
const seen: Record<string, boolean> = {}
|
|
132
|
+
for (const a of v.peg) {
|
|
133
|
+
const lift = superOf(ctx, a)
|
|
134
|
+
if (true === (lift as any).isTop) {
|
|
135
|
+
return v.place(top())
|
|
136
|
+
}
|
|
137
|
+
if (true !== seen[lift.canon]) {
|
|
138
|
+
seen[lift.canon] = true
|
|
139
|
+
arms.push(lift)
|
|
49
140
|
}
|
|
50
141
|
}
|
|
51
|
-
|
|
142
|
+
if (1 === arms.length) {
|
|
143
|
+
return v.place(arms[0])
|
|
144
|
+
}
|
|
145
|
+
return v.place(new DisjunctVal({ peg: arms }, ctx))
|
|
52
146
|
}
|
|
53
147
|
|
|
148
|
+
// A constraint's parent is the kind it constrains: the absorbed
|
|
149
|
+
// leaf kind when it has one (integer & min(3) -> integer), else the
|
|
150
|
+
// domain its atoms compare in (min(3) -> number, min("a") ->
|
|
151
|
+
// string). length() constrains strings, lists and maps alike, so
|
|
152
|
+
// with neither it falls through to top.
|
|
153
|
+
if (true === v.isConstraint) {
|
|
154
|
+
if (null != v.kind) {
|
|
155
|
+
return v.place(new ScalarKindVal({ peg: v.kind }))
|
|
156
|
+
}
|
|
157
|
+
if ('number' === v.domain) {
|
|
158
|
+
return v.place(new ScalarKindVal({ peg: Number }))
|
|
159
|
+
}
|
|
160
|
+
if ('string' === v.domain) {
|
|
161
|
+
return v.place(new ScalarKindVal({ peg: String }))
|
|
162
|
+
}
|
|
163
|
+
return v.place(top())
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// The lattice primitive answers for the forms it always served:
|
|
167
|
+
// a concrete scalar lifts to its leaf kind, a kind to its parent,
|
|
168
|
+
// top to itself, and a NIL to itself -- which is how a failed
|
|
169
|
+
// argument stays the failure: `super(1 & 2)` reports the conflict
|
|
170
|
+
// rather than typing it. Where it has no meaningful answer (superior()
|
|
171
|
+
// defaults to top for features), top is the honest remainder.
|
|
172
|
+
const sup = v.superior()
|
|
173
|
+
if (null != sup && true !== (sup as any).isTop) {
|
|
174
|
+
return sup
|
|
175
|
+
}
|
|
176
|
+
return v.place(top())
|
|
54
177
|
} /* node:coverage ignore next 6 */
|
|
55
178
|
|
|
56
179
|
|
|
57
180
|
export {
|
|
58
181
|
SuperFuncVal,
|
|
182
|
+
superOf,
|
|
59
183
|
}
|
package/src/val/TopVal.ts
CHANGED
package/src/val/Val.ts
CHANGED
|
@@ -80,17 +80,6 @@ const EMPTY_ERR: any[] = Object.freeze([]) as unknown as any[]
|
|
|
80
80
|
let ID = 1000
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
// A fresh Val id, for the one carrier that cannot take the one its
|
|
84
|
-
// class fixes: TopVal pins `id = 0` (there is only one top), and the
|
|
85
|
-
// identity mark (G4 phase 1) resolves to a top that must NOT collide
|
|
86
|
-
// with it — the fast path in `unite` returns early on two done Vals
|
|
87
|
-
// with the same id, which would drop an identity before the rider
|
|
88
|
-
// could carry it.
|
|
89
|
-
export function nextValId(): number {
|
|
90
|
-
return ID++
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
83
|
abstract class Val {
|
|
95
84
|
// Type-discriminator flags: defaults live on Val.prototype (see
|
|
96
85
|
// bottom of this file). Each subclass overrides only its own
|
|
@@ -172,25 +161,16 @@ abstract class Val {
|
|
|
172
161
|
// marks are.
|
|
173
162
|
deprecation?: Record<string, string>
|
|
174
163
|
|
|
175
|
-
// The
|
|
176
|
-
// A separate slot for the same reason the deprecation record has
|
|
177
|
-
// one — a boolean ValMark cannot hold a name — and carried through
|
|
178
|
-
// meets by the same rider in `unite`. Unlike the marks, canon
|
|
179
|
-
// RENDERS it: identity is semantic content, and G6's hash must see
|
|
180
|
-
// it.
|
|
181
|
-
entity?: string
|
|
182
|
-
|
|
183
|
-
// The LINK (G4 phase 2/3): the entity address a `refer` resolved to,
|
|
164
|
+
// The LINK (G4 phase 2/3): the tree address a `refer` resolved to,
|
|
184
165
|
// stamped on the string it answers. The string IS the value — a
|
|
185
166
|
// link, not an embedding — so nothing downstream could otherwise
|
|
186
167
|
// tell a checked link from a literal that happens to look like one,
|
|
187
168
|
// and the edge set (ts/src/graph.ts) is exactly the set of these.
|
|
188
169
|
link?: string
|
|
189
170
|
|
|
190
|
-
// The GRAPH of an evaluated document (G4 phase 3): the
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
// result.
|
|
171
|
+
// The GRAPH of an evaluated document (G4 phase 3): the edge set,
|
|
172
|
+
// stamped on the result by Aontu.unify the way the include manifest
|
|
173
|
+
// is. Absent on every Val that is not a unify result.
|
|
194
174
|
graph?: any
|
|
195
175
|
|
|
196
176
|
// Actual native value.
|
|
@@ -311,20 +291,34 @@ abstract class Val {
|
|
|
311
291
|
out.mark.type = this.mark.type && (fullspec.mark?.type ?? true)
|
|
312
292
|
out.mark.hide = this.mark.hide && (fullspec.mark?.hide ?? true)
|
|
313
293
|
|
|
314
|
-
// The
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
|
|
318
|
-
// link alone would be a branch no document takes, the reference
|
|
319
|
-
// clone catching the pending residual before it ever resolves.
|
|
320
|
-
if (null != this.entity || null != this.link) {
|
|
321
|
-
out.entity = this.entity
|
|
294
|
+
// The LINK rider travels with the clone: the address a resolved
|
|
295
|
+
// link POINTS AT is part of what the value is, and a copy of a
|
|
296
|
+
// link is still a link.
|
|
297
|
+
if (null != this.link) {
|
|
322
298
|
out.link = this.link
|
|
323
299
|
}
|
|
324
300
|
if (null != this.deprecation) {
|
|
325
301
|
out.deprecation = this.deprecation
|
|
326
302
|
}
|
|
327
303
|
|
|
304
|
+
// THE APPLY-ONCE MARK TRAVELS WITH THE CLONE. `_spr` records which
|
|
305
|
+
// spread template has already been merged into this value, and the
|
|
306
|
+
// bag loops read it to keep a template from being applied twice
|
|
307
|
+
// (MapVal.unify, ListVal.unify). A clone that dropped it looked
|
|
308
|
+
// un-spread, so a REFERENCE resolving to a templated bag had the
|
|
309
|
+
// template applied a second time -- over the value the first
|
|
310
|
+
// application had already produced. With `n: key()` that meant
|
|
311
|
+
// meeting the answered `"x"` as though it were a map and asking
|
|
312
|
+
// `key()` again, which answered `"n"`: `$.a.b.f.x.n.n`, "n"
|
|
313
|
+
// against "x" (use-cases/BUGS.md §50). The Go port carries it and
|
|
314
|
+
// answered correctly; this is the canonical side catching up.
|
|
315
|
+
if (null != (this as any)._spr) {
|
|
316
|
+
; (out as any)._spr = (this as any)._spr
|
|
317
|
+
}
|
|
318
|
+
if (null != (this as any)._sid) {
|
|
319
|
+
; (out as any)._sid = (this as any)._sid
|
|
320
|
+
}
|
|
321
|
+
|
|
328
322
|
// PROVENANCE TRAVELS WITH THE CLONE, exactly as the site does, and
|
|
329
323
|
// for the same reason: a clone of a value the author wrote IS that
|
|
330
324
|
// written value somewhere else, and it carries the author's site,
|
|
@@ -361,7 +355,7 @@ abstract class Val {
|
|
|
361
355
|
// once per destination child, and each application must own its
|
|
362
356
|
// path-dependent innards — a bare clone shared a call's arguments
|
|
363
357
|
// and a preference's inner value across destinations, so a spread
|
|
364
|
-
// like `&:
|
|
358
|
+
// like `&: {k: key(0)} & $.schema.C` resolved its one shared key()
|
|
365
359
|
// at the first child it met (use-cases/BUGS.md §12's id_name form).
|
|
366
360
|
spreadClone(ctx: AontuContext): Val {
|
|
367
361
|
const out = this.clone(ctx, { dup: true })
|
|
@@ -656,14 +650,27 @@ function pretty(s: string) {
|
|
|
656
650
|
}
|
|
657
651
|
|
|
658
652
|
|
|
653
|
+
// THE STABLE IDENTITY OF A SPREAD TEMPLATE, across clones. Every Val
|
|
654
|
+
// takes a fresh `id` when it is constructed, so the bag loops'
|
|
655
|
+
// apply-once mark -- which records WHICH template has already been
|
|
656
|
+
// merged into a value -- could never match after a clone: a reference
|
|
657
|
+
// resolving to a templated bag clones the bag AND its template, and the
|
|
658
|
+
// fresh template's id matched nothing, so the template was applied a
|
|
659
|
+
// second time over the value the first application had produced
|
|
660
|
+
// (use-cases/BUGS.md §50). The first call fixes the identity to the
|
|
661
|
+
// original's own id; Val.clone carries `_sid`, so every clone of that
|
|
662
|
+
// template answers with it.
|
|
663
|
+
function spreadId(cj: any): number {
|
|
664
|
+
return cj._sid ?? (cj._sid = cj.id)
|
|
665
|
+
}
|
|
666
|
+
|
|
659
667
|
function empty(o: any) {
|
|
660
668
|
return (
|
|
661
669
|
(Array.isArray(o) && 0 === o.length)
|
|
662
670
|
|| (null != o && 'object' === typeof o && 0 === Object.keys(o).length)
|
|
663
671
|
|| false
|
|
664
672
|
)
|
|
665
|
-
} /* node:coverage ignore next
|
|
666
|
-
|
|
673
|
+
} /* node:coverage ignore next 17 */
|
|
667
674
|
|
|
668
675
|
|
|
669
676
|
export type {
|
|
@@ -671,7 +678,9 @@ export type {
|
|
|
671
678
|
ValSpec,
|
|
672
679
|
}
|
|
673
680
|
|
|
681
|
+
|
|
674
682
|
export {
|
|
683
|
+
spreadId,
|
|
675
684
|
Val,
|
|
676
685
|
DONE,
|
|
677
686
|
SPREAD,
|
package/src/val/arith.ts
CHANGED
|
@@ -105,7 +105,10 @@ function unpref(v: any): any {
|
|
|
105
105
|
|
|
106
106
|
|
|
107
107
|
function arithKind(v: any): ArithKind | undefined {
|
|
108
|
-
|
|
108
|
+
// Every caller hands a driven Val (an operand past the signature
|
|
109
|
+
// gate, or a bag member from the aggregate fold), so scalarhood is
|
|
110
|
+
// the one question -- a container member lands here.
|
|
111
|
+
if (true !== v?.isScalar) {
|
|
109
112
|
return undefined
|
|
110
113
|
}
|
|
111
114
|
if (v.isBigInteger) {
|
package/src/vet.ts
CHANGED
|
@@ -146,8 +146,10 @@ export type VetOptions = {
|
|
|
146
146
|
// Vet's whole job is to evaluate a document its caller did not
|
|
147
147
|
// write, so the caller must be able to say what that document is
|
|
148
148
|
// allowed to reach: without this the include chain is the default
|
|
149
|
-
// one, and `@"
|
|
150
|
-
// the validating process.
|
|
149
|
+
// one, and `@"../../etc/passwd.aon"` in hostile data reads whatever
|
|
150
|
+
// the validating process can. (`@"x.js"` no longer executes --
|
|
151
|
+
// ADR-012 refuses the extension -- but reading is enough.) A server
|
|
152
|
+
// passes `{include:'none'}`.
|
|
151
153
|
trust?: TrustOptions
|
|
152
154
|
}
|
|
153
155
|
|
|
@@ -696,7 +698,18 @@ export function vet(
|
|
|
696
698
|
findings: [findingOf(failure, { data: new Set([dataUrl]) })],
|
|
697
699
|
}
|
|
698
700
|
}
|
|
699
|
-
|
|
701
|
+
// STAMP THE WHOLE SETTLED SCHEMA, not just the lifted anchor.
|
|
702
|
+
// Without `--at` these are the same tree. With it, the anchor is a
|
|
703
|
+
// subtree and the rest of the schema is still REACHABLE from inside
|
|
704
|
+
// it -- a `%alias` declaration (`[&: %U]`, target `$.%U`) or a
|
|
705
|
+
// recursive residual's `$.spec.Step`, both of which the meet
|
|
706
|
+
// resolves through _fixroot (RefVal.find, RecurseVal.body). A node
|
|
707
|
+
// reached that way but never stamped carries no url, so its site
|
|
708
|
+
// named no file while excerpting the schema's text -- against the
|
|
709
|
+
// invariant that every site names the file whose text it shows
|
|
710
|
+
// (finding F, §25). stampUrl only fills a url that is EMPTY, so
|
|
711
|
+
// stamping the superset never renames a value read from an include.
|
|
712
|
+
stampUrl(schemaVal, schemaUrl)
|
|
700
713
|
const dataUrls = stampUrl(dataVal, dataUrl)
|
|
701
714
|
// The projection every site in this report goes through: roles by
|
|
702
715
|
// url-set membership, names by how the caller reached each document.
|
|
@@ -820,6 +833,26 @@ export function vet(
|
|
|
820
833
|
stampUrl(meetAnchor, schemaUrl)
|
|
821
834
|
}
|
|
822
835
|
}
|
|
836
|
+
else {
|
|
837
|
+
// A RECURSIVE residual inside the lifted anchor still names its
|
|
838
|
+
// definition by absolute path (`then?: $.spec.Step` -- the
|
|
839
|
+
// fixpoint, RECURSION.0.md), and the meet's root is the anchored
|
|
840
|
+
// subtree, which does not contain `$.spec`. Without a tree to
|
|
841
|
+
// walk, the residual held its peer forever and everything under a
|
|
842
|
+
// recursive field vetted VALID unchecked. The settled schema root
|
|
843
|
+
// is kept on the meet context for exactly that walk
|
|
844
|
+
// (AontuContext._fixroot; RecurseVal.body and RefVal.find fall
|
|
845
|
+
// back to it).
|
|
846
|
+
; (ctx as any)._fixroot = schemaVal
|
|
847
|
+
// And the meet DRIVES AT the anchor's own path, so every finding
|
|
848
|
+
// minted live during it sits in the schema's namespace
|
|
849
|
+
// ($.spec.Step.then.approver), exactly where the findings carried
|
|
850
|
+
// on the settled anchor's stored paths already sit -- the Go port
|
|
851
|
+
// gets this for free from its clone discipline, and the shared
|
|
852
|
+
// anchored-vet rows pin the agreement.
|
|
853
|
+
; (ctx as any).path = options.at.replace(/^\$\.?/, '')
|
|
854
|
+
.split('.').filter((s: string) => '' !== s)
|
|
855
|
+
}
|
|
823
856
|
const pair = new ConjunctVal({ peg: [meetAnchor, dataVal] }, ctx)
|
|
824
857
|
const unified: any = aontu.unify(pair, undefined, ctx)
|
|
825
858
|
|