@llui/dom 0.0.33 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hmr.js +5 -0
- package/dist/hmr.js.map +1 -1
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +5 -0
- package/dist/mount.js.map +1 -1
- package/dist/types.d.ts +23 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/update-loop.d.ts +6 -1
- package/dist/update-loop.d.ts.map +1 -1
- package/dist/update-loop.js +130 -47
- package/dist/update-loop.js.map +1 -1
- package/package.json +1 -1
package/dist/hmr.js
CHANGED
|
@@ -213,6 +213,11 @@ function makeReplacementHandle(name, entry, typedInst) {
|
|
|
213
213
|
const [state, effects] = typedInst.def.update(typedInst.state, msg);
|
|
214
214
|
return { state, effects: effects };
|
|
215
215
|
},
|
|
216
|
+
setOnBindingError(hook) {
|
|
217
|
+
if (disposed)
|
|
218
|
+
return;
|
|
219
|
+
typedInst._onBindingError = hook ?? undefined;
|
|
220
|
+
},
|
|
216
221
|
};
|
|
217
222
|
}
|
|
218
223
|
function captureFocus(root) {
|
package/dist/hmr.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmr.js","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle } from './types.js'\nimport type { ComponentInstance } from './update-loop.js'\nimport { flushInstance } from './update-loop.js'\nimport { createLifetime, disposeLifetime } from './lifetime.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { getBindingDescriptors } from './binding-descriptors.js'\nimport { unregisterInstance } from './runtime.js'\nimport { _setHmrModule } from './mount.js'\nimport { createView } from './view-helpers.js'\n\n/**\n * Enable HMR state preservation. Called by compiler-generated dev code.\n * Importing this module registers it with mountApp for hot-swapping.\n */\nexport function enableHmr(): void {\n _setHmrModule({\n enableHmr,\n registerForHmr,\n registerForAnchor,\n unregisterForHmr,\n replaceComponent,\n })\n}\n\n// ── HMR Registry ─────────────────────────────────────────────────\n\ntype HmrEntry =\n | {\n kind: 'container'\n inst: ComponentInstance\n container: HTMLElement\n }\n | {\n kind: 'anchor'\n inst: ComponentInstance\n anchor: Comment\n endSentinel: Comment\n }\n\nconst hmrRegistry = new Map<string, HmrEntry[]>()\n\nexport function registerForHmr(name: string, inst: object, container: HTMLElement): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ kind: 'container', inst: inst as ComponentInstance, container })\n hmrRegistry.set(name, entries)\n}\n\nexport function registerForAnchor(\n name: string,\n inst: object,\n anchor: Comment,\n endSentinel: Comment,\n): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ kind: 'anchor', inst: inst as ComponentInstance, anchor, endSentinel })\n hmrRegistry.set(name, entries)\n}\n\nexport function unregisterForHmr(name: string, inst: object): void {\n const entries = hmrRegistry.get(name)\n if (!entries) return\n const idx = entries.findIndex((e) => e.inst === inst)\n if (idx !== -1) entries.splice(idx, 1)\n if (entries.length === 0) hmrRegistry.delete(name)\n}\n\n/**\n * Hot-swap a component definition on all live instances.\n *\n * Preserves the current state. Replaces update, view, onEffect, and __dirty.\n * Disposes the old scope tree (removing old DOM and bindings),\n * re-runs view(currentState, send) to rebuild fresh DOM.\n *\n * Returns an AppHandle for the first instance (for mountApp compatibility),\n * or null if no instances are registered (first mount).\n */\nexport function replaceComponent<S, M, E, D = void>(\n name: string,\n newDef: ComponentDef<S, M, E, D>,\n): AppHandle | null {\n const entries = hmrRegistry.get(name)\n if (!entries || entries.length === 0) return null\n\n let handle: AppHandle | null = null\n\n for (const entry of entries) {\n const typedInst = entry.inst as ComponentInstance<S, M, E>\n\n typedInst.def = {\n ...typedInst.def,\n update: newDef.update,\n view: newDef.view,\n onEffect: newDef.onEffect,\n __dirty: newDef.__dirty,\n __update: newDef.__update,\n __handlers: newDef.__handlers,\n }\n\n // Snapshot focus + selection + scroll BEFORE disposal — once the\n // root lifetime tears down its DOM, the activeElement and any\n // scrollable subtree are detached and can't be queried. We\n // restore best-effort after the new view renders. The cost of\n // skipping this step is the every-edit experience: the user\n // types in an input, saves, the input rebuilds and loses focus\n // and cursor position. That kills incremental editing flow.\n const ownerRoot: ParentNode | null =\n entry.kind === 'container' ? entry.container : (entry.anchor.parentElement ?? null)\n const focusSnapshot = ownerRoot ? captureFocus(ownerRoot) : null\n const scrollSnapshot = ownerRoot ? captureScroll(ownerRoot) : null\n\n disposeLifetime(typedInst.rootLifetime)\n\n // Clear the owned region per-kind.\n if (entry.kind === 'container') {\n entry.container.textContent = ''\n } else {\n // anchor kind — wipe siblings between anchor and endSentinel, keep the\n // anchor AND the end sentinel (they bracket the fresh render).\n let sib = entry.anchor.nextSibling\n while (sib !== null && sib !== entry.endSentinel) {\n const next = sib.nextSibling\n sib.parentNode!.removeChild(sib)\n sib = next\n }\n }\n\n typedInst.rootLifetime = createLifetime(null)\n typedInst.rootLifetime._kind = 'root'\n typedInst.allBindings = []\n typedInst.structuralBlocks = []\n\n setFlatBindings(typedInst.allBindings)\n setRenderContext({\n rootLifetime: typedInst.rootLifetime,\n state: typedInst.state,\n allBindings: typedInst.allBindings,\n structuralBlocks: typedInst.structuralBlocks,\n dom: typedInst.dom,\n container:\n entry.kind === 'container' ? entry.container : (entry.anchor.parentElement ?? undefined),\n send: typedInst.send as (msg: unknown) => void,\n instance: typedInst as ComponentInstance,\n })\n const nodes = typedInst.def.view(createView<S, M>(typedInst.send))\n clearRenderContext()\n setFlatBindings(null)\n\n if (entry.kind === 'container') {\n for (const node of nodes) {\n entry.container.appendChild(node)\n }\n } else {\n for (const node of nodes) {\n entry.anchor.parentNode!.insertBefore(node, entry.endSentinel)\n }\n }\n\n // Restore focus, selection, and scroll positions in the freshly\n // rendered DOM. Best-effort: when the new view's DOM has diverged\n // structurally (different IDs, different element ordering, the\n // input that was focused no longer exists), the restorers no-op\n // silently. This is the right tradeoff — failing loudly on\n // structural divergence would just mean every meaningful view\n // edit prints an error.\n if (ownerRoot) {\n if (focusSnapshot) restoreFocus(ownerRoot, focusSnapshot)\n if (scrollSnapshot) restoreScroll(ownerRoot, scrollSnapshot)\n }\n\n if (!handle) {\n handle = makeReplacementHandle(name, entry, typedInst)\n }\n }\n\n console.log(`[LLui HMR] ${name} updated — state preserved`)\n\n return handle\n}\n\nfunction makeReplacementHandle<S, M, E>(\n name: string,\n entry: HmrEntry,\n typedInst: ComponentInstance<S, M, E>,\n): AppHandle {\n const listeners = new Set<(s: unknown) => void>()\n typedInst._onCommit = (state: unknown) => {\n for (const l of Array.from(listeners)) {\n try {\n l(state)\n } catch (err) {\n console.error('[llui] listener threw:', err)\n }\n }\n }\n let disposed = false\n return {\n dispose() {\n if (disposed) return\n disposed = true\n listeners.clear()\n typedInst._onCommit = undefined\n unregisterForHmr(name, entry.inst)\n entry.inst.abortController.abort()\n unregisterInstance(entry.inst)\n disposeLifetime(typedInst.rootLifetime)\n if (entry.kind === 'container') {\n entry.container.textContent = ''\n } else {\n let sib = entry.anchor.nextSibling\n while (sib !== null && sib !== entry.endSentinel) {\n const next = sib.nextSibling\n sib.parentNode!.removeChild(sib)\n sib = next\n }\n entry.endSentinel.parentNode?.removeChild(entry.endSentinel)\n }\n },\n flush() {\n flushInstance(entry.inst)\n },\n send(msg: unknown) {\n ;(typedInst.send as (m: unknown) => void)(msg)\n },\n getState() {\n return typedInst.state\n },\n subscribe(listener: (state: unknown) => void) {\n if (disposed) return () => {}\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n getBindingDescriptors() {\n if (disposed) return []\n return getBindingDescriptors(typedInst as ComponentInstance)\n },\n swapUpdate(newUpdate, newOnEffect) {\n if (disposed) return\n flushInstance(entry.inst)\n ;(typedInst.def as { update: typeof newUpdate }).update = newUpdate\n if (newOnEffect !== undefined) {\n ;(typedInst.def as { onEffect?: typeof newOnEffect }).onEffect = newOnEffect\n }\n },\n runReducer(msg) {\n if (disposed) return null\n const [state, effects] = (\n typedInst.def.update as (s: unknown, m: unknown) => [unknown, unknown[]]\n )(typedInst.state, msg)\n return { state, effects: effects as unknown[] }\n },\n }\n}\n\n// ── Focus / selection / scroll preservation across HMR ──────────\n\n/**\n * What we record before disposing the root DOM. The locator is a\n * structural pointer: prefer `id` (resilient to view restructuring),\n * fall back to a child-index path through the rendered subtree. If\n * the new DOM doesn't match either, the restore call no-ops.\n */\ntype FocusSnapshot = {\n /** The element's `id` if it had one, else `null`. */\n id: string | null\n /** Sibling-index path from `ownerRoot` down to the focused element. */\n path: number[]\n /** Selection range if the focused element is a text input/textarea. */\n selection: { start: number; end: number; direction: 'forward' | 'backward' | 'none' } | null\n}\n\ntype ScrollSnapshot = Array<{\n id: string | null\n path: number[]\n scrollTop: number\n scrollLeft: number\n}>\n\nfunction captureFocus(root: ParentNode): FocusSnapshot | null {\n const doc = (root as Element).ownerDocument ?? globalThis.document\n if (!doc) return null\n const active = doc.activeElement\n if (!active || active === doc.body) return null\n // Only capture focus for elements inside our owned subtree —\n // anything outside is not ours to restore.\n if (!(root as ParentNode & Node).contains(active)) return null\n\n const path = pathFromAncestor(root as Node, active)\n if (path === null) return null\n\n let selection: FocusSnapshot['selection'] = null\n if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement) {\n // Some input types (number, email, etc.) reject selectionStart access.\n // Wrapper try/catch keeps the snapshot resilient to those cases.\n try {\n if (active.selectionStart !== null && active.selectionEnd !== null) {\n selection = {\n start: active.selectionStart,\n end: active.selectionEnd,\n direction: (active.selectionDirection ?? 'none') as 'forward' | 'backward' | 'none',\n }\n }\n } catch {\n selection = null\n }\n }\n\n return {\n id: active.id || null,\n path,\n selection,\n }\n}\n\nfunction restoreFocus(root: ParentNode, snap: FocusSnapshot): void {\n const target = locate(root, snap.id, snap.path)\n if (!target || !(target instanceof HTMLElement)) return\n try {\n target.focus({ preventScroll: true })\n } catch {\n return\n }\n if (\n snap.selection &&\n (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement)\n ) {\n try {\n target.setSelectionRange(snap.selection.start, snap.selection.end, snap.selection.direction)\n } catch {\n // Some input types throw on setSelectionRange; ignore.\n }\n }\n}\n\nfunction captureScroll(root: ParentNode): ScrollSnapshot {\n // Walk the subtree and snapshot every element with non-zero\n // scroll. Most subtrees have at most a handful, so the per-edit\n // cost is small. Capturing all-zeroes wastes the restore work for\n // no benefit; the filter keeps things tight.\n const out: ScrollSnapshot = []\n const walk = (node: Node): void => {\n if (node instanceof HTMLElement) {\n if (node.scrollTop !== 0 || node.scrollLeft !== 0) {\n const path = pathFromAncestor(root as Node, node)\n if (path !== null) {\n out.push({\n id: node.id || null,\n path,\n scrollTop: node.scrollTop,\n scrollLeft: node.scrollLeft,\n })\n }\n }\n }\n for (let c = node.firstChild; c !== null; c = c.nextSibling) {\n walk(c)\n }\n }\n walk(root as Node)\n return out\n}\n\nfunction restoreScroll(root: ParentNode, snap: ScrollSnapshot): void {\n for (const s of snap) {\n const target = locate(root, s.id, s.path)\n if (!target || !(target instanceof HTMLElement)) continue\n target.scrollTop = s.scrollTop\n target.scrollLeft = s.scrollLeft\n }\n}\n\n/**\n * Compute the child-index path from `ancestor` down to `target`, or\n * `null` if `target` isn't in the subtree. The path is what gets\n * walked on restore — no document-wide selectors, no string-encoded\n * selectors that can break on punctuation in IDs.\n */\nfunction pathFromAncestor(ancestor: Node, target: Node): number[] | null {\n const path: number[] = []\n let cur: Node | null = target\n while (cur !== null && cur !== ancestor) {\n const parent: Node | null = cur.parentNode\n if (parent === null) return null\n let idx = 0\n let sib: Node | null = parent.firstChild\n while (sib !== null && sib !== cur) {\n idx++\n sib = sib.nextSibling\n }\n if (sib === null) return null\n path.push(idx)\n cur = parent\n }\n if (cur !== ancestor) return null\n return path.reverse()\n}\n\n/**\n * Restore lookup: try `id` first (cheap and resilient to structural\n * change), then walk the captured child-index path. Returns `null`\n * if neither lookup succeeds — the restore caller silently no-ops.\n */\nfunction locate(root: ParentNode, id: string | null, path: number[]): Element | null {\n if (id) {\n const doc = (root as Element).ownerDocument ?? globalThis.document\n if (doc) {\n const byId = doc.getElementById(id)\n if (byId && (root as ParentNode & Node).contains(byId)) return byId\n }\n }\n let cur: Node = root as Node\n for (const idx of path) {\n let child = cur.firstChild\n let i = 0\n while (child && i < idx) {\n child = child.nextSibling\n i++\n }\n if (!child) return null\n cur = child\n }\n return cur instanceof Element ? cur : null\n}\n"]}
|
|
1
|
+
{"version":3,"file":"hmr.js","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle } from './types.js'\nimport type { ComponentInstance } from './update-loop.js'\nimport { flushInstance } from './update-loop.js'\nimport { createLifetime, disposeLifetime } from './lifetime.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { getBindingDescriptors } from './binding-descriptors.js'\nimport { unregisterInstance } from './runtime.js'\nimport { _setHmrModule } from './mount.js'\nimport { createView } from './view-helpers.js'\n\n/**\n * Enable HMR state preservation. Called by compiler-generated dev code.\n * Importing this module registers it with mountApp for hot-swapping.\n */\nexport function enableHmr(): void {\n _setHmrModule({\n enableHmr,\n registerForHmr,\n registerForAnchor,\n unregisterForHmr,\n replaceComponent,\n })\n}\n\n// ── HMR Registry ─────────────────────────────────────────────────\n\ntype HmrEntry =\n | {\n kind: 'container'\n inst: ComponentInstance\n container: HTMLElement\n }\n | {\n kind: 'anchor'\n inst: ComponentInstance\n anchor: Comment\n endSentinel: Comment\n }\n\nconst hmrRegistry = new Map<string, HmrEntry[]>()\n\nexport function registerForHmr(name: string, inst: object, container: HTMLElement): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ kind: 'container', inst: inst as ComponentInstance, container })\n hmrRegistry.set(name, entries)\n}\n\nexport function registerForAnchor(\n name: string,\n inst: object,\n anchor: Comment,\n endSentinel: Comment,\n): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ kind: 'anchor', inst: inst as ComponentInstance, anchor, endSentinel })\n hmrRegistry.set(name, entries)\n}\n\nexport function unregisterForHmr(name: string, inst: object): void {\n const entries = hmrRegistry.get(name)\n if (!entries) return\n const idx = entries.findIndex((e) => e.inst === inst)\n if (idx !== -1) entries.splice(idx, 1)\n if (entries.length === 0) hmrRegistry.delete(name)\n}\n\n/**\n * Hot-swap a component definition on all live instances.\n *\n * Preserves the current state. Replaces update, view, onEffect, and __dirty.\n * Disposes the old scope tree (removing old DOM and bindings),\n * re-runs view(currentState, send) to rebuild fresh DOM.\n *\n * Returns an AppHandle for the first instance (for mountApp compatibility),\n * or null if no instances are registered (first mount).\n */\nexport function replaceComponent<S, M, E, D = void>(\n name: string,\n newDef: ComponentDef<S, M, E, D>,\n): AppHandle | null {\n const entries = hmrRegistry.get(name)\n if (!entries || entries.length === 0) return null\n\n let handle: AppHandle | null = null\n\n for (const entry of entries) {\n const typedInst = entry.inst as ComponentInstance<S, M, E>\n\n typedInst.def = {\n ...typedInst.def,\n update: newDef.update,\n view: newDef.view,\n onEffect: newDef.onEffect,\n __dirty: newDef.__dirty,\n __update: newDef.__update,\n __handlers: newDef.__handlers,\n }\n\n // Snapshot focus + selection + scroll BEFORE disposal — once the\n // root lifetime tears down its DOM, the activeElement and any\n // scrollable subtree are detached and can't be queried. We\n // restore best-effort after the new view renders. The cost of\n // skipping this step is the every-edit experience: the user\n // types in an input, saves, the input rebuilds and loses focus\n // and cursor position. That kills incremental editing flow.\n const ownerRoot: ParentNode | null =\n entry.kind === 'container' ? entry.container : (entry.anchor.parentElement ?? null)\n const focusSnapshot = ownerRoot ? captureFocus(ownerRoot) : null\n const scrollSnapshot = ownerRoot ? captureScroll(ownerRoot) : null\n\n disposeLifetime(typedInst.rootLifetime)\n\n // Clear the owned region per-kind.\n if (entry.kind === 'container') {\n entry.container.textContent = ''\n } else {\n // anchor kind — wipe siblings between anchor and endSentinel, keep the\n // anchor AND the end sentinel (they bracket the fresh render).\n let sib = entry.anchor.nextSibling\n while (sib !== null && sib !== entry.endSentinel) {\n const next = sib.nextSibling\n sib.parentNode!.removeChild(sib)\n sib = next\n }\n }\n\n typedInst.rootLifetime = createLifetime(null)\n typedInst.rootLifetime._kind = 'root'\n typedInst.allBindings = []\n typedInst.structuralBlocks = []\n\n setFlatBindings(typedInst.allBindings)\n setRenderContext({\n rootLifetime: typedInst.rootLifetime,\n state: typedInst.state,\n allBindings: typedInst.allBindings,\n structuralBlocks: typedInst.structuralBlocks,\n dom: typedInst.dom,\n container:\n entry.kind === 'container' ? entry.container : (entry.anchor.parentElement ?? undefined),\n send: typedInst.send as (msg: unknown) => void,\n instance: typedInst as ComponentInstance,\n })\n const nodes = typedInst.def.view(createView<S, M>(typedInst.send))\n clearRenderContext()\n setFlatBindings(null)\n\n if (entry.kind === 'container') {\n for (const node of nodes) {\n entry.container.appendChild(node)\n }\n } else {\n for (const node of nodes) {\n entry.anchor.parentNode!.insertBefore(node, entry.endSentinel)\n }\n }\n\n // Restore focus, selection, and scroll positions in the freshly\n // rendered DOM. Best-effort: when the new view's DOM has diverged\n // structurally (different IDs, different element ordering, the\n // input that was focused no longer exists), the restorers no-op\n // silently. This is the right tradeoff — failing loudly on\n // structural divergence would just mean every meaningful view\n // edit prints an error.\n if (ownerRoot) {\n if (focusSnapshot) restoreFocus(ownerRoot, focusSnapshot)\n if (scrollSnapshot) restoreScroll(ownerRoot, scrollSnapshot)\n }\n\n if (!handle) {\n handle = makeReplacementHandle(name, entry, typedInst)\n }\n }\n\n console.log(`[LLui HMR] ${name} updated — state preserved`)\n\n return handle\n}\n\nfunction makeReplacementHandle<S, M, E>(\n name: string,\n entry: HmrEntry,\n typedInst: ComponentInstance<S, M, E>,\n): AppHandle {\n const listeners = new Set<(s: unknown) => void>()\n typedInst._onCommit = (state: unknown) => {\n for (const l of Array.from(listeners)) {\n try {\n l(state)\n } catch (err) {\n console.error('[llui] listener threw:', err)\n }\n }\n }\n let disposed = false\n return {\n dispose() {\n if (disposed) return\n disposed = true\n listeners.clear()\n typedInst._onCommit = undefined\n unregisterForHmr(name, entry.inst)\n entry.inst.abortController.abort()\n unregisterInstance(entry.inst)\n disposeLifetime(typedInst.rootLifetime)\n if (entry.kind === 'container') {\n entry.container.textContent = ''\n } else {\n let sib = entry.anchor.nextSibling\n while (sib !== null && sib !== entry.endSentinel) {\n const next = sib.nextSibling\n sib.parentNode!.removeChild(sib)\n sib = next\n }\n entry.endSentinel.parentNode?.removeChild(entry.endSentinel)\n }\n },\n flush() {\n flushInstance(entry.inst)\n },\n send(msg: unknown) {\n ;(typedInst.send as (m: unknown) => void)(msg)\n },\n getState() {\n return typedInst.state\n },\n subscribe(listener: (state: unknown) => void) {\n if (disposed) return () => {}\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n getBindingDescriptors() {\n if (disposed) return []\n return getBindingDescriptors(typedInst as ComponentInstance)\n },\n swapUpdate(newUpdate, newOnEffect) {\n if (disposed) return\n flushInstance(entry.inst)\n ;(typedInst.def as { update: typeof newUpdate }).update = newUpdate\n if (newOnEffect !== undefined) {\n ;(typedInst.def as { onEffect?: typeof newOnEffect }).onEffect = newOnEffect\n }\n },\n runReducer(msg) {\n if (disposed) return null\n const [state, effects] = (\n typedInst.def.update as (s: unknown, m: unknown) => [unknown, unknown[]]\n )(typedInst.state, msg)\n return { state, effects: effects as unknown[] }\n },\n setOnBindingError(hook) {\n if (disposed) return\n typedInst._onBindingError = hook ?? undefined\n },\n }\n}\n\n// ── Focus / selection / scroll preservation across HMR ──────────\n\n/**\n * What we record before disposing the root DOM. The locator is a\n * structural pointer: prefer `id` (resilient to view restructuring),\n * fall back to a child-index path through the rendered subtree. If\n * the new DOM doesn't match either, the restore call no-ops.\n */\ntype FocusSnapshot = {\n /** The element's `id` if it had one, else `null`. */\n id: string | null\n /** Sibling-index path from `ownerRoot` down to the focused element. */\n path: number[]\n /** Selection range if the focused element is a text input/textarea. */\n selection: { start: number; end: number; direction: 'forward' | 'backward' | 'none' } | null\n}\n\ntype ScrollSnapshot = Array<{\n id: string | null\n path: number[]\n scrollTop: number\n scrollLeft: number\n}>\n\nfunction captureFocus(root: ParentNode): FocusSnapshot | null {\n const doc = (root as Element).ownerDocument ?? globalThis.document\n if (!doc) return null\n const active = doc.activeElement\n if (!active || active === doc.body) return null\n // Only capture focus for elements inside our owned subtree —\n // anything outside is not ours to restore.\n if (!(root as ParentNode & Node).contains(active)) return null\n\n const path = pathFromAncestor(root as Node, active)\n if (path === null) return null\n\n let selection: FocusSnapshot['selection'] = null\n if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement) {\n // Some input types (number, email, etc.) reject selectionStart access.\n // Wrapper try/catch keeps the snapshot resilient to those cases.\n try {\n if (active.selectionStart !== null && active.selectionEnd !== null) {\n selection = {\n start: active.selectionStart,\n end: active.selectionEnd,\n direction: (active.selectionDirection ?? 'none') as 'forward' | 'backward' | 'none',\n }\n }\n } catch {\n selection = null\n }\n }\n\n return {\n id: active.id || null,\n path,\n selection,\n }\n}\n\nfunction restoreFocus(root: ParentNode, snap: FocusSnapshot): void {\n const target = locate(root, snap.id, snap.path)\n if (!target || !(target instanceof HTMLElement)) return\n try {\n target.focus({ preventScroll: true })\n } catch {\n return\n }\n if (\n snap.selection &&\n (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement)\n ) {\n try {\n target.setSelectionRange(snap.selection.start, snap.selection.end, snap.selection.direction)\n } catch {\n // Some input types throw on setSelectionRange; ignore.\n }\n }\n}\n\nfunction captureScroll(root: ParentNode): ScrollSnapshot {\n // Walk the subtree and snapshot every element with non-zero\n // scroll. Most subtrees have at most a handful, so the per-edit\n // cost is small. Capturing all-zeroes wastes the restore work for\n // no benefit; the filter keeps things tight.\n const out: ScrollSnapshot = []\n const walk = (node: Node): void => {\n if (node instanceof HTMLElement) {\n if (node.scrollTop !== 0 || node.scrollLeft !== 0) {\n const path = pathFromAncestor(root as Node, node)\n if (path !== null) {\n out.push({\n id: node.id || null,\n path,\n scrollTop: node.scrollTop,\n scrollLeft: node.scrollLeft,\n })\n }\n }\n }\n for (let c = node.firstChild; c !== null; c = c.nextSibling) {\n walk(c)\n }\n }\n walk(root as Node)\n return out\n}\n\nfunction restoreScroll(root: ParentNode, snap: ScrollSnapshot): void {\n for (const s of snap) {\n const target = locate(root, s.id, s.path)\n if (!target || !(target instanceof HTMLElement)) continue\n target.scrollTop = s.scrollTop\n target.scrollLeft = s.scrollLeft\n }\n}\n\n/**\n * Compute the child-index path from `ancestor` down to `target`, or\n * `null` if `target` isn't in the subtree. The path is what gets\n * walked on restore — no document-wide selectors, no string-encoded\n * selectors that can break on punctuation in IDs.\n */\nfunction pathFromAncestor(ancestor: Node, target: Node): number[] | null {\n const path: number[] = []\n let cur: Node | null = target\n while (cur !== null && cur !== ancestor) {\n const parent: Node | null = cur.parentNode\n if (parent === null) return null\n let idx = 0\n let sib: Node | null = parent.firstChild\n while (sib !== null && sib !== cur) {\n idx++\n sib = sib.nextSibling\n }\n if (sib === null) return null\n path.push(idx)\n cur = parent\n }\n if (cur !== ancestor) return null\n return path.reverse()\n}\n\n/**\n * Restore lookup: try `id` first (cheap and resilient to structural\n * change), then walk the captured child-index path. Returns `null`\n * if neither lookup succeeds — the restore caller silently no-ops.\n */\nfunction locate(root: ParentNode, id: string | null, path: number[]): Element | null {\n if (id) {\n const doc = (root as Element).ownerDocument ?? globalThis.document\n if (doc) {\n const byId = doc.getElementById(id)\n if (byId && (root as ParentNode & Node).contains(byId)) return byId\n }\n }\n let cur: Node = root as Node\n for (const idx of path) {\n let child = cur.firstChild\n let i = 0\n while (child && i < idx) {\n child = child.nextSibling\n i++\n }\n if (!child) return null\n cur = child\n }\n return cur instanceof Element ? cur : null\n}\n"]}
|
package/dist/mount.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACnE,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,cAAc,CAAA;AA4CtD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,UAAU;QAClB,GAAG,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KACxB;CACF;AAoCD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,QAAQ,CAAA;IACzB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC9B,SAAS,EAAE,WAAW,EACtB,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAAA;AACZ,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EACjC,SAAS,EAAE,WAAW,EACtB,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7B,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAAA;AAiIZ;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACnC,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAAA;AACZ,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EACtC,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7B,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAAA;AAsFZ;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAC/C,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7B,WAAW,EAAE,CAAC,EACd,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAyEX;
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACnE,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,cAAc,CAAA;AA4CtD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,UAAU;QAClB,GAAG,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KACxB;CACF;AAoCD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,QAAQ,CAAA;IACzB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC9B,SAAS,EAAE,WAAW,EACtB,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAAA;AACZ,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EACjC,SAAS,EAAE,WAAW,EACtB,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7B,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAAA;AAiIZ;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACnC,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAAA;AACZ,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EACtC,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7B,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAAA;AAsFZ;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAC/C,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7B,WAAW,EAAE,CAAC,EACd,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAyEX;AA2JD,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAC1C,SAAS,EAAE,WAAW,EACtB,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7B,WAAW,EAAE,CAAC,EACd,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CA8EX"}
|
package/dist/mount.js
CHANGED
|
@@ -461,6 +461,11 @@ function buildAppHandle(inst, hmrName, domCleanup) {
|
|
|
461
461
|
const [state, effects] = inst.def.update(inst.state, msg);
|
|
462
462
|
return { state, effects: effects };
|
|
463
463
|
},
|
|
464
|
+
setOnBindingError(hook) {
|
|
465
|
+
if (disposed)
|
|
466
|
+
return;
|
|
467
|
+
inst._onBindingError = hook ?? undefined;
|
|
468
|
+
},
|
|
464
469
|
};
|
|
465
470
|
}
|
|
466
471
|
export function hydrateApp(container, def, serverState, options) {
|
package/dist/mount.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle, Lifetime } from './types.js'\nimport { type DomEnv, browserEnv } from './dom-env.js'\nimport { createComponentInstance, flushInstance, type ComponentInstance } from './update-loop.js'\nimport { disposeLifetime } from './lifetime.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { getBindingDescriptors } from './binding-descriptors.js'\nimport { registerInstance, unregisterInstance } from './runtime.js'\nimport { createView } from './view-helpers.js'\nimport { pushMountQueue, popMountQueue, flushMountQueue } from './primitives/on-mount.js'\n\n// ── Sentinel-region helpers (used by anchor-based mount primitives) ─────\n\n/**\n * Remove every sibling from `anchor.nextSibling` up to but not including\n * `stopBefore`. Used by anchor-based mount primitives and their HMR\n * swap path to clear the owned DOM region between the pair.\n */\nfunction _removeBetween(anchor: Comment, stopBefore: Comment): void {\n const parent = anchor.parentNode\n if (parent === null) return\n while (anchor.nextSibling !== null && anchor.nextSibling !== stopBefore) {\n parent.removeChild(anchor.nextSibling)\n }\n}\n\n/**\n * Walk forward from `anchor.nextSibling` looking for an existing\n * `<!-- llui-mount-end -->` sentinel. Used by mount/hydrate at anchor\n * to reuse a server-emitted (or stale) sentinel rather than synthesizing\n * a duplicate. Returns null if no matching comment is found before the\n * end of the parent's children.\n */\nfunction _findEndSentinel(anchor: Comment): Comment | null {\n let node: Node | null = anchor.nextSibling\n while (node !== null) {\n if (node.nodeType === 8 && (node as Comment).nodeValue === 'llui-mount-end') {\n return node as Comment\n }\n node = node.nextSibling\n }\n return null\n}\n\n// Vite injects import.meta.env.DEV — declare the shape for TypeScript\ndeclare global {\n interface ImportMeta {\n env?: { DEV?: boolean }\n }\n}\n\n// ── HMR (dev only) ──────────────────────────────────────────────\n// Set by enableHmr() from '@llui/dom/hmr' — never imported in production.\n\nlet hmrModule: typeof import('./hmr') | null = null\n\n/**\n * @internal Called by enableHmr in the hmr module. Tests use this\n * (paired with `_getHmrModule`) to snapshot/restore prior state across\n * suite boundaries — pass `null` to clear.\n */\nexport function _setHmrModule(m: typeof import('./hmr') | null): void {\n hmrModule = m\n}\n\n/** @internal Read the currently-installed HMR module (or null). */\nexport function _getHmrModule(): typeof import('./hmr') | null {\n return hmrModule\n}\n\n// ── DevTools auto-install (dev only) ────────────────────────────\n// Set by enableDevTools() from '@llui/dom/devtools' — never imported in production.\n\nlet devToolsInstall: ((inst: object) => void) | null = null\n\n/** @internal Called by enableDevTools in the devtools module */\nexport function _setDevToolsInstall(fn: ((inst: object) => void) | null): void {\n devToolsInstall = fn\n}\n\n/** @internal Read the currently-installed devtools-install hook (or null). */\nexport function _getDevToolsInstall(): ((inst: object) => void) | null {\n return devToolsInstall\n}\n\nexport interface MountOptions {\n devTools?: boolean\n /**\n * Parent scope for the mounted component's rootLifetime. When provided,\n * the rootLifetime is created as a child of this scope — context lookups\n * from within the component walk up through the parent's scope tree,\n * and disposing the parent scope cascades into this instance's scope.\n * Used by `@llui/vike`'s persistent-layout machinery to mount a page\n * as a true scope-tree child of its enclosing layout, so layout-\n * provided contexts flow naturally into pages via `useContext`.\n *\n * When omitted (the default), the rootLifetime is detached — same as\n * every `mountApp` call before persistent layouts existed.\n */\n parentLifetime?: Lifetime\n /**\n * DOM env override. Defaults to `browserEnv()` — wraps the browser\n * globals. Specify only when mounting into a non-browser DOM (e.g.\n * a jsdom instance held by a test harness, or isolated DOM per\n * shadow root).\n */\n env?: DomEnv\n /**\n * **`hydrateApp` / `hydrateAtAnchor` only.** When `true`, fire the\n * effects that `init()` returned during hydration the same way\n * `mountApp` does on a fresh mount. Defaults to `false` because the\n * SSR render already ran `init()` on the server, and re-running its\n * effects on the client typically produces duplicate work — an\n * `httpGet` issued from `init()` would fetch on the server *and* on\n * hydration; a subscription would attach twice; etc.\n *\n * Opt in only when:\n * - `init()` returns no effects, OR\n * - all returned effects are idempotent / client-only (e.g.\n * wiring a `window` event listener, opening a `WebSocket`), AND\n * - the SSR path didn't run them (typically when `init()` checks a\n * `loaded` flag in state and returns `[]` on the server).\n *\n * Pre-0.0.31 behavior was to always run init effects on hydrate;\n * the option preserves it on demand for projects that depended on\n * it. The default-off direction matches the safer expectation that\n * \"hydration should be cheap and side-effect-free.\"\n */\n runInitEffectsOnHydrate?: boolean\n}\n\nexport function mountApp<S, M, E>(\n container: HTMLElement,\n def: ComponentDef<S, M, E>,\n data?: undefined,\n options?: MountOptions,\n): AppHandle\nexport function mountApp<S, M, E, D>(\n container: HTMLElement,\n def: ComponentDef<S, M, E, D>,\n data: D,\n options?: MountOptions,\n): AppHandle\nexport function mountApp<S, M, E, D>(\n container: HTMLElement,\n def: ComponentDef<S, M, E, D>,\n data?: D,\n options?: MountOptions,\n): AppHandle {\n // HMR: if this component is already mounted (module re-execution\n // during hot update), swap the definition instead of creating a new instance.\n // HMR swap bypasses parentLifetime — HMR re-mounts the outermost app handle,\n // which in a layout setup means the layout re-mounts at the root and the\n // rest of the chain is re-established via the normal mount path.\n if (hmrModule && def.name && !options?.parentLifetime) {\n const swapped = hmrModule.replaceComponent(def.name, def)\n if (swapped) return swapped\n }\n\n const inst = createComponentInstance(def, data, options?.parentLifetime ?? null, options?.env)\n\n // Dev-only: auto-install devtools if enabled via '@llui/dom/devtools' import\n if (devToolsInstall) devToolsInstall(inst)\n\n // Dev-only: warn if initial state contains non-serializable values.\n // Silent bug-bomb: Date/Map/Set/class instances break SSR, hydration, replay tools.\n if (import.meta.env?.DEV) {\n const offender = findNonSerializable(inst.state)\n if (offender) {\n console.warn(\n `[LLui] <${def.name}> initial state contains a non-serializable value at \"${offender.path}\":`,\n offender.value,\n '\\nState must be plain JSON (no Date/Map/Set/class instances/functions).' +\n '\\nThis will break SSR hydration, state replay, and devtools snapshots.' +\n '\\nhint: Convert to a serializable representation (e.g., Date → ISO string, Map → Record).',\n )\n }\n }\n\n // Run view() within a render context so primitives can register bindings.\n // Also collect onMount callbacks in a queue we'll flush synchronously\n // after node insertion — prevents the race where a user event fires\n // between mount and the queueMicrotask callback running.\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({\n ...inst,\n container,\n send: inst.send as (msg: unknown) => void,\n instance: inst as ComponentInstance,\n })\n const nodes = def.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Batch-insert via DocumentFragment — one layout-invalidating operation\n // instead of N individual appendChild calls on a live container element.\n if (nodes.length > 1) {\n const frag = inst.dom.createDocumentFragment()\n for (const node of nodes) frag.appendChild(node)\n container.appendChild(frag)\n } else if (nodes.length === 1) {\n container.appendChild(nodes[0]!)\n }\n\n // Flush onMount callbacks SYNCHRONOUSLY now that the DOM is in place.\n // Any listeners they attach are ready before this function returns,\n // so a synchronous dispatchEvent in the caller's next line fires\n // against a fully-wired tree.\n flushMountQueue(onMountQueue)\n\n registerInstance(inst)\n if (hmrModule && def.name) {\n hmrModule.registerForHmr(def.name, inst, container)\n }\n dispatchInitialEffects(inst)\n return buildAppHandle(inst, def.name ?? null, () => {\n container.textContent = ''\n })\n}\n\n// Walks an object graph looking for non-JSON-serializable values. Returns the\n// first offender found (depth-first), or null if everything is fine. Stops at\n// depth 6 to bound runtime cost for large states.\nfunction findNonSerializable(\n v: unknown,\n path = 'state',\n depth = 0,\n seen = new WeakSet<object>(),\n): { path: string; value: unknown } | null {\n if (depth > 6) return null\n if (v === null || v === undefined) return null\n const t = typeof v\n if (t === 'string' || t === 'number' || t === 'boolean') return null\n if (t === 'function') return { path, value: v }\n if (t === 'symbol' || t === 'bigint') return { path, value: v }\n if (t !== 'object') return null\n const obj = v as object\n if (seen.has(obj)) return null\n seen.add(obj)\n if (obj instanceof Date) return { path: `${path} (Date)`, value: v }\n if (obj instanceof Map) return { path: `${path} (Map)`, value: v }\n if (obj instanceof Set) return { path: `${path} (Set)`, value: v }\n if (obj instanceof RegExp) return { path: `${path} (RegExp)`, value: v }\n if (obj instanceof Promise) return { path: `${path} (Promise)`, value: v }\n // Plain objects/arrays have Object.prototype / Array.prototype. Class instances\n // have a different prototype.\n const proto = Object.getPrototypeOf(obj)\n if (proto !== null && proto !== Object.prototype && proto !== Array.prototype) {\n return { path: `${path} (${proto?.constructor?.name ?? 'class instance'})`, value: v }\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const r = findNonSerializable(v[i], `${path}[${i}]`, depth + 1, seen)\n if (r) return r\n }\n return null\n }\n for (const k of Object.keys(obj)) {\n const r = findNonSerializable(\n (obj as Record<string, unknown>)[k],\n `${path}.${k}`,\n depth + 1,\n seen,\n )\n if (r) return r\n }\n return null\n}\n\n/**\n * Mount a component relative to a comment anchor rather than inside a\n * container element. Inserts a synthesized end sentinel (`<!-- llui-mount-end -->`)\n * immediately after the anchor and places the component's nodes between\n * the pair. The anchor must already be attached to a live DOM tree.\n *\n * Unlike `mountApp`, the caller's anchor node is preserved across the\n * handle's lifetime — only the content between the pair (and the end\n * sentinel itself) is disposed. Used by `@llui/vike` persistent layouts\n * to mount chain layers without a wrapper element.\n *\n * If a pre-existing `<!-- llui-mount-end -->` is found after the anchor\n * (e.g. stale from an undisposed prior mount), the content between the\n * anchor and that sentinel is swept and the sentinel is reused. Dev mode\n * warns in that case.\n */\nexport function mountAtAnchor<S, M, E>(\n anchor: Comment,\n def: ComponentDef<S, M, E>,\n data?: undefined,\n options?: MountOptions,\n): AppHandle\nexport function mountAtAnchor<S, M, E, D>(\n anchor: Comment,\n def: ComponentDef<S, M, E, D>,\n data: D,\n options?: MountOptions,\n): AppHandle\nexport function mountAtAnchor<S, M, E, D>(\n anchor: Comment,\n def: ComponentDef<S, M, E, D>,\n data?: D,\n options?: MountOptions,\n): AppHandle {\n if (anchor.parentNode === null) {\n throw new Error(\n `[LLui] mountAtAnchor: anchor comment must be attached to a live DOM tree before mount`,\n )\n }\n\n // Locate or synthesize the end sentinel.\n const existingEnd = _findEndSentinel(anchor)\n let endSentinel: Comment\n if (existingEnd !== null) {\n if (import.meta.env?.DEV) {\n console.warn(\n `[LLui] mountAtAnchor: anchor has a pre-existing end sentinel. ` +\n `A prior mount was not disposed — sweeping stale siblings and reusing the sentinel.`,\n )\n }\n _removeBetween(anchor, existingEnd)\n endSentinel = existingEnd\n } else {\n // Use the caller-provided env if any — end-sentinel creation happens\n // before `inst` exists, so we pick the env directly from options.\n // (browserEnv() fallback matches what createComponentInstance will\n // use below when options.env is undefined.)\n endSentinel = (options?.env ?? browserEnv()).createComment('llui-mount-end')\n anchor.parentNode.insertBefore(endSentinel, anchor.nextSibling)\n }\n\n const inst = createComponentInstance(def, data, options?.parentLifetime ?? null, options?.env)\n\n if (devToolsInstall) devToolsInstall(inst)\n\n if (import.meta.env?.DEV) {\n const offender = findNonSerializable(inst.state)\n if (offender) {\n console.warn(\n `[LLui] <${def.name}> initial state contains a non-serializable value at \"${offender.path}\":`,\n offender.value,\n '\\nState must be plain JSON (no Date/Map/Set/class instances/functions).' +\n '\\nThis will break SSR hydration, state replay, and devtools snapshots.' +\n '\\nhint: Convert to a serializable representation (e.g., Date → ISO string, Map → Record).',\n )\n }\n }\n\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({\n ...inst,\n container: anchor.parentElement ?? undefined,\n send: inst.send as (msg: unknown) => void,\n instance: inst as ComponentInstance,\n })\n const nodes = def.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Batch-insert via DocumentFragment — one layout pass instead of N.\n if (nodes.length > 1) {\n const frag = inst.dom.createDocumentFragment()\n for (const node of nodes) frag.appendChild(node)\n anchor.parentNode.insertBefore(frag, endSentinel)\n } else if (nodes.length === 1) {\n anchor.parentNode.insertBefore(nodes[0]!, endSentinel)\n }\n\n flushMountQueue(onMountQueue)\n\n registerInstance(inst)\n if (hmrModule && def.name) {\n hmrModule.registerForAnchor(def.name, inst, anchor, endSentinel)\n }\n dispatchInitialEffects(inst)\n return buildAppHandle(inst, def.name ?? null, () => {\n _removeBetween(anchor, endSentinel)\n endSentinel.parentNode?.removeChild(endSentinel)\n })\n}\n\n/**\n * Hydrate a component relative to a comment anchor rather than inside a\n * container element. Analogous to `hydrateApp` — uses `serverState` as\n * the initial state (not `init()`'s output) while preserving `init()`'s\n * effects for post-mount dispatch.\n *\n * The DOM-handling path is identical to `mountAtAnchor`: reuses a\n * pre-existing end sentinel when present, synthesizes one otherwise.\n * Atomic-swaps the owned region whether or not server content is there\n * to replace. No error for a missing end sentinel — the vike chain's\n * outer `hydrateApp`'s `replaceChildren` wipes inner layers' sentinels,\n * so inner-layer `hydrateAtAnchor` calls routinely find nothing to\n * reuse, and that's normal.\n */\nexport function hydrateAtAnchor<S, M, E, D = void>(\n anchor: Comment,\n def: ComponentDef<S, M, E, D>,\n serverState: S,\n options?: MountOptions,\n): AppHandle {\n if (anchor.parentNode === null) {\n throw new Error(\n `[LLui] hydrateAtAnchor: anchor comment must be attached to a live DOM tree before hydrate`,\n )\n }\n\n const existingEnd = _findEndSentinel(anchor)\n let endSentinel: Comment\n if (existingEnd !== null) {\n _removeBetween(anchor, existingEnd)\n endSentinel = existingEnd\n } else {\n endSentinel = (options?.env ?? browserEnv()).createComment('llui-mount-end')\n anchor.parentNode.insertBefore(endSentinel, anchor.nextSibling)\n }\n\n // Run original init() to capture effects, then override state with server's.\n const [, originalEffects] = (def.init as (data: unknown) => [S, E[]])(undefined)\n const hydrateDef: ComponentDef<S, M, E> = {\n ...def,\n init: () => [serverState, originalEffects],\n }\n\n const inst = createComponentInstance(\n hydrateDef,\n undefined,\n options?.parentLifetime ?? null,\n options?.env,\n )\n\n if (devToolsInstall) devToolsInstall(inst)\n\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({\n ...inst,\n container: anchor.parentElement ?? undefined,\n send: inst.send as (msg: unknown) => void,\n instance: inst as ComponentInstance,\n })\n const nodes = hydrateDef.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n if (nodes.length > 1) {\n const frag = inst.dom.createDocumentFragment()\n for (const node of nodes) frag.appendChild(node)\n anchor.parentNode.insertBefore(frag, endSentinel)\n } else if (nodes.length === 1) {\n anchor.parentNode.insertBefore(nodes[0]!, endSentinel)\n }\n\n flushMountQueue(onMountQueue)\n\n registerInstance(inst)\n if (hmrModule && def.name) {\n hmrModule.registerForAnchor(def.name, inst, anchor, endSentinel)\n }\n // Hydration: skip init's effects by default. The SSR pass already ran\n // them on the server; re-running on the client typically produces\n // duplicate work (double fetches, double subscriptions). Opt back in\n // via `MountOptions.runInitEffectsOnHydrate: true`.\n if (options?.runInitEffectsOnHydrate) {\n dispatchInitialEffects(inst)\n } else {\n warnDroppedInitEffects(inst, 'hydrateAtAnchor')\n }\n return buildAppHandle(inst, def.name ?? null, () => {\n _removeBetween(anchor, endSentinel)\n endSentinel.parentNode?.removeChild(endSentinel)\n })\n}\n\nfunction dispatchInitialEffects<S, M, E>(\n inst: ReturnType<typeof createComponentInstance<S, M, E>>,\n): void {\n if (inst.initialEffects.length === 0 || !inst.def.onEffect) return\n for (const effect of inst.initialEffects) {\n inst.def.onEffect({ effect, send: inst.send, signal: inst.signal })\n }\n inst.initialEffects = []\n}\n\n/**\n * Dev-only warning when a hydrate path silently drops a non-empty\n * `initialEffects` array. The default-skip behavior is deliberate (the\n * server already ran them), but if `init()` produces effects that\n * weren't run on the server — typically client-only init pipelines —\n * silent drop is a footgun. Surface the count and the opt-in.\n */\nfunction warnDroppedInitEffects<S, M, E>(\n inst: ReturnType<typeof createComponentInstance<S, M, E>>,\n via: 'hydrateApp' | 'hydrateAtAnchor',\n): void {\n if (!import.meta.env?.DEV) return\n if (inst.initialEffects.length === 0) return\n const name = inst.def.name ?? '<anonymous>'\n console.warn(\n `[LLui] ${via}: skipped ${inst.initialEffects.length} init effect(s) for \"${name}\". ` +\n `Hydration drops init effects by default since the server already ran them. ` +\n `If these effects only fire on the client, pass \\`runInitEffectsOnHydrate: true\\` to opt in.`,\n )\n}\n\n/**\n * Build the `AppHandle` returned by every mount/hydrate path. Captures\n * the `_onCommit` listener registry, the `disposed` flag, and the\n * standard `flush` / `send` / `getState` / `subscribe` shape — all\n * code that was previously duplicated four times across `mountApp`,\n * `mountAtAnchor`, `hydrateApp`, and `hydrateAtAnchor`.\n *\n * Variation lives in the two parameters:\n * - `hmrName` — the def's name used to call `hmrModule.unregisterForHmr`\n * on dispose. Pass `null` to skip HMR unregistration (no current\n * mount path needs that, but it keeps the helper honest).\n * - `domCleanup` — final teardown step that detaches mounted nodes.\n * Container-rooted paths set `container.textContent = ''`;\n * anchor-rooted paths call `_removeBetween(anchor, endSentinel)`\n * and detach the end sentinel. Runs LAST in the dispose chain to\n * match the historical ordering exactly (lifetime is disposed\n * before nodes are detached, so binding teardown sees attached\n * DOM until the very end).\n *\n * The mount-path-parity test in `mount-path-parity.test.ts` enforces\n * that each public entry point produces structurally identical\n * AppHandle behavior — this helper is the realisation of that\n * promise.\n */\nfunction buildAppHandle<S, M, E>(\n inst: ReturnType<typeof createComponentInstance<S, M, E>>,\n hmrName: string | null,\n domCleanup: () => void,\n): AppHandle {\n let disposed = false\n const listeners = new Set<(s: unknown) => void>()\n\n inst._onCommit = (state: unknown) => {\n for (const l of Array.from(listeners)) {\n try {\n l(state)\n } catch (err) {\n console.error('[llui] listener threw:', err)\n }\n }\n }\n\n return {\n dispose() {\n if (disposed) return\n disposed = true\n listeners.clear()\n inst._onCommit = undefined\n if (hmrModule && hmrName) hmrModule.unregisterForHmr(hmrName, inst)\n inst.abortController.abort()\n unregisterInstance(inst)\n // Tag the root scope so the disposer log reports app-level\n // teardown distinct from in-tree component-unmount events.\n inst.rootLifetime.disposalCause = 'app-unmount'\n disposeLifetime(inst.rootLifetime)\n domCleanup()\n },\n flush() {\n if (disposed) return\n flushInstance(inst)\n },\n send(msg: unknown) {\n if (disposed) return\n ;(inst.send as (m: unknown) => void)(msg)\n },\n getState() {\n if (disposed) {\n throw new Error(\n '[LLui] AppHandle.getState() called after dispose — handle is dead. ' +\n 'Detach your event listener / cancel your timer when the handle ' +\n 'is disposed to avoid stale reads.',\n )\n }\n return inst.state\n },\n subscribe(listener: (state: unknown) => void) {\n if (disposed) return () => {}\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n getBindingDescriptors() {\n if (disposed) return []\n return getBindingDescriptors(inst as ComponentInstance)\n },\n swapUpdate(newUpdate, newOnEffect) {\n if (disposed) return\n // Drain pending messages with the OLD update first — anything\n // already in the queue was constructed under the old contract,\n // and re-routing it through a new reducer mid-flight could mix\n // half of one transition with half of another (e.g. a payload\n // shape the new update no longer accepts).\n flushInstance(inst)\n // Mutate the def in place so subsequent `inst.def.update`\n // reads — including the per-message read in `flushInstance`'s\n // generic loop — pick up the new function. We deliberately\n // don't replace `inst.def` itself: existing closures, the\n // `__update` fast path, and `__handlers` all stay valid; only\n // the user-visible reducer function changes.\n ;(inst.def as { update: typeof newUpdate }).update = newUpdate\n if (newOnEffect !== undefined) {\n ;(inst.def as { onEffect?: typeof newOnEffect }).onEffect = newOnEffect\n }\n },\n runReducer(msg) {\n if (disposed) return null\n // Direct invocation against current state. No subscribe, no\n // flush, no effect handler. The reducer's contract per TEA is\n // a pure function — calling it twice with the same args is a\n // no-op other than allocations. Returning the raw tuple\n // shape lets the agent inspect both halves without interpreting.\n const [state, effects] = (\n inst.def.update as (s: unknown, m: unknown) => [unknown, unknown[]]\n )(inst.state, msg)\n return { state, effects: effects as unknown[] }\n },\n }\n}\n\nexport function hydrateApp<S, M, E, D = void>(\n container: HTMLElement,\n def: ComponentDef<S, M, E, D>,\n serverState: S,\n options?: MountOptions,\n): AppHandle {\n // Run the original init once to capture its effects. The state it\n // returns is discarded — we use `serverState` (what the server\n // rendered with) instead. The effects are preserved and dispatched\n // after the DOM is in place, so components that rely on \"load data\n // or wire subscriptions on mount\" behave consistently between fresh\n // mount and SSR+hydrate. If the original init has already-loaded\n // data for the hydration case, gate the effect emission inside init\n // itself (e.g. based on a `loaded` flag in state).\n const [, originalEffects] = (def.init as (data: unknown) => [S, E[]])(undefined)\n\n const hydrateDef: ComponentDef<S, M, E> = {\n ...def,\n init: () => [serverState, originalEffects],\n }\n\n const inst = createComponentInstance(\n hydrateDef,\n undefined,\n options?.parentLifetime ?? null,\n options?.env,\n )\n\n // Dev-only: auto-install devtools if enabled via '@llui/dom/devtools'\n // import. The other three mount paths (mountApp / mountAtAnchor /\n // hydrateAtAnchor) all call this; without it, the hydrated layout\n // never appears in `window.__lluiComponents`, never sets\n // `window.__lluiDebug`, and is invisible to MCP / agent client /\n // devtools console — so a vike SSR app's outermost layout silently\n // drops out of every observability surface.\n if (devToolsInstall) devToolsInstall(inst)\n\n // Build the component DOM and swap atomically with server HTML.\n // Server HTML remains visible until JS finishes — no flash.\n // onMount callbacks are collected in a queue and flushed synchronously\n // after the swap, matching mountApp's ordering.\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({\n ...inst,\n container,\n send: inst.send as (msg: unknown) => void,\n instance: inst as ComponentInstance,\n })\n const nodes = hydrateDef.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Atomic swap — replaces server HTML with client DOM in one operation\n container.replaceChildren(...nodes)\n\n // Flush onMount callbacks synchronously now that the DOM is in place.\n flushMountQueue(onMountQueue)\n\n // Hydration: skip init's effects by default. The SSR pass already ran\n // them on the server; re-running on the client typically produces\n // duplicate work (double fetches, double subscriptions). Opt back in\n // via `MountOptions.runInitEffectsOnHydrate: true` for projects that\n // need the post-swap dispatch (typically when `init()` is gated by\n // a `loaded` flag and returns `[]` on the server).\n if (options?.runInitEffectsOnHydrate) {\n dispatchInitialEffects(inst)\n } else {\n warnDroppedInitEffects(inst, 'hydrateApp')\n }\n\n registerInstance(inst)\n // HMR registration — same as mountApp / mountAtAnchor /\n // hydrateAtAnchor. Without it, replaceComponent(name, newDef)\n // silently no-ops on the hydrated layout layer because the HMR\n // registry has no entry for it.\n if (hmrModule && hydrateDef.name) {\n hmrModule.registerForHmr(hydrateDef.name, inst, container)\n }\n return buildAppHandle(inst, hydrateDef.name ?? null, () => {\n container.textContent = ''\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle, Lifetime } from './types.js'\nimport { type DomEnv, browserEnv } from './dom-env.js'\nimport { createComponentInstance, flushInstance, type ComponentInstance } from './update-loop.js'\nimport { disposeLifetime } from './lifetime.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { getBindingDescriptors } from './binding-descriptors.js'\nimport { registerInstance, unregisterInstance } from './runtime.js'\nimport { createView } from './view-helpers.js'\nimport { pushMountQueue, popMountQueue, flushMountQueue } from './primitives/on-mount.js'\n\n// ── Sentinel-region helpers (used by anchor-based mount primitives) ─────\n\n/**\n * Remove every sibling from `anchor.nextSibling` up to but not including\n * `stopBefore`. Used by anchor-based mount primitives and their HMR\n * swap path to clear the owned DOM region between the pair.\n */\nfunction _removeBetween(anchor: Comment, stopBefore: Comment): void {\n const parent = anchor.parentNode\n if (parent === null) return\n while (anchor.nextSibling !== null && anchor.nextSibling !== stopBefore) {\n parent.removeChild(anchor.nextSibling)\n }\n}\n\n/**\n * Walk forward from `anchor.nextSibling` looking for an existing\n * `<!-- llui-mount-end -->` sentinel. Used by mount/hydrate at anchor\n * to reuse a server-emitted (or stale) sentinel rather than synthesizing\n * a duplicate. Returns null if no matching comment is found before the\n * end of the parent's children.\n */\nfunction _findEndSentinel(anchor: Comment): Comment | null {\n let node: Node | null = anchor.nextSibling\n while (node !== null) {\n if (node.nodeType === 8 && (node as Comment).nodeValue === 'llui-mount-end') {\n return node as Comment\n }\n node = node.nextSibling\n }\n return null\n}\n\n// Vite injects import.meta.env.DEV — declare the shape for TypeScript\ndeclare global {\n interface ImportMeta {\n env?: { DEV?: boolean }\n }\n}\n\n// ── HMR (dev only) ──────────────────────────────────────────────\n// Set by enableHmr() from '@llui/dom/hmr' — never imported in production.\n\nlet hmrModule: typeof import('./hmr') | null = null\n\n/**\n * @internal Called by enableHmr in the hmr module. Tests use this\n * (paired with `_getHmrModule`) to snapshot/restore prior state across\n * suite boundaries — pass `null` to clear.\n */\nexport function _setHmrModule(m: typeof import('./hmr') | null): void {\n hmrModule = m\n}\n\n/** @internal Read the currently-installed HMR module (or null). */\nexport function _getHmrModule(): typeof import('./hmr') | null {\n return hmrModule\n}\n\n// ── DevTools auto-install (dev only) ────────────────────────────\n// Set by enableDevTools() from '@llui/dom/devtools' — never imported in production.\n\nlet devToolsInstall: ((inst: object) => void) | null = null\n\n/** @internal Called by enableDevTools in the devtools module */\nexport function _setDevToolsInstall(fn: ((inst: object) => void) | null): void {\n devToolsInstall = fn\n}\n\n/** @internal Read the currently-installed devtools-install hook (or null). */\nexport function _getDevToolsInstall(): ((inst: object) => void) | null {\n return devToolsInstall\n}\n\nexport interface MountOptions {\n devTools?: boolean\n /**\n * Parent scope for the mounted component's rootLifetime. When provided,\n * the rootLifetime is created as a child of this scope — context lookups\n * from within the component walk up through the parent's scope tree,\n * and disposing the parent scope cascades into this instance's scope.\n * Used by `@llui/vike`'s persistent-layout machinery to mount a page\n * as a true scope-tree child of its enclosing layout, so layout-\n * provided contexts flow naturally into pages via `useContext`.\n *\n * When omitted (the default), the rootLifetime is detached — same as\n * every `mountApp` call before persistent layouts existed.\n */\n parentLifetime?: Lifetime\n /**\n * DOM env override. Defaults to `browserEnv()` — wraps the browser\n * globals. Specify only when mounting into a non-browser DOM (e.g.\n * a jsdom instance held by a test harness, or isolated DOM per\n * shadow root).\n */\n env?: DomEnv\n /**\n * **`hydrateApp` / `hydrateAtAnchor` only.** When `true`, fire the\n * effects that `init()` returned during hydration the same way\n * `mountApp` does on a fresh mount. Defaults to `false` because the\n * SSR render already ran `init()` on the server, and re-running its\n * effects on the client typically produces duplicate work — an\n * `httpGet` issued from `init()` would fetch on the server *and* on\n * hydration; a subscription would attach twice; etc.\n *\n * Opt in only when:\n * - `init()` returns no effects, OR\n * - all returned effects are idempotent / client-only (e.g.\n * wiring a `window` event listener, opening a `WebSocket`), AND\n * - the SSR path didn't run them (typically when `init()` checks a\n * `loaded` flag in state and returns `[]` on the server).\n *\n * Pre-0.0.31 behavior was to always run init effects on hydrate;\n * the option preserves it on demand for projects that depended on\n * it. The default-off direction matches the safer expectation that\n * \"hydration should be cheap and side-effect-free.\"\n */\n runInitEffectsOnHydrate?: boolean\n}\n\nexport function mountApp<S, M, E>(\n container: HTMLElement,\n def: ComponentDef<S, M, E>,\n data?: undefined,\n options?: MountOptions,\n): AppHandle\nexport function mountApp<S, M, E, D>(\n container: HTMLElement,\n def: ComponentDef<S, M, E, D>,\n data: D,\n options?: MountOptions,\n): AppHandle\nexport function mountApp<S, M, E, D>(\n container: HTMLElement,\n def: ComponentDef<S, M, E, D>,\n data?: D,\n options?: MountOptions,\n): AppHandle {\n // HMR: if this component is already mounted (module re-execution\n // during hot update), swap the definition instead of creating a new instance.\n // HMR swap bypasses parentLifetime — HMR re-mounts the outermost app handle,\n // which in a layout setup means the layout re-mounts at the root and the\n // rest of the chain is re-established via the normal mount path.\n if (hmrModule && def.name && !options?.parentLifetime) {\n const swapped = hmrModule.replaceComponent(def.name, def)\n if (swapped) return swapped\n }\n\n const inst = createComponentInstance(def, data, options?.parentLifetime ?? null, options?.env)\n\n // Dev-only: auto-install devtools if enabled via '@llui/dom/devtools' import\n if (devToolsInstall) devToolsInstall(inst)\n\n // Dev-only: warn if initial state contains non-serializable values.\n // Silent bug-bomb: Date/Map/Set/class instances break SSR, hydration, replay tools.\n if (import.meta.env?.DEV) {\n const offender = findNonSerializable(inst.state)\n if (offender) {\n console.warn(\n `[LLui] <${def.name}> initial state contains a non-serializable value at \"${offender.path}\":`,\n offender.value,\n '\\nState must be plain JSON (no Date/Map/Set/class instances/functions).' +\n '\\nThis will break SSR hydration, state replay, and devtools snapshots.' +\n '\\nhint: Convert to a serializable representation (e.g., Date → ISO string, Map → Record).',\n )\n }\n }\n\n // Run view() within a render context so primitives can register bindings.\n // Also collect onMount callbacks in a queue we'll flush synchronously\n // after node insertion — prevents the race where a user event fires\n // between mount and the queueMicrotask callback running.\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({\n ...inst,\n container,\n send: inst.send as (msg: unknown) => void,\n instance: inst as ComponentInstance,\n })\n const nodes = def.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Batch-insert via DocumentFragment — one layout-invalidating operation\n // instead of N individual appendChild calls on a live container element.\n if (nodes.length > 1) {\n const frag = inst.dom.createDocumentFragment()\n for (const node of nodes) frag.appendChild(node)\n container.appendChild(frag)\n } else if (nodes.length === 1) {\n container.appendChild(nodes[0]!)\n }\n\n // Flush onMount callbacks SYNCHRONOUSLY now that the DOM is in place.\n // Any listeners they attach are ready before this function returns,\n // so a synchronous dispatchEvent in the caller's next line fires\n // against a fully-wired tree.\n flushMountQueue(onMountQueue)\n\n registerInstance(inst)\n if (hmrModule && def.name) {\n hmrModule.registerForHmr(def.name, inst, container)\n }\n dispatchInitialEffects(inst)\n return buildAppHandle(inst, def.name ?? null, () => {\n container.textContent = ''\n })\n}\n\n// Walks an object graph looking for non-JSON-serializable values. Returns the\n// first offender found (depth-first), or null if everything is fine. Stops at\n// depth 6 to bound runtime cost for large states.\nfunction findNonSerializable(\n v: unknown,\n path = 'state',\n depth = 0,\n seen = new WeakSet<object>(),\n): { path: string; value: unknown } | null {\n if (depth > 6) return null\n if (v === null || v === undefined) return null\n const t = typeof v\n if (t === 'string' || t === 'number' || t === 'boolean') return null\n if (t === 'function') return { path, value: v }\n if (t === 'symbol' || t === 'bigint') return { path, value: v }\n if (t !== 'object') return null\n const obj = v as object\n if (seen.has(obj)) return null\n seen.add(obj)\n if (obj instanceof Date) return { path: `${path} (Date)`, value: v }\n if (obj instanceof Map) return { path: `${path} (Map)`, value: v }\n if (obj instanceof Set) return { path: `${path} (Set)`, value: v }\n if (obj instanceof RegExp) return { path: `${path} (RegExp)`, value: v }\n if (obj instanceof Promise) return { path: `${path} (Promise)`, value: v }\n // Plain objects/arrays have Object.prototype / Array.prototype. Class instances\n // have a different prototype.\n const proto = Object.getPrototypeOf(obj)\n if (proto !== null && proto !== Object.prototype && proto !== Array.prototype) {\n return { path: `${path} (${proto?.constructor?.name ?? 'class instance'})`, value: v }\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const r = findNonSerializable(v[i], `${path}[${i}]`, depth + 1, seen)\n if (r) return r\n }\n return null\n }\n for (const k of Object.keys(obj)) {\n const r = findNonSerializable(\n (obj as Record<string, unknown>)[k],\n `${path}.${k}`,\n depth + 1,\n seen,\n )\n if (r) return r\n }\n return null\n}\n\n/**\n * Mount a component relative to a comment anchor rather than inside a\n * container element. Inserts a synthesized end sentinel (`<!-- llui-mount-end -->`)\n * immediately after the anchor and places the component's nodes between\n * the pair. The anchor must already be attached to a live DOM tree.\n *\n * Unlike `mountApp`, the caller's anchor node is preserved across the\n * handle's lifetime — only the content between the pair (and the end\n * sentinel itself) is disposed. Used by `@llui/vike` persistent layouts\n * to mount chain layers without a wrapper element.\n *\n * If a pre-existing `<!-- llui-mount-end -->` is found after the anchor\n * (e.g. stale from an undisposed prior mount), the content between the\n * anchor and that sentinel is swept and the sentinel is reused. Dev mode\n * warns in that case.\n */\nexport function mountAtAnchor<S, M, E>(\n anchor: Comment,\n def: ComponentDef<S, M, E>,\n data?: undefined,\n options?: MountOptions,\n): AppHandle\nexport function mountAtAnchor<S, M, E, D>(\n anchor: Comment,\n def: ComponentDef<S, M, E, D>,\n data: D,\n options?: MountOptions,\n): AppHandle\nexport function mountAtAnchor<S, M, E, D>(\n anchor: Comment,\n def: ComponentDef<S, M, E, D>,\n data?: D,\n options?: MountOptions,\n): AppHandle {\n if (anchor.parentNode === null) {\n throw new Error(\n `[LLui] mountAtAnchor: anchor comment must be attached to a live DOM tree before mount`,\n )\n }\n\n // Locate or synthesize the end sentinel.\n const existingEnd = _findEndSentinel(anchor)\n let endSentinel: Comment\n if (existingEnd !== null) {\n if (import.meta.env?.DEV) {\n console.warn(\n `[LLui] mountAtAnchor: anchor has a pre-existing end sentinel. ` +\n `A prior mount was not disposed — sweeping stale siblings and reusing the sentinel.`,\n )\n }\n _removeBetween(anchor, existingEnd)\n endSentinel = existingEnd\n } else {\n // Use the caller-provided env if any — end-sentinel creation happens\n // before `inst` exists, so we pick the env directly from options.\n // (browserEnv() fallback matches what createComponentInstance will\n // use below when options.env is undefined.)\n endSentinel = (options?.env ?? browserEnv()).createComment('llui-mount-end')\n anchor.parentNode.insertBefore(endSentinel, anchor.nextSibling)\n }\n\n const inst = createComponentInstance(def, data, options?.parentLifetime ?? null, options?.env)\n\n if (devToolsInstall) devToolsInstall(inst)\n\n if (import.meta.env?.DEV) {\n const offender = findNonSerializable(inst.state)\n if (offender) {\n console.warn(\n `[LLui] <${def.name}> initial state contains a non-serializable value at \"${offender.path}\":`,\n offender.value,\n '\\nState must be plain JSON (no Date/Map/Set/class instances/functions).' +\n '\\nThis will break SSR hydration, state replay, and devtools snapshots.' +\n '\\nhint: Convert to a serializable representation (e.g., Date → ISO string, Map → Record).',\n )\n }\n }\n\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({\n ...inst,\n container: anchor.parentElement ?? undefined,\n send: inst.send as (msg: unknown) => void,\n instance: inst as ComponentInstance,\n })\n const nodes = def.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Batch-insert via DocumentFragment — one layout pass instead of N.\n if (nodes.length > 1) {\n const frag = inst.dom.createDocumentFragment()\n for (const node of nodes) frag.appendChild(node)\n anchor.parentNode.insertBefore(frag, endSentinel)\n } else if (nodes.length === 1) {\n anchor.parentNode.insertBefore(nodes[0]!, endSentinel)\n }\n\n flushMountQueue(onMountQueue)\n\n registerInstance(inst)\n if (hmrModule && def.name) {\n hmrModule.registerForAnchor(def.name, inst, anchor, endSentinel)\n }\n dispatchInitialEffects(inst)\n return buildAppHandle(inst, def.name ?? null, () => {\n _removeBetween(anchor, endSentinel)\n endSentinel.parentNode?.removeChild(endSentinel)\n })\n}\n\n/**\n * Hydrate a component relative to a comment anchor rather than inside a\n * container element. Analogous to `hydrateApp` — uses `serverState` as\n * the initial state (not `init()`'s output) while preserving `init()`'s\n * effects for post-mount dispatch.\n *\n * The DOM-handling path is identical to `mountAtAnchor`: reuses a\n * pre-existing end sentinel when present, synthesizes one otherwise.\n * Atomic-swaps the owned region whether or not server content is there\n * to replace. No error for a missing end sentinel — the vike chain's\n * outer `hydrateApp`'s `replaceChildren` wipes inner layers' sentinels,\n * so inner-layer `hydrateAtAnchor` calls routinely find nothing to\n * reuse, and that's normal.\n */\nexport function hydrateAtAnchor<S, M, E, D = void>(\n anchor: Comment,\n def: ComponentDef<S, M, E, D>,\n serverState: S,\n options?: MountOptions,\n): AppHandle {\n if (anchor.parentNode === null) {\n throw new Error(\n `[LLui] hydrateAtAnchor: anchor comment must be attached to a live DOM tree before hydrate`,\n )\n }\n\n const existingEnd = _findEndSentinel(anchor)\n let endSentinel: Comment\n if (existingEnd !== null) {\n _removeBetween(anchor, existingEnd)\n endSentinel = existingEnd\n } else {\n endSentinel = (options?.env ?? browserEnv()).createComment('llui-mount-end')\n anchor.parentNode.insertBefore(endSentinel, anchor.nextSibling)\n }\n\n // Run original init() to capture effects, then override state with server's.\n const [, originalEffects] = (def.init as (data: unknown) => [S, E[]])(undefined)\n const hydrateDef: ComponentDef<S, M, E> = {\n ...def,\n init: () => [serverState, originalEffects],\n }\n\n const inst = createComponentInstance(\n hydrateDef,\n undefined,\n options?.parentLifetime ?? null,\n options?.env,\n )\n\n if (devToolsInstall) devToolsInstall(inst)\n\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({\n ...inst,\n container: anchor.parentElement ?? undefined,\n send: inst.send as (msg: unknown) => void,\n instance: inst as ComponentInstance,\n })\n const nodes = hydrateDef.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n if (nodes.length > 1) {\n const frag = inst.dom.createDocumentFragment()\n for (const node of nodes) frag.appendChild(node)\n anchor.parentNode.insertBefore(frag, endSentinel)\n } else if (nodes.length === 1) {\n anchor.parentNode.insertBefore(nodes[0]!, endSentinel)\n }\n\n flushMountQueue(onMountQueue)\n\n registerInstance(inst)\n if (hmrModule && def.name) {\n hmrModule.registerForAnchor(def.name, inst, anchor, endSentinel)\n }\n // Hydration: skip init's effects by default. The SSR pass already ran\n // them on the server; re-running on the client typically produces\n // duplicate work (double fetches, double subscriptions). Opt back in\n // via `MountOptions.runInitEffectsOnHydrate: true`.\n if (options?.runInitEffectsOnHydrate) {\n dispatchInitialEffects(inst)\n } else {\n warnDroppedInitEffects(inst, 'hydrateAtAnchor')\n }\n return buildAppHandle(inst, def.name ?? null, () => {\n _removeBetween(anchor, endSentinel)\n endSentinel.parentNode?.removeChild(endSentinel)\n })\n}\n\nfunction dispatchInitialEffects<S, M, E>(\n inst: ReturnType<typeof createComponentInstance<S, M, E>>,\n): void {\n if (inst.initialEffects.length === 0 || !inst.def.onEffect) return\n for (const effect of inst.initialEffects) {\n inst.def.onEffect({ effect, send: inst.send, signal: inst.signal })\n }\n inst.initialEffects = []\n}\n\n/**\n * Dev-only warning when a hydrate path silently drops a non-empty\n * `initialEffects` array. The default-skip behavior is deliberate (the\n * server already ran them), but if `init()` produces effects that\n * weren't run on the server — typically client-only init pipelines —\n * silent drop is a footgun. Surface the count and the opt-in.\n */\nfunction warnDroppedInitEffects<S, M, E>(\n inst: ReturnType<typeof createComponentInstance<S, M, E>>,\n via: 'hydrateApp' | 'hydrateAtAnchor',\n): void {\n if (!import.meta.env?.DEV) return\n if (inst.initialEffects.length === 0) return\n const name = inst.def.name ?? '<anonymous>'\n console.warn(\n `[LLui] ${via}: skipped ${inst.initialEffects.length} init effect(s) for \"${name}\". ` +\n `Hydration drops init effects by default since the server already ran them. ` +\n `If these effects only fire on the client, pass \\`runInitEffectsOnHydrate: true\\` to opt in.`,\n )\n}\n\n/**\n * Build the `AppHandle` returned by every mount/hydrate path. Captures\n * the `_onCommit` listener registry, the `disposed` flag, and the\n * standard `flush` / `send` / `getState` / `subscribe` shape — all\n * code that was previously duplicated four times across `mountApp`,\n * `mountAtAnchor`, `hydrateApp`, and `hydrateAtAnchor`.\n *\n * Variation lives in the two parameters:\n * - `hmrName` — the def's name used to call `hmrModule.unregisterForHmr`\n * on dispose. Pass `null` to skip HMR unregistration (no current\n * mount path needs that, but it keeps the helper honest).\n * - `domCleanup` — final teardown step that detaches mounted nodes.\n * Container-rooted paths set `container.textContent = ''`;\n * anchor-rooted paths call `_removeBetween(anchor, endSentinel)`\n * and detach the end sentinel. Runs LAST in the dispose chain to\n * match the historical ordering exactly (lifetime is disposed\n * before nodes are detached, so binding teardown sees attached\n * DOM until the very end).\n *\n * The mount-path-parity test in `mount-path-parity.test.ts` enforces\n * that each public entry point produces structurally identical\n * AppHandle behavior — this helper is the realisation of that\n * promise.\n */\nfunction buildAppHandle<S, M, E>(\n inst: ReturnType<typeof createComponentInstance<S, M, E>>,\n hmrName: string | null,\n domCleanup: () => void,\n): AppHandle {\n let disposed = false\n const listeners = new Set<(s: unknown) => void>()\n\n inst._onCommit = (state: unknown) => {\n for (const l of Array.from(listeners)) {\n try {\n l(state)\n } catch (err) {\n console.error('[llui] listener threw:', err)\n }\n }\n }\n\n return {\n dispose() {\n if (disposed) return\n disposed = true\n listeners.clear()\n inst._onCommit = undefined\n if (hmrModule && hmrName) hmrModule.unregisterForHmr(hmrName, inst)\n inst.abortController.abort()\n unregisterInstance(inst)\n // Tag the root scope so the disposer log reports app-level\n // teardown distinct from in-tree component-unmount events.\n inst.rootLifetime.disposalCause = 'app-unmount'\n disposeLifetime(inst.rootLifetime)\n domCleanup()\n },\n flush() {\n if (disposed) return\n flushInstance(inst)\n },\n send(msg: unknown) {\n if (disposed) return\n ;(inst.send as (m: unknown) => void)(msg)\n },\n getState() {\n if (disposed) {\n throw new Error(\n '[LLui] AppHandle.getState() called after dispose — handle is dead. ' +\n 'Detach your event listener / cancel your timer when the handle ' +\n 'is disposed to avoid stale reads.',\n )\n }\n return inst.state\n },\n subscribe(listener: (state: unknown) => void) {\n if (disposed) return () => {}\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n getBindingDescriptors() {\n if (disposed) return []\n return getBindingDescriptors(inst as ComponentInstance)\n },\n swapUpdate(newUpdate, newOnEffect) {\n if (disposed) return\n // Drain pending messages with the OLD update first — anything\n // already in the queue was constructed under the old contract,\n // and re-routing it through a new reducer mid-flight could mix\n // half of one transition with half of another (e.g. a payload\n // shape the new update no longer accepts).\n flushInstance(inst)\n // Mutate the def in place so subsequent `inst.def.update`\n // reads — including the per-message read in `flushInstance`'s\n // generic loop — pick up the new function. We deliberately\n // don't replace `inst.def` itself: existing closures, the\n // `__update` fast path, and `__handlers` all stay valid; only\n // the user-visible reducer function changes.\n ;(inst.def as { update: typeof newUpdate }).update = newUpdate\n if (newOnEffect !== undefined) {\n ;(inst.def as { onEffect?: typeof newOnEffect }).onEffect = newOnEffect\n }\n },\n runReducer(msg) {\n if (disposed) return null\n // Direct invocation against current state. No subscribe, no\n // flush, no effect handler. The reducer's contract per TEA is\n // a pure function — calling it twice with the same args is a\n // no-op other than allocations. Returning the raw tuple\n // shape lets the agent inspect both halves without interpreting.\n const [state, effects] = (\n inst.def.update as (s: unknown, m: unknown) => [unknown, unknown[]]\n )(inst.state, msg)\n return { state, effects: effects as unknown[] }\n },\n setOnBindingError(hook) {\n if (disposed) return\n inst._onBindingError = hook ?? undefined\n },\n }\n}\n\nexport function hydrateApp<S, M, E, D = void>(\n container: HTMLElement,\n def: ComponentDef<S, M, E, D>,\n serverState: S,\n options?: MountOptions,\n): AppHandle {\n // Run the original init once to capture its effects. The state it\n // returns is discarded — we use `serverState` (what the server\n // rendered with) instead. The effects are preserved and dispatched\n // after the DOM is in place, so components that rely on \"load data\n // or wire subscriptions on mount\" behave consistently between fresh\n // mount and SSR+hydrate. If the original init has already-loaded\n // data for the hydration case, gate the effect emission inside init\n // itself (e.g. based on a `loaded` flag in state).\n const [, originalEffects] = (def.init as (data: unknown) => [S, E[]])(undefined)\n\n const hydrateDef: ComponentDef<S, M, E> = {\n ...def,\n init: () => [serverState, originalEffects],\n }\n\n const inst = createComponentInstance(\n hydrateDef,\n undefined,\n options?.parentLifetime ?? null,\n options?.env,\n )\n\n // Dev-only: auto-install devtools if enabled via '@llui/dom/devtools'\n // import. The other three mount paths (mountApp / mountAtAnchor /\n // hydrateAtAnchor) all call this; without it, the hydrated layout\n // never appears in `window.__lluiComponents`, never sets\n // `window.__lluiDebug`, and is invisible to MCP / agent client /\n // devtools console — so a vike SSR app's outermost layout silently\n // drops out of every observability surface.\n if (devToolsInstall) devToolsInstall(inst)\n\n // Build the component DOM and swap atomically with server HTML.\n // Server HTML remains visible until JS finishes — no flash.\n // onMount callbacks are collected in a queue and flushed synchronously\n // after the swap, matching mountApp's ordering.\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({\n ...inst,\n container,\n send: inst.send as (msg: unknown) => void,\n instance: inst as ComponentInstance,\n })\n const nodes = hydrateDef.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Atomic swap — replaces server HTML with client DOM in one operation\n container.replaceChildren(...nodes)\n\n // Flush onMount callbacks synchronously now that the DOM is in place.\n flushMountQueue(onMountQueue)\n\n // Hydration: skip init's effects by default. The SSR pass already ran\n // them on the server; re-running on the client typically produces\n // duplicate work (double fetches, double subscriptions). Opt back in\n // via `MountOptions.runInitEffectsOnHydrate: true` for projects that\n // need the post-swap dispatch (typically when `init()` is gated by\n // a `loaded` flag and returns `[]` on the server).\n if (options?.runInitEffectsOnHydrate) {\n dispatchInitialEffects(inst)\n } else {\n warnDroppedInitEffects(inst, 'hydrateApp')\n }\n\n registerInstance(inst)\n // HMR registration — same as mountApp / mountAtAnchor /\n // hydrateAtAnchor. Without it, replaceComponent(name, newDef)\n // silently no-ops on the hydrated layout layer because the HMR\n // registry has no entry for it.\n if (hmrModule && hydrateDef.name) {\n hmrModule.registerForHmr(hydrateDef.name, inst, container)\n }\n return buildAppHandle(inst, hydrateDef.name ?? null, () => {\n container.textContent = ''\n })\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -238,6 +238,29 @@ export interface AppHandle {
|
|
|
238
238
|
state: unknown;
|
|
239
239
|
effects: unknown[];
|
|
240
240
|
} | null;
|
|
241
|
+
/**
|
|
242
|
+
* Install a hook called whenever a binding's accessor throws during
|
|
243
|
+
* the update cycle. The runtime catches the throw, leaves the
|
|
244
|
+
* binding's `lastValue` unchanged (DOM stays at its previous value
|
|
245
|
+
* rather than blanking), continues with sibling bindings, and
|
|
246
|
+
* notifies this hook with `{kind, key?, message, stack?}`.
|
|
247
|
+
*
|
|
248
|
+
* Used by `@llui/agent` to fold binding-evaluation throws into the
|
|
249
|
+
* dispatch envelope's `drain.errors` — so an LLM dispatching a Msg
|
|
250
|
+
* that breaks scoring doesn't get HTTP 500 + a frozen UI; instead
|
|
251
|
+
* the dispatch reports as `{status: 'dispatched', drain: {errors:
|
|
252
|
+
* [...]}}` with the rest of the page rendering normally.
|
|
253
|
+
*
|
|
254
|
+
* Pass `null` to remove the hook. Without a hook, throws fall back
|
|
255
|
+
* to `console.error` (dev mode) or `console.warn` (prod) so they
|
|
256
|
+
* aren't silently swallowed.
|
|
257
|
+
*/
|
|
258
|
+
setOnBindingError(hook: ((info: {
|
|
259
|
+
kind: string;
|
|
260
|
+
key?: string;
|
|
261
|
+
message: string;
|
|
262
|
+
stack?: string;
|
|
263
|
+
}) => void) | null): void;
|
|
241
264
|
}
|
|
242
265
|
export interface Lifetime {
|
|
243
266
|
id: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAK7C,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,IAAI;IACrD,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3B,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACtC,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;IAC/B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,MAAM,EAAE,CAAC,CAAC;QAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAA;IAG3E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,CAAC,CAAC,CAAA;CAyClD;AAED,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAA;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IACzC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IAC1D,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC,GAAG,IAAI;IAC/B,IAAI,EAAE,MAAM,CAAA;IAKZ,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IACnC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IAC1D,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAA;AAID,MAAM,WAAW,SAAS;IACxB,OAAO,IAAI,IAAI,CAAA;IACf,KAAK,IAAI,IAAI,CAAA;IACb;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,IAAI,OAAO,CAAA;IACnB;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAA;IACzD;;;;;;;;;;;;OAYG;IACH,qBAAqB,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,UAAU,CACR,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EACjE,WAAW,CAAC,EAAE,OAAO,GACpB,IAAI,CAAA;IACP;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,CAAA;KAAE,GAAG,IAAI,CAAA;IACvE;;;;;;;;;;;;;;;;OAgBG;IACH,iBAAiB,CACf,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,GAC7F,IAAI,CAAA;CACR;AAID,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,QAAQ,EAAE,CAAA;IACpB,SAAS,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAA;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,yFAAyF;IACzF,YAAY,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAA;CAkBhC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAA;IACpF,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,YAAY,EAAE,CAAA;CACzB;AAID;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEjF,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;IACrC,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,IAAI,CAAA;IACV,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,QAAQ,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;CACd;AAID,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAAC,OAAO,EAAE,IAAI,EAAE,CAAC;QAAC,MAAM,EAAE,IAAI,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClG;AAED,UAAU,iBAAkB,SAAQ,iBAAiB;CAUpD;AAED;;;;;;GAMG;AACH,KAAK,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AAElE;;GAEG;AACH,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,iBAAiB,GAAG;IACzE,EAAE,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACtB,KAAK,EAAE;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;KAAE,CAAA;IAC9C,OAAO,CAAC,EAAE,KAAK,CAAA;CAChB,CAAA;AAED;;GAEG;AACH,KAAK,0BAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,iBAAiB,GAAG;IAC5E,EAAE,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACtB,KAAK,CAAC,EAAE;SAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;KAAE,CAAA;IAChD,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;CACnC,CAAA;AAED;;;;;;GAMG;AACH,KAAK,iBAAiB,CAAC,CAAC,EAAE,CAAC,IAAI,iBAAiB,GAAG;IACjD,EAAE,EAAE,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;IACjD,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;CACpC,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,SAAS,CAAC,GACnF,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,0BAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;AAE1E,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAE,SAAQ,iBAAiB;IACpE;;;;;;;OAOG;IACH,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,CAAA;IAC3C,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;IACjC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;CACrC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAE,SAAQ,iBAAiB;IACrE;;;;;OAKG;IACH,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,CAAA;IACvC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;CAGlC;AAED;;;;;;GAMG;AACH;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAC5B,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAA;CACpC,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;CAC7B,GAAG;IACF;;;;;;;OAOG;IACH,OAAO,IAAI,CAAC,CAAA;CACb,CAAA;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,OAAO,CAAE,SAAQ,iBAAiB;IACvE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;IACpB,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,CAAA;IACjC,MAAM,EAAE,CAAC,IAAI,EAAE;QACb,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QACb,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAA;QACrB;;;WAGG;QACH,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,CAAA;QAC1C,KAAK,EAAE,MAAM,MAAM,CAAA;QACnB;;;;;;WAMG;QACH,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;KAGd,KAAK,IAAI,EAAE,CAAA;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,WAAW,GAAG,MAAM,CAAA;IAC5B,MAAM,EAAE,MAAM,IAAI,EAAE,CAAA;CACrB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ;IAC/E;;;;;;;;;;;;;OAaG;IACH,KAAK,EAAE,CAAC,GAAG,EAAE;QAAE,SAAS,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;KAAE,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACvF,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;IAClB,IAAI,EACA,CAAC,CAAC,GAAG,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,CAAC,CAAC;QAAC,IAAI,EAAE,CAAC,GAAG,SAAS,CAAA;KAAE,KAAK,IAAI,CAAC,GACtE;SACG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE;YAAE,QAAQ,EAAE,QAAQ,CAAC;YAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;SAAE,KAAK,IAAI;KAC5F,CAAA;IACL,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;IACrC,SAAS,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;CAC7D;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,MAAM;IAMrC,GAAG,EAAE,eAAe,CAAA;IACpB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACxC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAA;CACxC"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,qEAAqE","sourcesContent":["// ── Component Definition ──────────────────────────────────────────\n\nimport type { View } from './view-helpers.js'\nimport type { StructuralBlock } from './structural.js'\nimport type { ComponentInstance } from './update-loop.js'\nimport type { DisposerEvent } from './tracking/disposer-log.js'\n\nexport interface ComponentDef<S, M, E = never, D = void> {\n name: string\n init: (data: D) => [S, E[]]\n update: (state: S, msg: M) => [S, E[]]\n view: (h: View<S, M>) => Node[]\n onEffect?: (ctx: { effect: E; send: Send<M>; signal: AbortSignal }) => void\n\n // Level 2 composition\n propsMsg?: (props: Record<string, unknown>) => M\n receives?: Record<string, (params: unknown) => M>\n\n /** @internal Compiler-injected */\n __dirty?: (oldState: S, newState: S) => number | [number, number]\n /** @internal Compiler-injected */\n __renderToString?: (state: S) => string\n /** @internal Compiler-injected */\n __msgSchema?: object\n /** @internal Compiler-injected; keyed by Msg discriminant → annotations. See agent spec §5.1. */\n __msgAnnotations?: Record<\n string,\n {\n intent: string | null\n alwaysAffordable: boolean\n requiresConfirm: boolean\n humanOnly: boolean\n }\n >\n /** @internal Compiler-emitted; one entry per send() call site in view(). See agent spec §5.2. */\n __bindingDescriptors?: Array<{ variant: string }>\n /** @internal Compiler-injected; 32-char hex SHA-256 of schemas + annotations. See agent spec §12.3. */\n __schemaHash?: string\n /** @internal Compiler-injected — maps top-level state field → dirty-mask bit(s) */\n __maskLegend?: Record<string, number>\n /** @internal Compiler-injected — source-file location of the component() call */\n __componentMeta?: { file: string; line: number }\n /** @internal Compiler-injected — shape of the State type (for introspection) */\n __stateSchema?: object\n /** @internal Compiler-injected — Effect union schema (for introspection) */\n __effectSchema?: object\n /** @internal Compiler-injected — replaces generic Phase 1 + Phase 2 loop */\n __update?: (\n state: S,\n dirty: number,\n bindings: Binding[],\n blocks: StructuralBlock[],\n bindingsBeforePhase1: number,\n ) => void\n /** @internal Compiler-injected — per-message-type specialized handlers.\n * Bypass the entire processMessages pipeline for single-message updates. */\n __handlers?: Record<string, (inst: object, msg: unknown) => [S, E[]]>\n}\n\nexport type Send<M> = (msg: M) => void\n\n/**\n * Type-erased component definition for use at module boundaries where\n * the consumer's `S`, `M`, `E` are internal and invisible to the caller.\n *\n * Why this exists: `ComponentDef<S, M, E, D>` uses property syntax for\n * its callable fields (`init: (data: D) => ...`), and TypeScript\n * checks property syntax with strict (contravariant) variance. That's\n * the right call for user-facing type safety when authoring a\n * component (a narrower `Msg` type can't accidentally satisfy the\n * `update`'s param), but it means `ComponentDef<MyState, MyMsg, MyEffect, MyData>`\n * is NOT structurally assignable to `ComponentDef<unknown, unknown, unknown, unknown>`\n * — the `init: (data: MyData) => ...` field is contravariant in `MyData`,\n * so widening to `unknown` is rejected.\n *\n * `AnyComponentDef` (and `LazyDef<D>` below) declare the same fields\n * using **method syntax** (`init(data: D): ...`), which TypeScript\n * checks bivariantly. Concrete `ComponentDef<S, M, E, D>` assigns into\n * these structurally without any `widenDef` helper at the callsite.\n *\n * Used by every API that accepts an opaque component definition at a\n * module boundary:\n *\n * - `child({ def })`\n * - `lazy({ loader })` — returns `LazyDef<D>` so the loader's `D` survives\n * - `createOnRenderClient({ Layout })` (from `@llui/vike`)\n * - `createOnRenderHtml({ Layout })` (from `@llui/vike`)\n *\n * The `D` parameter is `unknown` here — `child()` doesn't pass init\n * data through, and `Layout` callers pass route-supplied data whose\n * shape is unknown at the type-erased boundary. Use `LazyDef<D>` when\n * you need to preserve the init data shape (the lazy loader case).\n */\nexport interface AnyComponentDef {\n name: string\n init(data: unknown): [unknown, unknown[]]\n update(state: unknown, msg: unknown): [unknown, unknown[]]\n view(h: unknown): Node[]\n onEffect?: unknown\n propsMsg?: unknown\n receives?: unknown\n __dirty?: unknown\n __renderToString?: unknown\n __msgSchema?: unknown\n __msgAnnotations?: unknown\n __bindingDescriptors?: unknown\n __schemaHash?: unknown\n __maskLegend?: unknown\n __componentMeta?: unknown\n __stateSchema?: unknown\n __effectSchema?: unknown\n __update?: unknown\n __handlers?: unknown\n}\n\n/**\n * Type-erased component definition for use at module boundaries where the\n * loaded component's S, M, E are internal and invisible to the caller.\n * Only `D` (init data) survives because the caller provides it.\n *\n * `ComponentDef<S, M, E, D>` is structurally assignable to `LazyDef<D>`\n * for any S, M, E — `view: (h: unknown) => Node[]` accepts any View via\n * contravariance, and all other fields widen to `unknown` return types.\n *\n * Used by `lazy()` as the loader's return type. Use `AnyComponentDef`\n * (above) when D is also opaque — most other adapter-layer APIs.\n */\nexport interface LazyDef<D = void> {\n name: string\n // Method syntax — TypeScript checks methods bivariantly, so\n // ComponentDef<S, M, E, D>'s concrete (state: S, msg: M) => ...\n // assigns here even though S/M ≠ unknown. Property syntax would\n // be contravariant and reject the assignment.\n init(data: D): [unknown, unknown[]]\n update(state: unknown, msg: unknown): [unknown, unknown[]]\n view(h: unknown): Node[]\n onEffect?: unknown\n propsMsg?: unknown\n receives?: unknown\n __dirty?: unknown\n __renderToString?: unknown\n __msgSchema?: unknown\n __msgAnnotations?: unknown\n __bindingDescriptors?: unknown\n __schemaHash?: unknown\n __maskLegend?: unknown\n __componentMeta?: unknown\n __stateSchema?: unknown\n __effectSchema?: unknown\n __update?: unknown\n __handlers?: unknown\n}\n\n/**\n * Maps a value shape to a reactive-props shape: every field becomes an accessor\n * `(s: S) => V`. Use for Level-1 view function signatures.\n *\n * ```ts\n * type ToolbarData = { tools: Tool[]; theme: 'light' | 'dark' }\n *\n * export function toolbar<S>(props: Props<ToolbarData, S>, send: Send<Msg>) {\n * return [div({ class: props.theme }, [each({ items: props.tools, ... })])]\n * }\n *\n * // Caller — TypeScript enforces per-field accessors; passing a raw value errors:\n * toolbar({ tools: (s: State) => s.tools, theme: (s) => s.theme }, send)\n * ```\n */\nexport type Props<T, S> = {\n [K in keyof T]: (s: S) => T[K]\n}\n\n// ── App Handle ────────────────────────────────────────────────────\n\nexport interface AppHandle {\n dispose(): void\n flush(): void\n /**\n * Dispatch a message into the mounted instance from outside its\n * normal view-bound `send` channel. Useful for adapter layers that\n * need to push updates into a long-lived instance — e.g.\n * `@llui/vike`'s persistent-layout chain pushes layout-data updates\n * into surviving layer instances on client navigation when their\n * `propsMsg` translates the new data into a state-update message.\n *\n * Messages are queued through the same path as `view`-side `send`\n * calls — they batch into the next microtask and process via the\n * normal update loop. Calling `send` after `dispose` is a no-op.\n */\n send(msg: unknown): void\n /**\n * Read the current state snapshot. Safe to call from anywhere —\n * event handlers, async callbacks, adapter `send` wrappers, or any\n * imperative context where the render context is not live.\n *\n * Unlike `sample()` (a view primitive that requires an active\n * render context and throws outside of `view()`), `getState` is\n * the sanctioned escape hatch for \"I need to know the current\n * state to decide what to dispatch.\" Typical shape:\n *\n * ```ts\n * const handle = mountApp(root, MyApp)\n * container.addEventListener('drop', () => {\n * const { mode } = handle.getState() as AppState\n * if (mode === 'drag') handle.send({ type: 'commit' })\n * })\n * ```\n *\n * Throws after `dispose()` — stale reads are silent bugs; a thrown\n * error pinpoints the callsite that forgot to detach.\n *\n * The return type is `unknown` because `AppHandle` is state-type\n * erased at this boundary; cast to your app's state type at the\n * call site.\n */\n getState(): unknown\n /**\n * Register a listener called synchronously after every update cycle\n * completes. The listener receives the new state. Returns an\n * unsubscribe function. Safe after dispose (no-op; returns a no-op\n * unsubscribe). See agent spec §10.5 (state-update frames).\n */\n subscribe(listener: (state: unknown) => void): () => void\n /**\n * Snapshot the Msg variants currently dispatchable from rendered UI.\n * Each entry corresponds to one or more event-handler bindings the\n * compiler tagged with literal `send({type: '<variant>'})` calls;\n * the registry tracks live mounts via lifetime refcounts so the\n * snapshot reflects what the user can click *right now*, not the\n * static catalogue of every variant the app could ever accept.\n *\n * Used by `@llui/agent` to populate `list_actions`. Apps that don't\n * use the LLui compiler tagger pass (or whose views contain no\n * literal sends) get an empty array — agents fall back to the Msg\n * schema for affordance discovery.\n */\n getBindingDescriptors(): Array<{ variant: string }>\n /**\n * Hot-swap the component's `update` function (and optionally\n * `onEffect`) without rebuilding the DOM. Pending messages are\n * drained against the OLD `update` first so a half-applied\n * transition can't leave the state ill-formed; subsequent\n * dispatches go through the new function.\n *\n * This is the lightweight HMR escape hatch for cases where the\n * full `replaceComponent` flow (in `@llui/dom/hmr`) is overkill —\n * pure `update.ts` edits don't change the view, so disposing the\n * root lifetime and re-running the view just to install a new\n * function is wasteful and loses focus / scroll / transient DOM\n * state. Wire it via `import.meta.hot`:\n *\n * ```ts\n * // main.ts\n * const handle = mountApp(root, App)\n * if (import.meta.hot) {\n * import.meta.hot.accept('./app/update', (mod) => {\n * if (mod) handle.swapUpdate(mod.update)\n * })\n * }\n * ```\n *\n * Caveats:\n * - Doesn't compensate for State shape changes — if the new\n * `update` reads a field the old state doesn't have, you'll\n * see runtime errors. Hard-reload after structural state\n * changes.\n * - Doesn't swap `view` or compiler-emitted `__update`/`__dirty`\n * — for those, prefer the auto-injected component-level HMR\n * accept callback (which routes through `replaceComponent`).\n */\n swapUpdate(\n newUpdate: (state: unknown, msg: unknown) => [unknown, unknown[]],\n newOnEffect?: unknown,\n ): void\n /**\n * Run the reducer in isolation against the current state. Returns\n * `[newState, effects]` — the reducer's literal output without any\n * commit, flush, or effect-handler invocation. Used by the agent's\n * `would_dispatch` tool to predict what a candidate dispatch would\n * do before committing to it.\n *\n * Pure-reducer assumption: TEA mandates `update` be pure. LLui's\n * runtime treats it that way too (no speculative re-runs for any\n * other reason). Apps whose reducers branch on `Date.now()` or\n * read `localStorage` will see prediction drift from real dispatch\n * by exactly that amount of impurity — surface as documented at\n * the agent's call site, not silently corrected here.\n *\n * **No effects fire.** Effect descriptors are returned for the\n * agent to inspect; `onEffect` is not called. This is the entire\n * point of the API.\n */\n runReducer(msg: unknown): { state: unknown; effects: unknown[] } | null\n}\n\n// ── Lifetime ─────────────────────────────────────────────────────────\n\nexport interface Lifetime {\n id: number\n parent: Lifetime | null\n children: Lifetime[]\n disposers: Array<() => void>\n bindings: Binding[]\n /** Per-item updaters — called directly by each() when item changes, bypassing Phase 2 */\n itemUpdaters: Array<() => void>\n /**\n * @internal dev-only back-reference to the owning ComponentInstance.\n * Populated on the root scope by `installDevTools` so `disposeLifetime`\n * can walk up the scope chain and emit DisposerEvents into the\n * instance's `_disposerLog`. Undefined in production.\n */\n instance?: ComponentInstance\n /**\n * @internal dev-only cause hint. Structural primitives (branch, each,\n * child, mountApp teardown) set this field immediately before calling\n * `disposeLifetime`; the dispose path reads it once to stamp the emitted\n * DisposerEvent. Left undefined, `disposeLifetime` falls back to\n * `'component-unmount'`. Undefined in production.\n */\n disposalCause?: DisposerEvent['cause']\n /** @internal dev-only — populated by structural primitives for scope-tree classification */\n _kind?: 'root' | 'show' | 'each' | 'branch' | 'scope' | 'child' | 'portal' | 'foreign'\n}\n\nexport interface LifetimeNode {\n scopeId: string\n kind: 'root' | 'show' | 'each' | 'branch' | 'scope' | 'child' | 'portal' | 'foreign'\n active: boolean\n children: LifetimeNode[]\n}\n\n// ── Binding ───────────────────────────────────────────────────────\n\n/**\n * Binding output kinds.\n *\n * `'text' | 'prop' | 'attr' | 'class' | 'style'` write their accessor's\n * return value to the DOM. `'effect'` is a side-effect-only watcher:\n * the accessor is invoked every Phase 2 tick its mask is hit, but its\n * return value is discarded and `applyBinding` is a no-op. Used by\n * `child()` to fire the prop-diff/propsMsg cascade on parent updates\n * without the cost of stringifying the returned props bag onto a\n * detached anchor node every render.\n */\nexport type BindingKind = 'text' | 'prop' | 'attr' | 'class' | 'style' | 'effect'\n\nexport interface Binding {\n mask: number\n accessor: (state: unknown) => unknown\n lastValue: unknown\n kind: BindingKind\n node: Node\n key?: string\n ownerLifetime: Lifetime\n perItem: boolean\n dead: boolean\n}\n\n// ── Structural Primitives ─────────────────────────────────────────\n\nexport interface TransitionOptions {\n enter?: (nodes: Node[]) => void | Promise<void>\n leave?: (nodes: Node[]) => void | Promise<void>\n onTransition?: (ctx: { entering: Node[]; leaving: Node[]; parent: Node }) => void | Promise<void>\n}\n\ninterface BranchOptionsBase extends TransitionOptions {\n /**\n * @internal Set by `show()` / `scope()` sugar when delegating to\n * `branch()`, so the dev-only disposer log can report `'show-hide'` /\n * `'scope-rebuild'` instead of the default `'branch-swap'` for the\n * leaving arm. User code should not set this directly.\n */\n __disposalCause?: DisposerEvent['cause']\n /** @internal Compiler-injected mask of paths read by `on`. */\n __mask?: number\n}\n\n/**\n * Discriminant accessor — reads a string-keyed value either from the\n * current state (`(s) => …`) or from a closed-over item accessor /\n * memo (`() => item.kind()`). Both forms re-evaluate on every commit.\n * The zero-arg form is the canonical shape for branching on per-row\n * fields inside an `each.render` callback.\n */\ntype Discriminant<S, K extends string> = ((s: S) => K) | (() => K)\n\n/**\n * All cases covered by `cases` — no default allowed (would be dead code).\n */\ntype BranchOptionsExhaustive<S, M, K extends string> = BranchOptionsBase & {\n on: Discriminant<S, K>\n cases: { [P in K]: (h: View<S, M>) => Node[] }\n default?: never\n}\n\n/**\n * `cases` may cover some but not all keys; `default` handles the rest.\n */\ntype BranchOptionsNonExhaustive<S, M, K extends string> = BranchOptionsBase & {\n on: Discriminant<S, K>\n cases?: { [P in K]?: (h: View<S, M>) => Node[] }\n default: (h: View<S, M>) => Node[]\n}\n\n/**\n * `on` returns a wide `string` — exhaustiveness cannot be verified at\n * compile time (the key domain is infinite). Lenient: `default` is\n * optional so existing call sites that predate exhaustiveness typing\n * continue to compile. Authors who want the gate opt in by narrowing\n * `on`'s return type to a literal union.\n */\ntype BranchOptionsWide<S, M> = BranchOptionsBase & {\n on: Discriminant<S, string>\n cases?: Record<string, (h: View<S, M>) => Node[]>\n default?: (h: View<S, M>) => Node[]\n}\n\n/**\n * Options for `branch()`.\n *\n * When `on` returns a literal string union (e.g. `'idle' | 'loading'\n * | 'done'`), TypeScript enforces exhaustiveness: either every union\n * member has a case (and `default` is disallowed as unreachable), or\n * `default` is required to cover the remainder. When `on` returns a\n * wide `string`, `default` stays optional — exhaustiveness isn't\n * meaningful for an unbounded domain.\n *\n * `cases` is optional when `default` is present; `branch({ on, default })`\n * is the canonical dynamic-rebuild shape — `scope()` sugar wraps\n * exactly this form.\n */\nexport type BranchOptions<S, M = unknown, K extends string = string> = string extends K\n ? BranchOptionsWide<S, M>\n : BranchOptionsExhaustive<S, M, K> | BranchOptionsNonExhaustive<S, M, K>\n\nexport interface ShowOptions<S, M = unknown> extends TransitionOptions {\n /**\n * Predicate evaluated on every commit. `(s) => …` reads from\n * component state; `() => …` (zero-arg) reads from a closed-over\n * source — typically `item.field()` inside an `each.render`\n * callback. Both forms are reactive: the predicate runs against\n * each new state and the rendered subtree mounts/unmounts on the\n * boolean transition.\n */\n when: ((s: S) => boolean) | (() => boolean)\n render: (h: View<S, M>) => Node[]\n fallback?: (h: View<S, M>) => Node[]\n}\n\n/**\n * Options for `scope()` — rebuilds a subtree when `on(state)` changes.\n *\n * Sugar over `branch({ on, cases: {}, default: render, __disposalCause: 'scope-rebuild' })`.\n * Use when the key is dynamic (e.g. an epoch counter bumped from the\n * outside) and you want a fresh arm — fresh lifetime, fresh bindings —\n * each time it changes. Combine with `sample()` inside `render` for a\n * one-shot current-state read.\n */\nexport interface ScopeOptions<S, M = unknown> extends TransitionOptions {\n /**\n * Key accessor evaluated on every commit. `(s) => …` reads from\n * component state; `() => …` (zero-arg) reads from a closed-over\n * source. The render callback rebuilds whenever the returned key\n * changes — fresh lifetime, fresh bindings.\n */\n on: ((s: S) => string) | (() => string)\n render: (h: View<S, M>) => Node[]\n /** @internal Compiler-injected mask of paths read by `on`. */\n __mask?: number\n}\n\n/**\n * Options for `each()`. The inherited `enter` / `leave` callbacks fire **per item**:\n * `enter(nodes)` runs after an item's DOM is inserted (including initial mount);\n * `leave(nodes)` runs before an item's DOM is removed and may return a Promise\n * to hold the DOM until the animation resolves. Setting `leave` disables the\n * bulk-clear / full-replace fast paths.\n */\n/**\n * Per-item accessor. Two access forms:\n * - `item.field` — shorthand, returns accessor for `item.current[field]`\n * - `item(t => t.expr)` — computed expressions\n *\n * In both cases the returned value is a `() => V` accessor.\n * Invoke it (`item.field()`) to read the current value imperatively.\n */\nexport type ItemAccessor<T> = {\n <R>(selector: (t: T) => R): () => R\n} & {\n [K in keyof T]-?: () => T[K]\n} & {\n /**\n * Read the whole current item. Needed when T is a primitive (where the\n * field-map branch collapses to method names like `toString`) or when\n * you want to sample the entire record rather than a single field.\n *\n * Shadows any literal `current` field on T — if T has such a field,\n * use `item(r => r.current)` to disambiguate.\n */\n current(): T\n}\n\nexport interface EachOptions<S, T, M = unknown> extends TransitionOptions {\n items: (s: S) => T[]\n key: (item: T) => string | number\n render: (opts: {\n send: Send<M>\n item: ItemAccessor<T>\n /**\n * Plain (non-Proxy) accessor factory. Compiler-output path; avoid in user code\n * (use `item.field` / `item(fn)` — more ergonomic and bypasses Proxy when compiled).\n */\n acc: <R>(selector: (t: T) => R) => () => R\n index: () => number\n /**\n * The component's View bag (`h.text`, `h.show`, `h.branch`,\n * `h.scope`, `h.sample`, …). Each-render callers used to reach\n * for the top-level imports; the bag form is symmetric with how\n * `branch.cases[k]`, `show.render`, and `scope.render` receive it.\n * Both still work — destructure whichever is more convenient.\n */\n h: View<S, M>\n /** @internal Compiler-injected — entry reference for row factory */\n entry?: Record<string, unknown>\n }) => Node[]\n}\n\nexport interface PortalOptions {\n target: HTMLElement | string\n render: () => Node[]\n}\n\nexport interface ForeignOptions<S, M, T extends Record<string, unknown>, Instance> {\n /**\n * Construct the imperative instance. Can be async — return a\n * `Promise<Instance>` to defer construction until e.g. a dynamic\n * `import()` resolves. While the promise is pending:\n *\n * - The container element is in the DOM immediately (so layout\n * doesn't shift when the instance arrives).\n * - `sync` is NOT called. State changes are tracked by the\n * primitive and the latest props are applied as the initial\n * sync right after the promise resolves.\n * - If the owning scope disposes before the promise resolves,\n * `destroy(instance)` runs on resolution — no matter how long\n * the promise takes.\n */\n mount: (ctx: { container: HTMLElement; send: Send<M> }) => Instance | Promise<Instance>\n props: (s: S) => T\n sync:\n | ((ctx: { instance: Instance; props: T; prev: T | undefined }) => void)\n | {\n [K in keyof T]?: (ctx: { instance: Instance; value: T[K]; prev: T[K] | undefined }) => void\n }\n destroy: (instance: Instance) => void\n container?: { tag?: string; attrs?: Record<string, string> }\n}\n\nexport interface ChildOptions<S, ChildM> {\n // Type-erased via AnyComponentDef so callers can pass any concrete\n // ComponentDef<S, M, E, D> without a widening helper. The runtime\n // narrows the message shape via the user-supplied `onMsg` callback,\n // which keeps `ChildM` typed at this boundary even though the def\n // itself is opaque.\n def: AnyComponentDef\n key: string | number\n props: (s: S) => Record<string, unknown>\n onMsg?: (msg: ChildM) => unknown | null\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,qEAAqE","sourcesContent":["// ── Component Definition ──────────────────────────────────────────\n\nimport type { View } from './view-helpers.js'\nimport type { StructuralBlock } from './structural.js'\nimport type { ComponentInstance } from './update-loop.js'\nimport type { DisposerEvent } from './tracking/disposer-log.js'\n\nexport interface ComponentDef<S, M, E = never, D = void> {\n name: string\n init: (data: D) => [S, E[]]\n update: (state: S, msg: M) => [S, E[]]\n view: (h: View<S, M>) => Node[]\n onEffect?: (ctx: { effect: E; send: Send<M>; signal: AbortSignal }) => void\n\n // Level 2 composition\n propsMsg?: (props: Record<string, unknown>) => M\n receives?: Record<string, (params: unknown) => M>\n\n /** @internal Compiler-injected */\n __dirty?: (oldState: S, newState: S) => number | [number, number]\n /** @internal Compiler-injected */\n __renderToString?: (state: S) => string\n /** @internal Compiler-injected */\n __msgSchema?: object\n /** @internal Compiler-injected; keyed by Msg discriminant → annotations. See agent spec §5.1. */\n __msgAnnotations?: Record<\n string,\n {\n intent: string | null\n alwaysAffordable: boolean\n requiresConfirm: boolean\n humanOnly: boolean\n }\n >\n /** @internal Compiler-emitted; one entry per send() call site in view(). See agent spec §5.2. */\n __bindingDescriptors?: Array<{ variant: string }>\n /** @internal Compiler-injected; 32-char hex SHA-256 of schemas + annotations. See agent spec §12.3. */\n __schemaHash?: string\n /** @internal Compiler-injected — maps top-level state field → dirty-mask bit(s) */\n __maskLegend?: Record<string, number>\n /** @internal Compiler-injected — source-file location of the component() call */\n __componentMeta?: { file: string; line: number }\n /** @internal Compiler-injected — shape of the State type (for introspection) */\n __stateSchema?: object\n /** @internal Compiler-injected — Effect union schema (for introspection) */\n __effectSchema?: object\n /** @internal Compiler-injected — replaces generic Phase 1 + Phase 2 loop */\n __update?: (\n state: S,\n dirty: number,\n bindings: Binding[],\n blocks: StructuralBlock[],\n bindingsBeforePhase1: number,\n ) => void\n /** @internal Compiler-injected — per-message-type specialized handlers.\n * Bypass the entire processMessages pipeline for single-message updates. */\n __handlers?: Record<string, (inst: object, msg: unknown) => [S, E[]]>\n}\n\nexport type Send<M> = (msg: M) => void\n\n/**\n * Type-erased component definition for use at module boundaries where\n * the consumer's `S`, `M`, `E` are internal and invisible to the caller.\n *\n * Why this exists: `ComponentDef<S, M, E, D>` uses property syntax for\n * its callable fields (`init: (data: D) => ...`), and TypeScript\n * checks property syntax with strict (contravariant) variance. That's\n * the right call for user-facing type safety when authoring a\n * component (a narrower `Msg` type can't accidentally satisfy the\n * `update`'s param), but it means `ComponentDef<MyState, MyMsg, MyEffect, MyData>`\n * is NOT structurally assignable to `ComponentDef<unknown, unknown, unknown, unknown>`\n * — the `init: (data: MyData) => ...` field is contravariant in `MyData`,\n * so widening to `unknown` is rejected.\n *\n * `AnyComponentDef` (and `LazyDef<D>` below) declare the same fields\n * using **method syntax** (`init(data: D): ...`), which TypeScript\n * checks bivariantly. Concrete `ComponentDef<S, M, E, D>` assigns into\n * these structurally without any `widenDef` helper at the callsite.\n *\n * Used by every API that accepts an opaque component definition at a\n * module boundary:\n *\n * - `child({ def })`\n * - `lazy({ loader })` — returns `LazyDef<D>` so the loader's `D` survives\n * - `createOnRenderClient({ Layout })` (from `@llui/vike`)\n * - `createOnRenderHtml({ Layout })` (from `@llui/vike`)\n *\n * The `D` parameter is `unknown` here — `child()` doesn't pass init\n * data through, and `Layout` callers pass route-supplied data whose\n * shape is unknown at the type-erased boundary. Use `LazyDef<D>` when\n * you need to preserve the init data shape (the lazy loader case).\n */\nexport interface AnyComponentDef {\n name: string\n init(data: unknown): [unknown, unknown[]]\n update(state: unknown, msg: unknown): [unknown, unknown[]]\n view(h: unknown): Node[]\n onEffect?: unknown\n propsMsg?: unknown\n receives?: unknown\n __dirty?: unknown\n __renderToString?: unknown\n __msgSchema?: unknown\n __msgAnnotations?: unknown\n __bindingDescriptors?: unknown\n __schemaHash?: unknown\n __maskLegend?: unknown\n __componentMeta?: unknown\n __stateSchema?: unknown\n __effectSchema?: unknown\n __update?: unknown\n __handlers?: unknown\n}\n\n/**\n * Type-erased component definition for use at module boundaries where the\n * loaded component's S, M, E are internal and invisible to the caller.\n * Only `D` (init data) survives because the caller provides it.\n *\n * `ComponentDef<S, M, E, D>` is structurally assignable to `LazyDef<D>`\n * for any S, M, E — `view: (h: unknown) => Node[]` accepts any View via\n * contravariance, and all other fields widen to `unknown` return types.\n *\n * Used by `lazy()` as the loader's return type. Use `AnyComponentDef`\n * (above) when D is also opaque — most other adapter-layer APIs.\n */\nexport interface LazyDef<D = void> {\n name: string\n // Method syntax — TypeScript checks methods bivariantly, so\n // ComponentDef<S, M, E, D>'s concrete (state: S, msg: M) => ...\n // assigns here even though S/M ≠ unknown. Property syntax would\n // be contravariant and reject the assignment.\n init(data: D): [unknown, unknown[]]\n update(state: unknown, msg: unknown): [unknown, unknown[]]\n view(h: unknown): Node[]\n onEffect?: unknown\n propsMsg?: unknown\n receives?: unknown\n __dirty?: unknown\n __renderToString?: unknown\n __msgSchema?: unknown\n __msgAnnotations?: unknown\n __bindingDescriptors?: unknown\n __schemaHash?: unknown\n __maskLegend?: unknown\n __componentMeta?: unknown\n __stateSchema?: unknown\n __effectSchema?: unknown\n __update?: unknown\n __handlers?: unknown\n}\n\n/**\n * Maps a value shape to a reactive-props shape: every field becomes an accessor\n * `(s: S) => V`. Use for Level-1 view function signatures.\n *\n * ```ts\n * type ToolbarData = { tools: Tool[]; theme: 'light' | 'dark' }\n *\n * export function toolbar<S>(props: Props<ToolbarData, S>, send: Send<Msg>) {\n * return [div({ class: props.theme }, [each({ items: props.tools, ... })])]\n * }\n *\n * // Caller — TypeScript enforces per-field accessors; passing a raw value errors:\n * toolbar({ tools: (s: State) => s.tools, theme: (s) => s.theme }, send)\n * ```\n */\nexport type Props<T, S> = {\n [K in keyof T]: (s: S) => T[K]\n}\n\n// ── App Handle ────────────────────────────────────────────────────\n\nexport interface AppHandle {\n dispose(): void\n flush(): void\n /**\n * Dispatch a message into the mounted instance from outside its\n * normal view-bound `send` channel. Useful for adapter layers that\n * need to push updates into a long-lived instance — e.g.\n * `@llui/vike`'s persistent-layout chain pushes layout-data updates\n * into surviving layer instances on client navigation when their\n * `propsMsg` translates the new data into a state-update message.\n *\n * Messages are queued through the same path as `view`-side `send`\n * calls — they batch into the next microtask and process via the\n * normal update loop. Calling `send` after `dispose` is a no-op.\n */\n send(msg: unknown): void\n /**\n * Read the current state snapshot. Safe to call from anywhere —\n * event handlers, async callbacks, adapter `send` wrappers, or any\n * imperative context where the render context is not live.\n *\n * Unlike `sample()` (a view primitive that requires an active\n * render context and throws outside of `view()`), `getState` is\n * the sanctioned escape hatch for \"I need to know the current\n * state to decide what to dispatch.\" Typical shape:\n *\n * ```ts\n * const handle = mountApp(root, MyApp)\n * container.addEventListener('drop', () => {\n * const { mode } = handle.getState() as AppState\n * if (mode === 'drag') handle.send({ type: 'commit' })\n * })\n * ```\n *\n * Throws after `dispose()` — stale reads are silent bugs; a thrown\n * error pinpoints the callsite that forgot to detach.\n *\n * The return type is `unknown` because `AppHandle` is state-type\n * erased at this boundary; cast to your app's state type at the\n * call site.\n */\n getState(): unknown\n /**\n * Register a listener called synchronously after every update cycle\n * completes. The listener receives the new state. Returns an\n * unsubscribe function. Safe after dispose (no-op; returns a no-op\n * unsubscribe). See agent spec §10.5 (state-update frames).\n */\n subscribe(listener: (state: unknown) => void): () => void\n /**\n * Snapshot the Msg variants currently dispatchable from rendered UI.\n * Each entry corresponds to one or more event-handler bindings the\n * compiler tagged with literal `send({type: '<variant>'})` calls;\n * the registry tracks live mounts via lifetime refcounts so the\n * snapshot reflects what the user can click *right now*, not the\n * static catalogue of every variant the app could ever accept.\n *\n * Used by `@llui/agent` to populate `list_actions`. Apps that don't\n * use the LLui compiler tagger pass (or whose views contain no\n * literal sends) get an empty array — agents fall back to the Msg\n * schema for affordance discovery.\n */\n getBindingDescriptors(): Array<{ variant: string }>\n /**\n * Hot-swap the component's `update` function (and optionally\n * `onEffect`) without rebuilding the DOM. Pending messages are\n * drained against the OLD `update` first so a half-applied\n * transition can't leave the state ill-formed; subsequent\n * dispatches go through the new function.\n *\n * This is the lightweight HMR escape hatch for cases where the\n * full `replaceComponent` flow (in `@llui/dom/hmr`) is overkill —\n * pure `update.ts` edits don't change the view, so disposing the\n * root lifetime and re-running the view just to install a new\n * function is wasteful and loses focus / scroll / transient DOM\n * state. Wire it via `import.meta.hot`:\n *\n * ```ts\n * // main.ts\n * const handle = mountApp(root, App)\n * if (import.meta.hot) {\n * import.meta.hot.accept('./app/update', (mod) => {\n * if (mod) handle.swapUpdate(mod.update)\n * })\n * }\n * ```\n *\n * Caveats:\n * - Doesn't compensate for State shape changes — if the new\n * `update` reads a field the old state doesn't have, you'll\n * see runtime errors. Hard-reload after structural state\n * changes.\n * - Doesn't swap `view` or compiler-emitted `__update`/`__dirty`\n * — for those, prefer the auto-injected component-level HMR\n * accept callback (which routes through `replaceComponent`).\n */\n swapUpdate(\n newUpdate: (state: unknown, msg: unknown) => [unknown, unknown[]],\n newOnEffect?: unknown,\n ): void\n /**\n * Run the reducer in isolation against the current state. Returns\n * `[newState, effects]` — the reducer's literal output without any\n * commit, flush, or effect-handler invocation. Used by the agent's\n * `would_dispatch` tool to predict what a candidate dispatch would\n * do before committing to it.\n *\n * Pure-reducer assumption: TEA mandates `update` be pure. LLui's\n * runtime treats it that way too (no speculative re-runs for any\n * other reason). Apps whose reducers branch on `Date.now()` or\n * read `localStorage` will see prediction drift from real dispatch\n * by exactly that amount of impurity — surface as documented at\n * the agent's call site, not silently corrected here.\n *\n * **No effects fire.** Effect descriptors are returned for the\n * agent to inspect; `onEffect` is not called. This is the entire\n * point of the API.\n */\n runReducer(msg: unknown): { state: unknown; effects: unknown[] } | null\n /**\n * Install a hook called whenever a binding's accessor throws during\n * the update cycle. The runtime catches the throw, leaves the\n * binding's `lastValue` unchanged (DOM stays at its previous value\n * rather than blanking), continues with sibling bindings, and\n * notifies this hook with `{kind, key?, message, stack?}`.\n *\n * Used by `@llui/agent` to fold binding-evaluation throws into the\n * dispatch envelope's `drain.errors` — so an LLM dispatching a Msg\n * that breaks scoring doesn't get HTTP 500 + a frozen UI; instead\n * the dispatch reports as `{status: 'dispatched', drain: {errors:\n * [...]}}` with the rest of the page rendering normally.\n *\n * Pass `null` to remove the hook. Without a hook, throws fall back\n * to `console.error` (dev mode) or `console.warn` (prod) so they\n * aren't silently swallowed.\n */\n setOnBindingError(\n hook: ((info: { kind: string; key?: string; message: string; stack?: string }) => void) | null,\n ): void\n}\n\n// ── Lifetime ─────────────────────────────────────────────────────────\n\nexport interface Lifetime {\n id: number\n parent: Lifetime | null\n children: Lifetime[]\n disposers: Array<() => void>\n bindings: Binding[]\n /** Per-item updaters — called directly by each() when item changes, bypassing Phase 2 */\n itemUpdaters: Array<() => void>\n /**\n * @internal dev-only back-reference to the owning ComponentInstance.\n * Populated on the root scope by `installDevTools` so `disposeLifetime`\n * can walk up the scope chain and emit DisposerEvents into the\n * instance's `_disposerLog`. Undefined in production.\n */\n instance?: ComponentInstance\n /**\n * @internal dev-only cause hint. Structural primitives (branch, each,\n * child, mountApp teardown) set this field immediately before calling\n * `disposeLifetime`; the dispose path reads it once to stamp the emitted\n * DisposerEvent. Left undefined, `disposeLifetime` falls back to\n * `'component-unmount'`. Undefined in production.\n */\n disposalCause?: DisposerEvent['cause']\n /** @internal dev-only — populated by structural primitives for scope-tree classification */\n _kind?: 'root' | 'show' | 'each' | 'branch' | 'scope' | 'child' | 'portal' | 'foreign'\n}\n\nexport interface LifetimeNode {\n scopeId: string\n kind: 'root' | 'show' | 'each' | 'branch' | 'scope' | 'child' | 'portal' | 'foreign'\n active: boolean\n children: LifetimeNode[]\n}\n\n// ── Binding ───────────────────────────────────────────────────────\n\n/**\n * Binding output kinds.\n *\n * `'text' | 'prop' | 'attr' | 'class' | 'style'` write their accessor's\n * return value to the DOM. `'effect'` is a side-effect-only watcher:\n * the accessor is invoked every Phase 2 tick its mask is hit, but its\n * return value is discarded and `applyBinding` is a no-op. Used by\n * `child()` to fire the prop-diff/propsMsg cascade on parent updates\n * without the cost of stringifying the returned props bag onto a\n * detached anchor node every render.\n */\nexport type BindingKind = 'text' | 'prop' | 'attr' | 'class' | 'style' | 'effect'\n\nexport interface Binding {\n mask: number\n accessor: (state: unknown) => unknown\n lastValue: unknown\n kind: BindingKind\n node: Node\n key?: string\n ownerLifetime: Lifetime\n perItem: boolean\n dead: boolean\n}\n\n// ── Structural Primitives ─────────────────────────────────────────\n\nexport interface TransitionOptions {\n enter?: (nodes: Node[]) => void | Promise<void>\n leave?: (nodes: Node[]) => void | Promise<void>\n onTransition?: (ctx: { entering: Node[]; leaving: Node[]; parent: Node }) => void | Promise<void>\n}\n\ninterface BranchOptionsBase extends TransitionOptions {\n /**\n * @internal Set by `show()` / `scope()` sugar when delegating to\n * `branch()`, so the dev-only disposer log can report `'show-hide'` /\n * `'scope-rebuild'` instead of the default `'branch-swap'` for the\n * leaving arm. User code should not set this directly.\n */\n __disposalCause?: DisposerEvent['cause']\n /** @internal Compiler-injected mask of paths read by `on`. */\n __mask?: number\n}\n\n/**\n * Discriminant accessor — reads a string-keyed value either from the\n * current state (`(s) => …`) or from a closed-over item accessor /\n * memo (`() => item.kind()`). Both forms re-evaluate on every commit.\n * The zero-arg form is the canonical shape for branching on per-row\n * fields inside an `each.render` callback.\n */\ntype Discriminant<S, K extends string> = ((s: S) => K) | (() => K)\n\n/**\n * All cases covered by `cases` — no default allowed (would be dead code).\n */\ntype BranchOptionsExhaustive<S, M, K extends string> = BranchOptionsBase & {\n on: Discriminant<S, K>\n cases: { [P in K]: (h: View<S, M>) => Node[] }\n default?: never\n}\n\n/**\n * `cases` may cover some but not all keys; `default` handles the rest.\n */\ntype BranchOptionsNonExhaustive<S, M, K extends string> = BranchOptionsBase & {\n on: Discriminant<S, K>\n cases?: { [P in K]?: (h: View<S, M>) => Node[] }\n default: (h: View<S, M>) => Node[]\n}\n\n/**\n * `on` returns a wide `string` — exhaustiveness cannot be verified at\n * compile time (the key domain is infinite). Lenient: `default` is\n * optional so existing call sites that predate exhaustiveness typing\n * continue to compile. Authors who want the gate opt in by narrowing\n * `on`'s return type to a literal union.\n */\ntype BranchOptionsWide<S, M> = BranchOptionsBase & {\n on: Discriminant<S, string>\n cases?: Record<string, (h: View<S, M>) => Node[]>\n default?: (h: View<S, M>) => Node[]\n}\n\n/**\n * Options for `branch()`.\n *\n * When `on` returns a literal string union (e.g. `'idle' | 'loading'\n * | 'done'`), TypeScript enforces exhaustiveness: either every union\n * member has a case (and `default` is disallowed as unreachable), or\n * `default` is required to cover the remainder. When `on` returns a\n * wide `string`, `default` stays optional — exhaustiveness isn't\n * meaningful for an unbounded domain.\n *\n * `cases` is optional when `default` is present; `branch({ on, default })`\n * is the canonical dynamic-rebuild shape — `scope()` sugar wraps\n * exactly this form.\n */\nexport type BranchOptions<S, M = unknown, K extends string = string> = string extends K\n ? BranchOptionsWide<S, M>\n : BranchOptionsExhaustive<S, M, K> | BranchOptionsNonExhaustive<S, M, K>\n\nexport interface ShowOptions<S, M = unknown> extends TransitionOptions {\n /**\n * Predicate evaluated on every commit. `(s) => …` reads from\n * component state; `() => …` (zero-arg) reads from a closed-over\n * source — typically `item.field()` inside an `each.render`\n * callback. Both forms are reactive: the predicate runs against\n * each new state and the rendered subtree mounts/unmounts on the\n * boolean transition.\n */\n when: ((s: S) => boolean) | (() => boolean)\n render: (h: View<S, M>) => Node[]\n fallback?: (h: View<S, M>) => Node[]\n}\n\n/**\n * Options for `scope()` — rebuilds a subtree when `on(state)` changes.\n *\n * Sugar over `branch({ on, cases: {}, default: render, __disposalCause: 'scope-rebuild' })`.\n * Use when the key is dynamic (e.g. an epoch counter bumped from the\n * outside) and you want a fresh arm — fresh lifetime, fresh bindings —\n * each time it changes. Combine with `sample()` inside `render` for a\n * one-shot current-state read.\n */\nexport interface ScopeOptions<S, M = unknown> extends TransitionOptions {\n /**\n * Key accessor evaluated on every commit. `(s) => …` reads from\n * component state; `() => …` (zero-arg) reads from a closed-over\n * source. The render callback rebuilds whenever the returned key\n * changes — fresh lifetime, fresh bindings.\n */\n on: ((s: S) => string) | (() => string)\n render: (h: View<S, M>) => Node[]\n /** @internal Compiler-injected mask of paths read by `on`. */\n __mask?: number\n}\n\n/**\n * Options for `each()`. The inherited `enter` / `leave` callbacks fire **per item**:\n * `enter(nodes)` runs after an item's DOM is inserted (including initial mount);\n * `leave(nodes)` runs before an item's DOM is removed and may return a Promise\n * to hold the DOM until the animation resolves. Setting `leave` disables the\n * bulk-clear / full-replace fast paths.\n */\n/**\n * Per-item accessor. Two access forms:\n * - `item.field` — shorthand, returns accessor for `item.current[field]`\n * - `item(t => t.expr)` — computed expressions\n *\n * In both cases the returned value is a `() => V` accessor.\n * Invoke it (`item.field()`) to read the current value imperatively.\n */\nexport type ItemAccessor<T> = {\n <R>(selector: (t: T) => R): () => R\n} & {\n [K in keyof T]-?: () => T[K]\n} & {\n /**\n * Read the whole current item. Needed when T is a primitive (where the\n * field-map branch collapses to method names like `toString`) or when\n * you want to sample the entire record rather than a single field.\n *\n * Shadows any literal `current` field on T — if T has such a field,\n * use `item(r => r.current)` to disambiguate.\n */\n current(): T\n}\n\nexport interface EachOptions<S, T, M = unknown> extends TransitionOptions {\n items: (s: S) => T[]\n key: (item: T) => string | number\n render: (opts: {\n send: Send<M>\n item: ItemAccessor<T>\n /**\n * Plain (non-Proxy) accessor factory. Compiler-output path; avoid in user code\n * (use `item.field` / `item(fn)` — more ergonomic and bypasses Proxy when compiled).\n */\n acc: <R>(selector: (t: T) => R) => () => R\n index: () => number\n /**\n * The component's View bag (`h.text`, `h.show`, `h.branch`,\n * `h.scope`, `h.sample`, …). Each-render callers used to reach\n * for the top-level imports; the bag form is symmetric with how\n * `branch.cases[k]`, `show.render`, and `scope.render` receive it.\n * Both still work — destructure whichever is more convenient.\n */\n h: View<S, M>\n /** @internal Compiler-injected — entry reference for row factory */\n entry?: Record<string, unknown>\n }) => Node[]\n}\n\nexport interface PortalOptions {\n target: HTMLElement | string\n render: () => Node[]\n}\n\nexport interface ForeignOptions<S, M, T extends Record<string, unknown>, Instance> {\n /**\n * Construct the imperative instance. Can be async — return a\n * `Promise<Instance>` to defer construction until e.g. a dynamic\n * `import()` resolves. While the promise is pending:\n *\n * - The container element is in the DOM immediately (so layout\n * doesn't shift when the instance arrives).\n * - `sync` is NOT called. State changes are tracked by the\n * primitive and the latest props are applied as the initial\n * sync right after the promise resolves.\n * - If the owning scope disposes before the promise resolves,\n * `destroy(instance)` runs on resolution — no matter how long\n * the promise takes.\n */\n mount: (ctx: { container: HTMLElement; send: Send<M> }) => Instance | Promise<Instance>\n props: (s: S) => T\n sync:\n | ((ctx: { instance: Instance; props: T; prev: T | undefined }) => void)\n | {\n [K in keyof T]?: (ctx: { instance: Instance; value: T[K]; prev: T[K] | undefined }) => void\n }\n destroy: (instance: Instance) => void\n container?: { tag?: string; attrs?: Record<string, string> }\n}\n\nexport interface ChildOptions<S, ChildM> {\n // Type-erased via AnyComponentDef so callers can pass any concrete\n // ComponentDef<S, M, E, D> without a widening helper. The runtime\n // narrows the message shape via the user-supplied `onMsg` callback,\n // which keeps `ChildM` typed at this boundary even though the def\n // itself is opaque.\n def: AnyComponentDef\n key: string | number\n props: (s: S) => Record<string, unknown>\n onMsg?: (msg: ChildM) => unknown | null\n}\n"]}
|
package/dist/update-loop.d.ts
CHANGED
|
@@ -44,5 +44,10 @@ export declare function _handleMsg(inst: ComponentInstance, msg: unknown, dirty:
|
|
|
44
44
|
* Shared between genericUpdate and compiler-generated __update.
|
|
45
45
|
* @public — used by compiler-generated `__update` functions
|
|
46
46
|
*/
|
|
47
|
-
export declare function _runPhase2(state: unknown, dirty: number, bindings: Binding[], bindingsBeforePhase1: number, componentName?: string
|
|
47
|
+
export declare function _runPhase2(state: unknown, dirty: number, bindings: Binding[], bindingsBeforePhase1: number, componentName?: string, onBindingError?: (info: {
|
|
48
|
+
kind: string;
|
|
49
|
+
key?: string;
|
|
50
|
+
message: string;
|
|
51
|
+
stack?: string;
|
|
52
|
+
}) => void): void;
|
|
48
53
|
//# sourceMappingURL=update-loop.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-loop.d.ts","sourceRoot":"","sources":["../src/update-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAItD,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,cAAc,CAAA;AAmBtD,eAAO,MAAM,SAAS,QAAiB,CAAA;AAMvC,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,CAAC,GAAG,EAAE;IAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,IAAI,GAClE,IAAI,CAEN;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACtE,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,CAAC,CAAA;IACR,cAAc,EAAE,CAAC,EAAE,CAAA;IACnB,YAAY,EAAE,QAAQ,CAAA;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,OAAO,EAAE,CAAA;IACtB,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,kBAAkB,EAAE,OAAO,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,CAAC,EAAE,CAAA;IAChB,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,eAAe,EAAE,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"update-loop.d.ts","sourceRoot":"","sources":["../src/update-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAItD,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,cAAc,CAAA;AAmBtD,eAAO,MAAM,SAAS,QAAiB,CAAA;AAMvC,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,CAAC,GAAG,EAAE;IAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,IAAI,GAClE,IAAI,CAEN;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACtE,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,CAAC,CAAA;IACR,cAAc,EAAE,CAAC,EAAE,CAAA;IACnB,YAAY,EAAE,QAAQ,CAAA;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,OAAO,EAAE,CAAA;IACtB,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,kBAAkB,EAAE,OAAO,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,CAAC,EAAE,CAAA;IAChB,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,eAAe,EAAE,eAAe,CAAA;CAkEjC;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EACvD,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC7B,IAAI,CAAC,EAAE,CAAC,EACR,cAAc,GAAE,QAAQ,GAAG,IAAW,EACtC,GAAG,CAAC,EAAE,MAAM,GACX,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAgD5B;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAI7E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CA4DxF;AAiJD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,iBAAiB,EACvB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAqCtB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EAAE,EACnB,oBAAoB,EAAE,MAAM,EAC5B,aAAa,CAAC,EAAE,MAAM,EAMtB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,GAC/F,IAAI,CAkDN"}
|
package/dist/update-loop.js
CHANGED
|
@@ -98,14 +98,64 @@ export function _forceState(inst, newState) {
|
|
|
98
98
|
if (binding.dead)
|
|
99
99
|
continue;
|
|
100
100
|
if (binding.kind === 'effect') {
|
|
101
|
-
|
|
101
|
+
try {
|
|
102
|
+
binding.accessor(state);
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
reportBindingError(inst, binding, e);
|
|
106
|
+
}
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
let newValue;
|
|
110
|
+
try {
|
|
111
|
+
newValue = binding.accessor(state);
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
// Accessor threw — leave the binding's `lastValue` unchanged so
|
|
115
|
+
// the rendered DOM stays at its previous value rather than going
|
|
116
|
+
// blank. Sibling bindings on the same commit continue to
|
|
117
|
+
// evaluate. The error surfaces via the optional hook (or
|
|
118
|
+
// console.warn as a fallback) so it isn't silently swallowed.
|
|
119
|
+
reportBindingError(inst, binding, e);
|
|
102
120
|
continue;
|
|
103
121
|
}
|
|
104
|
-
const newValue = binding.accessor(state);
|
|
105
122
|
if (Object.is(newValue, binding.lastValue))
|
|
106
123
|
continue;
|
|
107
124
|
binding.lastValue = newValue;
|
|
108
|
-
|
|
125
|
+
try {
|
|
126
|
+
applyBinding(binding, newValue);
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
// applyBinding writes the value to the DOM (textContent,
|
|
130
|
+
// setAttribute, etc.). Throws here are usually environmental
|
|
131
|
+
// (a node was removed mid-flight by a sibling binding). Same
|
|
132
|
+
// contract: report and continue.
|
|
133
|
+
reportBindingError(inst, binding, e);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function reportBindingError(inst, binding, e) {
|
|
138
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
139
|
+
const stack = err.stack ? err.stack.split('\n').slice(0, 8).join('\n') : undefined;
|
|
140
|
+
const info = stack !== undefined
|
|
141
|
+
? {
|
|
142
|
+
kind: String(binding.kind),
|
|
143
|
+
key: binding.key,
|
|
144
|
+
message: `${err.name}: ${err.message}`,
|
|
145
|
+
stack,
|
|
146
|
+
}
|
|
147
|
+
: { kind: String(binding.kind), key: binding.key, message: `${err.name}: ${err.message}` };
|
|
148
|
+
if (inst._onBindingError !== undefined) {
|
|
149
|
+
try {
|
|
150
|
+
inst._onBindingError(info);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// The hook itself threw — nothing to do; we're in a recovery
|
|
154
|
+
// path already. Fall through to the console fallback.
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (typeof console !== 'undefined' && typeof console.warn === 'function') {
|
|
158
|
+
console.warn(`[llui] binding accessor threw (kind=${info.kind}${info.key ? `, key=${info.key}` : ''}): ${info.message}`);
|
|
109
159
|
}
|
|
110
160
|
}
|
|
111
161
|
function processMessages(inst) {
|
|
@@ -197,7 +247,7 @@ function genericUpdate(inst, state, combinedDirty, bindings, bindingsBeforePhase
|
|
|
197
247
|
block.reconcile(state, combinedDirty);
|
|
198
248
|
}
|
|
199
249
|
// Phase 2 — compact + update bindings
|
|
200
|
-
_runPhase2(state, combinedDirty, bindings, bindingsBeforePhase1, inst.def.name);
|
|
250
|
+
_runPhase2(state, combinedDirty, bindings, bindingsBeforePhase1, inst.def.name, inst._onBindingError);
|
|
201
251
|
}
|
|
202
252
|
/**
|
|
203
253
|
* Run a handler for a single message: call update(), reconcile blocks
|
|
@@ -239,7 +289,7 @@ export function _handleMsg(inst, msg, dirty, method) {
|
|
|
239
289
|
}
|
|
240
290
|
}
|
|
241
291
|
const b = inst.allBindings;
|
|
242
|
-
_runPhase2(s, dirty, b, b.length);
|
|
292
|
+
_runPhase2(s, dirty, b, b.length, inst.def.name, inst._onBindingError);
|
|
243
293
|
return [s, e];
|
|
244
294
|
}
|
|
245
295
|
/**
|
|
@@ -247,7 +297,13 @@ export function _handleMsg(inst, msg, dirty, method) {
|
|
|
247
297
|
* Shared between genericUpdate and compiler-generated __update.
|
|
248
298
|
* @public — used by compiler-generated `__update` functions
|
|
249
299
|
*/
|
|
250
|
-
export function _runPhase2(state, dirty, bindings, bindingsBeforePhase1, componentName
|
|
300
|
+
export function _runPhase2(state, dirty, bindings, bindingsBeforePhase1, componentName,
|
|
301
|
+
// Optional `_onBindingError` hook. Type is duplicated here rather
|
|
302
|
+
// than referenced as `ComponentInstance['_onBindingError']` because
|
|
303
|
+
// the underlying field is `@internal` — stripped from the generated
|
|
304
|
+
// `.d.ts` — and a public-export signature can't depend on a stripped
|
|
305
|
+
// type without breaking dependent packages' typecheck.
|
|
306
|
+
onBindingError) {
|
|
251
307
|
let phase2Len = bindingsBeforePhase1;
|
|
252
308
|
if (bindings.length > bindingsBeforePhase1 || (phase2Len > 0 && bindings[0].dead)) {
|
|
253
309
|
let w = 0;
|
|
@@ -259,54 +315,81 @@ export function _runPhase2(state, dirty, bindings, bindingsBeforePhase1, compone
|
|
|
259
315
|
phase2Len = Math.min(w, bindingsBeforePhase1);
|
|
260
316
|
}
|
|
261
317
|
if (dirty !== 0) {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
let newValue;
|
|
318
|
+
// Always catch+continue: a single accessor throw shouldn't abort
|
|
319
|
+
// the rest of the bindings on the same commit. The user-visible
|
|
320
|
+
// effect: a broken cell shows its previous value; sibling cells
|
|
321
|
+
// stay current. In dev mode, the wrapped error (with component
|
|
322
|
+
// name, kind, node descriptor, accessor source) is forwarded via
|
|
323
|
+
// the `_onBindingError` hook (agent integration) or to
|
|
324
|
+
// `console.error` (dev harness without an agent). The prior
|
|
325
|
+
// behavior of rethrowing from `flush()` made one bad binding
|
|
326
|
+
// visually break the entire view — the worst-case UX.
|
|
327
|
+
const isDev = import.meta.env?.DEV && componentName;
|
|
328
|
+
for (let i = 0, len = phase2Len; i < len; i++) {
|
|
329
|
+
const binding = bindings[i];
|
|
330
|
+
if (binding.dead || (binding.mask & dirty) === 0)
|
|
331
|
+
continue;
|
|
332
|
+
if (binding.kind === 'effect') {
|
|
281
333
|
try {
|
|
282
|
-
|
|
334
|
+
binding.accessor(state);
|
|
283
335
|
}
|
|
284
336
|
catch (e) {
|
|
285
|
-
|
|
337
|
+
handleBindingThrow(onBindingError, binding, e, isDev ? componentName : null);
|
|
286
338
|
}
|
|
287
|
-
|
|
288
|
-
if (newValue === last || (newValue !== newValue && last !== last))
|
|
289
|
-
continue;
|
|
290
|
-
binding.lastValue = newValue;
|
|
291
|
-
applyBinding(binding, newValue);
|
|
339
|
+
continue;
|
|
292
340
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
continue;
|
|
307
|
-
binding.lastValue = newValue;
|
|
341
|
+
let newValue;
|
|
342
|
+
try {
|
|
343
|
+
newValue = binding.accessor(state);
|
|
344
|
+
}
|
|
345
|
+
catch (e) {
|
|
346
|
+
handleBindingThrow(onBindingError, binding, e, isDev ? componentName : null);
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const last = binding.lastValue;
|
|
350
|
+
if (newValue === last || (newValue !== newValue && last !== last))
|
|
351
|
+
continue;
|
|
352
|
+
binding.lastValue = newValue;
|
|
353
|
+
try {
|
|
308
354
|
applyBinding(binding, newValue);
|
|
309
355
|
}
|
|
356
|
+
catch (e) {
|
|
357
|
+
handleBindingThrow(onBindingError, binding, e, isDev ? componentName : null);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function handleBindingThrow(onBindingError, binding, e, componentName) {
|
|
363
|
+
// Dev mode: build the rich wrapped error (with accessor source,
|
|
364
|
+
// node descriptor, undefined-hint detection). Prod skips the
|
|
365
|
+
// bookkeeping. Either way the report flows through `_onBindingError`
|
|
366
|
+
// when wired (agent setups), else falls back to console.error so
|
|
367
|
+
// operators see the cause.
|
|
368
|
+
const wrapped = componentName !== null && e instanceof Error
|
|
369
|
+
? enhanceBindingError(e, binding, componentName)
|
|
370
|
+
: null;
|
|
371
|
+
const err = wrapped ?? (e instanceof Error ? e : new Error(String(e)));
|
|
372
|
+
const stack = err.stack ? err.stack.split('\n').slice(0, 8).join('\n') : undefined;
|
|
373
|
+
const info = stack !== undefined
|
|
374
|
+
? { kind: String(binding.kind), key: binding.key, message: err.message, stack }
|
|
375
|
+
: { kind: String(binding.kind), key: binding.key, message: err.message };
|
|
376
|
+
if (onBindingError !== undefined) {
|
|
377
|
+
try {
|
|
378
|
+
onBindingError(info);
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
// hook itself threw; fall through to console
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
else if (typeof console !== 'undefined') {
|
|
385
|
+
// Dev mode shows the wrapped (richer) message. Prod shows a brief
|
|
386
|
+
// line — operators still see something but without the full source
|
|
387
|
+
// hint that's only useful at development time.
|
|
388
|
+
if (componentName !== null) {
|
|
389
|
+
console.error(err);
|
|
390
|
+
}
|
|
391
|
+
else if (typeof console.warn === 'function') {
|
|
392
|
+
console.warn(`[llui] binding accessor threw (kind=${info.kind}${info.key ? `, key=${info.key}` : ''}): ${info.message}`);
|
|
310
393
|
}
|
|
311
394
|
}
|
|
312
395
|
}
|
package/dist/update-loop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-loop.js","sourceRoot":"","sources":["../src/update-loop.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, Lifetime, Binding } from './types.js'\nimport type { StructuralBlock } from './structural.js'\nimport type { RingBuffer, EachDiff } from './tracking/each-diff.js'\nimport type { DisposerEvent } from './tracking/disposer-log.js'\nimport type { CoverageTracker } from './tracking/coverage.js'\nimport { type DomEnv, browserEnv } from './dom-env.js'\n\n// Single lazily-constructed browser env shared by every client-side\n// component instance. Falls through to globalThis at call time — safe\n// to construct on a server process (the lookups never fire there).\nlet _fallbackEnv: DomEnv | null = null\nfunction fallbackBrowserEnv(): DomEnv {\n if (_fallbackEnv === null) _fallbackEnv = browserEnv()\n return _fallbackEnv\n}\nimport type {\n EffectTimelineEntry,\n PendingEffectsList,\n MockRegistry,\n} from './tracking/effect-timeline.js'\nimport { createLifetime } from './lifetime.js'\nimport { applyBinding } from './binding.js'\nimport { setCurrentDirtyMask } from './primitives/memo.js'\n\nexport const FULL_MASK = 0xffffffff | 0\n\n// Addressed effect dispatcher — set by addressed.ts when imported\nlet addressedDispatcher: ((eff: { __targetKey: string | number; __msg: unknown }) => void) | null =\n null\n\nexport function setAddressedDispatcher(\n fn: (eff: { __targetKey: string | number; __msg: unknown }) => void,\n): void {\n addressedDispatcher = fn\n}\n\nexport interface ComponentInstance<S = unknown, M = unknown, E = unknown> {\n def: ComponentDef<S, M, E>\n state: S\n initialEffects: E[]\n rootLifetime: Lifetime\n dom: DomEnv\n allBindings: Binding[]\n structuralBlocks: StructuralBlock[]\n queue: M[]\n microtaskScheduled: boolean\n lastDirtyMask: number\n lastEffects: E[]\n send: (msg: M) => void\n signal: AbortSignal\n abortController: AbortController\n /** @internal dev-only — populated when `installDevTools` ran. Ring-buffered\n * per-each-site reconciliation diffs for MCP introspection tools. */\n _eachDiffLog?: RingBuffer<EachDiff>\n /** @internal dev-only — monotonically incremented by the devtools-intercepted\n * `update` before each history push. Read by `each.ts` to stamp diffs with\n * the `updateIndex` of the message that caused the reconciliation. */\n _updateCounter?: number\n /** @internal dev-only — populated when `installDevTools` ran. Ring-buffered\n * log of `disposeLifetime` firings (scope id + cause). Consumed by the\n * `llui_disposer_log` MCP tool to diagnose leaks on structural transitions. */\n _disposerLog?: RingBuffer<DisposerEvent>\n /** @internal dev-only — populated when `installDevTools` ran. Per-variant\n * Msg counter keyed by discriminant. Consumed by the `llui_coverage` MCP\n * tool to surface Msg variants that have never fired this session. */\n _coverage?: CoverageTracker\n /** @internal dev-only — populated when `installDevTools` ran. Ring-buffered\n * effect dispatch phase log (dispatched → resolved/cancelled) for USER\n * effects emitted from `update()`. Consumed by the `llui_effect_timeline`\n * MCP tool. Built-in plumbing effects (`delay`, `log`, addressed) are NOT\n * recorded here by design — they short-circuit in `dispatchEffect` before\n * `dispatchEffectDev` runs. They're runtime plumbing, not user intent,\n * and surface via other channels (message queue for `delay`, browser\n * console for `log`, addressed-target routing for addressed effects). */\n _effectTimeline?: RingBuffer<EffectTimelineEntry>\n /** @internal dev-only — populated when `installDevTools` ran. List of\n * currently-pending effects addressable by id, consumed by the\n * `llui_pending_effects` MCP tool. */\n _pendingEffects?: PendingEffectsList\n /** @internal dev-only — populated when `installDevTools` ran. Mock\n * registry consulted by the effect-dispatch wrapper to short-circuit\n * matching effects. Consumed by the `llui_mock_effect` MCP tool. */\n _effectMocks?: MockRegistry\n /**\n * @internal — set by mountApp/mountAtAnchor/hydrateApp/hydrateAtAnchor\n * to fire AppHandle.subscribe listeners after every update cycle.\n * Undefined until the first subscriber registers.\n */\n _onCommit?: (state: unknown) => void\n /**\n * @internal — live registry of currently-mounted Msg variants\n * dispatchable from rendered UI. Lazily allocated when the first\n * compiler-tagged event handler binds. Read by the agent layer (via\n * `AppHandle.getBindingDescriptors()`) to surface live affordances\n * to the LLM. See `binding-descriptors.ts` for the registration\n * protocol and `@llui/vite-plugin`'s tagger pass for the tag emission.\n */\n _bindingDescriptors?: import('./binding-descriptors.js').BindingDescriptorRegistry\n}\n\nexport function createComponentInstance<S, M, E, D = void>(\n def: ComponentDef<S, M, E, D>,\n data?: D,\n parentLifetime: Lifetime | null = null,\n dom?: DomEnv,\n): ComponentInstance<S, M, E> {\n const [initialState, initialEffects] = def.init(data as D)\n\n const controller = new AbortController()\n\n const inst: ComponentInstance<S, M, E> = {\n // `def` carries an arbitrary `D` for typed init data, but after init\n // has run the runtime never touches `def.init` again — update/view/\n // onEffect and HMR replacement don't depend on D. Cast to the\n // D=void instance storage shape here.\n def: def as ComponentDef<S, M, E>,\n state: initialState,\n initialEffects,\n // Caller-supplied DOM env. `mountApp` defaults this to `browserEnv()`;\n // `renderToString` passes the user's jsdom/linkedom env. Never null —\n // every primitive reads from inst.dom.\n dom: dom ?? fallbackBrowserEnv(),\n // When `parentLifetime` is provided the instance's rootLifetime becomes a\n // child of that scope. This is how persistent layouts wire pages\n // into the layout's scope tree: the page's rootLifetime is parented at\n // the layout's pageSlot() point so `useContext` lookups flow layout\n // → page, and scope disposal cascades correctly. Mount paths that\n // don't pass parentLifetime get the classic detached root.\n rootLifetime: createLifetime(parentLifetime),\n allBindings: [],\n structuralBlocks: [],\n queue: [],\n microtaskScheduled: false,\n lastDirtyMask: 0,\n lastEffects: [],\n signal: controller.signal,\n abortController: controller,\n\n send(msg: M) {\n inst.queue.push(msg)\n if (!inst.microtaskScheduled) {\n inst.microtaskScheduled = true\n queueMicrotask(() => {\n inst.microtaskScheduled = false\n processMessages(inst)\n })\n }\n },\n }\n\n inst.rootLifetime._kind = 'root'\n\n return inst\n}\n\nexport function flushInstance<S, M, E>(inst: ComponentInstance<S, M, E>): void {\n if (inst.queue.length === 0) return\n inst.microtaskScheduled = false\n processMessages(inst)\n}\n\n/**\n * Dev-only: overwrite instance state and re-run both phases with FULL_MASK\n * so every binding re-evaluates. Bypasses update() — use for devtools\n * snapshot/restore, not in app code.\n */\nexport function _forceState<S, M, E>(inst: ComponentInstance<S, M, E>, newState: S): void {\n inst.state = newState\n inst.lastDirtyMask = FULL_MASK\n\n const bindings = inst.allBindings\n const bindingsBeforePhase1 = bindings.length\n\n setCurrentDirtyMask(FULL_MASK)\n\n const snapshot = inst.structuralBlocks.slice()\n for (const block of snapshot) {\n block.reconcile(newState, FULL_MASK)\n }\n\n let phase2Len = bindingsBeforePhase1\n if (bindings.length > bindingsBeforePhase1 || (phase2Len > 0 && bindings[0]!.dead)) {\n let w = 0\n for (let r = 0; r < bindings.length; r++) {\n if (!bindings[r]!.dead) bindings[w++] = bindings[r]!\n }\n bindings.length = w\n phase2Len = Math.min(w, bindingsBeforePhase1)\n }\n\n const state = inst.state\n for (let i = 0, len = phase2Len; i < len; i++) {\n const binding = bindings[i]!\n if (binding.dead) continue\n if (binding.kind === 'effect') {\n binding.accessor(state)\n continue\n }\n const newValue = binding.accessor(state)\n if (Object.is(newValue, binding.lastValue)) continue\n binding.lastValue = newValue\n applyBinding(binding, newValue)\n }\n}\n\nfunction processMessages<S, M, E>(inst: ComponentInstance<S, M, E>): void {\n const queue = inst.queue\n\n // Single-message fast path: dispatch directly to per-message-type handler\n // if available. Skips dirty computation, Phase 1/2 entirely.\n if (queue.length === 1 && inst.def.__handlers) {\n const msg = queue[0]!\n const handler = inst.def.__handlers[(msg as Record<string, unknown>).type as string] as\n | ((inst: ComponentInstance, msg: unknown) => [S, E[]])\n | undefined\n if (handler) {\n queue.length = 0\n const [newState, effects] = handler(inst as ComponentInstance, msg)\n inst.state = newState\n inst._onCommit?.(newState as unknown)\n if (import.meta.env?.DEV) {\n inst.lastDirtyMask = FULL_MASK\n inst.lastEffects = effects\n }\n for (let i = 0; i < effects.length; i++) {\n dispatchEffect(inst, effects[i]!)\n }\n return\n }\n }\n\n // Generic pipeline — drain queue, accumulate dirty bits\n let state = inst.state\n let combinedDirty = 0\n const allEffects: E[] = []\n\n const defUpdate = inst.def.update\n const dirtyFn = inst.def.__dirty\n for (let qi = 0; qi < queue.length; qi++) {\n const msg = queue[qi]!\n const [newState, effects] = defUpdate(state, msg)\n const dirty = dirtyFn ? dirtyFn(state, newState) : FULL_MASK\n if (typeof dirty === 'number') {\n combinedDirty |= dirty\n } else {\n combinedDirty |= dirty[0] | dirty[1]\n }\n state = newState\n // Avoid spread — allocates an iterator per call. For typical effect\n // arrays (0-2 elements) this is a minor saving; for bursts it matters.\n for (let ei = 0; ei < effects.length; ei++) allEffects.push(effects[ei]!)\n }\n queue.length = 0\n\n inst.state = state\n inst._onCommit?.(state as unknown)\n // Dev-only bookkeeping — tests read lastDirtyMask/lastEffects, prod\n // doesn't. Gating here keeps two writes out of the prod hot path.\n if (import.meta.env?.DEV) {\n inst.lastDirtyMask = combinedDirty\n inst.lastEffects = allEffects\n }\n\n // Snapshot binding count before Phase 1 — bindings added during\n // Phase 1 already have correct initial values and skip Phase 2.\n const bindings = inst.allBindings\n const bindingsBeforePhase1 = bindings.length\n\n // Set current dirty mask BEFORE Phase 1 so memo() accessors used in\n // structural primitives (e.g. each.items) can use the bitmask fast path.\n setCurrentDirtyMask(combinedDirty)\n\n if (inst.def.__update) {\n // Compiler-generated fast path — replaces generic Phase 1 + Phase 2\n inst.def.__update(state, combinedDirty, bindings, inst.structuralBlocks, bindingsBeforePhase1)\n } else {\n // Generic Phase 1 + Phase 2 fallback (uncompiled components)\n genericUpdate(inst, state, combinedDirty, bindings, bindingsBeforePhase1)\n }\n\n // Dispatch effects after DOM updates\n for (let i = 0; i < allEffects.length; i++) {\n dispatchEffect(inst, allEffects[i]!)\n }\n}\n\nfunction genericUpdate<S, M, E>(\n inst: ComponentInstance<S, M, E>,\n state: S,\n combinedDirty: number,\n bindings: Binding[],\n bindingsBeforePhase1: number,\n): void {\n // Phase 1 — structural reconciliation. Structural primitives register\n // their blocks BEFORE running builders, so parents precede their nested\n // children in this array. That ordering matters: a parent's reconcile\n // may dispose the old arm, whose disposers splice nested child blocks\n // out of this shared array. Because children are always to the right\n // of their parent, the splice shifts entries left — which is safe for\n // a forward iterator that re-reads length each step.\n const blocks = inst.structuralBlocks\n for (let bi = 0; bi < blocks.length; bi++) {\n const block = blocks[bi]\n if (!block || (block.mask & combinedDirty) === 0) continue\n block.reconcile(state, combinedDirty)\n }\n\n // Phase 2 — compact + update bindings\n _runPhase2(state, combinedDirty, bindings, bindingsBeforePhase1, inst.def.name)\n}\n\n/**\n * Run a handler for a single message: call update(), reconcile blocks\n * with the given method, run Phase 2. Used by compiler-generated __handlers\n * to avoid duplicating boilerplate per message type.\n *\n * @param method 0=reconcile, 1=reconcileItems, 2=reconcileClear, 3=reconcileRemove, -1=skip blocks\n * @public — used by compiler-generated `__handlers`\n */\nexport function _handleMsg(\n inst: ComponentInstance,\n msg: unknown,\n dirty: number,\n method: number,\n): [unknown, unknown[]] {\n const [s, e] = (inst.def.update as (s: unknown, m: unknown) => [unknown, unknown[]])(\n inst.state,\n msg,\n )\n inst.state = s\n inst._onCommit?.(s)\n\n if (method >= 0) {\n const bl = inst.structuralBlocks\n for (let i = 0; i < bl.length; i++) {\n const block = bl[i]\n if (!block || !(block.mask & dirty)) continue\n switch (method) {\n case 0:\n block.reconcile(s, dirty)\n break\n case 1:\n block.reconcileItems?.(s)\n break\n case 2:\n block.reconcileClear?.()\n break\n case 3:\n block.reconcileRemove?.(s)\n break\n default:\n // method >= 10: reconcileChanged with stride = method - 10\n if (method >= 10) block.reconcileChanged?.(s, method - 10)\n break\n }\n }\n }\n\n const b = inst.allBindings\n _runPhase2(s, dirty, b, b.length)\n return [s, e]\n}\n\n/**\n * Phase 2: compact dead bindings + update live bindings.\n * Shared between genericUpdate and compiler-generated __update.\n * @public — used by compiler-generated `__update` functions\n */\nexport function _runPhase2(\n state: unknown,\n dirty: number,\n bindings: Binding[],\n bindingsBeforePhase1: number,\n componentName?: string,\n): void {\n let phase2Len = bindingsBeforePhase1\n if (bindings.length > bindingsBeforePhase1 || (phase2Len > 0 && bindings[0]!.dead)) {\n let w = 0\n for (let r = 0; r < bindings.length; r++) {\n if (!bindings[r]!.dead) bindings[w++] = bindings[r]!\n }\n bindings.length = w\n phase2Len = Math.min(w, bindingsBeforePhase1)\n }\n\n if (dirty !== 0) {\n if (import.meta.env?.DEV && componentName) {\n for (let i = 0, len = phase2Len; i < len; i++) {\n const binding = bindings[i]!\n if (binding.dead || (binding.mask & dirty) === 0) continue\n if (binding.kind === 'effect') {\n // Side-effect-only: run accessor, discard return, skip the\n // Object.is diff and `applyBinding` entirely. Used by child()'s\n // prop-watch binding so fresh-object props accessors don't\n // stringify onto a detached anchor every update.\n try {\n binding.accessor(state)\n } catch (e) {\n throw enhanceBindingError(e, binding, componentName)\n }\n continue\n }\n let newValue: unknown\n try {\n newValue = binding.accessor(state)\n } catch (e) {\n throw enhanceBindingError(e, binding, componentName)\n }\n const last = binding.lastValue\n if (newValue === last || (newValue !== newValue && last !== last)) continue\n binding.lastValue = newValue\n applyBinding(binding, newValue)\n }\n } else {\n for (let i = 0, len = phase2Len; i < len; i++) {\n const binding = bindings[i]!\n if (binding.dead || (binding.mask & dirty) === 0) continue\n if (binding.kind === 'effect') {\n binding.accessor(state)\n continue\n }\n const newValue = binding.accessor(state)\n const last = binding.lastValue\n if (newValue === last || (newValue !== newValue && last !== last)) continue\n binding.lastValue = newValue\n applyBinding(binding, newValue)\n }\n }\n }\n}\n\nfunction enhanceBindingError(err: unknown, binding: Binding, componentName: string): Error {\n // For text bindings, binding.node is the Text node — use its parent element.\n const node = binding.node\n const target = node.nodeType === 1 ? (node as Element) : (node.parentElement ?? null)\n let nodeDesc = '?'\n if (target) {\n const id = target.id ? `#${target.id}` : ''\n const cls =\n target.className && typeof target.className === 'string'\n ? `.${target.className.split(' ').filter(Boolean).slice(0, 2).join('.')}`\n : ''\n nodeDesc = `<${target.tagName.toLowerCase()}${id}${cls}>`\n if (node.nodeType === 3) nodeDesc += ' text-child'\n else if (node.nodeType === 8) nodeDesc += ' comment-child'\n }\n const keyPart = binding.key ? ` .${binding.key}` : ''\n const errMsg = err instanceof Error ? err.message : String(err)\n\n // Build accessor source hint if available\n let accessorHint = ''\n try {\n const src = binding.accessor.toString().slice(0, 80)\n accessorHint = `\\n accessor: ${src}${binding.accessor.toString().length > 80 ? '...' : ''}`\n } catch {\n // toString() may throw on revoked proxies, etc.\n }\n\n // Detect common undefined/null access pattern and add a helpful hint\n let undefinedHint = ''\n if (err instanceof TypeError && /Cannot read propert(ies|y).*of (undefined|null)/.test(errMsg)) {\n undefinedHint =\n '\\n hint: Check that your accessor handles undefined state fields (e.g., use optional chaining: s.user?.name)'\n }\n\n const wrapped = new Error(\n `[LLui] ${binding.kind}${keyPart} binding on ${nodeDesc} — accessor threw in <${componentName}>\\n` +\n ` ↳ ${errMsg}` +\n undefinedHint +\n accessorHint,\n err instanceof Error ? { cause: err } : undefined,\n )\n wrapped.stack = (err instanceof Error && err.stack) || wrapped.stack\n return wrapped\n}\n\nfunction dispatchEffect<S, M, E>(inst: ComponentInstance<S, M, E>, effect: E): void {\n const eff = effect as Record<string, unknown>\n\n // Addressed effects — dispatch to target component\n if (eff.__addressed === true && typeof eff.__targetKey !== 'undefined') {\n addressedDispatcher?.(eff as { __targetKey: string | number; __msg: unknown })\n return\n }\n\n // Built-in: delay\n if (eff.type === 'delay') {\n const ms = eff.ms as number\n const onDone = eff.onDone as M\n setTimeout(() => inst.send(onDone), ms)\n return\n }\n\n // Built-in: log\n if (eff.type === 'log') {\n console.log(eff.message)\n return\n }\n\n // Dev-only: record on the timeline / consult the mock registry.\n // Short-circuits real dispatch when a mock matches. Zero cost in\n // production — the guard on `_effectTimeline` is undefined unless\n // `installDevTools` populated the trackers.\n if (inst._effectTimeline !== undefined && dispatchEffectDev(inst, effect)) return\n\n // User onEffect handler\n if (inst.def.onEffect) {\n inst.def.onEffect({ effect, send: inst.send, signal: inst.signal })\n }\n}\n\n/**\n * Dev-only effect dispatch wrapper. Records the `dispatched` phase and,\n * when a mock matches, auto-delivers the mocked response through the\n * effect's own `onSuccess` callback on a microtask (same timing contract\n * as a real async resolve). Non-matched effects are tracked as pending\n * so `llui_pending_effects` / `llui_resolve_effect` can observe them.\n *\n * @returns `true` when a mock matched (caller should skip the real\n * dispatch) or `false` to proceed with the user-provided onEffect.\n */\nfunction dispatchEffectDev<S, M, E>(inst: ComponentInstance<S, M, E>, effect: E): boolean {\n const timeline = inst._effectTimeline\n if (timeline === undefined) return false\n\n const eff = effect as Record<string, unknown>\n const id = newEffectId()\n const type = typeof eff.type === 'string' ? eff.type : '<unknown>'\n const dispatchedAt = Date.now()\n\n const mock = inst._effectMocks?.match(effect)\n if (mock) {\n timeline.push({ effectId: id, type, phase: 'dispatched', timestamp: dispatchedAt })\n // Auto-deliver the mocked response via the effect's onSuccess callback (if any).\n // This mirrors what the real dispatch would do, so the component receives a Msg\n // from the mocked effect without any network/IO happening.\n const payload = effect as Record<string, unknown>\n if (typeof payload.onSuccess === 'function') {\n const msg = (payload.onSuccess as (d: unknown) => unknown)(mock.response)\n // Schedule delivery as a microtask so it runs after the current update\n // cycle completes (same timing contract as a real async effect resolve).\n Promise.resolve().then(() => inst.send(msg as never))\n }\n timeline.push({\n effectId: id,\n type,\n phase: 'resolved-mocked',\n timestamp: dispatchedAt,\n durationMs: 0,\n })\n return true\n }\n\n timeline.push({ effectId: id, type, phase: 'dispatched', timestamp: dispatchedAt })\n inst._pendingEffects?.push({ id, type, dispatchedAt, status: 'queued', payload: effect })\n return false\n}\n\nfunction newEffectId(): string {\n const cryptoObj = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n if (cryptoObj?.randomUUID) return cryptoObj.randomUUID()\n return `eff-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`\n}\n"]}
|
|
1
|
+
{"version":3,"file":"update-loop.js","sourceRoot":"","sources":["../src/update-loop.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,UAAU,EAAE,MAAM,cAAc,CAAA;AAEtD,oEAAoE;AACpE,sEAAsE;AACtE,mEAAmE;AACnE,IAAI,YAAY,GAAkB,IAAI,CAAA;AACtC,SAAS,kBAAkB;IACzB,IAAI,YAAY,KAAK,IAAI;QAAE,YAAY,GAAG,UAAU,EAAE,CAAA;IACtD,OAAO,YAAY,CAAA;AACrB,CAAC;AAMD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE1D,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,GAAG,CAAC,CAAA;AAEvC,kEAAkE;AAClE,IAAI,mBAAmB,GACrB,IAAI,CAAA;AAEN,MAAM,UAAU,sBAAsB,CACpC,EAAmE;IAEnE,mBAAmB,GAAG,EAAE,CAAA;AAC1B,CAAC;AAoFD,MAAM,UAAU,uBAAuB,CACrC,GAA6B,EAC7B,IAAQ,EACR,iBAAkC,IAAI,EACtC,GAAY;IAEZ,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAS,CAAC,CAAA;IAE1D,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;IAExC,MAAM,IAAI,GAA+B;QACvC,qEAAqE;QACrE,oEAAoE;QACpE,8DAA8D;QAC9D,sCAAsC;QACtC,GAAG,EAAE,GAA4B;QACjC,KAAK,EAAE,YAAY;QACnB,cAAc;QACd,uEAAuE;QACvE,sEAAsE;QACtE,uCAAuC;QACvC,GAAG,EAAE,GAAG,IAAI,kBAAkB,EAAE;QAChC,0EAA0E;QAC1E,iEAAiE;QACjE,uEAAuE;QACvE,oEAAoE;QACpE,kEAAkE;QAClE,2DAA2D;QAC3D,YAAY,EAAE,cAAc,CAAC,cAAc,CAAC;QAC5C,WAAW,EAAE,EAAE;QACf,gBAAgB,EAAE,EAAE;QACpB,KAAK,EAAE,EAAE;QACT,kBAAkB,EAAE,KAAK;QACzB,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,EAAE;QACf,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,eAAe,EAAE,UAAU;QAE3B,IAAI,CAAC,GAAM;YACT,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACpB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC7B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAA;gBAC9B,cAAc,CAAC,GAAG,EAAE;oBAClB,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAA;oBAC/B,eAAe,CAAC,IAAI,CAAC,CAAA;gBACvB,CAAC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;KACF,CAAA;IAED,IAAI,CAAC,YAAY,CAAC,KAAK,GAAG,MAAM,CAAA;IAEhC,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAU,IAAgC;IACrE,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IACnC,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAA;IAC/B,eAAe,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAU,IAAgC,EAAE,QAAW;IAChF,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAA;IACrB,IAAI,CAAC,aAAa,GAAG,SAAS,CAAA;IAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAA;IACjC,MAAM,oBAAoB,GAAG,QAAQ,CAAC,MAAM,CAAA;IAE5C,mBAAmB,CAAC,SAAS,CAAC,CAAA;IAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAA;IAC9C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IACtC,CAAC;IAED,IAAI,SAAS,GAAG,oBAAoB,CAAA;IACpC,IAAI,QAAQ,CAAC,MAAM,GAAG,oBAAoB,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnF,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI;gBAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;QACtD,CAAC;QACD,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;QACnB,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAA;IAC/C,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,SAAS,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;QAC5B,IAAI,OAAO,CAAC,IAAI;YAAE,SAAQ;QAC1B,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YACzB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;YACtC,CAAC;YACD,SAAQ;QACV,CAAC;QACD,IAAI,QAAiB,CAAA;QACrB,IAAI,CAAC;YACH,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACpC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,gEAAgE;YAChE,iEAAiE;YACjE,yDAAyD;YACzD,yDAAyD;YACzD,8DAA8D;YAC9D,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;YACpC,SAAQ;QACV,CAAC;QACD,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC;YAAE,SAAQ;QACpD,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAA;QAC5B,IAAI,CAAC;YACH,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QACjC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,yDAAyD;YACzD,6DAA6D;YAC7D,6DAA6D;YAC7D,iCAAiC;YACjC,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,IAAgC,EAChC,OAAgB,EAChB,CAAU;IAEV,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IACzD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAClF,MAAM,IAAI,GACR,KAAK,KAAK,SAAS;QACjB,CAAC,CAAC;YACE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;YAC1B,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE;YACtC,KAAK;SACN;QACH,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,EAAE,CAAA;IAC9F,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;YAC7D,sDAAsD;QACxD,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAChF,OAAO,CAAC,IAAI,CACV,uCAAuC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAC3G,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAU,IAAgC;IAChE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IAExB,0EAA0E;IAC1E,6DAA6D;IAC7D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAE,CAAA;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAE,GAA+B,CAAC,IAAc,CAEtE,CAAA;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;YAChB,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAyB,EAAE,GAAG,CAAC,CAAA;YACnE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAA;YACrB,IAAI,CAAC,SAAS,EAAE,CAAC,QAAmB,CAAC,CAAA;YACrC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;gBACzB,IAAI,CAAC,aAAa,GAAG,SAAS,CAAA;gBAC9B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAA;YAC5B,CAAC;YACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAE,CAAC,CAAA;YACnC,CAAC;YACD,OAAM;QACR,CAAC;IACH,CAAC;IAED,wDAAwD;IACxD,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACtB,IAAI,aAAa,GAAG,CAAC,CAAA;IACrB,MAAM,UAAU,GAAQ,EAAE,CAAA;IAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAA;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAA;IAChC,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,CAAE,CAAA;QACtB,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACjD,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,aAAa,IAAI,KAAK,CAAA;QACxB,CAAC;aAAM,CAAC;YACN,aAAa,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACtC,CAAC;QACD,KAAK,GAAG,QAAQ,CAAA;QAChB,oEAAoE;QACpE,uEAAuE;QACvE,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE;YAAE,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAE,CAAC,CAAA;IAC3E,CAAC;IACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IAEhB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IAClB,IAAI,CAAC,SAAS,EAAE,CAAC,KAAgB,CAAC,CAAA;IAClC,oEAAoE;IACpE,kEAAkE;IAClE,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAClC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAA;IAC/B,CAAC;IAED,gEAAgE;IAChE,gEAAgE;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAA;IACjC,MAAM,oBAAoB,GAAG,QAAQ,CAAC,MAAM,CAAA;IAE5C,oEAAoE;IACpE,yEAAyE;IACzE,mBAAmB,CAAC,aAAa,CAAC,CAAA;IAElC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACtB,oEAAoE;QACpE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,CAAA;IAChG,CAAC;SAAM,CAAC;QACN,6DAA6D;QAC7D,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAA;IAC3E,CAAC;IAED,qCAAqC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAE,CAAC,CAAA;IACtC,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,IAAgC,EAChC,KAAQ,EACR,aAAqB,EACrB,QAAmB,EACnB,oBAA4B;IAE5B,sEAAsE;IACtE,wEAAwE;IACxE,sEAAsE;IACtE,sEAAsE;IACtE,qEAAqE;IACrE,sEAAsE;IACtE,qDAAqD;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAA;IACpC,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAA;QACxB,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC;YAAE,SAAQ;QAC1D,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;IACvC,CAAC;IAED,sCAAsC;IACtC,UAAU,CACR,KAAK,EACL,aAAa,EACb,QAAQ,EACR,oBAAoB,EACpB,IAAI,CAAC,GAAG,CAAC,IAAI,EACb,IAAI,CAAC,eAAe,CACrB,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACxB,IAAuB,EACvB,GAAY,EACZ,KAAa,EACb,MAAc;IAEd,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAI,IAAI,CAAC,GAAG,CAAC,MAA2D,CAClF,IAAI,CAAC,KAAK,EACV,GAAG,CACJ,CAAA;IACD,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;IACd,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;IAEnB,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAA;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;YACnB,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;gBAAE,SAAQ;YAC7C,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,CAAC;oBACJ,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;oBACzB,MAAK;gBACP,KAAK,CAAC;oBACJ,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAA;oBACzB,MAAK;gBACP,KAAK,CAAC;oBACJ,KAAK,CAAC,cAAc,EAAE,EAAE,CAAA;oBACxB,MAAK;gBACP,KAAK,CAAC;oBACJ,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAA;oBAC1B,MAAK;gBACP;oBACE,2DAA2D;oBAC3D,IAAI,MAAM,IAAI,EAAE;wBAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,CAAA;oBAC1D,MAAK;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAA;IAC1B,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;IACtE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,KAAc,EACd,KAAa,EACb,QAAmB,EACnB,oBAA4B,EAC5B,aAAsB;AACtB,kEAAkE;AAClE,oEAAoE;AACpE,oEAAoE;AACpE,qEAAqE;AACrE,uDAAuD;AACvD,cAAgG;IAEhG,IAAI,SAAS,GAAG,oBAAoB,CAAA;IACpC,IAAI,QAAQ,CAAC,MAAM,GAAG,oBAAoB,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnF,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI;gBAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;QACtD,CAAC;QACD,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;QACnB,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,iEAAiE;QACjE,gEAAgE;QAChE,gEAAgE;QAChE,+DAA+D;QAC/D,iEAAiE;QACjE,uDAAuD;QACvD,4DAA4D;QAC5D,6DAA6D;QAC7D,sDAAsD;QACtD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,aAAa,CAAA;QACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,SAAS,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;YAC5B,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;gBAAE,SAAQ;YAC1D,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,CAAC;oBACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;gBACzB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,kBAAkB,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;gBAC9E,CAAC;gBACD,SAAQ;YACV,CAAC;YACD,IAAI,QAAiB,CAAA;YACrB,IAAI,CAAC;gBACH,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YACpC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,kBAAkB,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;gBAC5E,SAAQ;YACV,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAA;YAC9B,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAQ;YAC3E,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAA;YAC5B,IAAI,CAAC;gBACH,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;YACjC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,kBAAkB,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAC9E,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,cAAgE,EAChE,OAAgB,EAChB,CAAU,EACV,aAA4B;IAE5B,gEAAgE;IAChE,6DAA6D;IAC7D,qEAAqE;IACrE,iEAAiE;IACjE,2BAA2B;IAC3B,MAAM,OAAO,GACX,aAAa,KAAK,IAAI,IAAI,CAAC,YAAY,KAAK;QAC1C,CAAC,CAAC,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC;QAChD,CAAC,CAAC,IAAI,CAAA;IACV,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtE,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAClF,MAAM,IAAI,GACR,KAAK,KAAK,SAAS;QACjB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE;QAC/E,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAA;IAE5E,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,cAAc,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,6CAA6C;QAC/C,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;QAC1C,kEAAkE;QAClE,mEAAmE;QACnE,+CAA+C;QAC/C,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACpB,CAAC;aAAM,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CACV,uCAAuC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAC3G,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAY,EAAE,OAAgB,EAAE,aAAqB;IAChF,6EAA6E;IAC7E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAE,IAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,CAAA;IACrF,IAAI,QAAQ,GAAG,GAAG,CAAA;IAClB,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3C,MAAM,GAAG,GACP,MAAM,CAAC,SAAS,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;YACtD,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YACzE,CAAC,CAAC,EAAE,CAAA;QACR,QAAQ,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,CAAA;QACzD,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC;YAAE,QAAQ,IAAI,aAAa,CAAA;aAC7C,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC;YAAE,QAAQ,IAAI,gBAAgB,CAAA;IAC5D,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACrD,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAE/D,0CAA0C;IAC1C,IAAI,YAAY,GAAG,EAAE,CAAA;IACrB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACpD,YAAY,GAAG,iBAAiB,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IAC9F,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;IAED,qEAAqE;IACrE,IAAI,aAAa,GAAG,EAAE,CAAA;IACtB,IAAI,GAAG,YAAY,SAAS,IAAI,iDAAiD,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/F,aAAa;YACX,+GAA+G,CAAA;IACnH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,KAAK,CACvB,UAAU,OAAO,CAAC,IAAI,GAAG,OAAO,eAAe,QAAQ,yBAAyB,aAAa,KAAK;QAChG,OAAO,MAAM,EAAE;QACf,aAAa;QACb,YAAY,EACd,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAClD,CAAA;IACD,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,CAAA;IACpE,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,cAAc,CAAU,IAAgC,EAAE,MAAS;IAC1E,MAAM,GAAG,GAAG,MAAiC,CAAA;IAE7C,mDAAmD;IACnD,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;QACvE,mBAAmB,EAAE,CAAC,GAAuD,CAAC,CAAA;QAC9E,OAAM;IACR,CAAC;IAED,kBAAkB;IAClB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,GAAG,CAAC,EAAY,CAAA;QAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAW,CAAA;QAC9B,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;QACvC,OAAM;IACR,CAAC;IAED,gBAAgB;IAChB,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACxB,OAAM;IACR,CAAC;IAED,gEAAgE;IAChE,iEAAiE;IACjE,kEAAkE;IAClE,4CAA4C;IAC5C,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,OAAM;IAEjF,wBAAwB;IACxB,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IACrE,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CAAU,IAAgC,EAAE,MAAS;IAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAA;IACrC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IAExC,MAAM,GAAG,GAAG,MAAiC,CAAA;IAC7C,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAA;IAClE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAE/B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7C,IAAI,IAAI,EAAE,CAAC;QACT,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAA;QACnF,iFAAiF;QACjF,gFAAgF;QAChF,2DAA2D;QAC3D,MAAM,OAAO,GAAG,MAAiC,CAAA;QACjD,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;YAC5C,MAAM,GAAG,GAAI,OAAO,CAAC,SAAqC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACzE,uEAAuE;YACvE,yEAAyE;YACzE,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAY,CAAC,CAAC,CAAA;QACvD,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,EAAE;YACZ,IAAI;YACJ,KAAK,EAAE,iBAAiB;YACxB,SAAS,EAAE,YAAY;YACvB,UAAU,EAAE,CAAC;SACd,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAA;IACnF,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;IACzF,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,SAAS,GAAI,UAAyD,CAAC,MAAM,CAAA;IACnF,IAAI,SAAS,EAAE,UAAU;QAAE,OAAO,SAAS,CAAC,UAAU,EAAE,CAAA;IACxD,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAA;AACvE,CAAC","sourcesContent":["import type { ComponentDef, Lifetime, Binding } from './types.js'\nimport type { StructuralBlock } from './structural.js'\nimport type { RingBuffer, EachDiff } from './tracking/each-diff.js'\nimport type { DisposerEvent } from './tracking/disposer-log.js'\nimport type { CoverageTracker } from './tracking/coverage.js'\nimport { type DomEnv, browserEnv } from './dom-env.js'\n\n// Single lazily-constructed browser env shared by every client-side\n// component instance. Falls through to globalThis at call time — safe\n// to construct on a server process (the lookups never fire there).\nlet _fallbackEnv: DomEnv | null = null\nfunction fallbackBrowserEnv(): DomEnv {\n if (_fallbackEnv === null) _fallbackEnv = browserEnv()\n return _fallbackEnv\n}\nimport type {\n EffectTimelineEntry,\n PendingEffectsList,\n MockRegistry,\n} from './tracking/effect-timeline.js'\nimport { createLifetime } from './lifetime.js'\nimport { applyBinding } from './binding.js'\nimport { setCurrentDirtyMask } from './primitives/memo.js'\n\nexport const FULL_MASK = 0xffffffff | 0\n\n// Addressed effect dispatcher — set by addressed.ts when imported\nlet addressedDispatcher: ((eff: { __targetKey: string | number; __msg: unknown }) => void) | null =\n null\n\nexport function setAddressedDispatcher(\n fn: (eff: { __targetKey: string | number; __msg: unknown }) => void,\n): void {\n addressedDispatcher = fn\n}\n\nexport interface ComponentInstance<S = unknown, M = unknown, E = unknown> {\n def: ComponentDef<S, M, E>\n state: S\n initialEffects: E[]\n rootLifetime: Lifetime\n dom: DomEnv\n allBindings: Binding[]\n structuralBlocks: StructuralBlock[]\n queue: M[]\n microtaskScheduled: boolean\n lastDirtyMask: number\n lastEffects: E[]\n send: (msg: M) => void\n signal: AbortSignal\n abortController: AbortController\n /** @internal dev-only — populated when `installDevTools` ran. Ring-buffered\n * per-each-site reconciliation diffs for MCP introspection tools. */\n _eachDiffLog?: RingBuffer<EachDiff>\n /** @internal dev-only — monotonically incremented by the devtools-intercepted\n * `update` before each history push. Read by `each.ts` to stamp diffs with\n * the `updateIndex` of the message that caused the reconciliation. */\n _updateCounter?: number\n /** @internal dev-only — populated when `installDevTools` ran. Ring-buffered\n * log of `disposeLifetime` firings (scope id + cause). Consumed by the\n * `llui_disposer_log` MCP tool to diagnose leaks on structural transitions. */\n _disposerLog?: RingBuffer<DisposerEvent>\n /** @internal dev-only — populated when `installDevTools` ran. Per-variant\n * Msg counter keyed by discriminant. Consumed by the `llui_coverage` MCP\n * tool to surface Msg variants that have never fired this session. */\n _coverage?: CoverageTracker\n /** @internal dev-only — populated when `installDevTools` ran. Ring-buffered\n * effect dispatch phase log (dispatched → resolved/cancelled) for USER\n * effects emitted from `update()`. Consumed by the `llui_effect_timeline`\n * MCP tool. Built-in plumbing effects (`delay`, `log`, addressed) are NOT\n * recorded here by design — they short-circuit in `dispatchEffect` before\n * `dispatchEffectDev` runs. They're runtime plumbing, not user intent,\n * and surface via other channels (message queue for `delay`, browser\n * console for `log`, addressed-target routing for addressed effects). */\n _effectTimeline?: RingBuffer<EffectTimelineEntry>\n /** @internal dev-only — populated when `installDevTools` ran. List of\n * currently-pending effects addressable by id, consumed by the\n * `llui_pending_effects` MCP tool. */\n _pendingEffects?: PendingEffectsList\n /** @internal dev-only — populated when `installDevTools` ran. Mock\n * registry consulted by the effect-dispatch wrapper to short-circuit\n * matching effects. Consumed by the `llui_mock_effect` MCP tool. */\n _effectMocks?: MockRegistry\n /**\n * @internal — set by mountApp/mountAtAnchor/hydrateApp/hydrateAtAnchor\n * to fire AppHandle.subscribe listeners after every update cycle.\n * Undefined until the first subscriber registers.\n */\n _onCommit?: (state: unknown) => void\n /**\n * @internal — optional hook invoked when a binding's accessor throws\n * during Phase 2. The runtime catches the throw, leaves the binding's\n * `lastValue` unchanged (so the rendered DOM stays at its previous\n * value rather than going blank), and notifies this hook. The agent\n * factory wires it to drain.errors so the LLM sees that some bindings\n * failed; non-agent hosts can leave it undefined for the default\n * console-warn behavior.\n *\n * Why catch + continue instead of letting the throw propagate?\n * One bad binding shouldn't abort the entire update loop — sibling\n * bindings on the same commit are independent and have no business\n * going stale because a different binding crashed. The user-visible\n * effect: when one cell's accessor throws (e.g. scoring fails on a\n * malformed criterion), every other cell still renders correctly;\n * only the broken binding shows its previous value.\n */\n _onBindingError?: (info: { kind: string; key?: string; message: string; stack?: string }) => void\n /**\n * @internal — live registry of currently-mounted Msg variants\n * dispatchable from rendered UI. Lazily allocated when the first\n * compiler-tagged event handler binds. Read by the agent layer (via\n * `AppHandle.getBindingDescriptors()`) to surface live affordances\n * to the LLM. See `binding-descriptors.ts` for the registration\n * protocol and `@llui/vite-plugin`'s tagger pass for the tag emission.\n */\n _bindingDescriptors?: import('./binding-descriptors.js').BindingDescriptorRegistry\n}\n\nexport function createComponentInstance<S, M, E, D = void>(\n def: ComponentDef<S, M, E, D>,\n data?: D,\n parentLifetime: Lifetime | null = null,\n dom?: DomEnv,\n): ComponentInstance<S, M, E> {\n const [initialState, initialEffects] = def.init(data as D)\n\n const controller = new AbortController()\n\n const inst: ComponentInstance<S, M, E> = {\n // `def` carries an arbitrary `D` for typed init data, but after init\n // has run the runtime never touches `def.init` again — update/view/\n // onEffect and HMR replacement don't depend on D. Cast to the\n // D=void instance storage shape here.\n def: def as ComponentDef<S, M, E>,\n state: initialState,\n initialEffects,\n // Caller-supplied DOM env. `mountApp` defaults this to `browserEnv()`;\n // `renderToString` passes the user's jsdom/linkedom env. Never null —\n // every primitive reads from inst.dom.\n dom: dom ?? fallbackBrowserEnv(),\n // When `parentLifetime` is provided the instance's rootLifetime becomes a\n // child of that scope. This is how persistent layouts wire pages\n // into the layout's scope tree: the page's rootLifetime is parented at\n // the layout's pageSlot() point so `useContext` lookups flow layout\n // → page, and scope disposal cascades correctly. Mount paths that\n // don't pass parentLifetime get the classic detached root.\n rootLifetime: createLifetime(parentLifetime),\n allBindings: [],\n structuralBlocks: [],\n queue: [],\n microtaskScheduled: false,\n lastDirtyMask: 0,\n lastEffects: [],\n signal: controller.signal,\n abortController: controller,\n\n send(msg: M) {\n inst.queue.push(msg)\n if (!inst.microtaskScheduled) {\n inst.microtaskScheduled = true\n queueMicrotask(() => {\n inst.microtaskScheduled = false\n processMessages(inst)\n })\n }\n },\n }\n\n inst.rootLifetime._kind = 'root'\n\n return inst\n}\n\nexport function flushInstance<S, M, E>(inst: ComponentInstance<S, M, E>): void {\n if (inst.queue.length === 0) return\n inst.microtaskScheduled = false\n processMessages(inst)\n}\n\n/**\n * Dev-only: overwrite instance state and re-run both phases with FULL_MASK\n * so every binding re-evaluates. Bypasses update() — use for devtools\n * snapshot/restore, not in app code.\n */\nexport function _forceState<S, M, E>(inst: ComponentInstance<S, M, E>, newState: S): void {\n inst.state = newState\n inst.lastDirtyMask = FULL_MASK\n\n const bindings = inst.allBindings\n const bindingsBeforePhase1 = bindings.length\n\n setCurrentDirtyMask(FULL_MASK)\n\n const snapshot = inst.structuralBlocks.slice()\n for (const block of snapshot) {\n block.reconcile(newState, FULL_MASK)\n }\n\n let phase2Len = bindingsBeforePhase1\n if (bindings.length > bindingsBeforePhase1 || (phase2Len > 0 && bindings[0]!.dead)) {\n let w = 0\n for (let r = 0; r < bindings.length; r++) {\n if (!bindings[r]!.dead) bindings[w++] = bindings[r]!\n }\n bindings.length = w\n phase2Len = Math.min(w, bindingsBeforePhase1)\n }\n\n const state = inst.state\n for (let i = 0, len = phase2Len; i < len; i++) {\n const binding = bindings[i]!\n if (binding.dead) continue\n if (binding.kind === 'effect') {\n try {\n binding.accessor(state)\n } catch (e) {\n reportBindingError(inst, binding, e)\n }\n continue\n }\n let newValue: unknown\n try {\n newValue = binding.accessor(state)\n } catch (e) {\n // Accessor threw — leave the binding's `lastValue` unchanged so\n // the rendered DOM stays at its previous value rather than going\n // blank. Sibling bindings on the same commit continue to\n // evaluate. The error surfaces via the optional hook (or\n // console.warn as a fallback) so it isn't silently swallowed.\n reportBindingError(inst, binding, e)\n continue\n }\n if (Object.is(newValue, binding.lastValue)) continue\n binding.lastValue = newValue\n try {\n applyBinding(binding, newValue)\n } catch (e) {\n // applyBinding writes the value to the DOM (textContent,\n // setAttribute, etc.). Throws here are usually environmental\n // (a node was removed mid-flight by a sibling binding). Same\n // contract: report and continue.\n reportBindingError(inst, binding, e)\n }\n }\n}\n\nfunction reportBindingError<S, M, E>(\n inst: ComponentInstance<S, M, E>,\n binding: Binding,\n e: unknown,\n): void {\n const err = e instanceof Error ? e : new Error(String(e))\n const stack = err.stack ? err.stack.split('\\n').slice(0, 8).join('\\n') : undefined\n const info =\n stack !== undefined\n ? {\n kind: String(binding.kind),\n key: binding.key,\n message: `${err.name}: ${err.message}`,\n stack,\n }\n : { kind: String(binding.kind), key: binding.key, message: `${err.name}: ${err.message}` }\n if (inst._onBindingError !== undefined) {\n try {\n inst._onBindingError(info)\n } catch {\n // The hook itself threw — nothing to do; we're in a recovery\n // path already. Fall through to the console fallback.\n }\n } else if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(\n `[llui] binding accessor threw (kind=${info.kind}${info.key ? `, key=${info.key}` : ''}): ${info.message}`,\n )\n }\n}\n\nfunction processMessages<S, M, E>(inst: ComponentInstance<S, M, E>): void {\n const queue = inst.queue\n\n // Single-message fast path: dispatch directly to per-message-type handler\n // if available. Skips dirty computation, Phase 1/2 entirely.\n if (queue.length === 1 && inst.def.__handlers) {\n const msg = queue[0]!\n const handler = inst.def.__handlers[(msg as Record<string, unknown>).type as string] as\n | ((inst: ComponentInstance, msg: unknown) => [S, E[]])\n | undefined\n if (handler) {\n queue.length = 0\n const [newState, effects] = handler(inst as ComponentInstance, msg)\n inst.state = newState\n inst._onCommit?.(newState as unknown)\n if (import.meta.env?.DEV) {\n inst.lastDirtyMask = FULL_MASK\n inst.lastEffects = effects\n }\n for (let i = 0; i < effects.length; i++) {\n dispatchEffect(inst, effects[i]!)\n }\n return\n }\n }\n\n // Generic pipeline — drain queue, accumulate dirty bits\n let state = inst.state\n let combinedDirty = 0\n const allEffects: E[] = []\n\n const defUpdate = inst.def.update\n const dirtyFn = inst.def.__dirty\n for (let qi = 0; qi < queue.length; qi++) {\n const msg = queue[qi]!\n const [newState, effects] = defUpdate(state, msg)\n const dirty = dirtyFn ? dirtyFn(state, newState) : FULL_MASK\n if (typeof dirty === 'number') {\n combinedDirty |= dirty\n } else {\n combinedDirty |= dirty[0] | dirty[1]\n }\n state = newState\n // Avoid spread — allocates an iterator per call. For typical effect\n // arrays (0-2 elements) this is a minor saving; for bursts it matters.\n for (let ei = 0; ei < effects.length; ei++) allEffects.push(effects[ei]!)\n }\n queue.length = 0\n\n inst.state = state\n inst._onCommit?.(state as unknown)\n // Dev-only bookkeeping — tests read lastDirtyMask/lastEffects, prod\n // doesn't. Gating here keeps two writes out of the prod hot path.\n if (import.meta.env?.DEV) {\n inst.lastDirtyMask = combinedDirty\n inst.lastEffects = allEffects\n }\n\n // Snapshot binding count before Phase 1 — bindings added during\n // Phase 1 already have correct initial values and skip Phase 2.\n const bindings = inst.allBindings\n const bindingsBeforePhase1 = bindings.length\n\n // Set current dirty mask BEFORE Phase 1 so memo() accessors used in\n // structural primitives (e.g. each.items) can use the bitmask fast path.\n setCurrentDirtyMask(combinedDirty)\n\n if (inst.def.__update) {\n // Compiler-generated fast path — replaces generic Phase 1 + Phase 2\n inst.def.__update(state, combinedDirty, bindings, inst.structuralBlocks, bindingsBeforePhase1)\n } else {\n // Generic Phase 1 + Phase 2 fallback (uncompiled components)\n genericUpdate(inst, state, combinedDirty, bindings, bindingsBeforePhase1)\n }\n\n // Dispatch effects after DOM updates\n for (let i = 0; i < allEffects.length; i++) {\n dispatchEffect(inst, allEffects[i]!)\n }\n}\n\nfunction genericUpdate<S, M, E>(\n inst: ComponentInstance<S, M, E>,\n state: S,\n combinedDirty: number,\n bindings: Binding[],\n bindingsBeforePhase1: number,\n): void {\n // Phase 1 — structural reconciliation. Structural primitives register\n // their blocks BEFORE running builders, so parents precede their nested\n // children in this array. That ordering matters: a parent's reconcile\n // may dispose the old arm, whose disposers splice nested child blocks\n // out of this shared array. Because children are always to the right\n // of their parent, the splice shifts entries left — which is safe for\n // a forward iterator that re-reads length each step.\n const blocks = inst.structuralBlocks\n for (let bi = 0; bi < blocks.length; bi++) {\n const block = blocks[bi]\n if (!block || (block.mask & combinedDirty) === 0) continue\n block.reconcile(state, combinedDirty)\n }\n\n // Phase 2 — compact + update bindings\n _runPhase2(\n state,\n combinedDirty,\n bindings,\n bindingsBeforePhase1,\n inst.def.name,\n inst._onBindingError,\n )\n}\n\n/**\n * Run a handler for a single message: call update(), reconcile blocks\n * with the given method, run Phase 2. Used by compiler-generated __handlers\n * to avoid duplicating boilerplate per message type.\n *\n * @param method 0=reconcile, 1=reconcileItems, 2=reconcileClear, 3=reconcileRemove, -1=skip blocks\n * @public — used by compiler-generated `__handlers`\n */\nexport function _handleMsg(\n inst: ComponentInstance,\n msg: unknown,\n dirty: number,\n method: number,\n): [unknown, unknown[]] {\n const [s, e] = (inst.def.update as (s: unknown, m: unknown) => [unknown, unknown[]])(\n inst.state,\n msg,\n )\n inst.state = s\n inst._onCommit?.(s)\n\n if (method >= 0) {\n const bl = inst.structuralBlocks\n for (let i = 0; i < bl.length; i++) {\n const block = bl[i]\n if (!block || !(block.mask & dirty)) continue\n switch (method) {\n case 0:\n block.reconcile(s, dirty)\n break\n case 1:\n block.reconcileItems?.(s)\n break\n case 2:\n block.reconcileClear?.()\n break\n case 3:\n block.reconcileRemove?.(s)\n break\n default:\n // method >= 10: reconcileChanged with stride = method - 10\n if (method >= 10) block.reconcileChanged?.(s, method - 10)\n break\n }\n }\n }\n\n const b = inst.allBindings\n _runPhase2(s, dirty, b, b.length, inst.def.name, inst._onBindingError)\n return [s, e]\n}\n\n/**\n * Phase 2: compact dead bindings + update live bindings.\n * Shared between genericUpdate and compiler-generated __update.\n * @public — used by compiler-generated `__update` functions\n */\nexport function _runPhase2(\n state: unknown,\n dirty: number,\n bindings: Binding[],\n bindingsBeforePhase1: number,\n componentName?: string,\n // Optional `_onBindingError` hook. Type is duplicated here rather\n // than referenced as `ComponentInstance['_onBindingError']` because\n // the underlying field is `@internal` — stripped from the generated\n // `.d.ts` — and a public-export signature can't depend on a stripped\n // type without breaking dependent packages' typecheck.\n onBindingError?: (info: { kind: string; key?: string; message: string; stack?: string }) => void,\n): void {\n let phase2Len = bindingsBeforePhase1\n if (bindings.length > bindingsBeforePhase1 || (phase2Len > 0 && bindings[0]!.dead)) {\n let w = 0\n for (let r = 0; r < bindings.length; r++) {\n if (!bindings[r]!.dead) bindings[w++] = bindings[r]!\n }\n bindings.length = w\n phase2Len = Math.min(w, bindingsBeforePhase1)\n }\n\n if (dirty !== 0) {\n // Always catch+continue: a single accessor throw shouldn't abort\n // the rest of the bindings on the same commit. The user-visible\n // effect: a broken cell shows its previous value; sibling cells\n // stay current. In dev mode, the wrapped error (with component\n // name, kind, node descriptor, accessor source) is forwarded via\n // the `_onBindingError` hook (agent integration) or to\n // `console.error` (dev harness without an agent). The prior\n // behavior of rethrowing from `flush()` made one bad binding\n // visually break the entire view — the worst-case UX.\n const isDev = import.meta.env?.DEV && componentName\n for (let i = 0, len = phase2Len; i < len; i++) {\n const binding = bindings[i]!\n if (binding.dead || (binding.mask & dirty) === 0) continue\n if (binding.kind === 'effect') {\n try {\n binding.accessor(state)\n } catch (e) {\n handleBindingThrow(onBindingError, binding, e, isDev ? componentName : null)\n }\n continue\n }\n let newValue: unknown\n try {\n newValue = binding.accessor(state)\n } catch (e) {\n handleBindingThrow(onBindingError, binding, e, isDev ? componentName : null)\n continue\n }\n const last = binding.lastValue\n if (newValue === last || (newValue !== newValue && last !== last)) continue\n binding.lastValue = newValue\n try {\n applyBinding(binding, newValue)\n } catch (e) {\n handleBindingThrow(onBindingError, binding, e, isDev ? componentName : null)\n }\n }\n }\n}\n\nfunction handleBindingThrow(\n onBindingError: ComponentInstance['_onBindingError'] | undefined,\n binding: Binding,\n e: unknown,\n componentName: string | null,\n): void {\n // Dev mode: build the rich wrapped error (with accessor source,\n // node descriptor, undefined-hint detection). Prod skips the\n // bookkeeping. Either way the report flows through `_onBindingError`\n // when wired (agent setups), else falls back to console.error so\n // operators see the cause.\n const wrapped =\n componentName !== null && e instanceof Error\n ? enhanceBindingError(e, binding, componentName)\n : null\n const err = wrapped ?? (e instanceof Error ? e : new Error(String(e)))\n const stack = err.stack ? err.stack.split('\\n').slice(0, 8).join('\\n') : undefined\n const info =\n stack !== undefined\n ? { kind: String(binding.kind), key: binding.key, message: err.message, stack }\n : { kind: String(binding.kind), key: binding.key, message: err.message }\n\n if (onBindingError !== undefined) {\n try {\n onBindingError(info)\n } catch {\n // hook itself threw; fall through to console\n }\n } else if (typeof console !== 'undefined') {\n // Dev mode shows the wrapped (richer) message. Prod shows a brief\n // line — operators still see something but without the full source\n // hint that's only useful at development time.\n if (componentName !== null) {\n console.error(err)\n } else if (typeof console.warn === 'function') {\n console.warn(\n `[llui] binding accessor threw (kind=${info.kind}${info.key ? `, key=${info.key}` : ''}): ${info.message}`,\n )\n }\n }\n}\n\nfunction enhanceBindingError(err: unknown, binding: Binding, componentName: string): Error {\n // For text bindings, binding.node is the Text node — use its parent element.\n const node = binding.node\n const target = node.nodeType === 1 ? (node as Element) : (node.parentElement ?? null)\n let nodeDesc = '?'\n if (target) {\n const id = target.id ? `#${target.id}` : ''\n const cls =\n target.className && typeof target.className === 'string'\n ? `.${target.className.split(' ').filter(Boolean).slice(0, 2).join('.')}`\n : ''\n nodeDesc = `<${target.tagName.toLowerCase()}${id}${cls}>`\n if (node.nodeType === 3) nodeDesc += ' text-child'\n else if (node.nodeType === 8) nodeDesc += ' comment-child'\n }\n const keyPart = binding.key ? ` .${binding.key}` : ''\n const errMsg = err instanceof Error ? err.message : String(err)\n\n // Build accessor source hint if available\n let accessorHint = ''\n try {\n const src = binding.accessor.toString().slice(0, 80)\n accessorHint = `\\n accessor: ${src}${binding.accessor.toString().length > 80 ? '...' : ''}`\n } catch {\n // toString() may throw on revoked proxies, etc.\n }\n\n // Detect common undefined/null access pattern and add a helpful hint\n let undefinedHint = ''\n if (err instanceof TypeError && /Cannot read propert(ies|y).*of (undefined|null)/.test(errMsg)) {\n undefinedHint =\n '\\n hint: Check that your accessor handles undefined state fields (e.g., use optional chaining: s.user?.name)'\n }\n\n const wrapped = new Error(\n `[LLui] ${binding.kind}${keyPart} binding on ${nodeDesc} — accessor threw in <${componentName}>\\n` +\n ` ↳ ${errMsg}` +\n undefinedHint +\n accessorHint,\n err instanceof Error ? { cause: err } : undefined,\n )\n wrapped.stack = (err instanceof Error && err.stack) || wrapped.stack\n return wrapped\n}\n\nfunction dispatchEffect<S, M, E>(inst: ComponentInstance<S, M, E>, effect: E): void {\n const eff = effect as Record<string, unknown>\n\n // Addressed effects — dispatch to target component\n if (eff.__addressed === true && typeof eff.__targetKey !== 'undefined') {\n addressedDispatcher?.(eff as { __targetKey: string | number; __msg: unknown })\n return\n }\n\n // Built-in: delay\n if (eff.type === 'delay') {\n const ms = eff.ms as number\n const onDone = eff.onDone as M\n setTimeout(() => inst.send(onDone), ms)\n return\n }\n\n // Built-in: log\n if (eff.type === 'log') {\n console.log(eff.message)\n return\n }\n\n // Dev-only: record on the timeline / consult the mock registry.\n // Short-circuits real dispatch when a mock matches. Zero cost in\n // production — the guard on `_effectTimeline` is undefined unless\n // `installDevTools` populated the trackers.\n if (inst._effectTimeline !== undefined && dispatchEffectDev(inst, effect)) return\n\n // User onEffect handler\n if (inst.def.onEffect) {\n inst.def.onEffect({ effect, send: inst.send, signal: inst.signal })\n }\n}\n\n/**\n * Dev-only effect dispatch wrapper. Records the `dispatched` phase and,\n * when a mock matches, auto-delivers the mocked response through the\n * effect's own `onSuccess` callback on a microtask (same timing contract\n * as a real async resolve). Non-matched effects are tracked as pending\n * so `llui_pending_effects` / `llui_resolve_effect` can observe them.\n *\n * @returns `true` when a mock matched (caller should skip the real\n * dispatch) or `false` to proceed with the user-provided onEffect.\n */\nfunction dispatchEffectDev<S, M, E>(inst: ComponentInstance<S, M, E>, effect: E): boolean {\n const timeline = inst._effectTimeline\n if (timeline === undefined) return false\n\n const eff = effect as Record<string, unknown>\n const id = newEffectId()\n const type = typeof eff.type === 'string' ? eff.type : '<unknown>'\n const dispatchedAt = Date.now()\n\n const mock = inst._effectMocks?.match(effect)\n if (mock) {\n timeline.push({ effectId: id, type, phase: 'dispatched', timestamp: dispatchedAt })\n // Auto-deliver the mocked response via the effect's onSuccess callback (if any).\n // This mirrors what the real dispatch would do, so the component receives a Msg\n // from the mocked effect without any network/IO happening.\n const payload = effect as Record<string, unknown>\n if (typeof payload.onSuccess === 'function') {\n const msg = (payload.onSuccess as (d: unknown) => unknown)(mock.response)\n // Schedule delivery as a microtask so it runs after the current update\n // cycle completes (same timing contract as a real async effect resolve).\n Promise.resolve().then(() => inst.send(msg as never))\n }\n timeline.push({\n effectId: id,\n type,\n phase: 'resolved-mocked',\n timestamp: dispatchedAt,\n durationMs: 0,\n })\n return true\n }\n\n timeline.push({ effectId: id, type, phase: 'dispatched', timestamp: dispatchedAt })\n inst._pendingEffects?.push({ id, type, dispatchedAt, status: 'queued', payload: effect })\n return false\n}\n\nfunction newEffectId(): string {\n const cryptoObj = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n if (cryptoObj?.randomUUID) return cryptoObj.randomUUID()\n return `eff-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`\n}\n"]}
|