tutuca 0.13.3 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tutuca-cli.js +572 -379
- package/dist/tutuca-dev.ext.js +605 -409
- package/dist/tutuca-dev.js +616 -420
- package/dist/tutuca-dev.min.js +4 -4
- package/dist/tutuca-extra.ext.js +588 -374
- package/dist/tutuca-extra.js +595 -381
- package/dist/tutuca-extra.min.js +3 -3
- package/dist/tutuca.ext.js +588 -374
- package/dist/tutuca.js +595 -381
- package/dist/tutuca.min.js +3 -3
- package/package.json +1 -1
- package/skill/tutuca/SKILL.md +2 -2
- package/skill/tutuca/advanced.md +48 -17
- package/skill/tutuca/component-design.md +2 -2
- package/skill/tutuca/core.md +1 -1
- package/skill/tutuca/messages-and-intents.md +1 -1
- package/skill/tutuca/patterns/README.md +1 -1
- package/skill/tutuca/patterns/edit-through-a-dynamic-target.md +11 -6
- package/skill/tutuca/patterns/share-state-across-the-tree.md +18 -3
- package/skill/tutuca/semantics.md +43 -28
- package/skill/tutuca-source/tutuca.ext.js +588 -374
package/dist/tutuca-dev.ext.js
CHANGED
|
@@ -128,8 +128,8 @@ function jestMatchers(chai2, utils) {
|
|
|
128
128
|
expected
|
|
129
129
|
);
|
|
130
130
|
});
|
|
131
|
-
m("toHaveProperty", function(
|
|
132
|
-
const keys = Array.isArray(
|
|
131
|
+
m("toHaveProperty", function(path2, ...rest) {
|
|
132
|
+
const keys = Array.isArray(path2) ? path2 : String(path2).split(".");
|
|
133
133
|
let cur = this._obj;
|
|
134
134
|
let found = true;
|
|
135
135
|
for (const k of keys) {
|
|
@@ -144,7 +144,7 @@ function jestMatchers(chai2, utils) {
|
|
|
144
144
|
pass,
|
|
145
145
|
"expected #{this} to have property #{exp}",
|
|
146
146
|
"expected #{this} not to have property #{exp}",
|
|
147
|
-
|
|
147
|
+
path2
|
|
148
148
|
);
|
|
149
149
|
});
|
|
150
150
|
m("toBeInstanceOf", function(ctor) {
|
|
@@ -234,8 +234,11 @@ var Step = class {
|
|
|
234
234
|
}
|
|
235
235
|
setDraftValue(_root, _v) {
|
|
236
236
|
}
|
|
237
|
-
|
|
238
|
-
|
|
237
|
+
// Re-enter this step while rebuilding a stack. `renderPath` is the dispatch
|
|
238
|
+
// position AFTER this step: a rebuilt frame must carry the same render path
|
|
239
|
+
// the renderer had there, or the provides it publishes would be located wrong.
|
|
240
|
+
enterFrame(stack, next, renderPath) {
|
|
241
|
+
return stack.enter(next, {}, true, renderPath);
|
|
239
242
|
}
|
|
240
243
|
toAbstractPathStep() {
|
|
241
244
|
return this;
|
|
@@ -260,8 +263,8 @@ var BindStep = class _BindStep extends Step {
|
|
|
260
263
|
lookup(v, _dval) {
|
|
261
264
|
return v;
|
|
262
265
|
}
|
|
263
|
-
enterFrame(stack, next) {
|
|
264
|
-
return stack.enter(next, { ...this.binds }, false);
|
|
266
|
+
enterFrame(stack, next, renderPath) {
|
|
267
|
+
return stack.enter(next, { ...this.binds }, false, renderPath);
|
|
265
268
|
}
|
|
266
269
|
withIndex(i) {
|
|
267
270
|
return new _BindStep({ ...this.binds, key: i });
|
|
@@ -278,9 +281,9 @@ var ScopeBindStep = class _ScopeBindStep extends BindStep {
|
|
|
278
281
|
super(binds);
|
|
279
282
|
this.val = val;
|
|
280
283
|
}
|
|
281
|
-
enterFrame(stack, next) {
|
|
284
|
+
enterFrame(stack, next, renderPath) {
|
|
282
285
|
const dyn = this.val.evalAsHandler(stack)?.call(stack.it) ?? {};
|
|
283
|
-
return stack.enter(next, { ...this.binds, ...dyn }, false);
|
|
286
|
+
return stack.enter(next, { ...this.binds, ...dyn }, false, renderPath);
|
|
284
287
|
}
|
|
285
288
|
withIndex(i) {
|
|
286
289
|
return new _ScopeBindStep(this.val, { ...this.binds, key: i });
|
|
@@ -323,8 +326,8 @@ var SeqStep = class extends Step {
|
|
|
323
326
|
const seq = readKey(root, this.field, null);
|
|
324
327
|
if (seq != null) writeSeqKey(seq, this.key, v);
|
|
325
328
|
}
|
|
326
|
-
enterFrame(stack, next) {
|
|
327
|
-
return stack.enter(next, { key: this.key }, true);
|
|
329
|
+
enterFrame(stack, next, renderPath) {
|
|
330
|
+
return stack.enter(next, { key: this.key }, true, renderPath);
|
|
328
331
|
}
|
|
329
332
|
toKey() {
|
|
330
333
|
return { field: this.field, key: this.key };
|
|
@@ -370,60 +373,52 @@ var EachBindStep = class extends Step {
|
|
|
370
373
|
}
|
|
371
374
|
// Replay the renderer's per-item binds (key, value + any @enrich-with binds)
|
|
372
375
|
// so a rebuilt stack matches the one @each rendered with.
|
|
373
|
-
enterFrame(stack, next) {
|
|
374
|
-
return stack.enter(next, this.iterInfo.enrichBinds(stack, this.key), false);
|
|
376
|
+
enterFrame(stack, next, renderPath) {
|
|
377
|
+
return stack.enter(next, this.iterInfo.enrichBinds(stack, this.key), false, renderPath);
|
|
375
378
|
}
|
|
376
379
|
toAbstractPathStep() {
|
|
377
380
|
return null;
|
|
378
381
|
}
|
|
379
382
|
};
|
|
380
383
|
var EachRenderItStep = class extends SeqStep {
|
|
381
|
-
enterFrame(stack, next) {
|
|
382
|
-
return stack.enter(next, { key: this.key, value: next }, false).enter(next, {}, true);
|
|
384
|
+
enterFrame(stack, next, renderPath) {
|
|
385
|
+
return stack.enter(next, { key: this.key, value: next }, false, renderPath).enter(next, {}, true, renderPath);
|
|
383
386
|
}
|
|
384
387
|
toAbstractPathStep() {
|
|
385
388
|
return new SeqStep(this.field, this.key);
|
|
386
389
|
}
|
|
387
390
|
};
|
|
388
|
-
function
|
|
389
|
-
|
|
391
|
+
function stepToJson(step) {
|
|
392
|
+
if (step instanceof SeqStep) return { f: step.field, k: step.key };
|
|
393
|
+
if (step instanceof FieldStep) return { f: step.field };
|
|
394
|
+
if (step instanceof SeqAccessStep) return { f: step.seqField, a: step.keyField };
|
|
395
|
+
return null;
|
|
390
396
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
warnRawDynStep("lookup", this);
|
|
404
|
-
return dval;
|
|
405
|
-
}
|
|
406
|
-
enterFrame(stack, _next) {
|
|
407
|
-
warnRawDynStep("enterFrame", this);
|
|
408
|
-
return stack;
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
var DynEachStep = class extends DynStep {
|
|
412
|
-
constructor(producerCompId, producerSteps, key) {
|
|
413
|
-
super(producerCompId, producerSteps);
|
|
414
|
-
this.key = key;
|
|
397
|
+
function stepFromJson(j) {
|
|
398
|
+
if (j == null || typeof j.f !== "string") return null;
|
|
399
|
+
if (j.k !== void 0) return new SeqStep(j.f, j.k);
|
|
400
|
+
if (j.a !== void 0) return new SeqAccessStep(j.f, j.a);
|
|
401
|
+
return new FieldStep(j.f);
|
|
402
|
+
}
|
|
403
|
+
function pathToJson(path2) {
|
|
404
|
+
const out = [];
|
|
405
|
+
for (const step of path2.steps) {
|
|
406
|
+
const j = stepToJson(step);
|
|
407
|
+
if (j === null) return null;
|
|
408
|
+
out.push(j);
|
|
415
409
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
410
|
+
return out;
|
|
411
|
+
}
|
|
412
|
+
function pathFromJson(j) {
|
|
413
|
+
if (!Array.isArray(j)) return null;
|
|
414
|
+
const steps = [];
|
|
415
|
+
for (const item of j) {
|
|
416
|
+
const step = stepFromJson(item);
|
|
417
|
+
if (step === null) return null;
|
|
418
|
+
steps.push(step);
|
|
425
419
|
}
|
|
426
|
-
|
|
420
|
+
return new Path(steps);
|
|
421
|
+
}
|
|
427
422
|
var Path = class _Path {
|
|
428
423
|
constructor(steps = []) {
|
|
429
424
|
this.steps = steps;
|
|
@@ -434,40 +429,13 @@ var Path = class _Path {
|
|
|
434
429
|
popStep() {
|
|
435
430
|
return new _Path(this.steps.slice(0, -1));
|
|
436
431
|
}
|
|
437
|
-
//
|
|
438
|
-
//
|
|
432
|
+
// Frame-only steps removed, one step per crossed component: `popStep` over the
|
|
433
|
+
// result bubbles through every component.
|
|
439
434
|
compact() {
|
|
440
435
|
const out = [];
|
|
441
436
|
for (const step of this.steps) {
|
|
442
437
|
const s = step.toAbstractPathStep();
|
|
443
|
-
if (s !== null)
|
|
444
|
-
if (s !== step) s._originCid = step._originCid;
|
|
445
|
-
out.push(s);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
return new _Path(out);
|
|
449
|
-
}
|
|
450
|
-
// The abstract path used to apply a transaction: every DynStep is teleported —
|
|
451
|
-
// the steps interior to its producer..consumer span are dropped and the
|
|
452
|
-
// producer's own path spliced in — so a mutation lands on the data's real
|
|
453
|
-
// location. A path with no DynStep is returned unchanged.
|
|
454
|
-
toTransactionPath() {
|
|
455
|
-
let hasDyn = false;
|
|
456
|
-
for (const step of this.steps)
|
|
457
|
-
if (step instanceof DynStep) {
|
|
458
|
-
hasDyn = true;
|
|
459
|
-
break;
|
|
460
|
-
}
|
|
461
|
-
if (!hasDyn) return this;
|
|
462
|
-
const out = [];
|
|
463
|
-
for (const step of this.steps) {
|
|
464
|
-
if (step instanceof DynStep) {
|
|
465
|
-
while (out.length > 0 && step.interiorCids.has(out[out.length - 1]._originCid)) out.pop();
|
|
466
|
-
for (const ts of step.teleportSteps()) {
|
|
467
|
-
ts._originCid = step.producerCompId;
|
|
468
|
-
out.push(ts);
|
|
469
|
-
}
|
|
470
|
-
} else out.push(step);
|
|
438
|
+
if (s !== null) out.push(s);
|
|
471
439
|
}
|
|
472
440
|
return new _Path(out);
|
|
473
441
|
}
|
|
@@ -475,7 +443,6 @@ var Path = class _Path {
|
|
|
475
443
|
// key as it is *now* so a later lookup/setValue lands on the same item even if the
|
|
476
444
|
// keyField changed meanwhile (e.g. the selected tab moved while an intent was in
|
|
477
445
|
// flight). Returns a new Path with those steps replaced; `this` if nothing pinned.
|
|
478
|
-
// Must be called on a transaction path (no DynSteps — call toTransactionPath first).
|
|
479
446
|
pinKeys(root) {
|
|
480
447
|
let curVal = root;
|
|
481
448
|
let out = null;
|
|
@@ -498,8 +465,8 @@ var Path = class _Path {
|
|
|
498
465
|
}
|
|
499
466
|
// The values entered along the path, root→leaf (root included): index 0 is `root`,
|
|
500
467
|
// the last entry is the leaf this path resolves to. Stops early at the first
|
|
501
|
-
// unresolvable step.
|
|
502
|
-
//
|
|
468
|
+
// unresolvable step. Used to walk the component instances on a dispatch path
|
|
469
|
+
// (filter via Components.getCompFor).
|
|
503
470
|
resolveChain(root) {
|
|
504
471
|
const out = [root];
|
|
505
472
|
let curVal = root;
|
|
@@ -513,7 +480,7 @@ var Path = class _Path {
|
|
|
513
480
|
// A flat `[{ field, key? }]` list of the addressing steps, skipping frame-only
|
|
514
481
|
// steps (binds). Generic path introspection so tooling (e.g. the storybook
|
|
515
482
|
// activity log) can identify which subtree a transaction touched without
|
|
516
|
-
// depending on Step internals.
|
|
483
|
+
// depending on Step internals.
|
|
517
484
|
toKeys() {
|
|
518
485
|
const out = [];
|
|
519
486
|
for (const step of this.steps) {
|
|
@@ -534,62 +501,147 @@ var Path = class _Path {
|
|
|
534
501
|
});
|
|
535
502
|
}
|
|
536
503
|
buildStack(stack) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
504
|
+
return walkItems(stack, this.steps, stack.renderPath ?? new DispatchPath(), this)?.[0] ?? null;
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
function walkItems(stack, items, renderPath, path2) {
|
|
508
|
+
let prev = stack.it;
|
|
509
|
+
for (const step of items) {
|
|
510
|
+
const next = step.lookup(prev, NONE);
|
|
511
|
+
if (next === NONE) {
|
|
512
|
+
console.warn("bad PathItem", { root: stack.it, step, path: path2 });
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
515
|
+
renderPath = renderPath.pushItem(step);
|
|
516
|
+
stack = step.enterFrame(stack, next, renderPath);
|
|
517
|
+
prev = next;
|
|
518
|
+
}
|
|
519
|
+
return [stack, renderPath];
|
|
520
|
+
}
|
|
521
|
+
var EMPTY_PATH = new Path([]);
|
|
522
|
+
var DispatchPath = class _DispatchPath {
|
|
523
|
+
constructor(frames = [{ base: EMPTY_PATH, items: [] }]) {
|
|
524
|
+
this.frames = frames;
|
|
525
|
+
}
|
|
526
|
+
// Plain addressing steps in one frame based at the root: what a caller means
|
|
527
|
+
// by "this position" when it has no continuation of its own.
|
|
528
|
+
static ofSteps(steps) {
|
|
529
|
+
return new _DispatchPath([{ base: EMPTY_PATH, items: steps.slice() }]);
|
|
530
|
+
}
|
|
531
|
+
get top() {
|
|
532
|
+
return this.frames[this.frames.length - 1];
|
|
533
|
+
}
|
|
534
|
+
_withTopItems(items) {
|
|
535
|
+
const frames = this.frames.slice();
|
|
536
|
+
frames[frames.length - 1] = { base: this.top.base, items };
|
|
537
|
+
return new _DispatchPath(frames);
|
|
538
|
+
}
|
|
539
|
+
concat(steps) {
|
|
540
|
+
if (this.frames.length === 0) return _DispatchPath.ofSteps(steps);
|
|
541
|
+
return this._withTopItems(this.top.items.concat(steps));
|
|
542
|
+
}
|
|
543
|
+
pushItem(step) {
|
|
544
|
+
return this.concat([step]);
|
|
545
|
+
}
|
|
546
|
+
pushFrame(base) {
|
|
547
|
+
return new _DispatchPath(this.frames.concat({ base, items: [] }));
|
|
548
|
+
}
|
|
549
|
+
// Whether bubbling has anywhere left to go: another step in this frame, or a
|
|
550
|
+
// visual caller underneath it.
|
|
551
|
+
canPop() {
|
|
552
|
+
const n = this.frames.length;
|
|
553
|
+
return n > 1 || n === 1 && this.frames[0].items.length > 0;
|
|
554
|
+
}
|
|
555
|
+
isRoot() {
|
|
556
|
+
return this.toTransactionPath().steps.length === 0;
|
|
557
|
+
}
|
|
558
|
+
// One component closer to the root. At the top of a frame that is popping back
|
|
559
|
+
// to the visual caller, not to the producer's own parent — the caller is where
|
|
560
|
+
// the `*name` was written, and where an unhandled message should keep going.
|
|
561
|
+
popStep() {
|
|
562
|
+
const n = this.frames.length;
|
|
563
|
+
if (n === 0) return this;
|
|
564
|
+
const top = this.frames[n - 1];
|
|
565
|
+
if (top.items.length > 0) return this._withTopItems(top.items.slice(0, -1));
|
|
566
|
+
if (n > 1) return new _DispatchPath(this.frames.slice(0, -1));
|
|
567
|
+
return this;
|
|
568
|
+
}
|
|
569
|
+
// Drop frame-only steps inside every frame independently; a frame's base is
|
|
570
|
+
// already addressing-only.
|
|
571
|
+
compact() {
|
|
572
|
+
return new _DispatchPath(
|
|
573
|
+
this.frames.map(({ base, items }) => ({ base, items: new Path(items).compact().steps }))
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
// A stable string for the ADDRESS this path denotes, for the render cache. The
|
|
577
|
+
// same immutable value can sit at two places in the tree, and a subtree rendered
|
|
578
|
+
// at one of them bakes that address in — the provides it publishes are located
|
|
579
|
+
// there. Frame-only steps address nothing, so they are compacted out: two sites
|
|
580
|
+
// that differ only in binds do render the same subtree.
|
|
581
|
+
get addressKey() {
|
|
582
|
+
this._addressKey ??= renderPathText(this.toTransactionPath().compact());
|
|
583
|
+
return this._addressKey;
|
|
584
|
+
}
|
|
585
|
+
// The active transaction address: the top frame's absolute base followed by
|
|
586
|
+
// its ordinary descendant steps. This is where a mutation lands.
|
|
587
|
+
toTransactionPath() {
|
|
588
|
+
const top = this.top;
|
|
589
|
+
return top === void 0 ? EMPTY_PATH : top.base.concat(top.items);
|
|
590
|
+
}
|
|
591
|
+
// Rebuild the render stack this path was dispatched from. A frame with a base
|
|
592
|
+
// re-enters at that absolute value first — replaying the resume a `*name`
|
|
593
|
+
// render performed — and then walks its ordinary items.
|
|
594
|
+
buildStack(stack) {
|
|
595
|
+
let renderPath = new _DispatchPath();
|
|
596
|
+
for (let i = 0; i < this.frames.length; i++) {
|
|
597
|
+
const { base, items } = this.frames[i];
|
|
598
|
+
if (i > 0 || base.steps.length > 0) {
|
|
599
|
+
const baseValue = base.lookup(stack.root, NONE);
|
|
600
|
+
if (baseValue === NONE) {
|
|
601
|
+
console.warn("bad frame base", { base, path: this });
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
604
|
+
renderPath = renderPath.pushFrame(base);
|
|
605
|
+
stack = stack.enter(baseValue, {}, true, renderPath);
|
|
543
606
|
}
|
|
544
|
-
|
|
545
|
-
|
|
607
|
+
const walked = walkItems(stack, items, renderPath, this);
|
|
608
|
+
if (walked === null) return null;
|
|
609
|
+
[stack, renderPath] = walked;
|
|
546
610
|
}
|
|
547
611
|
return stack;
|
|
548
612
|
}
|
|
549
613
|
static fromNodeAndEventName(node, eventName, rootNode, maxDepth, comps, stopOnNoEvent = true) {
|
|
550
|
-
const
|
|
551
|
-
const pendingDyns = [];
|
|
614
|
+
const parts = [];
|
|
552
615
|
const bubbles = BUBBLING_EVENTS.has(eventName);
|
|
553
616
|
let depth = 0;
|
|
554
617
|
let eventIds = [];
|
|
555
618
|
let handlers = null;
|
|
556
|
-
let
|
|
619
|
+
let nodeRefs = [];
|
|
557
620
|
let isLeafComponent = true;
|
|
558
621
|
const crossComponent = (cidNum, vid) => {
|
|
559
622
|
const comp = comps.getComponentForId(cidNum);
|
|
560
|
-
let
|
|
623
|
+
let pushPart = true;
|
|
561
624
|
if (handlers === null && (isLeafComponent || bubbles)) {
|
|
562
625
|
handlers = findHandlers(comp, eventIds, vid, eventName);
|
|
563
626
|
if (handlers === null) {
|
|
564
627
|
if (isLeafComponent && stopOnNoEvent && !bubbles) return false;
|
|
565
628
|
} else if (!isLeafComponent) {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
pushStep = false;
|
|
629
|
+
parts.length = 0;
|
|
630
|
+
pushPart = false;
|
|
569
631
|
}
|
|
570
632
|
}
|
|
571
633
|
isLeafComponent = false;
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
if (step) {
|
|
576
|
-
step._originCid = cidNum;
|
|
577
|
-
pathSteps.push(step);
|
|
578
|
-
if (step instanceof DynStep) {
|
|
579
|
-
step.interiorCids.add(cidNum);
|
|
580
|
-
pendingDyns.push(step);
|
|
581
|
-
}
|
|
582
|
-
}
|
|
634
|
+
if (pushPart) {
|
|
635
|
+
const part = resolvePathPart(comp, nodeRefs, vid);
|
|
636
|
+
if (part) parts.push(part);
|
|
583
637
|
}
|
|
584
|
-
for (let i = pendingDyns.length - 1; i >= 0; i--)
|
|
585
|
-
if (pendingDyns[i].producerCompId === cidNum) pendingDyns.splice(i, 1);
|
|
586
638
|
eventIds = [];
|
|
587
|
-
|
|
639
|
+
nodeRefs = [];
|
|
588
640
|
return true;
|
|
589
641
|
};
|
|
590
642
|
while (node && node !== rootNode && depth < maxDepth) {
|
|
591
643
|
if (node?.dataset) {
|
|
592
|
-
const { eid, cid, vid } = node.dataset;
|
|
644
|
+
const { eid, cid, vid, rp } = node.dataset;
|
|
593
645
|
if (eid !== void 0) eventIds.push(eid);
|
|
594
646
|
const metas = metaChain(node.previousSibling);
|
|
595
647
|
let sawComp = false;
|
|
@@ -597,21 +649,47 @@ var Path = class _Path {
|
|
|
597
649
|
if (m.$ === "Comp") {
|
|
598
650
|
sawComp = true;
|
|
599
651
|
if (!crossComponent(m.cid, m.vid)) return NO_EVENT_INFO;
|
|
600
|
-
|
|
652
|
+
nodeRefs.push({ nid: m.nid, base: pathFromJson(m.base) });
|
|
601
653
|
} else {
|
|
602
|
-
|
|
654
|
+
nodeRefs.push({ nid: m.nid, si: m.si, sk: m.sk });
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (!sawComp && cid !== void 0) {
|
|
658
|
+
if (!crossComponent(+cid, vid)) return NO_EVENT_INFO;
|
|
659
|
+
if (rp !== void 0) {
|
|
660
|
+
const base = parseRenderPath(rp);
|
|
661
|
+
if (base !== null) nodeRefs.push({ base });
|
|
603
662
|
}
|
|
604
663
|
}
|
|
605
|
-
if (!sawComp && cid !== void 0 && !crossComponent(+cid, vid)) return NO_EVENT_INFO;
|
|
606
664
|
}
|
|
607
665
|
depth += 1;
|
|
608
666
|
node = node.parentNode;
|
|
609
667
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
668
|
+
parts.reverse();
|
|
669
|
+
let path2 = new _DispatchPath();
|
|
670
|
+
for (const part of parts)
|
|
671
|
+
path2 = part.base !== void 0 ? path2.pushFrame(part.base) : path2.pushItem(part.step);
|
|
672
|
+
return [path2, handlers];
|
|
613
673
|
}
|
|
614
674
|
};
|
|
675
|
+
function keyedPath(path2, key) {
|
|
676
|
+
const steps = path2.steps;
|
|
677
|
+
const last = steps[steps.length - 1];
|
|
678
|
+
if (last instanceof SeqStep || last instanceof FieldStep)
|
|
679
|
+
return new Path(steps.slice(0, -1).concat(new SeqStep(last.field, key)));
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
function renderPathText(path2) {
|
|
683
|
+
return JSON.stringify(pathToJson(path2));
|
|
684
|
+
}
|
|
685
|
+
function parseRenderPath(text) {
|
|
686
|
+
try {
|
|
687
|
+
return pathFromJson(JSON.parse(text));
|
|
688
|
+
} catch (err) {
|
|
689
|
+
console.warn("bad render path", err, text);
|
|
690
|
+
return null;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
615
693
|
function metaChain(n) {
|
|
616
694
|
const out = [];
|
|
617
695
|
while (n?.nodeType === 8 && n.textContent[0] === "§") {
|
|
@@ -664,20 +742,27 @@ var StepCtx = class _StepCtx {
|
|
|
664
742
|
return pi;
|
|
665
743
|
}
|
|
666
744
|
};
|
|
667
|
-
function
|
|
668
|
-
for (let i = 0; i <
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
if (
|
|
745
|
+
function resolvePathPart(comp, nodeRefs, vid) {
|
|
746
|
+
for (let i = 0; i < nodeRefs.length; i++) {
|
|
747
|
+
const ref = nodeRefs[i];
|
|
748
|
+
if (ref.base != null) return { base: ref.base };
|
|
749
|
+
if (ref.nid === void 0 || ref.nid === null) continue;
|
|
750
|
+
const ctx = new StepCtx(comp, nodeRefs, i, vid);
|
|
751
|
+
const step = ctx.resolveNode()?.toPathStep(ctx) ?? null;
|
|
752
|
+
if (step !== null) return { step };
|
|
672
753
|
}
|
|
673
754
|
return null;
|
|
674
755
|
}
|
|
675
756
|
var NO_EVENT_INFO = [null, null];
|
|
676
757
|
var BUBBLING_EVENTS = /* @__PURE__ */ new Set(["drop"]);
|
|
758
|
+
var path = () => new PathBuilder();
|
|
677
759
|
var PathBuilder = class {
|
|
678
760
|
constructor() {
|
|
679
761
|
this.pathChanges = [];
|
|
680
762
|
}
|
|
763
|
+
toPath() {
|
|
764
|
+
return new Path(this.pathChanges);
|
|
765
|
+
}
|
|
681
766
|
add(pathChange) {
|
|
682
767
|
this.pathChanges.push(pathChange);
|
|
683
768
|
return this;
|
|
@@ -1834,13 +1919,16 @@ function h(tagName, properties, children, namespace) {
|
|
|
1834
1919
|
}
|
|
1835
1920
|
|
|
1836
1921
|
// src/anode.js
|
|
1837
|
-
function
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1922
|
+
function renderTarget(val, stack) {
|
|
1923
|
+
if (val instanceof DynVal) {
|
|
1924
|
+
const loc = stack.lookupDynamicLocated(val.name);
|
|
1925
|
+
if (loc?.path == null) return [loc?.value ?? null, stack.renderPath, null];
|
|
1926
|
+
return [loc.value, stack.renderPath.pushFrame(loc.path), loc.path];
|
|
1927
|
+
}
|
|
1928
|
+
const step = val.toPathItem?.() ?? null;
|
|
1929
|
+
if (step === null) return [val.eval(stack), stack.renderPath, null];
|
|
1930
|
+
const path2 = stack.renderPath.pushItem(step);
|
|
1931
|
+
return [val.eval(stack), path2, stack.pendingFrame ? path2.toTransactionPath() : null];
|
|
1844
1932
|
}
|
|
1845
1933
|
var BaseNode = class {
|
|
1846
1934
|
render(_stack, _rx) {
|
|
@@ -2162,33 +2250,31 @@ var RenderViewId = class extends ANode {
|
|
|
2162
2250
|
setDataAttr(_key, _val) {
|
|
2163
2251
|
}
|
|
2164
2252
|
};
|
|
2165
|
-
function dynRenderStep(comp, name, key) {
|
|
2166
|
-
const p = resolveDynProducer(comp, name);
|
|
2167
|
-
if (!p) return null;
|
|
2168
|
-
return key === void 0 ? new DynStep(p.producerCompId, p.producerSteps) : new DynEachStep(p.producerCompId, p.producerSteps, key);
|
|
2169
|
-
}
|
|
2170
2253
|
var RenderNode = class extends RenderViewId {
|
|
2171
2254
|
render(stack, rx) {
|
|
2172
|
-
const
|
|
2173
|
-
|
|
2255
|
+
const [value, renderPath, base] = renderTarget(this.val, stack);
|
|
2256
|
+
const newStack = stack.enter(value, {}, true, renderPath, false);
|
|
2257
|
+
return rx.renderIt(newStack, this, "", this.evalViewName(stack), base);
|
|
2174
2258
|
}
|
|
2259
|
+
// A `*name` target contributes no step: the site recorded the absolute base it
|
|
2260
|
+
// resumed at, and event reconstruction turns that into a continuation frame.
|
|
2175
2261
|
toPathStep(ctx) {
|
|
2176
|
-
if (this.val instanceof DynVal) return
|
|
2262
|
+
if (this.val instanceof DynVal) return null;
|
|
2177
2263
|
return super.toPathStep(ctx);
|
|
2178
2264
|
}
|
|
2179
2265
|
};
|
|
2180
2266
|
var RenderItNode = class extends RenderViewId {
|
|
2181
2267
|
render(stack, rx) {
|
|
2182
|
-
const
|
|
2183
|
-
|
|
2268
|
+
const base = stack.pendingFrame ? stack.renderPath.toTransactionPath() : null;
|
|
2269
|
+
const newStack = stack.enter(stack.it, {}, true, stack.renderPath, false);
|
|
2270
|
+
return rx.renderIt(newStack, this, "", this.evalViewName(stack), base);
|
|
2184
2271
|
}
|
|
2185
2272
|
toPathStep(ctx) {
|
|
2186
2273
|
const next = ctx.next();
|
|
2187
2274
|
if (next === null) return null;
|
|
2188
2275
|
const nextNode = next.resolveNode();
|
|
2189
2276
|
if (nextNode instanceof EachNode && next.hasKey) {
|
|
2190
|
-
if (nextNode.val instanceof DynVal)
|
|
2191
|
-
return dynRenderStep(ctx.comp, nextNode.val.name, next.key);
|
|
2277
|
+
if (nextNode.val instanceof DynVal) return null;
|
|
2192
2278
|
return new EachRenderItStep(nextNode.val.name, next.key);
|
|
2193
2279
|
}
|
|
2194
2280
|
return null;
|
|
@@ -2290,11 +2376,19 @@ var EachNode = class extends WrapperNode {
|
|
|
2290
2376
|
this.iterInfo = new IterInfo(val, null, null, null);
|
|
2291
2377
|
}
|
|
2292
2378
|
render(stack, rx) {
|
|
2293
|
-
return rx.renderEachWhen(stack, this
|
|
2379
|
+
return rx.renderEachWhen(stack, this);
|
|
2294
2380
|
}
|
|
2295
2381
|
toPathStep(ctx) {
|
|
2296
2382
|
return ctx.hasKey ? new EachBindStep(this.iterInfo, ctx.key) : null;
|
|
2297
2383
|
}
|
|
2384
|
+
// Where one item lives, for the render path. `@each` re-binds `it` to the item
|
|
2385
|
+
// whether or not the body is a component, so the position moves either way and
|
|
2386
|
+
// the step has to address it — `.rows` iterated at `key` IS `rows[key]`.
|
|
2387
|
+
// Null for a dynamic sequence: `*rows` carries its own absolute path and enters
|
|
2388
|
+
// a continuation frame instead (see Renderer.renderEachWhen).
|
|
2389
|
+
itemStep(key) {
|
|
2390
|
+
return this.val instanceof FieldVal ? new SeqStep(this.val.name, key) : null;
|
|
2391
|
+
}
|
|
2298
2392
|
static register = true;
|
|
2299
2393
|
};
|
|
2300
2394
|
var IterInfo = class {
|
|
@@ -2633,6 +2727,215 @@ function collectAppClassesInSet(app) {
|
|
|
2633
2727
|
return classes;
|
|
2634
2728
|
}
|
|
2635
2729
|
|
|
2730
|
+
// src/stack.js
|
|
2731
|
+
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
2732
|
+
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
2733
|
+
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
2734
|
+
function routeLookup(route, lex, dyn) {
|
|
2735
|
+
for (let i = 0; i < route.length; i++) {
|
|
2736
|
+
const leg = route[i];
|
|
2737
|
+
if (leg === "dyn") {
|
|
2738
|
+
const v = dyn();
|
|
2739
|
+
if (v != null) return v;
|
|
2740
|
+
} else if (leg === "lex") {
|
|
2741
|
+
const v = lex();
|
|
2742
|
+
if (v != null) return v;
|
|
2743
|
+
} else {
|
|
2744
|
+
console.warn("unknown lookup route leg", leg, '- expected "dyn" or "lex"');
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
return null;
|
|
2748
|
+
}
|
|
2749
|
+
var isTypeName = (s) => {
|
|
2750
|
+
const c = s.charCodeAt(0);
|
|
2751
|
+
return c >= 65 && c <= 90;
|
|
2752
|
+
};
|
|
2753
|
+
function lookup(chain, name, dv = null) {
|
|
2754
|
+
let n = chain;
|
|
2755
|
+
while (n !== null) {
|
|
2756
|
+
const r = n[0].lookup(name);
|
|
2757
|
+
if (r === STOP) return dv;
|
|
2758
|
+
if (r !== NEXT) return r;
|
|
2759
|
+
n = n[1];
|
|
2760
|
+
}
|
|
2761
|
+
return dv;
|
|
2762
|
+
}
|
|
2763
|
+
var BindFrame = class {
|
|
2764
|
+
constructor(it, binds, isFrame) {
|
|
2765
|
+
this.it = it;
|
|
2766
|
+
this.binds = binds;
|
|
2767
|
+
this.isFrame = isFrame;
|
|
2768
|
+
}
|
|
2769
|
+
lookup(name) {
|
|
2770
|
+
const v = this.binds[name];
|
|
2771
|
+
return v === void 0 ? this.isFrame ? STOP : NEXT : v;
|
|
2772
|
+
}
|
|
2773
|
+
};
|
|
2774
|
+
var DynFrame = class {
|
|
2775
|
+
constructor(binds, types) {
|
|
2776
|
+
this.binds = binds;
|
|
2777
|
+
this.types = types;
|
|
2778
|
+
}
|
|
2779
|
+
lookup(name) {
|
|
2780
|
+
const v = (isTypeName(name) ? this.types : this.binds)[name];
|
|
2781
|
+
return v === void 0 ? NEXT : v;
|
|
2782
|
+
}
|
|
2783
|
+
};
|
|
2784
|
+
function computeViewsId(views) {
|
|
2785
|
+
let s = "";
|
|
2786
|
+
let n = views;
|
|
2787
|
+
while (n !== null) {
|
|
2788
|
+
s += n[0];
|
|
2789
|
+
n = n[1];
|
|
2790
|
+
}
|
|
2791
|
+
return s === "main" ? "" : s;
|
|
2792
|
+
}
|
|
2793
|
+
var Stack = class _Stack {
|
|
2794
|
+
constructor(fields) {
|
|
2795
|
+
Object.assign(this, fields);
|
|
2796
|
+
}
|
|
2797
|
+
_with(patch) {
|
|
2798
|
+
return new _Stack({ ...this, ...patch });
|
|
2799
|
+
}
|
|
2800
|
+
// Evaluate every provide the entered component publishes and push them as one
|
|
2801
|
+
// dynBinds frame, keyed by NAME. A value is published together with the absolute
|
|
2802
|
+
// path it lives at: the same declaration is read as `*name` AND resumed at by
|
|
2803
|
+
// `<x render="*name">`, so a consumer needs both halves. Types go in the same
|
|
2804
|
+
// frame's other map. No-op with no provides.
|
|
2805
|
+
_pushProvides() {
|
|
2806
|
+
const comp = this.comps.getCompFor(this.it);
|
|
2807
|
+
if (comp == null) return this;
|
|
2808
|
+
const { provide, provideType } = comp;
|
|
2809
|
+
const binds = {};
|
|
2810
|
+
const types = {};
|
|
2811
|
+
let has = false;
|
|
2812
|
+
const base = this._publishBase();
|
|
2813
|
+
for (const k in provide) {
|
|
2814
|
+
const step = provide[k].val.toPathItem?.() ?? null;
|
|
2815
|
+
if (step === null) continue;
|
|
2816
|
+
const value = provide[k].val.eval(this);
|
|
2817
|
+
binds[k] = { value, path: base === null ? null : base.concat([step]) };
|
|
2818
|
+
has = true;
|
|
2819
|
+
}
|
|
2820
|
+
for (const k in provideType) {
|
|
2821
|
+
types[k] = provideType[k];
|
|
2822
|
+
has = true;
|
|
2823
|
+
}
|
|
2824
|
+
if (!has) return this;
|
|
2825
|
+
return this._with({ dynBinds: [new DynFrame(binds, types), this.dynBinds] });
|
|
2826
|
+
}
|
|
2827
|
+
// The absolute address of the component being entered, or null when this
|
|
2828
|
+
// position cannot be written down as one. Frame-only steps carry bindings and
|
|
2829
|
+
// address nothing, so they are compacted away first; what is left is checked
|
|
2830
|
+
// against the value actually being rendered, because a scope CAN move the
|
|
2831
|
+
// render position without contributing an addressing step (a plain `@each`
|
|
2832
|
+
// body re-binds `it` to the item while its rebuild step is an identity).
|
|
2833
|
+
//
|
|
2834
|
+
// A null base still publishes the VALUE — `*name` reads it fine — but there is
|
|
2835
|
+
// nowhere to resume, so `<x render="*name">` renders nothing rather than
|
|
2836
|
+
// editing whatever happens to live at the address we guessed.
|
|
2837
|
+
_publishBase() {
|
|
2838
|
+
const base = this.renderPath.toTransactionPath().compact();
|
|
2839
|
+
return base.lookup(this.root, NOT_FOUND) === this.it ? base : null;
|
|
2840
|
+
}
|
|
2841
|
+
static root(comps, it, ctx = null) {
|
|
2842
|
+
return new _Stack({
|
|
2843
|
+
comps,
|
|
2844
|
+
root: it,
|
|
2845
|
+
it,
|
|
2846
|
+
binds: [new BindFrame(it, {}, true), null],
|
|
2847
|
+
dynBinds: [new DynFrame({}, {}), null],
|
|
2848
|
+
views: ["main", null],
|
|
2849
|
+
viewsId: "",
|
|
2850
|
+
renderPath: new DispatchPath(),
|
|
2851
|
+
pendingFrame: false,
|
|
2852
|
+
ctx
|
|
2853
|
+
})._pushProvides();
|
|
2854
|
+
}
|
|
2855
|
+
// `renderPath` defaults to this stack's own: an ordinary scope does not move.
|
|
2856
|
+
// `pendingFrame` clears on a component frame (which emits the base) and is
|
|
2857
|
+
// inherited by transparent scopes, which have to carry it to the next boundary.
|
|
2858
|
+
enter(it, bindings = {}, isFrame = true, renderPath = this.renderPath, pendingFrame = null) {
|
|
2859
|
+
const stack = this._with({
|
|
2860
|
+
it,
|
|
2861
|
+
binds: [new BindFrame(it, bindings, isFrame), this.binds],
|
|
2862
|
+
renderPath,
|
|
2863
|
+
pendingFrame: pendingFrame ?? (isFrame ? false : this.pendingFrame)
|
|
2864
|
+
});
|
|
2865
|
+
return isFrame ? stack._pushProvides() : stack;
|
|
2866
|
+
}
|
|
2867
|
+
pushViewName(name) {
|
|
2868
|
+
const views = [name, this.views];
|
|
2869
|
+
return this._with({ views, viewsId: computeViewsId(views) });
|
|
2870
|
+
}
|
|
2871
|
+
// Published types are stable per scope and would only churn the render cache, so
|
|
2872
|
+
// the cache key covers values alone.
|
|
2873
|
+
_pushDynBindValuesToArray(arr, comp) {
|
|
2874
|
+
for (const k in comp.provide) arr.push(this.lookupDynamic(k));
|
|
2875
|
+
for (const k in comp.lookup) arr.push(this.lookupDynamic(k));
|
|
2876
|
+
}
|
|
2877
|
+
// `*name`: the nearest binding above (including this component's own provides,
|
|
2878
|
+
// pushed on entering it), else a path registered in the component's lexical
|
|
2879
|
+
// scope, else this component's declared default, else null.
|
|
2880
|
+
//
|
|
2881
|
+
// One chain walk and no producer resolution: a lookup names what it WANTS, so the
|
|
2882
|
+
// frame it wants is keyed by that name. The default belongs to the CONSUMER's
|
|
2883
|
+
// declaration and is evaluated against the consumer's stack, which is why it is
|
|
2884
|
+
// consulted only after the whole chain has missed.
|
|
2885
|
+
lookupDynamicLocated(name) {
|
|
2886
|
+
if (isTypeName(name)) return null;
|
|
2887
|
+
const v = lookup(this.dynBinds, name);
|
|
2888
|
+
if (v != null) return v;
|
|
2889
|
+
const comp = this.comps.getCompFor(this.it);
|
|
2890
|
+
if (comp == null) return null;
|
|
2891
|
+
const path2 = comp.scope?.lookupPath?.(name) ?? null;
|
|
2892
|
+
if (path2 !== null) {
|
|
2893
|
+
const value2 = path2.lookup(this.root, NOT_FOUND);
|
|
2894
|
+
if (value2 !== NOT_FOUND) return { value: value2, path: path2 };
|
|
2895
|
+
}
|
|
2896
|
+
const dval = comp.lookup[name]?.val ?? null;
|
|
2897
|
+
if (dval === null) return null;
|
|
2898
|
+
const step = dval.toPathItem?.() ?? null;
|
|
2899
|
+
const value = dval.eval(this);
|
|
2900
|
+
return step === null ? { value, path: null } : { value, path: this.renderPath.toTransactionPath().concat([step]) };
|
|
2901
|
+
}
|
|
2902
|
+
lookupDynamic(name) {
|
|
2903
|
+
if (isTypeName(name)) return lookup(this.dynBinds, name);
|
|
2904
|
+
return this.lookupDynamicLocated(name)?.value ?? null;
|
|
2905
|
+
}
|
|
2906
|
+
lookupBind(name) {
|
|
2907
|
+
return lookup(this.binds, name);
|
|
2908
|
+
}
|
|
2909
|
+
lookupFieldRaw(name) {
|
|
2910
|
+
return this.it[name] ?? null;
|
|
2911
|
+
}
|
|
2912
|
+
lookupMethod(name) {
|
|
2913
|
+
const fn = this.it[name];
|
|
2914
|
+
return fn instanceof Function ? fn.call(this.it) : null;
|
|
2915
|
+
}
|
|
2916
|
+
// The dispatched DOM event / drag info, read only by EventMemberVal's
|
|
2917
|
+
// `e.<member>` handler args. Null outside a live event transaction.
|
|
2918
|
+
lookupEvent() {
|
|
2919
|
+
return this.ctx?.event ?? null;
|
|
2920
|
+
}
|
|
2921
|
+
lookupDragInfo() {
|
|
2922
|
+
return this.ctx?.dragInfo ?? null;
|
|
2923
|
+
}
|
|
2924
|
+
getHandlerFor(name, key) {
|
|
2925
|
+
return this.comps.getHandlerFor(this.it, name, key);
|
|
2926
|
+
}
|
|
2927
|
+
lookupBestView(views, defaultViewName) {
|
|
2928
|
+
let n = this.views;
|
|
2929
|
+
while (n !== null) {
|
|
2930
|
+
const view = views[n[0]];
|
|
2931
|
+
if (view !== void 0) return view;
|
|
2932
|
+
n = n[1];
|
|
2933
|
+
}
|
|
2934
|
+
return views[defaultViewName];
|
|
2935
|
+
}
|
|
2936
|
+
};
|
|
2937
|
+
var NOT_FOUND = /* @__PURE__ */ Symbol("NOT_FOUND");
|
|
2938
|
+
|
|
2636
2939
|
// src/components.js
|
|
2637
2940
|
var COMPONENT = /* @__PURE__ */ Symbol.for("tutuca.component");
|
|
2638
2941
|
var Components = class {
|
|
@@ -2671,12 +2974,14 @@ var ComponentStack = class _ComponentStack {
|
|
|
2671
2974
|
this.byName = {};
|
|
2672
2975
|
this.intentsByName = {};
|
|
2673
2976
|
this.macros = {};
|
|
2977
|
+
this.paths = {};
|
|
2674
2978
|
}
|
|
2675
2979
|
enter() {
|
|
2676
2980
|
return new _ComponentStack(this.comps, this);
|
|
2677
2981
|
}
|
|
2678
2982
|
registerComponents(comps, opts) {
|
|
2679
|
-
const { aliases = {} } = opts ?? {};
|
|
2983
|
+
const { aliases = {}, paths } = opts ?? {};
|
|
2984
|
+
if (paths) this.registerPaths(paths);
|
|
2680
2985
|
for (let i = 0; i < comps.length; i++) {
|
|
2681
2986
|
const Comp = comps[i];
|
|
2682
2987
|
Comp[COMPONENT].scope = this.enter();
|
|
@@ -2690,6 +2995,27 @@ var ComponentStack = class _ComponentStack {
|
|
|
2690
2995
|
else console.warn("alias", alias, "to inexistent component", aliases[alias]);
|
|
2691
2996
|
}
|
|
2692
2997
|
}
|
|
2998
|
+
// Register lowercase names as absolute paths from the app state root. A
|
|
2999
|
+
// descendant that declares one in its `lookup` reads and renders `*name` without
|
|
3000
|
+
// anything above it publishing one — which is what makes a session, a theme or a
|
|
3001
|
+
// host-owned value available in its natural registration scope, instead of forcing
|
|
3002
|
+
// an application root whose only job is to `provide` it. Register on a nested
|
|
3003
|
+
// scope to narrow a name; nearest registration wins.
|
|
3004
|
+
//
|
|
3005
|
+
// Uppercase names are ignored: a component TYPE is what `lookupComponent` already
|
|
3006
|
+
// answers, and a type has no path.
|
|
3007
|
+
registerPaths(paths) {
|
|
3008
|
+
for (const name in paths) {
|
|
3009
|
+
if (isTypeName(name)) {
|
|
3010
|
+
console.warn("registerPaths: a type name has no path", name);
|
|
3011
|
+
continue;
|
|
3012
|
+
}
|
|
3013
|
+
this.paths[name] = paths[name].toPath?.() ?? paths[name];
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
lookupPath(name) {
|
|
3017
|
+
return this.paths[name] ?? this.parent?.lookupPath(name) ?? null;
|
|
3018
|
+
}
|
|
2693
3019
|
registerMacros(macros) {
|
|
2694
3020
|
for (const key in macros) {
|
|
2695
3021
|
const lower = key.toLowerCase();
|
|
@@ -2721,17 +3047,16 @@ var ComponentStack = class _ComponentStack {
|
|
|
2721
3047
|
lookupComponent(name) {
|
|
2722
3048
|
return this.byName[name] ?? this.parent?.lookupComponent(name) ?? null;
|
|
2723
3049
|
}
|
|
2724
|
-
//
|
|
2725
|
-
// names
|
|
2726
|
-
//
|
|
2727
|
-
//
|
|
2728
|
-
//
|
|
2729
|
-
|
|
3050
|
+
// Whether anything in this scope chain provides `name`. Existence only: a lookup
|
|
3051
|
+
// names what it WANTS and takes whoever is nearest above it at render time, so
|
|
3052
|
+
// there is no producer to identify — several components may publish one name and
|
|
3053
|
+
// the live render ancestry decides. Used by the linter to tell a lookup that can
|
|
3054
|
+
// be satisfied from one that never will be.
|
|
3055
|
+
hasProvider(name) {
|
|
2730
3056
|
for (const compName in this.byName) {
|
|
2731
|
-
|
|
2732
|
-
if (Comp.provide?.[name] !== void 0) return Comp;
|
|
3057
|
+
if (this.byName[compName].provide?.[name] !== void 0) return true;
|
|
2733
3058
|
}
|
|
2734
|
-
return this.parent?.
|
|
3059
|
+
return this.parent?.hasProvider(name) ?? false;
|
|
2735
3060
|
}
|
|
2736
3061
|
lookupMacro(name) {
|
|
2737
3062
|
return this.macros[name] ?? this.parent?.lookupMacro(name) ?? null;
|
|
@@ -2748,10 +3073,6 @@ var LookupInfo = class {
|
|
|
2748
3073
|
}
|
|
2749
3074
|
};
|
|
2750
3075
|
var isString = (v) => typeof v === "string";
|
|
2751
|
-
var isTypeName = (s) => {
|
|
2752
|
-
const c = s.charCodeAt(0);
|
|
2753
|
-
return c >= 65 && c <= 90;
|
|
2754
|
-
};
|
|
2755
3076
|
var _rawSpecKeys = "name view style commonStyle globalStyle receive intent alter views provide lookup fields methods statics";
|
|
2756
3077
|
var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
2757
3078
|
var _compId = 0;
|
|
@@ -5115,7 +5436,6 @@ var DYN_VAL_NOT_DEFINED = "DYN_VAL_NOT_DEFINED";
|
|
|
5115
5436
|
var DYN_ALIAS_NOT_REFERENCED = "DYN_ALIAS_NOT_REFERENCED";
|
|
5116
5437
|
var PROVIDE_NOT_ADDRESSABLE = "PROVIDE_NOT_ADDRESSABLE";
|
|
5117
5438
|
var PROVIDE_TYPE_BAD_SHAPE = "PROVIDE_TYPE_BAD_SHAPE";
|
|
5118
|
-
var PROVIDE_NAME_COLLISION = "PROVIDE_NAME_COLLISION";
|
|
5119
5439
|
var LOOKUP_BAD_SHAPE = "LOOKUP_BAD_SHAPE";
|
|
5120
5440
|
var LOOKUP_NO_PROVIDER = "LOOKUP_NO_PROVIDER";
|
|
5121
5441
|
var RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP";
|
|
@@ -5238,7 +5558,6 @@ function checkComponent(Comp, lx = new LintContext(), { wellKnownExtras = EMPTY_
|
|
|
5238
5558
|
checkFieldMethodNameCollisions(lx, Comp);
|
|
5239
5559
|
checkProvidesAreAddressable(lx, Comp);
|
|
5240
5560
|
checkProvidedTypes(lx, Comp);
|
|
5241
|
-
checkProvideNameCollisions(lx, Comp);
|
|
5242
5561
|
checkLookupShapes(lx, Comp);
|
|
5243
5562
|
checkLookupTypesResolve(lx, Comp);
|
|
5244
5563
|
checkLookupsHaveProviders(lx, Comp);
|
|
@@ -5922,19 +6241,6 @@ function checkProvidedTypes(lx, Comp) {
|
|
|
5922
6241
|
if (raw !== "self") lx.error(PROVIDE_TYPE_BAD_SHAPE, { name, value: raw });
|
|
5923
6242
|
}
|
|
5924
6243
|
}
|
|
5925
|
-
function checkProvideNameCollisions(lx, Comp) {
|
|
5926
|
-
const scope = Comp.scope;
|
|
5927
|
-
if (!scope) return;
|
|
5928
|
-
for (const name in Comp.provide) {
|
|
5929
|
-
for (let s = scope; s; s = s.parent) {
|
|
5930
|
-
for (const otherName in s.byName) {
|
|
5931
|
-
const Other = s.byName[otherName];
|
|
5932
|
-
if (Other !== Comp && Other.provide?.[name] !== void 0)
|
|
5933
|
-
lx.error(PROVIDE_NAME_COLLISION, { name, other: Other.name });
|
|
5934
|
-
}
|
|
5935
|
-
}
|
|
5936
|
-
}
|
|
5937
|
-
}
|
|
5938
6244
|
var KNOWN_LOOKUP_KEYS = /* @__PURE__ */ new Set(["name", "default"]);
|
|
5939
6245
|
function checkLookupShapes(lx, Comp) {
|
|
5940
6246
|
const raw = Comp._rawLookup;
|
|
@@ -5976,7 +6282,7 @@ function checkLookupsHaveProviders(lx, Comp) {
|
|
|
5976
6282
|
if (!scope) return;
|
|
5977
6283
|
for (const name in Comp.lookup) {
|
|
5978
6284
|
if (isTypeName2(name)) continue;
|
|
5979
|
-
if (scope.
|
|
6285
|
+
if (scope.hasProvider?.(name) || scope.lookupPath?.(name)) continue;
|
|
5980
6286
|
const info = { name, hasDefault: Comp.lookup[name].val != null };
|
|
5981
6287
|
if (info.hasDefault) lx.hint(LOOKUP_NO_PROVIDER, info);
|
|
5982
6288
|
else lx.error(LOOKUP_NO_PROVIDER, info);
|
|
@@ -6336,160 +6642,6 @@ Component.fromSpec = (opts) => {
|
|
|
6336
6642
|
};
|
|
6337
6643
|
var component = (opts) => Component.fromSpec(opts);
|
|
6338
6644
|
|
|
6339
|
-
// src/stack.js
|
|
6340
|
-
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
6341
|
-
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
6342
|
-
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
6343
|
-
function routeLookup(route, lex, dyn) {
|
|
6344
|
-
for (let i = 0; i < route.length; i++) {
|
|
6345
|
-
const leg = route[i];
|
|
6346
|
-
if (leg === "dyn") {
|
|
6347
|
-
const v = dyn();
|
|
6348
|
-
if (v != null) return v;
|
|
6349
|
-
} else if (leg === "lex") {
|
|
6350
|
-
const v = lex();
|
|
6351
|
-
if (v != null) return v;
|
|
6352
|
-
} else {
|
|
6353
|
-
console.warn("unknown lookup route leg", leg, '- expected "dyn" or "lex"');
|
|
6354
|
-
}
|
|
6355
|
-
}
|
|
6356
|
-
return null;
|
|
6357
|
-
}
|
|
6358
|
-
function lookup(chain, name, dv = null) {
|
|
6359
|
-
let n = chain;
|
|
6360
|
-
while (n !== null) {
|
|
6361
|
-
const r = n[0].lookup(name);
|
|
6362
|
-
if (r === STOP) return dv;
|
|
6363
|
-
if (r !== NEXT) return r;
|
|
6364
|
-
n = n[1];
|
|
6365
|
-
}
|
|
6366
|
-
return dv;
|
|
6367
|
-
}
|
|
6368
|
-
var BindFrame = class {
|
|
6369
|
-
constructor(it, binds, isFrame) {
|
|
6370
|
-
this.it = it;
|
|
6371
|
-
this.binds = binds;
|
|
6372
|
-
this.isFrame = isFrame;
|
|
6373
|
-
}
|
|
6374
|
-
lookup(name) {
|
|
6375
|
-
const v = this.binds[name];
|
|
6376
|
-
return v === void 0 ? this.isFrame ? STOP : NEXT : v;
|
|
6377
|
-
}
|
|
6378
|
-
};
|
|
6379
|
-
var ObjectFrame = class {
|
|
6380
|
-
constructor(binds) {
|
|
6381
|
-
this.binds = binds;
|
|
6382
|
-
}
|
|
6383
|
-
lookup(key) {
|
|
6384
|
-
const v = this.binds[key];
|
|
6385
|
-
return v === void 0 ? NEXT : v;
|
|
6386
|
-
}
|
|
6387
|
-
};
|
|
6388
|
-
function computeViewsId(views) {
|
|
6389
|
-
let s = "";
|
|
6390
|
-
let n = views;
|
|
6391
|
-
while (n !== null) {
|
|
6392
|
-
s += n[0];
|
|
6393
|
-
n = n[1];
|
|
6394
|
-
}
|
|
6395
|
-
return s === "main" ? "" : s;
|
|
6396
|
-
}
|
|
6397
|
-
var Stack = class _Stack {
|
|
6398
|
-
constructor(comps, it, binds, dynBinds, views, viewsId, ctx = null) {
|
|
6399
|
-
this.comps = comps;
|
|
6400
|
-
this.it = it;
|
|
6401
|
-
this.binds = binds;
|
|
6402
|
-
this.dynBinds = dynBinds;
|
|
6403
|
-
this.views = views;
|
|
6404
|
-
this.viewsId = viewsId;
|
|
6405
|
-
this.ctx = ctx;
|
|
6406
|
-
}
|
|
6407
|
-
// Evaluate every provide the entered component publishes and push them as one
|
|
6408
|
-
// dynBinds frame, keyed by NAME. Published types go in the same frame: a type name
|
|
6409
|
-
// starts A-Z and a value name does not, so the two namespaces cannot collide and
|
|
6410
|
-
// nearest-ancestor-wins falls out of frame order for both. No-op with no provides.
|
|
6411
|
-
_pushProvides() {
|
|
6412
|
-
const comp = this.comps.getCompFor(this.it);
|
|
6413
|
-
if (comp == null) return this;
|
|
6414
|
-
const { provide, provideType } = comp;
|
|
6415
|
-
const dynObj = {};
|
|
6416
|
-
let has = false;
|
|
6417
|
-
for (const k in provide) {
|
|
6418
|
-
dynObj[k] = provide[k].val.eval(this);
|
|
6419
|
-
has = true;
|
|
6420
|
-
}
|
|
6421
|
-
for (const k in provideType) {
|
|
6422
|
-
dynObj[k] = provideType[k];
|
|
6423
|
-
has = true;
|
|
6424
|
-
}
|
|
6425
|
-
if (!has) return this;
|
|
6426
|
-
const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
|
|
6427
|
-
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
6428
|
-
return new _Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
|
|
6429
|
-
}
|
|
6430
|
-
static root(comps, it, ctx) {
|
|
6431
|
-
const binds = [new BindFrame(it, {}, true), null];
|
|
6432
|
-
const dynBinds = [new ObjectFrame({}), null];
|
|
6433
|
-
const views = ["main", null];
|
|
6434
|
-
return new _Stack(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();
|
|
6435
|
-
}
|
|
6436
|
-
enter(it, bindings = {}, isFrame = true) {
|
|
6437
|
-
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
6438
|
-
const newBinds = [new BindFrame(it, bindings, isFrame), binds];
|
|
6439
|
-
const stack = new _Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx);
|
|
6440
|
-
return isFrame ? stack._pushProvides() : stack;
|
|
6441
|
-
}
|
|
6442
|
-
pushViewName(name) {
|
|
6443
|
-
const { comps, it, binds, dynBinds, views, ctx } = this;
|
|
6444
|
-
const newViews = [name, views];
|
|
6445
|
-
return new _Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
6446
|
-
}
|
|
6447
|
-
// Published types are stable per scope and would only churn the render cache, so
|
|
6448
|
-
// the cache key covers values alone.
|
|
6449
|
-
_pushDynBindValuesToArray(arr, comp) {
|
|
6450
|
-
for (const k in comp.provide) arr.push(this.lookupDynamic(k));
|
|
6451
|
-
for (const k in comp.lookup) arr.push(this.lookupDynamic(k));
|
|
6452
|
-
}
|
|
6453
|
-
// `*name`: the nearest binding above (including this component's own provides,
|
|
6454
|
-
// pushed on entering it), else this component's declared default, else null.
|
|
6455
|
-
lookupDynamic(name) {
|
|
6456
|
-
const v = lookup(this.dynBinds, name);
|
|
6457
|
-
if (v != null) return v;
|
|
6458
|
-
const comp = this.comps.getCompFor(this.it);
|
|
6459
|
-
return comp?.lookup[name]?.val?.eval(this) ?? null;
|
|
6460
|
-
}
|
|
6461
|
-
lookupBind(name) {
|
|
6462
|
-
return lookup(this.binds, name);
|
|
6463
|
-
}
|
|
6464
|
-
lookupFieldRaw(name) {
|
|
6465
|
-
return this.it[name] ?? null;
|
|
6466
|
-
}
|
|
6467
|
-
lookupMethod(name) {
|
|
6468
|
-
const fn = this.it[name];
|
|
6469
|
-
return fn instanceof Function ? fn.call(this.it) : null;
|
|
6470
|
-
}
|
|
6471
|
-
// The dispatched DOM event / drag info, read only by EventMemberVal's
|
|
6472
|
-
// `e.<member>` handler args. Null outside a live event transaction.
|
|
6473
|
-
lookupEvent() {
|
|
6474
|
-
return this.ctx?.event ?? null;
|
|
6475
|
-
}
|
|
6476
|
-
lookupDragInfo() {
|
|
6477
|
-
return this.ctx?.dragInfo ?? null;
|
|
6478
|
-
}
|
|
6479
|
-
getHandlerFor(name, key) {
|
|
6480
|
-
return this.comps.getHandlerFor(this.it, name, key);
|
|
6481
|
-
}
|
|
6482
|
-
lookupBestView(views, defaultViewName) {
|
|
6483
|
-
let n = this.views;
|
|
6484
|
-
while (n !== null) {
|
|
6485
|
-
const view = views[n[0]];
|
|
6486
|
-
if (view !== void 0) return view;
|
|
6487
|
-
n = n[1];
|
|
6488
|
-
}
|
|
6489
|
-
return views[defaultViewName];
|
|
6490
|
-
}
|
|
6491
|
-
};
|
|
6492
|
-
|
|
6493
6645
|
// src/transactor.js
|
|
6494
6646
|
var State2 = class {
|
|
6495
6647
|
constructor(val) {
|
|
@@ -6565,9 +6717,9 @@ var Transactor = class {
|
|
|
6565
6717
|
// `.a[.selId]` render target reconstructed from a DOM event) against the root the
|
|
6566
6718
|
// handler read, so pathKeys carries concrete keys instead of dropping the dynamic
|
|
6567
6719
|
// step. No-op when nobody is observing.
|
|
6568
|
-
_emitRecord(root, { kind, name, args, path, targetPath, handler, handlerName, matched, before, after, parent }) {
|
|
6720
|
+
_emitRecord(root, { kind, name, args, path: path2, targetPath, handler, handlerName, matched, before, after, parent }) {
|
|
6569
6721
|
if (this._observers.length === 0) return;
|
|
6570
|
-
const pinned =
|
|
6722
|
+
const pinned = path2.pinKeys(root);
|
|
6571
6723
|
this._emit({
|
|
6572
6724
|
kind,
|
|
6573
6725
|
name,
|
|
@@ -6618,18 +6770,20 @@ var Transactor = class {
|
|
|
6618
6770
|
// intent's answerPath is: a reply must reach the sender that asked even if a key
|
|
6619
6771
|
// moved while the message was in flight. Null when nobody is waiting — a host
|
|
6620
6772
|
// sendAtRoot or a view's own `@on.*` — and ctx.sendReply refuses on that.
|
|
6621
|
-
pushSend(
|
|
6622
|
-
const t = new SendEvent(
|
|
6623
|
-
t.
|
|
6773
|
+
pushSend(path2, name, args = [], parent = null, origin = null, txnPath = null) {
|
|
6774
|
+
const t = new SendEvent(path2, this, name, args, parent);
|
|
6775
|
+
t.txnPath = txnPath;
|
|
6776
|
+
t.origin = origin;
|
|
6777
|
+
t.originPinned = origin === null ? null : origin.toTransactionPath().pinKeys(this.state.val);
|
|
6624
6778
|
this.pushTransaction(t);
|
|
6625
6779
|
return this._link(t, parent);
|
|
6626
6780
|
}
|
|
6627
6781
|
// Raise an intent: a job the sender did not address, walked along a route until
|
|
6628
6782
|
// something answers. `opts.route` is a list of legs (see DEFAULT_ROUTE) and
|
|
6629
6783
|
// `opts.livePath` opts out of pinning the answer's destination keys.
|
|
6630
|
-
pushIntent(
|
|
6784
|
+
pushIntent(path2, name, args = [], opts = {}, parent = null) {
|
|
6631
6785
|
const release = parent ? parent.completion.track() : null;
|
|
6632
|
-
const walk = new IntentWalk(this,
|
|
6786
|
+
const walk = new IntentWalk(this, path2, name, args, opts, parent, release);
|
|
6633
6787
|
walk.advance();
|
|
6634
6788
|
return walk;
|
|
6635
6789
|
}
|
|
@@ -6663,16 +6817,17 @@ var Transactor = class {
|
|
|
6663
6817
|
transaction._completion?.releaseSelf();
|
|
6664
6818
|
}
|
|
6665
6819
|
}
|
|
6666
|
-
transactInputNow(
|
|
6667
|
-
this.transact(new InputEvent(
|
|
6820
|
+
transactInputNow(path2, event, eventHandler, dragInfo) {
|
|
6821
|
+
this.transact(new InputEvent(path2, event, eventHandler, this, dragInfo));
|
|
6668
6822
|
}
|
|
6669
6823
|
};
|
|
6670
6824
|
function nullHandler() {
|
|
6671
6825
|
return this;
|
|
6672
6826
|
}
|
|
6673
6827
|
var Transaction = class {
|
|
6674
|
-
constructor(
|
|
6675
|
-
this.path =
|
|
6828
|
+
constructor(path2, transactor, parentTransaction = null) {
|
|
6829
|
+
this.path = path2;
|
|
6830
|
+
this.txnPath = null;
|
|
6676
6831
|
this.transactor = transactor;
|
|
6677
6832
|
this.parentTransaction = parentTransaction;
|
|
6678
6833
|
this._completion = null;
|
|
@@ -6721,9 +6876,11 @@ var Transaction = class {
|
|
|
6721
6876
|
getHandlerAndArgs(_root, _instance, _comps) {
|
|
6722
6877
|
return null;
|
|
6723
6878
|
}
|
|
6724
|
-
// The path used to apply the mutation
|
|
6725
|
-
//
|
|
6879
|
+
// The path used to apply the mutation: the ACTIVE frame of the dispatch path, so
|
|
6880
|
+
// an event inside a `<x render="*name">` subtree updates the value where it
|
|
6881
|
+
// really lives (the dispatch `this.path` keeps the visual callers, for bubbling).
|
|
6726
6882
|
getTransactionPath() {
|
|
6883
|
+
if (this.txnPath !== null) return this.txnPath;
|
|
6727
6884
|
return this.path.toTransactionPath().compact();
|
|
6728
6885
|
}
|
|
6729
6886
|
run(curRoot, comps) {
|
|
@@ -6741,15 +6898,16 @@ var Transaction = class {
|
|
|
6741
6898
|
}
|
|
6742
6899
|
};
|
|
6743
6900
|
var InputEvent = class extends Transaction {
|
|
6744
|
-
constructor(
|
|
6745
|
-
super(
|
|
6901
|
+
constructor(path2, e, handler, transactor, dragInfo) {
|
|
6902
|
+
super(path2, transactor);
|
|
6746
6903
|
this.e = e;
|
|
6747
6904
|
this.handler = handler;
|
|
6748
6905
|
this.dragInfo = dragInfo;
|
|
6749
6906
|
this._dispatchPath = null;
|
|
6750
6907
|
}
|
|
6751
|
-
// Frame steps removed,
|
|
6752
|
-
//
|
|
6908
|
+
// Frame-only steps removed, one step per crossed component kept — inside every
|
|
6909
|
+
// continuation frame independently, so bubbling it visits every component and
|
|
6910
|
+
// then returns to the caller that wrote the `*name`.
|
|
6753
6911
|
get dispatchPath() {
|
|
6754
6912
|
this._dispatchPath ??= this.path.compact();
|
|
6755
6913
|
return this._dispatchPath;
|
|
@@ -6784,11 +6942,11 @@ var InputEvent = class extends Transaction {
|
|
|
6784
6942
|
this.transactor.pushIntent(this.dispatchPath, name, args, rest, this);
|
|
6785
6943
|
}
|
|
6786
6944
|
getHandlerAndArgs(root, _instance, comps) {
|
|
6787
|
-
const stack = this.path.
|
|
6945
|
+
const stack = this.path.buildStack(Stack.root(comps, root, this));
|
|
6788
6946
|
const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
|
|
6789
6947
|
this._handlerArgs = [...args];
|
|
6790
|
-
const
|
|
6791
|
-
args.push(new EventContext(
|
|
6948
|
+
const path2 = this.dispatchPath;
|
|
6949
|
+
args.push(new EventContext(path2, this.transactor, this));
|
|
6792
6950
|
return [handler, args];
|
|
6793
6951
|
}
|
|
6794
6952
|
// The dispatched DOM event, read only through `e.<member>` handler args
|
|
@@ -6799,11 +6957,11 @@ var InputEvent = class extends Transaction {
|
|
|
6799
6957
|
}
|
|
6800
6958
|
};
|
|
6801
6959
|
var NameArgsTransaction = class extends Transaction {
|
|
6802
|
-
constructor(
|
|
6803
|
-
super(
|
|
6960
|
+
constructor(path2, transactor, name, args, parentTransaction) {
|
|
6961
|
+
super(path2, transactor, parentTransaction);
|
|
6804
6962
|
this.name = name;
|
|
6805
6963
|
this.args = args;
|
|
6806
|
-
this.targetPath =
|
|
6964
|
+
this.targetPath = path2;
|
|
6807
6965
|
}
|
|
6808
6966
|
handlerProp = null;
|
|
6809
6967
|
// NameArgs verbs map their handler bucket straight to the observed kind:
|
|
@@ -6860,8 +7018,8 @@ var SendEvent = class extends NameArgsTransaction {
|
|
|
6860
7018
|
};
|
|
6861
7019
|
var IntentEvent = class extends NameArgsTransaction {
|
|
6862
7020
|
handlerProp = "intent";
|
|
6863
|
-
constructor(
|
|
6864
|
-
super(
|
|
7021
|
+
constructor(path2, transactor, walk) {
|
|
7022
|
+
super(path2, transactor, walk.name, walk.args, walk.parent);
|
|
6865
7023
|
this.walk = walk;
|
|
6866
7024
|
this.targetPath = walk.origin;
|
|
6867
7025
|
}
|
|
@@ -6888,17 +7046,17 @@ var PASS = /* @__PURE__ */ Symbol.for("tutuca.intent.pass");
|
|
|
6888
7046
|
var REFUSAL_RING_CAP = 200;
|
|
6889
7047
|
var INTENT_DEPTH = 64;
|
|
6890
7048
|
var IntentWalk = class {
|
|
6891
|
-
constructor(transactor,
|
|
7049
|
+
constructor(transactor, path2, name, args, opts, parent, release) {
|
|
6892
7050
|
this.transactor = transactor;
|
|
6893
7051
|
this.name = name;
|
|
6894
7052
|
this.args = args;
|
|
6895
7053
|
this.route = opts?.route ?? DEFAULT_ROUTE;
|
|
6896
7054
|
this.parent = parent;
|
|
6897
7055
|
this.release = release;
|
|
6898
|
-
this.origin =
|
|
6899
|
-
this.answerPath = opts?.livePath ? null :
|
|
7056
|
+
this.origin = path2;
|
|
7057
|
+
this.answerPath = opts?.livePath ? null : path2.toTransactionPath().pinKeys(transactor.state.val);
|
|
6900
7058
|
this.legIndex = 0;
|
|
6901
|
-
this.dynAt =
|
|
7059
|
+
this.dynAt = path2;
|
|
6902
7060
|
this.hops = 0;
|
|
6903
7061
|
this.ended = false;
|
|
6904
7062
|
}
|
|
@@ -6910,7 +7068,7 @@ var IntentWalk = class {
|
|
|
6910
7068
|
while (this.legIndex < this.route.length) {
|
|
6911
7069
|
const leg = this.route[this.legIndex];
|
|
6912
7070
|
if (leg === "dyn") {
|
|
6913
|
-
if (this.dynAt.
|
|
7071
|
+
if (!this.dynAt.canPop()) {
|
|
6914
7072
|
this.legIndex++;
|
|
6915
7073
|
continue;
|
|
6916
7074
|
}
|
|
@@ -7007,8 +7165,8 @@ var IntentWalk = class {
|
|
|
7007
7165
|
if (this.ended) return;
|
|
7008
7166
|
this.ended = true;
|
|
7009
7167
|
if (name === null) return this.release?.();
|
|
7010
|
-
const
|
|
7011
|
-
|
|
7168
|
+
const t = new SendEvent(this.origin, this.transactor, name, args, this.parent);
|
|
7169
|
+
t.txnPath = this.answerPath;
|
|
7012
7170
|
t._isAnswer = true;
|
|
7013
7171
|
this.transactor.pushTransaction(t);
|
|
7014
7172
|
if (this.release) t.completion.whenSubtreeSettled().then(this.release);
|
|
@@ -7074,8 +7232,8 @@ var Completion = class {
|
|
|
7074
7232
|
}
|
|
7075
7233
|
};
|
|
7076
7234
|
var Dispatcher = class {
|
|
7077
|
-
constructor(
|
|
7078
|
-
this.path =
|
|
7235
|
+
constructor(path2, transactor, parentTransaction, root = transactor.state.val) {
|
|
7236
|
+
this.path = path2;
|
|
7079
7237
|
this.transactor = transactor;
|
|
7080
7238
|
this.parent = parentTransaction;
|
|
7081
7239
|
this.root = root;
|
|
@@ -7103,7 +7261,9 @@ var Dispatcher = class {
|
|
|
7103
7261
|
// replayed; provides are pushed on every component frame either way, so a provide
|
|
7104
7262
|
// that reads a loop binding is the one case this cannot reproduce faithfully.
|
|
7105
7263
|
_stack() {
|
|
7106
|
-
this._stackMemo ??= this.path.
|
|
7264
|
+
this._stackMemo ??= this.path.buildStack(
|
|
7265
|
+
Stack.root(this.transactor.comps, this.root, this.parent)
|
|
7266
|
+
);
|
|
7107
7267
|
return this._stackMemo;
|
|
7108
7268
|
}
|
|
7109
7269
|
// Resolve a name the way the renderer would. `opts.route` takes the same legs in
|
|
@@ -7117,14 +7277,19 @@ var Dispatcher = class {
|
|
|
7117
7277
|
);
|
|
7118
7278
|
}
|
|
7119
7279
|
// The `lex` leg without a Stack: the scope of the component whose handler is
|
|
7120
|
-
// running, which is the leaf of this ctx's path.
|
|
7280
|
+
// running, which is the leaf of this ctx's path. A type name resolves to the
|
|
7281
|
+
// component registered under it; a value name to a path registered under it
|
|
7282
|
+
// (see ComponentStack.registerPaths), read against the current root.
|
|
7121
7283
|
_lookupLex(name) {
|
|
7122
7284
|
let Comp = null;
|
|
7123
7285
|
this.walkPath((c) => {
|
|
7124
7286
|
Comp = c;
|
|
7125
7287
|
return false;
|
|
7126
7288
|
});
|
|
7127
|
-
|
|
7289
|
+
const scope = Comp?.scope;
|
|
7290
|
+
if (scope == null) return null;
|
|
7291
|
+
if (isTypeName(name)) return scope.lookupComponent(name) ?? null;
|
|
7292
|
+
return scope.lookupPath(name)?.lookup(this.root) ?? null;
|
|
7128
7293
|
}
|
|
7129
7294
|
// A component lookup is a value lookup constrained to a component. The `lex` leg
|
|
7130
7295
|
// can only ever answer with one; the `dyn` leg reads a binding an ancestor
|
|
@@ -7146,8 +7311,8 @@ var Dispatcher = class {
|
|
|
7146
7311
|
send(name, args) {
|
|
7147
7312
|
return this.sendAtPath(this.path, name, args);
|
|
7148
7313
|
}
|
|
7149
|
-
sendAtPath(
|
|
7150
|
-
return this.transactor.pushSend(
|
|
7314
|
+
sendAtPath(path2, name, args) {
|
|
7315
|
+
return this.transactor.pushSend(path2, name, args, this.parent, this.path);
|
|
7151
7316
|
}
|
|
7152
7317
|
// An intent is ROUTED: it names a job and walks until something answers. The verb
|
|
7153
7318
|
// does not decide which scope answers — `opts.route` does, written here at the call
|
|
@@ -7155,8 +7320,8 @@ var Dispatcher = class {
|
|
|
7155
7320
|
intent(name, args, opts) {
|
|
7156
7321
|
return this.intentAtPath(this.path, name, args, opts);
|
|
7157
7322
|
}
|
|
7158
|
-
intentAtPath(
|
|
7159
|
-
return this.transactor.pushIntent(
|
|
7323
|
+
intentAtPath(path2, name, args, opts) {
|
|
7324
|
+
return this.transactor.pushIntent(path2, name, args, opts, this.parent);
|
|
7160
7325
|
}
|
|
7161
7326
|
};
|
|
7162
7327
|
var EventContext = class extends Dispatcher {
|
|
@@ -7185,7 +7350,14 @@ var EventContext = class extends Dispatcher {
|
|
|
7185
7350
|
this.transactor.refuse("NO_SENDER", { name });
|
|
7186
7351
|
return null;
|
|
7187
7352
|
}
|
|
7188
|
-
return this.
|
|
7353
|
+
return this.transactor.pushSend(
|
|
7354
|
+
origin,
|
|
7355
|
+
name,
|
|
7356
|
+
args,
|
|
7357
|
+
this.parent,
|
|
7358
|
+
this.path,
|
|
7359
|
+
this.parent.originPinned
|
|
7360
|
+
);
|
|
7189
7361
|
}
|
|
7190
7362
|
// End the walk answering nothing — "served, and no answer".
|
|
7191
7363
|
stop() {
|
|
@@ -7217,13 +7389,13 @@ var PathChanges = class extends PathBuilder {
|
|
|
7217
7389
|
}
|
|
7218
7390
|
};
|
|
7219
7391
|
function rootDispatcher(transactor) {
|
|
7220
|
-
return new Dispatcher(new
|
|
7392
|
+
return new Dispatcher(new DispatchPath(), transactor, null);
|
|
7221
7393
|
}
|
|
7222
7394
|
|
|
7223
7395
|
// tools/core/results.js
|
|
7224
7396
|
var ModuleInfo = class {
|
|
7225
|
-
constructor({ path = null, present = /* @__PURE__ */ new Set(), counts = {}, warnings = [] }) {
|
|
7226
|
-
this.path =
|
|
7397
|
+
constructor({ path: path2 = null, present = /* @__PURE__ */ new Set(), counts = {}, warnings = [] }) {
|
|
7398
|
+
this.path = path2;
|
|
7227
7399
|
this.present = present;
|
|
7228
7400
|
this.counts = counts;
|
|
7229
7401
|
this.warnings = warnings;
|
|
@@ -7333,8 +7505,8 @@ var DescribeResult = class {
|
|
|
7333
7505
|
}
|
|
7334
7506
|
};
|
|
7335
7507
|
var ModuleTestReport = class {
|
|
7336
|
-
constructor({ path = null, suites = [], counts = { pass: 0, fail: 0, skip: 0, total: 0 } }) {
|
|
7337
|
-
this.path =
|
|
7508
|
+
constructor({ path: path2 = null, suites = [], counts = { pass: 0, fail: 0, skip: 0, total: 0 } }) {
|
|
7509
|
+
this.path = path2;
|
|
7338
7510
|
this.suites = suites;
|
|
7339
7511
|
this.counts = counts;
|
|
7340
7512
|
}
|
|
@@ -7377,8 +7549,8 @@ var Test = class {
|
|
|
7377
7549
|
}
|
|
7378
7550
|
};
|
|
7379
7551
|
var ModuleTests = class {
|
|
7380
|
-
constructor({ path = null, suites = [] } = {}) {
|
|
7381
|
-
this.path =
|
|
7552
|
+
constructor({ path: path2 = null, suites = [] } = {}) {
|
|
7553
|
+
this.path = path2;
|
|
7382
7554
|
this.suites = suites;
|
|
7383
7555
|
}
|
|
7384
7556
|
};
|
|
@@ -7400,8 +7572,8 @@ function titleFromArg(arg) {
|
|
|
7400
7572
|
if (typeof arg === "function") return arg.name || "(anonymous)";
|
|
7401
7573
|
return String(arg);
|
|
7402
7574
|
}
|
|
7403
|
-
function makeCollector({ path = null, components = [] } = {}) {
|
|
7404
|
-
const moduleTests = new ModuleTests({ path, suites: [] });
|
|
7575
|
+
function makeCollector({ path: path2 = null, components = [] } = {}) {
|
|
7576
|
+
const moduleTests = new ModuleTests({ path: path2, suites: [] });
|
|
7405
7577
|
const stack = [];
|
|
7406
7578
|
function describe(...args) {
|
|
7407
7579
|
let head;
|
|
@@ -7502,7 +7674,7 @@ async function driveStack(stack, value, phase, opts = {}) {
|
|
|
7502
7674
|
val
|
|
7503
7675
|
);
|
|
7504
7676
|
});
|
|
7505
|
-
dispatchPhase(rootDispatcher(transactor), new
|
|
7677
|
+
dispatchPhase(rootDispatcher(transactor), new DispatchPath(), phase, value);
|
|
7506
7678
|
await transactor.settle();
|
|
7507
7679
|
return transactor.state.val;
|
|
7508
7680
|
}
|
|
@@ -7512,7 +7684,7 @@ async function drive(cfg, value, phase, opts = {}) {
|
|
|
7512
7684
|
async function runTests({
|
|
7513
7685
|
getTests,
|
|
7514
7686
|
components = [],
|
|
7515
|
-
path = null,
|
|
7687
|
+
path: path2 = null,
|
|
7516
7688
|
expect: expect3,
|
|
7517
7689
|
name = null,
|
|
7518
7690
|
grep = null,
|
|
@@ -7523,13 +7695,13 @@ async function runTests({
|
|
|
7523
7695
|
const counts = { pass: 0, fail: 0, skip: 0, total: 0 };
|
|
7524
7696
|
if (typeof getTests !== "function") {
|
|
7525
7697
|
return new TestReport({
|
|
7526
|
-
modules: [new ModuleTestReport({ path, suites: [], counts })]
|
|
7698
|
+
modules: [new ModuleTestReport({ path: path2, suites: [], counts })]
|
|
7527
7699
|
});
|
|
7528
7700
|
}
|
|
7529
7701
|
if (typeof expect3 !== "function") {
|
|
7530
7702
|
throw new Error("runTests: expect must be provided (e.g. chai's expect)");
|
|
7531
7703
|
}
|
|
7532
|
-
const { describe, test: test2, moduleTests } = makeCollector({ path, components });
|
|
7704
|
+
const { describe, test: test2, moduleTests } = makeCollector({ path: path2, components });
|
|
7533
7705
|
let _stack = null;
|
|
7534
7706
|
const getStack = () => _stack ??= buildStack({ components, macros, intentHandlers });
|
|
7535
7707
|
const driveLocal = (value, phase, opts = {}) => driveStack(getStack(), value, phase, opts);
|
|
@@ -7592,7 +7764,7 @@ async function runTests({
|
|
|
7592
7764
|
if (r !== null) suiteResults.push(r);
|
|
7593
7765
|
}
|
|
7594
7766
|
return new TestReport({
|
|
7595
|
-
modules: [new ModuleTestReport({ path, suites: suiteResults, counts })]
|
|
7767
|
+
modules: [new ModuleTestReport({ path: path2, suites: suiteResults, counts })]
|
|
7596
7768
|
});
|
|
7597
7769
|
}
|
|
7598
7770
|
|
|
@@ -7761,15 +7933,13 @@ function lintIdToMessage(id, info) {
|
|
|
7761
7933
|
case "DYN_ALIAS_NOT_REFERENCED":
|
|
7762
7934
|
return `Lookup '${info.name}' is defined but never used — remove it or reference it as '*${info.name}' in a view`;
|
|
7763
7935
|
case "PROVIDE_NOT_ADDRESSABLE":
|
|
7764
|
-
return `Provide '${info.name}' value '${info.value}' must be a field ('.f') or seq-access ('.s[.k]') — a
|
|
7936
|
+
return `Provide '${info.name}' value '${info.value}' must be a field ('.f') or seq-access ('.s[.k]') — a provide doubles as the path '<x render="*${info.name}">' resumes at, so this one is dropped and '*${info.name}' resolves to nothing`;
|
|
7765
7937
|
case "LOOKUP_BAD_SHAPE":
|
|
7766
7938
|
return `Lookup '${info.name}' has an invalid shape: ${info.problem}`;
|
|
7767
7939
|
case "LOOKUP_NO_PROVIDER":
|
|
7768
|
-
return info.hasDefault ? `Lookup '${info.name}' is provided by no component in scope, so it always resolves to its default` : `Lookup '${info.name}' is provided by no component in scope — add a 'provide' for it, or give this lookup a default`;
|
|
7940
|
+
return info.hasDefault ? `Lookup '${info.name}' is provided by no component in scope and matches no registered path, so it always resolves to its default` : `Lookup '${info.name}' is provided by no component in scope and matches no registered path — add a 'provide' for it, register a path under that name, or give this lookup a default`;
|
|
7769
7941
|
case "PROVIDE_TYPE_BAD_SHAPE":
|
|
7770
7942
|
return `Provide '${info.name}' starts uppercase, so it publishes a component type — its value must be 'self', not '${info.value}'`;
|
|
7771
|
-
case "PROVIDE_NAME_COLLISION":
|
|
7772
|
-
return `Provide '${info.name}' is also provided by '${info.other}' in the same scope — one name, one provider, so a lookup can find it`;
|
|
7773
7943
|
case "UNKNOWN_MACRO_ARG":
|
|
7774
7944
|
return `Argument '${info.name}' is not declared in macro '${info.macroName}'`;
|
|
7775
7945
|
case "UNKNOWN_DIRECTIVE":
|
|
@@ -7935,7 +8105,7 @@ var App = class {
|
|
|
7935
8105
|
const { type } = e;
|
|
7936
8106
|
const isDrag = type === "dragover" || type === "dragstart" || type === "dragend" || type === "drop";
|
|
7937
8107
|
const { rootNode: root, maxEventNodeDepth: maxDepth, comps, transactor } = this;
|
|
7938
|
-
const [
|
|
8108
|
+
const [path2, handlers] = DispatchPath.fromNodeAndEventName(
|
|
7939
8109
|
e.target,
|
|
7940
8110
|
type,
|
|
7941
8111
|
root,
|
|
@@ -7943,9 +8113,9 @@ var App = class {
|
|
|
7943
8113
|
comps,
|
|
7944
8114
|
!isDrag
|
|
7945
8115
|
);
|
|
7946
|
-
if (isDrag) this._handleDragEvent(e, type,
|
|
7947
|
-
if (
|
|
7948
|
-
for (const handler of handlers) transactor.transactInputNow(
|
|
8116
|
+
if (isDrag) this._handleDragEvent(e, type, path2);
|
|
8117
|
+
if (path2 !== null && handlers !== null)
|
|
8118
|
+
for (const handler of handlers) transactor.transactInputNow(path2, e, handler, this.dragInfo);
|
|
7949
8119
|
}
|
|
7950
8120
|
_handleTouchEvent(e) {
|
|
7951
8121
|
const { type } = e;
|
|
@@ -7988,7 +8158,7 @@ var App = class {
|
|
|
7988
8158
|
this._touch = null;
|
|
7989
8159
|
}
|
|
7990
8160
|
}
|
|
7991
|
-
_handleDragEvent(e, type,
|
|
8161
|
+
_handleDragEvent(e, type, path2) {
|
|
7992
8162
|
if (type === "dragover") {
|
|
7993
8163
|
const dropTarget = getClosestDropTarget(e.target, this.rootNode, Infinity);
|
|
7994
8164
|
if (dropTarget !== null) {
|
|
@@ -8000,10 +8170,10 @@ var App = class {
|
|
|
8000
8170
|
} else if (type === "dragstart") {
|
|
8001
8171
|
e.target.dataset.dragging = 1;
|
|
8002
8172
|
const rootValue = this.state.val;
|
|
8003
|
-
const txnPath =
|
|
8173
|
+
const txnPath = path2.compact().toTransactionPath();
|
|
8004
8174
|
const value = txnPath.lookup(rootValue);
|
|
8005
8175
|
const dragType = e.target.dataset.dragtype ?? "?";
|
|
8006
|
-
const stack =
|
|
8176
|
+
const stack = path2.buildStack(this.makeStack(rootValue));
|
|
8007
8177
|
this.dragInfo = new DragInfo(stack, value, dragType, e.target);
|
|
8008
8178
|
} else if (type === "drop") {
|
|
8009
8179
|
e.preventDefault();
|
|
@@ -8078,7 +8248,7 @@ var App = class {
|
|
|
8078
8248
|
this.rootNode.removeEventListener(name, this, listenerOpts(name));
|
|
8079
8249
|
}
|
|
8080
8250
|
sendAtRoot(name, args) {
|
|
8081
|
-
this.transactor.pushSend(new
|
|
8251
|
+
this.transactor.pushSend(new DispatchPath(), name, args);
|
|
8082
8252
|
}
|
|
8083
8253
|
registerComponents(comps, opts) {
|
|
8084
8254
|
const scope = this.compStack.enter();
|
|
@@ -8218,7 +8388,20 @@ var WeakMapDomCache = class {
|
|
|
8218
8388
|
};
|
|
8219
8389
|
|
|
8220
8390
|
// src/renderer.js
|
|
8221
|
-
var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
|
|
8391
|
+
var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk", "rp"];
|
|
8392
|
+
function stampRenderBase(vdom, text) {
|
|
8393
|
+
if (vdom instanceof VNode)
|
|
8394
|
+
return new VNode(
|
|
8395
|
+
vdom.tag,
|
|
8396
|
+
{ ...vdom.attrs, "data-rp": text },
|
|
8397
|
+
vdom.childs,
|
|
8398
|
+
vdom.key,
|
|
8399
|
+
vdom.namespace
|
|
8400
|
+
);
|
|
8401
|
+
if (vdom instanceof VFragment)
|
|
8402
|
+
return new VFragment(vdom.childs.map((c) => stampRenderBase(c, text)));
|
|
8403
|
+
return vdom;
|
|
8404
|
+
}
|
|
8222
8405
|
var Renderer = class {
|
|
8223
8406
|
constructor(comps) {
|
|
8224
8407
|
this.comps = comps;
|
|
@@ -8255,17 +8438,17 @@ var Renderer = class {
|
|
|
8255
8438
|
if (comp === null) return null;
|
|
8256
8439
|
return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
|
|
8257
8440
|
}
|
|
8258
|
-
renderIt(stack, node, key, viewName) {
|
|
8441
|
+
renderIt(stack, node, key, viewName, base = null) {
|
|
8259
8442
|
const comp = this.comps.getCompFor(stack.it);
|
|
8260
|
-
return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName) : null;
|
|
8443
|
+
return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName, base) : null;
|
|
8261
8444
|
}
|
|
8262
8445
|
// `node` is the parse node of the render site (`<x render>` / `render-it` /
|
|
8263
8446
|
// `render-each`, or the view's root anode for the app root). It keys the
|
|
8264
8447
|
// cache as a globally-unique object: node ids alone are unique only within a
|
|
8265
8448
|
// single view, so the same value rendered by two components (e.g. through a
|
|
8266
8449
|
// shared dynamic-var sequence) would otherwise collide in the cache.
|
|
8267
|
-
_rValComp(stack, val, comp, node, key, viewName) {
|
|
8268
|
-
const cacheKey = `${viewName ?? ""}${stack.viewsId ?? ""}${key}`;
|
|
8450
|
+
_rValComp(stack, val, comp, node, key, viewName, base = null) {
|
|
8451
|
+
const cacheKey = `${viewName ?? ""}${stack.viewsId ?? ""}${key}${stack.renderPath.addressKey}`;
|
|
8269
8452
|
const cachePath = [node, val];
|
|
8270
8453
|
stack._pushDynBindValuesToArray(cachePath, comp);
|
|
8271
8454
|
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
@@ -8273,30 +8456,43 @@ var Renderer = class {
|
|
|
8273
8456
|
const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
|
|
8274
8457
|
const body = this.renderView(view, stack);
|
|
8275
8458
|
if (body == null) return null;
|
|
8459
|
+
const baseJson = base === null ? null : pathToJson(base);
|
|
8276
8460
|
const meta = this._renderMetadata({
|
|
8277
8461
|
$: "Comp",
|
|
8278
8462
|
nid: node?.nodeId ?? null,
|
|
8279
8463
|
cid: comp.id,
|
|
8280
|
-
vid: view.name
|
|
8464
|
+
vid: view.name,
|
|
8465
|
+
...baseJson === null ? null : { base: baseJson }
|
|
8281
8466
|
});
|
|
8282
|
-
const dom = new VFragment([
|
|
8467
|
+
const dom = new VFragment([
|
|
8468
|
+
meta,
|
|
8469
|
+
baseJson === null ? body : stampRenderBase(body, JSON.stringify(baseJson))
|
|
8470
|
+
]);
|
|
8283
8471
|
this.cache.set(cachePath, cacheKey, dom);
|
|
8284
8472
|
return dom;
|
|
8285
8473
|
}
|
|
8286
8474
|
pushEachEntry(r, nid, attrName, key, dom) {
|
|
8287
8475
|
r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
|
|
8288
8476
|
}
|
|
8289
|
-
renderEachWhen(stack,
|
|
8477
|
+
renderEachWhen(stack, each) {
|
|
8478
|
+
const { iterInfo, node: view, nodeId: nid } = each;
|
|
8290
8479
|
const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
|
|
8480
|
+
const seqPath = iterInfo.val instanceof DynVal ? stack.lookupDynamicLocated(iterInfo.val.name)?.path ?? null : null;
|
|
8291
8481
|
const r = [];
|
|
8292
8482
|
const it = stack.it;
|
|
8293
8483
|
const renderOne = (key, value, attrName, binds) => {
|
|
8484
|
+
const itemBase = seqPath === null ? null : keyedPath(seqPath, key);
|
|
8485
|
+
const itemStep = itemBase === null ? each.itemStep(key) : null;
|
|
8486
|
+
const itemPath = itemBase !== null ? stack.renderPath.pushFrame(itemBase) : itemStep !== null ? stack.renderPath.pushItem(itemStep) : stack.renderPath;
|
|
8294
8487
|
const cachePath = enricher ? [view, it, value] : [view, value];
|
|
8295
|
-
const cacheKey = `${stack.viewsId ?? ""}${nid}${key}`;
|
|
8488
|
+
const cacheKey = `${stack.viewsId ?? ""}${nid}${key}${itemPath.addressKey}`;
|
|
8296
8489
|
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
8297
8490
|
if (cachedNode) this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
8298
8491
|
else {
|
|
8299
|
-
const dom = this.renderView(
|
|
8492
|
+
const dom = this.renderView(
|
|
8493
|
+
view,
|
|
8494
|
+
stack.enter(value, binds, false, itemPath, itemBase !== null)
|
|
8495
|
+
);
|
|
8300
8496
|
if (dom != null) this.pushEachEntry(r, nid, attrName, key, dom);
|
|
8301
8497
|
this.cache.set(cachePath, cacheKey, dom);
|
|
8302
8498
|
}
|
|
@@ -8553,7 +8749,6 @@ export {
|
|
|
8553
8749
|
ModuleTests,
|
|
8554
8750
|
PASS,
|
|
8555
8751
|
PLACEHOLDERLESS_TEMPLATE_STRING,
|
|
8556
|
-
PROVIDE_NAME_COLLISION,
|
|
8557
8752
|
PROVIDE_NOT_ADDRESSABLE,
|
|
8558
8753
|
PROVIDE_TYPE_BAD_SHAPE,
|
|
8559
8754
|
ParseContext,
|
|
@@ -8594,6 +8789,7 @@ export {
|
|
|
8594
8789
|
lintIdToMessage,
|
|
8595
8790
|
macro,
|
|
8596
8791
|
makeCollector,
|
|
8792
|
+
path,
|
|
8597
8793
|
phaseOps,
|
|
8598
8794
|
reportTestReportToConsole,
|
|
8599
8795
|
resolveArgs,
|