tutuca 0.9.82 → 0.9.83

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.
@@ -1,5 +1,100 @@
1
- // dev.js
2
- import { expect, use } from "chai";
1
+ // deps/chai.js
2
+ import * as chai from "chai";
3
+
4
+ // src/chai-jest.js
5
+ function jestMatchers(chai, utils) {
6
+ const A = chai.Assertion;
7
+ const m = (name, fn) => A.addMethod(name, fn);
8
+ m("toBe", function(expected) {
9
+ this.assert(Object.is(this._obj, expected), "expected #{this} to be #{exp}", "expected #{this} not to be #{exp}", expected, this._obj);
10
+ });
11
+ m("toEqual", function(expected) {
12
+ this.assert(utils.eql(this._obj, expected), "expected #{this} to deeply equal #{exp}", "expected #{this} not to deeply equal #{exp}", expected, this._obj, true);
13
+ });
14
+ m("toBeTruthy", function() {
15
+ this.assert(Boolean(this._obj), "expected #{this} to be truthy", "expected #{this} not to be truthy");
16
+ });
17
+ m("toBeFalsy", function() {
18
+ this.assert(!this._obj, "expected #{this} to be falsy", "expected #{this} not to be falsy");
19
+ });
20
+ m("toBeNull", function() {
21
+ this.assert(this._obj === null, "expected #{this} to be null", "expected #{this} not to be null");
22
+ });
23
+ m("toBeUndefined", function() {
24
+ this.assert(this._obj === undefined, "expected #{this} to be undefined", "expected #{this} not to be undefined");
25
+ });
26
+ m("toBeDefined", function() {
27
+ this.assert(this._obj !== undefined, "expected #{this} to be defined", "expected #{this} to be undefined");
28
+ });
29
+ m("toBeNaN", function() {
30
+ this.assert(Number.isNaN(this._obj), "expected #{this} to be NaN", "expected #{this} not to be NaN");
31
+ });
32
+ const compare = (name, op, word) => m(name, function(expected) {
33
+ this.assert(op(this._obj, expected), `expected #{this} to be ${word} #{exp}`, `expected #{this} not to be ${word} #{exp}`, expected);
34
+ });
35
+ compare("toBeGreaterThan", (a, b) => a > b, "greater than");
36
+ compare("toBeGreaterThanOrEqual", (a, b) => a >= b, "greater than or equal to");
37
+ compare("toBeLessThan", (a, b) => a < b, "less than");
38
+ compare("toBeLessThanOrEqual", (a, b) => a <= b, "less than or equal to");
39
+ m("toBeCloseTo", function(expected, numDigits = 2) {
40
+ const pass = Math.abs(expected - this._obj) < 10 ** -numDigits / 2;
41
+ this.assert(pass, `expected #{this} to be close to #{exp} (${numDigits} digits)`, `expected #{this} not to be close to #{exp} (${numDigits} digits)`, expected);
42
+ });
43
+ m("toContain", function(item) {
44
+ const obj = this._obj;
45
+ const ok = typeof obj === "string" ? obj.includes(item) : Array.from(obj).includes(item);
46
+ this.assert(ok, "expected #{this} to contain #{exp}", "expected #{this} not to contain #{exp}", item);
47
+ });
48
+ m("toHaveLength", function(length) {
49
+ const actual = this._obj == null ? undefined : this._obj.length;
50
+ this.assert(actual === length, "expected #{this} to have length #{exp}", "expected #{this} not to have length #{exp}", length, actual);
51
+ });
52
+ m("toMatch", function(expected) {
53
+ const obj = this._obj;
54
+ const ok = expected instanceof RegExp ? expected.test(obj) : String(obj).includes(expected);
55
+ this.assert(ok, "expected #{this} to match #{exp}", "expected #{this} not to match #{exp}", expected);
56
+ });
57
+ m("toHaveProperty", function(path, ...rest) {
58
+ const keys = Array.isArray(path) ? path : String(path).split(".");
59
+ let cur = this._obj;
60
+ let found = true;
61
+ for (const k of keys) {
62
+ if (cur != null && k in Object(cur))
63
+ cur = cur[k];
64
+ else {
65
+ found = false;
66
+ break;
67
+ }
68
+ }
69
+ const pass = found && (rest.length === 0 || utils.eql(cur, rest[0]));
70
+ this.assert(pass, "expected #{this} to have property #{exp}", "expected #{this} not to have property #{exp}", path);
71
+ });
72
+ m("toBeInstanceOf", function(ctor) {
73
+ this.assert(this._obj instanceof ctor, "expected #{this} to be an instance of #{exp}", "expected #{this} not to be an instance of #{exp}", ctor.name ?? ctor);
74
+ });
75
+ m("toThrow", function(expected) {
76
+ const a = new chai.Assertion(this._obj);
77
+ if (utils.flag(this, "negate")) {
78
+ expected === undefined ? a.to.not.throw() : a.to.not.throw(expected);
79
+ } else {
80
+ expected === undefined ? a.to.throw() : a.to.throw(expected);
81
+ }
82
+ });
83
+ }
84
+
85
+ // deps/chai.js
86
+ import {
87
+ Assertion,
88
+ AssertionError,
89
+ Should,
90
+ assert,
91
+ config,
92
+ expect,
93
+ should,
94
+ use as use2,
95
+ util
96
+ } from "chai";
97
+ chai.use(jestMatchers);
3
98
 
4
99
  // src/value.js
5
100
  import { is } from "immutable";
@@ -853,9 +948,6 @@ class DynVal extends RenderNameVal {
853
948
  eval(stack) {
854
949
  return stack.lookupDynamic(this.name);
855
950
  }
856
- toPathItem() {
857
- return null;
858
- }
859
951
  toString() {
860
952
  return `*${this.name}`;
861
953
  }
@@ -1093,7 +1185,7 @@ class ConstAttrs extends Attributes {
1093
1185
  toMacroVars() {
1094
1186
  const r = {};
1095
1187
  for (const name in this.items)
1096
- r[name] = `'${this.items[name]}'`;
1188
+ r[name] = new ConstVal(`${this.items[name]}`).toString();
1097
1189
  return r;
1098
1190
  }
1099
1191
  isConstant() {
@@ -1199,6 +1291,79 @@ class RequestHandler {
1199
1291
  }
1200
1292
  }
1201
1293
 
1294
+ // src/renderer.js
1295
+ import { isIndexed, isKeyed } from "immutable";
1296
+
1297
+ // src/cache.js
1298
+ class NullDomCache {
1299
+ get(_keys, _cacheKey) {}
1300
+ set(_keys, _cacheKey, _v) {}
1301
+ evict() {
1302
+ return { hit: 0, miss: 0, badKey: 0 };
1303
+ }
1304
+ }
1305
+
1306
+ class WeakMapDomCache {
1307
+ constructor() {
1308
+ this.hit = this.miss = this.badKey = 0;
1309
+ this.keysByLen = new Map;
1310
+ }
1311
+ _returnValue(r) {
1312
+ if (r === undefined)
1313
+ this.miss += 1;
1314
+ else
1315
+ this.hit += 1;
1316
+ return r;
1317
+ }
1318
+ get(keys, cacheKey) {
1319
+ const len = keys.length;
1320
+ let cur = this.keysByLen.get(len);
1321
+ if (!cur)
1322
+ return this._returnValue(undefined);
1323
+ for (let i = 0;i < len - 1; i++) {
1324
+ cur = cur.get(keys[i]);
1325
+ if (!cur)
1326
+ return this._returnValue(undefined);
1327
+ }
1328
+ return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
1329
+ }
1330
+ set(keys, cacheKey, v) {
1331
+ const len = keys.length;
1332
+ let cur = this.keysByLen.get(len);
1333
+ if (!cur) {
1334
+ cur = new WeakMap;
1335
+ this.keysByLen.set(len, cur);
1336
+ }
1337
+ for (let i = 0;i < len - 1; i++) {
1338
+ const key = keys[i];
1339
+ let next = cur.get(key);
1340
+ if (!next) {
1341
+ if (typeof key !== "object") {
1342
+ this.badKey += 1;
1343
+ return;
1344
+ }
1345
+ next = new WeakMap;
1346
+ cur.set(key, next);
1347
+ }
1348
+ cur = next;
1349
+ }
1350
+ const lastKey = keys[len - 1];
1351
+ const leaf = cur.get(lastKey);
1352
+ if (leaf)
1353
+ leaf[cacheKey] = v;
1354
+ else if (typeof lastKey === "object")
1355
+ cur.set(lastKey, { [cacheKey]: v });
1356
+ else
1357
+ this.badKey += 1;
1358
+ }
1359
+ evict() {
1360
+ const { hit, miss, badKey } = this;
1361
+ this.hit = this.miss = this.badKey = 0;
1362
+ this.keysByLen = new Map;
1363
+ return { hit, miss, badKey };
1364
+ }
1365
+ }
1366
+
1202
1367
  // src/vdom.js
1203
1368
  var HTML_NS = "http://www.w3.org/1999/xhtml";
1204
1369
  var SVG_NS = "http://www.w3.org/2000/svg";
@@ -1226,6 +1391,7 @@ var NEVER_ASSIGN = new Set([
1226
1391
  "role",
1227
1392
  "popover"
1228
1393
  ]);
1394
+ var PROP_ATTR_NAME = { className: "class", htmlFor: "for" };
1229
1395
  function applyProperties(node, props) {
1230
1396
  const namespaced = isNamespaced(node);
1231
1397
  for (const name in props)
@@ -1244,15 +1410,22 @@ function setProp(node, name, value, namespaced) {
1244
1410
  }
1245
1411
  if (typeof value === "function")
1246
1412
  return;
1247
- if (!namespaced && !NEVER_ASSIGN.has(name) && name in node) {
1413
+ const usesProp = !namespaced && !NEVER_ASSIGN.has(name) && name in node;
1414
+ if (usesProp && value != null) {
1248
1415
  try {
1249
- node[name] = value == null ? "" : value;
1416
+ node[name] = value;
1250
1417
  return;
1251
1418
  } catch {}
1252
1419
  }
1253
- if (value == null || value === false && name[4] !== "-")
1254
- node.removeAttribute(name);
1255
- else
1420
+ if (value == null || value === false && name[4] !== "-") {
1421
+ if (usesProp) {
1422
+ try {
1423
+ node[name] = "";
1424
+ } catch {}
1425
+ node.removeAttribute(PROP_ATTR_NAME[name] ?? name);
1426
+ } else
1427
+ node.removeAttribute(name);
1428
+ } else
1256
1429
  node.setAttribute(name, value);
1257
1430
  }
1258
1431
  function applyValueLast(node, value) {
@@ -1433,22 +1606,12 @@ function morphNode(domNode, source, target, opts) {
1433
1606
  }
1434
1607
  if (type === 1 && source.isSameKind(target)) {
1435
1608
  const propsDiff = diffProps(source.attrs, target.attrs);
1436
- let pendingValue;
1437
- let pendingChecked;
1438
- let applyValue = false;
1439
- let applyChecked = false;
1609
+ const hasValue = propsDiff != null && "value" in propsDiff;
1610
+ const hasChecked = propsDiff != null && "checked" in propsDiff;
1440
1611
  if (propsDiff) {
1441
- if ("value" in propsDiff || "checked" in propsDiff) {
1442
- const { value, checked, ...rest } = propsDiff;
1612
+ if (hasValue || hasChecked) {
1613
+ const { value: _v, checked: _c, ...rest } = propsDiff;
1443
1614
  applyProperties(domNode, rest);
1444
- if ("value" in propsDiff) {
1445
- pendingValue = value;
1446
- applyValue = true;
1447
- }
1448
- if ("checked" in propsDiff) {
1449
- pendingChecked = checked;
1450
- applyChecked = true;
1451
- }
1452
1615
  } else
1453
1616
  applyProperties(domNode, propsDiff);
1454
1617
  }
@@ -1456,14 +1619,12 @@ function morphNode(domNode, source, target, opts) {
1456
1619
  const ns = effectiveNs(target, opts);
1457
1620
  morphChildren(domNode, source.childs, target.childs, childOpts(target, ns, opts));
1458
1621
  }
1459
- if (!applyValue && source.tag === "SELECT" && target.attrs.value !== undefined) {
1460
- pendingValue = target.attrs.value;
1461
- applyValue = true;
1462
- }
1463
- if (applyValue)
1464
- applyValueLast(domNode, pendingValue);
1465
- if (applyChecked)
1466
- setProp(domNode, "checked", pendingChecked, false);
1622
+ if (hasValue)
1623
+ applyValueLast(domNode, propsDiff.value);
1624
+ else if (source.tag === "SELECT" && target.attrs.value !== undefined)
1625
+ applyValueLast(domNode, target.attrs.value);
1626
+ if (hasChecked)
1627
+ setProp(domNode, "checked", propsDiff.checked, false);
1467
1628
  return domNode;
1468
1629
  }
1469
1630
  if (type === 11) {
@@ -1584,70 +1745,225 @@ function h(tagName, properties, children, namespace) {
1584
1745
  return new VNode(tag, props, normalizedChildren, key, namespace);
1585
1746
  }
1586
1747
 
1587
- // src/anode.js
1588
- function resolveDynProducer(comp, name) {
1589
- let producerComp, producerProvide;
1590
- const lk = comp?.lookup?.[name];
1591
- if (lk != null) {
1592
- producerComp = comp.scope?.lookupComponent(lk.compName);
1593
- producerProvide = producerComp?.provide?.[lk.provideName];
1594
- } else {
1595
- const p = comp?.provide?.[name];
1596
- if (p == null)
1597
- return null;
1598
- producerComp = comp;
1599
- producerProvide = p;
1600
- }
1601
- if (producerComp == null || producerProvide == null)
1602
- return null;
1603
- const pi = producerProvide.val?.toPathItem?.() ?? null;
1604
- return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
1605
- }
1748
+ // src/renderer.js
1749
+ var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
1606
1750
 
1607
- class BaseNode {
1608
- render(_stack, _rx) {
1609
- return null;
1610
- }
1611
- setDataAttr(key, val) {
1612
- console.warn("setDataAttr not implemented for", this, { key, val });
1751
+ class Renderer {
1752
+ constructor(comps) {
1753
+ this.comps = comps;
1754
+ this.cache = new WeakMapDomCache;
1755
+ this.renderTag = h;
1613
1756
  }
1614
- isConstant() {
1615
- return false;
1757
+ renderFragment(childs) {
1758
+ return new VFragment(childs);
1616
1759
  }
1617
- optimize() {}
1618
- }
1619
-
1620
- class TextNode extends BaseNode {
1621
- constructor(val) {
1622
- super();
1623
- this.val = val;
1760
+ renderComment(text) {
1761
+ return new VComment(text);
1624
1762
  }
1625
- render(_stack, _rx) {
1626
- return this.val;
1763
+ setNullCache() {
1764
+ this.cache = new NullDomCache;
1627
1765
  }
1628
- isWhiteSpace() {
1629
- for (let i = 0;i < this.val.length; i++) {
1630
- const c = this.val.charCodeAt(i);
1631
- if (!(c === 32 || c === 10 || c === 9 || c === 13))
1632
- return false;
1633
- }
1634
- return true;
1766
+ renderToDOM(stack, val) {
1767
+ const rootNode = document.createElement("div");
1768
+ const rOpts = { document };
1769
+ render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
1770
+ return rootNode.childNodes[0];
1635
1771
  }
1636
- hasNewLine() {
1637
- for (let i = 0;i < this.val.length; i++) {
1638
- const c = this.val.charCodeAt(i);
1639
- if (c === 10 || c === 13)
1640
- return true;
1772
+ renderToString(stack, val, cleanAttrs = true) {
1773
+ const dom = this.renderToDOM(stack, val);
1774
+ if (cleanAttrs) {
1775
+ const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
1776
+ for (const { dataset } of nodes)
1777
+ for (const name of DATASET_ATTRS)
1778
+ delete dataset[name];
1641
1779
  }
1642
- return false;
1780
+ return dom.innerHTML;
1643
1781
  }
1644
- condenseWhiteSpace(replacement = "") {
1645
- this.val = replacement;
1782
+ renderRoot(stack, val, viewName = null) {
1783
+ const comp = this.comps.getCompFor(val);
1784
+ if (comp === null)
1785
+ return null;
1786
+ return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
1646
1787
  }
1647
- isConstant() {
1648
- return true;
1788
+ renderIt(stack, node, key, viewName) {
1789
+ const comp = this.comps.getCompFor(stack.it);
1790
+ return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName) : null;
1649
1791
  }
1650
- setDataAttr(_key, _val) {}
1792
+ _rValComp(stack, val, comp, node, key, viewName) {
1793
+ const cacheKey = `${viewName ?? stack.viewsId ?? ""}-${key}`;
1794
+ const cachePath = [node, val];
1795
+ stack._pushDynBindValuesToArray(cachePath, comp);
1796
+ const cachedNode = this.cache.get(cachePath, cacheKey);
1797
+ if (cachedNode)
1798
+ return cachedNode;
1799
+ const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
1800
+ const meta = this._renderMetadata({
1801
+ $: "Comp",
1802
+ nid: node?.nodeId ?? null,
1803
+ cid: comp.id,
1804
+ vid: view.name
1805
+ });
1806
+ const dom = new VFragment([meta, this.renderView(view, stack)]);
1807
+ this.cache.set(cachePath, cacheKey, dom);
1808
+ return dom;
1809
+ }
1810
+ pushEachEntry(r, nid, attrName, key, dom) {
1811
+ r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
1812
+ }
1813
+ renderEach(stack, iterInfo, node, viewName) {
1814
+ const { seq, filter, loopWith } = iterInfo.eval(stack);
1815
+ const r = [];
1816
+ const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
1817
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
1818
+ if (filter.call(stack.it, key, value, iterData)) {
1819
+ const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
1820
+ this.pushEachEntry(r, node.nodeId, attrName, key, dom);
1821
+ }
1822
+ }, start, end);
1823
+ return r;
1824
+ }
1825
+ renderEachWhen(stack, iterInfo, view, nid) {
1826
+ const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
1827
+ const r = [];
1828
+ const it = stack.it;
1829
+ const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
1830
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
1831
+ if (filter.call(it, key, value, iterData)) {
1832
+ const cachePath = enricher ? [view, it, value] : [view, value];
1833
+ const binds = { key, value };
1834
+ const cacheKey = `${nid}-${key}`;
1835
+ if (enricher)
1836
+ enricher.call(it, binds, key, value, iterData);
1837
+ const cachedNode = this.cache.get(cachePath, cacheKey);
1838
+ if (cachedNode)
1839
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
1840
+ else {
1841
+ const dom = this.renderView(view, stack.enter(value, binds, false));
1842
+ this.pushEachEntry(r, nid, attrName, key, dom);
1843
+ this.cache.set(cachePath, cacheKey, dom);
1844
+ }
1845
+ }
1846
+ }, start, end);
1847
+ return r;
1848
+ }
1849
+ renderView(view, stack) {
1850
+ let n = stack.binds[1];
1851
+ while (n !== null) {
1852
+ const b = n[0];
1853
+ if (b.isFrame) {
1854
+ if (stack.it !== b.it)
1855
+ break;
1856
+ console.error("recursion detected", stack.it, b.it);
1857
+ return new VComment("RECURSION AVOIDED");
1858
+ }
1859
+ n = n[1];
1860
+ }
1861
+ return view.render(stack, this);
1862
+ }
1863
+ _renderMetadata(info) {
1864
+ return new VComment(`§${JSON.stringify(info)}§`);
1865
+ }
1866
+ }
1867
+ var getSeqInfo = (seq) => isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
1868
+ var normalizeRange = (start, end, size) => {
1869
+ let s = start == null ? 0 : start < 0 ? size + start : start;
1870
+ let e = end == null ? size : end < 0 ? size + end : end;
1871
+ s = s < 0 ? 0 : s > size ? size : s;
1872
+ e = e < 0 ? 0 : e > size ? size : e;
1873
+ return [s, e < s ? s : e];
1874
+ };
1875
+ var filterAlwaysTrue = (_v, _k, _seq) => true;
1876
+ var nullLoopWith = (seq) => ({ iterData: { seq } });
1877
+ var unpackLoopResult = (result, seq) => {
1878
+ const r = result ?? {};
1879
+ return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
1880
+ };
1881
+ var imIndexedIter = (seq, visit, start, end) => {
1882
+ const [s, e] = normalizeRange(start, end, seq.size);
1883
+ for (let i = s;i < e; i++)
1884
+ visit(i, seq.get(i), "si");
1885
+ };
1886
+ var imKeyedIter = (seq, visit, start, end) => {
1887
+ const [s, e] = normalizeRange(start, end, seq.size);
1888
+ let i = 0;
1889
+ for (const [k, v] of seq.toSeq().entries()) {
1890
+ if (i >= e)
1891
+ break;
1892
+ if (i >= s)
1893
+ visit(k, v, "sk");
1894
+ i++;
1895
+ }
1896
+ };
1897
+ var unkIter = () => {};
1898
+ var SEQ_INFO = Symbol.for("tutuca.seqInfo");
1899
+
1900
+ // src/util/env.js
1901
+ var isMac = (globalThis.navigator?.userAgent ?? "").toLowerCase().includes("mac");
1902
+
1903
+ // src/anode.js
1904
+ function resolveDynProducer(comp, name) {
1905
+ let producerComp, producerProvide;
1906
+ const lk = comp?.lookup?.[name];
1907
+ if (lk != null) {
1908
+ producerComp = comp.scope?.lookupComponent(lk.compName);
1909
+ producerProvide = producerComp?.provide?.[lk.provideName];
1910
+ } else {
1911
+ const p = comp?.provide?.[name];
1912
+ if (p == null)
1913
+ return null;
1914
+ producerComp = comp;
1915
+ producerProvide = p;
1916
+ }
1917
+ if (producerComp == null || producerProvide == null)
1918
+ return null;
1919
+ const pi = producerProvide.val?.toPathItem?.() ?? null;
1920
+ return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
1921
+ }
1922
+
1923
+ class BaseNode {
1924
+ render(_stack, _rx) {
1925
+ return null;
1926
+ }
1927
+ setDataAttr(key, val) {
1928
+ console.warn("setDataAttr not implemented for", this, { key, val });
1929
+ }
1930
+ isConstant() {
1931
+ return false;
1932
+ }
1933
+ optimize() {}
1934
+ }
1935
+
1936
+ class TextNode extends BaseNode {
1937
+ constructor(val) {
1938
+ super();
1939
+ this.val = val;
1940
+ }
1941
+ render(_stack, _rx) {
1942
+ return this.val;
1943
+ }
1944
+ isWhiteSpace() {
1945
+ for (let i = 0;i < this.val.length; i++) {
1946
+ const c = this.val.charCodeAt(i);
1947
+ if (!(c === 32 || c === 10 || c === 9 || c === 13))
1948
+ return false;
1949
+ }
1950
+ return true;
1951
+ }
1952
+ hasNewLine() {
1953
+ for (let i = 0;i < this.val.length; i++) {
1954
+ const c = this.val.charCodeAt(i);
1955
+ if (c === 10 || c === 13)
1956
+ return true;
1957
+ }
1958
+ return false;
1959
+ }
1960
+ condenseWhiteSpace(replacement = "") {
1961
+ this.val = replacement;
1962
+ }
1963
+ isConstant() {
1964
+ return true;
1965
+ }
1966
+ setDataAttr(_key, _val) {}
1651
1967
  }
1652
1968
 
1653
1969
  class CommentNode extends TextNode {
@@ -1787,7 +2103,7 @@ class ANode extends BaseNode {
1787
2103
  }
1788
2104
  }
1789
2105
  function parseXOp(attrs, childs, opIdx, px) {
1790
- if (attrs.length === 0)
2106
+ if (attrs.length <= opIdx)
1791
2107
  return maybeFragment(childs);
1792
2108
  const { name, value } = attrs[opIdx];
1793
2109
  const as = attrs.getNamedItem("as")?.value ?? null;
@@ -2108,8 +2424,6 @@ class IterInfo {
2108
2424
  return { seq, filter, loopWith, enricher };
2109
2425
  }
2110
2426
  }
2111
- var filterAlwaysTrue = (_v, _k, _seq) => true;
2112
- var nullLoopWith = (seq) => ({ iterData: { seq } });
2113
2427
  function xOp(consumed = [], { wrappable = false, wrapper = null } = {}) {
2114
2428
  return { consumed: new Set(consumed), wrappable, wrapper };
2115
2429
  }
@@ -2296,7 +2610,6 @@ class NodeEvent {
2296
2610
  return r;
2297
2611
  }
2298
2612
  }
2299
- var isMac = (globalThis.navigator?.userAgent ?? "").toLowerCase().includes("mac");
2300
2613
  var fwdIfCtxPred = (pred) => (w) => (that, f, args, ctx) => pred(ctx) ? w(that, f, args, ctx) : that;
2301
2614
  var fwdIfKey = (keyName) => fwdIfCtxPred((ctx) => ctx.e.key === keyName);
2302
2615
  var fwdCtrl = fwdIfCtxPred(({ e }) => isMac && e.metaKey || e.ctrlKey);
@@ -2327,96 +2640,15 @@ function compileModifiers(eventName, names) {
2327
2640
  };
2328
2641
  }
2329
2642
 
2330
- // src/chai-jest.js
2331
- function jestMatchers(chai, utils) {
2332
- const A = chai.Assertion;
2333
- const m = (name, fn) => A.addMethod(name, fn);
2334
- m("toBe", function(expected) {
2335
- this.assert(Object.is(this._obj, expected), "expected #{this} to be #{exp}", "expected #{this} not to be #{exp}", expected, this._obj);
2336
- });
2337
- m("toEqual", function(expected) {
2338
- this.assert(utils.eql(this._obj, expected), "expected #{this} to deeply equal #{exp}", "expected #{this} not to deeply equal #{exp}", expected, this._obj, true);
2339
- });
2340
- m("toBeTruthy", function() {
2341
- this.assert(Boolean(this._obj), "expected #{this} to be truthy", "expected #{this} not to be truthy");
2342
- });
2343
- m("toBeFalsy", function() {
2344
- this.assert(!this._obj, "expected #{this} to be falsy", "expected #{this} not to be falsy");
2345
- });
2346
- m("toBeNull", function() {
2347
- this.assert(this._obj === null, "expected #{this} to be null", "expected #{this} not to be null");
2348
- });
2349
- m("toBeUndefined", function() {
2350
- this.assert(this._obj === undefined, "expected #{this} to be undefined", "expected #{this} not to be undefined");
2351
- });
2352
- m("toBeDefined", function() {
2353
- this.assert(this._obj !== undefined, "expected #{this} to be defined", "expected #{this} to be undefined");
2354
- });
2355
- m("toBeNaN", function() {
2356
- this.assert(Number.isNaN(this._obj), "expected #{this} to be NaN", "expected #{this} not to be NaN");
2357
- });
2358
- const compare = (name, op, word) => m(name, function(expected) {
2359
- this.assert(op(this._obj, expected), `expected #{this} to be ${word} #{exp}`, `expected #{this} not to be ${word} #{exp}`, expected);
2360
- });
2361
- compare("toBeGreaterThan", (a, b) => a > b, "greater than");
2362
- compare("toBeGreaterThanOrEqual", (a, b) => a >= b, "greater than or equal to");
2363
- compare("toBeLessThan", (a, b) => a < b, "less than");
2364
- compare("toBeLessThanOrEqual", (a, b) => a <= b, "less than or equal to");
2365
- m("toBeCloseTo", function(expected, numDigits = 2) {
2366
- const pass = Math.abs(expected - this._obj) < 10 ** -numDigits / 2;
2367
- this.assert(pass, `expected #{this} to be close to #{exp} (${numDigits} digits)`, `expected #{this} not to be close to #{exp} (${numDigits} digits)`, expected);
2368
- });
2369
- m("toContain", function(item) {
2370
- const obj = this._obj;
2371
- const ok = typeof obj === "string" ? obj.includes(item) : Array.from(obj).includes(item);
2372
- this.assert(ok, "expected #{this} to contain #{exp}", "expected #{this} not to contain #{exp}", item);
2373
- });
2374
- m("toHaveLength", function(length) {
2375
- const actual = this._obj == null ? undefined : this._obj.length;
2376
- this.assert(actual === length, "expected #{this} to have length #{exp}", "expected #{this} not to have length #{exp}", length, actual);
2377
- });
2378
- m("toMatch", function(expected) {
2379
- const obj = this._obj;
2380
- const ok = expected instanceof RegExp ? expected.test(obj) : String(obj).includes(expected);
2381
- this.assert(ok, "expected #{this} to match #{exp}", "expected #{this} not to match #{exp}", expected);
2382
- });
2383
- m("toHaveProperty", function(path, ...rest) {
2384
- const keys = Array.isArray(path) ? path : String(path).split(".");
2385
- let cur = this._obj;
2386
- let found = true;
2387
- for (const k of keys) {
2388
- if (cur != null && k in Object(cur))
2389
- cur = cur[k];
2390
- else {
2391
- found = false;
2392
- break;
2393
- }
2394
- }
2395
- const pass = found && (rest.length === 0 || utils.eql(cur, rest[0]));
2396
- this.assert(pass, "expected #{this} to have property #{exp}", "expected #{this} not to have property #{exp}", path);
2397
- });
2398
- m("toBeInstanceOf", function(ctor) {
2399
- this.assert(this._obj instanceof ctor, "expected #{this} to be an instance of #{exp}", "expected #{this} not to be an instance of #{exp}", ctor.name ?? ctor);
2400
- });
2401
- m("toThrow", function(expected) {
2402
- const a = new chai.Assertion(this._obj);
2403
- if (utils.flag(this, "negate")) {
2404
- expected === undefined ? a.to.not.throw() : a.to.not.throw(expected);
2405
- } else {
2406
- expected === undefined ? a.to.throw() : a.to.throw(expected);
2407
- }
2408
- });
2409
- }
2410
-
2411
- // src/util/parsectx.js
2412
- class ParseCtxClassSetCollector extends ParseContext {
2413
- constructor(...args) {
2414
- super(...args);
2415
- this.classes = new Set;
2416
- }
2417
- _addClasses(s) {
2418
- for (const v of s.split(/\s+/)) {
2419
- this.classes.add(v);
2643
+ // src/util/parsectx.js
2644
+ class ParseCtxClassSetCollector extends ParseContext {
2645
+ constructor(...args) {
2646
+ super(...args);
2647
+ this.classes = new Set;
2648
+ }
2649
+ _addClasses(s) {
2650
+ for (const v of s.split(/\s+/)) {
2651
+ this.classes.add(v);
2420
2652
  }
2421
2653
  }
2422
2654
  enterMacro(macroName, macroVars, macroSlots) {
@@ -2464,6 +2696,18 @@ class ParseCtxClassSetCollector extends ParseContext {
2464
2696
  return false;
2465
2697
  }
2466
2698
  }
2699
+ function collectAppClassesInSet(app) {
2700
+ const classes = new Set;
2701
+ for (const Comp of app.comps.byId.values()) {
2702
+ for (const key in Comp.views) {
2703
+ const view = Comp.views[key];
2704
+ for (const name of view.ctx.classes) {
2705
+ classes.add(name);
2706
+ }
2707
+ }
2708
+ }
2709
+ return classes;
2710
+ }
2467
2711
 
2468
2712
  // tools/core/html-tokenizer.js
2469
2713
  var CharCodes = {
@@ -4800,6 +5044,16 @@ var PARSE_ISSUES = {
4800
5044
  },
4801
5045
  "bad-value": { id: BAD_VALUE }
4802
5046
  };
5047
+ function protoHasMethod(proto, name) {
5048
+ let cursor = proto;
5049
+ while (cursor && cursor !== Object.prototype) {
5050
+ const desc = Object.getOwnPropertyDescriptor(cursor, name);
5051
+ if (desc !== undefined)
5052
+ return typeof desc.value === "function";
5053
+ cursor = Object.getPrototypeOf(cursor);
5054
+ }
5055
+ return false;
5056
+ }
4803
5057
  function collectProtoMethodNames(proto) {
4804
5058
  const out = [];
4805
5059
  let cursor = proto;
@@ -5058,7 +5312,7 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
5058
5312
  referencedInputs?.add(handlerVal.name);
5059
5313
  const { name } = handlerVal;
5060
5314
  if (input[name] === undefined) {
5061
- const isMethodFix = proto[name] !== undefined;
5315
+ const isMethodFix = protoHasMethod(proto, name);
5062
5316
  lx.error(INPUT_HANDLER_NOT_IMPLEMENTED, { name, handler, event, eventName, originAttr }, isMethodFix ? { kind: "add-prefix", from: name, to: `$${name}` } : replaceNameSuggestion(name, Object.keys(input)));
5063
5317
  if (isMethodFix) {
5064
5318
  lx.hint(INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER, { name, handler, event, eventName, originAttr }, { kind: "add-prefix", from: name, to: `$${name}` });
@@ -5067,7 +5321,7 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
5067
5321
  } else if (hvName === "MethodVal") {
5068
5322
  referencedInputs?.add(handlerVal.name);
5069
5323
  const { name } = handlerVal;
5070
- if (proto[name] === undefined) {
5324
+ if (!protoHasMethod(proto, name)) {
5071
5325
  const isInputFix = input[name] !== undefined;
5072
5326
  lx.error(INPUT_HANDLER_METHOD_NOT_IMPLEMENTED, { name, handler, event, eventName, originAttr }, isInputFix ? { kind: "drop-prefix", from: `$${name}`, to: name } : replaceNameSuggestion(name, collectProtoMethodNames(proto)));
5073
5327
  if (isInputFix) {
@@ -5090,7 +5344,7 @@ var ATTR_VAL_CHECKERS = {
5090
5344
  const { name } = val;
5091
5345
  if (fields[name] !== undefined)
5092
5346
  return;
5093
- if (proto[name] !== undefined)
5347
+ if (protoHasMethod(proto, name))
5094
5348
  lx.error(FIELD_VAL_IS_METHOD, { ...errCtx, val, name }, fixTo(`.${name}`, `$${name}`));
5095
5349
  else
5096
5350
  reportUnknownName(lx, FIELD_VAL_NOT_DEFINED, name, Object.keys(fields), { ...errCtx, val });
@@ -5098,7 +5352,7 @@ var ATTR_VAL_CHECKERS = {
5098
5352
  MethodVal({ lx, val, env, errCtx }) {
5099
5353
  const { fields, proto } = env;
5100
5354
  const { name } = val;
5101
- if (proto[name] !== undefined)
5355
+ if (protoHasMethod(proto, name))
5102
5356
  return;
5103
5357
  if (fields[name] !== undefined)
5104
5358
  lx.error(METHOD_VAL_IS_FIELD, { ...errCtx, val, name }, fixTo(`$${name}`, `.${name}`));
@@ -5739,7 +5993,7 @@ async function runTests({
5739
5993
  getTests,
5740
5994
  components = [],
5741
5995
  path = null,
5742
- expect,
5996
+ expect: expect2,
5743
5997
  name = null,
5744
5998
  grep = null,
5745
5999
  bail = false
@@ -5750,11 +6004,11 @@ async function runTests({
5750
6004
  modules: [new ModuleTestReport({ path, suites: [], counts })]
5751
6005
  });
5752
6006
  }
5753
- if (typeof expect !== "function") {
6007
+ if (typeof expect2 !== "function") {
5754
6008
  throw new Error("runTests: expect must be provided (e.g. chai's expect)");
5755
6009
  }
5756
6010
  const { describe, test, moduleTests } = makeCollector({ path, components });
5757
- await getTests({ describe, test, expect });
6011
+ await getTests({ describe, test, expect: expect2 });
5758
6012
  let bailed = false;
5759
6013
  async function visit(node) {
5760
6014
  if (node instanceof Test) {
@@ -6596,7 +6850,6 @@ class Transaction {
6596
6850
  return null;
6597
6851
  }
6598
6852
  }
6599
- var isMac2 = (globalThis.navigator?.userAgent ?? "").toLowerCase().includes("mac");
6600
6853
  var toNullIfNaN = (v) => Number.isNaN(v) ? null : v;
6601
6854
  function getValue(e) {
6602
6855
  return e.target.type === "checkbox" ? e.target.checked : (e instanceof CustomEvent ? e.detail : e.target.value) ?? null;
@@ -6650,7 +6903,7 @@ class InputEvent extends Transaction {
6650
6903
  return e.shiftKey;
6651
6904
  case "isCtrl":
6652
6905
  case "isCmd":
6653
- return isMac2 && e.metaKey || e.ctrlKey;
6906
+ return isMac && e.metaKey || e.ctrlKey;
6654
6907
  case "key":
6655
6908
  return e.key;
6656
6909
  case "keyCode":
@@ -7074,8 +7327,60 @@ class DragInfo {
7074
7327
  }
7075
7328
  }
7076
7329
 
7077
- // extra/klist.js
7078
- import { Map as IMap2, List as List2 } from "immutable";
7330
+ // index.js
7331
+ import {
7332
+ Collection,
7333
+ fromJS,
7334
+ get,
7335
+ getIn,
7336
+ has,
7337
+ hash,
7338
+ hasIn,
7339
+ is as is2,
7340
+ isAssociative,
7341
+ isCollection,
7342
+ isImmutable,
7343
+ isIndexed as isIndexed2,
7344
+ isKeyed as isKeyed2,
7345
+ isList,
7346
+ isMap,
7347
+ isMap as isMap2,
7348
+ isOrdered,
7349
+ isOrderedMap,
7350
+ isOrderedMap as isOrderedMap2,
7351
+ isOrderedSet,
7352
+ isPlainObject,
7353
+ isRecord,
7354
+ isSeq,
7355
+ isSet,
7356
+ isStack,
7357
+ isValueObject,
7358
+ List as List2,
7359
+ Map as Map2,
7360
+ Map as Map3,
7361
+ merge,
7362
+ mergeDeep,
7363
+ mergeDeepWith,
7364
+ mergeWith,
7365
+ OrderedMap as OrderedMap2,
7366
+ OrderedMap as OrderedMap3,
7367
+ OrderedSet,
7368
+ PairSorting,
7369
+ Range,
7370
+ Record as Record2,
7371
+ Repeat,
7372
+ remove,
7373
+ removeIn,
7374
+ Seq,
7375
+ Set as Set2,
7376
+ Set as Set3,
7377
+ Stack as Stack2,
7378
+ set,
7379
+ setIn,
7380
+ update,
7381
+ updateIn,
7382
+ version
7383
+ } from "immutable";
7079
7384
 
7080
7385
  // src/oo.js
7081
7386
  import { Map as IMap, Set as ISet, List, OrderedMap, Record } from "immutable";
@@ -7344,8 +7649,8 @@ class FieldSet extends Field {
7344
7649
  }
7345
7650
  }
7346
7651
  function mkCompField(field, scope, args) {
7347
- const Comp = scope.lookupComponent(field.type);
7348
- console.assert(Comp !== null, "component not found", { field });
7652
+ const Comp = scope?.lookupComponent(field.type) ?? null;
7653
+ console.assert(!scope || Comp !== null, "component not found", { field });
7349
7654
  return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
7350
7655
  }
7351
7656
 
@@ -7462,378 +7767,7 @@ function classFromData(name, { fields = {}, methods, statics }) {
7462
7767
  Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
7463
7768
  var component = (opts) => Component.fromSpec(opts);
7464
7769
 
7465
- // src/renderer.js
7466
- import { isIndexed, isKeyed } from "immutable";
7467
-
7468
- // src/cache.js
7469
- class NullDomCache {
7470
- get(_keys, _cacheKey) {}
7471
- set(_keys, _cacheKey, _v) {}
7472
- evict() {
7473
- return { hit: 0, miss: 0, badKey: 0 };
7474
- }
7475
- }
7476
-
7477
- class WeakMapDomCache {
7478
- constructor() {
7479
- this.hit = this.miss = this.badKey = 0;
7480
- this.keysByLen = new Map;
7481
- }
7482
- _returnValue(r) {
7483
- if (r === undefined)
7484
- this.miss += 1;
7485
- else
7486
- this.hit += 1;
7487
- return r;
7488
- }
7489
- get(keys, cacheKey) {
7490
- const len = keys.length;
7491
- let cur = this.keysByLen.get(len);
7492
- if (!cur)
7493
- return this._returnValue(undefined);
7494
- for (let i = 0;i < len - 1; i++) {
7495
- cur = cur.get(keys[i]);
7496
- if (!cur)
7497
- return this._returnValue(undefined);
7498
- }
7499
- return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
7500
- }
7501
- set(keys, cacheKey, v) {
7502
- const len = keys.length;
7503
- let cur = this.keysByLen.get(len);
7504
- if (!cur) {
7505
- cur = new WeakMap;
7506
- this.keysByLen.set(len, cur);
7507
- }
7508
- for (let i = 0;i < len - 1; i++) {
7509
- const key = keys[i];
7510
- let next = cur.get(key);
7511
- if (!next) {
7512
- if (typeof key !== "object") {
7513
- this.badKey += 1;
7514
- return;
7515
- }
7516
- next = new WeakMap;
7517
- cur.set(key, next);
7518
- }
7519
- cur = next;
7520
- }
7521
- const lastKey = keys[len - 1];
7522
- const leaf = cur.get(lastKey);
7523
- if (leaf)
7524
- leaf[cacheKey] = v;
7525
- else if (typeof lastKey === "object")
7526
- cur.set(lastKey, { [cacheKey]: v });
7527
- else
7528
- this.badKey += 1;
7529
- }
7530
- evict() {
7531
- const { hit, miss, badKey } = this;
7532
- this.hit = this.miss = this.badKey = 0;
7533
- this.keysByLen = new Map;
7534
- return { hit, miss, badKey };
7535
- }
7536
- }
7537
-
7538
- // src/renderer.js
7539
- var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
7540
-
7541
- class Renderer {
7542
- constructor(comps) {
7543
- this.comps = comps;
7544
- this.cache = new WeakMapDomCache;
7545
- this.renderTag = h;
7546
- }
7547
- renderFragment(childs) {
7548
- return new VFragment(childs);
7549
- }
7550
- renderComment(text) {
7551
- return new VComment(text);
7552
- }
7553
- setNullCache() {
7554
- this.cache = new NullDomCache;
7555
- }
7556
- renderToDOM(stack, val) {
7557
- const rootNode = document.createElement("div");
7558
- const rOpts = { document };
7559
- render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
7560
- return rootNode.childNodes[0];
7561
- }
7562
- renderToString(stack, val, cleanAttrs = true) {
7563
- const dom = this.renderToDOM(stack, val);
7564
- if (cleanAttrs) {
7565
- const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
7566
- for (const { dataset } of nodes)
7567
- for (const name of DATASET_ATTRS)
7568
- delete dataset[name];
7569
- }
7570
- return dom.innerHTML;
7571
- }
7572
- renderRoot(stack, val, viewName = null) {
7573
- const comp = this.comps.getCompFor(val);
7574
- if (comp === null)
7575
- return null;
7576
- return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
7577
- }
7578
- renderIt(stack, node, key, viewName) {
7579
- const comp = this.comps.getCompFor(stack.it);
7580
- return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName) : null;
7581
- }
7582
- _rValComp(stack, val, comp, node, key, viewName) {
7583
- const cacheKey = `${viewName ?? stack.viewsId ?? ""}-${key}`;
7584
- const cachePath = [node, val];
7585
- stack._pushDynBindValuesToArray(cachePath, comp);
7586
- const cachedNode = this.cache.get(cachePath, cacheKey);
7587
- if (cachedNode)
7588
- return cachedNode;
7589
- const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
7590
- const meta = this._renderMetadata({
7591
- $: "Comp",
7592
- nid: node?.nodeId ?? null,
7593
- cid: comp.id,
7594
- vid: view.name
7595
- });
7596
- const dom = new VFragment([meta, this.renderView(view, stack)]);
7597
- this.cache.set(cachePath, cacheKey, dom);
7598
- return dom;
7599
- }
7600
- pushEachEntry(r, nid, attrName, key, dom) {
7601
- r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
7602
- }
7603
- renderEach(stack, iterInfo, node, viewName) {
7604
- const { seq, filter, loopWith } = iterInfo.eval(stack);
7605
- const r = [];
7606
- const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
7607
- getSeqInfo(seq)(seq, (key, value, attrName) => {
7608
- if (filter.call(stack.it, key, value, iterData)) {
7609
- const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
7610
- this.pushEachEntry(r, node.nodeId, attrName, key, dom);
7611
- }
7612
- }, start, end);
7613
- return r;
7614
- }
7615
- renderEachWhen(stack, iterInfo, view, nid) {
7616
- const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
7617
- const r = [];
7618
- const it = stack.it;
7619
- const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
7620
- getSeqInfo(seq)(seq, (key, value, attrName) => {
7621
- if (filter.call(it, key, value, iterData)) {
7622
- const cachePath = enricher ? [view, it, value] : [view, value];
7623
- const binds = { key, value };
7624
- const cacheKey = `${nid}-${key}`;
7625
- if (enricher)
7626
- enricher.call(it, binds, key, value, iterData);
7627
- const cachedNode = this.cache.get(cachePath, cacheKey);
7628
- if (cachedNode)
7629
- this.pushEachEntry(r, nid, attrName, key, cachedNode);
7630
- else {
7631
- const dom = this.renderView(view, stack.enter(value, binds, false));
7632
- this.pushEachEntry(r, nid, attrName, key, dom);
7633
- this.cache.set(cachePath, cacheKey, dom);
7634
- }
7635
- }
7636
- }, start, end);
7637
- return r;
7638
- }
7639
- renderView(view, stack) {
7640
- let n = stack.binds[1];
7641
- while (n !== null) {
7642
- const b = n[0];
7643
- if (b.isFrame) {
7644
- if (stack.it !== b.it)
7645
- break;
7646
- console.error("recursion detected", stack.it, b.it);
7647
- return new VComment("RECURSION AVOIDED");
7648
- }
7649
- n = n[1];
7650
- }
7651
- return view.render(stack, this);
7652
- }
7653
- _renderMetadata(info) {
7654
- return new VComment(`§${JSON.stringify(info)}§`);
7655
- }
7656
- }
7657
- var getSeqInfo = (seq) => isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
7658
- var normalizeRange = (start, end, size) => {
7659
- let s = start == null ? 0 : start < 0 ? size + start : start;
7660
- let e = end == null ? size : end < 0 ? size + end : end;
7661
- s = s < 0 ? 0 : s > size ? size : s;
7662
- e = e < 0 ? 0 : e > size ? size : e;
7663
- return [s, e < s ? s : e];
7664
- };
7665
- var unpackLoopResult = (result, seq) => {
7666
- const r = result ?? {};
7667
- return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
7668
- };
7669
- var imIndexedIter = (seq, visit, start, end) => {
7670
- const [s, e] = normalizeRange(start, end, seq.size);
7671
- for (let i = s;i < e; i++)
7672
- visit(i, seq.get(i), "si");
7673
- };
7674
- var imKeyedIter = (seq, visit, start, end) => {
7675
- const [s, e] = normalizeRange(start, end, seq.size);
7676
- let i = 0;
7677
- for (const [k, v] of seq.toSeq().entries()) {
7678
- if (i >= e)
7679
- break;
7680
- if (i >= s)
7681
- visit(k, v, "sk");
7682
- i++;
7683
- }
7684
- };
7685
- var unkIter = () => {};
7686
- var SEQ_INFO = Symbol.for("tutuca.seqInfo");
7687
-
7688
- // extra/klist.js
7689
- class KList {
7690
- constructor(items = IMap2(), order = List2()) {
7691
- this.items = items;
7692
- this.order = order;
7693
- this.$ = 0;
7694
- }
7695
- _clonish(items, order) {
7696
- return new KList(items, order, this.$);
7697
- }
7698
- toJS() {
7699
- return this.order.toArray().map((k) => this.items.get(k));
7700
- }
7701
- set(k, v) {
7702
- const newOrder = this.items.has(k) ? this.order : this.order.push(k);
7703
- return this._clonish(this.items.set(k, v), newOrder, this.$);
7704
- }
7705
- get(k, dval = null) {
7706
- return this.items.get(k, dval);
7707
- }
7708
- _nextFreeKey() {
7709
- let cur = this.$;
7710
- while (true) {
7711
- const key = `§${cur}§`;
7712
- if (!this.items.has(key)) {
7713
- return [key, cur];
7714
- }
7715
- cur += 1;
7716
- }
7717
- }
7718
- push(v) {
7719
- const [key, next$] = this._nextFreeKey();
7720
- const newKList = this.set(key, v);
7721
- newKList.$ = next$;
7722
- return newKList;
7723
- }
7724
- get size() {
7725
- return this.items.size;
7726
- }
7727
- delete(k) {
7728
- if (this.items.has(k)) {
7729
- const newOrder = this.order.delete(this.order.indexOf(k));
7730
- return this._clonish(this.items.delete(k), newOrder);
7731
- }
7732
- return this;
7733
- }
7734
- moveKeyBeforeKey(k1, k2) {
7735
- const { order } = this;
7736
- return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 0);
7737
- }
7738
- moveKeyAfterKey(k1, k2) {
7739
- const { order } = this;
7740
- return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 1);
7741
- }
7742
- moveKeyIndexToIndex(source, target, offset) {
7743
- if (source === -1 || target === -1 || source === target) {
7744
- return this;
7745
- }
7746
- const { order } = this;
7747
- const newPos = target + offset;
7748
- const oldPos = newPos < source ? source + 1 : source;
7749
- const newOrder = order.insert(newPos, order.get(source)).delete(oldPos);
7750
- return this._clonish(this.items, newOrder);
7751
- }
7752
- }
7753
- var klistCoercer = (_) => null;
7754
-
7755
- class CheckTypeKList {
7756
- isValid(v) {
7757
- return v instanceof KList;
7758
- }
7759
- getMessage(_v) {
7760
- return "KList expected";
7761
- }
7762
- }
7763
- var CHECK_TYPE_KLIST = new CheckTypeKList;
7764
-
7765
- class FieldKList extends Field {
7766
- constructor(name, defaultValue = new KList) {
7767
- super("KList", name, CHECK_TYPE_KLIST, klistCoercer, defaultValue);
7768
- }
7769
- extendProtoForType(proto, uname) {
7770
- extendProtoForKeyed(proto, this.name, uname);
7771
- const { name } = this;
7772
- extendProtoForKeyed(proto, name, uname);
7773
- proto[`pushIn${uname}`] = function(v) {
7774
- return this.set(name, this.get(name).push(v));
7775
- };
7776
- }
7777
- }
7778
- KList.prototype[FIELD_CLASS] = FieldKList;
7779
- KList.prototype[SEQ_INFO] = (seq, visit) => {
7780
- for (const k of seq.order)
7781
- visit(k, seq.items.get(k), "data-sk");
7782
- };
7783
7770
  // index.js
7784
- import {
7785
- Collection,
7786
- List as List3,
7787
- Map as Map2,
7788
- OrderedMap as OrderedMap2,
7789
- OrderedSet,
7790
- PairSorting,
7791
- Range,
7792
- Record as Record2,
7793
- Repeat,
7794
- Seq,
7795
- Set as Set2,
7796
- Stack as Stack2,
7797
- fromJS,
7798
- get,
7799
- getIn,
7800
- has,
7801
- hasIn,
7802
- hash,
7803
- is as is2,
7804
- isAssociative,
7805
- isCollection,
7806
- isImmutable,
7807
- isIndexed as isIndexed2,
7808
- isKeyed as isKeyed2,
7809
- isList,
7810
- isMap,
7811
- isOrdered,
7812
- isOrderedMap,
7813
- isOrderedSet,
7814
- isPlainObject,
7815
- isRecord,
7816
- isSeq,
7817
- isSet,
7818
- isStack,
7819
- isValueObject,
7820
- merge,
7821
- mergeDeep,
7822
- mergeDeepWith,
7823
- mergeWith,
7824
- remove,
7825
- removeIn,
7826
- set,
7827
- setIn,
7828
- update,
7829
- updateIn,
7830
- version,
7831
- isMap as isMap2,
7832
- isOrderedMap as isOrderedMap2,
7833
- Map as Map3,
7834
- OrderedMap as OrderedMap3,
7835
- Set as Set3
7836
- } from "immutable";
7837
7771
  var css = String.raw;
7838
7772
  var html = String.raw;
7839
7773
  var macro = (defaults, rawView) => new Macro(defaults, rawView);
@@ -7855,15 +7789,58 @@ async function compileClassesToStyle(app, compileClasses, styleId = "margaui-css
7855
7789
  async function compileClassesToStyleText(app, compileClasses, Ctx = ParseCtxClassSetCollector) {
7856
7790
  app.ParseContext = Ctx;
7857
7791
  app.compile();
7858
- const classes = new Set;
7859
- for (const Comp of app.comps.byId.values()) {
7860
- for (const key in Comp.views) {
7861
- const view = Comp.views[key];
7862
- for (const name of view.ctx.classes)
7863
- classes.add(name);
7864
- }
7792
+ return await compileClasses(Array.from(collectAppClassesInSet(app)));
7793
+ }
7794
+ // src/util/testing.js
7795
+ var plainArrayIter = (seq, visit, start, end) => {
7796
+ const [s, e] = normalizeRange(start, end, seq.length);
7797
+ for (let i = s;i < e; i++)
7798
+ visit(i, seq[i]);
7799
+ };
7800
+ var plainMapIter = (seq, visit, start, end) => {
7801
+ const [s, e] = normalizeRange(start, end, seq.size);
7802
+ let i = 0;
7803
+ for (const [k, v] of seq.entries()) {
7804
+ if (i >= e)
7805
+ break;
7806
+ if (i >= s)
7807
+ visit(k, v);
7808
+ i++;
7865
7809
  }
7866
- return await compileClasses(Array.from(classes));
7810
+ };
7811
+ function pickIter(seq) {
7812
+ if (Array.isArray(seq))
7813
+ return plainArrayIter;
7814
+ if (seq instanceof Map)
7815
+ return plainMapIter;
7816
+ return getSeqInfo(seq);
7817
+ }
7818
+ function resolveAlter(Comp, name) {
7819
+ if (name == null)
7820
+ return null;
7821
+ const fn = Comp.alter?.[name];
7822
+ if (typeof fn !== "function") {
7823
+ throw new Error(`alter handler '${name}' not found on component '${Comp.name}'`);
7824
+ }
7825
+ return fn;
7826
+ }
7827
+ function collectIterBindings(Comp, compInstance, seq, opts = {}) {
7828
+ const whenFn = resolveAlter(Comp, opts.when) ?? filterAlwaysTrue;
7829
+ const loopWithFn = resolveAlter(Comp, opts.loopWith) ?? nullLoopWith;
7830
+ const enrichFn = resolveAlter(Comp, opts.enrichWith);
7831
+ const it = compInstance;
7832
+ const { iterData, start, end } = unpackLoopResult(loopWithFn.call(it, seq), seq);
7833
+ const out = [];
7834
+ const iter = pickIter(seq);
7835
+ iter(seq, (key, value) => {
7836
+ if (!whenFn.call(it, key, value, iterData))
7837
+ return;
7838
+ const binds = { key, value };
7839
+ if (enrichFn)
7840
+ enrichFn.call(it, binds, key, value, iterData);
7841
+ out.push(binds);
7842
+ }, start, end);
7843
+ return out;
7867
7844
  }
7868
7845
  // tools/core/docs.js
7869
7846
  function getSignature(name, fn) {
@@ -8035,62 +8012,8 @@ function docComponents(normalized, { name = null } = {}) {
8035
8012
  const picked = name === null ? comps : comps.filter((c) => c.name === name);
8036
8013
  return new ComponentDocs({ items: getComponentsDocs(picked) });
8037
8014
  }
8038
- // src/util/testing.js
8039
- var filterAlwaysTrue2 = () => true;
8040
- var nullLoopWith2 = (seq) => ({ iterData: { seq } });
8041
- var plainArrayIter = (seq, visit, start, end) => {
8042
- const [s, e] = normalizeRange(start, end, seq.length);
8043
- for (let i = s;i < e; i++)
8044
- visit(i, seq[i]);
8045
- };
8046
- var plainMapIter = (seq, visit, start, end) => {
8047
- const [s, e] = normalizeRange(start, end, seq.size);
8048
- let i = 0;
8049
- for (const [k, v] of seq.entries()) {
8050
- if (i >= e)
8051
- break;
8052
- if (i >= s)
8053
- visit(k, v);
8054
- i++;
8055
- }
8056
- };
8057
- function pickIter(seq) {
8058
- if (Array.isArray(seq))
8059
- return plainArrayIter;
8060
- if (seq instanceof Map)
8061
- return plainMapIter;
8062
- return getSeqInfo(seq);
8063
- }
8064
- function resolveAlter(Comp, name) {
8065
- if (name == null)
8066
- return null;
8067
- const fn = Comp.alter?.[name];
8068
- if (typeof fn !== "function") {
8069
- throw new Error(`alter handler '${name}' not found on component '${Comp.name}'`);
8070
- }
8071
- return fn;
8072
- }
8073
- function collectIterBindings(Comp, compInstance, seq, opts = {}) {
8074
- const whenFn = resolveAlter(Comp, opts.when) ?? filterAlwaysTrue2;
8075
- const loopWithFn = resolveAlter(Comp, opts.loopWith) ?? nullLoopWith2;
8076
- const enrichFn = resolveAlter(Comp, opts.enrichWith);
8077
- const it = compInstance;
8078
- const { iterData, start, end } = unpackLoopResult(loopWithFn.call(it, seq), seq);
8079
- const out = [];
8080
- const iter = pickIter(seq);
8081
- iter(seq, (key, value) => {
8082
- if (!whenFn.call(it, key, value, iterData))
8083
- return;
8084
- const binds = { key, value };
8085
- if (enrichFn)
8086
- enrichFn.call(it, binds, key, value, iterData);
8087
- out.push(binds);
8088
- }, start, end);
8089
- return out;
8090
- }
8091
8015
 
8092
8016
  // dev.js
8093
- use(jestMatchers);
8094
8017
  async function test2(opts = {}) {
8095
8018
  const report = await runTests({ expect, ...opts });
8096
8019
  reportTestReportToConsole(report);
@@ -8253,7 +8176,7 @@ export {
8253
8176
  METHOD_VAL_IS_FIELD,
8254
8177
  MAYBE_DROP_AT_PREFIX,
8255
8178
  MAYBE_ADD_AT_PREFIX,
8256
- List3 as List,
8179
+ List2 as List,
8257
8180
  LintReport,
8258
8181
  LintParseContext,
8259
8182
  LintFinding,
@@ -8262,7 +8185,6 @@ export {
8262
8185
  LintClassCollectorCtx,
8263
8186
  LOOKUP_TARGET_MALFORMED,
8264
8187
  LOOKUP_BAD_SHAPE,
8265
- KList,
8266
8188
  Set3 as ISet,
8267
8189
  INPUT_HANDLER_NOT_REFERENCED,
8268
8190
  INPUT_HANDLER_NOT_IMPLEMENTED,