@lark.js/mvc 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // src/constants.ts
1
+ // src/common.ts
2
2
  var globalCounter = 0;
3
3
  var SPLITTER = String.fromCharCode(30);
4
4
  var RouterEvents = {
@@ -14,21 +14,136 @@ var VIEW_EVENT_METHOD_REGEXP = /^(\$?)([\w]*)<(.*?)>(?:<([\w ,]*)>)?$/;
14
14
  var URL_TRIM_HASH_REGEXP = /(?:^.*\/\/[^/]+|#.*$)/gi;
15
15
  var URL_TRIM_QUERY_REGEXP = /^[^#]*#?!?/;
16
16
  var URL_PARAM_REGEXP = /([^=&?/#]+)=?([^&#?]*)/g;
17
+ var IS_URL_PARAMS = /(?!^)=|&/;
17
18
  var URL_QUERY_HASH_REGEXP = /[#?].*$/;
18
19
  var SVG_NS = "http://www.w3.org/2000/svg";
19
20
  var MATH_NS = "http://www.w3.org/1998/Math/MathML";
20
21
  var TAG_NAME_REGEXP = /<([a-z][^/\0>\x20\t\r\n\f]+)/i;
21
22
  var CALL_BREAK_TIME = 48;
23
+ var V_TEXT_NODE = 0;
24
+ var TAG_STATIC_KEY = "_";
25
+ var VDOM_NS_MAP = {
26
+ svg: SVG_NS,
27
+ math: MATH_NS
28
+ };
22
29
  function nextCounter() {
23
30
  return ++globalCounter;
24
31
  }
32
+ var HTML_ENT_MAP = {
33
+ "&": "amp",
34
+ "<": "lt",
35
+ ">": "gt",
36
+ '"': "#34",
37
+ "'": "#39",
38
+ "`": "#96"
39
+ };
40
+ var HTML_ENT_REGEXP = /[&<>"'`]/g;
41
+ function strSafe(v) {
42
+ return String(v == null ? "" : v);
43
+ }
44
+ function encodeHTML(v) {
45
+ return String(v == null ? "" : v).replace(
46
+ HTML_ENT_REGEXP,
47
+ (m) => "&" + HTML_ENT_MAP[m] + ";"
48
+ );
49
+ }
50
+ var URI_ENT_MAP = {
51
+ "!": "%21",
52
+ "'": "%27",
53
+ "(": "%28",
54
+ ")": "%29",
55
+ "*": "%2A"
56
+ };
57
+ var URI_ENT_REGEXP = /[!')(*]/g;
58
+ function encodeURIExtra(v) {
59
+ return encodeURIComponent(strSafe(v)).replace(
60
+ URI_ENT_REGEXP,
61
+ (m) => URI_ENT_MAP[m]
62
+ );
63
+ }
64
+ var QUOTE_ENT_REGEXP = /['"\\]/g;
65
+ function encodeQuote(v) {
66
+ return strSafe(v).replace(QUOTE_ENT_REGEXP, "\\$&");
67
+ }
68
+ function refFn(ref, value, key) {
69
+ const counter = ref[SPLITTER];
70
+ for (let i = counter; --i; ) {
71
+ key = SPLITTER + i;
72
+ if (ref[key] === value) return key;
73
+ }
74
+ key = SPLITTER + ref[SPLITTER]++;
75
+ ref[key] = value;
76
+ return key;
77
+ }
78
+ function isRefToken(s) {
79
+ if (s.length < 2 || s[0] !== SPLITTER) return false;
80
+ for (let i = 1; i < s.length; i++) {
81
+ const c = s.charCodeAt(i);
82
+ if (c < "0".charCodeAt(0) || c > "9".charCodeAt(0)) return false;
83
+ }
84
+ return true;
85
+ }
25
86
 
26
87
  // src/utils.ts
88
+ var CALL_BREAK_TIME2 = 9;
89
+ var callQueue = [];
90
+ var callScheduled = false;
91
+ var schedulerYield = (() => {
92
+ try {
93
+ if (typeof globalThis?.scheduler?.yield === "function") {
94
+ return globalThis.scheduler.yield.bind(globalThis.scheduler);
95
+ }
96
+ } catch {
97
+ }
98
+ return void 0;
99
+ })();
100
+ async function startCall() {
101
+ callScheduled = false;
102
+ const startTime = performance.now();
103
+ while (callQueue.length > 0) {
104
+ const task2 = callQueue.shift();
105
+ try {
106
+ task2();
107
+ } catch (e) {
108
+ console.error("scheduler task error:", e);
109
+ }
110
+ if (callQueue.length > 0 && performance.now() - startTime > CALL_BREAK_TIME2) {
111
+ if (schedulerYield) {
112
+ await schedulerYield();
113
+ } else {
114
+ scheduleNextChunk();
115
+ return;
116
+ }
117
+ }
118
+ }
119
+ }
120
+ function scheduleNextChunk() {
121
+ setTimeout(() => startCall(), 0);
122
+ callScheduled = true;
123
+ }
124
+ function callFunction(fn, args) {
125
+ callQueue.push(() => fn(...args));
126
+ if (!callScheduled) {
127
+ scheduleNextChunk();
128
+ }
129
+ }
27
130
  function isPlainObject(value) {
28
131
  if (typeof value !== "object" || value === null) return false;
29
132
  const proto = Object.getPrototypeOf(value);
30
- if (proto === null) return true;
31
- return proto === Object.prototype || proto === null;
133
+ return proto === null || proto === Object.prototype;
134
+ }
135
+ function isRecord(value) {
136
+ return typeof value === "object" && value !== null;
137
+ }
138
+ function asRecord(value) {
139
+ if (isRecord(value)) {
140
+ return value;
141
+ }
142
+ console.error("fallback to Object.fromEntries, even an empty object {}.");
143
+ if (Array.isArray(value)) {
144
+ return Object.fromEntries(value.entries());
145
+ }
146
+ return {};
32
147
  }
33
148
  function isPrimitiveOrFunc(value) {
34
149
  return !value || typeof value !== "object" && typeof value !== "function";
@@ -40,9 +155,6 @@ var _localCounter = 0;
40
155
  function generateId(prefix) {
41
156
  return (prefix || "lark_") + _localCounter++;
42
157
  }
43
- function syncCounter(val) {
44
- _localCounter = val;
45
- }
46
158
  function noop() {
47
159
  }
48
160
  function hasOwnProperty(owner, prop) {
@@ -86,25 +198,17 @@ function setData(newData, oldData, changedKeys2, excludes) {
86
198
  let changed = false;
87
199
  for (const p in newData) {
88
200
  if (hasOwnProperty(newData, p)) {
89
- const now2 = newData[p];
201
+ const now = newData[p];
90
202
  const old = oldData[p];
91
- if ((!isPrimitiveOrFunc(now2) || old !== now2) && !excludes.has(p)) {
203
+ if ((!isPrimitiveOrFunc(now) || old !== now) && !excludes.has(p)) {
92
204
  changedKeys2.add(p);
93
205
  changed = true;
94
206
  }
95
- oldData[p] = now2;
207
+ oldData[p] = now;
96
208
  }
97
209
  }
98
210
  return changed;
99
211
  }
100
- function isRefToken(s) {
101
- if (s.length < 2 || s[0] !== SPLITTER) return false;
102
- for (let i = 1; i < s.length; i++) {
103
- const c = s.charCodeAt(i);
104
- if (c < 48 || c > 57) return false;
105
- }
106
- return true;
107
- }
108
212
  function translateData(data, value) {
109
213
  if (isPrimitive(value)) {
110
214
  const prop = String(value);
@@ -133,11 +237,11 @@ function getById(id) {
133
237
  function getAttribute(element, attr) {
134
238
  return Element.prototype.getAttribute.call(element, attr) ?? "";
135
239
  }
136
- function ensureElementId(element) {
240
+ function ensureElementId(element, prefix) {
137
241
  const id = element.getAttribute("id");
138
242
  if (id) return id;
139
243
  element.autoId = 1;
140
- const newId = generateId();
244
+ const newId = generateId(prefix);
141
245
  element.id = newId;
142
246
  return newId;
143
247
  }
@@ -167,11 +271,6 @@ function parseUri(uri) {
167
271
  });
168
272
  return { path: actualPath, params };
169
273
  }
170
- var IS_URL_PARAMS = {
171
- test(s) {
172
- return /(?!^)=|&/.test(s);
173
- }
174
- };
175
274
  function toUri(path, params, keepEmpty) {
176
275
  const pairs = [];
177
276
  let hasParams = false;
@@ -198,9 +297,6 @@ function toMap(list, key) {
198
297
  }
199
298
  return map;
200
299
  }
201
- function now() {
202
- return Date.now ? Date.now() : (/* @__PURE__ */ new Date()).getTime();
203
- }
204
300
 
205
301
  // src/apply-style.ts
206
302
  var injectedStyleIds = /* @__PURE__ */ new Set();
@@ -838,14 +934,12 @@ function getChanged(oldLoc, newLoc) {
838
934
  setDiff("path", oldLoc["path"], newLoc["path"]);
839
935
  if (changedParams["path"]) {
840
936
  result["path"] = changedParams["path"];
841
- hasChanged = true;
842
937
  result.changed = true;
843
938
  }
844
939
  const viewKey = "view";
845
940
  setDiff(viewKey, oldLoc.view, newLoc.view);
846
941
  if (changedParams[viewKey]) {
847
942
  result.view = changedParams[viewKey];
848
- hasChanged = true;
849
943
  result.changed = true;
850
944
  }
851
945
  const finalResult = {
@@ -954,10 +1048,7 @@ var Router = {
954
1048
  if (lastChanged["path"]) {
955
1049
  document.title = defaultTitle || document.title;
956
1050
  }
957
- emitter2.fire(
958
- RouterEvents.CHANGED,
959
- lastChanged
960
- );
1051
+ emitter2.fire(RouterEvents.CHANGED, asRecord(lastChanged));
961
1052
  }
962
1053
  silent = 0;
963
1054
  if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && lastChanged) {
@@ -1088,10 +1179,7 @@ var Router = {
1088
1179
  suspend = 1;
1089
1180
  }
1090
1181
  };
1091
- Router.fire(
1092
- RouterEvents.CHANGE,
1093
- changeEvent
1094
- );
1182
+ Router.fire(RouterEvents.CHANGE, changeEvent);
1095
1183
  if (suspend || changeEvent.p) {
1096
1184
  return;
1097
1185
  }
@@ -1365,6 +1453,53 @@ var EventDelegator = {
1365
1453
  }
1366
1454
  };
1367
1455
 
1456
+ // src/module-loader.ts
1457
+ var config = {
1458
+ rootId: "root",
1459
+ routeMode: "history",
1460
+ hashbang: "#!",
1461
+ error: (error) => {
1462
+ throw error;
1463
+ }
1464
+ };
1465
+ function use(names, callback) {
1466
+ const nameList = typeof names === "string" ? [names] : names;
1467
+ const loadPromise = (() => {
1468
+ if (config.require) {
1469
+ const result = config.require(nameList);
1470
+ if (result && typeof result.then === "function") {
1471
+ return result;
1472
+ }
1473
+ return Promise.resolve([]);
1474
+ }
1475
+ return Promise.all(
1476
+ nameList.map((name) => {
1477
+ const importPath = name.startsWith(".") || name.startsWith("/") ? name : `./${name}`;
1478
+ return import(
1479
+ /* @vite-ignore */
1480
+ /* webpackIgnore: true */
1481
+ importPath
1482
+ ).then((mod) => {
1483
+ return mod && (mod["__esModule"] || // For Webpack
1484
+ typeof mod["default"] === "function") ? mod["default"] : mod;
1485
+ }).catch((err) => {
1486
+ const errorHandler = config.error;
1487
+ if (errorHandler) {
1488
+ errorHandler(err instanceof Error ? err : new Error(String(err)));
1489
+ }
1490
+ return void 0;
1491
+ });
1492
+ })
1493
+ );
1494
+ })();
1495
+ if (callback) {
1496
+ loadPromise.then((modules) => {
1497
+ callback(...modules);
1498
+ });
1499
+ }
1500
+ return loadPromise;
1501
+ }
1502
+
1368
1503
  // src/dom.ts
1369
1504
  var wrapMeta = {
1370
1505
  option: [1, "<select multiple>"],
@@ -1440,13 +1575,11 @@ function domGetCompareKey(node) {
1440
1575
  function domSpecialDiff(oldNode, newNode) {
1441
1576
  const specials = DomSpecials[oldNode.nodeName];
1442
1577
  if (!specials) return 0;
1443
- const oldEl = oldNode;
1444
- const newEl = newNode;
1445
1578
  let result = 0;
1446
1579
  for (const prop of specials) {
1447
- if (oldEl[prop] !== newEl[prop]) {
1580
+ if (Reflect.get(oldNode, prop) !== Reflect.get(newNode, prop)) {
1448
1581
  result = 1;
1449
- oldEl[prop] = newEl[prop];
1582
+ Reflect.set(oldNode, prop, Reflect.get(newNode, prop));
1450
1583
  }
1451
1584
  }
1452
1585
  return result;
@@ -1627,57 +1760,530 @@ function applyIdUpdates(updates) {
1627
1760
  }
1628
1761
  }
1629
1762
  }
1630
- var EncoderMap = {
1631
- "&": "amp",
1632
- "<": "lt",
1633
- ">": "gt",
1634
- '"': "#34",
1635
- "'": "#39",
1636
- "`": "#96"
1763
+
1764
+ // src/vdom.ts
1765
+ var DOM_SPECIALS = {
1766
+ INPUT: ["value", "checked"],
1767
+ TEXTAREA: ["value"],
1768
+ OPTION: ["selected"]
1637
1769
  };
1638
- var ENCODE_REGEXP = /[&<>"'`]/g;
1639
- function encodeHTML(v) {
1640
- return String(v == null ? "" : v).replace(
1641
- ENCODE_REGEXP,
1642
- (m) => "&" + EncoderMap[m] + ";"
1643
- );
1770
+ function vdomCreate(tag, props, children, specials) {
1771
+ if (!tag) {
1772
+ return {
1773
+ tag: children ? SPLITTER : V_TEXT_NODE,
1774
+ html: String(props ?? "")
1775
+ };
1776
+ }
1777
+ const propsObj = props || {};
1778
+ const specialsObj = specials || {};
1779
+ const unary = children === 1;
1780
+ let compareKey;
1781
+ let innerHTML = "";
1782
+ let newChildren;
1783
+ let reused;
1784
+ let reusedTotal = 0;
1785
+ let viewList;
1786
+ let isLarkView2;
1787
+ let attrs = `<${tag}`;
1788
+ let hasSpecials;
1789
+ let prevChild;
1790
+ if (children && children !== 1) {
1791
+ for (const c of children) {
1792
+ if (c.attrs !== void 0) {
1793
+ innerHTML += c.attrs + (c.selfClose ? "/>" : `>${c.html}</${c.tag}>`);
1794
+ } else {
1795
+ if (c.tag === V_TEXT_NODE) {
1796
+ innerHTML += encodeHTML(c.html);
1797
+ } else {
1798
+ innerHTML += c.html;
1799
+ }
1800
+ }
1801
+ if (c.tag === V_TEXT_NODE && prevChild && prevChild.tag === V_TEXT_NODE) {
1802
+ prevChild.html += c.html;
1803
+ } else {
1804
+ if (!newChildren) newChildren = [];
1805
+ newChildren.push(c);
1806
+ prevChild = c;
1807
+ }
1808
+ if (c.compareKey) {
1809
+ if (!reused) reused = {};
1810
+ reused[c.compareKey] = (reused[c.compareKey] || 0) + 1;
1811
+ reusedTotal++;
1812
+ }
1813
+ if (c.views) {
1814
+ if (!viewList) viewList = [];
1815
+ viewList.push(...c.views);
1816
+ }
1817
+ }
1818
+ }
1819
+ hasSpecials = specials || void 0;
1820
+ for (const prop in propsObj) {
1821
+ let value = propsObj[prop];
1822
+ if (value === false || value == null) {
1823
+ if (!specialsObj[prop]) {
1824
+ delete propsObj[prop];
1825
+ }
1826
+ continue;
1827
+ } else if (value === true) {
1828
+ propsObj[prop] = value = specialsObj[prop] ? value : "";
1829
+ }
1830
+ if ((prop === "#" || prop === "id" || prop === TAG_STATIC_KEY) && !compareKey) {
1831
+ compareKey = value;
1832
+ if (prop !== "id") {
1833
+ delete propsObj[prop];
1834
+ continue;
1835
+ }
1836
+ }
1837
+ if (prop === LARK_VIEW && value) {
1838
+ const parsed = parseUri(value);
1839
+ isLarkView2 = parsed.path;
1840
+ if (!viewList) viewList = [];
1841
+ viewList.push([
1842
+ isLarkView2,
1843
+ propsObj["lark-owner"],
1844
+ value,
1845
+ parsed.params
1846
+ ]);
1847
+ if (!compareKey) {
1848
+ compareKey = tag + SPLITTER + isLarkView2;
1849
+ }
1850
+ }
1851
+ if (prop === "value" && tag === "textarea") {
1852
+ innerHTML = String(value);
1853
+ delete propsObj[prop];
1854
+ continue;
1855
+ }
1856
+ attrs += ` ${prop}="${value && encodeHTML(value)}"`;
1857
+ }
1858
+ return {
1859
+ tag,
1860
+ html: innerHTML,
1861
+ attrs,
1862
+ attrsMap: propsObj,
1863
+ attrsSpecials: specialsObj,
1864
+ hasSpecials,
1865
+ children: newChildren,
1866
+ compareKey,
1867
+ reused,
1868
+ reusedTotal,
1869
+ views: viewList,
1870
+ selfClose: unary,
1871
+ isLarkView: isLarkView2
1872
+ };
1644
1873
  }
1645
- function encodeSafe(v) {
1646
- return String(v == null ? "" : v);
1874
+ function isSameVDomNode(a, b) {
1875
+ return a.compareKey && b.compareKey === a.compareKey || !a.compareKey && !b.compareKey && a.tag === b.tag || a.tag === SPLITTER || b.tag === SPLITTER;
1647
1876
  }
1648
- var URIMap = {
1649
- "!": "%21",
1650
- "'": "%27",
1651
- "(": "%28",
1652
- ")": "%29",
1653
- "*": "%2A"
1654
- };
1655
- var URI_ENCODE_REGEXP = /[!')(*]/g;
1656
- function encodeURIExtra(v) {
1657
- return encodeURIComponent(encodeSafe(v)).replace(
1658
- URI_ENCODE_REGEXP,
1659
- (m) => URIMap[m]
1660
- );
1877
+ function getKeyNodes(list, nodes, start, end, realEnd) {
1878
+ const keyedNodes = {};
1879
+ for (let i = end, re = realEnd; i >= start; i--, re--) {
1880
+ const oc = list[i];
1881
+ const cKey = oc.compareKey;
1882
+ if (cKey) {
1883
+ const bucket = keyedNodes[cKey] || (keyedNodes[cKey] = []);
1884
+ bucket.push(nodes[re]);
1885
+ }
1886
+ }
1887
+ return keyedNodes;
1661
1888
  }
1662
- var QUOTE_REGEXP = /['"\\]/g;
1663
- function encodeQ(v) {
1664
- return encodeSafe(v).replace(QUOTE_REGEXP, "\\$&");
1889
+ function vdomCreateNode(vnode, owner, ref) {
1890
+ const tag = vnode.tag;
1891
+ if (tag === V_TEXT_NODE) {
1892
+ return document.createTextNode(vnode.html);
1893
+ }
1894
+ const sTag = typeof tag === "string" ? tag : tag.toString();
1895
+ const ns = VDOM_NS_MAP[sTag] || owner.namespaceURI;
1896
+ const el = document.createElementNS(ns, sTag);
1897
+ vdomSetAttributes(el, vnode, ref);
1898
+ el.innerHTML = vnode.html;
1899
+ return el;
1665
1900
  }
1666
-
1667
- // src/updater.ts
1668
- function updaterRef(refDataIn, value, key) {
1669
- const refData = refDataIn;
1670
- const counter = refData[SPLITTER];
1671
- for (let i = counter; --i; ) {
1672
- key = SPLITTER + i;
1673
- if (refData[key] === value) {
1674
- return key;
1901
+ function vdomSetAttributes(realNode, newVDom, ref, lastVDom) {
1902
+ let changed = 0;
1903
+ const nMap = newVDom.attrsMap || {};
1904
+ const nsMap = newVDom.attrsSpecials || {};
1905
+ if (lastVDom) {
1906
+ const oMap = lastVDom.attrsMap || {};
1907
+ const osMap = lastVDom.attrsSpecials || {};
1908
+ for (const key in oMap) {
1909
+ if (!hasOwnProperty(nMap, key)) {
1910
+ changed = 1;
1911
+ const sValue = osMap[key];
1912
+ if (sValue) {
1913
+ if (ref) {
1914
+ ref.nodeProps.push([realNode, sValue, ""]);
1915
+ } else {
1916
+ Reflect.set(realNode, sValue, "");
1917
+ }
1918
+ } else {
1919
+ realNode.removeAttribute(key);
1920
+ }
1921
+ }
1675
1922
  }
1676
1923
  }
1677
- key = SPLITTER + refData[SPLITTER]++;
1678
- refData[key] = value;
1679
- return key;
1924
+ for (const key in nMap) {
1925
+ const value = nMap[key];
1926
+ const sKey = nsMap[key];
1927
+ if (sKey) {
1928
+ if (Reflect.get(realNode, sKey) !== value) {
1929
+ changed = 1;
1930
+ if (ref) {
1931
+ ref.nodeProps.push([realNode, sKey, value]);
1932
+ } else {
1933
+ Reflect.set(realNode, sKey, value);
1934
+ }
1935
+ }
1936
+ } else {
1937
+ const oldMap = lastVDom?.attrsMap;
1938
+ if (!oldMap || oldMap[key] !== value) {
1939
+ changed = 1;
1940
+ realNode.setAttribute(key, String(value ?? ""));
1941
+ }
1942
+ }
1943
+ }
1944
+ return changed;
1945
+ }
1946
+ function vdomSyncFormState(realNode, newVDom) {
1947
+ const specials = DOM_SPECIALS[realNode.nodeName];
1948
+ if (!specials) return 0;
1949
+ const nMap = newVDom.attrsMap || {};
1950
+ let result = 0;
1951
+ for (const prop of specials) {
1952
+ const newVal = nMap[prop];
1953
+ if (newVal !== void 0 && Reflect.get(realNode, prop) !== newVal) {
1954
+ result = 1;
1955
+ Reflect.set(realNode, prop, newVal);
1956
+ }
1957
+ }
1958
+ return result;
1959
+ }
1960
+ function vdomSetNode(realNode, oldParent, lastVDom, newVDom, ref, frame, keys2, rootView, ready) {
1961
+ const lastTag = lastVDom.tag;
1962
+ const newTag = newVDom.tag;
1963
+ if (lastTag === V_TEXT_NODE || newTag === V_TEXT_NODE) {
1964
+ if (lastTag === newTag) {
1965
+ if (lastVDom.html !== newVDom.html) {
1966
+ ref.changed = 1;
1967
+ realNode.nodeValue = newVDom.html;
1968
+ }
1969
+ } else {
1970
+ ref.changed = 1;
1971
+ domUnmountFrames(frame, realNode);
1972
+ oldParent.replaceChild(vdomCreateNode(newVDom, oldParent, ref), realNode);
1973
+ }
1974
+ return;
1975
+ }
1976
+ if (lastTag === newTag) {
1977
+ const lastAMap = lastVDom.attrsMap || {};
1978
+ const newAMap = newVDom.attrsMap || {};
1979
+ if (lastVDom.compareKey && lastVDom.compareKey === newVDom.compareKey && !lastAMap["id"] && !newAMap["id"]) {
1980
+ return;
1981
+ }
1982
+ let attrChanged = 0;
1983
+ if (lastVDom.attrs !== newVDom.attrs || newVDom.hasSpecials) {
1984
+ attrChanged = vdomSetAttributes(
1985
+ realNode,
1986
+ newVDom,
1987
+ ref,
1988
+ lastVDom
1989
+ );
1990
+ if (attrChanged) ref.changed = 1;
1991
+ }
1992
+ let updateChildren = true;
1993
+ if (newVDom.isLarkView) {
1994
+ const oldFrameId = realNode.getAttribute("id") || "";
1995
+ const newViewPath = newVDom.isLarkView;
1996
+ const oldViewPath = lastVDom.isLarkView || "";
1997
+ if (oldFrameId && newViewPath === oldViewPath) {
1998
+ updateChildren = false;
1999
+ }
2000
+ }
2001
+ vdomSyncFormState(realNode, newVDom);
2002
+ if (updateChildren && !newVDom.selfClose) {
2003
+ vdomSetChildNodes(
2004
+ realNode,
2005
+ lastVDom,
2006
+ newVDom,
2007
+ ref,
2008
+ frame,
2009
+ keys2,
2010
+ rootView,
2011
+ ready
2012
+ );
2013
+ }
2014
+ } else {
2015
+ ref.changed = 1;
2016
+ domUnmountFrames(frame, realNode);
2017
+ oldParent.replaceChild(vdomCreateNode(newVDom, oldParent, ref), realNode);
2018
+ }
2019
+ }
2020
+ function vdomSetChildNodes(realNode, lastVDom, newVDom, ref, frame, keys2, view, ready) {
2021
+ if (!lastVDom) {
2022
+ ref.changed = 1;
2023
+ realNode.innerHTML = newVDom.html;
2024
+ return;
2025
+ }
2026
+ if (lastVDom.html === newVDom.html) {
2027
+ return;
2028
+ }
2029
+ const oldChildren = lastVDom.children;
2030
+ const newChildren = newVDom.children;
2031
+ const oldLen = oldChildren?.length || 0;
2032
+ const newLen = newChildren?.length || 0;
2033
+ if (oldLen === 0 && newLen === 0) return;
2034
+ const nodes = realNode.childNodes;
2035
+ let oldStart = 0;
2036
+ let oldEnd = oldLen - 1;
2037
+ let newStart = 0;
2038
+ let newEnd = newLen - 1;
2039
+ let realStart = oldStart;
2040
+ let realEnd = oldEnd;
2041
+ let keyedNodes;
2042
+ const oldReusedTotal = lastVDom.reusedTotal || 0;
2043
+ const newReusedTotal = newVDom.reusedTotal || 0;
2044
+ let oldStartNode = oldChildren?.[oldStart];
2045
+ let oldEndNode = oldChildren?.[oldEnd];
2046
+ let newStartNode = newChildren?.[newStart];
2047
+ let newEndNode = newChildren?.[newEnd];
2048
+ while (oldStart <= oldEnd && newStart <= newEnd) {
2049
+ if (!oldStartNode) {
2050
+ oldStartNode = oldChildren?.[++oldStart];
2051
+ realStart++;
2052
+ continue;
2053
+ }
2054
+ if (!oldEndNode) {
2055
+ oldEndNode = oldChildren?.[--oldEnd];
2056
+ realEnd--;
2057
+ continue;
2058
+ }
2059
+ if (isSameVDomNode(newStartNode, oldStartNode)) {
2060
+ if (newStartNode.tag === SPLITTER || oldStartNode.tag === SPLITTER) {
2061
+ ref.changed = 1;
2062
+ domUnmountFrames(frame, realNode);
2063
+ if (newStartNode.tag === SPLITTER) {
2064
+ realNode.innerHTML = newStartNode.html;
2065
+ } else {
2066
+ realNode.innerHTML = "";
2067
+ realNode.appendChild(vdomCreateNode(newStartNode, realNode, ref));
2068
+ }
2069
+ } else {
2070
+ vdomSetNode(
2071
+ nodes[realStart],
2072
+ realNode,
2073
+ oldStartNode,
2074
+ newStartNode,
2075
+ ref,
2076
+ frame,
2077
+ keys2,
2078
+ view,
2079
+ ready
2080
+ );
2081
+ }
2082
+ reduceCached(keyedNodes, oldStartNode, nodes[realStart]);
2083
+ realStart++;
2084
+ oldStartNode = oldChildren?.[++oldStart];
2085
+ newStartNode = newChildren?.[++newStart];
2086
+ } else if (isSameVDomNode(newEndNode, oldEndNode)) {
2087
+ if (newEndNode.tag === SPLITTER || oldEndNode.tag === SPLITTER) {
2088
+ ref.changed = 1;
2089
+ domUnmountFrames(frame, realNode);
2090
+ realNode.innerHTML = newEndNode.tag === SPLITTER ? newEndNode.html : "";
2091
+ if (newEndNode.tag !== SPLITTER) {
2092
+ realNode.appendChild(vdomCreateNode(newEndNode, realNode, ref));
2093
+ }
2094
+ } else {
2095
+ vdomSetNode(
2096
+ nodes[realEnd],
2097
+ realNode,
2098
+ oldEndNode,
2099
+ newEndNode,
2100
+ ref,
2101
+ frame,
2102
+ keys2,
2103
+ view,
2104
+ ready
2105
+ );
2106
+ }
2107
+ reduceCached(keyedNodes, oldEndNode, nodes[realEnd]);
2108
+ realEnd--;
2109
+ oldEndNode = oldChildren?.[--oldEnd];
2110
+ newEndNode = newChildren?.[--newEnd];
2111
+ } else if (isSameVDomNode(newEndNode, oldStartNode)) {
2112
+ if (newEndNode.tag === SPLITTER || oldStartNode.tag === SPLITTER) {
2113
+ ref.changed = 1;
2114
+ domUnmountFrames(frame, realNode);
2115
+ realNode.innerHTML = newEndNode.tag === SPLITTER ? newEndNode.html : "";
2116
+ if (newEndNode.tag !== SPLITTER) {
2117
+ realNode.appendChild(vdomCreateNode(newEndNode, realNode, ref));
2118
+ }
2119
+ } else {
2120
+ const oi = nodes[realStart];
2121
+ realNode.insertBefore(oi, nodes[realEnd + 1] || null);
2122
+ vdomSetNode(
2123
+ oi,
2124
+ realNode,
2125
+ oldStartNode,
2126
+ newEndNode,
2127
+ ref,
2128
+ frame,
2129
+ keys2,
2130
+ view,
2131
+ ready
2132
+ );
2133
+ }
2134
+ reduceCached(keyedNodes, oldStartNode, nodes[realStart]);
2135
+ realStart++;
2136
+ oldStartNode = oldChildren?.[++oldStart];
2137
+ newEndNode = newChildren?.[--newEnd];
2138
+ } else if (isSameVDomNode(newStartNode, oldEndNode)) {
2139
+ if (newStartNode.tag === SPLITTER || oldEndNode.tag === SPLITTER) {
2140
+ ref.changed = 1;
2141
+ domUnmountFrames(frame, realNode);
2142
+ realNode.innerHTML = newStartNode.tag === SPLITTER ? newStartNode.html : "";
2143
+ if (newStartNode.tag !== SPLITTER) {
2144
+ realNode.appendChild(vdomCreateNode(newStartNode, realNode, ref));
2145
+ }
2146
+ } else {
2147
+ const oi = nodes[realEnd];
2148
+ realNode.insertBefore(oi, nodes[realStart]);
2149
+ vdomSetNode(
2150
+ oi,
2151
+ realNode,
2152
+ oldEndNode,
2153
+ newStartNode,
2154
+ ref,
2155
+ frame,
2156
+ keys2,
2157
+ view,
2158
+ ready
2159
+ );
2160
+ }
2161
+ reduceCached(keyedNodes, oldEndNode, nodes[realEnd]);
2162
+ realEnd--;
2163
+ oldEndNode = oldChildren?.[--oldEnd];
2164
+ newStartNode = newChildren?.[++newStart];
2165
+ } else {
2166
+ if (!keyedNodes && newReusedTotal > 0 && oldReusedTotal > 0) {
2167
+ keyedNodes = getKeyNodes(
2168
+ oldChildren,
2169
+ nodes,
2170
+ oldStart,
2171
+ oldEnd,
2172
+ realEnd
2173
+ );
2174
+ }
2175
+ const cKey = newStartNode.compareKey;
2176
+ let found;
2177
+ let compareKey;
2178
+ if (cKey && keyedNodes) {
2179
+ found = keyedNodes[cKey];
2180
+ compareKey = void 0;
2181
+ while (found && found.length > 0) {
2182
+ compareKey = found.pop();
2183
+ if (compareKey) break;
2184
+ }
2185
+ if (found && found.length === 0) delete keyedNodes[cKey];
2186
+ }
2187
+ if (compareKey) {
2188
+ if (compareKey !== nodes[realStart]) {
2189
+ for (let j = oldStart + 1; j <= oldEnd; j++) {
2190
+ const oc = oldChildren?.[j];
2191
+ if (oc && nodes[realStart + (j - oldStart)] === compareKey) {
2192
+ oldChildren[j] = void 0;
2193
+ break;
2194
+ }
2195
+ }
2196
+ realNode.insertBefore(compareKey, nodes[realStart]);
2197
+ }
2198
+ vdomSetNode(
2199
+ compareKey,
2200
+ realNode,
2201
+ oldStartNode,
2202
+ newStartNode,
2203
+ ref,
2204
+ frame,
2205
+ keys2,
2206
+ view,
2207
+ ready
2208
+ );
2209
+ } else if (oldStartNode.compareKey && lastVDom.reused?.[oldStartNode.compareKey] && newVDom.reused?.[oldStartNode.compareKey] || nodes[realStart]?.id && realNode.querySelectorAll?.(
2210
+ `#${nodes[realStart].id}`
2211
+ )?.length && !newStartNode.isLarkView) {
2212
+ ref.changed = 1;
2213
+ const newNode = vdomCreateNode(newStartNode, realNode, ref);
2214
+ realNode.insertBefore(newNode, nodes[realStart]);
2215
+ realStart--;
2216
+ realEnd++;
2217
+ } else {
2218
+ vdomSetNode(
2219
+ nodes[realStart],
2220
+ realNode,
2221
+ oldStartNode,
2222
+ newStartNode,
2223
+ ref,
2224
+ frame,
2225
+ keys2,
2226
+ view,
2227
+ ready
2228
+ );
2229
+ }
2230
+ realStart++;
2231
+ oldStartNode = oldChildren?.[++oldStart];
2232
+ newStartNode = newChildren?.[++newStart];
2233
+ }
2234
+ }
2235
+ if (newStart <= newEnd) {
2236
+ const refNode = nodes[realEnd + 1] || null;
2237
+ for (let i = newStart; i <= newEnd; i++) {
2238
+ ref.changed = 1;
2239
+ const nc = newChildren[i];
2240
+ if (nc.tag === SPLITTER) {
2241
+ domUnmountFrames(frame, realNode);
2242
+ realNode.innerHTML = nc.html;
2243
+ return;
2244
+ }
2245
+ const newNode = vdomCreateNode(nc, realNode, ref);
2246
+ realNode.insertBefore(newNode, refNode);
2247
+ }
2248
+ }
2249
+ if (oldStart <= oldEnd) {
2250
+ for (let i = realEnd; i >= realStart; i--) {
2251
+ const node = nodes[i];
2252
+ if (node) {
2253
+ domUnmountFrames(frame, node);
2254
+ ref.changed = 1;
2255
+ realNode.removeChild(node);
2256
+ }
2257
+ }
2258
+ }
2259
+ if (ref.asyncCount === 0) {
2260
+ callFunction(ready, []);
2261
+ }
1680
2262
  }
2263
+ function reduceCached(keyedNodes, node, compared) {
2264
+ if (!keyedNodes || !node.compareKey) return;
2265
+ const bucket = keyedNodes[node.compareKey];
2266
+ if (bucket) {
2267
+ for (let i = bucket.length; i--; ) {
2268
+ if (bucket[i] === compared) {
2269
+ bucket[i] = void 0;
2270
+ break;
2271
+ }
2272
+ }
2273
+ }
2274
+ }
2275
+ function createVDomRef(viewId) {
2276
+ return {
2277
+ viewId,
2278
+ viewRenders: [],
2279
+ nodeProps: [],
2280
+ asyncCount: 0,
2281
+ changed: 0,
2282
+ domOps: []
2283
+ };
2284
+ }
2285
+
2286
+ // src/updater.ts
1681
2287
  var Updater = class {
1682
2288
  /** View ID (same as owner frame ID) */
1683
2289
  viewId;
@@ -1699,6 +2305,8 @@ var Updater = class {
1699
2305
  version = 0;
1700
2306
  /** Snapshot of `version` taken by `snapshot()`, used by `altered()`. */
1701
2307
  snapshotVersion;
2308
+ /** Last rendered VDOM tree (only used when virtualDom is enabled) */
2309
+ vdom;
1702
2310
  constructor(viewId) {
1703
2311
  this.viewId = viewId;
1704
2312
  this.data = { vId: viewId };
@@ -1778,28 +2386,61 @@ var Updater = class {
1778
2386
  if (changed && view && node && view.signature > 0 && frame) {
1779
2387
  const template = view.template;
1780
2388
  if (typeof template === "function") {
1781
- const html = template(
1782
- this.data,
1783
- this.viewId,
1784
- this.refData,
1785
- encodeHTML,
1786
- encodeSafe,
1787
- encodeURIExtra,
1788
- updaterRef,
1789
- encodeQ
1790
- );
1791
- const newDom = domGetNode(html, node);
1792
- const ref = createDomRef();
1793
- domSetChildNodes(node, newDom, ref, frame, keys2);
1794
- applyIdUpdates(ref.idUpdates);
1795
- applyDomOps(ref.domOps);
1796
- for (const v of ref.views) {
1797
- if (v.render) {
1798
- funcWithTry(v.render, [], v, noop);
2389
+ if (config.virtualDom) {
2390
+ const vdomTemplate = template;
2391
+ const newVDom = vdomTemplate(this.data, this.viewId, this.refData);
2392
+ const ref = createVDomRef(this.viewId);
2393
+ const ready = () => {
2394
+ this.vdom = newVDom;
2395
+ if (ref.changed || !view.rendered) {
2396
+ view.endUpdate(this.viewId);
2397
+ }
2398
+ for (const [el, prop, val] of ref.nodeProps) {
2399
+ Reflect.set(el, prop, val);
2400
+ }
2401
+ for (const v of ref.viewRenders) {
2402
+ if (v.render) {
2403
+ funcWithTry(v.render, [], v, noop);
2404
+ }
2405
+ }
2406
+ };
2407
+ vdomSetChildNodes(
2408
+ node,
2409
+ this.vdom,
2410
+ newVDom,
2411
+ ref,
2412
+ frame,
2413
+ keys2,
2414
+ view,
2415
+ ready
2416
+ );
2417
+ if (ref.asyncCount === 0) {
2418
+ ready();
2419
+ }
2420
+ } else {
2421
+ const html = template(
2422
+ this.data,
2423
+ this.viewId,
2424
+ this.refData,
2425
+ encodeHTML,
2426
+ strSafe,
2427
+ encodeURIExtra,
2428
+ refFn,
2429
+ encodeQuote
2430
+ );
2431
+ const newDom = domGetNode(html, node);
2432
+ const ref = createDomRef();
2433
+ domSetChildNodes(node, newDom, ref, frame, keys2);
2434
+ applyIdUpdates(ref.idUpdates);
2435
+ applyDomOps(ref.domOps);
2436
+ for (const v of ref.views) {
2437
+ if (v.render) {
2438
+ funcWithTry(v.render, [], v, noop);
2439
+ }
2440
+ }
2441
+ if (ref.hasChanged || !view.rendered) {
2442
+ view.endUpdate(this.viewId);
1799
2443
  }
1800
- }
1801
- if (ref.hasChanged || !view.rendered) {
1802
- view.endUpdate(this.viewId);
1803
2444
  }
1804
2445
  }
1805
2446
  }
@@ -1833,17 +2474,12 @@ var Updater = class {
1833
2474
  * Translate a refData reference back to its original value.
1834
2475
  *
1835
2476
  * The ref protocol is `SPLITTER` + ascii decimal digits — the exact format
1836
- * emitted by `updaterRef`. We require that exact shape so a user-supplied
2477
+ * emitted by `refFn`. We require that exact shape so a user-supplied
1837
2478
  * string that merely begins with SPLITTER is never accidentally resolved
1838
2479
  * (or mishandled as a "missing ref").
1839
2480
  */
1840
2481
  translate(data) {
1841
- if (typeof data !== "string") return data;
1842
- if (data.length < 2 || data[0] !== SPLITTER) return data;
1843
- for (let i = 1; i < data.length; i++) {
1844
- const c = data.charCodeAt(i);
1845
- if (c < 48 || c > 57) return data;
1846
- }
2482
+ if (typeof data !== "string" || !isRefToken(data)) return data;
1847
2483
  return hasOwnProperty(this.refData, data) ? this.refData[data] : data;
1848
2484
  }
1849
2485
  /**
@@ -1910,8 +2546,6 @@ var View = class _View {
1910
2546
  observedStateKeys;
1911
2547
  /** Resource map */
1912
2548
  resources = {};
1913
- /** Assign method reference */
1914
- assignMethod;
1915
2549
  /** Whether endUpdate pending */
1916
2550
  endUpdatePending;
1917
2551
  /** Internal event storage */
@@ -1988,7 +2622,7 @@ var View = class _View {
1988
2622
  */
1989
2623
  beginUpdate(id) {
1990
2624
  if (this.signature > 0 && this.endUpdatePending !== void 0) {
1991
- this.ownerFrame.unmountZone(id, true);
2625
+ this.ownerFrame.unmountZone(id);
1992
2626
  }
1993
2627
  }
1994
2628
  /**
@@ -2007,7 +2641,7 @@ var View = class _View {
2007
2641
  this.rendered = true;
2008
2642
  }
2009
2643
  const ownerFrame = this.ownerFrame;
2010
- ownerFrame.mountZone(updateId, inner);
2644
+ ownerFrame.mountZone(updateId);
2011
2645
  if (!flag) {
2012
2646
  setTimeout(
2013
2647
  this.wrapAsync(() => {
@@ -2157,17 +2791,16 @@ var View = class _View {
2157
2791
  }
2158
2792
  const makes = [];
2159
2793
  oView.makes = makes;
2160
- const proto = oView.prototype;
2161
2794
  const eventsObject = {};
2162
2795
  const eventsList = [];
2163
2796
  const selectorObject = {};
2164
- const mixins = proto["mixins"];
2797
+ const mixins = Reflect.get(oView.prototype, "mixins");
2165
2798
  if (mixins && Array.isArray(mixins)) {
2166
2799
  _View.mergeMixins(mixins, oView, makes);
2167
2800
  }
2168
- for (const p in proto) {
2169
- if (!hasOwnProperty(proto, p)) continue;
2170
- const currentFn = proto[p];
2801
+ for (const p in oView.prototype) {
2802
+ if (!hasOwnProperty(oView.prototype, p)) continue;
2803
+ const currentFn = Reflect.get(oView.prototype, p);
2171
2804
  if (typeof currentFn !== "function") continue;
2172
2805
  const matches = p.match(VIEW_EVENT_METHOD_REGEXP);
2173
2806
  if (!matches) continue;
@@ -2209,30 +2842,30 @@ var View = class _View {
2209
2842
  }
2210
2843
  eventsObject[item] = (eventsObject[item] || 0) | mask;
2211
2844
  const combinedKey = selectorOrCallback + SPLITTER + item;
2212
- const existingFn = proto[combinedKey];
2845
+ const existingFn = Reflect.get(oView.prototype, combinedKey);
2213
2846
  if (!existingFn) {
2214
- proto[combinedKey] = currentFn;
2847
+ Reflect.set(oView.prototype, combinedKey, currentFn);
2215
2848
  } else if (typeof existingFn === "function") {
2216
2849
  const mixinFn = currentFn;
2217
2850
  const existingMixin = existingFn;
2218
2851
  if (existingMixin.marker) {
2219
2852
  if (mixinFn.marker) {
2220
- proto[combinedKey] = _View.processMixinsSameEvent(
2221
- mixinFn,
2222
- existingMixin
2853
+ Reflect.set(
2854
+ oView.prototype,
2855
+ combinedKey,
2856
+ _View.processMixinsSameEvent(mixinFn, existingMixin)
2223
2857
  );
2224
- } else if (hasOwnProperty(proto, p)) {
2225
- proto[combinedKey] = currentFn;
2858
+ } else if (hasOwnProperty(oView.prototype, p)) {
2859
+ Reflect.set(oView.prototype, combinedKey, currentFn);
2226
2860
  }
2227
2861
  }
2228
2862
  }
2229
2863
  }
2230
2864
  }
2231
- _View.wrapMethod(proto, "render", "$renderWrap");
2232
- proto["$evtObjMap"] = eventsObject;
2233
- proto["$globalEvtList"] = eventsList;
2234
- proto["$selMap"] = selectorObject;
2235
- proto["$assignFn"] = proto["assign"];
2865
+ _View.wrapMethod(asRecord(oView.prototype), "render", "$renderWrap");
2866
+ Reflect.set(oView.prototype, "$evtObjMap", eventsObject);
2867
+ Reflect.set(oView.prototype, "$globalEvtList", eventsList);
2868
+ Reflect.set(oView.prototype, "$selMap", selectorObject);
2236
2869
  return makes;
2237
2870
  }
2238
2871
  /**
@@ -2323,7 +2956,7 @@ var View = class _View {
2323
2956
  this.signature++;
2324
2957
  this.fire("render");
2325
2958
  _View.destroyAllResources(this, false);
2326
- const lookup = this;
2959
+ const lookup = asRecord(this);
2327
2960
  const candidate = lookup[fnName];
2328
2961
  const instanceFn = typeof candidate === "function" ? candidate : originalAsFn;
2329
2962
  const fnToCall = instanceFn === wrapped ? originalAsFn : instanceFn;
@@ -2359,7 +2992,7 @@ var View = class _View {
2359
2992
  * Merge an array of mixin objects into the view prototype.
2360
2993
  */
2361
2994
  static mergeMixins(mixins, viewClass, makes) {
2362
- const proto = viewClass.prototype;
2995
+ const proto = asRecord(viewClass.prototype);
2363
2996
  const temp = {};
2364
2997
  for (const node of mixins) {
2365
2998
  for (const p in node) {
@@ -2450,17 +3083,15 @@ var View = class _View {
2450
3083
  }
2451
3084
  }
2452
3085
  };
2453
- const proto = ChildView.prototype;
2454
3086
  for (const key in definedProps) {
2455
3087
  if (hasOwnProperty(definedProps, key) && key !== "make") {
2456
- proto[key] = definedProps[key];
3088
+ Reflect.set(ChildView.prototype, key, definedProps[key]);
2457
3089
  }
2458
3090
  }
2459
3091
  if (statics) {
2460
- const staticTarget = ChildView;
2461
3092
  for (const key in statics) {
2462
3093
  if (hasOwnProperty(statics, key)) {
2463
- staticTarget[key] = statics[key];
3094
+ Reflect.set(ChildView, key, statics[key]);
2464
3095
  }
2465
3096
  }
2466
3097
  }
@@ -2479,53 +3110,6 @@ function defineView(props, statics) {
2479
3110
  return View.extend(props, statics);
2480
3111
  }
2481
3112
 
2482
- // src/module-loader.ts
2483
- var config = {
2484
- rootId: "root",
2485
- routeMode: "history",
2486
- hashbang: "#!",
2487
- error: (error) => {
2488
- throw error;
2489
- }
2490
- };
2491
- function use(names, callback) {
2492
- const nameList = typeof names === "string" ? [names] : names;
2493
- const loadPromise = (() => {
2494
- if (config.require) {
2495
- const result = config.require(nameList);
2496
- if (result && typeof result.then === "function") {
2497
- return result;
2498
- }
2499
- return Promise.resolve([]);
2500
- }
2501
- return Promise.all(
2502
- nameList.map((name) => {
2503
- const importPath = name.startsWith(".") || name.startsWith("/") ? name : `./${name}`;
2504
- return import(
2505
- /* @vite-ignore */
2506
- /* webpackIgnore: true */
2507
- importPath
2508
- ).then((mod) => {
2509
- return mod && (mod["__esModule"] || // For Webpack
2510
- typeof mod["default"] === "function") ? mod["default"] : mod;
2511
- }).catch((err) => {
2512
- const errorHandler = config.error;
2513
- if (errorHandler) {
2514
- errorHandler(err instanceof Error ? err : new Error(String(err)));
2515
- }
2516
- return void 0;
2517
- });
2518
- })
2519
- );
2520
- })();
2521
- if (callback) {
2522
- loadPromise.then((modules) => {
2523
- callback(...modules);
2524
- });
2525
- }
2526
- return loadPromise;
2527
- }
2528
-
2529
3113
  // src/view-registry.ts
2530
3114
  var viewClassRegistry = {};
2531
3115
  function getViewClass(path) {
@@ -2672,9 +3256,15 @@ var Frame = class _Frame extends EventEmitter {
2672
3256
  */
2673
3257
  doMountView(ViewClass, params, node, sign) {
2674
3258
  if (sign !== this.signature) return;
2675
- const mixinCtors = View.prepare(ViewClass);
2676
- const Ctor = ViewClass;
2677
- const view = new Ctor(this.id, this, params, node, mixinCtors);
3259
+ const mixinConstructors = View.prepare(ViewClass);
3260
+ const Constructor = ViewClass;
3261
+ const view = new Constructor(
3262
+ this.id,
3263
+ this,
3264
+ params,
3265
+ node,
3266
+ mixinConstructors
3267
+ );
2678
3268
  this.viewInstance = view;
2679
3269
  view.signature = 1;
2680
3270
  View.delegateEvents(view);
@@ -2746,7 +3336,7 @@ var Frame = class _Frame extends EventEmitter {
2746
3336
  /**
2747
3337
  * Unmount a child frame.
2748
3338
  */
2749
- unmountFrame(id, _inner) {
3339
+ unmountFrame(id) {
2750
3340
  const targetId = id ? this.childrenMap[id] : this.id;
2751
3341
  const frame = frameRegistry.get(targetId);
2752
3342
  if (!frame) return;
@@ -2768,7 +3358,7 @@ var Frame = class _Frame extends EventEmitter {
2768
3358
  /**
2769
3359
  * Mount all views in a zone.
2770
3360
  */
2771
- mountZone(zoneId, _inner) {
3361
+ mountZone(zoneId) {
2772
3362
  const targetZone = zoneId || this.id;
2773
3363
  this.holdFireCreated = 1;
2774
3364
  const rootEl = document.getElementById(targetZone);
@@ -2778,7 +3368,7 @@ var Frame = class _Frame extends EventEmitter {
2778
3368
  viewElements.forEach((el) => {
2779
3369
  if (!(el instanceof HTMLElement)) return;
2780
3370
  if (htmlElIsBound(el)) return;
2781
- const elId = ensureElementId2(el);
3371
+ const elId = ensureElementId(el, "frame_");
2782
3372
  el.frameBound = 1;
2783
3373
  const viewPath = getAttribute(el, LARK_VIEW);
2784
3374
  frames.push([elId, viewPath]);
@@ -2792,7 +3382,7 @@ var Frame = class _Frame extends EventEmitter {
2792
3382
  /**
2793
3383
  * Unmount all views in a zone.
2794
3384
  */
2795
- unmountZone(zoneId, _inner) {
3385
+ unmountZone(zoneId) {
2796
3386
  for (const childId in this.childrenMap) {
2797
3387
  if (hasOwnProperty(this.childrenMap, childId)) {
2798
3388
  if (!zoneId || childId !== zoneId) {
@@ -2835,8 +3425,7 @@ var Frame = class _Frame extends EventEmitter {
2835
3425
  let result;
2836
3426
  const view = this.view;
2837
3427
  if (view && view.rendered) {
2838
- const lookup = view;
2839
- const fn = lookup[name];
3428
+ const fn = Reflect.get(view, name);
2840
3429
  if (typeof fn === "function") {
2841
3430
  result = funcWithTry(fn, args || [], view, noop);
2842
3431
  }
@@ -2921,17 +3510,6 @@ var Frame = class _Frame extends EventEmitter {
2921
3510
  }
2922
3511
  return rootFrame;
2923
3512
  }
2924
- /**
2925
- * @deprecated Use `Frame.getRoot()` for read-only access or
2926
- * `Frame.createRoot(id)` to create the root explicitly. The single-method
2927
- * `root()` blurred the distinction and was a common source of bugs in
2928
- * Micro-Frontend hosts.
2929
- *
2930
- * Kept for backward compatibility — behavior unchanged.
2931
- */
2932
- static root(rootId) {
2933
- return _Frame.createRoot(rootId);
2934
- }
2935
3513
  /** Bind event listener (static) */
2936
3514
  static on(event, handler) {
2937
3515
  staticEmitter.on(event, handler);
@@ -2950,14 +3528,6 @@ var Frame = class _Frame extends EventEmitter {
2950
3528
  function htmlElIsBound(element) {
2951
3529
  return !!element.frameBound;
2952
3530
  }
2953
- function ensureElementId2(element) {
2954
- const id = element.getAttribute("id");
2955
- if (id) return id;
2956
- element.autoId = 1;
2957
- const newId = generateId("frame_");
2958
- element.id = newId;
2959
- return newId;
2960
- }
2961
3531
  function removeFrame(id, wasCreated) {
2962
3532
  const frameInstance = frameRegistry.get(id);
2963
3533
  if (!frameInstance) return;
@@ -3410,7 +3980,7 @@ var Service = class {
3410
3980
  }
3411
3981
  const cached = this._payloadCache.get(cacheKey);
3412
3982
  if (cached && cached.cacheInfo) {
3413
- if (now() - cached.cacheInfo.time > cache) {
3983
+ if (Date.now() - cached.cacheInfo.time > cache) {
3414
3984
  this._payloadCache.del(cacheKey);
3415
3985
  return void 0;
3416
3986
  }
@@ -3568,7 +4138,7 @@ function serviceSend(service, attrs, done, flag, save) {
3568
4138
  const list = pendingCacheKeys[cacheKey];
3569
4139
  const entity = list.entity;
3570
4140
  if (entity instanceof Payload && entity.cacheInfo) {
3571
- entity.cacheInfo.time = now();
4141
+ entity.cacheInfo.time = Date.now();
3572
4142
  internals.payloadCache.set(cacheKey, entity);
3573
4143
  }
3574
4144
  Reflect.deleteProperty(pendingCacheKeys, cacheKey);
@@ -3586,20 +4156,19 @@ function serviceSend(service, attrs, done, flag, save) {
3586
4156
  }
3587
4157
  }
3588
4158
 
3589
- // src/frame-visual.ts
3590
- var FrameVisualBridge = {
3591
- MSG_PING: "LARK_VIS_PING",
3592
- MSG_PONG: "LARK_VIS_PONG",
3593
- MSG_REQUEST_TREE: "LARK_VIS_REQUEST_TREE",
3594
- MSG_TREE: "LARK_VIS_TREE",
3595
- MSG_TREE_DELTA: "LARK_VIS_TREE_DELTA"
4159
+ // src/devtool.ts
4160
+ var FrameDevtoolBridge = {
4161
+ MSG_PING: "LARK_DEVTOOL_PING",
4162
+ MSG_PONG: "LARK_DEVTOOL_PONG",
4163
+ MSG_REQUEST_TREE: "LARK_DEVTOOL_REQUEST_TREE",
4164
+ MSG_TREE: "LARK_DEVTOOL_TREE",
4165
+ MSG_TREE_DELTA: "LARK_DEVTOOL_TREE_DELTA"
3596
4166
  };
3597
4167
  function serializeView(view) {
3598
4168
  const evtMap = view.eventObjectMap;
3599
4169
  const eventMethodKeys = evtMap ? Object.keys(evtMap) : [];
3600
4170
  const resourceKeys = view.resources ? Object.keys(view.resources) : [];
3601
- const lookup = view;
3602
- const hasAssign = typeof lookup["assign"] === "function";
4171
+ const hasAssign = typeof view["assign"] === "function";
3603
4172
  let updaterData = null;
3604
4173
  try {
3605
4174
  const ref = view.updater?.refData;
@@ -3677,7 +4246,7 @@ function serializeFrameTree() {
3677
4246
  }
3678
4247
  var bridgeInstalled = false;
3679
4248
  var lastTreeJson = "";
3680
- function installFrameVisualizerBridge() {
4249
+ function installFrameDevtoolBridge() {
3681
4250
  if (bridgeInstalled) return;
3682
4251
  if (typeof window === "undefined") return;
3683
4252
  bridgeInstalled = true;
@@ -3685,22 +4254,22 @@ function installFrameVisualizerBridge() {
3685
4254
  const data = event.data;
3686
4255
  if (!data || typeof data !== "object") return;
3687
4256
  const type = data.type;
3688
- if (type === FrameVisualBridge.MSG_PING) {
4257
+ if (type === FrameDevtoolBridge.MSG_PING) {
3689
4258
  const source = event.source;
3690
4259
  if (source) {
3691
4260
  source.postMessage(
3692
- { type: FrameVisualBridge.MSG_PONG },
4261
+ { type: FrameDevtoolBridge.MSG_PONG },
3693
4262
  { targetOrigin: "*" }
3694
4263
  );
3695
4264
  }
3696
4265
  return;
3697
4266
  }
3698
- if (type === FrameVisualBridge.MSG_REQUEST_TREE) {
4267
+ if (type === FrameDevtoolBridge.MSG_REQUEST_TREE) {
3699
4268
  const tree = serializeFrameTree();
3700
4269
  const source = event.source;
3701
4270
  if (source) {
3702
4271
  source.postMessage(
3703
- { type: FrameVisualBridge.MSG_TREE, data: tree },
4272
+ { type: FrameDevtoolBridge.MSG_TREE, data: tree },
3704
4273
  { targetOrigin: "*" }
3705
4274
  );
3706
4275
  }
@@ -3720,7 +4289,7 @@ function pushTreeUpdate() {
3720
4289
  if (treeJson !== lastTreeJson) {
3721
4290
  lastTreeJson = treeJson;
3722
4291
  window.parent.postMessage(
3723
- { type: FrameVisualBridge.MSG_TREE_DELTA, data: tree },
4292
+ { type: FrameDevtoolBridge.MSG_TREE_DELTA, data: tree },
3724
4293
  "*"
3725
4294
  );
3726
4295
  }
@@ -3733,7 +4302,7 @@ var taskIndex = 0;
3733
4302
  var taskScheduled = false;
3734
4303
  function executeTaskChunk(deadline) {
3735
4304
  const hasDeadline = !!deadline;
3736
- const startTime = now();
4305
+ const startTime = Date.now();
3737
4306
  while (true) {
3738
4307
  const fn = taskList[taskIndex];
3739
4308
  if (!fn) {
@@ -3747,7 +4316,7 @@ function executeTaskChunk(deadline) {
3747
4316
  scheduleTaskChunk();
3748
4317
  return;
3749
4318
  }
3750
- } else if (now() - startTime > CALL_BREAK_TIME && taskList.length > taskIndex + 3) {
4319
+ } else if (Date.now() - startTime > CALL_BREAK_TIME && taskList.length > taskIndex + 3) {
3751
4320
  scheduleTaskChunk();
3752
4321
  return;
3753
4322
  }
@@ -3879,10 +4448,10 @@ function waitZoneViewsRendered(viewId, timeout) {
3879
4448
  timeout = 30 * 1e3;
3880
4449
  }
3881
4450
  const checkFrame = Frame.get(viewId);
3882
- const endTime = now() + timeout;
4451
+ const endTime = Date.now() + timeout;
3883
4452
  return new Promise((resolve) => {
3884
4453
  const check = () => {
3885
- const currentTime = now();
4454
+ const currentTime = Date.now();
3886
4455
  if (currentTime > endTime || !checkFrame) {
3887
4456
  resolve(WAIT_TIMEOUT_OR_NOT_FOUND);
3888
4457
  } else if (checkFrame.childrenCount === checkFrame.readyCount) {
@@ -3944,7 +4513,7 @@ var Framework = {
3944
4513
  booted3 = true;
3945
4514
  markBooted();
3946
4515
  markRouterBooted();
3947
- installFrameVisualizerBridge();
4516
+ installFrameDevtoolBridge();
3948
4517
  const rootFrame2 = Frame.createRoot(config.rootId);
3949
4518
  Router._bind();
3950
4519
  const defaultView = config.defaultView || "";
@@ -4138,18 +4707,14 @@ function create(name, creator) {
4138
4707
  changedKeys2.add(key);
4139
4708
  }
4140
4709
  }
4141
- let recomputed = false;
4142
4710
  for (const [key, def] of computedDefs) {
4143
4711
  if (def.deps.some((dep) => changedKeys2.has(dep))) {
4144
4712
  const newVal = def.fn();
4145
4713
  if (!Object.is(state[key], newVal)) {
4146
4714
  state[key] = newVal;
4147
- recomputed = true;
4148
4715
  }
4149
4716
  }
4150
4717
  }
4151
- if (recomputed) {
4152
- }
4153
4718
  };
4154
4719
  const subscribe = (listener) => {
4155
4720
  listeners.add(listener);
@@ -4214,7 +4779,6 @@ function bindStore(view, store, selector) {
4214
4779
  view.on("destroy", off);
4215
4780
  return off;
4216
4781
  }
4217
- var defineStore = create;
4218
4782
  export {
4219
4783
  CALL_BREAK_TIME,
4220
4784
  Cache,
@@ -4223,7 +4787,6 @@ export {
4223
4787
  EventDelegator,
4224
4788
  EventEmitter,
4225
4789
  Frame,
4226
- FrameVisualBridge,
4227
4790
  Framework,
4228
4791
  LARK_VIEW,
4229
4792
  Payload,
@@ -4236,59 +4799,24 @@ export {
4236
4799
  Updater,
4237
4800
  VIEW_EVENT_METHOD_REGEXP,
4238
4801
  View,
4239
- applyDomOps,
4240
- applyIdUpdates,
4241
4802
  applyStyle,
4242
- assign,
4243
4803
  bindStore,
4244
4804
  computed,
4245
4805
  create,
4246
- createDomRef,
4247
- defineStore,
4806
+ createVDomRef,
4248
4807
  defineView,
4249
- domGetCompareKey,
4250
- domGetNode,
4251
- domSetAttributes,
4252
- domSetChildNodes,
4253
- domSetNode,
4254
- domSpecialDiff,
4255
- domUnmountFrames,
4256
- encodeHTML,
4257
- encodeQ,
4258
- encodeSafe,
4259
- encodeURIExtra,
4260
- ensureElementId,
4261
4808
  config as frameworkConfig,
4262
- funcWithTry,
4263
- generateId,
4264
- getAttribute,
4265
- getById,
4266
4809
  getRouteMode,
4267
- hasOwnProperty,
4268
- installFrameVisualizerBridge,
4269
4810
  invalidateViewClass,
4270
- isPlainObject,
4271
- isPrimitive,
4272
- isPrimitiveOrFunc,
4273
- keys,
4274
4811
  mark,
4275
4812
  markBooted,
4276
4813
  markRouterBooted,
4277
4814
  nextCounter,
4278
- nodeInside,
4279
- noop,
4280
- now,
4281
- parseUri,
4282
4815
  registerViewClass,
4283
4816
  resetProjectsMap,
4284
4817
  safeguard,
4285
- serializeFrameTree,
4286
- setData,
4287
- syncCounter,
4288
- toMap,
4289
- toUri,
4290
- translateData,
4291
4818
  unmark,
4292
4819
  use,
4293
- useUrlState
4820
+ useUrlState,
4821
+ vdomCreate
4294
4822
  };