@remix-run/ui 0.3.0 → 0.5.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 (434) hide show
  1. package/README.md +116 -157
  2. package/dist/accordion/index.d.ts +46 -0
  3. package/dist/accordion/index.js +142 -0
  4. package/dist/accordion/index.js.map +1 -0
  5. package/dist/accordion/primitives.d.ts +104 -0
  6. package/dist/accordion/primitives.js +312 -0
  7. package/dist/accordion/primitives.js.map +1 -0
  8. package/dist/{components/anchor/anchor.js → anchor/index.js} +1 -1
  9. package/dist/anchor/index.js.map +1 -0
  10. package/dist/animation/animate-layout-mixin.js +1 -1
  11. package/dist/animation/animate-layout-mixin.js.map +1 -1
  12. package/dist/animation/animate-mixins.js +2 -2
  13. package/dist/animation/animate-mixins.js.map +1 -1
  14. package/dist/animation/demos/color-interpolation.js +1 -1
  15. package/dist/animation/demos/color-interpolation.js.map +1 -1
  16. package/dist/animation/demos/drag-release.d.ts +1 -1
  17. package/dist/animation/demos/hold-to-confirm.d.ts +3 -3
  18. package/dist/animation/demos/material-ripple.js +1 -3
  19. package/dist/animation/demos/material-ripple.js.map +1 -1
  20. package/dist/animation/demos/reordering.js +9 -6
  21. package/dist/animation/demos/reordering.js.map +1 -1
  22. package/dist/animation/index.js +4 -4
  23. package/dist/animation/spring.js.map +1 -1
  24. package/dist/{components/breadcrumbs/breadcrumbs.js → breadcrumbs/index.js} +19 -19
  25. package/dist/breadcrumbs/index.js.map +1 -0
  26. package/dist/button/index.d.ts +15 -0
  27. package/dist/button/index.js +128 -0
  28. package/dist/button/index.js.map +1 -0
  29. package/dist/checkbox/index.d.ts +14 -0
  30. package/dist/checkbox/index.js +127 -0
  31. package/dist/checkbox/index.js.map +1 -0
  32. package/dist/combobox/index.d.ts +21 -0
  33. package/dist/combobox/index.js +58 -0
  34. package/dist/combobox/index.js.map +1 -0
  35. package/dist/{components/combobox/combobox.d.ts → combobox/primitives.d.ts} +4 -8
  36. package/dist/{components/combobox/combobox.js → combobox/primitives.js} +8 -61
  37. package/dist/combobox/primitives.js.map +1 -0
  38. package/dist/dev/refresh.d.ts +1 -0
  39. package/dist/dev/refresh.js +2 -0
  40. package/dist/dev/refresh.js.map +1 -0
  41. package/dist/index.d.ts +1 -1
  42. package/dist/index.js +14 -14
  43. package/dist/input/index.d.ts +13 -0
  44. package/dist/input/index.js +121 -0
  45. package/dist/input/index.js.map +1 -0
  46. package/dist/jsx-runtime.js +2 -2
  47. package/dist/listbox/flash-attribute.js.map +1 -0
  48. package/dist/{components/listbox/listbox.d.ts → listbox/index.d.ts} +2 -6
  49. package/dist/{components/listbox/listbox.js → listbox/index.js} +4 -82
  50. package/dist/listbox/index.js.map +1 -0
  51. package/dist/menu/hover-aim.js.map +1 -0
  52. package/dist/menu/index.d.ts +42 -0
  53. package/dist/menu/index.js +250 -0
  54. package/dist/menu/index.js.map +1 -0
  55. package/dist/{components/menu/menu.d.ts → menu/primitives.d.ts} +4 -33
  56. package/dist/{components/menu/menu.js → menu/primitives.js} +98 -315
  57. package/dist/menu/primitives.js.map +1 -0
  58. package/dist/{components/popover/popover.d.ts → popover/index.d.ts} +2 -4
  59. package/dist/{components/popover/popover.js → popover/index.js} +5 -48
  60. package/dist/popover/index.js.map +1 -0
  61. package/dist/{interactions/outside-click/outside-click-mixin.js → popover/outside-click.js} +1 -1
  62. package/dist/popover/outside-click.js.map +1 -0
  63. package/dist/popover/scroll-lock.d.ts +1 -0
  64. package/dist/{utils → popover}/scroll-lock.js +0 -18
  65. package/dist/popover/scroll-lock.js.map +1 -0
  66. package/dist/radio/index.d.ts +12 -0
  67. package/dist/radio/index.js +77 -0
  68. package/dist/radio/index.js.map +1 -0
  69. package/dist/runtime/client-entry-boundary.d.ts +14 -0
  70. package/dist/runtime/client-entry-boundary.js +29 -0
  71. package/dist/runtime/client-entry-boundary.js.map +1 -0
  72. package/dist/runtime/component.d.ts +19 -4
  73. package/dist/runtime/component.js +39 -9
  74. package/dist/runtime/component.js.map +1 -1
  75. package/dist/runtime/core/attributes.js +36 -3
  76. package/dist/runtime/core/attributes.js.map +1 -1
  77. package/dist/runtime/core/children.d.ts +2 -0
  78. package/dist/runtime/core/children.js +26 -2
  79. package/dist/runtime/core/children.js.map +1 -1
  80. package/dist/runtime/core/props.js +2 -2
  81. package/dist/runtime/core/vnode.d.ts +3 -3
  82. package/dist/runtime/core/vnode.js +22 -1
  83. package/dist/runtime/core/vnode.js.map +1 -1
  84. package/dist/runtime/create-element.d.ts +2 -2
  85. package/dist/runtime/create-element.js +3 -2
  86. package/dist/runtime/create-element.js.map +1 -1
  87. package/dist/runtime/diff-dom.js +294 -219
  88. package/dist/runtime/diff-dom.js.map +1 -1
  89. package/dist/runtime/diff-props.js +3 -3
  90. package/dist/runtime/dom.d.ts +12 -0
  91. package/dist/runtime/element-function.d.ts +3 -0
  92. package/dist/runtime/element-function.js +2 -0
  93. package/dist/runtime/element-function.js.map +1 -0
  94. package/dist/runtime/form-navigation.d.ts +25 -0
  95. package/dist/runtime/form-navigation.js +132 -0
  96. package/dist/runtime/form-navigation.js.map +1 -0
  97. package/dist/runtime/frame-resolution.d.ts +5 -0
  98. package/dist/runtime/frame-resolution.js +10 -0
  99. package/dist/runtime/frame-resolution.js.map +1 -0
  100. package/dist/runtime/frame.d.ts +58 -15
  101. package/dist/runtime/frame.js +367 -114
  102. package/dist/runtime/frame.js.map +1 -1
  103. package/dist/runtime/jsx.d.ts +1 -1
  104. package/dist/runtime/jsx.js +1 -1
  105. package/dist/runtime/jsx.js.map +1 -1
  106. package/dist/runtime/key.d.ts +1 -0
  107. package/dist/runtime/key.js +2 -0
  108. package/dist/runtime/key.js.map +1 -0
  109. package/dist/runtime/mixins/attrs-mixin.js +2 -2
  110. package/dist/runtime/mixins/link-mixin.js +4 -3
  111. package/dist/runtime/mixins/link-mixin.js.map +1 -1
  112. package/dist/runtime/mixins/mixin.d.ts +15 -10
  113. package/dist/runtime/mixins/mixin.js +4 -4
  114. package/dist/runtime/mixins/mixin.js.map +1 -1
  115. package/dist/runtime/mixins/on-mixin.js +1 -1
  116. package/dist/runtime/mixins/ref-mixin.js +1 -1
  117. package/dist/runtime/navigation.d.ts +4 -1
  118. package/dist/runtime/navigation.js +157 -32
  119. package/dist/runtime/navigation.js.map +1 -1
  120. package/dist/runtime/reconcile.d.ts +11 -10
  121. package/dist/runtime/reconcile.js +557 -423
  122. package/dist/runtime/reconcile.js.map +1 -1
  123. package/dist/runtime/refresh.d.ts +28 -0
  124. package/dist/runtime/refresh.js +31 -0
  125. package/dist/runtime/refresh.js.map +1 -0
  126. package/dist/runtime/render.js +1 -1
  127. package/dist/runtime/render.js.map +1 -1
  128. package/dist/runtime/run.d.ts +3 -1
  129. package/dist/runtime/run.js +15 -7
  130. package/dist/runtime/run.js.map +1 -1
  131. package/dist/runtime/scheduler.js +8 -16
  132. package/dist/runtime/scheduler.js.map +1 -1
  133. package/dist/runtime/to-vnode.d.ts +2 -2
  134. package/dist/runtime/to-vnode.js +68 -20
  135. package/dist/runtime/to-vnode.js.map +1 -1
  136. package/dist/runtime/vdom.d.ts +4 -2
  137. package/dist/runtime/vdom.js +89 -41
  138. package/dist/runtime/vdom.js.map +1 -1
  139. package/dist/runtime/vnode.d.ts +138 -67
  140. package/dist/runtime/vnode.js +17 -12
  141. package/dist/runtime/vnode.js.map +1 -1
  142. package/dist/select/index.d.ts +19 -0
  143. package/dist/select/index.js +95 -0
  144. package/dist/select/index.js.map +1 -0
  145. package/dist/select/keydown.js.map +1 -0
  146. package/dist/{components/select/select.d.ts → select/primitives.d.ts} +5 -7
  147. package/dist/{components/select/select.js → select/primitives.js} +11 -63
  148. package/dist/select/primitives.js.map +1 -0
  149. package/dist/server/stream.js +22 -29
  150. package/dist/server/stream.js.map +1 -1
  151. package/dist/shared/focus-styles.d.ts +1 -0
  152. package/dist/shared/focus-styles.js +2 -0
  153. package/dist/shared/focus-styles.js.map +1 -0
  154. package/dist/shared/icons.d.ts +9 -0
  155. package/dist/shared/icons.js +42 -0
  156. package/dist/shared/icons.js.map +1 -0
  157. package/dist/shared/listbox-popover-styles.d.ts +6 -0
  158. package/dist/shared/listbox-popover-styles.js +137 -0
  159. package/dist/shared/listbox-popover-styles.js.map +1 -0
  160. package/dist/shared/style-values.d.ts +78 -0
  161. package/dist/shared/style-values.js +88 -0
  162. package/dist/shared/style-values.js.map +1 -0
  163. package/dist/{interactions/typeahead/typeahead-mixin.js → shared/typeahead.js} +1 -1
  164. package/dist/shared/typeahead.js.map +1 -0
  165. package/dist/shared/wait-for-css-transition.js.map +1 -0
  166. package/dist/shared/wait.js.map +1 -0
  167. package/dist/style/css-mixin.js +3 -3
  168. package/dist/style/index.js +2 -2
  169. package/dist/style/style.js +25 -6
  170. package/dist/style/style.js.map +1 -1
  171. package/dist/style/stylesheet.d.ts +0 -1
  172. package/dist/style/stylesheet.js +13 -54
  173. package/dist/style/stylesheet.js.map +1 -1
  174. package/dist/tabs/index.d.ts +32 -0
  175. package/dist/tabs/index.js +157 -0
  176. package/dist/tabs/index.js.map +1 -0
  177. package/dist/tabs/primitives.d.ts +57 -0
  178. package/dist/tabs/primitives.js +238 -0
  179. package/dist/tabs/primitives.js.map +1 -0
  180. package/dist/test.js +1 -1
  181. package/dist/toggle/index.d.ts +9 -0
  182. package/dist/toggle/index.js +108 -0
  183. package/dist/toggle/index.js.map +1 -0
  184. package/dist/toggle/primitives.d.ts +29 -0
  185. package/dist/toggle/primitives.js +127 -0
  186. package/dist/toggle/primitives.js.map +1 -0
  187. package/package.json +81 -49
  188. package/src/{components/accordion → accordion}/README.md +50 -14
  189. package/src/accordion/index.tsx +285 -0
  190. package/src/accordion/primitives.tsx +512 -0
  191. package/src/{components/anchor → anchor}/README.md +37 -2
  192. package/src/animation/animate-mixins.ts +3 -3
  193. package/src/animation/demos/color-interpolation.tsx +1 -1
  194. package/src/animation/demos/reordering.tsx +9 -6
  195. package/src/{components/breadcrumbs → breadcrumbs}/README.md +4 -4
  196. package/src/{components/breadcrumbs/breadcrumbs.tsx → breadcrumbs/index.tsx} +18 -18
  197. package/src/button/README.md +44 -0
  198. package/src/button/index.ts +168 -0
  199. package/src/checkbox/README.md +59 -0
  200. package/src/checkbox/index.ts +164 -0
  201. package/src/{components/combobox → combobox}/README.md +58 -9
  202. package/src/combobox/index.tsx +112 -0
  203. package/src/{components/combobox/combobox.tsx → combobox/primitives.tsx} +5 -91
  204. package/src/dev/refresh.ts +1 -0
  205. package/src/index.ts +1 -1
  206. package/src/input/README.md +52 -0
  207. package/src/input/index.ts +147 -0
  208. package/src/{components/listbox → listbox}/README.md +9 -41
  209. package/src/{components/listbox/listbox.ts → listbox/index.ts} +2 -87
  210. package/src/{components/menu → menu}/README.md +55 -14
  211. package/src/menu/index.tsx +354 -0
  212. package/src/{components/menu/menu.tsx → menu/primitives.tsx} +99 -413
  213. package/src/{components/popover → popover}/README.md +20 -39
  214. package/src/{components/popover/popover.ts → popover/index.ts} +3 -57
  215. package/src/{utils → popover}/scroll-lock.ts +0 -28
  216. package/src/radio/README.md +53 -0
  217. package/src/radio/index.ts +101 -0
  218. package/src/runtime/client-entry-boundary.ts +54 -0
  219. package/src/runtime/component.ts +65 -16
  220. package/src/runtime/core/attributes.ts +35 -1
  221. package/src/runtime/core/children.ts +24 -2
  222. package/src/runtime/core/vnode.ts +25 -4
  223. package/src/runtime/create-element.ts +6 -5
  224. package/src/runtime/demos/readme.demo.tsx +20 -18
  225. package/src/runtime/diff-dom.ts +358 -243
  226. package/src/runtime/dom.ts +331 -214
  227. package/src/runtime/element-function.ts +1 -0
  228. package/src/runtime/event-listeners.ts +1 -1
  229. package/src/runtime/form-navigation.ts +184 -0
  230. package/src/runtime/frame-resolution.ts +13 -0
  231. package/src/runtime/frame.ts +482 -124
  232. package/src/runtime/jsx.ts +3 -5
  233. package/src/runtime/key.ts +1 -0
  234. package/src/runtime/mixins/link-mixin.ts +1 -0
  235. package/src/runtime/mixins/mixin.ts +21 -18
  236. package/src/runtime/navigation.ts +204 -30
  237. package/src/runtime/reconcile.ts +769 -760
  238. package/src/runtime/refresh.ts +46 -0
  239. package/src/runtime/run.ts +12 -2
  240. package/src/runtime/scheduler.ts +9 -29
  241. package/src/runtime/to-vnode.ts +85 -23
  242. package/src/runtime/vdom.ts +91 -69
  243. package/src/runtime/vnode.ts +192 -88
  244. package/src/{components/select → select}/README.md +29 -19
  245. package/src/select/index.tsx +159 -0
  246. package/src/{components/select/select.tsx → select/primitives.tsx} +10 -98
  247. package/src/server/stream.ts +25 -31
  248. package/src/shared/focus-styles.ts +2 -0
  249. package/src/shared/icons.tsx +62 -0
  250. package/src/shared/listbox-popover-styles.ts +146 -0
  251. package/src/shared/style-values.ts +165 -0
  252. package/src/style/style.ts +25 -6
  253. package/src/style/stylesheet.ts +32 -57
  254. package/src/tabs/README.md +141 -0
  255. package/src/tabs/index.tsx +245 -0
  256. package/src/tabs/primitives.ts +365 -0
  257. package/src/test/README.md +151 -60
  258. package/src/toggle/README.md +56 -0
  259. package/src/toggle/index.tsx +136 -0
  260. package/src/toggle/primitives.ts +192 -0
  261. package/dist/animation/demos/animation.demo.d.ts +0 -5
  262. package/dist/animation/demos/animation.demo.js +0 -92
  263. package/dist/animation/demos/animation.demo.js.map +0 -1
  264. package/dist/animation/demos/spring.demo.d.ts +0 -6
  265. package/dist/animation/demos/spring.demo.js +0 -304
  266. package/dist/animation/demos/spring.demo.js.map +0 -1
  267. package/dist/components/accordion/accordion.d.ts +0 -92
  268. package/dist/components/accordion/accordion.js +0 -335
  269. package/dist/components/accordion/accordion.js.map +0 -1
  270. package/dist/components/accordion/demos/card.demo.d.ts +0 -7
  271. package/dist/components/accordion/demos/card.demo.js +0 -59
  272. package/dist/components/accordion/demos/card.demo.js.map +0 -1
  273. package/dist/components/accordion/demos/multiple.demo.d.ts +0 -7
  274. package/dist/components/accordion/demos/multiple.demo.js +0 -20
  275. package/dist/components/accordion/demos/multiple.demo.js.map +0 -1
  276. package/dist/components/accordion/demos/overview.demo.d.ts +0 -7
  277. package/dist/components/accordion/demos/overview.demo.js +0 -20
  278. package/dist/components/accordion/demos/overview.demo.js.map +0 -1
  279. package/dist/components/anchor/anchor.js.map +0 -1
  280. package/dist/components/breadcrumbs/basic.demo.d.ts +0 -6
  281. package/dist/components/breadcrumbs/basic.demo.js +0 -15
  282. package/dist/components/breadcrumbs/basic.demo.js.map +0 -1
  283. package/dist/components/breadcrumbs/breadcrumbs.js.map +0 -1
  284. package/dist/components/breadcrumbs/separator.demo.d.ts +0 -6
  285. package/dist/components/breadcrumbs/separator.demo.js +0 -15
  286. package/dist/components/breadcrumbs/separator.demo.js.map +0 -1
  287. package/dist/components/button/button.d.ts +0 -105
  288. package/dist/components/button/button.js +0 -207
  289. package/dist/components/button/button.js.map +0 -1
  290. package/dist/components/button/demos/aliases.demo.d.ts +0 -7
  291. package/dist/components/button/demos/aliases.demo.js +0 -19
  292. package/dist/components/button/demos/aliases.demo.js.map +0 -1
  293. package/dist/components/button/demos/basic.demo.d.ts +0 -7
  294. package/dist/components/button/demos/basic.demo.js +0 -20
  295. package/dist/components/button/demos/basic.demo.js.map +0 -1
  296. package/dist/components/button/demos/states.demo.d.ts +0 -7
  297. package/dist/components/button/demos/states.demo.js +0 -30
  298. package/dist/components/button/demos/states.demo.js.map +0 -1
  299. package/dist/components/combobox/combobox.js.map +0 -1
  300. package/dist/components/combobox/overview.demo.d.ts +0 -7
  301. package/dist/components/combobox/overview.demo.js +0 -154
  302. package/dist/components/combobox/overview.demo.js.map +0 -1
  303. package/dist/components/glyph/glyph.d.ts +0 -14
  304. package/dist/components/glyph/glyph.js +0 -65
  305. package/dist/components/glyph/glyph.js.map +0 -1
  306. package/dist/components/listbox/listbox.js.map +0 -1
  307. package/dist/components/listbox/overview.demo.d.ts +0 -7
  308. package/dist/components/listbox/overview.demo.js +0 -65
  309. package/dist/components/listbox/overview.demo.js.map +0 -1
  310. package/dist/components/menu/demos/bubbling.demo.d.ts +0 -6
  311. package/dist/components/menu/demos/bubbling.demo.js +0 -16
  312. package/dist/components/menu/demos/bubbling.demo.js.map +0 -1
  313. package/dist/components/menu/demos/context-trigger.demo.d.ts +0 -7
  314. package/dist/components/menu/demos/context-trigger.demo.js +0 -87
  315. package/dist/components/menu/demos/context-trigger.demo.js.map +0 -1
  316. package/dist/components/menu/demos/overview.demo.d.ts +0 -7
  317. package/dist/components/menu/demos/overview.demo.js +0 -33
  318. package/dist/components/menu/demos/overview.demo.js.map +0 -1
  319. package/dist/components/menu/hover-aim.js.map +0 -1
  320. package/dist/components/menu/menu.js.map +0 -1
  321. package/dist/components/popover/overview.demo.d.ts +0 -7
  322. package/dist/components/popover/overview.demo.js +0 -65
  323. package/dist/components/popover/overview.demo.js.map +0 -1
  324. package/dist/components/popover/popover.js.map +0 -1
  325. package/dist/components/select/deconstructed.demo.d.ts +0 -7
  326. package/dist/components/select/deconstructed.demo.js +0 -54
  327. package/dist/components/select/deconstructed.demo.js.map +0 -1
  328. package/dist/components/select/overview.demo.d.ts +0 -6
  329. package/dist/components/select/overview.demo.js +0 -28
  330. package/dist/components/select/overview.demo.js.map +0 -1
  331. package/dist/components/select/select.js.map +0 -1
  332. package/dist/components/separator/separator.d.ts +0 -2
  333. package/dist/components/separator/separator.js +0 -15
  334. package/dist/components/separator/separator.js.map +0 -1
  335. package/dist/components/tabs/tabs.d.ts +0 -78
  336. package/dist/components/tabs/tabs.js +0 -339
  337. package/dist/components/tabs/tabs.js.map +0 -1
  338. package/dist/interactions/keydown/keydown.js.map +0 -1
  339. package/dist/interactions/outside-click/outside-click-mixin.js.map +0 -1
  340. package/dist/interactions/typeahead/typeahead-mixin.js.map +0 -1
  341. package/dist/runtime/demos/basic.demo.d.ts +0 -6
  342. package/dist/runtime/demos/basic.demo.js +0 -16
  343. package/dist/runtime/demos/basic.demo.js.map +0 -1
  344. package/dist/runtime/demos/controlled-uncontrolled-values.demo.d.ts +0 -6
  345. package/dist/runtime/demos/controlled-uncontrolled-values.demo.js +0 -77
  346. package/dist/runtime/demos/controlled-uncontrolled-values.demo.js.map +0 -1
  347. package/dist/runtime/demos/keyed-list.demo.d.ts +0 -6
  348. package/dist/runtime/demos/keyed-list.demo.js +0 -62
  349. package/dist/runtime/demos/keyed-list.demo.js.map +0 -1
  350. package/dist/runtime/demos/readme.demo.d.ts +0 -5
  351. package/dist/runtime/demos/readme.demo.js +0 -396
  352. package/dist/runtime/demos/readme.demo.js.map +0 -1
  353. package/dist/theme/contract.d.ts +0 -61
  354. package/dist/theme/contract.js +0 -131
  355. package/dist/theme/contract.js.map +0 -1
  356. package/dist/theme/glyph-contract.d.ts +0 -11
  357. package/dist/theme/glyph-contract.js +0 -34
  358. package/dist/theme/glyph-contract.js.map +0 -1
  359. package/dist/theme/presets/rmx-01/glyphs.d.ts +0 -2
  360. package/dist/theme/presets/rmx-01/glyphs.js +0 -252
  361. package/dist/theme/presets/rmx-01/glyphs.js.map +0 -1
  362. package/dist/theme/presets/rmx-01/index.d.ts +0 -4
  363. package/dist/theme/presets/rmx-01/index.js +0 -119
  364. package/dist/theme/presets/rmx-01/index.js.map +0 -1
  365. package/dist/theme/runtime.d.ts +0 -2
  366. package/dist/theme/runtime.js +0 -84
  367. package/dist/theme/runtime.js.map +0 -1
  368. package/dist/theme/theme.d.ts +0 -6
  369. package/dist/theme/theme.js +0 -5
  370. package/dist/theme/theme.js.map +0 -1
  371. package/dist/utils/flash-attribute.js.map +0 -1
  372. package/dist/utils/scroll-lock.d.ts +0 -3
  373. package/dist/utils/scroll-lock.js.map +0 -1
  374. package/dist/utils/wait-for-css-transition.js.map +0 -1
  375. package/dist/utils/wait.js.map +0 -1
  376. package/src/animation/demos/animation.demo.tsx +0 -194
  377. package/src/animation/demos/spring.demo.tsx +0 -385
  378. package/src/components/accordion/accordion.tsx +0 -565
  379. package/src/components/accordion/demos/card.demo.tsx +0 -114
  380. package/src/components/accordion/demos/multiple.demo.tsx +0 -57
  381. package/src/components/accordion/demos/overview.demo.tsx +0 -57
  382. package/src/components/breadcrumbs/basic.demo.tsx +0 -18
  383. package/src/components/breadcrumbs/separator.demo.tsx +0 -19
  384. package/src/components/button/README.md +0 -44
  385. package/src/components/button/button.tsx +0 -286
  386. package/src/components/button/demos/aliases.demo.tsx +0 -28
  387. package/src/components/button/demos/basic.demo.tsx +0 -31
  388. package/src/components/button/demos/states.demo.tsx +0 -53
  389. package/src/components/combobox/overview.demo.tsx +0 -200
  390. package/src/components/glyph/README.md +0 -72
  391. package/src/components/glyph/glyph.tsx +0 -110
  392. package/src/components/listbox/overview.demo.tsx +0 -102
  393. package/src/components/menu/demos/bubbling.demo.tsx +0 -35
  394. package/src/components/menu/demos/context-trigger.demo.tsx +0 -133
  395. package/src/components/menu/demos/overview.demo.tsx +0 -77
  396. package/src/components/popover/overview.demo.tsx +0 -144
  397. package/src/components/select/deconstructed.demo.tsx +0 -96
  398. package/src/components/select/overview.demo.tsx +0 -52
  399. package/src/components/separator/separator.ts +0 -19
  400. package/src/components/tabs/README.md +0 -105
  401. package/src/components/tabs/tabs.tsx +0 -504
  402. package/src/runtime/demos/basic.demo.tsx +0 -21
  403. package/src/runtime/demos/controlled-uncontrolled-values.demo.tsx +0 -177
  404. package/src/runtime/demos/keyed-list.demo.tsx +0 -94
  405. package/src/theme/README.md +0 -103
  406. package/src/theme/contract.ts +0 -215
  407. package/src/theme/glyph-contract.ts +0 -59
  408. package/src/theme/presets/rmx-01/glyphs.tsx +0 -308
  409. package/src/theme/presets/rmx-01/index.ts +0 -123
  410. package/src/theme/runtime.ts +0 -119
  411. package/src/theme/theme.ts +0 -15
  412. package/src/utils/scroll-lock/README.md +0 -33
  413. /package/dist/{components/anchor/anchor.d.ts → anchor/index.d.ts} +0 -0
  414. /package/dist/{components/breadcrumbs/breadcrumbs.d.ts → breadcrumbs/index.d.ts} +0 -0
  415. /package/dist/{utils → listbox}/flash-attribute.d.ts +0 -0
  416. /package/dist/{utils → listbox}/flash-attribute.js +0 -0
  417. /package/dist/{components/menu → menu}/hover-aim.d.ts +0 -0
  418. /package/dist/{components/menu → menu}/hover-aim.js +0 -0
  419. /package/dist/{interactions/outside-click/outside-click-mixin.d.ts → popover/outside-click.d.ts} +0 -0
  420. /package/dist/{interactions/keydown → select}/keydown.d.ts +0 -0
  421. /package/dist/{interactions/keydown → select}/keydown.js +0 -0
  422. /package/dist/{interactions/typeahead/typeahead-mixin.d.ts → shared/typeahead.d.ts} +0 -0
  423. /package/dist/{utils → shared}/wait-for-css-transition.d.ts +0 -0
  424. /package/dist/{utils → shared}/wait-for-css-transition.js +0 -0
  425. /package/dist/{utils → shared}/wait.d.ts +0 -0
  426. /package/dist/{utils → shared}/wait.js +0 -0
  427. /package/src/{components/anchor/anchor.ts → anchor/index.ts} +0 -0
  428. /package/src/{utils → listbox}/flash-attribute.ts +0 -0
  429. /package/src/{components/menu → menu}/hover-aim.ts +0 -0
  430. /package/src/{interactions/outside-click/outside-click-mixin.ts → popover/outside-click.ts} +0 -0
  431. /package/src/{interactions/keydown → select}/keydown.ts +0 -0
  432. /package/src/{interactions/typeahead/typeahead-mixin.ts → shared/typeahead.ts} +0 -0
  433. /package/src/{utils → shared}/wait-for-css-transition.ts +0 -0
  434. /package/src/{utils → shared}/wait.ts +0 -0
@@ -1,13 +1,16 @@
1
- import { createComponent, Frame } from "./component.js";
2
- import { createFrame } from "./frame.js";
3
- import { createRangeRoot } from "./vdom.js";
4
- import { isCommittedComponentNode, isComponentNode, isCommittedHostNode, isCommittedTextNode, isFragmentNode, isHostNode, isNonRenderNode, isTextNode, findContextFromAncestry, } from "./vnode.js";
5
- import { invariant } from "./invariant.js";
6
- import { patchHostProps } from "./core/props.js";
7
- import { skipComments, logHydrationMismatch } from "./client-entries.js";
8
- import { toVNode } from "./to-vnode.js";
9
- import { bindMixinRuntime, cancelPendingMixinRemoval, dispatchMixinBeforeUpdate, dispatchMixinCommit, getMixinRuntimeSignal, prepareMixinRemoval, resolveMixedProps, teardownMixins, } from "./mixins/mixin.js";
10
- import { isOnMixinDescriptor } from "./mixins/on-mixin.js";
1
+ import { createComponent } from './component.js';
2
+ import { createFrame, isFrameRuntime } from './frame.js';
3
+ import { unwrapFrameResolution } from './frame-resolution.js';
4
+ import { createRangeRoot } from './vdom.js';
5
+ import { isCommittedComponentNode, isCommittedHostNode, isCommittedTextNode, isFragmentNode, isHostNode, findContextFromAncestry, } from './vnode.js';
6
+ import { invariant } from './invariant.js';
7
+ import { patchHostProps } from './core/props.js';
8
+ import { skipComments, logHydrationMismatch } from './client-entries.js';
9
+ import { toVNode } from './to-vnode.js';
10
+ import { bindMixinRuntime, cancelPendingMixinRemoval, dispatchMixinBeforeUpdate, dispatchMixinCommit, getMixinRuntimeSignal, prepareMixinRemoval, resolveMixedProps, teardownMixins, } from './mixins/mixin.js';
11
+ import { isOnMixinDescriptor } from './mixins/on-mixin.js';
12
+ import { createComponentErrorEvent } from './error-event.js';
13
+ import { componentStalenessCheck } from './refresh.js';
11
14
  const SVG_NS = 'http://www.w3.org/2000/svg';
12
15
  let idCounter = 0;
13
16
  let persistedRemovalToken = 0;
@@ -15,40 +18,36 @@ const persistedMixinNodes = new Set();
15
18
  let activeSchedulerUpdateParents;
16
19
  // Compute SVG context for a node based on its parent and type.
17
20
  // Returns true if the node is within an SVG subtree, false otherwise.
18
- function getSvgContext(vParent, nodeType) {
21
+ function getSvgContext(vParent, node) {
19
22
  // Only host elements (strings) can affect SVG context
20
- if (typeof nodeType === 'string') {
23
+ if (node.kind === 'host') {
21
24
  // svg element creates SVG context
22
- if (nodeType === 'svg')
25
+ if (node.type === 'svg')
23
26
  return true;
24
27
  // foreignObject switches back to HTML context
25
- if (nodeType === 'foreignObject')
28
+ if (node.type === 'foreignObject')
26
29
  return false;
27
30
  }
28
31
  // Otherwise inherit from parent
29
- return vParent._svg ?? false;
32
+ return vParent._svg;
30
33
  }
31
34
  function getHostProps(node) {
32
- return node._mixedProps ?? node.props;
35
+ return '_mixedProps' in node ? node._mixedProps : node.props;
33
36
  }
34
37
  function markNodePersistedByMixins(node, domParent, token) {
35
- node._persistedByMixins = true;
36
- node._persistedParentByMixins = domParent;
37
- node._persistedRemovalToken = token;
38
+ node._persistence = { parent: domParent, token };
38
39
  persistedMixinNodes.add(node);
39
40
  bindMixinRuntime(node._mixState, undefined);
40
41
  }
41
42
  function unmarkNodePersistedByMixins(node) {
42
- node._persistedByMixins = false;
43
- node._persistedParentByMixins = undefined;
44
- node._persistedRemovalToken = undefined;
43
+ node._persistence = undefined;
45
44
  persistedMixinNodes.delete(node);
46
45
  }
47
46
  function findMatchingPersistedMixinNode(type, key, domParent) {
48
47
  if (key == null)
49
48
  return null;
50
49
  for (let node of persistedMixinNodes) {
51
- if (node._persistedParentByMixins !== domParent)
50
+ if (node._persistence?.parent !== domParent)
52
51
  continue;
53
52
  if (node.type !== type)
54
53
  continue;
@@ -59,6 +58,7 @@ function findMatchingPersistedMixinNode(type, key, domParent) {
59
58
  return null;
60
59
  }
61
60
  const EMPTY_DIRECT_EVENT_DESCRIPTORS = [];
61
+ const EMPTY_COMMITTED_CHILDREN = [];
62
62
  function shouldRestoreControlledReflectionOnInput(node, state) {
63
63
  // Some controls dispatch `input` before `change` for the same interaction.
64
64
  // When checked/value state is typically handled on `change`, restoring on the
@@ -152,6 +152,15 @@ function teardownControlledReflection(node) {
152
152
  state.listenersAttached = false;
153
153
  }
154
154
  }
155
+ // See abandonDirectEventListeners: skips removeEventListener for discarded subtrees.
156
+ function abandonControlledReflection(node) {
157
+ let state = node._controlledState;
158
+ if (!state)
159
+ return;
160
+ state.disposed = true;
161
+ state.pendingRestoreVersion++;
162
+ state.listenersAttached = false;
163
+ }
155
164
  function canManageValue(type, element) {
156
165
  if (type === 'progress')
157
166
  return false;
@@ -176,23 +185,16 @@ function setPropertyReflection(element, key, value) {
176
185
  return;
177
186
  element[key] = value == null ? '' : value;
178
187
  }
179
- function resolveNodeMixProps(node, frame, scheduler, state) {
188
+ function resolveNodeMixProps(node, parent, frame, scheduler, state) {
180
189
  let mix = node.props.mix;
181
190
  let directEventDescriptors = resolveDirectEventDescriptors(mix);
182
191
  if (directEventDescriptors) {
183
- if (state) {
192
+ if (state)
184
193
  teardownMixins(state);
185
- }
186
- node._mixState = undefined;
187
- node._mixedProps = node.props;
188
- node._directEventDescriptors = directEventDescriptors;
189
- return node.props;
194
+ return { props: node.props, directEventDescriptors };
190
195
  }
191
- node._directEventDescriptors = undefined;
192
196
  if (state == null && (mix == null || (Array.isArray(mix) && mix.length === 0))) {
193
- node._mixState = undefined;
194
- node._mixedProps = node.props;
195
- return node.props;
197
+ return { props: node.props };
196
198
  }
197
199
  let resolved = resolveMixedProps({
198
200
  hostType: node.type,
@@ -202,14 +204,17 @@ function resolveNodeMixProps(node, frame, scheduler, state) {
202
204
  if (typeof type !== 'function') {
203
205
  return undefined;
204
206
  }
205
- return findContextFromAncestry(node, type);
207
+ return findContextFromAncestry(parent, type);
206
208
  },
207
209
  props: node.props,
208
210
  state,
209
211
  });
210
- node._mixState = resolved.state;
212
+ return { props: resolved.props, mixState: resolved.state };
213
+ }
214
+ function applyResolvedHostProps(node, resolved) {
211
215
  node._mixedProps = resolved.props;
212
- return resolved.props;
216
+ node._mixState = resolved.mixState;
217
+ node._directEventDescriptors = resolved.directEventDescriptors;
213
218
  }
214
219
  function resolveDirectEventDescriptors(mix) {
215
220
  if (!mix)
@@ -220,8 +225,8 @@ function resolveDirectEventDescriptors(mix) {
220
225
  return areOnMixinDescriptors(mix) ? mix : null;
221
226
  }
222
227
  function areOnMixinDescriptors(descriptors) {
223
- for (let item of descriptors) {
224
- if (!isOnMixinDescriptor(item))
228
+ for (let i = 0; i < descriptors.length; i++) {
229
+ if (!isOnMixinDescriptor(descriptors[i]))
225
230
  return false;
226
231
  }
227
232
  return true;
@@ -237,8 +242,13 @@ function enqueueMixinBindingUpdate(done) {
237
242
  }
238
243
  dispatchMixinBeforeUpdate(state);
239
244
  let prevProps = getHostProps(node);
240
- let nextProps = resolveNodeMixProps(node, this.frame, this.scheduler, state);
241
- patchHostProps(prevProps, nextProps, this.node);
245
+ let resolved = resolveNodeMixProps(node, node._parent, this.frame, this.scheduler, state);
246
+ applyResolvedHostProps(node, resolved);
247
+ patchHostProps(prevProps, resolved.props, this.node);
248
+ if (node._controlledState || shouldTrackControlledReflection(resolved.props)) {
249
+ ensureControlledReflection(node, this.scheduler);
250
+ syncControlledReflection(node, resolved.props);
251
+ }
242
252
  dispatchMixinCommit(state);
243
253
  done(state ? getMixinRuntimeSignal(state) : AbortSignal.abort());
244
254
  },
@@ -248,7 +258,7 @@ function bindNodeMixRuntime(node, frame, scheduler, styles, reclaimed = false, p
248
258
  let state = node._mixState;
249
259
  bindMixinRuntime(state, {
250
260
  node: node._dom,
251
- parent: parent ?? node._dom.parentNode,
261
+ parent: parent ?? getRequiredDomParent(node._dom),
252
262
  key: node.key,
253
263
  target: node,
254
264
  frame,
@@ -263,6 +273,11 @@ function isHeadHostNode(node) {
263
273
  return false;
264
274
  return node.type.toLowerCase() === 'head';
265
275
  }
276
+ function getRequiredDomParent(node) {
277
+ let parent = node.parentNode;
278
+ invariant(parent, 'Expected mounted host node to have a DOM parent');
279
+ return parent;
280
+ }
266
281
  function getDocumentHead(domParent) {
267
282
  if (domParent instanceof Document) {
268
283
  return domParent.head;
@@ -272,65 +287,112 @@ function getDocumentHead(domParent) {
272
287
  }
273
288
  return null;
274
289
  }
275
- export function diffVNodes(curr, next, domParent, frame, scheduler, styles, vParent, rootTarget, anchor, rootCursor) {
276
- next._parent = vParent; // set parent for initial render context lookups
277
- next._svg = getSvgContext(vParent, next.type);
278
- // new
290
+ function commitNonRenderNode(node, parent, svg) {
291
+ let committed = node;
292
+ committed._parent = parent;
293
+ committed._svg = svg;
294
+ return committed;
295
+ }
296
+ function commitTextNode(node, parent, svg, dom) {
297
+ let committed = node;
298
+ committed._parent = parent;
299
+ committed._svg = svg;
300
+ committed._dom = dom;
301
+ return committed;
302
+ }
303
+ function beginFragmentNode(node, parent, svg) {
304
+ let committed = node;
305
+ committed._parent = parent;
306
+ committed._svg = svg;
307
+ committed._children = EMPTY_COMMITTED_CHILDREN;
308
+ return committed;
309
+ }
310
+ function commitHostNode(node, parent, svg, dom, resolved, children = EMPTY_COMMITTED_CHILDREN) {
311
+ let committed = node;
312
+ committed._parent = parent;
313
+ committed._svg = svg;
314
+ committed._dom = dom;
315
+ committed._children = children;
316
+ committed._mixedProps = resolved.props;
317
+ committed._mixState = resolved.mixState;
318
+ committed._directEventDescriptors = resolved.directEventDescriptors;
319
+ return committed;
320
+ }
321
+ function beginComponentNode(node, parent, svg, handle, context) {
322
+ let mounting = node;
323
+ mounting._parent = parent;
324
+ mounting._svg = svg;
325
+ mounting._handle = handle;
326
+ mounting._context = context;
327
+ return mounting;
328
+ }
329
+ function commitComponentNode(node, content) {
330
+ let committed = node;
331
+ committed._content = content;
332
+ return committed;
333
+ }
334
+ export function diffVNodes(curr, next, domParent, vParent, context, anchor, cursor) {
279
335
  if (curr === null) {
280
- return insert(next, domParent, frame, scheduler, styles, vParent, rootTarget, anchor, rootCursor);
281
- }
282
- if (curr.type !== next.type) {
283
- replace(curr, next, domParent, frame, scheduler, styles, vParent, rootTarget, anchor);
284
- return rootCursor;
336
+ return insert(next, domParent, vParent, context, anchor, cursor);
285
337
  }
286
- if (isNonRenderNode(curr) && isNonRenderNode(next)) {
287
- return rootCursor;
338
+ if (componentStalenessCheck !== null &&
339
+ curr.kind === 'component' &&
340
+ next.kind === 'component' &&
341
+ componentStalenessCheck(curr.type) === true) {
342
+ return replace(curr, next, domParent, vParent, context, anchor);
288
343
  }
289
- if (isCommittedTextNode(curr) && isTextNode(next)) {
290
- diffText(curr, next, vParent);
291
- return rootCursor;
344
+ if (curr.kind !== next.kind || curr.type !== next.type) {
345
+ return replace(curr, next, domParent, vParent, context, anchor);
292
346
  }
293
- if (isCommittedHostNode(curr) && isHostNode(next)) {
294
- diffHost(curr, next, frame, scheduler, styles, vParent, rootTarget);
295
- return rootCursor;
296
- }
297
- if (isCommittedComponentNode(curr) && isComponentNode(next)) {
298
- diffComponent(curr, next, frame, scheduler, styles, domParent, vParent, rootTarget);
299
- return rootCursor;
300
- }
301
- if (isFragmentNode(curr) && isFragmentNode(next)) {
302
- diffChildren(curr._children, next._children, domParent, frame, scheduler, styles, next, rootTarget, undefined, anchor);
303
- return rootCursor;
304
- }
305
- if (curr.type === Frame && next.type === Frame) {
306
- diffFrame(curr, next, domParent, frame, scheduler, styles, vParent, rootTarget, anchor);
307
- return rootCursor;
347
+ switch (next.kind) {
348
+ case 'host': {
349
+ return diffHost(curr, next, vParent, context);
350
+ }
351
+ case 'text': {
352
+ return diffText(curr, next, vParent, getSvgContext(vParent, next));
353
+ }
354
+ case 'empty': {
355
+ return commitNonRenderNode(next, vParent, getSvgContext(vParent, next));
356
+ }
357
+ case 'fragment': {
358
+ let childInputs = next._children;
359
+ let committed = beginFragmentNode(next, vParent, getSvgContext(vParent, next));
360
+ committed._children = diffChildren(curr._children, childInputs, domParent, committed, context, undefined, anchor);
361
+ return committed;
362
+ }
363
+ case 'frame': {
364
+ return diffFrame(curr, next, domParent, vParent, context, getSvgContext(vParent, next), anchor);
365
+ }
366
+ case 'component': {
367
+ return diffComponent(curr, next, domParent, vParent, context, getSvgContext(vParent, next), anchor, cursor);
368
+ }
308
369
  }
309
- invariant(false, 'Unexpected diff case');
310
370
  }
311
- function replace(curr, next, domParent, frame, scheduler, styles, vParent, rootTarget, anchor) {
371
+ function replace(curr, next, domParent, vParent, context, anchor) {
312
372
  let currAnchor = findFirstDomAnchor(curr);
313
373
  if (currAnchor && currAnchor.parentNode === domParent) {
314
374
  let replacementAnchor = document.createComment('rmx:replace');
315
375
  domParent.insertBefore(replacementAnchor, currAnchor);
316
376
  try {
317
- remove(curr, domParent, scheduler, styles);
318
- insert(next, domParent, frame, scheduler, styles, vParent, rootTarget, replacementAnchor);
377
+ remove(curr, domParent, context);
378
+ return insert(next, domParent, vParent, context, replacementAnchor);
319
379
  }
320
380
  finally {
321
381
  replacementAnchor.parentNode?.removeChild(replacementAnchor);
322
382
  }
323
- return;
324
383
  }
325
384
  let replacementAnchor = findNextSiblingDomAnchor(curr) ?? anchor;
326
- remove(curr, domParent, scheduler, styles);
327
- insert(next, domParent, frame, scheduler, styles, vParent, rootTarget, replacementAnchor);
385
+ remove(curr, domParent, context);
386
+ return insert(next, domParent, vParent, context, replacementAnchor);
328
387
  }
329
- function diffHost(curr, next, frame, scheduler, styles, vParent, rootTarget) {
388
+ function diffHost(curr, next, vParent, context) {
389
+ let { frame, scheduler, styles } = context;
330
390
  let mixState = curr._mixState;
331
391
  let currProps = getHostProps(curr);
332
- let nextProps = resolveNodeMixProps(next, frame, scheduler, mixState);
333
- let nextMixState = next._mixState;
392
+ let resolved = resolveNodeMixProps(next, vParent, frame, scheduler, mixState);
393
+ let childInputs = next._children;
394
+ let nextProps = resolved.props;
395
+ let nextMixState = resolved.mixState;
334
396
  let shouldDispatchMixinLifecycle = (nextMixState?.runners.length ?? 0) > 0 && shouldDispatchInlineMixinLifecycle(curr._dom);
335
397
  if (shouldDispatchMixinLifecycle) {
336
398
  dispatchMixinBeforeUpdate(nextMixState);
@@ -346,34 +408,30 @@ function diffHost(curr, next, frame, scheduler, styles, vParent, rootTarget) {
346
408
  // innerHTML was removed, clear it before adding children
347
409
  curr._dom.innerHTML = '';
348
410
  }
349
- diffChildren(curr._children, next._children, curr._dom, frame, scheduler, styles, next, rootTarget);
411
+ let committed = commitHostNode(next, vParent, getSvgContext(vParent, next), curr._dom, resolved);
412
+ committed._directEventState = curr._directEventState;
413
+ committed._controlledState = curr._controlledState;
414
+ committed._children = diffChildren(curr._children, childInputs, curr._dom, committed, context);
350
415
  patchHostProps(currProps, nextProps, curr._dom);
351
- next._dom = curr._dom;
352
- next._parent = vParent;
353
- next._controller = curr._controller;
354
- next._directEventState = curr._directEventState;
355
- next._controlledState = curr._controlledState;
356
- syncDirectEventListeners(next);
357
- if (next._controlledState || shouldTrackControlledReflection(nextProps)) {
358
- ensureControlledReflection(next, scheduler);
359
- syncControlledReflection(next, nextProps);
360
- }
361
- if (next._mixState) {
362
- bindNodeMixRuntime(next, frame, scheduler, styles);
416
+ syncDirectEventListeners(committed);
417
+ if (committed._controlledState || shouldTrackControlledReflection(nextProps)) {
418
+ ensureControlledReflection(committed, scheduler);
419
+ syncControlledReflection(committed, nextProps);
420
+ }
421
+ if (committed._mixState) {
422
+ bindNodeMixRuntime(committed, frame, scheduler, styles);
363
423
  }
364
424
  if (shouldDispatchMixinLifecycle) {
365
425
  scheduler.enqueueCommitPhase([() => dispatchMixinCommit(nextMixState)]);
366
426
  }
367
- return;
427
+ return committed;
368
428
  }
369
- function setupHostNode(node, dom, scheduler) {
370
- node._dom = dom;
429
+ function setupHostNode(node, scheduler) {
371
430
  let props = getHostProps(node);
372
- let committedNode = node;
373
- syncDirectEventListeners(committedNode);
431
+ syncDirectEventListeners(node);
374
432
  if (shouldTrackControlledReflection(props)) {
375
- ensureControlledReflection(committedNode, scheduler);
376
- syncControlledReflection(committedNode, props);
433
+ ensureControlledReflection(node, scheduler);
434
+ syncControlledReflection(node, props);
377
435
  }
378
436
  }
379
437
  function syncDirectEventListeners(node) {
@@ -393,8 +451,12 @@ function syncDirectEventListeners(node) {
393
451
  }
394
452
  let bindings = state.bindings;
395
453
  for (let index = 0; index < descriptors.length; index++) {
396
- let descriptor = descriptors[index];
397
- let [type, handler, captureBoolean = false] = descriptor.args;
454
+ // Indexed access instead of array destructuring: destructuring goes through
455
+ // the iterator protocol and allocates on every host-node update.
456
+ let args = descriptors[index].args;
457
+ let type = args[0];
458
+ let handler = args[1];
459
+ let captureBoolean = args[2] ?? false;
398
460
  let binding = bindings[index];
399
461
  if (!binding) {
400
462
  binding = createDirectEventBinding(type, handler, captureBoolean);
@@ -453,256 +515,286 @@ function teardownDirectEventListeners(node) {
453
515
  state.bindings.length = 0;
454
516
  node._directEventState = undefined;
455
517
  }
518
+ // Teardown for a node whose DOM subtree is being discarded wholesale: abort
519
+ // pending handler work but skip removeEventListener — the listeners die with
520
+ // the detached node, and removing them one-by-one dominates large teardowns.
521
+ function abandonDirectEventListeners(node) {
522
+ let state = node._directEventState;
523
+ if (!state)
524
+ return;
525
+ for (let binding of state.bindings) {
526
+ binding.reentry?.abort(new DOMException('', 'AbortError'));
527
+ binding.reentry = null;
528
+ }
529
+ state.bindings.length = 0;
530
+ node._directEventState = undefined;
531
+ }
456
532
  function invokeDirectEventBinding(binding, event) {
457
533
  binding.reentry?.abort(new DOMException('', 'EventReentry'));
458
534
  binding.reentry = new AbortController();
459
535
  void binding.handler(event, binding.reentry.signal);
460
536
  }
461
- function diffText(curr, next, vParent) {
537
+ function diffText(curr, next, vParent, svg) {
462
538
  if (curr._text !== next._text) {
463
539
  curr._dom.textContent = next._text;
464
540
  }
465
- next._dom = curr._dom;
466
- next._parent = vParent;
541
+ return commitTextNode(next, vParent, svg, curr._dom);
467
542
  }
468
- function insert(node, domParent, frame, scheduler, styles, vParent, rootTarget, anchor, cursor) {
469
- node._parent = vParent; // set parent for initial render context lookups
470
- node._svg = getSvgContext(vParent, node.type);
543
+ function insert(node, domParent, vParent, context, anchor, cursor) {
544
+ let { frame, scheduler, styles } = context;
545
+ let svg = getSvgContext(vParent, node);
546
+ let hydrationNode = cursor?.current;
471
547
  // Stop hydration if cursor has reached the anchor (end boundary)
472
548
  // Check BEFORE skipComments to prevent escaping range root markers
473
- if (cursor && anchor && cursor === anchor) {
474
- cursor = null;
475
- }
476
- cursor =
477
- node.type === Frame
478
- ? skipCommentsExceptFrameStart(cursor ?? null)
479
- : skipComments(cursor ?? null);
549
+ if (hydrationNode && anchor && hydrationNode === anchor) {
550
+ hydrationNode = null;
551
+ }
552
+ // Preserve frame-start markers for non-Frame nodes too, so a following <Frame>
553
+ // (e.g. the first child of a bare Fragment at a clientEntry boundary) can still
554
+ // claim its rmx:f marker during hydration instead of being re-inserted fresh.
555
+ // A rmx:f marker always belongs to a <Frame>, so no non-Frame node should
556
+ // consume one.
557
+ hydrationNode = skipCommentsExceptFrameStart(hydrationNode ?? null);
480
558
  // Also check after skipComments in case we skipped past the anchor
481
- if (cursor && anchor && cursor === anchor) {
482
- cursor = null;
559
+ if (hydrationNode && anchor && hydrationNode === anchor) {
560
+ hydrationNode = null;
483
561
  }
562
+ if (cursor)
563
+ cursor.current = hydrationNode;
484
564
  let doInsert = anchor
485
565
  ? (dom) => domParent.insertBefore(dom, anchor)
486
566
  : (dom) => domParent.appendChild(dom);
487
- if (isNonRenderNode(node)) {
488
- return cursor;
567
+ if (node.kind === 'empty') {
568
+ return commitNonRenderNode(node, vParent, svg);
489
569
  }
490
- if (isTextNode(node)) {
491
- if (cursor instanceof Text) {
492
- node._parent = vParent;
570
+ if (node.kind === 'text') {
571
+ if (hydrationNode instanceof Text) {
493
572
  // Handle text node consolidation: server renders adjacent text as single node
494
573
  // e.g., <span>Hello {world}</span> → server: "Hello world", client: ["Hello ", "world"]
495
- if (cursor.data !== node._text) {
496
- if (cursor.data.startsWith(node._text) && node._text.length < cursor.data.length) {
574
+ if (hydrationNode.data !== node._text) {
575
+ if (hydrationNode.data.startsWith(node._text) &&
576
+ node._text.length < hydrationNode.data.length) {
497
577
  // Consolidation case: split the text node at the boundary
498
578
  // cursor becomes the first part (node._text), remainder is returned for next vnode
499
- let remainder = cursor.splitText(node._text.length);
500
- node._dom = cursor;
501
- return remainder;
579
+ let remainder = hydrationNode.splitText(node._text.length);
580
+ if (cursor)
581
+ cursor.current = remainder;
582
+ return commitTextNode(node, vParent, svg, hydrationNode);
502
583
  }
503
584
  // Genuine mismatch - correct it
504
- logHydrationMismatch('text mismatch', cursor.data, node._text);
505
- cursor.data = node._text;
585
+ logHydrationMismatch('text mismatch', hydrationNode.data, node._text);
586
+ hydrationNode.data = node._text;
506
587
  }
507
- node._dom = cursor;
508
- return cursor.nextSibling;
588
+ if (cursor)
589
+ cursor.current = hydrationNode.nextSibling;
590
+ return commitTextNode(node, vParent, svg, hydrationNode);
509
591
  }
510
592
  let dom = document.createTextNode(node._text);
511
- node._dom = dom;
512
- node._parent = vParent;
513
593
  doInsert(dom);
514
- return cursor;
594
+ return commitTextNode(node, vParent, svg, dom);
515
595
  }
516
- if (isHostNode(node)) {
517
- let hostProps = resolveNodeMixProps(node, frame, scheduler);
596
+ if (node.kind === 'host') {
597
+ let resolved = resolveNodeMixProps(node, vParent, frame, scheduler);
598
+ let hostProps = resolved.props;
599
+ let childInputs = node._children;
518
600
  if (isHeadHostNode(node)) {
519
601
  let targetHead = getDocumentHead(domParent);
520
602
  if (targetHead) {
521
- let childCursor = cursor;
522
- if (cursor instanceof Element && cursor.tagName.toLowerCase() === 'head') {
523
- childCursor = cursor.firstChild;
524
- let nextCursor = cursor.nextSibling;
525
- if (cursor !== targetHead) {
526
- while (cursor.firstChild) {
527
- targetHead.appendChild(cursor.firstChild);
603
+ let childCursor = cursor ? { current: hydrationNode } : undefined;
604
+ if (hydrationNode instanceof Element && hydrationNode.tagName.toLowerCase() === 'head') {
605
+ if (childCursor)
606
+ childCursor.current = hydrationNode.firstChild;
607
+ let nextCursor = hydrationNode.nextSibling;
608
+ if (hydrationNode !== targetHead) {
609
+ while (hydrationNode.firstChild) {
610
+ targetHead.appendChild(hydrationNode.firstChild);
528
611
  }
529
- cursor.remove();
612
+ hydrationNode.remove();
530
613
  }
531
- cursor = nextCursor;
614
+ if (cursor)
615
+ cursor.current = nextCursor;
532
616
  }
617
+ let committed = commitHostNode(node, vParent, svg, targetHead, resolved);
533
618
  // Render explicit <head> children directly into document.head.
534
- diffChildren(null, node._children, targetHead, frame, scheduler, styles, node, rootTarget, childCursor);
619
+ committed._children = diffChildren(null, childInputs, targetHead, committed, context, childCursor);
535
620
  patchHostProps({}, hostProps, targetHead);
536
- setupHostNode(node, targetHead, scheduler);
537
- if (node._mixState) {
538
- bindNodeMixRuntime(node, frame, scheduler, styles);
621
+ setupHostNode(committed, scheduler);
622
+ if (committed._mixState) {
623
+ bindNodeMixRuntime(committed, frame, scheduler, styles);
539
624
  }
540
- return cursor;
625
+ return committed;
541
626
  }
542
627
  }
543
628
  // Check for matching mixin-persisted node that can be reclaimed
544
629
  let persistedNode = findMatchingPersistedMixinNode(node.type, node.key, domParent);
545
630
  if (persistedNode) {
546
- reclaimPersistedMixinNode(persistedNode, node, frame, scheduler, styles, vParent, rootTarget);
547
- return cursor;
631
+ return reclaimPersistedMixinNode(persistedNode, node, vParent, context);
548
632
  }
549
- if (cursor instanceof Element) {
633
+ if (hydrationNode instanceof Element) {
550
634
  // SVG elements have case-sensitive tag names (e.g. linearGradient, clipPath)
551
635
  // HTML elements are case-insensitive, so we lowercase for comparison
552
- let cursorTag = node._svg ? cursor.tagName : cursor.tagName.toLowerCase();
636
+ let cursorTag = svg ? hydrationNode.tagName : hydrationNode.tagName.toLowerCase();
553
637
  if (cursorTag === node.type) {
554
- let nextCursor = cursor.nextSibling;
555
- patchHostProps({}, hostProps, cursor);
638
+ let nextCursor = hydrationNode.nextSibling;
639
+ patchHostProps({}, hostProps, hydrationNode);
640
+ let committed = commitHostNode(node, vParent, svg, hydrationNode, resolved);
556
641
  // Handle innerHTML prop
557
642
  if (hostProps.innerHTML != null) {
558
- cursor.innerHTML = hostProps.innerHTML;
643
+ hydrationNode.innerHTML = hostProps.innerHTML;
559
644
  }
560
645
  else {
561
- let childCursor = cursor.firstChild;
646
+ let childCursor = { current: hydrationNode.firstChild };
562
647
  // Ignore excess nodes - browser extensions may inject content
563
- diffChildren(null, node._children, cursor, frame, scheduler, styles, node, rootTarget, childCursor);
648
+ committed._children = diffChildren(null, childInputs, hydrationNode, committed, context, childCursor);
564
649
  }
565
- setupHostNode(node, cursor, scheduler);
566
- if (node._mixState) {
567
- bindNodeMixRuntime(node, frame, scheduler, styles);
650
+ setupHostNode(committed, scheduler);
651
+ if (committed._mixState) {
652
+ bindNodeMixRuntime(committed, frame, scheduler, styles);
568
653
  }
569
- return nextCursor;
654
+ if (cursor)
655
+ cursor.current = nextCursor;
656
+ return committed;
570
657
  }
571
658
  else {
572
659
  // Type mismatch - try single-advance retry to handle browser extension injections
573
660
  // at the start of containers. Skip this node and try the next sibling once.
574
- let nextSibling = skipComments(cursor.nextSibling);
661
+ let nextSibling = skipComments(hydrationNode.nextSibling);
575
662
  if (nextSibling instanceof Element) {
576
- let nextTag = node._svg ? nextSibling.tagName : nextSibling.tagName.toLowerCase();
663
+ let nextTag = svg ? nextSibling.tagName : nextSibling.tagName.toLowerCase();
577
664
  if (nextTag === node.type) {
578
665
  let nextCursor = nextSibling.nextSibling;
579
666
  // Found a match after skipping - adopt it and leave skipped node in place
580
667
  patchHostProps({}, hostProps, nextSibling);
668
+ let committed = commitHostNode(node, vParent, svg, nextSibling, resolved);
581
669
  if (hostProps.innerHTML != null) {
582
670
  nextSibling.innerHTML = hostProps.innerHTML;
583
671
  }
584
672
  else {
585
- let childCursor = nextSibling.firstChild;
586
- diffChildren(null, node._children, nextSibling, frame, scheduler, styles, node, rootTarget, childCursor);
673
+ let childCursor = { current: nextSibling.firstChild };
674
+ committed._children = diffChildren(null, childInputs, nextSibling, committed, context, childCursor);
587
675
  }
588
- setupHostNode(node, nextSibling, scheduler);
589
- if (node._mixState) {
590
- bindNodeMixRuntime(node, frame, scheduler, styles);
676
+ setupHostNode(committed, scheduler);
677
+ if (committed._mixState) {
678
+ bindNodeMixRuntime(committed, frame, scheduler, styles);
591
679
  }
592
- return nextCursor;
680
+ if (cursor)
681
+ cursor.current = nextCursor;
682
+ return committed;
593
683
  }
594
684
  }
595
685
  // Retry failed - log mismatch and create new element (don't remove mismatched nodes)
596
686
  logHydrationMismatch('tag', cursorTag, node.type);
597
- cursor = undefined; // stop hydration for this tree
687
+ if (cursor)
688
+ cursor.current = undefined; // stop hydration for this tree
598
689
  }
599
690
  }
600
- let dom = node._svg
601
- ? document.createElementNS(SVG_NS, node.type)
602
- : document.createElement(node.type);
691
+ let dom = svg ? document.createElementNS(SVG_NS, node.type) : document.createElement(node.type);
603
692
  patchHostProps({}, hostProps, dom);
693
+ let committed = commitHostNode(node, vParent, svg, dom, resolved);
604
694
  // Handle innerHTML prop
605
695
  if (hostProps.innerHTML != null) {
606
696
  dom.innerHTML = hostProps.innerHTML;
607
697
  }
608
698
  else {
609
- diffChildren(null, node._children, dom, frame, scheduler, styles, node, rootTarget);
699
+ committed._children = diffChildren(null, childInputs, dom, committed, context);
610
700
  }
611
- setupHostNode(node, dom, scheduler);
612
- if (node._mixState) {
613
- bindNodeMixRuntime(node, frame, scheduler, styles, false, domParent);
701
+ setupHostNode(committed, scheduler);
702
+ if (committed._mixState) {
703
+ bindNodeMixRuntime(committed, frame, scheduler, styles, false, domParent);
614
704
  }
615
705
  doInsert(dom);
616
- return cursor;
706
+ return committed;
617
707
  }
618
- if (isFragmentNode(node)) {
708
+ if (node.kind === 'fragment') {
709
+ let childInputs = node._children;
710
+ let committed = beginFragmentNode(node, vParent, svg);
711
+ let children = childInputs;
619
712
  // Insert fragment children in order before the same anchor
620
- for (let child of node._children) {
621
- cursor = insert(child, domParent, frame, scheduler, styles, node, rootTarget, anchor, cursor);
713
+ for (let i = 0; i < childInputs.length; i++) {
714
+ children[i] = insert(childInputs[i], domParent, committed, context, anchor, cursor);
622
715
  }
623
- return cursor;
716
+ committed._children = children;
717
+ return committed;
624
718
  }
625
- if (isComponentNode(node)) {
626
- return diffComponent(null, node, frame, scheduler, styles, domParent, vParent, rootTarget, anchor, cursor);
719
+ if (node.kind === 'component') {
720
+ return diffComponent(null, node, domParent, vParent, context, svg, anchor, cursor);
627
721
  }
628
- if (node.type === Frame) {
629
- return insertFrame(node, domParent, frame, scheduler, styles, vParent, rootTarget, anchor, cursor);
722
+ if (node.kind === 'frame') {
723
+ return insertFrame(node, domParent, vParent, context, svg, anchor, cursor);
630
724
  }
631
725
  invariant(false, 'Unexpected node type');
632
726
  }
633
- function diffFrame(curr, next, domParent, frame, scheduler, styles, vParent, rootTarget, anchor) {
727
+ function diffFrame(curr, next, domParent, vParent, context, svg, anchor) {
728
+ let { frame } = context;
634
729
  let currSrc = getFrameSrc(curr);
635
730
  let nextSrc = getFrameSrc(next);
636
731
  let currName = getFrameName(curr);
637
732
  let nextName = getFrameName(next);
638
733
  if (currName !== nextName) {
639
- let replaceAnchor = curr._rangeEnd?.nextSibling ?? anchor;
640
- remove(curr, domParent, scheduler, styles);
641
- insert(next, domParent, frame, scheduler, styles, vParent, rootTarget, replaceAnchor);
642
- return;
734
+ let replaceAnchor = curr._rangeEnd.nextSibling ?? anchor;
735
+ remove(curr, domParent, context);
736
+ return insertFrame(next, domParent, vParent, context, svg, replaceAnchor);
643
737
  }
644
738
  // If the frame hasn't resolved yet, preserve existing cancel/remount behavior
645
739
  // so pending streams from the old src cannot take over the new src.
646
- if (currSrc !== nextSrc && !curr._frameResolved) {
647
- let replaceAnchor = curr._rangeEnd?.nextSibling ?? anchor;
648
- remove(curr, domParent, scheduler, styles);
649
- insert(next, domParent, frame, scheduler, styles, vParent, rootTarget, replaceAnchor);
650
- return;
740
+ if (currSrc !== nextSrc && !curr._state.resolved) {
741
+ let replaceAnchor = curr._rangeEnd.nextSibling ?? anchor;
742
+ remove(curr, domParent, context);
743
+ return insertFrame(next, domParent, vParent, context, svg, replaceAnchor);
651
744
  }
652
- next._rangeStart = curr._rangeStart;
653
- next._rangeEnd = curr._rangeEnd;
654
- next._frameInstance = curr._frameInstance;
655
- next._frameFallbackRoot = curr._frameFallbackRoot;
656
- next._frameResolveToken = curr._frameResolveToken;
657
- next._frameResolved = curr._frameResolved;
658
- next._parent = vParent;
745
+ let committed = next;
746
+ Object.assign(committed, {
747
+ _rangeStart: curr._rangeStart,
748
+ _rangeEnd: curr._rangeEnd,
749
+ _state: curr._state,
750
+ _parent: vParent,
751
+ _svg: svg,
752
+ });
753
+ let frameRuntime = getFrameRuntime(frame);
754
+ let frameInstance = committed._state.instance;
755
+ let serverFrameReload = frameRuntime?.serverFrameReload;
659
756
  if (currSrc !== nextSrc) {
660
- let frameInstance = next._frameInstance;
661
757
  if (frameInstance) {
662
758
  frameInstance.handle.src = nextSrc;
663
759
  }
664
- let runtime = getFrameRuntime(frame);
665
- if (runtime) {
666
- resolveClientFrame(next, runtime);
760
+ if (frameRuntime) {
761
+ resolveClientFrame(committed, frameRuntime, serverFrameReload);
667
762
  }
668
763
  }
669
- if (!next._frameResolved && next._frameFallbackRoot) {
670
- next._frameFallbackRoot.render(next.props?.fallback ?? null);
764
+ else if (frameRuntime && frameInstance && serverFrameReload) {
765
+ // Reload client frames that have the same src during a render triggered by an ancestor frame reload
766
+ resolveClientFrame(committed, frameRuntime, serverFrameReload);
671
767
  }
768
+ if (!committed._state.resolved && committed._state.fallbackRoot) {
769
+ committed._state.fallbackRoot.render(committed.props.fallback ?? null);
770
+ }
771
+ return committed;
672
772
  }
673
- function insertFrame(node, domParent, frame, scheduler, styles, vParent, rootTarget, anchor, cursor) {
773
+ function insertFrame(node, domParent, vParent, context, svg, anchor, cursor) {
774
+ let { frame, styles } = context;
674
775
  let runtime = getFrameRuntime(frame);
675
776
  if (!runtime || runtime.canResolveFrames === false) {
676
777
  throw new Error('Cannot render <Frame /> without frame runtime. Use run() or pass frameInit to createRoot/createRangeRoot.');
677
778
  }
678
779
  // Hydration path: adopt server-rendered frame markers and reuse the existing
679
780
  // frame instance created during createSubFrames().
680
- if (isFrameStartComment(cursor)) {
681
- let start = cursor;
781
+ if (isFrameStartComment(cursor?.current)) {
782
+ let start = cursor.current;
682
783
  let end = findFrameEndComment(start);
683
784
  if (end) {
684
- node._rangeStart = start;
685
- node._rangeEnd = end;
686
- node._parent = vParent;
687
- node._frameResolveToken = 0;
688
- node._frameResolveController = undefined;
689
- node._frameFallbackRoot = undefined;
690
- node._frameResolved = true;
691
- let frameId = getFrameIdFromComment(start);
692
- let marker = frameId ? runtime.data.f?.[frameId] : undefined;
693
- let src = marker?.src ?? getFrameSrc(node);
694
785
  let instance = runtime.frameInstances.get(start);
786
+ let src = instance?.handle.src ?? getFrameSrc(node);
695
787
  if (!instance) {
696
788
  instance = createFrame([start, end], {
697
789
  name: getFrameName(node),
698
790
  src,
699
- marker: frameId && marker ? { ...marker, id: frameId } : undefined,
700
791
  errorTarget: runtime.errorTarget,
701
792
  loadModule: runtime.loadModule,
702
793
  resolveFrame: runtime.resolveFrame,
703
794
  pendingClientEntries: runtime.pendingClientEntries,
704
795
  scheduler: runtime.scheduler,
705
- data: runtime.data,
796
+ styleManager: runtime.styleManager,
797
+ data: {},
706
798
  moduleCache: runtime.moduleCache,
707
799
  moduleLoads: runtime.moduleLoads,
708
800
  frameInstances: runtime.frameInstances,
@@ -710,8 +802,20 @@ function insertFrame(node, domParent, frame, scheduler, styles, vParent, rootTar
710
802
  });
711
803
  runtime.frameInstances.set(start, instance);
712
804
  }
713
- node._frameInstance = instance;
714
- return end.nextSibling;
805
+ cursor.current = end.nextSibling;
806
+ return Object.assign(node, {
807
+ _rangeStart: start,
808
+ _rangeEnd: end,
809
+ _parent: vParent,
810
+ _svg: svg,
811
+ _state: {
812
+ instance,
813
+ resolveToken: 0,
814
+ resolveController: undefined,
815
+ fallbackRoot: undefined,
816
+ resolved: true,
817
+ },
818
+ });
715
819
  }
716
820
  }
717
821
  let start = document.createComment(` rmx:f:${randomFrameId()} `);
@@ -721,17 +825,11 @@ function insertFrame(node, domParent, frame, scheduler, styles, vParent, rootTar
721
825
  : (dom) => domParent.appendChild(dom);
722
826
  doInsert(start);
723
827
  doInsert(end);
724
- node._rangeStart = start;
725
- node._rangeEnd = end;
726
- node._parent = vParent;
727
828
  let fallbackRoot = createRangeRoot([start, end], {
728
829
  frame,
729
830
  styleManager: styles,
730
831
  });
731
- fallbackRoot.render(node.props?.fallback ?? null);
732
- node._frameFallbackRoot = fallbackRoot;
733
- node._frameResolved = false;
734
- node._frameResolveToken = 0;
832
+ fallbackRoot.render(node.props.fallback ?? null);
735
833
  let instance = createFrame([start, end], {
736
834
  name: getFrameName(node),
737
835
  src: getFrameSrc(node),
@@ -740,57 +838,84 @@ function insertFrame(node, domParent, frame, scheduler, styles, vParent, rootTar
740
838
  resolveFrame: runtime.resolveFrame,
741
839
  pendingClientEntries: runtime.pendingClientEntries,
742
840
  scheduler: runtime.scheduler,
743
- data: runtime.data,
841
+ styleManager: runtime.styleManager,
842
+ data: {},
744
843
  moduleCache: runtime.moduleCache,
745
844
  moduleLoads: runtime.moduleLoads,
746
845
  frameInstances: runtime.frameInstances,
747
846
  namedFrames: runtime.namedFrames,
748
847
  });
749
- node._frameInstance = instance;
750
848
  runtime.frameInstances.set(start, instance);
751
- resolveClientFrame(node, runtime);
752
- return cursor;
849
+ let committed = Object.assign(node, {
850
+ _rangeStart: start,
851
+ _rangeEnd: end,
852
+ _parent: vParent,
853
+ _svg: svg,
854
+ _state: {
855
+ instance,
856
+ fallbackRoot,
857
+ resolved: false,
858
+ resolveToken: 0,
859
+ resolveController: undefined,
860
+ },
861
+ });
862
+ resolveClientFrame(committed, runtime);
863
+ return committed;
753
864
  }
754
- function resolveClientFrame(node, runtime) {
865
+ function resolveClientFrame(node, runtime, serverFrameReload) {
755
866
  let frameSrc = getFrameSrc(node);
756
- let instance = node._frameInstance;
757
- if (!instance)
758
- return;
759
- let token = (node._frameResolveToken ?? 0) + 1;
760
- node._frameResolveToken = token;
761
- node._frameResolveController?.abort();
762
- let resolveController = new AbortController();
763
- node._frameResolveController = resolveController;
764
- Promise.resolve(runtime.resolveFrame(frameSrc, resolveController.signal))
765
- .then(async (content) => {
766
- if (node._frameResolveToken !== token || resolveController.signal.aborted)
867
+ let state = node._state;
868
+ let instance = state.instance;
869
+ let token = state.resolveToken + 1;
870
+ state.resolveToken = token;
871
+ state.resolveController?.abort();
872
+ let reload = serverFrameReload
873
+ ? instance.beginClientFrameReloadForAncestorReload(serverFrameReload.signal)
874
+ : undefined;
875
+ if (!reload) {
876
+ instance.cancelReload();
877
+ }
878
+ let resolveController = reload?.controller ?? new AbortController();
879
+ state.resolveController = resolveController;
880
+ Promise.resolve()
881
+ .then(() => runtime.resolveFrame(frameSrc, {
882
+ signal: resolveController.signal,
883
+ target: getFrameName(node),
884
+ }))
885
+ .then(async (resolution) => {
886
+ if (state.resolveToken !== token || resolveController.signal.aborted)
887
+ return;
888
+ let { content } = await unwrapFrameResolution(resolution);
889
+ if (state.resolveToken !== token || resolveController.signal.aborted)
767
890
  return;
768
- node._frameFallbackRoot?.dispose();
769
- node._frameFallbackRoot = undefined;
891
+ state.fallbackRoot?.dispose();
892
+ state.fallbackRoot = undefined;
770
893
  let nextContent = asAbortableFrameContent(content, resolveController.signal);
771
894
  await instance.render(nextContent, { signal: resolveController.signal });
772
- if (node._frameResolveToken !== token || resolveController.signal.aborted)
895
+ if (state.resolveToken !== token || resolveController.signal.aborted)
773
896
  return;
774
- node._frameResolved = true;
897
+ state.resolved = true;
898
+ })
899
+ .catch((error) => {
900
+ if (reload && state.resolveToken === token && !resolveController.signal.aborted) {
901
+ runtime.errorTarget.dispatchEvent(createComponentErrorEvent(error));
902
+ }
775
903
  })
776
- .catch(() => { })
777
904
  .finally(() => {
778
- if (node._frameResolveController === resolveController) {
779
- node._frameResolveController = undefined;
905
+ reload?.complete();
906
+ if (state.resolveController === resolveController) {
907
+ state.resolveController = undefined;
780
908
  }
781
909
  });
782
910
  }
783
911
  function disposeFrameResources(node) {
784
- node._frameResolveToken = (node._frameResolveToken ?? 0) + 1;
785
- node._frameResolveController?.abort();
786
- node._frameResolveController = undefined;
787
- node._frameFallbackRoot?.dispose();
788
- node._frameFallbackRoot = undefined;
789
- let frameInstance = node._frameInstance;
790
- if (frameInstance) {
791
- frameInstance.dispose();
792
- node._frameInstance = undefined;
793
- }
912
+ let state = node._state;
913
+ state.resolveToken++;
914
+ state.resolveController?.abort();
915
+ state.resolveController = undefined;
916
+ state.fallbackRoot?.dispose();
917
+ state.fallbackRoot = undefined;
918
+ state.instance.dispose();
794
919
  }
795
920
  function asAbortableFrameContent(content, signal) {
796
921
  if (!(content instanceof ReadableStream))
@@ -826,13 +951,13 @@ function createAbortableReadableStream(source, signal) {
826
951
  removeAbortReadListener = () => signal.removeEventListener('abort', onAbortRead);
827
952
  signal.addEventListener('abort', onAbortRead, { once: true });
828
953
  });
829
- let { done, value } = await Promise.race([reader.read(), abortRead]);
954
+ let result = await Promise.race([reader.read(), abortRead]);
830
955
  removeAbortReadListener?.();
831
- if (done) {
956
+ if (result.done) {
832
957
  controller.close();
833
958
  return;
834
959
  }
835
- controller.enqueue(value);
960
+ controller.enqueue(result.value);
836
961
  },
837
962
  cancel(reason) {
838
963
  signal.removeEventListener('abort', onAbort);
@@ -843,8 +968,6 @@ function createAbortableReadableStream(source, signal) {
843
968
  function removeFrameDomRange(node, domParent) {
844
969
  let start = node._rangeStart;
845
970
  let end = node._rangeEnd;
846
- if (!(start instanceof Comment) || !(end instanceof Comment))
847
- return;
848
971
  let cursor = start;
849
972
  while (cursor) {
850
973
  let nextSibling = cursor.nextSibling;
@@ -855,19 +978,16 @@ function removeFrameDomRange(node, domParent) {
855
978
  break;
856
979
  cursor = nextSibling;
857
980
  }
858
- node._rangeStart = undefined;
859
- node._rangeEnd = undefined;
860
981
  }
861
982
  function getFrameRuntime(frame) {
862
- return frame.$runtime;
983
+ let runtime = frame.$runtime;
984
+ return isFrameRuntime(runtime) ? runtime : undefined;
863
985
  }
864
986
  function getFrameSrc(node) {
865
- let src = node.props?.src;
866
- invariant(typeof src === 'string' && src.length > 0, '<Frame /> requires a src prop');
867
- return src;
987
+ return node.props.src;
868
988
  }
869
989
  function getFrameName(node) {
870
- let name = node.props?.name;
990
+ let name = node.props.name;
871
991
  return typeof name === 'string' && name.length > 0 ? name : undefined;
872
992
  }
873
993
  function randomFrameId() {
@@ -882,16 +1002,13 @@ function skipCommentsExceptFrameStart(cursor) {
882
1002
  return cursor;
883
1003
  }
884
1004
  function isFrameStartComment(node) {
885
- return node instanceof Comment && node.data.trim().startsWith('rmx:f:');
1005
+ return isCommentNode(node) && node.data.trim().startsWith('rmx:f:');
886
1006
  }
887
1007
  function isFrameEndComment(node) {
888
- return node instanceof Comment && node.data.trim() === '/rmx:f';
1008
+ return isCommentNode(node) && node.data.trim() === '/rmx:f';
889
1009
  }
890
- function getFrameIdFromComment(comment) {
891
- let text = comment.data.trim();
892
- if (!text.startsWith('rmx:f:'))
893
- return undefined;
894
- return text.slice('rmx:f:'.length);
1010
+ function isCommentNode(node) {
1011
+ return node?.nodeType === Node.COMMENT_NODE;
895
1012
  }
896
1013
  function findFrameEndComment(start) {
897
1014
  let depth = 1;
@@ -908,32 +1025,32 @@ function findFrameEndComment(start) {
908
1025
  }
909
1026
  return null;
910
1027
  }
911
- export function renderComponent(handle, currContent, next, domParent, frame, scheduler, styles, rootTarget, vParent, anchor, cursor) {
912
- if (handle.isRemoved())
913
- return cursor;
1028
+ export function renderComponent(currContent, next, domParent, context, anchor, cursor) {
1029
+ let { scheduler } = context;
1030
+ let handle = next._handle;
1031
+ if (handle.isRemoved()) {
1032
+ invariant('_content' in next, 'Expected removed component to be committed');
1033
+ return next;
1034
+ }
914
1035
  let [element, tasks] = handle.render(next.props);
915
- let content = toVNode(element);
916
- let newCursor = diffVNodes(currContent, content, domParent, frame, scheduler, styles, next, rootTarget, anchor, cursor);
917
- next._content = content;
918
- next._handle = handle;
919
- next._parent = vParent;
920
- let committed = next;
921
- handle.setScheduleUpdate(() => {
922
- scheduler.enqueue(committed, domParent);
923
- });
1036
+ let content = diffVNodes(currContent, toVNode(element), domParent, next, context, anchor, cursor);
1037
+ let committed = commitComponentNode(next, content);
1038
+ handle.setScheduleUpdate(scheduler, committed, domParent);
924
1039
  scheduler.enqueueTasks(tasks);
925
- return newCursor;
1040
+ return committed;
926
1041
  }
927
- function diffComponent(curr, next, frame, scheduler, styles, domParent, vParent, rootTarget, anchor, cursor) {
1042
+ function diffComponent(curr, next, domParent, vParent, context, svg, anchor, cursor) {
1043
+ let { frame } = context;
928
1044
  if (curr === null) {
929
- let componentId = vParent._pendingHydrationComponentId;
1045
+ let componentId = vParent.kind === 'root' ? vParent._pendingHydrationComponentId : undefined;
930
1046
  if (componentId) {
931
- vParent._pendingHydrationComponentId = undefined;
1047
+ if (vParent.kind === 'root')
1048
+ vParent._pendingHydrationComponentId = undefined;
932
1049
  }
933
1050
  else {
934
1051
  componentId = `c${++idCounter}`;
935
1052
  }
936
- next._handle = createComponent({
1053
+ let handle = createComponent({
937
1054
  id: componentId,
938
1055
  frame,
939
1056
  type: next.type,
@@ -947,52 +1064,54 @@ function diffComponent(curr, next, frame, scheduler, styles, domParent, vParent,
947
1064
  return runtime?.topFrame;
948
1065
  },
949
1066
  });
950
- return renderComponent(next._handle, null, next, domParent, frame, scheduler, styles, rootTarget, vParent, anchor, cursor);
1067
+ let mounting = beginComponentNode(next, vParent, svg, handle, context);
1068
+ return renderComponent(null, mounting, domParent, context, anchor, cursor);
951
1069
  }
952
- next._handle = curr._handle;
953
- let { _content, _handle } = curr;
954
- return renderComponent(_handle, _content, next, domParent, frame, scheduler, styles, rootTarget, vParent, anchor, cursor);
1070
+ let mounting = beginComponentNode(next, vParent, svg, curr._handle, context);
1071
+ return renderComponent(curr._content, mounting, domParent, context, anchor, cursor);
955
1072
  }
956
1073
  // Cleanup without DOM removal - used for descendants when parent DOM node is removed
957
- function cleanupDescendants(node, scheduler, styles) {
1074
+ function cleanupDescendants(node, context) {
1075
+ let { scheduler } = context;
958
1076
  if (isCommittedTextNode(node)) {
959
1077
  return;
960
1078
  }
961
1079
  if (isCommittedHostNode(node)) {
962
- for (let child of node._children) {
963
- cleanupDescendants(child, scheduler, styles);
1080
+ let children = node._children;
1081
+ for (let i = 0; i < children.length; i++) {
1082
+ cleanupDescendants(children[i], context);
964
1083
  }
965
1084
  teardownMixins(node._mixState);
966
- teardownDirectEventListeners(node);
967
- teardownControlledReflection(node);
968
- if (node._controller)
969
- node._controller.abort();
1085
+ abandonDirectEventListeners(node);
1086
+ abandonControlledReflection(node);
970
1087
  return;
971
1088
  }
972
1089
  if (isFragmentNode(node)) {
973
- for (let child of node._children) {
974
- cleanupDescendants(child, scheduler, styles);
1090
+ let children = node._children;
1091
+ for (let i = 0; i < children.length; i++) {
1092
+ cleanupDescendants(children[i], context);
975
1093
  }
976
1094
  return;
977
1095
  }
978
1096
  if (isCommittedComponentNode(node)) {
979
- cleanupDescendants(node._content, scheduler, styles);
1097
+ cleanupDescendants(node._content, context);
980
1098
  let tasks = node._handle.remove();
981
1099
  scheduler.enqueueTasks(tasks);
982
1100
  return;
983
1101
  }
984
- if (node.type === Frame) {
1102
+ if (node.kind === 'frame') {
985
1103
  disposeFrameResources(node);
986
1104
  return;
987
1105
  }
988
1106
  }
989
- export function remove(node, domParent, scheduler, styles) {
1107
+ export function remove(node, domParent, context) {
1108
+ let { scheduler } = context;
990
1109
  if (isCommittedTextNode(node)) {
991
1110
  node._dom.parentNode?.removeChild(node._dom);
992
1111
  return;
993
1112
  }
994
1113
  if (isCommittedHostNode(node)) {
995
- if (node._persistedByMixins)
1114
+ if (node._persistence)
996
1115
  return;
997
1116
  let persistedRemoval = prepareMixinRemoval(node._mixState);
998
1117
  if (persistedRemoval) {
@@ -1001,106 +1120,108 @@ export function remove(node, domParent, scheduler, styles) {
1001
1120
  void persistedRemoval
1002
1121
  .catch(() => { })
1003
1122
  .finally(() => {
1004
- if (!node._persistedByMixins)
1123
+ if (!node._persistence)
1005
1124
  return;
1006
- if (node._persistedRemovalToken !== token)
1125
+ if (node._persistence.token !== token)
1007
1126
  return;
1008
1127
  unmarkNodePersistedByMixins(node);
1009
- performHostNodeRemoval(node, domParent, scheduler, styles);
1128
+ performHostNodeRemoval(node, domParent, context);
1010
1129
  });
1011
1130
  return;
1012
1131
  }
1013
- performHostNodeRemoval(node, domParent, scheduler, styles);
1132
+ performHostNodeRemoval(node, domParent, context);
1014
1133
  return;
1015
1134
  }
1016
1135
  if (isFragmentNode(node)) {
1017
- for (let child of node._children) {
1018
- remove(child, domParent, scheduler, styles);
1136
+ let children = node._children;
1137
+ for (let i = 0; i < children.length; i++) {
1138
+ remove(children[i], domParent, context);
1019
1139
  }
1020
1140
  return;
1021
1141
  }
1022
1142
  if (isCommittedComponentNode(node)) {
1023
- remove(node._content, domParent, scheduler, styles);
1143
+ remove(node._content, domParent, context);
1024
1144
  let tasks = node._handle.remove();
1025
1145
  scheduler.enqueueTasks(tasks);
1026
1146
  return;
1027
1147
  }
1028
- if (node.type === Frame) {
1148
+ if (node.kind === 'frame') {
1029
1149
  disposeFrameResources(node);
1030
1150
  removeFrameDomRange(node, domParent);
1031
1151
  return;
1032
1152
  }
1033
1153
  }
1034
1154
  // Actually remove a host node from DOM and clean up
1035
- function performHostNodeRemoval(node, domParent, scheduler, styles) {
1155
+ function performHostNodeRemoval(node, domParent, context) {
1156
+ let children = node._children;
1036
1157
  if (isHeadHostNode(node)) {
1037
- for (let child of node._children) {
1038
- remove(child, node._dom, scheduler, styles);
1158
+ for (let i = 0; i < children.length; i++) {
1159
+ remove(children[i], node._dom, context);
1039
1160
  }
1040
1161
  }
1041
1162
  else {
1042
1163
  // Clean up all descendants first (before removing DOM subtree)
1043
- for (let child of node._children) {
1044
- cleanupDescendants(child, scheduler, styles);
1164
+ for (let i = 0; i < children.length; i++) {
1165
+ cleanupDescendants(children[i], context);
1045
1166
  }
1046
1167
  }
1047
1168
  teardownMixins(node._mixState);
1048
- teardownDirectEventListeners(node);
1049
- teardownControlledReflection(node);
1050
- // Never remove the real document.head node when reconciling a <head> vnode.
1051
- if (!isHeadHostNode(node)) {
1169
+ // Never remove the real document.head node when reconciling a <head> vnode,
1170
+ // and since it stays alive, detach its listeners for real.
1171
+ if (isHeadHostNode(node)) {
1172
+ teardownDirectEventListeners(node);
1173
+ teardownControlledReflection(node);
1174
+ }
1175
+ else {
1176
+ abandonDirectEventListeners(node);
1177
+ abandonControlledReflection(node);
1052
1178
  node._dom.parentNode?.removeChild(node._dom);
1053
1179
  }
1054
- if (node._controller)
1055
- node._controller.abort();
1056
1180
  }
1057
- function diffChildren(curr, next, domParent, frame, scheduler, styles, vParent, rootTarget, cursor, anchor) {
1181
+ function diffChildren(curr, next, domParent, vParent, context, cursor, anchor) {
1058
1182
  let hasKeys = hasKeyedChildren(next);
1183
+ let committed = next;
1059
1184
  if (curr === null) {
1060
1185
  if (hasKeys) {
1061
1186
  warnDuplicateKeys(next);
1062
1187
  }
1063
- for (let node of next) {
1064
- cursor = insert(node, domParent, frame, scheduler, styles, vParent, rootTarget, anchor, cursor);
1188
+ for (let i = 0; i < next.length; i++) {
1189
+ committed[i] = insert(next[i], domParent, vParent, context, anchor, cursor);
1065
1190
  }
1066
- vParent._children = next;
1067
- return cursor;
1191
+ return committed;
1068
1192
  }
1069
1193
  if (next.length === 0 &&
1070
1194
  anchor === undefined &&
1071
1195
  !parentUsesInnerHTML(vParent) &&
1072
1196
  canBulkClearChildren(curr)) {
1073
- for (let node of curr) {
1074
- cleanupDescendants(node, scheduler, styles);
1197
+ for (let i = 0; i < curr.length; i++) {
1198
+ cleanupDescendants(curr[i], context);
1075
1199
  }
1076
1200
  domParent.textContent = '';
1077
- vParent._children = next;
1078
- return;
1201
+ return EMPTY_COMMITTED_CHILDREN;
1079
1202
  }
1080
1203
  if (!hasKeys) {
1081
1204
  for (let i = 0; i < next.length; i++) {
1082
1205
  let currentNode = i < curr.length ? curr[i] : null;
1083
- diffVNodes(currentNode, next[i], domParent, frame, scheduler, styles, vParent, rootTarget, anchor, cursor);
1206
+ committed[i] = diffVNodes(currentNode, next[i], domParent, vParent, context, anchor, cursor);
1084
1207
  }
1085
1208
  if (curr.length > next.length) {
1086
1209
  for (let i = next.length; i < curr.length; i++) {
1087
1210
  let node = curr[i];
1088
1211
  if (node)
1089
- remove(node, domParent, scheduler, styles);
1212
+ remove(node, domParent, context);
1090
1213
  }
1091
1214
  }
1092
- vParent._children = next;
1093
- return;
1215
+ return committed;
1094
1216
  }
1095
- patchKeyedChildren(curr, next, domParent, frame, scheduler, styles, vParent, rootTarget, cursor, anchor);
1096
- return;
1217
+ return patchKeyedChildren(curr, next, domParent, vParent, context, cursor, anchor);
1097
1218
  }
1098
1219
  function parentUsesInnerHTML(parent) {
1099
1220
  return isHostNode(parent) && getHostProps(parent).innerHTML != null;
1100
1221
  }
1101
1222
  function canBulkClearChildren(children) {
1102
- for (let child of children) {
1103
- if (!canBulkClearNode(child))
1223
+ for (let i = 0; i < children.length; i++) {
1224
+ if (!canBulkClearNode(children[i]))
1104
1225
  return false;
1105
1226
  }
1106
1227
  return true;
@@ -1111,11 +1232,7 @@ function canBulkClearNode(node) {
1111
1232
  if (isCommittedHostNode(node)) {
1112
1233
  if (node._mixState)
1113
1234
  return false;
1114
- for (let child of node._children) {
1115
- if (!canBulkClearNode(child))
1116
- return false;
1117
- }
1118
- return true;
1235
+ return canBulkClearChildren(node._children);
1119
1236
  }
1120
1237
  if (isFragmentNode(node)) {
1121
1238
  return canBulkClearChildren(node._children);
@@ -1126,8 +1243,8 @@ function canBulkClearNode(node) {
1126
1243
  return false;
1127
1244
  }
1128
1245
  function hasKeyedChildren(children) {
1129
- for (let node of children) {
1130
- if (node.key != null)
1246
+ for (let i = 0; i < children.length; i++) {
1247
+ if (children[i].key != null)
1131
1248
  return true;
1132
1249
  }
1133
1250
  return false;
@@ -1151,11 +1268,11 @@ function warnDuplicateKeys(children) {
1151
1268
  }
1152
1269
  }
1153
1270
  if (duplicateKeys?.size) {
1154
- let quotedKeys = Array.from(duplicateKeys, (key) => `"${key}"`);
1271
+ let quotedKeys = Array.from(duplicateKeys, (key) => `"${String(key)}"`);
1155
1272
  console.warn(`Duplicate keys detected in siblings: ${quotedKeys.join(', ')}. Keys should be unique.`);
1156
1273
  }
1157
1274
  }
1158
- function patchKeyedChildren(curr, next, domParent, frame, scheduler, styles, vParent, rootTarget, cursor, anchor) {
1275
+ function patchKeyedChildren(curr, next, domParent, vParent, context, cursor, anchor) {
1159
1276
  let matches = matchKeyedChildrenInOrder(curr, next) ??
1160
1277
  matchKeyedChildrenAfterSingleRemoval(curr, next) ??
1161
1278
  matchKeyedChildrenAfterPairSwap(curr, next);
@@ -1163,34 +1280,36 @@ function patchKeyedChildren(curr, next, domParent, frame, scheduler, styles, vPa
1163
1280
  warnDuplicateKeys(next);
1164
1281
  matches = matchKeyedChildren(curr, next);
1165
1282
  }
1283
+ let committed = next;
1166
1284
  let matchAnalysis = analyzeKeyedChildMatches(curr.length, matches);
1167
1285
  if (matchAnalysis.hasRemovals) {
1168
1286
  let usedOldIndexes = new Uint8Array(curr.length);
1169
- for (let match of matches) {
1170
- if (match.oldIndex >= 0) {
1171
- usedOldIndexes[match.oldIndex] = 1;
1287
+ for (let index = 0; index < matches.length; index++) {
1288
+ let oldIndex = matches[index];
1289
+ if (oldIndex >= 0) {
1290
+ usedOldIndexes[oldIndex] = 1;
1172
1291
  }
1173
1292
  }
1174
1293
  for (let oldIndex = 0; oldIndex < curr.length; oldIndex++) {
1175
1294
  if (usedOldIndexes[oldIndex] === 0) {
1176
- remove(curr[oldIndex], domParent, scheduler, styles);
1295
+ remove(curr[oldIndex], domParent, context);
1177
1296
  }
1178
1297
  }
1179
1298
  }
1180
- vParent._children = next;
1181
1299
  for (let index = 0; index < next.length; index++) {
1182
- let match = matches[index];
1183
- let oldNode = match.oldIndex >= 0 ? curr[match.oldIndex] : null;
1184
- diffVNodes(oldNode, next[index], domParent, frame, scheduler, styles, vParent, rootTarget, anchor, cursor);
1300
+ let oldIndex = matches[index];
1301
+ let oldNode = oldIndex >= 0 ? curr[oldIndex] : null;
1302
+ committed[index] = diffVNodes(oldNode, next[index], domParent, vParent, context, anchor, cursor);
1185
1303
  }
1304
+ let committedChildren = committed;
1186
1305
  if (matchAnalysis.canSkipPlacement) {
1187
- return;
1306
+ return committedChildren;
1188
1307
  }
1189
1308
  let stableIndexes = lisMatches(matches);
1190
1309
  let stableCursor = stableIndexes.length - 1;
1191
1310
  let placementAnchor = anchor ?? null;
1192
1311
  for (let index = next.length - 1; index >= 0; index--) {
1193
- let nextNode = next[index];
1312
+ let nextNode = committedChildren[index];
1194
1313
  let isStable = stableIndexes[stableCursor] === index;
1195
1314
  if (isStable) {
1196
1315
  stableCursor--;
@@ -1200,7 +1319,11 @@ function patchKeyedChildren(curr, next, domParent, frame, scheduler, styles, vPa
1200
1319
  }
1201
1320
  placementAnchor = findFirstDomAnchor(nextNode) ?? placementAnchor;
1202
1321
  }
1322
+ return committedChildren;
1203
1323
  }
1324
+ // Keyed child matches are arrays of old indexes (-1 = no match / new node),
1325
+ // parallel to `next`. Plain numbers instead of wrapper objects keep large
1326
+ // keyed diffs (1000-row tables) allocation-free.
1204
1327
  function matchKeyedChildren(curr, next) {
1205
1328
  let oldKeyMap = new Map();
1206
1329
  let usedOldIndexes = new Set();
@@ -1210,7 +1333,9 @@ function matchKeyedChildren(curr, next) {
1210
1333
  if (key != null)
1211
1334
  oldKeyMap.set(key, index);
1212
1335
  }
1213
- return next.map((nextNode) => {
1336
+ let matches = [];
1337
+ for (let nextIndex = 0; nextIndex < next.length; nextIndex++) {
1338
+ let nextNode = next[nextIndex];
1214
1339
  let oldIndex = -1;
1215
1340
  if (nextNode.key != null) {
1216
1341
  let keyedOldIndex = oldKeyMap.get(nextNode.key);
@@ -1234,8 +1359,9 @@ function matchKeyedChildren(curr, next) {
1234
1359
  }
1235
1360
  if (oldIndex >= 0)
1236
1361
  usedOldIndexes.add(oldIndex);
1237
- return { oldIndex };
1238
- });
1362
+ matches.push(oldIndex);
1363
+ }
1364
+ return matches;
1239
1365
  }
1240
1366
  function matchKeyedChildrenInOrder(curr, next) {
1241
1367
  let length = Math.min(curr.length, next.length);
@@ -1248,12 +1374,12 @@ function matchKeyedChildrenInOrder(curr, next) {
1248
1374
  if (oldNode.key !== nextNode.key || oldNode.type !== nextNode.type) {
1249
1375
  return null;
1250
1376
  }
1251
- matches.push({ oldIndex: index });
1377
+ matches.push(index);
1252
1378
  }
1253
1379
  for (let index = length; index < next.length; index++) {
1254
1380
  if (next[index].key == null)
1255
1381
  return null;
1256
- matches.push({ oldIndex: -1 });
1382
+ matches.push(-1);
1257
1383
  }
1258
1384
  return matches;
1259
1385
  }
@@ -1269,7 +1395,7 @@ function matchKeyedChildrenAfterSingleRemoval(curr, next) {
1269
1395
  return null;
1270
1396
  let oldNode = curr[oldIndex];
1271
1397
  if (oldNode.key === nextNode.key && oldNode.type === nextNode.type) {
1272
- matches.push({ oldIndex });
1398
+ matches.push(oldIndex);
1273
1399
  oldIndex++;
1274
1400
  continue;
1275
1401
  }
@@ -1281,7 +1407,7 @@ function matchKeyedChildrenAfterSingleRemoval(curr, next) {
1281
1407
  if (oldNode.key !== nextNode.key || oldNode.type !== nextNode.type) {
1282
1408
  return null;
1283
1409
  }
1284
- matches.push({ oldIndex });
1410
+ matches.push(oldIndex);
1285
1411
  oldIndex++;
1286
1412
  }
1287
1413
  return matches;
@@ -1298,7 +1424,7 @@ function matchKeyedChildrenAfterPairSwap(curr, next) {
1298
1424
  return null;
1299
1425
  let oldNode = curr[index];
1300
1426
  if (oldNode.key === nextNode.key && oldNode.type === nextNode.type) {
1301
- matches.push({ oldIndex: index });
1427
+ matches.push(index);
1302
1428
  continue;
1303
1429
  }
1304
1430
  if (firstMismatch === -1) {
@@ -1310,7 +1436,7 @@ function matchKeyedChildrenAfterPairSwap(curr, next) {
1310
1436
  else {
1311
1437
  return null;
1312
1438
  }
1313
- matches.push({ oldIndex: -1 });
1439
+ matches.push(-1);
1314
1440
  }
1315
1441
  if (firstMismatch === -1)
1316
1442
  return matches;
@@ -1326,8 +1452,8 @@ function matchKeyedChildrenAfterPairSwap(curr, next) {
1326
1452
  secondOldNode.type !== firstNextNode.type) {
1327
1453
  return null;
1328
1454
  }
1329
- matches[firstMismatch] = { oldIndex: secondMismatch };
1330
- matches[secondMismatch] = { oldIndex: firstMismatch };
1455
+ matches[firstMismatch] = secondMismatch;
1456
+ matches[secondMismatch] = firstMismatch;
1331
1457
  return matches;
1332
1458
  }
1333
1459
  function analyzeKeyedChildMatches(currentLength, matches) {
@@ -1335,16 +1461,17 @@ function analyzeKeyedChildMatches(currentLength, matches) {
1335
1461
  let canSkipPlacement = true;
1336
1462
  let lastOldIndex = -1;
1337
1463
  let sawNewNode = false;
1338
- for (let match of matches) {
1339
- if (match.oldIndex < 0) {
1464
+ for (let index = 0; index < matches.length; index++) {
1465
+ let oldIndex = matches[index];
1466
+ if (oldIndex < 0) {
1340
1467
  hasRemovals = true;
1341
1468
  sawNewNode = true;
1342
1469
  continue;
1343
1470
  }
1344
- if (sawNewNode || match.oldIndex < lastOldIndex) {
1471
+ if (sawNewNode || oldIndex < lastOldIndex) {
1345
1472
  canSkipPlacement = false;
1346
1473
  }
1347
- lastOldIndex = match.oldIndex;
1474
+ lastOldIndex = oldIndex;
1348
1475
  }
1349
1476
  return { hasRemovals, canSkipPlacement };
1350
1477
  }
@@ -1352,14 +1479,14 @@ function lisMatches(matches) {
1352
1479
  let predecessors = Array.from({ length: matches.length });
1353
1480
  let tails = [];
1354
1481
  for (let index = 0; index < matches.length; index++) {
1355
- let value = matches[index].oldIndex + 1;
1482
+ let value = matches[index] + 1;
1356
1483
  if (value === 0)
1357
1484
  continue;
1358
1485
  let low = 0;
1359
1486
  let high = tails.length;
1360
1487
  while (low < high) {
1361
1488
  let middle = (low + high) >> 1;
1362
- if (matches[tails[middle]].oldIndex + 1 < value) {
1489
+ if (matches[tails[middle]] + 1 < value) {
1363
1490
  low = middle + 1;
1364
1491
  }
1365
1492
  else {
@@ -1398,11 +1525,12 @@ export function findFirstDomAnchor(node) {
1398
1525
  return node._dom;
1399
1526
  if (isCommittedComponentNode(node))
1400
1527
  return findFirstDomAnchor(node._content);
1401
- if (node.type === Frame)
1402
- return node._rangeStart ?? null;
1528
+ if (node.kind === 'frame')
1529
+ return node._rangeStart;
1403
1530
  if (isFragmentNode(node)) {
1404
- for (let child of node._children) {
1405
- let dom = findFirstDomAnchor(child);
1531
+ let children = node._children;
1532
+ for (let i = 0; i < children.length; i++) {
1533
+ let dom = findFirstDomAnchor(children[i]);
1406
1534
  if (dom)
1407
1535
  return dom;
1408
1536
  }
@@ -1418,8 +1546,8 @@ export function findLastDomAnchor(node) {
1418
1546
  return node._dom;
1419
1547
  if (isCommittedComponentNode(node))
1420
1548
  return findLastDomAnchor(node._content);
1421
- if (node.type === Frame)
1422
- return node._rangeEnd ?? null;
1549
+ if (node.kind === 'frame')
1550
+ return node._rangeEnd;
1423
1551
  if (isFragmentNode(node)) {
1424
1552
  for (let i = node._children.length - 1; i >= 0; i--) {
1425
1553
  let dom = findLastDomAnchor(node._children[i]);
@@ -1458,6 +1586,8 @@ function shouldDispatchInlineMixinLifecycle(node) {
1458
1586
  if (!parents?.length)
1459
1587
  return true;
1460
1588
  for (let parent of parents) {
1589
+ if (!(parent instanceof Node))
1590
+ continue;
1461
1591
  let parentNode = parent;
1462
1592
  if (parentNode === node)
1463
1593
  return false;
@@ -1468,11 +1598,16 @@ function shouldDispatchInlineMixinLifecycle(node) {
1468
1598
  }
1469
1599
  export function findNextSiblingDomAnchor(curr) {
1470
1600
  let vParent = curr._parent;
1471
- if (!vParent || !Array.isArray(vParent._children))
1472
- return null;
1473
- let children = vParent._children;
1474
- if (children.length === 0)
1601
+ if (vParent.kind === 'component')
1475
1602
  return findNextSiblingDomAnchor(vParent);
1603
+ let children = vParent._children;
1604
+ if (children.length === 0) {
1605
+ if (vParent.kind === 'root')
1606
+ return vParent._rangeEnd ?? null;
1607
+ if (vParent.kind === 'fragment')
1608
+ return findNextSiblingDomAnchor(vParent);
1609
+ return null;
1610
+ }
1476
1611
  let idx = children.indexOf(curr);
1477
1612
  if (idx === -1)
1478
1613
  return null;
@@ -1484,34 +1619,33 @@ export function findNextSiblingDomAnchor(curr) {
1484
1619
  if (isFragmentNode(vParent)) {
1485
1620
  return findNextSiblingDomAnchor(vParent);
1486
1621
  }
1487
- return null;
1622
+ return vParent.kind === 'root' ? (vParent._rangeEnd ?? null) : null;
1488
1623
  }
1489
- function reclaimPersistedMixinNode(persistedNode, newNode, frame, scheduler, styles, vParent, rootTarget) {
1624
+ function reclaimPersistedMixinNode(persistedNode, newNode, vParent, context) {
1625
+ let { frame, scheduler, styles } = context;
1490
1626
  cancelPendingMixinRemoval(persistedNode._mixState);
1491
1627
  unmarkNodePersistedByMixins(persistedNode);
1492
- newNode._dom = persistedNode._dom;
1493
- newNode._parent = vParent;
1494
- newNode._controller = persistedNode._controller;
1495
- newNode._mixState = persistedNode._mixState;
1496
- newNode._directEventState = persistedNode._directEventState;
1497
- newNode._controlledState = persistedNode._controlledState;
1498
1628
  let prevProps = getHostProps(persistedNode);
1499
- let nextProps = resolveNodeMixProps(newNode, frame, scheduler, newNode._mixState);
1629
+ let childInputs = newNode._children;
1630
+ let resolved = resolveNodeMixProps(newNode, vParent, frame, scheduler, persistedNode._mixState);
1631
+ let nextProps = resolved.props;
1632
+ let committed = commitHostNode(newNode, vParent, getSvgContext(vParent, newNode), persistedNode._dom, resolved);
1633
+ committed._directEventState = persistedNode._directEventState;
1634
+ committed._controlledState = persistedNode._controlledState;
1500
1635
  if (shouldDispatchInlineMixinLifecycle(persistedNode._dom)) {
1501
- dispatchMixinBeforeUpdate(newNode._mixState);
1636
+ dispatchMixinBeforeUpdate(committed._mixState);
1502
1637
  }
1503
1638
  patchHostProps(prevProps, nextProps, persistedNode._dom);
1504
- syncDirectEventListeners(newNode);
1505
- ensureControlledReflection(newNode, scheduler);
1506
- syncControlledReflection(newNode, nextProps);
1507
- diffChildren(persistedNode._children, newNode._children, persistedNode._dom, frame, scheduler, styles, newNode, rootTarget);
1508
- if (newNode._mixState) {
1509
- bindNodeMixRuntime(newNode, frame, scheduler, styles, true);
1639
+ syncDirectEventListeners(committed);
1640
+ ensureControlledReflection(committed, scheduler);
1641
+ syncControlledReflection(committed, nextProps);
1642
+ committed._children = diffChildren(persistedNode._children, childInputs, persistedNode._dom, committed, context);
1643
+ if (committed._mixState) {
1644
+ bindNodeMixRuntime(committed, frame, scheduler, styles, true);
1510
1645
  }
1511
1646
  if (shouldDispatchInlineMixinLifecycle(persistedNode._dom)) {
1512
- scheduler.enqueueCommitPhase([
1513
- () => dispatchMixinCommit(newNode._mixState),
1514
- ]);
1647
+ scheduler.enqueueCommitPhase([() => dispatchMixinCommit(committed._mixState)]);
1515
1648
  }
1649
+ return committed;
1516
1650
  }
1517
1651
  //# sourceMappingURL=reconcile.js.map