@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.js CHANGED
@@ -21,7 +21,6 @@ var MATH_NS = "http://www.w3.org/1998/Math/MathML";
21
21
  var TAG_NAME_REGEXP = /<([a-z][^/\0>\x20\t\r\n\f]+)/i;
22
22
  var CALL_BREAK_TIME = 48;
23
23
  var V_TEXT_NODE = 0;
24
- var TAG_STATIC_KEY = "_";
25
24
  var VDOM_NS_MAP = {
26
25
  svg: SVG_NS,
27
26
  math: MATH_NS
@@ -367,61 +366,6 @@ function unmark(host) {
367
366
  }
368
367
  }
369
368
 
370
- // src/safeguard.ts
371
- var proxiesPool = /* @__PURE__ */ new Map();
372
- var SAFEGUARD_SENTINEL = "_safe_";
373
- function safeguard(data, getter, setter, isRoot) {
374
- if (typeof window.__lark_Debug === "undefined" || !window.__lark_Debug) {
375
- return data;
376
- }
377
- if (typeof Proxy === "undefined") {
378
- return data;
379
- }
380
- if (isPrimitive(data)) {
381
- return data;
382
- }
383
- const build = (prefix, obj) => {
384
- const cacheKey = (getter || "") + "" + (setter || "");
385
- const cached = proxiesPool.get(obj);
386
- if (cached && cached.cacheKey === cacheKey) {
387
- return cached.entity;
388
- }
389
- if (Reflect.get(obj, SAFEGUARD_SENTINEL)) {
390
- return obj;
391
- }
392
- const entity = new Proxy(obj, {
393
- set(target, property, value) {
394
- if (!setter && !prefix) {
395
- throw new Error(
396
- "Avoid write back, key: " + prefix + property + " value:" + value + " more: https://github.com/hangtiancheng/lark"
397
- );
398
- }
399
- Reflect.set(target, property, value);
400
- if (setter) {
401
- setter(prefix + property, value);
402
- }
403
- return true;
404
- },
405
- get(target, property) {
406
- if (property === SAFEGUARD_SENTINEL) {
407
- return true;
408
- }
409
- const out = Reflect.get(target, property);
410
- if (!prefix && getter) {
411
- getter(property);
412
- }
413
- if (!isRoot && hasOwnProperty(target, property) && (Array.isArray(out) || isPlainObject(out))) {
414
- return build(prefix + property + ".", out);
415
- }
416
- return out;
417
- }
418
- });
419
- proxiesPool.set(obj, { cacheKey, entity });
420
- return entity;
421
- };
422
- return build("", data);
423
- }
424
-
425
369
  // src/cache.ts
426
370
  function sortCacheEntries(a, b) {
427
371
  return b.frequency - a.frequency || b.lastTimestamp - a.lastTimestamp;
@@ -697,7 +641,6 @@ var keyRefCounts = {};
697
641
  var changedKeys = /* @__PURE__ */ new Set();
698
642
  var stashedChangedKeys = EMPTY_STRING_SET;
699
643
  var dataIsChanged = false;
700
- var dataWhereSet = {};
701
644
  var emitter = new EventEmitter();
702
645
  var booted = false;
703
646
  function markBooted() {
@@ -721,47 +664,16 @@ function teardownKeysRef(keyList) {
721
664
  if (count <= 0) {
722
665
  Reflect.deleteProperty(keyRefCounts, key);
723
666
  Reflect.deleteProperty(appData, key);
724
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
725
- Reflect.deleteProperty(dataWhereSet, key);
726
- }
727
667
  }
728
668
  }
729
669
  }
730
670
  }
731
- var warnedKeys = /* @__PURE__ */ new Set();
732
- function clearNotify(key) {
733
- warnedKeys.delete(key);
734
- }
735
- function delayNotify(key, message) {
736
- if (warnedKeys.has(key)) return;
737
- warnedKeys.add(key);
738
- console.warn(message);
739
- }
740
671
  var State = {
741
672
  /**
742
673
  * Get data from state.
743
674
  */
744
675
  get(key) {
745
676
  const result = key ? appData[key] : appData;
746
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
747
- return safeguard(
748
- result,
749
- (dataKey) => {
750
- if (booted && hasOwnProperty(dataWhereSet, dataKey) && dataWhereSet[dataKey] !== window.location.pathname) {
751
- console.warn(
752
- `beware! You get state:"{State}.${dataKey}" where it set by page:${dataWhereSet[dataKey]}`
753
- );
754
- }
755
- },
756
- (path, _value) => {
757
- const sub = key || path;
758
- delayNotify(
759
- sub,
760
- `beware! You direct modify "{State}.${sub}" You should call State.set() and State.digest() to notify other views`
761
- );
762
- }
763
- );
764
- }
765
677
  return result;
766
678
  },
767
679
  /**
@@ -769,11 +681,6 @@ var State = {
769
681
  */
770
682
  set(data, excludes) {
771
683
  dataIsChanged = setData(data, appData, changedKeys, excludes || EMPTY_STRING_SET) || dataIsChanged;
772
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && booted) {
773
- for (const p in data) {
774
- dataWhereSet[p] = window.location.pathname;
775
- }
776
- }
777
684
  return State;
778
685
  },
779
686
  /**
@@ -784,11 +691,6 @@ var State = {
784
691
  State.set(data, excludes);
785
692
  }
786
693
  if (dataIsChanged) {
787
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
788
- for (const p of changedKeys) {
789
- clearNotify(p);
790
- }
791
- }
792
694
  dataIsChanged = false;
793
695
  const keys2 = changedKeys;
794
696
  stashedChangedKeys = keys2;
@@ -1030,9 +932,6 @@ var Router = {
1030
932
  attachViewAndPath(location);
1031
933
  hrefCache.set(href, location);
1032
934
  }
1033
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
1034
- location["params"] = safeguard(location["params"]);
1035
- }
1036
935
  return location;
1037
936
  },
1038
937
  /**
@@ -1051,9 +950,6 @@ var Router = {
1051
950
  emitter2.fire(RouterEvents.CHANGED, asRecord(lastChanged));
1052
951
  }
1053
952
  silent = 0;
1054
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && lastChanged) {
1055
- lastChanged = safeguard(lastChanged);
1056
- }
1057
953
  return lastChanged;
1058
954
  },
1059
955
  /**
@@ -1810,6 +1706,13 @@ function vdomCreate(tag, props, children, specials) {
1810
1706
  reused[c.compareKey] = (reused[c.compareKey] || 0) + 1;
1811
1707
  reusedTotal++;
1812
1708
  }
1709
+ if (c.reused) {
1710
+ if (!reused) reused = {};
1711
+ for (const key in c.reused) {
1712
+ reused[key] = (reused[key] || 0) + c.reused[key];
1713
+ reusedTotal += c.reused[key];
1714
+ }
1715
+ }
1813
1716
  if (c.views) {
1814
1717
  if (!viewList) viewList = [];
1815
1718
  viewList.push(...c.views);
@@ -1827,7 +1730,7 @@ function vdomCreate(tag, props, children, specials) {
1827
1730
  } else if (value === true) {
1828
1731
  propsObj[prop] = value = specialsObj[prop] ? value : "";
1829
1732
  }
1830
- if ((prop === "#" || prop === "id" || prop === TAG_STATIC_KEY) && !compareKey) {
1733
+ if ((prop === "#" || prop === "id") && !compareKey) {
1831
1734
  compareKey = value;
1832
1735
  if (prop !== "id") {
1833
1736
  delete propsObj[prop];
@@ -1874,18 +1777,6 @@ function vdomCreate(tag, props, children, specials) {
1874
1777
  function isSameVDomNode(a, b) {
1875
1778
  return a.compareKey && b.compareKey === a.compareKey || !a.compareKey && !b.compareKey && a.tag === b.tag || a.tag === SPLITTER || b.tag === SPLITTER;
1876
1779
  }
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;
1888
- }
1889
1780
  function vdomCreateNode(vnode, owner, ref) {
1890
1781
  const tag = vnode.tag;
1891
1782
  if (tag === V_TEXT_NODE) {
@@ -1974,9 +1865,10 @@ function vdomSetNode(realNode, oldParent, lastVDom, newVDom, ref, frame, keys2,
1974
1865
  return;
1975
1866
  }
1976
1867
  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"]) {
1868
+ if (lastVDom.attrs === newVDom.attrs && lastVDom.html === newVDom.html) {
1869
+ if (newVDom.hasSpecials) {
1870
+ vdomSyncFormState(realNode, newVDom);
1871
+ }
1980
1872
  return;
1981
1873
  }
1982
1874
  let attrChanged = 0;
@@ -2017,261 +1909,209 @@ function vdomSetNode(realNode, oldParent, lastVDom, newVDom, ref, frame, keys2,
2017
1909
  oldParent.replaceChild(vdomCreateNode(newVDom, oldParent, ref), realNode);
2018
1910
  }
2019
1911
  }
1912
+ function computeLIS(sequence) {
1913
+ const len = sequence.length;
1914
+ if (len === 0) return [];
1915
+ const result = [];
1916
+ const tails = [];
1917
+ const predecessors = new Array(len);
1918
+ let lisLength = 0;
1919
+ for (let i = 0; i < len; i++) {
1920
+ const value = sequence[i];
1921
+ if (value < 0) continue;
1922
+ let lo = 0;
1923
+ let hi = lisLength;
1924
+ while (lo < hi) {
1925
+ const mid = lo + hi >>> 1;
1926
+ if (sequence[tails[mid]] < value) lo = mid + 1;
1927
+ else hi = mid;
1928
+ }
1929
+ tails[lo] = i;
1930
+ predecessors[i] = lo > 0 ? tails[lo - 1] : -1;
1931
+ if (lo === lisLength) lisLength++;
1932
+ }
1933
+ let cursor = tails[lisLength - 1];
1934
+ for (let i = lisLength - 1; i >= 0; i--) {
1935
+ result[i] = cursor;
1936
+ cursor = predecessors[cursor];
1937
+ }
1938
+ return result;
1939
+ }
2020
1940
  function vdomSetChildNodes(realNode, lastVDom, newVDom, ref, frame, keys2, view, ready) {
2021
1941
  if (!lastVDom) {
2022
1942
  ref.changed = 1;
2023
1943
  realNode.innerHTML = newVDom.html;
1944
+ callFunction(ready, []);
2024
1945
  return;
2025
1946
  }
2026
1947
  if (lastVDom.html === newVDom.html) {
1948
+ callFunction(ready, []);
2027
1949
  return;
2028
1950
  }
2029
1951
  const oldChildren = lastVDom.children;
2030
1952
  const newChildren = newVDom.children;
2031
1953
  const oldLen = oldChildren?.length || 0;
2032
1954
  const newLen = newChildren?.length || 0;
2033
- if (oldLen === 0 && newLen === 0) return;
1955
+ if (oldLen === 0 && newLen === 0) {
1956
+ callFunction(ready, []);
1957
+ return;
1958
+ }
2034
1959
  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];
1960
+ const oldDomNodes = new Array(oldLen);
1961
+ for (let i = 0; i < oldLen; i++) {
1962
+ oldDomNodes[i] = nodes[i];
1963
+ }
1964
+ const usedOldDomNodes = /* @__PURE__ */ new Set();
1965
+ let headIdx = 0;
1966
+ let tailIdx = oldLen - 1;
1967
+ let newHead = 0;
1968
+ let newTail = newLen - 1;
1969
+ while (headIdx <= tailIdx && newHead <= newTail) {
1970
+ const oc = oldChildren[headIdx];
1971
+ const nc = newChildren[newHead];
1972
+ if (!isSameVDomNode(nc, oc)) break;
1973
+ if (nc.tag === SPLITTER || oc.tag === SPLITTER) break;
1974
+ vdomSetNode(
1975
+ oldDomNodes[headIdx],
1976
+ realNode,
1977
+ oc,
1978
+ nc,
1979
+ ref,
1980
+ frame,
1981
+ keys2,
1982
+ view,
1983
+ ready
1984
+ );
1985
+ usedOldDomNodes.add(oldDomNodes[headIdx]);
1986
+ headIdx++;
1987
+ newHead++;
1988
+ }
1989
+ while (headIdx <= tailIdx && newHead <= newTail) {
1990
+ const oc = oldChildren[tailIdx];
1991
+ const nc = newChildren[newTail];
1992
+ if (!isSameVDomNode(nc, oc)) break;
1993
+ if (nc.tag === SPLITTER || oc.tag === SPLITTER) break;
1994
+ vdomSetNode(
1995
+ oldDomNodes[tailIdx],
1996
+ realNode,
1997
+ oc,
1998
+ nc,
1999
+ ref,
2000
+ frame,
2001
+ keys2,
2002
+ view,
2003
+ ready
2004
+ );
2005
+ usedOldDomNodes.add(oldDomNodes[tailIdx]);
2006
+ tailIdx--;
2007
+ newTail--;
2008
+ }
2009
+ if (headIdx > tailIdx && newHead > newTail) {
2010
+ if (ref.asyncCount === 0) callFunction(ready, []);
2011
+ return;
2012
+ }
2013
+ const keyMap = {};
2014
+ for (let i = headIdx; i <= tailIdx; i++) {
2015
+ const c = oldChildren[i];
2016
+ if (c?.compareKey) {
2017
+ if (!keyMap[c.compareKey]) keyMap[c.compareKey] = [];
2018
+ keyMap[c.compareKey].push({ domNode: oldDomNodes[i], vdomNode: c });
2019
+ }
2020
+ }
2021
+ const newRemaining = newTail - newHead + 1;
2022
+ const sequence = new Array(newRemaining);
2023
+ for (let i = 0; i < newRemaining; i++) {
2024
+ const nc = newChildren[newHead + i];
2025
+ const cKey = nc.compareKey;
2026
+ const entries = cKey ? keyMap[cKey] : void 0;
2027
+ if (entries && entries.length > 0) {
2028
+ const entry = entries.shift();
2029
+ if (entries.length === 0) delete keyMap[cKey];
2030
+ const oldIdx = oldChildren.indexOf(entry.vdomNode, headIdx);
2031
+ sequence[i] = oldIdx >= 0 ? oldIdx : -1;
2032
+ usedOldDomNodes.add(entry.domNode);
2165
2033
  } 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) {
2034
+ sequence[i] = -1;
2035
+ }
2036
+ }
2037
+ if (newHead > newTail) {
2038
+ for (let i = 0; i < oldLen; i++) {
2039
+ const domNode = oldDomNodes[i];
2040
+ if (domNode && !usedOldDomNodes.has(domNode) && domNode.parentNode === realNode) {
2041
+ domUnmountFrames(frame, domNode);
2212
2042
  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
- );
2043
+ realNode.removeChild(domNode);
2229
2044
  }
2230
- realStart++;
2231
- oldStartNode = oldChildren?.[++oldStart];
2232
- newStartNode = newChildren?.[++newStart];
2233
2045
  }
2046
+ if (ref.asyncCount === 0) callFunction(ready, []);
2047
+ return;
2234
2048
  }
2235
- if (newStart <= newEnd) {
2236
- const refNode = nodes[realEnd + 1] || null;
2237
- for (let i = newStart; i <= newEnd; i++) {
2049
+ if (headIdx > tailIdx) {
2050
+ const insertRef = tailIdx < oldLen ? oldDomNodes[tailIdx + 1] ?? null : null;
2051
+ for (let i = newHead; i <= newTail; i++) {
2052
+ ref.changed = 1;
2053
+ const newNode = vdomCreateNode(newChildren[i], realNode, ref);
2054
+ realNode.insertBefore(newNode, insertRef);
2055
+ }
2056
+ if (ref.asyncCount === 0) callFunction(ready, []);
2057
+ return;
2058
+ }
2059
+ const lis = computeLIS(sequence);
2060
+ let lisCursor = lis.length - 1;
2061
+ let nextNode = tailIdx + 1 < oldLen ? oldDomNodes[tailIdx + 1] : null;
2062
+ for (let j = newRemaining - 1; j >= 0; j--) {
2063
+ const newIdx = newHead + j;
2064
+ const nc = newChildren[newIdx];
2065
+ if (lisCursor >= 0 && lis[lisCursor] === j) {
2066
+ const oldIdx = sequence[j];
2067
+ vdomSetNode(
2068
+ oldDomNodes[oldIdx],
2069
+ realNode,
2070
+ oldChildren[oldIdx],
2071
+ nc,
2072
+ ref,
2073
+ frame,
2074
+ keys2,
2075
+ view,
2076
+ ready
2077
+ );
2078
+ nextNode = oldDomNodes[oldIdx];
2079
+ lisCursor--;
2080
+ } else if (sequence[j] >= 0) {
2081
+ const oldIdx = sequence[j];
2082
+ ref.changed = 1;
2083
+ realNode.insertBefore(oldDomNodes[oldIdx], nextNode);
2084
+ vdomSetNode(
2085
+ oldDomNodes[oldIdx],
2086
+ realNode,
2087
+ oldChildren[oldIdx],
2088
+ nc,
2089
+ ref,
2090
+ frame,
2091
+ keys2,
2092
+ view,
2093
+ ready
2094
+ );
2095
+ nextNode = oldDomNodes[oldIdx];
2096
+ } else {
2238
2097
  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
2098
  const newNode = vdomCreateNode(nc, realNode, ref);
2246
- realNode.insertBefore(newNode, refNode);
2099
+ realNode.insertBefore(newNode, nextNode);
2100
+ nextNode = newNode;
2247
2101
  }
2248
2102
  }
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
- }
2103
+ for (let i = 0; i < oldLen; i++) {
2104
+ const domNode = oldDomNodes[i];
2105
+ if (domNode && !usedOldDomNodes.has(domNode) && domNode.parentNode === realNode) {
2106
+ domUnmountFrames(frame, domNode);
2107
+ ref.changed = 1;
2108
+ realNode.removeChild(domNode);
2257
2109
  }
2258
2110
  }
2259
2111
  if (ref.asyncCount === 0) {
2260
2112
  callFunction(ready, []);
2261
2113
  }
2262
2114
  }
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
2115
  function createVDomRef(viewId) {
2276
2116
  return {
2277
2117
  viewId,
@@ -2324,9 +2164,6 @@ var Updater = class {
2324
2164
  if (key) {
2325
2165
  result = this.data[key];
2326
2166
  }
2327
- if (typeof window !== "undefined" && window.__lark_Debug) {
2328
- return safeguard(result);
2329
- }
2330
2167
  return result;
2331
2168
  }
2332
2169
  /**
@@ -2414,9 +2251,6 @@ var Updater = class {
2414
2251
  view,
2415
2252
  ready
2416
2253
  );
2417
- if (ref.asyncCount === 0) {
2418
- ready();
2419
- }
2420
2254
  } else {
2421
2255
  const html = template(
2422
2256
  this.data,
@@ -2515,6 +2349,63 @@ var Updater = class {
2515
2349
  }
2516
2350
  };
2517
2351
 
2352
+ // src/view-registry.ts
2353
+ var viewClassRegistry = {};
2354
+ function getViewClass(path) {
2355
+ return viewClassRegistry[path];
2356
+ }
2357
+ function registerViewClass(viewPath, ViewClass) {
2358
+ const parsed = parseUri(viewPath);
2359
+ const path = parsed.path;
2360
+ if (path) {
2361
+ viewClassRegistry[path] = ViewClass;
2362
+ }
2363
+ }
2364
+ function invalidateViewClass(viewPath) {
2365
+ const parsed = parseUri(viewPath);
2366
+ const path = parsed.path;
2367
+ if (path) {
2368
+ Reflect.deleteProperty(viewClassRegistry, path);
2369
+ }
2370
+ }
2371
+ function getViewClassRegistry() {
2372
+ return viewClassRegistry;
2373
+ }
2374
+
2375
+ // src/hmr.ts
2376
+ function reloadViews(viewPath) {
2377
+ const allFrames = Frame.getAll();
2378
+ const toReload = [];
2379
+ for (const [, frame] of allFrames) {
2380
+ if (frame.viewPath) {
2381
+ const parsed = parseUri(frame.viewPath);
2382
+ if (parsed.path === viewPath) {
2383
+ toReload.push({ frame, fullPath: frame.viewPath });
2384
+ }
2385
+ }
2386
+ }
2387
+ for (const { frame, fullPath } of toReload) {
2388
+ frame.mountView(fullPath);
2389
+ }
2390
+ }
2391
+ function acceptView(hot, viewPath) {
2392
+ hot.accept((newModule) => {
2393
+ const candidate = newModule?.default ?? newModule;
2394
+ if (typeof candidate === "function") {
2395
+ const NewViewClass = candidate;
2396
+ registerViewClass(viewPath, NewViewClass);
2397
+ reloadViews(viewPath);
2398
+ } else {
2399
+ hot.invalidate();
2400
+ }
2401
+ });
2402
+ }
2403
+ function disposeView(hot, viewPath) {
2404
+ hot.dispose(() => {
2405
+ invalidateViewClass(viewPath);
2406
+ });
2407
+ }
2408
+
2518
2409
  // src/view.ts
2519
2410
  var VIEW_GLOBALS = {};
2520
2411
  if (typeof window !== "undefined") {
@@ -3105,34 +2996,51 @@ var View = class _View {
3105
2996
  _View.mergeMixins(mixins, this, existingCtors);
3106
2997
  return this;
3107
2998
  }
2999
+ // ============================================================
3000
+ // HMR support (static accept / dispose)
3001
+ // ============================================================
3002
+ /**
3003
+ * Set up HMR accept handler for this view module.
3004
+ *
3005
+ * When the module is hot-replaced, the new View class is extracted from
3006
+ * the new module, registered in the view registry, and all currently
3007
+ * mounted frames using this viewPath are re-mounted.
3008
+ *
3009
+ * No-op when `hot` is undefined (production / non-HMR environment).
3010
+ *
3011
+ * ```ts
3012
+ * if (import.meta.hot) {
3013
+ * HomeView.accept(import.meta.hot, 'home');
3014
+ * }
3015
+ * ```
3016
+ */
3017
+ static accept(hot, viewPath) {
3018
+ if (!hot) return;
3019
+ acceptView(hot, viewPath);
3020
+ }
3021
+ /**
3022
+ * Set up HMR dispose handler for this view module.
3023
+ *
3024
+ * When the module is about to be replaced, the old View class is removed
3025
+ * from the registry so subsequent lookups don't return the stale class.
3026
+ *
3027
+ * No-op when `hot` is undefined (production / non-HMR environment).
3028
+ *
3029
+ * ```ts
3030
+ * if (import.meta.hot) {
3031
+ * HomeView.dispose(import.meta.hot, 'home');
3032
+ * }
3033
+ * ```
3034
+ */
3035
+ static dispose(hot, viewPath) {
3036
+ if (!hot) return;
3037
+ disposeView(hot, viewPath);
3038
+ }
3108
3039
  };
3109
3040
  function defineView(props, statics) {
3110
3041
  return View.extend(props, statics);
3111
3042
  }
3112
3043
 
3113
- // src/view-registry.ts
3114
- var viewClassRegistry = {};
3115
- function getViewClass(path) {
3116
- return viewClassRegistry[path];
3117
- }
3118
- function registerViewClass(viewPath, ViewClass) {
3119
- const parsed = parseUri(viewPath);
3120
- const path = parsed.path;
3121
- if (path) {
3122
- viewClassRegistry[path] = ViewClass;
3123
- }
3124
- }
3125
- function invalidateViewClass(viewPath) {
3126
- const parsed = parseUri(viewPath);
3127
- const path = parsed.path;
3128
- if (path) {
3129
- Reflect.deleteProperty(viewClassRegistry, path);
3130
- }
3131
- }
3132
- function getViewClassRegistry() {
3133
- return viewClassRegistry;
3134
- }
3135
-
3136
3044
  // src/frame.ts
3137
3045
  var frameRegistry = /* @__PURE__ */ new Map();
3138
3046
  var rootFrame;
@@ -4590,10 +4498,6 @@ var Framework = {
4590
4498
  * Generate globally unique ID.
4591
4499
  */
4592
4500
  guid: generateId,
4593
- /**
4594
- * Proxy-based debug guard.
4595
- */
4596
- guard: safeguard,
4597
4501
  /**
4598
4502
  * Cache class.
4599
4503
  */
@@ -4813,8 +4717,8 @@ export {
4813
4717
  markRouterBooted,
4814
4718
  nextCounter,
4815
4719
  registerViewClass,
4720
+ reloadViews,
4816
4721
  resetProjectsMap,
4817
- safeguard,
4818
4722
  unmark,
4819
4723
  use,
4820
4724
  useUrlState,