aontu 0.56.0 → 0.57.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 +2 -1
- package/dist/aontu.js +1 -1
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +5 -1
- package/dist/cli.js +89 -18
- package/dist/cli.js.map +1 -1
- package/dist/escape.d.ts +5 -0
- package/dist/escape.js +455 -0
- package/dist/escape.js.map +1 -0
- package/dist/format.d.ts +9 -0
- package/dist/format.js +544 -55
- package/dist/format.js.map +1 -1
- package/dist/hints.js +35 -1
- package/dist/hints.js.map +1 -1
- package/dist/lang.js +20 -1
- package/dist/lang.js.map +1 -1
- package/dist/lsp.d.ts +1 -1
- package/dist/lsp.js +3 -3
- package/dist/lsp.js.map +1 -1
- package/dist/mcp-server.js +2 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/mod-tool.js +8 -7
- package/dist/mod-tool.js.map +1 -1
- package/dist/mod.js +6 -6
- package/dist/mod.js.map +1 -1
- package/dist/sigdecl.js +1 -1
- package/dist/sigdecl.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/val/EachFuncVal.js +1 -2
- package/dist/val/EachFuncVal.js.map +1 -1
- package/dist/val/EmitFuncVal.d.ts +23 -0
- package/dist/val/EmitFuncVal.js +261 -0
- package/dist/val/EmitFuncVal.js.map +1 -0
- package/dist/val/FilterFuncVal.js +1 -2
- package/dist/val/FilterFuncVal.js.map +1 -1
- package/dist/val/FuncBaseVal.d.ts +1 -0
- package/dist/val/FuncBaseVal.js +16 -0
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/PackFuncVal.js +1 -2
- package/dist/val/PackFuncVal.js.map +1 -1
- package/dist/val/PlaceVal.d.ts +3 -1
- package/dist/val/PlaceVal.js +8 -6
- package/dist/val/PlaceVal.js.map +1 -1
- package/dist/val/StrFuncVal.d.ts +32 -0
- package/dist/val/StrFuncVal.js +292 -0
- package/dist/val/StrFuncVal.js.map +1 -0
- package/grammar/aontu.abnf +4 -3
- package/grammar/aontu.gbnf +4 -3
- package/grammar/aontu.lark +4 -3
- package/grammar/aontu.tmLanguage.json +1 -1
- package/package.json +1 -1
- package/src/aontu.ts +2 -1
- package/src/cli.ts +113 -20
- package/src/escape.ts +371 -0
- package/src/format.ts +638 -56
- package/src/hints.ts +48 -1
- package/src/lang.ts +24 -1
- package/src/lsp.ts +3 -3
- package/src/mcp-server.ts +3 -2
- package/src/mod-tool.ts +9 -8
- package/src/mod.ts +6 -6
- package/src/sigdecl.ts +1 -1
- package/src/val/EachFuncVal.ts +1 -3
- package/src/val/EmitFuncVal.ts +401 -0
- package/src/val/FilterFuncVal.ts +1 -3
- package/src/val/FuncBaseVal.ts +18 -0
- package/src/val/PackFuncVal.ts +1 -3
- package/src/val/PlaceVal.ts +8 -6
- package/src/val/StrFuncVal.ts +334 -0
package/src/hints.ts
CHANGED
|
@@ -222,11 +222,33 @@ const hints: Record<string, string> = {
|
|
|
222
222
|
|
|
223
223
|
match_none: 'No pattern matched, and there is no default. `match` tries each\npattern in the order written and takes the first the value unifies\nwith; the value {value} unified with none of {tried}. Add a trailing\ndefault — the argument after the last pair — if the rest was meant\nto be allowed.\n \nExamples:\n match(1, integer, ok) -> "ok" # The first pattern matches;\n match(x, integer, ok, other) -> "other" # ... or the default does;\n match(x, integer, ok) -> nil # ... but nothing here does.',
|
|
224
224
|
|
|
225
|
+
emit_data: 'The first argument to emit() is not a bag. `emit` visits the\nchildren of its SELECTION, so the selection has to have children: a\nlist of nodes, or a map whose values are the nodes.\n \nExamples:\n emit([{k:1}], {match:{k:1},body:[a]}) -> [..] # A list of nodes;\n emit({x:{k:1}}, {match:{k:1},body:[a]}) -> [..] # ... or a map of them;\n emit(1, {match:{k:1},body:[a]}) -> nil # ... but not a scalar.',
|
|
226
|
+
|
|
227
|
+
emit_table: 'The second argument to emit() is not a rule table. A table is a\nLIST of templates, tried in order; a single template may be written\nas the map itself, which is that list of one.\n \nExamples:\n emit($.n, [{match:integer,body:[a]}]) -> [..] # A table of rules;\n emit($.n, {match:integer,body:[a]}) -> [..] # ... or one rule alone;\n emit($.n, integer) -> nil # ... but not a value.',
|
|
228
|
+
|
|
229
|
+
emit_template: 'A template in an emit() table is not a rule. Every rule is a map\nnaming both a `match` — the pattern the node is tried against — and a\n`body`, the pieces to emit. A rule with no pattern would claim every\nnode by accident; one with no body would claim a node and emit\nnothing.\n \nExamples:\n {match: {kind: sqs}, body: [a]} # A rule;\n {match: {kind: sqs}} # ... but a pattern is not one;\n {body: [a]} # ... nor is a body alone.',
|
|
230
|
+
|
|
231
|
+
emit_body: 'A template body in an emit() table is not a list. A body is the\nSEQUENCE of pieces the matched node emits, so it is written as a\nlist even when it holds one piece — which is what lets bodies\ncompose, since a body element that is itself a list splices.\n \nExamples:\n {match: integer, body: [a]} -> [..] # One piece;\n {match: integer, body: [a,b]} -> [..] # ... or several;\n {match: integer, body: a} -> nil # ... but not a bare value.',
|
|
232
|
+
|
|
233
|
+
emit_ref: 'A template body names {ref}, and the node it matched cannot\nanswer it. Inside a body a relative reference is a field of the\nMATCHED NODE — `.pin` is that node\'s `pin` — so the node has to have\nthe field; the node was {value}. An absolute reference (`$.x`) reads\nthe document root instead, and is untouched.\n \nExamples:\n {match:{pin:string}, body:[.pin]} -> [..] # A field of the node;\n {match:{pin:string}, body:[$.z]} -> [..] # ... or the root;\n {match:{pin:string}, body:[.port]} -> nil # ... but not a field it\n # has not got.',
|
|
234
|
+
|
|
235
|
+
emit_none: 'No template matched a node, and there is no catch-all. `emit`\ntries each template in the order written and takes the first the\nnode unifies with; the node {value} unified with none of {tried}.\nAdd a template whose `match` is `any` — last, since the first match\nwins — if the rest of the selection was meant to be allowed.\n \nExamples:\n emit([1], [{match:integer,body:[a]}]) -> [..] # A pattern matches;\n emit([x], [{match:any,body:[a]}]) -> [..] # ... or a catch-all;\n emit([x], [{match:integer,body:[a]}]) -> nil # ... but nothing here.',
|
|
236
|
+
|
|
237
|
+
esc_variant: 'esc() and usc() were given a variant that names no convention.\nA variant names a CONVENTION rather than a language, because several\nlanguages share one and one language has several. The names are `sq`,\n`sql`, `shell`, `xml`, `uri` and `regex`; written with no variant at\nall it is the C escape, JSON canonical, which covers the double-quoted\nliteral of every C-family language.\n \nExamples:\n esc(text) -> ... # C / JSON, the default;\n esc(text, sq) -> ... # ... single-quoted C-family;\n esc(text, pascal) -> nil # ... but that is not a convention.',
|
|
238
|
+
|
|
239
|
+
usc_malformed: 'usc() was given text the convention could not have produced,\nso there is nothing to read back out: a truncated code-point escape, an\nescape the convention does not define, or an escape character standing\nalone where the convention doubles it. `usc` is the LEFT inverse of\n`esc` and it is partial — every escaped value has an original, but not\nevery string is an escaped value.\n \nExamples:\n usc(esc(text)) -> ... # Whatever esc() wrote;\n usc(text, sql) -> ... # ... in the same convention;\n usc(text, shell) -> nil # ... but not in another one.',
|
|
240
|
+
|
|
241
|
+
rep_pattern: 'The pattern given to rep() is outside the portable subset. It is\nthe same subset re() takes — RE2-compatible, no backreferences, no\nlookaround — so one document has one regexp language rather than two,\nand so a generator running a pattern over model data cannot take\nexponential time doing it.\n \nExamples:\n rep(s, "[:,]", " ") -> ... # A class;\n rep(s, "(a)(b)", "$2$1") -> ... # ... a group;\n rep(s, "(?=a)", "x") -> nil # ... but not a lookahead.',
|
|
242
|
+
|
|
243
|
+
rep_sub: 'The substitution given to rep() names something the pattern has\nnot got. `$1` to `$9` are the numbered groups, `$&` is the whole match\nand `$$` is a literal `$`; a `$` naming anything else, or a group\nnumber the pattern does not have, is refused rather than expanded to\nnothing — a generator that writes a file with a hole in it and says\nnothing is the failure this refusal exists to close.\n \nExamples:\n rep(s, "(a)", "[$1]") -> ... # A group the pattern has;\n rep(s, "a", "$$") -> ... # ... a literal dollar;\n rep(s, "a", "$1") -> nil # ... but not a group it has not.',
|
|
244
|
+
|
|
245
|
+
split_sep: 'The separator given to split() is neither a string nor a pattern.\nA plain string is a LITERAL and an `re(…)` argument is a pattern — the\nasymmetry with rep() is deliberate, since splitting is usually on a\nliteral, and it removes the trap where `split(v, ".")` silently cuts\nbetween every character.\n \nExamples:\n split("a,b", ",") -> [..] # A literal separator;\n split("a1b", re("[0-9]")) -> [..] # ... or a pattern;\n split("a,b", 1) -> nil # ... but not a number.',
|
|
246
|
+
|
|
225
247
|
place_pair: 'Two placeholders met, and neither has a value to fill the other.\n`_` is a HOLE: it is filled by whatever the call is unified with, so\na call holding one needs a peer that does not. Give one side a\nvalue.\n \nExamples:\n upper(_) & hello -> "HELLO" # The peer fills the hole;\n _ + 2 & 1 -> 3 # ... whatever the call is;\n upper(_) & lower(_) -> nil # ... but two holes fill nothing.',
|
|
226
248
|
|
|
227
249
|
|
|
228
250
|
module_path: 'A module import is domain-shaped and carries a major, but its\npath cannot be a directory on every platform the toolchain runs on --\nso it is refused before anything is built from it. An element may not\nbe empty, may not begin or end with `.` (which is what forbids `..`),\nand may not be a reserved device name. These are Go\'s module-path\nrules, for Go\'s reason: a module path becomes a real directory.\n \nExamples:\n @"corp.example/s@1" -> {..} # An ordinary path is fine;\n @"corp.example/../s@1" -> nil # ... `..` would escape the store;\n @"corp.example/nul@1" -> nil # ... and Windows has no such file.',
|
|
229
|
-
module_missing: 'A module import names a module that is not in this project. A\nmodule is resolved from LOCAL stores only -- `
|
|
251
|
+
module_missing: 'A module import names a module that is not in this project. A\nmodule is resolved from LOCAL stores only -- `aontu_meta/vendor/` beside the\nproject\'s mod.aon, then the user cache -- because evaluation never\ntouches the network. Fetching is a separate step, and the message\nnames it.\n \nExamples:\n @"corp.example/s@1" -> nil # Not fetched: run aontu mod get;\n @"./local.aon" -> {..} # ... a local path is not a module;\n @"corp.example/s@1#aon1-…" -> {..} # ... and a pin does not fetch it either.',
|
|
230
252
|
|
|
231
253
|
module_integrity: 'A module resolved locally does not have the MEANING it was pinned\nto. The pin is a canon-hash -- the hash of the module unified\nstandalone -- so it survives comments, formatting and refactoring and\nbreaks on any semantic change in the module\'s transitive closure.\nVerification is always local: the registry\'s annotation is advisory.\n \nExamples:\n @"corp.example/s@1" -> {..} # No pin, no check;\n @"corp.example/s@1#aon1-x" -> nil # ... a pin that disagrees refuses;\n aontu hash <file> # ... and this is what it should be.',
|
|
232
254
|
|
|
@@ -549,6 +571,31 @@ const codeClasses: Record<string, string> = {
|
|
|
549
571
|
filter_data: 'parse',
|
|
550
572
|
match_none: 'conflict',
|
|
551
573
|
|
|
574
|
+
// G9 phase 6 -- the string builtins. All five are class `parse`:
|
|
575
|
+
// what is wrong is the CALL as written -- a variant that names no
|
|
576
|
+
// convention, a pattern outside the subset, a substitution naming a
|
|
577
|
+
// group that does not exist, a separator that is neither string nor
|
|
578
|
+
// pattern. `usc_malformed` is the odd one and still `parse`: the
|
|
579
|
+
// TEXT the call was given has no inverse, which is a fact about the
|
|
580
|
+
// argument rather than about any meet.
|
|
581
|
+
esc_variant: 'parse',
|
|
582
|
+
usc_malformed: 'parse',
|
|
583
|
+
rep_pattern: 'parse',
|
|
584
|
+
rep_sub: 'parse',
|
|
585
|
+
split_sep: 'parse',
|
|
586
|
+
|
|
587
|
+
// G9 phase 6 -- apply-templates. The four shape codes are class
|
|
588
|
+
// `parse`: what is wrong is the CALL as written -- a selection with
|
|
589
|
+
// no children, a table that is not one, a rule missing a half.
|
|
590
|
+
// `emit_none` is class `conflict` for `match_none`'s reason: the
|
|
591
|
+
// node and every pattern written for it disagreed.
|
|
592
|
+
emit_data: 'parse',
|
|
593
|
+
emit_table: 'parse',
|
|
594
|
+
emit_template: 'parse',
|
|
595
|
+
emit_body: 'parse',
|
|
596
|
+
emit_none: 'conflict',
|
|
597
|
+
emit_ref: 'conflict',
|
|
598
|
+
|
|
552
599
|
// G8 phase 3 -- the placeholder. Class `conflict`: two values met
|
|
553
600
|
// and neither could answer for the other, which is what every
|
|
554
601
|
// conflict is.
|
package/src/lang.ts
CHANGED
|
@@ -145,6 +145,10 @@ import { PackFuncVal } from './val/PackFuncVal'
|
|
|
145
145
|
import { EachFuncVal } from './val/EachFuncVal'
|
|
146
146
|
import { FilterFuncVal } from './val/FilterFuncVal'
|
|
147
147
|
import { MatchFuncVal } from './val/MatchFuncVal'
|
|
148
|
+
import { EmitFuncVal } from './val/EmitFuncVal'
|
|
149
|
+
import {
|
|
150
|
+
EscFuncVal, UscFuncVal, RepFuncVal, SplitFuncVal,
|
|
151
|
+
} from './val/StrFuncVal'
|
|
148
152
|
import {
|
|
149
153
|
AddFuncVal, SubFuncVal, MulFuncVal, DivFuncVal, ModFuncVal, RemFuncVal,
|
|
150
154
|
} from './val/ArithFuncVal'
|
|
@@ -667,6 +671,25 @@ help isolate the syntax error.`,
|
|
|
667
671
|
// the language does not grow a second. It is the primitive that
|
|
668
672
|
// turns a bag of computed lines into a file.
|
|
669
673
|
join: JoinFuncVal,
|
|
674
|
+
|
|
675
|
+
// G9 phase 6: apply-templates. One flat list of pieces from a
|
|
676
|
+
// selection and a RULE TABLE -- for each node, the first template
|
|
677
|
+
// whose `match` it unifies with, its `body` instantiated at that
|
|
678
|
+
// node. The dispatch is the engine's because a body referenced by
|
|
679
|
+
// path resolves its references at the definition site, and the
|
|
680
|
+
// relative resolution that does exist is a dot count that does not
|
|
681
|
+
// survive a second dispatch (docs/design/EMIT.0.md).
|
|
682
|
+
emit: EmitFuncVal,
|
|
683
|
+
|
|
684
|
+
// G9 phase 6: the string builtins the rule layer needs. `esc`
|
|
685
|
+
// makes a value safe inside a literal and `usc` reads it back;
|
|
686
|
+
// `rep` and `split` derive names from model data. All four are
|
|
687
|
+
// ordinary string functions -- they know nothing about generation,
|
|
688
|
+
// which is why they can land before the renderer does.
|
|
689
|
+
esc: EscFuncVal,
|
|
690
|
+
usc: UscFuncVal,
|
|
691
|
+
rep: RepFuncVal,
|
|
692
|
+
split: SplitFuncVal,
|
|
670
693
|
}
|
|
671
694
|
|
|
672
695
|
|
|
@@ -2065,7 +2088,7 @@ function makeModelResolver(options: any) {
|
|
|
2065
2088
|
const found = resolveModule(modref, from, modFs(ctx), {
|
|
2066
2089
|
// The user cache lives outside any confinement root, so it is
|
|
2067
2090
|
// consulted only when nothing confines this evaluation. A
|
|
2068
|
-
// rooted profile sees the project's own `
|
|
2091
|
+
// rooted profile sees the project's own `aontu_meta/vendor/` and
|
|
2069
2092
|
// nothing else, which is what `root` means.
|
|
2070
2093
|
...(null == rootDir ? { cache: modCache(options) } : {}),
|
|
2071
2094
|
eval: options.mod?.eval,
|
package/src/lsp.ts
CHANGED
|
@@ -527,13 +527,13 @@ const COMPLETION_KEYWORD = 14
|
|
|
527
527
|
// between G4 phases 1/2 and G8 phase 1.
|
|
528
528
|
const BUILTIN_FUNCS = [
|
|
529
529
|
'above', 'acyclic', 'add', 'below', 'close', 'copy', 'deprecate', 'div',
|
|
530
|
-
'each',
|
|
530
|
+
'each', 'emit', 'esc',
|
|
531
531
|
'filter', 'greatest',
|
|
532
532
|
'hide', 'inverse', 'join', 'key', 'least', 'length', 'list', 'lower',
|
|
533
533
|
'map', 'match', 'max', 'min', 'mod', 'move', 'mul', 'must', 'neq', 'open',
|
|
534
534
|
'pack', 'path', 'pick',
|
|
535
|
-
'pref', 're', 'refer', 'rel', 'rem', '
|
|
536
|
-
'upper',
|
|
535
|
+
'pref', 're', 'refer', 'rel', 'rem', 'rep', 'split', 'sub', 'sum',
|
|
536
|
+
'super', 'type', 'unique', 'upper', 'usc',
|
|
537
537
|
]
|
|
538
538
|
|
|
539
539
|
// Scalar-kind and literal keywords.
|
package/src/mcp-server.ts
CHANGED
|
@@ -30,9 +30,9 @@ import type { McpRequest, McpResponse } from './mcp'
|
|
|
30
30
|
import { VERSION } from './aontu'
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
const USAGE = 'aontu
|
|
33
|
+
const USAGE = 'aontu mcp - Aontu MCP server (stdio, NDJSON JSON-RPC)\n' +
|
|
34
34
|
'\n' +
|
|
35
|
-
' aontu
|
|
35
|
+
' aontu mcp [--root <dir>]\n' +
|
|
36
36
|
'\n' +
|
|
37
37
|
' --root <dir> Serve <name>Path file arguments and resolve\n' +
|
|
38
38
|
' @"..." includes, confined below <dir>\n' +
|
|
@@ -41,6 +41,7 @@ const USAGE = 'aontu-mcp - Aontu MCP server (stdio, NDJSON JSON-RPC)\n' +
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
// The startup arguments. Parsed here rather than in bin/aontu-mcp.js
|
|
44
|
+
// or the CLI's mcp verb
|
|
44
45
|
// so the parsing is import-testable; unknown options REFUSE rather
|
|
45
46
|
// than warn, because a server whose operator typo'd --root must not
|
|
46
47
|
// come up quietly unconfined.
|
package/src/mod-tool.ts
CHANGED
|
@@ -78,7 +78,7 @@ export type ModVerifyReport = {
|
|
|
78
78
|
|
|
79
79
|
export type ModVendorReport = {
|
|
80
80
|
verdict: 'ok' | 'missing'
|
|
81
|
-
// The modules materialised into `
|
|
81
|
+
// The modules materialised into `aontu_meta/vendor/`, sorted.
|
|
82
82
|
vendored: string[]
|
|
83
83
|
// Locked modules present in no store, sorted.
|
|
84
84
|
missing: string[]
|
|
@@ -193,7 +193,7 @@ function usableRef(mod: string): ModuleRef | undefined {
|
|
|
193
193
|
function storeDir(
|
|
194
194
|
root: string, ref: ModuleRef, hash: string, options: ModToolOptions,
|
|
195
195
|
): string | undefined {
|
|
196
|
-
const stores = [moduleDir(pathJoin(root, '
|
|
196
|
+
const stores = [moduleDir(pathJoin(root, 'aontu_meta', 'vendor'), ref)]
|
|
197
197
|
if (null != options.cache && '' !== hash) {
|
|
198
198
|
stores.push(pathJoin(options.cache, hash))
|
|
199
199
|
}
|
|
@@ -203,7 +203,7 @@ function storeDir(
|
|
|
203
203
|
|
|
204
204
|
// The lockfile's entries, as written.
|
|
205
205
|
function readLock(root: string): Record<string, ModLock> {
|
|
206
|
-
const file = pathJoin(root, 'mod-lock.aon')
|
|
206
|
+
const file = pathJoin(root, 'aontu_meta', 'mod-lock.aon')
|
|
207
207
|
if (!existsSync(file)) {
|
|
208
208
|
return {}
|
|
209
209
|
}
|
|
@@ -335,7 +335,8 @@ export function modTidy(root: string, options: ModToolOptions): ModTidyReport {
|
|
|
335
335
|
const uniqueUnevaluable = [...new Set(unevaluable)].sort()
|
|
336
336
|
const held = 0 === uniqueMissing.length && 0 === uniqueUnevaluable.length
|
|
337
337
|
if (held) {
|
|
338
|
-
|
|
338
|
+
mkdirSync(pathJoin(root, 'aontu_meta'), { recursive: true })
|
|
339
|
+
writeFileSync(pathJoin(root, 'aontu_meta', 'mod-lock.aon'),
|
|
339
340
|
LOCK_HEADER + lockText(lock, options) + '\n')
|
|
340
341
|
}
|
|
341
342
|
|
|
@@ -441,14 +442,14 @@ export function modVerify(root: string, options: ModToolOptions):
|
|
|
441
442
|
}
|
|
442
443
|
|
|
443
444
|
|
|
444
|
-
// `aontu mod vendor`: materialise the locked closure into `
|
|
445
|
+
// `aontu mod vendor`: materialise the locked closure into `aontu_meta/vendor/`.
|
|
445
446
|
export function modVendor(root: string, options: ModToolOptions):
|
|
446
447
|
ModVendorReport {
|
|
447
448
|
const locked = readLock(root)
|
|
448
449
|
const vendored: string[] = []
|
|
449
450
|
const missing: string[] = []
|
|
450
451
|
|
|
451
|
-
const vendorRoot = pathJoin(root, '
|
|
452
|
+
const vendorRoot = pathJoin(root, 'aontu_meta', 'vendor')
|
|
452
453
|
|
|
453
454
|
for (const mod of Object.keys(locked).sort()) {
|
|
454
455
|
const ref = usableRef(mod)
|
|
@@ -593,13 +594,13 @@ function majorOf(version: string): string {
|
|
|
593
594
|
|
|
594
595
|
|
|
595
596
|
// Every file of a module's source tree, relative and forward-slashed.
|
|
596
|
-
// `
|
|
597
|
+
// `aontu_meta/vendor/` is excluded: a published module carries its own
|
|
597
598
|
// sources, not a copy of everyone else's -- a consumer resolves the
|
|
598
599
|
// closure itself, and a nested vendor tree would publish the world.
|
|
599
600
|
function layerFiles(dir: string, prefix = ''): string[] {
|
|
600
601
|
const out: string[] = []
|
|
601
602
|
for (const name of readdirSync(dir).sort()) {
|
|
602
|
-
if ('
|
|
603
|
+
if ('aontu_meta' === name) {
|
|
603
604
|
continue
|
|
604
605
|
}
|
|
605
606
|
const full = pathJoin(dir, name)
|
package/src/mod.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// local: @"./fragment.aon" <- unchanged, not a module
|
|
13
13
|
//
|
|
14
14
|
// EVALUATION NEVER TOUCHES THE NETWORK. Resolution reads local stores
|
|
15
|
-
// only: `
|
|
15
|
+
// only: `aontu_meta/vendor/` beside the project's `mod.aon`, then a
|
|
16
16
|
// content-addressed user cache keyed by canon-hash. Fetching is a
|
|
17
17
|
// separate, explicit tool step, and a module that is in neither store
|
|
18
18
|
// is an evaluation error that says so.
|
|
@@ -81,7 +81,7 @@ export function parseModuleRef(spec: string): ModuleRef | undefined {
|
|
|
81
81
|
// `[A-Za-z0-9._-]` admits `..`, and `moduleDir` joins elements with
|
|
82
82
|
// pathJoin, which CLEANS `..` rather than refusing it:
|
|
83
83
|
//
|
|
84
|
-
// moduleDir('/store/
|
|
84
|
+
// moduleDir('/store/aontu_meta/vendor', 'corp.example/../../etc/passwd@1')
|
|
85
85
|
// -> /store/etc/passwd@1
|
|
86
86
|
//
|
|
87
87
|
// `mod vendor` then copied a tree THERE, outside the project entirely,
|
|
@@ -168,9 +168,9 @@ export function moduleDir(store: string, ref: ModuleRef): string {
|
|
|
168
168
|
// root being a directory holding a `mod.aon`. This used to answer with
|
|
169
169
|
// the NEAREST one alone, and the plural is the fix, because a
|
|
170
170
|
// VENDORED MODULE IS A PROJECT INSIDE A PROJECT. A module in
|
|
171
|
-
// `
|
|
171
|
+
// `aontu_meta/vendor/` carries its own `mod.aon`, which stopped the upward
|
|
172
172
|
// walk there, so a nested import resolved against the vendored
|
|
173
|
-
// module's own directory: a tree with no `
|
|
173
|
+
// module's own directory: a tree with no `aontu_meta/vendor/` of its own, and
|
|
174
174
|
// therefore a `module not fetched` for a dependency sitting flat
|
|
175
175
|
// beside it in the CONSUMER's vendor tree — the only layout `mod
|
|
176
176
|
// vendor` produces (use-cases/BUGS.md §31).
|
|
@@ -272,7 +272,7 @@ export function modCacheDirFor(
|
|
|
272
272
|
|
|
273
273
|
export function lockHash(root: string, ref: ModuleRef, fs: ModuleFs):
|
|
274
274
|
string | undefined {
|
|
275
|
-
const file = pathJoin(root, 'mod-lock.aon')
|
|
275
|
+
const file = pathJoin(root, 'aontu_meta', 'mod-lock.aon')
|
|
276
276
|
if (!fs.existsSync(file)) {
|
|
277
277
|
return undefined
|
|
278
278
|
}
|
|
@@ -392,7 +392,7 @@ export function resolveModule(
|
|
|
392
392
|
roots.map((r) => lockHash(r, ref, fs)).find((h) => null != h)
|
|
393
393
|
|
|
394
394
|
const stores: string[] =
|
|
395
|
-
roots.map((r) => moduleDir(pathJoin(r, '
|
|
395
|
+
roots.map((r) => moduleDir(pathJoin(r, 'aontu_meta', 'vendor'), ref))
|
|
396
396
|
if (null != options.cache && null != expect) {
|
|
397
397
|
// Content-addressed: the cache is keyed by the hash, so a cache hit
|
|
398
398
|
// is already the right MEANING before anything is read from it.
|
package/src/sigdecl.ts
CHANGED
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
// this copy is identical with the shared file.
|
|
7
7
|
|
|
8
8
|
const SIGDECL: string =
|
|
9
|
-
"# The call surface: one declaration line per built-in function\n# (docs/design/SIGNATURES.0.md). THIS FILE IS THE SOURCE — both ports\n# carry a build-time-inlined copy (ts/src/sigdecl.ts, go/sigdecl.txt;\n# `make sig` regenerates both, and each port's suite asserts its copy\n# is byte-identical with this file) and parse it at initialisation\n# with the signature grammar, a tabnas grammar (ts/src/sig.ts,\n# go/sig.go). The suites also round-trip every line:\n# render(parse(line)) must be the line exactly, in both ports.\n#\n# The syntax (rendered TypeScript-ish, honest about argument MODES):\n# line = name '(' [ arg {',' arg} ] ')' ':' type\n# arg = [mode] name ['?'] ':' type\n# | '...' name ':' '(' [mode] type {',' [mode] type} ')'\n# type = word {'|' word}\n# mode = 'capture' | 'template' | 'trial' | 'projector' | 'text'\n# `value` mode is unmarked. `constraint` is the result word for\n# residuals whose meet depends on the peer; `any` is the honest type\n# where a function is a wrapper.\nupper(s: string|number) : string\nlower(s: string|number) : string\ncopy(v: any) : any\npref(v: any) : any\nsuper(t: any) : any\ntype(t: any) : any\nhide(v: any) : any\nclose(m: any) : any\nopen(m: any) : any\nmove(v: any) : any\npath(capture p?: path) : path\nmap() : map\nlist() : list\nmin(n: number|string) : constraint\nmax(n: number|string) : constraint\nabove(n: number|string) : constraint\nbelow(n: number|string) : constraint\nre(text p: string) : constraint\nlength(n: number|constraint) : constraint\nkey(up?: integer|biginteger) : string\nunique(projector k?: string) : constraint\nneq(...vals: number|string) : constraint\nmust(trial c: any, text msg: string) : constraint\ndeprecate(v: any, r?: map) : any\nacyclic() : constraint\ninverse(projector k: string) : constraint\nrefer(template t?: any) : constraint\nrel(template t?: any) : constraint\npack(d: map|list, template t: any) : map\neach(d: map|list, template t?: any) : list\nfilter(d: map|list, trial c: any) : map|list\nmatch(s: any, ...pr: (trial any, any), dflt?: any) : any\nadd(a: number, b: number) : number\nsub(a: number, b: number) : number\nmul(a: number, b: number) : number\ndiv(a: number, b: number) : number\nmod(a: number, b: number) : number\nrem(a: number, b: number) : number\nsum(d: map|list) : number\nleast(d: map|list) : number\ngreatest(d: map|list) : number\npick(d: map|list, projector k: string|integer) : any\njoin(d: map|list, sep?: string) : string\n"
|
|
9
|
+
"# The call surface: one declaration line per built-in function\n# (docs/design/SIGNATURES.0.md). THIS FILE IS THE SOURCE — both ports\n# carry a build-time-inlined copy (ts/src/sigdecl.ts, go/sigdecl.txt;\n# `make sig` regenerates both, and each port's suite asserts its copy\n# is byte-identical with this file) and parse it at initialisation\n# with the signature grammar, a tabnas grammar (ts/src/sig.ts,\n# go/sig.go). The suites also round-trip every line:\n# render(parse(line)) must be the line exactly, in both ports.\n#\n# The syntax (rendered TypeScript-ish, honest about argument MODES):\n# line = name '(' [ arg {',' arg} ] ')' ':' type\n# arg = [mode] name ['?'] ':' type\n# | '...' name ':' '(' [mode] type {',' [mode] type} ')'\n# type = word {'|' word}\n# mode = 'capture' | 'template' | 'trial' | 'projector' | 'text'\n# `value` mode is unmarked. `constraint` is the result word for\n# residuals whose meet depends on the peer; `any` is the honest type\n# where a function is a wrapper.\nupper(s: string|number) : string\nlower(s: string|number) : string\ncopy(v: any) : any\npref(v: any) : any\nsuper(t: any) : any\ntype(t: any) : any\nhide(v: any) : any\nclose(m: any) : any\nopen(m: any) : any\nmove(v: any) : any\npath(capture p?: path) : path\nmap() : map\nlist() : list\nmin(n: number|string) : constraint\nmax(n: number|string) : constraint\nabove(n: number|string) : constraint\nbelow(n: number|string) : constraint\nre(text p: string) : constraint\nlength(n: number|constraint) : constraint\nkey(up?: integer|biginteger) : string\nunique(projector k?: string) : constraint\nneq(...vals: number|string) : constraint\nmust(trial c: any, text msg: string) : constraint\ndeprecate(v: any, r?: map) : any\nacyclic() : constraint\ninverse(projector k: string) : constraint\nrefer(template t?: any) : constraint\nrel(template t?: any) : constraint\npack(d: map|list, template t: any) : map\neach(d: map|list, template t?: any) : list\nfilter(d: map|list, trial c: any) : map|list\nmatch(s: any, ...pr: (trial any, any), dflt?: any) : any\nadd(a: number, b: number) : number\nsub(a: number, b: number) : number\nmul(a: number, b: number) : number\ndiv(a: number, b: number) : number\nmod(a: number, b: number) : number\nrem(a: number, b: number) : number\nsum(d: map|list) : number\nleast(d: map|list) : number\ngreatest(d: map|list) : number\npick(d: map|list, projector k: string|integer) : any\njoin(d: map|list, sep?: string) : string\nesc(s: string, variant?: string) : string\nusc(s: string, variant?: string) : string\nrep(s: string, text p: string, text sub: string) : string\nsplit(s: string, sep: string|constraint) : list\nemit(s: map|list, template t: map|list) : list\n"
|
|
10
10
|
|
|
11
11
|
export { SIGDECL }
|
package/src/val/EachFuncVal.ts
CHANGED
|
@@ -86,9 +86,7 @@ class EachFuncVal extends FuncBaseVal {
|
|
|
86
86
|
// ONE argument is driven: the data. The template is not (see
|
|
87
87
|
// prepare above), and driveStagedArgs answers whether the data has
|
|
88
88
|
// settled -- the other half of "ready to fire".
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (!ready || !ctx.settle) {
|
|
89
|
+
if (!this.stagedReady(peer, ctx, 1)) {
|
|
92
90
|
return this.residuate(peer, ctx)
|
|
93
91
|
}
|
|
94
92
|
|