tutuca 0.12.0 → 0.13.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 +601 -475
- package/dist/tutuca-components.js +6 -6
- package/dist/tutuca-dev.ext.js +563 -491
- package/dist/tutuca-dev.js +564 -492
- package/dist/tutuca-dev.min.js +4 -4
- package/dist/tutuca-extra.ext.js +470 -410
- package/dist/tutuca-extra.js +470 -410
- package/dist/tutuca-extra.min.js +3 -3
- package/dist/tutuca-storybook.js +4 -4
- package/dist/tutuca.ext.js +470 -410
- package/dist/tutuca.js +470 -410
- package/dist/tutuca.min.js +3 -3
- package/package.json +1 -1
- package/skill/tutuca/advanced.md +56 -7
- package/skill/tutuca/core.md +21 -13
- package/skill/tutuca/messages-and-intents.md +17 -0
- package/skill/tutuca/patterns/edit-through-a-dynamic-target.md +1 -1
- package/skill/tutuca/patterns/handle-events.md +3 -2
- package/skill/tutuca/patterns/share-state-across-the-tree.md +1 -1
- package/skill/tutuca/semantics.md +4 -4
- package/skill/tutuca-source/tutuca.ext.js +470 -410
package/dist/tutuca-dev.ext.js
CHANGED
|
@@ -237,9 +237,6 @@ var Step = class {
|
|
|
237
237
|
lookup(_v, dval = null) {
|
|
238
238
|
return dval;
|
|
239
239
|
}
|
|
240
|
-
setValue(root, _v) {
|
|
241
|
-
return root;
|
|
242
|
-
}
|
|
243
240
|
setDraftValue(_root, _v) {
|
|
244
241
|
}
|
|
245
242
|
enterFrame(stack, _prev, next) {
|
|
@@ -268,9 +265,6 @@ var BindStep = class _BindStep extends Step {
|
|
|
268
265
|
lookup(v, _dval) {
|
|
269
266
|
return v;
|
|
270
267
|
}
|
|
271
|
-
setValue(_root, v) {
|
|
272
|
-
return v;
|
|
273
|
-
}
|
|
274
268
|
enterFrame(stack, _prev, next) {
|
|
275
269
|
return stack.enter(next, { ...this.binds }, false);
|
|
276
270
|
}
|
|
@@ -308,9 +302,6 @@ var FieldStep = class extends Step {
|
|
|
308
302
|
lookup(v, dval = null) {
|
|
309
303
|
return readKey(v, this.field, dval);
|
|
310
304
|
}
|
|
311
|
-
setValue(root, v) {
|
|
312
|
-
return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
|
|
313
|
-
}
|
|
314
305
|
setDraftValue(root, v) {
|
|
315
306
|
writeKey(root, this.field, v);
|
|
316
307
|
}
|
|
@@ -333,9 +324,6 @@ var SeqStep = class extends Step {
|
|
|
333
324
|
lookup(v, dval = null) {
|
|
334
325
|
return readSeqKey(readKey(v, this.field, null), this.key, dval);
|
|
335
326
|
}
|
|
336
|
-
setValue(root, v) {
|
|
337
|
-
return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
|
|
338
|
-
}
|
|
339
327
|
setDraftValue(root, v) {
|
|
340
328
|
const seq = readKey(root, this.field, null);
|
|
341
329
|
if (seq != null) writeSeqKey(seq, this.key, v);
|
|
@@ -358,9 +346,6 @@ var SeqAccessStep = class extends Step {
|
|
|
358
346
|
const key = readKey(v, this.keyField, NONE);
|
|
359
347
|
return key !== NONE && seq !== NONE ? readSeqKey(seq, key, dval) : dval;
|
|
360
348
|
}
|
|
361
|
-
setValue(root, v) {
|
|
362
|
-
return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
|
|
363
|
-
}
|
|
364
349
|
setDraftValue(root, v) {
|
|
365
350
|
const seq = readKey(root, this.seqField, NONE);
|
|
366
351
|
const key = readKey(root, this.keyField, NONE);
|
|
@@ -388,9 +373,6 @@ var EachBindStep = class extends Step {
|
|
|
388
373
|
lookup(v, _dval) {
|
|
389
374
|
return v;
|
|
390
375
|
}
|
|
391
|
-
setValue(_root, v) {
|
|
392
|
-
return v;
|
|
393
|
-
}
|
|
394
376
|
// Replay the renderer's per-item binds (key, value + any @enrich-with binds)
|
|
395
377
|
// so a rebuilt stack matches the one @each rendered with.
|
|
396
378
|
enterFrame(stack, _prev, next) {
|
|
@@ -426,10 +408,6 @@ var DynStep = class extends Step {
|
|
|
426
408
|
warnRawDynStep("lookup", this);
|
|
427
409
|
return dval;
|
|
428
410
|
}
|
|
429
|
-
setValue(root, _v) {
|
|
430
|
-
warnRawDynStep("setValue", this);
|
|
431
|
-
return root;
|
|
432
|
-
}
|
|
433
411
|
enterFrame(stack, _prev, _next) {
|
|
434
412
|
warnRawDynStep("enterFrame", this);
|
|
435
413
|
return stack;
|
|
@@ -500,7 +478,7 @@ var Path = class _Path {
|
|
|
500
478
|
}
|
|
501
479
|
// Resolve every field-keyed step (e.g. `SeqAccessStep`) against `root`, freezing the
|
|
502
480
|
// key as it is *now* so a later lookup/setValue lands on the same item even if the
|
|
503
|
-
// keyField changed meanwhile (e.g. the selected tab moved while
|
|
481
|
+
// keyField changed meanwhile (e.g. the selected tab moved while an intent was in
|
|
504
482
|
// flight). Returns a new Path with those steps replaced; `this` if nothing pinned.
|
|
505
483
|
// Must be called on a transaction path (no DynSteps — call toTransactionPath first).
|
|
506
484
|
pinKeys(root) {
|
|
@@ -742,7 +720,6 @@ var K_FIELD = 4;
|
|
|
742
720
|
var K_BIND = 8;
|
|
743
721
|
var K_DYN = 16;
|
|
744
722
|
var K_NAME = 32;
|
|
745
|
-
var K_TYPE = 64;
|
|
746
723
|
var K_SEQ = 256;
|
|
747
724
|
var K_METHOD = 1024;
|
|
748
725
|
var K_EVENT = 2048;
|
|
@@ -752,7 +729,7 @@ var G_COMPONENT = K_FIELD | K_SEQ | K_DYN;
|
|
|
752
729
|
var G_SEQUENCE = K_FIELD | K_DYN;
|
|
753
730
|
var G_PROVIDE = K_FIELD | K_SEQ;
|
|
754
731
|
var G_FIELD = K_FIELD | K_METHOD | K_CONST | K_SEQ;
|
|
755
|
-
var G_VALUE = K_FIELD | K_METHOD | K_BIND | K_DYN | K_NAME |
|
|
732
|
+
var G_VALUE = K_FIELD | K_METHOD | K_BIND | K_DYN | K_NAME | K_CONST;
|
|
756
733
|
var G_HANDLER_ARG = G_VALUE & ~K_NAME | K_EVENT;
|
|
757
734
|
var G_ALL = G_VALUE | K_STRTPL | K_SEQ;
|
|
758
735
|
function sizeOf(v) {
|
|
@@ -822,7 +799,6 @@ function parseToken(s, px) {
|
|
|
822
799
|
if (m !== null) return new EventMemberVal(s.split(".").slice(1));
|
|
823
800
|
}
|
|
824
801
|
if (c0 >= 97 && c0 <= 122) return mkVal(s, NameVal);
|
|
825
|
-
if (c0 >= 65 && c0 <= 90) return mkVal(s, TypeVal);
|
|
826
802
|
return null;
|
|
827
803
|
}
|
|
828
804
|
function _parseSeqAccess(s, px) {
|
|
@@ -937,7 +913,6 @@ function kindOf(val) {
|
|
|
937
913
|
if (val instanceof MethodVal) return K_METHOD;
|
|
938
914
|
if (val instanceof BindVal) return K_BIND;
|
|
939
915
|
if (val instanceof DynVal) return K_DYN;
|
|
940
|
-
if (val instanceof TypeVal) return K_TYPE;
|
|
941
916
|
if (val instanceof NameVal) return K_NAME;
|
|
942
917
|
if (val instanceof EventMemberVal) return K_EVENT;
|
|
943
918
|
return 0;
|
|
@@ -1051,9 +1026,6 @@ var NameVal = class extends VarVal {
|
|
|
1051
1026
|
super();
|
|
1052
1027
|
this.name = name;
|
|
1053
1028
|
}
|
|
1054
|
-
eval(stack) {
|
|
1055
|
-
return stack.lookupName(this.name);
|
|
1056
|
-
}
|
|
1057
1029
|
toString() {
|
|
1058
1030
|
return this.name;
|
|
1059
1031
|
}
|
|
@@ -1074,11 +1046,6 @@ var mk404Handler = (stack, type, name) => function(...args) {
|
|
|
1074
1046
|
else console.warn("handler not found", { type, name });
|
|
1075
1047
|
return this;
|
|
1076
1048
|
};
|
|
1077
|
-
var TypeVal = class extends NameVal {
|
|
1078
|
-
eval(stack) {
|
|
1079
|
-
return stack.lookupType(this.name);
|
|
1080
|
-
}
|
|
1081
|
-
};
|
|
1082
1049
|
var keyIs = (k) => (e) => e.key === k;
|
|
1083
1050
|
var macCtrl = (e) => isMac && e.metaKey || e.ctrlKey;
|
|
1084
1051
|
var nullSafe = (fn) => (e, stack) => {
|
|
@@ -1211,9 +1178,6 @@ var Attributes = class {
|
|
|
1211
1178
|
constructor(items) {
|
|
1212
1179
|
this.items = items;
|
|
1213
1180
|
}
|
|
1214
|
-
eval(_stack) {
|
|
1215
|
-
return {};
|
|
1216
|
-
}
|
|
1217
1181
|
static parse(attributes, px, parseAll = false) {
|
|
1218
1182
|
return getAttrParser(px).parse(attributes, parseAll);
|
|
1219
1183
|
}
|
|
@@ -1223,11 +1187,26 @@ var Attributes = class {
|
|
|
1223
1187
|
};
|
|
1224
1188
|
var booleanAttrsRaw = "itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly,async,autofocus,autoplay,controls,default,defer,disabled,hidden,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected";
|
|
1225
1189
|
var booleanAttrs = new Set(booleanAttrsRaw.split(","));
|
|
1190
|
+
function parseDirectiveValue(px, directiveName, source, parser) {
|
|
1191
|
+
const val = parser(source, px);
|
|
1192
|
+
if (val === null) {
|
|
1193
|
+
px.onParseIssue("bad-value", {
|
|
1194
|
+
role: "directive",
|
|
1195
|
+
directive: directiveName,
|
|
1196
|
+
value: source
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
return val;
|
|
1200
|
+
}
|
|
1201
|
+
function parseIterationDirectives(attributes, px) {
|
|
1202
|
+
const parseNamed = (name) => {
|
|
1203
|
+
const attr = attributes.getNamedItem(`@${name}`);
|
|
1204
|
+
return attr ? parseDirectiveValue(px, name, attr.value, parseAlterHandler) : null;
|
|
1205
|
+
};
|
|
1206
|
+
return { whenVal: parseNamed("when"), loopWithVal: parseNamed("loop-with") };
|
|
1207
|
+
}
|
|
1226
1208
|
var AttrParser = class {
|
|
1227
1209
|
constructor(px) {
|
|
1228
|
-
this.clear(px);
|
|
1229
|
-
}
|
|
1230
|
-
clear(px) {
|
|
1231
1210
|
this.px = px;
|
|
1232
1211
|
this.attrs = null;
|
|
1233
1212
|
this.hasDynamic = false;
|
|
@@ -1282,12 +1261,7 @@ var AttrParser = class {
|
|
|
1282
1261
|
}
|
|
1283
1262
|
}
|
|
1284
1263
|
_parseDirectiveValue(directiveName, s, parserFn) {
|
|
1285
|
-
|
|
1286
|
-
if (val === null) {
|
|
1287
|
-
const info = { role: "directive", directive: directiveName, value: s };
|
|
1288
|
-
this.px.onParseIssue("bad-value", info);
|
|
1289
|
-
}
|
|
1290
|
-
return val;
|
|
1264
|
+
return parseDirectiveValue(this.px, directiveName, s, parserFn);
|
|
1291
1265
|
}
|
|
1292
1266
|
parseDirective(s, directiveName) {
|
|
1293
1267
|
switch (directiveName) {
|
|
@@ -1451,11 +1425,8 @@ var IfAttr = class extends BaseAttr {
|
|
|
1451
1425
|
return this.condVal.eval(stack) ? this.thenVal.eval(stack) : this.elseVal.eval(stack);
|
|
1452
1426
|
}
|
|
1453
1427
|
};
|
|
1454
|
-
var _attrParser = null;
|
|
1455
1428
|
function getAttrParser(px) {
|
|
1456
|
-
|
|
1457
|
-
_attrParser.clear(px);
|
|
1458
|
-
return _attrParser;
|
|
1429
|
+
return new AttrParser(px);
|
|
1459
1430
|
}
|
|
1460
1431
|
var EventHandler = class _EventHandler {
|
|
1461
1432
|
constructor(handlerVal, args = []) {
|
|
@@ -1479,70 +1450,77 @@ var IntentHandler = class {
|
|
|
1479
1450
|
}
|
|
1480
1451
|
};
|
|
1481
1452
|
|
|
1482
|
-
// src/
|
|
1483
|
-
var
|
|
1484
|
-
var
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
return { hit: 0, miss: 0, badKey: 0 };
|
|
1491
|
-
}
|
|
1453
|
+
// src/iteration.js
|
|
1454
|
+
var SEQ_INFO = /* @__PURE__ */ Symbol.for("tutuca.seqInfo");
|
|
1455
|
+
var normalizeRange = (start, end, size) => {
|
|
1456
|
+
let s = start == null ? 0 : start < 0 ? size + start : start;
|
|
1457
|
+
let e = end == null ? size : end < 0 ? size + end : end;
|
|
1458
|
+
s = s < 0 ? 0 : s > size ? size : s;
|
|
1459
|
+
e = e < 0 ? 0 : e > size ? size : e;
|
|
1460
|
+
return [s, e < s ? s : e];
|
|
1492
1461
|
};
|
|
1493
|
-
var
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
const len = keys.length;
|
|
1505
|
-
let cur = this.keysByLen.get(len);
|
|
1506
|
-
if (!cur) return this._returnValue(void 0);
|
|
1507
|
-
for (let i = 0; i < len - 1; i++) {
|
|
1508
|
-
cur = cur.get(keys[i]);
|
|
1509
|
-
if (!cur) return this._returnValue(void 0);
|
|
1510
|
-
}
|
|
1511
|
-
return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
|
|
1512
|
-
}
|
|
1513
|
-
set(keys, cacheKey, v) {
|
|
1514
|
-
const len = keys.length;
|
|
1515
|
-
let cur = this.keysByLen.get(len);
|
|
1516
|
-
if (!cur) {
|
|
1517
|
-
cur = /* @__PURE__ */ new WeakMap();
|
|
1518
|
-
this.keysByLen.set(len, cur);
|
|
1519
|
-
}
|
|
1520
|
-
for (let i = 0; i < len - 1; i++) {
|
|
1521
|
-
const key = keys[i];
|
|
1522
|
-
let next = cur.get(key);
|
|
1523
|
-
if (!next) {
|
|
1524
|
-
if (!isWeakKey(key)) {
|
|
1525
|
-
this.badKey += 1;
|
|
1526
|
-
return;
|
|
1527
|
-
}
|
|
1528
|
-
next = /* @__PURE__ */ new WeakMap();
|
|
1529
|
-
cur.set(key, next);
|
|
1530
|
-
}
|
|
1531
|
-
cur = next;
|
|
1532
|
-
}
|
|
1533
|
-
const lastKey = keys[len - 1];
|
|
1534
|
-
const leaf = cur.get(lastKey);
|
|
1535
|
-
if (leaf) leaf[cacheKey] = v;
|
|
1536
|
-
else if (isWeakKey(lastKey)) cur.set(lastKey, { [cacheKey]: v });
|
|
1537
|
-
else this.badKey += 1;
|
|
1538
|
-
}
|
|
1539
|
-
evict() {
|
|
1540
|
-
const { hit, miss, badKey } = this;
|
|
1541
|
-
this.hit = this.miss = this.badKey = 0;
|
|
1542
|
-
this.keysByLen = /* @__PURE__ */ new Map();
|
|
1543
|
-
return { hit, miss, badKey };
|
|
1462
|
+
var nativeIndexedIter = (seq, visit, start, end) => {
|
|
1463
|
+
const [s, e] = normalizeRange(start, end, seqSize(seq));
|
|
1464
|
+
for (let i = s; i < e; i++) visit(i, seq[i], "si");
|
|
1465
|
+
};
|
|
1466
|
+
var nativeKeyedIter = (seq, visit, start, end) => {
|
|
1467
|
+
const [s, e] = normalizeRange(start, end, seqSize(seq));
|
|
1468
|
+
let i = 0;
|
|
1469
|
+
for (const [key, value] of seqEntries(seq)) {
|
|
1470
|
+
if (i >= e) break;
|
|
1471
|
+
if (i >= s) visit(key, value, "sk");
|
|
1472
|
+
i++;
|
|
1544
1473
|
}
|
|
1545
1474
|
};
|
|
1475
|
+
var unknownIter = () => {
|
|
1476
|
+
};
|
|
1477
|
+
var getSeqInfo = (seq) => isIndexedSeq(seq) ? nativeIndexedIter : isKeyedSeq(seq) || isSetSeq(seq) ? nativeKeyedIter : seq?.[SEQ_INFO] ?? unknownIter;
|
|
1478
|
+
var filterAlwaysTrue = (_key, _value, _iterData) => true;
|
|
1479
|
+
var nullLoopWith = (seq) => ({ iterData: { seq } });
|
|
1480
|
+
var unpackLoopResult = (result, seq) => {
|
|
1481
|
+
const value = result ?? {};
|
|
1482
|
+
return {
|
|
1483
|
+
iterData: value.iterData ?? { seq },
|
|
1484
|
+
start: value.start,
|
|
1485
|
+
end: value.end,
|
|
1486
|
+
keys: value.keys
|
|
1487
|
+
};
|
|
1488
|
+
};
|
|
1489
|
+
var makeLoopCtx = (stack, filter) => ({
|
|
1490
|
+
lookup: (name) => stack.lookupBind(name),
|
|
1491
|
+
filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
|
|
1492
|
+
});
|
|
1493
|
+
var callEnricher = (enricher, it, binds, key, value, iterData) => {
|
|
1494
|
+
enricher.call(it, binds, key, value, iterData);
|
|
1495
|
+
console.assert(
|
|
1496
|
+
binds.key === key && binds.value === value,
|
|
1497
|
+
"@enrich-with handlers must not overwrite binds.key or binds.value"
|
|
1498
|
+
);
|
|
1499
|
+
binds.key = key;
|
|
1500
|
+
binds.value = value;
|
|
1501
|
+
};
|
|
1502
|
+
var visitKeys = (seq, keys, visit) => {
|
|
1503
|
+
const attrName = isIndexedSeq(seq) ? "si" : "sk";
|
|
1504
|
+
for (const key of keys) visit(key, seqGet(seq, key), attrName);
|
|
1505
|
+
};
|
|
1506
|
+
function walkLoopBindings({ seq, it, filter, loopWith, enricher, ctx }, visit) {
|
|
1507
|
+
const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(it, seq, ctx), seq);
|
|
1508
|
+
const visitOne = (key, value, attrName) => {
|
|
1509
|
+
const binds = { key, value };
|
|
1510
|
+
if (enricher) callEnricher(enricher, it, binds, key, value, iterData);
|
|
1511
|
+
visit(key, value, attrName, binds);
|
|
1512
|
+
};
|
|
1513
|
+
if (keys) visitKeys(seq, keys, visitOne);
|
|
1514
|
+
else
|
|
1515
|
+
getSeqInfo(seq)(
|
|
1516
|
+
seq,
|
|
1517
|
+
(key, value, attrName) => {
|
|
1518
|
+
if (filter.call(it, key, value, iterData)) visitOne(key, value, attrName);
|
|
1519
|
+
},
|
|
1520
|
+
start,
|
|
1521
|
+
end
|
|
1522
|
+
);
|
|
1523
|
+
}
|
|
1546
1524
|
|
|
1547
1525
|
// src/vdom.js
|
|
1548
1526
|
var HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
@@ -1887,189 +1865,11 @@ function h(tagName, properties, children, namespace) {
|
|
|
1887
1865
|
return new VNode(tag, props, normalizedChildren, key, namespace);
|
|
1888
1866
|
}
|
|
1889
1867
|
|
|
1890
|
-
// src/renderer.js
|
|
1891
|
-
var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
|
|
1892
|
-
var Renderer = class {
|
|
1893
|
-
constructor(comps) {
|
|
1894
|
-
this.comps = comps;
|
|
1895
|
-
this.cache = new WeakMapDomCache();
|
|
1896
|
-
this.renderTag = h;
|
|
1897
|
-
}
|
|
1898
|
-
renderFragment(childs) {
|
|
1899
|
-
return new VFragment(childs);
|
|
1900
|
-
}
|
|
1901
|
-
renderComment(text) {
|
|
1902
|
-
return new VComment(text);
|
|
1903
|
-
}
|
|
1904
|
-
setNullCache() {
|
|
1905
|
-
this.cache = new NullDomCache();
|
|
1906
|
-
}
|
|
1907
|
-
renderToDOM(stack, val) {
|
|
1908
|
-
const rootNode = document.createElement("div");
|
|
1909
|
-
const rOpts = { document };
|
|
1910
|
-
render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
|
|
1911
|
-
return rootNode.childNodes[0];
|
|
1912
|
-
}
|
|
1913
|
-
renderToString(stack, val, cleanAttrs = true) {
|
|
1914
|
-
const dom = this.renderToDOM(stack, val);
|
|
1915
|
-
if (cleanAttrs) {
|
|
1916
|
-
const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
|
|
1917
|
-
for (const { dataset } of nodes) for (const name of DATASET_ATTRS) delete dataset[name];
|
|
1918
|
-
}
|
|
1919
|
-
return dom.innerHTML;
|
|
1920
|
-
}
|
|
1921
|
-
renderRoot(stack, val, viewName = null) {
|
|
1922
|
-
const comp = this.comps.getCompFor(val);
|
|
1923
|
-
if (comp === null) return null;
|
|
1924
|
-
return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
|
|
1925
|
-
}
|
|
1926
|
-
renderIt(stack, node, key, viewName) {
|
|
1927
|
-
const comp = this.comps.getCompFor(stack.it);
|
|
1928
|
-
return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName) : null;
|
|
1929
|
-
}
|
|
1930
|
-
// `node` is the parse node of the render site (`<x render>` / `render-it` /
|
|
1931
|
-
// `render-each`, or the view's root anode for the app root). It keys the
|
|
1932
|
-
// cache as a globally-unique object: node ids alone are unique only within a
|
|
1933
|
-
// single view, so the same value rendered by two components (e.g. through a
|
|
1934
|
-
// shared dynamic-var sequence) would otherwise collide in the cache.
|
|
1935
|
-
_rValComp(stack, val, comp, node, key, viewName) {
|
|
1936
|
-
const cacheKey = `${viewName ?? ""}${stack.viewsId ?? ""}${key}`;
|
|
1937
|
-
const cachePath = [node, val];
|
|
1938
|
-
stack._pushDynBindValuesToArray(cachePath, comp);
|
|
1939
|
-
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
1940
|
-
if (cachedNode) return cachedNode;
|
|
1941
|
-
const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
|
|
1942
|
-
const body = this.renderView(view, stack);
|
|
1943
|
-
if (body == null) return null;
|
|
1944
|
-
const meta = this._renderMetadata({
|
|
1945
|
-
$: "Comp",
|
|
1946
|
-
nid: node?.nodeId ?? null,
|
|
1947
|
-
cid: comp.id,
|
|
1948
|
-
vid: view.name
|
|
1949
|
-
});
|
|
1950
|
-
const dom = new VFragment([meta, body]);
|
|
1951
|
-
this.cache.set(cachePath, cacheKey, dom);
|
|
1952
|
-
return dom;
|
|
1953
|
-
}
|
|
1954
|
-
pushEachEntry(r, nid, attrName, key, dom) {
|
|
1955
|
-
r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
|
|
1956
|
-
}
|
|
1957
|
-
renderEachWhen(stack, iterInfo, view, nid) {
|
|
1958
|
-
const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
|
|
1959
|
-
const r = [];
|
|
1960
|
-
const it = stack.it;
|
|
1961
|
-
const { iterData, start, end, keys } = unpackLoopResult(
|
|
1962
|
-
loopWith.call(it, seq, makeLoopCtx(stack, filter)),
|
|
1963
|
-
seq
|
|
1964
|
-
);
|
|
1965
|
-
const renderOne = (key, value, attrName) => {
|
|
1966
|
-
const cachePath = enricher ? [view, it, value] : [view, value];
|
|
1967
|
-
const binds = { key, value };
|
|
1968
|
-
const cacheKey = `${stack.viewsId ?? ""}${nid}${key}`;
|
|
1969
|
-
if (enricher) callEnricher(enricher, it, binds, key, value, iterData);
|
|
1970
|
-
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
1971
|
-
if (cachedNode) this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
1972
|
-
else {
|
|
1973
|
-
const dom = this.renderView(view, stack.enter(value, binds, false));
|
|
1974
|
-
if (dom != null) this.pushEachEntry(r, nid, attrName, key, dom);
|
|
1975
|
-
this.cache.set(cachePath, cacheKey, dom);
|
|
1976
|
-
}
|
|
1977
|
-
};
|
|
1978
|
-
if (keys) keysIter(seq, renderOne, keys);
|
|
1979
|
-
else
|
|
1980
|
-
getSeqInfo(seq)(
|
|
1981
|
-
seq,
|
|
1982
|
-
(key, value, attrName) => {
|
|
1983
|
-
if (filter.call(it, key, value, iterData)) renderOne(key, value, attrName);
|
|
1984
|
-
},
|
|
1985
|
-
start,
|
|
1986
|
-
end
|
|
1987
|
-
);
|
|
1988
|
-
return r;
|
|
1989
|
-
}
|
|
1990
|
-
renderView(view, stack) {
|
|
1991
|
-
let n = stack.binds[1];
|
|
1992
|
-
while (n !== null) {
|
|
1993
|
-
const b = n[0];
|
|
1994
|
-
if (b.isFrame) {
|
|
1995
|
-
if (stack.it !== b.it) break;
|
|
1996
|
-
console.error("recursion detected", stack.it, b.it);
|
|
1997
|
-
return new VComment("RECURSION AVOIDED");
|
|
1998
|
-
}
|
|
1999
|
-
n = n[1];
|
|
2000
|
-
}
|
|
2001
|
-
return view.render(stack, this);
|
|
2002
|
-
}
|
|
2003
|
-
_renderMetadata(info) {
|
|
2004
|
-
return new VComment(`§${JSON.stringify(info)}§`);
|
|
2005
|
-
}
|
|
2006
|
-
// Prefix a loop-less @enrich-with subtree with a boundary meta so event-path
|
|
2007
|
-
// reconstruction replays its binds (mirrors the §Each§ / §Comp§ metas).
|
|
2008
|
-
renderScopeMeta(nid, dom) {
|
|
2009
|
-
return new VFragment([this._renderMetadata({ $: "Scope", nid }), dom]);
|
|
2010
|
-
}
|
|
2011
|
-
};
|
|
2012
|
-
var getSeqInfo = (seq) => isIndexedSeq(seq) ? nativeIndexedIter : isKeyedSeq(seq) || isSetSeq(seq) ? nativeKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
|
|
2013
|
-
var normalizeRange = (start, end, size) => {
|
|
2014
|
-
let s = start == null ? 0 : start < 0 ? size + start : start;
|
|
2015
|
-
let e = end == null ? size : end < 0 ? size + end : end;
|
|
2016
|
-
s = s < 0 ? 0 : s > size ? size : s;
|
|
2017
|
-
e = e < 0 ? 0 : e > size ? size : e;
|
|
2018
|
-
return [s, e < s ? s : e];
|
|
2019
|
-
};
|
|
2020
|
-
var callEnricher = (enricher, it, binds, key, value, iterData) => {
|
|
2021
|
-
enricher.call(it, binds, key, value, iterData);
|
|
2022
|
-
console.assert(
|
|
2023
|
-
binds.key === key && binds.value === value,
|
|
2024
|
-
"@enrich-with handlers must not overwrite binds.key or binds.value"
|
|
2025
|
-
);
|
|
2026
|
-
binds.key = key;
|
|
2027
|
-
binds.value = value;
|
|
2028
|
-
};
|
|
2029
|
-
var filterAlwaysTrue = (_v, _k, _seq) => true;
|
|
2030
|
-
var nullLoopWith = (seq) => ({ iterData: { seq } });
|
|
2031
|
-
var unpackLoopResult = (result, seq) => {
|
|
2032
|
-
const r = result ?? {};
|
|
2033
|
-
return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end, keys: r.keys };
|
|
2034
|
-
};
|
|
2035
|
-
var keysIter = (seq, visit, keys) => {
|
|
2036
|
-
const attrName = isIndexedSeq(seq) ? "si" : "sk";
|
|
2037
|
-
for (const key of keys) visit(key, seqGet(seq, key), attrName);
|
|
2038
|
-
};
|
|
2039
|
-
var makeLoopCtx = (stack, filter) => ({
|
|
2040
|
-
lookup: (name) => stack.lookupBind(name),
|
|
2041
|
-
filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
|
|
2042
|
-
});
|
|
2043
|
-
var nativeIndexedIter = (seq, visit, start, end) => {
|
|
2044
|
-
const [s, e] = normalizeRange(start, end, seqSize(seq));
|
|
2045
|
-
for (let i = s; i < e; i++) visit(i, seq[i], "si");
|
|
2046
|
-
};
|
|
2047
|
-
var nativeKeyedIter = (seq, visit, start, end) => {
|
|
2048
|
-
const [s, e] = normalizeRange(start, end, seqSize(seq));
|
|
2049
|
-
let i = 0;
|
|
2050
|
-
for (const [k, v] of seqEntries(seq)) {
|
|
2051
|
-
if (i >= e) break;
|
|
2052
|
-
if (i >= s) visit(k, v, "sk");
|
|
2053
|
-
i++;
|
|
2054
|
-
}
|
|
2055
|
-
};
|
|
2056
|
-
var unkIter = () => {
|
|
2057
|
-
};
|
|
2058
|
-
var SEQ_INFO = /* @__PURE__ */ Symbol.for("tutuca.seqInfo");
|
|
2059
|
-
|
|
2060
1868
|
// src/anode.js
|
|
2061
1869
|
function resolveDynProducer(comp, name) {
|
|
2062
|
-
|
|
2063
|
-
const
|
|
2064
|
-
|
|
2065
|
-
producerComp = comp.scope?.lookupComponent(lk.compName);
|
|
2066
|
-
producerProvide = producerComp?.provide?.[lk.provideName];
|
|
2067
|
-
} else {
|
|
2068
|
-
const p = comp?.provide?.[name];
|
|
2069
|
-
if (p == null) return null;
|
|
2070
|
-
producerComp = comp;
|
|
2071
|
-
producerProvide = p;
|
|
2072
|
-
}
|
|
1870
|
+
const own = comp?.provide?.[name];
|
|
1871
|
+
const producerComp = own != null ? comp : comp?.scope?.lookupProvider(name) ?? null;
|
|
1872
|
+
const producerProvide = own ?? producerComp?.provide?.[name];
|
|
2073
1873
|
if (producerComp == null || producerProvide == null) return null;
|
|
2074
1874
|
const pi = producerProvide.val?.toPathItem?.() ?? null;
|
|
2075
1875
|
return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
|
|
@@ -2430,16 +2230,10 @@ function parseRenderEach(px, value, as, attrs) {
|
|
|
2430
2230
|
const seqVal = parseXOpVal("render-each", value, px, parseSequence);
|
|
2431
2231
|
if (seqVal === null) return null;
|
|
2432
2232
|
const renderIt = px.addNode(RenderItNode, as);
|
|
2433
|
-
const
|
|
2434
|
-
const eachAttr = attrParser.pushWrapper("each", value, seqVal);
|
|
2435
|
-
attrParser.eachAttr = eachAttr;
|
|
2436
|
-
const when = attrs.getNamedItem("@when");
|
|
2437
|
-
if (when) attrParser._parseWhen(when.value);
|
|
2438
|
-
const lWith = attrs.getNamedItem("@loop-with");
|
|
2439
|
-
if (lWith) attrParser._parseLoopWith(lWith.value);
|
|
2233
|
+
const { whenVal, loopWithVal } = parseIterationDirectives(attrs, px);
|
|
2440
2234
|
const each = px.addNodeIf(EachNode, seqVal);
|
|
2441
|
-
each.iterInfo.whenVal =
|
|
2442
|
-
each.iterInfo.loopWithVal =
|
|
2235
|
+
each.iterInfo.whenVal = whenVal;
|
|
2236
|
+
each.iterInfo.loopWithVal = loopWithVal;
|
|
2443
2237
|
each.fromRenderEach = true;
|
|
2444
2238
|
each.wrapNode(renderIt);
|
|
2445
2239
|
return each;
|
|
@@ -2906,7 +2700,7 @@ var Components = class {
|
|
|
2906
2700
|
}
|
|
2907
2701
|
compileStyles() {
|
|
2908
2702
|
const styles = [];
|
|
2909
|
-
for (const
|
|
2703
|
+
for (const Comp of this.byId.values()) styles.push(Comp[COMPONENT].compileStyle());
|
|
2910
2704
|
return styles.join("\n");
|
|
2911
2705
|
}
|
|
2912
2706
|
};
|
|
@@ -2965,32 +2759,39 @@ var ComponentStack = class _ComponentStack {
|
|
|
2965
2759
|
lookupComponent(name) {
|
|
2966
2760
|
return this.byName[name] ?? this.parent?.lookupComponent(name) ?? null;
|
|
2967
2761
|
}
|
|
2762
|
+
// The component in this scope chain that provides `name`, innermost first. A lookup
|
|
2763
|
+
// names a value without naming its producer, so the render-target teleport
|
|
2764
|
+
// (resolveDynProducer) recovers the producer here instead. Sound because
|
|
2765
|
+
// PROVIDE_NAME_COLLISION keeps a provide name to one producer per chain; with two,
|
|
2766
|
+
// this returns the innermost and the linter has already reported the ambiguity.
|
|
2767
|
+
lookupProvider(name) {
|
|
2768
|
+
for (const compName in this.byName) {
|
|
2769
|
+
const Comp = this.byName[compName];
|
|
2770
|
+
if (Comp.provide?.[name] !== void 0) return Comp;
|
|
2771
|
+
}
|
|
2772
|
+
return this.parent?.lookupProvider(name) ?? null;
|
|
2773
|
+
}
|
|
2968
2774
|
lookupMacro(name) {
|
|
2969
2775
|
return this.macros[name] ?? this.parent?.lookupMacro(name) ?? null;
|
|
2970
2776
|
}
|
|
2971
2777
|
};
|
|
2972
2778
|
var ProvideInfo = class {
|
|
2973
|
-
constructor(name, val
|
|
2779
|
+
constructor(name, val) {
|
|
2974
2780
|
this.name = name;
|
|
2975
2781
|
this.val = val;
|
|
2976
|
-
this.symbol = symbol;
|
|
2977
2782
|
}
|
|
2978
2783
|
};
|
|
2979
2784
|
var LookupInfo = class {
|
|
2980
|
-
constructor(name,
|
|
2785
|
+
constructor(name, val) {
|
|
2981
2786
|
this.name = name;
|
|
2982
|
-
this.compName = compName;
|
|
2983
|
-
this.provideName = provideName;
|
|
2984
2787
|
this.val = val;
|
|
2985
|
-
this._sym = void 0;
|
|
2986
|
-
}
|
|
2987
|
-
getProducerSymbol(stack) {
|
|
2988
|
-
if (this._sym === void 0)
|
|
2989
|
-
this._sym = stack.lookupType(this.compName)?.provide?.[this.provideName]?.symbol ?? null;
|
|
2990
|
-
return this._sym;
|
|
2991
2788
|
}
|
|
2992
2789
|
};
|
|
2993
2790
|
var isString = (v) => typeof v === "string";
|
|
2791
|
+
var isTypeName = (s) => {
|
|
2792
|
+
const c = s.charCodeAt(0);
|
|
2793
|
+
return c >= 65 && c <= 90;
|
|
2794
|
+
};
|
|
2994
2795
|
var _rawSpecKeys = "name view style commonStyle globalStyle receive intent alter views provide lookup fields methods statics";
|
|
2995
2796
|
var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
2996
2797
|
var _compId = 0;
|
|
@@ -3011,8 +2812,9 @@ var Component = class {
|
|
|
3011
2812
|
this.views[name] = new View(name, view, style);
|
|
3012
2813
|
}
|
|
3013
2814
|
this._rawProvide = o.provide ?? {};
|
|
3014
|
-
this._rawLookup = o.lookup ??
|
|
2815
|
+
this._rawLookup = o.lookup ?? [];
|
|
3015
2816
|
this.provide = {};
|
|
2817
|
+
this.provideType = {};
|
|
3016
2818
|
this.lookup = {};
|
|
3017
2819
|
this.scope = null;
|
|
3018
2820
|
this.spec = o;
|
|
@@ -3024,25 +2826,23 @@ var Component = class {
|
|
|
3024
2826
|
this.views[name].compile(new ParseContext2(), this.scope, this.id);
|
|
3025
2827
|
const ctx = this.views.main.ctx;
|
|
3026
2828
|
for (const key in this._rawProvide) {
|
|
2829
|
+
if (isTypeName(key)) {
|
|
2830
|
+
if (this._rawProvide[key] === "self") this.provideType[key] = this.Class;
|
|
2831
|
+
continue;
|
|
2832
|
+
}
|
|
3027
2833
|
const val = parseProvide(this._rawProvide[key], ctx);
|
|
3028
|
-
if (val) this.provide[key] = new ProvideInfo(key, val
|
|
2834
|
+
if (val) this.provide[key] = new ProvideInfo(key, val);
|
|
3029
2835
|
}
|
|
3030
|
-
for (const
|
|
3031
|
-
const
|
|
3032
|
-
|
|
3033
|
-
const
|
|
3034
|
-
|
|
3035
|
-
const defStr = isString(linfo?.default) ? linfo.default : null;
|
|
3036
|
-
const val = defStr === null ? null : parseField(defStr, ctx);
|
|
3037
|
-
this.lookup[key] = new LookupInfo(key, compName, provideName, val);
|
|
2836
|
+
for (const entry of this._rawLookup) {
|
|
2837
|
+
const name = isString(entry) ? entry : isString(entry?.name) ? entry.name : null;
|
|
2838
|
+
if (name === null) continue;
|
|
2839
|
+
const defStr = isString(entry?.default) ? entry.default : null;
|
|
2840
|
+
this.lookup[name] = new LookupInfo(name, defStr === null ? null : parseField(defStr, ctx));
|
|
3038
2841
|
}
|
|
3039
2842
|
for (const key in this.lookup)
|
|
3040
2843
|
if (this.provide[key] !== void 0)
|
|
3041
2844
|
console.warn("name declared in both provide and lookup", this.name, key);
|
|
3042
2845
|
}
|
|
3043
|
-
make(args, opts) {
|
|
3044
|
-
return this.Class.make(args, opts ?? { scope: this.scope });
|
|
3045
|
-
}
|
|
3046
2846
|
getView(name) {
|
|
3047
2847
|
return this.views[name] ?? this.views.main;
|
|
3048
2848
|
}
|
|
@@ -5345,13 +5145,19 @@ var KNOWN_DIRECTIVE_NAMES = /* @__PURE__ */ new Set([
|
|
|
5345
5145
|
"then",
|
|
5346
5146
|
"else"
|
|
5347
5147
|
]);
|
|
5148
|
+
var isTypeName2 = (s) => {
|
|
5149
|
+
const c = s.charCodeAt(0);
|
|
5150
|
+
return c >= 65 && c <= 90;
|
|
5151
|
+
};
|
|
5348
5152
|
var ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED";
|
|
5349
5153
|
var ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED";
|
|
5350
5154
|
var DYN_VAL_NOT_DEFINED = "DYN_VAL_NOT_DEFINED";
|
|
5351
5155
|
var DYN_ALIAS_NOT_REFERENCED = "DYN_ALIAS_NOT_REFERENCED";
|
|
5352
5156
|
var PROVIDE_NOT_ADDRESSABLE = "PROVIDE_NOT_ADDRESSABLE";
|
|
5157
|
+
var PROVIDE_TYPE_BAD_SHAPE = "PROVIDE_TYPE_BAD_SHAPE";
|
|
5158
|
+
var PROVIDE_NAME_COLLISION = "PROVIDE_NAME_COLLISION";
|
|
5353
5159
|
var LOOKUP_BAD_SHAPE = "LOOKUP_BAD_SHAPE";
|
|
5354
|
-
var
|
|
5160
|
+
var LOOKUP_NO_PROVIDER = "LOOKUP_NO_PROVIDER";
|
|
5355
5161
|
var RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP";
|
|
5356
5162
|
var UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER";
|
|
5357
5163
|
var RECEIVE_HANDLER_NOT_IMPLEMENTED = "RECEIVE_HANDLER_NOT_IMPLEMENTED";
|
|
@@ -5471,7 +5277,11 @@ function checkComponent(Comp, lx = new LintContext(), { wellKnownExtras = EMPTY_
|
|
|
5471
5277
|
checkFieldDeclarations(lx, Comp);
|
|
5472
5278
|
checkFieldMethodNameCollisions(lx, Comp);
|
|
5473
5279
|
checkProvidesAreAddressable(lx, Comp);
|
|
5280
|
+
checkProvidedTypes(lx, Comp);
|
|
5281
|
+
checkProvideNameCollisions(lx, Comp);
|
|
5474
5282
|
checkLookupShapes(lx, Comp);
|
|
5283
|
+
checkLookupTypesResolve(lx, Comp);
|
|
5284
|
+
checkLookupsHaveProviders(lx, Comp);
|
|
5475
5285
|
checkHandlersNotAsync(lx, Comp);
|
|
5476
5286
|
checkHandlerNameCollisions(lx, Comp);
|
|
5477
5287
|
checkScopedStyleTopLevel(lx, Comp);
|
|
@@ -5806,16 +5616,6 @@ var ATTR_VAL_CHECKERS = {
|
|
|
5806
5616
|
recurse(val.seqVal);
|
|
5807
5617
|
recurse(val.keyVal);
|
|
5808
5618
|
},
|
|
5809
|
-
TypeVal({ lx, val, env, errCtx }) {
|
|
5810
|
-
if (env.scope.lookupComponent(val.name) === null)
|
|
5811
|
-
reportUnknownName(
|
|
5812
|
-
lx,
|
|
5813
|
-
UNKNOWN_COMPONENT_NAME,
|
|
5814
|
-
val.name,
|
|
5815
|
-
scopeKeysAlong(env.scope, "byName"),
|
|
5816
|
-
errCtx
|
|
5817
|
-
);
|
|
5818
|
-
},
|
|
5819
5619
|
// NameVals on a macro call-site attribute are macro-param bindings, not
|
|
5820
5620
|
// handler args — their role is determined inside the macro body after
|
|
5821
5621
|
// ^-substitution, where re-parsing handles validation. No checker: a NameVal
|
|
@@ -6149,48 +5949,90 @@ function checkScopedStyleTopLevel(lx, Comp) {
|
|
|
6149
5949
|
}
|
|
6150
5950
|
function checkProvidesAreAddressable(lx, Comp) {
|
|
6151
5951
|
for (const name in Comp._rawProvide) {
|
|
5952
|
+
if (isTypeName2(name)) continue;
|
|
6152
5953
|
if (Comp.provide[name] === void 0) {
|
|
6153
5954
|
lx.error(PROVIDE_NOT_ADDRESSABLE, { name, value: Comp._rawProvide[name] });
|
|
6154
5955
|
}
|
|
6155
5956
|
}
|
|
6156
5957
|
}
|
|
6157
|
-
|
|
5958
|
+
function checkProvidedTypes(lx, Comp) {
|
|
5959
|
+
for (const name in Comp._rawProvide) {
|
|
5960
|
+
if (!isTypeName2(name)) continue;
|
|
5961
|
+
const raw = Comp._rawProvide[name];
|
|
5962
|
+
if (raw !== "self") lx.error(PROVIDE_TYPE_BAD_SHAPE, { name, value: raw });
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
function checkProvideNameCollisions(lx, Comp) {
|
|
5966
|
+
const scope = Comp.scope;
|
|
5967
|
+
if (!scope) return;
|
|
5968
|
+
for (const name in Comp.provide) {
|
|
5969
|
+
for (let s = scope; s; s = s.parent) {
|
|
5970
|
+
for (const otherName in s.byName) {
|
|
5971
|
+
const Other = s.byName[otherName];
|
|
5972
|
+
if (Other !== Comp && Other.provide?.[name] !== void 0)
|
|
5973
|
+
lx.error(PROVIDE_NAME_COLLISION, { name, other: Other.name });
|
|
5974
|
+
}
|
|
5975
|
+
}
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5978
|
+
var KNOWN_LOOKUP_KEYS = /* @__PURE__ */ new Set(["name", "default"]);
|
|
6158
5979
|
function checkLookupShapes(lx, Comp) {
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
5980
|
+
const raw = Comp._rawLookup;
|
|
5981
|
+
if (!Array.isArray(raw)) {
|
|
5982
|
+
if (raw !== void 0 && Object.keys(raw).length > 0)
|
|
5983
|
+
lx.error(LOOKUP_BAD_SHAPE, { name: "lookup", problem: "must be a list of names" });
|
|
5984
|
+
return;
|
|
5985
|
+
}
|
|
5986
|
+
for (const entry of raw) {
|
|
5987
|
+
if (typeof entry === "string") continue;
|
|
5988
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) {
|
|
6165
5989
|
lx.error(LOOKUP_BAD_SHAPE, {
|
|
6166
|
-
name,
|
|
6167
|
-
problem: 'must be a "
|
|
5990
|
+
name: String(entry),
|
|
5991
|
+
problem: 'must be a "name" string or a { name, default } object'
|
|
5992
|
+
});
|
|
5993
|
+
continue;
|
|
5994
|
+
}
|
|
5995
|
+
const extra = Object.keys(entry).filter((k) => !KNOWN_LOOKUP_KEYS.has(k));
|
|
5996
|
+
if (extra.length > 0) {
|
|
5997
|
+
lx.error(LOOKUP_BAD_SHAPE, {
|
|
5998
|
+
name: String(entry.name),
|
|
5999
|
+
problem: `unknown key(s): ${extra.join(", ")}`
|
|
6168
6000
|
});
|
|
6169
6001
|
continue;
|
|
6170
|
-
} else {
|
|
6171
|
-
const extra = Object.keys(raw).filter((k) => !KNOWN_LOOKUP_KEYS.has(k));
|
|
6172
|
-
if (extra.length > 0) {
|
|
6173
|
-
lx.error(LOOKUP_BAD_SHAPE, { name, problem: `unknown key(s): ${extra.join(", ")}` });
|
|
6174
|
-
continue;
|
|
6175
|
-
}
|
|
6176
|
-
if (typeof raw.for !== "string") {
|
|
6177
|
-
lx.error(LOOKUP_BAD_SHAPE, { name, problem: "'for' is required and must be a string" });
|
|
6178
|
-
continue;
|
|
6179
|
-
}
|
|
6180
|
-
if (raw.default !== void 0 && typeof raw.default !== "string") {
|
|
6181
|
-
lx.error(LOOKUP_BAD_SHAPE, { name, problem: "'default' must be a string" });
|
|
6182
|
-
continue;
|
|
6183
|
-
}
|
|
6184
|
-
target = raw.for;
|
|
6185
6002
|
}
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6003
|
+
if (typeof entry.name !== "string" || entry.name === "") {
|
|
6004
|
+
lx.error(LOOKUP_BAD_SHAPE, {
|
|
6005
|
+
name: String(entry.name),
|
|
6006
|
+
problem: "'name' is required and must be a string"
|
|
6007
|
+
});
|
|
6008
|
+
continue;
|
|
6189
6009
|
}
|
|
6010
|
+
if (entry.default !== void 0 && typeof entry.default !== "string")
|
|
6011
|
+
lx.error(LOOKUP_BAD_SHAPE, { name: entry.name, problem: "'default' must be a string" });
|
|
6012
|
+
}
|
|
6013
|
+
}
|
|
6014
|
+
function checkLookupsHaveProviders(lx, Comp) {
|
|
6015
|
+
const scope = Comp.scope;
|
|
6016
|
+
if (!scope) return;
|
|
6017
|
+
for (const name in Comp.lookup) {
|
|
6018
|
+
if (isTypeName2(name)) continue;
|
|
6019
|
+
if (scope.lookupProvider?.(name)) continue;
|
|
6020
|
+
const info = { name, hasDefault: Comp.lookup[name].val != null };
|
|
6021
|
+
if (info.hasDefault) lx.hint(LOOKUP_NO_PROVIDER, info);
|
|
6022
|
+
else lx.error(LOOKUP_NO_PROVIDER, info);
|
|
6023
|
+
}
|
|
6024
|
+
}
|
|
6025
|
+
function checkLookupTypesResolve(lx, Comp) {
|
|
6026
|
+
if (!Comp.scope) return;
|
|
6027
|
+
for (const name in Comp.lookup) {
|
|
6028
|
+
if (!isTypeName2(name)) continue;
|
|
6029
|
+
if (Comp.scope.lookupComponent(name) === null)
|
|
6030
|
+
reportUnknownName(lx, UNKNOWN_COMPONENT_NAME, name, scopeKeysAlong(Comp.scope, "byName"), {});
|
|
6190
6031
|
}
|
|
6191
6032
|
}
|
|
6192
6033
|
function checkUnreferencedDynamics(lx, Comp, referencedDynamics) {
|
|
6193
6034
|
for (const name in Comp.lookup) {
|
|
6035
|
+
if (isTypeName2(name)) continue;
|
|
6194
6036
|
if (!referencedDynamics.has(name)) {
|
|
6195
6037
|
lx.hint(DYN_ALIAS_NOT_REFERENCED, { name });
|
|
6196
6038
|
}
|
|
@@ -6255,7 +6097,7 @@ function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
|
6255
6097
|
const args = resolveArgs(op.args, self);
|
|
6256
6098
|
switch (op.type) {
|
|
6257
6099
|
case "send":
|
|
6258
|
-
dispatcher.sendAtPath(targetPath, op.name, args
|
|
6100
|
+
dispatcher.sendAtPath(targetPath, op.name, args);
|
|
6259
6101
|
break;
|
|
6260
6102
|
case "intent":
|
|
6261
6103
|
dispatcher.intentAtPath(targetPath, op.name, args, op.opts);
|
|
@@ -6267,11 +6109,6 @@ function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
|
6267
6109
|
// src/oo.js
|
|
6268
6110
|
var BAD_VALUE2 = /* @__PURE__ */ Symbol("BadValue");
|
|
6269
6111
|
var nullCoercer = (v) => v;
|
|
6270
|
-
var isPlainObject2 = (v) => {
|
|
6271
|
-
if (v === null || typeof v !== "object") return false;
|
|
6272
|
-
const proto = Object.getPrototypeOf(v);
|
|
6273
|
-
return proto === Object.prototype || proto === null;
|
|
6274
|
-
};
|
|
6275
6112
|
function defaultToData(v) {
|
|
6276
6113
|
if (v instanceof Map) return [...v.entries()];
|
|
6277
6114
|
if (v instanceof Set) return [...v.values()];
|
|
@@ -6340,7 +6177,7 @@ var CHECK_TYPE_FLOAT = check(Number.isFinite, "Float expected");
|
|
|
6340
6177
|
var CHECK_TYPE_BOOL = check((v) => typeof v === "boolean", "Boolean expected");
|
|
6341
6178
|
var CHECK_TYPE_STRING = check((v) => typeof v === "string", "String expected");
|
|
6342
6179
|
var CHECK_TYPE_LIST = check(Array.isArray, "Array expected");
|
|
6343
|
-
var CHECK_TYPE_OBJECT = check(
|
|
6180
|
+
var CHECK_TYPE_OBJECT = check(isPlainObject, "Plain object expected");
|
|
6344
6181
|
var CHECK_TYPE_MAP = check((v) => v instanceof Map, "Map expected");
|
|
6345
6182
|
var CHECK_TYPE_SET = check((v) => v instanceof Set, "Set expected");
|
|
6346
6183
|
var FieldBool = class extends Field {
|
|
@@ -6409,7 +6246,7 @@ var FieldObject = class extends Field {
|
|
|
6409
6246
|
"object",
|
|
6410
6247
|
name,
|
|
6411
6248
|
CHECK_TYPE_OBJECT,
|
|
6412
|
-
(v) =>
|
|
6249
|
+
(v) => isPlainObject(v) ? { ...v } : null,
|
|
6413
6250
|
defaultValue
|
|
6414
6251
|
);
|
|
6415
6252
|
}
|
|
@@ -6422,7 +6259,7 @@ var FieldMap = class extends Field {
|
|
|
6422
6259
|
CHECK_TYPE_MAP,
|
|
6423
6260
|
(v) => {
|
|
6424
6261
|
if (v instanceof Map) return new Map(v);
|
|
6425
|
-
if (Array.isArray(v) ||
|
|
6262
|
+
if (Array.isArray(v) || isPlainObject(v))
|
|
6426
6263
|
return new Map(Array.isArray(v) ? v : Object.entries(v));
|
|
6427
6264
|
return null;
|
|
6428
6265
|
},
|
|
@@ -6547,7 +6384,7 @@ function classFromData(name, { fields = {}, methods, statics }) {
|
|
|
6547
6384
|
b.addField(field, dval, FieldCls);
|
|
6548
6385
|
} else if (value?.component && value?.args !== void 0)
|
|
6549
6386
|
b.addCompField(field, value.component, value.args);
|
|
6550
|
-
else if (
|
|
6387
|
+
else if (isPlainObject(value)) b.addField(field, { ...value }, FieldObject);
|
|
6551
6388
|
else {
|
|
6552
6389
|
const FieldCls = value?.[FIELD_CLASS] ?? FieldAny;
|
|
6553
6390
|
b.addField(field, value, FieldCls);
|
|
@@ -6571,10 +6408,24 @@ function validateDraftFields(current, draft) {
|
|
|
6571
6408
|
}
|
|
6572
6409
|
}
|
|
6573
6410
|
}
|
|
6574
|
-
var META_KEYS = "name id fields methods views receive intent alter provide lookup spec extra commonStyle globalStyle scope _rawProvide _rawLookup".split(
|
|
6411
|
+
var META_KEYS = "name id fields methods views receive intent alter provide provideType lookup spec extra commonStyle globalStyle scope _rawProvide _rawLookup".split(
|
|
6575
6412
|
" "
|
|
6576
6413
|
);
|
|
6414
|
+
var RESERVED_COMPONENT_STATICS = /* @__PURE__ */ new Set([
|
|
6415
|
+
...META_KEYS,
|
|
6416
|
+
"make",
|
|
6417
|
+
"getMetaClass",
|
|
6418
|
+
...Object.getOwnPropertyNames(Component.prototype)
|
|
6419
|
+
]);
|
|
6420
|
+
function assertNoReservedComponentStatics(statics = {}) {
|
|
6421
|
+
for (const name in statics) {
|
|
6422
|
+
if (RESERVED_COMPONENT_STATICS.has(name)) {
|
|
6423
|
+
throw new TypeError(`component static "${name}" is reserved by the framework`);
|
|
6424
|
+
}
|
|
6425
|
+
}
|
|
6426
|
+
}
|
|
6577
6427
|
Component.fromSpec = (opts) => {
|
|
6428
|
+
assertNoReservedComponentStatics(opts.statics);
|
|
6578
6429
|
const Class = classFromData(opts.name, opts);
|
|
6579
6430
|
const comp = new Component(Class, opts);
|
|
6580
6431
|
const metaClass = Class.getMetaClass();
|
|
@@ -6594,7 +6445,7 @@ Component.fromSpec = (opts) => {
|
|
|
6594
6445
|
configurable: true
|
|
6595
6446
|
});
|
|
6596
6447
|
for (const key of Object.getOwnPropertyNames(Component.prototype))
|
|
6597
|
-
if (key !== "constructor" &&
|
|
6448
|
+
if (key !== "constructor" && !Object.hasOwn(Class, key))
|
|
6598
6449
|
Class[key] = (...args) => comp[key](...args);
|
|
6599
6450
|
return Class;
|
|
6600
6451
|
};
|
|
@@ -6603,6 +6454,22 @@ var component = (opts) => Component.fromSpec(opts);
|
|
|
6603
6454
|
// src/stack.js
|
|
6604
6455
|
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
6605
6456
|
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
6457
|
+
var DEFAULT_LOOKUP_ROUTE = ["dyn", "lex"];
|
|
6458
|
+
function routeLookup(route, lex, dyn) {
|
|
6459
|
+
for (let i = 0; i < route.length; i++) {
|
|
6460
|
+
const leg = route[i];
|
|
6461
|
+
if (leg === "dyn") {
|
|
6462
|
+
const v = dyn();
|
|
6463
|
+
if (v != null) return v;
|
|
6464
|
+
} else if (leg === "lex") {
|
|
6465
|
+
const v = lex();
|
|
6466
|
+
if (v != null) return v;
|
|
6467
|
+
} else {
|
|
6468
|
+
console.warn("unknown lookup route leg", leg, '- expected "dyn" or "lex"');
|
|
6469
|
+
}
|
|
6470
|
+
}
|
|
6471
|
+
return null;
|
|
6472
|
+
}
|
|
6606
6473
|
function lookup(chain, name, dv = null) {
|
|
6607
6474
|
let n = chain;
|
|
6608
6475
|
while (n !== null) {
|
|
@@ -6653,14 +6520,21 @@ var Stack = class _Stack {
|
|
|
6653
6520
|
this.ctx = ctx;
|
|
6654
6521
|
}
|
|
6655
6522
|
// Evaluate every provide the entered component publishes and push them as one
|
|
6656
|
-
// dynBinds frame
|
|
6523
|
+
// dynBinds frame, keyed by NAME. Published types go in the same frame: a type name
|
|
6524
|
+
// starts A-Z and a value name does not, so the two namespaces cannot collide and
|
|
6525
|
+
// nearest-ancestor-wins falls out of frame order for both. No-op with no provides.
|
|
6657
6526
|
_pushProvides() {
|
|
6658
|
-
const
|
|
6659
|
-
if (
|
|
6527
|
+
const comp = this.comps.getCompFor(this.it);
|
|
6528
|
+
if (comp == null) return this;
|
|
6529
|
+
const { provide, provideType } = comp;
|
|
6660
6530
|
const dynObj = {};
|
|
6661
6531
|
let has = false;
|
|
6662
6532
|
for (const k in provide) {
|
|
6663
|
-
dynObj[
|
|
6533
|
+
dynObj[k] = provide[k].val.eval(this);
|
|
6534
|
+
has = true;
|
|
6535
|
+
}
|
|
6536
|
+
for (const k in provideType) {
|
|
6537
|
+
dynObj[k] = provideType[k];
|
|
6664
6538
|
has = true;
|
|
6665
6539
|
}
|
|
6666
6540
|
if (!has) return this;
|
|
@@ -6685,30 +6559,36 @@ var Stack = class _Stack {
|
|
|
6685
6559
|
const newViews = [name, views];
|
|
6686
6560
|
return new _Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
6687
6561
|
}
|
|
6562
|
+
// Published types are stable per scope and would only churn the render cache, so
|
|
6563
|
+
// the cache key covers values alone.
|
|
6688
6564
|
_pushDynBindValuesToArray(arr, comp) {
|
|
6689
|
-
for (const k in comp.provide) arr.push(this.
|
|
6690
|
-
for (const k in comp.lookup) arr.push(this.
|
|
6691
|
-
}
|
|
6692
|
-
_lookupProvide(p) {
|
|
6693
|
-
return lookup(this.dynBinds, p.symbol) ?? p.val.eval(this) ?? null;
|
|
6694
|
-
}
|
|
6695
|
-
_lookupAlias(lk) {
|
|
6696
|
-
const sym = lk.getProducerSymbol(this);
|
|
6697
|
-
return (sym != null ? lookup(this.dynBinds, sym) : null) ?? lk.val?.eval(this) ?? null;
|
|
6565
|
+
for (const k in comp.provide) arr.push(this.lookupDynamic(k));
|
|
6566
|
+
for (const k in comp.lookup) arr.push(this.lookupDynamic(k));
|
|
6698
6567
|
}
|
|
6568
|
+
// `*name`: the nearest binding above (including this component's own provides,
|
|
6569
|
+
// pushed on entering it), else this component's declared default, else null.
|
|
6699
6570
|
lookupDynamic(name) {
|
|
6571
|
+
const v = lookup(this.dynBinds, name);
|
|
6572
|
+
if (v != null) return v;
|
|
6700
6573
|
const comp = this.comps.getCompFor(this.it);
|
|
6701
|
-
|
|
6702
|
-
const lk = comp.lookup[name];
|
|
6703
|
-
if (lk !== void 0) return this._lookupAlias(lk);
|
|
6704
|
-
const p = comp.provide[name];
|
|
6705
|
-
return p !== void 0 ? this._lookupProvide(p) : null;
|
|
6574
|
+
return comp?.lookup[name]?.val?.eval(this) ?? null;
|
|
6706
6575
|
}
|
|
6707
6576
|
lookupBind(name) {
|
|
6708
6577
|
return lookup(this.binds, name);
|
|
6709
6578
|
}
|
|
6710
|
-
|
|
6711
|
-
|
|
6579
|
+
// The `lex` leg: what a name means in the registration scope of the component being
|
|
6580
|
+
// rendered. The scope chain holds components, so this leg only ever answers for a
|
|
6581
|
+
// type name — for a value name it is a miss, which is why one default route serves
|
|
6582
|
+
// both. Guarded: a non-component `it` has no scope to ask.
|
|
6583
|
+
_lookupLex(name) {
|
|
6584
|
+
return this.comps.getCompFor(this.it)?.scope.lookupComponent(name) ?? null;
|
|
6585
|
+
}
|
|
6586
|
+
lookupRouted(name, route = DEFAULT_LOOKUP_ROUTE) {
|
|
6587
|
+
return routeLookup(
|
|
6588
|
+
route,
|
|
6589
|
+
() => this._lookupLex(name),
|
|
6590
|
+
() => this.lookupDynamic(name)
|
|
6591
|
+
);
|
|
6712
6592
|
}
|
|
6713
6593
|
lookupFieldRaw(name) {
|
|
6714
6594
|
return this.it[name] ?? null;
|
|
@@ -6717,12 +6597,6 @@ var Stack = class _Stack {
|
|
|
6717
6597
|
const fn = this.it[name];
|
|
6718
6598
|
return fn instanceof Function ? fn.call(this.it) : null;
|
|
6719
6599
|
}
|
|
6720
|
-
// Bare implicit event names are gone: a sigil-less word cannot reach a
|
|
6721
|
-
// handler-arg slot anymore, so this only ever serves stale NameVals parsed
|
|
6722
|
-
// before the removal (e.g. macro-attr pass-throughs). Always null.
|
|
6723
|
-
lookupName(_name) {
|
|
6724
|
-
return null;
|
|
6725
|
-
}
|
|
6726
6600
|
// The dispatched DOM event / drag info, read only by EventMemberVal's
|
|
6727
6601
|
// `e.<member>` handler args. Null outside a live event transaction.
|
|
6728
6602
|
lookupEvent() {
|
|
@@ -6759,9 +6633,6 @@ var State2 = class {
|
|
|
6759
6633
|
this.val = val;
|
|
6760
6634
|
for (const sub of this.changeSubs) sub({ val, old, info, timestamp: Date.now() });
|
|
6761
6635
|
}
|
|
6762
|
-
update(fn, info) {
|
|
6763
|
-
return this.set(fn(this.val), info);
|
|
6764
|
-
}
|
|
6765
6636
|
};
|
|
6766
6637
|
var Transactor = class {
|
|
6767
6638
|
constructor(comps, rootValue) {
|
|
@@ -6822,7 +6693,7 @@ var Transactor = class {
|
|
|
6822
6693
|
// Build and dispatch the observer record for a settled transaction. The
|
|
6823
6694
|
// resolved handler (`_resolvedHandler`/`_matched`) and per-leaf before/after
|
|
6824
6695
|
// (`_before`/`_after`) were captured while the handler ran (see callHandler /
|
|
6825
|
-
//
|
|
6696
|
+
// Transaction.run). No-op when nobody is observing.
|
|
6826
6697
|
_emitTransaction(transaction, root) {
|
|
6827
6698
|
if (this._observers.length === 0) return;
|
|
6828
6699
|
if (transaction._resolvedHandler === void 0) return;
|
|
@@ -6854,8 +6725,13 @@ var Transactor = class {
|
|
|
6854
6725
|
}
|
|
6855
6726
|
return child;
|
|
6856
6727
|
}
|
|
6857
|
-
|
|
6858
|
-
|
|
6728
|
+
// `origin` is where the message came FROM, pinned now for the same reason an
|
|
6729
|
+
// intent's answerPath is: a reply must reach the sender that asked even if a key
|
|
6730
|
+
// moved while the message was in flight. Null when nobody is waiting — a host
|
|
6731
|
+
// sendAtRoot or a view's own `@on.*` — and ctx.sendReply refuses on that.
|
|
6732
|
+
pushSend(path, name, args = [], parent = null, origin = null) {
|
|
6733
|
+
const t = new SendEvent(path, this, name, args, parent);
|
|
6734
|
+
t.origin = origin === null ? null : origin.toTransactionPath().pinKeys(this.state.val);
|
|
6859
6735
|
this.pushTransaction(t);
|
|
6860
6736
|
return this._link(t, parent);
|
|
6861
6737
|
}
|
|
@@ -6868,9 +6744,9 @@ var Transactor = class {
|
|
|
6868
6744
|
walk.advance();
|
|
6869
6745
|
return walk;
|
|
6870
6746
|
}
|
|
6871
|
-
// Drain queued transactions and await
|
|
6872
|
-
//
|
|
6873
|
-
//
|
|
6747
|
+
// Drain queued transactions and await async intent handlers until quiescent. A
|
|
6748
|
+
// completed handler may enqueue an answer, which may dispatch more work, so we loop.
|
|
6749
|
+
// `maxTurns` backstops a pathological non-terminating cascade.
|
|
6874
6750
|
async settle(maxTurns = 1e4) {
|
|
6875
6751
|
while ((this.hasPendingTransactions || this._inflight.size) && maxTurns-- > 0) {
|
|
6876
6752
|
while (this.hasPendingTransactions) this.transactNext();
|
|
@@ -6927,9 +6803,6 @@ var Transaction = class {
|
|
|
6927
6803
|
whenSubtreeSettled() {
|
|
6928
6804
|
return this.completion.whenSubtreeSettled();
|
|
6929
6805
|
}
|
|
6930
|
-
run(rootValue, comps) {
|
|
6931
|
-
return this.updateRootValue(rootValue, comps);
|
|
6932
|
-
}
|
|
6933
6806
|
afterTransaction() {
|
|
6934
6807
|
}
|
|
6935
6808
|
// Ending a walk and forwarding belong to the two dispatch buckets; the base warns
|
|
@@ -6941,12 +6814,6 @@ var Transaction = class {
|
|
|
6941
6814
|
forward(_opts) {
|
|
6942
6815
|
console.warn('ctx.forward() needs a "receive" or "intent" handler - ignored');
|
|
6943
6816
|
}
|
|
6944
|
-
buildRootStack(root, comps) {
|
|
6945
|
-
return Stack.root(comps, root);
|
|
6946
|
-
}
|
|
6947
|
-
buildStack(root, comps) {
|
|
6948
|
-
return this.path.toTransactionPath().buildStack(this.buildRootStack(root, comps));
|
|
6949
|
-
}
|
|
6950
6817
|
// The kind reported to observers (see Transactor.observe); null on the base.
|
|
6951
6818
|
get observeKind() {
|
|
6952
6819
|
return null;
|
|
@@ -6966,12 +6833,11 @@ var Transaction = class {
|
|
|
6966
6833
|
return null;
|
|
6967
6834
|
}
|
|
6968
6835
|
// The path used to apply the mutation. Teleports dynamic-var renders so it lands on
|
|
6969
|
-
// the data's real location (the dispatch `this.path` keeps intermediates).
|
|
6970
|
-
// may override to supply a pre-resolved path (see ResponseEvent's pinned keys).
|
|
6836
|
+
// the data's real location (the dispatch `this.path` keeps intermediates).
|
|
6971
6837
|
getTransactionPath() {
|
|
6972
6838
|
return this.path.toTransactionPath().compact();
|
|
6973
6839
|
}
|
|
6974
|
-
|
|
6840
|
+
run(curRoot, comps) {
|
|
6975
6841
|
const txnPath = this.getTransactionPath();
|
|
6976
6842
|
const curLeaf = txnPath.lookup(curRoot);
|
|
6977
6843
|
const newLeaf = (0, immer_exports.produce)(curLeaf, (draft) => {
|
|
@@ -7028,8 +6894,8 @@ var InputEvent = class extends Transaction {
|
|
|
7028
6894
|
}
|
|
7029
6895
|
this.transactor.pushIntent(this.dispatchPath, name, args, rest, this);
|
|
7030
6896
|
}
|
|
7031
|
-
|
|
7032
|
-
return Stack.root(comps, root, this);
|
|
6897
|
+
buildStack(root, comps) {
|
|
6898
|
+
return this.path.toTransactionPath().buildStack(Stack.root(comps, root, this));
|
|
7033
6899
|
}
|
|
7034
6900
|
getHandlerAndArgs(root, _instance, comps) {
|
|
7035
6901
|
const stack = this.buildStack(root, comps);
|
|
@@ -7047,11 +6913,10 @@ var InputEvent = class extends Transaction {
|
|
|
7047
6913
|
}
|
|
7048
6914
|
};
|
|
7049
6915
|
var NameArgsTransaction = class extends Transaction {
|
|
7050
|
-
constructor(path, transactor, name, args, parentTransaction
|
|
6916
|
+
constructor(path, transactor, name, args, parentTransaction) {
|
|
7051
6917
|
super(path, transactor, parentTransaction);
|
|
7052
6918
|
this.name = name;
|
|
7053
6919
|
this.args = args;
|
|
7054
|
-
this.opts = opts;
|
|
7055
6920
|
this.targetPath = path;
|
|
7056
6921
|
}
|
|
7057
6922
|
handlerProp = null;
|
|
@@ -7110,7 +6975,7 @@ var SendEvent = class extends NameArgsTransaction {
|
|
|
7110
6975
|
var IntentEvent = class extends NameArgsTransaction {
|
|
7111
6976
|
handlerProp = "intent";
|
|
7112
6977
|
constructor(path, transactor, walk) {
|
|
7113
|
-
super(path, transactor, walk.name, walk.args, walk.parent
|
|
6978
|
+
super(path, transactor, walk.name, walk.args, walk.parent);
|
|
7114
6979
|
this.walk = walk;
|
|
7115
6980
|
this.targetPath = walk.origin;
|
|
7116
6981
|
}
|
|
@@ -7210,7 +7075,7 @@ var IntentWalk = class {
|
|
|
7210
7075
|
async _runLex(chain, i) {
|
|
7211
7076
|
if (this.ended) return;
|
|
7212
7077
|
if (i >= chain.length) return this.advance();
|
|
7213
|
-
const ctx = new
|
|
7078
|
+
const ctx = new Dispatcher(this.origin, this.transactor, this.parent);
|
|
7214
7079
|
try {
|
|
7215
7080
|
const res = await chain[i].fn.apply(null, [...this.args, ctx]);
|
|
7216
7081
|
if (res === PASS) return this._runLex(chain, i + 1);
|
|
@@ -7263,7 +7128,7 @@ var IntentWalk = class {
|
|
|
7263
7128
|
this.ended = true;
|
|
7264
7129
|
if (name === null) return this.release?.();
|
|
7265
7130
|
const path = this.answerPath ?? this.origin;
|
|
7266
|
-
const t = new SendEvent(path, this.transactor, name, args, this.parent
|
|
7131
|
+
const t = new SendEvent(path, this.transactor, name, args, this.parent);
|
|
7267
7132
|
t._isAnswer = true;
|
|
7268
7133
|
this.transactor.pushTransaction(t);
|
|
7269
7134
|
if (this.release) t.completion.whenSubtreeSettled().then(this.release);
|
|
@@ -7302,7 +7167,7 @@ var Completion = class {
|
|
|
7302
7167
|
this.val = val;
|
|
7303
7168
|
this._selfResolve?.(val);
|
|
7304
7169
|
}
|
|
7305
|
-
// Settle self even when no handler produced a value (
|
|
7170
|
+
// Settle self even when no handler produced a value (undefined-state / throw paths).
|
|
7306
7171
|
ensureSelfSettled() {
|
|
7307
7172
|
if (!this.selfSettled) this.markSelfSettled(this.val);
|
|
7308
7173
|
}
|
|
@@ -7348,12 +7213,64 @@ var Dispatcher = class {
|
|
|
7348
7213
|
get at() {
|
|
7349
7214
|
return new PathChanges(this);
|
|
7350
7215
|
}
|
|
7216
|
+
// The render-time Stack, rebuilt on demand. A handler does not get one: the stack
|
|
7217
|
+
// that evaluated its arguments is a local in getHandlerAndArgs and is gone by the
|
|
7218
|
+
// time the body runs, and send/intent transactions never build one at all. Both
|
|
7219
|
+
// halves it needs are pinned on this ctx, so the `dyn` leg reconstructs it — and
|
|
7220
|
+
// only the `dyn` leg does, which is why this is lazy rather than eager.
|
|
7221
|
+
//
|
|
7222
|
+
// The path is compacted, so per-item binds (`@each`, `@enrich-with`) are not
|
|
7223
|
+
// replayed; provides are pushed on every component frame either way, so a provide
|
|
7224
|
+
// that reads a loop binding is the one case this cannot reproduce faithfully.
|
|
7225
|
+
_stack() {
|
|
7226
|
+
this._stackMemo ??= this.path.toTransactionPath().buildStack(Stack.root(this.transactor.comps, this.root, this.parent));
|
|
7227
|
+
return this._stackMemo;
|
|
7228
|
+
}
|
|
7229
|
+
// Resolve a name the way the renderer would. `opts.route` takes the same legs in
|
|
7230
|
+
// the same spelling as `ctx.intent` — `["dyn"]` the render ancestry, `["lex"]` the
|
|
7231
|
+
// registration scope, default both.
|
|
7232
|
+
lookup(name, opts) {
|
|
7233
|
+
const route = opts?.route ?? DEFAULT_LOOKUP_ROUTE;
|
|
7234
|
+
return routeLookup(
|
|
7235
|
+
route,
|
|
7236
|
+
() => this._lookupLex(name),
|
|
7237
|
+
() => this._stack()?.lookupDynamic(name) ?? null
|
|
7238
|
+
);
|
|
7239
|
+
}
|
|
7240
|
+
// The `lex` leg without a Stack: the scope of the component whose handler is
|
|
7241
|
+
// running, which is the leaf of this ctx's path.
|
|
7242
|
+
_lookupLex(name) {
|
|
7243
|
+
let Comp = null;
|
|
7244
|
+
this.walkPath((c) => {
|
|
7245
|
+
Comp = c;
|
|
7246
|
+
return false;
|
|
7247
|
+
});
|
|
7248
|
+
return Comp?.scope?.lookupComponent(name) ?? null;
|
|
7249
|
+
}
|
|
7250
|
+
// A component lookup is a value lookup constrained to a component. The `lex` leg
|
|
7251
|
+
// can only ever answer with one; the `dyn` leg reads a binding an ancestor
|
|
7252
|
+
// published, so it is the leg that has to be checked.
|
|
7253
|
+
lookupType(name, opts) {
|
|
7254
|
+
const v = this.lookup(name, opts);
|
|
7255
|
+
if (v == null) {
|
|
7256
|
+
this.transactor.refuse("TYPE_NOT_FOUND", {
|
|
7257
|
+
name,
|
|
7258
|
+
route: opts?.route ?? DEFAULT_LOOKUP_ROUTE
|
|
7259
|
+
});
|
|
7260
|
+
return null;
|
|
7261
|
+
}
|
|
7262
|
+
if (v?.[COMPONENT] == null) {
|
|
7263
|
+
this.transactor.refuse("TYPE_NOT_COMPONENT", { name, got: typeof v });
|
|
7264
|
+
return null;
|
|
7265
|
+
}
|
|
7266
|
+
return v;
|
|
7267
|
+
}
|
|
7351
7268
|
// A message is ADDRESSED: it names one component and stops there.
|
|
7352
|
-
send(name, args
|
|
7353
|
-
return this.sendAtPath(this.path, name, args
|
|
7269
|
+
send(name, args) {
|
|
7270
|
+
return this.sendAtPath(this.path, name, args);
|
|
7354
7271
|
}
|
|
7355
|
-
sendAtPath(path, name, args
|
|
7356
|
-
return this.transactor.pushSend(path, name, args,
|
|
7272
|
+
sendAtPath(path, name, args) {
|
|
7273
|
+
return this.transactor.pushSend(path, name, args, this.parent, this.path);
|
|
7357
7274
|
}
|
|
7358
7275
|
// An intent is ROUTED: it names a job and walks until something answers. The verb
|
|
7359
7276
|
// does not decide which scope answers — `opts.route` does, written here at the call
|
|
@@ -7364,9 +7281,6 @@ var Dispatcher = class {
|
|
|
7364
7281
|
intentAtPath(path, name, args, opts) {
|
|
7365
7282
|
return this.transactor.pushIntent(path, name, args, opts, this.parent);
|
|
7366
7283
|
}
|
|
7367
|
-
lookupTypeFor(name, inst) {
|
|
7368
|
-
return this.transactor.comps.getCompFor(inst).scope.lookupComponent(name);
|
|
7369
|
-
}
|
|
7370
7284
|
};
|
|
7371
7285
|
var EventContext = class extends Dispatcher {
|
|
7372
7286
|
get name() {
|
|
@@ -7383,6 +7297,19 @@ var EventContext = class extends Dispatcher {
|
|
|
7383
7297
|
fail(error) {
|
|
7384
7298
|
return this.parent.walk === void 0 ? warnNotIntent("fail") : this.parent.walk.answer("Error", error);
|
|
7385
7299
|
}
|
|
7300
|
+
// Reply to the sender of the MESSAGE being handled. An intent answers under a name
|
|
7301
|
+
// the runtime derives (`<name>Ok`), because the raiser asked a question and declared
|
|
7302
|
+
// arms for it; a message did not, so the replier names the reply itself and the
|
|
7303
|
+
// sender handles it like any other message. Refuses when nobody sent this — a view's
|
|
7304
|
+
// own `@on.*`, or a host sendAtRoot.
|
|
7305
|
+
sendReply(name, args) {
|
|
7306
|
+
const origin = this.parent?.origin ?? null;
|
|
7307
|
+
if (origin == null) {
|
|
7308
|
+
this.transactor.refuse("NO_SENDER", { name });
|
|
7309
|
+
return null;
|
|
7310
|
+
}
|
|
7311
|
+
return this.sendAtPath(origin, name, args);
|
|
7312
|
+
}
|
|
7386
7313
|
// End the walk answering nothing — "served, and no answer".
|
|
7387
7314
|
stop() {
|
|
7388
7315
|
return this.parent.stop();
|
|
@@ -7394,8 +7321,6 @@ var EventContext = class extends Dispatcher {
|
|
|
7394
7321
|
return this.parent.forward(opts);
|
|
7395
7322
|
}
|
|
7396
7323
|
};
|
|
7397
|
-
var IntentContext = class extends Dispatcher {
|
|
7398
|
-
};
|
|
7399
7324
|
function warnNotIntent(verb) {
|
|
7400
7325
|
console.warn(`ctx.${verb}() is only meaningful in an "intent" handler - ignored`);
|
|
7401
7326
|
}
|
|
@@ -7404,8 +7329,8 @@ var PathChanges = class extends PathBuilder {
|
|
|
7404
7329
|
super();
|
|
7405
7330
|
this.dispatcher = dispatcher;
|
|
7406
7331
|
}
|
|
7407
|
-
send(name, args
|
|
7408
|
-
return this.dispatcher.sendAtPath(this.buildPath(), name, args
|
|
7332
|
+
send(name, args) {
|
|
7333
|
+
return this.dispatcher.sendAtPath(this.buildPath(), name, args);
|
|
7409
7334
|
}
|
|
7410
7335
|
intent(name, args, opts) {
|
|
7411
7336
|
return this.dispatcher.intentAtPath(this.buildPath(), name, args, opts);
|
|
@@ -7962,8 +7887,12 @@ function lintIdToMessage(id, info) {
|
|
|
7962
7887
|
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`;
|
|
7963
7888
|
case "LOOKUP_BAD_SHAPE":
|
|
7964
7889
|
return `Lookup '${info.name}' has an invalid shape: ${info.problem}`;
|
|
7965
|
-
case "
|
|
7966
|
-
return `Lookup '${info.name}'
|
|
7890
|
+
case "LOOKUP_NO_PROVIDER":
|
|
7891
|
+
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`;
|
|
7892
|
+
case "PROVIDE_TYPE_BAD_SHAPE":
|
|
7893
|
+
return `Provide '${info.name}' starts uppercase, so it publishes a component type — its value must be 'self', not '${info.value}'`;
|
|
7894
|
+
case "PROVIDE_NAME_COLLISION":
|
|
7895
|
+
return `Provide '${info.name}' is also provided by '${info.other}' in the same scope — one name, one provider, so a lookup can find it`;
|
|
7967
7896
|
case "UNKNOWN_MACRO_ARG":
|
|
7968
7897
|
return `Argument '${info.name}' is not declared in macro '${info.macroName}'`;
|
|
7969
7898
|
case "UNKNOWN_DIRECTIVE":
|
|
@@ -8235,9 +8164,10 @@ var App = class {
|
|
|
8235
8164
|
}
|
|
8236
8165
|
compile() {
|
|
8237
8166
|
for (const Comp of this.comps.byId.values()) {
|
|
8238
|
-
Comp
|
|
8239
|
-
|
|
8240
|
-
|
|
8167
|
+
const meta = Comp[COMPONENT];
|
|
8168
|
+
meta.compile(this.ParseContext);
|
|
8169
|
+
for (const key in meta.views)
|
|
8170
|
+
for (const name of meta.views[key].ctx.genEventNames()) this._eventNames.add(name);
|
|
8241
8171
|
}
|
|
8242
8172
|
this._compiled = true;
|
|
8243
8173
|
}
|
|
@@ -8263,8 +8193,8 @@ var App = class {
|
|
|
8263
8193
|
for (const name of this._eventNames)
|
|
8264
8194
|
this.rootNode.removeEventListener(name, this, listenerOpts(name));
|
|
8265
8195
|
}
|
|
8266
|
-
sendAtRoot(name, args
|
|
8267
|
-
this.transactor.pushSend(new Path([]), name, args
|
|
8196
|
+
sendAtRoot(name, args) {
|
|
8197
|
+
this.transactor.pushSend(new Path([]), name, args);
|
|
8268
8198
|
}
|
|
8269
8199
|
registerComponents(comps, opts) {
|
|
8270
8200
|
const scope = this.compStack.enter();
|
|
@@ -8340,6 +8270,182 @@ var DragInfo = class {
|
|
|
8340
8270
|
}
|
|
8341
8271
|
};
|
|
8342
8272
|
|
|
8273
|
+
// src/cache.js
|
|
8274
|
+
var isWeakKey = (k) => k !== null && (typeof k === "object" || typeof k === "function");
|
|
8275
|
+
var NullDomCache = class {
|
|
8276
|
+
get(_keys, _cacheKey) {
|
|
8277
|
+
}
|
|
8278
|
+
set(_keys, _cacheKey, _v) {
|
|
8279
|
+
}
|
|
8280
|
+
evict() {
|
|
8281
|
+
return { hit: 0, miss: 0, badKey: 0 };
|
|
8282
|
+
}
|
|
8283
|
+
};
|
|
8284
|
+
var WeakMapDomCache = class {
|
|
8285
|
+
constructor() {
|
|
8286
|
+
this.hit = this.miss = this.badKey = 0;
|
|
8287
|
+
this.keysByLen = /* @__PURE__ */ new Map();
|
|
8288
|
+
}
|
|
8289
|
+
_returnValue(r) {
|
|
8290
|
+
if (r === void 0) this.miss += 1;
|
|
8291
|
+
else this.hit += 1;
|
|
8292
|
+
return r;
|
|
8293
|
+
}
|
|
8294
|
+
get(keys, cacheKey) {
|
|
8295
|
+
const len = keys.length;
|
|
8296
|
+
let cur = this.keysByLen.get(len);
|
|
8297
|
+
if (!cur) return this._returnValue(void 0);
|
|
8298
|
+
for (let i = 0; i < len - 1; i++) {
|
|
8299
|
+
cur = cur.get(keys[i]);
|
|
8300
|
+
if (!cur) return this._returnValue(void 0);
|
|
8301
|
+
}
|
|
8302
|
+
return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
|
|
8303
|
+
}
|
|
8304
|
+
set(keys, cacheKey, v) {
|
|
8305
|
+
const len = keys.length;
|
|
8306
|
+
let cur = this.keysByLen.get(len);
|
|
8307
|
+
if (!cur) {
|
|
8308
|
+
cur = /* @__PURE__ */ new WeakMap();
|
|
8309
|
+
this.keysByLen.set(len, cur);
|
|
8310
|
+
}
|
|
8311
|
+
for (let i = 0; i < len - 1; i++) {
|
|
8312
|
+
const key = keys[i];
|
|
8313
|
+
let next = cur.get(key);
|
|
8314
|
+
if (!next) {
|
|
8315
|
+
if (!isWeakKey(key)) {
|
|
8316
|
+
this.badKey += 1;
|
|
8317
|
+
return;
|
|
8318
|
+
}
|
|
8319
|
+
next = /* @__PURE__ */ new WeakMap();
|
|
8320
|
+
cur.set(key, next);
|
|
8321
|
+
}
|
|
8322
|
+
cur = next;
|
|
8323
|
+
}
|
|
8324
|
+
const lastKey = keys[len - 1];
|
|
8325
|
+
const leaf = cur.get(lastKey);
|
|
8326
|
+
if (leaf) leaf[cacheKey] = v;
|
|
8327
|
+
else if (isWeakKey(lastKey)) cur.set(lastKey, { [cacheKey]: v });
|
|
8328
|
+
else this.badKey += 1;
|
|
8329
|
+
}
|
|
8330
|
+
evict() {
|
|
8331
|
+
const { hit, miss, badKey } = this;
|
|
8332
|
+
this.hit = this.miss = this.badKey = 0;
|
|
8333
|
+
this.keysByLen = /* @__PURE__ */ new Map();
|
|
8334
|
+
return { hit, miss, badKey };
|
|
8335
|
+
}
|
|
8336
|
+
};
|
|
8337
|
+
|
|
8338
|
+
// src/renderer.js
|
|
8339
|
+
var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
|
|
8340
|
+
var Renderer = class {
|
|
8341
|
+
constructor(comps) {
|
|
8342
|
+
this.comps = comps;
|
|
8343
|
+
this.cache = new WeakMapDomCache();
|
|
8344
|
+
this.renderTag = h;
|
|
8345
|
+
}
|
|
8346
|
+
renderFragment(childs) {
|
|
8347
|
+
return new VFragment(childs);
|
|
8348
|
+
}
|
|
8349
|
+
renderComment(text) {
|
|
8350
|
+
return new VComment(text);
|
|
8351
|
+
}
|
|
8352
|
+
setNullCache() {
|
|
8353
|
+
this.cache = new NullDomCache();
|
|
8354
|
+
}
|
|
8355
|
+
renderToDOM(stack, val) {
|
|
8356
|
+
const rootNode = document.createElement("div");
|
|
8357
|
+
const rOpts = { document };
|
|
8358
|
+
render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
|
|
8359
|
+
return rootNode.childNodes[0];
|
|
8360
|
+
}
|
|
8361
|
+
renderToString(stack, val, cleanAttrs = true) {
|
|
8362
|
+
const dom = this.renderToDOM(stack, val);
|
|
8363
|
+
if (cleanAttrs) {
|
|
8364
|
+
const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
|
|
8365
|
+
for (const { dataset } of nodes) for (const name of DATASET_ATTRS) delete dataset[name];
|
|
8366
|
+
}
|
|
8367
|
+
return dom.innerHTML;
|
|
8368
|
+
}
|
|
8369
|
+
renderRoot(stack, val, viewName = null) {
|
|
8370
|
+
const comp = this.comps.getCompFor(val);
|
|
8371
|
+
if (comp === null) return null;
|
|
8372
|
+
return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
|
|
8373
|
+
}
|
|
8374
|
+
renderIt(stack, node, key, viewName) {
|
|
8375
|
+
const comp = this.comps.getCompFor(stack.it);
|
|
8376
|
+
return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName) : null;
|
|
8377
|
+
}
|
|
8378
|
+
// `node` is the parse node of the render site (`<x render>` / `render-it` /
|
|
8379
|
+
// `render-each`, or the view's root anode for the app root). It keys the
|
|
8380
|
+
// cache as a globally-unique object: node ids alone are unique only within a
|
|
8381
|
+
// single view, so the same value rendered by two components (e.g. through a
|
|
8382
|
+
// shared dynamic-var sequence) would otherwise collide in the cache.
|
|
8383
|
+
_rValComp(stack, val, comp, node, key, viewName) {
|
|
8384
|
+
const cacheKey = `${viewName ?? ""}${stack.viewsId ?? ""}${key}`;
|
|
8385
|
+
const cachePath = [node, val];
|
|
8386
|
+
stack._pushDynBindValuesToArray(cachePath, comp);
|
|
8387
|
+
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
8388
|
+
if (cachedNode) return cachedNode;
|
|
8389
|
+
const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
|
|
8390
|
+
const body = this.renderView(view, stack);
|
|
8391
|
+
if (body == null) return null;
|
|
8392
|
+
const meta = this._renderMetadata({
|
|
8393
|
+
$: "Comp",
|
|
8394
|
+
nid: node?.nodeId ?? null,
|
|
8395
|
+
cid: comp.id,
|
|
8396
|
+
vid: view.name
|
|
8397
|
+
});
|
|
8398
|
+
const dom = new VFragment([meta, body]);
|
|
8399
|
+
this.cache.set(cachePath, cacheKey, dom);
|
|
8400
|
+
return dom;
|
|
8401
|
+
}
|
|
8402
|
+
pushEachEntry(r, nid, attrName, key, dom) {
|
|
8403
|
+
r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
|
|
8404
|
+
}
|
|
8405
|
+
renderEachWhen(stack, iterInfo, view, nid) {
|
|
8406
|
+
const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
|
|
8407
|
+
const r = [];
|
|
8408
|
+
const it = stack.it;
|
|
8409
|
+
const renderOne = (key, value, attrName, binds) => {
|
|
8410
|
+
const cachePath = enricher ? [view, it, value] : [view, value];
|
|
8411
|
+
const cacheKey = `${stack.viewsId ?? ""}${nid}${key}`;
|
|
8412
|
+
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
8413
|
+
if (cachedNode) this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
8414
|
+
else {
|
|
8415
|
+
const dom = this.renderView(view, stack.enter(value, binds, false));
|
|
8416
|
+
if (dom != null) this.pushEachEntry(r, nid, attrName, key, dom);
|
|
8417
|
+
this.cache.set(cachePath, cacheKey, dom);
|
|
8418
|
+
}
|
|
8419
|
+
};
|
|
8420
|
+
walkLoopBindings(
|
|
8421
|
+
{ seq, it, filter, loopWith, enricher, ctx: makeLoopCtx(stack, filter) },
|
|
8422
|
+
renderOne
|
|
8423
|
+
);
|
|
8424
|
+
return r;
|
|
8425
|
+
}
|
|
8426
|
+
renderView(view, stack) {
|
|
8427
|
+
let n = stack.binds[1];
|
|
8428
|
+
while (n !== null) {
|
|
8429
|
+
const b = n[0];
|
|
8430
|
+
if (b.isFrame) {
|
|
8431
|
+
if (stack.it !== b.it) break;
|
|
8432
|
+
console.error("recursion detected", stack.it, b.it);
|
|
8433
|
+
return new VComment("RECURSION AVOIDED");
|
|
8434
|
+
}
|
|
8435
|
+
n = n[1];
|
|
8436
|
+
}
|
|
8437
|
+
return view.render(stack, this);
|
|
8438
|
+
}
|
|
8439
|
+
_renderMetadata(info) {
|
|
8440
|
+
return new VComment(`§${JSON.stringify(info)}§`);
|
|
8441
|
+
}
|
|
8442
|
+
// Prefix a loop-less @enrich-with subtree with a boundary meta so event-path
|
|
8443
|
+
// reconstruction replays its binds (mirrors the §Each§ / §Comp§ metas).
|
|
8444
|
+
renderScopeMeta(nid, dom) {
|
|
8445
|
+
return new VFragment([this._renderMetadata({ $: "Scope", nid }), dom]);
|
|
8446
|
+
}
|
|
8447
|
+
};
|
|
8448
|
+
|
|
8343
8449
|
// index.js
|
|
8344
8450
|
var css = String.raw;
|
|
8345
8451
|
var html = String.raw;
|
|
@@ -8366,24 +8472,6 @@ async function compileClassesToStyleText(app, compileClasses, Ctx = ParseCtxClas
|
|
|
8366
8472
|
}
|
|
8367
8473
|
|
|
8368
8474
|
// src/util/testing.js
|
|
8369
|
-
var plainArrayIter = (seq, visit, start, end) => {
|
|
8370
|
-
const [s, e] = normalizeRange(start, end, seq.length);
|
|
8371
|
-
for (let i = s; i < e; i++) visit(i, seq[i]);
|
|
8372
|
-
};
|
|
8373
|
-
var plainMapIter = (seq, visit, start, end) => {
|
|
8374
|
-
const [s, e] = normalizeRange(start, end, seq.size);
|
|
8375
|
-
let i = 0;
|
|
8376
|
-
for (const [k, v] of seq.entries()) {
|
|
8377
|
-
if (i >= e) break;
|
|
8378
|
-
if (i >= s) visit(k, v);
|
|
8379
|
-
i++;
|
|
8380
|
-
}
|
|
8381
|
-
};
|
|
8382
|
-
function pickIter(seq) {
|
|
8383
|
-
if (Array.isArray(seq)) return plainArrayIter;
|
|
8384
|
-
if (seq instanceof Map) return plainMapIter;
|
|
8385
|
-
return getSeqInfo(seq);
|
|
8386
|
-
}
|
|
8387
8475
|
function resolveAlter(Comp, name) {
|
|
8388
8476
|
if (name == null) return null;
|
|
8389
8477
|
const fn = Comp.alter?.[name];
|
|
@@ -8401,30 +8489,12 @@ function collectIterBindings(Comp, compInstance, seq, opts = {}) {
|
|
|
8401
8489
|
const scope = scopeEnrichFn ? scopeEnrichFn.call(it) ?? {} : opts.scope ?? {};
|
|
8402
8490
|
const ctx = {
|
|
8403
8491
|
lookup: (name) => scope[name],
|
|
8404
|
-
filter: (key, value,
|
|
8492
|
+
filter: (key, value, iterData) => whenFn.call(it, key, value, iterData)
|
|
8405
8493
|
};
|
|
8406
|
-
const { iterData, start, end, keys } = unpackLoopResult(loopWithFn.call(it, seq, ctx), seq);
|
|
8407
8494
|
const out = [];
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
const binds = { key, value };
|
|
8412
|
-
if (enrichFn) enrichFn.call(it, binds, key, value, iterData);
|
|
8413
|
-
out.push(binds);
|
|
8414
|
-
}
|
|
8415
|
-
return out;
|
|
8416
|
-
}
|
|
8417
|
-
const iter = pickIter(seq);
|
|
8418
|
-
iter(
|
|
8419
|
-
seq,
|
|
8420
|
-
(key, value) => {
|
|
8421
|
-
if (!whenFn.call(it, key, value, iterData)) return;
|
|
8422
|
-
const binds = { key, value };
|
|
8423
|
-
if (enrichFn) enrichFn.call(it, binds, key, value, iterData);
|
|
8424
|
-
out.push(binds);
|
|
8425
|
-
},
|
|
8426
|
-
start,
|
|
8427
|
-
end
|
|
8495
|
+
walkLoopBindings(
|
|
8496
|
+
{ seq, it, filter: whenFn, loopWith: loopWithFn, enricher: enrichFn, ctx },
|
|
8497
|
+
(_key, _value, _attrName, binds) => out.push(binds)
|
|
8428
8498
|
);
|
|
8429
8499
|
return out;
|
|
8430
8500
|
}
|
|
@@ -8583,7 +8653,7 @@ export {
|
|
|
8583
8653
|
HANDLER_NAME_COLLISION,
|
|
8584
8654
|
IF_NO_BRANCH_SET,
|
|
8585
8655
|
LOOKUP_BAD_SHAPE,
|
|
8586
|
-
|
|
8656
|
+
LOOKUP_NO_PROVIDER,
|
|
8587
8657
|
LintClassCollectorCtx,
|
|
8588
8658
|
LintComponentResult,
|
|
8589
8659
|
LintContext,
|
|
@@ -8599,7 +8669,9 @@ export {
|
|
|
8599
8669
|
ModuleTests,
|
|
8600
8670
|
PASS,
|
|
8601
8671
|
PLACEHOLDERLESS_TEMPLATE_STRING,
|
|
8672
|
+
PROVIDE_NAME_COLLISION,
|
|
8602
8673
|
PROVIDE_NOT_ADDRESSABLE,
|
|
8674
|
+
PROVIDE_TYPE_BAD_SHAPE,
|
|
8603
8675
|
ParseContext,
|
|
8604
8676
|
RECEIVE_HANDLER_NOT_IMPLEMENTED,
|
|
8605
8677
|
REDUNDANT_TEMPLATE_STRING,
|