@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/devtool.cjs CHANGED
@@ -785,61 +785,6 @@ var EventDelegator = {
785
785
  }
786
786
  };
787
787
 
788
- // src/safeguard.ts
789
- var proxiesPool = /* @__PURE__ */ new Map();
790
- var SAFEGUARD_SENTINEL = "_safe_";
791
- function safeguard(data, getter, setter, isRoot) {
792
- if (typeof window.__lark_Debug === "undefined" || !window.__lark_Debug) {
793
- return data;
794
- }
795
- if (typeof Proxy === "undefined") {
796
- return data;
797
- }
798
- if (isPrimitive(data)) {
799
- return data;
800
- }
801
- const build = (prefix, obj) => {
802
- const cacheKey = (getter || "") + "" + (setter || "");
803
- const cached = proxiesPool.get(obj);
804
- if (cached && cached.cacheKey === cacheKey) {
805
- return cached.entity;
806
- }
807
- if (Reflect.get(obj, SAFEGUARD_SENTINEL)) {
808
- return obj;
809
- }
810
- const entity = new Proxy(obj, {
811
- set(target, property, value) {
812
- if (!setter && !prefix) {
813
- throw new Error(
814
- "Avoid write back, key: " + prefix + property + " value:" + value + " more: https://github.com/hangtiancheng/lark"
815
- );
816
- }
817
- Reflect.set(target, property, value);
818
- if (setter) {
819
- setter(prefix + property, value);
820
- }
821
- return true;
822
- },
823
- get(target, property) {
824
- if (property === SAFEGUARD_SENTINEL) {
825
- return true;
826
- }
827
- const out = Reflect.get(target, property);
828
- if (!prefix && getter) {
829
- getter(property);
830
- }
831
- if (!isRoot && hasOwnProperty(target, property) && (Array.isArray(out) || isPlainObject(out))) {
832
- return build(prefix + property + ".", out);
833
- }
834
- return out;
835
- }
836
- });
837
- proxiesPool.set(obj, { cacheKey, entity });
838
- return entity;
839
- };
840
- return build("", data);
841
- }
842
-
843
788
  // src/module-loader.ts
844
789
  var config = {
845
790
  rootId: "root",
@@ -1157,18 +1102,6 @@ var DOM_SPECIALS = {
1157
1102
  function isSameVDomNode(a, b) {
1158
1103
  return a.compareKey && b.compareKey === a.compareKey || !a.compareKey && !b.compareKey && a.tag === b.tag || a.tag === SPLITTER || b.tag === SPLITTER;
1159
1104
  }
1160
- function getKeyNodes(list, nodes, start, end, realEnd) {
1161
- const keyedNodes = {};
1162
- for (let i = end, re = realEnd; i >= start; i--, re--) {
1163
- const oc = list[i];
1164
- const cKey = oc.compareKey;
1165
- if (cKey) {
1166
- const bucket = keyedNodes[cKey] || (keyedNodes[cKey] = []);
1167
- bucket.push(nodes[re]);
1168
- }
1169
- }
1170
- return keyedNodes;
1171
- }
1172
1105
  function vdomCreateNode(vnode, owner, ref) {
1173
1106
  const tag = vnode.tag;
1174
1107
  if (tag === V_TEXT_NODE) {
@@ -1257,9 +1190,10 @@ function vdomSetNode(realNode, oldParent, lastVDom, newVDom, ref, frame, keys, r
1257
1190
  return;
1258
1191
  }
1259
1192
  if (lastTag === newTag) {
1260
- const lastAMap = lastVDom.attrsMap || {};
1261
- const newAMap = newVDom.attrsMap || {};
1262
- if (lastVDom.compareKey && lastVDom.compareKey === newVDom.compareKey && !lastAMap["id"] && !newAMap["id"]) {
1193
+ if (lastVDom.attrs === newVDom.attrs && lastVDom.html === newVDom.html) {
1194
+ if (newVDom.hasSpecials) {
1195
+ vdomSyncFormState(realNode, newVDom);
1196
+ }
1263
1197
  return;
1264
1198
  }
1265
1199
  let attrChanged = 0;
@@ -1300,261 +1234,209 @@ function vdomSetNode(realNode, oldParent, lastVDom, newVDom, ref, frame, keys, r
1300
1234
  oldParent.replaceChild(vdomCreateNode(newVDom, oldParent, ref), realNode);
1301
1235
  }
1302
1236
  }
1237
+ function computeLIS(sequence) {
1238
+ const len = sequence.length;
1239
+ if (len === 0) return [];
1240
+ const result = [];
1241
+ const tails = [];
1242
+ const predecessors = new Array(len);
1243
+ let lisLength = 0;
1244
+ for (let i = 0; i < len; i++) {
1245
+ const value = sequence[i];
1246
+ if (value < 0) continue;
1247
+ let lo = 0;
1248
+ let hi = lisLength;
1249
+ while (lo < hi) {
1250
+ const mid = lo + hi >>> 1;
1251
+ if (sequence[tails[mid]] < value) lo = mid + 1;
1252
+ else hi = mid;
1253
+ }
1254
+ tails[lo] = i;
1255
+ predecessors[i] = lo > 0 ? tails[lo - 1] : -1;
1256
+ if (lo === lisLength) lisLength++;
1257
+ }
1258
+ let cursor = tails[lisLength - 1];
1259
+ for (let i = lisLength - 1; i >= 0; i--) {
1260
+ result[i] = cursor;
1261
+ cursor = predecessors[cursor];
1262
+ }
1263
+ return result;
1264
+ }
1303
1265
  function vdomSetChildNodes(realNode, lastVDom, newVDom, ref, frame, keys, view, ready) {
1304
1266
  if (!lastVDom) {
1305
1267
  ref.changed = 1;
1306
1268
  realNode.innerHTML = newVDom.html;
1269
+ callFunction(ready, []);
1307
1270
  return;
1308
1271
  }
1309
1272
  if (lastVDom.html === newVDom.html) {
1273
+ callFunction(ready, []);
1310
1274
  return;
1311
1275
  }
1312
1276
  const oldChildren = lastVDom.children;
1313
1277
  const newChildren = newVDom.children;
1314
1278
  const oldLen = oldChildren?.length || 0;
1315
1279
  const newLen = newChildren?.length || 0;
1316
- if (oldLen === 0 && newLen === 0) return;
1280
+ if (oldLen === 0 && newLen === 0) {
1281
+ callFunction(ready, []);
1282
+ return;
1283
+ }
1317
1284
  const nodes = realNode.childNodes;
1318
- let oldStart = 0;
1319
- let oldEnd = oldLen - 1;
1320
- let newStart = 0;
1321
- let newEnd = newLen - 1;
1322
- let realStart = oldStart;
1323
- let realEnd = oldEnd;
1324
- let keyedNodes;
1325
- const oldReusedTotal = lastVDom.reusedTotal || 0;
1326
- const newReusedTotal = newVDom.reusedTotal || 0;
1327
- let oldStartNode = oldChildren?.[oldStart];
1328
- let oldEndNode = oldChildren?.[oldEnd];
1329
- let newStartNode = newChildren?.[newStart];
1330
- let newEndNode = newChildren?.[newEnd];
1331
- while (oldStart <= oldEnd && newStart <= newEnd) {
1332
- if (!oldStartNode) {
1333
- oldStartNode = oldChildren?.[++oldStart];
1334
- realStart++;
1335
- continue;
1336
- }
1337
- if (!oldEndNode) {
1338
- oldEndNode = oldChildren?.[--oldEnd];
1339
- realEnd--;
1340
- continue;
1341
- }
1342
- if (isSameVDomNode(newStartNode, oldStartNode)) {
1343
- if (newStartNode.tag === SPLITTER || oldStartNode.tag === SPLITTER) {
1344
- ref.changed = 1;
1345
- domUnmountFrames(frame, realNode);
1346
- if (newStartNode.tag === SPLITTER) {
1347
- realNode.innerHTML = newStartNode.html;
1348
- } else {
1349
- realNode.innerHTML = "";
1350
- realNode.appendChild(vdomCreateNode(newStartNode, realNode, ref));
1351
- }
1352
- } else {
1353
- vdomSetNode(
1354
- nodes[realStart],
1355
- realNode,
1356
- oldStartNode,
1357
- newStartNode,
1358
- ref,
1359
- frame,
1360
- keys,
1361
- view,
1362
- ready
1363
- );
1364
- }
1365
- reduceCached(keyedNodes, oldStartNode, nodes[realStart]);
1366
- realStart++;
1367
- oldStartNode = oldChildren?.[++oldStart];
1368
- newStartNode = newChildren?.[++newStart];
1369
- } else if (isSameVDomNode(newEndNode, oldEndNode)) {
1370
- if (newEndNode.tag === SPLITTER || oldEndNode.tag === SPLITTER) {
1371
- ref.changed = 1;
1372
- domUnmountFrames(frame, realNode);
1373
- realNode.innerHTML = newEndNode.tag === SPLITTER ? newEndNode.html : "";
1374
- if (newEndNode.tag !== SPLITTER) {
1375
- realNode.appendChild(vdomCreateNode(newEndNode, realNode, ref));
1376
- }
1377
- } else {
1378
- vdomSetNode(
1379
- nodes[realEnd],
1380
- realNode,
1381
- oldEndNode,
1382
- newEndNode,
1383
- ref,
1384
- frame,
1385
- keys,
1386
- view,
1387
- ready
1388
- );
1389
- }
1390
- reduceCached(keyedNodes, oldEndNode, nodes[realEnd]);
1391
- realEnd--;
1392
- oldEndNode = oldChildren?.[--oldEnd];
1393
- newEndNode = newChildren?.[--newEnd];
1394
- } else if (isSameVDomNode(newEndNode, oldStartNode)) {
1395
- if (newEndNode.tag === SPLITTER || oldStartNode.tag === SPLITTER) {
1396
- ref.changed = 1;
1397
- domUnmountFrames(frame, realNode);
1398
- realNode.innerHTML = newEndNode.tag === SPLITTER ? newEndNode.html : "";
1399
- if (newEndNode.tag !== SPLITTER) {
1400
- realNode.appendChild(vdomCreateNode(newEndNode, realNode, ref));
1401
- }
1402
- } else {
1403
- const oi = nodes[realStart];
1404
- realNode.insertBefore(oi, nodes[realEnd + 1] || null);
1405
- vdomSetNode(
1406
- oi,
1407
- realNode,
1408
- oldStartNode,
1409
- newEndNode,
1410
- ref,
1411
- frame,
1412
- keys,
1413
- view,
1414
- ready
1415
- );
1416
- }
1417
- reduceCached(keyedNodes, oldStartNode, nodes[realStart]);
1418
- realStart++;
1419
- oldStartNode = oldChildren?.[++oldStart];
1420
- newEndNode = newChildren?.[--newEnd];
1421
- } else if (isSameVDomNode(newStartNode, oldEndNode)) {
1422
- if (newStartNode.tag === SPLITTER || oldEndNode.tag === SPLITTER) {
1423
- ref.changed = 1;
1424
- domUnmountFrames(frame, realNode);
1425
- realNode.innerHTML = newStartNode.tag === SPLITTER ? newStartNode.html : "";
1426
- if (newStartNode.tag !== SPLITTER) {
1427
- realNode.appendChild(vdomCreateNode(newStartNode, realNode, ref));
1428
- }
1429
- } else {
1430
- const oi = nodes[realEnd];
1431
- realNode.insertBefore(oi, nodes[realStart]);
1432
- vdomSetNode(
1433
- oi,
1434
- realNode,
1435
- oldEndNode,
1436
- newStartNode,
1437
- ref,
1438
- frame,
1439
- keys,
1440
- view,
1441
- ready
1442
- );
1443
- }
1444
- reduceCached(keyedNodes, oldEndNode, nodes[realEnd]);
1445
- realEnd--;
1446
- oldEndNode = oldChildren?.[--oldEnd];
1447
- newStartNode = newChildren?.[++newStart];
1285
+ const oldDomNodes = new Array(oldLen);
1286
+ for (let i = 0; i < oldLen; i++) {
1287
+ oldDomNodes[i] = nodes[i];
1288
+ }
1289
+ const usedOldDomNodes = /* @__PURE__ */ new Set();
1290
+ let headIdx = 0;
1291
+ let tailIdx = oldLen - 1;
1292
+ let newHead = 0;
1293
+ let newTail = newLen - 1;
1294
+ while (headIdx <= tailIdx && newHead <= newTail) {
1295
+ const oc = oldChildren[headIdx];
1296
+ const nc = newChildren[newHead];
1297
+ if (!isSameVDomNode(nc, oc)) break;
1298
+ if (nc.tag === SPLITTER || oc.tag === SPLITTER) break;
1299
+ vdomSetNode(
1300
+ oldDomNodes[headIdx],
1301
+ realNode,
1302
+ oc,
1303
+ nc,
1304
+ ref,
1305
+ frame,
1306
+ keys,
1307
+ view,
1308
+ ready
1309
+ );
1310
+ usedOldDomNodes.add(oldDomNodes[headIdx]);
1311
+ headIdx++;
1312
+ newHead++;
1313
+ }
1314
+ while (headIdx <= tailIdx && newHead <= newTail) {
1315
+ const oc = oldChildren[tailIdx];
1316
+ const nc = newChildren[newTail];
1317
+ if (!isSameVDomNode(nc, oc)) break;
1318
+ if (nc.tag === SPLITTER || oc.tag === SPLITTER) break;
1319
+ vdomSetNode(
1320
+ oldDomNodes[tailIdx],
1321
+ realNode,
1322
+ oc,
1323
+ nc,
1324
+ ref,
1325
+ frame,
1326
+ keys,
1327
+ view,
1328
+ ready
1329
+ );
1330
+ usedOldDomNodes.add(oldDomNodes[tailIdx]);
1331
+ tailIdx--;
1332
+ newTail--;
1333
+ }
1334
+ if (headIdx > tailIdx && newHead > newTail) {
1335
+ if (ref.asyncCount === 0) callFunction(ready, []);
1336
+ return;
1337
+ }
1338
+ const keyMap = {};
1339
+ for (let i = headIdx; i <= tailIdx; i++) {
1340
+ const c = oldChildren[i];
1341
+ if (c?.compareKey) {
1342
+ if (!keyMap[c.compareKey]) keyMap[c.compareKey] = [];
1343
+ keyMap[c.compareKey].push({ domNode: oldDomNodes[i], vdomNode: c });
1344
+ }
1345
+ }
1346
+ const newRemaining = newTail - newHead + 1;
1347
+ const sequence = new Array(newRemaining);
1348
+ for (let i = 0; i < newRemaining; i++) {
1349
+ const nc = newChildren[newHead + i];
1350
+ const cKey = nc.compareKey;
1351
+ const entries = cKey ? keyMap[cKey] : void 0;
1352
+ if (entries && entries.length > 0) {
1353
+ const entry = entries.shift();
1354
+ if (entries.length === 0) delete keyMap[cKey];
1355
+ const oldIdx = oldChildren.indexOf(entry.vdomNode, headIdx);
1356
+ sequence[i] = oldIdx >= 0 ? oldIdx : -1;
1357
+ usedOldDomNodes.add(entry.domNode);
1448
1358
  } else {
1449
- if (!keyedNodes && newReusedTotal > 0 && oldReusedTotal > 0) {
1450
- keyedNodes = getKeyNodes(
1451
- oldChildren,
1452
- nodes,
1453
- oldStart,
1454
- oldEnd,
1455
- realEnd
1456
- );
1457
- }
1458
- const cKey = newStartNode.compareKey;
1459
- let found;
1460
- let compareKey;
1461
- if (cKey && keyedNodes) {
1462
- found = keyedNodes[cKey];
1463
- compareKey = void 0;
1464
- while (found && found.length > 0) {
1465
- compareKey = found.pop();
1466
- if (compareKey) break;
1467
- }
1468
- if (found && found.length === 0) delete keyedNodes[cKey];
1469
- }
1470
- if (compareKey) {
1471
- if (compareKey !== nodes[realStart]) {
1472
- for (let j = oldStart + 1; j <= oldEnd; j++) {
1473
- const oc = oldChildren?.[j];
1474
- if (oc && nodes[realStart + (j - oldStart)] === compareKey) {
1475
- oldChildren[j] = void 0;
1476
- break;
1477
- }
1478
- }
1479
- realNode.insertBefore(compareKey, nodes[realStart]);
1480
- }
1481
- vdomSetNode(
1482
- compareKey,
1483
- realNode,
1484
- oldStartNode,
1485
- newStartNode,
1486
- ref,
1487
- frame,
1488
- keys,
1489
- view,
1490
- ready
1491
- );
1492
- } else if (oldStartNode.compareKey && lastVDom.reused?.[oldStartNode.compareKey] && newVDom.reused?.[oldStartNode.compareKey] || nodes[realStart]?.id && realNode.querySelectorAll?.(
1493
- `#${nodes[realStart].id}`
1494
- )?.length && !newStartNode.isLarkView) {
1359
+ sequence[i] = -1;
1360
+ }
1361
+ }
1362
+ if (newHead > newTail) {
1363
+ for (let i = 0; i < oldLen; i++) {
1364
+ const domNode = oldDomNodes[i];
1365
+ if (domNode && !usedOldDomNodes.has(domNode) && domNode.parentNode === realNode) {
1366
+ domUnmountFrames(frame, domNode);
1495
1367
  ref.changed = 1;
1496
- const newNode = vdomCreateNode(newStartNode, realNode, ref);
1497
- realNode.insertBefore(newNode, nodes[realStart]);
1498
- realStart--;
1499
- realEnd++;
1500
- } else {
1501
- vdomSetNode(
1502
- nodes[realStart],
1503
- realNode,
1504
- oldStartNode,
1505
- newStartNode,
1506
- ref,
1507
- frame,
1508
- keys,
1509
- view,
1510
- ready
1511
- );
1368
+ realNode.removeChild(domNode);
1512
1369
  }
1513
- realStart++;
1514
- oldStartNode = oldChildren?.[++oldStart];
1515
- newStartNode = newChildren?.[++newStart];
1516
1370
  }
1371
+ if (ref.asyncCount === 0) callFunction(ready, []);
1372
+ return;
1517
1373
  }
1518
- if (newStart <= newEnd) {
1519
- const refNode = nodes[realEnd + 1] || null;
1520
- for (let i = newStart; i <= newEnd; i++) {
1374
+ if (headIdx > tailIdx) {
1375
+ const insertRef = tailIdx < oldLen ? oldDomNodes[tailIdx + 1] ?? null : null;
1376
+ for (let i = newHead; i <= newTail; i++) {
1377
+ ref.changed = 1;
1378
+ const newNode = vdomCreateNode(newChildren[i], realNode, ref);
1379
+ realNode.insertBefore(newNode, insertRef);
1380
+ }
1381
+ if (ref.asyncCount === 0) callFunction(ready, []);
1382
+ return;
1383
+ }
1384
+ const lis = computeLIS(sequence);
1385
+ let lisCursor = lis.length - 1;
1386
+ let nextNode = tailIdx + 1 < oldLen ? oldDomNodes[tailIdx + 1] : null;
1387
+ for (let j = newRemaining - 1; j >= 0; j--) {
1388
+ const newIdx = newHead + j;
1389
+ const nc = newChildren[newIdx];
1390
+ if (lisCursor >= 0 && lis[lisCursor] === j) {
1391
+ const oldIdx = sequence[j];
1392
+ vdomSetNode(
1393
+ oldDomNodes[oldIdx],
1394
+ realNode,
1395
+ oldChildren[oldIdx],
1396
+ nc,
1397
+ ref,
1398
+ frame,
1399
+ keys,
1400
+ view,
1401
+ ready
1402
+ );
1403
+ nextNode = oldDomNodes[oldIdx];
1404
+ lisCursor--;
1405
+ } else if (sequence[j] >= 0) {
1406
+ const oldIdx = sequence[j];
1407
+ ref.changed = 1;
1408
+ realNode.insertBefore(oldDomNodes[oldIdx], nextNode);
1409
+ vdomSetNode(
1410
+ oldDomNodes[oldIdx],
1411
+ realNode,
1412
+ oldChildren[oldIdx],
1413
+ nc,
1414
+ ref,
1415
+ frame,
1416
+ keys,
1417
+ view,
1418
+ ready
1419
+ );
1420
+ nextNode = oldDomNodes[oldIdx];
1421
+ } else {
1521
1422
  ref.changed = 1;
1522
- const nc = newChildren[i];
1523
- if (nc.tag === SPLITTER) {
1524
- domUnmountFrames(frame, realNode);
1525
- realNode.innerHTML = nc.html;
1526
- return;
1527
- }
1528
1423
  const newNode = vdomCreateNode(nc, realNode, ref);
1529
- realNode.insertBefore(newNode, refNode);
1424
+ realNode.insertBefore(newNode, nextNode);
1425
+ nextNode = newNode;
1530
1426
  }
1531
1427
  }
1532
- if (oldStart <= oldEnd) {
1533
- for (let i = realEnd; i >= realStart; i--) {
1534
- const node = nodes[i];
1535
- if (node) {
1536
- domUnmountFrames(frame, node);
1537
- ref.changed = 1;
1538
- realNode.removeChild(node);
1539
- }
1428
+ for (let i = 0; i < oldLen; i++) {
1429
+ const domNode = oldDomNodes[i];
1430
+ if (domNode && !usedOldDomNodes.has(domNode) && domNode.parentNode === realNode) {
1431
+ domUnmountFrames(frame, domNode);
1432
+ ref.changed = 1;
1433
+ realNode.removeChild(domNode);
1540
1434
  }
1541
1435
  }
1542
1436
  if (ref.asyncCount === 0) {
1543
1437
  callFunction(ready, []);
1544
1438
  }
1545
1439
  }
1546
- function reduceCached(keyedNodes, node, compared) {
1547
- if (!keyedNodes || !node.compareKey) return;
1548
- const bucket = keyedNodes[node.compareKey];
1549
- if (bucket) {
1550
- for (let i = bucket.length; i--; ) {
1551
- if (bucket[i] === compared) {
1552
- bucket[i] = void 0;
1553
- break;
1554
- }
1555
- }
1556
- }
1557
- }
1558
1440
  function createVDomRef(viewId) {
1559
1441
  return {
1560
1442
  viewId,
@@ -1607,9 +1489,6 @@ var Updater = class {
1607
1489
  if (key) {
1608
1490
  result = this.data[key];
1609
1491
  }
1610
- if (typeof window !== "undefined" && window.__lark_Debug) {
1611
- return safeguard(result);
1612
- }
1613
1492
  return result;
1614
1493
  }
1615
1494
  /**
@@ -1697,9 +1576,6 @@ var Updater = class {
1697
1576
  view,
1698
1577
  ready
1699
1578
  );
1700
- if (ref.asyncCount === 0) {
1701
- ready();
1702
- }
1703
1579
  } else {
1704
1580
  const html = template(
1705
1581
  this.data,
@@ -1988,9 +1864,6 @@ var Router = {
1988
1864
  attachViewAndPath(location);
1989
1865
  hrefCache.set(href, location);
1990
1866
  }
1991
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
1992
- location["params"] = safeguard(location["params"]);
1993
- }
1994
1867
  return location;
1995
1868
  },
1996
1869
  /**
@@ -2009,9 +1882,6 @@ var Router = {
2009
1882
  emitter.fire(RouterEvents.CHANGED, asRecord(lastChanged));
2010
1883
  }
2011
1884
  silent = 0;
2012
- if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && lastChanged) {
2013
- lastChanged = safeguard(lastChanged);
2014
- }
2015
1885
  return lastChanged;
2016
1886
  },
2017
1887
  /**
@@ -2196,6 +2066,60 @@ var Router = {
2196
2066
  }
2197
2067
  };
2198
2068
 
2069
+ // src/view-registry.ts
2070
+ var viewClassRegistry = {};
2071
+ function getViewClass(path) {
2072
+ return viewClassRegistry[path];
2073
+ }
2074
+ function registerViewClass(viewPath, ViewClass) {
2075
+ const parsed = parseUri(viewPath);
2076
+ const path = parsed.path;
2077
+ if (path) {
2078
+ viewClassRegistry[path] = ViewClass;
2079
+ }
2080
+ }
2081
+ function invalidateViewClass(viewPath) {
2082
+ const parsed = parseUri(viewPath);
2083
+ const path = parsed.path;
2084
+ if (path) {
2085
+ Reflect.deleteProperty(viewClassRegistry, path);
2086
+ }
2087
+ }
2088
+
2089
+ // src/hmr.ts
2090
+ function reloadViews(viewPath) {
2091
+ const allFrames = Frame.getAll();
2092
+ const toReload = [];
2093
+ for (const [, frame] of allFrames) {
2094
+ if (frame.viewPath) {
2095
+ const parsed = parseUri(frame.viewPath);
2096
+ if (parsed.path === viewPath) {
2097
+ toReload.push({ frame, fullPath: frame.viewPath });
2098
+ }
2099
+ }
2100
+ }
2101
+ for (const { frame, fullPath } of toReload) {
2102
+ frame.mountView(fullPath);
2103
+ }
2104
+ }
2105
+ function acceptView(hot, viewPath) {
2106
+ hot.accept((newModule) => {
2107
+ const candidate = newModule?.default ?? newModule;
2108
+ if (typeof candidate === "function") {
2109
+ const NewViewClass = candidate;
2110
+ registerViewClass(viewPath, NewViewClass);
2111
+ reloadViews(viewPath);
2112
+ } else {
2113
+ hot.invalidate();
2114
+ }
2115
+ });
2116
+ }
2117
+ function disposeView(hot, viewPath) {
2118
+ hot.dispose(() => {
2119
+ invalidateViewClass(viewPath);
2120
+ });
2121
+ }
2122
+
2199
2123
  // src/view.ts
2200
2124
  var VIEW_GLOBALS = {};
2201
2125
  if (typeof window !== "undefined") {
@@ -2786,20 +2710,47 @@ var View = class _View {
2786
2710
  _View.mergeMixins(mixins, this, existingCtors);
2787
2711
  return this;
2788
2712
  }
2789
- };
2790
-
2791
- // src/view-registry.ts
2792
- var viewClassRegistry = {};
2793
- function getViewClass(path) {
2794
- return viewClassRegistry[path];
2795
- }
2796
- function registerViewClass(viewPath, ViewClass) {
2797
- const parsed = parseUri(viewPath);
2798
- const path = parsed.path;
2799
- if (path) {
2800
- viewClassRegistry[path] = ViewClass;
2713
+ // ============================================================
2714
+ // HMR support (static accept / dispose)
2715
+ // ============================================================
2716
+ /**
2717
+ * Set up HMR accept handler for this view module.
2718
+ *
2719
+ * When the module is hot-replaced, the new View class is extracted from
2720
+ * the new module, registered in the view registry, and all currently
2721
+ * mounted frames using this viewPath are re-mounted.
2722
+ *
2723
+ * No-op when `hot` is undefined (production / non-HMR environment).
2724
+ *
2725
+ * ```ts
2726
+ * if (import.meta.hot) {
2727
+ * HomeView.accept(import.meta.hot, 'home');
2728
+ * }
2729
+ * ```
2730
+ */
2731
+ static accept(hot, viewPath) {
2732
+ if (!hot) return;
2733
+ acceptView(hot, viewPath);
2801
2734
  }
2802
- }
2735
+ /**
2736
+ * Set up HMR dispose handler for this view module.
2737
+ *
2738
+ * When the module is about to be replaced, the old View class is removed
2739
+ * from the registry so subsequent lookups don't return the stale class.
2740
+ *
2741
+ * No-op when `hot` is undefined (production / non-HMR environment).
2742
+ *
2743
+ * ```ts
2744
+ * if (import.meta.hot) {
2745
+ * HomeView.dispose(import.meta.hot, 'home');
2746
+ * }
2747
+ * ```
2748
+ */
2749
+ static dispose(hot, viewPath) {
2750
+ if (!hot) return;
2751
+ disposeView(hot, viewPath);
2752
+ }
2753
+ };
2803
2754
 
2804
2755
  // src/frame.ts
2805
2756
  var frameRegistry = /* @__PURE__ */ new Map();