what-core 0.13.4 → 0.13.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/render.js CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { effect, untrack, _createItemScope, signal, memo, __DEV__ } from './reactive.js';
6
6
  import { __resetIdCounter } from './a11y.js';
7
- import { createDOM, disposeTree, getComponentStack, addHydrationDisposer, addHydratedComponent, _setSelectValue, _isUnsafeAttr, _isEventProp, _installLazyChildren, _handleNavigationSignal } from './dom.js';
7
+ import { createDOM, disposeTree, getComponentStack, addHydrationDisposer, addHydratedComponent, _liveRegionNodes, _setSelectValue, _isUnsafeAttr, _isEventProp, _installLazyChildren, _handleNavigationSignal } from './dom.js';
8
8
  import { _injectIslandRuntime, reportError } from './components.js';
9
9
  export { effect, untrack };
10
10
  // Re-export memo for compiled output (branch memoization: the compiler emits
@@ -17,45 +17,70 @@ export { memo };
17
17
  // _setTextInsertHook(). When null (default), zero cost — no module loaded,
18
18
  // no branch taken. The hook receives (parentElement, textString) on every
19
19
  // dynamic text insertion and update.
20
+ /** @type {((parent: any, text: string) => void) | null} */
20
21
  let _onTextInsert = null;
21
22
 
22
23
  export function _setTextInsertHook(fn) {
23
24
  _onTextInsert = typeof fn === 'function' ? fn : null;
24
25
  }
25
26
 
26
- // --- _$createComponent(Component, props, children) ---
27
- // Internal compiler target for component instantiation. The compiler emits calls
28
- // to this function instead of h() — keeping h() out of compiled output entirely.
29
- // Merges children into props and delegates to createDOM which calls createComponent.
27
+ // --- _$componentVNode(Component, props, children) ---
28
+ // The VNode half of _$createComponent: same argument protocol, stopping one step
29
+ // short of building anything.
30
+ //
31
+ // It exists because hydrate() needs an UNBUILT tree and compiled JSX had no way
32
+ // to spell one. A built node cannot adopt the server's markup — its bindings are
33
+ // already wired to itself — so hydrateNode can only insert it and let the trim
34
+ // delete what the server sent (see the isDomNode branch, and the warning above
35
+ // it). `hydrate(<App />)`, the documented client entry, lowered to
36
+ // _$createComponent and therefore threw the whole server render away on every
37
+ // load. The compiler now emits this instead for the JSX handed straight to
38
+ // hydrate(), and hydrateNode's component branch walks the result against the
39
+ // server's DOM the same way it walks an h() tree.
40
+ //
41
+ // Only the hydrate root uses this. Everywhere else the built form is what the
42
+ // caller asked for, and returning a VNode there would hand _$insert and the
43
+ // element setup a shape they do not expect.
30
44
 
31
- export function _$createComponent(Component, props, children) {
45
+ export function _$componentVNode(Component, props, children) {
32
46
  // Deferred children (compiled JSX): the compiler passes a zero-arg factory
33
47
  // when children contain elements, so their DOM is not built before this
34
48
  // component runs. Pass it along marked; createComponent decides how the
35
49
  // component sees it. h() and the JSX runtime pass arrays and take the path
36
- // below unchanged.
50
+ // below unchanged. hydrateNode reads the same _$lazyChildren marker, so the
51
+ // protocol survives the unbuilt route intact.
37
52
  if (typeof children === 'function') {
38
53
  const lazy = () => {
39
54
  const kids = children();
40
55
  return kids.length === 1 ? kids[0] : kids;
41
56
  };
42
57
  lazy._lazyChildren = true;
43
- if (!props) props = {};
58
+ // Copy first. The lazy marker is an expando, and `props` may be a
59
+ // user-owned object (a lone JSX spread, or a hand-written call).
60
+ props = props ? Object.assign({}, props) : {};
44
61
  Object.defineProperty(props, '_$lazyChildren', { value: lazy, configurable: true });
45
- return createDOM({ tag: Component, props, children: [], key: null, _vnode: true });
62
+ return { tag: Component, props, children: [], key: null, _vnode: true };
46
63
  }
47
64
  if (children && children.length > 0) {
48
65
  const mergedChildren = children.length === 1 ? children[0] : children;
49
- // Mutate props in place when possible to avoid object spread allocation.
50
- // Compiled output creates a fresh props object per call, so mutation is safe.
51
- if (props) {
52
- props.children = mergedChildren;
53
- } else {
54
- props = { children: mergedChildren };
55
- }
56
- }
57
- // Build a VNode-like object and pass to createDOM which handles component execution
58
- return createDOM({ tag: Component, props: props || {}, children: children || [], key: null, _vnode: true });
66
+ // Never write onto the object we were handed. A lone spread is the
67
+ // caller's value; writing `children` onto it leaks into the next call
68
+ // that reuses the same object and permanently corrupts user state.
69
+ // Object.assign copies accessor VALUES without invoking them.
70
+ props = props
71
+ ? Object.assign({}, props, { children: mergedChildren })
72
+ : { children: mergedChildren };
73
+ }
74
+ return { tag: Component, props: props || {}, children: children || [], key: null, _vnode: true };
75
+ }
76
+
77
+ // --- _$createComponent(Component, props, children) ---
78
+ // Internal compiler target for component instantiation. The compiler emits calls
79
+ // to this function instead of h() — keeping h() out of compiled output entirely.
80
+ // Merges children into props and delegates to createDOM which calls createComponent.
81
+
82
+ export function _$createComponent(Component, props, children) {
83
+ return createDOM(_$componentVNode(Component, props, children));
59
84
  }
60
85
 
61
86
  // --- template(html) ---
@@ -189,6 +214,41 @@ export function svgTemplate(html) {
189
214
  return () => /** @type {Node} */ (/** @type {Node} */ (t.content.firstChild).firstChild).cloneNode(true);
190
215
  }
191
216
 
217
+ // --- anchorDispose(anchor, dispose) ---
218
+ //
219
+ // Hang a reactive region's disposer on a DOM node so disposeTree can find it.
220
+ // Teardown starts from the DOM: disposeTree walks a removed subtree and calls
221
+ // `_dispose` on every node carrying one. A disposer that lives only in a closure
222
+ // is unreachable, and the effect behind it runs for the life of the page.
223
+ //
224
+ // The h() path in dom.js already does this with the comment markers it creates.
225
+ // insert() did not, so every region the COMPILER emits leaked: each toggle of a
226
+ // conditional stranded one more live effect, and mount()'s own disposer could
227
+ // not stop any of them.
228
+ //
229
+ // The anchor is the region's end marker (the compiler's `<!--$-->` hole) when
230
+ // there is one, because it is the only node that lives exactly as long as the
231
+ // region: the content around it is replaced on every update. Registering with
232
+ // the owning component instead would miss the case that actually leaks, a region
233
+ // switched off while its owner stays mounted. With no marker the region owns the
234
+ // tail of `parent`, so `parent` is the nearest stable anchor there is.
235
+ function anchorDispose(anchor, dispose) {
236
+ if (!anchor) return;
237
+ // A node can be reached by more than one teardown route, and every extra call
238
+ // reports another effect disposal to devtools. Same guard as the hydration
239
+ // region's, for the same reason.
240
+ let disposed = false;
241
+ const disposeOnce = () => {
242
+ if (disposed) return;
243
+ disposed = true;
244
+ dispose();
245
+ };
246
+ // Only the markerless form can collide: two regions appended to the same
247
+ // parent have nothing but the parent to share.
248
+ const previous = anchor._dispose;
249
+ anchor._dispose = previous ? () => { previous(); disposeOnce(); } : disposeOnce;
250
+ }
251
+
192
252
  // --- insert(parent, child, marker?) ---
193
253
  // Reactive child insertion. Handles all child types:
194
254
  // - string/number → text node
@@ -216,7 +276,9 @@ export function insert(parent, child, marker) {
216
276
  // effect's first run re-evaluated child() — creating components twice
217
277
  // on mount for non-text children. (SPRINT v0.11 C3)
218
278
  const m = marker || null;
279
+ /** @type {any} */
219
280
  let current = null;
281
+ /** @type {Text | null} */
220
282
  let textNode = null; // non-null while on the text fast path
221
283
  let mounted = false;
222
284
  // Capture the owning component at CREATION time. See the identical capture
@@ -232,7 +294,7 @@ export function insert(parent, child, marker) {
232
294
  // every `{() => ...}`, was not. So it was broken for exactly the users on
233
295
  // the recommended build setup.
234
296
  const owner = captureOwner();
235
- effect(() => withOwner(owner, () => {
297
+ const dispose = effect(() => withOwner(owner, () => {
236
298
  const val = child();
237
299
  const vt = typeof val;
238
300
  if (!mounted) {
@@ -260,6 +322,7 @@ export function insert(parent, child, marker) {
260
322
  textNode = null;
261
323
  current = reconcileInsert(parent, val, current, m);
262
324
  }));
325
+ anchorDispose(m || parent, dispose);
263
326
  return current;
264
327
  }
265
328
 
@@ -438,7 +501,7 @@ function reconcileInsert(parent, value, current, marker) {
438
501
  const targetMarker = marker || null;
439
502
 
440
503
  if (value == null || typeof value === 'boolean') {
441
- const oldNodes = asNodeArray(current);
504
+ const oldNodes = _liveRegionNodes(asNodeArray(current));
442
505
  for (let i = 0; i < oldNodes.length; i++) {
443
506
  const oldNode = oldNodes[i];
444
507
  if (oldNode.parentNode === parent) {
@@ -491,9 +554,14 @@ function reconcileInsert(parent, value, current, marker) {
491
554
 
492
555
  // Remove old nodes not in the new set. For small arrays (typical case),
493
556
  // linear scan is faster than Set allocation + hashing.
557
+ //
558
+ // The removal set is the LIVE one: an embedded list has been editing its own
559
+ // rows since this region recorded them, and the rows it added late are just as
560
+ // much this region's to remove as the ones it saw at mount.
561
+ const staleNodes = _liveRegionNodes(oldNodes);
494
562
  const newLen = newNodes.length;
495
- for (let i = 0; i < oldNodes.length; i++) {
496
- const oldNode = oldNodes[i];
563
+ for (let i = 0; i < staleNodes.length; i++) {
564
+ const oldNode = staleNodes[i];
497
565
  if (oldNode.parentNode !== parent) continue;
498
566
  let found = false;
499
567
  for (let j = 0; j < newLen; j++) {
@@ -544,7 +612,7 @@ export function mapArray(source, mapFn, options) {
544
612
  const endMarker = document.createComment('/list');
545
613
  parent.insertBefore(endMarker, marker || null);
546
614
 
547
- effect(() => {
615
+ const dispose = effect(() => {
548
616
  const newItems = source() || [];
549
617
  // Resolve the LIVE parent from the end marker each run. When this inserter
550
618
  // is mounted at a fragment-as-root (`<>{items().map(...)}</>`), createDOM
@@ -563,6 +631,19 @@ export function mapArray(source, mapFn, options) {
563
631
  items = newItems.length > 0 ? newItems.slice() : newItems;
564
632
  });
565
633
 
634
+ // Same anchoring as insert(), and needed for the same reason: the list's own
635
+ // effect and its per-item scopes were only ever released by a reconcile, so a
636
+ // list that was removed WHOLESALE (a compiled `<For>` inside a branch that
637
+ // switched off) kept diffing an invisible list and kept every row's effects
638
+ // alive. The rows' own markers are disposed by the walk before it reaches
639
+ // this marker; the item scopes hold their onCleanup callbacks, so they are
640
+ // released here.
641
+ anchorDispose(endMarker, () => {
642
+ dispose();
643
+ for (let i = 0; i < disposeFns.length; i++) disposeFns[i]?.();
644
+ disposeFns.length = 0;
645
+ });
646
+
566
647
  return endMarker;
567
648
  };
568
649
  inserter._mapArray = true;
@@ -1687,7 +1768,8 @@ export function classList(el, classes) {
1687
1768
  // After hydration is complete, switches to normal rendering for updates.
1688
1769
 
1689
1770
  let _isHydrating = false;
1690
- let _hydrationCursor = null;
1771
+ /** @type {WhatHydrationCursor} */
1772
+ let _hydrationCursor = /** @type {any} */ (null);
1691
1773
 
1692
1774
  export function isHydrating() {
1693
1775
  return _isHydrating;
@@ -1700,6 +1782,7 @@ export function isHydrating() {
1700
1782
  */
1701
1783
  export function hydrate(vnode, container) {
1702
1784
  _isHydrating = true;
1785
+ _warnedAlreadyBuilt = false;
1703
1786
  // Restart the useId sequence so the client reproduces the server's ids rather
1704
1787
  // than continuing past them. The server allocates from a render-scoped counter
1705
1788
  // starting at 1; without this reset any client-side useId call made before
@@ -1722,7 +1805,7 @@ export function hydrate(vnode, container) {
1722
1805
  return result;
1723
1806
  } finally {
1724
1807
  _isHydrating = false;
1725
- _hydrationCursor = null;
1808
+ _hydrationCursor = /** @type {any} */ (null);
1726
1809
  }
1727
1810
  }
1728
1811
 
@@ -1832,9 +1915,14 @@ function peekNode(parent) {
1832
1915
  * once and then ignored the signal forever.
1833
1916
  */
1834
1917
  function insertAtCursor(parent, node) {
1918
+ // A fragment contributes its CHILDREN, not itself, so the cursor has to step
1919
+ // over however many nodes actually landed. Advancing by one would leave the
1920
+ // rest of them in front of the cursor, where trimUnclaimed reads them as
1921
+ // stranded server markup and deletes what was just inserted.
1922
+ const landed = node.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */ ? node.childNodes.length : 1;
1835
1923
  if (_hydrationCursor && _hydrationCursor.parent === parent) {
1836
1924
  parent.insertBefore(node, parent.childNodes[_hydrationCursor.index] || null);
1837
- _hydrationCursor.index++;
1925
+ _hydrationCursor.index += landed;
1838
1926
  } else {
1839
1927
  parent.appendChild(node);
1840
1928
  }
@@ -1852,6 +1940,33 @@ function isDevMode() {
1852
1940
  return __DEV__;
1853
1941
  }
1854
1942
 
1943
+ // One warning per hydrate() call, not one per node. A compiled tree reaches the
1944
+ // already-built branch for every element in it, and a hundred copies of the same
1945
+ // message buries the one thing the developer needs to read.
1946
+ //
1947
+ // The warning stays even though the compiler no longer causes it. It named one
1948
+ // cause and prescribed one cure, and both have changed: what-compiler now lowers
1949
+ // the JSX inside a hydrate() call to _$componentVNode, which is unbuilt. What is
1950
+ // left are the cases nothing can lower for the caller, and they are the ones a
1951
+ // developer has no other way to notice, because a client render of the same tree
1952
+ // produces identical markup.
1953
+ let _warnedAlreadyBuilt = false;
1954
+
1955
+ function warnAlreadyBuilt() {
1956
+ if (!isDevMode() || _warnedAlreadyBuilt) return;
1957
+ _warnedAlreadyBuilt = true;
1958
+ console.warn(
1959
+ '[what] hydrate() was given DOM that is already built, so the server\'s markup is being ' +
1960
+ 'REPLACED by a client render rather than adopted. Hydration needs an unbuilt vnode tree, ' +
1961
+ 'which is what h() returns. what-compiler emits the unbuilt form for JSX written directly ' +
1962
+ 'inside a hydrate() call, so the remaining causes are: a tree built before the call ' +
1963
+ '(`const tree = <App />; hydrate(tree, el)`), a component whose own body what-compiler ' +
1964
+ 'lowered (it returns a template clone, which is finished DOM, and cannot be rendered by ' +
1965
+ 'renderToString either), or a DOM node passed in by hand. The page below is correct and ' +
1966
+ 'interactive; only the reuse is lost.'
1967
+ );
1968
+ }
1969
+
1855
1970
  function hydrateNode(vnode, parent) {
1856
1971
  if (vnode == null || typeof vnode === 'boolean') {
1857
1972
  return null;
@@ -1952,7 +2067,19 @@ function hydrateNode(vnode, parent) {
1952
2067
  if (typeof vnode === 'function' && vnode._mapArray) {
1953
2068
  const cursorInParent = !!(_hydrationCursor && _hydrationCursor.parent === parent);
1954
2069
  const anchor = cursorInParent ? (parent.childNodes[_hydrationCursor.index] || null) : null;
2070
+ // Open the list with the same start marker the client path uses (createDOM
2071
+ // in dom.js), and for the same reason. A region that embeds this list owns
2072
+ // whatever sits between its own markers AT HYDRATION, and the list goes on
2073
+ // adding rows afterwards. Without a bracket to walk, switching the region
2074
+ // off removed the rows hydration had seen and stranded every later one; with
2075
+ // it, _liveRegionNodes sweeps the list as it stands. The list already
2076
+ // inserts an end marker the server never sent, so this is the same trade
2077
+ // already being made, one node further left.
2078
+ const startMarker = document.createComment('list');
2079
+ parent.insertBefore(startMarker, anchor);
2080
+ if (cursorInParent) _hydrationCursor.index++;
1955
2081
  const endMarker = vnode(parent, anchor);
2082
+ /** @type {any} */ (startMarker)._rangeEnd = endMarker;
1956
2083
  if (cursorInParent) {
1957
2084
  const index = Array.prototype.indexOf.call(parent.childNodes, endMarker);
1958
2085
  if (index >= 0) _hydrationCursor.index = index + 1;
@@ -2069,6 +2196,10 @@ function hydrateNode(vnode, parent) {
2069
2196
  startMarker._dispose = disposeOnce;
2070
2197
  endMarker._dispose = disposeOnce;
2071
2198
  addHydrationDisposer(startMarker, disposeOnce);
2199
+ // Pair the markers for an OUTER region's teardown, exactly as the client
2200
+ // path does: this region replaces everything between them on every re-run,
2201
+ // so a list of nodes taken from it goes stale the moment it does.
2202
+ /** @type {any} */ (startMarker)._rangeEnd = endMarker;
2072
2203
  return current;
2073
2204
  }
2074
2205
 
@@ -2108,6 +2239,7 @@ function hydrateNode(vnode, parent) {
2108
2239
  componentStack.push(ctx);
2109
2240
 
2110
2241
  let result;
2242
+ /** @type {(() => void) | null} */
2111
2243
  let endChildrenPass = null;
2112
2244
  try {
2113
2245
  // Same children protocol as createComponent: compiled JSX passes a
@@ -2273,6 +2405,19 @@ function hydrateNode(vnode, parent) {
2273
2405
  // Match! Reuse this element. Apply props/bindings.
2274
2406
  hydrateElementProps(existing, vnode.props || {});
2275
2407
 
2408
+ // The server's correlation marker has done its job: this element is
2409
+ // claimed. Nothing on the client ever reads data-hk (the prop loop only
2410
+ // skips it, and islands find themselves through data-island), so leaving
2411
+ // it behind means a hydrated page keeps an attribute a client-rendered
2412
+ // page never has, on every component root, forever.
2413
+ //
2414
+ // Stripping here rather than in a sweep over the container keeps the
2415
+ // scope honest: only elements this walk actually claimed lose the
2416
+ // marker. An element the client declares empty is left untouched below,
2417
+ // because an island fills its host from the server markup still inside
2418
+ // it and hydrates that markup later.
2419
+ existing.removeAttribute('data-hk');
2420
+
2276
2421
  // Hydrate children
2277
2422
  const savedCursor = _hydrationCursor;
2278
2423
  _hydrationCursor = { parent: existing, index: 0 };
@@ -2324,8 +2469,41 @@ function hydrateNode(vnode, parent) {
2324
2469
  return newEl;
2325
2470
  }
2326
2471
 
2327
- // DOM node use directly
2472
+ // Already-built DOM node: there is nothing left to hydrate.
2473
+ //
2474
+ // Compiled JSX used to make this the NATURAL spelling of a hydrate root, since
2475
+ // `hydrate(<App />)` lowered to `hydrate(_$createComponent(App, ...))`, which
2476
+ // had already run the component and built its DOM by the time hydrate() saw it.
2477
+ // That call site now lowers to _$componentVNode instead, but the branch still
2478
+ // has to hold: a compiled component BODY returns a template clone, and a caller
2479
+ // can always hand over a node built earlier or by hand.
2480
+ //
2481
+ // Returning the node without inserting it claimed nothing, so the walk
2482
+ // finished with the cursor still at zero and trimUnclaimed deleted every
2483
+ // server child: a blank page, an inert button, and not one warning.
2484
+ //
2485
+ // The node cannot adopt the server's markup, because its bindings are already
2486
+ // wired to itself, so a client render is the honest outcome. Inserting it at
2487
+ // the cursor puts it ahead of the server's nodes and lets the walk's own trim
2488
+ // clear them. The page is then correct and interactive; what is lost is the
2489
+ // reuse, which is the entire point of hydrating, hence the warning.
2490
+ //
2491
+ // The one server node under the cursor is claimed and replaced rather than
2492
+ // merely displaced, because <body> is the one container trimUnclaimed refuses
2493
+ // to tidy (it also holds the scripts and the hydration payload). Without the
2494
+ // claim, a compiled root hydrated into <body> rendered correctly and left the
2495
+ // server's copy sitting underneath it, doubled.
2328
2496
  if (isDomNode(vnode)) {
2497
+ warnAlreadyBuilt();
2498
+ // Read the child count first: replaceChild empties a fragment.
2499
+ const landed = vnode.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */ ? vnode.childNodes.length : 1;
2500
+ const cursorInParent = !!(_hydrationCursor && _hydrationCursor.parent === parent);
2501
+ const existing = cursorInParent ? claimNode(parent) : null;
2502
+ if (!existing) return insertAtCursor(parent, vnode);
2503
+ parent.replaceChild(vnode, existing);
2504
+ // claimNode counted the one node it took; the rest of what landed in its
2505
+ // place still has to be stepped over, or the trim deletes it.
2506
+ _hydrationCursor.index += landed - 1;
2329
2507
  return vnode;
2330
2508
  }
2331
2509
 
package/src/scheduler.js CHANGED
@@ -169,6 +169,7 @@ export function raf(key, fn) {
169
169
  // Batched resize observations.
170
170
 
171
171
  const resizeObservers = new WeakMap();
172
+ /** @type {ResizeObserver | null} */
172
173
  let sharedResizeObserver = null;
173
174
 
174
175
  export function onResize(element, callback) {
@@ -191,12 +192,13 @@ export function onResize(element, callback) {
191
192
  });
192
193
  }
193
194
 
195
+ const observer = sharedResizeObserver;
194
196
  resizeObservers.set(element, callback);
195
- sharedResizeObserver.observe(element);
197
+ observer.observe(element);
196
198
 
197
199
  return () => {
198
200
  resizeObservers.delete(element);
199
- sharedResizeObserver.unobserve(element);
201
+ observer.unobserve(element);
200
202
  };
201
203
  }
202
204
 
@@ -12,7 +12,9 @@
12
12
  // getServerContext() returns null on the client and outside of any render, so
13
13
  // `typeof document === 'undefined'` guards keep behaving correctly.
14
14
 
15
+ /** @type {any} */
15
16
  let _current = null;
17
+ /** @type {{ getStore: () => any, run: (store: any, fn: () => any) => any } | null} */
16
18
  let _asyncContextStorage = null;
17
19
 
18
20
  /**
package/src/testing.js CHANGED
@@ -7,8 +7,35 @@ import { mount } from './dom.js';
7
7
  import { h } from './h.js';
8
8
 
9
9
  // Minimal DOM implementation for Node.js
10
+ /** @type {HTMLDivElement | null} */
10
11
  let container = null;
11
12
 
13
+ // Every tree render()/renderTest() mounted, so cleanup() can dispose it.
14
+ //
15
+ // mount() returns the only disposer a tree has, and render() dropped it on the
16
+ // floor. cleanup() then cleared innerHTML and detached the container, which
17
+ // removes NODES and touches not one effect: every page a suite mounted stayed
18
+ // live for the rest of the process, still answering signal writes and still
19
+ // running the intervals its onCleanup was supposed to clear. In a real suite
20
+ // that showed up as a file that never finished and a worker pinned at 140% CPU,
21
+ // which no per-test timeout can interrupt, and as tests that passed alone and
22
+ // timed out together. No app could fix it from outside, because the disposer
23
+ // render() threw away was the only handle that ever existed.
24
+ const mountedTrees = new Set();
25
+
26
+ // Idempotent and re-entrant: renderTest's own unmount() calls cleanup() at the
27
+ // end, so a disposer that is still in the set when cleanup() runs must not fire
28
+ // twice.
29
+ function trackMount(dispose) {
30
+ const unmount = () => {
31
+ if (!mountedTrees.has(unmount)) return;
32
+ mountedTrees.delete(unmount);
33
+ dispose();
34
+ };
35
+ mountedTrees.add(unmount);
36
+ return unmount;
37
+ }
38
+
12
39
  // --- Setup and Cleanup ---
13
40
 
14
41
  export function setupDOM() {
@@ -22,6 +49,9 @@ export function setupDOM() {
22
49
  }
23
50
 
24
51
  export function cleanup() {
52
+ for (const unmount of [...mountedTrees]) {
53
+ try { unmount(); } catch { /* already unmounted */ }
54
+ }
25
55
  if (container) {
26
56
  container.innerHTML = '';
27
57
  if (container.parentNode) {
@@ -41,7 +71,7 @@ export function render(vnode, options = {}) {
41
71
  throw new Error('No DOM container available. Are you running in Node.js without jsdom?');
42
72
  }
43
73
 
44
- const unmount = mount(vnode, target);
74
+ const unmount = trackMount(mount(vnode, target));
45
75
 
46
76
  return {
47
77
  container: target,
@@ -73,6 +103,7 @@ export function renderTest(Component, props) {
73
103
 
74
104
  // Track signals created during component render
75
105
  const signalRegistry = {};
106
+ /** @type {(() => void) | null} */
76
107
  let rootDispose = null;
77
108
 
78
109
  // Create a reactive root so we can flush synchronously
@@ -80,7 +111,7 @@ export function renderTest(Component, props) {
80
111
  createRoot((dispose) => {
81
112
  rootDispose = dispose;
82
113
  const vnode = h(Component, props || {});
83
- unmountFn = mount(vnode, target);
114
+ unmountFn = trackMount(mount(vnode, target));
84
115
  });
85
116
 
86
117
  return {
@@ -1,11 +0,0 @@
1
- import{E as Tt,Q as W,R as St,T as Lt,U as it,V as I,X as G,Y as Nt,Z as Q,a as z,aa as Bt,ba as Mt,ca as ht,d as O,f as P,j as At,n as Y,r as wt,z as Et}from"./chunk-OKM3GKVP.min.js";import{a as Z}from"./chunk-O3SKPRTY.min.js";var Dt=O(null);typeof document<"u"&&document.addEventListener("focusin",t=>{Dt.set(t.target)});function Te(){return{current:()=>Dt(),focus:t=>t?.focus(),blur:()=>document.activeElement?.blur()}}function Se(){let t={current:null};function e(r){typeof document>"u"||(t.current=r||document.activeElement||null)}function n(r){let o=t.current||r;o&&typeof o.focus=="function"&&o.focus()}return{capture:e,restore:n,previous:()=>t.current}}function Qt(t){let e=null;function n(){if(typeof document>"u")return;e=document.activeElement;let o=t.current||t;if(!o||typeof o.querySelectorAll!="function")return;let i=Ht(o);if(i.length===0)return;i[0].focus();function g(f){if(f.key!=="Tab")return;let a=Ht(o),c=a[0],p=a[a.length-1];f.shiftKey?document.activeElement===c&&(f.preventDefault(),p.focus()):document.activeElement===p&&(f.preventDefault(),c.focus())}return o.addEventListener("keydown",g),()=>{o.removeEventListener("keydown",g)}}function r(){e&&typeof e.focus=="function"&&e.focus()}return{activate:n,deactivate:r}}function Ht(t){let e=["button:not([disabled])","a[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])",'[tabindex]:not([tabindex="-1"])'].join(",");return Array.from(t.querySelectorAll(e)).filter(n=>n.offsetParent!==null)}function Le({children:t,active:e=!0}){let n={current:null},r=O(0),o=Qt(n),i=null,g=c=>{n.current=c,r.set(p=>p+1)},f=P(()=>{if(r(),i&&(i(),i=null,o.deactivate()),e&&n.current)return i=o.activate(),()=>{i?.(),i=null,o.deactivate()}}),a=Nt?.();return a&&(a._cleanupCallbacks=a._cleanupCallbacks||[],a._cleanupCallbacks.push(()=>{f(),i?.(),i=null,o.deactivate()})),Z("div",{ref:g},t)}var U=null,pt=0;function vt(){return typeof document>"u"?null:(U||(U=document.createElement("div"),U.id="what-announcer",U.setAttribute("aria-live","polite"),U.setAttribute("aria-atomic","true"),U.style.cssText=`
2
- position: absolute;
3
- width: 1px;
4
- height: 1px;
5
- padding: 0;
6
- margin: -1px;
7
- overflow: hidden;
8
- clip: rect(0, 0, 0, 0);
9
- white-space: nowrap;
10
- border: 0;
11
- `,document.body.appendChild(U)),U)}function Ft(t,e={}){let{priority:n="polite",timeout:r=1e3}=e,o=vt();if(!o)return;o.setAttribute("aria-live",n);let i=++pt;o.textContent="",requestAnimationFrame(()=>{pt===i&&(o.textContent=t)}),setTimeout(()=>{pt===i&&(o.textContent="")},r)}function Ne(t){return Ft(t,{priority:"assertive"})}function Be({href:t="#main",children:e="Skip to content"}){return Z("a",{href:t,class:"what-skip-link",onClick:n=>{n.preventDefault();let r=document.querySelector(t);r&&(r.focus(),r.scrollIntoView())},style:{position:"absolute",top:"-40px",left:"0",padding:"8px",background:"#000",color:"#fff",textDecoration:"none",zIndex:"10000"},onFocus:n=>{n.target.style.top="0"},onBlur:n=>{n.target.style.top="-40px"}},e)}function gt(t){return t?"true":"false"}function Me(t=!1){let e=O(t);return{expanded:()=>e(),toggle:()=>e.set(!e.peek()),open:()=>e.set(!0),close:()=>e.set(!1),buttonProps:()=>({"aria-expanded":()=>gt(e()),onClick:()=>e.set(!e.peek())}),panelProps:()=>({hidden:()=>!e()})}}function He(t=null){let e=O(t);return{selected:()=>e(),select:n=>e.set(n),isSelected:n=>e()===n,itemProps:n=>({"aria-selected":()=>gt(e()===n),onClick:()=>e.set(n)})}}function De(t=!1){let e=O(t);return{checked:()=>e(),toggle:()=>e.set(!e.peek()),set:n=>e.set(n),checkboxProps:()=>({role:"checkbox","aria-checked":()=>gt(e()),tabIndex:0,onClick:()=>e.set(!e.peek()),onKeyDown:n=>{(n.key===" "||n.key==="Enter")&&(n.preventDefault(),e.set(!e.peek()))}})}}function je(t,e={}){let n=typeof t=="function"?t:()=>t,r=O(0),o=e?.role||null,i=[],g=[],f=[];function a(h){let s=g[h];return s||(s={get current(){return i[h]||null},set current(d){i[h]=d||null;let x=f[h];typeof x=="function"?x(d):x&&typeof x=="object"&&(x.current=d)}},g[h]=s),s}function c(h){let s=i[h];return s?s.isConnected===!1?null:s:null}function p(h){let s=c(h);return!s||typeof s.focus!="function"?null:((typeof document>"u"||document.activeElement!==s)&&s.focus(),s)}function u(){if(typeof document>"u")return!1;let h=document.activeElement;if(!h)return!1;for(let s=0;s<i.length;s++){let d=i[s];if(d&&(d===h||typeof d.contains=="function"&&d.contains(h)))return!0}return!1}function y(h,s){return!(s>0)||h<0?0:h>s-1?s-1:h}function b(){return y(r(),n())}function m(h){return Number.isInteger(h)&&h>=0&&h<n()}function _(h){let s=n();if(s<=0)return;let d=y(r.peek(),s),x=d;switch(h.key){case"ArrowDown":case"ArrowRight":x=(d+1)%s;break;case"ArrowUp":case"ArrowLeft":x=(d-1+s)%s;break;case"Home":x=0;break;case"End":x=s-1;break;default:return}h.preventDefault(),r.set(x),p(x)}return{focusIndex:()=>b(),setFocusIndex:h=>{m(h)&&(r.set(h),u()&&p(h))},focusItem:h=>m(h)?(r.set(h),p(h)):null,getItemProps:(h,s)=>{let{ref:d,...x}=s||{};return f[h]=d||null,{ref:a(h),tabIndex:()=>b()===h?0:-1,onKeyDown:_,onFocus:S=>{let H=S&&(S.currentTarget||S.target);H&&(i[h]=H),r.set(h)},...x}},containerProps:h=>o?{role:o,...h}:{...h}}}function Pe({children:t,as:e="span"}){return Z(e,{style:{position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",border:"0"}},t)}function Re({children:t,priority:e="polite",atomic:n=!0}){return Z("div",{"aria-live":e,"aria-atomic":n},t)}var jt=0;function Pt(){let t=wt();return t?(t.idCounter=(t.idCounter||0)+1,t.idCounter):++jt}function Rt(){jt=0}function Kt(t="what"){let e=`${t}-${Pt()}`;return()=>e}function Ke(t,e="what"){let n=[];for(let r=0;r<t;r++)n.push(`${e}-${Pt()}`);return n}function $e(t){let e=Kt("desc");return{descriptionId:e,descriptionProps:()=>({id:e(),style:{display:"none"}}),describedByProps:()=>({"aria-describedby":e()}),Description:()=>Z("div",{id:e(),style:{display:"none"}},t)}}function Ie(t){let e=Kt("label");return{labelId:e,labelProps:()=>({id:e()}),labelledByProps:()=>({"aria-labelledby":e()})}}var Oe={Enter:"Enter",Space:" ",Escape:"Escape",ArrowUp:"ArrowUp",ArrowDown:"ArrowDown",ArrowLeft:"ArrowLeft",ArrowRight:"ArrowRight",Home:"Home",End:"End",Tab:"Tab"};function Ve(t,e){return n=>{n.key===t&&e(n)}}function ze(t,e){return n=>{t.includes(n.key)&&e(n)}}var et=null;function Je(t){et=typeof t=="function"?t:null}function Ze(t,e,n){if(typeof n=="function"){let r=()=>{let o=n();return o.length===1?o[0]:o};return r._lazyChildren=!0,e||(e={}),Object.defineProperty(e,"_$lazyChildren",{value:r,configurable:!0}),G({tag:t,props:e,children:[],key:null,_vnode:!0})}if(n&&n.length>0){let r=n.length===1?n[0]:n;e?e.children=r:e={children:r}}return G({tag:t,props:e||{},children:n||[],key:null,_vnode:!0})}var te={tr:{depth:2,wrap:"<table><tbody>",unwrap:"</tbody></table>"},td:{depth:3,wrap:"<table><tbody><tr>",unwrap:"</tr></tbody></table>"},th:{depth:3,wrap:"<table><tbody><tr>",unwrap:"</tr></tbody></table>"},thead:{depth:1,wrap:"<table>",unwrap:"</table>"},tbody:{depth:1,wrap:"<table>",unwrap:"</table>"},tfoot:{depth:1,wrap:"<table>",unwrap:"</table>"},colgroup:{depth:1,wrap:"<table>",unwrap:"</table>"},col:{depth:1,wrap:"<table>",unwrap:"</table>"},caption:{depth:1,wrap:"<table>",unwrap:"</table>"}},ee=new Set(["svg","path","circle","rect","line","polyline","polygon","ellipse","g","defs","use","text","tspan","foreignObject","clipPath","mask","pattern","linearGradient","radialGradient","stop","marker","symbol","image","animate","animateTransform","animateMotion","set","filter","feGaussianBlur","feOffset","feMerge","feMergeNode","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feFlood","feImage","feMorphology","feSpecularLighting","feTile","feTurbulence","feDistantLight","fePointLight","feSpotLight"]);function zt(t){let e=t.match(/^<([a-zA-Z][a-zA-Z0-9]*)/);return e?e[1]:""}function ne(t){let e=t.trim(),n=zt(e);if(ee.has(n))return re(e);let r=te[n];if(r){let i=document.createElement("template");i.innerHTML=r.wrap+e+r.unwrap;let g=i.content.firstChild;for(let f=0;f<r.depth;f++)g=g.firstChild;return()=>g.cloneNode(!0)}let o=document.createElement("template");if(o.innerHTML=e,z&&o.content.childNodes.length!==1){let i=[...o.content.childNodes].find((g,f)=>f>0&&g.nodeType===1);throw Object.assign(new Error(`[what] <${n}> cannot contain <${i?i.nodeName.toLowerCase():"that element"}>: the HTML parser closed the outer tag early, so the rendered tree does not match your JSX.`),{code:"ERR_INVALID_HTML_NESTING"})}return()=>o.content.firstChild.cloneNode(!0)}var $t=!1;function Ye(t){return z&&!$t&&($t=!0,console.warn("[what] template() is a compiler internal. Use JSX instead. Direct calls with user input can lead to XSS vulnerabilities.")),ne(t)}function re(t){let e=t.trim();if(zt(e)==="svg"){let o=document.createElement("template");return o.innerHTML=e,()=>o.content.firstChild.cloneNode(!0)}let r=document.createElement("template");return r.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg">${e}</svg>`,()=>r.content.firstChild.firstChild.cloneNode(!0)}function Gt(t,e,n){if(typeof e=="function"&&e._mapArray)return e(t,n||null);if(typeof e=="function"&&e._lazyChildren)return Gt(t,e(),n);if(typeof e=="function"){let r=n||null,o=null,i=null,g=!1,f=Ct();return P(()=>kt(f,()=>{let a=e(),c=typeof a;if(!g){g=!0,c==="string"||c==="number"?(i=document.createTextNode(String(a)),r?t.insertBefore(i,r):t.appendChild(i),et&&et(t,String(a)),o=i):o=ft(t,a,null,r);return}if(i!==null&&(c==="string"||c==="number")){let p=String(a);i.data!==p&&(i.data=p),et&&et(t,p);return}i=null,o=ft(t,a,o,r)})),o}if(typeof e=="string"||typeof e=="number"){let r=document.createTextNode(String(e));return n?t.insertBefore(r,n):t.appendChild(r),r}return e!=null&&typeof e=="object"&&e.nodeType>0?(n?t.insertBefore(e,n):t.appendChild(e),e):ft(t,e,null,n||null)}function Ut(t){return!t||typeof t!="object"?!1:typeof Node<"u"&&t instanceof Node?!0:typeof t.nodeType=="number"&&typeof t.nodeName=="string"}function oe(t){return!!t&&typeof t=="object"&&(t._vnode===!0||"tag"in t)}var lt=typeof SVGElement<"u";function _t(t){return lt&&t instanceof SVGElement&&t.tagName!=="foreignObject"}function Ct(){let t=Q();return t[t.length-1]||null}function kt(t,e){let n=Q(),r=t!==null&&n[n.length-1]!==t;r&&n.push(t);try{return e()}finally{r&&n.pop()}}function It(t){return t==null?[]:Array.isArray(t)?t:[t]}function qt(t,e,n){if(t==null||typeof t=="boolean")return n;if(Array.isArray(t)){for(let r=0;r<t.length;r++)qt(t[r],e,n);return n}if(typeof t=="function"){let r=G(t,e,_t(e));if(r&&r.nodeType===11){let o=Array.from(r.childNodes);for(let i=0;i<o.length;i++)n.push(o[i])}else r&&n.push(r);return n}if(typeof t=="string"||typeof t=="number")return n.push(document.createTextNode(String(t))),n;if(Ut(t)){if(t.nodeType===11&&t.childNodes.length>0){let r=Array.from(t.childNodes);for(let o=0;o<r.length;o++)n.push(r[o])}else n.push(t);return n}if(oe(t)){let r=G(t,e,_t(e));if(r&&r.nodeType===11)if(r.childNodes.length===0)n.push(r);else{let o=Array.from(r.childNodes);for(let i=0;i<o.length;i++)n.push(o[i])}else r&&n.push(r);return n}return n.push(document.createTextNode(String(t))),n}function ie(t,e){if(t.length!==e.length)return!1;for(let n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}function ft(t,e,n,r){if(!t||typeof t.insertBefore!="function")return z&&console.warn("[what] reconcileInsert called with invalid parent:",t),n;let o=r||null;if(e==null||typeof e=="boolean"){let c=It(n);for(let p=0;p<c.length;p++){let u=c[p];u.parentNode===t&&(I(u),t.removeChild(u))}return null}if((typeof e=="string"||typeof e=="number")&&n&&!Array.isArray(n)&&n.nodeType===3){let c=String(e);return n.data!==c&&(n.data=c),n}if(typeof e=="object"&&e!==null&&e.nodeType>0&&e.nodeType!==11&&!Array.isArray(e)){if(e===n)return n;if(n&&!Array.isArray(n)&&n.nodeType>0&&n.nodeType!==11)return n.parentNode===t?(I(n),t.replaceChild(e,n)):o?t.insertBefore(e,o):t.appendChild(e),e}let i=qt(e,t,[]),g=It(n);if(ie(g,i))return n;let f=i.length;for(let c=0;c<g.length;c++){let p=g[c];if(p.parentNode!==t)continue;let u=!1;for(let y=0;y<f;y++)if(i[y]===p){u=!0;break}u||(I(p),t.removeChild(p))}let a=o;for(let c=i.length-1;c>=0;c--){let p=i[c];(p.parentNode!==t||p.nextSibling!==a)&&(a&&a.parentNode!==t&&(a=null),a?t.insertBefore(p,a):t.appendChild(p)),a=p}return i.length===0?null:i.length===1?i[0]:i}function Qe(t,e,n){let r=n?.key,o=n?.raw||!1,i=(g,f)=>{let a=[],c=[],p=[],u=r&&!o?new Map:null,y=document.createComment("/list");return g.insertBefore(y,f||null),P(()=>{let b=t()||[],m=y.parentNode||g;r?ue(m,y,a,b,c,p,e,r,u):fe(m,y,a,b,c,p,e),a=b.length>0?b.slice():b}),y};return i._mapArray=!0,i._mapArraySource=t,i._mapArrayFn=e,i._mapArrayKeyed=!!r&&!o,i}function ve(t){let e=t._mapArraySource()||[],n=t._mapArrayFn,r=t._mapArrayKeyed;return e.map((o,i)=>n(r?()=>o:o,i))}function fe(t,e,n,r,o,i,g){let f=r.length,a=n.length;if(f===0){if(a>0){for(let s=0;s<a;s++)i[s]&&i[s]();for(let s=a-1;s>=0;s--){let d=o[s];d&&(I(d),d.parentNode===t&&t.removeChild(d))}o.length=0,i.length=0}return}if(a===0){let s=document.createDocumentFragment();for(let d=0;d<f;d++){let x=r[d],S=Y(H=>(i[d]=H,g(x,d)));o[d]=S,s.appendChild(S)}t.insertBefore(s,e);return}let c=0,p=Math.min(a,f);for(;c<p&&n[c]===r[c];)c++;if(c===a&&c===f)return;let u=a-1,y=f-1;for(;u>=c&&y>=c&&n[u]===r[y];)u--,y--;let b=new Array(f),m=new Array(f);for(let s=0;s<c;s++)b[s]=o[s],m[s]=i[s];for(let s=y+1;s<f;s++){let d=u+1+(s-y-1);b[s]=o[d],m[s]=i[d]}let _=y-c+1,h=u-c+1;if(_===0)for(let s=c;s<=u;s++)i[s]?.(),o[s]&&I(o[s]),o[s]?.parentNode&&o[s].parentNode.removeChild(o[s]);else if(h===0){let s=c<f&&b[y+1]?b[y+1]:e,d=document.createDocumentFragment();for(let x=c;x<=y;x++){let S=r[x],H=x;b[x]=Y(N=>(m[H]=N,g(S,H))),d.appendChild(b[x])}t.insertBefore(d,s)}else ce(t,e,n,r,o,i,g,c,u,y,b,m);o.length=f,i.length=f;for(let s=0;s<f;s++)o[s]=b[s],i[s]=m[s]}function ce(t,e,n,r,o,i,g,f,a,c,p,u){let y=new Map;for(let d=f;d<=a;d++)y.set(n[d],d);let b=c-f+1,m=new Int32Array(b);m.fill(-1);for(let d=f;d<=c;d++){let x=y.get(r[d]);x!==void 0&&(y.delete(r[d]),p[d]=o[x],u[d]=i[x],m[d-f]=x)}for(let[,d]of y)i[d]?.(),o[d]&&I(o[d]),o[d]?.parentNode&&o[d].parentNode.removeChild(o[d]);let _=b-se(m,b),h=new Uint8Array(b);if(_>1){let d=new Int32Array(_),x=new Int32Array(_),S=0;for(let N=0;N<b;N++)m[N]!==-1&&(d[S]=m[N],x[S]=N,S++);let H=Wt(d,_);for(let N=0;N<H.length;N++)h[x[H[N]]]=1}else if(_===1){for(let d=0;d<b;d++)if(m[d]!==-1){h[d]=1;break}}for(let d=f;d<=c;d++)if(!p[d]){let x=r[d],S=d;p[d]=Y(H=>(u[S]=H,g(x,S)))}let s=c+1<p.length&&p[c+1]?p[c+1]:e;for(let d=c;d>=f;d--){let x=d-f;(m[x]===-1||!h[x])&&(s&&s.parentNode!==t&&(s=e),t.insertBefore(p[d],s)),s=p[d]}}function se(t,e){let n=0;for(let r=0;r<e;r++)t[r]===-1&&n++;return n}function Wt(t,e){if(e===0)return[];if(e===1)return[0];let n=new Int32Array(e),r=new Int32Array(e),o=1;n[0]=0,r[0]=-1;for(let f=1;f<e;f++)if(t[f]>t[n[o-1]])r[f]=n[o-1],n[o++]=f;else{let a=0,c=o-1;for(;a<c;){let p=a+c>>1;t[n[p]]<t[f]?a=p+1:c=p}n[a]=f,r[f]=a>0?n[a-1]:-1}let i=new Array(o),g=n[o-1];for(let f=o-1;f>=0;f--)i[f]=g,g=r[g];return i}function le(){return document.createComment("i")}function v(t,e,n,r){let o=e;for(;o&&o!==n;){let i=o.nextSibling;t.insertBefore(o,r),o=i}}function yt(t,e,n){let r=e;for(;r&&r!==n;){let o=r.nextSibling;I(r),t.removeChild(r),r=o}}function mt(t,e,n,r,o,i,g,f,a){let c;if(o){let y=r(e),b=a(e);c=b,o.set(y,{itemSig:b})}else c=e;let p=le();t.appendChild(p);let u=Y(y=>(f[n]=y,i(c,n)));t.appendChild(u),g[n]=p}function ue(t,e,n,r,o,i,g,f,a){let c=r.length,p=n.length;if(c===0){if(p>0){for(let l=0;l<p;l++)i[l]&&i[l]();o[0]&&yt(t,o[0],e),o.length=0,i.length=0,a&&a.clear()}return}if(p===0){let l=document.createDocumentFragment();for(let E=0;E<c;E++)mt(l,r[E],E,f,a,g,o,i,O);t.insertBefore(l,e);return}let u=0,y=Math.min(p,c);for(;u<y;){if(n[u]===r[u]){u++;continue}let l=f(n[u]),E=f(r[u]);if(l!==E)break;a&&a.get(l).itemSig.set(r[u]),u++}let b=p-1,m=c-1;for(;b>=u&&m>=u;){if(n[b]===r[m]){b--,m--;continue}let l=f(n[b]),E=f(r[m]);if(l!==E)break;a&&a.get(l).itemSig.set(r[m]),b--,m--}if(u>b&&u>m)return;let _=new Array(c),h=new Array(c);for(let l=0;l<u;l++)_[l]=o[l],h[l]=i[l];for(let l=m+1;l<c;l++){let E=b+1+(l-m-1);_[l]=o[E],h[l]=i[E]}let s=m-u+1,d=b-u+1;if(d===0){let l=m+1<c&&_[m+1]?_[m+1]:e,E=document.createDocumentFragment();for(let B=u;B<=m;B++)mt(E,r[B],B,f,a,g,_,h,O);t.insertBefore(E,l),F(o,i,_,h,c);return}if(s===0){for(let l=u;l<=b;l++){i[l]?.();let E=X(t,o[l],o,l,e);yt(t,o[l],E),a&&a.delete(f(n[l]))}F(o,i,_,h,c);return}if(s===d&&s>=2&&s<=Math.max(d,200)){let l=0,E=-1,B=-1;for(let A=0;A<s&&l<=4;A++){let w=f(n[u+A]),$=f(r[u+A]);w!==$&&(l===0?E=A:l===1&&(B=A),l++)}if(l===2){let A=u+E,w=u+B,$=f(n[A]),J=f(n[w]),dt=f(r[A]),q=f(r[w]);if($===q&&J===dt){for(let L=0;L<u;L++)_[L]=o[L],h[L]=i[L];for(let L=u;L<=m;L++)_[L]=o[L],h[L]=i[L];for(let L=m+1;L<c;L++){let K=b+1+(L-m-1);_[L]=o[K],h[L]=i[K]}let R=_[A];_[A]=_[w],_[w]=R;let M=h[A];if(h[A]=h[w],h[w]=M,a){if(r[A]!==n[A]){let L=f(r[A]),K=a.get(L);K&&K.itemSig.set(r[A])}if(r[w]!==n[w]){let L=f(r[w]),K=a.get(L);K&&K.itemSig.set(r[w])}}let D=w===A+1||A===w+1,j=Math.min(A,w),T=Math.max(A,w);if(D){let L=X(t,o[T],o,T,e);v(t,o[T],L,o[j])}else{let L=X(t,o[w],o,w,e),K=document.createComment("tmp");t.insertBefore(K,o[w]),v(t,o[w],L,o[A]);let Yt=X(t,o[A],o,A,e);v(t,o[A],Yt,K),t.removeChild(K)}F(o,i,_,h,c);return}}if(l>=2&&l<=s){let A=E,w=-1,$=-1,J=!1,dt=f(n[u+A]),q=-1;for(let R=A;R<s;R++)if(f(r[u+R])===dt){q=R;break}if(q>A){let R=!0;for(let M=A;M<q;M++)if(f(n[u+M+1])!==f(r[u+M])){R=!1;break}if(R){let M=!0;for(let D=q+1;D<s;D++)if(f(n[u+D])!==f(r[u+D])){M=!1;break}M&&(J=!0,w=u+A,$=u+q)}}if(!J){let R=f(r[u+A]),M=-1;for(let D=A;D<d;D++)if(f(n[u+D])===R){M=D;break}if(M>A){let D=!0;for(let j=A;j<M;j++)if(f(n[u+j])!==f(r[u+j+1])){D=!1;break}if(D){let j=!0;for(let T=M+1;T<s;T++)if(f(n[u+T])!==f(r[u+T])){j=!1;break}j&&(J=!0,w=u+M,$=u+A)}}}if(J){for(let T=u;T<=b;T++)_[T]=o[T],h[T]=i[T];let R=_[w],M=h[w];if(w<$)for(let T=w;T<$;T++)_[T]=_[T+1],h[T]=h[T+1];else for(let T=w;T>$;T--)_[T]=_[T-1],h[T]=h[T-1];if(_[$]=R,h[$]=M,a)for(let T=u;T<=m;T++){let L=f(r[T]);if(r[T]!==n[T]){let K=a.get(L);K&&K.itemSig.set(r[T])}}let D=X(t,R,o,w,e),j;$+1<c?j=_[$+1]:j=e,($>=m+1||j&&j.parentNode!==t)&&(j=e),v(t,R,D,j),F(o,i,_,h,c);return}}}let x=new Map;for(let l=u;l<=b;l++)x.set(f(n[l]),l);let S=new Int32Array(s);S.fill(-1);for(let l=u;l<=m;l++){let E=f(r[l]),B=x.get(E);B!==void 0&&(x.delete(E),_[l]=o[B],h[l]=i[B],S[l-u]=B,a&&r[l]!==n[B]&&a.get(E).itemSig.set(r[l]))}let H=[...x.values()].sort((l,E)=>E-l);for(let l of H){i[l]?.();let E=X(t,o[l],o,l,e);yt(t,o[l],E),a&&a.delete(f(n[l]))}for(let l=u;l<=m;l++)if(!_[l]){let E=document.createDocumentFragment();mt(E,r[l],l,f,a,g,_,h,O),_[l]._frag=E}let N=0,rt=!0,ot=-1;for(let l=0;l<s;l++)S[l]!==-1&&(N++,S[l]<=ot&&(rt=!1),ot=S[l]);let V=new Uint8Array(s);if(rt)for(let l=0;l<s;l++)S[l]!==-1&&(V[l]=1);else if(N>1){let l=new Int32Array(N),E=new Int32Array(N),B=0;for(let w=0;w<s;w++)S[w]!==-1&&(l[B]=S[w],E[B]=w,B++);let A=Wt(l,N);for(let w=0;w<A.length;w++)V[E[A[w]]]=1}else if(N===1){for(let l=0;l<s;l++)if(S[l]!==-1){V[l]=1;break}}F(o,i,_,h,c);let at=m+1<c&&o[m+1]?o[m+1]:e;for(let l=m;l>=u;l--){let E=l-u,B=o[l];if(S[E]===-1)B._frag&&(t.insertBefore(B._frag,at),delete B._frag);else if(!V[E]){let A=X(t,B,o,l,e);v(t,B,A,at)}at=B}}function X(t,e,n,r,o){let i=e.nextSibling;for(;i&&i!==o;){if(i.nodeType===8&&i.data==="i")return i;i=i.nextSibling}return o}function F(t,e,n,r,o){t.length=o,e.length=o;for(let i=0;i<o;i++)t[i]=n[i],e[i]=r[i]}function Fe(t,e){for(let n in e){let r=e[n];if(n==="ref"){typeof r=="function"?r(t):r&&typeof r=="object"&&(r.current=t);continue}if(W(n)){if(typeof r!="function")continue;let o=n.slice(2).toLowerCase();t.addEventListener(o,r);continue}if(typeof r=="function"&&!W(n)){if(t._propEffects||(t._propEffects={}),t._propEffects[n])try{t._propEffects[n]()}catch{}n==="class"||n==="className"?t._propEffects[n]=P(()=>{let o=r()||"";lt&&t instanceof SVGElement?t.setAttribute("class",o):t.className=o}):n==="style"&&typeof r()=="object"?t._propEffects[n]=P(()=>{ut(t,r())}):t._propEffects[n]=P(()=>{ct(t,n,r())})}else ct(t,n,r)}}function ct(t,e,n){if(e==="ref"){typeof n=="function"?n(t):n&&typeof n=="object"&&(n.current=t);return}if(e==="key")return;if(typeof n=="function"&&!W(e)){if(t._propEffects||(t._propEffects={}),t._propEffects[e])try{t._propEffects[e]()}catch{}t._propEffects[e]=P(()=>ct(t,e,n()));return}if(W(e))return;if(St(e,n)){typeof console<"u"&&console.warn(`[what] Blocked unsafe URL in "${e}" attribute:`,n);return}let r=lt&&t instanceof SVGElement;if(e==="class"||e==="className")r?t.setAttribute("class",n||""):t.className=n||"";else if(e==="dangerouslySetInnerHTML"){let o=n?.__html??"";typeof z<"u"&&z&&typeof o=="string"&&/(<script|onerror\s*=|onload\s*=|javascript:)/i.test(o)&&console.warn("[what] dangerouslySetInnerHTML contains potential XSS vectors. Ensure content is sanitized."),t.innerHTML=o}else if(e==="innerHTML")if(n&&typeof n=="object"&&"__html"in n){let o=n.__html??"";typeof z<"u"&&z&&typeof o=="string"&&/(<script|onerror\s*=|onload\s*=|javascript:)/i.test(o)&&console.warn("[what] dangerouslySetInnerHTML contains potential XSS vectors. Ensure content is sanitized."),t.innerHTML=o}else typeof console<"u"&&n!=null&&n!==""&&console.warn('[what] Plain string innerHTML is not allowed. Use { __html: "..." } or dangerouslySetInnerHTML={{ __html: "..." }} instead.');else if(e==="style")ut(t,n);else if(n==null){if(e in t)try{t[e]=""}catch{}t.removeAttribute(e)}else e.startsWith("data-")||e.startsWith("aria-")?t.setAttribute(e,n):typeof n=="boolean"?n?t.setAttribute(e,""):t.removeAttribute(e):r?t.setAttribute(e,n):e==="value"&&t.tagName==="SELECT"?ht(t,n):e in t?t[e]=n:t.setAttribute(e,n)}function nt(t,e,n,r){if(t._propEffects||(t._propEffects={}),t._propEffects[e])try{t._propEffects[e]()}catch{}t._propEffects[e]=P(()=>r(t,n()))}function ae(t,e){if(typeof e=="function")return nt(t,"class",e,ae);lt&&t instanceof SVGElement?t.setAttribute("class",e||""):t.className=e||""}function ut(t,e){if(typeof e=="function")return nt(t,"style",e,ut);if(typeof e=="string")t.style.cssText=e,t._lastStyleObj=null;else if(e&&typeof e=="object"){let n=t.style,r=t._lastStyleObj;if(r)for(let o in r)o in e||(n[o]="");for(let o in e)n[o]=e[o]??"";t._lastStyleObj=e}else e==null&&(t.style.cssText="",t._lastStyleObj=null)}function de(t,e,n){if(typeof n=="function")return nt(t,e,n,(r,o)=>de(r,e,o));n==null?t.removeAttribute(e):t.setAttribute(e,n)}function he(t,e){if(typeof e=="function")return nt(t,"value",e,he);if(t.tagName==="SELECT"){ht(t,e);return}let n=e==null?"":String(e);t.value!==n&&(t.value=n)}function pe(t,e){if(typeof e=="function")return nt(t,"checked",e,pe);t.checked=!!e}var Ot=new Set;function tn(t){for(let e of t)Ot.has(e)||(Ot.add(e),document.addEventListener(e,n=>{let r=n.target,o="$$"+e;for(Object.defineProperty(n,"currentTarget",{configurable:!0,get(){return r||document}});r;){let i=r[o];if(i&&(i(n),n.cancelBubble))return;r=r.parentNode}}))}function en(t,e,n){return t.addEventListener(e,n),()=>t.removeEventListener(e,n)}function nn(t,e){P(()=>{for(let n in e){let r=typeof e[n]=="function"?e[n]():e[n];t.classList.toggle(n,!!r)}})}var st=!1,C=null;function rn(){return st}function ge(t,e){st=!0,Rt(),C={parent:e,index:0};try{let n=k(t,e);return e!==document.body&&e!==document.documentElement&&Xt(e),n}finally{st=!1,C=null}}function Xt(t){if(!(!C||C.parent!==t))for(;t.childNodes.length>C.index;){let e=t.lastChild;I(e),t.removeChild(e)}}var ye=new Set(["$","/$","[]","/[]","fn","/fn","eb:start","eb:end","sb:start","sb:end","portal","portal:empty"]);function Jt(t){return t.nodeType===8&&ye.has(t.textContent)}function bt(t){let e=t.childNodes;for(;C.index<e.length;){let n=e[C.index];if(Jt(n)){C.index++;continue}return C.index++,n}return null}function Zt(t){if(!C||C.parent!==t)return null;let e=t.childNodes;for(let n=C.index;n<e.length;n++){let r=e[n];if(!Jt(r))return r}return null}function tt(t,e){return C&&C.parent===t?(t.insertBefore(e,t.childNodes[C.index]||null),C.index++):t.appendChild(e),e}function xt(){return z}function k(t,e){if(t==null||typeof t=="boolean")return null;if(typeof t=="string"||typeof t=="number"){let n=String(t);if(n===""){let i=Zt(e);return i&&i.nodeType===3?(bt(e),i.textContent="",i):tt(e,document.createTextNode(""))}let r=bt(e);if(r&&r.nodeType===3)return r.textContent!==n&&(xt()&&console.warn(`[what] Hydration mismatch: expected text "${n}", got "${r.textContent}"`),r.textContent=n),r;xt()&&console.warn(`[what] Hydration mismatch: expected text node "${n}", got ${r?r.nodeName:"nothing"}. Falling back to client render.`);let o=document.createTextNode(n);return r?e.replaceChild(o,r):tt(e,o),o}if(typeof t=="function"&&t._lazyChildren)return k(t(),e);if(typeof t=="function"&&t._mapArray){let n=!!(C&&C.parent===e),r=n&&e.childNodes[C.index]||null,o=t(e,r);if(n){let i=Array.prototype.indexOf.call(e.childNodes,o);i>=0&&(C.index=i+1)}return o}if(typeof t=="function"){let n=!!(C&&C.parent===e),r=document.createComment("fn"),o=document.createComment("/fn");n?(e.insertBefore(r,e.childNodes[C.index]||null),C.index++):e.appendChild(r),k(t(),e),n?(e.insertBefore(o,e.childNodes[C.index]||null),C.index++):e.appendChild(o);let i=[];for(let u=r.nextSibling;u&&u!==o;u=u.nextSibling)i.push(u);let g=i.length===0?null:i.length===1?i[0]:i,f=Ct(),a=P(()=>kt(f,()=>{let u=t();st||(g=ft(o.parentNode||e,u,g,o))})),c=!1,p=()=>{c||(c=!0,a())};return r._dispose=p,o._dispose=p,Lt(r,p),g}if(Array.isArray(t)){let n=[];for(let r of t){let o=k(r,e);o&&n.push(o)}return n.length===1?n[0]:n}if(typeof t=="object"&&t._vnode){if(typeof t.tag=="function"){let i=Q(),g=t.tag,f=t.props||{},a=t.children||[],c={hooks:[],hookIndex:0,effects:[],cleanups:[],mounted:!1,disposed:!1,Component:g,_parentCtx:i[i.length-1]||null,_errorBoundary:null};i.push(c);let p,u=null;try{let y={...f};f._$lazyChildren?u=Bt(g,y,f._$lazyChildren):y.children=a.length===0?f.children:a.length===1?a[0]:a,p=g(y),u&&u()}catch(y){return i.pop(),!Mt(y)&&!(y&&typeof y.then=="function"&&me(y,c))&&!Et(y,c)&&console.error("[what] Error in component during hydration:",g.name||"Anonymous",y),null}c.mounted=!0,c._mountCallbacks&&queueMicrotask(()=>{if(!c.disposed)for(let y of c._mountCallbacks)try{y()}catch(b){console.error("[what] onMount error:",b)}});try{let y=k(p,e),b=typeof p=="function"||Array.isArray(p)&&p.some(h=>typeof h=="function"),m=Array.isArray(y)?y[0]:y,_=!b&&m&&m.nodeType?m:e;return it(_,c),y}finally{i.pop()}}if(t.tag==="__errorBoundary"){let{errorState:i,fallback:g,reset:f,handleError:a}=t.props;return Vt(t,e,{startText:"eb:start",endText:"eb:end",ctxExtras:{_errorBoundary:a},state:i,contentFor:c=>c?typeof g=="function"?g({error:c,reset:f}):g:t.children||[]})}if(t.tag==="__suspense"){let{boundary:i,fallback:g,loading:f}=t.props;return Vt(t,e,{startText:"sb:start",endText:"sb:end",ctxExtras:{_suspenseBoundary:i},state:f,contentFor:a=>a?g:t.children||[]})}if(t.tag==="__portal"){let i=G(t,e);return i?tt(e,i):null}let n=bt(e),r=t.tag.toLowerCase();if(n&&n.nodeType===1&&n.nodeName.toLowerCase()===r){_e(n,t.props||{});let i=C;if(C={parent:n,index:0},t.props?.dangerouslySetInnerHTML?.__html==null){for(let f of t.children)k(f,n);t.children.length>0&&Xt(n)}return C=i,n}xt()&&console.warn(`[what] Hydration mismatch: expected <${t.tag}>, got ${n?n.nodeName:"nothing"}. Falling back to client render.`);let o=G(t,e,_t(e));return n?e.replaceChild(o,n):tt(e,o),o}return Ut(t)?t:tt(e,document.createTextNode(String(t)))}function me(t,e){for(let n=e;n;n=n._parentCtx)if(n._suspenseBoundary)return n._suspenseBoundary.onSuspend(t),!0;return!1}function be(t,e){return typeof t=="string"||typeof t=="number"?e.nodeType!==3:t&&t._vnode&&typeof t.tag=="string"?e.nodeType!==1||e.nodeName.toLowerCase()!==t.tag.toLowerCase():!1}function xe(t,e,n){if(e<0||!C||C.parent!==t||C.index!==e)return!1;let r=Zt(t);if(!r)return!1;let o=n(),i=Array.isArray(o)?o:[o],g=i.find(f=>f!=null&&typeof f!="boolean");if(g===void 0)return!0;if(be(g,r))return!1;for(let f of i)k(f,t);return!0}function Vt(t,e,{startText:n,endText:r,ctxExtras:o,state:i,contentFor:g}){let f=t.children||[],a=!!(C&&C.parent===e),c=document.createComment(n),p=document.createComment(r),u={hooks:[],hookIndex:0,effects:[],cleanups:[],mounted:!1,disposed:!1,_parentCtx:Ct(),_startComment:c,_endComment:p,...o};a?(e.insertBefore(c,e.childNodes[C.index]||null),C.index++):e.appendChild(c);let y=a?C.index:-1,b=Q();b.push(u);try{for(let x of f)k(x,e)}finally{b.pop()}let m=At(i),_=!m;if(m){b.push(u);try{_=xe(e,y,()=>g(m))}finally{b.pop()}}a?(e.insertBefore(p,e.childNodes[C.index]||null),C.index++):e.appendChild(p);let h=!0,s=0,d=P(()=>{let x=i();if(h&&(h=!1,_&&x===m))return;let S=c.parentNode;if(!S)return;let H=++s;for(;c.nextSibling&&c.nextSibling!==p;){let N=c.nextSibling;I(N),S.removeChild(N)}b.push(u);try{let N=g(x),rt=Array.isArray(N)?N:[N];for(let ot of rt){let V=G(ot,S);if(H!==s){V&&I(V);break}V&&(p.parentNode?p.parentNode.insertBefore(V,p):I(V))}}finally{b.pop()}});if(a&&C&&C.parent===e){let x=Array.prototype.indexOf.call(e.childNodes,p);x>=0&&(C.index=x+1)}return u.effects.push(d),it(c,u),it(p,u),c}function _e(t,e){for(let n in e){if(n==="children"||n==="key"||n==="dangerouslySetInnerHTML"||n==="innerHTML")continue;if(n==="ref"){let o=e.ref;typeof o=="function"?o(t):o&&typeof o=="object"&&(o.current=t);continue}let r=e[n];if(W(n)){if(typeof r!="function")continue;let o=n.slice(2).toLowerCase();t.addEventListener(o,r);continue}if(n.startsWith("$$")){t[n]=r;continue}if(typeof r=="function"&&!W(n)){n==="class"||n==="className"?P(()=>{t.className=r()||""}):n==="style"&&typeof r()=="object"?P(()=>{ut(t,r())}):P(()=>{ct(t,n,r())});continue}}}Tt({hydrate:ge,insert:Gt});export{Te as a,Se as b,Qt as c,Le as d,Ft as e,Ne as f,Be as g,Me as h,He as i,De as j,je as k,Pe as l,Re as m,Kt as n,Ke as o,$e as p,Ie as q,Oe as r,Ve as s,ze as t,Je as u,Ze as v,ne as w,Ye as x,re as y,Gt as z,Qe as A,ve as B,Fe as C,ct as D,ae as E,ut as F,de as G,he as H,pe as I,tn as J,en as K,nn as L,rn as M,ge as N};