tutuca 0.9.22 → 0.9.24

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,99 +1552,469 @@ 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
+ if (node.constructor.name === "RenderEachNode") {
1815
+ const iter = node.iterInfo;
1816
+ if (iter.whenVal)
1817
+ checkConsistentAttrVal(lx, iter.whenVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1818
+ if (iter.loopWithVal)
1819
+ checkConsistentAttrVal(lx, iter.loopWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
1820
+ }
1821
+ }
1822
+ });
1614
1823
  }
1615
1824
  }
1616
-
1617
- class NullComputedCache {
1618
- getKey(v, _key, fn) {
1619
- return fn.call(v);
1825
+ function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
1826
+ for (const name in Comp.alter) {
1827
+ if (!referencedAlters.has(name)) {
1828
+ lx.hint(ALT_HANDLER_NOT_REFERENCED, { name });
1829
+ }
1620
1830
  }
1621
1831
  }
1622
-
1623
- class WeakMapComputedCache {
1624
- constructor() {
1625
- this.map = new WeakMap;
1832
+ function checkUnreferencedInputHandlers(lx, Comp, referencedInputs) {
1833
+ for (const name in Comp.input) {
1834
+ if (!referencedInputs.has(name)) {
1835
+ lx.hint(INPUT_HANDLER_NOT_REFERENCED, { name });
1836
+ }
1626
1837
  }
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;
1838
+ }
1839
+ function checkUnreferencedComputed(lx, Comp, referencedComputed) {
1840
+ for (const name in Comp.computed) {
1841
+ if (!referencedComputed.has(name)) {
1842
+ lx.hint(COMPUTED_NOT_REFERENCED, { name });
1636
1843
  }
1637
- const newValue = fn.call(v) ?? null;
1638
- this.map.set(v, { [key]: newValue });
1639
- return newValue;
1640
1844
  }
1641
1845
  }
1642
1846
 
1643
- // src/components.js
1644
- class Components {
1847
+ class LintContext {
1645
1848
  constructor() {
1646
- this.getComponentSymbol = Symbol("getComponent");
1647
- this.byId = new Map;
1849
+ this.reports = [];
1850
+ this.frame = {};
1851
+ }
1852
+ push(patch, fn) {
1853
+ const prev = this.frame;
1854
+ this.frame = { ...prev, ...patch };
1855
+ try {
1856
+ return fn();
1857
+ } finally {
1858
+ this.frame = prev;
1859
+ }
1860
+ }
1861
+ error(id, info) {
1862
+ this.report(id, info, LEVEL_ERROR);
1863
+ }
1864
+ warn(id, info) {
1865
+ this.report(id, info, LEVEL_WARN);
1866
+ }
1867
+ hint(id, info) {
1868
+ this.report(id, info, LEVEL_HINT);
1869
+ }
1870
+ report(id, info = {}, level = LEVEL_ERROR) {
1871
+ this.reports.push({ id, info, level, context: { ...this.frame } });
1872
+ }
1873
+ }
1874
+
1875
+ class LintParseContext extends ParseContext {
1876
+ constructor(DOMParser, Text, Comment) {
1877
+ super(DOMParser, Text, Comment);
1878
+ this.attrs = [];
1879
+ }
1880
+ onAttributes(attrs, wrapperAttrs, textChild) {
1881
+ this.attrs.push({ attrs, wrapperAttrs, textChild });
1882
+ }
1883
+ }
1884
+
1885
+ // tools/format/lint.js
1886
+ function lintIdToMessage(id, info) {
1887
+ switch (id) {
1888
+ case "RENDER_IT_OUTSIDE_OF_LOOP":
1889
+ return "render-it used outside of a loop";
1890
+ case "UNKNOWN_EVENT_MODIFIER":
1891
+ return `Unknown modifier '${info.modifier}' on '${info.name}' event`;
1892
+ case "UNKNOWN_HANDLER_ARG_NAME":
1893
+ return `Unknown handler argument '${info.name}'`;
1894
+ case "INPUT_HANDLER_NOT_IMPLEMENTED":
1895
+ return `Input handler '${info.name}' is not implemented`;
1896
+ case "INPUT_HANDLER_NOT_REFERENCED":
1897
+ return `Input handler '${info.name}' is defined but not referenced`;
1898
+ case "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED":
1899
+ return `Method '.${info.name}' is not implemented`;
1900
+ case "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD":
1901
+ return `'${info.name}' exists as input handler — use without '.' prefix`;
1902
+ case "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER":
1903
+ return `'${info.name}' exists as method — use with '.' prefix`;
1904
+ case "FIELD_VAL_NOT_DEFINED":
1905
+ return `Field '.${info.name}' is not defined`;
1906
+ case "COMPUTED_VAL_NOT_DEFINED":
1907
+ return `Computed property '$${info.name}' is not defined`;
1908
+ case "COMPUTED_NOT_REFERENCED":
1909
+ return `Computed property '$${info.name}' is defined but not referenced`;
1910
+ case "UNKNOWN_REQUEST_NAME":
1911
+ return `Unknown request '!${info.name}'`;
1912
+ case "UNKNOWN_COMPONENT_NAME":
1913
+ return `Unknown component '${info.name}'`;
1914
+ case "ALT_HANDLER_NOT_DEFINED":
1915
+ return `Alter handler '${info.name}' is not defined`;
1916
+ case "ALT_HANDLER_NOT_REFERENCED":
1917
+ return `Alter handler '${info.name}' is defined but not referenced`;
1918
+ case "LINT_ERROR":
1919
+ return info.message;
1920
+ default:
1921
+ return id;
1922
+ }
1923
+ }
1924
+
1925
+ // src/cache.js
1926
+ class NullDomCache {
1927
+ get(_k, _cacheKey) {}
1928
+ set(_k, _cacheKey, _v) {}
1929
+ get2(_k1, _k2, _cacheKey) {}
1930
+ set2(_k1, _k2, _cacheKey, _v) {}
1931
+ evict() {
1932
+ return { hit: 0, miss: 0, badKey: 0 };
1933
+ }
1934
+ }
1935
+
1936
+ class WeakMapDomCache {
1937
+ constructor() {
1938
+ this.hit = this.miss = this.badKey = 0;
1939
+ this.map = new WeakMap;
1940
+ }
1941
+ _returnValue(r) {
1942
+ if (r === undefined)
1943
+ this.miss += 1;
1944
+ else
1945
+ this.hit += 1;
1946
+ return r;
1947
+ }
1948
+ get(k, cacheKey) {
1949
+ return this._returnValue(this.map.get(k)?.[cacheKey]);
1950
+ }
1951
+ set(k, cacheKey, v) {
1952
+ const cur = this.map.get(k);
1953
+ if (cur)
1954
+ cur[cacheKey] = v;
1955
+ else if (typeof k === "object")
1956
+ this.map.set(k, { [cacheKey]: v });
1957
+ else
1958
+ this.badKey += 1;
1959
+ }
1960
+ get2(k1, k2, cacheKey) {
1961
+ return this._returnValue(this.map.get(k1)?.get?.(k2)?.[cacheKey]);
1962
+ }
1963
+ set2(k1, k2, cacheKey, v) {
1964
+ const cur1 = this.map.get(k1);
1965
+ if (cur1) {
1966
+ const cur = cur1.get(k2);
1967
+ if (cur)
1968
+ cur[cacheKey] = v;
1969
+ else
1970
+ cur1.set(k2, { [cacheKey]: v });
1971
+ } else if (typeof k1 === "object" && typeof k2 === "object") {
1972
+ const cur = new WeakMap;
1973
+ cur.set(k2, { [cacheKey]: v });
1974
+ this.map.set(k1, cur);
1975
+ } else {
1976
+ this.badKey += 1;
1977
+ }
1978
+ }
1979
+ evict() {
1980
+ const { hit, miss, badKey } = this;
1981
+ this.hit = this.miss = this.badKey = 0;
1982
+ this.map = new WeakMap;
1983
+ return { hit, miss, badKey };
1984
+ }
1985
+ }
1986
+
1987
+ class NullComputedCache {
1988
+ getKey(v, _key, fn) {
1989
+ return fn.call(v);
1990
+ }
1991
+ }
1992
+
1993
+ class WeakMapComputedCache {
1994
+ constructor() {
1995
+ this.map = new WeakMap;
1996
+ }
1997
+ getKey(v, key, fn) {
1998
+ const cur = this.map.get(v);
1999
+ if (cur) {
2000
+ const curValue = cur[key];
2001
+ if (curValue !== undefined)
2002
+ return curValue;
2003
+ const newValue2 = fn.call(v) ?? null;
2004
+ cur[key] = newValue2;
2005
+ return newValue2;
2006
+ }
2007
+ const newValue = fn.call(v) ?? null;
2008
+ this.map.set(v, { [key]: newValue });
2009
+ return newValue;
2010
+ }
2011
+ }
2012
+
2013
+ // src/components.js
2014
+ class Components {
2015
+ constructor() {
2016
+ this.getComponentSymbol = Symbol("getComponent");
2017
+ this.byId = new Map;
1648
2018
  this.computedCache = new WeakMapComputedCache;
1649
2019
  }
1650
2020
  setNullComputedCache() {
@@ -7736,483 +8106,205 @@ class Renderer {
7736
8106
  pushEachEntry(r, nid, attrName, key, dom) {
7737
8107
  r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
7738
8108
  }
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
- }
8109
+ renderEach(stack, iterInfo, nodeId, viewName) {
8110
+ const { seq, filter, loopWith } = iterInfo.eval(stack);
8111
+ const r = [];
8112
+ const iterData = loopWith.call(stack.it, seq);
8113
+ this.getSeqInfo(seq)(seq, (key, value, attrName) => {
8114
+ if (filter.call(stack.it, key, value, iterData)) {
8115
+ const newStack = stack.enter(value, { key }, true);
8116
+ const dom = this.renderIt(newStack, nodeId, key, viewName);
8117
+ this.pushEachEntry(r, nodeId, attrName, key, dom);
8142
8118
  }
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
- }
8119
+ });
8120
+ return r;
8121
+ }
8122
+ renderEachWhen(stack, iterInfo, view, nid) {
8123
+ const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
8124
+ const r = [];
8125
+ const iterData = loopWith.call(stack.it, seq);
8126
+ const it = stack.it;
8127
+ this.getSeqInfo(seq)(seq, (key, value, attrName) => {
8128
+ if (filter.call(it, key, value, iterData)) {
8129
+ const bindings = { key, value };
8130
+ const cacheKey = `${nid}-${key}`;
8131
+ let cachedNode;
8132
+ if (enricher) {
8133
+ enricher.call(it, bindings, key, value, iterData);
8134
+ cachedNode = this.cache.get2(it, value, cacheKey);
8135
+ } else
8136
+ cachedNode = this.cache.get(value, cacheKey);
8137
+ if (cachedNode) {
8138
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
8139
+ return;
8155
8140
  }
8141
+ const newStack = stack.enter(value, bindings, false);
8142
+ const dom = this.renderView(view, newStack);
8143
+ this.pushEachEntry(r, nid, attrName, key, dom);
8144
+ if (enricher)
8145
+ this.cache.set2(it, value, cacheKey, dom);
8146
+ else
8147
+ this.cache.set(value, cacheKey, dom);
8156
8148
  }
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);
8149
+ });
8150
+ return r;
8151
+ }
8152
+ renderView(view, stack) {
8153
+ let n = stack.binds[1];
8154
+ while (n !== null) {
8155
+ const b = n[0];
8156
+ if (b.isFrame) {
8157
+ if (stack.it !== b.it)
8158
+ break;
8159
+ console.error("recursion detected", stack.it, b.it);
8160
+ return new VComment("RECURSION AVOIDED");
8164
8161
  }
8162
+ n = n[1];
8165
8163
  }
8164
+ return view.render(stack, this);
8165
+ }
8166
+ _renderMetadata(info) {
8167
+ return new VComment(`§${JSON.stringify(info)}§`);
8166
8168
  }
8167
8169
  }
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 });
8170
+ var imIndexedIter = (seq, visit) => {
8171
+ let i = 0;
8172
+ for (const v of seq)
8173
+ visit(i++, v, "si");
8174
+ };
8175
+ var imKeyedIter = (seq, visit) => {
8176
+ for (const [k, v] of seq.toSeq().entries())
8177
+ visit(k, v, "sk");
8178
+ };
8179
+ var unkIter = () => {};
8180
+ var seqInfoByClass = new Map;
8181
+
8182
+ // extra/klist.js
8183
+ class KList {
8184
+ constructor(items = Map2(), order = List()) {
8185
+ this.items = items;
8186
+ this.order = order;
8187
+ this.$ = 0;
8188
+ }
8189
+ _clonish(items, order) {
8190
+ return new KList(items, order, this.$);
8191
+ }
8192
+ toJS() {
8193
+ return this.order.toArray().map((k) => this.items.get(k));
8194
+ }
8195
+ set(k, v) {
8196
+ const newOrder = this.items.has(k) ? this.order : this.order.push(k);
8197
+ return this._clonish(this.items.set(k, v), newOrder, this.$);
8198
+ }
8199
+ get(k, dval = null) {
8200
+ return this.items.get(k, dval);
8201
+ }
8202
+ _nextFreeKey() {
8203
+ let cur = this.$;
8204
+ while (true) {
8205
+ const key = `§${cur}§`;
8206
+ if (!this.items.has(key)) {
8207
+ return [key, cur];
8208
+ }
8209
+ cur += 1;
8172
8210
  }
8173
8211
  }
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 });
8212
+ push(v) {
8213
+ const [key, next$] = this._nextFreeKey();
8214
+ const newKList = this.set(key, v);
8215
+ newKList.$ = next$;
8216
+ return newKList;
8217
+ }
8218
+ get size() {
8219
+ return this.items.size;
8220
+ }
8221
+ delete(k) {
8222
+ if (this.items.has(k)) {
8223
+ const newOrder = this.order.delete(this.order.indexOf(k));
8224
+ return this._clonish(this.items.delete(k), newOrder);
8179
8225
  }
8226
+ return this;
8180
8227
  }
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 });
8228
+ moveKeyBeforeKey(k1, k2) {
8229
+ const { order } = this;
8230
+ return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 0);
8231
+ }
8232
+ moveKeyAfterKey(k1, k2) {
8233
+ const { order } = this;
8234
+ return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 1);
8235
+ }
8236
+ moveKeyIndexToIndex(source, target, offset) {
8237
+ if (source === -1 || target === -1 || source === target) {
8238
+ return this;
8186
8239
  }
8240
+ const { order } = this;
8241
+ const newPos = target + offset;
8242
+ const oldPos = newPos < source ? source + 1 : source;
8243
+ const newOrder = order.insert(newPos, order.get(source)).delete(oldPos);
8244
+ return this._clonish(this.items, newOrder);
8187
8245
  }
8188
8246
  }
8247
+ var klistCoercer = (_) => null;
8189
8248
 
8190
- class LintContext {
8191
- constructor() {
8192
- this.reports = [];
8193
- }
8194
- error(id, info) {
8195
- this.report(id, info, LEVEL_ERROR);
8249
+ class CheckTypeKList {
8250
+ isValid(v) {
8251
+ return v instanceof KList;
8196
8252
  }
8197
- warn(id, info) {
8198
- this.report(id, info, LEVEL_WARN);
8253
+ getMessage(_v) {
8254
+ return "KList expected";
8199
8255
  }
8200
- hint(id, info) {
8201
- this.report(id, info, LEVEL_HINT);
8256
+ }
8257
+ var CHECK_TYPE_KLIST = new CheckTypeKList;
8258
+
8259
+ class FieldKList extends Field {
8260
+ constructor(name, defaultValue = new KList) {
8261
+ super("KList", name, CHECK_TYPE_KLIST, klistCoercer, defaultValue);
8202
8262
  }
8203
- report(id, info = {}, level = LEVEL_ERROR) {
8204
- this.reports.push({ id, info, level });
8263
+ extendProtoForType(proto, uname) {
8264
+ extendProtoForKeyed(proto, this.name, uname);
8265
+ const { name } = this;
8266
+ extendProtoForKeyed(proto, name, uname);
8267
+ proto[`pushIn${uname}`] = function(v) {
8268
+ return this.set(name, this.get(name).push(v));
8269
+ };
8205
8270
  }
8206
8271
  }
8272
+ fieldsByClass.set(KList, FieldKList);
8273
+ seqInfoByClass.set(KList, (seq, visit) => {
8274
+ for (const k of seq.order)
8275
+ visit(k, seq.items.get(k), "data-sk");
8276
+ });
8277
+ // index.js
8278
+ var css = String.raw;
8279
+ var html = String.raw;
8280
+ var macro = (defaults, rawView) => new Macro(defaults, rawView);
8281
+ function tutuca(nodeOrSelector) {
8282
+ const rootNode = typeof nodeOrSelector === "string" ? document.querySelector(nodeOrSelector) : nodeOrSelector;
8283
+ const comps = new Components;
8284
+ const renderer = new Renderer(comps);
8285
+ return new App(rootNode, comps, renderer, ParseContext);
8286
+ }
8207
8287
 
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 });
8288
+ // extra.js
8289
+ async function compileClassesToStyle(app, compileClasses, styleId = "margaui-css") {
8290
+ const t1 = performance.now();
8291
+ const css2 = await compileClassesToStyleText(app, compileClasses);
8292
+ const t2 = performance.now();
8293
+ injectCss(styleId, css2);
8294
+ return t2 - t1;
8295
+ }
8296
+ async function compileClassesToStyleText(app, compileClasses, extraCSSClasses, Ctx = ParseCtxClassSetCollector) {
8297
+ app.ParseContext = Ctx;
8298
+ app.compile();
8299
+ const classes = new Set(extraCSSClasses ?? []);
8300
+ for (const Comp of app.comps.byId.values()) {
8301
+ for (const key in Comp.views) {
8302
+ const view = Comp.views[key];
8303
+ for (const name of view.ctx.classes)
8304
+ classes.add(name);
8305
+ }
8215
8306
  }
8307
+ return await compileClasses(Array.from(classes));
8216
8308
  }
8217
8309
  // tools/core/results.js
8218
8310
  class ComponentDocs {
@@ -8407,47 +8499,41 @@ function docComponents(normalized, { name = null } = {}) {
8407
8499
  const picked = name === null ? comps : comps.filter((c) => c.name === name);
8408
8500
  return new ComponentDocs({ items: getComponentsDocs(picked) });
8409
8501
  }
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;
8502
+
8503
+ // dev.js
8504
+ function check(app) {
8505
+ const counts = { error: 0, warn: 0, hint: 0 };
8506
+ for (const Comp of app.comps.byId.values()) {
8507
+ const shadowViews = {};
8508
+ for (const name in Comp.views) {
8509
+ const ctx = new LintParseContext;
8510
+ ANode.parse(Comp.views[name].rawView, ctx);
8511
+ ctx.compile(Comp.scope);
8512
+ shadowViews[name] = { name, ctx };
8513
+ }
8514
+ const shadowComp = Object.create(Comp);
8515
+ shadowComp.views = shadowViews;
8516
+ const { reports } = checkComponent(shadowComp);
8517
+ if (reports.length === 0)
8518
+ continue;
8519
+ console.group(Comp.name);
8520
+ for (const r of reports) {
8521
+ counts[r.level]++;
8522
+ const line = `[${r.level}] ${lintIdToMessage(r.id, r.info)}`;
8523
+ if (r.level === "error")
8524
+ console.error(line);
8525
+ else if (r.level === "warn")
8526
+ console.warn(line);
8527
+ else
8528
+ console.log(line);
8529
+ }
8530
+ console.groupEnd();
8447
8531
  }
8532
+ const total = counts.error + counts.warn + counts.hint;
8533
+ console.log(total === 0 ? "check: no issues" : `check: ${counts.error} error, ${counts.warn} warn, ${counts.hint} hint`);
8534
+ return counts;
8448
8535
  }
8449
8536
 
8450
- // dev.js
8451
8537
  class LintClassCollectorCtx extends ParseCtxClassSetCollector {
8452
8538
  constructor(...args) {
8453
8539
  super(...args);
@@ -8516,8 +8602,8 @@ export {
8516
8602
  component,
8517
8603
  compileClassesToStyleText,
8518
8604
  compileClassesToStyle,
8519
- checkView,
8520
8605
  checkComponent,
8606
+ check,
8521
8607
  UNKNOWN_REQUEST_NAME,
8522
8608
  UNKNOWN_HANDLER_ARG_NAME,
8523
8609
  UNKNOWN_EVENT_MODIFIER,
@@ -8539,9 +8625,6 @@ export {
8539
8625
  LintParseContext,
8540
8626
  LintContext,
8541
8627
  LintClassCollectorCtx,
8542
- LEVEL_WARN,
8543
- LEVEL_HINT,
8544
- LEVEL_ERROR,
8545
8628
  KList,
8546
8629
  Set2 as ISet,
8547
8630
  INPUT_HANDLER_NOT_REFERENCED,