@askrjs/askr 0.0.47 → 0.0.49

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 (394) hide show
  1. package/dist/benchmark.js +6 -6
  2. package/dist/benchmark.js.map +1 -1
  3. package/dist/boot/hydration.js +140 -0
  4. package/dist/boot/hydration.js.map +1 -0
  5. package/dist/boot/index.d.ts +3 -56
  6. package/dist/boot/index.d.ts.map +1 -1
  7. package/dist/boot/index.js +62 -410
  8. package/dist/boot/index.js.map +1 -1
  9. package/dist/boot/root-lifecycle.d.ts +15 -0
  10. package/dist/boot/root-lifecycle.d.ts.map +1 -0
  11. package/dist/boot/root-lifecycle.js +205 -0
  12. package/dist/boot/root-lifecycle.js.map +1 -0
  13. package/dist/boot/route-startup.js +45 -0
  14. package/dist/boot/route-startup.js.map +1 -0
  15. package/dist/boot/types.d.ts +62 -0
  16. package/dist/boot/types.d.ts.map +1 -0
  17. package/dist/common/component.d.ts +3 -1
  18. package/dist/common/component.d.ts.map +1 -1
  19. package/dist/common/jsx.d.ts +1 -1
  20. package/dist/common/jsx.d.ts.map +1 -1
  21. package/dist/common/jsx.js.map +1 -1
  22. package/dist/common/props.d.ts +1 -1
  23. package/dist/common/render-context.js +55 -0
  24. package/dist/common/render-context.js.map +1 -0
  25. package/dist/common/router.d.ts +5 -1
  26. package/dist/common/router.d.ts.map +1 -1
  27. package/dist/common/ssr.d.ts +1 -1
  28. package/dist/common/ssr.js.map +1 -1
  29. package/dist/common/vnode.d.ts +5 -4
  30. package/dist/common/vnode.d.ts.map +1 -1
  31. package/dist/common/vnode.js.map +1 -1
  32. package/dist/components/error-boundary.d.ts +1 -1
  33. package/dist/components/error-boundary.js +2 -1
  34. package/dist/components/error-boundary.js.map +1 -1
  35. package/dist/components/link.js.map +1 -1
  36. package/dist/control/for.js +2 -1
  37. package/dist/control/for.js.map +1 -1
  38. package/dist/data/data-runtime.d.ts +28 -0
  39. package/dist/data/data-runtime.d.ts.map +1 -0
  40. package/dist/data/data-runtime.js +114 -0
  41. package/dist/data/data-runtime.js.map +1 -0
  42. package/dist/data/index.d.ts +6 -142
  43. package/dist/data/index.js +5 -539
  44. package/dist/data/invalidation.d.ts +9 -0
  45. package/dist/data/invalidation.d.ts.map +1 -0
  46. package/dist/data/invalidation.js +27 -0
  47. package/dist/data/invalidation.js.map +1 -0
  48. package/dist/data/mutation-cell.d.ts +28 -0
  49. package/dist/data/mutation-cell.d.ts.map +1 -0
  50. package/dist/data/mutation-cell.js +132 -0
  51. package/dist/data/mutation-cell.js.map +1 -0
  52. package/dist/data/query-cell.d.ts +46 -0
  53. package/dist/data/query-cell.d.ts.map +1 -0
  54. package/dist/data/query-cell.js +290 -0
  55. package/dist/data/query-cell.js.map +1 -0
  56. package/dist/data/query-key.js +42 -0
  57. package/dist/data/query-key.js.map +1 -0
  58. package/dist/data/shared.js +20 -0
  59. package/dist/data/shared.js.map +1 -0
  60. package/dist/data/types.d.ts +161 -0
  61. package/dist/data/types.d.ts.map +1 -0
  62. package/dist/foundations/icon/icon.d.ts.map +1 -1
  63. package/dist/foundations/icon/icon.js.map +1 -1
  64. package/dist/foundations/structures/portal.d.ts +1 -1
  65. package/dist/foundations/structures/portal.d.ts.map +1 -1
  66. package/dist/foundations/structures/portal.js +2 -1
  67. package/dist/foundations/structures/portal.js.map +1 -1
  68. package/dist/fx/fx.d.ts +1 -1
  69. package/dist/fx/fx.js +5 -4
  70. package/dist/fx/fx.js.map +1 -1
  71. package/dist/fx/timing.d.ts.map +1 -1
  72. package/dist/fx/timing.js +10 -6
  73. package/dist/fx/timing.js.map +1 -1
  74. package/dist/index.d.ts +3 -2
  75. package/dist/index.js +4 -2
  76. package/dist/index.js.map +1 -1
  77. package/dist/jsx/index.d.ts +2 -1
  78. package/dist/jsx/index.js +3 -2
  79. package/dist/jsx/types.d.ts +2 -0
  80. package/dist/jsx/types.js +2 -1
  81. package/dist/jsx-runtime2.d.ts +2 -1
  82. package/dist/jsx-runtime2.js +3 -2
  83. package/dist/renderer/attributes.js +231 -0
  84. package/dist/renderer/attributes.js.map +1 -0
  85. package/dist/renderer/boundaries.js +266 -0
  86. package/dist/renderer/boundaries.js.map +1 -0
  87. package/dist/renderer/child-shape.js +85 -0
  88. package/dist/renderer/child-shape.js.map +1 -0
  89. package/dist/renderer/children.js +3 -2
  90. package/dist/renderer/children.js.map +1 -1
  91. package/dist/renderer/cleanup.js +2 -1
  92. package/dist/renderer/cleanup.js.map +1 -1
  93. package/dist/renderer/component-host-cleanup.js +68 -0
  94. package/dist/renderer/component-host-cleanup.js.map +1 -0
  95. package/dist/renderer/component-host-instances.js +65 -0
  96. package/dist/renderer/component-host-instances.js.map +1 -0
  97. package/dist/renderer/component-host.js +247 -0
  98. package/dist/renderer/component-host.js.map +1 -0
  99. package/dist/renderer/dom-host.js +13 -0
  100. package/dist/renderer/dom-host.js.map +1 -0
  101. package/dist/renderer/dom-internal.js +185 -0
  102. package/dist/renderer/dom-internal.js.map +1 -0
  103. package/dist/renderer/dom.js +9 -2356
  104. package/dist/renderer/element-children.js +279 -0
  105. package/dist/renderer/element-children.js.map +1 -0
  106. package/dist/renderer/env.js +2 -1
  107. package/dist/renderer/error-boundary-dom.js +29 -0
  108. package/dist/renderer/error-boundary-dom.js.map +1 -0
  109. package/dist/renderer/evaluate-dom-range.js +85 -0
  110. package/dist/renderer/evaluate-dom-range.js.map +1 -0
  111. package/dist/renderer/evaluate-reconcile.js +281 -0
  112. package/dist/renderer/evaluate-reconcile.js.map +1 -0
  113. package/dist/renderer/evaluate.js +13 -399
  114. package/dist/renderer/evaluate.js.map +1 -1
  115. package/dist/renderer/fastpath.js +6 -5
  116. package/dist/renderer/fastpath.js.map +1 -1
  117. package/dist/renderer/for-commit-dom-map.js +83 -0
  118. package/dist/renderer/for-commit-dom-map.js.map +1 -0
  119. package/dist/renderer/for-commit-removal.js +36 -0
  120. package/dist/renderer/for-commit-removal.js.map +1 -0
  121. package/dist/renderer/for-commit-reorder.js +89 -0
  122. package/dist/renderer/for-commit-reorder.js.map +1 -0
  123. package/dist/renderer/for-commit.js +6 -188
  124. package/dist/renderer/for-commit.js.map +1 -1
  125. package/dist/renderer/index.js +28 -16
  126. package/dist/renderer/index.js.map +1 -1
  127. package/dist/renderer/keyed-children.js +32 -0
  128. package/dist/renderer/keyed-children.js.map +1 -0
  129. package/dist/renderer/keyed.js +2 -15
  130. package/dist/renderer/keyed.js.map +1 -1
  131. package/dist/renderer/namespaces.js +23 -0
  132. package/dist/renderer/namespaces.js.map +1 -0
  133. package/dist/renderer/prop-bindings.js +280 -0
  134. package/dist/renderer/prop-bindings.js.map +1 -0
  135. package/dist/renderer/reactive-child-dom.js +133 -0
  136. package/dist/renderer/reactive-child-dom.js.map +1 -0
  137. package/dist/renderer/reactive-child-sources.js +184 -0
  138. package/dist/renderer/reactive-child-sources.js.map +1 -0
  139. package/dist/renderer/reactive-children.js +294 -0
  140. package/dist/renderer/reactive-children.js.map +1 -0
  141. package/dist/renderer/reconcile-commit.js +38 -0
  142. package/dist/renderer/reconcile-commit.js.map +1 -0
  143. package/dist/renderer/reconcile-fastpaths.js +106 -0
  144. package/dist/renderer/reconcile-fastpaths.js.map +1 -0
  145. package/dist/renderer/reconcile-resolution.js +187 -0
  146. package/dist/renderer/reconcile-resolution.js.map +1 -0
  147. package/dist/renderer/reconcile.js +9 -371
  148. package/dist/renderer/reconcile.js.map +1 -1
  149. package/dist/renderer/retained-element-rollback.js +276 -0
  150. package/dist/renderer/retained-element-rollback.js.map +1 -0
  151. package/dist/renderer/stable-patch.js +82 -0
  152. package/dist/renderer/stable-patch.js.map +1 -0
  153. package/dist/renderer/static-reuse.js +96 -0
  154. package/dist/renderer/static-reuse.js.map +1 -0
  155. package/dist/renderer/types.js +2 -1
  156. package/dist/renderer/utils.js +4 -4
  157. package/dist/renderer/utils.js.map +1 -1
  158. package/dist/resources/index.d.ts +3 -2
  159. package/dist/resources/index.js +5 -2
  160. package/dist/router/access.js +36 -0
  161. package/dist/router/access.js.map +1 -0
  162. package/dist/router/activity.d.ts +10 -0
  163. package/dist/router/activity.d.ts.map +1 -0
  164. package/dist/router/activity.js +89 -0
  165. package/dist/router/activity.js.map +1 -0
  166. package/dist/router/authoring.d.ts +22 -0
  167. package/dist/router/authoring.d.ts.map +1 -0
  168. package/dist/router/authoring.js +198 -0
  169. package/dist/router/authoring.js.map +1 -0
  170. package/dist/router/index.d.ts +12 -4
  171. package/dist/router/index.js +9 -2
  172. package/dist/router/internal-types.d.ts +31 -0
  173. package/dist/router/internal-types.d.ts.map +1 -0
  174. package/dist/router/lazy.d.ts +19 -0
  175. package/dist/router/lazy.d.ts.map +1 -0
  176. package/dist/router/lazy.js +52 -0
  177. package/dist/router/lazy.js.map +1 -0
  178. package/dist/router/manifest.d.ts +10 -0
  179. package/dist/router/manifest.d.ts.map +1 -0
  180. package/dist/router/manifest.js +49 -0
  181. package/dist/router/manifest.js.map +1 -0
  182. package/dist/router/navigate.d.ts +4 -33
  183. package/dist/router/navigate.d.ts.map +1 -1
  184. package/dist/router/navigate.js +17 -414
  185. package/dist/router/navigate.js.map +1 -1
  186. package/dist/router/navigation-registry.d.ts +32 -0
  187. package/dist/router/navigation-registry.d.ts.map +1 -0
  188. package/dist/router/navigation-registry.js +105 -0
  189. package/dist/router/navigation-registry.js.map +1 -0
  190. package/dist/router/navigation-scroll.d.ts +14 -0
  191. package/dist/router/navigation-scroll.d.ts.map +1 -0
  192. package/dist/router/navigation-scroll.js +93 -0
  193. package/dist/router/navigation-scroll.js.map +1 -0
  194. package/dist/router/navigation-targets.d.ts +31 -0
  195. package/dist/router/navigation-targets.d.ts.map +1 -0
  196. package/dist/router/navigation-targets.js +253 -0
  197. package/dist/router/navigation-targets.js.map +1 -0
  198. package/dist/router/policy.d.ts +7 -1
  199. package/dist/router/policy.d.ts.map +1 -1
  200. package/dist/router/policy.js +27 -9
  201. package/dist/router/policy.js.map +1 -1
  202. package/dist/router/rendering.d.ts +10 -0
  203. package/dist/router/rendering.d.ts.map +1 -0
  204. package/dist/router/rendering.js +45 -0
  205. package/dist/router/rendering.js.map +1 -0
  206. package/dist/router/resolution.d.ts +17 -0
  207. package/dist/router/resolution.d.ts.map +1 -0
  208. package/dist/router/resolution.js +253 -0
  209. package/dist/router/resolution.js.map +1 -0
  210. package/dist/router/route-query.d.ts +17 -0
  211. package/dist/router/route-query.d.ts.map +1 -0
  212. package/dist/router/route-query.js +47 -0
  213. package/dist/router/route-query.js.map +1 -0
  214. package/dist/router/route.d.ts +8 -149
  215. package/dist/router/route.js +8 -854
  216. package/dist/router/store.d.ts +50 -0
  217. package/dist/router/store.d.ts.map +1 -0
  218. package/dist/router/store.js +171 -0
  219. package/dist/router/store.js.map +1 -0
  220. package/dist/runtime/access.js +45 -0
  221. package/dist/runtime/access.js.map +1 -0
  222. package/dist/runtime/child-scope.d.ts +1 -1
  223. package/dist/runtime/child-scope.js +4 -1
  224. package/dist/runtime/child-scope.js.map +1 -1
  225. package/dist/runtime/component-cleanup.d.ts +16 -0
  226. package/dist/runtime/component-cleanup.d.ts.map +1 -0
  227. package/dist/runtime/component-cleanup.js +70 -0
  228. package/dist/runtime/component-cleanup.js.map +1 -0
  229. package/dist/runtime/component-commit.js +165 -0
  230. package/dist/runtime/component-commit.js.map +1 -0
  231. package/dist/runtime/component-contracts.js +5 -0
  232. package/dist/runtime/component-facade.d.ts +5 -0
  233. package/dist/runtime/component-facade.js +4 -0
  234. package/dist/runtime/component-internal.d.ts +100 -0
  235. package/dist/runtime/component-internal.d.ts.map +1 -0
  236. package/dist/runtime/component-internal.js +219 -0
  237. package/dist/runtime/component-internal.js.map +1 -0
  238. package/dist/runtime/component-lifecycle.d.ts +49 -0
  239. package/dist/runtime/component-lifecycle.d.ts.map +1 -0
  240. package/dist/runtime/component-lifecycle.js +176 -0
  241. package/dist/runtime/component-lifecycle.js.map +1 -0
  242. package/dist/runtime/component-scope.d.ts +55 -0
  243. package/dist/runtime/component-scope.d.ts.map +1 -0
  244. package/dist/runtime/component-scope.js +154 -0
  245. package/dist/runtime/component-scope.js.map +1 -0
  246. package/dist/runtime/component.d.ts +4 -152
  247. package/dist/runtime/component.js +4 -692
  248. package/dist/runtime/context.d.ts +1 -1
  249. package/dist/runtime/context.js +6 -4
  250. package/dist/runtime/context.js.map +1 -1
  251. package/dist/runtime/control.d.ts +3 -3
  252. package/dist/runtime/control.js +2 -1
  253. package/dist/runtime/control.js.map +1 -1
  254. package/dist/runtime/derive.d.ts.map +1 -1
  255. package/dist/runtime/derive.js +6 -5
  256. package/dist/runtime/derive.js.map +1 -1
  257. package/dist/runtime/effect.d.ts +1 -1
  258. package/dist/runtime/effect.d.ts.map +1 -1
  259. package/dist/runtime/effect.js +2 -2
  260. package/dist/runtime/effect.js.map +1 -1
  261. package/dist/runtime/events.js +3 -3
  262. package/dist/runtime/events.js.map +1 -1
  263. package/dist/runtime/fastlane.js +13 -27
  264. package/dist/runtime/fastlane.js.map +1 -1
  265. package/dist/runtime/for-bench.d.ts +1 -1
  266. package/dist/runtime/for-bench.js +1 -4
  267. package/dist/runtime/for-bench.js.map +1 -1
  268. package/dist/runtime/for-internal.d.ts +43 -0
  269. package/dist/runtime/for-internal.d.ts.map +1 -0
  270. package/dist/runtime/for-internal.js +98 -0
  271. package/dist/runtime/for-internal.js.map +1 -0
  272. package/dist/runtime/for-reconcile.d.ts +8 -0
  273. package/dist/runtime/for-reconcile.d.ts.map +1 -0
  274. package/dist/runtime/for-reconcile.js +389 -0
  275. package/dist/runtime/for-reconcile.js.map +1 -0
  276. package/dist/runtime/for-scopes.d.ts +26 -0
  277. package/dist/runtime/for-scopes.d.ts.map +1 -0
  278. package/dist/runtime/for-scopes.js +160 -0
  279. package/dist/runtime/for-scopes.js.map +1 -0
  280. package/dist/runtime/for-signals.d.ts +30 -0
  281. package/dist/runtime/for-signals.d.ts.map +1 -0
  282. package/dist/runtime/for-signals.js +139 -0
  283. package/dist/runtime/for-signals.js.map +1 -0
  284. package/dist/runtime/for.d.ts +4 -66
  285. package/dist/runtime/for.js +5 -773
  286. package/dist/runtime/lifecycle-operations.d.ts +31 -0
  287. package/dist/runtime/lifecycle-operations.d.ts.map +1 -0
  288. package/dist/runtime/lifecycle-operations.js +195 -0
  289. package/dist/runtime/lifecycle-operations.js.map +1 -0
  290. package/dist/runtime/operations.d.ts +3 -40
  291. package/dist/runtime/operations.js +2 -357
  292. package/dist/runtime/readable.d.ts +2 -3
  293. package/dist/runtime/readable.d.ts.map +1 -1
  294. package/dist/runtime/readable.js +6 -5
  295. package/dist/runtime/readable.js.map +1 -1
  296. package/dist/runtime/resource-cell.js +2 -2
  297. package/dist/runtime/resource-cell.js.map +1 -1
  298. package/dist/runtime/resource-operation.d.ts +13 -0
  299. package/dist/runtime/resource-operation.d.ts.map +1 -0
  300. package/dist/runtime/resource-operation.js +170 -0
  301. package/dist/runtime/resource-operation.js.map +1 -0
  302. package/dist/runtime/runtime.d.ts +42 -0
  303. package/dist/runtime/runtime.d.ts.map +1 -0
  304. package/dist/runtime/runtime.js +59 -0
  305. package/dist/runtime/runtime.js.map +1 -0
  306. package/dist/runtime/scheduler.d.ts +5 -1
  307. package/dist/runtime/scheduler.d.ts.map +1 -1
  308. package/dist/runtime/scheduler.js +17 -17
  309. package/dist/runtime/scheduler.js.map +1 -1
  310. package/dist/runtime/selector.js +4 -3
  311. package/dist/runtime/selector.js.map +1 -1
  312. package/dist/runtime/snapshot-source.d.ts +1 -1
  313. package/dist/runtime/snapshot-source.js +1 -1
  314. package/dist/runtime/state.js +2 -1
  315. package/dist/runtime/state.js.map +1 -1
  316. package/dist/ssg/batch-render.js +2 -1
  317. package/dist/ssg/batch-render.js.map +1 -1
  318. package/dist/ssg/create-static-gen.d.ts +9 -3
  319. package/dist/ssg/create-static-gen.d.ts.map +1 -1
  320. package/dist/ssg/create-static-gen.js +12 -99
  321. package/dist/ssg/create-static-gen.js.map +1 -1
  322. package/dist/ssg/generation-plan.js +70 -0
  323. package/dist/ssg/generation-plan.js.map +1 -0
  324. package/dist/ssg/incremental-manifest.js +1 -1
  325. package/dist/ssg/static-routes.js +101 -0
  326. package/dist/ssg/static-routes.js.map +1 -0
  327. package/dist/ssg/types.d.ts +15 -7
  328. package/dist/ssg/types.d.ts.map +1 -1
  329. package/dist/ssr/boundaries.js +113 -0
  330. package/dist/ssr/boundaries.js.map +1 -0
  331. package/dist/ssr/component-runtime.js +111 -0
  332. package/dist/ssr/component-runtime.js.map +1 -0
  333. package/dist/ssr/context.d.ts +3 -1
  334. package/dist/ssr/context.d.ts.map +1 -1
  335. package/dist/ssr/context.js +9 -2
  336. package/dist/ssr/context.js.map +1 -1
  337. package/dist/ssr/errors.d.ts +2 -0
  338. package/dist/ssr/errors.js +11 -1
  339. package/dist/ssr/errors.js.map +1 -1
  340. package/dist/ssr/escape.js +3 -3
  341. package/dist/ssr/escape.js.map +1 -1
  342. package/dist/ssr/hydration-data.js +10 -0
  343. package/dist/ssr/hydration-data.js.map +1 -0
  344. package/dist/ssr/hydration-verify.d.ts +12 -0
  345. package/dist/ssr/hydration-verify.d.ts.map +1 -0
  346. package/dist/ssr/hydration-verify.js +144 -0
  347. package/dist/ssr/hydration-verify.js.map +1 -0
  348. package/dist/ssr/index-internal.d.ts +15 -0
  349. package/dist/ssr/index-internal.d.ts.map +1 -0
  350. package/dist/ssr/index-internal.js +19 -0
  351. package/dist/ssr/index-internal.js.map +1 -0
  352. package/dist/ssr/index.d.ts +5 -57
  353. package/dist/ssr/index.js +3 -738
  354. package/dist/ssr/render-keys.js +9 -32
  355. package/dist/ssr/render-keys.js.map +1 -1
  356. package/dist/ssr/render-resolved.d.ts +1 -1
  357. package/dist/ssr/render-resolved.d.ts.map +1 -1
  358. package/dist/ssr/render-resolved.js +4 -2
  359. package/dist/ssr/render-resolved.js.map +1 -1
  360. package/dist/ssr/render-sync.d.ts +21 -0
  361. package/dist/ssr/render-sync.d.ts.map +1 -0
  362. package/dist/ssr/render-sync.js +275 -0
  363. package/dist/ssr/render-sync.js.map +1 -0
  364. package/dist/ssr/route-policy-resolution.js +77 -0
  365. package/dist/ssr/route-policy-resolution.js.map +1 -0
  366. package/dist/ssr/route-render.d.ts +77 -0
  367. package/dist/ssr/route-render.d.ts.map +1 -0
  368. package/dist/ssr/route-render.js +119 -0
  369. package/dist/ssr/route-render.js.map +1 -0
  370. package/dist/ssr/sink.d.ts +26 -0
  371. package/dist/ssr/sink.d.ts.map +1 -0
  372. package/dist/ssr/types.d.ts +1 -0
  373. package/dist/ssr/types.d.ts.map +1 -1
  374. package/dist/ssr/verify-hydration.js.map +1 -1
  375. package/dist/testing/index.d.ts +1 -2
  376. package/dist/testing/index.d.ts.map +1 -1
  377. package/dist/testing/index.js +2 -1
  378. package/dist/testing/index.js.map +1 -1
  379. package/package.json +4 -3
  380. package/dist/data/index.d.ts.map +0 -1
  381. package/dist/data/index.js.map +0 -1
  382. package/dist/renderer/dom.js.map +0 -1
  383. package/dist/router/route.d.ts.map +0 -1
  384. package/dist/router/route.js.map +0 -1
  385. package/dist/runtime/component.d.ts.map +0 -1
  386. package/dist/runtime/component.js.map +0 -1
  387. package/dist/runtime/for.d.ts.map +0 -1
  388. package/dist/runtime/for.js.map +0 -1
  389. package/dist/runtime/operations.d.ts.map +0 -1
  390. package/dist/runtime/operations.js.map +0 -1
  391. package/dist/runtime/ssr-bridge.js +0 -24
  392. package/dist/runtime/ssr-bridge.js.map +0 -1
  393. package/dist/ssr/index.d.ts.map +0 -1
  394. package/dist/ssr/index.js.map +0 -1
@@ -0,0 +1,276 @@
1
+ import { logger } from "../dev/logger.js";
2
+ import { addDelegatedListener, getDelegatedHandlersForElement, removeDelegatedListener, updateDelegatedListener } from "../runtime/events.js";
3
+ import { elementListeners, elementReactivePropsCleanup, elementRefs } from "./cleanup.js";
4
+ import { keyedElements } from "./keyed.js";
5
+ //#region src/renderer/retained-element-rollback.ts
6
+ function collectElementSubtree(root) {
7
+ const elements = [root];
8
+ const descendants = root.querySelectorAll("*");
9
+ for (let index = 0; index < descendants.length; index += 1) elements.push(descendants[index]);
10
+ return elements;
11
+ }
12
+ function collectTextSnapshots(root) {
13
+ const snapshots = [];
14
+ const stack = Array.from(root.childNodes).reverse();
15
+ while (stack.length > 0) {
16
+ const node = stack.pop();
17
+ if (node.nodeType === 3) {
18
+ snapshots.push({
19
+ node,
20
+ data: node.data
21
+ });
22
+ continue;
23
+ }
24
+ for (let child = node.lastChild; child; child = child.previousSibling) stack.push(child);
25
+ }
26
+ return snapshots;
27
+ }
28
+ function getFormControlSnapshot(element) {
29
+ const control = element;
30
+ const snapshot = { element };
31
+ if ("value" in control) snapshot.value = String(control.value ?? "");
32
+ if ("checked" in control) snapshot.checked = Boolean(control.checked);
33
+ return snapshot.value !== void 0 || snapshot.checked !== void 0 ? snapshot : null;
34
+ }
35
+ function cloneListenerEntry(entry) {
36
+ return {
37
+ handler: entry.handler,
38
+ original: entry.original,
39
+ eventName: entry.eventName,
40
+ options: entry.options,
41
+ isDelegated: entry.isDelegated,
42
+ updateHandler: entry.updateHandler
43
+ };
44
+ }
45
+ function cloneReactivePropEntry(entry) {
46
+ return {
47
+ cleanup: entry.cleanup,
48
+ fnRef: entry.fnRef,
49
+ restoreFn: entry.restoreFn,
50
+ updateFn: entry.updateFn
51
+ };
52
+ }
53
+ function snapshotRetainedElement(element) {
54
+ const elements = collectElementSubtree(element);
55
+ const attributes = [];
56
+ const childNodes = [];
57
+ const delegatedListeners = [];
58
+ const formControls = [];
59
+ const listeners = [];
60
+ const reactiveProps = [];
61
+ const refs = [];
62
+ for (const currentElement of elements) {
63
+ attributes.push({
64
+ element: currentElement,
65
+ attributes: Array.from(currentElement.attributes, (attribute) => [attribute.name, attribute.value])
66
+ });
67
+ childNodes.push({
68
+ element: currentElement,
69
+ childNodes: Array.from(currentElement.childNodes)
70
+ });
71
+ const formControl = getFormControlSnapshot(currentElement);
72
+ if (formControl) formControls.push(formControl);
73
+ const listenerMap = elementListeners.get(currentElement);
74
+ listeners.push({
75
+ element: currentElement,
76
+ entries: listenerMap ? Array.from(listenerMap, ([listenerKey, entry]) => ({
77
+ listenerKey,
78
+ entry: cloneListenerEntry(entry)
79
+ })) : []
80
+ });
81
+ const delegatedHandlerMap = getDelegatedHandlersForElement(currentElement);
82
+ delegatedListeners.push({
83
+ element: currentElement,
84
+ entries: delegatedHandlerMap ? Array.from(delegatedHandlerMap, ([eventName, entry]) => ({
85
+ eventName,
86
+ handler: entry.handler,
87
+ original: entry.original,
88
+ options: entry.options
89
+ })) : []
90
+ });
91
+ const reactivePropMap = elementReactivePropsCleanup.get(currentElement);
92
+ reactiveProps.push({
93
+ element: currentElement,
94
+ entries: reactivePropMap ? Array.from(reactivePropMap, ([propName, entry]) => ({
95
+ propName,
96
+ entry: cloneReactivePropEntry(entry)
97
+ })) : []
98
+ });
99
+ refs.push({
100
+ element: currentElement,
101
+ ref: elementRefs.get(currentElement)
102
+ });
103
+ }
104
+ const keyedMap = keyedElements.get(element);
105
+ return {
106
+ attributes,
107
+ childNodes,
108
+ delegatedListeners,
109
+ formControls,
110
+ keyedMap: keyedMap ? new Map(keyedMap) : void 0,
111
+ listeners,
112
+ reactiveProps,
113
+ refs,
114
+ textNodes: collectTextSnapshots(element)
115
+ };
116
+ }
117
+ function sameChildOrder(element, childNodes) {
118
+ if (element.childNodes.length !== childNodes.length) return false;
119
+ for (let index = 0; index < childNodes.length; index += 1) if (element.childNodes[index] !== childNodes[index]) return false;
120
+ return true;
121
+ }
122
+ function restoreAttributes(snapshot) {
123
+ for (const { element, attributes } of snapshot.attributes) {
124
+ const expectedNames = new Set(attributes.map(([name]) => name));
125
+ for (const attribute of Array.from(element.attributes)) if (!expectedNames.has(attribute.name)) element.removeAttribute(attribute.name);
126
+ for (const [name, value] of attributes) if (element.getAttribute(name) !== value) element.setAttribute(name, value);
127
+ }
128
+ }
129
+ function restoreFormControls(snapshot) {
130
+ for (const { element, value, checked } of snapshot.formControls) {
131
+ const control = element;
132
+ if (value !== void 0 && "value" in control) control.value = value;
133
+ if (checked !== void 0 && "checked" in control) control.checked = checked;
134
+ }
135
+ }
136
+ function applyRefValue(ref, value) {
137
+ if (!ref) return;
138
+ try {
139
+ if (typeof ref === "function") {
140
+ ref(value);
141
+ return;
142
+ }
143
+ if (Object.isExtensible(ref)) ref.current = value;
144
+ } catch {}
145
+ }
146
+ function restoreRefs(snapshot) {
147
+ for (const { element, ref } of snapshot.refs) {
148
+ const currentRef = elementRefs.get(element);
149
+ if (currentRef !== ref) applyRefValue(currentRef, null);
150
+ if (ref) {
151
+ applyRefValue(ref, element);
152
+ elementRefs.set(element, ref);
153
+ } else elementRefs.delete(element);
154
+ }
155
+ }
156
+ function removeDirectListener(element, entry) {
157
+ if (entry.isDelegated) return;
158
+ if (entry.options !== void 0) element.removeEventListener(entry.eventName, entry.handler, entry.options);
159
+ else element.removeEventListener(entry.eventName, entry.handler);
160
+ }
161
+ function addDirectListener(element, entry) {
162
+ if (entry.isDelegated) return;
163
+ if (entry.options !== void 0) element.addEventListener(entry.eventName, entry.handler, entry.options);
164
+ else element.addEventListener(entry.eventName, entry.handler);
165
+ }
166
+ function restoreListeners(snapshot) {
167
+ for (const { element, entries } of snapshot.listeners) {
168
+ const expectedKeys = new Set(entries.map(({ listenerKey }) => listenerKey));
169
+ let currentMap = elementListeners.get(element);
170
+ if (currentMap) {
171
+ for (const [listenerKey, entry] of Array.from(currentMap)) if (!expectedKeys.has(listenerKey)) {
172
+ removeDirectListener(element, entry);
173
+ currentMap.delete(listenerKey);
174
+ }
175
+ }
176
+ if (entries.length === 0) {
177
+ if (currentMap?.size === 0) elementListeners.delete(element);
178
+ continue;
179
+ }
180
+ if (!currentMap) {
181
+ currentMap = /* @__PURE__ */ new Map();
182
+ elementListeners.set(element, currentMap);
183
+ }
184
+ for (const { listenerKey, entry } of entries) {
185
+ const currentEntry = currentMap.get(listenerKey);
186
+ entry.updateHandler?.(entry.original);
187
+ if (currentEntry && currentEntry.handler !== entry.handler) removeDirectListener(element, currentEntry);
188
+ if (!currentEntry || currentEntry.handler !== entry.handler) addDirectListener(element, entry);
189
+ else currentEntry.updateHandler?.(entry.original);
190
+ currentMap.set(listenerKey, cloneListenerEntry(entry));
191
+ }
192
+ }
193
+ }
194
+ function restoreDelegatedListeners(snapshot) {
195
+ for (const { element, entries } of snapshot.delegatedListeners) {
196
+ const expectedEventNames = new Set(entries.map(({ eventName }) => eventName));
197
+ const currentMap = getDelegatedHandlersForElement(element);
198
+ if (currentMap) {
199
+ for (const eventName of currentMap.keys()) if (!expectedEventNames.has(eventName)) removeDelegatedListener(element, eventName);
200
+ }
201
+ for (const { eventName, handler, original, options } of entries) if (!updateDelegatedListener(element, eventName, handler, original, options)) addDelegatedListener(element, eventName, handler, original, options);
202
+ }
203
+ }
204
+ function restoreReactiveProps(snapshot) {
205
+ for (const { element, entries } of snapshot.reactiveProps) {
206
+ const expectedPropNames = new Set(entries.map(({ propName }) => propName));
207
+ let currentMap = elementReactivePropsCleanup.get(element);
208
+ if (currentMap) {
209
+ for (const [propName, entry] of Array.from(currentMap)) if (!expectedPropNames.has(propName)) {
210
+ entry.cleanup();
211
+ currentMap.delete(propName);
212
+ }
213
+ }
214
+ if (entries.length === 0) {
215
+ if (currentMap?.size === 0) elementReactivePropsCleanup.delete(element);
216
+ continue;
217
+ }
218
+ if (!currentMap) {
219
+ currentMap = /* @__PURE__ */ new Map();
220
+ elementReactivePropsCleanup.set(element, currentMap);
221
+ }
222
+ for (const { propName, entry } of entries) {
223
+ const currentEntry = currentMap.get(propName);
224
+ if (currentEntry) {
225
+ currentEntry.updateFn?.(entry.fnRef);
226
+ currentEntry.fnRef = entry.fnRef;
227
+ currentMap.set(propName, currentEntry);
228
+ continue;
229
+ }
230
+ currentMap.set(propName, entry.restoreFn?.(entry.fnRef) ?? cloneReactivePropEntry(entry));
231
+ }
232
+ }
233
+ }
234
+ function restoreChildNodes(snapshot, cleanupRangeNode) {
235
+ for (const { element, childNodes } of snapshot.childNodes) {
236
+ const expectedChildren = new Set(childNodes);
237
+ for (const child of Array.from(element.childNodes)) if (!expectedChildren.has(child)) cleanupRangeNode(child);
238
+ }
239
+ for (const { element, childNodes } of snapshot.childNodes) if (!sameChildOrder(element, childNodes)) element.replaceChildren(...childNodes);
240
+ }
241
+ function restoreTextNodes(snapshot) {
242
+ for (const { node, data } of snapshot.textNodes) if (node.data !== data) node.data = data;
243
+ }
244
+ function restoreKeyedMap(element, snapshot) {
245
+ if (snapshot.keyedMap) keyedElements.set(element, new Map(snapshot.keyedMap));
246
+ else keyedElements.delete(element);
247
+ }
248
+ function restoreRetainedElement(element, snapshot, cleanupRangeNode) {
249
+ restoreChildNodes(snapshot, cleanupRangeNode);
250
+ restoreReactiveProps(snapshot);
251
+ restoreAttributes(snapshot);
252
+ restoreTextNodes(snapshot);
253
+ restoreFormControls(snapshot);
254
+ restoreRefs(snapshot);
255
+ restoreListeners(snapshot);
256
+ restoreDelegatedListeners(snapshot);
257
+ restoreKeyedMap(element, snapshot);
258
+ }
259
+ function runRetainedElementUpdate(element, cleanupRangeNode, update, onError) {
260
+ const snapshot = snapshotRetainedElement(element);
261
+ try {
262
+ update();
263
+ } catch (err) {
264
+ onError?.();
265
+ try {
266
+ restoreRetainedElement(element, snapshot, cleanupRangeNode);
267
+ } catch (rollbackError) {
268
+ logger.warn("[Askr] retained element rollback failed:", rollbackError);
269
+ }
270
+ throw err;
271
+ }
272
+ }
273
+ //#endregion
274
+ export { restoreRetainedElement, runRetainedElementUpdate, snapshotRetainedElement };
275
+
276
+ //# sourceMappingURL=retained-element-rollback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retained-element-rollback.js","names":[],"sources":["../../src/renderer/retained-element-rollback.ts"],"sourcesContent":["import { logger } from '../dev/logger';\nimport {\n addDelegatedListener,\n getDelegatedHandlersForElement,\n removeDelegatedListener,\n updateDelegatedListener,\n} from '../runtime/events';\nimport {\n elementListeners,\n elementReactivePropsCleanup,\n elementRefs,\n type ListenerMapEntry,\n type ReactivePropCleanupEntry,\n} from './cleanup';\nimport { keyedElements } from './keyed';\n\ninterface AttributeSnapshot {\n element: Element;\n attributes: Array<[string, string]>;\n}\n\ninterface ChildNodesSnapshot {\n element: Element;\n childNodes: Node[];\n}\n\ninterface FormControlSnapshot {\n element: Element;\n value?: string;\n checked?: boolean;\n}\n\ninterface DelegatedListenerEntrySnapshot {\n eventName: string;\n handler: EventListener;\n original: EventListener;\n options?: AddEventListenerOptions;\n}\n\ninterface DelegatedListenerSnapshot {\n element: Element;\n entries: DelegatedListenerEntrySnapshot[];\n}\n\ninterface ListenerEntrySnapshot {\n listenerKey: string;\n entry: ListenerMapEntry;\n}\n\ninterface ListenerSnapshot {\n element: Element;\n entries: ListenerEntrySnapshot[];\n}\n\ninterface RefSnapshot {\n element: Element;\n ref: unknown;\n}\n\ninterface ReactivePropEntrySnapshot {\n propName: string;\n entry: ReactivePropCleanupEntry;\n}\n\ninterface ReactivePropsSnapshot {\n element: Element;\n entries: ReactivePropEntrySnapshot[];\n}\n\ninterface TextSnapshot {\n node: Text;\n data: string;\n}\n\nexport interface RetainedElementSnapshot {\n attributes: AttributeSnapshot[];\n childNodes: ChildNodesSnapshot[];\n delegatedListeners: DelegatedListenerSnapshot[];\n formControls: FormControlSnapshot[];\n keyedMap: Map<string | number, Element> | undefined;\n listeners: ListenerSnapshot[];\n reactiveProps: ReactivePropsSnapshot[];\n refs: RefSnapshot[];\n textNodes: TextSnapshot[];\n}\n\nfunction collectElementSubtree(root: Element): Element[] {\n const elements = [root];\n const descendants = root.querySelectorAll('*');\n for (let index = 0; index < descendants.length; index += 1) {\n elements.push(descendants[index]);\n }\n return elements;\n}\n\nfunction collectTextSnapshots(root: Element): TextSnapshot[] {\n const snapshots: TextSnapshot[] = [];\n const stack = Array.from(root.childNodes).reverse();\n\n while (stack.length > 0) {\n const node = stack.pop()!;\n if (node.nodeType === 3) {\n snapshots.push({ node: node as Text, data: (node as Text).data });\n continue;\n }\n\n for (let child = node.lastChild; child; child = child.previousSibling) {\n stack.push(child);\n }\n }\n\n return snapshots;\n}\n\nfunction getFormControlSnapshot(element: Element): FormControlSnapshot | null {\n const control = element as Element & {\n value?: unknown;\n checked?: unknown;\n };\n const snapshot: FormControlSnapshot = { element };\n\n if ('value' in control) {\n snapshot.value = String(control.value ?? '');\n }\n\n if ('checked' in control) {\n snapshot.checked = Boolean(control.checked);\n }\n\n return snapshot.value !== undefined || snapshot.checked !== undefined\n ? snapshot\n : null;\n}\n\nfunction cloneListenerEntry(entry: ListenerMapEntry): ListenerMapEntry {\n return {\n handler: entry.handler,\n original: entry.original,\n eventName: entry.eventName,\n options: entry.options,\n isDelegated: entry.isDelegated,\n updateHandler: entry.updateHandler,\n };\n}\n\nfunction cloneReactivePropEntry(\n entry: ReactivePropCleanupEntry\n): ReactivePropCleanupEntry {\n return {\n cleanup: entry.cleanup,\n fnRef: entry.fnRef,\n restoreFn: entry.restoreFn,\n updateFn: entry.updateFn,\n };\n}\n\nexport function snapshotRetainedElement(\n element: Element\n): RetainedElementSnapshot {\n const elements = collectElementSubtree(element);\n const attributes: AttributeSnapshot[] = [];\n const childNodes: ChildNodesSnapshot[] = [];\n const delegatedListeners: DelegatedListenerSnapshot[] = [];\n const formControls: FormControlSnapshot[] = [];\n const listeners: ListenerSnapshot[] = [];\n const reactiveProps: ReactivePropsSnapshot[] = [];\n const refs: RefSnapshot[] = [];\n\n for (const currentElement of elements) {\n attributes.push({\n element: currentElement,\n attributes: Array.from(currentElement.attributes, (attribute) => [\n attribute.name,\n attribute.value,\n ]),\n });\n childNodes.push({\n element: currentElement,\n childNodes: Array.from(currentElement.childNodes),\n });\n\n const formControl = getFormControlSnapshot(currentElement);\n if (formControl) {\n formControls.push(formControl);\n }\n\n const listenerMap = elementListeners.get(currentElement);\n listeners.push({\n element: currentElement,\n entries: listenerMap\n ? Array.from(listenerMap, ([listenerKey, entry]) => ({\n listenerKey,\n entry: cloneListenerEntry(entry),\n }))\n : [],\n });\n\n const delegatedHandlerMap = getDelegatedHandlersForElement(currentElement);\n delegatedListeners.push({\n element: currentElement,\n entries: delegatedHandlerMap\n ? Array.from(delegatedHandlerMap, ([eventName, entry]) => ({\n eventName,\n handler: entry.handler,\n original: entry.original,\n options: entry.options,\n }))\n : [],\n });\n\n const reactivePropMap = elementReactivePropsCleanup.get(currentElement);\n reactiveProps.push({\n element: currentElement,\n entries: reactivePropMap\n ? Array.from(reactivePropMap, ([propName, entry]) => ({\n propName,\n entry: cloneReactivePropEntry(entry),\n }))\n : [],\n });\n\n refs.push({\n element: currentElement,\n ref: elementRefs.get(currentElement),\n });\n }\n\n const keyedMap = keyedElements.get(element);\n\n return {\n attributes,\n childNodes,\n delegatedListeners,\n formControls,\n keyedMap: keyedMap ? new Map(keyedMap) : undefined,\n listeners,\n reactiveProps,\n refs,\n textNodes: collectTextSnapshots(element),\n };\n}\n\nfunction sameChildOrder(element: Element, childNodes: Node[]): boolean {\n if (element.childNodes.length !== childNodes.length) {\n return false;\n }\n\n for (let index = 0; index < childNodes.length; index += 1) {\n if (element.childNodes[index] !== childNodes[index]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction restoreAttributes(snapshot: RetainedElementSnapshot): void {\n for (const { element, attributes } of snapshot.attributes) {\n const expectedNames = new Set(attributes.map(([name]) => name));\n\n for (const attribute of Array.from(element.attributes)) {\n if (!expectedNames.has(attribute.name)) {\n element.removeAttribute(attribute.name);\n }\n }\n\n for (const [name, value] of attributes) {\n if (element.getAttribute(name) !== value) {\n element.setAttribute(name, value);\n }\n }\n }\n}\n\nfunction restoreFormControls(snapshot: RetainedElementSnapshot): void {\n for (const { element, value, checked } of snapshot.formControls) {\n const control = element as Element & {\n value?: string;\n checked?: boolean;\n };\n\n if (value !== undefined && 'value' in control) {\n control.value = value;\n }\n\n if (checked !== undefined && 'checked' in control) {\n control.checked = checked;\n }\n }\n}\n\nfunction applyRefValue<T>(ref: unknown, value: T | null): void {\n if (!ref) {\n return;\n }\n\n try {\n if (typeof ref === 'function') {\n (ref as (value: T | null) => void)(value);\n return;\n }\n\n if (Object.isExtensible(ref)) {\n (ref as { current: T | null }).current = value;\n }\n } catch {\n // Rollback must preserve the original render error.\n }\n}\n\nfunction restoreRefs(snapshot: RetainedElementSnapshot): void {\n for (const { element, ref } of snapshot.refs) {\n const currentRef = elementRefs.get(element);\n\n if (currentRef !== ref) {\n applyRefValue(currentRef, null);\n }\n\n if (ref) {\n applyRefValue(ref, element);\n elementRefs.set(element, ref);\n } else {\n elementRefs.delete(element);\n }\n }\n}\n\nfunction removeDirectListener(element: Element, entry: ListenerMapEntry): void {\n if (entry.isDelegated) {\n return;\n }\n\n if (entry.options !== undefined) {\n element.removeEventListener(entry.eventName, entry.handler, entry.options);\n } else {\n element.removeEventListener(entry.eventName, entry.handler);\n }\n}\n\nfunction addDirectListener(element: Element, entry: ListenerMapEntry): void {\n if (entry.isDelegated) {\n return;\n }\n\n if (entry.options !== undefined) {\n element.addEventListener(entry.eventName, entry.handler, entry.options);\n } else {\n element.addEventListener(entry.eventName, entry.handler);\n }\n}\n\nfunction restoreListeners(snapshot: RetainedElementSnapshot): void {\n for (const { element, entries } of snapshot.listeners) {\n const expectedKeys = new Set(entries.map(({ listenerKey }) => listenerKey));\n let currentMap = elementListeners.get(element);\n\n if (currentMap) {\n for (const [listenerKey, entry] of Array.from(currentMap)) {\n if (!expectedKeys.has(listenerKey)) {\n removeDirectListener(element, entry);\n currentMap.delete(listenerKey);\n }\n }\n }\n\n if (entries.length === 0) {\n if (currentMap?.size === 0) {\n elementListeners.delete(element);\n }\n continue;\n }\n\n if (!currentMap) {\n currentMap = new Map();\n elementListeners.set(element, currentMap);\n }\n\n for (const { listenerKey, entry } of entries) {\n const currentEntry = currentMap.get(listenerKey);\n\n entry.updateHandler?.(entry.original);\n\n if (currentEntry && currentEntry.handler !== entry.handler) {\n removeDirectListener(element, currentEntry);\n }\n\n if (!currentEntry || currentEntry.handler !== entry.handler) {\n addDirectListener(element, entry);\n } else {\n currentEntry.updateHandler?.(entry.original);\n }\n\n currentMap.set(listenerKey, cloneListenerEntry(entry));\n }\n }\n}\n\nfunction restoreDelegatedListeners(snapshot: RetainedElementSnapshot): void {\n for (const { element, entries } of snapshot.delegatedListeners) {\n const expectedEventNames = new Set(\n entries.map(({ eventName }) => eventName)\n );\n const currentMap = getDelegatedHandlersForElement(element);\n\n if (currentMap) {\n for (const eventName of currentMap.keys()) {\n if (!expectedEventNames.has(eventName)) {\n removeDelegatedListener(element, eventName);\n }\n }\n }\n\n for (const { eventName, handler, original, options } of entries) {\n if (\n !updateDelegatedListener(element, eventName, handler, original, options)\n ) {\n addDelegatedListener(element, eventName, handler, original, options);\n }\n }\n }\n}\n\nfunction restoreReactiveProps(snapshot: RetainedElementSnapshot): void {\n for (const { element, entries } of snapshot.reactiveProps) {\n const expectedPropNames = new Set(entries.map(({ propName }) => propName));\n let currentMap = elementReactivePropsCleanup.get(element);\n\n if (currentMap) {\n for (const [propName, entry] of Array.from(currentMap)) {\n if (!expectedPropNames.has(propName)) {\n entry.cleanup();\n currentMap.delete(propName);\n }\n }\n }\n\n if (entries.length === 0) {\n if (currentMap?.size === 0) {\n elementReactivePropsCleanup.delete(element);\n }\n continue;\n }\n\n if (!currentMap) {\n currentMap = new Map();\n elementReactivePropsCleanup.set(element, currentMap);\n }\n\n for (const { propName, entry } of entries) {\n const currentEntry = currentMap.get(propName);\n\n if (currentEntry) {\n currentEntry.updateFn?.(entry.fnRef);\n currentEntry.fnRef = entry.fnRef;\n currentMap.set(propName, currentEntry);\n continue;\n }\n\n currentMap.set(\n propName,\n entry.restoreFn?.(entry.fnRef) ?? cloneReactivePropEntry(entry)\n );\n }\n }\n}\n\nfunction restoreChildNodes(\n snapshot: RetainedElementSnapshot,\n cleanupRangeNode: (node: Node) => void\n): void {\n for (const { element, childNodes } of snapshot.childNodes) {\n const expectedChildren = new Set(childNodes);\n\n for (const child of Array.from(element.childNodes)) {\n if (!expectedChildren.has(child)) {\n cleanupRangeNode(child);\n }\n }\n }\n\n for (const { element, childNodes } of snapshot.childNodes) {\n if (!sameChildOrder(element, childNodes)) {\n element.replaceChildren(...childNodes);\n }\n }\n}\n\nfunction restoreTextNodes(snapshot: RetainedElementSnapshot): void {\n for (const { node, data } of snapshot.textNodes) {\n if (node.data !== data) {\n node.data = data;\n }\n }\n}\n\nfunction restoreKeyedMap(\n element: Element,\n snapshot: RetainedElementSnapshot\n): void {\n if (snapshot.keyedMap) {\n keyedElements.set(element, new Map(snapshot.keyedMap));\n } else {\n keyedElements.delete(element);\n }\n}\n\nexport function restoreRetainedElement(\n element: Element,\n snapshot: RetainedElementSnapshot,\n cleanupRangeNode: (node: Node) => void\n): void {\n restoreChildNodes(snapshot, cleanupRangeNode);\n restoreReactiveProps(snapshot);\n restoreAttributes(snapshot);\n restoreTextNodes(snapshot);\n restoreFormControls(snapshot);\n restoreRefs(snapshot);\n restoreListeners(snapshot);\n restoreDelegatedListeners(snapshot);\n restoreKeyedMap(element, snapshot);\n}\n\nexport function runRetainedElementUpdate(\n element: Element,\n cleanupRangeNode: (node: Node) => void,\n update: () => void,\n onError?: () => void\n): void {\n const snapshot = snapshotRetainedElement(element);\n\n try {\n update();\n } catch (err) {\n onError?.();\n\n try {\n restoreRetainedElement(element, snapshot, cleanupRangeNode);\n } catch (rollbackError) {\n logger.warn('[Askr] retained element rollback failed:', rollbackError);\n }\n\n throw err;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { _isDOMElement } from "../common/vnode.js";
2
+ import "./types.js";
3
+ import { getCurrentContextFrame, getVNodeContextFrame, withContext } from "../runtime/context.js";
4
+ import { incDevCounter } from "../runtime/dev-namespace.js";
5
+ import { getCurrentInstance } from "../runtime/component-scope.js";
6
+ import { isPromiseLike } from "../common/promise.js";
7
+ import { captureInlineRenderSnapshot, renderComponentInline, warnUnusedStateReads } from "../runtime/component-internal.js";
8
+ import "../runtime/component-contracts.js";
9
+ import { tagNamesEqualIgnoreCase } from "./utils.js";
10
+ import { recordBenchEvent } from "../runtime/for-bench.js";
11
+ import "../runtime/for.js";
12
+ import { getRendererDOMHost } from "./dom-host.js";
13
+ import { findHostInstanceByType, inheritComponentCleanupStrict, inheritComponentKey, isRouteRootComponentVNode } from "./component-host-instances.js";
14
+ import { resolveNestedComponentResult } from "./component-host.js";
15
+ //#region src/renderer/stable-patch.ts
16
+ function normalizeStableIntrinsicChildren(children) {
17
+ if (children === null || children === void 0 || children === false) return [];
18
+ return Array.isArray(children) ? children : [children];
19
+ }
20
+ function getStableIntrinsicChildren(vnode) {
21
+ return normalizeStableIntrinsicChildren(vnode.props?.children ?? vnode.children);
22
+ }
23
+ function patchStableIntrinsicText(domNode, nextVNode) {
24
+ if (domNode.nodeType !== 3 || typeof nextVNode !== "string" && typeof nextVNode !== "number") return false;
25
+ const nextText = String(nextVNode);
26
+ const textNode = domNode;
27
+ if (textNode.data !== nextText) {
28
+ recordBenchEvent("domTextSet");
29
+ textNode.data = nextText;
30
+ }
31
+ return true;
32
+ }
33
+ function patchStableIntrinsicElement(dom, nextVNode) {
34
+ if (typeof nextVNode.type !== "string" || !tagNamesEqualIgnoreCase(dom.tagName, nextVNode.type)) return false;
35
+ getRendererDOMHost().updateElementFromVnode(dom, nextVNode, false);
36
+ const nextChildren = getStableIntrinsicChildren(nextVNode);
37
+ if (dom.childNodes.length !== nextChildren.length) return false;
38
+ for (let index = 0; index < nextChildren.length; index += 1) {
39
+ const nextChild = nextChildren[index];
40
+ const currentChildNode = dom.childNodes[index];
41
+ if (!currentChildNode) return false;
42
+ if (patchStableIntrinsicText(currentChildNode, nextChild)) continue;
43
+ if (currentChildNode instanceof Element && _isDOMElement(nextChild) && typeof nextChild.type === "string" && patchStableIntrinsicElement(currentChildNode, nextChild)) continue;
44
+ return false;
45
+ }
46
+ return true;
47
+ }
48
+ function resolveStableIntrinsicPatchVNode(dom, vnode) {
49
+ if (!_isDOMElement(vnode)) return null;
50
+ if (typeof vnode.type === "string") return tagNamesEqualIgnoreCase(dom.tagName, vnode.type) ? vnode : null;
51
+ if (typeof vnode.type !== "function") return null;
52
+ const host = dom;
53
+ const existingInstance = findHostInstanceByType(host, vnode.type);
54
+ if (!existingInstance || existingInstance.fn !== vnode.type || host.__ASKR_WRAPPER_HOST) return null;
55
+ const snapshot = getVNodeContextFrame(vnode) || getCurrentContextFrame() || existingInstance.ownerFrame || null;
56
+ captureInlineRenderSnapshot(existingInstance);
57
+ existingInstance.props = (vnode.props ?? {}) || {};
58
+ existingInstance.isRoot = isRouteRootComponentVNode(vnode);
59
+ existingInstance.portalScope = getCurrentInstance()?.portalScope ?? existingInstance.portalScope;
60
+ inheritComponentCleanupStrict(existingInstance);
61
+ if (snapshot) existingInstance.ownerFrame = snapshot;
62
+ const result = withContext(snapshot, () => renderComponentInline(existingInstance));
63
+ if (isPromiseLike(result)) throw new Error("Async components are not supported. Components must return synchronously.");
64
+ const resolvedResult = resolveNestedComponentResult(result, snapshot ?? null, existingInstance);
65
+ if (_isDOMElement(resolvedResult) && typeof resolvedResult.type === "string" && tagNamesEqualIgnoreCase(dom.tagName, resolvedResult.type)) return inheritComponentKey(resolvedResult, vnode);
66
+ return null;
67
+ }
68
+ function tryPatchStableForDirtyItem(scope) {
69
+ incDevCounter("stableForPatchAttempt");
70
+ if (!(scope.dom instanceof Element) || scope.vnode === void 0) return false;
71
+ const nextIntrinsic = resolveStableIntrinsicPatchVNode(scope.dom, scope.vnode);
72
+ if (!nextIntrinsic) return false;
73
+ const didPatch = patchStableIntrinsicElement(scope.dom, nextIntrinsic);
74
+ const existingInstance = scope.dom.__ASKR_INSTANCE;
75
+ if (didPatch && existingInstance) warnUnusedStateReads(existingInstance);
76
+ if (didPatch) incDevCounter("stableForPatchHit");
77
+ return didPatch;
78
+ }
79
+ //#endregion
80
+ export { tryPatchStableForDirtyItem };
81
+
82
+ //# sourceMappingURL=stable-patch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stable-patch.js","names":[],"sources":["../../src/renderer/stable-patch.ts"],"sourcesContent":["import { isPromiseLike } from '../common/promise';\nimport {\n captureInlineRenderSnapshot,\n getCurrentInstance,\n renderComponentInline,\n warnUnusedStateReads,\n type ComponentFunction,\n} from '../runtime/component-contracts';\nimport {\n getCurrentContextFrame,\n getVNodeContextFrame,\n withContext,\n} from '../runtime/context';\nimport { incDevCounter } from '../runtime/dev-namespace';\nimport { recordBenchEvent } from '../runtime/for';\nimport {\n findHostInstanceByType,\n inheritComponentCleanupStrict,\n inheritComponentKey,\n isRouteRootComponentVNode,\n resolveNestedComponentResult,\n} from './component-host';\nimport { getRendererDOMHost, type InstanceHostElement } from './dom-host';\nimport { _isDOMElement, type DOMElement, type VNode } from './types';\nimport { tagNamesEqualIgnoreCase } from './utils';\n\nfunction normalizeStableIntrinsicChildren(\n children: VNode | VNode[] | undefined\n): VNode[] {\n if (children === null || children === undefined || children === false) {\n return [];\n }\n\n return Array.isArray(children) ? children : [children];\n}\n\nfunction getStableIntrinsicChildren(vnode: DOMElement): VNode[] {\n return normalizeStableIntrinsicChildren(\n (vnode.props?.children as VNode | VNode[] | undefined) ?? vnode.children\n );\n}\n\nfunction patchStableIntrinsicText(domNode: Node, nextVNode: VNode): boolean {\n if (\n domNode.nodeType !== 3 ||\n (typeof nextVNode !== 'string' && typeof nextVNode !== 'number')\n ) {\n return false;\n }\n\n const nextText = String(nextVNode);\n const textNode = domNode as Text;\n if (textNode.data !== nextText) {\n recordBenchEvent('domTextSet');\n textNode.data = nextText;\n }\n\n return true;\n}\n\nfunction patchStableIntrinsicElement(\n dom: Element,\n nextVNode: DOMElement\n): boolean {\n if (\n typeof nextVNode.type !== 'string' ||\n !tagNamesEqualIgnoreCase(dom.tagName, nextVNode.type)\n ) {\n return false;\n }\n\n getRendererDOMHost().updateElementFromVnode(dom, nextVNode, false);\n\n const nextChildren = getStableIntrinsicChildren(nextVNode);\n if (dom.childNodes.length !== nextChildren.length) {\n return false;\n }\n\n for (let index = 0; index < nextChildren.length; index += 1) {\n const nextChild = nextChildren[index];\n\n const currentChildNode = dom.childNodes[index];\n if (!currentChildNode) {\n return false;\n }\n\n if (patchStableIntrinsicText(currentChildNode, nextChild)) {\n continue;\n }\n\n if (\n currentChildNode instanceof Element &&\n _isDOMElement(nextChild) &&\n typeof nextChild.type === 'string' &&\n patchStableIntrinsicElement(currentChildNode, nextChild)\n ) {\n continue;\n }\n\n return false;\n }\n\n return true;\n}\n\nfunction resolveStableIntrinsicPatchVNode(\n dom: Element,\n vnode: VNode\n): DOMElement | null {\n if (!_isDOMElement(vnode)) {\n return null;\n }\n\n if (typeof vnode.type === 'string') {\n return tagNamesEqualIgnoreCase(dom.tagName, vnode.type) ? vnode : null;\n }\n\n if (typeof vnode.type !== 'function') {\n return null;\n }\n\n const host = dom as InstanceHostElement;\n const existingInstance = findHostInstanceByType(\n host,\n vnode.type as ComponentFunction\n );\n if (\n !existingInstance ||\n existingInstance.fn !== vnode.type ||\n host.__ASKR_WRAPPER_HOST\n ) {\n return null;\n }\n\n const snapshot =\n getVNodeContextFrame(vnode) ||\n getCurrentContextFrame() ||\n existingInstance.ownerFrame ||\n null;\n\n captureInlineRenderSnapshot(existingInstance);\n\n existingInstance.props =\n (((vnode as DOMElement).props ?? {}) as Record<string, unknown>) || {};\n existingInstance.isRoot = isRouteRootComponentVNode(vnode);\n existingInstance.portalScope =\n getCurrentInstance()?.portalScope ?? existingInstance.portalScope;\n inheritComponentCleanupStrict(existingInstance);\n\n if (snapshot) {\n existingInstance.ownerFrame = snapshot;\n }\n\n const result = withContext(snapshot, () =>\n renderComponentInline(existingInstance)\n );\n if (isPromiseLike(result)) {\n throw new Error(\n 'Async components are not supported. Components must return synchronously.'\n );\n }\n\n const resolvedResult = resolveNestedComponentResult(\n result,\n snapshot ?? null,\n existingInstance\n );\n if (\n _isDOMElement(resolvedResult) &&\n typeof resolvedResult.type === 'string' &&\n tagNamesEqualIgnoreCase(dom.tagName, resolvedResult.type)\n ) {\n return inheritComponentKey(resolvedResult, vnode as DOMElement);\n }\n\n return null;\n}\n\nexport function tryPatchStableForDirtyItem(scope: {\n dom?: Node;\n vnode?: VNode;\n}): boolean {\n incDevCounter('stableForPatchAttempt');\n if (!(scope.dom instanceof Element) || scope.vnode === undefined) {\n return false;\n }\n\n const nextIntrinsic = resolveStableIntrinsicPatchVNode(\n scope.dom,\n scope.vnode\n );\n if (!nextIntrinsic) {\n return false;\n }\n\n const didPatch = patchStableIntrinsicElement(scope.dom, nextIntrinsic);\n\n const existingInstance = (scope.dom as InstanceHostElement).__ASKR_INSTANCE;\n if (didPatch && existingInstance) {\n warnUnusedStateReads(existingInstance);\n }\n\n if (didPatch) {\n incDevCounter('stableForPatchHit');\n }\n\n return didPatch;\n}\n"],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import { _isDOMElement } from "../common/vnode.js";
2
+ import "./types.js";
3
+ import { Fragment } from "../common/jsx.js";
4
+ import { tagNamesEqualIgnoreCase } from "./utils.js";
5
+ import "../jsx-runtime.js";
6
+ import { hasMatchingStaticProps } from "./attributes.js";
7
+ //#region src/renderer/static-reuse.ts
8
+ /**
9
+ * Static subtree reuse checks for intrinsic DOM children.
10
+ */
11
+ function isFragmentVNode(node) {
12
+ return _isDOMElement(node) && typeof node.type === "symbol" && (node.type === Fragment || String(node.type) === "Symbol(askr.fragment)");
13
+ }
14
+ function upperCommonTagName(tag) {
15
+ switch (tag) {
16
+ case "div": return "DIV";
17
+ case "span": return "SPAN";
18
+ case "p": return "P";
19
+ case "a": return "A";
20
+ case "button": return "BUTTON";
21
+ case "input": return "INPUT";
22
+ case "ul": return "UL";
23
+ case "ol": return "OL";
24
+ case "li": return "LI";
25
+ default: return null;
26
+ }
27
+ }
28
+ function tagsEqualIgnoreCase(elementTagName, vnodeType) {
29
+ const upperCommon = upperCommonTagName(vnodeType);
30
+ if (upperCommon !== null && elementTagName === upperCommon) return true;
31
+ return tagNamesEqualIgnoreCase(elementTagName, vnodeType);
32
+ }
33
+ const STATIC_CHILD_SLOTS_CACHE = Symbol.for("__askrStaticChildSlots");
34
+ let staticChildSlotsCacheEnabled = true;
35
+ function setStaticChildSlotsCacheEnabled(enabled) {
36
+ staticChildSlotsCacheEnabled = enabled;
37
+ }
38
+ function collectStaticChildSlots(children, slots) {
39
+ if (isFragmentVNode(children)) return collectStaticChildSlots(children.props?.children ?? children.children, slots);
40
+ if (Array.isArray(children)) {
41
+ for (const child of children) if (!collectStaticChildSlots(child, slots)) return false;
42
+ return true;
43
+ }
44
+ if (children === null || children === void 0 || children === false) return true;
45
+ if (typeof children === "string" || typeof children === "number") {
46
+ slots.push({
47
+ kind: "text",
48
+ value: String(children)
49
+ });
50
+ return true;
51
+ }
52
+ if (_isDOMElement(children) && typeof children.type === "string") {
53
+ slots.push({
54
+ kind: "element",
55
+ value: children
56
+ });
57
+ return true;
58
+ }
59
+ return false;
60
+ }
61
+ function getStaticChildSlots(vnode) {
62
+ if (staticChildSlotsCacheEnabled) {
63
+ const cached = vnode[STATIC_CHILD_SLOTS_CACHE];
64
+ if (cached !== void 0) return cached;
65
+ }
66
+ const slots = [];
67
+ const staticSlots = collectStaticChildSlots(vnode.props?.children ?? vnode.children, slots) ? slots : null;
68
+ if (staticChildSlotsCacheEnabled) {
69
+ const cacheNode = vnode;
70
+ if (Object.isExtensible(vnode)) cacheNode[STATIC_CHILD_SLOTS_CACHE] = staticSlots;
71
+ }
72
+ return staticSlots;
73
+ }
74
+ function canReuseStaticSubtree(el, vnode) {
75
+ if (typeof vnode.type !== "string" || !tagsEqualIgnoreCase(el.tagName, vnode.type)) return false;
76
+ if (!hasMatchingStaticProps(el, vnode.props || {}, vnode.type)) return false;
77
+ const slots = getStaticChildSlots(vnode);
78
+ if (!slots) return false;
79
+ if (el.childNodes.length !== slots.length) return false;
80
+ for (let index = 0; index < slots.length; index += 1) {
81
+ const slot = slots[index];
82
+ const current = el.childNodes[index];
83
+ if (!current) return false;
84
+ if (slot.kind === "text") {
85
+ if (current.nodeType !== 3 || current.data !== slot.value) return false;
86
+ continue;
87
+ }
88
+ if (!(current instanceof Element)) return false;
89
+ if (!canReuseStaticSubtree(current, slot.value)) return false;
90
+ }
91
+ return true;
92
+ }
93
+ //#endregion
94
+ export { canReuseStaticSubtree, setStaticChildSlotsCacheEnabled, tagsEqualIgnoreCase };
95
+
96
+ //# sourceMappingURL=static-reuse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-reuse.js","names":[],"sources":["../../src/renderer/static-reuse.ts"],"sourcesContent":["/**\n * Static subtree reuse checks for intrinsic DOM children.\n */\n\nimport { Fragment } from '../jsx/jsx-runtime';\nimport { hasMatchingStaticProps } from './attributes';\nimport { _isDOMElement, type DOMElement } from './types';\nimport { tagNamesEqualIgnoreCase } from './utils';\n\nfunction isFragmentVNode(node: unknown): node is DOMElement {\n return (\n _isDOMElement(node) &&\n typeof (node as DOMElement).type === 'symbol' &&\n ((node as DOMElement).type === Fragment ||\n String((node as DOMElement).type) === 'Symbol(askr.fragment)')\n );\n}\n\nfunction upperCommonTagName(tag: string): string | null {\n switch (tag) {\n case 'div':\n return 'DIV';\n case 'span':\n return 'SPAN';\n case 'p':\n return 'P';\n case 'a':\n return 'A';\n case 'button':\n return 'BUTTON';\n case 'input':\n return 'INPUT';\n case 'ul':\n return 'UL';\n case 'ol':\n return 'OL';\n case 'li':\n return 'LI';\n default:\n return null;\n }\n}\n\nexport function tagsEqualIgnoreCase(\n elementTagName: string,\n vnodeType: string\n): boolean {\n const upperCommon = upperCommonTagName(vnodeType);\n if (upperCommon !== null && elementTagName === upperCommon) return true;\n return tagNamesEqualIgnoreCase(elementTagName, vnodeType);\n}\n\ntype StaticChildSlot =\n | { kind: 'text'; value: string }\n | { kind: 'element'; value: DOMElement };\n\nconst STATIC_CHILD_SLOTS_CACHE = Symbol.for('__askrStaticChildSlots');\nlet staticChildSlotsCacheEnabled = true;\n\ninterface StaticChildSlotsCacheNode {\n [STATIC_CHILD_SLOTS_CACHE]?: StaticChildSlot[] | null;\n}\n\nexport function setStaticChildSlotsCacheEnabled(enabled: boolean): void {\n staticChildSlotsCacheEnabled = enabled;\n}\n\nfunction collectStaticChildSlots(\n children: unknown,\n slots: StaticChildSlot[]\n): boolean {\n if (isFragmentVNode(children)) {\n const fragmentChildren = children.props?.children ?? children.children;\n return collectStaticChildSlots(fragmentChildren, slots);\n }\n\n if (Array.isArray(children)) {\n for (const child of children) {\n if (!collectStaticChildSlots(child, slots)) {\n return false;\n }\n }\n return true;\n }\n\n if (children === null || children === undefined || children === false) {\n return true;\n }\n\n if (typeof children === 'string' || typeof children === 'number') {\n slots.push({ kind: 'text', value: String(children) });\n return true;\n }\n\n if (\n _isDOMElement(children) &&\n typeof (children as DOMElement).type === 'string'\n ) {\n slots.push({ kind: 'element', value: children as DOMElement });\n return true;\n }\n\n return false;\n}\n\nfunction getStaticChildSlots(vnode: DOMElement): StaticChildSlot[] | null {\n if (staticChildSlotsCacheEnabled) {\n const cacheNode = vnode as DOMElement & StaticChildSlotsCacheNode;\n const cached = cacheNode[STATIC_CHILD_SLOTS_CACHE];\n if (cached !== undefined) {\n return cached;\n }\n }\n\n const slots: StaticChildSlot[] = [];\n const staticSlots = collectStaticChildSlots(\n (vnode.props?.children ?? vnode.children) as unknown,\n slots\n )\n ? slots\n : null;\n if (staticChildSlotsCacheEnabled) {\n const cacheNode = vnode as DOMElement & StaticChildSlotsCacheNode;\n if (Object.isExtensible(vnode)) {\n cacheNode[STATIC_CHILD_SLOTS_CACHE] = staticSlots;\n }\n }\n return staticSlots;\n}\n\nexport function canReuseStaticSubtree(el: Element, vnode: DOMElement): boolean {\n if (\n typeof vnode.type !== 'string' ||\n !tagsEqualIgnoreCase(el.tagName, vnode.type)\n ) {\n return false;\n }\n\n const props = (vnode.props || {}) as Record<string, unknown>;\n if (!hasMatchingStaticProps(el, props, vnode.type)) {\n return false;\n }\n\n const slots = getStaticChildSlots(vnode);\n if (!slots) {\n return false;\n }\n\n if (el.childNodes.length !== slots.length) {\n return false;\n }\n\n for (let index = 0; index < slots.length; index += 1) {\n const slot = slots[index];\n const current = el.childNodes[index];\n if (!current) {\n return false;\n }\n\n if (slot.kind === 'text') {\n if (current.nodeType !== 3 || (current as Text).data !== slot.value) {\n return false;\n }\n continue;\n }\n\n if (!(current instanceof Element)) {\n return false;\n }\n\n if (!canReuseStaticSubtree(current, slot.value)) {\n return false;\n }\n }\n\n return true;\n}\n"],"mappings":";;;;;;;;;;AASA,SAAS,gBAAgB,MAAmC;CAC1D,OACE,cAAc,IAAI,KAClB,OAAQ,KAAoB,SAAS,aACnC,KAAoB,SAAS,YAC7B,OAAQ,KAAoB,IAAI,MAAM;AAE5C;AAEA,SAAS,mBAAmB,KAA4B;CACtD,QAAQ,KAAR;EACE,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,KACH,OAAO;EACT,KAAK,KACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,SACE,OAAO;CACX;AACF;AAEA,SAAgB,oBACd,gBACA,WACS;CACT,MAAM,cAAc,mBAAmB,SAAS;CAChD,IAAI,gBAAgB,QAAQ,mBAAmB,aAAa,OAAO;CACnE,OAAO,wBAAwB,gBAAgB,SAAS;AAC1D;AAMA,MAAM,2BAA2B,OAAO,IAAI,wBAAwB;AACpE,IAAI,+BAA+B;AAMnC,SAAgB,gCAAgC,SAAwB;CACtE,+BAA+B;AACjC;AAEA,SAAS,wBACP,UACA,OACS;CACT,IAAI,gBAAgB,QAAQ,GAE1B,OAAO,wBADkB,SAAS,OAAO,YAAY,SAAS,UACb,KAAK;CAGxD,IAAI,MAAM,QAAQ,QAAQ,GAAG;EAC3B,KAAK,MAAM,SAAS,UAClB,IAAI,CAAC,wBAAwB,OAAO,KAAK,GACvC,OAAO;EAGX,OAAO;CACT;CAEA,IAAI,aAAa,QAAQ,aAAa,UAAa,aAAa,OAC9D,OAAO;CAGT,IAAI,OAAO,aAAa,YAAY,OAAO,aAAa,UAAU;EAChE,MAAM,KAAK;GAAE,MAAM;GAAQ,OAAO,OAAO,QAAQ;EAAE,CAAC;EACpD,OAAO;CACT;CAEA,IACE,cAAc,QAAQ,KACtB,OAAQ,SAAwB,SAAS,UACzC;EACA,MAAM,KAAK;GAAE,MAAM;GAAW,OAAO;EAAuB,CAAC;EAC7D,OAAO;CACT;CAEA,OAAO;AACT;AAEA,SAAS,oBAAoB,OAA6C;CACxE,IAAI,8BAA8B;EAEhC,MAAM,SAAS,MAAU;EACzB,IAAI,WAAW,QACb,OAAO;CAEX;CAEA,MAAM,QAA2B,CAAC;CAClC,MAAM,cAAc,wBACjB,MAAM,OAAO,YAAY,MAAM,UAChC,KACF,IACI,QACA;CACJ,IAAI,8BAA8B;EAChC,MAAM,YAAY;EAClB,IAAI,OAAO,aAAa,KAAK,GAC3B,UAAU,4BAA4B;CAE1C;CACA,OAAO;AACT;AAEA,SAAgB,sBAAsB,IAAa,OAA4B;CAC7E,IACE,OAAO,MAAM,SAAS,YACtB,CAAC,oBAAoB,GAAG,SAAS,MAAM,IAAI,GAE3C,OAAO;CAIT,IAAI,CAAC,uBAAuB,IADb,MAAM,SAAS,CAAC,GACQ,MAAM,IAAI,GAC/C,OAAO;CAGT,MAAM,QAAQ,oBAAoB,KAAK;CACvC,IAAI,CAAC,OACH,OAAO;CAGT,IAAI,GAAG,WAAW,WAAW,MAAM,QACjC,OAAO;CAGT,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;EACpD,MAAM,OAAO,MAAM;EACnB,MAAM,UAAU,GAAG,WAAW;EAC9B,IAAI,CAAC,SACH,OAAO;EAGT,IAAI,KAAK,SAAS,QAAQ;GACxB,IAAI,QAAQ,aAAa,KAAM,QAAiB,SAAS,KAAK,OAC5D,OAAO;GAET;EACF;EAEA,IAAI,EAAE,mBAAmB,UACvB,OAAO;EAGT,IAAI,CAAC,sBAAsB,SAAS,KAAK,KAAK,GAC5C,OAAO;CAEX;CAEA,OAAO;AACT"}
@@ -1 +1,2 @@
1
- import "../common/vnode.js";
1
+ import { _isDOMElement } from "../common/vnode.js";
2
+ export { _isDOMElement };
@@ -1,6 +1,6 @@
1
1
  import { getRuntimeEnv } from "../common/env.js";
2
2
  import { logger } from "../dev/logger.js";
3
- import { globalScheduler } from "../runtime/scheduler.js";
3
+ import { runRuntimeHandlerScope } from "../runtime/access.js";
4
4
  import { incDevCounter, setDevValue } from "../runtime/dev-namespace.js";
5
5
  import { getPublicAttributeName } from "../common/attr-names.js";
6
6
  import "./env.js";
@@ -61,7 +61,7 @@ function createWrappedHandler(handler, flushAfter = false) {
61
61
  }
62
62
  const wrapped = (event) => {
63
63
  try {
64
- globalScheduler.runInHandlerScope(() => {
64
+ runRuntimeHandlerScope(() => {
65
65
  try {
66
66
  handler(event);
67
67
  } catch (error) {
@@ -88,7 +88,7 @@ function createMutableWrappedHandler(handler, flushAfter = false) {
88
88
  let currentHandler = handler;
89
89
  const wrapped = (event) => {
90
90
  try {
91
- globalScheduler.runInHandlerScope(() => {
91
+ runRuntimeHandlerScope(() => {
92
92
  try {
93
93
  currentHandler(event);
94
94
  } catch (error) {
@@ -250,6 +250,6 @@ function now() {
250
250
  return typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
251
251
  }
252
252
  //#endregion
253
- export { buildKeyMapFromChildren, canUseDirectReplaceChildrenSpread, checkPropChanges, createMutableWrappedHandler, createWrappedHandler, extractKey, getEventListenerKey, getEventListenerOptions, getRenderedAttributeName, hasNonTrivialProps, hasPropChanged, isIgnoredForPropChanges, isSkippedProp, logFastPathDebug, now, parseEventName, parseEventProp, readElementClassName, recordDOMReplace, recordFastPathStats, removeRenderedAttribute, setRenderedAttribute, tagNamesEqualIgnoreCase, writeElementClassName };
253
+ export { DIRECT_REPLACE_CHILDREN_SPREAD_LIMIT, buildKeyMapFromChildren, canUseDirectReplaceChildrenSpread, checkPropChanges, createMutableWrappedHandler, createWrappedHandler, extractKey, getEventListenerKey, getEventListenerOptions, getPassiveOptions, getRenderedAttributeName, hasNonTrivialProps, hasPropChanged, isIgnoredForPropChanges, isSVGDomElement, isSkippedProp, logFastPathDebug, now, parseEventName, parseEventProp, readElementClassName, recordDOMReplace, recordFastPathStats, removeRenderedAttribute, setRenderedAttribute, tagNamesEqualIgnoreCase, writeElementClassName };
254
254
 
255
255
  //# sourceMappingURL=utils.js.map