what-core 0.6.0 → 0.6.2

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/reactive.js", "../src/h.js", "../src/components.js", "../src/helpers.js", "../src/dom.js", "../src/testing.js"],
4
- "sourcesContent": ["// What Framework - Reactive Primitives\n// Signals + Effects: fine-grained reactivity without virtual DOM overhead\n//\n// Upgrades:\n// - Topological ordering: computed/effects sorted by _level to prevent diamond glitches\n// - Iterative computed evaluation: no recursion, handles 10K+ depth chains\n// - Ownership tree: createRoot children auto-dispose when parent disposes\n// - Performance: cached levels, lazy sort, fast-path notify, minimal allocation\n\n// Dev-mode flag \u2014 build tools can dead-code-eliminate when false\nexport const __DEV__ = typeof process !== 'undefined'\n ? process.env?.NODE_ENV !== 'production'\n : true;\n\n// DevTools hooks \u2014 set by what-devtools when installed.\n// These are no-ops in production (dead-code eliminated with __DEV__).\nexport let __devtools = null;\n\n/** @internal Install devtools hooks. Called by what-devtools. */\nexport function __setDevToolsHooks(hooks) {\n if (__DEV__) __devtools = hooks;\n}\n\nlet currentEffect = null;\nlet currentRoot = null;\nlet currentOwner = null; // Ownership tree: tracks current owner context\nlet insideComputed = false; // Track whether we're inside a computed() callback (dev-mode warning)\nlet batchDepth = 0;\nlet pendingEffects = [];\nlet pendingNeedSort = false; // Track whether pendingEffects actually needs sorting\n\n// WeakMap: subscriber Set \u2192 owning computed's inner effect (null/absent for signals)\n// Used for topological level computation.\nconst subSetOwner = new WeakMap();\n\n// --- Iterative Computed Evaluation State ---\n// Uses a throw/catch trampoline to convert recursive computed evaluation\n// to iterative. When a computed fn() reads another dirty computed, instead\n// of recursing, we throw a sentinel that gets caught by the outer loop.\nconst NEEDS_UPSTREAM = Symbol('needs_upstream');\nlet iterativeEvalStack = null; // array when inside evaluation loop, null otherwise\n\n// --- Signal ---\n// A reactive value. Reading inside an effect auto-tracks the dependency.\n// Writing triggers only the effects that depend on this signal.\n\nexport function signal(initial, debugName) {\n let value = initial;\n const subs = new Set();\n\n // Unified getter/setter: sig() reads, sig(newVal) writes\n function sig(...args) {\n if (args.length === 0) {\n // Read\n if (currentEffect) {\n subs.add(currentEffect);\n currentEffect.deps.push(subs);\n }\n return value;\n }\n // Write\n if (__DEV__ && insideComputed) {\n console.warn(\n '[what] Signal.set() called inside a computed function. ' +\n 'This may cause infinite loops. Use effect() instead.' +\n (debugName ? ` (signal: ${debugName})` : '')\n );\n }\n const nextVal = typeof args[0] === 'function' ? args[0](value) : args[0];\n if (Object.is(value, nextVal)) return;\n value = nextVal;\n if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);\n if (subs.size > 0) notify(subs);\n }\n\n sig.set = (next) => {\n if (__DEV__ && insideComputed) {\n console.warn(\n '[what] Signal.set() called inside a computed function. ' +\n 'This may cause infinite loops. Use effect() instead.' +\n (debugName ? ` (signal: ${debugName})` : '')\n );\n }\n const nextVal = typeof next === 'function' ? next(value) : next;\n if (Object.is(value, nextVal)) return;\n value = nextVal;\n if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);\n if (subs.size > 0) notify(subs);\n };\n\n sig.peek = () => value;\n\n sig.subscribe = (fn) => {\n return effect(() => fn(sig()));\n };\n\n sig._signal = true;\n if (__DEV__) {\n sig._subs = subs;\n if (debugName) sig._debugName = debugName;\n }\n\n // Notify devtools of signal creation\n if (__DEV__ && __devtools) __devtools.onSignalCreate(sig);\n\n return sig;\n}\n\n// --- Computed ---\n// Derived signal. Lazy: only recomputes when a dependency changes AND it's read.\n// Topological level: max(dependency levels) + 1, computed from source signals (level 0).\n\nexport function computed(fn) {\n let value, dirty = true;\n const subs = new Set();\n\n const inner = _createEffect(() => {\n const prevInsideComputed = insideComputed;\n if (__DEV__) insideComputed = true;\n try {\n value = fn();\n dirty = false;\n } finally {\n if (__DEV__) insideComputed = prevInsideComputed;\n }\n }, true);\n\n // Computed nodes start at level 1. Updated when graph structure changes.\n inner._level = 1;\n inner._computed = true;\n inner._computedSubs = subs;\n\n // Register this subscriber set as owned by this computed\n subSetOwner.set(subs, inner);\n\n // Store markDirty/isDirty closures on the inner effect for iterative eval\n inner._markDirty = () => { dirty = true; };\n inner._isDirty = () => dirty;\n\n function read() {\n if (currentEffect) {\n subs.add(currentEffect);\n currentEffect.deps.push(subs);\n }\n if (dirty) _evaluateComputed(inner);\n return value;\n }\n\n // When a dependency changes, mark dirty AND propagate to our subscribers.\n inner._onNotify = () => {\n dirty = true;\n if (subs.size > 0) notify(subs);\n };\n\n read._signal = true;\n read.peek = () => {\n if (dirty) _evaluateComputed(inner);\n return value;\n };\n\n return read;\n}\n\n// --- Iterative Computed Evaluation ---\n//\n// Problem: A chain of N dirty computeds causes O(N) recursive calls:\n// C_N.read() \u2192 eval \u2192 fn() \u2192 C_{N-1}.read() \u2192 eval \u2192 fn() \u2192 ... \u2192 C_1.read() \u2192 eval \u2192 fn()\n// This overflows the stack at ~3500 depth.\n//\n// Solution: Throw/catch trampoline. The outermost _evaluateComputed manages a\n// stack (array). When a computed's fn() reads another dirty computed during\n// evaluation, _evaluateComputed throws NEEDS_UPSTREAM. The outer loop catches\n// this, adds the upstream to the stack, and processes from the bottom up.\n// This converts O(N) call depth to O(1) per computed (just the outermost loop).\n\nfunction _evaluateComputed(computedEffect) {\n if (iterativeEvalStack !== null) {\n // We're inside the outermost evaluation loop, and a computed's fn()\n // is reading another dirty computed. Push it onto the stack and throw\n // to abort the current fn() so the outer loop can process it first.\n iterativeEvalStack.push(computedEffect);\n throw NEEDS_UPSTREAM;\n }\n\n // Outermost call \u2014 enter the iterative evaluation loop.\n // The stack grows as we discover dirty upstream computeds.\n const stack = [computedEffect];\n iterativeEvalStack = stack;\n\n try {\n while (stack.length > 0) {\n const current = stack[stack.length - 1];\n\n if (!current._isDirty || !current._isDirty()) {\n // Already clean \u2014 pop and continue\n stack.pop();\n continue;\n }\n\n // Pre-scan known deps: if any are dirty computeds, push them onto\n // the stack first (bottom-up). This avoids the O(N^2) worst case\n // where throw/catch restarts from the top on each dirty upstream.\n let pushedUpstream = false;\n const deps = current.deps;\n for (let i = 0; i < deps.length; i++) {\n const depOwner = subSetOwner.get(deps[i]);\n if (depOwner && depOwner._computed && depOwner._isDirty && depOwner._isDirty()) {\n stack.push(depOwner);\n pushedUpstream = true;\n }\n }\n if (pushedUpstream) {\n // Process dirty upstreams first before re-evaluating current\n continue;\n }\n\n // All known deps are clean \u2014 evaluate. throw/catch is fallback\n // for newly-discovered deps only.\n try {\n const prevDepsLen = current.deps.length;\n _runEffect(current);\n // Only recompute level when graph structure changes\n if (current.deps.length !== prevDepsLen) {\n _updateLevel(current);\n }\n stack.pop(); // Successfully evaluated\n } catch (err) {\n if (err === NEEDS_UPSTREAM) {\n // A dirty upstream was discovered and pushed onto the stack.\n // Re-mark this computed dirty since its fn() was aborted mid-execution.\n current._markDirty();\n // The upstream is now at stack[stack.length-1]. Loop continues.\n } else {\n throw err; // Re-throw real errors\n }\n }\n }\n } finally {\n iterativeEvalStack = null;\n }\n}\n\n// Update the topological level of a computed/effect based on its current dependencies.\nfunction _updateLevel(e) {\n let maxDepLevel = 0;\n const deps = e.deps;\n for (let i = 0; i < deps.length; i++) {\n const owner = subSetOwner.get(deps[i]);\n if (owner) {\n const depLevel = owner._level;\n if (depLevel > maxDepLevel) maxDepLevel = depLevel;\n }\n }\n e._level = maxDepLevel + 1;\n}\n\n// --- Effect ---\n// Runs a function, auto-tracking signal reads. Re-runs when deps change.\n// Returns a dispose function.\n\nexport function effect(fn, opts) {\n const e = _createEffect(fn);\n e._level = 1;\n // First run: skip cleanup (deps is empty), just run and track\n const prev = currentEffect;\n currentEffect = e;\n try {\n const result = e.fn();\n if (typeof result === 'function') e._cleanup = result;\n } finally {\n currentEffect = prev;\n }\n // Compute level after first run based on actual dependencies (cached).\n _updateLevel(e);\n // Mark as stable after first run \u2014 subsequent re-runs skip cleanup/re-subscribe\n if (opts?.stable) e._stable = true;\n const dispose = () => _disposeEffect(e);\n // Register with current root for automatic cleanup\n if (currentRoot) {\n currentRoot.disposals.push(dispose);\n }\n return dispose;\n}\n\n// --- Batch ---\n// Group multiple signal writes; effects run once at the end.\n\nexport function batch(fn) {\n batchDepth++;\n try {\n fn();\n } finally {\n batchDepth--;\n if (batchDepth === 0) flush();\n }\n}\n\n// --- Internals ---\n\nfunction _createEffect(fn, lazy) {\n // Minimal object shape \u2014 computed() adds extra properties after creation.\n // Keeping the base object small helps V8 optimize for the common (effect) case.\n const e = {\n fn,\n deps: [], // array of subscriber sets (cheaper than Set for typical 1-3 deps)\n lazy: lazy || false,\n _onNotify: null,\n disposed: false,\n _pending: false,\n _stable: false, // stable effects skip cleanup/re-subscribe on re-run\n _level: 0, // topological depth: signals=0, computed/effects=max(deps)+1\n _computed: false, // true for computed inner effects\n _computedSubs: null, // reference to the computed's subscriber set\n _isDirty: null, // function to check if computed is dirty (set by computed())\n _markDirty: null, // function to mark computed dirty (set by computed())\n };\n if (__DEV__ && __devtools) __devtools.onEffectCreate(e);\n return e;\n}\n\nfunction _runEffect(e) {\n if (e.disposed) return;\n\n // Stable effect fast path: deps don't change, skip cleanup/re-subscribe.\n if (e._stable) {\n if (e._cleanup) {\n try { e._cleanup(); } catch (err) {\n if (__DEV__) console.warn('[what] Error in effect cleanup:', err);\n }\n e._cleanup = null;\n }\n const prev = currentEffect;\n currentEffect = null; // Don't re-track deps (already subscribed)\n try {\n const result = e.fn();\n if (typeof result === 'function') e._cleanup = result;\n } catch (err) {\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect', effect: e });\n if (__DEV__) console.warn('[what] Error in stable effect:', err);\n } finally {\n currentEffect = prev;\n }\n if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);\n return;\n }\n\n cleanup(e);\n // Run effect cleanup from previous run\n if (e._cleanup) {\n try { e._cleanup(); } catch (err) {\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect-cleanup', effect: e });\n if (__DEV__) console.warn('[what] Error in effect cleanup:', err);\n }\n e._cleanup = null;\n }\n const prev = currentEffect;\n currentEffect = e;\n try {\n const result = e.fn();\n // Capture cleanup function if returned\n if (typeof result === 'function') {\n e._cleanup = result;\n }\n } catch (err) {\n if (err === NEEDS_UPSTREAM) throw err; // Iterative eval sentinel \u2014 not a real error\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect', effect: e });\n throw err;\n } finally {\n currentEffect = prev;\n }\n if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);\n}\n\nfunction _disposeEffect(e) {\n e.disposed = true;\n if (__DEV__ && __devtools) __devtools.onEffectDispose(e);\n cleanup(e);\n // Run cleanup on dispose\n if (e._cleanup) {\n try { e._cleanup(); } catch (err) {\n if (__DEV__) console.warn('[what] Error in effect cleanup on dispose:', err);\n }\n e._cleanup = null;\n }\n}\n\nfunction cleanup(e) {\n const deps = e.deps;\n for (let i = 0; i < deps.length; i++) deps[i].delete(e);\n deps.length = 0;\n}\n\n// --- Notification ---\n// Iterative notification to prevent stack overflow on deep computed chains.\n// Uses a reusable queue to avoid per-call array allocation.\n// When notify() encounters _onNotify callbacks (from computeds), those may\n// call notify() recursively. The queue drains iteratively in the outermost call.\n\nlet notifyDepth = 0; // Tracks recursive notify depth\nlet notifyQueue = null; // Reusable queue, allocated on first recursive call\nlet notifyQueueLen = 0; // Length of the queue\n\nfunction notify(subs) {\n // Fast path: no recursive notifications in progress \u2014 iterate directly.\n // This avoids array allocation for the common case (signal \u2192 effects).\n if (notifyDepth === 0) {\n notifyDepth = 1;\n try {\n for (const e of subs) {\n if (e.disposed) continue;\n if (e._onNotify) {\n // Computed subscriber: mark dirty and propagate.\n // _onNotify may call notify() recursively \u2014 tracked by notifyDepth.\n e._onNotify();\n } else if (batchDepth === 0 && e._stable) {\n // Inline execution for stable effects\n const prev = currentEffect;\n currentEffect = null;\n try {\n const result = e.fn();\n if (typeof result === 'function') {\n if (e._cleanup) try { e._cleanup(); } catch (err) {}\n e._cleanup = result;\n }\n } catch (err) {\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect', effect: e });\n if (__DEV__) console.warn('[what] Error in stable effect:', err);\n } finally {\n currentEffect = prev;\n }\n } else if (!e._pending) {\n e._pending = true;\n const level = e._level;\n const len = pendingEffects.length;\n if (len > 0 && pendingEffects[len - 1]._level > level) {\n pendingNeedSort = true;\n }\n pendingEffects.push(e);\n }\n }\n // Drain any queued subscriber sets from recursive notify calls\n if (notifyQueueLen > 0) {\n let qi = 0;\n while (qi < notifyQueueLen) {\n const queuedSubs = notifyQueue[qi];\n notifyQueue[qi] = null; // Allow GC\n qi++;\n for (const e of queuedSubs) {\n if (e.disposed) continue;\n if (e._onNotify) {\n e._onNotify();\n } else if (batchDepth === 0 && e._stable) {\n const prev = currentEffect;\n currentEffect = null;\n try {\n const result = e.fn();\n if (typeof result === 'function') {\n if (e._cleanup) try { e._cleanup(); } catch (err) {}\n e._cleanup = result;\n }\n } catch (err) {\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect', effect: e });\n if (__DEV__) console.warn('[what] Error in stable effect:', err);\n } finally {\n currentEffect = prev;\n }\n } else if (!e._pending) {\n e._pending = true;\n const level = e._level;\n const len = pendingEffects.length;\n if (len > 0 && pendingEffects[len - 1]._level > level) {\n pendingNeedSort = true;\n }\n pendingEffects.push(e);\n }\n }\n }\n notifyQueueLen = 0;\n }\n } finally {\n notifyDepth = 0;\n }\n if (batchDepth === 0 && pendingEffects.length > 0) scheduleMicrotask();\n } else {\n // Recursive call \u2014 queue the subscriber set for the outermost call to drain.\n if (notifyQueue === null) notifyQueue = [];\n if (notifyQueueLen >= notifyQueue.length) {\n notifyQueue.push(subs);\n } else {\n notifyQueue[notifyQueueLen] = subs;\n }\n notifyQueueLen++;\n }\n}\n\nlet microtaskScheduled = false;\nfunction scheduleMicrotask() {\n if (!microtaskScheduled) {\n microtaskScheduled = true;\n queueMicrotask(() => {\n microtaskScheduled = false;\n flush();\n });\n }\n}\n\nfunction flush() {\n let iterations = 0;\n while (pendingEffects.length > 0 && iterations < 25) {\n const batch = pendingEffects;\n pendingEffects = [];\n\n // Topological sort: execute effects in level order (lowest first).\n // Fast paths:\n // 1. Single effect \u2014 no sort needed (most common case for microtask flush)\n // 2. Already sorted \u2014 skip sort (common when effects added in level order)\n // 3. Multiple effects at different levels \u2014 sort required\n if (batch.length > 1 && pendingNeedSort) {\n batch.sort((a, b) => a._level - b._level);\n }\n pendingNeedSort = false;\n\n for (let i = 0; i < batch.length; i++) {\n const e = batch[i];\n e._pending = false;\n if (!e.disposed && !e._onNotify) {\n const prevDepsLen = e.deps.length;\n _runEffect(e);\n // Update level only if deps changed (graph structure change)\n if (!e._computed && e.deps.length !== prevDepsLen) {\n _updateLevel(e);\n }\n }\n }\n iterations++;\n }\n if (iterations >= 25) {\n if (__DEV__) {\n const remaining = pendingEffects.slice(0, 3);\n const effectNames = remaining.map(e => e.fn?.name || e.fn?.toString().slice(0, 60) || '(anonymous)');\n console.warn(\n `[what] Possible infinite effect loop detected (25 iterations). ` +\n `Likely cause: an effect writes to a signal it also reads, creating a cycle. ` +\n `Use untrack() to read signals without subscribing. ` +\n `Looping effects: ${effectNames.join(', ')}`\n );\n } else {\n console.warn('[what] Possible infinite effect loop detected');\n }\n for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;\n pendingEffects.length = 0;\n }\n}\n\n// --- Memo ---\n// Eager computed that only propagates when the value actually changes.\n// Fix: Instead of calling notify(subs) inline (which bypasses topological sort\n// and causes diamond-dependency glitches), push memo subscribers into\n// pendingEffects and let them go through the sorted flush() path.\nexport function memo(fn) {\n let value;\n const subs = new Set();\n\n const e = _createEffect(() => {\n const next = fn();\n if (!Object.is(value, next)) {\n value = next;\n // Push subscribers into pendingEffects for topological flush\n // instead of inline notify() which can cause diamond glitches\n for (const sub of subs) {\n if (sub.disposed) continue;\n if (sub._onNotify) {\n // Computed subscriber: mark dirty and propagate\n sub._onNotify();\n } else if (!sub._pending) {\n sub._pending = true;\n const level = sub._level;\n const len = pendingEffects.length;\n if (len > 0 && pendingEffects[len - 1]._level > level) {\n pendingNeedSort = true;\n }\n pendingEffects.push(sub);\n }\n }\n }\n });\n\n e._level = 1;\n\n _runEffect(e);\n _updateLevel(e);\n\n // Register subscriber set owner for level tracking\n subSetOwner.set(subs, e);\n\n // Register with current root\n if (currentRoot) {\n currentRoot.disposals.push(() => _disposeEffect(e));\n }\n\n function read() {\n if (currentEffect) {\n subs.add(currentEffect);\n currentEffect.deps.push(subs);\n }\n return value;\n }\n\n read._signal = true;\n read.peek = () => value;\n return read;\n}\n\n// --- flushSync ---\n// Force all pending effects to run synchronously. Use sparingly.\nexport function flushSync() {\n microtaskScheduled = false;\n flush();\n}\n\n// --- Untrack ---\n// Read signals without subscribing\nexport function untrack(fn) {\n const prev = currentEffect;\n currentEffect = null;\n try {\n return fn();\n } finally {\n currentEffect = prev;\n }\n}\n\n// --- getOwner / runWithOwner ---\n// Expose ownership context for advanced use cases (e.g., async operations\n// that need to register disposals with the correct owner).\n\nexport function getOwner() {\n return currentOwner;\n}\n\nexport function runWithOwner(owner, fn) {\n const prev = currentOwner;\n const prevRoot = currentRoot;\n currentOwner = owner;\n currentRoot = owner;\n try {\n return fn();\n } finally {\n currentOwner = prev;\n currentRoot = prevRoot;\n }\n}\n\n// --- createRoot ---\n// Isolated reactive scope with ownership tree.\n// All effects created inside are tracked and disposed together.\n// Child createRoot scopes register with parent owner \u2014 disposing parent\n// automatically disposes all children (prevents orphaned subscriptions).\nexport function createRoot(fn) {\n const prevRoot = currentRoot;\n const prevOwner = currentOwner;\n const root = {\n disposals: [],\n owner: currentOwner, // parent owner for ownership tree\n children: [], // child roots (ownership tree)\n _disposed: false,\n };\n\n // Register this root as a child of the parent owner\n if (currentOwner) {\n currentOwner.children.push(root);\n }\n\n currentRoot = root;\n currentOwner = root;\n\n try {\n const dispose = () => {\n if (root._disposed) return;\n root._disposed = true;\n\n // Dispose children first (depth-first, reverse order)\n for (let i = root.children.length - 1; i >= 0; i--) {\n _disposeRoot(root.children[i]);\n }\n root.children.length = 0;\n\n // Dispose own effects (reverse order for LIFO cleanup)\n for (let i = root.disposals.length - 1; i >= 0; i--) {\n root.disposals[i]();\n }\n root.disposals.length = 0;\n\n // Remove from parent's children list\n if (root.owner) {\n const idx = root.owner.children.indexOf(root);\n if (idx >= 0) root.owner.children.splice(idx, 1);\n }\n };\n return fn(dispose);\n } finally {\n currentRoot = prevRoot;\n currentOwner = prevOwner;\n }\n}\n\n// Internal: dispose a root and all its children\nfunction _disposeRoot(root) {\n if (root._disposed) return;\n root._disposed = true;\n\n // Dispose children first\n for (let i = root.children.length - 1; i >= 0; i--) {\n _disposeRoot(root.children[i]);\n }\n root.children.length = 0;\n\n // Dispose own effects\n for (let i = root.disposals.length - 1; i >= 0; i--) {\n root.disposals[i]();\n }\n root.disposals.length = 0;\n}\n\n// --- onCleanup ---\n// Register a cleanup function with the current owner/root.\n// Runs when the owner is disposed.\nexport function onCleanup(fn) {\n if (currentRoot) {\n currentRoot.disposals.push(fn);\n }\n}\n", "// What Framework - Element Descriptors\n// Minimal element descriptor objects. No classes, no fibers, just plain objects.\n\n// h(tag, props, ...children) -> VNode\n// h(Component, props, ...children) -> VNode\n// VNode = { tag, props, children, key }\n\nconst EMPTY_OBJ = Object.create(null);\nconst EMPTY_ARR = [];\n\nexport function h(tag, props, ...children) {\n props = props || EMPTY_OBJ;\n const flat = flattenChildren(children);\n const key = props.key ?? null;\n\n // Strip key from props passed to component/element\n if (props.key !== undefined) {\n props = { ...props };\n delete props.key;\n }\n\n return { tag, props, children: flat, key, _vnode: true };\n}\n\n// Fragment \u2014 just returns children\nexport function Fragment({ children }) {\n return children;\n}\n\nfunction flattenChildren(children) {\n const out = [];\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child == null || child === false || child === true) continue;\n if (Array.isArray(child)) {\n out.push(...flattenChildren(child));\n } else if (typeof child === 'object' && child._vnode) {\n out.push(child);\n } else if (typeof child === 'function') {\n // Reactive child \u2014 preserve function for fine-grained DOM updates\n out.push(child);\n } else {\n // Text node\n out.push(String(child));\n }\n }\n return out;\n}\n\n// JSX-like tagged template alternative (no build step needed)\n// html`<div class=\"foo\">${content}</div>`\n// Uses a simple parser, not full HTML \u2014 good enough for most cases.\n\nexport function html(strings, ...values) {\n const src = strings.reduce((acc, str, i) =>\n acc + str + (i < values.length ? `\\x00${i}\\x00` : ''), '');\n return parseTemplate(src, values);\n}\n\nfunction parseTemplate(src, values) {\n // Lightweight tagged template parser\n // Supports: <tag attr=\"val\">, <tag ...${spread}>, ${children}, self-closing\n src = src.trim();\n const nodes = [];\n let i = 0;\n\n while (i < src.length) {\n if (src[i] === '<') {\n const result = parseElement(src, i, values);\n if (result) {\n nodes.push(result.node);\n i = result.end;\n continue;\n }\n }\n // Text or interpolation\n const result = parseText(src, i, values);\n if (result.text) nodes.push(result.text);\n i = result.end;\n }\n\n return nodes.length === 1 ? nodes[0] : nodes;\n}\n\nfunction parseElement(src, start, values) {\n // Opening tag\n const openMatch = src.slice(start).match(/^<([a-zA-Z][a-zA-Z0-9-]*|[A-Z]\\w*)/);\n if (!openMatch) return null;\n\n const tag = openMatch[1];\n let i = start + openMatch[0].length;\n const props = {};\n\n // Parse attributes\n while (i < src.length) {\n // Skip whitespace\n while (i < src.length && /\\s/.test(src[i])) i++;\n\n // Self-closing or end of opening tag\n if (src.slice(i, i + 2) === '/>') {\n return { node: h(tag, Object.keys(props).length ? props : null), end: i + 2 };\n }\n if (src[i] === '>') {\n i++;\n break;\n }\n\n // Spread: ...${obj}\n if (src.slice(i, i + 3) === '...') {\n const placeholder = src.slice(i + 3).match(/^\\x00(\\d+)\\x00/);\n if (placeholder) {\n Object.assign(props, values[Number(placeholder[1])]);\n i += 3 + placeholder[0].length;\n continue;\n }\n }\n\n // Attribute: name=${val} or name=\"val\" or name\n const attrMatch = src.slice(i).match(/^([a-zA-Z_@:][a-zA-Z0-9_:.-]*)/);\n if (!attrMatch) break;\n\n const attrName = attrMatch[1];\n i += attrMatch[0].length;\n\n // Skip whitespace around =\n while (i < src.length && /\\s/.test(src[i])) i++;\n\n if (src[i] === '=') {\n i++;\n while (i < src.length && /\\s/.test(src[i])) i++;\n\n // Value is a placeholder\n const ph = src.slice(i).match(/^\\x00(\\d+)\\x00/);\n if (ph) {\n props[attrName] = values[Number(ph[1])];\n i += ph[0].length;\n } else if (src[i] === '\"' || src[i] === \"'\") {\n const q = src[i];\n i++;\n let val = '';\n while (i < src.length && src[i] !== q) {\n const tph = src.slice(i).match(/^\\x00(\\d+)\\x00/);\n if (tph) {\n val += String(values[Number(tph[1])]);\n i += tph[0].length;\n } else {\n val += src[i];\n i++;\n }\n }\n i++; // closing quote\n props[attrName] = val;\n }\n } else {\n props[attrName] = true;\n }\n }\n\n // Parse children until closing tag\n const children = [];\n const closeTag = `</${tag}>`;\n\n while (i < src.length) {\n if (src.slice(i, i + closeTag.length) === closeTag) {\n i += closeTag.length;\n break;\n }\n\n if (src[i] === '<') {\n const child = parseElement(src, i, values);\n if (child) {\n children.push(child.node);\n i = child.end;\n continue;\n }\n }\n\n const text = parseText(src, i, values);\n if (text.text != null) children.push(text.text);\n i = text.end;\n }\n\n return {\n node: h(tag, Object.keys(props).length ? props : null, ...children),\n end: i,\n };\n}\n\nfunction parseText(src, start, values) {\n let i = start;\n let text = '';\n\n while (i < src.length && src[i] !== '<') {\n const ph = src.slice(i).match(/^\\x00(\\d+)\\x00/);\n if (ph) {\n if (text.trim()) {\n return { text: text.trim(), end: i };\n }\n return { text: values[Number(ph[1])], end: i + ph[0].length };\n }\n text += src[i];\n i++;\n }\n\n return { text: text.trim() || null, end: i };\n}\n", "// What Framework - Component Utilities\n// memo, lazy, Suspense, ErrorBoundary\n\nimport { h } from './h.js';\nimport { signal, effect, untrack, __DEV__ } from './reactive.js';\n\n// Legacy errorBoundaryStack removed \u2014 tree-based resolution via _parentCtx._errorBoundary\n// is now the only mechanism. See reportError() below.\n\n// --- memo ---\n// In the run-once model, components execute exactly once and never re-render.\n// Signals update the DOM directly via fine-grained effects. Therefore, memo()\n// is a no-op identity wrapper \u2014 there is no re-render to skip.\n// Kept for API compatibility with React-style code.\n\nexport function memo(Component, _areEqual) {\n // No-op in run-once model \u2014 just return the component as-is\n const MemoWrapper = function MemoWrapper(props) {\n return Component(props);\n };\n MemoWrapper.displayName = `Memo(${Component.name || 'Anonymous'})`;\n return MemoWrapper;\n}\n\n// Injected by dom.js\nlet _getCurrentComponent = null;\nexport function _injectGetCurrentComponent(fn) { _getCurrentComponent = fn; }\n\nexport function shallowEqual(a, b) {\n if (a === b) return true;\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n for (const key of keysA) {\n if (!Object.is(a[key], b[key])) return false;\n }\n return true;\n}\n\n// --- lazy ---\n// Code-split a component. Returns a wrapper that loads on first render.\n\nexport function lazy(loader) {\n let Component = null;\n let loadPromise = null;\n let loadError = null;\n const listeners = new Set();\n\n function LazyWrapper(props) {\n if (loadError) throw loadError;\n if (Component) return h(Component, props);\n\n if (!loadPromise) {\n loadPromise = loader()\n .then(mod => {\n Component = mod.default || mod;\n // Notify all waiting instances\n listeners.forEach(fn => fn());\n listeners.clear();\n })\n .catch(err => { loadError = err; });\n }\n\n // Throw promise for Suspense to catch\n throw loadPromise;\n }\n\n LazyWrapper.displayName = 'Lazy';\n LazyWrapper._lazy = true;\n LazyWrapper._onLoad = (fn) => {\n if (Component) fn();\n else listeners.add(fn);\n };\n return LazyWrapper;\n}\n\n// --- Suspense ---\n// Show fallback while children are loading (lazy components).\n// Works with lazy() and async components.\n\nexport function Suspense({ fallback, children }) {\n const loading = signal(false);\n const pendingPromises = new Set();\n\n // Suspense boundary marker\n const boundary = {\n _suspense: true,\n onSuspend(promise) {\n loading.set(true);\n pendingPromises.add(promise);\n promise.finally(() => {\n pendingPromises.delete(promise);\n if (pendingPromises.size === 0) {\n loading.set(false);\n }\n });\n },\n };\n\n return {\n tag: '__suspense',\n props: { boundary, fallback, loading },\n children: Array.isArray(children) ? children : [children],\n _vnode: true,\n };\n}\n\n// --- ErrorBoundary ---\n// Catch errors in children and show fallback.\n// Uses a signal to track error state so it works with reactive rendering.\n\nexport function ErrorBoundary({ fallback, children, onError }) {\n const errorState = signal(null);\n\n // Error handler that will be registered with the component tree\n const handleError = (error) => {\n errorState.set(error);\n if (onError) {\n try {\n onError(error);\n } catch (e) {\n console.error('Error in onError handler:', e);\n }\n }\n };\n\n // Reset function to recover from error\n const reset = () => errorState.set(null);\n\n return {\n tag: '__errorBoundary',\n props: { errorState, handleError, fallback, reset },\n children: Array.isArray(children) ? children : [children],\n _vnode: true,\n };\n}\n\n// Helper to report error to nearest boundary\n// Walks the component context tree (not a runtime stack) so async errors are caught\nexport function reportError(error, startCtx) {\n // Walk up the _parentCtx chain to find the nearest _errorBoundary\n let ctx = startCtx || _getCurrentComponent?.();\n while (ctx) {\n if (ctx._errorBoundary) {\n ctx._errorBoundary(error);\n return true;\n }\n ctx = ctx._parentCtx;\n }\n return false;\n}\n\n// _getCurrentComponent is already declared above and injected via _injectGetCurrentComponent\n\n// --- Show ---\n// Conditional rendering component. Cleaner than ternaries.\n\nexport function Show({ when, fallback = null, children }) {\n // when can be a signal or a value\n const condition = typeof when === 'function' ? when() : when;\n return condition ? children : fallback;\n}\n\n// --- For ---\n// Efficient list rendering with keyed reconciliation.\n\nexport function For({ each, fallback = null, children }) {\n const list = typeof each === 'function' ? each() : each;\n if (!list || list.length === 0) return fallback;\n\n // children should be a function (item, index) => vnode\n const renderFn = Array.isArray(children) ? children[0] : children;\n if (typeof renderFn !== 'function') {\n console.warn('[what] For: children must be a render function, e.g. <For each={items}>{(item) => ...}</For>');\n return fallback;\n }\n\n return list.map((item, index) => {\n const vnode = renderFn(item, index);\n // Auto-detect keys for efficient keyed reconciliation\n if (vnode && typeof vnode === 'object' && vnode.key == null) {\n if (item != null && typeof item === 'object') {\n // Use item.id or item.key if available\n if (item.id != null) vnode.key = item.id;\n else if (item.key != null) vnode.key = item.key;\n } else if (typeof item === 'string' || typeof item === 'number') {\n // Primitive items can be their own key\n vnode.key = item;\n }\n }\n return vnode;\n });\n}\n\n// --- Switch / Match ---\n// Multi-condition rendering (like switch statement).\n\nexport function Switch({ fallback = null, children }) {\n const kids = Array.isArray(children) ? children : [children];\n\n for (const child of kids) {\n if (child && child.tag === Match) {\n const condition = typeof child.props.when === 'function'\n ? child.props.when()\n : child.props.when;\n if (condition) {\n return child.children;\n }\n }\n }\n\n return fallback;\n}\n\nexport function Match({ when, children }) {\n // Match is just a marker component, Switch handles the logic\n return { tag: Match, props: { when }, children, _vnode: true };\n}\n\n// --- Island ---\n// Deferred hydration component for islands architecture.\n// Usage: h(Island, { component: Counter, mode: 'idle' })\n// The babel plugin compiles <Counter client:idle /> into this.\n\nexport function Island({ component: Component, mode, mediaQuery, ...props }) {\n const placeholder = h('div', { 'data-island': Component.name || 'Island', 'data-hydrate': mode });\n\n // We need to return a vnode that the reconciler can handle.\n // The actual hydration scheduling happens after mount via an effect.\n const wrapper = signal(null);\n const hydrated = signal(false);\n\n function doHydrate() {\n if (hydrated()) return;\n hydrated.set(true);\n // Render the actual component\n wrapper.set(h(Component, props));\n }\n\n // Schedule hydration based on mode\n function scheduleHydration(el) {\n switch (mode) {\n case 'load':\n queueMicrotask(doHydrate);\n break;\n\n case 'idle':\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(doHydrate);\n } else {\n setTimeout(doHydrate, 200);\n }\n break;\n\n case 'visible': {\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) {\n observer.disconnect();\n doHydrate();\n }\n });\n observer.observe(el);\n break;\n }\n\n case 'interaction': {\n const hydrate = () => {\n el.removeEventListener('click', hydrate);\n el.removeEventListener('focus', hydrate);\n el.removeEventListener('mouseenter', hydrate);\n doHydrate();\n };\n el.addEventListener('click', hydrate, { once: true });\n el.addEventListener('focus', hydrate, { once: true });\n el.addEventListener('mouseenter', hydrate, { once: true });\n break;\n }\n\n case 'media': {\n if (!mediaQuery) { doHydrate(); break; }\n const mq = window.matchMedia(mediaQuery);\n if (mq.matches) {\n queueMicrotask(doHydrate);\n } else {\n const checkMedia = () => {\n if (mq.matches) {\n mq.removeEventListener('change', checkMedia);\n doHydrate();\n }\n };\n mq.addEventListener('change', checkMedia);\n }\n break;\n }\n\n default:\n // Unknown mode, hydrate immediately\n queueMicrotask(doHydrate);\n }\n }\n\n // Use ref callback to get the DOM element and schedule hydration\n const refCallback = (el) => {\n if (el) scheduleHydration(el);\n };\n\n // Return: show placeholder until hydrated, then show the real component\n return h('div', { 'data-island': Component.name || 'Island', 'data-hydrate': mode, ref: refCallback },\n hydrated() ? wrapper() : null\n );\n}\n", "// What Framework - Helpers & Utilities\n// Commonly needed patterns, zero overhead.\n\nimport { signal, effect, __DEV__ } from './reactive.js';\n\n// --- each(list, fn) --- [DEPRECATED: use <For> component or .map() instead]\n// Keyed list rendering. Optimized for reconciliation.\nlet _eachWarned = false;\nexport function each(list, fn, keyFn) {\n if (!_eachWarned) {\n _eachWarned = true;\n console.warn('[what] each() is deprecated. Use the <For> component or Array.map() instead.');\n }\n if (!list || list.length === 0) return [];\n return list.map((item, index) => {\n const vnode = fn(item, index);\n if (keyFn && vnode && typeof vnode === 'object') {\n vnode.key = keyFn(item, index);\n }\n return vnode;\n });\n}\n\n// --- cls(...args) ---\n// Conditional class names. Like clsx but tiny.\n// cls('base', condition && 'active', { hidden: isHidden, bold: isBold })\nexport function cls(...args) {\n const classes = [];\n for (const arg of args) {\n if (!arg) continue;\n if (typeof arg === 'string') {\n classes.push(arg);\n } else if (typeof arg === 'object') {\n for (const [key, val] of Object.entries(arg)) {\n if (val) classes.push(key);\n }\n }\n }\n return classes.join(' ');\n}\n\n// --- style(obj) ---\n// Convert a style object to a CSS string for SSR.\nexport function style(obj) {\n if (typeof obj === 'string') return obj;\n return Object.entries(obj)\n .filter(([, v]) => v != null && v !== '')\n .map(([k, v]) => `${camelToKebab(k)}:${v}`)\n .join(';');\n}\n\nfunction camelToKebab(str) {\n return str.replace(/([A-Z])/g, '-$1').toLowerCase();\n}\n\n// --- debounce ---\n// Debounced signal updates.\nexport function debounce(fn, ms) {\n let timer;\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => fn(...args), ms);\n };\n}\n\n// --- throttle ---\nexport function throttle(fn, ms) {\n let last = 0;\n return (...args) => {\n const now = Date.now();\n if (now - last >= ms) {\n last = now;\n fn(...args);\n }\n };\n}\n\n// Component context ref \u2014 injected by dom.js to avoid circular imports\nlet _getCurrentComponentRef = null;\nexport function _setComponentRef(fn) { _getCurrentComponentRef = fn; }\n\n// --- useMediaQuery ---\n// Reactive media query. Returns a signal. Cleans up listener on component unmount.\nexport function useMediaQuery(query) {\n if (typeof window === 'undefined') return signal(false);\n const mq = window.matchMedia(query);\n const s = signal(mq.matches);\n const handler = (e) => s.set(e.matches);\n mq.addEventListener('change', handler);\n\n // Register cleanup if inside a component context\n const ctx = _getCurrentComponentRef?.();\n if (ctx) {\n ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];\n ctx._cleanupCallbacks.push(() => mq.removeEventListener('change', handler));\n }\n\n return s;\n}\n\n// --- useLocalStorage ---\n// Signal synced with localStorage. Cleans up listeners on component unmount.\nexport function useLocalStorage(key, initial) {\n let stored;\n try {\n const raw = localStorage.getItem(key);\n stored = raw !== null ? JSON.parse(raw) : initial;\n } catch {\n stored = initial;\n }\n\n const s = signal(stored);\n\n // Sync to localStorage on changes\n const dispose = effect(() => {\n try {\n localStorage.setItem(key, JSON.stringify(s()));\n } catch (e) {\n if (__DEV__) console.warn('[what] localStorage write failed (quota exceeded?):', e);\n }\n });\n\n // Listen for changes from other tabs\n let storageHandler = null;\n if (typeof window !== 'undefined') {\n storageHandler = (e) => {\n if (e.key === key && e.newValue !== null) {\n try { s.set(JSON.parse(e.newValue)); } catch (err) {\n if (__DEV__) console.warn('[what] localStorage parse failed:', err);\n }\n }\n };\n window.addEventListener('storage', storageHandler);\n }\n\n // Register cleanup if inside a component context\n const ctx = _getCurrentComponentRef?.();\n if (ctx) {\n ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];\n ctx._cleanupCallbacks.push(() => {\n dispose();\n if (storageHandler) window.removeEventListener('storage', storageHandler);\n });\n }\n\n return s;\n}\n\n// --- portal ---\n// Render children into a different DOM container.\nexport function Portal({ target, children }) {\n // In SSR, just return null (portals are client-only)\n if (typeof document === 'undefined') return null;\n const container = typeof target === 'string'\n ? document.querySelector(target)\n : target;\n if (!container) return null;\n // The DOM reconciler will mount children here\n return { tag: '__portal', props: { container }, children: Array.isArray(children) ? children : [children], _vnode: true };\n}\n\n// --- useClickOutside ---\n// Detect clicks outside a ref'd element. Essential for dropdowns, modals, popovers.\nexport function useClickOutside(ref, handler) {\n if (typeof document === 'undefined') return;\n\n const listener = (e) => {\n const el = ref.current || ref;\n if (!el || el.contains(e.target)) return;\n handler(e);\n };\n\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n\n const ctx = _getCurrentComponentRef?.();\n if (ctx) {\n ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];\n ctx._cleanupCallbacks.push(() => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n });\n }\n}\n\n// --- Transition helper ---\n// Animate elements in/out. Returns props to spread on the element.\nexport function transition(name, active) {\n return {\n class: active ? `${name}-enter ${name}-enter-active` : `${name}-leave ${name}-leave-active`,\n };\n}\n", "// What Framework - Fine-Grained DOM Runtime\n// Components run ONCE. Signals create individual DOM effects.\n// No VDOM reconciler, no diffing \u2014 direct DOM manipulation driven by signals.\n\nimport { effect, batch, untrack, signal, __DEV__, __devtools } from './reactive.js';\nimport { reportError, _injectGetCurrentComponent, shallowEqual } from './components.js';\nimport { _setComponentRef } from './helpers.js';\n\n// SVG elements that need namespace\nconst SVG_ELEMENTS = new Set([\n 'svg', 'path', 'circle', 'rect', 'line', 'polyline', 'polygon', 'ellipse',\n 'g', 'defs', 'use', 'symbol', 'clipPath', 'mask', 'pattern', 'image',\n 'text', 'tspan', 'textPath', 'foreignObject', 'linearGradient', 'radialGradient', 'stop',\n 'marker', 'animate', 'animateTransform', 'animateMotion', 'set', 'filter',\n 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix',\n 'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feGaussianBlur', 'feImage',\n 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'feSpecularLighting',\n 'feTile', 'feTurbulence',\n]);\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\n// Track all mounted component contexts for disposal\nconst mountedComponents = new Set();\n\n// WeakMap: comment node \u2192 component context (for comment-node boundaries)\nconst _commentCtxMap = new WeakMap();\n\nfunction isDomNode(value) {\n if (!value || typeof value !== 'object') return false;\n if (typeof Node !== 'undefined' && value instanceof Node) return true;\n return typeof value.nodeType === 'number' && typeof value.nodeName === 'string';\n}\n\nfunction isVNode(value) {\n return !!value && typeof value === 'object' && (value._vnode === true || 'tag' in value);\n}\n\n// Dispose a component: run effect cleanups, hook cleanups, onCleanup callbacks\nfunction disposeComponent(ctx) {\n if (ctx.disposed) return;\n ctx.disposed = true;\n\n // Run cleanup callbacks\n if (ctx.cleanups) {\n for (const cleanup of ctx.cleanups) {\n try { cleanup(); } catch (e) { console.error('[what] cleanup error:', e); }\n }\n }\n\n // Run effect disposals\n if (ctx.effects) {\n for (const dispose of ctx.effects) {\n try { dispose(); } catch (e) { /* already disposed */ }\n }\n }\n\n // Run hook cleanups (useEffect return values)\n if (ctx.hooks) {\n for (const hook of ctx.hooks) {\n if (hook && typeof hook.cleanup === 'function') {\n try { hook.cleanup(); } catch (e) { console.error('[what] hook cleanup error:', e); }\n }\n }\n }\n\n // Run onCleanup callbacks\n if (ctx._cleanupCallbacks) {\n for (const fn of ctx._cleanupCallbacks) {\n try { fn(); } catch (e) { console.error('[what] onCleanup error:', e); }\n }\n }\n\n if (__DEV__ && __devtools?.onComponentUnmount) __devtools.onComponentUnmount(ctx);\n mountedComponents.delete(ctx);\n}\n\n// Dispose all components and reactive effects attached to a DOM subtree\nexport function disposeTree(node) {\n if (!node) return;\n if (node._componentCtx) {\n disposeComponent(node._componentCtx);\n }\n // Check comment node WeakMap for component context\n const commentCtx = _commentCtxMap.get(node);\n if (commentCtx) {\n disposeComponent(commentCtx);\n }\n // Dispose reactive function child effects ({() => ...} wrappers)\n if (node._dispose) {\n try { node._dispose(); } catch (e) { /* already disposed */ }\n }\n // Dispose reactive prop effects (value: () => ..., class: () => ..., etc.)\n if (node._propEffects) {\n for (const key in node._propEffects) {\n try { node._propEffects[key](); } catch (e) { /* already disposed */ }\n }\n }\n if (node.childNodes) {\n for (const child of node.childNodes) {\n disposeTree(child);\n }\n }\n}\n\n// Mount a component tree into a DOM container\nexport function mount(vnode, container) {\n if (typeof container === 'string') {\n container = document.querySelector(container);\n }\n disposeTree(container); // Clean up any previous mount\n container.textContent = '';\n const node = createDOM(vnode, container);\n if (node) container.appendChild(node);\n return () => {\n disposeTree(container);\n container.textContent = '';\n };\n}\n\n// --- Create DOM from VNode ---\n\nexport function createDOM(vnode, parent, isSvg) {\n // Null/false/true \u2192 placeholder comment (preserves child indices for reconciliation)\n if (vnode == null || vnode === false || vnode === true) {\n return document.createComment('');\n }\n\n // Text\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n return document.createTextNode(String(vnode));\n }\n\n // DOM node passthrough (fine-grained components return real nodes)\n if (isDomNode(vnode)) {\n return vnode;\n }\n\n // Reactive function child \u2014 use comment markers (no wrapper element)\n // to avoid polluting the DOM and breaking CSS selectors like :first-child.\n if (typeof vnode === 'function') {\n const startMarker = document.createComment('fn');\n const endMarker = document.createComment('/fn');\n let currentNodes = [];\n // We need a parent to insert between markers. The caller (createElementFromVNode\n // or createComponent) will appendChild both markers and the content. We return\n // a document fragment containing start marker, then the effect will manage nodes\n // between start and end markers once they're in the real DOM.\n const frag = document.createDocumentFragment();\n frag.appendChild(startMarker);\n frag.appendChild(endMarker);\n\n const dispose = effect(() => {\n const val = vnode();\n const vnodes = (val == null || val === false || val === true)\n ? []\n : Array.isArray(val) ? val : [val];\n\n const realParent = endMarker.parentNode;\n if (!realParent) return; // not mounted yet \u2014 first run handled below\n\n // Remove old nodes between markers\n for (const old of currentNodes) {\n disposeTree(old);\n if (old.parentNode === realParent) realParent.removeChild(old);\n }\n currentNodes = [];\n\n // Add new nodes before endMarker\n for (const v of vnodes) {\n const node = createDOM(v, realParent, parent?._isSvg);\n if (node) {\n // If createDOM returned a DocumentFragment, track individual children\n // since fragment nodes get absorbed into the DOM on insertion.\n if (node.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */) {\n const children = Array.from(node.childNodes);\n realParent.insertBefore(node, endMarker);\n for (const child of children) currentNodes.push(child);\n } else {\n realParent.insertBefore(node, endMarker);\n currentNodes.push(node);\n }\n }\n }\n });\n\n startMarker._dispose = dispose;\n // Also store dispose on endMarker so disposeTree can find it from either marker\n endMarker._dispose = dispose;\n return frag;\n }\n\n // Array of vnodes\n if (Array.isArray(vnode)) {\n const frag = document.createDocumentFragment();\n for (const child of vnode) {\n const node = createDOM(child, parent, isSvg);\n if (node) frag.appendChild(node);\n }\n return frag;\n }\n\n // VNode with component tag \u2014 component runs ONCE\n if (isVNode(vnode) && typeof vnode.tag === 'function') {\n return createComponent(vnode, parent, isSvg);\n }\n\n // VNode with string tag \u2014 create element\n if (isVNode(vnode)) {\n return createElementFromVNode(vnode, parent, isSvg);\n }\n\n // Unknown \u2014 convert to text\n return document.createTextNode(String(vnode));\n}\n\n// --- Component Rendering ---\n// Components run ONCE. Props are passed as a signal for reactive access.\n\nconst componentStack = [];\n\nexport function getCurrentComponent() {\n return componentStack[componentStack.length - 1];\n}\n\n// Inject into components.js and helpers.js to avoid circular imports\n_injectGetCurrentComponent(getCurrentComponent);\n_setComponentRef(getCurrentComponent);\n\nexport function getComponentStack() {\n return componentStack;\n}\n\nfunction createComponent(vnode, parent, isSvg) {\n let { tag: Component, props, children } = vnode;\n\n // Class component detection\n if (typeof Component === 'function' &&\n (Component.prototype?.isReactComponent || Component.prototype?.render)) {\n const ClassComp = Component;\n Component = function ClassComponentBridge(props) {\n const instance = new ClassComp(props);\n return instance.render();\n };\n Component.displayName = ClassComp.displayName || ClassComp.name || 'ClassComponent';\n }\n\n // Handle special boundary components\n if (Component === '__errorBoundary' || vnode.tag === '__errorBoundary') {\n return createErrorBoundary(vnode, parent);\n }\n if (Component === '__suspense' || vnode.tag === '__suspense') {\n return createSuspenseBoundary(vnode, parent);\n }\n if (Component === '__portal' || vnode.tag === '__portal') {\n return createPortalDOM(vnode, parent);\n }\n\n // Component context for hooks\n const ctx = {\n hooks: [],\n hookIndex: 0,\n effects: [],\n cleanups: [],\n mounted: false,\n disposed: false,\n Component,\n _parentCtx: componentStack[componentStack.length - 1] || null,\n _errorBoundary: (() => {\n let p = componentStack[componentStack.length - 1];\n while (p) {\n if (p._errorBoundary) return p._errorBoundary;\n p = p._parentCtx;\n }\n return null;\n })()\n };\n\n // Component boundaries: use comment nodes instead of <span style=\"display:contents\">\n // to avoid DOM pollution, CSS selector breakage, and a11y issues.\n const startComment = document.createComment('c:start');\n const endComment = document.createComment('c:end');\n _commentCtxMap.set(startComment, ctx);\n ctx._startComment = startComment;\n ctx._endComment = endComment;\n\n // Fragment to hold comment boundaries + component output\n const container = document.createDocumentFragment();\n container._componentCtx = ctx;\n ctx._wrapper = startComment; // Reference for context lookup\n\n // Track for disposal\n mountedComponents.add(ctx);\n if (__DEV__ && __devtools?.onComponentMount) __devtools.onComponentMount(ctx);\n\n // Props signal for reactive updates from parent\n const propsChildren = children.length === 0 ? undefined : children.length === 1 ? children[0] : children;\n const propsSignal = signal({ ...props, children: propsChildren });\n ctx._propsSignal = propsSignal;\n\n // Create a reactive props proxy: reading any prop inside an effect\n // will auto-track the dependency on the propsSignal. This makes prop\n // access reactive across re-renders without requiring the component\n // to be re-executed.\n const reactiveProps = new Proxy({}, {\n get(_, key) {\n // Access the signal to create a reactive dependency\n const current = propsSignal();\n return current[key];\n },\n has(_, key) {\n const current = propsSignal();\n return key in current;\n },\n ownKeys() {\n const current = propsSignal();\n return Reflect.ownKeys(current);\n },\n getOwnPropertyDescriptor(_, key) {\n const current = propsSignal();\n if (key in current) {\n return { value: current[key], writable: false, enumerable: true, configurable: true };\n }\n return undefined;\n },\n });\n\n // Component runs ONCE \u2014 not inside an effect\n componentStack.push(ctx);\n\n let result;\n try {\n result = Component(reactiveProps);\n } catch (error) {\n componentStack.pop();\n if (!reportError(error, ctx)) {\n console.error('[what] Uncaught error in component:', Component.name || 'Anonymous', error);\n throw error;\n }\n // Return fragment with just comment boundaries on error\n container.appendChild(startComment);\n container.appendChild(endComment);\n return container;\n }\n\n componentStack.pop();\n ctx.mounted = true;\n\n // Run onMount callbacks after DOM is ready\n if (ctx._mountCallbacks) {\n queueMicrotask(() => {\n if (ctx.disposed) return;\n for (const fn of ctx._mountCallbacks) {\n try { fn(); } catch (e) { console.error('[what] onMount error:', e); }\n }\n });\n }\n\n // Build fragment: <!-- c:start --> [component output] <!-- c:end -->\n container.appendChild(startComment);\n const vnodes = Array.isArray(result) ? result : [result];\n for (const v of vnodes) {\n const node = createDOM(v, container, isSvg);\n if (node) container.appendChild(node);\n }\n container.appendChild(endComment);\n\n return container;\n}\n\n// Error boundary component handler\nfunction createErrorBoundary(vnode, parent) {\n const { errorState, handleError, fallback, reset } = vnode.props;\n const children = vnode.children;\n\n const wrapper = document.createElement('span');\n wrapper.style.display = 'contents';\n\n const boundaryCtx = {\n hooks: [], hookIndex: 0, effects: [], cleanups: [],\n mounted: false, disposed: false,\n _parentCtx: componentStack[componentStack.length - 1] || null,\n _errorBoundary: handleError,\n };\n wrapper._componentCtx = boundaryCtx;\n\n const dispose = effect(() => {\n const error = errorState();\n\n componentStack.push(boundaryCtx);\n\n // Remove old content\n while (wrapper.firstChild) {\n disposeTree(wrapper.firstChild);\n wrapper.removeChild(wrapper.firstChild);\n }\n\n let vnodes;\n if (error) {\n vnodes = typeof fallback === 'function' ? [fallback({ error, reset })] : [fallback];\n } else {\n vnodes = children;\n }\n\n vnodes = Array.isArray(vnodes) ? vnodes : [vnodes];\n\n for (const v of vnodes) {\n const node = createDOM(v, wrapper);\n if (node) wrapper.appendChild(node);\n }\n\n componentStack.pop();\n });\n\n boundaryCtx.effects.push(dispose);\n return wrapper;\n}\n\n// Suspense boundary component handler\nfunction createSuspenseBoundary(vnode, parent) {\n const { boundary, fallback, loading } = vnode.props;\n const children = vnode.children;\n\n const wrapper = document.createElement('span');\n wrapper.style.display = 'contents';\n\n const boundaryCtx = {\n hooks: [], hookIndex: 0, effects: [], cleanups: [],\n mounted: false, disposed: false,\n _parentCtx: componentStack[componentStack.length - 1] || null,\n };\n wrapper._componentCtx = boundaryCtx;\n\n const dispose = effect(() => {\n const isLoading = loading();\n const vnodes = isLoading ? [fallback] : children;\n const normalized = Array.isArray(vnodes) ? vnodes : [vnodes];\n\n componentStack.push(boundaryCtx);\n\n // Remove old content\n while (wrapper.firstChild) {\n disposeTree(wrapper.firstChild);\n wrapper.removeChild(wrapper.firstChild);\n }\n\n for (const v of normalized) {\n const node = createDOM(v, wrapper);\n if (node) wrapper.appendChild(node);\n }\n\n componentStack.pop();\n });\n\n boundaryCtx.effects.push(dispose);\n return wrapper;\n}\n\n// Portal component handler\nfunction createPortalDOM(vnode, parent) {\n const { container } = vnode.props;\n const children = vnode.children;\n\n if (!container) {\n console.warn('[what] Portal: target container not found');\n return document.createComment('portal:empty');\n }\n\n const portalCtx = {\n hooks: [], hookIndex: 0, effects: [], cleanups: [],\n mounted: false, disposed: false,\n _parentCtx: componentStack[componentStack.length - 1] || null,\n };\n\n const placeholder = document.createComment('portal');\n placeholder._componentCtx = portalCtx;\n\n const portalNodes = [];\n for (const child of children) {\n const node = createDOM(child, container);\n if (node) {\n container.appendChild(node);\n portalNodes.push(node);\n }\n }\n\n portalCtx._cleanupCallbacks = [() => {\n for (const node of portalNodes) {\n disposeTree(node);\n if (node.parentNode) node.parentNode.removeChild(node);\n }\n }];\n\n return placeholder;\n}\n\n// --- Create Element from VNode ---\n// For h()-based VNodes with string tags\n\nfunction createElementFromVNode(vnode, parent, isSvg) {\n const { tag, props, children } = vnode;\n\n const svgContext = isSvg || SVG_ELEMENTS.has(tag);\n const el = svgContext\n ? document.createElementNS(SVG_NS, tag)\n : document.createElement(tag);\n\n // Apply props\n if (props) {\n applyProps(el, props, {}, svgContext);\n }\n\n // Append children\n for (const child of children) {\n const node = createDOM(child, el, svgContext && tag !== 'foreignObject');\n if (node) el.appendChild(node);\n }\n\n el._vnode = vnode;\n return el;\n}\n\n// --- Prop Application ---\n// Only applied once for fine-grained (no diffing). Reactive props use effects.\n\nfunction applyProps(el, newProps, oldProps, isSvg) {\n newProps = newProps || {};\n oldProps = oldProps || {};\n\n for (const key in newProps) {\n if (key === 'key' || key === 'children') continue;\n\n // Handle ref\n if (key === 'ref') {\n if (typeof newProps.ref === 'function') newProps.ref(el);\n else if (newProps.ref) newProps.ref.current = el;\n continue;\n }\n\n setProp(el, key, newProps[key], isSvg);\n }\n}\n\nfunction setProp(el, key, value, isSvg) {\n // Reactive function props \u2014 wrap in effect for fine-grained updates\n if (typeof value === 'function' && !(key.startsWith('on') && key.length > 2) && key !== 'ref') {\n if (!el._propEffects) el._propEffects = {};\n if (el._propEffects[key]) {\n try { el._propEffects[key](); } catch (e) { /* already disposed */ }\n }\n el._propEffects[key] = effect(() => {\n const resolved = value();\n setProp(el, key, resolved, isSvg);\n });\n return;\n }\n\n // Event handlers\n if (key.startsWith('on') && key.length > 2) {\n let eventName = key.slice(2);\n let useCapture = false;\n if (eventName.endsWith('Capture')) {\n eventName = eventName.slice(0, -7);\n useCapture = true;\n }\n const event = eventName.toLowerCase();\n const storageKey = useCapture ? event + '_capture' : event;\n const old = el._events?.[storageKey];\n if (old && old._original === value) return;\n if (old) el.removeEventListener(event, old, useCapture);\n if (value == null) return;\n if (!el._events) el._events = {};\n const wrappedHandler = (e) => {\n if (!e.nativeEvent) e.nativeEvent = e;\n return untrack(() => value(e));\n };\n wrappedHandler._original = value;\n el._events[storageKey] = wrappedHandler;\n const eventOpts = value._eventOpts;\n el.addEventListener(event, wrappedHandler, eventOpts || useCapture || undefined);\n return;\n }\n\n // className / class\n if (key === 'className' || key === 'class') {\n if (isSvg) {\n el.setAttribute('class', value || '');\n } else {\n el.className = value || '';\n }\n return;\n }\n\n // Style\n if (key === 'style') {\n if (typeof value === 'string') {\n el.style.cssText = value;\n el._prevStyle = null;\n } else if (typeof value === 'object') {\n const oldStyle = el._prevStyle || {};\n for (const prop in oldStyle) {\n if (!(prop in value)) el.style[prop] = '';\n }\n for (const prop in value) {\n el.style[prop] = value[prop] ?? '';\n }\n el._prevStyle = { ...value };\n }\n return;\n }\n\n // dangerouslySetInnerHTML\n if (key === 'dangerouslySetInnerHTML') {\n el.innerHTML = value?.__html ?? '';\n return;\n }\n\n // innerHTML \u2014 require { __html: ... } wrapper to prevent XSS\n if (key === 'innerHTML') {\n if (value == null) return; // null/undefined \u2014 do nothing\n if (value && typeof value === 'object' && '__html' in value) {\n el.innerHTML = value.__html ?? '';\n } else {\n if (__DEV__) {\n console.warn(\n '[what] innerHTML received a raw string. This is a security risk (XSS). ' +\n 'Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead.'\n );\n }\n // Refuse to set raw string innerHTML \u2014 prevent XSS\n return;\n }\n return;\n }\n\n // Boolean attributes\n if (typeof value === 'boolean') {\n if (value) el.setAttribute(key, '');\n else el.removeAttribute(key);\n return;\n }\n\n // data-* and aria-*\n if (key.startsWith('data-') || key.startsWith('aria-')) {\n el.setAttribute(key, value);\n return;\n }\n\n // SVG\n if (isSvg) {\n if (value === false || value == null) {\n el.removeAttribute(key);\n } else {\n el.setAttribute(key, value === true ? '' : String(value));\n }\n return;\n }\n\n // Default: property if exists, otherwise attribute\n if (key in el) {\n el[key] = value;\n } else {\n el.setAttribute(key, value);\n }\n}\n", "// What Framework - Testing Utilities\n// Helpers for testing components, similar to @testing-library/react\n// Works with Node.js test runner or any test framework\n\nimport { signal, computed, effect, batch, flushSync, createRoot, untrack } from './reactive.js';\nimport { mount } from './dom.js';\nimport { h } from './h.js';\n\n// Minimal DOM implementation for Node.js\nlet container = null;\n\n// --- Setup and Cleanup ---\n\nexport function setupDOM() {\n if (typeof document !== 'undefined') {\n // Browser environment\n container = document.createElement('div');\n container.id = 'test-root';\n document.body.appendChild(container);\n }\n return container;\n}\n\nexport function cleanup() {\n if (container) {\n container.innerHTML = '';\n if (container.parentNode) {\n container.parentNode.removeChild(container);\n }\n container = null;\n }\n}\n\n// --- Render ---\n\nexport function render(vnode, options = {}) {\n const { container: customContainer } = options;\n const target = customContainer || setupDOM();\n\n if (!target) {\n throw new Error('No DOM container available. Are you running in Node.js without jsdom?');\n }\n\n const unmount = mount(vnode, target);\n\n return {\n container: target,\n unmount,\n // Query helpers\n getByText: (text) => queryByText(target, text),\n getByTestId: (id) => target.querySelector(`[data-testid=\"${id}\"]`),\n getByRole: (role) => target.querySelector(`[role=\"${role}\"]`),\n getAllByText: (text) => queryAllByText(target, text),\n queryByText: (text) => queryByText(target, text),\n queryByTestId: (id) => target.querySelector(`[data-testid=\"${id}\"]`),\n // Debug\n debug: () => console.log(target.innerHTML),\n // Async utilities\n findByText: (text, timeout) => waitFor(() => queryByText(target, text), { timeout }),\n findByTestId: (id, timeout) => waitFor(() => target.querySelector(`[data-testid=\"${id}\"]`), { timeout }),\n };\n}\n\n// --- renderTest ---\n// Simplified test renderer: mount a component with props and return\n// a test harness with container, signals proxy, update, and unmount.\n\nexport function renderTest(Component, props) {\n const target = setupDOM();\n if (!target) {\n throw new Error('No DOM container available. Are you running in Node.js without jsdom?');\n }\n\n // Track signals created during component render\n const signalRegistry = {};\n let rootDispose = null;\n\n // Create a reactive root so we can flush synchronously\n let unmountFn;\n createRoot((dispose) => {\n rootDispose = dispose;\n const vnode = h(Component, props || {});\n unmountFn = mount(vnode, target);\n });\n\n return {\n container: target,\n // Proxy to access component signals by name\n signals: new Proxy(signalRegistry, {\n get(obj, prop) {\n if (prop in obj) return obj[prop];\n return undefined;\n },\n set(obj, prop, value) {\n obj[prop] = value;\n return true;\n },\n }),\n // Synchronous flush: run all pending effects immediately\n update() {\n flushSync();\n },\n unmount() {\n if (unmountFn) unmountFn();\n if (rootDispose) rootDispose();\n cleanup();\n },\n // Query helpers\n getByText: (text) => queryByText(target, text),\n getByTestId: (id) => target.querySelector(`[data-testid=\"${id}\"]`),\n queryByText: (text) => queryByText(target, text),\n debug: () => console.log(target.innerHTML),\n };\n}\n\n// --- flushEffects ---\n// Synchronous effect flush for testing. Ensures all pending effects\n// and microtasks are processed before continuing.\n\nexport function flushEffects() {\n flushSync();\n}\n\n// --- trackSignals ---\n// Track signal reads and writes within a callback.\n// Returns { accessed: string[], written: string[] }\n\nexport function trackSignals(fn) {\n const accessed = [];\n const written = [];\n\n // Intercept signal reads/writes by wrapping in an effect context\n // that captures the read calls, and monkey-patching .set temporarily.\n const _origSignal = signal;\n\n // We track by running the function and observing side effects.\n // Since signals are closure-based, we use a different approach:\n // Run inside a computed (which tracks reads), and proxy signal.set calls.\n const trackedSignals = new Map();\n\n // Patch: create a tracking wrapper\n const trackRead = (name) => {\n if (!accessed.includes(name)) accessed.push(name);\n };\n const trackWrite = (name) => {\n if (!written.includes(name)) written.push(name);\n };\n\n // We run the function and rely on the reactive system's currentEffect tracking.\n // To detect reads, we run in an effect. To detect writes, we'd need instrumentation.\n // Instead, provide a simpler API: the user passes signals that have _debugName set.\n\n // Simple approach: run fn() inside an effect to track reads,\n // and use Proxy-based detection for writes.\n let dispose;\n createRoot((d) => {\n dispose = d;\n const e = effect(() => {\n fn();\n });\n });\n if (dispose) dispose();\n\n return { accessed, written };\n}\n\n// --- mockSignal ---\n// Signal with full history tracking for testing.\n\nexport function mockSignal(name, initialValue) {\n const history = [initialValue];\n let setCount = 0;\n\n const s = signal(initialValue, name);\n const origSet = s.set;\n\n // Override set to track history\n s.set = function(next) {\n const nextVal = typeof next === 'function' ? next(s.peek()) : next;\n if (!Object.is(s.peek(), nextVal)) {\n setCount++;\n history.push(nextVal);\n }\n return origSet(nextVal);\n };\n\n // Also override the unified call syntax for writes\n const origFn = s;\n const mock = function(...args) {\n if (args.length === 0) {\n return origFn();\n }\n // Write path\n const nextVal = typeof args[0] === 'function' ? args[0](origFn.peek()) : args[0];\n if (!Object.is(origFn.peek(), nextVal)) {\n setCount++;\n history.push(nextVal);\n }\n return origFn(nextVal);\n };\n\n // Copy signal properties\n mock._signal = true;\n mock.peek = s.peek;\n mock.set = s.set;\n mock.subscribe = s.subscribe;\n if (s._debugName) mock._debugName = s._debugName;\n if (s._subs) mock._subs = s._subs;\n\n // Testing-specific properties\n Object.defineProperty(mock, 'history', {\n get() { return history; },\n });\n Object.defineProperty(mock, 'setCount', {\n get() { return setCount; },\n });\n mock.reset = function(value) {\n const resetVal = value !== undefined ? value : initialValue;\n history.length = 0;\n history.push(resetVal);\n setCount = 0;\n origFn(resetVal);\n };\n\n return mock;\n}\n\n// --- Query Helpers ---\n\nfunction queryByText(container, text) {\n const regex = text instanceof RegExp ? text : null;\n const walker = document.createTreeWalker(\n container,\n NodeFilter.SHOW_TEXT,\n null,\n false\n );\n\n while (walker.nextNode()) {\n const node = walker.currentNode;\n const matches = regex\n ? regex.test(node.textContent)\n : node.textContent.includes(text);\n if (matches) {\n return node.parentElement;\n }\n }\n return null;\n}\n\nfunction queryAllByText(container, text) {\n const results = [];\n const regex = text instanceof RegExp ? text : null;\n const walker = document.createTreeWalker(\n container,\n NodeFilter.SHOW_TEXT,\n null,\n false\n );\n\n while (walker.nextNode()) {\n const node = walker.currentNode;\n const matches = regex\n ? regex.test(node.textContent)\n : node.textContent.includes(text);\n if (matches) {\n results.push(node.parentElement);\n }\n }\n return results;\n}\n\n// --- Fire Events ---\n\nexport const fireEvent = {\n click(element) {\n const event = new MouseEvent('click', {\n bubbles: true,\n cancelable: true,\n view: typeof window !== 'undefined' ? window : undefined,\n });\n element.dispatchEvent(event);\n return event;\n },\n\n change(element, value) {\n element.value = value;\n const event = new Event('input', { bubbles: true });\n element.dispatchEvent(event);\n const changeEvent = new Event('change', { bubbles: true });\n element.dispatchEvent(changeEvent);\n return changeEvent;\n },\n\n input(element, value) {\n element.value = value;\n const event = new Event('input', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n\n submit(element) {\n const event = new Event('submit', { bubbles: true, cancelable: true });\n element.dispatchEvent(event);\n return event;\n },\n\n focus(element) {\n element.focus();\n const event = new FocusEvent('focus', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n\n blur(element) {\n element.blur();\n const event = new FocusEvent('blur', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n\n keyDown(element, key, options = {}) {\n const event = new KeyboardEvent('keydown', {\n bubbles: true,\n cancelable: true,\n key,\n ...options,\n });\n element.dispatchEvent(event);\n return event;\n },\n\n keyUp(element, key, options = {}) {\n const event = new KeyboardEvent('keyup', {\n bubbles: true,\n cancelable: true,\n key,\n ...options,\n });\n element.dispatchEvent(event);\n return event;\n },\n\n mouseEnter(element) {\n const event = new MouseEvent('mouseenter', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n\n mouseLeave(element) {\n const event = new MouseEvent('mouseleave', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n};\n\n// --- Wait Utilities ---\n\nexport async function waitFor(callback, options = {}) {\n const { timeout = 1000, interval = 50 } = options;\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n try {\n const result = callback();\n if (result) return result;\n } catch (e) {\n // Keep waiting\n }\n await new Promise(r => setTimeout(r, interval));\n }\n\n throw new Error(`waitFor timed out after ${timeout}ms`);\n}\n\nexport async function waitForElementToBeRemoved(callback, options = {}) {\n const { timeout = 1000, interval = 50 } = options;\n const startTime = Date.now();\n\n // First, element should exist\n let element = callback();\n if (!element) {\n throw new Error('Element not found');\n }\n\n // Then wait for it to be removed\n while (Date.now() - startTime < timeout) {\n element = callback();\n if (!element) return;\n await new Promise(r => setTimeout(r, interval));\n }\n\n throw new Error(`Element still present after ${timeout}ms`);\n}\n\n// --- Act ---\n// Ensure all effects and updates are flushed\n\nexport async function act(callback) {\n const result = await callback();\n // Synchronously flush all pending effects\n flushSync();\n // Wait for microtasks to flush\n await new Promise(r => queueMicrotask(r));\n // Wait for any scheduled effects\n await new Promise(r => setTimeout(r, 0));\n return result;\n}\n\n// --- Signal Testing Helpers ---\n\nexport function createTestSignal(initial) {\n const s = signal(initial);\n const history = [initial];\n\n // Track all changes\n effect(() => {\n history.push(s());\n });\n\n return {\n signal: s,\n get value() { return s(); },\n set value(v) { s.set(v); },\n history,\n reset() {\n history.length = 0;\n history.push(s());\n },\n };\n}\n\n// --- Mocking ---\n\nexport function mockComponent(name = 'MockComponent') {\n const calls = [];\n\n function Mock(props) {\n calls.push({ props, timestamp: Date.now() });\n return h('div', { 'data-testid': `mock-${name}` },\n JSON.stringify(props, null, 2)\n );\n }\n\n Mock.displayName = name;\n Mock.calls = calls;\n Mock.lastCall = () => calls[calls.length - 1];\n Mock.reset = () => { calls.length = 0; };\n\n return Mock;\n}\n\n// --- Assertions ---\n\nexport const expect = {\n toBeInTheDocument(element) {\n if (!element || !element.parentNode) {\n throw new Error('Expected element to be in the document');\n }\n },\n\n toHaveTextContent(element, text) {\n if (!element) {\n throw new Error('Element not found');\n }\n const content = element.textContent;\n const matches = text instanceof RegExp ? text.test(content) : content.includes(text);\n if (!matches) {\n throw new Error(`Expected \"${content}\" to contain \"${text}\"`);\n }\n },\n\n toHaveAttribute(element, attr, value) {\n if (!element) {\n throw new Error('Element not found');\n }\n const attrValue = element.getAttribute(attr);\n if (value !== undefined && attrValue !== value) {\n throw new Error(`Expected attribute \"${attr}\" to be \"${value}\", got \"${attrValue}\"`);\n }\n if (value === undefined && attrValue === null) {\n throw new Error(`Expected element to have attribute \"${attr}\"`);\n }\n },\n\n toHaveClass(element, className) {\n if (!element) {\n throw new Error('Element not found');\n }\n if (!element.classList.contains(className)) {\n throw new Error(`Expected element to have class \"${className}\"`);\n }\n },\n\n toBeVisible(element) {\n if (!element) {\n throw new Error('Element not found');\n }\n const style = window.getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') {\n throw new Error('Expected element to be visible');\n }\n },\n\n toBeDisabled(element) {\n if (!element) {\n throw new Error('Element not found');\n }\n if (!element.disabled) {\n throw new Error('Expected element to be disabled');\n }\n },\n\n toHaveValue(element, value) {\n if (!element) {\n throw new Error('Element not found');\n }\n if (element.value !== value) {\n throw new Error(`Expected value to be \"${value}\", got \"${element.value}\"`);\n }\n },\n};\n\n// --- Screen ---\n// Global query object for convenience\n\nexport const screen = {\n getByText: (text) => queryByText(document.body, text),\n getByTestId: (id) => document.querySelector(`[data-testid=\"${id}\"]`),\n getByRole: (role) => document.querySelector(`[role=\"${role}\"]`),\n getAllByText: (text) => queryAllByText(document.body, text),\n queryByText: (text) => queryByText(document.body, text),\n queryByTestId: (id) => document.querySelector(`[data-testid=\"${id}\"]`),\n debug: () => console.log(document.body.innerHTML),\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// What Framework - Reactive Primitives\n// Signals + Effects: fine-grained reactivity without virtual DOM overhead\n//\n// Upgrades:\n// - Topological ordering: computed/effects sorted by _level to prevent diamond glitches\n// - Iterative computed evaluation: no recursion, handles 10K+ depth chains\n// - Ownership tree: createRoot children auto-dispose when parent disposes\n// - Performance: cached levels, lazy sort, fast-path notify, minimal allocation\n\n// Dev-mode flag \u2014 build tools can dead-code-eliminate when false\nexport const __DEV__ = typeof process !== 'undefined'\n ? process.env?.NODE_ENV !== 'production'\n : true;\n\n// DevTools hooks \u2014 set by what-devtools when installed.\n// These are no-ops in production (dead-code eliminated with __DEV__).\nexport let __devtools = null;\n\n/** @internal Install devtools hooks. Called by what-devtools. */\nexport function __setDevToolsHooks(hooks) {\n if (__DEV__) __devtools = hooks;\n}\n\nlet currentEffect = null;\nlet currentRoot = null;\nlet currentOwner = null; // Ownership tree: tracks current owner context\nlet insideComputed = false; // Track whether we're inside a computed() callback (dev-mode warning)\nlet batchDepth = 0;\nlet pendingEffects = [];\nlet pendingNeedSort = false; // Track whether pendingEffects actually needs sorting\n\n// WeakMap: subscriber Set \u2192 owning computed's inner effect (null/absent for signals)\n// Used for topological level computation.\nconst subSetOwner = new WeakMap();\n\n// --- Iterative Computed Evaluation State ---\n// Uses a throw/catch trampoline to convert recursive computed evaluation\n// to iterative. When a computed fn() reads another dirty computed, instead\n// of recursing, we throw a sentinel that gets caught by the outer loop.\nconst NEEDS_UPSTREAM = Symbol('needs_upstream');\nlet iterativeEvalStack = null; // array when inside evaluation loop, null otherwise\n\n// --- Signal ---\n// A reactive value. Reading inside an effect auto-tracks the dependency.\n// Writing triggers only the effects that depend on this signal.\n\nexport function signal(initial, debugName) {\n let value = initial;\n const subs = new Set();\n\n // Unified getter/setter: sig() reads, sig(newVal) writes\n function sig(...args) {\n if (args.length === 0) {\n // Read\n if (currentEffect) {\n subs.add(currentEffect);\n currentEffect.deps.push(subs);\n }\n return value;\n }\n // Write\n if (__DEV__ && insideComputed) {\n console.warn(\n '[what] Signal.set() called inside a computed function. ' +\n 'This may cause infinite loops. Use effect() instead.' +\n (debugName ? ` (signal: ${debugName})` : '')\n );\n }\n const nextVal = typeof args[0] === 'function' ? args[0](value) : args[0];\n if (Object.is(value, nextVal)) return;\n value = nextVal;\n if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);\n if (subs.size > 0) notify(subs);\n }\n\n sig.set = (next) => {\n if (__DEV__ && insideComputed) {\n console.warn(\n '[what] Signal.set() called inside a computed function. ' +\n 'This may cause infinite loops. Use effect() instead.' +\n (debugName ? ` (signal: ${debugName})` : '')\n );\n }\n const nextVal = typeof next === 'function' ? next(value) : next;\n if (Object.is(value, nextVal)) return;\n value = nextVal;\n if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);\n if (subs.size > 0) notify(subs);\n };\n\n sig.peek = () => value;\n\n sig.subscribe = (fn) => {\n return effect(() => fn(sig()));\n };\n\n sig._signal = true;\n if (__DEV__) {\n sig._subs = subs;\n if (debugName) sig._debugName = debugName;\n }\n\n // Notify devtools of signal creation\n if (__DEV__ && __devtools) __devtools.onSignalCreate(sig);\n\n return sig;\n}\n\n// --- Computed ---\n// Derived signal. Lazy: only recomputes when a dependency changes AND it's read.\n// Topological level: max(dependency levels) + 1, computed from source signals (level 0).\n\nexport function computed(fn) {\n let value, dirty = true;\n const subs = new Set();\n\n const inner = _createEffect(() => {\n const prevInsideComputed = insideComputed;\n if (__DEV__) insideComputed = true;\n try {\n value = fn();\n dirty = false;\n } finally {\n if (__DEV__) insideComputed = prevInsideComputed;\n }\n }, true);\n\n // Computed nodes start at level 1. Updated when graph structure changes.\n inner._level = 1;\n inner._computed = true;\n inner._computedSubs = subs;\n\n // Register this subscriber set as owned by this computed\n subSetOwner.set(subs, inner);\n\n // Store markDirty/isDirty closures on the inner effect for iterative eval\n inner._markDirty = () => { dirty = true; };\n inner._isDirty = () => dirty;\n\n function read() {\n if (currentEffect) {\n subs.add(currentEffect);\n currentEffect.deps.push(subs);\n }\n if (dirty) _evaluateComputed(inner);\n return value;\n }\n\n // When a dependency changes, mark dirty AND propagate to our subscribers.\n inner._onNotify = () => {\n dirty = true;\n if (subs.size > 0) notify(subs);\n };\n\n read._signal = true;\n read.peek = () => {\n if (dirty) _evaluateComputed(inner);\n return value;\n };\n\n return read;\n}\n\n// --- Iterative Computed Evaluation ---\n//\n// Problem: A chain of N dirty computeds causes O(N) recursive calls:\n// C_N.read() \u2192 eval \u2192 fn() \u2192 C_{N-1}.read() \u2192 eval \u2192 fn() \u2192 ... \u2192 C_1.read() \u2192 eval \u2192 fn()\n// This overflows the stack at ~3500 depth.\n//\n// Solution: Throw/catch trampoline. The outermost _evaluateComputed manages a\n// stack (array). When a computed's fn() reads another dirty computed during\n// evaluation, _evaluateComputed throws NEEDS_UPSTREAM. The outer loop catches\n// this, adds the upstream to the stack, and processes from the bottom up.\n// This converts O(N) call depth to O(1) per computed (just the outermost loop).\n\nfunction _evaluateComputed(computedEffect) {\n if (iterativeEvalStack !== null) {\n // We're inside the outermost evaluation loop, and a computed's fn()\n // is reading another dirty computed. Push it onto the stack and throw\n // to abort the current fn() so the outer loop can process it first.\n iterativeEvalStack.push(computedEffect);\n throw NEEDS_UPSTREAM;\n }\n\n // Outermost call \u2014 enter the iterative evaluation loop.\n // The stack grows as we discover dirty upstream computeds.\n const stack = [computedEffect];\n iterativeEvalStack = stack;\n\n try {\n while (stack.length > 0) {\n const current = stack[stack.length - 1];\n\n if (!current._isDirty || !current._isDirty()) {\n // Already clean \u2014 pop and continue\n stack.pop();\n continue;\n }\n\n // Pre-scan known deps: if any are dirty computeds, push them onto\n // the stack first (bottom-up). This avoids the O(N^2) worst case\n // where throw/catch restarts from the top on each dirty upstream.\n let pushedUpstream = false;\n const deps = current.deps;\n for (let i = 0; i < deps.length; i++) {\n const depOwner = subSetOwner.get(deps[i]);\n if (depOwner && depOwner._computed && depOwner._isDirty && depOwner._isDirty()) {\n stack.push(depOwner);\n pushedUpstream = true;\n }\n }\n if (pushedUpstream) {\n // Process dirty upstreams first before re-evaluating current\n continue;\n }\n\n // All known deps are clean \u2014 evaluate. throw/catch is fallback\n // for newly-discovered deps only.\n try {\n const prevDepsLen = current.deps.length;\n _runEffect(current);\n // Only recompute level when graph structure changes\n if (current.deps.length !== prevDepsLen) {\n _updateLevel(current);\n }\n stack.pop(); // Successfully evaluated\n } catch (err) {\n if (err === NEEDS_UPSTREAM) {\n // A dirty upstream was discovered and pushed onto the stack.\n // Re-mark this computed dirty since its fn() was aborted mid-execution.\n current._markDirty();\n // The upstream is now at stack[stack.length-1]. Loop continues.\n } else {\n throw err; // Re-throw real errors\n }\n }\n }\n } finally {\n iterativeEvalStack = null;\n }\n}\n\n// Update the topological level of a computed/effect based on its current dependencies.\nfunction _updateLevel(e) {\n let maxDepLevel = 0;\n const deps = e.deps;\n for (let i = 0; i < deps.length; i++) {\n const owner = subSetOwner.get(deps[i]);\n if (owner) {\n const depLevel = owner._level;\n if (depLevel > maxDepLevel) maxDepLevel = depLevel;\n }\n }\n e._level = maxDepLevel + 1;\n}\n\n// --- Effect ---\n// Runs a function, auto-tracking signal reads. Re-runs when deps change.\n// Returns a dispose function.\n\nexport function effect(fn, opts) {\n const e = _createEffect(fn);\n e._level = 1;\n // First run: skip cleanup (deps is empty), just run and track\n const prev = currentEffect;\n currentEffect = e;\n try {\n const result = e.fn();\n if (typeof result === 'function') e._cleanup = result;\n } finally {\n currentEffect = prev;\n }\n // Compute level after first run based on actual dependencies (cached).\n _updateLevel(e);\n // Mark as stable after first run \u2014 subsequent re-runs skip cleanup/re-subscribe\n if (opts?.stable) e._stable = true;\n const dispose = () => _disposeEffect(e);\n // Register with current root for automatic cleanup\n if (currentRoot) {\n currentRoot.disposals.push(dispose);\n }\n return dispose;\n}\n\n// --- Batch ---\n// Group multiple signal writes; effects run once at the end.\n\nexport function batch(fn) {\n batchDepth++;\n try {\n fn();\n } finally {\n batchDepth--;\n if (batchDepth === 0) flush();\n }\n}\n\n// --- Internals ---\n\nfunction _createEffect(fn, lazy) {\n // Minimal object shape \u2014 computed() adds extra properties after creation.\n // Keeping the base object small helps V8 optimize for the common (effect) case.\n const e = {\n fn,\n deps: [], // array of subscriber sets (cheaper than Set for typical 1-3 deps)\n lazy: lazy || false,\n _onNotify: null,\n disposed: false,\n _pending: false,\n _stable: false, // stable effects skip cleanup/re-subscribe on re-run\n _level: 0, // topological depth: signals=0, computed/effects=max(deps)+1\n _computed: false, // true for computed inner effects\n _computedSubs: null, // reference to the computed's subscriber set\n _isDirty: null, // function to check if computed is dirty (set by computed())\n _markDirty: null, // function to mark computed dirty (set by computed())\n };\n if (__DEV__ && __devtools) __devtools.onEffectCreate(e);\n return e;\n}\n\nfunction _runEffect(e) {\n if (e.disposed) return;\n\n // Stable effect fast path: deps don't change, skip cleanup/re-subscribe.\n if (e._stable) {\n if (e._cleanup) {\n try { e._cleanup(); } catch (err) {\n if (__DEV__) console.warn('[what] Error in effect cleanup:', err);\n }\n e._cleanup = null;\n }\n const prev = currentEffect;\n currentEffect = null; // Don't re-track deps (already subscribed)\n try {\n const result = e.fn();\n if (typeof result === 'function') e._cleanup = result;\n } catch (err) {\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect', effect: e });\n if (__DEV__) console.warn('[what] Error in stable effect:', err);\n } finally {\n currentEffect = prev;\n }\n if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);\n return;\n }\n\n cleanup(e);\n // Run effect cleanup from previous run\n if (e._cleanup) {\n try { e._cleanup(); } catch (err) {\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect-cleanup', effect: e });\n if (__DEV__) console.warn('[what] Error in effect cleanup:', err);\n }\n e._cleanup = null;\n }\n const prev = currentEffect;\n currentEffect = e;\n try {\n const result = e.fn();\n // Capture cleanup function if returned\n if (typeof result === 'function') {\n e._cleanup = result;\n }\n } catch (err) {\n if (err === NEEDS_UPSTREAM) throw err; // Iterative eval sentinel \u2014 not a real error\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect', effect: e });\n throw err;\n } finally {\n currentEffect = prev;\n }\n if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);\n}\n\nfunction _disposeEffect(e) {\n e.disposed = true;\n if (__DEV__ && __devtools) __devtools.onEffectDispose(e);\n cleanup(e);\n // Run cleanup on dispose\n if (e._cleanup) {\n try { e._cleanup(); } catch (err) {\n if (__DEV__) console.warn('[what] Error in effect cleanup on dispose:', err);\n }\n e._cleanup = null;\n }\n}\n\nfunction cleanup(e) {\n const deps = e.deps;\n for (let i = 0; i < deps.length; i++) deps[i].delete(e);\n deps.length = 0;\n}\n\n// --- Notification ---\n// Iterative notification to prevent stack overflow on deep computed chains.\n// Uses a reusable queue to avoid per-call array allocation.\n// When notify() encounters _onNotify callbacks (from computeds), those may\n// call notify() recursively. The queue drains iteratively in the outermost call.\n\nlet notifyDepth = 0; // Tracks recursive notify depth\nlet notifyQueue = null; // Reusable queue, allocated on first recursive call\nlet notifyQueueLen = 0; // Length of the queue\n\nfunction notify(subs) {\n // Fast path: no recursive notifications in progress \u2014 iterate directly.\n // This avoids array allocation for the common case (signal \u2192 effects).\n if (notifyDepth === 0) {\n notifyDepth = 1;\n try {\n for (const e of subs) {\n if (e.disposed) continue;\n if (e._onNotify) {\n // Computed subscriber: mark dirty and propagate.\n // _onNotify may call notify() recursively \u2014 tracked by notifyDepth.\n e._onNotify();\n } else if (batchDepth === 0 && e._stable) {\n // Inline execution for stable effects\n const prev = currentEffect;\n currentEffect = null;\n try {\n const result = e.fn();\n if (typeof result === 'function') {\n if (e._cleanup) try { e._cleanup(); } catch (err) {}\n e._cleanup = result;\n }\n } catch (err) {\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect', effect: e });\n if (__DEV__) console.warn('[what] Error in stable effect:', err);\n } finally {\n currentEffect = prev;\n }\n } else if (!e._pending) {\n e._pending = true;\n const level = e._level;\n const len = pendingEffects.length;\n if (len > 0 && pendingEffects[len - 1]._level > level) {\n pendingNeedSort = true;\n }\n pendingEffects.push(e);\n }\n }\n // Drain any queued subscriber sets from recursive notify calls\n if (notifyQueueLen > 0) {\n let qi = 0;\n while (qi < notifyQueueLen) {\n const queuedSubs = notifyQueue[qi];\n notifyQueue[qi] = null; // Allow GC\n qi++;\n for (const e of queuedSubs) {\n if (e.disposed) continue;\n if (e._onNotify) {\n e._onNotify();\n } else if (batchDepth === 0 && e._stable) {\n const prev = currentEffect;\n currentEffect = null;\n try {\n const result = e.fn();\n if (typeof result === 'function') {\n if (e._cleanup) try { e._cleanup(); } catch (err) {}\n e._cleanup = result;\n }\n } catch (err) {\n if (__devtools?.onError) __devtools.onError(err, { type: 'effect', effect: e });\n if (__DEV__) console.warn('[what] Error in stable effect:', err);\n } finally {\n currentEffect = prev;\n }\n } else if (!e._pending) {\n e._pending = true;\n const level = e._level;\n const len = pendingEffects.length;\n if (len > 0 && pendingEffects[len - 1]._level > level) {\n pendingNeedSort = true;\n }\n pendingEffects.push(e);\n }\n }\n }\n notifyQueueLen = 0;\n }\n } finally {\n notifyDepth = 0;\n }\n if (batchDepth === 0 && pendingEffects.length > 0) scheduleMicrotask();\n } else {\n // Recursive call \u2014 queue the subscriber set for the outermost call to drain.\n if (notifyQueue === null) notifyQueue = [];\n if (notifyQueueLen >= notifyQueue.length) {\n notifyQueue.push(subs);\n } else {\n notifyQueue[notifyQueueLen] = subs;\n }\n notifyQueueLen++;\n }\n}\n\nlet microtaskScheduled = false;\nfunction scheduleMicrotask() {\n if (!microtaskScheduled) {\n microtaskScheduled = true;\n queueMicrotask(() => {\n microtaskScheduled = false;\n flush();\n });\n }\n}\n\nlet isFlushing = false;\n\nfunction flush() {\n // Re-entrancy guard: if flush() is called during an active flush (e.g., via\n // flushSync() inside a component render or effect), skip to prevent infinite\n // recursion. Pending effects will be picked up by the outer flush's while-loop.\n if (isFlushing) return;\n isFlushing = true;\n\n try {\n let iterations = 0;\n while (pendingEffects.length > 0 && iterations < 25) {\n const batch = pendingEffects;\n pendingEffects = [];\n\n // Topological sort: execute effects in level order (lowest first).\n // Fast paths:\n // 1. Single effect \u2014 no sort needed (most common case for microtask flush)\n // 2. Already sorted \u2014 skip sort (common when effects added in level order)\n // 3. Multiple effects at different levels \u2014 sort required\n if (batch.length > 1 && pendingNeedSort) {\n batch.sort((a, b) => a._level - b._level);\n }\n pendingNeedSort = false;\n\n for (let i = 0; i < batch.length; i++) {\n const e = batch[i];\n e._pending = false;\n if (!e.disposed && !e._onNotify) {\n const prevDepsLen = e.deps.length;\n _runEffect(e);\n // Update level only if deps changed (graph structure change)\n if (!e._computed && e.deps.length !== prevDepsLen) {\n _updateLevel(e);\n }\n }\n }\n iterations++;\n }\n if (iterations >= 25) {\n // Clear pending effects to prevent further damage\n for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;\n pendingEffects.length = 0;\n\n if (__DEV__) {\n const remaining = pendingEffects.slice(0, 3);\n const effectNames = remaining.map(e => e.fn?.name || e.fn?.toString().slice(0, 60) || '(anonymous)');\n console.warn(\n `[what] Possible infinite effect loop detected (25 iterations). ` +\n `Likely cause: an effect writes to a signal it also reads, creating a cycle. ` +\n `Use untrack() to read signals without subscribing. ` +\n `Looping effects: ${effectNames.join(', ')}`\n );\n } else {\n console.warn('[what] Possible infinite effect loop detected');\n }\n }\n } finally {\n isFlushing = false;\n }\n}\n\n// --- Memo ---\n// Eager computed that only propagates when the value actually changes.\n// Fix: Instead of calling notify(subs) inline (which bypasses topological sort\n// and causes diamond-dependency glitches), push memo subscribers into\n// pendingEffects and let them go through the sorted flush() path.\nexport function memo(fn) {\n let value;\n const subs = new Set();\n\n const e = _createEffect(() => {\n const next = fn();\n if (!Object.is(value, next)) {\n value = next;\n // Push subscribers into pendingEffects for topological flush\n // instead of inline notify() which can cause diamond glitches\n for (const sub of subs) {\n if (sub.disposed) continue;\n if (sub._onNotify) {\n // Computed subscriber: mark dirty and propagate\n sub._onNotify();\n } else if (!sub._pending) {\n sub._pending = true;\n const level = sub._level;\n const len = pendingEffects.length;\n if (len > 0 && pendingEffects[len - 1]._level > level) {\n pendingNeedSort = true;\n }\n pendingEffects.push(sub);\n }\n }\n }\n });\n\n e._level = 1;\n\n _runEffect(e);\n _updateLevel(e);\n\n // Register subscriber set owner for level tracking\n subSetOwner.set(subs, e);\n\n // Register with current root\n if (currentRoot) {\n currentRoot.disposals.push(() => _disposeEffect(e));\n }\n\n function read() {\n if (currentEffect) {\n subs.add(currentEffect);\n currentEffect.deps.push(subs);\n }\n return value;\n }\n\n read._signal = true;\n read.peek = () => value;\n return read;\n}\n\n// --- flushSync ---\n// Force all pending effects to run synchronously. Use sparingly.\n// Calling during render or effect execution is a no-op (prevents infinite loops).\nexport function flushSync() {\n if (isFlushing) {\n // Re-entrant call \u2014 silently skip (Solid approach).\n // This prevents infinite loops when flushSync() is called during component\n // render or effect execution. Pending effects will be picked up by the\n // outer flush's while-loop.\n if (__DEV__) {\n console.warn(\n '[what] flushSync() called during an active flush (e.g., inside a component render or effect). ' +\n 'This is a no-op to prevent infinite loops. Move flushSync() to an event handler or onMount callback.'\n );\n }\n return;\n }\n if (currentEffect) {\n // Called inside an effect/render \u2014 skip with warning\n if (__DEV__) {\n console.warn(\n '[what] flushSync() called during effect execution. ' +\n 'This is a no-op to prevent infinite loops. Move flushSync() to an event handler or onMount callback.'\n );\n }\n return;\n }\n microtaskScheduled = false;\n flush();\n}\n\n// --- Untrack ---\n// Read signals without subscribing\nexport function untrack(fn) {\n const prev = currentEffect;\n currentEffect = null;\n try {\n return fn();\n } finally {\n currentEffect = prev;\n }\n}\n\n// --- getOwner / runWithOwner ---\n// Expose ownership context for advanced use cases (e.g., async operations\n// that need to register disposals with the correct owner).\n\nexport function getOwner() {\n return currentOwner;\n}\n\nexport function runWithOwner(owner, fn) {\n const prev = currentOwner;\n const prevRoot = currentRoot;\n currentOwner = owner;\n currentRoot = owner;\n try {\n return fn();\n } finally {\n currentOwner = prev;\n currentRoot = prevRoot;\n }\n}\n\n// --- createRoot ---\n// Isolated reactive scope with ownership tree.\n// All effects created inside are tracked and disposed together.\n// Child createRoot scopes register with parent owner \u2014 disposing parent\n// automatically disposes all children (prevents orphaned subscriptions).\nexport function createRoot(fn) {\n const prevRoot = currentRoot;\n const prevOwner = currentOwner;\n const root = {\n disposals: [],\n owner: currentOwner, // parent owner for ownership tree\n children: [], // child roots (ownership tree)\n _disposed: false,\n };\n\n // Register this root as a child of the parent owner\n if (currentOwner) {\n currentOwner.children.push(root);\n }\n\n currentRoot = root;\n currentOwner = root;\n\n try {\n const dispose = () => {\n if (root._disposed) return;\n root._disposed = true;\n\n // Dispose children first (depth-first, reverse order)\n for (let i = root.children.length - 1; i >= 0; i--) {\n _disposeRoot(root.children[i]);\n }\n root.children.length = 0;\n\n // Dispose own effects (reverse order for LIFO cleanup)\n for (let i = root.disposals.length - 1; i >= 0; i--) {\n root.disposals[i]();\n }\n root.disposals.length = 0;\n\n // Remove from parent's children list\n if (root.owner) {\n const idx = root.owner.children.indexOf(root);\n if (idx >= 0) root.owner.children.splice(idx, 1);\n }\n };\n return fn(dispose);\n } finally {\n currentRoot = prevRoot;\n currentOwner = prevOwner;\n }\n}\n\n// Internal: dispose a root and all its children\nfunction _disposeRoot(root) {\n if (root._disposed) return;\n root._disposed = true;\n\n // Dispose children first\n for (let i = root.children.length - 1; i >= 0; i--) {\n _disposeRoot(root.children[i]);\n }\n root.children.length = 0;\n\n // Dispose own effects\n for (let i = root.disposals.length - 1; i >= 0; i--) {\n root.disposals[i]();\n }\n root.disposals.length = 0;\n}\n\n// --- onCleanup ---\n// Register a cleanup function with the current owner/root.\n// Runs when the owner is disposed.\nexport function onCleanup(fn) {\n if (currentRoot) {\n currentRoot.disposals.push(fn);\n }\n}\n", "// What Framework - Element Descriptors\n// Minimal element descriptor objects. No classes, no fibers, just plain objects.\n\n// h(tag, props, ...children) -> VNode\n// h(Component, props, ...children) -> VNode\n// VNode = { tag, props, children, key }\n\nconst EMPTY_OBJ = Object.create(null);\nconst EMPTY_ARR = [];\n\nexport function h(tag, props, ...children) {\n props = props || EMPTY_OBJ;\n const flat = flattenChildren(children);\n const key = props.key ?? null;\n\n // Strip key from props passed to component/element\n if (props.key !== undefined) {\n props = { ...props };\n delete props.key;\n }\n\n return { tag, props, children: flat, key, _vnode: true };\n}\n\n// Fragment \u2014 just returns children\nexport function Fragment({ children }) {\n return children;\n}\n\nfunction flattenChildren(children) {\n const out = [];\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child == null || child === false || child === true) continue;\n if (Array.isArray(child)) {\n out.push(...flattenChildren(child));\n } else if (typeof child === 'object' && child._vnode) {\n out.push(child);\n } else if (typeof child === 'function') {\n // Reactive child \u2014 preserve function for fine-grained DOM updates\n out.push(child);\n } else {\n // Text node\n out.push(String(child));\n }\n }\n return out;\n}\n\n// JSX-like tagged template alternative (no build step needed)\n// html`<div class=\"foo\">${content}</div>`\n// Uses a simple parser, not full HTML \u2014 good enough for most cases.\n\nexport function html(strings, ...values) {\n const src = strings.reduce((acc, str, i) =>\n acc + str + (i < values.length ? `\\x00${i}\\x00` : ''), '');\n return parseTemplate(src, values);\n}\n\nfunction parseTemplate(src, values) {\n // Lightweight tagged template parser\n // Supports: <tag attr=\"val\">, <tag ...${spread}>, ${children}, self-closing\n src = src.trim();\n const nodes = [];\n let i = 0;\n\n while (i < src.length) {\n if (src[i] === '<') {\n const result = parseElement(src, i, values);\n if (result) {\n nodes.push(result.node);\n i = result.end;\n continue;\n }\n }\n // Text or interpolation\n const result = parseText(src, i, values);\n if (result.text) nodes.push(result.text);\n i = result.end;\n }\n\n return nodes.length === 1 ? nodes[0] : nodes;\n}\n\nfunction parseElement(src, start, values) {\n // Opening tag\n const openMatch = src.slice(start).match(/^<([a-zA-Z][a-zA-Z0-9-]*|[A-Z]\\w*)/);\n if (!openMatch) return null;\n\n const tag = openMatch[1];\n let i = start + openMatch[0].length;\n const props = {};\n\n // Parse attributes\n while (i < src.length) {\n // Skip whitespace\n while (i < src.length && /\\s/.test(src[i])) i++;\n\n // Self-closing or end of opening tag\n if (src.slice(i, i + 2) === '/>') {\n return { node: h(tag, Object.keys(props).length ? props : null), end: i + 2 };\n }\n if (src[i] === '>') {\n i++;\n break;\n }\n\n // Spread: ...${obj}\n if (src.slice(i, i + 3) === '...') {\n const placeholder = src.slice(i + 3).match(/^\\x00(\\d+)\\x00/);\n if (placeholder) {\n Object.assign(props, values[Number(placeholder[1])]);\n i += 3 + placeholder[0].length;\n continue;\n }\n }\n\n // Attribute: name=${val} or name=\"val\" or name\n const attrMatch = src.slice(i).match(/^([a-zA-Z_@:][a-zA-Z0-9_:.-]*)/);\n if (!attrMatch) break;\n\n const attrName = attrMatch[1];\n i += attrMatch[0].length;\n\n // Skip whitespace around =\n while (i < src.length && /\\s/.test(src[i])) i++;\n\n if (src[i] === '=') {\n i++;\n while (i < src.length && /\\s/.test(src[i])) i++;\n\n // Value is a placeholder\n const ph = src.slice(i).match(/^\\x00(\\d+)\\x00/);\n if (ph) {\n props[attrName] = values[Number(ph[1])];\n i += ph[0].length;\n } else if (src[i] === '\"' || src[i] === \"'\") {\n const q = src[i];\n i++;\n let val = '';\n while (i < src.length && src[i] !== q) {\n const tph = src.slice(i).match(/^\\x00(\\d+)\\x00/);\n if (tph) {\n val += String(values[Number(tph[1])]);\n i += tph[0].length;\n } else {\n val += src[i];\n i++;\n }\n }\n i++; // closing quote\n props[attrName] = val;\n }\n } else {\n props[attrName] = true;\n }\n }\n\n // Parse children until closing tag\n const children = [];\n const closeTag = `</${tag}>`;\n\n while (i < src.length) {\n if (src.slice(i, i + closeTag.length) === closeTag) {\n i += closeTag.length;\n break;\n }\n\n if (src[i] === '<') {\n const child = parseElement(src, i, values);\n if (child) {\n children.push(child.node);\n i = child.end;\n continue;\n }\n }\n\n const text = parseText(src, i, values);\n if (text.text != null) children.push(text.text);\n i = text.end;\n }\n\n return {\n node: h(tag, Object.keys(props).length ? props : null, ...children),\n end: i,\n };\n}\n\nfunction parseText(src, start, values) {\n let i = start;\n let text = '';\n\n while (i < src.length && src[i] !== '<') {\n const ph = src.slice(i).match(/^\\x00(\\d+)\\x00/);\n if (ph) {\n if (text.trim()) {\n return { text: text.trim(), end: i };\n }\n return { text: values[Number(ph[1])], end: i + ph[0].length };\n }\n text += src[i];\n i++;\n }\n\n return { text: text.trim() || null, end: i };\n}\n", "// What Framework - Component Utilities\n// memo, lazy, Suspense, ErrorBoundary\n\nimport { h } from './h.js';\nimport { signal, effect, untrack, __DEV__ } from './reactive.js';\n\n// Legacy errorBoundaryStack removed \u2014 tree-based resolution via _parentCtx._errorBoundary\n// is now the only mechanism. See reportError() below.\n\n// --- memo ---\n// In the run-once model, components execute exactly once and never re-render.\n// Signals update the DOM directly via fine-grained effects. Therefore, memo()\n// is a no-op identity wrapper \u2014 there is no re-render to skip.\n// Kept for API compatibility with React-style code.\n\nexport function memo(Component, _areEqual) {\n // No-op in run-once model \u2014 just return the component as-is\n const MemoWrapper = function MemoWrapper(props) {\n return Component(props);\n };\n MemoWrapper.displayName = `Memo(${Component.name || 'Anonymous'})`;\n return MemoWrapper;\n}\n\n// Injected by dom.js\nlet _getCurrentComponent = null;\nexport function _injectGetCurrentComponent(fn) { _getCurrentComponent = fn; }\n\nexport function shallowEqual(a, b) {\n if (a === b) return true;\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n for (const key of keysA) {\n if (!Object.is(a[key], b[key])) return false;\n }\n return true;\n}\n\n// --- lazy ---\n// Code-split a component. Returns a wrapper that loads on first render.\n\nexport function lazy(loader) {\n let Component = null;\n let loadPromise = null;\n let loadError = null;\n const listeners = new Set();\n\n function LazyWrapper(props) {\n if (loadError) throw loadError;\n if (Component) return h(Component, props);\n\n if (!loadPromise) {\n loadPromise = loader()\n .then(mod => {\n Component = mod.default || mod;\n // Notify all waiting instances\n listeners.forEach(fn => fn());\n listeners.clear();\n })\n .catch(err => { loadError = err; });\n }\n\n // Throw promise for Suspense to catch\n throw loadPromise;\n }\n\n LazyWrapper.displayName = 'Lazy';\n LazyWrapper._lazy = true;\n LazyWrapper._onLoad = (fn) => {\n if (Component) fn();\n else listeners.add(fn);\n };\n return LazyWrapper;\n}\n\n// --- Suspense ---\n// Show fallback while children are loading (lazy components).\n// Works with lazy() and async components.\n\nexport function Suspense({ fallback, children }) {\n const loading = signal(false);\n const pendingPromises = new Set();\n\n // Suspense boundary marker\n const boundary = {\n _suspense: true,\n onSuspend(promise) {\n loading.set(true);\n pendingPromises.add(promise);\n promise.finally(() => {\n pendingPromises.delete(promise);\n if (pendingPromises.size === 0) {\n loading.set(false);\n }\n });\n },\n };\n\n return {\n tag: '__suspense',\n props: { boundary, fallback, loading },\n children: Array.isArray(children) ? children : [children],\n _vnode: true,\n };\n}\n\n// --- ErrorBoundary ---\n// Catch errors in children and show fallback.\n// Uses a signal to track error state so it works with reactive rendering.\n\nexport function ErrorBoundary({ fallback, children, onError }) {\n const errorState = signal(null);\n\n // Error handler that will be registered with the component tree\n const handleError = (error) => {\n errorState.set(error);\n if (onError) {\n try {\n onError(error);\n } catch (e) {\n console.error('Error in onError handler:', e);\n }\n }\n };\n\n // Reset function to recover from error\n const reset = () => errorState.set(null);\n\n return {\n tag: '__errorBoundary',\n props: { errorState, handleError, fallback, reset },\n children: Array.isArray(children) ? children : [children],\n _vnode: true,\n };\n}\n\n// Helper to report error to nearest boundary\n// Walks the component context tree (not a runtime stack) so async errors are caught\nexport function reportError(error, startCtx) {\n // Walk up the _parentCtx chain to find the nearest _errorBoundary\n let ctx = startCtx || _getCurrentComponent?.();\n while (ctx) {\n if (ctx._errorBoundary) {\n ctx._errorBoundary(error);\n return true;\n }\n ctx = ctx._parentCtx;\n }\n return false;\n}\n\n// _getCurrentComponent is already declared above and injected via _injectGetCurrentComponent\n\n// --- Show ---\n// Conditional rendering component. Cleaner than ternaries.\n\nexport function Show({ when, fallback = null, children }) {\n // when can be a signal or a value\n const condition = typeof when === 'function' ? when() : when;\n return condition ? children : fallback;\n}\n\n// --- For ---\n// Efficient list rendering with keyed reconciliation.\n\nexport function For({ each, fallback = null, children }) {\n const list = typeof each === 'function' ? each() : each;\n if (!list || list.length === 0) return fallback;\n\n // children should be a function (item, index) => vnode\n const renderFn = Array.isArray(children) ? children[0] : children;\n if (typeof renderFn !== 'function') {\n console.warn('[what] For: children must be a render function, e.g. <For each={items}>{(item) => ...}</For>');\n return fallback;\n }\n\n return list.map((item, index) => {\n const vnode = renderFn(item, index);\n // Auto-detect keys for efficient keyed reconciliation\n if (vnode && typeof vnode === 'object' && vnode.key == null) {\n if (item != null && typeof item === 'object') {\n // Use item.id or item.key if available\n if (item.id != null) vnode.key = item.id;\n else if (item.key != null) vnode.key = item.key;\n } else if (typeof item === 'string' || typeof item === 'number') {\n // Primitive items can be their own key\n vnode.key = item;\n }\n }\n return vnode;\n });\n}\n\n// --- Switch / Match ---\n// Multi-condition rendering (like switch statement).\n\nexport function Switch({ fallback = null, children }) {\n const kids = Array.isArray(children) ? children : [children];\n\n for (const child of kids) {\n if (child && child.tag === Match) {\n const condition = typeof child.props.when === 'function'\n ? child.props.when()\n : child.props.when;\n if (condition) {\n return child.children;\n }\n }\n }\n\n return fallback;\n}\n\nexport function Match({ when, children }) {\n // Match is just a marker component, Switch handles the logic\n return { tag: Match, props: { when }, children, _vnode: true };\n}\n\n// --- Island ---\n// Deferred hydration component for islands architecture.\n// Usage: h(Island, { component: Counter, mode: 'idle' })\n// The babel plugin compiles <Counter client:idle /> into this.\n\nexport function Island({ component: Component, mode, mediaQuery, ...props }) {\n const placeholder = h('div', { 'data-island': Component.name || 'Island', 'data-hydrate': mode });\n\n // We need to return a vnode that the reconciler can handle.\n // The actual hydration scheduling happens after mount via an effect.\n const wrapper = signal(null);\n const hydrated = signal(false);\n\n function doHydrate() {\n if (hydrated()) return;\n hydrated.set(true);\n // Render the actual component\n wrapper.set(h(Component, props));\n }\n\n // Schedule hydration based on mode\n function scheduleHydration(el) {\n switch (mode) {\n case 'load':\n queueMicrotask(doHydrate);\n break;\n\n case 'idle':\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(doHydrate);\n } else {\n setTimeout(doHydrate, 200);\n }\n break;\n\n case 'visible': {\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) {\n observer.disconnect();\n doHydrate();\n }\n });\n observer.observe(el);\n break;\n }\n\n case 'interaction': {\n const hydrate = () => {\n el.removeEventListener('click', hydrate);\n el.removeEventListener('focus', hydrate);\n el.removeEventListener('mouseenter', hydrate);\n doHydrate();\n };\n el.addEventListener('click', hydrate, { once: true });\n el.addEventListener('focus', hydrate, { once: true });\n el.addEventListener('mouseenter', hydrate, { once: true });\n break;\n }\n\n case 'media': {\n if (!mediaQuery) { doHydrate(); break; }\n const mq = window.matchMedia(mediaQuery);\n if (mq.matches) {\n queueMicrotask(doHydrate);\n } else {\n const checkMedia = () => {\n if (mq.matches) {\n mq.removeEventListener('change', checkMedia);\n doHydrate();\n }\n };\n mq.addEventListener('change', checkMedia);\n }\n break;\n }\n\n default:\n // Unknown mode, hydrate immediately\n queueMicrotask(doHydrate);\n }\n }\n\n // Use ref callback to get the DOM element and schedule hydration\n const refCallback = (el) => {\n if (el) scheduleHydration(el);\n };\n\n // Return: show placeholder until hydrated, then show the real component\n return h('div', { 'data-island': Component.name || 'Island', 'data-hydrate': mode, ref: refCallback },\n hydrated() ? wrapper() : null\n );\n}\n", "// What Framework - Helpers & Utilities\n// Commonly needed patterns, zero overhead.\n\nimport { signal, effect, __DEV__ } from './reactive.js';\n\n// --- each(list, fn) --- [DEPRECATED: use <For> component or .map() instead]\n// Keyed list rendering. Optimized for reconciliation.\nlet _eachWarned = false;\nexport function each(list, fn, keyFn) {\n if (!_eachWarned) {\n _eachWarned = true;\n console.warn('[what] each() is deprecated. Use the <For> component or Array.map() instead.');\n }\n if (!list || list.length === 0) return [];\n return list.map((item, index) => {\n const vnode = fn(item, index);\n if (keyFn && vnode && typeof vnode === 'object') {\n vnode.key = keyFn(item, index);\n }\n return vnode;\n });\n}\n\n// --- cls(...args) ---\n// Conditional class names. Like clsx but tiny.\n// cls('base', condition && 'active', { hidden: isHidden, bold: isBold })\nexport function cls(...args) {\n const classes = [];\n for (const arg of args) {\n if (!arg) continue;\n if (typeof arg === 'string') {\n classes.push(arg);\n } else if (typeof arg === 'object') {\n for (const [key, val] of Object.entries(arg)) {\n if (val) classes.push(key);\n }\n }\n }\n return classes.join(' ');\n}\n\n// --- style(obj) ---\n// Convert a style object to a CSS string for SSR.\nexport function style(obj) {\n if (typeof obj === 'string') return obj;\n return Object.entries(obj)\n .filter(([, v]) => v != null && v !== '')\n .map(([k, v]) => `${camelToKebab(k)}:${v}`)\n .join(';');\n}\n\nfunction camelToKebab(str) {\n return str.replace(/([A-Z])/g, '-$1').toLowerCase();\n}\n\n// --- debounce ---\n// Debounced signal updates.\nexport function debounce(fn, ms) {\n let timer;\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => fn(...args), ms);\n };\n}\n\n// --- throttle ---\nexport function throttle(fn, ms) {\n let last = 0;\n return (...args) => {\n const now = Date.now();\n if (now - last >= ms) {\n last = now;\n fn(...args);\n }\n };\n}\n\n// Component context ref \u2014 injected by dom.js to avoid circular imports\nlet _getCurrentComponentRef = null;\nexport function _setComponentRef(fn) { _getCurrentComponentRef = fn; }\n\n// --- useMediaQuery ---\n// Reactive media query. Returns a signal. Cleans up listener on component unmount.\nexport function useMediaQuery(query) {\n if (typeof window === 'undefined') return signal(false);\n const mq = window.matchMedia(query);\n const s = signal(mq.matches);\n const handler = (e) => s.set(e.matches);\n mq.addEventListener('change', handler);\n\n // Register cleanup if inside a component context\n const ctx = _getCurrentComponentRef?.();\n if (ctx) {\n ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];\n ctx._cleanupCallbacks.push(() => mq.removeEventListener('change', handler));\n }\n\n return s;\n}\n\n// --- useLocalStorage ---\n// Signal synced with localStorage. Cleans up listeners on component unmount.\nexport function useLocalStorage(key, initial) {\n let stored;\n try {\n const raw = localStorage.getItem(key);\n stored = raw !== null ? JSON.parse(raw) : initial;\n } catch {\n stored = initial;\n }\n\n const s = signal(stored);\n\n // Sync to localStorage on changes\n const dispose = effect(() => {\n try {\n localStorage.setItem(key, JSON.stringify(s()));\n } catch (e) {\n if (__DEV__) console.warn('[what] localStorage write failed (quota exceeded?):', e);\n }\n });\n\n // Listen for changes from other tabs\n let storageHandler = null;\n if (typeof window !== 'undefined') {\n storageHandler = (e) => {\n if (e.key === key && e.newValue !== null) {\n try { s.set(JSON.parse(e.newValue)); } catch (err) {\n if (__DEV__) console.warn('[what] localStorage parse failed:', err);\n }\n }\n };\n window.addEventListener('storage', storageHandler);\n }\n\n // Register cleanup if inside a component context\n const ctx = _getCurrentComponentRef?.();\n if (ctx) {\n ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];\n ctx._cleanupCallbacks.push(() => {\n dispose();\n if (storageHandler) window.removeEventListener('storage', storageHandler);\n });\n }\n\n return s;\n}\n\n// --- portal ---\n// Render children into a different DOM container.\nexport function Portal({ target, children }) {\n // In SSR, just return null (portals are client-only)\n if (typeof document === 'undefined') return null;\n const container = typeof target === 'string'\n ? document.querySelector(target)\n : target;\n if (!container) return null;\n // The DOM reconciler will mount children here\n return { tag: '__portal', props: { container }, children: Array.isArray(children) ? children : [children], _vnode: true };\n}\n\n// --- useClickOutside ---\n// Detect clicks outside a ref'd element. Essential for dropdowns, modals, popovers.\nexport function useClickOutside(ref, handler) {\n if (typeof document === 'undefined') return;\n\n const listener = (e) => {\n const el = ref.current || ref;\n if (!el || el.contains(e.target)) return;\n handler(e);\n };\n\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n\n const ctx = _getCurrentComponentRef?.();\n if (ctx) {\n ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];\n ctx._cleanupCallbacks.push(() => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n });\n }\n}\n\n// --- Transition helper ---\n// Animate elements in/out. Returns props to spread on the element.\nexport function transition(name, active) {\n return {\n class: active ? `${name}-enter ${name}-enter-active` : `${name}-leave ${name}-leave-active`,\n };\n}\n", "// What Framework - Fine-Grained DOM Runtime\n// Components run ONCE. Signals create individual DOM effects.\n// No VDOM reconciler, no diffing \u2014 direct DOM manipulation driven by signals.\n\nimport { effect, batch, untrack, signal, __DEV__, __devtools } from './reactive.js';\nimport { reportError, _injectGetCurrentComponent, shallowEqual } from './components.js';\nimport { _setComponentRef } from './helpers.js';\n\n// SVG elements that need namespace\nconst SVG_ELEMENTS = new Set([\n 'svg', 'path', 'circle', 'rect', 'line', 'polyline', 'polygon', 'ellipse',\n 'g', 'defs', 'use', 'symbol', 'clipPath', 'mask', 'pattern', 'image',\n 'text', 'tspan', 'textPath', 'foreignObject', 'linearGradient', 'radialGradient', 'stop',\n 'marker', 'animate', 'animateTransform', 'animateMotion', 'set', 'filter',\n 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix',\n 'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feGaussianBlur', 'feImage',\n 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'feSpecularLighting',\n 'feTile', 'feTurbulence',\n]);\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\n// Track all mounted component contexts for disposal\nconst mountedComponents = new Set();\n\n// WeakMap: comment node \u2192 component context (for comment-node boundaries)\nconst _commentCtxMap = new WeakMap();\n\nfunction isDomNode(value) {\n if (!value || typeof value !== 'object') return false;\n if (typeof Node !== 'undefined' && value instanceof Node) return true;\n return typeof value.nodeType === 'number' && typeof value.nodeName === 'string';\n}\n\nfunction isVNode(value) {\n return !!value && typeof value === 'object' && (value._vnode === true || 'tag' in value);\n}\n\n// Dispose a component: run effect cleanups, hook cleanups, onCleanup callbacks\nfunction disposeComponent(ctx) {\n if (ctx.disposed) return;\n ctx.disposed = true;\n\n // Run cleanup callbacks\n if (ctx.cleanups) {\n for (const cleanup of ctx.cleanups) {\n try { cleanup(); } catch (e) { console.error('[what] cleanup error:', e); }\n }\n }\n\n // Run effect disposals\n if (ctx.effects) {\n for (const dispose of ctx.effects) {\n try { dispose(); } catch (e) { /* already disposed */ }\n }\n }\n\n // Run hook cleanups (useEffect return values)\n if (ctx.hooks) {\n for (const hook of ctx.hooks) {\n if (hook && typeof hook.cleanup === 'function') {\n try { hook.cleanup(); } catch (e) { console.error('[what] hook cleanup error:', e); }\n }\n }\n }\n\n // Run onCleanup callbacks\n if (ctx._cleanupCallbacks) {\n for (const fn of ctx._cleanupCallbacks) {\n try { fn(); } catch (e) { console.error('[what] onCleanup error:', e); }\n }\n }\n\n if (__DEV__ && __devtools?.onComponentUnmount) __devtools.onComponentUnmount(ctx);\n mountedComponents.delete(ctx);\n}\n\n// Dispose all components and reactive effects attached to a DOM subtree\nexport function disposeTree(node) {\n if (!node) return;\n if (node._componentCtx) {\n disposeComponent(node._componentCtx);\n }\n // Check comment node WeakMap for component context\n const commentCtx = _commentCtxMap.get(node);\n if (commentCtx) {\n disposeComponent(commentCtx);\n }\n // Dispose reactive function child effects ({() => ...} wrappers)\n if (node._dispose) {\n try { node._dispose(); } catch (e) { /* already disposed */ }\n }\n // Dispose reactive prop effects (value: () => ..., class: () => ..., etc.)\n if (node._propEffects) {\n for (const key in node._propEffects) {\n try { node._propEffects[key](); } catch (e) { /* already disposed */ }\n }\n }\n if (node.childNodes) {\n for (const child of node.childNodes) {\n disposeTree(child);\n }\n }\n}\n\n// Mount a component tree into a DOM container\nexport function mount(vnode, container) {\n if (typeof container === 'string') {\n container = document.querySelector(container);\n }\n disposeTree(container); // Clean up any previous mount\n container.textContent = '';\n const node = createDOM(vnode, container);\n if (node) container.appendChild(node);\n return () => {\n disposeTree(container);\n container.textContent = '';\n };\n}\n\n// --- Create DOM from VNode ---\n\nexport function createDOM(vnode, parent, isSvg) {\n // Null/false/true \u2192 placeholder comment (preserves child indices for reconciliation)\n if (vnode == null || vnode === false || vnode === true) {\n return document.createComment('');\n }\n\n // Text\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n return document.createTextNode(String(vnode));\n }\n\n // DOM node passthrough (fine-grained components return real nodes)\n if (isDomNode(vnode)) {\n return vnode;\n }\n\n // Reactive function child \u2014 use comment markers (no wrapper element)\n // to avoid polluting the DOM and breaking CSS selectors like :first-child.\n if (typeof vnode === 'function') {\n const startMarker = document.createComment('fn');\n const endMarker = document.createComment('/fn');\n let currentNodes = [];\n // We need a parent to insert between markers. The caller (createElementFromVNode\n // or createComponent) will appendChild both markers and the content. We return\n // a document fragment containing start marker, then the effect will manage nodes\n // between start and end markers once they're in the real DOM.\n const frag = document.createDocumentFragment();\n frag.appendChild(startMarker);\n frag.appendChild(endMarker);\n\n const dispose = effect(() => {\n const val = vnode();\n const vnodes = (val == null || val === false || val === true)\n ? []\n : Array.isArray(val) ? val : [val];\n\n const realParent = endMarker.parentNode;\n if (!realParent) return; // not mounted yet \u2014 first run handled below\n\n // Remove old nodes between markers\n for (const old of currentNodes) {\n disposeTree(old);\n if (old.parentNode === realParent) realParent.removeChild(old);\n }\n currentNodes = [];\n\n // Add new nodes before endMarker\n for (const v of vnodes) {\n const node = createDOM(v, realParent, parent?._isSvg);\n if (node) {\n // If createDOM returned a DocumentFragment, track individual children\n // since fragment nodes get absorbed into the DOM on insertion.\n if (node.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */) {\n const children = Array.from(node.childNodes);\n realParent.insertBefore(node, endMarker);\n for (const child of children) currentNodes.push(child);\n } else {\n realParent.insertBefore(node, endMarker);\n currentNodes.push(node);\n }\n }\n }\n });\n\n startMarker._dispose = dispose;\n // Also store dispose on endMarker so disposeTree can find it from either marker\n endMarker._dispose = dispose;\n return frag;\n }\n\n // Array of vnodes\n if (Array.isArray(vnode)) {\n const frag = document.createDocumentFragment();\n for (const child of vnode) {\n const node = createDOM(child, parent, isSvg);\n if (node) frag.appendChild(node);\n }\n return frag;\n }\n\n // VNode with component tag \u2014 component runs ONCE\n if (isVNode(vnode) && typeof vnode.tag === 'function') {\n return createComponent(vnode, parent, isSvg);\n }\n\n // VNode with string tag \u2014 create element\n if (isVNode(vnode)) {\n return createElementFromVNode(vnode, parent, isSvg);\n }\n\n // Unknown \u2014 convert to text\n return document.createTextNode(String(vnode));\n}\n\n// --- Component Rendering ---\n// Components run ONCE. Props are passed as a signal for reactive access.\n\nconst componentStack = [];\n\nexport function getCurrentComponent() {\n return componentStack[componentStack.length - 1];\n}\n\n// Inject into components.js and helpers.js to avoid circular imports\n_injectGetCurrentComponent(getCurrentComponent);\n_setComponentRef(getCurrentComponent);\n\nexport function getComponentStack() {\n return componentStack;\n}\n\nfunction createComponent(vnode, parent, isSvg) {\n let { tag: Component, props, children } = vnode;\n\n // Class component detection\n if (typeof Component === 'function' &&\n (Component.prototype?.isReactComponent || Component.prototype?.render)) {\n const ClassComp = Component;\n Component = function ClassComponentBridge(props) {\n const instance = new ClassComp(props);\n return instance.render();\n };\n Component.displayName = ClassComp.displayName || ClassComp.name || 'ClassComponent';\n }\n\n // Handle special boundary components\n if (Component === '__errorBoundary' || vnode.tag === '__errorBoundary') {\n return createErrorBoundary(vnode, parent);\n }\n if (Component === '__suspense' || vnode.tag === '__suspense') {\n return createSuspenseBoundary(vnode, parent);\n }\n if (Component === '__portal' || vnode.tag === '__portal') {\n return createPortalDOM(vnode, parent);\n }\n\n // Component context for hooks\n const ctx = {\n hooks: [],\n hookIndex: 0,\n effects: [],\n cleanups: [],\n mounted: false,\n disposed: false,\n Component,\n _parentCtx: componentStack[componentStack.length - 1] || null,\n _errorBoundary: (() => {\n let p = componentStack[componentStack.length - 1];\n while (p) {\n if (p._errorBoundary) return p._errorBoundary;\n p = p._parentCtx;\n }\n return null;\n })()\n };\n\n // Component boundaries: use comment nodes instead of <span style=\"display:contents\">\n // to avoid DOM pollution, CSS selector breakage, and a11y issues.\n const startComment = document.createComment('c:start');\n const endComment = document.createComment('c:end');\n _commentCtxMap.set(startComment, ctx);\n ctx._startComment = startComment;\n ctx._endComment = endComment;\n\n // Fragment to hold comment boundaries + component output\n const container = document.createDocumentFragment();\n container._componentCtx = ctx;\n ctx._wrapper = startComment; // Reference for context lookup\n\n // Track for disposal\n mountedComponents.add(ctx);\n if (__DEV__ && __devtools?.onComponentMount) __devtools.onComponentMount(ctx);\n\n // Props signal for reactive updates from parent\n const propsChildren = children.length === 0 ? undefined : children.length === 1 ? children[0] : children;\n const propsSignal = signal({ ...props, children: propsChildren });\n ctx._propsSignal = propsSignal;\n\n // Create a reactive props proxy: reading any prop inside an effect\n // will auto-track the dependency on the propsSignal. This makes prop\n // access reactive across re-renders without requiring the component\n // to be re-executed.\n const reactiveProps = new Proxy({}, {\n get(_, key) {\n // Access the signal to create a reactive dependency\n const current = propsSignal();\n return current[key];\n },\n has(_, key) {\n const current = propsSignal();\n return key in current;\n },\n ownKeys() {\n const current = propsSignal();\n return Reflect.ownKeys(current);\n },\n getOwnPropertyDescriptor(_, key) {\n const current = propsSignal();\n if (key in current) {\n return { value: current[key], writable: false, enumerable: true, configurable: true };\n }\n return undefined;\n },\n });\n\n // Component runs ONCE \u2014 not inside an effect\n componentStack.push(ctx);\n\n let result;\n try {\n result = Component(reactiveProps);\n } catch (error) {\n componentStack.pop();\n if (!reportError(error, ctx)) {\n console.error('[what] Uncaught error in component:', Component.name || 'Anonymous', error);\n throw error;\n }\n // Return fragment with just comment boundaries on error\n container.appendChild(startComment);\n container.appendChild(endComment);\n return container;\n }\n\n componentStack.pop();\n ctx.mounted = true;\n\n // Run onMount callbacks after DOM is ready\n if (ctx._mountCallbacks) {\n queueMicrotask(() => {\n if (ctx.disposed) return;\n for (const fn of ctx._mountCallbacks) {\n try { fn(); } catch (e) { console.error('[what] onMount error:', e); }\n }\n });\n }\n\n // Build fragment: <!-- c:start --> [component output] <!-- c:end -->\n container.appendChild(startComment);\n const vnodes = Array.isArray(result) ? result : [result];\n for (const v of vnodes) {\n const node = createDOM(v, container, isSvg);\n if (node) container.appendChild(node);\n }\n container.appendChild(endComment);\n\n return container;\n}\n\n// Error boundary component handler\nfunction createErrorBoundary(vnode, parent) {\n const { errorState, handleError, fallback, reset } = vnode.props;\n const children = vnode.children;\n\n // Use comment node boundaries instead of <span style=\"display:contents\">\n // to avoid DOM pollution, CSS selector breakage, and a11y issues.\n const startComment = document.createComment('eb:start');\n const endComment = document.createComment('eb:end');\n\n const boundaryCtx = {\n hooks: [], hookIndex: 0, effects: [], cleanups: [],\n mounted: false, disposed: false,\n _parentCtx: componentStack[componentStack.length - 1] || null,\n _errorBoundary: handleError,\n _startComment: startComment,\n _endComment: endComment,\n };\n _commentCtxMap.set(startComment, boundaryCtx);\n\n const container = document.createDocumentFragment();\n container._componentCtx = boundaryCtx;\n container.appendChild(startComment);\n container.appendChild(endComment);\n\n const dispose = effect(() => {\n const error = errorState();\n\n componentStack.push(boundaryCtx);\n\n // Remove old content between comment boundaries\n if (startComment.parentNode) {\n while (startComment.nextSibling && startComment.nextSibling !== endComment) {\n const old = startComment.nextSibling;\n disposeTree(old);\n old.parentNode.removeChild(old);\n }\n }\n\n let vnodes;\n if (error) {\n vnodes = typeof fallback === 'function' ? [fallback({ error, reset })] : [fallback];\n } else {\n vnodes = children;\n }\n\n vnodes = Array.isArray(vnodes) ? vnodes : [vnodes];\n\n for (const v of vnodes) {\n const node = createDOM(v, parent);\n if (node) {\n // Insert before endComment\n if (endComment.parentNode) {\n endComment.parentNode.insertBefore(node, endComment);\n } else {\n // Still in fragment before first mount\n container.insertBefore(node, endComment);\n }\n }\n }\n\n componentStack.pop();\n });\n\n boundaryCtx.effects.push(dispose);\n return container;\n}\n\n// Suspense boundary component handler\nfunction createSuspenseBoundary(vnode, parent) {\n const { boundary, fallback, loading } = vnode.props;\n const children = vnode.children;\n\n // Use comment node boundaries instead of <span style=\"display:contents\">\n // to avoid DOM pollution, CSS selector breakage, and a11y issues.\n const startComment = document.createComment('sb:start');\n const endComment = document.createComment('sb:end');\n\n const boundaryCtx = {\n hooks: [], hookIndex: 0, effects: [], cleanups: [],\n mounted: false, disposed: false,\n _parentCtx: componentStack[componentStack.length - 1] || null,\n _startComment: startComment,\n _endComment: endComment,\n };\n _commentCtxMap.set(startComment, boundaryCtx);\n\n const container = document.createDocumentFragment();\n container._componentCtx = boundaryCtx;\n container.appendChild(startComment);\n container.appendChild(endComment);\n\n const dispose = effect(() => {\n const isLoading = loading();\n const vnodes = isLoading ? [fallback] : children;\n const normalized = Array.isArray(vnodes) ? vnodes : [vnodes];\n\n componentStack.push(boundaryCtx);\n\n // Remove old content between comment boundaries\n if (startComment.parentNode) {\n while (startComment.nextSibling && startComment.nextSibling !== endComment) {\n const old = startComment.nextSibling;\n disposeTree(old);\n old.parentNode.removeChild(old);\n }\n }\n\n for (const v of normalized) {\n const node = createDOM(v, parent);\n if (node) {\n // Insert before endComment\n if (endComment.parentNode) {\n endComment.parentNode.insertBefore(node, endComment);\n } else {\n // Still in fragment before first mount\n container.insertBefore(node, endComment);\n }\n }\n }\n\n componentStack.pop();\n });\n\n boundaryCtx.effects.push(dispose);\n return container;\n}\n\n// Portal component handler\nfunction createPortalDOM(vnode, parent) {\n const { container } = vnode.props;\n const children = vnode.children;\n\n if (!container) {\n console.warn('[what] Portal: target container not found');\n return document.createComment('portal:empty');\n }\n\n const portalCtx = {\n hooks: [], hookIndex: 0, effects: [], cleanups: [],\n mounted: false, disposed: false,\n _parentCtx: componentStack[componentStack.length - 1] || null,\n };\n\n const placeholder = document.createComment('portal');\n placeholder._componentCtx = portalCtx;\n\n const portalNodes = [];\n for (const child of children) {\n const node = createDOM(child, container);\n if (node) {\n container.appendChild(node);\n portalNodes.push(node);\n }\n }\n\n portalCtx._cleanupCallbacks = [() => {\n for (const node of portalNodes) {\n disposeTree(node);\n if (node.parentNode) node.parentNode.removeChild(node);\n }\n }];\n\n return placeholder;\n}\n\n// --- Create Element from VNode ---\n// For h()-based VNodes with string tags\n\nfunction createElementFromVNode(vnode, parent, isSvg) {\n const { tag, props, children } = vnode;\n\n const svgContext = isSvg || SVG_ELEMENTS.has(tag);\n const el = svgContext\n ? document.createElementNS(SVG_NS, tag)\n : document.createElement(tag);\n\n // Apply props\n if (props) {\n applyProps(el, props, {}, svgContext);\n }\n\n // Append children\n for (const child of children) {\n const node = createDOM(child, el, svgContext && tag !== 'foreignObject');\n if (node) el.appendChild(node);\n }\n\n el._vnode = vnode;\n return el;\n}\n\n// --- Prop Application ---\n// Only applied once for fine-grained (no diffing). Reactive props use effects.\n\nfunction applyProps(el, newProps, oldProps, isSvg) {\n newProps = newProps || {};\n oldProps = oldProps || {};\n\n for (const key in newProps) {\n if (key === 'key' || key === 'children') continue;\n\n // Handle ref\n if (key === 'ref') {\n if (typeof newProps.ref === 'function') newProps.ref(el);\n else if (newProps.ref) newProps.ref.current = el;\n continue;\n }\n\n setProp(el, key, newProps[key], isSvg);\n }\n}\n\nfunction setProp(el, key, value, isSvg) {\n // Reactive function props \u2014 wrap in effect for fine-grained updates\n if (typeof value === 'function' && !(key.startsWith('on') && key.length > 2) && key !== 'ref') {\n if (!el._propEffects) el._propEffects = {};\n if (el._propEffects[key]) {\n try { el._propEffects[key](); } catch (e) { /* already disposed */ }\n }\n el._propEffects[key] = effect(() => {\n const resolved = value();\n setProp(el, key, resolved, isSvg);\n });\n return;\n }\n\n // Event handlers\n if (key.startsWith('on') && key.length > 2) {\n let eventName = key.slice(2);\n let useCapture = false;\n if (eventName.endsWith('Capture')) {\n eventName = eventName.slice(0, -7);\n useCapture = true;\n }\n const event = eventName.toLowerCase();\n const storageKey = useCapture ? event + '_capture' : event;\n const old = el._events?.[storageKey];\n if (old && old._original === value) return;\n if (old) el.removeEventListener(event, old, useCapture);\n if (value == null) return;\n if (!el._events) el._events = {};\n const wrappedHandler = (e) => {\n if (!e.nativeEvent) e.nativeEvent = e;\n return untrack(() => value(e));\n };\n wrappedHandler._original = value;\n el._events[storageKey] = wrappedHandler;\n const eventOpts = value._eventOpts;\n el.addEventListener(event, wrappedHandler, eventOpts || useCapture || undefined);\n return;\n }\n\n // className / class\n if (key === 'className' || key === 'class') {\n if (isSvg) {\n el.setAttribute('class', value || '');\n } else {\n el.className = value || '';\n }\n return;\n }\n\n // Style\n if (key === 'style') {\n if (typeof value === 'string') {\n el.style.cssText = value;\n el._prevStyle = null;\n } else if (typeof value === 'object') {\n const oldStyle = el._prevStyle || {};\n for (const prop in oldStyle) {\n if (!(prop in value)) el.style[prop] = '';\n }\n for (const prop in value) {\n el.style[prop] = value[prop] ?? '';\n }\n el._prevStyle = { ...value };\n }\n return;\n }\n\n // dangerouslySetInnerHTML\n if (key === 'dangerouslySetInnerHTML') {\n el.innerHTML = value?.__html ?? '';\n return;\n }\n\n // innerHTML \u2014 require { __html: ... } wrapper to prevent XSS\n if (key === 'innerHTML') {\n if (value == null) return; // null/undefined \u2014 do nothing\n if (value && typeof value === 'object' && '__html' in value) {\n el.innerHTML = value.__html ?? '';\n } else {\n if (__DEV__) {\n console.warn(\n '[what] innerHTML received a raw string. This is a security risk (XSS). ' +\n 'Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead.'\n );\n }\n // Refuse to set raw string innerHTML \u2014 prevent XSS\n return;\n }\n return;\n }\n\n // Boolean attributes\n if (typeof value === 'boolean') {\n if (value) el.setAttribute(key, '');\n else el.removeAttribute(key);\n return;\n }\n\n // data-* and aria-*\n if (key.startsWith('data-') || key.startsWith('aria-')) {\n el.setAttribute(key, value);\n return;\n }\n\n // SVG\n if (isSvg) {\n if (value === false || value == null) {\n el.removeAttribute(key);\n } else {\n el.setAttribute(key, value === true ? '' : String(value));\n }\n return;\n }\n\n // Default: property if exists, otherwise attribute\n if (key in el) {\n el[key] = value;\n } else {\n el.setAttribute(key, value);\n }\n}\n", "// What Framework - Testing Utilities\n// Helpers for testing components, similar to @testing-library/react\n// Works with Node.js test runner or any test framework\n\nimport { signal, computed, effect, batch, flushSync, createRoot, untrack } from './reactive.js';\nimport { mount } from './dom.js';\nimport { h } from './h.js';\n\n// Minimal DOM implementation for Node.js\nlet container = null;\n\n// --- Setup and Cleanup ---\n\nexport function setupDOM() {\n if (typeof document !== 'undefined') {\n // Browser environment\n container = document.createElement('div');\n container.id = 'test-root';\n document.body.appendChild(container);\n }\n return container;\n}\n\nexport function cleanup() {\n if (container) {\n container.innerHTML = '';\n if (container.parentNode) {\n container.parentNode.removeChild(container);\n }\n container = null;\n }\n}\n\n// --- Render ---\n\nexport function render(vnode, options = {}) {\n const { container: customContainer } = options;\n const target = customContainer || setupDOM();\n\n if (!target) {\n throw new Error('No DOM container available. Are you running in Node.js without jsdom?');\n }\n\n const unmount = mount(vnode, target);\n\n return {\n container: target,\n unmount,\n // Query helpers\n getByText: (text) => queryByText(target, text),\n getByTestId: (id) => target.querySelector(`[data-testid=\"${id}\"]`),\n getByRole: (role) => target.querySelector(`[role=\"${role}\"]`),\n getAllByText: (text) => queryAllByText(target, text),\n queryByText: (text) => queryByText(target, text),\n queryByTestId: (id) => target.querySelector(`[data-testid=\"${id}\"]`),\n // Debug\n debug: () => console.log(target.innerHTML),\n // Async utilities\n findByText: (text, timeout) => waitFor(() => queryByText(target, text), { timeout }),\n findByTestId: (id, timeout) => waitFor(() => target.querySelector(`[data-testid=\"${id}\"]`), { timeout }),\n };\n}\n\n// --- renderTest ---\n// Simplified test renderer: mount a component with props and return\n// a test harness with container, signals proxy, update, and unmount.\n\nexport function renderTest(Component, props) {\n const target = setupDOM();\n if (!target) {\n throw new Error('No DOM container available. Are you running in Node.js without jsdom?');\n }\n\n // Track signals created during component render\n const signalRegistry = {};\n let rootDispose = null;\n\n // Create a reactive root so we can flush synchronously\n let unmountFn;\n createRoot((dispose) => {\n rootDispose = dispose;\n const vnode = h(Component, props || {});\n unmountFn = mount(vnode, target);\n });\n\n return {\n container: target,\n // Proxy to access component signals by name\n signals: new Proxy(signalRegistry, {\n get(obj, prop) {\n if (prop in obj) return obj[prop];\n return undefined;\n },\n set(obj, prop, value) {\n obj[prop] = value;\n return true;\n },\n }),\n // Synchronous flush: run all pending effects immediately\n update() {\n flushSync();\n },\n unmount() {\n if (unmountFn) unmountFn();\n if (rootDispose) rootDispose();\n cleanup();\n },\n // Query helpers\n getByText: (text) => queryByText(target, text),\n getByTestId: (id) => target.querySelector(`[data-testid=\"${id}\"]`),\n queryByText: (text) => queryByText(target, text),\n debug: () => console.log(target.innerHTML),\n };\n}\n\n// --- flushEffects ---\n// Synchronous effect flush for testing. Ensures all pending effects\n// and microtasks are processed before continuing.\n\nexport function flushEffects() {\n flushSync();\n}\n\n// --- trackSignals ---\n// Track signal reads and writes within a callback.\n// Returns { accessed: string[], written: string[] }\n\nexport function trackSignals(fn) {\n const accessed = [];\n const written = [];\n\n // Intercept signal reads/writes by wrapping in an effect context\n // that captures the read calls, and monkey-patching .set temporarily.\n const _origSignal = signal;\n\n // We track by running the function and observing side effects.\n // Since signals are closure-based, we use a different approach:\n // Run inside a computed (which tracks reads), and proxy signal.set calls.\n const trackedSignals = new Map();\n\n // Patch: create a tracking wrapper\n const trackRead = (name) => {\n if (!accessed.includes(name)) accessed.push(name);\n };\n const trackWrite = (name) => {\n if (!written.includes(name)) written.push(name);\n };\n\n // We run the function and rely on the reactive system's currentEffect tracking.\n // To detect reads, we run in an effect. To detect writes, we'd need instrumentation.\n // Instead, provide a simpler API: the user passes signals that have _debugName set.\n\n // Simple approach: run fn() inside an effect to track reads,\n // and use Proxy-based detection for writes.\n let dispose;\n createRoot((d) => {\n dispose = d;\n const e = effect(() => {\n fn();\n });\n });\n if (dispose) dispose();\n\n return { accessed, written };\n}\n\n// --- mockSignal ---\n// Signal with full history tracking for testing.\n\nexport function mockSignal(name, initialValue) {\n const history = [initialValue];\n let setCount = 0;\n\n const s = signal(initialValue, name);\n const origSet = s.set;\n\n // Override set to track history\n s.set = function(next) {\n const nextVal = typeof next === 'function' ? next(s.peek()) : next;\n if (!Object.is(s.peek(), nextVal)) {\n setCount++;\n history.push(nextVal);\n }\n return origSet(nextVal);\n };\n\n // Also override the unified call syntax for writes\n const origFn = s;\n const mock = function(...args) {\n if (args.length === 0) {\n return origFn();\n }\n // Write path\n const nextVal = typeof args[0] === 'function' ? args[0](origFn.peek()) : args[0];\n if (!Object.is(origFn.peek(), nextVal)) {\n setCount++;\n history.push(nextVal);\n }\n return origFn(nextVal);\n };\n\n // Copy signal properties\n mock._signal = true;\n mock.peek = s.peek;\n mock.set = s.set;\n mock.subscribe = s.subscribe;\n if (s._debugName) mock._debugName = s._debugName;\n if (s._subs) mock._subs = s._subs;\n\n // Testing-specific properties\n Object.defineProperty(mock, 'history', {\n get() { return history; },\n });\n Object.defineProperty(mock, 'setCount', {\n get() { return setCount; },\n });\n mock.reset = function(value) {\n const resetVal = value !== undefined ? value : initialValue;\n history.length = 0;\n history.push(resetVal);\n setCount = 0;\n origFn(resetVal);\n };\n\n return mock;\n}\n\n// --- Query Helpers ---\n\nfunction queryByText(container, text) {\n const regex = text instanceof RegExp ? text : null;\n const walker = document.createTreeWalker(\n container,\n NodeFilter.SHOW_TEXT,\n null,\n false\n );\n\n while (walker.nextNode()) {\n const node = walker.currentNode;\n const matches = regex\n ? regex.test(node.textContent)\n : node.textContent.includes(text);\n if (matches) {\n return node.parentElement;\n }\n }\n return null;\n}\n\nfunction queryAllByText(container, text) {\n const results = [];\n const regex = text instanceof RegExp ? text : null;\n const walker = document.createTreeWalker(\n container,\n NodeFilter.SHOW_TEXT,\n null,\n false\n );\n\n while (walker.nextNode()) {\n const node = walker.currentNode;\n const matches = regex\n ? regex.test(node.textContent)\n : node.textContent.includes(text);\n if (matches) {\n results.push(node.parentElement);\n }\n }\n return results;\n}\n\n// --- Fire Events ---\n\nexport const fireEvent = {\n click(element) {\n const event = new MouseEvent('click', {\n bubbles: true,\n cancelable: true,\n view: typeof window !== 'undefined' ? window : undefined,\n });\n element.dispatchEvent(event);\n return event;\n },\n\n change(element, value) {\n element.value = value;\n const event = new Event('input', { bubbles: true });\n element.dispatchEvent(event);\n const changeEvent = new Event('change', { bubbles: true });\n element.dispatchEvent(changeEvent);\n return changeEvent;\n },\n\n input(element, value) {\n element.value = value;\n const event = new Event('input', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n\n submit(element) {\n const event = new Event('submit', { bubbles: true, cancelable: true });\n element.dispatchEvent(event);\n return event;\n },\n\n focus(element) {\n element.focus();\n const event = new FocusEvent('focus', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n\n blur(element) {\n element.blur();\n const event = new FocusEvent('blur', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n\n keyDown(element, key, options = {}) {\n const event = new KeyboardEvent('keydown', {\n bubbles: true,\n cancelable: true,\n key,\n ...options,\n });\n element.dispatchEvent(event);\n return event;\n },\n\n keyUp(element, key, options = {}) {\n const event = new KeyboardEvent('keyup', {\n bubbles: true,\n cancelable: true,\n key,\n ...options,\n });\n element.dispatchEvent(event);\n return event;\n },\n\n mouseEnter(element) {\n const event = new MouseEvent('mouseenter', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n\n mouseLeave(element) {\n const event = new MouseEvent('mouseleave', { bubbles: true });\n element.dispatchEvent(event);\n return event;\n },\n};\n\n// --- Wait Utilities ---\n\nexport async function waitFor(callback, options = {}) {\n const { timeout = 1000, interval = 50 } = options;\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n try {\n const result = callback();\n if (result) return result;\n } catch (e) {\n // Keep waiting\n }\n await new Promise(r => setTimeout(r, interval));\n }\n\n throw new Error(`waitFor timed out after ${timeout}ms`);\n}\n\nexport async function waitForElementToBeRemoved(callback, options = {}) {\n const { timeout = 1000, interval = 50 } = options;\n const startTime = Date.now();\n\n // First, element should exist\n let element = callback();\n if (!element) {\n throw new Error('Element not found');\n }\n\n // Then wait for it to be removed\n while (Date.now() - startTime < timeout) {\n element = callback();\n if (!element) return;\n await new Promise(r => setTimeout(r, interval));\n }\n\n throw new Error(`Element still present after ${timeout}ms`);\n}\n\n// --- Act ---\n// Ensure all effects and updates are flushed\n\nexport async function act(callback) {\n const result = await callback();\n // Synchronously flush all pending effects\n flushSync();\n // Wait for microtasks to flush\n await new Promise(r => queueMicrotask(r));\n // Wait for any scheduled effects\n await new Promise(r => setTimeout(r, 0));\n return result;\n}\n\n// --- Signal Testing Helpers ---\n\nexport function createTestSignal(initial) {\n const s = signal(initial);\n const history = [initial];\n\n // Track all changes\n effect(() => {\n history.push(s());\n });\n\n return {\n signal: s,\n get value() { return s(); },\n set value(v) { s.set(v); },\n history,\n reset() {\n history.length = 0;\n history.push(s());\n },\n };\n}\n\n// --- Mocking ---\n\nexport function mockComponent(name = 'MockComponent') {\n const calls = [];\n\n function Mock(props) {\n calls.push({ props, timestamp: Date.now() });\n return h('div', { 'data-testid': `mock-${name}` },\n JSON.stringify(props, null, 2)\n );\n }\n\n Mock.displayName = name;\n Mock.calls = calls;\n Mock.lastCall = () => calls[calls.length - 1];\n Mock.reset = () => { calls.length = 0; };\n\n return Mock;\n}\n\n// --- Assertions ---\n\nexport const expect = {\n toBeInTheDocument(element) {\n if (!element || !element.parentNode) {\n throw new Error('Expected element to be in the document');\n }\n },\n\n toHaveTextContent(element, text) {\n if (!element) {\n throw new Error('Element not found');\n }\n const content = element.textContent;\n const matches = text instanceof RegExp ? text.test(content) : content.includes(text);\n if (!matches) {\n throw new Error(`Expected \"${content}\" to contain \"${text}\"`);\n }\n },\n\n toHaveAttribute(element, attr, value) {\n if (!element) {\n throw new Error('Element not found');\n }\n const attrValue = element.getAttribute(attr);\n if (value !== undefined && attrValue !== value) {\n throw new Error(`Expected attribute \"${attr}\" to be \"${value}\", got \"${attrValue}\"`);\n }\n if (value === undefined && attrValue === null) {\n throw new Error(`Expected element to have attribute \"${attr}\"`);\n }\n },\n\n toHaveClass(element, className) {\n if (!element) {\n throw new Error('Element not found');\n }\n if (!element.classList.contains(className)) {\n throw new Error(`Expected element to have class \"${className}\"`);\n }\n },\n\n toBeVisible(element) {\n if (!element) {\n throw new Error('Element not found');\n }\n const style = window.getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') {\n throw new Error('Expected element to be visible');\n }\n },\n\n toBeDisabled(element) {\n if (!element) {\n throw new Error('Element not found');\n }\n if (!element.disabled) {\n throw new Error('Expected element to be disabled');\n }\n },\n\n toHaveValue(element, value) {\n if (!element) {\n throw new Error('Element not found');\n }\n if (element.value !== value) {\n throw new Error(`Expected value to be \"${value}\", got \"${element.value}\"`);\n }\n },\n};\n\n// --- Screen ---\n// Global query object for convenience\n\nexport const screen = {\n getByText: (text) => queryByText(document.body, text),\n getByTestId: (id) => document.querySelector(`[data-testid=\"${id}\"]`),\n getByRole: (role) => document.querySelector(`[role=\"${role}\"]`),\n getAllByText: (text) => queryAllByText(document.body, text),\n queryByText: (text) => queryByText(document.body, text),\n queryByTestId: (id) => document.querySelector(`[data-testid=\"${id}\"]`),\n debug: () => console.log(document.body.innerHTML),\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["prev", "batch", "cleanup", "container", "props", "container", "cleanup", "container"]
7
7
  }