@lark.js/mvc 0.0.11 → 0.0.13

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.cjs CHANGED
@@ -53,8 +53,8 @@ __export(index_exports, {
53
53
  markRouterBooted: () => markRouterBooted,
54
54
  nextCounter: () => nextCounter,
55
55
  registerViewClass: () => registerViewClass,
56
+ reloadViews: () => reloadViews,
56
57
  resetProjectsMap: () => resetProjectsMap,
57
- safeguard: () => safeguard,
58
58
  unmark: () => unmark,
59
59
  use: () => use,
60
60
  useUrlState: () => useUrlState,
@@ -85,7 +85,6 @@ var MATH_NS = "http://www.w3.org/1998/Math/MathML";
85
85
  var TAG_NAME_REGEXP = /<([a-z][^/\0>\x20\t\r\n\f]+)/i;
86
86
  var CALL_BREAK_TIME = 48;
87
87
  var V_TEXT_NODE = 0;
88
- var TAG_STATIC_KEY = "_";
89
88
  var VDOM_NS_MAP = {
90
89
  svg: SVG_NS,
91
90
  math: MATH_NS
@@ -431,61 +430,6 @@ function unmark(host) {
431
430
  }
432
431
  }
433
432
 
434
- // src/safeguard.ts
435
- var proxiesPool = /* @__PURE__ */ new Map();
436
- var SAFEGUARD_SENTINEL = "_safe_";
437
- function safeguard(data, getter, setter, isRoot) {
438
- if (typeof window.__lark_Debug === "undefined" || !window.__lark_Debug) {
439
- return data;
440
- }
441
- if (typeof Proxy === "undefined") {
442
- return data;
443
- }
444
- if (isPrimitive(data)) {
445
- return data;
446
- }
447
- const build = (prefix, obj) => {
448
- const cacheKey = (getter || "") + "" + (setter || "");
449
- const cached = proxiesPool.get(obj);
450
- if (cached && cached.cacheKey === cacheKey) {
451
- return cached.entity;
452
- }
453
- if (Reflect.get(obj, SAFEGUARD_SENTINEL)) {
454
- return obj;
455
- }
456
- const entity = new Proxy(obj, {
457
- set(target, property, value) {
458
- if (!setter && !prefix) {
459
- throw new Error(
460
- "Avoid write back, key: " + prefix + property + " value:" + value + " more: https://github.com/hangtiancheng/lark"
461
- );
462
- }
463
- Reflect.set(target, property, value);
464
- if (setter) {
465
- setter(prefix + property, value);
466
- }
467
- return true;
468
- },
469
- get(target, property) {
470
- if (property === SAFEGUARD_SENTINEL) {
471
- return true;
472
- }
473
- const out = Reflect.get(target, property);
474
- if (!prefix && getter) {
475
- getter(property);
476
- }
477
- if (!isRoot && hasOwnProperty(target, property) && (Array.isArray(out) || isPlainObject(out))) {
478
- return build(prefix + property + ".", out);
479
- }
480
- return out;
481
- }
482
- });
483
- proxiesPool.set(obj, { cacheKey, entity });
484
- return entity;
485
- };
486
- return build("", data);
487
- }
488
-
489
433
  // src/cache.ts
490
434
  function sortCacheEntries(a, b) {
491
435
  return b.frequency - a.frequency || b.lastTimestamp - a.lastTimestamp;
@@ -761,7 +705,6 @@ var keyRefCounts = {};
761
705
  var changedKeys = /* @__PURE__ */ new Set();
762
706
  var stashedChangedKeys = EMPTY_STRING_SET;
763
707
  var dataIsChanged = false;
764
- var dataWhereSet = {};
765
708
  var emitter = new EventEmitter();
766
709
  var booted = false;
767
710
  function markBooted() {
@@ -785,47 +728,16 @@ function teardownKeysRef(keyList) {
785
728
  if (count <= 0) {
786
729
  Reflect.deleteProperty(keyRefCounts, key);
787
730
  Reflect.deleteProperty(appData, key);
788
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
789
- Reflect.deleteProperty(dataWhereSet, key);
790
- }
791
731
  }
792
732
  }
793
733
  }
794
734
  }
795
- var warnedKeys = /* @__PURE__ */ new Set();
796
- function clearNotify(key) {
797
- warnedKeys.delete(key);
798
- }
799
- function delayNotify(key, message) {
800
- if (warnedKeys.has(key)) return;
801
- warnedKeys.add(key);
802
- console.warn(message);
803
- }
804
735
  var State = {
805
736
  /**
806
737
  * Get data from state.
807
738
  */
808
739
  get(key) {
809
740
  const result = key ? appData[key] : appData;
810
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
811
- return safeguard(
812
- result,
813
- (dataKey) => {
814
- if (booted && hasOwnProperty(dataWhereSet, dataKey) && dataWhereSet[dataKey] !== window.location.pathname) {
815
- console.warn(
816
- `beware! You get state:"{State}.${dataKey}" where it set by page:${dataWhereSet[dataKey]}`
817
- );
818
- }
819
- },
820
- (path, _value) => {
821
- const sub = key || path;
822
- delayNotify(
823
- sub,
824
- `beware! You direct modify "{State}.${sub}" You should call State.set() and State.digest() to notify other views`
825
- );
826
- }
827
- );
828
- }
829
741
  return result;
830
742
  },
831
743
  /**
@@ -833,11 +745,6 @@ var State = {
833
745
  */
834
746
  set(data, excludes) {
835
747
  dataIsChanged = setData(data, appData, changedKeys, excludes || EMPTY_STRING_SET) || dataIsChanged;
836
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && booted) {
837
- for (const p in data) {
838
- dataWhereSet[p] = window.location.pathname;
839
- }
840
- }
841
748
  return State;
842
749
  },
843
750
  /**
@@ -848,11 +755,6 @@ var State = {
848
755
  State.set(data, excludes);
849
756
  }
850
757
  if (dataIsChanged) {
851
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
852
- for (const p of changedKeys) {
853
- clearNotify(p);
854
- }
855
- }
856
758
  dataIsChanged = false;
857
759
  const keys2 = changedKeys;
858
760
  stashedChangedKeys = keys2;
@@ -1094,9 +996,6 @@ var Router = {
1094
996
  attachViewAndPath(location);
1095
997
  hrefCache.set(href, location);
1096
998
  }
1097
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
1098
- location["params"] = safeguard(location["params"]);
1099
- }
1100
999
  return location;
1101
1000
  },
1102
1001
  /**
@@ -1115,9 +1014,6 @@ var Router = {
1115
1014
  emitter2.fire(RouterEvents.CHANGED, asRecord(lastChanged));
1116
1015
  }
1117
1016
  silent = 0;
1118
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && lastChanged) {
1119
- lastChanged = safeguard(lastChanged);
1120
- }
1121
1017
  return lastChanged;
1122
1018
  },
1123
1019
  /**
@@ -1874,6 +1770,13 @@ function vdomCreate(tag, props, children, specials) {
1874
1770
  reused[c.compareKey] = (reused[c.compareKey] || 0) + 1;
1875
1771
  reusedTotal++;
1876
1772
  }
1773
+ if (c.reused) {
1774
+ if (!reused) reused = {};
1775
+ for (const key in c.reused) {
1776
+ reused[key] = (reused[key] || 0) + c.reused[key];
1777
+ reusedTotal += c.reused[key];
1778
+ }
1779
+ }
1877
1780
  if (c.views) {
1878
1781
  if (!viewList) viewList = [];
1879
1782
  viewList.push(...c.views);
@@ -1891,7 +1794,7 @@ function vdomCreate(tag, props, children, specials) {
1891
1794
  } else if (value === true) {
1892
1795
  propsObj[prop] = value = specialsObj[prop] ? value : "";
1893
1796
  }
1894
- if ((prop === "#" || prop === "id" || prop === TAG_STATIC_KEY) && !compareKey) {
1797
+ if ((prop === "#" || prop === "id") && !compareKey) {
1895
1798
  compareKey = value;
1896
1799
  if (prop !== "id") {
1897
1800
  delete propsObj[prop];
@@ -1938,18 +1841,6 @@ function vdomCreate(tag, props, children, specials) {
1938
1841
  function isSameVDomNode(a, b) {
1939
1842
  return a.compareKey && b.compareKey === a.compareKey || !a.compareKey && !b.compareKey && a.tag === b.tag || a.tag === SPLITTER || b.tag === SPLITTER;
1940
1843
  }
1941
- function getKeyNodes(list, nodes, start, end, realEnd) {
1942
- const keyedNodes = {};
1943
- for (let i = end, re = realEnd; i >= start; i--, re--) {
1944
- const oc = list[i];
1945
- const cKey = oc.compareKey;
1946
- if (cKey) {
1947
- const bucket = keyedNodes[cKey] || (keyedNodes[cKey] = []);
1948
- bucket.push(nodes[re]);
1949
- }
1950
- }
1951
- return keyedNodes;
1952
- }
1953
1844
  function vdomCreateNode(vnode, owner, ref) {
1954
1845
  const tag = vnode.tag;
1955
1846
  if (tag === V_TEXT_NODE) {
@@ -2038,9 +1929,10 @@ function vdomSetNode(realNode, oldParent, lastVDom, newVDom, ref, frame, keys2,
2038
1929
  return;
2039
1930
  }
2040
1931
  if (lastTag === newTag) {
2041
- const lastAMap = lastVDom.attrsMap || {};
2042
- const newAMap = newVDom.attrsMap || {};
2043
- if (lastVDom.compareKey && lastVDom.compareKey === newVDom.compareKey && !lastAMap["id"] && !newAMap["id"]) {
1932
+ if (lastVDom.attrs === newVDom.attrs && lastVDom.html === newVDom.html) {
1933
+ if (newVDom.hasSpecials) {
1934
+ vdomSyncFormState(realNode, newVDom);
1935
+ }
2044
1936
  return;
2045
1937
  }
2046
1938
  let attrChanged = 0;
@@ -2081,261 +1973,209 @@ function vdomSetNode(realNode, oldParent, lastVDom, newVDom, ref, frame, keys2,
2081
1973
  oldParent.replaceChild(vdomCreateNode(newVDom, oldParent, ref), realNode);
2082
1974
  }
2083
1975
  }
1976
+ function computeLIS(sequence) {
1977
+ const len = sequence.length;
1978
+ if (len === 0) return [];
1979
+ const result = [];
1980
+ const tails = [];
1981
+ const predecessors = new Array(len);
1982
+ let lisLength = 0;
1983
+ for (let i = 0; i < len; i++) {
1984
+ const value = sequence[i];
1985
+ if (value < 0) continue;
1986
+ let lo = 0;
1987
+ let hi = lisLength;
1988
+ while (lo < hi) {
1989
+ const mid = lo + hi >>> 1;
1990
+ if (sequence[tails[mid]] < value) lo = mid + 1;
1991
+ else hi = mid;
1992
+ }
1993
+ tails[lo] = i;
1994
+ predecessors[i] = lo > 0 ? tails[lo - 1] : -1;
1995
+ if (lo === lisLength) lisLength++;
1996
+ }
1997
+ let cursor = tails[lisLength - 1];
1998
+ for (let i = lisLength - 1; i >= 0; i--) {
1999
+ result[i] = cursor;
2000
+ cursor = predecessors[cursor];
2001
+ }
2002
+ return result;
2003
+ }
2084
2004
  function vdomSetChildNodes(realNode, lastVDom, newVDom, ref, frame, keys2, view, ready) {
2085
2005
  if (!lastVDom) {
2086
2006
  ref.changed = 1;
2087
2007
  realNode.innerHTML = newVDom.html;
2008
+ callFunction(ready, []);
2088
2009
  return;
2089
2010
  }
2090
2011
  if (lastVDom.html === newVDom.html) {
2012
+ callFunction(ready, []);
2091
2013
  return;
2092
2014
  }
2093
2015
  const oldChildren = lastVDom.children;
2094
2016
  const newChildren = newVDom.children;
2095
2017
  const oldLen = oldChildren?.length || 0;
2096
2018
  const newLen = newChildren?.length || 0;
2097
- if (oldLen === 0 && newLen === 0) return;
2019
+ if (oldLen === 0 && newLen === 0) {
2020
+ callFunction(ready, []);
2021
+ return;
2022
+ }
2098
2023
  const nodes = realNode.childNodes;
2099
- let oldStart = 0;
2100
- let oldEnd = oldLen - 1;
2101
- let newStart = 0;
2102
- let newEnd = newLen - 1;
2103
- let realStart = oldStart;
2104
- let realEnd = oldEnd;
2105
- let keyedNodes;
2106
- const oldReusedTotal = lastVDom.reusedTotal || 0;
2107
- const newReusedTotal = newVDom.reusedTotal || 0;
2108
- let oldStartNode = oldChildren?.[oldStart];
2109
- let oldEndNode = oldChildren?.[oldEnd];
2110
- let newStartNode = newChildren?.[newStart];
2111
- let newEndNode = newChildren?.[newEnd];
2112
- while (oldStart <= oldEnd && newStart <= newEnd) {
2113
- if (!oldStartNode) {
2114
- oldStartNode = oldChildren?.[++oldStart];
2115
- realStart++;
2116
- continue;
2117
- }
2118
- if (!oldEndNode) {
2119
- oldEndNode = oldChildren?.[--oldEnd];
2120
- realEnd--;
2121
- continue;
2122
- }
2123
- if (isSameVDomNode(newStartNode, oldStartNode)) {
2124
- if (newStartNode.tag === SPLITTER || oldStartNode.tag === SPLITTER) {
2125
- ref.changed = 1;
2126
- domUnmountFrames(frame, realNode);
2127
- if (newStartNode.tag === SPLITTER) {
2128
- realNode.innerHTML = newStartNode.html;
2129
- } else {
2130
- realNode.innerHTML = "";
2131
- realNode.appendChild(vdomCreateNode(newStartNode, realNode, ref));
2132
- }
2133
- } else {
2134
- vdomSetNode(
2135
- nodes[realStart],
2136
- realNode,
2137
- oldStartNode,
2138
- newStartNode,
2139
- ref,
2140
- frame,
2141
- keys2,
2142
- view,
2143
- ready
2144
- );
2145
- }
2146
- reduceCached(keyedNodes, oldStartNode, nodes[realStart]);
2147
- realStart++;
2148
- oldStartNode = oldChildren?.[++oldStart];
2149
- newStartNode = newChildren?.[++newStart];
2150
- } else if (isSameVDomNode(newEndNode, oldEndNode)) {
2151
- if (newEndNode.tag === SPLITTER || oldEndNode.tag === SPLITTER) {
2152
- ref.changed = 1;
2153
- domUnmountFrames(frame, realNode);
2154
- realNode.innerHTML = newEndNode.tag === SPLITTER ? newEndNode.html : "";
2155
- if (newEndNode.tag !== SPLITTER) {
2156
- realNode.appendChild(vdomCreateNode(newEndNode, realNode, ref));
2157
- }
2158
- } else {
2159
- vdomSetNode(
2160
- nodes[realEnd],
2161
- realNode,
2162
- oldEndNode,
2163
- newEndNode,
2164
- ref,
2165
- frame,
2166
- keys2,
2167
- view,
2168
- ready
2169
- );
2170
- }
2171
- reduceCached(keyedNodes, oldEndNode, nodes[realEnd]);
2172
- realEnd--;
2173
- oldEndNode = oldChildren?.[--oldEnd];
2174
- newEndNode = newChildren?.[--newEnd];
2175
- } else if (isSameVDomNode(newEndNode, oldStartNode)) {
2176
- if (newEndNode.tag === SPLITTER || oldStartNode.tag === SPLITTER) {
2177
- ref.changed = 1;
2178
- domUnmountFrames(frame, realNode);
2179
- realNode.innerHTML = newEndNode.tag === SPLITTER ? newEndNode.html : "";
2180
- if (newEndNode.tag !== SPLITTER) {
2181
- realNode.appendChild(vdomCreateNode(newEndNode, realNode, ref));
2182
- }
2183
- } else {
2184
- const oi = nodes[realStart];
2185
- realNode.insertBefore(oi, nodes[realEnd + 1] || null);
2186
- vdomSetNode(
2187
- oi,
2188
- realNode,
2189
- oldStartNode,
2190
- newEndNode,
2191
- ref,
2192
- frame,
2193
- keys2,
2194
- view,
2195
- ready
2196
- );
2197
- }
2198
- reduceCached(keyedNodes, oldStartNode, nodes[realStart]);
2199
- realStart++;
2200
- oldStartNode = oldChildren?.[++oldStart];
2201
- newEndNode = newChildren?.[--newEnd];
2202
- } else if (isSameVDomNode(newStartNode, oldEndNode)) {
2203
- if (newStartNode.tag === SPLITTER || oldEndNode.tag === SPLITTER) {
2204
- ref.changed = 1;
2205
- domUnmountFrames(frame, realNode);
2206
- realNode.innerHTML = newStartNode.tag === SPLITTER ? newStartNode.html : "";
2207
- if (newStartNode.tag !== SPLITTER) {
2208
- realNode.appendChild(vdomCreateNode(newStartNode, realNode, ref));
2209
- }
2210
- } else {
2211
- const oi = nodes[realEnd];
2212
- realNode.insertBefore(oi, nodes[realStart]);
2213
- vdomSetNode(
2214
- oi,
2215
- realNode,
2216
- oldEndNode,
2217
- newStartNode,
2218
- ref,
2219
- frame,
2220
- keys2,
2221
- view,
2222
- ready
2223
- );
2224
- }
2225
- reduceCached(keyedNodes, oldEndNode, nodes[realEnd]);
2226
- realEnd--;
2227
- oldEndNode = oldChildren?.[--oldEnd];
2228
- newStartNode = newChildren?.[++newStart];
2024
+ const oldDomNodes = new Array(oldLen);
2025
+ for (let i = 0; i < oldLen; i++) {
2026
+ oldDomNodes[i] = nodes[i];
2027
+ }
2028
+ const usedOldDomNodes = /* @__PURE__ */ new Set();
2029
+ let headIdx = 0;
2030
+ let tailIdx = oldLen - 1;
2031
+ let newHead = 0;
2032
+ let newTail = newLen - 1;
2033
+ while (headIdx <= tailIdx && newHead <= newTail) {
2034
+ const oc = oldChildren[headIdx];
2035
+ const nc = newChildren[newHead];
2036
+ if (!isSameVDomNode(nc, oc)) break;
2037
+ if (nc.tag === SPLITTER || oc.tag === SPLITTER) break;
2038
+ vdomSetNode(
2039
+ oldDomNodes[headIdx],
2040
+ realNode,
2041
+ oc,
2042
+ nc,
2043
+ ref,
2044
+ frame,
2045
+ keys2,
2046
+ view,
2047
+ ready
2048
+ );
2049
+ usedOldDomNodes.add(oldDomNodes[headIdx]);
2050
+ headIdx++;
2051
+ newHead++;
2052
+ }
2053
+ while (headIdx <= tailIdx && newHead <= newTail) {
2054
+ const oc = oldChildren[tailIdx];
2055
+ const nc = newChildren[newTail];
2056
+ if (!isSameVDomNode(nc, oc)) break;
2057
+ if (nc.tag === SPLITTER || oc.tag === SPLITTER) break;
2058
+ vdomSetNode(
2059
+ oldDomNodes[tailIdx],
2060
+ realNode,
2061
+ oc,
2062
+ nc,
2063
+ ref,
2064
+ frame,
2065
+ keys2,
2066
+ view,
2067
+ ready
2068
+ );
2069
+ usedOldDomNodes.add(oldDomNodes[tailIdx]);
2070
+ tailIdx--;
2071
+ newTail--;
2072
+ }
2073
+ if (headIdx > tailIdx && newHead > newTail) {
2074
+ if (ref.asyncCount === 0) callFunction(ready, []);
2075
+ return;
2076
+ }
2077
+ const keyMap = {};
2078
+ for (let i = headIdx; i <= tailIdx; i++) {
2079
+ const c = oldChildren[i];
2080
+ if (c?.compareKey) {
2081
+ if (!keyMap[c.compareKey]) keyMap[c.compareKey] = [];
2082
+ keyMap[c.compareKey].push({ domNode: oldDomNodes[i], vdomNode: c });
2083
+ }
2084
+ }
2085
+ const newRemaining = newTail - newHead + 1;
2086
+ const sequence = new Array(newRemaining);
2087
+ for (let i = 0; i < newRemaining; i++) {
2088
+ const nc = newChildren[newHead + i];
2089
+ const cKey = nc.compareKey;
2090
+ const entries = cKey ? keyMap[cKey] : void 0;
2091
+ if (entries && entries.length > 0) {
2092
+ const entry = entries.shift();
2093
+ if (entries.length === 0) delete keyMap[cKey];
2094
+ const oldIdx = oldChildren.indexOf(entry.vdomNode, headIdx);
2095
+ sequence[i] = oldIdx >= 0 ? oldIdx : -1;
2096
+ usedOldDomNodes.add(entry.domNode);
2229
2097
  } else {
2230
- if (!keyedNodes && newReusedTotal > 0 && oldReusedTotal > 0) {
2231
- keyedNodes = getKeyNodes(
2232
- oldChildren,
2233
- nodes,
2234
- oldStart,
2235
- oldEnd,
2236
- realEnd
2237
- );
2238
- }
2239
- const cKey = newStartNode.compareKey;
2240
- let found;
2241
- let compareKey;
2242
- if (cKey && keyedNodes) {
2243
- found = keyedNodes[cKey];
2244
- compareKey = void 0;
2245
- while (found && found.length > 0) {
2246
- compareKey = found.pop();
2247
- if (compareKey) break;
2248
- }
2249
- if (found && found.length === 0) delete keyedNodes[cKey];
2250
- }
2251
- if (compareKey) {
2252
- if (compareKey !== nodes[realStart]) {
2253
- for (let j = oldStart + 1; j <= oldEnd; j++) {
2254
- const oc = oldChildren?.[j];
2255
- if (oc && nodes[realStart + (j - oldStart)] === compareKey) {
2256
- oldChildren[j] = void 0;
2257
- break;
2258
- }
2259
- }
2260
- realNode.insertBefore(compareKey, nodes[realStart]);
2261
- }
2262
- vdomSetNode(
2263
- compareKey,
2264
- realNode,
2265
- oldStartNode,
2266
- newStartNode,
2267
- ref,
2268
- frame,
2269
- keys2,
2270
- view,
2271
- ready
2272
- );
2273
- } else if (oldStartNode.compareKey && lastVDom.reused?.[oldStartNode.compareKey] && newVDom.reused?.[oldStartNode.compareKey] || nodes[realStart]?.id && realNode.querySelectorAll?.(
2274
- `#${nodes[realStart].id}`
2275
- )?.length && !newStartNode.isLarkView) {
2098
+ sequence[i] = -1;
2099
+ }
2100
+ }
2101
+ if (newHead > newTail) {
2102
+ for (let i = 0; i < oldLen; i++) {
2103
+ const domNode = oldDomNodes[i];
2104
+ if (domNode && !usedOldDomNodes.has(domNode) && domNode.parentNode === realNode) {
2105
+ domUnmountFrames(frame, domNode);
2276
2106
  ref.changed = 1;
2277
- const newNode = vdomCreateNode(newStartNode, realNode, ref);
2278
- realNode.insertBefore(newNode, nodes[realStart]);
2279
- realStart--;
2280
- realEnd++;
2281
- } else {
2282
- vdomSetNode(
2283
- nodes[realStart],
2284
- realNode,
2285
- oldStartNode,
2286
- newStartNode,
2287
- ref,
2288
- frame,
2289
- keys2,
2290
- view,
2291
- ready
2292
- );
2107
+ realNode.removeChild(domNode);
2293
2108
  }
2294
- realStart++;
2295
- oldStartNode = oldChildren?.[++oldStart];
2296
- newStartNode = newChildren?.[++newStart];
2297
2109
  }
2110
+ if (ref.asyncCount === 0) callFunction(ready, []);
2111
+ return;
2298
2112
  }
2299
- if (newStart <= newEnd) {
2300
- const refNode = nodes[realEnd + 1] || null;
2301
- for (let i = newStart; i <= newEnd; i++) {
2113
+ if (headIdx > tailIdx) {
2114
+ const insertRef = tailIdx < oldLen ? oldDomNodes[tailIdx + 1] ?? null : null;
2115
+ for (let i = newHead; i <= newTail; i++) {
2116
+ ref.changed = 1;
2117
+ const newNode = vdomCreateNode(newChildren[i], realNode, ref);
2118
+ realNode.insertBefore(newNode, insertRef);
2119
+ }
2120
+ if (ref.asyncCount === 0) callFunction(ready, []);
2121
+ return;
2122
+ }
2123
+ const lis = computeLIS(sequence);
2124
+ let lisCursor = lis.length - 1;
2125
+ let nextNode = tailIdx + 1 < oldLen ? oldDomNodes[tailIdx + 1] : null;
2126
+ for (let j = newRemaining - 1; j >= 0; j--) {
2127
+ const newIdx = newHead + j;
2128
+ const nc = newChildren[newIdx];
2129
+ if (lisCursor >= 0 && lis[lisCursor] === j) {
2130
+ const oldIdx = sequence[j];
2131
+ vdomSetNode(
2132
+ oldDomNodes[oldIdx],
2133
+ realNode,
2134
+ oldChildren[oldIdx],
2135
+ nc,
2136
+ ref,
2137
+ frame,
2138
+ keys2,
2139
+ view,
2140
+ ready
2141
+ );
2142
+ nextNode = oldDomNodes[oldIdx];
2143
+ lisCursor--;
2144
+ } else if (sequence[j] >= 0) {
2145
+ const oldIdx = sequence[j];
2146
+ ref.changed = 1;
2147
+ realNode.insertBefore(oldDomNodes[oldIdx], nextNode);
2148
+ vdomSetNode(
2149
+ oldDomNodes[oldIdx],
2150
+ realNode,
2151
+ oldChildren[oldIdx],
2152
+ nc,
2153
+ ref,
2154
+ frame,
2155
+ keys2,
2156
+ view,
2157
+ ready
2158
+ );
2159
+ nextNode = oldDomNodes[oldIdx];
2160
+ } else {
2302
2161
  ref.changed = 1;
2303
- const nc = newChildren[i];
2304
- if (nc.tag === SPLITTER) {
2305
- domUnmountFrames(frame, realNode);
2306
- realNode.innerHTML = nc.html;
2307
- return;
2308
- }
2309
2162
  const newNode = vdomCreateNode(nc, realNode, ref);
2310
- realNode.insertBefore(newNode, refNode);
2163
+ realNode.insertBefore(newNode, nextNode);
2164
+ nextNode = newNode;
2311
2165
  }
2312
2166
  }
2313
- if (oldStart <= oldEnd) {
2314
- for (let i = realEnd; i >= realStart; i--) {
2315
- const node = nodes[i];
2316
- if (node) {
2317
- domUnmountFrames(frame, node);
2318
- ref.changed = 1;
2319
- realNode.removeChild(node);
2320
- }
2167
+ for (let i = 0; i < oldLen; i++) {
2168
+ const domNode = oldDomNodes[i];
2169
+ if (domNode && !usedOldDomNodes.has(domNode) && domNode.parentNode === realNode) {
2170
+ domUnmountFrames(frame, domNode);
2171
+ ref.changed = 1;
2172
+ realNode.removeChild(domNode);
2321
2173
  }
2322
2174
  }
2323
2175
  if (ref.asyncCount === 0) {
2324
2176
  callFunction(ready, []);
2325
2177
  }
2326
2178
  }
2327
- function reduceCached(keyedNodes, node, compared) {
2328
- if (!keyedNodes || !node.compareKey) return;
2329
- const bucket = keyedNodes[node.compareKey];
2330
- if (bucket) {
2331
- for (let i = bucket.length; i--; ) {
2332
- if (bucket[i] === compared) {
2333
- bucket[i] = void 0;
2334
- break;
2335
- }
2336
- }
2337
- }
2338
- }
2339
2179
  function createVDomRef(viewId) {
2340
2180
  return {
2341
2181
  viewId,
@@ -2388,9 +2228,6 @@ var Updater = class {
2388
2228
  if (key) {
2389
2229
  result = this.data[key];
2390
2230
  }
2391
- if (typeof window !== "undefined" && window.__lark_Debug) {
2392
- return safeguard(result);
2393
- }
2394
2231
  return result;
2395
2232
  }
2396
2233
  /**
@@ -2478,9 +2315,6 @@ var Updater = class {
2478
2315
  view,
2479
2316
  ready
2480
2317
  );
2481
- if (ref.asyncCount === 0) {
2482
- ready();
2483
- }
2484
2318
  } else {
2485
2319
  const html = template(
2486
2320
  this.data,
@@ -2579,6 +2413,63 @@ var Updater = class {
2579
2413
  }
2580
2414
  };
2581
2415
 
2416
+ // src/view-registry.ts
2417
+ var viewClassRegistry = {};
2418
+ function getViewClass(path) {
2419
+ return viewClassRegistry[path];
2420
+ }
2421
+ function registerViewClass(viewPath, ViewClass) {
2422
+ const parsed = parseUri(viewPath);
2423
+ const path = parsed.path;
2424
+ if (path) {
2425
+ viewClassRegistry[path] = ViewClass;
2426
+ }
2427
+ }
2428
+ function invalidateViewClass(viewPath) {
2429
+ const parsed = parseUri(viewPath);
2430
+ const path = parsed.path;
2431
+ if (path) {
2432
+ Reflect.deleteProperty(viewClassRegistry, path);
2433
+ }
2434
+ }
2435
+ function getViewClassRegistry() {
2436
+ return viewClassRegistry;
2437
+ }
2438
+
2439
+ // src/hmr.ts
2440
+ function reloadViews(viewPath) {
2441
+ const allFrames = Frame.getAll();
2442
+ const toReload = [];
2443
+ for (const [, frame] of allFrames) {
2444
+ if (frame.viewPath) {
2445
+ const parsed = parseUri(frame.viewPath);
2446
+ if (parsed.path === viewPath) {
2447
+ toReload.push({ frame, fullPath: frame.viewPath });
2448
+ }
2449
+ }
2450
+ }
2451
+ for (const { frame, fullPath } of toReload) {
2452
+ frame.mountView(fullPath);
2453
+ }
2454
+ }
2455
+ function acceptView(hot, viewPath) {
2456
+ hot.accept((newModule) => {
2457
+ const candidate = newModule?.default ?? newModule;
2458
+ if (typeof candidate === "function") {
2459
+ const NewViewClass = candidate;
2460
+ registerViewClass(viewPath, NewViewClass);
2461
+ reloadViews(viewPath);
2462
+ } else {
2463
+ hot.invalidate();
2464
+ }
2465
+ });
2466
+ }
2467
+ function disposeView(hot, viewPath) {
2468
+ hot.dispose(() => {
2469
+ invalidateViewClass(viewPath);
2470
+ });
2471
+ }
2472
+
2582
2473
  // src/view.ts
2583
2474
  var VIEW_GLOBALS = {};
2584
2475
  if (typeof window !== "undefined") {
@@ -3169,34 +3060,51 @@ var View = class _View {
3169
3060
  _View.mergeMixins(mixins, this, existingCtors);
3170
3061
  return this;
3171
3062
  }
3063
+ // ============================================================
3064
+ // HMR support (static accept / dispose)
3065
+ // ============================================================
3066
+ /**
3067
+ * Set up HMR accept handler for this view module.
3068
+ *
3069
+ * When the module is hot-replaced, the new View class is extracted from
3070
+ * the new module, registered in the view registry, and all currently
3071
+ * mounted frames using this viewPath are re-mounted.
3072
+ *
3073
+ * No-op when `hot` is undefined (production / non-HMR environment).
3074
+ *
3075
+ * ```ts
3076
+ * if (import.meta.hot) {
3077
+ * HomeView.accept(import.meta.hot, 'home');
3078
+ * }
3079
+ * ```
3080
+ */
3081
+ static accept(hot, viewPath) {
3082
+ if (!hot) return;
3083
+ acceptView(hot, viewPath);
3084
+ }
3085
+ /**
3086
+ * Set up HMR dispose handler for this view module.
3087
+ *
3088
+ * When the module is about to be replaced, the old View class is removed
3089
+ * from the registry so subsequent lookups don't return the stale class.
3090
+ *
3091
+ * No-op when `hot` is undefined (production / non-HMR environment).
3092
+ *
3093
+ * ```ts
3094
+ * if (import.meta.hot) {
3095
+ * HomeView.dispose(import.meta.hot, 'home');
3096
+ * }
3097
+ * ```
3098
+ */
3099
+ static dispose(hot, viewPath) {
3100
+ if (!hot) return;
3101
+ disposeView(hot, viewPath);
3102
+ }
3172
3103
  };
3173
3104
  function defineView(props, statics) {
3174
3105
  return View.extend(props, statics);
3175
3106
  }
3176
3107
 
3177
- // src/view-registry.ts
3178
- var viewClassRegistry = {};
3179
- function getViewClass(path) {
3180
- return viewClassRegistry[path];
3181
- }
3182
- function registerViewClass(viewPath, ViewClass) {
3183
- const parsed = parseUri(viewPath);
3184
- const path = parsed.path;
3185
- if (path) {
3186
- viewClassRegistry[path] = ViewClass;
3187
- }
3188
- }
3189
- function invalidateViewClass(viewPath) {
3190
- const parsed = parseUri(viewPath);
3191
- const path = parsed.path;
3192
- if (path) {
3193
- Reflect.deleteProperty(viewClassRegistry, path);
3194
- }
3195
- }
3196
- function getViewClassRegistry() {
3197
- return viewClassRegistry;
3198
- }
3199
-
3200
3108
  // src/frame.ts
3201
3109
  var frameRegistry = /* @__PURE__ */ new Map();
3202
3110
  var rootFrame;
@@ -4654,10 +4562,6 @@ var Framework = {
4654
4562
  * Generate globally unique ID.
4655
4563
  */
4656
4564
  guid: generateId,
4657
- /**
4658
- * Proxy-based debug guard.
4659
- */
4660
- guard: safeguard,
4661
4565
  /**
4662
4566
  * Cache class.
4663
4567
  */
@@ -4878,8 +4782,8 @@ function bindStore(view, store, selector) {
4878
4782
  markRouterBooted,
4879
4783
  nextCounter,
4880
4784
  registerViewClass,
4785
+ reloadViews,
4881
4786
  resetProjectsMap,
4882
- safeguard,
4883
4787
  unmark,
4884
4788
  use,
4885
4789
  useUrlState,