tutuca 0.9.93 → 0.9.94
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/tutuca-cli.js +230 -59
- package/dist/tutuca-dev.ext.js +1362 -1199
- package/dist/tutuca-dev.js +1362 -1199
- package/dist/tutuca-dev.min.js +2 -2
- package/dist/tutuca-extra.ext.js +186 -52
- package/dist/tutuca-extra.js +187 -53
- package/dist/tutuca-extra.min.js +1 -1
- package/dist/tutuca-storybook.js +69 -11
- package/dist/tutuca.ext.js +186 -52
- package/dist/tutuca.js +187 -53
- package/dist/tutuca.min.js +1 -1
- package/package.json +2 -1
- package/skill/tutuca/core.md +10 -1
- package/skill/tutuca/storybook.md +46 -0
- package/skill/tutuca/testing.md +33 -0
- package/skill/tutuca-source/tutuca.ext.js +186 -52
package/dist/tutuca-dev.js
CHANGED
|
@@ -13451,1386 +13451,1546 @@ class LintParseContext extends ParseContext {
|
|
|
13451
13451
|
}
|
|
13452
13452
|
}
|
|
13453
13453
|
|
|
13454
|
-
//
|
|
13455
|
-
class
|
|
13456
|
-
constructor(
|
|
13457
|
-
this.
|
|
13458
|
-
this.
|
|
13459
|
-
this.counts = counts;
|
|
13460
|
-
this.warnings = warnings;
|
|
13461
|
-
}
|
|
13462
|
-
}
|
|
13463
|
-
|
|
13464
|
-
class ComponentSummary {
|
|
13465
|
-
constructor({ name, views, fields }) {
|
|
13466
|
-
this.name = name;
|
|
13467
|
-
this.views = views;
|
|
13468
|
-
this.fields = fields;
|
|
13469
|
-
}
|
|
13470
|
-
}
|
|
13471
|
-
|
|
13472
|
-
class ComponentList {
|
|
13473
|
-
constructor({ items, total = null, truncated = false }) {
|
|
13474
|
-
this.items = items;
|
|
13475
|
-
this.total = total ?? items.length;
|
|
13476
|
-
this.truncated = truncated;
|
|
13454
|
+
// src/components.js
|
|
13455
|
+
class Components {
|
|
13456
|
+
constructor() {
|
|
13457
|
+
this.getComponentSymbol = Symbol("getComponent");
|
|
13458
|
+
this.byId = new Map;
|
|
13477
13459
|
}
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
constructor({ sections, total = null, truncated = false }) {
|
|
13482
|
-
this.sections = sections;
|
|
13483
|
-
this.total = total ?? sections.reduce((n, s) => n + (s.items?.length ?? 0), 0);
|
|
13484
|
-
this.truncated = truncated;
|
|
13460
|
+
registerComponent(comp) {
|
|
13461
|
+
comp.Class.prototype[this.getComponentSymbol] = () => comp;
|
|
13462
|
+
this.byId.set(comp.id, comp);
|
|
13485
13463
|
}
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
class ComponentDocs {
|
|
13489
|
-
constructor({ items }) {
|
|
13490
|
-
this.items = items;
|
|
13464
|
+
getComponentForId(id) {
|
|
13465
|
+
return this.byId.get(id) ?? null;
|
|
13491
13466
|
}
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
class LintFinding {
|
|
13495
|
-
constructor({ id, level, info, context = {}, suggestion = null }) {
|
|
13496
|
-
this.id = id;
|
|
13497
|
-
this.level = level;
|
|
13498
|
-
this.info = info;
|
|
13499
|
-
this.context = context;
|
|
13500
|
-
this.suggestion = suggestion;
|
|
13467
|
+
getCompFor(v) {
|
|
13468
|
+
return v?.[this.getComponentSymbol]?.() ?? null;
|
|
13501
13469
|
}
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
class LintComponentResult {
|
|
13505
|
-
constructor({ componentName, findings }) {
|
|
13506
|
-
this.componentName = componentName;
|
|
13507
|
-
this.findings = findings;
|
|
13470
|
+
getHandlerFor(v, name, key) {
|
|
13471
|
+
return this.getCompFor(v)?.[key][name] ?? null;
|
|
13508
13472
|
}
|
|
13509
|
-
|
|
13510
|
-
return this.
|
|
13473
|
+
getRequestFor(v, name) {
|
|
13474
|
+
return this.getCompFor(v)?.scope.lookupRequest(name) ?? null;
|
|
13511
13475
|
}
|
|
13512
|
-
|
|
13513
|
-
|
|
13476
|
+
compileStyles() {
|
|
13477
|
+
const styles2 = [];
|
|
13478
|
+
for (const comp of this.byId.values())
|
|
13479
|
+
styles2.push(comp.compileStyle());
|
|
13480
|
+
return styles2.join(`
|
|
13481
|
+
`);
|
|
13514
13482
|
}
|
|
13515
13483
|
}
|
|
13516
13484
|
|
|
13517
|
-
class
|
|
13518
|
-
constructor(
|
|
13519
|
-
this.
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13485
|
+
class ComponentStack {
|
|
13486
|
+
constructor(comps = new Components, parent = null) {
|
|
13487
|
+
this.comps = comps;
|
|
13488
|
+
this.parent = parent;
|
|
13489
|
+
this.byName = {};
|
|
13490
|
+
this.reqsByName = {};
|
|
13491
|
+
this.macros = {};
|
|
13523
13492
|
}
|
|
13524
|
-
|
|
13525
|
-
return this.
|
|
13493
|
+
enter() {
|
|
13494
|
+
return new ComponentStack(this.comps, this);
|
|
13526
13495
|
}
|
|
13527
|
-
|
|
13528
|
-
|
|
13496
|
+
registerComponents(comps, opts) {
|
|
13497
|
+
const { aliases: aliases2 = {} } = opts ?? {};
|
|
13498
|
+
for (let i = 0;i < comps.length; i++) {
|
|
13499
|
+
const comp = comps[i];
|
|
13500
|
+
comp.scope = this.enter();
|
|
13501
|
+
comp.Class.scope = comp.scope;
|
|
13502
|
+
this.comps.registerComponent(comp);
|
|
13503
|
+
this.byName[comp.name] = comp;
|
|
13504
|
+
}
|
|
13505
|
+
for (const alias in aliases2) {
|
|
13506
|
+
const comp = this.byName[aliases2[alias]];
|
|
13507
|
+
console.assert(this.byName[alias] === undefined, "alias overrides component", alias);
|
|
13508
|
+
if (comp !== undefined)
|
|
13509
|
+
this.byName[alias] = comp;
|
|
13510
|
+
else
|
|
13511
|
+
console.warn("alias", alias, "to inexistent component", aliases2[alias]);
|
|
13512
|
+
}
|
|
13529
13513
|
}
|
|
13530
|
-
|
|
13531
|
-
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
this.componentName = componentName;
|
|
13537
|
-
this.view = view;
|
|
13538
|
-
this.html = html;
|
|
13539
|
-
this.error = error;
|
|
13514
|
+
registerMacros(macros) {
|
|
13515
|
+
for (const key in macros) {
|
|
13516
|
+
const lower = key.toLowerCase();
|
|
13517
|
+
console.assert(this.macros[lower] === undefined, "macro key collision", lower);
|
|
13518
|
+
this.macros[lower] = macros[key];
|
|
13519
|
+
}
|
|
13540
13520
|
}
|
|
13541
|
-
|
|
13542
|
-
|
|
13543
|
-
class RenderedSection {
|
|
13544
|
-
constructor({ title, description = null, items }) {
|
|
13545
|
-
this.title = title;
|
|
13546
|
-
this.description = description;
|
|
13547
|
-
this.items = items;
|
|
13521
|
+
getCompFor(v) {
|
|
13522
|
+
return this.comps.getCompFor(v);
|
|
13548
13523
|
}
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
constructor({ sections }) {
|
|
13553
|
-
this.sections = sections;
|
|
13524
|
+
registerRequestHandlers(handlers) {
|
|
13525
|
+
for (const name in handlers)
|
|
13526
|
+
this.reqsByName[name] = new RequestHandler(name, handlers[name]);
|
|
13554
13527
|
}
|
|
13555
|
-
|
|
13556
|
-
return this.
|
|
13528
|
+
lookupRequest(name) {
|
|
13529
|
+
return this.reqsByName[name] ?? this.parent?.lookupRequest(name) ?? null;
|
|
13557
13530
|
}
|
|
13558
|
-
|
|
13559
|
-
|
|
13560
|
-
class TestResult {
|
|
13561
|
-
constructor({ title, fullPath, componentName = null, status, durationMs = 0, error = null }) {
|
|
13562
|
-
this.title = title;
|
|
13563
|
-
this.fullPath = fullPath;
|
|
13564
|
-
this.componentName = componentName;
|
|
13565
|
-
this.status = status;
|
|
13566
|
-
this.durationMs = durationMs;
|
|
13567
|
-
this.error = error;
|
|
13531
|
+
lookupComponent(name) {
|
|
13532
|
+
return this.byName[name] ?? this.parent?.lookupComponent(name) ?? null;
|
|
13568
13533
|
}
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
class DescribeResult {
|
|
13572
|
-
constructor({ title, componentName = null, children = [] }) {
|
|
13573
|
-
this.title = title;
|
|
13574
|
-
this.componentName = componentName;
|
|
13575
|
-
this.children = children;
|
|
13534
|
+
lookupMacro(name) {
|
|
13535
|
+
return this.macros[name] ?? this.parent?.lookupMacro(name) ?? null;
|
|
13576
13536
|
}
|
|
13577
13537
|
}
|
|
13578
13538
|
|
|
13579
|
-
class
|
|
13580
|
-
constructor(
|
|
13581
|
-
this.
|
|
13582
|
-
this.
|
|
13583
|
-
this.
|
|
13539
|
+
class ProvideInfo {
|
|
13540
|
+
constructor(name, val, symbol) {
|
|
13541
|
+
this.name = name;
|
|
13542
|
+
this.val = val;
|
|
13543
|
+
this.symbol = symbol;
|
|
13584
13544
|
}
|
|
13585
13545
|
}
|
|
13586
13546
|
|
|
13587
|
-
class
|
|
13588
|
-
constructor(
|
|
13589
|
-
this.
|
|
13590
|
-
|
|
13591
|
-
|
|
13592
|
-
|
|
13593
|
-
|
|
13594
|
-
fail: acc.fail + m.counts.fail,
|
|
13595
|
-
skip: acc.skip + m.counts.skip,
|
|
13596
|
-
total: acc.total + m.counts.total
|
|
13597
|
-
}), { pass: 0, fail: 0, skip: 0, total: 0 });
|
|
13547
|
+
class LookupInfo {
|
|
13548
|
+
constructor(name, compName, provideName, val) {
|
|
13549
|
+
this.name = name;
|
|
13550
|
+
this.compName = compName;
|
|
13551
|
+
this.provideName = provideName;
|
|
13552
|
+
this.val = val;
|
|
13553
|
+
this._sym = undefined;
|
|
13598
13554
|
}
|
|
13599
|
-
|
|
13600
|
-
|
|
13555
|
+
getProducerSymbol(stack) {
|
|
13556
|
+
if (this._sym === undefined)
|
|
13557
|
+
this._sym = stack.lookupType(this.compName)?.provide?.[this.provideName]?.symbol ?? null;
|
|
13558
|
+
return this._sym;
|
|
13601
13559
|
}
|
|
13602
13560
|
}
|
|
13561
|
+
var isString = (v) => typeof v === "string";
|
|
13562
|
+
var _rawSpecKeys = "name view style commonStyle globalStyle input receive bubble response alter views provide lookup fields methods statics";
|
|
13563
|
+
var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
13564
|
+
var _compId = 0;
|
|
13603
13565
|
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
this.
|
|
13608
|
-
this.
|
|
13609
|
-
this.
|
|
13610
|
-
this.
|
|
13566
|
+
class Component {
|
|
13567
|
+
constructor(Class, o) {
|
|
13568
|
+
this.id = _compId++;
|
|
13569
|
+
this.name = o.name ?? "UnkComp";
|
|
13570
|
+
this.Class = Class;
|
|
13571
|
+
this.views = { main: new View("main", o.view, o.style) };
|
|
13572
|
+
this.commonStyle = o.commonStyle ?? "";
|
|
13573
|
+
this.globalStyle = o.globalStyle ?? "";
|
|
13574
|
+
this.input = o.input ?? {};
|
|
13575
|
+
this.receive = o.receive ?? {};
|
|
13576
|
+
this.bubble = o.bubble ?? {};
|
|
13577
|
+
this.response = o.response ?? {};
|
|
13578
|
+
this.alter = o.alter ?? {};
|
|
13579
|
+
for (const name in o.views ?? {}) {
|
|
13580
|
+
const v = o.views[name];
|
|
13581
|
+
const { view, style } = isString(v) ? { view: v } : v;
|
|
13582
|
+
this.views[name] = new View(name, view, style);
|
|
13583
|
+
}
|
|
13584
|
+
this._rawProvide = o.provide ?? {};
|
|
13585
|
+
this._rawLookup = o.lookup ?? {};
|
|
13586
|
+
this.provide = {};
|
|
13587
|
+
this.lookup = {};
|
|
13588
|
+
this.scope = null;
|
|
13589
|
+
this.spec = o;
|
|
13590
|
+
this.extra = {};
|
|
13591
|
+
for (const key of Object.keys(o))
|
|
13592
|
+
if (!KNOWN_SPEC_KEYS.has(key))
|
|
13593
|
+
this.extra[key] = o[key];
|
|
13611
13594
|
}
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
class Test {
|
|
13615
|
-
constructor({ title, fn, componentName = null, parent = null }) {
|
|
13616
|
-
this.title = title;
|
|
13617
|
-
this.fn = fn;
|
|
13618
|
-
this.componentName = componentName;
|
|
13619
|
-
this.parent = parent;
|
|
13595
|
+
clone() {
|
|
13596
|
+
return Component.fromSpec(this.spec);
|
|
13620
13597
|
}
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
this.
|
|
13626
|
-
|
|
13598
|
+
compile(ParseContext2) {
|
|
13599
|
+
for (const name in this.views)
|
|
13600
|
+
this.views[name].compile(new ParseContext2, this.scope, this.id);
|
|
13601
|
+
const ctx = this.views.main.ctx;
|
|
13602
|
+
for (const key in this._rawProvide) {
|
|
13603
|
+
const val = vp.parseProvide(this._rawProvide[key], ctx);
|
|
13604
|
+
if (val)
|
|
13605
|
+
this.provide[key] = new ProvideInfo(key, val, Symbol(key));
|
|
13606
|
+
}
|
|
13607
|
+
for (const key in this._rawLookup) {
|
|
13608
|
+
const linfo = this._rawLookup[key];
|
|
13609
|
+
const forStr = isString(linfo) ? linfo : isString(linfo?.for) ? linfo.for : null;
|
|
13610
|
+
const [compName, provideName] = forStr === null ? [] : forStr.split(".");
|
|
13611
|
+
if (!isString(compName) || !isString(provideName))
|
|
13612
|
+
continue;
|
|
13613
|
+
const defStr = isString(linfo?.default) ? linfo.default : null;
|
|
13614
|
+
const val = defStr === null ? null : vp.parseField(defStr, ctx);
|
|
13615
|
+
this.lookup[key] = new LookupInfo(key, compName, provideName, val);
|
|
13616
|
+
}
|
|
13617
|
+
for (const key in this.lookup)
|
|
13618
|
+
if (this.provide[key] !== undefined)
|
|
13619
|
+
console.warn("name declared in both provide and lookup", this.name, key);
|
|
13620
|
+
}
|
|
13621
|
+
make(args, opts) {
|
|
13622
|
+
return this.Class.make(args, opts ?? { scope: this.scope });
|
|
13623
|
+
}
|
|
13624
|
+
getView(name) {
|
|
13625
|
+
return this.views[name] ?? this.views.main;
|
|
13626
|
+
}
|
|
13627
|
+
getEventForId(id, name = "main") {
|
|
13628
|
+
return this.getView(name).ctx.getEventForId(id);
|
|
13629
|
+
}
|
|
13630
|
+
getNodeForId(id, name = "main") {
|
|
13631
|
+
return this.getView(name).ctx.getNodeForId(id);
|
|
13632
|
+
}
|
|
13633
|
+
compileStyle() {
|
|
13634
|
+
const { id, commonStyle, globalStyle, views } = this;
|
|
13635
|
+
const styles2 = commonStyle ? [`[data-cid="${id}"]{${commonStyle}}`] : [];
|
|
13636
|
+
if (globalStyle !== "")
|
|
13637
|
+
styles2.push(globalStyle);
|
|
13638
|
+
for (const name in views) {
|
|
13639
|
+
const { style } = views[name];
|
|
13640
|
+
if (style !== "")
|
|
13641
|
+
styles2.push(`[data-cid="${id}"][data-vid="${name}"]{${style}}`);
|
|
13642
|
+
}
|
|
13643
|
+
return styles2.join(`
|
|
13644
|
+
`);
|
|
13627
13645
|
}
|
|
13628
13646
|
}
|
|
13629
13647
|
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13648
|
+
// src/on.js
|
|
13649
|
+
var OP_KINDS = ["send", "bubble", "request", "input"];
|
|
13650
|
+
function phaseOps(phase) {
|
|
13651
|
+
const ops = [];
|
|
13652
|
+
for (const type3 of OP_KINDS)
|
|
13653
|
+
for (const a of phase[type3] ?? [])
|
|
13654
|
+
ops.push({ type: type3, ...a });
|
|
13655
|
+
for (const a of phase.do ?? [])
|
|
13656
|
+
ops.push(a);
|
|
13657
|
+
return ops;
|
|
13634
13658
|
}
|
|
13635
|
-
function
|
|
13636
|
-
return
|
|
13659
|
+
function resolveArgs(args, self) {
|
|
13660
|
+
return typeof args === "function" ? args(self) ?? [] : args ?? [];
|
|
13637
13661
|
}
|
|
13638
|
-
function
|
|
13639
|
-
if (
|
|
13640
|
-
return
|
|
13641
|
-
|
|
13642
|
-
|
|
13643
|
-
|
|
13644
|
-
|
|
13662
|
+
function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
13663
|
+
if (!phase)
|
|
13664
|
+
return;
|
|
13665
|
+
for (const op of phaseOps(phase)) {
|
|
13666
|
+
const args = resolveArgs(op.args, self);
|
|
13667
|
+
switch (op.type) {
|
|
13668
|
+
case "send":
|
|
13669
|
+
dispatcher.sendAtPath(targetPath, op.name, args, op.opts);
|
|
13670
|
+
break;
|
|
13671
|
+
case "bubble":
|
|
13672
|
+
dispatcher.sendAtPath(targetPath, op.name, args, {
|
|
13673
|
+
skipSelf: true,
|
|
13674
|
+
bubbles: true,
|
|
13675
|
+
...op.opts
|
|
13676
|
+
});
|
|
13677
|
+
break;
|
|
13678
|
+
case "request":
|
|
13679
|
+
dispatcher.requestAtPath(targetPath, op.name, args, op.opts);
|
|
13680
|
+
break;
|
|
13681
|
+
case "input":
|
|
13682
|
+
dispatcher.inputAtPath(targetPath, op.name, args, op.opts);
|
|
13683
|
+
break;
|
|
13684
|
+
}
|
|
13645
13685
|
}
|
|
13646
|
-
return null;
|
|
13647
13686
|
}
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13687
|
+
|
|
13688
|
+
// src/stack.js
|
|
13689
|
+
var STOP = Symbol("STOP");
|
|
13690
|
+
var NEXT = Symbol("NEXT");
|
|
13691
|
+
function lookup(chain, name, dv = null) {
|
|
13692
|
+
let n = chain;
|
|
13693
|
+
while (n !== null) {
|
|
13694
|
+
const r = n[0].lookup(name);
|
|
13695
|
+
if (r === STOP)
|
|
13696
|
+
return dv;
|
|
13697
|
+
if (r !== NEXT)
|
|
13698
|
+
return r;
|
|
13699
|
+
n = n[1];
|
|
13700
|
+
}
|
|
13701
|
+
return dv;
|
|
13656
13702
|
}
|
|
13657
|
-
|
|
13658
|
-
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
|
|
13662
|
-
|
|
13663
|
-
let fn;
|
|
13664
|
-
if (args.length === 2) {
|
|
13665
|
-
[head, fn] = args;
|
|
13666
|
-
} else if (args.length === 3) {
|
|
13667
|
-
[head, options, fn] = args;
|
|
13668
|
-
} else {
|
|
13669
|
-
throw new Error(`describe() expects 2 or 3 arguments, got ${args.length}`);
|
|
13670
|
-
}
|
|
13671
|
-
if (typeof fn !== "function") {
|
|
13672
|
-
throw new Error(`describe(${JSON.stringify(titleFromArg(head))}): final argument must be a function`);
|
|
13673
|
-
}
|
|
13674
|
-
let componentName = null;
|
|
13675
|
-
if (typeof head !== "string") {
|
|
13676
|
-
componentName = resolveComponentName(head, components);
|
|
13677
|
-
}
|
|
13678
|
-
if (componentName === null && options && options.component != null) {
|
|
13679
|
-
componentName = resolveComponentName(options.component, components);
|
|
13680
|
-
}
|
|
13681
|
-
if (componentName === null) {
|
|
13682
|
-
const parent2 = stack.length ? stack[stack.length - 1] : null;
|
|
13683
|
-
if (parent2)
|
|
13684
|
-
componentName = parent2.componentName;
|
|
13685
|
-
}
|
|
13686
|
-
const parent = stack.length ? stack[stack.length - 1] : null;
|
|
13687
|
-
const node = new Describe({
|
|
13688
|
-
title: titleFromArg(head),
|
|
13689
|
-
componentName,
|
|
13690
|
-
parent
|
|
13691
|
-
});
|
|
13692
|
-
if (parent)
|
|
13693
|
-
parent.children.push(node);
|
|
13694
|
-
else
|
|
13695
|
-
moduleTests.suites.push(node);
|
|
13696
|
-
stack.push(node);
|
|
13697
|
-
try {
|
|
13698
|
-
fn();
|
|
13699
|
-
} finally {
|
|
13700
|
-
stack.pop();
|
|
13701
|
-
}
|
|
13703
|
+
|
|
13704
|
+
class BindFrame {
|
|
13705
|
+
constructor(it, binds, isFrame) {
|
|
13706
|
+
this.it = it;
|
|
13707
|
+
this.binds = binds;
|
|
13708
|
+
this.isFrame = isFrame;
|
|
13702
13709
|
}
|
|
13703
|
-
|
|
13704
|
-
|
|
13705
|
-
|
|
13706
|
-
}
|
|
13707
|
-
if (typeof fn !== "function") {
|
|
13708
|
-
throw new Error(`test(${JSON.stringify(title)}): fn must be a function`);
|
|
13709
|
-
}
|
|
13710
|
-
const parent = stack.length ? stack[stack.length - 1] : null;
|
|
13711
|
-
if (!parent) {
|
|
13712
|
-
throw new Error(`test(${JSON.stringify(title)}) must be called inside a describe()`);
|
|
13713
|
-
}
|
|
13714
|
-
parent.children.push(new Test({
|
|
13715
|
-
title,
|
|
13716
|
-
fn,
|
|
13717
|
-
componentName: parent.componentName,
|
|
13718
|
-
parent
|
|
13719
|
-
}));
|
|
13710
|
+
lookup(name) {
|
|
13711
|
+
const v = this.binds[name];
|
|
13712
|
+
return v === undefined ? this.isFrame ? STOP : NEXT : v;
|
|
13720
13713
|
}
|
|
13721
|
-
return { describe, test: test2, moduleTests };
|
|
13722
13714
|
}
|
|
13723
13715
|
|
|
13724
|
-
|
|
13725
|
-
|
|
13726
|
-
|
|
13727
|
-
|
|
13728
|
-
|
|
13729
|
-
|
|
13730
|
-
|
|
13716
|
+
class ObjectFrame {
|
|
13717
|
+
constructor(binds) {
|
|
13718
|
+
this.binds = binds;
|
|
13719
|
+
}
|
|
13720
|
+
lookup(key) {
|
|
13721
|
+
const v = this.binds[key];
|
|
13722
|
+
return v === undefined ? NEXT : v;
|
|
13731
13723
|
}
|
|
13732
|
-
return parts.join(" > ");
|
|
13733
13724
|
}
|
|
13734
|
-
function
|
|
13735
|
-
|
|
13736
|
-
|
|
13737
|
-
|
|
13738
|
-
|
|
13739
|
-
|
|
13740
|
-
|
|
13725
|
+
function computeViewsId(views) {
|
|
13726
|
+
let s = "";
|
|
13727
|
+
let n = views;
|
|
13728
|
+
while (n !== null) {
|
|
13729
|
+
s += n[0];
|
|
13730
|
+
n = n[1];
|
|
13731
|
+
}
|
|
13732
|
+
return s === "main" ? "" : s;
|
|
13741
13733
|
}
|
|
13742
|
-
|
|
13743
|
-
|
|
13744
|
-
|
|
13745
|
-
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
13749
|
-
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
if (typeof getTests !== "function") {
|
|
13753
|
-
return new TestReport({
|
|
13754
|
-
modules: [new ModuleTestReport({ path, suites: [], counts })]
|
|
13755
|
-
});
|
|
13734
|
+
|
|
13735
|
+
class Stack2 {
|
|
13736
|
+
constructor(comps, it, binds, dynBinds, views, viewsId, ctx = null) {
|
|
13737
|
+
this.comps = comps;
|
|
13738
|
+
this.it = it;
|
|
13739
|
+
this.binds = binds;
|
|
13740
|
+
this.dynBinds = dynBinds;
|
|
13741
|
+
this.views = views;
|
|
13742
|
+
this.viewsId = viewsId;
|
|
13743
|
+
this.ctx = ctx;
|
|
13756
13744
|
}
|
|
13757
|
-
|
|
13758
|
-
|
|
13745
|
+
_pushProvides() {
|
|
13746
|
+
const provide = this.comps.getCompFor(this.it)?.provide;
|
|
13747
|
+
if (provide == null)
|
|
13748
|
+
return this;
|
|
13749
|
+
const dynObj = {};
|
|
13750
|
+
let has2 = false;
|
|
13751
|
+
for (const k in provide) {
|
|
13752
|
+
dynObj[provide[k].symbol] = provide[k].val.eval(this);
|
|
13753
|
+
has2 = true;
|
|
13754
|
+
}
|
|
13755
|
+
if (!has2)
|
|
13756
|
+
return this;
|
|
13757
|
+
const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
|
|
13758
|
+
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
13759
|
+
return new Stack2(comps, it, binds, newDynBinds, views, viewsId, ctx);
|
|
13759
13760
|
}
|
|
13760
|
-
|
|
13761
|
-
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13766
|
-
|
|
13767
|
-
|
|
13768
|
-
|
|
13769
|
-
|
|
13770
|
-
|
|
13771
|
-
|
|
13772
|
-
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
|
|
13776
|
-
|
|
13777
|
-
|
|
13778
|
-
|
|
13779
|
-
|
|
13780
|
-
|
|
13781
|
-
|
|
13782
|
-
|
|
13783
|
-
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
|
|
13792
|
-
|
|
13793
|
-
if (bail)
|
|
13794
|
-
bailed = true;
|
|
13795
|
-
return new TestResult({
|
|
13796
|
-
title: node.title,
|
|
13797
|
-
fullPath,
|
|
13798
|
-
componentName: node.componentName,
|
|
13799
|
-
status: "fail",
|
|
13800
|
-
durationMs: performance.now() - start,
|
|
13801
|
-
error: captureError(e)
|
|
13802
|
-
});
|
|
13803
|
-
}
|
|
13804
|
-
}
|
|
13805
|
-
const childResults = [];
|
|
13806
|
-
for (const child of node.children) {
|
|
13807
|
-
const r = await visit(child);
|
|
13808
|
-
if (r !== null)
|
|
13809
|
-
childResults.push(r);
|
|
13810
|
-
}
|
|
13811
|
-
if (childResults.length === 0)
|
|
13761
|
+
static root(comps, it, ctx) {
|
|
13762
|
+
const binds = [new BindFrame(it, { it }, true), null];
|
|
13763
|
+
const dynBinds = [new ObjectFrame({}), null];
|
|
13764
|
+
const views = ["main", null];
|
|
13765
|
+
return new Stack2(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();
|
|
13766
|
+
}
|
|
13767
|
+
enter(it, bindings = {}, isFrame = true) {
|
|
13768
|
+
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
13769
|
+
const newBinds = [new BindFrame(it, bindings, isFrame), binds];
|
|
13770
|
+
const stack = new Stack2(comps, it, newBinds, dynBinds, views, viewsId, ctx);
|
|
13771
|
+
return isFrame ? stack._pushProvides() : stack;
|
|
13772
|
+
}
|
|
13773
|
+
pushViewName(name) {
|
|
13774
|
+
const { comps, it, binds, dynBinds, views, ctx } = this;
|
|
13775
|
+
const newViews = [name, views];
|
|
13776
|
+
return new Stack2(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
13777
|
+
}
|
|
13778
|
+
_pushDynBindValuesToArray(arr, comp) {
|
|
13779
|
+
for (const k in comp.provide)
|
|
13780
|
+
arr.push(this._lookupProvide(comp.provide[k]));
|
|
13781
|
+
for (const k in comp.lookup)
|
|
13782
|
+
arr.push(this._lookupAlias(comp.lookup[k]));
|
|
13783
|
+
}
|
|
13784
|
+
_lookupProvide(p) {
|
|
13785
|
+
return lookup(this.dynBinds, p.symbol) ?? p.val.eval(this) ?? null;
|
|
13786
|
+
}
|
|
13787
|
+
_lookupAlias(lk) {
|
|
13788
|
+
const sym = lk.getProducerSymbol(this);
|
|
13789
|
+
return (sym != null ? lookup(this.dynBinds, sym) : null) ?? lk.val?.eval(this) ?? null;
|
|
13790
|
+
}
|
|
13791
|
+
lookupDynamic(name) {
|
|
13792
|
+
const comp = this.comps.getCompFor(this.it);
|
|
13793
|
+
if (comp == null)
|
|
13812
13794
|
return null;
|
|
13813
|
-
|
|
13814
|
-
|
|
13815
|
-
|
|
13816
|
-
|
|
13817
|
-
|
|
13795
|
+
const lk = comp.lookup[name];
|
|
13796
|
+
if (lk !== undefined)
|
|
13797
|
+
return this._lookupAlias(lk);
|
|
13798
|
+
const p = comp.provide[name];
|
|
13799
|
+
return p !== undefined ? this._lookupProvide(p) : null;
|
|
13818
13800
|
}
|
|
13819
|
-
|
|
13820
|
-
|
|
13821
|
-
const r = await visit(suite);
|
|
13822
|
-
if (r !== null)
|
|
13823
|
-
suiteResults.push(r);
|
|
13801
|
+
lookupBind(name) {
|
|
13802
|
+
return lookup(this.binds, name);
|
|
13824
13803
|
}
|
|
13825
|
-
|
|
13826
|
-
|
|
13827
|
-
});
|
|
13828
|
-
}
|
|
13829
|
-
|
|
13830
|
-
// tools/core/test-console.js
|
|
13831
|
-
var PASS = "color: #0a0; font-weight: bold";
|
|
13832
|
-
var FAIL = "color: #c00; font-weight: bold";
|
|
13833
|
-
var SKIP = "color: #888";
|
|
13834
|
-
var DIM = "color: #888";
|
|
13835
|
-
var RESET = "color: inherit; font-weight: normal";
|
|
13836
|
-
function reportTestNode(node) {
|
|
13837
|
-
if (node.children) {
|
|
13838
|
-
const label = node.componentName ? `${node.title} [${node.componentName}]` : node.title;
|
|
13839
|
-
console.group(label);
|
|
13840
|
-
for (const child of node.children)
|
|
13841
|
-
reportTestNode(child);
|
|
13842
|
-
console.groupEnd();
|
|
13843
|
-
return;
|
|
13804
|
+
lookupType(name) {
|
|
13805
|
+
return this.comps.getCompFor(this.it).scope.lookupComponent(name);
|
|
13844
13806
|
}
|
|
13845
|
-
|
|
13846
|
-
|
|
13847
|
-
console.log(`%c✓%c ${node.title}%c${dur}`, PASS, RESET, DIM);
|
|
13848
|
-
} else if (node.status === "skip") {
|
|
13849
|
-
console.log(`%c○ ${node.title}%c (skipped)`, SKIP, RESET);
|
|
13850
|
-
} else {
|
|
13851
|
-
console.group(`%c✗%c ${node.title}%c${dur}`, FAIL, RESET, DIM);
|
|
13852
|
-
console.error(node.error?.message ?? "(no error message)");
|
|
13853
|
-
if (node.error && (("expected" in node.error) || ("actual" in node.error))) {
|
|
13854
|
-
console.log("expected:", node.error.expected);
|
|
13855
|
-
console.log("actual: ", node.error.actual);
|
|
13856
|
-
}
|
|
13857
|
-
if (node.error?.stack)
|
|
13858
|
-
console.log(node.error.stack);
|
|
13859
|
-
console.groupEnd();
|
|
13807
|
+
lookupFieldRaw(name) {
|
|
13808
|
+
return this.it[name] ?? null;
|
|
13860
13809
|
}
|
|
13861
|
-
|
|
13862
|
-
|
|
13863
|
-
|
|
13864
|
-
|
|
13865
|
-
|
|
13866
|
-
|
|
13867
|
-
|
|
13868
|
-
|
|
13869
|
-
|
|
13870
|
-
|
|
13810
|
+
lookupMethod(name) {
|
|
13811
|
+
const fn = this.it[name];
|
|
13812
|
+
return fn instanceof Function ? fn.call(this.it) : null;
|
|
13813
|
+
}
|
|
13814
|
+
lookupName(name) {
|
|
13815
|
+
return this.ctx.lookupName(name);
|
|
13816
|
+
}
|
|
13817
|
+
getHandlerFor(name, key) {
|
|
13818
|
+
return this.comps.getHandlerFor(this.it, name, key);
|
|
13819
|
+
}
|
|
13820
|
+
lookupRequest(name) {
|
|
13821
|
+
return this.comps.getRequestFor(this.it, name);
|
|
13822
|
+
}
|
|
13823
|
+
lookupBestView(views, defaultViewName) {
|
|
13824
|
+
let n = this.views;
|
|
13825
|
+
while (n !== null) {
|
|
13826
|
+
const view = views[n[0]];
|
|
13827
|
+
if (view !== undefined)
|
|
13828
|
+
return view;
|
|
13829
|
+
n = n[1];
|
|
13871
13830
|
}
|
|
13872
|
-
|
|
13873
|
-
const summary = `${c.pass} passed, ${c.fail} failed, ${c.skip} skipped (${c.total} total)`;
|
|
13874
|
-
if (c.fail > 0)
|
|
13875
|
-
console.error(`%c${summary}`, FAIL);
|
|
13876
|
-
else if (c.total === 0)
|
|
13877
|
-
console.log(`%c${summary}`, DIM);
|
|
13878
|
-
else
|
|
13879
|
-
console.log(`%c${summary}`, PASS);
|
|
13880
|
-
console.groupEnd();
|
|
13831
|
+
return views[defaultViewName];
|
|
13881
13832
|
}
|
|
13882
|
-
return report;
|
|
13883
13833
|
}
|
|
13884
13834
|
|
|
13885
|
-
//
|
|
13886
|
-
|
|
13887
|
-
|
|
13888
|
-
|
|
13889
|
-
|
|
13890
|
-
"call-with-args": "method call with arguments"
|
|
13891
|
-
};
|
|
13892
|
-
function unsupportedExprMessage(info) {
|
|
13893
|
-
const v = JSON.stringify(info.value);
|
|
13894
|
-
const label = UNSUPPORTED_EXPR_LABEL[info.detected] ?? "expression";
|
|
13895
|
-
switch (info.role) {
|
|
13896
|
-
case "attr":
|
|
13897
|
-
return `Unsupported ${label} ${v} in dynamic attribute ':${info.attr}'`;
|
|
13898
|
-
case "directive":
|
|
13899
|
-
return `Unsupported ${label} ${v} in directive '@${info.directive}'`;
|
|
13900
|
-
case "if":
|
|
13901
|
-
return `Unsupported ${label} ${v} in '@if.${info.attr}' condition`;
|
|
13902
|
-
case "x-op":
|
|
13903
|
-
return `Unsupported ${label} ${v} in <x ${info.op}>`;
|
|
13904
|
-
default:
|
|
13905
|
-
return `Unsupported ${label} ${v}`;
|
|
13835
|
+
// src/transactor.js
|
|
13836
|
+
class State2 {
|
|
13837
|
+
constructor(val) {
|
|
13838
|
+
this.val = val;
|
|
13839
|
+
this.changeSubs = [];
|
|
13906
13840
|
}
|
|
13907
|
-
|
|
13908
|
-
|
|
13909
|
-
const v = JSON.stringify(info.value);
|
|
13910
|
-
switch (info.role) {
|
|
13911
|
-
case "attr":
|
|
13912
|
-
return `Cannot parse value ${v} for attribute ':${info.attr}'`;
|
|
13913
|
-
case "directive":
|
|
13914
|
-
return `Cannot parse value ${v} for directive '@${info.directive}'`;
|
|
13915
|
-
case "if":
|
|
13916
|
-
return `Cannot parse condition ${v} for '@if.${info.attr}'`;
|
|
13917
|
-
case "x-op":
|
|
13918
|
-
return `Cannot parse value ${v} for <x ${info.op}>`;
|
|
13919
|
-
case "handler-name":
|
|
13920
|
-
return `Cannot parse handler name ${v}`;
|
|
13921
|
-
case "handler-arg":
|
|
13922
|
-
return `Cannot parse handler argument ${v}`;
|
|
13923
|
-
case "macro-var":
|
|
13924
|
-
return `Macro variable '^${info.name}' is not defined`;
|
|
13925
|
-
default:
|
|
13926
|
-
return `Cannot parse value ${v}`;
|
|
13841
|
+
onChange(cb) {
|
|
13842
|
+
this.changeSubs.push(cb);
|
|
13927
13843
|
}
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
const t = tagDisplay(info?.tag);
|
|
13934
|
-
return t && t !== "x" ? ` on <${t}>` : "";
|
|
13935
|
-
}
|
|
13936
|
-
function fmtOriginSuffix(info) {
|
|
13937
|
-
if (!info)
|
|
13938
|
-
return "";
|
|
13939
|
-
const parts = [];
|
|
13940
|
-
if (info.originAttr) {
|
|
13941
|
-
const branch = info.branch ? `[${info.branch}]` : "";
|
|
13942
|
-
parts.push(`in ${info.originAttr}${branch}`);
|
|
13844
|
+
set(val, info) {
|
|
13845
|
+
const old = this.val;
|
|
13846
|
+
this.val = val;
|
|
13847
|
+
for (const sub of this.changeSubs)
|
|
13848
|
+
sub({ val, old, info, timestamp: Date.now() });
|
|
13943
13849
|
}
|
|
13944
|
-
|
|
13945
|
-
|
|
13850
|
+
update(fn, info) {
|
|
13851
|
+
return this.set(fn(this.val), info);
|
|
13946
13852
|
}
|
|
13947
|
-
const t = tagDisplay(info.tag);
|
|
13948
|
-
if (t && t !== "x")
|
|
13949
|
-
parts.push(`on <${t}>`);
|
|
13950
|
-
return parts.length ? ` (${parts.join(", ")})` : "";
|
|
13951
|
-
}
|
|
13952
|
-
function fmtEventSuffix(info) {
|
|
13953
|
-
if (info?.originAttr)
|
|
13954
|
-
return ` in ${info.originAttr}`;
|
|
13955
|
-
if (info?.eventName)
|
|
13956
|
-
return ` in @on.${info.eventName}`;
|
|
13957
|
-
return "";
|
|
13958
13853
|
}
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
case "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD":
|
|
13977
|
-
return `'$${info.name}' is a method reference, but '${info.name}' is defined as an input handler${fmtEventSuffix(info)}`;
|
|
13978
|
-
case "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER":
|
|
13979
|
-
return `'${info.name}' is an input handler reference, but '${info.name}' is defined as a method${fmtEventSuffix(info)}`;
|
|
13980
|
-
case "FIELD_VAL_NOT_DEFINED":
|
|
13981
|
-
return `Field '.${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
13982
|
-
case "FIELD_VAL_IS_METHOD":
|
|
13983
|
-
return `'.${info.name}' reads a field, but '${info.name}' is defined as a method — use '$${info.name}'${fmtOriginSuffix(info)}`;
|
|
13984
|
-
case "METHOD_VAL_NOT_DEFINED":
|
|
13985
|
-
return `Method '$${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
13986
|
-
case "METHOD_VAL_IS_FIELD":
|
|
13987
|
-
return `'$${info.name}' calls a method, but '${info.name}' is defined as a field — use '.${info.name}'${fmtOriginSuffix(info)}`;
|
|
13988
|
-
case "DUPLICATE_ATTR_DEFINITION": {
|
|
13989
|
-
const sources = info.sources?.length ? ` (${info.sources.join(", ")})` : "";
|
|
13990
|
-
const tag = info.tag ? ` on <${String(info.tag).toLowerCase()}>` : "";
|
|
13991
|
-
return `Attribute '${info.name}' is set ${info.sources?.length ?? "multiple"} times${sources}${tag}`;
|
|
13854
|
+
|
|
13855
|
+
class Transactor {
|
|
13856
|
+
constructor(comps, rootValue) {
|
|
13857
|
+
this.comps = comps;
|
|
13858
|
+
this.transactions = [];
|
|
13859
|
+
this.state = new State2(rootValue);
|
|
13860
|
+
this.onTransactionPushed = () => {};
|
|
13861
|
+
this._inflight = new Set;
|
|
13862
|
+
}
|
|
13863
|
+
pushTransaction(t) {
|
|
13864
|
+
this.transactions.push(t);
|
|
13865
|
+
this.onTransactionPushed(t);
|
|
13866
|
+
}
|
|
13867
|
+
_link(child, parent) {
|
|
13868
|
+
if (parent) {
|
|
13869
|
+
const release = parent.completion.track();
|
|
13870
|
+
child.completion.whenSubtreeSettled().then(release);
|
|
13992
13871
|
}
|
|
13993
|
-
|
|
13994
|
-
|
|
13995
|
-
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
|
|
14003
|
-
|
|
14004
|
-
|
|
14005
|
-
|
|
14006
|
-
|
|
14007
|
-
|
|
14008
|
-
|
|
14009
|
-
|
|
14010
|
-
|
|
14011
|
-
|
|
14012
|
-
|
|
14013
|
-
|
|
14014
|
-
|
|
14015
|
-
|
|
14016
|
-
|
|
14017
|
-
|
|
14018
|
-
|
|
14019
|
-
|
|
14020
|
-
|
|
14021
|
-
|
|
14022
|
-
|
|
14023
|
-
|
|
13872
|
+
return child;
|
|
13873
|
+
}
|
|
13874
|
+
pushSend(path, name, args = [], opts = {}, parent = null) {
|
|
13875
|
+
const t = new SendEvent(path, this, name, args, parent, opts);
|
|
13876
|
+
this.pushTransaction(t);
|
|
13877
|
+
return this._link(t, parent);
|
|
13878
|
+
}
|
|
13879
|
+
pushInput(path, name, args = [], opts = {}, parent = null) {
|
|
13880
|
+
const t = new InputDispatchEvent(path, this, name, args, parent, opts);
|
|
13881
|
+
this.pushTransaction(t);
|
|
13882
|
+
return this._link(t, parent);
|
|
13883
|
+
}
|
|
13884
|
+
pushBubble(path, name, args = [], opts = {}, parent = null, targetPath = null) {
|
|
13885
|
+
const newOpts = opts.skipSelf ? { ...opts, skipSelf: false } : opts;
|
|
13886
|
+
const t = new BubbleEvent(path, this, name, args, parent, newOpts, targetPath);
|
|
13887
|
+
this.pushTransaction(t);
|
|
13888
|
+
return this._link(t, parent);
|
|
13889
|
+
}
|
|
13890
|
+
pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
13891
|
+
const release = parent ? parent.completion.track() : null;
|
|
13892
|
+
const p = this._runRequest(path, name, args, opts, parent, release);
|
|
13893
|
+
this._inflight.add(p);
|
|
13894
|
+
p.finally(() => this._inflight.delete(p));
|
|
13895
|
+
return p;
|
|
13896
|
+
}
|
|
13897
|
+
async settle(maxTurns = 1e4) {
|
|
13898
|
+
while ((this.hasPendingTransactions || this._inflight.size) && maxTurns-- > 0) {
|
|
13899
|
+
while (this.hasPendingTransactions)
|
|
13900
|
+
this.transactNext();
|
|
13901
|
+
if (this._inflight.size)
|
|
13902
|
+
await Promise.allSettled([...this._inflight]);
|
|
13903
|
+
}
|
|
13904
|
+
}
|
|
13905
|
+
async _runRequest(path, name, args = [], opts = {}, parent = null, release = null) {
|
|
13906
|
+
let released = false;
|
|
13907
|
+
const transfer = (t) => {
|
|
13908
|
+
if (release) {
|
|
13909
|
+
released = true;
|
|
13910
|
+
t.completion.whenSubtreeSettled().then(release);
|
|
13911
|
+
}
|
|
13912
|
+
};
|
|
13913
|
+
try {
|
|
13914
|
+
const curRoot = this.state.val;
|
|
13915
|
+
const txnPath = path.toTransactionPath();
|
|
13916
|
+
const curLeaf = txnPath.lookup(curRoot);
|
|
13917
|
+
const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
|
|
13918
|
+
const reqCtx = new RequestContext(path, this, parent, curRoot);
|
|
13919
|
+
const resHandlerName = opts?.onResName ?? name;
|
|
13920
|
+
const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
|
|
13921
|
+
const push = (specificName, baseName, singleArg, result, error) => {
|
|
13922
|
+
const resArgs = specificName ? [singleArg] : [result, error];
|
|
13923
|
+
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
|
|
13924
|
+
transfer(t);
|
|
13925
|
+
this.pushTransaction(t);
|
|
13926
|
+
};
|
|
13927
|
+
try {
|
|
13928
|
+
const result = await handler.fn.apply(null, [...args, reqCtx]);
|
|
13929
|
+
push(opts?.onOkName, resHandlerName, result, result, null);
|
|
13930
|
+
} catch (error) {
|
|
13931
|
+
push(opts?.onErrorName, resHandlerName, error, null, error);
|
|
13932
|
+
}
|
|
13933
|
+
} finally {
|
|
13934
|
+
if (release && !released)
|
|
13935
|
+
release();
|
|
14024
13936
|
}
|
|
14025
|
-
case "MAYBE_ADD_AT_PREFIX":
|
|
14026
|
-
return `'${info.name}' on <${(info.tag ?? "").toLowerCase()}> is a plain attribute, but '@${info.name}' is a directive — add the leading '@'`;
|
|
14027
|
-
case "BAD_VALUE":
|
|
14028
|
-
return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
|
|
14029
|
-
case "UNSUPPORTED_EXPR_SYNTAX":
|
|
14030
|
-
return `${unsupportedExprMessage(info)}${fmtTagSuffix(info)}`;
|
|
14031
|
-
case "REDUNDANT_TEMPLATE_STRING":
|
|
14032
|
-
return `Redundant template string — '{${info.simpler}}' should be just '${info.simpler}'${fmtOriginSuffix(info)}`;
|
|
14033
|
-
case "PLACEHOLDERLESS_TEMPLATE_STRING":
|
|
14034
|
-
return `Template string has no dynamic parts — use the string literal ${info.literal} instead${fmtOriginSuffix(info)}`;
|
|
14035
|
-
case "UNKNOWN_COMPONENT_SPEC_KEY":
|
|
14036
|
-
return `Unknown component spec key '${info.key}' — value will be ignored at runtime`;
|
|
14037
|
-
case "COMP_FIELD_BAD_SHAPE":
|
|
14038
|
-
return info.kind === "args-not-object" ? `Field '${info.fieldName}': in { component, args }, 'args' must be a plain object, got ${info.got}` : `Field '${info.fieldName}': in { component, args }, 'component' must be the component name as a string, got ${info.gotName ? `the ${info.gotName} class` : info.got}`;
|
|
14039
|
-
case "HTML_TAG_NAME_HAS_UPPERCASE":
|
|
14040
|
-
return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
14041
|
-
case "HTML_SVG_TAG_WILL_LOWERCASE":
|
|
14042
|
-
return `SVG tag <${info.raw}> is not in the WHATWG case-correction list — will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
14043
|
-
case "HTML_TAG_NOT_ALLOWED_IN_PARENT":
|
|
14044
|
-
return `<${info.tag}> not allowed under <${info.parent ?? "?"}> in ${info.mode} — ${htmlActionPhrase(info.action, info.tag, info.parent)}${fmtLocationSuffix(info)}`;
|
|
14045
|
-
case "HTML_TEXT_NOT_ALLOWED_IN_PARENT":
|
|
14046
|
-
return `Non-whitespace text not allowed in ${info.mode}: ${JSON.stringify(info.snippet)}${fmtLocationSuffix(info)}`;
|
|
14047
|
-
case "HTML_VOID_ELEMENT_HAS_CLOSE_TAG":
|
|
14048
|
-
return `Void element <${info.tag}> has an explicit close tag${fmtLocationSuffix(info)}`;
|
|
14049
|
-
case "HTML_DUPLICATE_FORM":
|
|
14050
|
-
return `Nested <form> — the inner form will be dropped by the parser${fmtLocationSuffix(info)}`;
|
|
14051
|
-
case "HTML_NESTED_INTERACTIVE":
|
|
14052
|
-
return `<${info.tag}> nested inside another <${info.tag}> — adoption agency will reorder${fmtLocationSuffix(info)}`;
|
|
14053
|
-
case "HTML_MISNESTED_FORMATTING":
|
|
14054
|
-
return `Misnested formatting tag </${info.tag}> — adoption agency will reorder nodes${fmtLocationSuffix(info)}`;
|
|
14055
|
-
case "HTML_UNEXPECTED_END_TAG":
|
|
14056
|
-
return `Unexpected end tag </${info.tag}>${fmtLocationSuffix(info)}`;
|
|
14057
|
-
case "HTML_UNCLOSED_BEFORE_END":
|
|
14058
|
-
return `<${info.unclosed}> still open when </${info.tag}> was seen — implicitly closed${fmtLocationSuffix(info)}`;
|
|
14059
|
-
case "HTML_DUPLICATE_ATTRIBUTE":
|
|
14060
|
-
return `Duplicate attribute '${info.name}' — second occurrence dropped${fmtLocationSuffix(info)}`;
|
|
14061
|
-
case "HTML_ATTRIBUTES_ON_END_TAG":
|
|
14062
|
-
return `Attributes on end tag </${info.tag}> — dropped by the parser${fmtLocationSuffix(info)}`;
|
|
14063
|
-
case "HTML_SELF_CLOSING_END_TAG":
|
|
14064
|
-
return `Self-closing end tag </${info.tag}/> — trailing '/' is meaningless${fmtLocationSuffix(info)}`;
|
|
14065
|
-
case "HTML_MISSING_ATTRIBUTE_VALUE":
|
|
14066
|
-
return `Attribute '${info.name}' is missing a value${fmtLocationSuffix(info)}`;
|
|
14067
|
-
case "HTML_CDATA_IN_HTML_NAMESPACE":
|
|
14068
|
-
return `CDATA section in HTML namespace — reinterpreted as a bogus comment${fmtLocationSuffix(info)}`;
|
|
14069
|
-
case "HTML_BOGUS_COMMENT":
|
|
14070
|
-
return `Bogus comment — content dropped by the parser${fmtLocationSuffix(info)}`;
|
|
14071
|
-
case "HTML_SVG_ATTR_WILL_LOWERCASE":
|
|
14072
|
-
return `SVG attribute '${info.raw}' will be rewritten to '${info.canonical}'${fmtLocationSuffix(info)}`;
|
|
14073
|
-
case "HTML_MATHML_ATTR_WILL_LOWERCASE":
|
|
14074
|
-
return `MathML attribute '${info.raw}' will be rewritten to '${info.canonical}'${fmtLocationSuffix(info)}`;
|
|
14075
|
-
case "ASYNC_HANDLER":
|
|
14076
|
-
return `Handler '${info.name}' in '${info.channel}' is an async function — handlers must be synchronous and return the updated state (an async function returns a Promise the framework won't await)`;
|
|
14077
|
-
case "TOP_LEVEL_AT_RULE_IN_SCOPED_STYLE":
|
|
14078
|
-
return `'@${info.atRule}' is a top-level-only at-rule, but '${info.key}' is wrapped in a component-scoped selector ([data-cid=…]{…}) where it is invalid and silently dropped — move it to 'globalStyle'${fmtLocationSuffix(info)}`;
|
|
14079
|
-
case "GLOBAL_SELECTOR_IN_SCOPED_STYLE":
|
|
14080
|
-
return `Selector '${info.selector}' targets the document root, but '${info.key}' is wrapped in a component-scoped selector, so it becomes a descendant selector that never matches — move it to 'globalStyle'${fmtLocationSuffix(info)}`;
|
|
14081
|
-
case "LINT_ERROR":
|
|
14082
|
-
return info.message;
|
|
14083
|
-
default:
|
|
14084
|
-
return id;
|
|
14085
13937
|
}
|
|
14086
|
-
|
|
14087
|
-
|
|
14088
|
-
|
|
14089
|
-
|
|
14090
|
-
|
|
14091
|
-
|
|
14092
|
-
|
|
14093
|
-
|
|
14094
|
-
|
|
14095
|
-
|
|
14096
|
-
|
|
14097
|
-
|
|
14098
|
-
|
|
14099
|
-
|
|
14100
|
-
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14105
|
-
|
|
14106
|
-
|
|
13938
|
+
get hasPendingTransactions() {
|
|
13939
|
+
return this.transactions.length > 0;
|
|
13940
|
+
}
|
|
13941
|
+
transactNext() {
|
|
13942
|
+
if (this.hasPendingTransactions)
|
|
13943
|
+
this.transact(this.transactions.shift());
|
|
13944
|
+
}
|
|
13945
|
+
transact(transaction) {
|
|
13946
|
+
try {
|
|
13947
|
+
const curState = this.state.val;
|
|
13948
|
+
const newState = transaction.run(curState, this.comps);
|
|
13949
|
+
if (newState !== undefined) {
|
|
13950
|
+
this.state.set(newState, { transaction });
|
|
13951
|
+
transaction.afterTransaction();
|
|
13952
|
+
} else
|
|
13953
|
+
console.warn("undefined new state", { curState, transaction });
|
|
13954
|
+
} finally {
|
|
13955
|
+
transaction._completion?.ensureSelfSettled();
|
|
13956
|
+
transaction._completion?.releaseSelf();
|
|
13957
|
+
}
|
|
13958
|
+
}
|
|
13959
|
+
transactInputNow(path, event, eventHandler, dragInfo) {
|
|
13960
|
+
this.transact(new InputEvent(path, event, eventHandler, this, dragInfo));
|
|
14107
13961
|
}
|
|
14108
13962
|
}
|
|
14109
|
-
function
|
|
14110
|
-
const
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
return
|
|
13963
|
+
function mkReq404(name) {
|
|
13964
|
+
const fn = () => {
|
|
13965
|
+
throw new Error(`Request not found: ${name}`);
|
|
13966
|
+
};
|
|
13967
|
+
return { fn };
|
|
14114
13968
|
}
|
|
14115
|
-
function
|
|
14116
|
-
|
|
14117
|
-
case "ignored":
|
|
14118
|
-
return `the parser will drop this <${tag}>`;
|
|
14119
|
-
case "drop":
|
|
14120
|
-
return `the parser will drop this <${tag}>`;
|
|
14121
|
-
case "auto-close-implicit":
|
|
14122
|
-
return `the parser will close <${parent ?? "?"}> first, then place <${tag}> as a sibling`;
|
|
14123
|
-
case "foster-parent":
|
|
14124
|
-
return `the parser will move <${tag}> outside <${parent ?? "?"}> (foster-parenting)`;
|
|
14125
|
-
case "foreign-breakout":
|
|
14126
|
-
return `the parser will exit foreign content and re-process <${tag}> in HTML mode`;
|
|
14127
|
-
default:
|
|
14128
|
-
return `parser action: ${action}`;
|
|
14129
|
-
}
|
|
13969
|
+
function nullHandler() {
|
|
13970
|
+
return this;
|
|
14130
13971
|
}
|
|
14131
13972
|
|
|
14132
|
-
|
|
14133
|
-
|
|
14134
|
-
|
|
14135
|
-
this.
|
|
14136
|
-
this.
|
|
13973
|
+
class Transaction {
|
|
13974
|
+
constructor(path, transactor, parentTransaction = null) {
|
|
13975
|
+
this.path = path;
|
|
13976
|
+
this.transactor = transactor;
|
|
13977
|
+
this.parentTransaction = parentTransaction;
|
|
13978
|
+
this._completion = null;
|
|
14137
13979
|
}
|
|
14138
|
-
|
|
14139
|
-
|
|
14140
|
-
this.
|
|
13980
|
+
get completion() {
|
|
13981
|
+
this._completion ??= new Completion;
|
|
13982
|
+
return this._completion;
|
|
14141
13983
|
}
|
|
14142
|
-
|
|
14143
|
-
return this.
|
|
13984
|
+
whenSettled() {
|
|
13985
|
+
return this.completion.whenSettled();
|
|
14144
13986
|
}
|
|
14145
|
-
|
|
14146
|
-
return
|
|
13987
|
+
whenSubtreeSettled() {
|
|
13988
|
+
return this.completion.whenSubtreeSettled();
|
|
14147
13989
|
}
|
|
14148
|
-
|
|
14149
|
-
return this.
|
|
13990
|
+
run(rootValue, comps) {
|
|
13991
|
+
return this.updateRootValue(rootValue, comps);
|
|
14150
13992
|
}
|
|
14151
|
-
|
|
14152
|
-
|
|
13993
|
+
afterTransaction() {}
|
|
13994
|
+
buildRootStack(root, comps) {
|
|
13995
|
+
return Stack2.root(comps, root);
|
|
14153
13996
|
}
|
|
14154
|
-
|
|
14155
|
-
|
|
14156
|
-
for (const comp of this.byId.values())
|
|
14157
|
-
styles2.push(comp.compileStyle());
|
|
14158
|
-
return styles2.join(`
|
|
14159
|
-
`);
|
|
13997
|
+
buildStack(root, comps) {
|
|
13998
|
+
return this.path.toTransactionPath().buildStack(this.buildRootStack(root, comps));
|
|
14160
13999
|
}
|
|
14161
|
-
|
|
14162
|
-
|
|
14163
|
-
|
|
14164
|
-
constructor(comps = new Components, parent = null) {
|
|
14165
|
-
this.comps = comps;
|
|
14166
|
-
this.parent = parent;
|
|
14167
|
-
this.byName = {};
|
|
14168
|
-
this.reqsByName = {};
|
|
14169
|
-
this.macros = {};
|
|
14000
|
+
callHandler(root, instance, comps) {
|
|
14001
|
+
const [handler, args] = this.getHandlerAndArgs(root, instance, comps);
|
|
14002
|
+
return handler.apply(instance, args);
|
|
14170
14003
|
}
|
|
14171
|
-
|
|
14172
|
-
return
|
|
14004
|
+
getHandlerAndArgs(_root, _instance, _comps) {
|
|
14005
|
+
return null;
|
|
14173
14006
|
}
|
|
14174
|
-
|
|
14175
|
-
|
|
14176
|
-
for (let i = 0;i < comps.length; i++) {
|
|
14177
|
-
const comp = comps[i];
|
|
14178
|
-
comp.scope = this.enter();
|
|
14179
|
-
comp.Class.scope = comp.scope;
|
|
14180
|
-
this.comps.registerComponent(comp);
|
|
14181
|
-
this.byName[comp.name] = comp;
|
|
14182
|
-
}
|
|
14183
|
-
for (const alias in aliases2) {
|
|
14184
|
-
const comp = this.byName[aliases2[alias]];
|
|
14185
|
-
console.assert(this.byName[alias] === undefined, "alias overrides component", alias);
|
|
14186
|
-
if (comp !== undefined)
|
|
14187
|
-
this.byName[alias] = comp;
|
|
14188
|
-
else
|
|
14189
|
-
console.warn("alias", alias, "to inexistent component", aliases2[alias]);
|
|
14190
|
-
}
|
|
14007
|
+
getTransactionPath() {
|
|
14008
|
+
return this.path.toTransactionPath();
|
|
14191
14009
|
}
|
|
14192
|
-
|
|
14193
|
-
|
|
14194
|
-
|
|
14195
|
-
|
|
14196
|
-
|
|
14197
|
-
|
|
14010
|
+
updateRootValue(curRoot, comps) {
|
|
14011
|
+
const txnPath = this.getTransactionPath();
|
|
14012
|
+
const curLeaf = txnPath.lookup(curRoot);
|
|
14013
|
+
const newLeaf = this.callHandler(curRoot, curLeaf, comps);
|
|
14014
|
+
this._completion?.markSelfSettled({ value: newLeaf, old: curLeaf });
|
|
14015
|
+
return curLeaf !== newLeaf ? txnPath.setValue(curRoot, newLeaf) : curRoot;
|
|
14198
14016
|
}
|
|
14199
|
-
|
|
14200
|
-
return
|
|
14017
|
+
lookupName(_name) {
|
|
14018
|
+
return null;
|
|
14201
14019
|
}
|
|
14202
|
-
|
|
14203
|
-
|
|
14204
|
-
|
|
14020
|
+
}
|
|
14021
|
+
var toNullIfNaN = (v) => Number.isNaN(v) ? null : v;
|
|
14022
|
+
function getValue(e) {
|
|
14023
|
+
return e.target.type === "checkbox" ? e.target.checked : (e instanceof CustomEvent ? e.detail : e.target.value) ?? null;
|
|
14024
|
+
}
|
|
14025
|
+
|
|
14026
|
+
class InputEvent extends Transaction {
|
|
14027
|
+
constructor(path, e, handler, transactor, dragInfo) {
|
|
14028
|
+
super(path, transactor);
|
|
14029
|
+
this.e = e;
|
|
14030
|
+
this.handler = handler;
|
|
14031
|
+
this.dragInfo = dragInfo;
|
|
14032
|
+
this._dispatchPath = null;
|
|
14205
14033
|
}
|
|
14206
|
-
|
|
14207
|
-
|
|
14034
|
+
get dispatchPath() {
|
|
14035
|
+
this._dispatchPath ??= this.path.compact();
|
|
14036
|
+
return this._dispatchPath;
|
|
14208
14037
|
}
|
|
14209
|
-
|
|
14210
|
-
return
|
|
14038
|
+
buildRootStack(root, comps) {
|
|
14039
|
+
return Stack2.root(comps, root, this);
|
|
14211
14040
|
}
|
|
14212
|
-
|
|
14213
|
-
|
|
14041
|
+
getHandlerAndArgs(root, _instance, comps) {
|
|
14042
|
+
const stack = this.buildStack(root, comps);
|
|
14043
|
+
const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
|
|
14044
|
+
const path = this.dispatchPath;
|
|
14045
|
+
let dispatcher;
|
|
14046
|
+
for (let i = 0;i < args.length; i++) {
|
|
14047
|
+
if (args[i]?.toHandlerArg) {
|
|
14048
|
+
dispatcher ??= new Dispatcher(path, this.transactor, this);
|
|
14049
|
+
args[i] = args[i].toHandlerArg(dispatcher);
|
|
14050
|
+
}
|
|
14051
|
+
}
|
|
14052
|
+
args.push(new EventContext(path, this.transactor, this));
|
|
14053
|
+
return [handler, args];
|
|
14054
|
+
}
|
|
14055
|
+
lookupName(name) {
|
|
14056
|
+
const { e } = this;
|
|
14057
|
+
switch (name) {
|
|
14058
|
+
case "value":
|
|
14059
|
+
return getValue(e);
|
|
14060
|
+
case "valueAsInt":
|
|
14061
|
+
return toNullIfNaN(parseInt(getValue(e), 10));
|
|
14062
|
+
case "valueAsFloat":
|
|
14063
|
+
return toNullIfNaN(parseFloat(getValue(e)));
|
|
14064
|
+
case "target":
|
|
14065
|
+
return e.target;
|
|
14066
|
+
case "event":
|
|
14067
|
+
return e;
|
|
14068
|
+
case "isAlt":
|
|
14069
|
+
return e.altKey;
|
|
14070
|
+
case "isShift":
|
|
14071
|
+
return e.shiftKey;
|
|
14072
|
+
case "isCtrl":
|
|
14073
|
+
case "isCmd":
|
|
14074
|
+
return isMac && e.metaKey || e.ctrlKey;
|
|
14075
|
+
case "key":
|
|
14076
|
+
return e.key;
|
|
14077
|
+
case "keyCode":
|
|
14078
|
+
return e.keyCode;
|
|
14079
|
+
case "isUpKey":
|
|
14080
|
+
return e.key === "ArrowUp";
|
|
14081
|
+
case "isDownKey":
|
|
14082
|
+
return e.key === "ArrowDown";
|
|
14083
|
+
case "isSend":
|
|
14084
|
+
return e.key === "Enter";
|
|
14085
|
+
case "isCancel":
|
|
14086
|
+
return e.key === "Escape";
|
|
14087
|
+
case "isTabKey":
|
|
14088
|
+
return e.key === "Tab";
|
|
14089
|
+
case "ctx":
|
|
14090
|
+
return new EventContext(this.dispatchPath, this.transactor, this);
|
|
14091
|
+
case "dragInfo":
|
|
14092
|
+
return this.dragInfo;
|
|
14093
|
+
}
|
|
14094
|
+
return null;
|
|
14214
14095
|
}
|
|
14215
14096
|
}
|
|
14216
14097
|
|
|
14217
|
-
class
|
|
14218
|
-
constructor(name,
|
|
14098
|
+
class NameArgsTransaction extends Transaction {
|
|
14099
|
+
constructor(path, transactor, name, args, parentTransaction, opts = {}) {
|
|
14100
|
+
super(path, transactor, parentTransaction);
|
|
14219
14101
|
this.name = name;
|
|
14220
|
-
this.
|
|
14221
|
-
this.
|
|
14102
|
+
this.args = args;
|
|
14103
|
+
this.opts = opts;
|
|
14104
|
+
this.targetPath = path;
|
|
14105
|
+
}
|
|
14106
|
+
handlerProp = null;
|
|
14107
|
+
getHandlerForName(comp) {
|
|
14108
|
+
const handlers = comp?.[this.handlerProp];
|
|
14109
|
+
return handlers?.[this.name] ?? handlers?.$unknown ?? nullHandler;
|
|
14110
|
+
}
|
|
14111
|
+
getHandlerAndArgs(_root, instance, comps) {
|
|
14112
|
+
const handler = this.getHandlerForName(comps.getCompFor(instance));
|
|
14113
|
+
return [handler, [...this.args, new EventContext(this.path, this.transactor, this)]];
|
|
14222
14114
|
}
|
|
14223
14115
|
}
|
|
14224
14116
|
|
|
14225
|
-
class
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
this.
|
|
14230
|
-
this.val = val;
|
|
14231
|
-
this._sym = undefined;
|
|
14117
|
+
class ResponseEvent extends NameArgsTransaction {
|
|
14118
|
+
handlerProp = "response";
|
|
14119
|
+
constructor(path, transactor, name, args, parent, txnPath = null) {
|
|
14120
|
+
super(path, transactor, name, args, parent);
|
|
14121
|
+
this._txnPath = txnPath;
|
|
14232
14122
|
}
|
|
14233
|
-
|
|
14234
|
-
|
|
14235
|
-
this._sym = stack.lookupType(this.compName)?.provide?.[this.provideName]?.symbol ?? null;
|
|
14236
|
-
return this._sym;
|
|
14123
|
+
getTransactionPath() {
|
|
14124
|
+
return this._txnPath ?? super.getTransactionPath();
|
|
14237
14125
|
}
|
|
14238
14126
|
}
|
|
14239
|
-
var isString = (v) => typeof v === "string";
|
|
14240
|
-
var _rawSpecKeys = "name view style commonStyle globalStyle input receive bubble response alter views provide lookup fields methods statics";
|
|
14241
|
-
var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
14242
|
-
var _compId = 0;
|
|
14243
14127
|
|
|
14244
|
-
class
|
|
14245
|
-
|
|
14246
|
-
|
|
14247
|
-
this.
|
|
14248
|
-
this.Class = Class;
|
|
14249
|
-
this.views = { main: new View("main", o.view, o.style) };
|
|
14250
|
-
this.commonStyle = o.commonStyle ?? "";
|
|
14251
|
-
this.globalStyle = o.globalStyle ?? "";
|
|
14252
|
-
this.input = o.input ?? {};
|
|
14253
|
-
this.receive = o.receive ?? {};
|
|
14254
|
-
this.bubble = o.bubble ?? {};
|
|
14255
|
-
this.response = o.response ?? {};
|
|
14256
|
-
this.alter = o.alter ?? {};
|
|
14257
|
-
for (const name in o.views ?? {}) {
|
|
14258
|
-
const v = o.views[name];
|
|
14259
|
-
const { view, style } = isString(v) ? { view: v } : v;
|
|
14260
|
-
this.views[name] = new View(name, view, style);
|
|
14261
|
-
}
|
|
14262
|
-
this._rawProvide = o.provide ?? {};
|
|
14263
|
-
this._rawLookup = o.lookup ?? {};
|
|
14264
|
-
this.provide = {};
|
|
14265
|
-
this.lookup = {};
|
|
14266
|
-
this.scope = null;
|
|
14267
|
-
this.spec = o;
|
|
14268
|
-
this.extra = {};
|
|
14269
|
-
for (const key of Object.keys(o))
|
|
14270
|
-
if (!KNOWN_SPEC_KEYS.has(key))
|
|
14271
|
-
this.extra[key] = o[key];
|
|
14128
|
+
class SendEvent extends NameArgsTransaction {
|
|
14129
|
+
handlerProp = "receive";
|
|
14130
|
+
run(rootVal, comps) {
|
|
14131
|
+
return this.opts.skipSelf ? rootVal : this.updateRootValue(rootVal, comps);
|
|
14272
14132
|
}
|
|
14273
|
-
|
|
14274
|
-
|
|
14133
|
+
afterTransaction() {
|
|
14134
|
+
const { path, name, args, opts, targetPath } = this;
|
|
14135
|
+
if (opts.bubbles && path.steps.length > 0)
|
|
14136
|
+
this.transactor.pushBubble(path.popStep(), name, args, opts, this, targetPath);
|
|
14275
14137
|
}
|
|
14276
|
-
|
|
14277
|
-
|
|
14278
|
-
|
|
14279
|
-
|
|
14280
|
-
|
|
14281
|
-
|
|
14282
|
-
|
|
14283
|
-
this.provide[key] = new ProvideInfo(key, val, Symbol(key));
|
|
14284
|
-
}
|
|
14285
|
-
for (const key in this._rawLookup) {
|
|
14286
|
-
const linfo = this._rawLookup[key];
|
|
14287
|
-
const forStr = isString(linfo) ? linfo : isString(linfo?.for) ? linfo.for : null;
|
|
14288
|
-
const [compName, provideName] = forStr === null ? [] : forStr.split(".");
|
|
14289
|
-
if (!isString(compName) || !isString(provideName))
|
|
14290
|
-
continue;
|
|
14291
|
-
const defStr = isString(linfo?.default) ? linfo.default : null;
|
|
14292
|
-
const val = defStr === null ? null : vp.parseField(defStr, ctx);
|
|
14293
|
-
this.lookup[key] = new LookupInfo(key, compName, provideName, val);
|
|
14294
|
-
}
|
|
14295
|
-
for (const key in this.lookup)
|
|
14296
|
-
if (this.provide[key] !== undefined)
|
|
14297
|
-
console.warn("name declared in both provide and lookup", this.name, key);
|
|
14138
|
+
}
|
|
14139
|
+
|
|
14140
|
+
class BubbleEvent extends SendEvent {
|
|
14141
|
+
handlerProp = "bubble";
|
|
14142
|
+
constructor(path, transactor, name, args, parent, opts, targetPath) {
|
|
14143
|
+
super(path, transactor, name, args, parent, opts);
|
|
14144
|
+
this.targetPath = targetPath ?? path;
|
|
14298
14145
|
}
|
|
14299
|
-
|
|
14300
|
-
|
|
14146
|
+
stopPropagation() {
|
|
14147
|
+
this.opts.bubbles = false;
|
|
14301
14148
|
}
|
|
14302
|
-
|
|
14303
|
-
|
|
14149
|
+
}
|
|
14150
|
+
|
|
14151
|
+
class InputDispatchEvent extends NameArgsTransaction {
|
|
14152
|
+
handlerProp = "input";
|
|
14153
|
+
}
|
|
14154
|
+
|
|
14155
|
+
class Completion {
|
|
14156
|
+
constructor() {
|
|
14157
|
+
this.val = undefined;
|
|
14158
|
+
this.selfSettled = false;
|
|
14159
|
+
this.subtreeSettled = false;
|
|
14160
|
+
this.pending = 1;
|
|
14161
|
+
this._selfResolve = null;
|
|
14162
|
+
this._selfPromise = null;
|
|
14163
|
+
this._subtreeResolve = null;
|
|
14164
|
+
this._subtreePromise = null;
|
|
14165
|
+
this._selfReleased = false;
|
|
14166
|
+
}
|
|
14167
|
+
whenSettled() {
|
|
14168
|
+
if (this.selfSettled)
|
|
14169
|
+
return Promise.resolve(this.val);
|
|
14170
|
+
this._selfPromise ??= new Promise((res) => {
|
|
14171
|
+
this._selfResolve = res;
|
|
14172
|
+
});
|
|
14173
|
+
return this._selfPromise;
|
|
14304
14174
|
}
|
|
14305
|
-
|
|
14306
|
-
|
|
14175
|
+
whenSubtreeSettled() {
|
|
14176
|
+
if (this.subtreeSettled)
|
|
14177
|
+
return Promise.resolve(this.val);
|
|
14178
|
+
this._subtreePromise ??= new Promise((res) => {
|
|
14179
|
+
this._subtreeResolve = res;
|
|
14180
|
+
});
|
|
14181
|
+
return this._subtreePromise;
|
|
14307
14182
|
}
|
|
14308
|
-
|
|
14309
|
-
|
|
14183
|
+
markSelfSettled(val) {
|
|
14184
|
+
if (this.selfSettled)
|
|
14185
|
+
return;
|
|
14186
|
+
this.selfSettled = true;
|
|
14187
|
+
this.val = val;
|
|
14188
|
+
this._selfResolve?.(val);
|
|
14310
14189
|
}
|
|
14311
|
-
|
|
14312
|
-
|
|
14313
|
-
|
|
14314
|
-
|
|
14315
|
-
|
|
14316
|
-
|
|
14317
|
-
|
|
14318
|
-
|
|
14319
|
-
|
|
14190
|
+
ensureSelfSettled() {
|
|
14191
|
+
if (!this.selfSettled)
|
|
14192
|
+
this.markSelfSettled(this.val);
|
|
14193
|
+
}
|
|
14194
|
+
track() {
|
|
14195
|
+
this.pending++;
|
|
14196
|
+
let done = false;
|
|
14197
|
+
return () => {
|
|
14198
|
+
if (done)
|
|
14199
|
+
return;
|
|
14200
|
+
done = true;
|
|
14201
|
+
this._release();
|
|
14202
|
+
};
|
|
14203
|
+
}
|
|
14204
|
+
releaseSelf() {
|
|
14205
|
+
if (this._selfReleased)
|
|
14206
|
+
return;
|
|
14207
|
+
this._selfReleased = true;
|
|
14208
|
+
this._release();
|
|
14209
|
+
}
|
|
14210
|
+
_release() {
|
|
14211
|
+
if (--this.pending === 0) {
|
|
14212
|
+
this.subtreeSettled = true;
|
|
14213
|
+
this._subtreeResolve?.(this.val);
|
|
14320
14214
|
}
|
|
14321
|
-
return styles2.join(`
|
|
14322
|
-
`);
|
|
14323
14215
|
}
|
|
14324
14216
|
}
|
|
14325
14217
|
|
|
14326
|
-
|
|
14327
|
-
|
|
14328
|
-
|
|
14329
|
-
|
|
14330
|
-
|
|
14331
|
-
|
|
14332
|
-
const r = n[0].lookup(name);
|
|
14333
|
-
if (r === STOP)
|
|
14334
|
-
return dv;
|
|
14335
|
-
if (r !== NEXT)
|
|
14336
|
-
return r;
|
|
14337
|
-
n = n[1];
|
|
14338
|
-
}
|
|
14339
|
-
return dv;
|
|
14340
|
-
}
|
|
14341
|
-
|
|
14342
|
-
class BindFrame {
|
|
14343
|
-
constructor(it, binds, isFrame) {
|
|
14344
|
-
this.it = it;
|
|
14345
|
-
this.binds = binds;
|
|
14346
|
-
this.isFrame = isFrame;
|
|
14218
|
+
class Dispatcher {
|
|
14219
|
+
constructor(path, transactor, parentTransaction, root = transactor.state.val) {
|
|
14220
|
+
this.path = path;
|
|
14221
|
+
this.transactor = transactor;
|
|
14222
|
+
this.parent = parentTransaction;
|
|
14223
|
+
this.root = root;
|
|
14347
14224
|
}
|
|
14348
|
-
|
|
14349
|
-
const
|
|
14350
|
-
|
|
14225
|
+
walkPath(callback) {
|
|
14226
|
+
const comps = this.transactor.comps;
|
|
14227
|
+
const chain = this.path.toTransactionPath().resolveChain(this.root);
|
|
14228
|
+
for (let i = chain.length - 1;i >= 0; i--) {
|
|
14229
|
+
const comp = comps.getCompFor(chain[i]);
|
|
14230
|
+
if (comp && callback(comp, chain[i]) === false)
|
|
14231
|
+
return;
|
|
14232
|
+
}
|
|
14351
14233
|
}
|
|
14352
|
-
|
|
14353
|
-
|
|
14354
|
-
class ObjectFrame {
|
|
14355
|
-
constructor(binds) {
|
|
14356
|
-
this.binds = binds;
|
|
14234
|
+
get at() {
|
|
14235
|
+
return new PathChanges(this);
|
|
14357
14236
|
}
|
|
14358
|
-
|
|
14359
|
-
|
|
14360
|
-
return v === undefined ? NEXT : v;
|
|
14237
|
+
send(name, args, opts) {
|
|
14238
|
+
return this.sendAtPath(this.path, name, args, opts);
|
|
14361
14239
|
}
|
|
14362
|
-
|
|
14363
|
-
|
|
14364
|
-
let s = "";
|
|
14365
|
-
let n = views;
|
|
14366
|
-
while (n !== null) {
|
|
14367
|
-
s += n[0];
|
|
14368
|
-
n = n[1];
|
|
14240
|
+
bubble(name, args, opts) {
|
|
14241
|
+
return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
|
|
14369
14242
|
}
|
|
14370
|
-
|
|
14371
|
-
|
|
14372
|
-
|
|
14373
|
-
class Stack2 {
|
|
14374
|
-
constructor(comps, it, binds, dynBinds, views, viewsId, ctx = null) {
|
|
14375
|
-
this.comps = comps;
|
|
14376
|
-
this.it = it;
|
|
14377
|
-
this.binds = binds;
|
|
14378
|
-
this.dynBinds = dynBinds;
|
|
14379
|
-
this.views = views;
|
|
14380
|
-
this.viewsId = viewsId;
|
|
14381
|
-
this.ctx = ctx;
|
|
14243
|
+
sendAtPath(path, name, args, opts) {
|
|
14244
|
+
return this.transactor.pushSend(path, name, args, opts, this.parent);
|
|
14382
14245
|
}
|
|
14383
|
-
|
|
14384
|
-
|
|
14385
|
-
if (provide == null)
|
|
14386
|
-
return this;
|
|
14387
|
-
const dynObj = {};
|
|
14388
|
-
let has2 = false;
|
|
14389
|
-
for (const k in provide) {
|
|
14390
|
-
dynObj[provide[k].symbol] = provide[k].val.eval(this);
|
|
14391
|
-
has2 = true;
|
|
14392
|
-
}
|
|
14393
|
-
if (!has2)
|
|
14394
|
-
return this;
|
|
14395
|
-
const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
|
|
14396
|
-
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
14397
|
-
return new Stack2(comps, it, binds, newDynBinds, views, viewsId, ctx);
|
|
14246
|
+
request(name, args, opts) {
|
|
14247
|
+
return this.requestAtPath(this.path, name, args, opts);
|
|
14398
14248
|
}
|
|
14399
|
-
|
|
14400
|
-
|
|
14401
|
-
const dynBinds = [new ObjectFrame({}), null];
|
|
14402
|
-
const views = ["main", null];
|
|
14403
|
-
return new Stack2(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();
|
|
14249
|
+
requestAtPath(path, name, args, opts) {
|
|
14250
|
+
return this.transactor.pushRequest(path, name, args, opts, this.parent);
|
|
14404
14251
|
}
|
|
14405
|
-
|
|
14406
|
-
|
|
14407
|
-
const newBinds = [new BindFrame(it, bindings, isFrame), binds];
|
|
14408
|
-
const stack = new Stack2(comps, it, newBinds, dynBinds, views, viewsId, ctx);
|
|
14409
|
-
return isFrame ? stack._pushProvides() : stack;
|
|
14252
|
+
inputAtPath(path, name, args, opts) {
|
|
14253
|
+
return this.transactor.pushInput(path, name, args, opts, this.parent);
|
|
14410
14254
|
}
|
|
14411
|
-
|
|
14412
|
-
|
|
14413
|
-
const newViews = [name, views];
|
|
14414
|
-
return new Stack2(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
14255
|
+
lookupTypeFor(name, inst) {
|
|
14256
|
+
return this.transactor.comps.getCompFor(inst).scope.lookupComponent(name);
|
|
14415
14257
|
}
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14419
|
-
|
|
14420
|
-
|
|
14258
|
+
}
|
|
14259
|
+
|
|
14260
|
+
class EventContext extends Dispatcher {
|
|
14261
|
+
get name() {
|
|
14262
|
+
return this.parent?.name ?? null;
|
|
14421
14263
|
}
|
|
14422
|
-
|
|
14423
|
-
return
|
|
14264
|
+
get targetPath() {
|
|
14265
|
+
return this.parent.targetPath;
|
|
14424
14266
|
}
|
|
14425
|
-
|
|
14426
|
-
|
|
14427
|
-
return (sym != null ? lookup(this.dynBinds, sym) : null) ?? lk.val?.eval(this) ?? null;
|
|
14267
|
+
stopPropagation() {
|
|
14268
|
+
return this.parent.stopPropagation();
|
|
14428
14269
|
}
|
|
14429
|
-
|
|
14430
|
-
|
|
14431
|
-
|
|
14432
|
-
|
|
14433
|
-
|
|
14434
|
-
|
|
14435
|
-
|
|
14436
|
-
|
|
14437
|
-
|
|
14270
|
+
}
|
|
14271
|
+
|
|
14272
|
+
class RequestContext extends Dispatcher {
|
|
14273
|
+
}
|
|
14274
|
+
|
|
14275
|
+
class PathChanges extends PathBuilder {
|
|
14276
|
+
constructor(dispatcher) {
|
|
14277
|
+
super();
|
|
14278
|
+
this.dispatcher = dispatcher;
|
|
14438
14279
|
}
|
|
14439
|
-
|
|
14440
|
-
return
|
|
14280
|
+
send(name, args, opts) {
|
|
14281
|
+
return this.dispatcher.sendAtPath(this.buildPath(), name, args, opts);
|
|
14441
14282
|
}
|
|
14442
|
-
|
|
14443
|
-
return this.
|
|
14283
|
+
bubble(name, args, opts) {
|
|
14284
|
+
return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
|
|
14444
14285
|
}
|
|
14445
|
-
|
|
14446
|
-
return this.
|
|
14286
|
+
buildPath() {
|
|
14287
|
+
return this.dispatcher.path.concat(this.pathChanges);
|
|
14447
14288
|
}
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14289
|
+
}
|
|
14290
|
+
function rootDispatcher(transactor) {
|
|
14291
|
+
return new Dispatcher(new Path([]), transactor, null);
|
|
14292
|
+
}
|
|
14293
|
+
|
|
14294
|
+
// tools/core/results.js
|
|
14295
|
+
class ModuleInfo {
|
|
14296
|
+
constructor({ path = null, present = new Set, counts = {}, warnings = [] }) {
|
|
14297
|
+
this.path = path;
|
|
14298
|
+
this.present = present;
|
|
14299
|
+
this.counts = counts;
|
|
14300
|
+
this.warnings = warnings;
|
|
14451
14301
|
}
|
|
14452
|
-
|
|
14453
|
-
|
|
14302
|
+
}
|
|
14303
|
+
|
|
14304
|
+
class ComponentSummary {
|
|
14305
|
+
constructor({ name, views, fields }) {
|
|
14306
|
+
this.name = name;
|
|
14307
|
+
this.views = views;
|
|
14308
|
+
this.fields = fields;
|
|
14454
14309
|
}
|
|
14455
|
-
|
|
14456
|
-
|
|
14310
|
+
}
|
|
14311
|
+
|
|
14312
|
+
class ComponentList {
|
|
14313
|
+
constructor({ items, total = null, truncated = false }) {
|
|
14314
|
+
this.items = items;
|
|
14315
|
+
this.total = total ?? items.length;
|
|
14316
|
+
this.truncated = truncated;
|
|
14457
14317
|
}
|
|
14458
|
-
|
|
14459
|
-
|
|
14318
|
+
}
|
|
14319
|
+
|
|
14320
|
+
class ExampleIndex {
|
|
14321
|
+
constructor({ sections, total = null, truncated = false }) {
|
|
14322
|
+
this.sections = sections;
|
|
14323
|
+
this.total = total ?? sections.reduce((n, s) => n + (s.items?.length ?? 0), 0);
|
|
14324
|
+
this.truncated = truncated;
|
|
14460
14325
|
}
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
return view;
|
|
14467
|
-
n = n[1];
|
|
14468
|
-
}
|
|
14469
|
-
return views[defaultViewName];
|
|
14326
|
+
}
|
|
14327
|
+
|
|
14328
|
+
class ComponentDocs {
|
|
14329
|
+
constructor({ items }) {
|
|
14330
|
+
this.items = items;
|
|
14470
14331
|
}
|
|
14471
14332
|
}
|
|
14472
14333
|
|
|
14473
|
-
|
|
14474
|
-
|
|
14475
|
-
|
|
14476
|
-
this.
|
|
14477
|
-
this.
|
|
14334
|
+
class LintFinding {
|
|
14335
|
+
constructor({ id, level, info, context = {}, suggestion = null }) {
|
|
14336
|
+
this.id = id;
|
|
14337
|
+
this.level = level;
|
|
14338
|
+
this.info = info;
|
|
14339
|
+
this.context = context;
|
|
14340
|
+
this.suggestion = suggestion;
|
|
14478
14341
|
}
|
|
14479
|
-
|
|
14480
|
-
|
|
14342
|
+
}
|
|
14343
|
+
|
|
14344
|
+
class LintComponentResult {
|
|
14345
|
+
constructor({ componentName, findings }) {
|
|
14346
|
+
this.componentName = componentName;
|
|
14347
|
+
this.findings = findings;
|
|
14481
14348
|
}
|
|
14482
|
-
|
|
14483
|
-
|
|
14484
|
-
this.val = val;
|
|
14485
|
-
for (const sub of this.changeSubs)
|
|
14486
|
-
sub({ val, old, info, timestamp: Date.now() });
|
|
14349
|
+
get errorCount() {
|
|
14350
|
+
return this.findings.filter((f) => f.level === "error").length;
|
|
14487
14351
|
}
|
|
14488
|
-
|
|
14489
|
-
return this.
|
|
14352
|
+
get warnCount() {
|
|
14353
|
+
return this.findings.filter((f) => f.level === "warn").length;
|
|
14490
14354
|
}
|
|
14491
14355
|
}
|
|
14492
14356
|
|
|
14493
|
-
class
|
|
14494
|
-
constructor(
|
|
14495
|
-
this.
|
|
14496
|
-
this.transactions = [];
|
|
14497
|
-
this.state = new State2(rootValue);
|
|
14498
|
-
this.onTransactionPushed = () => {};
|
|
14357
|
+
class LintReport {
|
|
14358
|
+
constructor({ components }) {
|
|
14359
|
+
this.components = components;
|
|
14499
14360
|
}
|
|
14500
|
-
|
|
14501
|
-
this.
|
|
14502
|
-
this.onTransactionPushed(t);
|
|
14361
|
+
get hasErrors() {
|
|
14362
|
+
return this.components.some((c) => c.errorCount > 0);
|
|
14503
14363
|
}
|
|
14504
|
-
|
|
14505
|
-
this.
|
|
14364
|
+
get totalErrors() {
|
|
14365
|
+
return this.components.reduce((n, c) => n + c.errorCount, 0);
|
|
14506
14366
|
}
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
this.pushTransaction(new BubbleEvent(path, this, name, args, parent, newOpts, targetPath));
|
|
14510
|
-
}
|
|
14511
|
-
async pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
14512
|
-
const curRoot = this.state.val;
|
|
14513
|
-
const txnPath = path.toTransactionPath();
|
|
14514
|
-
const curLeaf = txnPath.lookup(curRoot);
|
|
14515
|
-
const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
|
|
14516
|
-
const reqCtx = new RequestContext(path, this, parent, curRoot);
|
|
14517
|
-
const resHandlerName = opts?.onResName ?? name;
|
|
14518
|
-
const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
|
|
14519
|
-
const push = (specificName, baseName, singleArg, result, error) => {
|
|
14520
|
-
const resArgs = specificName ? [singleArg] : [result, error];
|
|
14521
|
-
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
|
|
14522
|
-
this.pushTransaction(t);
|
|
14523
|
-
};
|
|
14524
|
-
try {
|
|
14525
|
-
const result = await handler.fn.apply(null, [...args, reqCtx]);
|
|
14526
|
-
push(opts?.onOkName, resHandlerName, result, result, null);
|
|
14527
|
-
} catch (error) {
|
|
14528
|
-
push(opts?.onErrorName, resHandlerName, error, null, error);
|
|
14529
|
-
}
|
|
14530
|
-
}
|
|
14531
|
-
get hasPendingTransactions() {
|
|
14532
|
-
return this.transactions.length > 0;
|
|
14533
|
-
}
|
|
14534
|
-
transactNext() {
|
|
14535
|
-
if (this.hasPendingTransactions)
|
|
14536
|
-
this.transact(this.transactions.shift());
|
|
14537
|
-
}
|
|
14538
|
-
transact(transaction) {
|
|
14539
|
-
const curState = this.state.val;
|
|
14540
|
-
const newState = transaction.run(curState, this.comps);
|
|
14541
|
-
if (newState !== undefined) {
|
|
14542
|
-
this.state.set(newState, { transaction });
|
|
14543
|
-
transaction.afterTransaction();
|
|
14544
|
-
} else
|
|
14545
|
-
console.warn("undefined new state", { curState, transaction });
|
|
14546
|
-
}
|
|
14547
|
-
transactInputNow(path, event, eventHandler, dragInfo) {
|
|
14548
|
-
this.transact(new InputEvent(path, event, eventHandler, this, dragInfo));
|
|
14367
|
+
get totalWarnings() {
|
|
14368
|
+
return this.components.reduce((n, c) => n + c.warnCount, 0);
|
|
14549
14369
|
}
|
|
14550
14370
|
}
|
|
14551
|
-
function mkReq404(name) {
|
|
14552
|
-
const fn = () => {
|
|
14553
|
-
throw new Error(`Request not found: ${name}`);
|
|
14554
|
-
};
|
|
14555
|
-
return { fn };
|
|
14556
|
-
}
|
|
14557
|
-
function nullHandler() {
|
|
14558
|
-
return this;
|
|
14559
|
-
}
|
|
14560
14371
|
|
|
14561
|
-
class
|
|
14562
|
-
constructor(
|
|
14563
|
-
this.
|
|
14564
|
-
this.
|
|
14565
|
-
this.
|
|
14566
|
-
this.
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
this._task ??= new Task;
|
|
14570
|
-
return this._task;
|
|
14571
|
-
}
|
|
14572
|
-
getCompletionPromise() {
|
|
14573
|
-
return this.task.promise;
|
|
14574
|
-
}
|
|
14575
|
-
setParent(parentTransaction) {
|
|
14576
|
-
this.parentTransaction = parentTransaction;
|
|
14577
|
-
parentTransaction.task.addDep(this.task);
|
|
14578
|
-
}
|
|
14579
|
-
run(rootValue, comps) {
|
|
14580
|
-
return this.updateRootValue(rootValue, comps);
|
|
14581
|
-
}
|
|
14582
|
-
afterTransaction() {}
|
|
14583
|
-
buildRootStack(root, comps) {
|
|
14584
|
-
return Stack2.root(comps, root);
|
|
14585
|
-
}
|
|
14586
|
-
buildStack(root, comps) {
|
|
14587
|
-
return this.path.toTransactionPath().buildStack(this.buildRootStack(root, comps));
|
|
14588
|
-
}
|
|
14589
|
-
callHandler(root, instance, comps) {
|
|
14590
|
-
const [handler, args] = this.getHandlerAndArgs(root, instance, comps);
|
|
14591
|
-
return handler.apply(instance, args);
|
|
14592
|
-
}
|
|
14593
|
-
getHandlerAndArgs(_root, _instance, _comps) {
|
|
14594
|
-
return null;
|
|
14595
|
-
}
|
|
14596
|
-
getTransactionPath() {
|
|
14597
|
-
return this.path.toTransactionPath();
|
|
14598
|
-
}
|
|
14599
|
-
updateRootValue(curRoot, comps) {
|
|
14600
|
-
const txnPath = this.getTransactionPath();
|
|
14601
|
-
const curLeaf = txnPath.lookup(curRoot);
|
|
14602
|
-
const newLeaf = this.callHandler(curRoot, curLeaf, comps);
|
|
14603
|
-
this._task?.complete?.({ value: newLeaf, old: curLeaf });
|
|
14604
|
-
return curLeaf !== newLeaf ? txnPath.setValue(curRoot, newLeaf) : curRoot;
|
|
14605
|
-
}
|
|
14606
|
-
lookupName(_name) {
|
|
14607
|
-
return null;
|
|
14372
|
+
class RenderedExample {
|
|
14373
|
+
constructor({ title, description = null, componentName, view, html, error = null }) {
|
|
14374
|
+
this.title = title;
|
|
14375
|
+
this.description = description;
|
|
14376
|
+
this.componentName = componentName;
|
|
14377
|
+
this.view = view;
|
|
14378
|
+
this.html = html;
|
|
14379
|
+
this.error = error;
|
|
14608
14380
|
}
|
|
14609
14381
|
}
|
|
14610
|
-
var toNullIfNaN = (v) => Number.isNaN(v) ? null : v;
|
|
14611
|
-
function getValue(e) {
|
|
14612
|
-
return e.target.type === "checkbox" ? e.target.checked : (e instanceof CustomEvent ? e.detail : e.target.value) ?? null;
|
|
14613
|
-
}
|
|
14614
14382
|
|
|
14615
|
-
class
|
|
14616
|
-
constructor(
|
|
14617
|
-
|
|
14618
|
-
this.
|
|
14619
|
-
this.
|
|
14620
|
-
this.dragInfo = dragInfo;
|
|
14621
|
-
this._dispatchPath = null;
|
|
14622
|
-
}
|
|
14623
|
-
get dispatchPath() {
|
|
14624
|
-
this._dispatchPath ??= this.path.compact();
|
|
14625
|
-
return this._dispatchPath;
|
|
14626
|
-
}
|
|
14627
|
-
buildRootStack(root, comps) {
|
|
14628
|
-
return Stack2.root(comps, root, this);
|
|
14629
|
-
}
|
|
14630
|
-
getHandlerAndArgs(root, _instance, comps) {
|
|
14631
|
-
const stack = this.buildStack(root, comps);
|
|
14632
|
-
const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
|
|
14633
|
-
const path = this.dispatchPath;
|
|
14634
|
-
let dispatcher;
|
|
14635
|
-
for (let i = 0;i < args.length; i++) {
|
|
14636
|
-
if (args[i]?.toHandlerArg) {
|
|
14637
|
-
dispatcher ??= new Dispatcher(path, this.transactor, this);
|
|
14638
|
-
args[i] = args[i].toHandlerArg(dispatcher);
|
|
14639
|
-
}
|
|
14640
|
-
}
|
|
14641
|
-
args.push(new EventContext(path, this.transactor, this));
|
|
14642
|
-
return [handler, args];
|
|
14643
|
-
}
|
|
14644
|
-
lookupName(name) {
|
|
14645
|
-
const { e } = this;
|
|
14646
|
-
switch (name) {
|
|
14647
|
-
case "value":
|
|
14648
|
-
return getValue(e);
|
|
14649
|
-
case "valueAsInt":
|
|
14650
|
-
return toNullIfNaN(parseInt(getValue(e), 10));
|
|
14651
|
-
case "valueAsFloat":
|
|
14652
|
-
return toNullIfNaN(parseFloat(getValue(e)));
|
|
14653
|
-
case "target":
|
|
14654
|
-
return e.target;
|
|
14655
|
-
case "event":
|
|
14656
|
-
return e;
|
|
14657
|
-
case "isAlt":
|
|
14658
|
-
return e.altKey;
|
|
14659
|
-
case "isShift":
|
|
14660
|
-
return e.shiftKey;
|
|
14661
|
-
case "isCtrl":
|
|
14662
|
-
case "isCmd":
|
|
14663
|
-
return isMac && e.metaKey || e.ctrlKey;
|
|
14664
|
-
case "key":
|
|
14665
|
-
return e.key;
|
|
14666
|
-
case "keyCode":
|
|
14667
|
-
return e.keyCode;
|
|
14668
|
-
case "isUpKey":
|
|
14669
|
-
return e.key === "ArrowUp";
|
|
14670
|
-
case "isDownKey":
|
|
14671
|
-
return e.key === "ArrowDown";
|
|
14672
|
-
case "isSend":
|
|
14673
|
-
return e.key === "Enter";
|
|
14674
|
-
case "isCancel":
|
|
14675
|
-
return e.key === "Escape";
|
|
14676
|
-
case "isTabKey":
|
|
14677
|
-
return e.key === "Tab";
|
|
14678
|
-
case "ctx":
|
|
14679
|
-
return new EventContext(this.dispatchPath, this.transactor, this);
|
|
14680
|
-
case "dragInfo":
|
|
14681
|
-
return this.dragInfo;
|
|
14682
|
-
}
|
|
14683
|
-
return null;
|
|
14383
|
+
class RenderedSection {
|
|
14384
|
+
constructor({ title, description = null, items }) {
|
|
14385
|
+
this.title = title;
|
|
14386
|
+
this.description = description;
|
|
14387
|
+
this.items = items;
|
|
14684
14388
|
}
|
|
14685
14389
|
}
|
|
14686
14390
|
|
|
14687
|
-
class
|
|
14688
|
-
constructor(
|
|
14689
|
-
|
|
14690
|
-
this.name = name;
|
|
14691
|
-
this.args = args;
|
|
14692
|
-
this.opts = opts;
|
|
14693
|
-
this.targetPath = path;
|
|
14694
|
-
}
|
|
14695
|
-
handlerProp = null;
|
|
14696
|
-
getHandlerForName(comp) {
|
|
14697
|
-
const handlers = comp?.[this.handlerProp];
|
|
14698
|
-
return handlers?.[this.name] ?? handlers?.$unknown ?? nullHandler;
|
|
14391
|
+
class RenderBatch {
|
|
14392
|
+
constructor({ sections }) {
|
|
14393
|
+
this.sections = sections;
|
|
14699
14394
|
}
|
|
14700
|
-
|
|
14701
|
-
|
|
14702
|
-
return [handler, [...this.args, new EventContext(this.path, this.transactor, this)]];
|
|
14395
|
+
get hasErrors() {
|
|
14396
|
+
return this.sections.some((s) => s.items.some((i) => i.error !== null));
|
|
14703
14397
|
}
|
|
14704
14398
|
}
|
|
14705
14399
|
|
|
14706
|
-
class
|
|
14707
|
-
|
|
14708
|
-
|
|
14709
|
-
|
|
14710
|
-
this.
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14400
|
+
class TestResult {
|
|
14401
|
+
constructor({ title, fullPath, componentName = null, status, durationMs = 0, error = null }) {
|
|
14402
|
+
this.title = title;
|
|
14403
|
+
this.fullPath = fullPath;
|
|
14404
|
+
this.componentName = componentName;
|
|
14405
|
+
this.status = status;
|
|
14406
|
+
this.durationMs = durationMs;
|
|
14407
|
+
this.error = error;
|
|
14714
14408
|
}
|
|
14715
14409
|
}
|
|
14716
14410
|
|
|
14717
|
-
class
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
afterTransaction() {
|
|
14723
|
-
const { path, name, args, opts, targetPath } = this;
|
|
14724
|
-
if (opts.bubbles && path.steps.length > 0)
|
|
14725
|
-
this.transactor.pushBubble(path.popStep(), name, args, opts, this, targetPath);
|
|
14411
|
+
class DescribeResult {
|
|
14412
|
+
constructor({ title, componentName = null, children = [] }) {
|
|
14413
|
+
this.title = title;
|
|
14414
|
+
this.componentName = componentName;
|
|
14415
|
+
this.children = children;
|
|
14726
14416
|
}
|
|
14727
14417
|
}
|
|
14728
14418
|
|
|
14729
|
-
class
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
this.
|
|
14734
|
-
}
|
|
14735
|
-
stopPropagation() {
|
|
14736
|
-
this.opts.bubbles = false;
|
|
14419
|
+
class ModuleTestReport {
|
|
14420
|
+
constructor({ path = null, suites = [], counts = { pass: 0, fail: 0, skip: 0, total: 0 } }) {
|
|
14421
|
+
this.path = path;
|
|
14422
|
+
this.suites = suites;
|
|
14423
|
+
this.counts = counts;
|
|
14737
14424
|
}
|
|
14738
14425
|
}
|
|
14739
14426
|
|
|
14740
|
-
class
|
|
14741
|
-
constructor() {
|
|
14742
|
-
this.
|
|
14743
|
-
this.val = this.resolve = this.reject = null;
|
|
14744
|
-
this.promise = new Promise((res, rej) => {
|
|
14745
|
-
this.resolve = res;
|
|
14746
|
-
this.reject = rej;
|
|
14747
|
-
});
|
|
14748
|
-
this.isCompleted = false;
|
|
14427
|
+
class TestReport {
|
|
14428
|
+
constructor({ modules = [] }) {
|
|
14429
|
+
this.modules = modules;
|
|
14749
14430
|
}
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
|
|
14431
|
+
get totals() {
|
|
14432
|
+
return this.modules.reduce((acc, m) => ({
|
|
14433
|
+
pass: acc.pass + m.counts.pass,
|
|
14434
|
+
fail: acc.fail + m.counts.fail,
|
|
14435
|
+
skip: acc.skip + m.counts.skip,
|
|
14436
|
+
total: acc.total + m.counts.total
|
|
14437
|
+
}), { pass: 0, fail: 0, skip: 0, total: 0 });
|
|
14754
14438
|
}
|
|
14755
|
-
|
|
14756
|
-
this.
|
|
14757
|
-
this._check();
|
|
14439
|
+
get hasFailures() {
|
|
14440
|
+
return this.modules.some((m) => m.counts.fail > 0);
|
|
14758
14441
|
}
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14442
|
+
}
|
|
14443
|
+
|
|
14444
|
+
// tools/core/tests.js
|
|
14445
|
+
class Describe {
|
|
14446
|
+
constructor({ title, componentName = null, parent = null }) {
|
|
14447
|
+
this.title = title;
|
|
14448
|
+
this.componentName = componentName;
|
|
14449
|
+
this.parent = parent;
|
|
14450
|
+
this.children = [];
|
|
14764
14451
|
}
|
|
14765
14452
|
}
|
|
14766
14453
|
|
|
14767
|
-
class
|
|
14768
|
-
constructor(
|
|
14769
|
-
this.
|
|
14770
|
-
this.
|
|
14771
|
-
this.
|
|
14772
|
-
this.
|
|
14454
|
+
class Test {
|
|
14455
|
+
constructor({ title, fn, componentName = null, parent = null }) {
|
|
14456
|
+
this.title = title;
|
|
14457
|
+
this.fn = fn;
|
|
14458
|
+
this.componentName = componentName;
|
|
14459
|
+
this.parent = parent;
|
|
14773
14460
|
}
|
|
14774
|
-
|
|
14775
|
-
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14779
|
-
|
|
14780
|
-
return;
|
|
14781
|
-
}
|
|
14461
|
+
}
|
|
14462
|
+
|
|
14463
|
+
class ModuleTests {
|
|
14464
|
+
constructor({ path = null, suites = [] } = {}) {
|
|
14465
|
+
this.path = path;
|
|
14466
|
+
this.suites = suites;
|
|
14782
14467
|
}
|
|
14783
|
-
|
|
14784
|
-
|
|
14468
|
+
}
|
|
14469
|
+
|
|
14470
|
+
class TestIndex {
|
|
14471
|
+
constructor({ modules = [] } = {}) {
|
|
14472
|
+
this.modules = modules;
|
|
14785
14473
|
}
|
|
14786
|
-
|
|
14787
|
-
|
|
14474
|
+
}
|
|
14475
|
+
function isComponentObject(x) {
|
|
14476
|
+
return x !== null && typeof x === "object" && typeof x.name === "string" && typeof x.Class === "function";
|
|
14477
|
+
}
|
|
14478
|
+
function resolveComponentName(arg, components) {
|
|
14479
|
+
if (isComponentObject(arg))
|
|
14480
|
+
return arg.name;
|
|
14481
|
+
if (typeof arg === "function") {
|
|
14482
|
+
for (const c of components)
|
|
14483
|
+
if (c.Class === arg)
|
|
14484
|
+
return c.name;
|
|
14788
14485
|
}
|
|
14789
|
-
|
|
14790
|
-
|
|
14486
|
+
return null;
|
|
14487
|
+
}
|
|
14488
|
+
function titleFromArg(arg) {
|
|
14489
|
+
if (typeof arg === "string")
|
|
14490
|
+
return arg;
|
|
14491
|
+
if (isComponentObject(arg))
|
|
14492
|
+
return arg.name;
|
|
14493
|
+
if (typeof arg === "function")
|
|
14494
|
+
return arg.name || "(anonymous)";
|
|
14495
|
+
return String(arg);
|
|
14496
|
+
}
|
|
14497
|
+
function makeCollector({ path = null, components = [] } = {}) {
|
|
14498
|
+
const moduleTests = new ModuleTests({ path, suites: [] });
|
|
14499
|
+
const stack = [];
|
|
14500
|
+
function describe(...args) {
|
|
14501
|
+
let head;
|
|
14502
|
+
let options = null;
|
|
14503
|
+
let fn;
|
|
14504
|
+
if (args.length === 2) {
|
|
14505
|
+
[head, fn] = args;
|
|
14506
|
+
} else if (args.length === 3) {
|
|
14507
|
+
[head, options, fn] = args;
|
|
14508
|
+
} else {
|
|
14509
|
+
throw new Error(`describe() expects 2 or 3 arguments, got ${args.length}`);
|
|
14510
|
+
}
|
|
14511
|
+
if (typeof fn !== "function") {
|
|
14512
|
+
throw new Error(`describe(${JSON.stringify(titleFromArg(head))}): final argument must be a function`);
|
|
14513
|
+
}
|
|
14514
|
+
let componentName = null;
|
|
14515
|
+
if (typeof head !== "string") {
|
|
14516
|
+
componentName = resolveComponentName(head, components);
|
|
14517
|
+
}
|
|
14518
|
+
if (componentName === null && options && options.component != null) {
|
|
14519
|
+
componentName = resolveComponentName(options.component, components);
|
|
14520
|
+
}
|
|
14521
|
+
if (componentName === null) {
|
|
14522
|
+
const parent2 = stack.length ? stack[stack.length - 1] : null;
|
|
14523
|
+
if (parent2)
|
|
14524
|
+
componentName = parent2.componentName;
|
|
14525
|
+
}
|
|
14526
|
+
const parent = stack.length ? stack[stack.length - 1] : null;
|
|
14527
|
+
const node = new Describe({
|
|
14528
|
+
title: titleFromArg(head),
|
|
14529
|
+
componentName,
|
|
14530
|
+
parent
|
|
14531
|
+
});
|
|
14532
|
+
if (parent)
|
|
14533
|
+
parent.children.push(node);
|
|
14534
|
+
else
|
|
14535
|
+
moduleTests.suites.push(node);
|
|
14536
|
+
stack.push(node);
|
|
14537
|
+
try {
|
|
14538
|
+
fn();
|
|
14539
|
+
} finally {
|
|
14540
|
+
stack.pop();
|
|
14541
|
+
}
|
|
14791
14542
|
}
|
|
14792
|
-
|
|
14793
|
-
|
|
14543
|
+
function test2(title, fn) {
|
|
14544
|
+
if (typeof title !== "string") {
|
|
14545
|
+
throw new Error("test(title, fn): title must be a string");
|
|
14546
|
+
}
|
|
14547
|
+
if (typeof fn !== "function") {
|
|
14548
|
+
throw new Error(`test(${JSON.stringify(title)}): fn must be a function`);
|
|
14549
|
+
}
|
|
14550
|
+
const parent = stack.length ? stack[stack.length - 1] : null;
|
|
14551
|
+
if (!parent) {
|
|
14552
|
+
throw new Error(`test(${JSON.stringify(title)}) must be called inside a describe()`);
|
|
14553
|
+
}
|
|
14554
|
+
parent.children.push(new Test({
|
|
14555
|
+
title,
|
|
14556
|
+
fn,
|
|
14557
|
+
componentName: parent.componentName,
|
|
14558
|
+
parent
|
|
14559
|
+
}));
|
|
14794
14560
|
}
|
|
14795
|
-
|
|
14796
|
-
|
|
14561
|
+
return { describe, test: test2, moduleTests };
|
|
14562
|
+
}
|
|
14563
|
+
|
|
14564
|
+
// tools/core/test.js
|
|
14565
|
+
function buildPath(node) {
|
|
14566
|
+
const parts = [];
|
|
14567
|
+
let cur = node;
|
|
14568
|
+
while (cur) {
|
|
14569
|
+
parts.unshift(cur.title);
|
|
14570
|
+
cur = cur.parent;
|
|
14797
14571
|
}
|
|
14798
|
-
|
|
14799
|
-
|
|
14572
|
+
return parts.join(" > ");
|
|
14573
|
+
}
|
|
14574
|
+
function captureError(e) {
|
|
14575
|
+
const out = { message: e.message, stack: e.stack };
|
|
14576
|
+
if ("expected" in e)
|
|
14577
|
+
out.expected = e.expected;
|
|
14578
|
+
if ("actual" in e)
|
|
14579
|
+
out.actual = e.actual;
|
|
14580
|
+
return out;
|
|
14581
|
+
}
|
|
14582
|
+
async function runTests({
|
|
14583
|
+
getTests,
|
|
14584
|
+
components = [],
|
|
14585
|
+
path = null,
|
|
14586
|
+
expect: expect2,
|
|
14587
|
+
name = null,
|
|
14588
|
+
grep = null,
|
|
14589
|
+
bail = false,
|
|
14590
|
+
requestHandlers = null,
|
|
14591
|
+
macros = null
|
|
14592
|
+
} = {}) {
|
|
14593
|
+
const counts = { pass: 0, fail: 0, skip: 0, total: 0 };
|
|
14594
|
+
if (typeof getTests !== "function") {
|
|
14595
|
+
return new TestReport({
|
|
14596
|
+
modules: [new ModuleTestReport({ path, suites: [], counts })]
|
|
14597
|
+
});
|
|
14800
14598
|
}
|
|
14801
|
-
|
|
14802
|
-
|
|
14599
|
+
if (typeof expect2 !== "function") {
|
|
14600
|
+
throw new Error("runTests: expect must be provided (e.g. chai's expect)");
|
|
14803
14601
|
}
|
|
14804
|
-
}
|
|
14805
|
-
|
|
14806
|
-
|
|
14807
|
-
|
|
14808
|
-
|
|
14602
|
+
const { describe, test: test2, moduleTests } = makeCollector({ path, components });
|
|
14603
|
+
await getTests({ describe, test: test2, expect: expect2, drive });
|
|
14604
|
+
let _stack = null;
|
|
14605
|
+
function getStack() {
|
|
14606
|
+
if (_stack)
|
|
14607
|
+
return _stack;
|
|
14608
|
+
_stack = new ComponentStack;
|
|
14609
|
+
_stack.registerComponents(components);
|
|
14610
|
+
if (macros)
|
|
14611
|
+
_stack.registerMacros(macros);
|
|
14612
|
+
if (requestHandlers)
|
|
14613
|
+
_stack.registerRequestHandlers(requestHandlers);
|
|
14614
|
+
return _stack;
|
|
14615
|
+
}
|
|
14616
|
+
async function drive(value, phase, opts = {}) {
|
|
14617
|
+
const transactor = new Transactor(getStack().comps, value);
|
|
14618
|
+
if (opts.onMessage)
|
|
14619
|
+
transactor.state.onChange(({ val, old, info }) => {
|
|
14620
|
+
const t = info?.transaction;
|
|
14621
|
+
opts.onMessage({ kind: t?.handlerProp ?? "input", name: t?.name, args: t?.args, path: t?.path }, old, val);
|
|
14622
|
+
});
|
|
14623
|
+
dispatchPhase(rootDispatcher(transactor), new Path([]), phase, value);
|
|
14624
|
+
await transactor.settle();
|
|
14625
|
+
return transactor.state.val;
|
|
14809
14626
|
}
|
|
14810
|
-
|
|
14811
|
-
|
|
14627
|
+
let bailed = false;
|
|
14628
|
+
async function visit(node) {
|
|
14629
|
+
if (node instanceof Test) {
|
|
14630
|
+
if (name !== null && node.componentName !== name)
|
|
14631
|
+
return null;
|
|
14632
|
+
const fullPath = buildPath(node);
|
|
14633
|
+
if (grep !== null && !fullPath.includes(grep))
|
|
14634
|
+
return null;
|
|
14635
|
+
counts.total++;
|
|
14636
|
+
if (bailed) {
|
|
14637
|
+
counts.skip++;
|
|
14638
|
+
return new TestResult({
|
|
14639
|
+
title: node.title,
|
|
14640
|
+
fullPath,
|
|
14641
|
+
componentName: node.componentName,
|
|
14642
|
+
status: "skip"
|
|
14643
|
+
});
|
|
14644
|
+
}
|
|
14645
|
+
const start = performance.now();
|
|
14646
|
+
try {
|
|
14647
|
+
await node.fn();
|
|
14648
|
+
counts.pass++;
|
|
14649
|
+
return new TestResult({
|
|
14650
|
+
title: node.title,
|
|
14651
|
+
fullPath,
|
|
14652
|
+
componentName: node.componentName,
|
|
14653
|
+
status: "pass",
|
|
14654
|
+
durationMs: performance.now() - start
|
|
14655
|
+
});
|
|
14656
|
+
} catch (e) {
|
|
14657
|
+
counts.fail++;
|
|
14658
|
+
if (bail)
|
|
14659
|
+
bailed = true;
|
|
14660
|
+
return new TestResult({
|
|
14661
|
+
title: node.title,
|
|
14662
|
+
fullPath,
|
|
14663
|
+
componentName: node.componentName,
|
|
14664
|
+
status: "fail",
|
|
14665
|
+
durationMs: performance.now() - start,
|
|
14666
|
+
error: captureError(e)
|
|
14667
|
+
});
|
|
14668
|
+
}
|
|
14669
|
+
}
|
|
14670
|
+
const childResults = [];
|
|
14671
|
+
for (const child of node.children) {
|
|
14672
|
+
const r = await visit(child);
|
|
14673
|
+
if (r !== null)
|
|
14674
|
+
childResults.push(r);
|
|
14675
|
+
}
|
|
14676
|
+
if (childResults.length === 0)
|
|
14677
|
+
return null;
|
|
14678
|
+
return new DescribeResult({
|
|
14679
|
+
title: node.title,
|
|
14680
|
+
componentName: node.componentName,
|
|
14681
|
+
children: childResults
|
|
14682
|
+
});
|
|
14812
14683
|
}
|
|
14813
|
-
|
|
14814
|
-
|
|
14684
|
+
const suiteResults = [];
|
|
14685
|
+
for (const suite of moduleTests.suites) {
|
|
14686
|
+
const r = await visit(suite);
|
|
14687
|
+
if (r !== null)
|
|
14688
|
+
suiteResults.push(r);
|
|
14815
14689
|
}
|
|
14690
|
+
return new TestReport({
|
|
14691
|
+
modules: [new ModuleTestReport({ path, suites: suiteResults, counts })]
|
|
14692
|
+
});
|
|
14816
14693
|
}
|
|
14817
14694
|
|
|
14818
|
-
|
|
14819
|
-
|
|
14820
|
-
|
|
14821
|
-
|
|
14822
|
-
|
|
14823
|
-
|
|
14824
|
-
|
|
14825
|
-
|
|
14826
|
-
|
|
14827
|
-
|
|
14828
|
-
|
|
14829
|
-
|
|
14830
|
-
|
|
14695
|
+
// tools/core/test-console.js
|
|
14696
|
+
var PASS = "color: #0a0; font-weight: bold";
|
|
14697
|
+
var FAIL = "color: #c00; font-weight: bold";
|
|
14698
|
+
var SKIP = "color: #888";
|
|
14699
|
+
var DIM = "color: #888";
|
|
14700
|
+
var RESET = "color: inherit; font-weight: normal";
|
|
14701
|
+
function reportTestNode(node) {
|
|
14702
|
+
if (node.children) {
|
|
14703
|
+
const label = node.componentName ? `${node.title} [${node.componentName}]` : node.title;
|
|
14704
|
+
console.group(label);
|
|
14705
|
+
for (const child of node.children)
|
|
14706
|
+
reportTestNode(child);
|
|
14707
|
+
console.groupEnd();
|
|
14708
|
+
return;
|
|
14831
14709
|
}
|
|
14832
|
-
|
|
14833
|
-
|
|
14710
|
+
const dur = node.status === "skip" ? "" : ` (${Math.round(node.durationMs)}ms)`;
|
|
14711
|
+
if (node.status === "pass") {
|
|
14712
|
+
console.log(`%c✓%c ${node.title}%c${dur}`, PASS, RESET, DIM);
|
|
14713
|
+
} else if (node.status === "skip") {
|
|
14714
|
+
console.log(`%c○ ${node.title}%c (skipped)`, SKIP, RESET);
|
|
14715
|
+
} else {
|
|
14716
|
+
console.group(`%c✗%c ${node.title}%c${dur}`, FAIL, RESET, DIM);
|
|
14717
|
+
console.error(node.error?.message ?? "(no error message)");
|
|
14718
|
+
if (node.error && (("expected" in node.error) || ("actual" in node.error))) {
|
|
14719
|
+
console.log("expected:", node.error.expected);
|
|
14720
|
+
console.log("actual: ", node.error.actual);
|
|
14721
|
+
}
|
|
14722
|
+
if (node.error?.stack)
|
|
14723
|
+
console.log(node.error.stack);
|
|
14724
|
+
console.groupEnd();
|
|
14725
|
+
}
|
|
14726
|
+
}
|
|
14727
|
+
function reportTestReportToConsole(report) {
|
|
14728
|
+
for (const m of report.modules) {
|
|
14729
|
+
const label = `tutuca tests${m.path ? ` — ${m.path}` : ""}`;
|
|
14730
|
+
console.group(label);
|
|
14731
|
+
if (m.suites.length === 0) {
|
|
14732
|
+
console.log("(no tests)");
|
|
14733
|
+
} else {
|
|
14734
|
+
for (const s of m.suites)
|
|
14735
|
+
reportTestNode(s);
|
|
14736
|
+
}
|
|
14737
|
+
const c = m.counts;
|
|
14738
|
+
const summary = `${c.pass} passed, ${c.fail} failed, ${c.skip} skipped (${c.total} total)`;
|
|
14739
|
+
if (c.fail > 0)
|
|
14740
|
+
console.error(`%c${summary}`, FAIL);
|
|
14741
|
+
else if (c.total === 0)
|
|
14742
|
+
console.log(`%c${summary}`, DIM);
|
|
14743
|
+
else
|
|
14744
|
+
console.log(`%c${summary}`, PASS);
|
|
14745
|
+
console.groupEnd();
|
|
14746
|
+
}
|
|
14747
|
+
return report;
|
|
14748
|
+
}
|
|
14749
|
+
|
|
14750
|
+
// tools/format/lint.js
|
|
14751
|
+
var UNSUPPORTED_EXPR_LABEL = {
|
|
14752
|
+
ternary: "ternary expression",
|
|
14753
|
+
comparison: "comparison",
|
|
14754
|
+
logical: "logical expression",
|
|
14755
|
+
"call-with-args": "method call with arguments"
|
|
14756
|
+
};
|
|
14757
|
+
function unsupportedExprMessage(info) {
|
|
14758
|
+
const v = JSON.stringify(info.value);
|
|
14759
|
+
const label = UNSUPPORTED_EXPR_LABEL[info.detected] ?? "expression";
|
|
14760
|
+
switch (info.role) {
|
|
14761
|
+
case "attr":
|
|
14762
|
+
return `Unsupported ${label} ${v} in dynamic attribute ':${info.attr}'`;
|
|
14763
|
+
case "directive":
|
|
14764
|
+
return `Unsupported ${label} ${v} in directive '@${info.directive}'`;
|
|
14765
|
+
case "if":
|
|
14766
|
+
return `Unsupported ${label} ${v} in '@if.${info.attr}' condition`;
|
|
14767
|
+
case "x-op":
|
|
14768
|
+
return `Unsupported ${label} ${v} in <x ${info.op}>`;
|
|
14769
|
+
default:
|
|
14770
|
+
return `Unsupported ${label} ${v}`;
|
|
14771
|
+
}
|
|
14772
|
+
}
|
|
14773
|
+
function badValueMessage(info) {
|
|
14774
|
+
const v = JSON.stringify(info.value);
|
|
14775
|
+
switch (info.role) {
|
|
14776
|
+
case "attr":
|
|
14777
|
+
return `Cannot parse value ${v} for attribute ':${info.attr}'`;
|
|
14778
|
+
case "directive":
|
|
14779
|
+
return `Cannot parse value ${v} for directive '@${info.directive}'`;
|
|
14780
|
+
case "if":
|
|
14781
|
+
return `Cannot parse condition ${v} for '@if.${info.attr}'`;
|
|
14782
|
+
case "x-op":
|
|
14783
|
+
return `Cannot parse value ${v} for <x ${info.op}>`;
|
|
14784
|
+
case "handler-name":
|
|
14785
|
+
return `Cannot parse handler name ${v}`;
|
|
14786
|
+
case "handler-arg":
|
|
14787
|
+
return `Cannot parse handler argument ${v}`;
|
|
14788
|
+
case "macro-var":
|
|
14789
|
+
return `Macro variable '^${info.name}' is not defined`;
|
|
14790
|
+
default:
|
|
14791
|
+
return `Cannot parse value ${v}`;
|
|
14792
|
+
}
|
|
14793
|
+
}
|
|
14794
|
+
function tagDisplay(tag) {
|
|
14795
|
+
return tag ? String(tag).toLowerCase() : null;
|
|
14796
|
+
}
|
|
14797
|
+
function fmtTagSuffix(info) {
|
|
14798
|
+
const t = tagDisplay(info?.tag);
|
|
14799
|
+
return t && t !== "x" ? ` on <${t}>` : "";
|
|
14800
|
+
}
|
|
14801
|
+
function fmtOriginSuffix(info) {
|
|
14802
|
+
if (!info)
|
|
14803
|
+
return "";
|
|
14804
|
+
const parts = [];
|
|
14805
|
+
if (info.originAttr) {
|
|
14806
|
+
const branch = info.branch ? `[${info.branch}]` : "";
|
|
14807
|
+
parts.push(`in ${info.originAttr}${branch}`);
|
|
14808
|
+
}
|
|
14809
|
+
if (info.handlerName) {
|
|
14810
|
+
parts.push(`handler '${info.handlerName}'${info.argIndex !== undefined ? ` arg ${info.argIndex}` : ""}`);
|
|
14811
|
+
}
|
|
14812
|
+
const t = tagDisplay(info.tag);
|
|
14813
|
+
if (t && t !== "x")
|
|
14814
|
+
parts.push(`on <${t}>`);
|
|
14815
|
+
return parts.length ? ` (${parts.join(", ")})` : "";
|
|
14816
|
+
}
|
|
14817
|
+
function fmtEventSuffix(info) {
|
|
14818
|
+
if (info?.originAttr)
|
|
14819
|
+
return ` in ${info.originAttr}`;
|
|
14820
|
+
if (info?.eventName)
|
|
14821
|
+
return ` in @on.${info.eventName}`;
|
|
14822
|
+
return "";
|
|
14823
|
+
}
|
|
14824
|
+
function lintIdToMessage(id, info) {
|
|
14825
|
+
switch (id) {
|
|
14826
|
+
case "RENDER_IT_OUTSIDE_OF_LOOP":
|
|
14827
|
+
return "<x render-it> used outside of a loop";
|
|
14828
|
+
case "UNKNOWN_EVENT_MODIFIER": {
|
|
14829
|
+
const mods = info.handler?.modifiers ?? [info.modifier];
|
|
14830
|
+
const written = `@on.${info.name}+${mods.join("+")}`;
|
|
14831
|
+
return `Unknown modifier '+${info.modifier}' in '${written}'`;
|
|
14832
|
+
}
|
|
14833
|
+
case "UNKNOWN_HANDLER_ARG_NAME":
|
|
14834
|
+
return `Unknown handler argument '${info.name}'${fmtOriginSuffix(info)}`;
|
|
14835
|
+
case "INPUT_HANDLER_NOT_IMPLEMENTED":
|
|
14836
|
+
return `Input handler '${info.name}' is not implemented${fmtEventSuffix(info)}`;
|
|
14837
|
+
case "INPUT_HANDLER_NOT_REFERENCED":
|
|
14838
|
+
return `Input handler '${info.name}' is defined but never used — remove it or wire it to an @on.* event`;
|
|
14839
|
+
case "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED":
|
|
14840
|
+
return `Method '$${info.name}' is not implemented${fmtEventSuffix(info)}`;
|
|
14841
|
+
case "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD":
|
|
14842
|
+
return `'$${info.name}' is a method reference, but '${info.name}' is defined as an input handler${fmtEventSuffix(info)}`;
|
|
14843
|
+
case "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER":
|
|
14844
|
+
return `'${info.name}' is an input handler reference, but '${info.name}' is defined as a method${fmtEventSuffix(info)}`;
|
|
14845
|
+
case "FIELD_VAL_NOT_DEFINED":
|
|
14846
|
+
return `Field '.${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
14847
|
+
case "FIELD_VAL_IS_METHOD":
|
|
14848
|
+
return `'.${info.name}' reads a field, but '${info.name}' is defined as a method — use '$${info.name}'${fmtOriginSuffix(info)}`;
|
|
14849
|
+
case "METHOD_VAL_NOT_DEFINED":
|
|
14850
|
+
return `Method '$${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
14851
|
+
case "METHOD_VAL_IS_FIELD":
|
|
14852
|
+
return `'$${info.name}' calls a method, but '${info.name}' is defined as a field — use '.${info.name}'${fmtOriginSuffix(info)}`;
|
|
14853
|
+
case "DUPLICATE_ATTR_DEFINITION": {
|
|
14854
|
+
const sources = info.sources?.length ? ` (${info.sources.join(", ")})` : "";
|
|
14855
|
+
const tag = info.tag ? ` on <${String(info.tag).toLowerCase()}>` : "";
|
|
14856
|
+
return `Attribute '${info.name}' is set ${info.sources?.length ?? "multiple"} times${sources}${tag}`;
|
|
14857
|
+
}
|
|
14858
|
+
case "IF_NO_BRANCH_SET":
|
|
14859
|
+
return `'@if.${info.attr}' has no '@then' or '@else' branch — add '@then="…"' or '@else="…"' (or both)${fmtTagSuffix(info)}`;
|
|
14860
|
+
case "UNKNOWN_REQUEST_NAME":
|
|
14861
|
+
return `Unknown request '!${info.name}'${fmtOriginSuffix(info)}`;
|
|
14862
|
+
case "UNKNOWN_COMPONENT_NAME":
|
|
14863
|
+
return `Unknown component '${info.name}'${fmtOriginSuffix(info)}`;
|
|
14864
|
+
case "ALT_HANDLER_NOT_DEFINED":
|
|
14865
|
+
return `Alter handler '${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
14866
|
+
case "ALT_HANDLER_NOT_REFERENCED":
|
|
14867
|
+
return `Alter handler '${info.name}' is defined but never used — remove it or reference it from @when, @enrich-with, or @loop-with`;
|
|
14868
|
+
case "DYN_VAL_NOT_DEFINED":
|
|
14869
|
+
return `Dynamic variable '*${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
14870
|
+
case "DYN_ALIAS_NOT_REFERENCED":
|
|
14871
|
+
return `Lookup '${info.name}' is defined but never used — remove it or reference it as '*${info.name}' in a view`;
|
|
14872
|
+
case "PROVIDE_NOT_ADDRESSABLE":
|
|
14873
|
+
return `Provide '${info.name}' value '${info.value}' must be a field ('.f') or seq-access ('.s[.k]') — a method/constant can't be a render target`;
|
|
14874
|
+
case "LOOKUP_BAD_SHAPE":
|
|
14875
|
+
return `Lookup '${info.name}' has an invalid shape: ${info.problem}`;
|
|
14876
|
+
case "LOOKUP_TARGET_MALFORMED":
|
|
14877
|
+
return `Lookup '${info.name}' target '${info.target}' must be 'Producer.provideName' (a string, or the 'for' of { for, default })`;
|
|
14878
|
+
case "UNKNOWN_MACRO_ARG":
|
|
14879
|
+
return `Argument '${info.name}' is not declared in macro '${info.macroName}'`;
|
|
14880
|
+
case "UNKNOWN_DIRECTIVE":
|
|
14881
|
+
return `Unknown directive '@${info.name}=${JSON.stringify(info.value)}'${fmtTagSuffix(info)}`;
|
|
14882
|
+
case "UNKNOWN_X_OP":
|
|
14883
|
+
return `Unknown <x> op '${info.name}=${JSON.stringify(info.value)}'${fmtTagSuffix(info)}`;
|
|
14884
|
+
case "UNKNOWN_X_ATTR":
|
|
14885
|
+
return `Unknown attribute '${info.name}=${JSON.stringify(info.value)}' on <x ${info.op}>${fmtTagSuffix(info)}`;
|
|
14886
|
+
case "MAYBE_DROP_AT_PREFIX": {
|
|
14887
|
+
const written = info.value !== undefined ? `${info.name}=${JSON.stringify(info.value)}` : info.name;
|
|
14888
|
+
return `'${written}' on <x> looks like a directive but is actually an x op/attr written with a leading '@'`;
|
|
14889
|
+
}
|
|
14890
|
+
case "MAYBE_ADD_AT_PREFIX":
|
|
14891
|
+
return `'${info.name}' on <${(info.tag ?? "").toLowerCase()}> is a plain attribute, but '@${info.name}' is a directive — add the leading '@'`;
|
|
14892
|
+
case "BAD_VALUE":
|
|
14893
|
+
return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
|
|
14894
|
+
case "UNSUPPORTED_EXPR_SYNTAX":
|
|
14895
|
+
return `${unsupportedExprMessage(info)}${fmtTagSuffix(info)}`;
|
|
14896
|
+
case "REDUNDANT_TEMPLATE_STRING":
|
|
14897
|
+
return `Redundant template string — '{${info.simpler}}' should be just '${info.simpler}'${fmtOriginSuffix(info)}`;
|
|
14898
|
+
case "PLACEHOLDERLESS_TEMPLATE_STRING":
|
|
14899
|
+
return `Template string has no dynamic parts — use the string literal ${info.literal} instead${fmtOriginSuffix(info)}`;
|
|
14900
|
+
case "UNKNOWN_COMPONENT_SPEC_KEY":
|
|
14901
|
+
return `Unknown component spec key '${info.key}' — value will be ignored at runtime`;
|
|
14902
|
+
case "COMP_FIELD_BAD_SHAPE":
|
|
14903
|
+
return info.kind === "args-not-object" ? `Field '${info.fieldName}': in { component, args }, 'args' must be a plain object, got ${info.got}` : `Field '${info.fieldName}': in { component, args }, 'component' must be the component name as a string, got ${info.gotName ? `the ${info.gotName} class` : info.got}`;
|
|
14904
|
+
case "HTML_TAG_NAME_HAS_UPPERCASE":
|
|
14905
|
+
return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
14906
|
+
case "HTML_SVG_TAG_WILL_LOWERCASE":
|
|
14907
|
+
return `SVG tag <${info.raw}> is not in the WHATWG case-correction list — will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
14908
|
+
case "HTML_TAG_NOT_ALLOWED_IN_PARENT":
|
|
14909
|
+
return `<${info.tag}> not allowed under <${info.parent ?? "?"}> in ${info.mode} — ${htmlActionPhrase(info.action, info.tag, info.parent)}${fmtLocationSuffix(info)}`;
|
|
14910
|
+
case "HTML_TEXT_NOT_ALLOWED_IN_PARENT":
|
|
14911
|
+
return `Non-whitespace text not allowed in ${info.mode}: ${JSON.stringify(info.snippet)}${fmtLocationSuffix(info)}`;
|
|
14912
|
+
case "HTML_VOID_ELEMENT_HAS_CLOSE_TAG":
|
|
14913
|
+
return `Void element <${info.tag}> has an explicit close tag${fmtLocationSuffix(info)}`;
|
|
14914
|
+
case "HTML_DUPLICATE_FORM":
|
|
14915
|
+
return `Nested <form> — the inner form will be dropped by the parser${fmtLocationSuffix(info)}`;
|
|
14916
|
+
case "HTML_NESTED_INTERACTIVE":
|
|
14917
|
+
return `<${info.tag}> nested inside another <${info.tag}> — adoption agency will reorder${fmtLocationSuffix(info)}`;
|
|
14918
|
+
case "HTML_MISNESTED_FORMATTING":
|
|
14919
|
+
return `Misnested formatting tag </${info.tag}> — adoption agency will reorder nodes${fmtLocationSuffix(info)}`;
|
|
14920
|
+
case "HTML_UNEXPECTED_END_TAG":
|
|
14921
|
+
return `Unexpected end tag </${info.tag}>${fmtLocationSuffix(info)}`;
|
|
14922
|
+
case "HTML_UNCLOSED_BEFORE_END":
|
|
14923
|
+
return `<${info.unclosed}> still open when </${info.tag}> was seen — implicitly closed${fmtLocationSuffix(info)}`;
|
|
14924
|
+
case "HTML_DUPLICATE_ATTRIBUTE":
|
|
14925
|
+
return `Duplicate attribute '${info.name}' — second occurrence dropped${fmtLocationSuffix(info)}`;
|
|
14926
|
+
case "HTML_ATTRIBUTES_ON_END_TAG":
|
|
14927
|
+
return `Attributes on end tag </${info.tag}> — dropped by the parser${fmtLocationSuffix(info)}`;
|
|
14928
|
+
case "HTML_SELF_CLOSING_END_TAG":
|
|
14929
|
+
return `Self-closing end tag </${info.tag}/> — trailing '/' is meaningless${fmtLocationSuffix(info)}`;
|
|
14930
|
+
case "HTML_MISSING_ATTRIBUTE_VALUE":
|
|
14931
|
+
return `Attribute '${info.name}' is missing a value${fmtLocationSuffix(info)}`;
|
|
14932
|
+
case "HTML_CDATA_IN_HTML_NAMESPACE":
|
|
14933
|
+
return `CDATA section in HTML namespace — reinterpreted as a bogus comment${fmtLocationSuffix(info)}`;
|
|
14934
|
+
case "HTML_BOGUS_COMMENT":
|
|
14935
|
+
return `Bogus comment — content dropped by the parser${fmtLocationSuffix(info)}`;
|
|
14936
|
+
case "HTML_SVG_ATTR_WILL_LOWERCASE":
|
|
14937
|
+
return `SVG attribute '${info.raw}' will be rewritten to '${info.canonical}'${fmtLocationSuffix(info)}`;
|
|
14938
|
+
case "HTML_MATHML_ATTR_WILL_LOWERCASE":
|
|
14939
|
+
return `MathML attribute '${info.raw}' will be rewritten to '${info.canonical}'${fmtLocationSuffix(info)}`;
|
|
14940
|
+
case "ASYNC_HANDLER":
|
|
14941
|
+
return `Handler '${info.name}' in '${info.channel}' is an async function — handlers must be synchronous and return the updated state (an async function returns a Promise the framework won't await)`;
|
|
14942
|
+
case "TOP_LEVEL_AT_RULE_IN_SCOPED_STYLE":
|
|
14943
|
+
return `'@${info.atRule}' is a top-level-only at-rule, but '${info.key}' is wrapped in a component-scoped selector ([data-cid=…]{…}) where it is invalid and silently dropped — move it to 'globalStyle'${fmtLocationSuffix(info)}`;
|
|
14944
|
+
case "GLOBAL_SELECTOR_IN_SCOPED_STYLE":
|
|
14945
|
+
return `Selector '${info.selector}' targets the document root, but '${info.key}' is wrapped in a component-scoped selector, so it becomes a descendant selector that never matches — move it to 'globalStyle'${fmtLocationSuffix(info)}`;
|
|
14946
|
+
case "LINT_ERROR":
|
|
14947
|
+
return info.message;
|
|
14948
|
+
default:
|
|
14949
|
+
return id;
|
|
14950
|
+
}
|
|
14951
|
+
}
|
|
14952
|
+
function suggestionToMessage(suggestion) {
|
|
14953
|
+
if (!suggestion)
|
|
14954
|
+
return null;
|
|
14955
|
+
switch (suggestion.kind) {
|
|
14956
|
+
case "replace-name":
|
|
14957
|
+
return `did you mean '${suggestion.to}'?`;
|
|
14958
|
+
case "drop-prefix":
|
|
14959
|
+
return `did you mean '${suggestion.to}'? (drop the leading '${suggestion.from.slice(0, suggestion.from.length - suggestion.to.length)}')`;
|
|
14960
|
+
case "add-prefix":
|
|
14961
|
+
return `did you mean '${suggestion.to}'? (add the leading '${suggestion.to.slice(0, suggestion.to.length - suggestion.from.length)}')`;
|
|
14962
|
+
case "remove":
|
|
14963
|
+
return `remove ${suggestion.what}`;
|
|
14964
|
+
case "rewrite":
|
|
14965
|
+
return `use '${suggestion.to}' instead of '${suggestion.from}'`;
|
|
14966
|
+
case "wrap":
|
|
14967
|
+
return `wrap it in ${suggestion.to}`;
|
|
14968
|
+
case "rephrase":
|
|
14969
|
+
return suggestion.text ?? null;
|
|
14970
|
+
default:
|
|
14971
|
+
return null;
|
|
14972
|
+
}
|
|
14973
|
+
}
|
|
14974
|
+
function fmtLocationSuffix(info) {
|
|
14975
|
+
const loc = info?.location;
|
|
14976
|
+
if (!loc)
|
|
14977
|
+
return "";
|
|
14978
|
+
return ` at line ${loc.line}, col ${loc.column}`;
|
|
14979
|
+
}
|
|
14980
|
+
function htmlActionPhrase(action, tag, parent) {
|
|
14981
|
+
switch (action) {
|
|
14982
|
+
case "ignored":
|
|
14983
|
+
return `the parser will drop this <${tag}>`;
|
|
14984
|
+
case "drop":
|
|
14985
|
+
return `the parser will drop this <${tag}>`;
|
|
14986
|
+
case "auto-close-implicit":
|
|
14987
|
+
return `the parser will close <${parent ?? "?"}> first, then place <${tag}> as a sibling`;
|
|
14988
|
+
case "foster-parent":
|
|
14989
|
+
return `the parser will move <${tag}> outside <${parent ?? "?"}> (foster-parenting)`;
|
|
14990
|
+
case "foreign-breakout":
|
|
14991
|
+
return `the parser will exit foreign content and re-process <${tag}> in HTML mode`;
|
|
14992
|
+
default:
|
|
14993
|
+
return `parser action: ${action}`;
|
|
14834
14994
|
}
|
|
14835
14995
|
}
|
|
14836
14996
|
|
|
@@ -15802,9 +15962,11 @@ export {
|
|
|
15802
15962
|
setIn$1 as setIn,
|
|
15803
15963
|
set2 as set,
|
|
15804
15964
|
runTests,
|
|
15965
|
+
resolveArgs,
|
|
15805
15966
|
reportTestReportToConsole,
|
|
15806
15967
|
removeIn,
|
|
15807
15968
|
remove,
|
|
15969
|
+
phaseOps,
|
|
15808
15970
|
mergeWith$1 as mergeWith,
|
|
15809
15971
|
mergeDeepWith$1 as mergeDeepWith,
|
|
15810
15972
|
mergeDeep$1 as mergeDeep,
|
|
@@ -15841,6 +16003,7 @@ export {
|
|
|
15841
16003
|
get2 as get,
|
|
15842
16004
|
fromJS,
|
|
15843
16005
|
docComponents,
|
|
16006
|
+
dispatchPhase,
|
|
15844
16007
|
css,
|
|
15845
16008
|
component,
|
|
15846
16009
|
compileClassesToStyleText,
|