tutuca 0.9.21 → 0.9.23

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.
@@ -1552,100 +1552,463 @@ class ParseCtxClassSetCollector extends ParseContext {
1552
1552
  }
1553
1553
  }
1554
1554
 
1555
- // src/cache.js
1556
- class NullDomCache {
1557
- get(_k, _cacheKey) {}
1558
- set(_k, _cacheKey, _v) {}
1559
- get2(_k1, _k2, _cacheKey) {}
1560
- set2(_k1, _k2, _cacheKey, _v) {}
1561
- evict() {
1562
- return { hit: 0, miss: 0, badKey: 0 };
1563
- }
1555
+ // tools/core/lint-check.js
1556
+ var ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED";
1557
+ var ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED";
1558
+ var RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP";
1559
+ var UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER";
1560
+ var UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME";
1561
+ var INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED";
1562
+ var INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED";
1563
+ var INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED";
1564
+ var INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD";
1565
+ var INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER";
1566
+ var FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED";
1567
+ var COMPUTED_VAL_NOT_DEFINED = "COMPUTED_VAL_NOT_DEFINED";
1568
+ var COMPUTED_NOT_REFERENCED = "COMPUTED_NOT_REFERENCED";
1569
+ var UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME";
1570
+ var UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME";
1571
+ var LEVEL_WARN = "warn";
1572
+ var LEVEL_ERROR = "error";
1573
+ var LEVEL_HINT = "hint";
1574
+ function checkComponent(Comp, lx = new LintContext) {
1575
+ return lx.push({ componentName: Comp.name }, () => {
1576
+ const referencedAlters = new Set;
1577
+ const referencedInputs = new Set;
1578
+ const referencedComputed = new Set;
1579
+ checkEventHandlersHaveImpls(lx, Comp, referencedInputs);
1580
+ checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed);
1581
+ for (const name in Comp.views) {
1582
+ lx.push({ viewName: name }, () => checkView(lx, Comp.views[name], Comp, referencedAlters, referencedComputed));
1583
+ }
1584
+ checkUnreferencedAlterHandlers(lx, Comp, referencedAlters);
1585
+ checkUnreferencedInputHandlers(lx, Comp, referencedInputs);
1586
+ checkUnreferencedComputed(lx, Comp, referencedComputed);
1587
+ return lx;
1588
+ });
1564
1589
  }
1565
-
1566
- class WeakMapDomCache {
1567
- constructor() {
1568
- this.hit = this.miss = this.badKey = 0;
1569
- this.map = new WeakMap;
1590
+ function checkView(lx, view, Comp, referencedAlters, referencedComputed) {
1591
+ checkRenderItInLoop(lx, view);
1592
+ checkEventModifiers(lx, view);
1593
+ checkKnownHandlerNames(lx, view, Comp, referencedAlters, referencedComputed);
1594
+ }
1595
+ function checkRenderItInLoop(lx, view) {
1596
+ let hasRenderIt = false;
1597
+ for (const node of view.ctx.nodes) {
1598
+ if (node.constructor.name === "RenderItNode") {
1599
+ hasRenderIt = true;
1600
+ break;
1601
+ }
1570
1602
  }
1571
- _returnValue(r) {
1572
- if (r === undefined)
1573
- this.miss += 1;
1574
- else
1575
- this.hit += 1;
1576
- return r;
1603
+ if (!hasRenderIt)
1604
+ return;
1605
+ walkForRenderIt(lx, view.anode, 0);
1606
+ }
1607
+ function walkForRenderIt(lx, node, loopDepth) {
1608
+ if (node === null || node === undefined)
1609
+ return;
1610
+ switch (node.constructor.name) {
1611
+ case "RenderItNode":
1612
+ if (loopDepth === 0)
1613
+ lx.error(RENDER_IT_OUTSIDE_OF_LOOP, { node });
1614
+ return;
1615
+ case "EachNode":
1616
+ walkForRenderIt(lx, node.node, loopDepth + 1);
1617
+ return;
1618
+ case "ShowNode":
1619
+ case "HideNode":
1620
+ case "ScopeNode":
1621
+ case "SlotNode":
1622
+ case "PushViewNameNode":
1623
+ case "MacroNode":
1624
+ case "RenderOnceNode":
1625
+ walkForRenderIt(lx, node.node, loopDepth);
1626
+ return;
1627
+ case "DomNode":
1628
+ case "FragmentNode":
1629
+ for (const child of node.childs)
1630
+ walkForRenderIt(lx, child, loopDepth);
1631
+ return;
1632
+ default:
1633
+ return;
1577
1634
  }
1578
- get(k, cacheKey) {
1579
- return this._returnValue(this.map.get(k)?.[cacheKey]);
1635
+ }
1636
+ var NO_WRAPPERS = {};
1637
+ function checkEventModifiers(lx, view) {
1638
+ for (const event of view.ctx.events) {
1639
+ for (const handler of event.handlers) {
1640
+ const { name, modifiers } = handler;
1641
+ const modWrappers = MOD_WRAPPERS_BY_EVENT[name] ?? NO_WRAPPERS;
1642
+ for (const modifier of modifiers) {
1643
+ if (modWrappers[modifier] === undefined) {
1644
+ lx.warn(UNKNOWN_EVENT_MODIFIER, { name, modifier, handler, event });
1645
+ }
1646
+ }
1647
+ }
1580
1648
  }
1581
- set(k, cacheKey, v) {
1582
- const cur = this.map.get(k);
1583
- if (cur)
1584
- cur[cacheKey] = v;
1585
- else if (typeof k === "object")
1586
- this.map.set(k, { [cacheKey]: v });
1587
- else
1588
- this.badKey += 1;
1649
+ }
1650
+ var KNOWN_HANDLER_NAMES = new Set([
1651
+ "value",
1652
+ "valueAsInt",
1653
+ "valueAsFloat",
1654
+ "target",
1655
+ "event",
1656
+ "isAlt",
1657
+ "isShift",
1658
+ "isCtrl",
1659
+ "isCmd",
1660
+ "key",
1661
+ "keyCode",
1662
+ "isUpKey",
1663
+ "isDownKey",
1664
+ "isSend",
1665
+ "isCancel",
1666
+ "isTabKey",
1667
+ "ctx",
1668
+ "dragInfo"
1669
+ ]);
1670
+ function isKnownHandlerName(name) {
1671
+ return KNOWN_HANDLER_NAMES.has(name);
1672
+ }
1673
+ function checkKnownHandlerNames(lx, view, Comp, referencedAlters, referencedComputed) {
1674
+ const { computed, scope, alter, Class } = Comp;
1675
+ const { prototype: proto } = Class;
1676
+ const { fields } = Class.getMetaClass();
1677
+ for (const event of view.ctx.events) {
1678
+ for (const handler of event.handlers) {
1679
+ const { args } = handler.handlerCall;
1680
+ for (let i = 0;i < args.length; i++) {
1681
+ const arg = args[i];
1682
+ checkConsistentAttrVal(lx, arg, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1683
+ }
1684
+ }
1589
1685
  }
1590
- get2(k1, k2, cacheKey) {
1591
- return this._returnValue(this.map.get(k1)?.get?.(k2)?.[cacheKey]);
1686
+ }
1687
+ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
1688
+ const { input, views, Class } = Comp;
1689
+ const { prototype: proto } = Class;
1690
+ for (const viewName in views) {
1691
+ lx.push({ viewName }, () => {
1692
+ const view = views[viewName];
1693
+ for (const event of view.ctx.events) {
1694
+ for (const handler of event.handlers) {
1695
+ const { handlerVal } = handler.handlerCall;
1696
+ const hvName = handlerVal?.constructor.name;
1697
+ if (hvName === "InputHandlerNameVal") {
1698
+ referencedInputs?.add(handlerVal.name);
1699
+ if (input[handlerVal.name] === undefined) {
1700
+ lx.warn(INPUT_HANDLER_NOT_IMPLEMENTED, {
1701
+ name: handlerVal.name,
1702
+ handler,
1703
+ event
1704
+ });
1705
+ if (proto[handlerVal.name] !== undefined) {
1706
+ lx.hint(INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER, {
1707
+ name: handlerVal.name,
1708
+ handler,
1709
+ event
1710
+ });
1711
+ }
1712
+ }
1713
+ } else if (hvName === "RawFieldVal") {
1714
+ referencedInputs?.add(handlerVal.name);
1715
+ if (proto[handlerVal.name] === undefined) {
1716
+ lx.warn(INPUT_HANDLER_METHOD_NOT_IMPLEMENTED, {
1717
+ name: handlerVal.name,
1718
+ handler,
1719
+ event
1720
+ });
1721
+ if (input[handlerVal.name] !== undefined) {
1722
+ lx.hint(INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD, {
1723
+ name: handlerVal.name,
1724
+ handler,
1725
+ event
1726
+ });
1727
+ }
1728
+ }
1729
+ }
1730
+ }
1731
+ }
1732
+ });
1592
1733
  }
1593
- set2(k1, k2, cacheKey, v) {
1594
- const cur1 = this.map.get(k1);
1595
- if (cur1) {
1596
- const cur = cur1.get(k2);
1597
- if (cur)
1598
- cur[cacheKey] = v;
1599
- else
1600
- cur1.set(k2, { [cacheKey]: v });
1601
- } else if (typeof k1 === "object" && typeof k2 === "object") {
1602
- const cur = new WeakMap;
1603
- cur.set(k2, { [cacheKey]: v });
1604
- this.map.set(k1, cur);
1605
- } else {
1606
- this.badKey += 1;
1734
+ }
1735
+ function checkConsistentAttrVal(lx, val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed) {
1736
+ const valName = val?.constructor.name;
1737
+ if (valName === "FieldVal" || valName === "RawFieldVal") {
1738
+ const { name } = val;
1739
+ if (fields[name] === undefined && proto[name] === undefined) {
1740
+ lx.error(FIELD_VAL_NOT_DEFINED, { val, name });
1741
+ }
1742
+ } else if (valName === "ComputedVal") {
1743
+ const { name } = val;
1744
+ referencedComputed?.add(name);
1745
+ if (computed[name] === undefined) {
1746
+ lx.error(COMPUTED_VAL_NOT_DEFINED, { val, name });
1747
+ }
1748
+ } else if (valName === "SeqAccessVal") {
1749
+ checkConsistentAttrVal(lx, val.seqVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1750
+ checkConsistentAttrVal(lx, val.keyVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1751
+ } else if (valName === "RequestVal") {
1752
+ if (scope.lookupRequest(val.name) === null) {
1753
+ lx.warn(UNKNOWN_REQUEST_NAME, { name: val.name });
1754
+ }
1755
+ } else if (valName === "TypeVal") {
1756
+ if (scope.lookupComponent(val.name) === null) {
1757
+ lx.warn(UNKNOWN_COMPONENT_NAME, { name: val.name });
1758
+ }
1759
+ } else if (valName === "NameVal") {
1760
+ if (!isKnownHandlerName(val.name)) {
1761
+ lx.warn(UNKNOWN_HANDLER_ARG_NAME, { name: val.name });
1762
+ }
1763
+ } else if (valName === "StrTplVal") {
1764
+ for (const subVal of val.vals) {
1765
+ checkConsistentAttrVal(lx, subVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1766
+ }
1767
+ } else if (valName === "AlterHandlerNameVal") {
1768
+ referencedAlters?.add(val.name);
1769
+ if (alter[val.name] === undefined) {
1770
+ lx.warn(ALT_HANDLER_NOT_DEFINED, { name: val.name });
1607
1771
  }
1772
+ } else if (valName !== "ConstVal" && valName !== "BindVal") {
1773
+ console.log(val);
1608
1774
  }
1609
- evict() {
1610
- const { hit, miss, badKey } = this;
1611
- this.hit = this.miss = this.badKey = 0;
1612
- this.map = new WeakMap;
1613
- return { hit, miss, badKey };
1775
+ }
1776
+ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed) {
1777
+ const { computed, scope, views, alter, Class } = Comp;
1778
+ const { prototype: proto } = Class;
1779
+ const { fields } = Class.getMetaClass();
1780
+ for (const viewName in views) {
1781
+ lx.push({ viewName }, () => {
1782
+ const view = views[viewName];
1783
+ for (const attr of view.ctx.attrs) {
1784
+ const { attrs, wrapperAttrs, textChild } = attr;
1785
+ if (attrs?.constructor.name === "DynAttrs") {
1786
+ for (const attr2 of attrs.items) {
1787
+ if (attr2?.constructor.name === "Attr") {
1788
+ checkConsistentAttrVal(lx, attr2.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1789
+ }
1790
+ }
1791
+ }
1792
+ if (wrapperAttrs !== null) {
1793
+ for (const w of wrapperAttrs) {
1794
+ if (w.name === "each") {
1795
+ if (w.whenVal)
1796
+ checkConsistentAttrVal(lx, w.whenVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1797
+ if (w.enrichWithVal)
1798
+ checkConsistentAttrVal(lx, w.enrichWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1799
+ if (w.loopWithVal)
1800
+ checkConsistentAttrVal(lx, w.loopWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1801
+ } else if (w.name !== "scope") {
1802
+ checkConsistentAttrVal(lx, w.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1803
+ }
1804
+ }
1805
+ }
1806
+ if (textChild) {
1807
+ checkConsistentAttrVal(lx, textChild, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1808
+ }
1809
+ }
1810
+ for (const node of view.ctx.nodes) {
1811
+ if (node.val) {
1812
+ checkConsistentAttrVal(lx, node.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1813
+ }
1814
+ }
1815
+ });
1614
1816
  }
1615
1817
  }
1616
-
1617
- class NullComputedCache {
1618
- getKey(v, _key, fn) {
1619
- return fn.call(v);
1818
+ function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
1819
+ for (const name in Comp.alter) {
1820
+ if (!referencedAlters.has(name)) {
1821
+ lx.hint(ALT_HANDLER_NOT_REFERENCED, { name });
1822
+ }
1620
1823
  }
1621
1824
  }
1622
-
1623
- class WeakMapComputedCache {
1624
- constructor() {
1625
- this.map = new WeakMap;
1825
+ function checkUnreferencedInputHandlers(lx, Comp, referencedInputs) {
1826
+ for (const name in Comp.input) {
1827
+ if (!referencedInputs.has(name)) {
1828
+ lx.hint(INPUT_HANDLER_NOT_REFERENCED, { name });
1829
+ }
1626
1830
  }
1627
- getKey(v, key, fn) {
1628
- const cur = this.map.get(v);
1629
- if (cur) {
1630
- const curValue = cur[key];
1631
- if (curValue !== undefined)
1632
- return curValue;
1633
- const newValue2 = fn.call(v) ?? null;
1634
- cur[key] = newValue2;
1635
- return newValue2;
1831
+ }
1832
+ function checkUnreferencedComputed(lx, Comp, referencedComputed) {
1833
+ for (const name in Comp.computed) {
1834
+ if (!referencedComputed.has(name)) {
1835
+ lx.hint(COMPUTED_NOT_REFERENCED, { name });
1636
1836
  }
1637
- const newValue = fn.call(v) ?? null;
1638
- this.map.set(v, { [key]: newValue });
1639
- return newValue;
1640
1837
  }
1641
1838
  }
1642
1839
 
1643
- // src/components.js
1644
- class Components {
1840
+ class LintContext {
1645
1841
  constructor() {
1646
- this.getComponentSymbol = Symbol("getComponent");
1647
- this.byId = new Map;
1648
- this.computedCache = new WeakMapComputedCache;
1842
+ this.reports = [];
1843
+ this.frame = {};
1844
+ }
1845
+ push(patch, fn) {
1846
+ const prev = this.frame;
1847
+ this.frame = { ...prev, ...patch };
1848
+ try {
1849
+ return fn();
1850
+ } finally {
1851
+ this.frame = prev;
1852
+ }
1853
+ }
1854
+ error(id, info) {
1855
+ this.report(id, info, LEVEL_ERROR);
1856
+ }
1857
+ warn(id, info) {
1858
+ this.report(id, info, LEVEL_WARN);
1859
+ }
1860
+ hint(id, info) {
1861
+ this.report(id, info, LEVEL_HINT);
1862
+ }
1863
+ report(id, info = {}, level = LEVEL_ERROR) {
1864
+ this.reports.push({ id, info, level, context: { ...this.frame } });
1865
+ }
1866
+ }
1867
+
1868
+ class LintParseContext extends ParseContext {
1869
+ constructor(DOMParser, Text, Comment) {
1870
+ super(DOMParser, Text, Comment);
1871
+ this.attrs = [];
1872
+ }
1873
+ onAttributes(attrs, wrapperAttrs, textChild) {
1874
+ this.attrs.push({ attrs, wrapperAttrs, textChild });
1875
+ }
1876
+ }
1877
+
1878
+ // tools/format/lint.js
1879
+ function lintIdToMessage(id, info) {
1880
+ switch (id) {
1881
+ case "RENDER_IT_OUTSIDE_OF_LOOP":
1882
+ return "render-it used outside of a loop";
1883
+ case "UNKNOWN_EVENT_MODIFIER":
1884
+ return `Unknown modifier '${info.modifier}' on '${info.name}' event`;
1885
+ case "UNKNOWN_HANDLER_ARG_NAME":
1886
+ return `Unknown handler argument '${info.name}'`;
1887
+ case "INPUT_HANDLER_NOT_IMPLEMENTED":
1888
+ return `Input handler '${info.name}' is not implemented`;
1889
+ case "INPUT_HANDLER_NOT_REFERENCED":
1890
+ return `Input handler '${info.name}' is defined but not referenced`;
1891
+ case "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED":
1892
+ return `Method '.${info.name}' is not implemented`;
1893
+ case "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD":
1894
+ return `'${info.name}' exists as input handler — use without '.' prefix`;
1895
+ case "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER":
1896
+ return `'${info.name}' exists as method — use with '.' prefix`;
1897
+ case "FIELD_VAL_NOT_DEFINED":
1898
+ return `Field '.${info.name}' is not defined`;
1899
+ case "COMPUTED_VAL_NOT_DEFINED":
1900
+ return `Computed property '$${info.name}' is not defined`;
1901
+ case "COMPUTED_NOT_REFERENCED":
1902
+ return `Computed property '$${info.name}' is defined but not referenced`;
1903
+ case "UNKNOWN_REQUEST_NAME":
1904
+ return `Unknown request '!${info.name}'`;
1905
+ case "UNKNOWN_COMPONENT_NAME":
1906
+ return `Unknown component '${info.name}'`;
1907
+ case "ALT_HANDLER_NOT_DEFINED":
1908
+ return `Alter handler '${info.name}' is not defined`;
1909
+ case "ALT_HANDLER_NOT_REFERENCED":
1910
+ return `Alter handler '${info.name}' is defined but not referenced`;
1911
+ case "LINT_ERROR":
1912
+ return info.message;
1913
+ default:
1914
+ return id;
1915
+ }
1916
+ }
1917
+
1918
+ // src/cache.js
1919
+ class NullDomCache {
1920
+ get(_k, _cacheKey) {}
1921
+ set(_k, _cacheKey, _v) {}
1922
+ get2(_k1, _k2, _cacheKey) {}
1923
+ set2(_k1, _k2, _cacheKey, _v) {}
1924
+ evict() {
1925
+ return { hit: 0, miss: 0, badKey: 0 };
1926
+ }
1927
+ }
1928
+
1929
+ class WeakMapDomCache {
1930
+ constructor() {
1931
+ this.hit = this.miss = this.badKey = 0;
1932
+ this.map = new WeakMap;
1933
+ }
1934
+ _returnValue(r) {
1935
+ if (r === undefined)
1936
+ this.miss += 1;
1937
+ else
1938
+ this.hit += 1;
1939
+ return r;
1940
+ }
1941
+ get(k, cacheKey) {
1942
+ return this._returnValue(this.map.get(k)?.[cacheKey]);
1943
+ }
1944
+ set(k, cacheKey, v) {
1945
+ const cur = this.map.get(k);
1946
+ if (cur)
1947
+ cur[cacheKey] = v;
1948
+ else if (typeof k === "object")
1949
+ this.map.set(k, { [cacheKey]: v });
1950
+ else
1951
+ this.badKey += 1;
1952
+ }
1953
+ get2(k1, k2, cacheKey) {
1954
+ return this._returnValue(this.map.get(k1)?.get?.(k2)?.[cacheKey]);
1955
+ }
1956
+ set2(k1, k2, cacheKey, v) {
1957
+ const cur1 = this.map.get(k1);
1958
+ if (cur1) {
1959
+ const cur = cur1.get(k2);
1960
+ if (cur)
1961
+ cur[cacheKey] = v;
1962
+ else
1963
+ cur1.set(k2, { [cacheKey]: v });
1964
+ } else if (typeof k1 === "object" && typeof k2 === "object") {
1965
+ const cur = new WeakMap;
1966
+ cur.set(k2, { [cacheKey]: v });
1967
+ this.map.set(k1, cur);
1968
+ } else {
1969
+ this.badKey += 1;
1970
+ }
1971
+ }
1972
+ evict() {
1973
+ const { hit, miss, badKey } = this;
1974
+ this.hit = this.miss = this.badKey = 0;
1975
+ this.map = new WeakMap;
1976
+ return { hit, miss, badKey };
1977
+ }
1978
+ }
1979
+
1980
+ class NullComputedCache {
1981
+ getKey(v, _key, fn) {
1982
+ return fn.call(v);
1983
+ }
1984
+ }
1985
+
1986
+ class WeakMapComputedCache {
1987
+ constructor() {
1988
+ this.map = new WeakMap;
1989
+ }
1990
+ getKey(v, key, fn) {
1991
+ const cur = this.map.get(v);
1992
+ if (cur) {
1993
+ const curValue = cur[key];
1994
+ if (curValue !== undefined)
1995
+ return curValue;
1996
+ const newValue2 = fn.call(v) ?? null;
1997
+ cur[key] = newValue2;
1998
+ return newValue2;
1999
+ }
2000
+ const newValue = fn.call(v) ?? null;
2001
+ this.map.set(v, { [key]: newValue });
2002
+ return newValue;
2003
+ }
2004
+ }
2005
+
2006
+ // src/components.js
2007
+ class Components {
2008
+ constructor() {
2009
+ this.getComponentSymbol = Symbol("getComponent");
2010
+ this.byId = new Map;
2011
+ this.computedCache = new WeakMapComputedCache;
1649
2012
  }
1650
2013
  setNullComputedCache() {
1651
2014
  this.computedCache = new NullComputedCache;
@@ -7736,483 +8099,205 @@ class Renderer {
7736
8099
  pushEachEntry(r, nid, attrName, key, dom) {
7737
8100
  r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
7738
8101
  }
7739
- renderEach(stack, iterInfo, nodeId, viewName) {
7740
- const { seq, filter, loopWith } = iterInfo.eval(stack);
7741
- const r = [];
7742
- const iterData = loopWith.call(stack.it, seq);
7743
- this.getSeqInfo(seq)(seq, (key, value, attrName) => {
7744
- if (filter.call(stack.it, key, value, iterData)) {
7745
- const newStack = stack.enter(value, { key }, true);
7746
- const dom = this.renderIt(newStack, nodeId, key, viewName);
7747
- this.pushEachEntry(r, nodeId, attrName, key, dom);
7748
- }
7749
- });
7750
- return r;
7751
- }
7752
- renderEachWhen(stack, iterInfo, view, nid) {
7753
- const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
7754
- const r = [];
7755
- const iterData = loopWith.call(stack.it, seq);
7756
- const it = stack.it;
7757
- this.getSeqInfo(seq)(seq, (key, value, attrName) => {
7758
- if (filter.call(it, key, value, iterData)) {
7759
- const bindings = { key, value };
7760
- const cacheKey = `${nid}-${key}`;
7761
- let cachedNode;
7762
- if (enricher) {
7763
- enricher.call(it, bindings, key, value, iterData);
7764
- cachedNode = this.cache.get2(it, value, cacheKey);
7765
- } else
7766
- cachedNode = this.cache.get(value, cacheKey);
7767
- if (cachedNode) {
7768
- this.pushEachEntry(r, nid, attrName, key, cachedNode);
7769
- return;
7770
- }
7771
- const newStack = stack.enter(value, bindings, false);
7772
- const dom = this.renderView(view, newStack);
7773
- this.pushEachEntry(r, nid, attrName, key, dom);
7774
- if (enricher)
7775
- this.cache.set2(it, value, cacheKey, dom);
7776
- else
7777
- this.cache.set(value, cacheKey, dom);
7778
- }
7779
- });
7780
- return r;
7781
- }
7782
- renderView(view, stack) {
7783
- let n = stack.binds[1];
7784
- while (n !== null) {
7785
- const b = n[0];
7786
- if (b.isFrame) {
7787
- if (stack.it !== b.it)
7788
- break;
7789
- console.error("recursion detected", stack.it, b.it);
7790
- return new VComment("RECURSION AVOIDED");
7791
- }
7792
- n = n[1];
7793
- }
7794
- return view.render(stack, this);
7795
- }
7796
- _renderMetadata(info) {
7797
- return new VComment(`§${JSON.stringify(info)}§`);
7798
- }
7799
- }
7800
- var imIndexedIter = (seq, visit) => {
7801
- let i = 0;
7802
- for (const v of seq)
7803
- visit(i++, v, "si");
7804
- };
7805
- var imKeyedIter = (seq, visit) => {
7806
- for (const [k, v] of seq.toSeq().entries())
7807
- visit(k, v, "sk");
7808
- };
7809
- var unkIter = () => {};
7810
- var seqInfoByClass = new Map;
7811
-
7812
- // extra/klist.js
7813
- class KList {
7814
- constructor(items = Map2(), order = List()) {
7815
- this.items = items;
7816
- this.order = order;
7817
- this.$ = 0;
7818
- }
7819
- _clonish(items, order) {
7820
- return new KList(items, order, this.$);
7821
- }
7822
- toJS() {
7823
- return this.order.toArray().map((k) => this.items.get(k));
7824
- }
7825
- set(k, v) {
7826
- const newOrder = this.items.has(k) ? this.order : this.order.push(k);
7827
- return this._clonish(this.items.set(k, v), newOrder, this.$);
7828
- }
7829
- get(k, dval = null) {
7830
- return this.items.get(k, dval);
7831
- }
7832
- _nextFreeKey() {
7833
- let cur = this.$;
7834
- while (true) {
7835
- const key = `§${cur}§`;
7836
- if (!this.items.has(key)) {
7837
- return [key, cur];
7838
- }
7839
- cur += 1;
7840
- }
7841
- }
7842
- push(v) {
7843
- const [key, next$] = this._nextFreeKey();
7844
- const newKList = this.set(key, v);
7845
- newKList.$ = next$;
7846
- return newKList;
7847
- }
7848
- get size() {
7849
- return this.items.size;
7850
- }
7851
- delete(k) {
7852
- if (this.items.has(k)) {
7853
- const newOrder = this.order.delete(this.order.indexOf(k));
7854
- return this._clonish(this.items.delete(k), newOrder);
7855
- }
7856
- return this;
7857
- }
7858
- moveKeyBeforeKey(k1, k2) {
7859
- const { order } = this;
7860
- return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 0);
7861
- }
7862
- moveKeyAfterKey(k1, k2) {
7863
- const { order } = this;
7864
- return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 1);
7865
- }
7866
- moveKeyIndexToIndex(source, target, offset) {
7867
- if (source === -1 || target === -1 || source === target) {
7868
- return this;
7869
- }
7870
- const { order } = this;
7871
- const newPos = target + offset;
7872
- const oldPos = newPos < source ? source + 1 : source;
7873
- const newOrder = order.insert(newPos, order.get(source)).delete(oldPos);
7874
- return this._clonish(this.items, newOrder);
7875
- }
7876
- }
7877
- var klistCoercer = (_) => null;
7878
-
7879
- class CheckTypeKList {
7880
- isValid(v) {
7881
- return v instanceof KList;
7882
- }
7883
- getMessage(_v) {
7884
- return "KList expected";
7885
- }
7886
- }
7887
- var CHECK_TYPE_KLIST = new CheckTypeKList;
7888
-
7889
- class FieldKList extends Field {
7890
- constructor(name, defaultValue = new KList) {
7891
- super("KList", name, CHECK_TYPE_KLIST, klistCoercer, defaultValue);
7892
- }
7893
- extendProtoForType(proto, uname) {
7894
- extendProtoForKeyed(proto, this.name, uname);
7895
- const { name } = this;
7896
- extendProtoForKeyed(proto, name, uname);
7897
- proto[`pushIn${uname}`] = function(v) {
7898
- return this.set(name, this.get(name).push(v));
7899
- };
7900
- }
7901
- }
7902
- fieldsByClass.set(KList, FieldKList);
7903
- seqInfoByClass.set(KList, (seq, visit) => {
7904
- for (const k of seq.order)
7905
- visit(k, seq.items.get(k), "data-sk");
7906
- });
7907
- // index.js
7908
- var css = String.raw;
7909
- var html = String.raw;
7910
- var macro = (defaults, rawView) => new Macro(defaults, rawView);
7911
- function tutuca(nodeOrSelector) {
7912
- const rootNode = typeof nodeOrSelector === "string" ? document.querySelector(nodeOrSelector) : nodeOrSelector;
7913
- const comps = new Components;
7914
- const renderer = new Renderer(comps);
7915
- return new App(rootNode, comps, renderer, ParseContext);
7916
- }
7917
-
7918
- // extra.js
7919
- async function compileClassesToStyle(app, compileClasses, styleId = "margaui-css") {
7920
- const t1 = performance.now();
7921
- const css2 = await compileClassesToStyleText(app, compileClasses);
7922
- const t2 = performance.now();
7923
- injectCss(styleId, css2);
7924
- return t2 - t1;
7925
- }
7926
- async function compileClassesToStyleText(app, compileClasses, extraCSSClasses, Ctx = ParseCtxClassSetCollector) {
7927
- app.ParseContext = Ctx;
7928
- app.compile();
7929
- const classes = new Set(extraCSSClasses ?? []);
7930
- for (const Comp of app.comps.byId.values()) {
7931
- for (const key in Comp.views) {
7932
- const view = Comp.views[key];
7933
- for (const name of view.ctx.classes)
7934
- classes.add(name);
7935
- }
7936
- }
7937
- return await compileClasses(Array.from(classes));
7938
- }
7939
- // tools/core/lint-check.js
7940
- var ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED";
7941
- var ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED";
7942
- var RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP";
7943
- var UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER";
7944
- var UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME";
7945
- var INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED";
7946
- var INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED";
7947
- var INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED";
7948
- var INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD";
7949
- var INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER";
7950
- var FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED";
7951
- var COMPUTED_VAL_NOT_DEFINED = "COMPUTED_VAL_NOT_DEFINED";
7952
- var COMPUTED_NOT_REFERENCED = "COMPUTED_NOT_REFERENCED";
7953
- var UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME";
7954
- var UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME";
7955
- var LEVEL_WARN = "warn";
7956
- var LEVEL_ERROR = "error";
7957
- var LEVEL_HINT = "hint";
7958
- function checkComponent(Comp, lx = new LintContext) {
7959
- const referencedAlters = new Set;
7960
- const referencedInputs = new Set;
7961
- const referencedComputed = new Set;
7962
- checkEventHandlersHaveImpls(lx, Comp, referencedInputs);
7963
- checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed);
7964
- for (const name in Comp.views) {
7965
- checkView(lx, Comp.views[name], Comp, referencedAlters, referencedComputed);
7966
- }
7967
- checkUnreferencedAlterHandlers(lx, Comp, referencedAlters);
7968
- checkUnreferencedInputHandlers(lx, Comp, referencedInputs);
7969
- checkUnreferencedComputed(lx, Comp, referencedComputed);
7970
- return lx;
7971
- }
7972
- function checkView(lx, view, Comp, referencedAlters, referencedComputed) {
7973
- checkRenderItInLoop(lx, view);
7974
- checkEventModifiers(lx, view);
7975
- checkKnownHandlerNames(lx, view, Comp, referencedAlters, referencedComputed);
7976
- }
7977
- function checkRenderItInLoop(lx, view) {
7978
- const { nodes } = view.ctx;
7979
- for (let i = 0;i < nodes.length; i++) {
7980
- const node = nodes[i];
7981
- if (node.constructor.name === "RenderItNode") {
7982
- const next = nodes[i + 1];
7983
- const nextName = next?.constructor.name;
7984
- if (nextName !== "EachNode" && nextName !== "RenderEachNode") {
7985
- lx.error(RENDER_IT_OUTSIDE_OF_LOOP, { node });
7986
- }
7987
- }
7988
- }
7989
- }
7990
- var NO_WRAPPERS = {};
7991
- function checkEventModifiers(lx, view) {
7992
- for (const event of view.ctx.events) {
7993
- for (const handler of event.handlers) {
7994
- const { name, modifiers } = handler;
7995
- const modWrappers = MOD_WRAPPERS_BY_EVENT[name] ?? NO_WRAPPERS;
7996
- for (const modifier of modifiers) {
7997
- if (modWrappers[modifier] === undefined) {
7998
- lx.warn(UNKNOWN_EVENT_MODIFIER, { name, modifier, handler, event });
7999
- }
8000
- }
8001
- }
8002
- }
8003
- }
8004
- var KNOWN_HANDLER_NAMES = new Set([
8005
- "value",
8006
- "valueAsInt",
8007
- "valueAsFloat",
8008
- "target",
8009
- "event",
8010
- "isAlt",
8011
- "isShift",
8012
- "isCtrl",
8013
- "isCmd",
8014
- "key",
8015
- "keyCode",
8016
- "isUpKey",
8017
- "isDownKey",
8018
- "isSend",
8019
- "isCancel",
8020
- "isTabKey",
8021
- "ctx",
8022
- "dragInfo"
8023
- ]);
8024
- function isKnownHandlerName(name) {
8025
- return KNOWN_HANDLER_NAMES.has(name);
8026
- }
8027
- function checkKnownHandlerNames(lx, view, Comp, referencedAlters, referencedComputed) {
8028
- const { computed, scope, alter, Class } = Comp;
8029
- const { prototype: proto } = Class;
8030
- const { fields } = Class.getMetaClass();
8031
- for (const event of view.ctx.events) {
8032
- for (const handler of event.handlers) {
8033
- const { args } = handler.handlerCall;
8034
- for (let i = 0;i < args.length; i++) {
8035
- const arg = args[i];
8036
- checkConsistentAttrVal(lx, arg, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8037
- }
8038
- }
8039
- }
8040
- }
8041
- function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
8042
- const { input, views, Class } = Comp;
8043
- const { prototype: proto } = Class;
8044
- for (const viewName in views) {
8045
- const view = views[viewName];
8046
- for (const event of view.ctx.events) {
8047
- for (const handler of event.handlers) {
8048
- const { handlerVal } = handler.handlerCall;
8049
- const hvName = handlerVal?.constructor.name;
8050
- if (hvName === "InputHandlerNameVal") {
8051
- referencedInputs?.add(handlerVal.name);
8052
- if (input[handlerVal.name] === undefined) {
8053
- lx.warn(INPUT_HANDLER_NOT_IMPLEMENTED, {
8054
- name: handlerVal.name,
8055
- handler,
8056
- event
8057
- });
8058
- if (proto[handlerVal.name] !== undefined) {
8059
- lx.hint(INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER, {
8060
- name: handlerVal.name,
8061
- handler,
8062
- event
8063
- });
8064
- }
8065
- }
8066
- } else if (hvName === "RawFieldVal") {
8067
- referencedInputs?.add(handlerVal.name);
8068
- if (proto[handlerVal.name] === undefined) {
8069
- lx.warn(INPUT_HANDLER_METHOD_NOT_IMPLEMENTED, {
8070
- name: handlerVal.name,
8071
- handler,
8072
- event
8073
- });
8074
- if (input[handlerVal.name] !== undefined) {
8075
- lx.hint(INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD, {
8076
- name: handlerVal.name,
8077
- handler,
8078
- event
8079
- });
8080
- }
8081
- }
8082
- }
8083
- }
8084
- }
8085
- }
8086
- }
8087
- function checkConsistentAttrVal(lx, val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed) {
8088
- const valName = val?.constructor.name;
8089
- if (valName === "FieldVal" || valName === "RawFieldVal") {
8090
- const { name } = val;
8091
- if (fields[name] === undefined && proto[name] === undefined) {
8092
- lx.error(FIELD_VAL_NOT_DEFINED, { val, name });
8093
- }
8094
- } else if (valName === "ComputedVal") {
8095
- const { name } = val;
8096
- referencedComputed?.add(name);
8097
- if (computed[name] === undefined) {
8098
- lx.error(COMPUTED_VAL_NOT_DEFINED, { val, name });
8099
- }
8100
- } else if (valName === "SeqAccessVal") {
8101
- checkConsistentAttrVal(lx, val.seqVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8102
- checkConsistentAttrVal(lx, val.keyVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8103
- } else if (valName === "RequestVal") {
8104
- if (scope.lookupRequest(val.name) === null) {
8105
- lx.warn(UNKNOWN_REQUEST_NAME, { name: val.name });
8106
- }
8107
- } else if (valName === "TypeVal") {
8108
- if (scope.lookupComponent(val.name) === null) {
8109
- lx.warn(UNKNOWN_COMPONENT_NAME, { name: val.name });
8110
- }
8111
- } else if (valName === "NameVal") {
8112
- if (!isKnownHandlerName(val.name)) {
8113
- lx.warn(UNKNOWN_HANDLER_ARG_NAME, { name: val.name });
8114
- }
8115
- } else if (valName === "StrTplVal") {
8116
- for (const subVal of val.vals) {
8117
- checkConsistentAttrVal(lx, subVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8118
- }
8119
- } else if (valName === "AlterHandlerNameVal") {
8120
- referencedAlters?.add(val.name);
8121
- if (alter[val.name] === undefined) {
8122
- lx.warn(ALT_HANDLER_NOT_DEFINED, { name: val.name });
8123
- }
8124
- } else if (valName !== "ConstVal" && valName !== "BindVal") {
8125
- console.log(val);
8126
- }
8127
- }
8128
- function checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed) {
8129
- const { computed, scope, views, alter, Class } = Comp;
8130
- const { prototype: proto } = Class;
8131
- const { fields } = Class.getMetaClass();
8132
- for (const viewName in views) {
8133
- const view = views[viewName];
8134
- for (const attr of view.ctx.attrs) {
8135
- const { attrs, wrapperAttrs, textChild } = attr;
8136
- if (attrs?.constructor.name === "DynAttrs") {
8137
- for (const attr2 of attrs.items) {
8138
- if (attr2?.constructor.name === "Attr") {
8139
- checkConsistentAttrVal(lx, attr2.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8140
- }
8141
- }
8102
+ renderEach(stack, iterInfo, nodeId, viewName) {
8103
+ const { seq, filter, loopWith } = iterInfo.eval(stack);
8104
+ const r = [];
8105
+ const iterData = loopWith.call(stack.it, seq);
8106
+ this.getSeqInfo(seq)(seq, (key, value, attrName) => {
8107
+ if (filter.call(stack.it, key, value, iterData)) {
8108
+ const newStack = stack.enter(value, { key }, true);
8109
+ const dom = this.renderIt(newStack, nodeId, key, viewName);
8110
+ this.pushEachEntry(r, nodeId, attrName, key, dom);
8142
8111
  }
8143
- if (wrapperAttrs !== null) {
8144
- for (const w of wrapperAttrs) {
8145
- if (w.name === "each") {
8146
- if (w.whenVal)
8147
- checkConsistentAttrVal(lx, w.whenVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8148
- if (w.enrichWithVal)
8149
- checkConsistentAttrVal(lx, w.enrichWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8150
- if (w.loopWithVal)
8151
- checkConsistentAttrVal(lx, w.loopWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8152
- } else if (w.name !== "scope") {
8153
- checkConsistentAttrVal(lx, w.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8154
- }
8112
+ });
8113
+ return r;
8114
+ }
8115
+ renderEachWhen(stack, iterInfo, view, nid) {
8116
+ const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
8117
+ const r = [];
8118
+ const iterData = loopWith.call(stack.it, seq);
8119
+ const it = stack.it;
8120
+ this.getSeqInfo(seq)(seq, (key, value, attrName) => {
8121
+ if (filter.call(it, key, value, iterData)) {
8122
+ const bindings = { key, value };
8123
+ const cacheKey = `${nid}-${key}`;
8124
+ let cachedNode;
8125
+ if (enricher) {
8126
+ enricher.call(it, bindings, key, value, iterData);
8127
+ cachedNode = this.cache.get2(it, value, cacheKey);
8128
+ } else
8129
+ cachedNode = this.cache.get(value, cacheKey);
8130
+ if (cachedNode) {
8131
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
8132
+ return;
8155
8133
  }
8134
+ const newStack = stack.enter(value, bindings, false);
8135
+ const dom = this.renderView(view, newStack);
8136
+ this.pushEachEntry(r, nid, attrName, key, dom);
8137
+ if (enricher)
8138
+ this.cache.set2(it, value, cacheKey, dom);
8139
+ else
8140
+ this.cache.set(value, cacheKey, dom);
8156
8141
  }
8157
- if (textChild) {
8158
- checkConsistentAttrVal(lx, textChild, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8159
- }
8160
- }
8161
- for (const node of view.ctx.nodes) {
8162
- if (node.val) {
8163
- checkConsistentAttrVal(lx, node.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
8142
+ });
8143
+ return r;
8144
+ }
8145
+ renderView(view, stack) {
8146
+ let n = stack.binds[1];
8147
+ while (n !== null) {
8148
+ const b = n[0];
8149
+ if (b.isFrame) {
8150
+ if (stack.it !== b.it)
8151
+ break;
8152
+ console.error("recursion detected", stack.it, b.it);
8153
+ return new VComment("RECURSION AVOIDED");
8164
8154
  }
8155
+ n = n[1];
8165
8156
  }
8157
+ return view.render(stack, this);
8158
+ }
8159
+ _renderMetadata(info) {
8160
+ return new VComment(`§${JSON.stringify(info)}§`);
8166
8161
  }
8167
8162
  }
8168
- function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
8169
- for (const name in Comp.alter) {
8170
- if (!referencedAlters.has(name)) {
8171
- lx.hint(ALT_HANDLER_NOT_REFERENCED, { name });
8163
+ var imIndexedIter = (seq, visit) => {
8164
+ let i = 0;
8165
+ for (const v of seq)
8166
+ visit(i++, v, "si");
8167
+ };
8168
+ var imKeyedIter = (seq, visit) => {
8169
+ for (const [k, v] of seq.toSeq().entries())
8170
+ visit(k, v, "sk");
8171
+ };
8172
+ var unkIter = () => {};
8173
+ var seqInfoByClass = new Map;
8174
+
8175
+ // extra/klist.js
8176
+ class KList {
8177
+ constructor(items = Map2(), order = List()) {
8178
+ this.items = items;
8179
+ this.order = order;
8180
+ this.$ = 0;
8181
+ }
8182
+ _clonish(items, order) {
8183
+ return new KList(items, order, this.$);
8184
+ }
8185
+ toJS() {
8186
+ return this.order.toArray().map((k) => this.items.get(k));
8187
+ }
8188
+ set(k, v) {
8189
+ const newOrder = this.items.has(k) ? this.order : this.order.push(k);
8190
+ return this._clonish(this.items.set(k, v), newOrder, this.$);
8191
+ }
8192
+ get(k, dval = null) {
8193
+ return this.items.get(k, dval);
8194
+ }
8195
+ _nextFreeKey() {
8196
+ let cur = this.$;
8197
+ while (true) {
8198
+ const key = `§${cur}§`;
8199
+ if (!this.items.has(key)) {
8200
+ return [key, cur];
8201
+ }
8202
+ cur += 1;
8172
8203
  }
8173
8204
  }
8174
- }
8175
- function checkUnreferencedInputHandlers(lx, Comp, referencedInputs) {
8176
- for (const name in Comp.input) {
8177
- if (!referencedInputs.has(name)) {
8178
- lx.hint(INPUT_HANDLER_NOT_REFERENCED, { name });
8205
+ push(v) {
8206
+ const [key, next$] = this._nextFreeKey();
8207
+ const newKList = this.set(key, v);
8208
+ newKList.$ = next$;
8209
+ return newKList;
8210
+ }
8211
+ get size() {
8212
+ return this.items.size;
8213
+ }
8214
+ delete(k) {
8215
+ if (this.items.has(k)) {
8216
+ const newOrder = this.order.delete(this.order.indexOf(k));
8217
+ return this._clonish(this.items.delete(k), newOrder);
8179
8218
  }
8219
+ return this;
8180
8220
  }
8181
- }
8182
- function checkUnreferencedComputed(lx, Comp, referencedComputed) {
8183
- for (const name in Comp.computed) {
8184
- if (!referencedComputed.has(name)) {
8185
- lx.hint(COMPUTED_NOT_REFERENCED, { name });
8221
+ moveKeyBeforeKey(k1, k2) {
8222
+ const { order } = this;
8223
+ return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 0);
8224
+ }
8225
+ moveKeyAfterKey(k1, k2) {
8226
+ const { order } = this;
8227
+ return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 1);
8228
+ }
8229
+ moveKeyIndexToIndex(source, target, offset) {
8230
+ if (source === -1 || target === -1 || source === target) {
8231
+ return this;
8186
8232
  }
8233
+ const { order } = this;
8234
+ const newPos = target + offset;
8235
+ const oldPos = newPos < source ? source + 1 : source;
8236
+ const newOrder = order.insert(newPos, order.get(source)).delete(oldPos);
8237
+ return this._clonish(this.items, newOrder);
8187
8238
  }
8188
8239
  }
8240
+ var klistCoercer = (_) => null;
8189
8241
 
8190
- class LintContext {
8191
- constructor() {
8192
- this.reports = [];
8193
- }
8194
- error(id, info) {
8195
- this.report(id, info, LEVEL_ERROR);
8242
+ class CheckTypeKList {
8243
+ isValid(v) {
8244
+ return v instanceof KList;
8196
8245
  }
8197
- warn(id, info) {
8198
- this.report(id, info, LEVEL_WARN);
8246
+ getMessage(_v) {
8247
+ return "KList expected";
8199
8248
  }
8200
- hint(id, info) {
8201
- this.report(id, info, LEVEL_HINT);
8249
+ }
8250
+ var CHECK_TYPE_KLIST = new CheckTypeKList;
8251
+
8252
+ class FieldKList extends Field {
8253
+ constructor(name, defaultValue = new KList) {
8254
+ super("KList", name, CHECK_TYPE_KLIST, klistCoercer, defaultValue);
8202
8255
  }
8203
- report(id, info = {}, level = LEVEL_ERROR) {
8204
- this.reports.push({ id, info, level });
8256
+ extendProtoForType(proto, uname) {
8257
+ extendProtoForKeyed(proto, this.name, uname);
8258
+ const { name } = this;
8259
+ extendProtoForKeyed(proto, name, uname);
8260
+ proto[`pushIn${uname}`] = function(v) {
8261
+ return this.set(name, this.get(name).push(v));
8262
+ };
8205
8263
  }
8206
8264
  }
8265
+ fieldsByClass.set(KList, FieldKList);
8266
+ seqInfoByClass.set(KList, (seq, visit) => {
8267
+ for (const k of seq.order)
8268
+ visit(k, seq.items.get(k), "data-sk");
8269
+ });
8270
+ // index.js
8271
+ var css = String.raw;
8272
+ var html = String.raw;
8273
+ var macro = (defaults, rawView) => new Macro(defaults, rawView);
8274
+ function tutuca(nodeOrSelector) {
8275
+ const rootNode = typeof nodeOrSelector === "string" ? document.querySelector(nodeOrSelector) : nodeOrSelector;
8276
+ const comps = new Components;
8277
+ const renderer = new Renderer(comps);
8278
+ return new App(rootNode, comps, renderer, ParseContext);
8279
+ }
8207
8280
 
8208
- class LintParseContext extends ParseContext {
8209
- constructor(DOMParser, Text, Comment) {
8210
- super(DOMParser, Text, Comment);
8211
- this.attrs = [];
8212
- }
8213
- onAttributes(attrs, wrapperAttrs, textChild) {
8214
- this.attrs.push({ attrs, wrapperAttrs, textChild });
8281
+ // extra.js
8282
+ async function compileClassesToStyle(app, compileClasses, styleId = "margaui-css") {
8283
+ const t1 = performance.now();
8284
+ const css2 = await compileClassesToStyleText(app, compileClasses);
8285
+ const t2 = performance.now();
8286
+ injectCss(styleId, css2);
8287
+ return t2 - t1;
8288
+ }
8289
+ async function compileClassesToStyleText(app, compileClasses, extraCSSClasses, Ctx = ParseCtxClassSetCollector) {
8290
+ app.ParseContext = Ctx;
8291
+ app.compile();
8292
+ const classes = new Set(extraCSSClasses ?? []);
8293
+ for (const Comp of app.comps.byId.values()) {
8294
+ for (const key in Comp.views) {
8295
+ const view = Comp.views[key];
8296
+ for (const name of view.ctx.classes)
8297
+ classes.add(name);
8298
+ }
8215
8299
  }
8300
+ return await compileClasses(Array.from(classes));
8216
8301
  }
8217
8302
  // tools/core/results.js
8218
8303
  class ComponentDocs {
@@ -8407,47 +8492,41 @@ function docComponents(normalized, { name = null } = {}) {
8407
8492
  const picked = name === null ? comps : comps.filter((c) => c.name === name);
8408
8493
  return new ComponentDocs({ items: getComponentsDocs(picked) });
8409
8494
  }
8410
- // tools/format/lint.js
8411
- function lintIdToMessage(id, info) {
8412
- switch (id) {
8413
- case "RENDER_IT_OUTSIDE_OF_LOOP":
8414
- return "render-it used outside of a loop";
8415
- case "UNKNOWN_EVENT_MODIFIER":
8416
- return `Unknown modifier '${info.modifier}' on '${info.name}' event`;
8417
- case "UNKNOWN_HANDLER_ARG_NAME":
8418
- return `Unknown handler argument '${info.name}'`;
8419
- case "INPUT_HANDLER_NOT_IMPLEMENTED":
8420
- return `Input handler '${info.name}' is not implemented`;
8421
- case "INPUT_HANDLER_NOT_REFERENCED":
8422
- return `Input handler '${info.name}' is defined but not referenced`;
8423
- case "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED":
8424
- return `Method '.${info.name}' is not implemented`;
8425
- case "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD":
8426
- return `'${info.name}' exists as input handler — use without '.' prefix`;
8427
- case "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER":
8428
- return `'${info.name}' exists as method — use with '.' prefix`;
8429
- case "FIELD_VAL_NOT_DEFINED":
8430
- return `Field '.${info.name}' is not defined`;
8431
- case "COMPUTED_VAL_NOT_DEFINED":
8432
- return `Computed property '$${info.name}' is not defined`;
8433
- case "COMPUTED_NOT_REFERENCED":
8434
- return `Computed property '$${info.name}' is defined but not referenced`;
8435
- case "UNKNOWN_REQUEST_NAME":
8436
- return `Unknown request '!${info.name}'`;
8437
- case "UNKNOWN_COMPONENT_NAME":
8438
- return `Unknown component '${info.name}'`;
8439
- case "ALT_HANDLER_NOT_DEFINED":
8440
- return `Alter handler '${info.name}' is not defined`;
8441
- case "ALT_HANDLER_NOT_REFERENCED":
8442
- return `Alter handler '${info.name}' is defined but not referenced`;
8443
- case "LINT_ERROR":
8444
- return info.message;
8445
- default:
8446
- return id;
8495
+
8496
+ // dev.js
8497
+ function check(app) {
8498
+ const counts = { error: 0, warn: 0, hint: 0 };
8499
+ for (const Comp of app.comps.byId.values()) {
8500
+ const shadowViews = {};
8501
+ for (const name in Comp.views) {
8502
+ const ctx = new LintParseContext;
8503
+ ANode.parse(Comp.views[name].rawView, ctx);
8504
+ ctx.compile(Comp.scope);
8505
+ shadowViews[name] = { name, ctx };
8506
+ }
8507
+ const shadowComp = Object.create(Comp);
8508
+ shadowComp.views = shadowViews;
8509
+ const { reports } = checkComponent(shadowComp);
8510
+ if (reports.length === 0)
8511
+ continue;
8512
+ console.group(Comp.name);
8513
+ for (const r of reports) {
8514
+ counts[r.level]++;
8515
+ const line = `[${r.level}] ${lintIdToMessage(r.id, r.info)}`;
8516
+ if (r.level === "error")
8517
+ console.error(line);
8518
+ else if (r.level === "warn")
8519
+ console.warn(line);
8520
+ else
8521
+ console.log(line);
8522
+ }
8523
+ console.groupEnd();
8447
8524
  }
8525
+ const total = counts.error + counts.warn + counts.hint;
8526
+ console.log(total === 0 ? "check: no issues" : `check: ${counts.error} error, ${counts.warn} warn, ${counts.hint} hint`);
8527
+ return counts;
8448
8528
  }
8449
8529
 
8450
- // dev.js
8451
8530
  class LintClassCollectorCtx extends ParseCtxClassSetCollector {
8452
8531
  constructor(...args) {
8453
8532
  super(...args);
@@ -8518,6 +8597,7 @@ export {
8518
8597
  compileClassesToStyle,
8519
8598
  checkView,
8520
8599
  checkComponent,
8600
+ check,
8521
8601
  UNKNOWN_REQUEST_NAME,
8522
8602
  UNKNOWN_HANDLER_ARG_NAME,
8523
8603
  UNKNOWN_EVENT_MODIFIER,