@askrjs/askr 0.0.39 → 0.0.40

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 (250) hide show
  1. package/dist/bench/components/benchmark-row.d.ts.map +1 -1
  2. package/dist/bench/components/benchmark-row.js.map +1 -1
  3. package/dist/bench/components/benchmark-table.js.map +1 -1
  4. package/dist/benchmark.d.ts.map +1 -1
  5. package/dist/benchmark.js +2 -2
  6. package/dist/benchmark.js.map +1 -1
  7. package/dist/bin/askr-ssg.d.ts.map +1 -1
  8. package/dist/bin/askr-ssg.js.map +1 -1
  9. package/dist/boot/index.d.ts +9 -6
  10. package/dist/boot/index.d.ts.map +1 -1
  11. package/dist/boot/index.js +210 -75
  12. package/dist/boot/index.js.map +1 -1
  13. package/dist/common/attr-names.js +17 -0
  14. package/dist/common/attr-names.js.map +1 -0
  15. package/dist/common/component.d.ts.map +1 -1
  16. package/dist/common/control.d.ts.map +1 -1
  17. package/dist/common/control.js.map +1 -1
  18. package/dist/common/env.js.map +1 -1
  19. package/dist/common/jsx.d.ts.map +1 -1
  20. package/dist/common/jsx.js.map +1 -1
  21. package/dist/common/promise.js +8 -0
  22. package/dist/common/promise.js.map +1 -0
  23. package/dist/common/props.d.ts +286 -1
  24. package/dist/common/props.d.ts.map +1 -1
  25. package/dist/common/router-internal.js +6 -0
  26. package/dist/common/router-internal.js.map +1 -0
  27. package/dist/common/router.d.ts +45 -36
  28. package/dist/common/router.d.ts.map +1 -1
  29. package/dist/common/ssr-errors.d.ts.map +1 -1
  30. package/dist/common/ssr-errors.js.map +1 -1
  31. package/dist/common/ssr.d.ts +1 -0
  32. package/dist/common/ssr.d.ts.map +1 -1
  33. package/dist/common/ssr.js +6 -0
  34. package/dist/common/ssr.js.map +1 -0
  35. package/dist/common/vnode.d.ts +2 -1
  36. package/dist/common/vnode.d.ts.map +1 -1
  37. package/dist/common/vnode.js.map +1 -1
  38. package/dist/components/error-boundary.d.ts +7 -4
  39. package/dist/components/error-boundary.d.ts.map +1 -1
  40. package/dist/components/error-boundary.js.map +1 -1
  41. package/dist/components/link.d.ts +2 -1
  42. package/dist/components/link.d.ts.map +1 -1
  43. package/dist/components/link.js +10 -1
  44. package/dist/components/link.js.map +1 -1
  45. package/dist/control/case.d.ts +4 -2
  46. package/dist/control/case.d.ts.map +1 -1
  47. package/dist/control/case.js.map +1 -1
  48. package/dist/control/for.d.ts +2 -1
  49. package/dist/control/for.d.ts.map +1 -1
  50. package/dist/control/for.js.map +1 -1
  51. package/dist/control/shared.d.ts +9 -0
  52. package/dist/control/shared.d.ts.map +1 -0
  53. package/dist/control/shared.js.map +1 -1
  54. package/dist/control/show.d.ts +4 -3
  55. package/dist/control/show.d.ts.map +1 -1
  56. package/dist/control/show.js.map +1 -1
  57. package/dist/data/index.d.ts +94 -14
  58. package/dist/data/index.d.ts.map +1 -1
  59. package/dist/data/index.js +65 -14
  60. package/dist/data/index.js.map +1 -1
  61. package/dist/dev/invariant.js.map +1 -1
  62. package/dist/dev/logger.js.map +1 -1
  63. package/dist/foundations/icon/icon.d.ts.map +1 -1
  64. package/dist/foundations/icon/icon.js.map +1 -1
  65. package/dist/foundations/icon/icon.types.d.ts.map +1 -1
  66. package/dist/foundations/interactions/dismissable.d.ts +9 -3
  67. package/dist/foundations/interactions/dismissable.d.ts.map +1 -1
  68. package/dist/foundations/interactions/dismissable.js.map +1 -1
  69. package/dist/foundations/interactions/focusable.d.ts.map +1 -1
  70. package/dist/foundations/interactions/focusable.js.map +1 -1
  71. package/dist/foundations/interactions/hoverable.d.ts.map +1 -1
  72. package/dist/foundations/interactions/hoverable.js.map +1 -1
  73. package/dist/foundations/interactions/interaction-policy.d.ts +1 -1
  74. package/dist/foundations/interactions/interaction-policy.d.ts.map +1 -1
  75. package/dist/foundations/interactions/interaction-policy.js +3 -3
  76. package/dist/foundations/interactions/interaction-policy.js.map +1 -1
  77. package/dist/foundations/interactions/pressable.d.ts.map +1 -1
  78. package/dist/foundations/interactions/pressable.js.map +1 -1
  79. package/dist/foundations/interactions/roving-focus.d.ts.map +1 -1
  80. package/dist/foundations/interactions/roving-focus.js +8 -8
  81. package/dist/foundations/interactions/roving-focus.js.map +1 -1
  82. package/dist/foundations/state/controllable.d.ts.map +1 -1
  83. package/dist/foundations/state/controllable.js.map +1 -1
  84. package/dist/foundations/structures/collection.d.ts.map +1 -1
  85. package/dist/foundations/structures/collection.js.map +1 -1
  86. package/dist/foundations/structures/layer.d.ts.map +1 -1
  87. package/dist/foundations/structures/layer.js.map +1 -1
  88. package/dist/foundations/structures/layout.d.ts +4 -2
  89. package/dist/foundations/structures/layout.d.ts.map +1 -1
  90. package/dist/foundations/structures/layout.js.map +1 -1
  91. package/dist/foundations/structures/portal.d.ts +9 -25
  92. package/dist/foundations/structures/portal.d.ts.map +1 -1
  93. package/dist/foundations/structures/portal.js +98 -17
  94. package/dist/foundations/structures/portal.js.map +1 -1
  95. package/dist/foundations/structures/presence.d.ts +4 -3
  96. package/dist/foundations/structures/presence.d.ts.map +1 -1
  97. package/dist/foundations/structures/presence.js +2 -2
  98. package/dist/foundations/structures/presence.js.map +1 -1
  99. package/dist/foundations/structures/slot.d.ts +2 -1
  100. package/dist/foundations/structures/slot.d.ts.map +1 -1
  101. package/dist/foundations/structures/slot.js.map +1 -1
  102. package/dist/foundations/utilities/aria.d.ts.map +1 -1
  103. package/dist/foundations/utilities/aria.js.map +1 -1
  104. package/dist/foundations/utilities/compose-handlers.d.ts.map +1 -1
  105. package/dist/foundations/utilities/compose-handlers.js.map +1 -1
  106. package/dist/foundations/utilities/compose-ref.d.ts.map +1 -1
  107. package/dist/foundations/utilities/compose-ref.js.map +1 -1
  108. package/dist/foundations/utilities/event-types.d.ts.map +1 -1
  109. package/dist/foundations/utilities/merge-props.js.map +1 -1
  110. package/dist/foundations/utilities/use-id.d.ts.map +1 -1
  111. package/dist/foundations/utilities/use-id.js.map +1 -1
  112. package/dist/fx/fx.d.ts.map +1 -1
  113. package/dist/fx/fx.js.map +1 -1
  114. package/dist/fx/noop.js.map +1 -1
  115. package/dist/fx/timing.d.ts +5 -4
  116. package/dist/fx/timing.d.ts.map +1 -1
  117. package/dist/fx/timing.js +7 -4
  118. package/dist/fx/timing.js.map +1 -1
  119. package/dist/index.js.map +1 -1
  120. package/dist/jsx/types.d.ts +3 -3
  121. package/dist/jsx/types.d.ts.map +1 -1
  122. package/dist/jsx/utils.d.ts.map +1 -1
  123. package/dist/jsx/utils.js.map +1 -1
  124. package/dist/jsx-dev-runtime.d.ts +6 -2
  125. package/dist/jsx-dev-runtime.d.ts.map +1 -1
  126. package/dist/jsx-dev-runtime.js.map +1 -1
  127. package/dist/jsx-runtime.d.ts +16 -6
  128. package/dist/jsx-runtime.d.ts.map +1 -1
  129. package/dist/jsx-runtime.js.map +1 -1
  130. package/dist/renderer/children.js.map +1 -1
  131. package/dist/renderer/cleanup.js +40 -13
  132. package/dist/renderer/cleanup.js.map +1 -1
  133. package/dist/renderer/dom.js +163 -63
  134. package/dist/renderer/dom.js.map +1 -1
  135. package/dist/renderer/evaluate.js +9 -6
  136. package/dist/renderer/evaluate.js.map +1 -1
  137. package/dist/renderer/fastpath.js.map +1 -1
  138. package/dist/renderer/for-commit.js +1 -0
  139. package/dist/renderer/for-commit.js.map +1 -1
  140. package/dist/renderer/index.js.map +1 -1
  141. package/dist/renderer/keyed.js.map +1 -1
  142. package/dist/renderer/reconcile.js +34 -0
  143. package/dist/renderer/reconcile.js.map +1 -1
  144. package/dist/renderer/utils.js +34 -3
  145. package/dist/renderer/utils.js.map +1 -1
  146. package/dist/router/index.d.ts +2 -2
  147. package/dist/router/match.js +16 -2
  148. package/dist/router/match.js.map +1 -1
  149. package/dist/router/navigate.d.ts +9 -1
  150. package/dist/router/navigate.d.ts.map +1 -1
  151. package/dist/router/navigate.js +235 -81
  152. package/dist/router/navigate.js.map +1 -1
  153. package/dist/router/policy.d.ts +7 -7
  154. package/dist/router/policy.d.ts.map +1 -1
  155. package/dist/router/policy.js +5 -7
  156. package/dist/router/policy.js.map +1 -1
  157. package/dist/router/route-context.js.map +1 -1
  158. package/dist/router/route.d.ts +20 -9
  159. package/dist/router/route.d.ts.map +1 -1
  160. package/dist/router/route.js +95 -29
  161. package/dist/router/route.js.map +1 -1
  162. package/dist/runtime/child-scope.d.ts.map +1 -1
  163. package/dist/runtime/child-scope.js +5 -1
  164. package/dist/runtime/child-scope.js.map +1 -1
  165. package/dist/runtime/component.d.ts +5 -2
  166. package/dist/runtime/component.d.ts.map +1 -1
  167. package/dist/runtime/component.js +85 -25
  168. package/dist/runtime/component.js.map +1 -1
  169. package/dist/runtime/context.d.ts +5 -2
  170. package/dist/runtime/context.d.ts.map +1 -1
  171. package/dist/runtime/context.js +5 -2
  172. package/dist/runtime/context.js.map +1 -1
  173. package/dist/runtime/control.d.ts.map +1 -1
  174. package/dist/runtime/control.js.map +1 -1
  175. package/dist/runtime/derive.d.ts.map +1 -1
  176. package/dist/runtime/derive.js +3 -1
  177. package/dist/runtime/derive.js.map +1 -1
  178. package/dist/runtime/dev-namespace.js.map +1 -1
  179. package/dist/runtime/effect.d.ts.map +1 -1
  180. package/dist/runtime/effect.js +17 -11
  181. package/dist/runtime/effect.js.map +1 -1
  182. package/dist/runtime/events.js +43 -1
  183. package/dist/runtime/events.js.map +1 -1
  184. package/dist/runtime/execution-model.js.map +1 -1
  185. package/dist/runtime/fastlane.js +2 -23
  186. package/dist/runtime/fastlane.js.map +1 -1
  187. package/dist/runtime/for-bench.d.ts.map +1 -1
  188. package/dist/runtime/for-bench.js.map +1 -1
  189. package/dist/runtime/for.d.ts +1 -1
  190. package/dist/runtime/for.d.ts.map +1 -1
  191. package/dist/runtime/for.js +36 -12
  192. package/dist/runtime/for.js.map +1 -1
  193. package/dist/runtime/operations.d.ts +3 -13
  194. package/dist/runtime/operations.d.ts.map +1 -1
  195. package/dist/runtime/operations.js +47 -39
  196. package/dist/runtime/operations.js.map +1 -1
  197. package/dist/runtime/perf-metrics.js.map +1 -1
  198. package/dist/runtime/readable.d.ts +1 -0
  199. package/dist/runtime/readable.d.ts.map +1 -1
  200. package/dist/runtime/readable.js +6 -1
  201. package/dist/runtime/readable.js.map +1 -1
  202. package/dist/runtime/resource-cell.js +13 -2
  203. package/dist/runtime/resource-cell.js.map +1 -1
  204. package/dist/runtime/scheduler.d.ts.map +1 -1
  205. package/dist/runtime/scheduler.js +8 -4
  206. package/dist/runtime/scheduler.js.map +1 -1
  207. package/dist/runtime/selector.d.ts.map +1 -1
  208. package/dist/runtime/selector.js +8 -2
  209. package/dist/runtime/selector.js.map +1 -1
  210. package/dist/runtime/snapshot-source.d.ts.map +1 -1
  211. package/dist/runtime/snapshot-source.js.map +1 -1
  212. package/dist/runtime/ssr-bridge.js.map +1 -1
  213. package/dist/runtime/state.d.ts +4 -3
  214. package/dist/runtime/state.d.ts.map +1 -1
  215. package/dist/runtime/state.js.map +1 -1
  216. package/dist/ssg/batch-render.js +4 -8
  217. package/dist/ssg/batch-render.js.map +1 -1
  218. package/dist/ssg/create-static-gen.d.ts +10 -2
  219. package/dist/ssg/create-static-gen.d.ts.map +1 -1
  220. package/dist/ssg/create-static-gen.js +5 -4
  221. package/dist/ssg/create-static-gen.js.map +1 -1
  222. package/dist/ssg/generate-metadata.js.map +1 -1
  223. package/dist/ssg/incremental-manifest.js.map +1 -1
  224. package/dist/ssg/resolve-ssg-data.js +54 -12
  225. package/dist/ssg/resolve-ssg-data.js.map +1 -1
  226. package/dist/ssg/route-utils.js.map +1 -1
  227. package/dist/ssg/types.d.ts +8 -7
  228. package/dist/ssg/types.d.ts.map +1 -1
  229. package/dist/ssg/write-static-files.js.map +1 -1
  230. package/dist/ssr/attrs.js +3 -2
  231. package/dist/ssr/attrs.js.map +1 -1
  232. package/dist/ssr/context.d.ts +1 -0
  233. package/dist/ssr/context.d.ts.map +1 -1
  234. package/dist/ssr/context.js +1 -0
  235. package/dist/ssr/context.js.map +1 -1
  236. package/dist/ssr/errors.d.ts.map +1 -1
  237. package/dist/ssr/escape.js.map +1 -1
  238. package/dist/ssr/index.d.ts +8 -12
  239. package/dist/ssr/index.d.ts.map +1 -1
  240. package/dist/ssr/index.js +55 -30
  241. package/dist/ssr/index.js.map +1 -1
  242. package/dist/ssr/render-keys.js +15 -4
  243. package/dist/ssr/render-keys.js.map +1 -1
  244. package/dist/ssr/render-resolved.js +33 -0
  245. package/dist/ssr/render-resolved.js.map +1 -0
  246. package/dist/ssr/sink.js.map +1 -1
  247. package/dist/ssr/types.d.ts.map +1 -1
  248. package/dist/ssr/verify-hydration.js +5 -6
  249. package/dist/ssr/verify-hydration.js.map +1 -1
  250. package/package.json +12 -4
@@ -7,12 +7,14 @@ import { globalScheduler } from "../runtime/scheduler.js";
7
7
  import { Fragment, STATIC_CHILDREN } from "../common/jsx.js";
8
8
  import { getCurrentContextFrame, getVNodeContextFrame, markVNodeTreeWithContextFrame, withContext } from "../runtime/context.js";
9
9
  import { getDevValue, incDevCounter } from "../runtime/dev-namespace.js";
10
+ import { isPromiseLike } from "../common/promise.js";
10
11
  import "./env.js";
11
- import { createMutableWrappedHandler, extractKey, getPassiveOptions, isSkippedProp, parseEventName, readElementClassName, tagNamesEqualIgnoreCase, writeElementClassName } from "./utils.js";
12
+ import { createMutableWrappedHandler, extractKey, getEventListenerKey, getEventListenerOptions, getRenderedAttributeName, isSkippedProp, parseEventName, parseEventProp, readElementClassName, removeRenderedAttribute, setRenderedAttribute, tagNamesEqualIgnoreCase, writeElementClassName } from "./utils.js";
12
13
  import { keyedElements } from "./keyed.js";
13
14
  import { cleanupComponent, createComponentInstance, getCurrentInstance, mountInstanceInline, renderComponentInline, warnUnusedStateReads } from "../runtime/component.js";
14
15
  import { addDelegatedListener, getDelegatedHandlerForElement, getDelegatedHandlersForElement, isDelegatedEvent, isEventDelegationEnabled, removeDelegatedListener, updateDelegatedListener } from "../runtime/events.js";
15
16
  import { REACTIVE_CHILDREN_KEY, elementListeners, elementReactivePropsCleanup, removeAllListeners, removeElementListeners, removeElementReactiveProps, teardownNodeSubtree } from "./cleanup.js";
17
+ import { ROUTE_ROOT_COMPONENT } from "../common/router-internal.js";
16
18
  import "../jsx-runtime.js";
17
19
  import { createChildScope, disposeChildScope, rerenderChildScope } from "../runtime/child-scope.js";
18
20
  import { isBenchMetricScopeActive, recordBenchCounter, recordBenchEvent } from "../runtime/for-bench.js";
@@ -26,6 +28,13 @@ import { createBoundaryReset, reportBoundaryError, resolveErrorBoundaryFallback
26
28
  //#region src/renderer/dom.ts
27
29
  const reactivePropRegistry = /* @__PURE__ */ new Set();
28
30
  const controlBoundaryOwners = /* @__PURE__ */ new WeakMap();
31
+ function isRouteRootComponentVNode(node) {
32
+ return typeof node === "object" && node !== null && node[ROUTE_ROOT_COMPONENT] === true;
33
+ }
34
+ function inheritComponentCleanupStrict(instance) {
35
+ const owner = getCurrentInstance();
36
+ if (owner) instance.cleanupStrict = owner.cleanupStrict;
37
+ }
29
38
  let reactiveChildScopeId = 0;
30
39
  function collectReactiveScalarSequenceValue(value, normalized) {
31
40
  if (isFragmentVNode(value)) return collectReactiveScalarSequenceValue(value.props?.children ?? value.children, normalized);
@@ -694,22 +703,25 @@ function nextComponentInstanceId() {
694
703
  * Add an event listener to an element with tracking
695
704
  * Uses event delegation when enabled (opt-out model)
696
705
  */
697
- function addTrackedListener(el, eventName, handler) {
698
- if (isEventDelegationEnabled() && isDelegatedEvent(eventName)) {
706
+ function addTrackedListener(el, eventName, handler, capture = false) {
707
+ const useDelegation = !capture && isEventDelegationEnabled() && isDelegatedEvent(eventName);
708
+ const listenerKey = getEventListenerKey(eventName, capture);
709
+ if (useDelegation) {
699
710
  addDelegatedListener(el, eventName, handler, handler, void 0);
700
711
  if (isBenchMetricScopeActive("coldCreate")) recordBenchCounter("listenerBindings");
701
712
  return;
702
713
  }
703
- const options = getPassiveOptions(eventName);
714
+ const options = getEventListenerOptions(eventName, capture);
704
715
  const mutableHandler = createMutableWrappedHandler(handler, true);
705
716
  const trackedHandler = mutableHandler.handler;
706
717
  if (options !== void 0) el.addEventListener(eventName, trackedHandler, options);
707
718
  else el.addEventListener(eventName, trackedHandler);
708
719
  incDevCounter("listenerAdds");
709
720
  if (!elementListeners.has(el)) elementListeners.set(el, /* @__PURE__ */ new Map());
710
- elementListeners.get(el).set(eventName, {
721
+ elementListeners.get(el).set(listenerKey, {
711
722
  handler: trackedHandler,
712
723
  original: handler,
724
+ eventName,
713
725
  options,
714
726
  isDelegated: false,
715
727
  updateHandler: mutableHandler?.updateHandler
@@ -786,13 +798,13 @@ function applyPropValue(el, key, value, tagName, previousValue, descriptor) {
786
798
  } else if (key === "value") applyFormControlProp(el, key, "", tagName);
787
799
  else if (key === "checked") applyFormControlProp(el, key, false, tagName);
788
800
  else if (key === "style") applyStylePropValue(el, null);
789
- else el.removeAttribute(key);
801
+ else removeRenderedAttribute(el, key);
790
802
  return;
791
803
  }
792
804
  if (key === "class" || key === "className") applyClassPropValue(el, value, previousValue, descriptor);
793
805
  else if (key === "style") applyStylePropValue(el, value);
794
806
  else if (key === "value" || key === "checked") applyFormControlProp(el, key, value, tagName);
795
- else el.setAttribute(key, String(value));
807
+ else setRenderedAttribute(el, key, String(value));
796
808
  }
797
809
  function normalizeStylePropertyName(propertyName) {
798
810
  if (propertyName.startsWith("--")) return propertyName;
@@ -931,12 +943,12 @@ function applyPropsToElement(el, props, tagName) {
931
943
  }
932
944
  if (isSkippedProp(key)) continue;
933
945
  if (value === void 0 || value === null || value === false) continue;
934
- const eventName = parseEventName(key);
935
- if (eventName) {
936
- addTrackedListener(el, eventName, value);
946
+ const eventProp = parseEventProp(key);
947
+ if (eventProp) {
948
+ addTrackedListener(el, eventProp.eventName, value, eventProp.capture);
937
949
  continue;
938
950
  }
939
- if (typeof value === "function" && !eventName && key !== "ref") {
951
+ if (typeof value === "function" && key !== "ref") {
940
952
  const reactive = setupReactiveProp(el, key, value, tagName);
941
953
  if (!elementReactivePropsCleanup.has(el)) elementReactivePropsCleanup.set(el, /* @__PURE__ */ new Map());
942
954
  elementReactivePropsCleanup.get(el).set(key, {
@@ -951,7 +963,7 @@ function applyPropsToElement(el, props, tagName) {
951
963
  if (key === "class" || key === "className") writeElementClassName(el, String(value));
952
964
  else if (key === "style") applyStylePropValue(el, value);
953
965
  else if (key === "value" || key === "checked") applyFormControlProp(el, key, value, tagName);
954
- else el.setAttribute(key, String(value));
966
+ else setRenderedAttribute(el, key, String(value));
955
967
  }
956
968
  }
957
969
  function applyRef(el, ref) {
@@ -963,12 +975,6 @@ function applyRef(el, ref) {
963
975
  }
964
976
  if (Object.isExtensible(r)) r.current = el;
965
977
  }
966
- function getRenderedAttributeName(el, propName) {
967
- let attributeName = propName;
968
- if (propName === "className") attributeName = "class";
969
- else if (propName === "htmlFor") attributeName = "for";
970
- return el.namespaceURI === SVG_NAMESPACE ? attributeName : attributeName.toLowerCase();
971
- }
972
978
  function removeStaleAttributes(el, vnode, props) {
973
979
  const desiredAttributes = /* @__PURE__ */ new Set();
974
980
  if (extractKey(vnode) !== void 0) desiredAttributes.add("data-key");
@@ -1126,7 +1132,7 @@ function applyStaticScalarPropsToElement(el, props) {
1126
1132
  if (key === "class" || key === "className") writeElementClassName(el, String(value));
1127
1133
  else if (key === "style") applyStylePropValue(el, value);
1128
1134
  else if (key === "value" || key === "checked") el[key] = value;
1129
- else el.setAttribute(key, String(value));
1135
+ else setRenderedAttribute(el, key, String(value));
1130
1136
  }
1131
1137
  }
1132
1138
  /**
@@ -1207,23 +1213,60 @@ function materializeComponentResultNode(childInstance, result, parentNamespace)
1207
1213
  mountInstanceInline(childInstance, host);
1208
1214
  return host;
1209
1215
  }
1210
- function resolveNestedComponentResult(result, snapshot) {
1216
+ function resolveNestedComponentResult(result, snapshot, parentInstance) {
1211
1217
  let currentResult = result;
1212
1218
  let activeSnapshot = snapshot;
1213
1219
  let depth = 0;
1214
1220
  while (_isDOMElement(currentResult) && typeof currentResult.type === "function" && depth < 16) {
1215
1221
  const nestedSnapshot = getVNodeContextFrame(currentResult) ?? activeSnapshot;
1216
1222
  const nestedInstance = createComponentInstance(nextComponentInstanceId(), currentResult.type, currentResult.props ?? {}, null);
1223
+ nestedInstance.isRoot = isRouteRootComponentVNode(currentResult);
1224
+ nestedInstance.portalScope = parentInstance?.portalScope ?? nestedInstance.portalScope;
1225
+ inheritComponentCleanupStrict(nestedInstance);
1217
1226
  if (nestedSnapshot) nestedInstance.ownerFrame = nestedSnapshot;
1218
1227
  const nextResult = withContext(nestedSnapshot ?? null, () => renderComponentInline(nestedInstance));
1219
1228
  cleanupComponent(nestedInstance);
1220
- if (nextResult instanceof Promise) throw new Error("Async components are not supported. Components must return synchronously.");
1229
+ if (isPromiseLike(nextResult)) throw new Error("Async components are not supported. Components must return synchronously.");
1221
1230
  activeSnapshot = nestedSnapshot ?? null;
1222
1231
  currentResult = nextResult;
1223
1232
  depth += 1;
1224
1233
  }
1225
1234
  return currentResult;
1226
1235
  }
1236
+ function resolveHostNestedComponentResult(host, retainedInstance, result, snapshot) {
1237
+ let currentResult = result;
1238
+ let activeSnapshot = snapshot;
1239
+ let depth = 0;
1240
+ const retainedInstances = new Set([retainedInstance]);
1241
+ const createdInstances = [];
1242
+ while (_isDOMElement(currentResult) && typeof currentResult.type === "function" && depth < 16) {
1243
+ const nestedSnapshot = getVNodeContextFrame(currentResult) ?? activeSnapshot;
1244
+ let nestedInstance = findHostInstanceByType(host, currentResult.type);
1245
+ if (!nestedInstance) {
1246
+ nestedInstance = createComponentInstance(nextComponentInstanceId(), currentResult.type, currentResult.props ?? {}, null);
1247
+ createdInstances.push(nestedInstance);
1248
+ }
1249
+ setVNodeComponentInstance(currentResult, nestedInstance);
1250
+ nestedInstance.isRoot = isRouteRootComponentVNode(currentResult);
1251
+ nestedInstance.portalScope = retainedInstance.portalScope ?? nestedInstance.portalScope;
1252
+ inheritComponentCleanupStrict(nestedInstance);
1253
+ nestedInstance.props = (currentResult.props ?? {}) || {};
1254
+ if (nestedSnapshot) nestedInstance.ownerFrame = nestedSnapshot;
1255
+ const nextResult = withContext(nestedSnapshot ?? null, () => renderComponentInline(nestedInstance));
1256
+ if (isPromiseLike(nextResult)) throw new Error("Async components are not supported. Components must return synchronously.");
1257
+ retainedInstances.add(nestedInstance);
1258
+ warnUnusedStateReads(nestedInstance);
1259
+ activeSnapshot = nestedSnapshot ?? null;
1260
+ currentResult = markVNodeTreeWithContextFrame(nextResult, activeSnapshot);
1261
+ depth += 1;
1262
+ }
1263
+ const previousInstances = host.__ASKR_INSTANCES ?? [];
1264
+ for (const instance of previousInstances) if (!retainedInstances.has(instance)) cleanupComponent(instance);
1265
+ host.__ASKR_INSTANCES = previousInstances.filter((instance) => retainedInstances.has(instance));
1266
+ host.__ASKR_INSTANCE = host.__ASKR_INSTANCES[0] ?? retainedInstance;
1267
+ for (const instance of createdInstances) mountInstanceInline(instance, host);
1268
+ return currentResult;
1269
+ }
1227
1270
  function resolveWrapperHostResult(host, result, snapshot) {
1228
1271
  let currentResult = result;
1229
1272
  let activeSnapshot = snapshot;
@@ -1233,9 +1276,12 @@ function resolveWrapperHostResult(host, result, snapshot) {
1233
1276
  const nestedInstance = findHostInstanceByType(host, currentResult.type);
1234
1277
  if (!nestedInstance) break;
1235
1278
  nestedInstance.props = (currentResult.props ?? {}) || {};
1279
+ nestedInstance.isRoot = isRouteRootComponentVNode(currentResult);
1280
+ nestedInstance.portalScope = getCurrentInstance()?.portalScope ?? nestedInstance.portalScope;
1281
+ inheritComponentCleanupStrict(nestedInstance);
1236
1282
  if (nestedSnapshot) nestedInstance.ownerFrame = nestedSnapshot;
1237
1283
  const nextResult = withContext(nestedSnapshot ?? null, () => renderComponentInline(nestedInstance));
1238
- if (nextResult instanceof Promise) throw new Error("Async components are not supported. Components must return synchronously.");
1284
+ if (isPromiseLike(nextResult)) throw new Error("Async components are not supported. Components must return synchronously.");
1239
1285
  warnUnusedStateReads(nestedInstance);
1240
1286
  activeSnapshot = nestedSnapshot ?? null;
1241
1287
  currentResult = nextResult;
@@ -1262,10 +1308,13 @@ function syncComponentElement(currentDom, node, type, props, parentNamespace, fo
1262
1308
  if (!existingInstance || existingInstance.fn !== type) {
1263
1309
  const snapshot = getVNodeContextFrame(node) || getCurrentContextFrame() || null;
1264
1310
  const hydrationInstance = createComponentInstance(nextComponentInstanceId(), type, props || {}, existingHost);
1311
+ hydrationInstance.isRoot = isRouteRootComponentVNode(node);
1312
+ hydrationInstance.portalScope = getCurrentInstance()?.portalScope ?? hydrationInstance.portalScope;
1313
+ inheritComponentCleanupStrict(hydrationInstance);
1265
1314
  setVNodeComponentInstance(node, hydrationInstance);
1266
1315
  if (snapshot) hydrationInstance.ownerFrame = snapshot;
1267
1316
  const result = withContext(snapshot, () => renderComponentInline(hydrationInstance));
1268
- if (result instanceof Promise) throw new Error("Async components are not supported. Components must return synchronously.");
1317
+ if (isPromiseLike(result)) throw new Error("Async components are not supported. Components must return synchronously.");
1269
1318
  const scopedResult = markVNodeTreeWithContextFrame(result, snapshot ?? null);
1270
1319
  if (scopedResult && typeof scopedResult === "object" && "type" in scopedResult && typeof scopedResult.type === "string" && tagNamesEqualIgnoreCase(existingHost.tagName, scopedResult.type)) {
1271
1320
  withContext(snapshot, () => {
@@ -1277,7 +1326,7 @@ function syncComponentElement(currentDom, node, type, props, parentNamespace, fo
1277
1326
  warnUnusedStateReads(hydrationInstance);
1278
1327
  return existingHost;
1279
1328
  }
1280
- const resolvedResult = resolveNestedComponentResult(scopedResult, snapshot ?? null);
1329
+ const resolvedResult = resolveHostNestedComponentResult(existingHost, hydrationInstance, scopedResult, snapshot ?? null);
1281
1330
  if (_isDOMElement(resolvedResult) && typeof resolvedResult.type === "string" && tagNamesEqualIgnoreCase(existingHost.tagName, resolvedResult.type)) {
1282
1331
  withContext(snapshot, () => {
1283
1332
  updateElementFromVnode(existingHost, inheritComponentKey(resolvedResult, node), true, forceChildrenUpdate || hydrationInstance.mounted === false);
@@ -1299,9 +1348,12 @@ function syncComponentElement(currentDom, node, type, props, parentNamespace, fo
1299
1348
  }
1300
1349
  const snapshot = getVNodeContextFrame(node) || getCurrentContextFrame() || existingInstance.ownerFrame || null;
1301
1350
  existingInstance.props = props || {};
1351
+ existingInstance.isRoot = isRouteRootComponentVNode(node);
1352
+ existingInstance.portalScope = getCurrentInstance()?.portalScope ?? existingInstance.portalScope;
1353
+ inheritComponentCleanupStrict(existingInstance);
1302
1354
  if (snapshot) existingInstance.ownerFrame = snapshot;
1303
1355
  const result = withContext(snapshot, () => renderComponentInline(existingInstance));
1304
- if (result instanceof Promise) throw new Error("Async components are not supported. Components must return synchronously.");
1356
+ if (isPromiseLike(result)) throw new Error("Async components are not supported. Components must return synchronously.");
1305
1357
  const scopedResult = markVNodeTreeWithContextFrame(result, snapshot ?? null);
1306
1358
  if (existingHost.__ASKR_WRAPPER_HOST) {
1307
1359
  updateElementChildren(existingHost, normalizeComponentChildren(resolveWrapperHostResult(existingHost, scopedResult, snapshot ?? null)));
@@ -1316,7 +1368,7 @@ function syncComponentElement(currentDom, node, type, props, parentNamespace, fo
1316
1368
  warnUnusedStateReads(existingInstance);
1317
1369
  return existingHost;
1318
1370
  }
1319
- const resolvedResult = resolveNestedComponentResult(scopedResult, snapshot ?? null);
1371
+ const resolvedResult = resolveHostNestedComponentResult(existingHost, existingInstance, scopedResult, snapshot ?? null);
1320
1372
  if (_isDOMElement(resolvedResult) && typeof resolvedResult.type === "string" && tagNamesEqualIgnoreCase(existingHost.tagName, resolvedResult.type)) {
1321
1373
  withContext(snapshot, () => {
1322
1374
  updateElementFromVnode(existingHost, inheritComponentKey(resolvedResult, node), true, forceChildrenUpdate || existingInstance.mounted === false);
@@ -1350,10 +1402,13 @@ function createComponentElement(node, type, props, parentNamespace) {
1350
1402
  childInstance = createComponentInstance(nextComponentInstanceId(), componentFn, props || {}, null);
1351
1403
  setVNodeComponentInstance(node, childInstance);
1352
1404
  }
1405
+ childInstance.portalScope = getCurrentInstance()?.portalScope ?? childInstance.portalScope;
1353
1406
  childInstance.props = props || {};
1407
+ childInstance.isRoot = isRouteRootComponentVNode(node);
1408
+ inheritComponentCleanupStrict(childInstance);
1354
1409
  if (snapshot) childInstance.ownerFrame = snapshot;
1355
1410
  const result = withContext(snapshot, () => renderComponentInline(childInstance));
1356
- if (result instanceof Promise) throw new Error("Async components are not supported. Components must return synchronously.");
1411
+ if (isPromiseLike(result)) throw new Error("Async components are not supported. Components must return synchronously.");
1357
1412
  const scopedResult = markVNodeTreeWithContextFrame(result, snapshot ?? null);
1358
1413
  const dom = withContext(snapshot, () => materializeComponentResultNode(childInstance, scopedResult, parentNamespace));
1359
1414
  warnUnusedStateReads(childInstance);
@@ -1449,16 +1504,22 @@ function clearControlBoundaryCommitOwner(parent) {
1449
1504
  if (owner) {
1450
1505
  owner._enqueueBoundaryCommit = null;
1451
1506
  owner._hasPendingBoundaryCommit = false;
1507
+ if (owner._commitOwner === parent) owner._commitOwner = null;
1452
1508
  }
1453
1509
  controlBoundaryOwners.delete(parent);
1454
1510
  }
1455
1511
  function registerControlBoundaryCommitOwner(parent, controlState) {
1512
+ const ownerState = controlState;
1513
+ const previousParent = ownerState._commitOwner;
1514
+ if (previousParent && previousParent !== parent && controlBoundaryOwners.get(previousParent) === controlState) controlBoundaryOwners.delete(previousParent);
1456
1515
  const previousOwner = controlBoundaryOwners.get(parent);
1457
1516
  if (previousOwner && previousOwner !== controlState) {
1458
1517
  previousOwner._enqueueBoundaryCommit = null;
1459
1518
  previousOwner._hasPendingBoundaryCommit = false;
1519
+ if (previousOwner._commitOwner === parent) previousOwner._commitOwner = null;
1460
1520
  }
1461
1521
  controlBoundaryOwners.set(parent, controlState);
1522
+ ownerState._commitOwner = parent;
1462
1523
  controlState._enqueueBoundaryCommit = () => {
1463
1524
  if (controlState._hasPendingBoundaryCommit) return;
1464
1525
  controlState._hasPendingBoundaryCommit = true;
@@ -1631,10 +1692,13 @@ function resolveStableIntrinsicPatchVNode(dom, vnode) {
1631
1692
  if (!existingInstance || existingInstance.fn !== vnode.type || host.__ASKR_WRAPPER_HOST) return null;
1632
1693
  const snapshot = getVNodeContextFrame(vnode) || getCurrentContextFrame() || existingInstance.ownerFrame || null;
1633
1694
  existingInstance.props = (vnode.props ?? {}) || {};
1695
+ existingInstance.isRoot = isRouteRootComponentVNode(vnode);
1696
+ existingInstance.portalScope = getCurrentInstance()?.portalScope ?? existingInstance.portalScope;
1697
+ inheritComponentCleanupStrict(existingInstance);
1634
1698
  if (snapshot) existingInstance.ownerFrame = snapshot;
1635
1699
  const result = withContext(snapshot, () => renderComponentInline(existingInstance));
1636
- if (result instanceof Promise) throw new Error("Async components are not supported. Components must return synchronously.");
1637
- const resolvedResult = resolveNestedComponentResult(result, snapshot ?? null);
1700
+ if (isPromiseLike(result)) throw new Error("Async components are not supported. Components must return synchronously.");
1701
+ const resolvedResult = resolveNestedComponentResult(result, snapshot ?? null, existingInstance);
1638
1702
  if (_isDOMElement(resolvedResult) && typeof resolvedResult.type === "string" && tagNamesEqualIgnoreCase(dom.tagName, resolvedResult.type)) return inheritComponentKey(resolvedResult, vnode);
1639
1703
  return null;
1640
1704
  }
@@ -1699,35 +1763,39 @@ function updateElementFromVnode(el, vnode, updateChildren = true, forceChildrenU
1699
1763
  return;
1700
1764
  }
1701
1765
  }
1702
- let desiredEventNames = null;
1766
+ let desiredListenerKeys = null;
1767
+ let desiredDelegatedEventNames = null;
1703
1768
  let desiredReactivePropNames = null;
1704
1769
  const usesReactiveChildren = syncReactiveScalarChild(el, props.children ?? domVNode.children);
1705
1770
  if (usesReactiveChildren) (desiredReactivePropNames ??= /* @__PURE__ */ new Set()).add(REACTIVE_CHILDREN_KEY);
1706
1771
  for (const key in props) {
1707
1772
  const value = props[key];
1708
1773
  if (isSkippedProp(key)) continue;
1709
- const eventName = parseEventName(key);
1774
+ const eventProp = parseEventProp(key);
1775
+ const eventName = eventProp?.eventName;
1776
+ const eventCapture = eventProp?.capture ?? false;
1777
+ const listenerKey = eventName === void 0 ? null : getEventListenerKey(eventName, eventCapture);
1710
1778
  if (value === void 0 || value === null || value === false) {
1711
1779
  if (key === "class" || key === "className") writeElementClassName(el, "");
1712
1780
  else if (key === "value") applyFormControlProp(el, key, "", vnode.type);
1713
1781
  else if (key === "checked") applyFormControlProp(el, key, false, vnode.type);
1714
- else if (eventName && existingListeners?.has(eventName)) {
1715
- const entry = existingListeners.get(eventName);
1782
+ else if (listenerKey && existingListeners?.has(listenerKey)) {
1783
+ const entry = existingListeners.get(listenerKey);
1716
1784
  incDevCounter("listenerRemoves");
1717
- if (entry.isDelegated) removeDelegatedListener(el, eventName);
1718
- else if (entry.options !== void 0) el.removeEventListener(eventName, entry.handler, entry.options);
1719
- else el.removeEventListener(eventName, entry.handler);
1720
- existingListeners.delete(eventName);
1785
+ if (entry.isDelegated) removeDelegatedListener(el, entry.eventName);
1786
+ else if (entry.options !== void 0) el.removeEventListener(entry.eventName, entry.handler, entry.options);
1787
+ else el.removeEventListener(entry.eventName, entry.handler);
1788
+ existingListeners.delete(listenerKey);
1721
1789
  } else {
1722
1790
  const entry = existingReactiveProps?.get(key);
1723
1791
  if (entry) {
1724
1792
  entry.cleanup();
1725
1793
  existingReactiveProps?.delete(key);
1726
- } else el.removeAttribute(key);
1794
+ } else removeRenderedAttribute(el, key);
1727
1795
  }
1728
1796
  continue;
1729
1797
  }
1730
- if (typeof value === "function" && !eventName && key !== "ref") {
1798
+ if (typeof value === "function" && !eventProp && key !== "ref") {
1731
1799
  const existingEntry = existingReactiveProps?.get(key);
1732
1800
  if (existingReactiveProps && existingReactiveProps.size > 0) (desiredReactivePropNames ??= /* @__PURE__ */ new Set()).add(key);
1733
1801
  if (existingEntry && existingEntry.fnRef === value) continue;
@@ -1756,9 +1824,11 @@ function updateElementFromVnode(el, vnode, updateChildren = true, forceChildrenU
1756
1824
  if (key === "class" || key === "className") writeElementClassName(el, String(value));
1757
1825
  else if (key === "style") applyStylePropValue(el, value);
1758
1826
  else if (key === "value" || key === "checked") applyFormControlProp(el, key, value, vnode.type);
1759
- else if (eventName) {
1760
- const useDelegation = isEventDelegationEnabled() && isDelegatedEvent(eventName);
1761
- (desiredEventNames ??= /* @__PURE__ */ new Set()).add(eventName);
1827
+ else if (eventProp && listenerKey) {
1828
+ const eventName = eventProp.eventName;
1829
+ const eventCapture = eventProp.capture;
1830
+ const useDelegation = !eventCapture && isEventDelegationEnabled() && isDelegatedEvent(eventName);
1831
+ if (useDelegation) (desiredDelegatedEventNames ??= /* @__PURE__ */ new Set()).add(eventName);
1762
1832
  if (useDelegation) {
1763
1833
  const existingDelegated = getDelegatedHandlerForElement(el, eventName);
1764
1834
  if (existingDelegated?.original === value) continue;
@@ -1766,7 +1836,8 @@ function updateElementFromVnode(el, vnode, updateChildren = true, forceChildrenU
1766
1836
  addDelegatedListener(el, eventName, value, value, void 0);
1767
1837
  continue;
1768
1838
  }
1769
- const existing = existingListeners?.get(eventName);
1839
+ (desiredListenerKeys ??= /* @__PURE__ */ new Set()).add(listenerKey);
1840
+ const existing = existingListeners?.get(listenerKey);
1770
1841
  if (existing && existing.original === value) continue;
1771
1842
  if (existing) {
1772
1843
  if (useDelegation && existing.isDelegated && updateDelegatedListener(el, eventName, value, value, void 0)) {
@@ -1780,11 +1851,11 @@ function updateElementFromVnode(el, vnode, updateChildren = true, forceChildrenU
1780
1851
  existing.original = value;
1781
1852
  continue;
1782
1853
  }
1783
- if (existing.isDelegated) removeDelegatedListener(el, eventName);
1784
- else if (existing.options !== void 0) el.removeEventListener(eventName, existing.handler, existing.options);
1785
- else el.removeEventListener(eventName, existing.handler);
1854
+ if (existing.isDelegated) removeDelegatedListener(el, existing.eventName);
1855
+ else if (existing.options !== void 0) el.removeEventListener(existing.eventName, existing.handler, existing.options);
1856
+ else el.removeEventListener(existing.eventName, existing.handler);
1786
1857
  }
1787
- const options = getPassiveOptions(eventName);
1858
+ const options = getEventListenerOptions(eventName, eventCapture);
1788
1859
  const mutableHandler = createMutableWrappedHandler(value, true);
1789
1860
  const trackedHandler = mutableHandler.handler;
1790
1861
  if (options !== void 0) el.addEventListener(eventName, trackedHandler, options);
@@ -1793,39 +1864,40 @@ function updateElementFromVnode(el, vnode, updateChildren = true, forceChildrenU
1793
1864
  const listenerEntry = {
1794
1865
  handler: trackedHandler,
1795
1866
  original: value,
1867
+ eventName,
1796
1868
  options,
1797
1869
  isDelegated: false,
1798
1870
  updateHandler: mutableHandler?.updateHandler
1799
1871
  };
1800
1872
  if (!elementListeners.has(el)) elementListeners.set(el, /* @__PURE__ */ new Map());
1801
- elementListeners.get(el).set(eventName, listenerEntry);
1802
- } else el.setAttribute(key, String(value));
1873
+ elementListeners.get(el).set(listenerKey, listenerEntry);
1874
+ } else setRenderedAttribute(el, key, String(value));
1803
1875
  }
1804
1876
  removeStaleAttributes(el, domVNode, props);
1805
- if (existingListeners && existingListeners.size > 0) if (desiredEventNames === null) {
1806
- existingListeners.forEach((entry, eventName) => {
1877
+ if (existingListeners && existingListeners.size > 0) if (desiredListenerKeys === null) {
1878
+ existingListeners.forEach((entry) => {
1807
1879
  incDevCounter("listenerRemoves");
1808
- if (entry.isDelegated) removeDelegatedListener(el, eventName);
1809
- else if (entry.options !== void 0) el.removeEventListener(eventName, entry.handler, entry.options);
1810
- else el.removeEventListener(eventName, entry.handler);
1880
+ if (entry.isDelegated) removeDelegatedListener(el, entry.eventName);
1881
+ else if (entry.options !== void 0) el.removeEventListener(entry.eventName, entry.handler, entry.options);
1882
+ else el.removeEventListener(entry.eventName, entry.handler);
1811
1883
  });
1812
1884
  elementListeners.delete(el);
1813
1885
  } else {
1814
- existingListeners.forEach((entry, eventName) => {
1815
- if (!desiredEventNames.has(eventName)) {
1886
+ existingListeners.forEach((entry, listenerKey) => {
1887
+ if (!desiredListenerKeys.has(listenerKey)) {
1816
1888
  incDevCounter("listenerRemoves");
1817
- if (entry.isDelegated) removeDelegatedListener(el, eventName);
1818
- else if (entry.options !== void 0) el.removeEventListener(eventName, entry.handler, entry.options);
1819
- else el.removeEventListener(eventName, entry.handler);
1820
- existingListeners.delete(eventName);
1889
+ if (entry.isDelegated) removeDelegatedListener(el, entry.eventName);
1890
+ else if (entry.options !== void 0) el.removeEventListener(entry.eventName, entry.handler, entry.options);
1891
+ else el.removeEventListener(entry.eventName, entry.handler);
1892
+ existingListeners.delete(listenerKey);
1821
1893
  }
1822
1894
  });
1823
1895
  if (existingListeners.size === 0) elementListeners.delete(el);
1824
1896
  }
1825
1897
  const delegatedHandlers = getDelegatedHandlersForElement(el);
1826
1898
  if (delegatedHandlers && delegatedHandlers.size > 0) {
1827
- if (desiredEventNames === null) for (const eventName of delegatedHandlers.keys()) removeDelegatedListener(el, eventName);
1828
- else for (const eventName of delegatedHandlers.keys()) if (!desiredEventNames.has(eventName)) removeDelegatedListener(el, eventName);
1899
+ if (desiredDelegatedEventNames === null) for (const eventName of delegatedHandlers.keys()) removeDelegatedListener(el, eventName);
1900
+ else for (const eventName of delegatedHandlers.keys()) if (!desiredDelegatedEventNames.has(eventName)) removeDelegatedListener(el, eventName);
1829
1901
  }
1830
1902
  if (existingReactiveProps && existingReactiveProps.size > 0) if (desiredReactivePropNames === null) {
1831
1903
  existingReactiveProps.forEach((entry) => {
@@ -2028,7 +2100,7 @@ function hasMatchingStaticProps(el, props, vnodeType) {
2028
2100
  staticPropCount += 1;
2029
2101
  continue;
2030
2102
  }
2031
- if (el.getAttribute(key) !== String(value)) return false;
2103
+ if (el.getAttribute(getRenderedAttributeName(el, key)) !== String(value)) return false;
2032
2104
  staticPropCount += 1;
2033
2105
  }
2034
2106
  return el.attributes.length === staticPropCount;
@@ -2058,6 +2130,32 @@ function updateUnkeyedChildren(parent, newChildren, forceUpdate = false) {
2058
2130
  if (typeof next.type !== "function") return null;
2059
2131
  return syncComponentElement(currentDom, next, next.type, (next.props ?? {}) || {}, parentNamespace, forceUpdate);
2060
2132
  };
2133
+ const trySyncControlBoundaryChild = (parent, currentNode, next) => {
2134
+ if (next.type !== __FOR_BOUNDARY__) return false;
2135
+ const controlState = getControlBoundaryState(next);
2136
+ if (!controlState || controlState.kind === "for") return false;
2137
+ const childrenVNodes = evaluateControlBoundaryState(controlState);
2138
+ const activeScope = controlState.activeScope;
2139
+ const activeVNode = childrenVNodes[0];
2140
+ const nextDom = activeScope && activeVNode !== void 0 ? syncForItemDom(parent, activeScope, activeVNode) : null;
2141
+ for (let i = 0; i < controlState.lastRemovedNodes.length; i++) {
2142
+ const removedNode = controlState.lastRemovedNodes[i];
2143
+ if (removedNode.parentNode !== parent) continue;
2144
+ teardownNodeSubtree(removedNode);
2145
+ if (nextDom && nextDom !== removedNode && !nextDom.parentNode) parent.replaceChild(nextDom, removedNode);
2146
+ else parent.removeChild(removedNode);
2147
+ }
2148
+ if (nextDom && !nextDom.parentNode) if (currentNode?.parentNode === parent) {
2149
+ teardownNodeSubtree(currentNode);
2150
+ parent.replaceChild(nextDom, currentNode);
2151
+ } else parent.appendChild(nextDom);
2152
+ else if (!nextDom && currentNode?.parentNode === parent) {
2153
+ teardownNodeSubtree(currentNode);
2154
+ parent.removeChild(currentNode);
2155
+ }
2156
+ clearControlBoundaryDomUpdateState(controlState);
2157
+ return true;
2158
+ };
2061
2159
  const hasText = newChildren.some((c) => typeof c === "string" || typeof c === "number");
2062
2160
  const hasElements = newChildren.some((c) => _isDOMElement(c));
2063
2161
  const hasEmptyChildren = newChildren.some(isEmptyChild);
@@ -2078,6 +2176,7 @@ function updateUnkeyedChildren(parent, newChildren, forceUpdate = false) {
2078
2176
  }
2079
2177
  }
2080
2178
  else if (_isDOMElement(next)) {
2179
+ if (trySyncControlBoundaryChild(parent, current, next)) continue;
2081
2180
  const synced = trySyncComponentChild(current, next);
2082
2181
  if (synced && synced !== current) teardownNodeSubtree(current);
2083
2182
  else if (!synced) {
@@ -2132,6 +2231,7 @@ function updateUnkeyedChildren(parent, newChildren, forceUpdate = false) {
2132
2231
  }
2133
2232
  }
2134
2233
  else {
2234
+ if (trySyncControlBoundaryChild(parent, currentNode, next)) continue;
2135
2235
  const synced = trySyncComponentChild(currentEl, next);
2136
2236
  if (synced && synced !== currentNode) teardownNodeSubtree(currentEl);
2137
2237
  else if (!synced) {