sibujs 3.1.0 → 3.2.0

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.
Files changed (78) hide show
  1. package/README.md +6 -0
  2. package/dist/browser.cjs +16 -8
  3. package/dist/browser.js +6 -5
  4. package/dist/build.cjs +235 -147
  5. package/dist/build.js +35 -24
  6. package/dist/cdn.global.js +7 -7
  7. package/dist/{chunk-WYU7CYJ3.js → chunk-2C4E3HBM.js} +5 -5
  8. package/dist/{chunk-3DYB5B3S.js → chunk-4JCAUOLN.js} +45 -23
  9. package/dist/{chunk-2HAGQWDV.js → chunk-5N74TKLD.js} +1 -1
  10. package/dist/{chunk-SVVAUX7J.js → chunk-7XDYVJLE.js} +19 -9
  11. package/dist/{chunk-2N2UL7O4.js → chunk-BGNLPNGV.js} +20 -12
  12. package/dist/{chunk-RK4BQG25.js → chunk-C427DVQF.js} +1 -1
  13. package/dist/{chunk-ZIBE2SAT.js → chunk-FDY42FIU.js} +3 -2
  14. package/dist/{chunk-GQ7RRFPU.js → chunk-FOI23UJL.js} +11 -1
  15. package/dist/{chunk-2RA7SHDA.js → chunk-GOJMFRBL.js} +20 -4
  16. package/dist/{chunk-IVOUCSZL.js → chunk-GOUM4JCT.js} +6 -6
  17. package/dist/chunk-H3SRKIYX.js +17 -0
  18. package/dist/{chunk-3DJH25UO.js → chunk-H6PCHJZQ.js} +2 -2
  19. package/dist/{chunk-UCS6AMJ7.js → chunk-HMJFCBRR.js} +26 -3
  20. package/dist/{chunk-JYD2PWXH.js → chunk-HXMS4SNP.js} +22 -15
  21. package/dist/{chunk-SC437AMI.js → chunk-JYXOEYI4.js} +12 -18
  22. package/dist/{chunk-KB3BA2XK.js → chunk-NFYWLRUO.js} +11 -18
  23. package/dist/{chunk-QNQY5DUS.js → chunk-NPIEEKPT.js} +20 -11
  24. package/dist/{chunk-UYX2NDOH.js → chunk-OYLPZO4N.js} +33 -15
  25. package/dist/{chunk-LYTCUZ7H.js → chunk-RDRSWYNP.js} +1 -1
  26. package/dist/{chunk-2ZJ7TSW4.js → chunk-RLUJL2MV.js} +4 -8
  27. package/dist/{chunk-CR4MXPHB.js → chunk-V2MTG5FT.js} +99 -36
  28. package/dist/{chunk-CNZ35WI2.js → chunk-VJE6DDYM.js} +2 -2
  29. package/dist/{chunk-PMSDFTK3.js → chunk-VOCE4NNK.js} +157 -75
  30. package/dist/{chunk-WKUXSE7V.js → chunk-X67UYC74.js} +12 -11
  31. package/dist/{chunk-EFOAE5NC.js → chunk-YFDGQWDA.js} +1 -1
  32. package/dist/{chunk-3U4ZVXVD.js → chunk-Z2FWAE4B.js} +6 -2
  33. package/dist/data.cjs +190 -94
  34. package/dist/data.d.cts +7 -1
  35. package/dist/data.d.ts +7 -1
  36. package/dist/data.js +8 -8
  37. package/dist/devtools.cjs +38 -10
  38. package/dist/devtools.d.cts +1 -1
  39. package/dist/devtools.d.ts +1 -1
  40. package/dist/devtools.js +6 -6
  41. package/dist/ecosystem.cjs +123 -63
  42. package/dist/ecosystem.js +9 -9
  43. package/dist/extras.cjs +380 -196
  44. package/dist/extras.d.cts +2 -2
  45. package/dist/extras.d.ts +2 -2
  46. package/dist/extras.js +27 -24
  47. package/dist/index.cjs +214 -136
  48. package/dist/index.d.cts +15 -2
  49. package/dist/index.d.ts +15 -2
  50. package/dist/index.js +15 -13
  51. package/dist/{introspect-BZWKvQUZ.d.ts → introspect-DOZfmC-4.d.ts} +1 -1
  52. package/dist/{introspect-DsJlDD2T.d.cts → introspect-RjLfIFpL.d.cts} +1 -1
  53. package/dist/motion.cjs +10 -0
  54. package/dist/motion.js +3 -3
  55. package/dist/patterns.cjs +45 -40
  56. package/dist/patterns.js +8 -7
  57. package/dist/performance.cjs +101 -25
  58. package/dist/performance.d.cts +2 -2
  59. package/dist/performance.d.ts +2 -2
  60. package/dist/performance.js +8 -7
  61. package/dist/plugins.cjs +203 -136
  62. package/dist/plugins.d.cts +1 -1
  63. package/dist/plugins.d.ts +1 -1
  64. package/dist/plugins.js +96 -45
  65. package/dist/{ssr-FXD2PPMC.js → ssr-2QDQ27EV.js} +5 -3
  66. package/dist/{ssr-CrVNy6Pa.d.cts → ssr-D62yFwuw.d.cts} +8 -1
  67. package/dist/{ssr-CrVNy6Pa.d.ts → ssr-D62yFwuw.d.ts} +8 -1
  68. package/dist/ssr.cjs +145 -66
  69. package/dist/ssr.d.cts +1 -1
  70. package/dist/ssr.d.ts +1 -1
  71. package/dist/ssr.js +12 -10
  72. package/dist/testing.cjs +9 -4
  73. package/dist/testing.js +3 -3
  74. package/dist/ui.cjs +54 -38
  75. package/dist/ui.js +10 -9
  76. package/dist/widgets.cjs +40 -24
  77. package/dist/widgets.js +8 -8
  78. package/package.json +3 -1
package/dist/ssr.cjs CHANGED
@@ -38,6 +38,7 @@ __export(ssr_exports, {
38
38
  hydrate: () => hydrate,
39
39
  hydrateIslands: () => hydrateIslands,
40
40
  hydrateProgressively: () => hydrateProgressively,
41
+ isDangerousMetaRefresh: () => isDangerousMetaRefresh,
41
42
  isWasmCached: () => isWasmCached,
42
43
  island: () => island,
43
44
  loadRemoteModule: () => loadRemoteModule,
@@ -83,11 +84,15 @@ function devWarn(message) {
83
84
  var als = null;
84
85
  try {
85
86
  if (typeof process !== "undefined" && process.versions && process.versions.node) {
86
- const req = Function("return typeof require==='function'?require:null")();
87
- if (req) {
88
- const mod = req("node:async_hooks");
89
- als = new mod.AsyncLocalStorage();
87
+ let mod = null;
88
+ const getBuiltin = process.getBuiltinModule;
89
+ if (typeof getBuiltin === "function") {
90
+ mod = getBuiltin("node:async_hooks");
91
+ } else {
92
+ const req = Function("return typeof require==='function'?require:null")();
93
+ if (req) mod = req("node:async_hooks");
90
94
  }
95
+ if (mod) als = new mod.AsyncLocalStorage();
91
96
  }
92
97
  } catch {
93
98
  als = null;
@@ -105,9 +110,17 @@ function isSSR() {
105
110
  }
106
111
 
107
112
  // src/utils/sanitize.ts
113
+ function stripControlChars(value) {
114
+ return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
115
+ }
116
+ function isEventHandlerAttr(name) {
117
+ if (name.length < 3) return false;
118
+ const lower = name.toLowerCase();
119
+ return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
120
+ }
108
121
  var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
109
122
  function sanitizeUrl(url) {
110
- const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
123
+ const trimmed = stripControlChars(url).trim();
111
124
  if (!trimmed) return "";
112
125
  const lower = trimmed.toLowerCase();
113
126
  let schemeEnd = -1;
@@ -170,20 +183,18 @@ var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
170
183
  "data"
171
184
  ]);
172
185
  function isUrlAttribute(attr) {
173
- return URL_ATTRIBUTES.has(attr);
186
+ return URL_ATTRIBUTES.has(attr.toLowerCase());
174
187
  }
175
188
 
176
189
  // src/platform/ssr.ts
190
+ function sanitizeUrlAttr(name, value) {
191
+ return name === "srcset" ? sanitizeSrcset(value) : sanitizeUrl(value);
192
+ }
177
193
  var _isDev2 = isDev();
178
194
  var SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
179
195
  function isSafeAttrName(name) {
180
196
  return SAFE_ATTR_NAME.test(name);
181
197
  }
182
- function isEventHandlerAttr(name) {
183
- if (name.length < 3) return false;
184
- const lower = name.toLowerCase();
185
- return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
186
- }
187
198
  var URL_ATTRS = /* @__PURE__ */ new Set([
188
199
  "href",
189
200
  "src",
@@ -258,7 +269,7 @@ function renderToString(element) {
258
269
  const lowerName = rawName.toLowerCase();
259
270
  let value = attr.value;
260
271
  if (URL_ATTRS.has(lowerName)) {
261
- value = sanitizeUrl(value);
272
+ value = sanitizeUrlAttr(lowerName, value);
262
273
  if (!value) continue;
263
274
  }
264
275
  html2 += ` ${rawName}="${escapeAttr(value)}"`;
@@ -399,7 +410,7 @@ function buildAttrString(attrs, { allowEventHandlers = false } = {}) {
399
410
  const lowerKey = rawKey.toLowerCase();
400
411
  let value = String(attrs[rawKey]);
401
412
  if (URL_ATTRS.has(lowerKey)) {
402
- value = sanitizeUrl(value);
413
+ value = sanitizeUrlAttr(lowerKey, value);
403
414
  if (!value) continue;
404
415
  }
405
416
  out.push(`${rawKey}="${escapeAttr(value)}"`);
@@ -407,12 +418,17 @@ function buildAttrString(attrs, { allowEventHandlers = false } = {}) {
407
418
  return out.join(" ");
408
419
  }
409
420
  function isDangerousMetaRefresh(metaProps) {
410
- const httpEquiv = metaProps["http-equiv"];
421
+ let httpEquiv;
422
+ let content;
423
+ for (const k in metaProps) {
424
+ const lk = k.toLowerCase();
425
+ if (lk === "http-equiv") httpEquiv = metaProps[k];
426
+ else if (lk === "content") content = metaProps[k];
427
+ }
411
428
  if (typeof httpEquiv !== "string") return false;
412
429
  if (httpEquiv.toLowerCase() !== "refresh") return false;
413
- const content = metaProps.content;
414
430
  if (typeof content !== "string") return false;
415
- const normalized = content.replace(/[\x00-\x20\x7f-\x9f]+/g, "").toLowerCase();
431
+ const normalized = stripControlChars(content).toLowerCase();
416
432
  return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
417
433
  }
418
434
  function renderToDocument(component, options = {}) {
@@ -494,7 +510,7 @@ async function* renderToStream(element) {
494
510
  const lowerName = rawName.toLowerCase();
495
511
  let value = attr.value;
496
512
  if (URL_ATTRS.has(lowerName)) {
497
- value = sanitizeUrl(value);
513
+ value = sanitizeUrlAttr(lowerName, value);
498
514
  if (!value) continue;
499
515
  }
500
516
  openTag += ` ${rawName}="${escapeAttr(value)}"`;
@@ -571,11 +587,11 @@ function hydrateProgressively(container, islands, options) {
571
587
  (entries) => {
572
588
  for (const entry of entries) {
573
589
  if (entry.isIntersecting) {
590
+ observer.disconnect();
574
591
  const clientTree = factory();
575
592
  clientTree.setAttribute("data-sibu-island", id);
576
593
  clientTree.setAttribute("data-sibu-hydrated", "true");
577
594
  marker2.replaceWith(clientTree);
578
- observer.disconnect();
579
595
  break;
580
596
  }
581
597
  }
@@ -829,7 +845,7 @@ function track(effectFn, subscriber) {
829
845
  function reactiveBinding(commit) {
830
846
  const run = () => {
831
847
  const s2 = subscriber;
832
- if (s2._reentrant) return;
848
+ if (s2._disposed || s2._reentrant) return;
833
849
  s2._reentrant = true;
834
850
  try {
835
851
  retrack(commit, subscriber);
@@ -845,8 +861,12 @@ function reactiveBinding(commit) {
845
861
  subscriber._runEpoch = 0;
846
862
  subscriber._runs = 0;
847
863
  subscriber._reentrant = false;
864
+ subscriber._disposed = false;
848
865
  run();
849
- return subscriber._dispose ?? (subscriber._dispose = () => cleanup(subscriber));
866
+ return subscriber._dispose ?? (subscriber._dispose = () => {
867
+ subscriber._disposed = true;
868
+ cleanup(subscriber);
869
+ });
850
870
  }
851
871
  function recordDependency(signal2) {
852
872
  if (!currentSubscriber) return;
@@ -1114,6 +1134,7 @@ function effect(effectFn, options) {
1114
1134
  ctx.fn(ctx.onCleanup);
1115
1135
  };
1116
1136
  const sub2 = (() => {
1137
+ if (ctx.disposed) return;
1117
1138
  if (ctx.running) {
1118
1139
  ctx.rerunPending = true;
1119
1140
  return;
@@ -1155,24 +1176,28 @@ function sanitizeHeadAttr(key, value) {
1155
1176
  if (HEAD_URL_ATTRS.has(key)) return sanitizeUrl(value);
1156
1177
  return value;
1157
1178
  }
1179
+ function isDangerousRefreshContent(content) {
1180
+ const normalized = stripControlChars(content).toLowerCase();
1181
+ return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
1182
+ }
1183
+ function getMetaAttr(metaProps, name) {
1184
+ for (const k in metaProps) {
1185
+ if (k.toLowerCase() === name) return metaProps[k];
1186
+ }
1187
+ return void 0;
1188
+ }
1158
1189
  function isDangerousMetaRefresh2(metaProps) {
1159
- const httpEquiv = metaProps["http-equiv"];
1190
+ const httpEquiv = getMetaAttr(metaProps, "http-equiv");
1160
1191
  if (typeof httpEquiv !== "string") return false;
1161
1192
  if (httpEquiv.toLowerCase() !== "refresh") return false;
1162
- const content = metaProps.content;
1193
+ const content = getMetaAttr(metaProps, "content");
1163
1194
  if (typeof content !== "string") return false;
1164
- const normalized = content.replace(/[\x00-\x20\x7f-\x9f]+/g, "").toLowerCase();
1165
- return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
1195
+ return isDangerousRefreshContent(content);
1166
1196
  }
1167
1197
  var SAFE_HEAD_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
1168
- function isEventHandlerAttr2(name) {
1169
- if (name.length < 3) return false;
1170
- const lower = name.toLowerCase();
1171
- return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
1172
- }
1173
1198
  function isSafeHeadAttr(name) {
1174
1199
  if (!SAFE_HEAD_ATTR_NAME.test(name)) return false;
1175
- if (isEventHandlerAttr2(name)) return false;
1200
+ if (isEventHandlerAttr(name)) return false;
1176
1201
  return true;
1177
1202
  }
1178
1203
  function escapeScriptJsonLocal(json) {
@@ -1205,15 +1230,27 @@ function Head(props) {
1205
1230
  if (props.meta) {
1206
1231
  for (const metaProps of props.meta) {
1207
1232
  if (isDangerousMetaRefresh2(metaProps)) continue;
1233
+ const httpEquiv = getMetaAttr(metaProps, "http-equiv");
1234
+ const isRefreshNow = () => {
1235
+ const eq = typeof httpEquiv === "function" ? httpEquiv() : httpEquiv;
1236
+ return typeof eq === "string" && eq.toLowerCase() === "refresh";
1237
+ };
1208
1238
  const el = document.createElement("meta");
1209
1239
  for (const [key, value] of Object.entries(metaProps)) {
1210
1240
  if (!isSafeHeadAttr(key)) continue;
1241
+ const isContent = key.toLowerCase() === "content";
1211
1242
  if (typeof value === "function") {
1212
1243
  const cleanupFn = effect(() => {
1213
- el.setAttribute(key, sanitizeHeadAttr(key, value()));
1244
+ const resolved = value();
1245
+ if (isContent && isRefreshNow() && isDangerousRefreshContent(resolved)) {
1246
+ el.removeAttribute(key);
1247
+ return;
1248
+ }
1249
+ el.setAttribute(key, sanitizeHeadAttr(key, resolved));
1214
1250
  });
1215
1251
  effectCleanups.push(cleanupFn);
1216
1252
  } else {
1253
+ if (isContent && isRefreshNow() && isDangerousRefreshContent(value)) continue;
1217
1254
  el.setAttribute(key, sanitizeHeadAttr(key, value));
1218
1255
  }
1219
1256
  }
@@ -1433,13 +1470,13 @@ function createISR(options) {
1433
1470
  if (typeof console !== "undefined") console.warn("[SibuJS ISR] revalidate failed", err);
1434
1471
  });
1435
1472
  }, revalidateAfter);
1436
- const dispose = () => {
1473
+ const dispose2 = () => {
1437
1474
  if (disposed) return;
1438
1475
  disposed = true;
1439
1476
  clearInterval(intervalId);
1440
1477
  controller.abort();
1441
1478
  };
1442
- return { data: data2, isStale, revalidate, dispose };
1479
+ return { data: data2, isStale, revalidate, dispose: dispose2 };
1443
1480
  }
1444
1481
 
1445
1482
  // src/platform/routeActions.ts
@@ -1502,14 +1539,14 @@ function scrollRestoration(options) {
1502
1539
  };
1503
1540
  window.addEventListener("popstate", popstateHandler);
1504
1541
  }
1505
- const dispose = () => {
1542
+ const dispose2 = () => {
1506
1543
  if (popstateHandler) {
1507
1544
  window.removeEventListener("popstate", popstateHandler);
1508
1545
  popstateHandler = null;
1509
1546
  }
1510
1547
  positions.clear();
1511
1548
  };
1512
- return { save, restore, getPosition, dispose };
1549
+ return { save, restore, getPosition, dispose: dispose2 };
1513
1550
  }
1514
1551
 
1515
1552
  // src/platform/routeMiddleware.ts
@@ -1548,13 +1585,8 @@ var _isDev5 = isDev();
1548
1585
  function setProp(el, key, val) {
1549
1586
  el[key] = val;
1550
1587
  }
1551
- function isEventHandlerAttr3(name) {
1552
- if (name.length < 3) return false;
1553
- const lower = name.toLowerCase();
1554
- return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
1555
- }
1556
1588
  function bindAttribute(el, attr, getter) {
1557
- if (isEventHandlerAttr3(attr)) {
1589
+ if (isEventHandlerAttr(attr)) {
1558
1590
  if (_isDev5)
1559
1591
  devWarn(
1560
1592
  `bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
@@ -1591,8 +1623,69 @@ function bindAttribute(el, attr, getter) {
1591
1623
  return reactiveBinding(commit);
1592
1624
  }
1593
1625
 
1594
- // src/reactivity/bindChildNode.ts
1626
+ // src/core/rendering/dispose.ts
1627
+ var elementDisposers = /* @__PURE__ */ new WeakMap();
1595
1628
  var _isDev6 = isDev();
1629
+ var activeBindingCount = 0;
1630
+ function registerDisposer(node, teardown) {
1631
+ let disposers = elementDisposers.get(node);
1632
+ if (!disposers) {
1633
+ disposers = [];
1634
+ elementDisposers.set(node, disposers);
1635
+ }
1636
+ disposers.push(teardown);
1637
+ if (_isDev6) activeBindingCount++;
1638
+ }
1639
+ function dispose(node) {
1640
+ const stack = [node];
1641
+ const order = [];
1642
+ while (stack.length > 0) {
1643
+ const current = stack.pop();
1644
+ order.push(current);
1645
+ const children = Array.from(current.childNodes);
1646
+ for (let i2 = 0; i2 < children.length; i2++) {
1647
+ stack.push(children[i2]);
1648
+ }
1649
+ }
1650
+ for (let i2 = order.length - 1; i2 >= 0; i2--) {
1651
+ const current = order[i2];
1652
+ const disposers = elementDisposers.get(current);
1653
+ if (disposers) {
1654
+ const snapshot = disposers.slice();
1655
+ elementDisposers.delete(current);
1656
+ if (_isDev6) activeBindingCount -= snapshot.length;
1657
+ for (const d of snapshot) {
1658
+ try {
1659
+ d();
1660
+ } catch (err) {
1661
+ if (_isDev6 && typeof console !== "undefined") {
1662
+ console.warn("[SibuJS] Disposer threw during cleanup:", err);
1663
+ }
1664
+ }
1665
+ }
1666
+ let extraPasses = 0;
1667
+ while (extraPasses++ < 8) {
1668
+ const added = elementDisposers.get(current);
1669
+ if (!added || added.length === 0) break;
1670
+ const moreSnapshot = added.slice();
1671
+ elementDisposers.delete(current);
1672
+ if (_isDev6) activeBindingCount -= moreSnapshot.length;
1673
+ for (const d of moreSnapshot) {
1674
+ try {
1675
+ d();
1676
+ } catch (err) {
1677
+ if (_isDev6 && typeof console !== "undefined") {
1678
+ console.warn("[SibuJS] Disposer threw during cleanup:", err);
1679
+ }
1680
+ }
1681
+ }
1682
+ }
1683
+ }
1684
+ }
1685
+ }
1686
+
1687
+ // src/reactivity/bindChildNode.ts
1688
+ var _isDev7 = isDev();
1596
1689
  function bindChildNode(placeholder, getter) {
1597
1690
  let lastNodes = [];
1598
1691
  function commit() {
@@ -1600,12 +1693,13 @@ function bindChildNode(placeholder, getter) {
1600
1693
  try {
1601
1694
  result = getter();
1602
1695
  } catch (err) {
1603
- if (_isDev6) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
1696
+ if (_isDev7) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
1604
1697
  return;
1605
1698
  }
1606
1699
  if (result == null || typeof result === "boolean") {
1607
1700
  for (let i2 = 0; i2 < lastNodes.length; i2++) {
1608
1701
  const node = lastNodes[i2];
1702
+ dispose(node);
1609
1703
  if (node.parentNode) node.parentNode.removeChild(node);
1610
1704
  }
1611
1705
  lastNodes.length = 0;
@@ -1625,7 +1719,7 @@ function bindChildNode(placeholder, getter) {
1625
1719
  if (item == null || typeof item === "boolean") continue;
1626
1720
  const node = item instanceof Node ? item : document.createTextNode(String(item));
1627
1721
  if (seen.has(node)) {
1628
- if (_isDev6)
1722
+ if (_isDev7)
1629
1723
  devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
1630
1724
  continue;
1631
1725
  }
@@ -1647,38 +1741,22 @@ function bindChildNode(placeholder, getter) {
1647
1741
  for (let i2 = 0; i2 < lastNodes.length; i2++) {
1648
1742
  const node = lastNodes[i2];
1649
1743
  if (reused?.has(node)) continue;
1744
+ dispose(node);
1650
1745
  if (node.parentNode) node.parentNode.removeChild(node);
1651
1746
  }
1652
- const anchor = placeholder.nextSibling;
1747
+ let prev = placeholder;
1653
1748
  for (let i2 = 0; i2 < newNodes.length; i2++) {
1654
1749
  const node = newNodes[i2];
1655
- if (reused?.has(node) && node.parentNode === parent) {
1656
- if (node.nextSibling !== anchor) {
1657
- parent.insertBefore(node, anchor);
1658
- }
1659
- } else {
1660
- parent.insertBefore(node, anchor);
1750
+ if (prev.nextSibling !== node) {
1751
+ parent.insertBefore(node, prev.nextSibling);
1661
1752
  }
1753
+ prev = node;
1662
1754
  }
1663
1755
  lastNodes = newNodes;
1664
1756
  }
1665
1757
  return reactiveBinding(commit);
1666
1758
  }
1667
1759
 
1668
- // src/core/rendering/dispose.ts
1669
- var elementDisposers = /* @__PURE__ */ new WeakMap();
1670
- var _isDev7 = isDev();
1671
- var activeBindingCount = 0;
1672
- function registerDisposer(node, teardown) {
1673
- let disposers = elementDisposers.get(node);
1674
- if (!disposers) {
1675
- disposers = [];
1676
- elementDisposers.set(node, disposers);
1677
- }
1678
- disposers.push(teardown);
1679
- if (_isDev7) activeBindingCount++;
1680
- }
1681
-
1682
1760
  // src/core/rendering/tagFactory.ts
1683
1761
  var SVG_NS = "http://www.w3.org/2000/svg";
1684
1762
  var _isDev8 = isDev();
@@ -1914,7 +1992,7 @@ var tagFactory = (tag, ns) => {
1914
1992
  const value = props[key];
1915
1993
  if (value == null) continue;
1916
1994
  const lkey = key.toLowerCase();
1917
- if (lkey[0] === "o" && lkey[1] === "n") continue;
1995
+ if (isEventHandlerAttr(key)) continue;
1918
1996
  if (typeof value === "function") {
1919
1997
  registerDisposer(el, bindAttribute(el, key, value));
1920
1998
  } else if (typeof value === "boolean") {
@@ -2681,6 +2759,7 @@ function isWasmCached(key) {
2681
2759
  hydrate,
2682
2760
  hydrateIslands,
2683
2761
  hydrateProgressively,
2762
+ isDangerousMetaRefresh,
2684
2763
  isWasmCached,
2685
2764
  island,
2686
2765
  loadRemoteModule,
package/dist/ssr.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as island, r as renderToDocument, g as renderToReadableStream, j as renderToStream, k as renderToString, l as renderToSuspenseStream, m as resetSSRState, s as serializeState, n as ssrSuspense, o as suspenseSwapScript, t as trustHTML } from './ssr-CrVNy6Pa.cjs';
1
+ export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as isDangerousMetaRefresh, g as island, r as renderToDocument, j as renderToReadableStream, k as renderToStream, l as renderToString, m as renderToSuspenseStream, n as resetSSRState, s as serializeState, o as ssrSuspense, p as suspenseSwapScript, t as trustHTML } from './ssr-D62yFwuw.cjs';
2
2
 
3
3
  interface HeadProps {
4
4
  title?: string | (() => string);
package/dist/ssr.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as island, r as renderToDocument, g as renderToReadableStream, j as renderToStream, k as renderToString, l as renderToSuspenseStream, m as resetSSRState, s as serializeState, n as ssrSuspense, o as suspenseSwapScript, t as trustHTML } from './ssr-CrVNy6Pa.js';
1
+ export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as isDangerousMetaRefresh, g as island, r as renderToDocument, j as renderToReadableStream, k as renderToStream, l as renderToString, m as renderToSuspenseStream, n as resetSSRState, s as serializeState, o as ssrSuspense, p as suspenseSwapScript, t as trustHTML } from './ssr-D62yFwuw.js';
2
2
 
3
3
  interface HeadProps {
4
4
  title?: string | (() => string);
package/dist/ssr.js CHANGED
@@ -22,8 +22,8 @@ import {
22
22
  wasm,
23
23
  worker,
24
24
  workerFn
25
- } from "./chunk-UYX2NDOH.js";
26
- import "./chunk-2HAGQWDV.js";
25
+ } from "./chunk-OYLPZO4N.js";
26
+ import "./chunk-5N74TKLD.js";
27
27
  import {
28
28
  collectStream,
29
29
  deserializeState,
@@ -31,6 +31,7 @@ import {
31
31
  hydrate,
32
32
  hydrateIslands,
33
33
  hydrateProgressively,
34
+ isDangerousMetaRefresh,
34
35
  island,
35
36
  renderToDocument,
36
37
  renderToReadableStream,
@@ -42,15 +43,15 @@ import {
42
43
  ssrSuspense,
43
44
  suspenseSwapScript,
44
45
  trustHTML
45
- } from "./chunk-JYD2PWXH.js";
46
- import "./chunk-WKUXSE7V.js";
47
- import "./chunk-2ZJ7TSW4.js";
46
+ } from "./chunk-HXMS4SNP.js";
47
+ import "./chunk-X67UYC74.js";
48
+ import "./chunk-RLUJL2MV.js";
48
49
  import "./chunk-2UPRY23K.js";
49
- import "./chunk-UCS6AMJ7.js";
50
- import "./chunk-ZIBE2SAT.js";
51
- import "./chunk-2RA7SHDA.js";
52
- import "./chunk-RK4BQG25.js";
53
- import "./chunk-3U4ZVXVD.js";
50
+ import "./chunk-HMJFCBRR.js";
51
+ import "./chunk-FDY42FIU.js";
52
+ import "./chunk-GOJMFRBL.js";
53
+ import "./chunk-C427DVQF.js";
54
+ import "./chunk-Z2FWAE4B.js";
54
55
  import "./chunk-LMLD24FC.js";
55
56
  export {
56
57
  Head,
@@ -71,6 +72,7 @@ export {
71
72
  hydrate,
72
73
  hydrateIslands,
73
74
  hydrateProgressively,
75
+ isDangerousMetaRefresh,
74
76
  isWasmCached,
75
77
  island,
76
78
  loadRemoteModule,
package/dist/testing.cjs CHANGED
@@ -1637,11 +1637,15 @@ function cleanup(subscriber) {
1637
1637
  var als = null;
1638
1638
  try {
1639
1639
  if (typeof process !== "undefined" && process.versions && process.versions.node) {
1640
- const req = Function("return typeof require==='function'?require:null")();
1641
- if (req) {
1642
- const mod = req("node:async_hooks");
1643
- als = new mod.AsyncLocalStorage();
1640
+ let mod = null;
1641
+ const getBuiltin = process.getBuiltinModule;
1642
+ if (typeof getBuiltin === "function") {
1643
+ mod = getBuiltin("node:async_hooks");
1644
+ } else {
1645
+ const req = Function("return typeof require==='function'?require:null")();
1646
+ if (req) mod = req("node:async_hooks");
1644
1647
  }
1648
+ if (mod) als = new mod.AsyncLocalStorage();
1645
1649
  }
1646
1650
  } catch {
1647
1651
  als = null;
@@ -1743,6 +1747,7 @@ function effect(effectFn, options) {
1743
1747
  ctx.fn(ctx.onCleanup);
1744
1748
  };
1745
1749
  const sub = (() => {
1750
+ if (ctx.disposed) return;
1746
1751
  if (ctx.running) {
1747
1752
  ctx.rerunPending = true;
1748
1753
  return;
package/dist/testing.js CHANGED
@@ -3,9 +3,9 @@ import {
3
3
  } from "./chunk-2UPRY23K.js";
4
4
  import {
5
5
  effect
6
- } from "./chunk-ZIBE2SAT.js";
7
- import "./chunk-2RA7SHDA.js";
8
- import "./chunk-3U4ZVXVD.js";
6
+ } from "./chunk-FDY42FIU.js";
7
+ import "./chunk-GOJMFRBL.js";
8
+ import "./chunk-Z2FWAE4B.js";
9
9
  import "./chunk-LMLD24FC.js";
10
10
 
11
11
  // src/testing/a11y.ts