streetui 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing.ts","../../core/src/identity.ts","../../core/src/lifecycle.ts","../../core/src/diagnostics.ts","../../compiler/src/validation/validator.ts","../../compiler/src/transform/transform.ts","../../compiler/src/compile.ts","../../dom/src/browser-adapter.ts","../../dom/src/server-node.ts","../../dom/src/server-adapter.ts","../../dom/src/focus.ts","../../renderer/src/render-context.ts","../../renderer/src/node-instance.ts","../../renderer/src/attributes.ts","../../renderer/src/events.ts","../../renderer/src/tag-map.ts","../../renderer/src/patch.ts","../../renderer/src/reconciliation.ts","../../renderer/src/transition.ts","../../renderer/src/head.ts","../../renderer/src/mount.ts","../../renderer/src/hydration-diagnostics.ts","../../renderer/src/hydrate.ts","../../renderer/src/render-handle.ts","../../renderer/src/renderer.ts","../../compiler/src/analysis/analyze.ts","../../compiler/src/analysis/inspect.ts","../../renderer/src/static-ssr-plan.ts","../../renderer/src/ssr.ts","../../testing/src/test-renderer.ts","../../scheduler/src/scheduler.ts","../../testing/src/helpers.ts","../../dsl/src/transition.ts","../../dsl/src/head.ts","../../state/src/signal.ts","../../dsl/src/builders.ts","../../graph/src/graph-node.ts","../../graph/src/graph.ts","../../dsl/src/dsl.ts","../../testing/src/component.ts","../src/version.ts"],"sourcesContent":["/**\n * `streetui/testing` — testing utilities for StreetUI applications.\n *\n * A curated entry for the already-implemented testing helpers (render,\n * findByRole, waitFor, renderServerThenHydrate, …). It lives on its own subpath\n * so that test-only helpers stay out of the main runtime barrel — and so the\n * one cross-package name collision (`RenderResult`, shared with the CLI's render\n * types) is resolved cleanly: the testing `RenderResult` is reachable only from\n * here.\n *\n * ```ts\n * import { render, findByRole, waitFor } from 'streetui/testing';\n * ```\n */\nexport * from '@streetui/testing';\n\n// Opt-in compiler diagnostics (spec §14): static-graph analysis + inspection.\n// Exposed on the diagnostic subpath so they stay OUT of the runtime barrel\n// (`streetui`), keeping the shipped client bundle lean (§6/§7).\nexport * from '@streetui/compiler/diagnostics';\n\n// Re-export the framework version for parity with the main entry.\nexport { VERSION } from './version.js';\n","/**\n * Node and application identity utilities.\n * Every node in the semantic graph has a stable, unique identity.\n */\n\nlet _counter = 0;\n\n/** Generate a framework-internal monotonic integer ID. */\nexport function nextId(): number {\n return ++_counter;\n}\n\n/** Reset the counter (test use only). */\nexport function resetIdCounter(): void {\n _counter = 0;\n}\n\n/** Opaque branded type for node IDs. */\nexport type NodeId = string & { readonly __brand: 'NodeId' };\n\n/** Create a NodeId from a string (must be unique at call site). */\nexport function createNodeId(value: string): NodeId {\n return value as NodeId;\n}\n\n/** Generate a fresh, unique NodeId. */\nexport function generateNodeId(prefix: string = 'node'): NodeId {\n return createNodeId(`${prefix}:${nextId()}`);\n}\n\n/** Parse the prefix from a NodeId. */\nexport function nodeIdPrefix(id: NodeId): string {\n const colon = id.indexOf(':');\n return colon === -1 ? id : id.slice(0, colon);\n}\n\n/** Branded type for application IDs. */\nexport type ApplicationId = string & { readonly __brand: 'ApplicationId' };\n\n/** Generate a fresh application ID. */\nexport function generateApplicationId(name: string): ApplicationId {\n return `app:${name}:${nextId()}` as ApplicationId;\n}\n","/**\n * Application and component lifecycle primitives.\n *\n * Lifecycle phases:\n * created → mounted → active ⇄ updating → unmounting → destroyed\n */\n\nexport type LifecyclePhase =\n | 'created'\n | 'mounted'\n | 'active'\n | 'updating'\n | 'unmounting'\n | 'destroyed';\n\nexport type LifecycleHook = () => void | Promise<void>;\n\nexport class Lifecycle {\n private _phase: LifecyclePhase = 'created';\n private readonly _hooks: Map<LifecyclePhase, LifecycleHook[]> = new Map();\n\n get phase(): LifecyclePhase {\n return this._phase;\n }\n\n get isMounted(): boolean {\n return this._phase === 'mounted' || this._phase === 'active' || this._phase === 'updating';\n }\n\n get isDestroyed(): boolean {\n return this._phase === 'destroyed';\n }\n\n on(phase: LifecyclePhase, hook: LifecycleHook): () => void {\n const hooks = this._hooks.get(phase) ?? [];\n hooks.push(hook);\n this._hooks.set(phase, hooks);\n return () => {\n const current = this._hooks.get(phase);\n if (current !== undefined) {\n const idx = current.indexOf(hook);\n if (idx !== -1) current.splice(idx, 1);\n }\n };\n }\n\n async transition(to: LifecyclePhase): Promise<void> {\n this._phase = to;\n const hooks = this._hooks.get(to) ?? [];\n for (const hook of hooks) {\n await hook();\n }\n }\n\n onMount(hook: LifecycleHook): () => void {\n return this.on('mounted', hook);\n }\n\n onUnmount(hook: LifecycleHook): () => void {\n return this.on('unmounting', hook);\n }\n\n onDestroy(hook: LifecycleHook): () => void {\n return this.on('destroyed', hook);\n }\n}\n\n/** A simple cleanup registry — collect teardown functions and run them all at once. */\nexport class CleanupRegistry {\n private readonly _fns: Array<() => void> = [];\n\n add(fn: () => void): void {\n this._fns.push(fn);\n }\n\n run(): void {\n for (const fn of this._fns) {\n try {\n fn();\n } catch {\n // Best-effort cleanup; don't let one failure block others\n }\n }\n this._fns.length = 0;\n }\n}\n","/**\n * Framework diagnostics — structured errors, warnings, and hints\n * that flow through the compiler, validator, and runtime.\n */\n\nexport type DiagnosticSeverity = 'error' | 'warning' | 'info';\n\nexport interface DiagnosticLocation {\n readonly file?: string;\n readonly line?: number;\n readonly column?: number;\n readonly nodeId?: string;\n}\n\nexport interface Diagnostic {\n readonly severity: DiagnosticSeverity;\n readonly code: string;\n readonly message: string;\n readonly location: DiagnosticLocation | undefined;\n readonly cause: unknown;\n}\n\nexport class DiagnosticError extends Error {\n readonly diagnostics: readonly Diagnostic[];\n\n constructor(diagnostics: readonly Diagnostic[]) {\n const summary = diagnostics\n .filter(d => d.severity === 'error')\n .map(d => `[${d.code}] ${d.message}`)\n .join('\\n');\n super(`StreetUI diagnostics:\\n${summary}`);\n this.name = 'DiagnosticError';\n this.diagnostics = diagnostics;\n }\n}\n\nexport class DiagnosticCollector {\n private readonly _diagnostics: Diagnostic[] = [];\n\n get diagnostics(): readonly Diagnostic[] {\n return this._diagnostics;\n }\n\n get hasErrors(): boolean {\n return this._diagnostics.some(d => d.severity === 'error');\n }\n\n get hasWarnings(): boolean {\n return this._diagnostics.some(d => d.severity === 'warning');\n }\n\n error(\n code: string,\n message: string,\n location?: DiagnosticLocation,\n cause?: unknown,\n ): void {\n this._diagnostics.push({ severity: 'error', code, message, location: location ?? undefined, cause: cause ?? undefined });\n }\n\n warn(\n code: string,\n message: string,\n location?: DiagnosticLocation,\n ): void {\n this._diagnostics.push({ severity: 'warning', code, message, location: location ?? undefined, cause: undefined });\n }\n\n info(\n code: string,\n message: string,\n location?: DiagnosticLocation,\n ): void {\n this._diagnostics.push({ severity: 'info', code, message, location: location ?? undefined, cause: undefined });\n }\n\n merge(other: DiagnosticCollector): void {\n for (const d of other.diagnostics) {\n this._diagnostics.push(d);\n }\n }\n\n throwIfErrors(): void {\n if (this.hasErrors) {\n throw new DiagnosticError(this._diagnostics);\n }\n }\n\n clear(): void {\n this._diagnostics.length = 0;\n }\n}\n\n/** Format a single diagnostic as a human-readable string. */\nexport function formatDiagnostic(d: Diagnostic): string {\n const loc = d.location !== undefined\n ? ` (${[d.location.file, d.location.line, d.location.column]\n .filter(Boolean)\n .join(':')})`\n : '';\n return `[${d.severity.toUpperCase()}] ${d.code}: ${d.message}${loc}`;\n}\n","/**\n * Compiler-phase validation of the ApplicationGraph.\n *\n * This runs after the DSL has built the graph but before the runtime\n * receives a CompiledApplication. More checks live here than in the\n * graph's own validate() because the compiler has broader context.\n */\n\nimport { DiagnosticCollector } from '@streetui/core';\nimport { ApplicationGraph, GraphNode } from '@streetui/graph';\n\nexport function validateGraph(graph: ApplicationGraph): DiagnosticCollector {\n const dc = new DiagnosticCollector();\n\n // Merge built-in graph validations\n dc.merge(graph.validate());\n\n // Must have at least one page\n const pages = graph.findByType('page');\n if (pages.length === 0) {\n dc.warn(\n 'COMPILER_NO_PAGES',\n 'Application has no pages defined. At least one page is recommended.',\n );\n }\n\n // Walk and validate individual nodes\n graph.walk((node) => {\n validateNode(node, dc);\n });\n\n return dc;\n}\n\nfunction validateNode(node: GraphNode, dc: DiagnosticCollector): void {\n switch (node.type) {\n case 'heading': {\n const text = node.getProp('text');\n if (text === undefined || text === '') {\n dc.warn('COMPILER_EMPTY_HEADING', `Heading node \"${node.id}\" has no text content`, {\n nodeId: node.id,\n });\n }\n break;\n }\n case 'image': {\n const src = node.getProp('src');\n const alt = node.getProp('alt');\n if (!src) {\n dc.error('COMPILER_IMAGE_NO_SRC', `Image node \"${node.id}\" is missing src`, {\n nodeId: node.id,\n });\n }\n if (!alt) {\n dc.warn('COMPILER_IMAGE_NO_ALT', `Image node \"${node.id}\" is missing alt text`, {\n nodeId: node.id,\n });\n }\n break;\n }\n case 'link': {\n const href = node.getProp('href');\n if (!href) {\n dc.error('COMPILER_LINK_NO_HREF', `Link node \"${node.id}\" is missing href`, {\n nodeId: node.id,\n });\n }\n break;\n }\n default:\n break;\n }\n}\n","/**\n * Graph transformation pass.\n *\n * After validation, the transformer prepares the graph for the runtime by:\n * - Resolving implicit defaults (e.g. heading level defaults to 1)\n * - Normalizing prop names\n * - Assigning deterministic render keys where missing\n * - Flattening / hoisting where beneficial\n */\n\nimport { ApplicationGraph, GraphNode } from '@streetui/graph';\n\nexport function transformGraph(graph: ApplicationGraph): void {\n graph.walk((node, depth) => {\n applyDefaults(node);\n ensureRenderKey(node, depth);\n });\n}\n\nfunction applyDefaults(node: GraphNode): void {\n switch (node.type) {\n case 'heading': {\n if (node.getProp('level') === undefined) {\n node.setProp('level', 1);\n }\n break;\n }\n case 'input': {\n if (node.getProp('inputType') === undefined) {\n node.setProp('inputType', 'text');\n }\n break;\n }\n case 'link': {\n if (node.getProp('external') === undefined) {\n node.setProp('external', false);\n }\n break;\n }\n default:\n break;\n }\n}\n\nfunction ensureRenderKey(node: GraphNode, depth: number): void {\n if (node.getProp('_renderKey') === undefined) {\n const key = node.key ?? `${node.type}:${node.id}:${depth}`;\n node.setProp('_renderKey', key);\n }\n}\n","/**\n * StreetUI compiler entry point.\n *\n * Pipeline:\n * StreetApp (DSL)\n * → ApplicationGraph (build)\n * → validate\n * → transform\n * → CompiledApplication\n */\n\nimport { DiagnosticCollector } from '@streetui/core';\nimport { type ApplicationGraph } from '@streetui/graph';\nimport { type StreetApp } from '@streetui/dsl';\nimport { validateGraph } from './validation/validator.js';\nimport { transformGraph } from './transform/transform.js';\n\nexport interface CompiledApplication {\n /** The fully built, validated, and transformed graph. */\n readonly graph: ApplicationGraph;\n /** Diagnostics accumulated during compilation. */\n readonly diagnostics: DiagnosticCollector;\n /** Metadata */\n readonly name: string;\n readonly version: string;\n readonly compiledAt: number;\n}\n\nexport interface CompileOptions {\n /** If true, compilation throws on errors. Defaults to true. */\n readonly strict?: boolean;\n /** If true, also throw on warnings. Defaults to false. */\n readonly strictWarnings?: boolean;\n}\n\n/**\n * Compile a StreetApp DSL definition into a CompiledApplication\n * ready for the runtime to execute.\n */\nexport function compile(\n app: StreetApp,\n options: CompileOptions = {},\n): CompiledApplication {\n const strict = options.strict ?? true;\n const strictWarnings = options.strictWarnings ?? false;\n const dc = new DiagnosticCollector();\n\n // 1. Build the graph from the DSL\n const graph = app.graph;\n\n // 2. Validate\n const validationDc = validateGraph(graph);\n dc.merge(validationDc);\n\n if (strict && dc.hasErrors) {\n dc.throwIfErrors();\n }\n if (strictWarnings && dc.hasWarnings) {\n throw new Error(\n `[StreetUI Compiler] Compilation failed: warnings treated as errors.\\n` +\n dc.diagnostics\n .filter(d => d.severity === 'warning')\n .map(d => ` [${d.code}] ${d.message}`)\n .join('\\n'),\n );\n }\n\n // 3. Transform\n transformGraph(graph);\n\n return {\n graph,\n diagnostics: dc,\n name: graph.name,\n version: graph.version,\n compiledAt: Date.now(),\n };\n}\n\n/**\n * Compile from a pre-built ApplicationGraph (used when the graph\n * was constructed programmatically rather than through the DSL).\n */\nexport function compileGraph(\n graph: ApplicationGraph,\n options: CompileOptions = {},\n): CompiledApplication {\n const strict = options.strict ?? true;\n const dc = new DiagnosticCollector();\n\n const validationDc = validateGraph(graph);\n dc.merge(validationDc);\n\n if (strict && dc.hasErrors) {\n dc.throwIfErrors();\n }\n\n transformGraph(graph);\n\n return {\n graph,\n diagnostics: dc,\n name: graph.name,\n version: graph.version,\n compiledAt: Date.now(),\n };\n}\n","/**\n * Browser implementation of DOMAdapter — delegates directly to browser APIs.\n */\n\nimport type { DOMAdapter } from './adapter.js';\n\nexport class BrowserDOMAdapter implements DOMAdapter {\n createElement(tag: string, ns?: string): Element {\n if (ns !== undefined) {\n return document.createElementNS(ns, tag);\n }\n return document.createElement(tag);\n }\n\n createTextNode(data: string): Text {\n return document.createTextNode(data);\n }\n\n createComment(data: string): Comment {\n return document.createComment(data);\n }\n\n createFragment(): DocumentFragment {\n return document.createDocumentFragment();\n }\n\n appendChild(parent: Node, child: Node): void {\n parent.appendChild(child);\n }\n\n insertBefore(parent: Node, child: Node, reference: Node | null): void {\n parent.insertBefore(child, reference);\n }\n\n removeChild(parent: Node, child: Node): void {\n parent.removeChild(child);\n }\n\n replaceChild(parent: Node, newChild: Node, oldChild: Node): void {\n parent.replaceChild(newChild, oldChild);\n }\n\n setAttribute(element: Element, name: string, value: string): void {\n element.setAttribute(name, value);\n }\n\n removeAttribute(element: Element, name: string): void {\n element.removeAttribute(name);\n }\n\n getAttribute(element: Element, name: string): string | null {\n return element.getAttribute(name);\n }\n\n setProperty(element: Element, name: string, value: unknown): void {\n (element as unknown as Record<string, unknown>)[name] = value;\n }\n\n setTextContent(node: Node, text: string): void {\n node.textContent = text;\n }\n\n getTextContent(node: Node): string | null {\n return node.textContent;\n }\n\n addEventListener(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n ): void {\n target.addEventListener(type, handler, options);\n }\n\n removeEventListener(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: EventListenerOptions,\n ): void {\n target.removeEventListener(type, handler, options);\n }\n\n querySelector(root: Element | Document, selector: string): Element | null {\n return root.querySelector(selector);\n }\n\n querySelectorAll(root: Element | Document, selector: string): NodeListOf<Element> {\n return root.querySelectorAll(selector);\n }\n\n getElementById(id: string): Element | null {\n return document.getElementById(id);\n }\n\n focus(element: Element): void {\n (element as unknown as { focus?: () => void }).focus?.();\n }\n\n body(): Element | null {\n return document.body ?? null;\n }\n\n head(): Element | null {\n return document.head ?? null;\n }\n\n activeElement(): Element | null {\n return document.activeElement ?? null;\n }\n\n contains(ancestor: Element, node: Node): boolean {\n return ancestor.contains(node);\n }\n\n matches(element: Element, selector: string): boolean {\n return typeof element.matches === 'function' && element.matches(selector);\n }\n\n isElement(node: Node): node is Element {\n return node.nodeType === Node.ELEMENT_NODE;\n }\n\n isTextNode(node: Node): node is Text {\n return node.nodeType === Node.TEXT_NODE;\n }\n\n tagName(element: Element): string {\n return element.tagName.toLowerCase();\n }\n\n parentNode(node: Node): Node | null {\n return node.parentNode;\n }\n\n nextSibling(node: Node): Node | null {\n return node.nextSibling;\n }\n\n firstChild(node: Node): Node | null {\n return node.firstChild;\n }\n\n childNodes(node: Node): Node[] {\n return Array.from(node.childNodes);\n }\n}\n\n// `/* @__PURE__ */`: convenience singleton, unreferenced by internal runtime\n// paths. Marking construction pure lets bundlers drop it when unused instead of\n// retaining it (and the BrowserDOMAdapter class) as an import-time side effect.\nexport const browserDOMAdapter = /* @__PURE__ */ new BrowserDOMAdapter();\n","/**\n * Server-side DOM node model.\n *\n * A tiny, dependency-free tree of plain objects that mirrors just enough of the\n * browser DOM for StreetUI's renderer to build a tree on the server and\n * serialize it to an HTML string. There is NO browser global here — these are\n * ordinary classes usable in any JavaScript environment (Node, workers, tests).\n *\n * The renderer never touches these types directly; it goes through the\n * `DOMAdapter` interface, and `ServerDOMAdapter` translates adapter calls into\n * operations on this model.\n */\n\nexport type ServerNodeKind = 'element' | 'text' | 'comment' | 'fragment' | 'raw';\n\nexport interface ServerNode {\n readonly kind: ServerNodeKind;\n parent: ServerParent | null;\n}\n\nexport type ServerParent = ServerElement | ServerFragment;\n\n/** A minimal inline-style holder mirroring `element.style.setProperty`. */\nexport class ServerStyle {\n readonly declarations = new Map<string, string>();\n setProperty(name: string, value: string): void {\n this.declarations.set(name, value);\n }\n get isEmpty(): boolean {\n return this.declarations.size === 0;\n }\n toCss(): string {\n return [...this.declarations.entries()].map(([k, v]) => `${k}: ${v}`).join('; ');\n }\n}\n\nexport class ServerText implements ServerNode {\n readonly kind = 'text' as const;\n parent: ServerParent | null = null;\n data: string;\n constructor(data: string) {\n this.data = data;\n }\n}\n\nexport class ServerComment implements ServerNode {\n readonly kind = 'comment' as const;\n parent: ServerParent | null = null;\n data: string;\n constructor(data: string) {\n this.data = data;\n }\n}\n\nexport class ServerFragment implements ServerNode {\n readonly kind = 'fragment' as const;\n parent: ServerParent | null = null;\n readonly children: ServerNode[] = [];\n}\n\n/**\n * A pre-serialized, verbatim HTML fragment (v1.7 static SSR plan).\n *\n * Emitted for provably-static subtrees whose HTML the compiler-derived static\n * SSR plan already computed once. Serializing this node copies its stored\n * string directly — it allocates no ServerElement/ServerText, no attribute Map\n * and no children array for the collapsed subtree. The stored `html` is\n * produced by the exact same mount + serialize pipeline as the runtime path, so\n * the output is byte-identical (the v1.7 byte-identity gate proves this).\n *\n * This node is SSR-only: it is created solely via `ServerDOMAdapter.createRawHTML`\n * on the server render path and never appears in a browser build.\n */\nexport class ServerRawHTML implements ServerNode {\n readonly kind = 'raw' as const;\n parent: ServerParent | null = null;\n readonly html: string;\n constructor(html: string) {\n this.html = html;\n }\n}\n\nexport class ServerElement implements ServerNode {\n readonly kind = 'element' as const;\n parent: ServerParent | null = null;\n readonly tagName: string;\n readonly attributes = new Map<string, string>();\n readonly children: ServerNode[] = [];\n\n // Lazily-allocated stores. On the 10k-row SSR corpus ~0% of elements carry JS\n // properties or inline styles (measured, §5: 1 of 80,029 elements uses\n // `properties`, 0 use `style`), so eagerly allocating a `properties` Map plus\n // a `ServerStyle` (which itself holds a Map) per element wasted ~240k\n // allocations per /users render — all in the dominant mount phase. These are\n // created on first WRITE via the `properties`/`style` getters; the serializer\n // reads the raw `_properties`/`_style` fields so a READ never forces an\n // allocation. Output is byte-identical: an unset store previously serialized\n // to nothing (empty `properties.has(...)` / `style.isEmpty`), and a null store\n // is skipped the same way.\n _properties: Map<string, unknown> | null = null;\n _style: ServerStyle | null = null;\n\n constructor(tagName: string) {\n this.tagName = tagName.toLowerCase();\n }\n\n /** JS properties set via `setProperty` (e.g. input `value`, `checked`). Allocated on first access. */\n get properties(): Map<string, unknown> {\n return (this._properties ??= new Map());\n }\n\n /** Inline-style holder mirroring `element.style`. Allocated on first access. */\n get style(): ServerStyle {\n return (this._style ??= new ServerStyle());\n }\n}\n\n// ── HTML serialization ─────────────────────────────────────────────────────────\n\n/**\n * HTML \"void\" elements — self-closing, never given a closing tag or children.\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n]);\n\n/**\n * Element properties that should be reflected into the serialized HTML so the\n * hydrated DOM carries the same initial state. `value`/`checked` matter for\n * form controls whose live state is a JS property, not an attribute.\n */\nconst SERIALIZED_PROPERTIES: Record<string, 'attr' | 'boolean'> = {\n value: 'attr',\n checked: 'boolean',\n selected: 'boolean',\n};\n\n/**\n * Precomputed `[name, kind]` pairs of SERIALIZED_PROPERTIES. Hoisted to module\n * scope so `serializeAttributes` does not allocate a fresh entries array for\n * every element serialized (measured hot: ~80k elements on the 10k-row route).\n */\nconst SERIALIZED_PROPERTY_ENTRIES: ReadonlyArray<readonly [string, 'attr' | 'boolean']> =\n Object.entries(SERIALIZED_PROPERTIES) as Array<[string, 'attr' | 'boolean']>;\n\n// Fast-path escaping. The chained `.replace(/…/g, …)` form makes 3–4 full\n// passes and allocates an intermediate string per pass even when nothing needs\n// escaping. These variants scan once and, in the overwhelmingly common case of\n// no special character, return the input unchanged (zero allocation). Output is\n// byte-identical to the chained form (verified over the real SSR corpus).\nconst TEXT_SPECIAL = /[&<>]/;\nconst ATTR_SPECIAL = /[&<>\"]/;\n\n/** Escape text node content. */\nexport function escapeHtmlText(value: string): string {\n if (!TEXT_SPECIAL.test(value)) return value;\n let out = '';\n let last = 0;\n for (let i = 0; i < value.length; i++) {\n let esc: string;\n switch (value.charCodeAt(i)) {\n case 38: esc = '&amp;'; break; // &\n case 60: esc = '&lt;'; break; // <\n case 62: esc = '&gt;'; break; // >\n default: continue;\n }\n out += value.slice(last, i) + esc;\n last = i + 1;\n }\n return out + value.slice(last);\n}\n\n/** Escape a double-quoted attribute value. */\nexport function escapeHtmlAttr(value: string): string {\n if (!ATTR_SPECIAL.test(value)) return value;\n let out = '';\n let last = 0;\n for (let i = 0; i < value.length; i++) {\n let esc: string;\n switch (value.charCodeAt(i)) {\n case 38: esc = '&amp;'; break; // &\n case 60: esc = '&lt;'; break; // <\n case 62: esc = '&gt;'; break; // >\n case 34: esc = '&quot;'; break; // \"\n default: continue;\n }\n out += value.slice(last, i) + esc;\n last = i + 1;\n }\n return out + value.slice(last);\n}\n\nfunction serializeAttributes(el: ServerElement): string {\n const parts: string[] = [];\n\n for (const [name, value] of el.attributes) {\n if (value === '') {\n parts.push(` ${name}`);\n } else {\n parts.push(` ${name}=\"${escapeHtmlAttr(value)}\"`);\n }\n }\n\n // Read the raw backing field (may be null): most elements have no JS\n // properties, so skipping the whole loop avoids touching a store that was\n // never allocated (§5).\n const props = el._properties;\n if (props !== null) {\n for (const [name, kind] of SERIALIZED_PROPERTY_ENTRIES) {\n if (!props.has(name)) continue;\n if (el.attributes.has(name)) continue; // an explicit attribute already won\n const raw = props.get(name);\n if (kind === 'boolean') {\n if (raw === true) parts.push(` ${name}`);\n } else {\n if (raw !== undefined && raw !== null) {\n parts.push(` ${name}=\"${escapeHtmlAttr(String(raw))}\"`);\n }\n }\n }\n }\n\n const style = el._style;\n if (style !== null && !style.isEmpty && !el.attributes.has('style')) {\n parts.push(` style=\"${escapeHtmlAttr(style.toCss())}\"`);\n }\n\n return parts.join('');\n}\n\n/** Serialize a single server node (element/text/comment/fragment/raw) to HTML. */\nexport function serializeServerNode(node: ServerNode): string {\n switch (node.kind) {\n case 'text':\n return escapeHtmlText((node as ServerText).data);\n case 'comment':\n return `<!--${(node as ServerComment).data}-->`;\n case 'fragment':\n return serializeChildren(node as ServerFragment);\n case 'raw':\n // Verbatim: the string was produced by this same serializer for a static\n // subtree, so it is already correctly escaped. Copy it as-is (§8).\n return (node as ServerRawHTML).html;\n case 'element': {\n const el = node as ServerElement;\n const tag = el.tagName;\n const attrs = serializeAttributes(el);\n if (VOID_ELEMENTS.has(tag)) {\n return `<${tag}${attrs}>`;\n }\n return `<${tag}${attrs}>${serializeChildren(el)}</${tag}>`;\n }\n }\n}\n\n/** Serialize the children of an element or fragment (its \"inner HTML\"). */\nexport function serializeChildren(node: ServerElement | ServerFragment): string {\n let out = '';\n for (const child of node.children) {\n out += serializeServerNode(child);\n }\n return out;\n}\n","/**\n * Server implementation of `DOMAdapter`.\n *\n * Builds a lightweight in-memory tree (see `server-node.ts`) instead of touching\n * a real browser DOM, then lets the caller serialize it to an HTML string. It is\n * completely free of browser globals, so the exact same renderer that runs in\n * the browser can produce HTML on the server.\n *\n * The `DOMAdapter` interface is typed against the lib DOM types (`Element`,\n * `Node`, `Text`, …). Our server nodes structurally stand in for those at\n * runtime, so the boundary uses `as unknown as` casts in one place. Everything\n * inside operates on the real server-node model.\n */\n\nimport type { DOMAdapter } from './adapter.js';\nimport {\n ServerElement,\n ServerText,\n ServerComment,\n ServerFragment,\n ServerRawHTML,\n serializeChildren,\n serializeServerNode,\n type ServerNode,\n type ServerParent,\n} from './server-node.js';\n\nfunction asServer(node: unknown): ServerNode {\n return node as unknown as ServerNode;\n}\nfunction asParent(node: unknown): ServerParent {\n return node as unknown as ServerParent;\n}\n\nexport class ServerDOMAdapter implements DOMAdapter {\n createElement(tag: string, _ns?: string): Element {\n return new ServerElement(tag) as unknown as Element;\n }\n\n createTextNode(data: string): Text {\n return new ServerText(data) as unknown as Text;\n }\n\n createComment(data: string): Comment {\n return new ServerComment(data) as unknown as Comment;\n }\n\n createFragment(): DocumentFragment {\n return new ServerFragment() as unknown as DocumentFragment;\n }\n\n /**\n * Create a verbatim pre-serialized HTML node (v1.7 static SSR plan, §6).\n * Server-only: the browser adapter does not implement this, and the renderer\n * fast path only invokes it when a static SSR plan is present (SSR). The\n * stored HTML was produced by this same serializer, so it is emitted as-is.\n */\n createRawHTML(html: string): Node {\n return new ServerRawHTML(html) as unknown as Node;\n }\n\n appendChild(parent: Node, child: Node): void {\n const p = asParent(parent);\n const c = asServer(child);\n this._detach(c);\n c.parent = p;\n p.children.push(c);\n }\n\n insertBefore(parent: Node, child: Node, reference: Node | null): void {\n const p = asParent(parent);\n const c = asServer(child);\n this._detach(c);\n c.parent = p;\n if (reference === null) {\n p.children.push(c);\n return;\n }\n const ref = asServer(reference);\n const idx = p.children.indexOf(ref);\n if (idx === -1) p.children.push(c);\n else p.children.splice(idx, 0, c);\n }\n\n removeChild(parent: Node, child: Node): void {\n const p = asParent(parent);\n const c = asServer(child);\n const idx = p.children.indexOf(c);\n if (idx !== -1) {\n p.children.splice(idx, 1);\n c.parent = null;\n }\n }\n\n replaceChild(parent: Node, newChild: Node, oldChild: Node): void {\n const p = asParent(parent);\n const nc = asServer(newChild);\n const oc = asServer(oldChild);\n const idx = p.children.indexOf(oc);\n if (idx === -1) return;\n this._detach(nc);\n nc.parent = p;\n p.children.splice(idx, 1, nc);\n oc.parent = null;\n }\n\n private _detach(node: ServerNode): void {\n if (node.parent !== null) {\n const siblings = node.parent.children;\n const idx = siblings.indexOf(node);\n if (idx !== -1) siblings.splice(idx, 1);\n node.parent = null;\n }\n }\n\n setAttribute(element: Element, name: string, value: string): void {\n (element as unknown as ServerElement).attributes.set(name, value);\n }\n\n removeAttribute(element: Element, name: string): void {\n (element as unknown as ServerElement).attributes.delete(name);\n }\n\n getAttribute(element: Element, name: string): string | null {\n return (element as unknown as ServerElement).attributes.get(name) ?? null;\n }\n\n setProperty(element: Element, name: string, value: unknown): void {\n (element as unknown as ServerElement).properties.set(name, value);\n }\n\n setTextContent(node: Node, text: string): void {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n const el = n as ServerElement | ServerFragment;\n el.children.length = 0;\n const t = new ServerText(text);\n t.parent = el;\n el.children.push(t);\n } else if (n.kind === 'text') {\n (n as ServerText).data = text;\n }\n }\n\n getTextContent(node: Node): string | null {\n const n = asServer(node);\n if (n.kind === 'text') return (n as ServerText).data;\n if (n.kind === 'element' || n.kind === 'fragment') {\n let out = '';\n for (const c of (n as ServerElement | ServerFragment).children) {\n out += this.getTextContent(c as unknown as Node) ?? '';\n }\n return out;\n }\n return null;\n }\n\n // Server nodes never dispatch events — listeners are a no-op on the server.\n addEventListener(): void {\n /* no-op on the server */\n }\n removeEventListener(): void {\n /* no-op on the server */\n }\n\n querySelector(): Element | null {\n return null;\n }\n querySelectorAll(): NodeListOf<Element> {\n return [] as unknown as NodeListOf<Element>;\n }\n getElementById(): Element | null {\n return null;\n }\n\n focus(): void {\n // No focus concept on the server — intentional no-op (SSR-safe).\n }\n\n body(): Element | null {\n // No document on the server — portals degrade to inline rendering.\n return null;\n }\n\n head(): Element | null {\n // No document on the server — head metadata is emitted as a string by\n // `renderHead()` instead of being applied to a live document.head.\n return null;\n }\n\n activeElement(): Element | null {\n return null;\n }\n\n contains(_ancestor: Element, _node: Node): boolean {\n return false;\n }\n\n matches(_element: Element, _selector: string): boolean {\n return false;\n }\n\n isElement(node: Node): node is Element {\n return asServer(node).kind === 'element';\n }\n\n isTextNode(node: Node): node is Text {\n return asServer(node).kind === 'text';\n }\n\n tagName(element: Element): string {\n return (element as unknown as ServerElement).tagName;\n }\n\n parentNode(node: Node): Node | null {\n return (asServer(node).parent as unknown as Node | null) ?? null;\n }\n\n nextSibling(node: Node): Node | null {\n const n = asServer(node);\n const parent = n.parent;\n if (parent === null) return null;\n const idx = parent.children.indexOf(n);\n if (idx === -1 || idx + 1 >= parent.children.length) return null;\n return parent.children[idx + 1] as unknown as Node;\n }\n\n firstChild(node: Node): Node | null {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n const el = n as ServerElement | ServerFragment;\n return (el.children[0] as unknown as Node) ?? null;\n }\n return null;\n }\n\n childNodes(node: Node): Node[] {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n return (n as ServerElement | ServerFragment).children as unknown as Node[];\n }\n return [];\n }\n\n // ── Server-only ────────────────────────────────────────────────────────────\n\n /** Serialize a node's children (\"inner HTML\") to an HTML string. */\n serializeInner(node: Node): string {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n return serializeChildren(n as ServerElement | ServerFragment);\n }\n return '';\n }\n\n /** Serialize a node (including itself) to an HTML string. */\n serializeOuter(node: Node): string {\n return serializeServerNode(asServer(node));\n }\n}\n\n// `/* @__PURE__ */`: this singleton is a convenience export only (no internal\n// runtime path references it). Marking construction pure lets bundlers drop it —\n// and with it the whole server serializer chain (serializeServerNode/escape/\n// VOID_ELEMENTS) — out of client bundles that never import SSR. Without this,\n// the un-annotated `new` is treated as a side effect and retained everywhere.\nexport const serverDOMAdapter = /* @__PURE__ */ new ServerDOMAdapter();\n","/**\n * Focus helpers built on the {@link DOMAdapter} abstraction.\n *\n * These are the minimal, genuinely-useful focus operations an app needs:\n * focus a specific element (e.g. the first field when a route or modal opens)\n * or focus the first focusable element inside a container (e.g. move focus\n * into a dialog). Both go through the adapter, so they are no-ops on the server\n * (`ServerDOMAdapter.querySelector` returns null / `focus` does nothing) and\n * therefore safe to call from universal code.\n */\n\nimport type { DOMAdapter } from './adapter.js';\n\n/** Default selector for natively focusable / tabbable elements. */\nexport const FOCUSABLE_SELECTOR =\n 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Focus the element with the given id, scoped to `root`.\n * Returns true if an element was found and focused.\n */\nexport function focusById(dom: DOMAdapter, root: Element | Document, id: string): boolean {\n const el = dom.querySelector(root, `[id=\"${id}\"]`);\n if (el === null) return false;\n dom.focus(el);\n return true;\n}\n\n/**\n * Focus the first focusable element inside `container`.\n * Returns true if a focusable element was found and focused.\n */\nexport function focusFirst(\n dom: DOMAdapter,\n container: Element | Document,\n selector: string = FOCUSABLE_SELECTOR,\n): boolean {\n const el = dom.querySelector(container, selector);\n if (el === null) return false;\n dom.focus(el);\n return true;\n}\n\n/**\n * Ordered list of focusable/tabbable descendants of `container`.\n * Re-checks each candidate against the selector so elements disabled after the\n * initial query (e.g. a button toggled to `disabled`) are excluded.\n */\nexport function getFocusable(\n dom: DOMAdapter,\n container: Element,\n selector: string = FOCUSABLE_SELECTOR,\n): Element[] {\n return Array.from(dom.querySelectorAll(container, selector)).filter((el) =>\n dom.matches(el, selector),\n );\n}\n\n/**\n * Capture the currently-focused element so it can be restored later (e.g. when\n * a dialog closes). Returns null on the server or when nothing is focused.\n */\nexport function saveFocus(dom: DOMAdapter): Element | null {\n return dom.activeElement();\n}\n\n/** Restore focus to a previously {@link saveFocus}-d element. No-op if null. */\nexport function restoreFocus(dom: DOMAdapter, saved: Element | null): void {\n if (saved !== null) dom.focus(saved);\n}\n\n/**\n * Move focus into `container` on open: the element with id `initialFocusId` if\n * given and present, otherwise the first focusable element. Server-safe no-op.\n */\nexport function focusInitial(\n dom: DOMAdapter,\n container: Element,\n initialFocusId?: string,\n): void {\n if (initialFocusId !== undefined && focusById(dom, container, initialFocusId)) return;\n focusFirst(dom, container);\n}\n\n/**\n * Trap Tab / Shift+Tab focus within `container` (wrap-around at both ends).\n * Attaches a keydown listener to the container and returns a cleanup function\n * that detaches it. Server-safe: `addEventListener` is a no-op, and the returned\n * cleanup is still callable.\n */\nexport function trapFocus(dom: DOMAdapter, container: Element): () => void {\n const onKeydown = ((event: KeyboardEvent): void => {\n if (event.key !== 'Tab') return;\n const items = getFocusable(dom, container);\n if (items.length === 0) {\n event.preventDefault();\n return;\n }\n const first = items[0]!;\n const last = items[items.length - 1]!;\n const active = dom.activeElement();\n if (active === null || !dom.contains(container, active)) {\n event.preventDefault();\n dom.focus(first);\n } else if (event.shiftKey && active === first) {\n event.preventDefault();\n dom.focus(last);\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n dom.focus(first);\n }\n }) as EventListener;\n dom.addEventListener(container, 'keydown', onKeydown);\n return () => dom.removeEventListener(container, 'keydown', onKeydown);\n}\n\n/**\n * Modal containment: if focus moves to an element outside `container`, redirect\n * it back inside. Listens on the document body (focusin bubbles there) and\n * returns a cleanup function. Server-safe no-op (body() is null).\n *\n * Nested modals (§16): every active containment pushes its container onto a\n * module-level stack, and a handler only redirects while ITS container is the\n * top of the stack — i.e. the most recently opened modal. This is the framework's\n * minimal \"focus owner\" concept: because overlay panels are relocated to\n * body-level portals (siblings, not descendants), two overlapping `containFocus`\n * handlers would otherwise fight over every `focusin`. The stack makes exactly\n * one owner authoritative at a time; cleanup pops it so the previous modal\n * resumes ownership. State is internal and torn down on cleanup — nothing is\n * retained on the graph (§18).\n */\nconst containmentStack: Element[] = [];\n\nexport function containFocus(dom: DOMAdapter, container: Element): () => void {\n const body = dom.body();\n if (body === null) return () => {};\n containmentStack.push(container);\n const onFocusIn = ((event: FocusEvent): void => {\n // Only the topmost owner enforces containment (nested-modal correctness).\n if (containmentStack[containmentStack.length - 1] !== container) return;\n const target = event.target as Node | null;\n if (target !== null && !dom.contains(container, target)) {\n focusFirst(dom, container);\n }\n }) as EventListener;\n dom.addEventListener(body, 'focusin', onFocusIn);\n return () => {\n dom.removeEventListener(body, 'focusin', onFocusIn);\n const index = containmentStack.lastIndexOf(container);\n if (index !== -1) containmentStack.splice(index, 1);\n };\n}\n\n/**\n * Invoke `handler` when Escape is pressed while focus is within `target`.\n * Returns a cleanup function. Server-safe no-op.\n */\nexport function onEscape(dom: DOMAdapter, target: Element, handler: () => void): () => void {\n const onKeydown = ((event: KeyboardEvent): void => {\n if (event.key === 'Escape') handler();\n }) as EventListener;\n dom.addEventListener(target, 'keydown', onKeydown);\n return () => dom.removeEventListener(target, 'keydown', onKeydown);\n}\n\n/**\n * Roving-focus keyboard navigation for a menu (role=\"menu\") container: the\n * arrow keys move focus between the container's focusable items (wrap-around at\n * both ends), Home/End jump to the first/last item, and Enter/Space activate\n * the currently-focused item (a native `click`, so an item's `onClick` fires).\n * `Tab` and `Escape` are deliberately left alone — the overlay layer wires\n * Escape-to-close separately and a menu does not trap Tab.\n *\n * Items are re-queried on every key (via {@link getFocusable}) so a menu whose\n * items change reactively is always navigated against the live set, and items\n * disabled after mount are skipped. Attaches a keydown listener to the\n * container and returns a cleanup function. Server-safe: `addEventListener` is\n * a no-op and the returned cleanup is still callable.\n */\nexport function rovingMenu(\n dom: DOMAdapter,\n container: Element,\n selector: string = FOCUSABLE_SELECTOR,\n): () => void {\n const onKeydown = ((event: KeyboardEvent): void => {\n const key = event.key;\n const isActivate = key === 'Enter' || key === ' ' || key === 'Spacebar';\n const isMove =\n key === 'ArrowDown' || key === 'ArrowUp' || key === 'Home' || key === 'End';\n if (!isActivate && !isMove) return;\n\n const items = getFocusable(dom, container, selector);\n if (items.length === 0) return;\n const active = dom.activeElement();\n const index = active === null ? -1 : items.indexOf(active);\n\n if (isActivate) {\n // Activating a menu item only makes sense when one is focused; otherwise\n // let the event fall through unchanged.\n if (index < 0) return;\n event.preventDefault();\n (items[index] as unknown as { click?: () => void }).click?.();\n return;\n }\n\n event.preventDefault();\n let next: number;\n if (key === 'Home') next = 0;\n else if (key === 'End') next = items.length - 1;\n else if (key === 'ArrowDown') next = index < 0 ? 0 : (index + 1) % items.length;\n else next = index <= 0 ? items.length - 1 : index - 1; // ArrowUp\n dom.focus(items[next]!);\n }) as EventListener;\n dom.addEventListener(container, 'keydown', onKeydown);\n return () => dom.removeEventListener(container, 'keydown', onKeydown);\n}\n\n","/**\n * RenderContext — shared state for a single mount operation.\n *\n * Passed through the render pipeline so every sub-function has access\n * to the DOM adapter, graph, and instance map without prop-drilling.\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport type { NodeInstance } from './node-instance.js';\nimport type { HydrationDiagnosticSink } from './hydration-diagnostics.js';\nimport type { HeadManager } from './head.js';\n\nexport interface RenderContext {\n readonly dom: DOMAdapter;\n readonly graph: ApplicationGraph;\n /** Maps GraphNode.id → its live NodeInstance */\n readonly instances: Map<string, NodeInstance>;\n /** The root container element. */\n readonly container: Element;\n /**\n * Optional dev-only sink that observes hydration mismatch repairs. When\n * absent (the default) the hydration path does no extra work — this is how\n * DevTools/diagnostics stay off the production runtime path.\n */\n readonly hydrationDiagnostics?: HydrationDiagnosticSink;\n /**\n * Optional SSR-only static-subtree plan (v1.7). Maps a maximal\n * static-subtree root GraphNode.id → its precomputed, verbatim HTML string.\n * Present only on the server render path when a plan has been built; on the\n * browser mount path it is always `undefined`, so the client hot path is\n * unaffected (a single `=== undefined` check short-circuits). When a mounted\n * node's id is in this map, the renderer emits the precomputed HTML via\n * `dom.createRawHTML` instead of recursively constructing the subtree.\n */\n readonly staticHTML?: ReadonlyMap<string, string>;\n /**\n * Lazily-created coordinator for `head()` metadata nodes (2.0 §1). Created on\n * first `wireHeadBehavior` call on the browser (never on the server, where\n * `dom.head()` is null and `renderHead` emits the metadata instead). Mutable\n * because it is attached on demand; a render with no `head()` nodes never\n * allocates one.\n */\n head?: HeadManager;\n}\n\nexport function createRenderContext(\n dom: DOMAdapter,\n graph: ApplicationGraph,\n container: Element,\n hydrationDiagnostics?: HydrationDiagnosticSink,\n staticHTML?: ReadonlyMap<string, string>,\n): RenderContext {\n return {\n dom,\n graph,\n instances: new Map(),\n container,\n ...(hydrationDiagnostics !== undefined ? { hydrationDiagnostics } : {}),\n ...(staticHTML !== undefined ? { staticHTML } : {}),\n };\n}\n","/**\n * NodeInstance — the renderer's live counterpart to a GraphNode.\n *\n * Tracks the actual DOM node(s), all signal subscriptions that drive\n * targeted DOM updates, and DOM event listener teardowns.\n */\n\nimport { CleanupRegistry } from '@streetui/core';\nimport type { GraphNode } from '@streetui/graph';\nimport type { ReadonlySignal } from '@streetui/state';\n\nexport class NodeInstance {\n readonly graphNode: GraphNode;\n /** The primary DOM node for this instance (element or text node). */\n domNode: Node;\n readonly children: NodeInstance[] = [];\n readonly cleanup: CleanupRegistry = new CleanupRegistry();\n\n constructor(graphNode: GraphNode, domNode: Node) {\n this.graphNode = graphNode;\n this.domNode = domNode;\n }\n\n addChild(child: NodeInstance): void {\n this.children.push(child);\n }\n\n /** Subscribe to a signal; auto-cleanup on unmount. */\n trackSignal<T>(sig: ReadonlySignal<T>, handler: (v: T) => void): void {\n const unsub = sig.subscribe(handler);\n this.cleanup.add(unsub);\n }\n\n /** Register a raw cleanup fn (DOM event removal, etc.). */\n trackCleanup(fn: () => void): void {\n this.cleanup.add(fn);\n }\n\n dispose(): void {\n for (const child of this.children) {\n child.dispose();\n }\n this.cleanup.run();\n }\n}\n","/**\n * Attribute and property application helpers.\n *\n * Decides whether a prop should be set as a DOM attribute or a JS property,\n * handling special cases (boolean attrs, event-like props, style, class).\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\n\n// Properties that must be set as JS object properties, not HTML attributes\nconst DOM_PROPERTIES = new Set([\n 'value', 'checked', 'selected', 'indeterminate',\n 'innerHTML', 'textContent', 'innerText',\n 'scrollTop', 'scrollLeft',\n]);\n\n// Boolean attributes — present means true, absent means false\nconst BOOLEAN_ATTRS = new Set([\n 'disabled', 'readonly', 'required', 'checked', 'selected',\n 'multiple', 'autofocus', 'autoplay', 'controls', 'default',\n 'defer', 'formnovalidate', 'hidden', 'ismap', 'loop',\n 'novalidate', 'open', 'reversed', 'scoped', 'seamless',\n]);\n\nexport function applyProp(\n dom: DOMAdapter,\n element: Element,\n name: string,\n value: unknown,\n): void {\n // Skip internal renderer metadata\n if (name.startsWith('_')) return;\n // Skip event handlers (handled separately)\n if (name.startsWith('on')) return;\n\n if (DOM_PROPERTIES.has(name)) {\n dom.setProperty(element, name, value);\n return;\n }\n\n if (BOOLEAN_ATTRS.has(name)) {\n if (value === true || value === '' || value === name) {\n dom.setAttribute(element, name, '');\n } else {\n dom.removeAttribute(element, name);\n }\n return;\n }\n\n if (name === 'class' || name === 'className') {\n dom.setAttribute(element, 'class', String(value ?? ''));\n return;\n }\n\n if (name === 'style' && typeof value === 'object' && value !== null) {\n const el = element as HTMLElement;\n const styles = value as Record<string, string>;\n for (const [k, v] of Object.entries(styles)) {\n el.style.setProperty(k, v);\n }\n return;\n }\n\n if (value === null || value === undefined || value === false) {\n dom.removeAttribute(element, name);\n return;\n }\n\n dom.setAttribute(element, name, String(value));\n}\n\nexport function patchProp(\n dom: DOMAdapter,\n element: Element,\n name: string,\n oldValue: unknown,\n newValue: unknown,\n): void {\n if (Object.is(oldValue, newValue)) return;\n applyProp(dom, element, name, newValue);\n}\n","/**\n * Event wiring for the renderer.\n *\n * Given a GraphNode with event descriptors, this wires DOM listeners\n * that call the handlers stored in the graph's handler registry.\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport type { NodeInstance } from './node-instance.js';\n\nexport function wireEvents(\n dom: DOMAdapter,\n graph: ApplicationGraph,\n node: GraphNode,\n element: Element,\n instance: NodeInstance,\n): void {\n // Fast exit for event-free nodes — avoids allocating a for-of iterator over\n // an empty array on every node during a large mount/hydrate.\n if (node.events.length === 0) return;\n for (const eventDesc of node.events) {\n const handler = graph.getHandler(eventDesc.handlerKey);\n if (handler === undefined) continue;\n\n const domListener: EventListener = (domEvent: Event) => {\n // For input events, pass the current value as first arg\n if (eventDesc.type === 'input' || eventDesc.type === 'change') {\n const input = domEvent.target as HTMLInputElement;\n (handler as (v: string) => void)(input.value);\n } else if (eventDesc.type === 'submit') {\n domEvent.preventDefault();\n (handler as (e: Event) => void)(domEvent);\n } else {\n (handler as () => void)();\n }\n };\n\n dom.addEventListener(element, eventDesc.type, domListener);\n instance.trackCleanup(() => {\n dom.removeEventListener(element, eventDesc.type, domListener);\n });\n }\n}\n","/**\n * Maps semantic node types to HTML tag names.\n */\n\nimport type { SemanticNodeType } from '@streetui/core';\n\nconst TAG_MAP: Partial<Record<SemanticNodeType, string>> = {\n application: 'div',\n page: 'div',\n section: 'section',\n container: 'div',\n heading: 'h1',\n text: 'span',\n button: 'button',\n input: 'input',\n form: 'form',\n list: 'ul',\n 'list-item': 'li',\n image: 'img',\n link: 'a',\n component: 'div',\n slot: 'div',\n fragment: 'div',\n 'reactive-list': 'ul',\n // A portal renders as a neutral inline anchor <div> at its declaration site;\n // its children are relocated to a document.body container on the browser\n // (see the portal branch in mount.ts). On the server (no body) it renders\n // inline, so the anchor tag is what SSR/hydration positionally match on.\n portal: 'div',\n // A `head()` node renders as a neutral, empty inline anchor <div> at its\n // declaration site (like a portal anchor). Its actual contribution — title/\n // meta/link/etc. — is applied to `document.head` by `wireHeadBehavior` on the\n // browser, and emitted separately by `renderHead()` on the server. Keeping a\n // one-node/one-element anchor preserves positional hydration.\n head: 'div',\n};\n\nexport function resolveTag(type: SemanticNodeType): string {\n return TAG_MAP[type] ?? 'div';\n}\n","/**\n * Patch — targeted DOM updates driven by signal changes.\n *\n * When a signal fires, we look up the NodeInstance and apply\n * only the changed prop — no full re-render, no tree diffing.\n */\n\nimport type { RenderContext } from './render-context.js';\nimport type { GraphNode } from '@streetui/graph';\nimport { applyProp, patchProp } from './attributes.js';\n\nexport function patchNode(\n ctx: RenderContext,\n graphNode: GraphNode,\n propKey: string,\n newValue: unknown,\n): void {\n const instance = ctx.instances.get(graphNode.id);\n if (instance === undefined) return;\n\n const domNode = instance.domNode;\n if (!ctx.dom.isElement(domNode)) return;\n\n const oldValue = graphNode.getProp(propKey);\n\n switch (propKey) {\n case 'text':\n if (!Object.is(oldValue, newValue)) {\n ctx.dom.setTextContent(domNode, String(newValue ?? ''));\n graphNode.setProp('text', String(newValue ?? ''));\n }\n break;\n case 'label':\n if (!Object.is(oldValue, newValue)) {\n ctx.dom.setTextContent(domNode, String(newValue ?? ''));\n graphNode.setProp('label', String(newValue ?? ''));\n }\n break;\n case 'disabled':\n if (newValue === true) {\n ctx.dom.setAttribute(domNode, 'disabled', '');\n } else {\n ctx.dom.removeAttribute(domNode, 'disabled');\n }\n graphNode.setProp('disabled', Boolean(newValue));\n break;\n case 'value':\n if (!Object.is(oldValue, newValue)) {\n ctx.dom.setProperty(domNode, 'value', String(newValue ?? ''));\n graphNode.setProp('value', String(newValue ?? ''));\n }\n break;\n default:\n patchProp(ctx.dom, domNode, propKey, oldValue, newValue);\n graphNode.setProp(propKey, newValue as string);\n break;\n }\n}\n","/**\n * Reconciliation — diff-based child list updates.\n *\n * When the children of a node change (e.g. a list driven by state),\n * this reconciler:\n * 1. Matches old instances to new graph nodes by key\n * 2. Reuses matched instances (updates their props)\n * 3. Applies a targeted content update to a reused item whose data changed\n * 4. Creates new instances for additions\n * 5. Removes stale instances (and prunes their handler registrations)\n * 6. Moves DOM nodes to match new order\n *\n * This is keyed reconciliation over the semantic graph — there is no virtual\n * DOM. A reused item keeps its own DOM element; only its changed content is\n * updated in place (falling back to remounting a subtree only where its shape\n * actually changed).\n */\n\nimport type { RenderContext } from './render-context.js';\nimport type { GraphNode } from '@streetui/graph';\nimport type { NodeInstance } from './node-instance.js';\nimport type { TransitionHooks } from './transition.js';\nimport { patchNode } from './patch.js';\n\nexport type MountFn = (node: GraphNode, parent: Element) => NodeInstance;\n\nexport interface ReconcileResult {\n /** Instances in the new order. */\n instances: NodeInstance[];\n /** Instances that were removed and must be disposed. */\n removed: NodeInstance[];\n /**\n * GraphNodes freshly materialised during this reconcile (new rows + rebuilt\n * changed rows). The caller detaches any of these that were not adopted as a\n * live instance's graph node, so no orphan subtree lingers in the graph index.\n */\n built?: GraphNode[];\n}\n\n/**\n * A lazy reconciliation descriptor for one reactive-list row (mirrors the DSL's\n * `ListPlanEntry`). `sig()` and `build()` are only invoked for rows that are\n * genuinely new or whose source reference changed — the whole point of the\n * plan path (spec §15).\n */\nexport interface PlanEntry {\n readonly key: string;\n readonly item: unknown;\n readonly sig: () => string;\n readonly build: () => GraphNode;\n}\n\n/**\n * Reconcile children of a container element against a new list of graph nodes.\n *\n * @param ctx Render context\n * @param parentDom The DOM parent element\n * @param oldInstances Current child instances (in order)\n * @param newNodes New graph children (in desired order)\n * @param mountFn Factory to create a new NodeInstance for a graph node\n */\nexport function reconcileChildren(\n ctx: RenderContext,\n parentDom: Element,\n oldInstances: NodeInstance[],\n newNodes: readonly GraphNode[],\n mountFn: MountFn,\n hooks?: TransitionHooks,\n): ReconcileResult {\n // Build key → old instance map\n const oldByKey = new Map<string, NodeInstance>();\n for (const inst of oldInstances) {\n const key = inst.graphNode.key ?? inst.graphNode.id;\n oldByKey.set(key, inst);\n }\n\n const newInstances: NodeInstance[] = [];\n const usedKeys = new Set<string>();\n\n for (const newNode of newNodes) {\n const key = newNode.key ?? newNode.id;\n const existing = oldByKey.get(key);\n\n if (existing !== undefined) {\n // Reuse — identity is stable, so the DOM element is preserved.\n usedKeys.add(key);\n const oldSig = existing.graphNode.getProp('_sig');\n const newSig = newNode.getProp('_sig');\n patchExistingInstance(ctx, existing, newNode);\n // Data changed but identity did not → targeted content update in place.\n if (!Object.is(oldSig, newSig)) {\n reconcileItemChildren(ctx, existing, newNode, mountFn);\n }\n newInstances.push(existing);\n } else {\n // Leave→enter cancellation (§6): if this key is currently animating out,\n // reclaim its live instance instead of mounting a duplicate.\n const reclaimed = hooks?.takeLeaving(key);\n if (reclaimed !== undefined) {\n patchExistingInstance(ctx, reclaimed, newNode);\n reconcileItemChildren(ctx, reclaimed, newNode, mountFn);\n hooks?.onEnter(reclaimed);\n newInstances.push(reclaimed);\n } else {\n // New — create and mount, then play its enter animation (if any).\n const inst = mountFn(newNode, parentDom);\n hooks?.onEnter(inst);\n newInstances.push(inst);\n }\n }\n }\n\n // Determine + remove stale instances. A removed instance that carries a\n // transition has its DOM-remove + dispose deferred to leave-animation end by\n // `beginLeave` (which then also forgets + detaches it), so it is excluded from\n // `removed` and the caller does not tear it down (§3/§7).\n const removed: NodeInstance[] = [];\n for (const inst of oldInstances) {\n const key = inst.graphNode.key ?? inst.graphNode.id;\n if (usedKeys.has(key)) continue;\n if (hooks !== undefined && hooks.beginLeave(inst)) continue;\n const parent = ctx.dom.parentNode(inst.domNode);\n if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);\n inst.dispose();\n removed.push(inst);\n }\n\n // Reorder DOM nodes to match new order\n reorderDom(ctx, parentDom, newInstances);\n\n return { instances: newInstances, removed };\n}\n\n/**\n * Plan-based keyed reconciliation (spec §15 — the optimised reactive-list path).\n *\n * Identical observable result to {@link reconcileChildren}, but driven by lazy\n * {@link PlanEntry} descriptors instead of a pre-built array of GraphNodes:\n *\n * - a reused row whose `item` reference is unchanged does **zero** work — no\n * signature hash, no subtree build, no prop patch (the common case for\n * append / prepend / remove / reorder / reverse, where existing item objects\n * keep their identity);\n * - a reused row whose reference changed hashes lazily and, only on a real\n * signature change, materialises a fresh subtree for a targeted in-place\n * content update;\n * - a genuinely new key builds + mounts exactly one subtree.\n *\n * DOM reordering uses a longest-increasing-subsequence pass so the number of\n * moves is minimal (e.g. a prepend into a 10k list moves 1 node, not 10k).\n */\nexport function reconcileChildrenByPlan(\n ctx: RenderContext,\n parentDom: Element,\n oldInstances: NodeInstance[],\n plan: readonly PlanEntry[],\n mountFn: MountFn,\n hooks?: TransitionHooks,\n): ReconcileResult {\n const oldByKey = new Map<string, NodeInstance>();\n for (const inst of oldInstances) {\n oldByKey.set(inst.graphNode.key ?? inst.graphNode.id, inst);\n }\n\n const newInstances: NodeInstance[] = [];\n const usedKeys = new Set<string>();\n const built: GraphNode[] = [];\n\n for (const entry of plan) {\n const existing = oldByKey.get(entry.key);\n if (existing !== undefined) {\n usedKeys.add(entry.key);\n const oldItem = existing.graphNode.getProp('_item');\n // Identity short-circuit: same reference ⇒ data cannot have changed.\n if (!Object.is(oldItem, entry.item)) {\n const newSig = entry.sig();\n const oldSig = existing.graphNode.getProp('_sig');\n if (!Object.is(oldSig, newSig)) {\n const freshNode = entry.build();\n built.push(freshNode);\n patchExistingInstance(ctx, existing, freshNode);\n reconcileItemChildren(ctx, existing, freshNode, mountFn);\n existing.graphNode.setProp('_sig', newSig);\n }\n // Cache the new reference so the next pass can short-circuit again.\n existing.graphNode.setProp('_item', entry.item as never);\n }\n newInstances.push(existing);\n } else {\n // Leave→enter reclaim (§6/§7): a key removed then re-added mid-leave keeps\n // its identity and its live DOM node rather than mounting a duplicate.\n const reclaimed = hooks?.takeLeaving(entry.key);\n if (reclaimed !== undefined) {\n const freshNode = entry.build();\n built.push(freshNode);\n patchExistingInstance(ctx, reclaimed, freshNode);\n reconcileItemChildren(ctx, reclaimed, freshNode, mountFn);\n reclaimed.graphNode.setProp('_sig', freshNode.getProp('_sig') as never);\n reclaimed.graphNode.setProp('_item', entry.item as never);\n hooks?.onEnter(reclaimed);\n newInstances.push(reclaimed);\n } else {\n const freshNode = entry.build();\n built.push(freshNode);\n const inst = mountFn(freshNode, parentDom);\n hooks?.onEnter(inst);\n newInstances.push(inst);\n }\n }\n }\n\n // Determine + remove stale instances. Transitioned rows defer their whole\n // teardown chain to leave-animation end (§7) and are excluded from `removed`.\n const removed: NodeInstance[] = [];\n for (const inst of oldInstances) {\n const key = inst.graphNode.key ?? inst.graphNode.id;\n if (usedKeys.has(key)) continue;\n if (hooks !== undefined && hooks.beginLeave(inst)) continue;\n const parent = ctx.dom.parentNode(inst.domNode);\n if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);\n inst.dispose();\n removed.push(inst);\n }\n\n // Minimal-move reorder to the desired order.\n reorderDomMinimal(ctx, parentDom, oldInstances, newInstances);\n\n return { instances: newInstances, removed, built };\n}\n\n/**\n * Minimal-move DOM reorder.\n *\n * Reused nodes retain their previous DOM slots and newly-mounted nodes sit at\n * the end. We compute the longest increasing subsequence of the reused nodes'\n * previous positions; those are already in correct relative order and stay put.\n * Every other node is inserted before its right-hand neighbour, walking\n * right-to-left. This yields exactly (n − |LIS|) `insertBefore` calls — the\n * minimum — instead of the O(n) sweep the naive reorder performs on a prepend.\n */\nfunction reorderDomMinimal(\n ctx: RenderContext,\n parentDom: Element,\n oldInstances: NodeInstance[],\n newInstances: NodeInstance[],\n): void {\n const n = newInstances.length;\n if (n === 0) return;\n\n const oldIndexOf = new Map<NodeInstance, number>();\n for (let i = 0; i < oldInstances.length; i++) oldIndexOf.set(oldInstances[i]!, i);\n\n const source = new Array<number>(n);\n let moved = false;\n let lastSeen = -1;\n for (let i = 0; i < n; i++) {\n const oi = oldIndexOf.get(newInstances[i]!);\n if (oi === undefined) {\n source[i] = -1; // freshly mounted row\n moved = true;\n } else {\n source[i] = oi;\n if (oi < lastSeen) moved = true; // an out-of-order reused row exists\n else lastSeen = oi;\n }\n }\n\n // Fast path: nothing is out of order and there are no new rows to reposition.\n if (!moved) return;\n\n const keep = longestIncreasingSubsequence(source);\n\n let refNode: Node | null = null;\n for (let i = n - 1; i >= 0; i--) {\n const domNode = newInstances[i]!.domNode;\n if (source[i] === -1 || !keep.has(i)) {\n if (ctx.dom.nextSibling(domNode) !== refNode) {\n ctx.dom.insertBefore(parentDom, domNode, refNode);\n }\n }\n refNode = domNode;\n }\n}\n\n/**\n * Indices (into `source`) forming a longest strictly-increasing subsequence,\n * ignoring `-1` entries (new rows, which always move). O(n log n) with\n * predecessor reconstruction.\n */\nfunction longestIncreasingSubsequence(source: readonly number[]): Set<number> {\n const keep = new Set<number>();\n const n = source.length;\n const tails: number[] = []; // tails[k] = source-index of smallest tail of an LIS of length k+1\n const prev = new Array<number>(n).fill(-1);\n\n for (let i = 0; i < n; i++) {\n const v = source[i]!;\n if (v < 0) continue;\n let lo = 0;\n let hi = tails.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (source[tails[mid]!]! < v) lo = mid + 1;\n else hi = mid;\n }\n if (lo > 0) prev[i] = tails[lo - 1]!;\n tails[lo] = i;\n }\n\n let idx = tails.length > 0 ? tails[tails.length - 1]! : -1;\n while (idx >= 0) {\n keep.add(idx);\n idx = prev[idx]!;\n }\n return keep;\n}\n\n/**\n * Targeted in-place content update for a reused list item whose data changed.\n *\n * The item's DOM element is kept; only its contents are updated. Children are\n * matched positionally against the freshly-built subtree:\n * - same node type at a position → the existing child is reused and its props\n * are patched in place (e.g. a text node's text is rewritten), then we\n * recurse into its children;\n * - different type / new position → the fresh child node is reparented onto the\n * live item node and mounted;\n * - surplus old children → disposed, with DOM, subscriptions, listeners and\n * handler registrations all torn down.\n *\n * This deliberately reuses the same keyed/positional strategy rather than a\n * virtual DOM, and never destroys the item element itself.\n */\nfunction reconcileItemChildren(\n ctx: RenderContext,\n itemInstance: NodeInstance,\n newItemNode: GraphNode,\n mountFn: MountFn,\n): void {\n const el = itemInstance.domNode;\n if (!ctx.dom.isElement(el)) return;\n\n const oldChildren = [...itemInstance.children];\n const newChildNodes = [...newItemNode.children];\n const nextChildren: NodeInstance[] = [];\n const kept = new Set<NodeInstance>();\n\n for (let i = 0; i < newChildNodes.length; i++) {\n const newChild = newChildNodes[i]!;\n const oldChild = oldChildren[i];\n\n if (oldChild !== undefined && oldChild.graphNode.type === newChild.type) {\n // Reuse in place — patch this node's props and recurse into descendants.\n patchExistingInstance(ctx, oldChild, newChild);\n reconcileItemChildren(ctx, oldChild, newChild, mountFn);\n nextChildren.push(oldChild);\n kept.add(oldChild);\n } else {\n // Structural change at this position — mount the fresh child. Reparent it\n // out of the freshly-built subtree so the wholesale detach of the\n // unadopted item node (in mount.ts) does not remove this now-live node.\n itemInstance.graphNode.appendChild(newChild);\n const inst = mountFn(newChild, el);\n nextChildren.push(inst);\n }\n }\n\n // Dispose old children that were not reused (surplus or type-mismatched).\n for (const old of oldChildren) {\n if (kept.has(old)) continue;\n const parent = ctx.dom.parentNode(old.domNode);\n if (parent !== null) ctx.dom.removeChild(parent, old.domNode);\n old.dispose();\n forgetInstanceTree(ctx, old);\n ctx.graph.detachNode(old.graphNode);\n }\n\n // Restore correct DOM order within the item element.\n reorderDom(ctx, el, nextChildren);\n\n // Sync the live instance's children.\n itemInstance.children.length = 0;\n for (const c of nextChildren) itemInstance.children.push(c);\n\n // Keep the graph model's item children consistent with the reconciled order.\n for (const c of [...itemInstance.graphNode.children]) {\n itemInstance.graphNode.removeChild(c);\n }\n for (const c of nextChildren) itemInstance.graphNode.appendChild(c.graphNode);\n}\n\n/** Move a parent's DOM children to match the given instance order (minimal moves). */\nfunction reorderDom(\n ctx: RenderContext,\n parentDom: Element,\n instances: NodeInstance[],\n): void {\n let referenceNode: Node | null = null;\n for (let i = instances.length - 1; i >= 0; i--) {\n const inst = instances[i];\n if (inst === undefined) continue;\n const domNode = inst.domNode;\n const currentNext = ctx.dom.nextSibling(domNode);\n if (currentNext !== referenceNode) {\n ctx.dom.insertBefore(parentDom, domNode, referenceNode);\n }\n referenceNode = domNode;\n }\n}\n\n/** Recursively drop an instance subtree from the renderer's instance index. */\nfunction forgetInstanceTree(ctx: RenderContext, instance: NodeInstance): void {\n ctx.instances.delete(instance.graphNode.id);\n for (const child of instance.children) forgetInstanceTree(ctx, child);\n}\n\nfunction patchExistingInstance(\n ctx: RenderContext,\n instance: NodeInstance,\n newNode: GraphNode,\n): void {\n const oldNode = instance.graphNode;\n for (const [key, newVal] of Object.entries(newNode.props)) {\n const oldVal = oldNode.getProp(key);\n if (!Object.is(oldVal, newVal)) {\n patchNode(ctx, instance.graphNode, key, newVal);\n }\n }\n}\n","/**\n * CSS class-based enter/leave transition controller (§2–§8).\n *\n * This is the browser-only runtime that consumes the `__transition__<nodeId>`\n * descriptor the DSL registers (a pre-resolved {@link ResolvedTransitionLike}).\n * It is deliberately structural about that descriptor — like the renderer's\n * `__overlay__`/`__component__` handling — so the renderer takes NO compile-time\n * dependency on the DSL package.\n *\n * Engine (confirmed decision): CSS classes, no Web Animations API, no\n * browser-only API referenced at module scope. Every timer / rAF / event\n * binding is reached lazily through `globalThis` and only ever runs when\n * `dom.body() !== null` (the same SSR guard `wireOverlayBehavior` uses), so:\n * - server output is byte-identical (nothing here runs during SSR — §21);\n * - happy-dom, which dispatches no `transitionend`/`animationend`, still\n * completes deterministically via the fallback timeout (§24).\n *\n * The controller is created once per reactive container instance (reactive-list\n * or conditional) so its `leaving` map survives across reconcile passes — that\n * is what makes leave→enter reclaim (§6) and keyed-identity list leave (§7)\n * correct.\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport type { NodeInstance } from './node-instance.js';\n\n/**\n * The renderer's structural view of the resolved transition the DSL stores in\n * `__transition__<id>`. Mirrors `@streetui/dsl`'s `ResolvedTransition` without\n * importing it (no renderer→dsl dependency).\n */\nexport interface ResolvedTransitionLike {\n readonly enterActive: readonly string[];\n readonly enterFrom: readonly string[];\n readonly enterTo: readonly string[];\n readonly leaveActive: readonly string[];\n readonly leaveFrom: readonly string[];\n readonly leaveTo: readonly string[];\n readonly appear: boolean;\n readonly duration: number;\n}\n\n/**\n * Hooks handed to the reconciler so it can (a) reclaim an instance that is\n * mid-leave when its key re-enters (leave→enter cancellation), (b) defer the\n * remove/dispose/forget/detach chain for a leaving instance until its animation\n * ends, and (c) play the enter animation for a freshly-inserted instance. When\n * no transition applies (or we are on the server) every hook degrades to the\n * pre-transition synchronous behaviour.\n */\nexport interface TransitionHooks {\n /**\n * If an instance for `key` is currently animating out, cancel its leave and\n * return it for reuse; otherwise undefined. The caller re-mounts nothing and\n * reuses the returned instance's live DOM node.\n */\n takeLeaving(key: string): NodeInstance | undefined;\n /**\n * Begin a leave animation for a removed instance. Returns true when the whole\n * teardown chain has been deferred to animation-end (caller must NOT remove,\n * dispose, forget or detach it), or false when there is no transition / no\n * browser and the caller should tear it down synchronously as before.\n */\n beginLeave(inst: NodeInstance): boolean;\n /** Play the enter animation for a freshly-inserted (or reclaimed) instance. */\n onEnter(inst: NodeInstance): void;\n}\n\n/** Read the pre-resolved transition descriptor for a node, if any. */\nexport function getResolvedTransition(\n graph: ApplicationGraph,\n nodeId: string,\n): ResolvedTransitionLike | undefined {\n const fn = graph.getHandler(`__transition__${nodeId}`) as\n | (() => ResolvedTransitionLike)\n | undefined;\n return fn === undefined ? undefined : fn();\n}\n\n// ── Browser-global access (lazy, never at module scope) ──────────────────────\n\ninterface RafHost {\n requestAnimationFrame?: (cb: () => void) => number;\n setTimeout: (cb: () => void, ms: number) => unknown;\n clearTimeout: (h: unknown) => void;\n}\n\nfunction host(): RafHost {\n return globalThis as unknown as RafHost;\n}\n\n/** Schedule a callback for the next frame (falls back to a macrotask). */\nfunction nextFrame(cb: () => void): void {\n const h = host();\n const raf = h.requestAnimationFrame;\n if (typeof raf === 'function') {\n // Double rAF: ensures the \"from\" classes have been painted before we flip\n // to the \"to\" classes, so the transition actually runs in real browsers.\n raf(() => raf(cb));\n } else {\n h.setTimeout(cb, 0);\n }\n}\n\n// ── Class list manipulation via the adapter (no classList dependency) ─────────\n\nfunction splitClass(value: string | null): string[] {\n if (value === null) return [];\n const out: string[] = [];\n for (const t of value.split(/\\s+/)) if (t.length > 0) out.push(t);\n return out;\n}\n\nfunction addClasses(dom: DOMAdapter, el: Element, classes: readonly string[]): void {\n if (classes.length === 0) return;\n const current = splitClass(dom.getAttribute(el, 'class'));\n let changed = false;\n for (const c of classes) {\n if (!current.includes(c)) {\n current.push(c);\n changed = true;\n }\n }\n if (changed) dom.setAttribute(el, 'class', current.join(' '));\n}\n\nfunction removeClasses(dom: DOMAdapter, el: Element, classes: readonly string[]): void {\n if (classes.length === 0) return;\n const current = splitClass(dom.getAttribute(el, 'class'));\n const next = current.filter((c) => !classes.includes(c));\n if (next.length !== current.length) {\n if (next.length === 0) dom.removeAttribute(el, 'class');\n else dom.setAttribute(el, 'class', next.join(' '));\n }\n}\n\n/**\n * One running enter-or-leave animation on a single element. Owns exactly one set\n * of DOM listeners + one fallback timer, and guarantees `settle`/`cancel` run\n * their cleanup at most once — no stale callbacks, no duplicate listeners, no\n * duplicate cleanup (§6).\n */\ninterface Run {\n /** Force the animation to its end synchronously (used by cancellation). */\n cancel(): void;\n}\n\nfunction startRun(\n dom: DOMAdapter,\n el: Element,\n active: readonly string[],\n from: readonly string[],\n to: readonly string[],\n duration: number,\n onDone: () => void,\n): Run {\n const h = host();\n let finished = false;\n let timer: unknown = null;\n\n const onEvent = ((e: Event): void => {\n // Ignore bubbling transition/animation events from descendants.\n if (e.target !== el) return;\n finish();\n }) as EventListener;\n\n const detach = (): void => {\n dom.removeEventListener(el, 'transitionend', onEvent);\n dom.removeEventListener(el, 'animationend', onEvent);\n if (timer !== null) {\n h.clearTimeout(timer);\n timer = null;\n }\n };\n\n const finish = (): void => {\n if (finished) return;\n finished = true;\n detach();\n // Clear all transition classes so the element rests in its natural state.\n removeClasses(dom, el, active);\n removeClasses(dom, el, to);\n removeClasses(dom, el, from);\n onDone();\n };\n\n // Phase 1: apply the starting + active classes immediately.\n addClasses(dom, el, from);\n addClasses(dom, el, active);\n\n dom.addEventListener(el, 'transitionend', onEvent);\n dom.addEventListener(el, 'animationend', onEvent);\n // Fallback completion: the safety net for elements that fire no transition\n // event (and the ONLY completion signal under happy-dom, where tests set a\n // small duration). 0 → next macrotask.\n timer = h.setTimeout(finish, duration);\n\n // Phase 2: on the next frame flip from → to so the CSS transition runs.\n nextFrame(() => {\n if (finished) return;\n removeClasses(dom, el, from);\n addClasses(dom, el, to);\n });\n\n return {\n cancel: () => {\n // Cancel = settle immediately (removes classes, clears listeners/timer)\n // but WITHOUT invoking onDone, so a cancelled leave never finalizes the\n // node it was about to destroy.\n if (finished) return;\n finished = true;\n detach();\n removeClasses(dom, el, active);\n removeClasses(dom, el, to);\n removeClasses(dom, el, from);\n },\n };\n}\n\ninterface LeavingEntry {\n readonly inst: NodeInstance;\n readonly run: Run;\n}\n\n/** Which half of a transition to play on a bare element. */\nexport type TransitionPhase = 'enter' | 'leave';\n\n/**\n * Play one enter/leave transition on a bare DOM element, outside the keyed\n * reconciler — the seam the router uses for route leave/enter (§9) and any other\n * consumer that owns a single host element rather than a reactive container.\n *\n * Reuses the exact same {@link startRun} mechanics as list/conditional\n * transitions (from+active applied immediately, next-frame flip to `to`,\n * completion on transitionend/animationend or the fallback timer), so there is\n * one transition engine, not two. The returned handle's `cancel()` settles the\n * run immediately WITHOUT invoking `onDone` — the caller uses it to abort an\n * in-flight enter when the same host is about to start leaving (rapid\n * navigation), avoiding overlapping runs/duplicate listeners on one element.\n *\n * On the server (or any non-element target) there is nothing to animate, so\n * `onDone` runs synchronously and `cancel()` is a no-op — the caller's teardown\n * still happens exactly once.\n */\nexport function runElementTransition(\n dom: DOMAdapter,\n el: Element,\n rt: ResolvedTransitionLike,\n phase: TransitionPhase,\n onDone: () => void,\n): { cancel(): void } {\n if (dom.body() === null || !dom.isElement(el)) {\n onDone();\n return { cancel: () => {} };\n }\n const active = phase === 'enter' ? rt.enterActive : rt.leaveActive;\n const from = phase === 'enter' ? rt.enterFrom : rt.leaveFrom;\n const to = phase === 'enter' ? rt.enterTo : rt.leaveTo;\n return startRun(dom, el, active, from, to, rt.duration, onDone);\n}\n\n\n/**\n * Per-container transition controller. One instance is created for each\n * reactive-list / conditional NodeInstance in {@link wireReactiveList}; its\n * `leaving` map persists across every reconcile of that container.\n */\nexport class TransitionController {\n private readonly leaving = new Map<string, LeavingEntry>();\n\n constructor(\n private readonly dom: DOMAdapter,\n private readonly graph: ApplicationGraph,\n /** Full teardown of a leaving instance (remove + dispose + forget + detach). */\n private readonly finalize: (inst: NodeInstance) => void,\n ) {}\n\n /** True only in a real DOM environment (browser). */\n private get browser(): boolean {\n return this.dom.body() !== null;\n }\n\n private keyOf(inst: NodeInstance): string {\n return inst.graphNode.key ?? inst.graphNode.id;\n }\n\n private resolved(node: GraphNode): ResolvedTransitionLike | undefined {\n return getResolvedTransition(this.graph, node.id);\n }\n\n /** Run the enter animation for `inst` if it carries a transition (browser only). */\n enter(inst: NodeInstance): void {\n if (!this.browser) return;\n const rt = this.resolved(inst.graphNode);\n if (rt === undefined) return;\n const el = inst.domNode;\n if (!this.dom.isElement(el)) return;\n startRun(this.dom, el, rt.enterActive, rt.enterFrom, rt.enterTo, rt.duration, () => {\n /* enter has no teardown; classes already cleared by the run */\n });\n }\n\n /**\n * Play `appear` for any initial child that opted into it (fresh browser mount\n * only — hydration must never animate appear, §22, and this is called only on\n * the mount path).\n */\n appear(children: readonly NodeInstance[]): void {\n if (!this.browser) return;\n for (const child of children) {\n const rt = this.resolved(child.graphNode);\n if (rt !== undefined && rt.appear) this.enter(child);\n }\n }\n\n hooks(): TransitionHooks {\n return {\n takeLeaving: (key) => {\n const entry = this.leaving.get(key);\n if (entry === undefined) return undefined;\n entry.run.cancel(); // leave→enter: stop the leave, keep the live node\n this.leaving.delete(key);\n return entry.inst;\n },\n beginLeave: (inst) => {\n if (!this.browser) return false;\n const rt = this.resolved(inst.graphNode);\n if (rt === undefined) return false;\n const el = inst.domNode;\n if (!this.dom.isElement(el)) return false;\n const key = this.keyOf(inst);\n // If a prior leave for this key is somehow still running, settle it.\n const prior = this.leaving.get(key);\n if (prior !== undefined) prior.run.cancel();\n const run = startRun(\n this.dom,\n el,\n rt.leaveActive,\n rt.leaveFrom,\n rt.leaveTo,\n rt.duration,\n () => {\n // Only finalize if THIS run is still the registered one (it may have\n // been reclaimed by a re-entering key, which cancels without done).\n const current = this.leaving.get(key);\n if (current !== undefined && current.run === run) {\n this.leaving.delete(key);\n this.finalize(inst);\n }\n },\n );\n this.leaving.set(key, { inst, run });\n return true;\n },\n onEnter: (inst) => this.enter(inst),\n };\n }\n}\n","/**\n * Document head / metadata runtime (2.0 §1–§3).\n *\n * Two entry points, sharing the normalized {@link HeadEntry} model the DSL's\n * `head()` produces (mirrored here as a local structural type so the renderer\n * takes no compile-time dependency on the DSL package — the same convention as\n * the overlay/component descriptors):\n *\n * • `wireHeadBehavior(ctx, node, instance)` — BROWSER. Reads the\n * `__head__<id>` descriptor, registers this node's contribution with a\n * per-render {@link HeadManager} (created lazily on `ctx`), subscribes to any\n * reactive attr/text signals, and tracks cleanup on the NodeInstance so the\n * contribution is withdrawn (and the manager re-applies the merged result)\n * when the node unmounts or the route changes. Server-safe: when\n * `dom.head()` is null (SSR) it is a no-op.\n *\n * • `renderHead(compiled)` — SERVER. Walks the compiled graph in document\n * order, merges every live `head()` contribution (last-in-document-order\n * wins per dedup key — §3), and serializes the effective tags to an HTML\n * string for the caller to place inside `<head>`. Only the active graph is\n * walked, so only active-route metadata is emitted (§2). Each tag carries\n * `data-streetui-head` + `data-streetui-head-key=\"…\"` so the browser adopts\n * it on hydration instead of creating a duplicate.\n */\n\nimport type { GraphNode, ApplicationGraph } from '@streetui/graph';\nimport { ServerDOMAdapter } from '@streetui/dom';\nimport type { CompiledApplication } from '@streetui/compiler';\nimport type { DOMAdapter } from '@streetui/dom';\nimport type { RenderContext } from './render-context.js';\nimport type { NodeInstance } from './node-instance.js';\n\n/** The marker attribute stamped on every framework-managed head tag. */\nconst HEAD_MARKER = 'data-streetui-head';\n/** The attribute carrying a tag's dedup key, so hydration can match server tags. */\nconst HEAD_KEY = 'data-streetui-head-key';\n\n// ── Structural mirror of the DSL's head entry model ─────────────────────────────\n\ninterface HeadEntryLike {\n readonly tag: 'title' | 'meta' | 'link' | 'base';\n readonly dedupKey: string;\n readonly attrs: Readonly<Record<string, unknown>>;\n readonly text?: unknown;\n}\ninterface HeadContributionLike {\n readonly entries: readonly HeadEntryLike[];\n}\n\ninterface SignalLike {\n subscribe: (fn: (v: unknown) => void) => () => void;\n peek: () => unknown;\n}\n\nfunction isSignalLike(v: unknown): v is SignalLike {\n return (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as Record<string, unknown>)['subscribe'] === 'function' &&\n typeof (v as Record<string, unknown>)['peek'] === 'function'\n );\n}\n\n/** Read a bindable value to its current string (peeking a signal, else stringifying). */\nfunction readValue(v: unknown): string {\n if (isSignalLike(v)) return String(v.peek() ?? '');\n return String(v ?? '');\n}\n\n/** A fully-resolved head tag: concrete strings, ready to write to the DOM/serialize. */\ninterface ResolvedTag {\n readonly tag: 'title' | 'meta' | 'link' | 'base';\n readonly attrs: Record<string, string>;\n readonly text?: string;\n}\n\nfunction resolveEntry(entry: HeadEntryLike): ResolvedTag {\n const attrs: Record<string, string> = {};\n for (const key of Object.keys(entry.attrs)) {\n attrs[key] = readValue(entry.attrs[key]);\n }\n const resolved: ResolvedTag = { tag: entry.tag, attrs };\n if (entry.tag === 'title') {\n return { ...resolved, text: readValue(entry.text) };\n }\n return resolved;\n}\n\n// ── Browser head manager ────────────────────────────────────────────────────────\n\ninterface AppliedRecord {\n el: Element;\n attrKeys: Set<string>;\n tag: string;\n}\n\n/**\n * Coordinates every live `head()` node's contribution into a single\n * `document.head`. One instance per render (lazily created on `ctx`). Merges by\n * dedup key with last-in-document-order winning, and applies the minimal diff to\n * the DOM on every register/unregister/signal change. Adopts server-emitted tags\n * on the first apply so hydration produces no duplicates.\n */\nexport class HeadManager {\n private readonly _dom: DOMAdapter;\n private readonly _head: Element;\n private readonly _contributions = new Map<string, { order: number; entries: readonly HeadEntryLike[] }>();\n private readonly _applied = new Map<string, AppliedRecord>();\n private _order = 0;\n private _adopted = false;\n\n constructor(dom: DOMAdapter, head: Element) {\n this._dom = dom;\n this._head = head;\n }\n\n /** Register (or replace) a node's contribution and re-apply the merged result. */\n register(nodeId: string, entries: readonly HeadEntryLike[]): void {\n this._contributions.set(nodeId, { order: this._order++, entries });\n this.apply();\n }\n\n /** Withdraw a node's contribution (unmount / route change) and re-apply. */\n unregister(nodeId: string): void {\n if (this._contributions.delete(nodeId)) this.apply();\n }\n\n /** Recompute the merged head and patch `document.head` to match. */\n apply(): void {\n if (!this._adopted) {\n this._adoptServerTags();\n this._adopted = true;\n }\n\n // Merge: iterate contributions in document order; per dedup key the last\n // writer wins (§3). Within a contribution, later entries win too.\n const ordered = [...this._contributions.values()].sort((a, b) => a.order - b.order);\n const merged = new Map<string, ResolvedTag>();\n for (const contribution of ordered) {\n for (const entry of contribution.entries) {\n merged.set(entry.dedupKey, resolveEntry(entry));\n }\n }\n\n // Upsert desired tags.\n for (const [key, desired] of merged) {\n const existing = this._applied.get(key);\n if (existing !== undefined && existing.tag === desired.tag) {\n this._reconcileAttrs(existing, desired);\n } else {\n if (existing !== undefined) {\n // Tag kind changed for this key (rare) — drop the old element.\n this._dom.removeChild(this._head, existing.el);\n this._applied.delete(key);\n }\n const el = this._createTag(key, desired);\n this._dom.appendChild(this._head, el);\n this._applied.set(key, { el, attrKeys: new Set(Object.keys(desired.attrs)), tag: desired.tag });\n }\n }\n\n // Remove managed tags no longer desired.\n for (const [key, record] of [...this._applied]) {\n if (!merged.has(key)) {\n this._dom.removeChild(this._head, record.el);\n this._applied.delete(key);\n }\n }\n }\n\n private _createTag(key: string, desired: ResolvedTag): Element {\n const el = this._dom.createElement(desired.tag);\n this._dom.setAttribute(el, HEAD_MARKER, '');\n this._dom.setAttribute(el, HEAD_KEY, key);\n for (const attr of Object.keys(desired.attrs)) {\n this._dom.setAttribute(el, attr, desired.attrs[attr]!);\n }\n if (desired.tag === 'title') this._dom.setTextContent(el, desired.text ?? '');\n return el;\n }\n\n private _reconcileAttrs(record: AppliedRecord, desired: ResolvedTag): void {\n const nextKeys = new Set(Object.keys(desired.attrs));\n // Remove attrs that are no longer present.\n for (const attr of record.attrKeys) {\n if (!nextKeys.has(attr)) this._dom.removeAttribute(record.el, attr);\n }\n // Set/overwrite desired attrs (idempotent when unchanged — matters on the\n // hydration adopt path, where the element is a server tag being re-asserted).\n for (const attr of nextKeys) {\n this._dom.setAttribute(record.el, attr, desired.attrs[attr]!);\n }\n if (desired.tag === 'title') this._dom.setTextContent(record.el, desired.text ?? '');\n record.attrKeys = nextKeys;\n }\n\n /**\n * Seed `_applied` from server-emitted `[data-streetui-head-key]` tags already\n * in `document.head`. The subsequent diff reuses these elements when the\n * client desires the same key (no duplicate), rewrites them if the value\n * changed, or removes them if the client graph no longer wants them.\n */\n private _adoptServerTags(): void {\n for (const child of this._dom.childNodes(this._head)) {\n if (!this._dom.isElement(child)) continue;\n const el = child as Element;\n const key = this._dom.getAttribute(el, HEAD_KEY);\n if (key === null) continue;\n this._applied.set(key, {\n el,\n attrKeys: new Set(this._attrNames(el)),\n tag: this._dom.tagName(el),\n });\n }\n }\n\n /** The framework-managed attribute names currently on a server tag. */\n private _attrNames(el: Element): string[] {\n // We cannot enumerate a live element's attributes through the minimal\n // DOMAdapter surface, so we re-assert from the desired set on first apply\n // (see `_reconcileAttrs`, which sets desired keys and removes only tracked\n // ones). Tracking the marker keys is enough to keep them from lingering.\n const names: string[] = [];\n if (this._dom.getAttribute(el, HEAD_MARKER) !== null) names.push(HEAD_MARKER);\n if (this._dom.getAttribute(el, HEAD_KEY) !== null) names.push(HEAD_KEY);\n return names;\n }\n}\n\n/** Lazily get (or create) the render's HeadManager. Null on the server. */\nfunction getHeadManager(ctx: RenderContext): HeadManager | null {\n const head = ctx.dom.head();\n if (head === null) return null; // server render pass — renderHead handles SSR\n const mutable = ctx as { head?: HeadManager };\n if (mutable.head === undefined) mutable.head = new HeadManager(ctx.dom, head);\n return mutable.head;\n}\n\n/**\n * Wire a mounted/hydrated `head` node's contribution into `document.head`.\n * Server-safe (no-op when there is no document). Shared by the mount and hydrate\n * paths so both establish identical ownership + cleanup.\n */\nexport function wireHeadBehavior(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n): void {\n const manager = getHeadManager(ctx);\n if (manager === null) return;\n\n const descFn = ctx.graph.getHandler(`__head__${graphNode.id}`) as\n | (() => HeadContributionLike)\n | undefined;\n if (descFn === undefined) return;\n\n const contribution = descFn();\n const nodeId = graphNode.id;\n manager.register(nodeId, contribution.entries);\n\n // Subscribe to any reactive attr/text signals; a change re-applies the merged\n // head. All subscriptions + the contribution withdrawal are tracked on the\n // instance, so a route change / unmount tears them down and re-applies.\n for (const entry of contribution.entries) {\n for (const attrKey of Object.keys(entry.attrs)) {\n const v = entry.attrs[attrKey];\n if (isSignalLike(v)) {\n instance.trackCleanup(v.subscribe(() => manager.apply()));\n }\n }\n if (isSignalLike(entry.text)) {\n instance.trackCleanup(entry.text.subscribe(() => manager.apply()));\n }\n }\n\n instance.trackCleanup(() => manager.unregister(nodeId));\n}\n\n// ── Server-side head emission ─────────────────────────────────────────────────\n\n/**\n * Render the active graph's merged document metadata to an HTML string suitable\n * for placing inside `<head>`. Walks the graph in document order, merges every\n * `head()` contribution (last-in-document-order wins per dedup key), and\n * serializes each effective tag with the `data-streetui-head` marker so the\n * browser adopts it on hydration. Returns `''` when the app declares no metadata\n * — so apps that never call `head()` emit nothing extra and existing SSR output\n * is unchanged.\n */\nexport function renderHead(compiled: CompiledApplication): string {\n const graph: ApplicationGraph = compiled.graph;\n\n const merged = new Map<string, ResolvedTag>();\n graph.walk((node) => {\n if (node.type !== 'head') return;\n const descFn = graph.getHandler(`__head__${node.id}`) as\n | (() => HeadContributionLike)\n | undefined;\n if (descFn === undefined) return;\n for (const entry of descFn().entries) {\n merged.set(entry.dedupKey, resolveEntry(entry));\n }\n });\n\n if (merged.size === 0) return '';\n\n const dom = new ServerDOMAdapter();\n let out = '';\n for (const [key, desired] of merged) {\n const el = dom.createElement(desired.tag);\n dom.setAttribute(el, HEAD_MARKER, '');\n dom.setAttribute(el, HEAD_KEY, key);\n for (const attr of Object.keys(desired.attrs)) {\n dom.setAttribute(el, attr, desired.attrs[attr]!);\n }\n if (desired.tag === 'title') dom.setTextContent(el, desired.text ?? '');\n out += dom.serializeOuter(el);\n }\n return out;\n}\n","/**\n * Initial mount — creates DOM nodes for every GraphNode and\n * attaches them into the container.\n *\n * This is a recursive depth-first walk. For each GraphNode:\n * 1. Create the DOM element (or text node)\n * 2. Apply props/attributes\n * 3. Wire events\n * 4. Wire signal subscriptions for reactive props\n * 5. Recurse into children\n * 6. Insert into the DOM\n */\n\nimport type { GraphNode, ApplicationGraph } from '@streetui/graph';\nimport type { DOMAdapter } from '@streetui/dom';\nimport {\n focusInitial,\n trapFocus,\n containFocus,\n onEscape,\n rovingMenu,\n saveFocus,\n restoreFocus,\n} from '@streetui/dom';\nimport type { RenderContext } from './render-context.js';\nimport { NodeInstance } from './node-instance.js';\nimport { applyProp } from './attributes.js';\nimport { wireEvents } from './events.js';\nimport { resolveTag } from './tag-map.js';\nimport {\n reconcileChildren,\n reconcileChildrenByPlan,\n type PlanEntry,\n} from './reconciliation.js';\nimport { TransitionController, type TransitionHooks } from './transition.js';\nimport { wireHeadBehavior } from './head.js';\n\n/**\n * Prop keys handled by the per-type mount branches (or reserved internals), so\n * `applyNodeProps` must skip them to avoid double-applying. This set is\n * invariant across nodes, so it is hoisted to module scope: allocating it once\n * (rather than per node) removes N Set allocations per mount/SSR pass and the\n * GC pressure they create. Treat as read-only — never mutate.\n */\nconst SKIP_PROP_KEYS: ReadonlySet<string> = new Set([\n 'text', 'label', 'level', 'inputType', 'src', 'alt', 'href', 'external',\n 'value', 'placeholder', 'disabled', '_renderKey', 'key', 'name',\n]);\n\nexport function mountGraph(ctx: RenderContext): NodeInstance {\n return mountNode(ctx, ctx.graph.root, ctx.container);\n}\n\nexport function mountNode(\n ctx: RenderContext,\n graphNode: GraphNode,\n parentDom: Node,\n): NodeInstance {\n const { dom, graph } = ctx;\n\n // ── v1.7 static SSR fast path (SSR-only) ──────────────────────────────────\n // When a compiler-derived static SSR plan is present (server render only)\n // and this node is a maximal static-subtree root, emit its precomputed HTML\n // verbatim instead of recursively constructing ServerElement/ServerText/\n // NodeInstance for the whole subtree. `ctx.staticHTML` is always undefined on\n // the browser path, so this is a single short-circuiting check there — the\n // client hot path and its semantics are untouched (§5/§6/§23). The stored\n // string is produced by this same mount+serialize pipeline, so output is\n // byte-identical (§8). We still register ONE NodeInstance for the root so the\n // parent's children bookkeeping and post-render dispose behave normally.\n const staticHTML = ctx.staticHTML;\n if (staticHTML !== undefined && dom.createRawHTML !== undefined) {\n const precomputed = staticHTML.get(graphNode.id);\n if (precomputed !== undefined) {\n const raw = dom.createRawHTML(precomputed);\n dom.appendChild(parentDom, raw);\n const instance = new NodeInstance(graphNode, raw);\n ctx.instances.set(graphNode.id, instance);\n return instance;\n }\n }\n\n // The application root node maps to the container itself — don't create a duplicate element\n if (graphNode.type === 'application') {\n const instance = new NodeInstance(graphNode, parentDom);\n ctx.instances.set(graphNode.id, instance);\n for (const child of graphNode.children) {\n const childInstance = mountNode(ctx, child, parentDom);\n instance.addChild(childInstance);\n }\n return instance;\n }\n\n // Text-only nodes render as a <span> containing a text node\n if (graphNode.type === 'text') {\n const text = String(graphNode.getProp('text') ?? '');\n const el = dom.createElement('span');\n const textNode = dom.createTextNode(text);\n dom.appendChild(el, textNode);\n applyNodeProps(ctx, graphNode, el);\n\n // Create the live instance up front and reuse it for event wiring. The\n // previous code allocated a throwaway NodeInstance solely to satisfy\n // wireEvents' signature, wasting one NodeInstance (+ its children array and\n // CleanupRegistry) per text node — pure GC pressure on the hottest mount\n // path. wireEvents/wireSignalBindings each early-return on empty arrays.\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n // Reactive text binding — only build the update closure when the node has\n // bindings. wireSignalBindings early-returns on empty stateRefs, so for a\n // static text node (the common case in a large initial render) the\n // textUpdate closure would be allocated and thrown away: avoidable GC\n // pressure on the hottest mount path.\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, textUpdate(dom, el, textNode));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Heading nodes\n if (graphNode.type === 'heading') {\n const level = (graphNode.getProp('level') as number | undefined) ?? 1;\n const tag = `h${level}` as string;\n const el = dom.createElement(tag);\n const text = String(graphNode.getProp('text') ?? '');\n dom.setTextContent(el, text);\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, headingUpdate(dom, el));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Input nodes\n if (graphNode.type === 'input') {\n const el = dom.createElement('input') as HTMLInputElement;\n const inputType = String(graphNode.getProp('inputType') ?? 'text');\n dom.setAttribute(el, 'type', inputType);\n const placeholder = graphNode.getProp('placeholder');\n if (placeholder !== undefined) dom.setAttribute(el, 'placeholder', String(placeholder));\n const value = graphNode.getProp('value');\n if (value !== undefined) dom.setProperty(el, 'value', String(value));\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, inputUpdate(dom, el));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Image nodes\n if (graphNode.type === 'image') {\n const el = dom.createElement('img') as HTMLImageElement;\n const src = graphNode.getProp('src');\n const alt = graphNode.getProp('alt');\n if (src !== undefined) dom.setAttribute(el, 'src', String(src));\n if (alt !== undefined) dom.setAttribute(el, 'alt', String(alt));\n const width = graphNode.getProp('width');\n const height = graphNode.getProp('height');\n if (width !== undefined) dom.setAttribute(el, 'width', String(width));\n if (height !== undefined) dom.setAttribute(el, 'height', String(height));\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Link nodes\n if (graphNode.type === 'link') {\n const el = dom.createElement('a') as HTMLAnchorElement;\n const href = graphNode.getProp('href');\n const label = graphNode.getProp('label');\n const external = graphNode.getProp('external');\n if (href !== undefined) dom.setAttribute(el, 'href', String(href));\n if (label !== undefined) dom.setTextContent(el, String(label));\n if (external === true) {\n dom.setAttribute(el, 'target', '_blank');\n dom.setAttribute(el, 'rel', 'noopener noreferrer');\n }\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n // A link's label/href may be bound to signals (e.g. i18n `t()` in nav). Wire\n // the same signal-binding path buttons use so the text updates reactively.\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, linkUpdate(dom, el));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Button nodes\n if (graphNode.type === 'button') {\n const el = dom.createElement('button') as HTMLButtonElement;\n const label = graphNode.getProp('label');\n if (label !== undefined) dom.setTextContent(el, String(label));\n const disabled = graphNode.getProp('disabled');\n if (disabled === true) dom.setAttribute(el, 'disabled', '');\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, buttonUpdate(dom, el));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Reactive list / conditional — a container whose children are driven by a\n // Signal. Initial child subtrees are already built into the graph by the DSL;\n // on signal change we reconcile the freshly-built desired children against the\n // live DOM using the keyed reconciler (no virtual DOM). A `conditional` uses\n // the identical machinery but renders as a neutral <div> holding 0..1 branch.\n if (graphNode.type === 'reactive-list' || graphNode.type === 'conditional') {\n const tag = resolveTag(graphNode.type);\n const el = dom.createElement(tag);\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n\n for (const child of graphNode.children) {\n const childInstance = mountNode(ctx, child, el);\n instance.addChild(childInstance);\n }\n\n dom.appendChild(parentDom, el);\n wireReactiveList(ctx, graphNode, instance, el, true);\n return instance;\n }\n\n // Portal — a container whose children are relocated to a different DOM\n // location (document.body) on the browser, while a neutral inline anchor\n // stays at the declaration site. On the server there is no body, so the\n // children render inline in the anchor (deterministic HTML; hydration then\n // relocates them). This is the substrate for overlays (dialog/popover/…):\n // `wireOverlayBehavior` reads an optional `__overlay__<id>` descriptor and,\n // when present, wires focus trap/restore/containment/escape to the open\n // signal. A plain portal has no descriptor, so overlay wiring is a no-op.\n if (graphNode.type === 'portal') {\n const anchor = dom.createElement(resolveTag('portal'));\n dom.setAttribute(anchor, 'data-streetui-portal', '');\n applyNodeProps(ctx, graphNode, anchor);\n const instance = new NodeInstance(graphNode, anchor);\n ctx.instances.set(graphNode.id, instance);\n\n const body = dom.body();\n let target: Element = anchor; // SSR / no body → render inline in the anchor\n if (body !== null) {\n const portalContainer = dom.createElement('div');\n dom.setAttribute(portalContainer, 'data-streetui-portal-container', '');\n dom.appendChild(body, portalContainer);\n instance.trackCleanup(() => dom.removeChild(body, portalContainer));\n target = portalContainer;\n }\n\n for (const child of graphNode.children) {\n instance.addChild(mountNode(ctx, child, target));\n }\n\n dom.appendChild(parentDom, anchor);\n wireOverlayBehavior(ctx, graphNode, instance, target);\n return instance;\n }\n\n // Head — a metadata node (title/meta/link/base). Renders as a neutral inline\n // anchor at the declaration site (like a portal), while its contribution is\n // applied to `document.head` by `wireHeadBehavior` (browser) or emitted by\n // `renderHead` (server). No visible children; the anchor keeps hydration\n // structurally aligned with the SSR output.\n if (graphNode.type === 'head') {\n const anchor = dom.createElement(resolveTag('head'));\n dom.setAttribute(anchor, 'data-streetui-head-anchor', '');\n applyNodeProps(ctx, graphNode, anchor);\n const instance = new NodeInstance(graphNode, anchor);\n ctx.instances.set(graphNode.id, instance);\n\n dom.appendChild(parentDom, anchor);\n wireHeadBehavior(ctx, graphNode, instance);\n return instance;\n }\n\n // Container / section / page / form / list / list-item — structural nodes\n const tag = resolveTag(graphNode.type);\n const el = dom.createElement(tag);\n applyNodeProps(ctx, graphNode, el);\n\n // Surface a reactive-list item's stable, identity-only reconciliation key as a\n // public `data-streetui-key` attribute (e.g. \"id:1\"). This exposes only the\n // identity part — never the internal `_sig` value signature, signal ids or\n // graph node ids — so a row is directly selectable and its identity is\n // inspectable across reorders and in-place data updates.\n if (graphNode.type === 'list-item') {\n const itemKey = graphNode.getProp('key');\n if (itemKey !== undefined) {\n dom.setAttribute(el, 'data-streetui-key', String(itemKey));\n }\n }\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n\n // wire form submit (reuse the live instance rather than a throwaway)\n if (graphNode.type === 'form') {\n wireEvents(dom, graph, graphNode, el, instance);\n }\n\n // Recurse into children\n for (const child of graphNode.children) {\n const childInstance = mountNode(ctx, child, el);\n instance.addChild(childInstance);\n }\n\n dom.appendChild(parentDom, el);\n if (graphNode.type === 'component') wireComponentBehavior(ctx, graphNode, instance);\n return instance;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/**\n * Per-node-type reactive-binding factories. Each returns the `onUpdate`\n * callback that `wireSignalBindings` invokes when a bound signal changes.\n * Extracted so both the browser mount path and the hydration path apply the\n * exact same DOM mutation semantics for each prop — no duplicated rendering\n * logic.\n */\nexport function textUpdate(\n dom: DOMAdapter,\n el: Element,\n textNode: Text,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'text') {\n dom.setTextContent(textNode, String(value ?? ''));\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function headingUpdate(\n dom: DOMAdapter,\n el: Element,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'text') {\n dom.setTextContent(el, String(value ?? ''));\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function inputUpdate(\n dom: DOMAdapter,\n el: Element,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'value') {\n dom.setProperty(el, 'value', String(value ?? ''));\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function buttonUpdate(\n dom: DOMAdapter,\n el: Element,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'label') {\n dom.setTextContent(el, String(value ?? ''));\n } else if (propKey === 'disabled') {\n if (value === true) {\n dom.setAttribute(el, 'disabled', '');\n } else {\n dom.removeAttribute(el, 'disabled');\n }\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function linkUpdate(\n dom: DOMAdapter,\n el: Element,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'label') {\n dom.setTextContent(el, String(value ?? ''));\n } else if (propKey === 'href') {\n dom.setAttribute(el, 'href', String(value ?? ''));\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function applyNodeProps(ctx: RenderContext, graphNode: GraphNode, el: Element): void {\n // Iterate own enumerable keys directly rather than via Object.entries, which\n // allocates a wrapper array plus one [key,value] tuple per prop — measurable\n // GC pressure when multiplied across every node in a large initial render.\n const props = graphNode.props;\n for (const key in props) {\n if (!Object.hasOwn(props, key)) continue;\n if (SKIP_PROP_KEYS.has(key)) continue;\n applyProp(ctx.dom, el, key, props[key]);\n }\n}\n\nexport function wireSignalBindings(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n onUpdate: (propKey: string, value: unknown) => void,\n): void {\n // Fast exit for the common non-reactive node — avoids allocating a for-of\n // iterator over an empty stateRefs array on every static node.\n if (graphNode.stateRefs.length === 0) return;\n for (const stateRef of graphNode.stateRefs) {\n const signalKey = `__signal__${stateRef.signalId}`;\n const maybeSig = ctx.graph.getHandler(signalKey) as\n | { subscribe: (fn: (v: unknown) => void) => () => void; peek: () => unknown }\n | undefined;\n if (maybeSig === undefined || typeof maybeSig.subscribe !== 'function') continue;\n\n // Subscribe directly — avoids the ReadonlySignal<T> generic variance issue\n const unsub = maybeSig.subscribe((value) => {\n onUpdate(stateRef.propKey, value);\n });\n instance.trackCleanup(unsub);\n }\n}\n\n// ── Reactive list wiring ────────────────────────────────────────────────────────\n\ntype ListBuildFn = (items: unknown) => GraphNode[];\ntype ListPlanFn = (items: unknown) => PlanEntry[];\n\n/**\n * Subscribe a reactive-list instance to its driving signal. On each change the\n * DSL-registered plan factory produces lightweight per-row descriptors, which\n * are reconciled against the live DOM with the keyed, minimal-move reconciler\n * (spec §15). A `conditional` node has no plan handler and falls back to the\n * eager build factory (it only ever renders 0..1 branch, so eager is fine).\n */\nexport function wireReactiveList(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n el: Element,\n runAppear = false,\n): void {\n const plan = ctx.graph.getHandler(`__listplan__${graphNode.id}`) as\n | ListPlanFn\n | undefined;\n const build = ctx.graph.getHandler(`__listbuild__${graphNode.id}`) as\n | ListBuildFn\n | undefined;\n if (plan === undefined && build === undefined) return;\n\n // One transition controller per reactive container, created here so its\n // leaving-instance map survives across every reconcile of this container\n // (that persistence is what makes leave→enter reclaim and keyed list-leave\n // correct — §6/§7). `finalize` runs the full deferred teardown chain when a\n // leave animation completes: DOM-remove + dispose + forget + detach, exactly\n // the work the synchronous path splits between the reconciler and the two\n // reconcile* helpers below. On the server (no body) the controller's hooks\n // no-op, so SSR is unchanged (§21).\n const controller = new TransitionController(ctx.dom, ctx.graph, (leaving) => {\n // Full teardown at leave-animation end — the same four steps the synchronous\n // path splits between the reconciler (DOM-remove + dispose) and this helper\n // (forget + detach). Deferred here because `beginLeave` excluded this\n // instance from `result.removed`, so nothing else will tear it down.\n const parent = ctx.dom.parentNode(leaving.domNode);\n if (parent !== null) ctx.dom.removeChild(parent, leaving.domNode);\n leaving.dispose();\n forgetInstance(ctx, leaving);\n ctx.graph.detachNode(leaving.graphNode);\n });\n const hooks = controller.hooks();\n\n // `appear`: animate any initial child that opted in — but ONLY on a fresh\n // browser mount, never on hydration (§22: the DOM is already present and\n // correct, so appear must not run). The hydrate path calls this with\n // `runAppear` omitted (false).\n if (runAppear) controller.appear(instance.children);\n\n for (const stateRef of graphNode.stateRefs) {\n if (stateRef.propKey !== 'items') continue;\n const sig = ctx.graph.getHandler(`__signal__${stateRef.signalId}`) as\n | { subscribe: (fn: (v: unknown) => void) => () => void }\n | undefined;\n if (sig === undefined || typeof sig.subscribe !== 'function') continue;\n\n const unsub = sig.subscribe((value) => {\n if (plan !== undefined) {\n reconcileReactiveListByPlan(ctx, graphNode, instance, el, plan(value), hooks);\n } else {\n reconcileReactiveList(ctx, graphNode, instance, el, build!(value), hooks);\n }\n });\n instance.trackCleanup(unsub);\n }\n}\n\nfunction reconcileReactiveListByPlan(\n ctx: RenderContext,\n listNode: GraphNode,\n listInstance: NodeInstance,\n listEl: Element,\n plan: PlanEntry[],\n hooks: TransitionHooks,\n): void {\n const oldInstances = [...listInstance.children];\n const result = reconcileChildrenByPlan(\n ctx,\n listEl,\n oldInstances,\n plan,\n (node, parent) => mountNode(ctx, node, parent),\n hooks,\n );\n\n // Sync the live instance's children to the reconciled order.\n listInstance.children.length = 0;\n for (const inst of result.instances) listInstance.children.push(inst);\n\n // Forget removed instances, and drop their graph nodes.\n for (const removed of result.removed) {\n forgetInstance(ctx, removed);\n ctx.graph.detachNode(removed.graphNode);\n }\n // Detach any freshly-built subtree that was not adopted as a live instance\n // (e.g. the top node of a rebuilt changed row, whose live instance keeps its\n // original graph node).\n const adopted = new Set(result.instances.map((i) => i.graphNode));\n for (const node of result.built ?? []) {\n if (!adopted.has(node)) ctx.graph.detachNode(node);\n }\n\n // Keep the graph model consistent: list node children match the new order.\n for (const child of [...listNode.children]) listNode.removeChild(child);\n for (const inst of result.instances) listNode.appendChild(inst.graphNode);\n}\n\nfunction reconcileReactiveList(\n ctx: RenderContext,\n listNode: GraphNode,\n listInstance: NodeInstance,\n listEl: Element,\n newNodes: GraphNode[],\n hooks: TransitionHooks,\n): void {\n const oldInstances = [...listInstance.children];\n const result = reconcileChildren(\n ctx,\n listEl,\n oldInstances,\n newNodes,\n (node, parent) => mountNode(ctx, node, parent),\n hooks,\n );\n\n // Sync the live instance's children to the reconciled order.\n listInstance.children.length = 0;\n for (const inst of result.instances) listInstance.children.push(inst);\n\n // Forget removed instances from the renderer index, and drop their graph\n // nodes (and any un-adopted freshly-built duplicates) from the graph index.\n for (const removed of result.removed) {\n forgetInstance(ctx, removed);\n ctx.graph.detachNode(removed.graphNode);\n }\n const adopted = new Set(result.instances.map((i) => i.graphNode));\n for (const built of newNodes) {\n if (!adopted.has(built)) ctx.graph.detachNode(built);\n }\n\n // Keep the graph model consistent: list node children match the new order.\n for (const child of [...listNode.children]) listNode.removeChild(child);\n for (const inst of result.instances) listNode.appendChild(inst.graphNode);\n}\n\n/** Recursively remove an instance subtree from the renderer's instance index. */\nfunction forgetInstance(ctx: RenderContext, instance: NodeInstance): void {\n ctx.instances.delete(instance.graphNode.id);\n for (const child of instance.children) forgetInstance(ctx, child);\n}\n\n// ── Overlay behavior wiring ─────────────────────────────────────────────────────\n\n/**\n * Opaque overlay descriptor, read from the `__overlay__<portalId>` handler that\n * the DSL registers for dialog/popover/tooltip/dropdown/toast. Declared here as\n * a local structural type (mirroring the list plan/build handler pattern) so the\n * renderer never takes a compile-time dependency on the DSL package.\n */\ninterface OverlayBehavior {\n /** Reactive open/visibility state — the same signal that drives the panel's `when()`. */\n readonly open: {\n subscribe: (fn: (v: boolean) => void) => () => void;\n peek: () => unknown;\n };\n /** Trap Tab focus within, and redirect escaped focus back inside (modal semantics). */\n readonly modal: boolean;\n /** Move focus into the panel when it opens. */\n readonly takesFocus: boolean;\n /** Wire arrow/Home/End/Enter/Space roving-focus navigation (role=\"menu\"). */\n readonly menu: boolean;\n /** Escape key invokes `onClose`. */\n readonly closeOnEscape: boolean;\n /** Restore focus to the pre-open element on close. */\n readonly restoreFocus: boolean;\n /** id of the element to focus first when opening. */\n readonly initialFocusId?: string;\n /** Requested-close callback (Escape). The app flips its own open signal here. */\n readonly onClose?: () => void;\n}\n\n/**\n * Attach overlay focus/keyboard behavior to a mounted portal. Server-safe: on\n * the server `dom.body()` is null so this returns immediately (SSR emits inert\n * markup, no focus concept). A plain portal has no `__overlay__` descriptor, so\n * this also returns immediately — the behavior is purely additive.\n *\n * The panel is mounted/unmounted by the portal's inner `when(open, …)`, whose\n * signal subscription is registered *before* this one (the conditional child is\n * mounted earlier in the portal branch). Signal subscribers fire synchronously\n * in subscription order, so on open→true the panel DOM exists before we move\n * focus into it, and on open→false the panel is torn down before we restore\n * focus. All listeners are tracked on the instance and torn down on unmount.\n */\nexport function wireOverlayBehavior(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n target: Element,\n): void {\n const { dom, graph } = ctx;\n if (dom.body() === null) return; // server / no DOM environment\n\n const descFn = graph.getHandler(`__overlay__${graphNode.id}`) as\n | (() => OverlayBehavior)\n | undefined;\n if (descFn === undefined) return; // plain portal — no overlay behavior\n\n const desc = descFn();\n const openSig = desc.open;\n if (openSig === undefined || typeof openSig.subscribe !== 'function') return;\n\n let active: Array<() => void> = [];\n let saved: Element | null = null;\n\n const teardown = (): void => {\n for (const fn of active) fn();\n active = [];\n };\n\n const onOpenChange = (isOpen: boolean): void => {\n if (isOpen) {\n if (desc.restoreFocus) saved = saveFocus(dom);\n // Establish containment/roving BEFORE moving focus in, so that when a\n // nested modal opens it becomes the authoritative focus owner before its\n // initial focus fires — otherwise the outer modal's still-active\n // containment would pull that focus back out (§16).\n if (desc.modal) {\n active.push(trapFocus(dom, target));\n active.push(containFocus(dom, target));\n }\n if (desc.menu) {\n active.push(rovingMenu(dom, target));\n }\n if (desc.takesFocus) focusInitial(dom, target, desc.initialFocusId);\n if (desc.closeOnEscape && desc.onClose !== undefined) {\n active.push(onEscape(dom, target, desc.onClose));\n }\n } else {\n teardown();\n if (desc.restoreFocus && saved !== null) {\n restoreFocus(dom, saved);\n saved = null;\n }\n }\n };\n\n const unsub = openSig.subscribe(onOpenChange);\n instance.trackCleanup(unsub);\n instance.trackCleanup(teardown);\n\n // `subscribe` fires only on change; an overlay that is open on initial mount\n // has its panel already built into the graph, so run the open path now.\n if (openSig.peek() === true) onOpenChange(true);\n}\n\n/**\n * Wire a component instance's lifecycle (§9). Reads the optional\n * `__component__<id>` descriptor — an array of teardown callbacks the DSL's\n * `component()` collected from the setup's `ctx.effect`/`ctx.onCleanup` — and\n * routes each into `NodeInstance.trackCleanup`, so they run (children-first)\n * when the component leaves the graph. Shared by the mount and hydrate paths so\n * both attach identical ownership. A `'component'` node with no cleanups (no\n * effects/resources) registers no descriptor and this is a no-op.\n */\nexport function wireComponentBehavior(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n): void {\n const fn = ctx.graph.getHandler(`__component__${graphNode.id}`) as\n | (() => Array<() => void>)\n | undefined;\n if (fn === undefined) return;\n for (const cleanup of fn()) instance.trackCleanup(cleanup);\n}\n","/**\n * Hydration diagnostics — dev-only, opt-in explanations of hydration mismatches.\n *\n * Hydration is self-repairing: when the server-rendered DOM does not match the\n * graph at a position, the renderer mounts a fresh subtree in place and drops\n * the offending element (see `hydrateChildren` in `hydrate.ts`). That recovery\n * is silent by design — a local mismatch must never tear down the whole app.\n *\n * During development, though, a silent repair hides a real problem (usually a\n * server/client divergence). A `HydrationDiagnosticSink` can be attached to the\n * renderer to *observe* those repairs without changing them: for every mismatch\n * the renderer reports what it expected, what it found, where, and what it did\n * to recover. Nothing is thrown, nothing is mutated differently, and when no\n * sink is attached there is zero additional work on the hydration path.\n */\n\n/** What kind of divergence the hydrator encountered at a position. */\nexport type HydrationMismatchType =\n | 'tag-mismatch' // an element existed but was the wrong tag\n | 'missing-element' // the graph expected a child the DOM did not provide\n | 'surplus-element'; // the DOM had a child the graph no longer expects\n\n/** A single, fully-described hydration divergence and the repair taken. */\nexport interface HydrationDiagnostic {\n /** The category of mismatch. */\n readonly type: HydrationMismatchType;\n /** The tag the graph expected at this position (null for a surplus element). */\n readonly expected: string | null;\n /** The tag actually found in the server DOM (null for a missing element). */\n readonly found: string | null;\n /** A human-readable path to the position, e.g. `app / page[0] / section[1]`. */\n readonly path: string;\n /** The graph node id involved, when one exists (null for surplus DOM). */\n readonly nodeId: string | null;\n /** The semantic node type involved, when one exists (null for surplus DOM). */\n readonly nodeType: string | null;\n /** The recovery action the renderer performed. */\n readonly action: string;\n /** A single-line, developer-facing summary of the whole diagnostic. */\n readonly message: string;\n}\n\n/**\n * Receives hydration diagnostics as they are discovered. Kept intentionally\n * tiny so any logger — `console`, a test collector, a `DiagnosticSink` — can\n * satisfy it. Implementations must not throw.\n */\nexport interface HydrationDiagnosticSink {\n report(diagnostic: HydrationDiagnostic): void;\n}\n\n/** Build the canonical one-line message for a diagnostic. */\nexport function formatHydrationDiagnostic(\n d: Omit<HydrationDiagnostic, 'message'>,\n): string {\n const at = ` at ${d.path}`;\n switch (d.type) {\n case 'tag-mismatch':\n return `Hydration mismatch${at} — Expected: ${d.expected} / Found: ${d.found} / Action: ${d.action}`;\n case 'missing-element':\n return `Hydration mismatch${at} — Expected: ${d.expected} / Found: (nothing) / Action: ${d.action}`;\n case 'surplus-element':\n return `Hydration mismatch${at} — Expected: (nothing) / Found: ${d.found} / Action: ${d.action}`;\n }\n}\n\n/**\n * A ready-made sink that accumulates diagnostics into an array — the shape most\n * useful for tests and for a DevTools panel. The returned `diagnostics` array is\n * appended to in-place as repairs happen.\n */\nexport function createHydrationDiagnosticCollector(): {\n readonly sink: HydrationDiagnosticSink;\n readonly diagnostics: HydrationDiagnostic[];\n} {\n const diagnostics: HydrationDiagnostic[] = [];\n return {\n diagnostics,\n sink: {\n report(d) {\n diagnostics.push(d);\n },\n },\n };\n}\n\n/**\n * A sink that forwards each diagnostic to a `console`-like logger as a single\n * warning line. Handy default when you just want the messages surfaced in dev.\n */\nexport function consoleHydrationDiagnosticSink(\n logger: { warn(message: string): void } = console,\n): HydrationDiagnosticSink {\n return {\n report(d) {\n logger.warn(d.message);\n },\n };\n}\n","/**\n * Hydration — attach a live StreetUI runtime to server-rendered HTML.\n *\n * `hydrate` walks the semantic application graph top-down against the DOM that\n * the server already produced. For every graph node it *adopts* the matching\n * existing element (creating a `NodeInstance` that points at it) and attaches\n * behavior — event listeners and signal subscriptions — using the exact same\n * helpers the browser mount path uses (`wireEvents`, `wireSignalBindings`,\n * `wireReactiveList`, and the per-type update factories). Nothing is recreated\n * when the DOM matches.\n *\n * Matching is positional and works because every non-application graph node\n * maps to exactly one element (see mount.ts). When the element at a position\n * does not match the expected tag (or is missing), only that subtree is\n * repaired: the fresh subtree is mounted and spliced into place, leaving the\n * rest of the hydrated tree untouched. A local mismatch never tears down the\n * whole app.\n */\n\nimport type { GraphNode } from '@streetui/graph';\nimport type { RenderContext } from './render-context.js';\nimport { NodeInstance } from './node-instance.js';\nimport { wireEvents } from './events.js';\nimport { resolveTag } from './tag-map.js';\nimport { formatHydrationDiagnostic } from './hydration-diagnostics.js';\nimport { wireHeadBehavior } from './head.js';\nimport {\n mountNode,\n wireSignalBindings,\n wireReactiveList,\n wireOverlayBehavior,\n wireComponentBehavior,\n textUpdate,\n headingUpdate,\n inputUpdate,\n buttonUpdate,\n linkUpdate,\n} from './mount.js';\n\n/** Hydrate the whole application graph against `ctx.container`. */\nexport function hydrateGraph(ctx: RenderContext): NodeInstance {\n const root = ctx.graph.root;\n // The application root maps to the container itself (no element of its own),\n // exactly as in mountNode.\n const instance = new NodeInstance(root, ctx.container);\n ctx.instances.set(root.id, instance);\n hydrateChildren(ctx, root, instance, ctx.container, 'app');\n return instance;\n}\n\n/**\n * Adopt `domNode` as the live element for `graphNode` and attach behavior.\n * The caller has already verified `domNode` matches `graphNode` (right tag).\n * `path` is the human-readable position used only for dev diagnostics.\n */\nfunction hydrateNode(\n ctx: RenderContext,\n graphNode: GraphNode,\n domNode: Element,\n path: string,\n): NodeInstance {\n const { dom, graph } = ctx;\n\n switch (graphNode.type) {\n case 'text': {\n // <span> with an inner text node. Adopt the text node (or create one if\n // the server markup somehow lacks it).\n let textNode = dom.firstChild(domNode);\n if (textNode === null || !dom.isTextNode(textNode)) {\n const created = dom.createTextNode(String(graphNode.getProp('text') ?? ''));\n dom.appendChild(domNode, created);\n textNode = created;\n }\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, domNode, instance);\n // Only build the per-type update closure when the node actually has\n // reactive bindings. wireSignalBindings early-returns on an empty\n // stateRefs list, so for a static node the `textUpdate(...)` closure would\n // be allocated and immediately discarded — pure GC pressure on the hot\n // hydration path, where the vast majority of nodes are static.\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, textUpdate(dom, domNode, textNode as Text));\n }\n return instance;\n }\n\n case 'heading': {\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, domNode, instance);\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, headingUpdate(dom, domNode));\n }\n return instance;\n }\n\n case 'input': {\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n // The controlled value is already present in the server HTML (reflected as\n // the `value` attribute). Re-assert it as a live property so the element's\n // current value matches the bound signal exactly.\n const value = graphNode.getProp('value');\n if (value !== undefined) dom.setProperty(domNode, 'value', String(value));\n wireEvents(dom, graph, graphNode, domNode, instance);\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, inputUpdate(dom, domNode));\n }\n return instance;\n }\n\n case 'button': {\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, domNode, instance);\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, buttonUpdate(dom, domNode));\n }\n return instance;\n }\n\n case 'image':\n case 'link': {\n // Leaf elements. Links may carry click handlers and — like buttons — a\n // label/href bound to a signal (e.g. i18n `t()` in nav), so wire the same\n // reactive binding path after adopting the server node.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n if (graphNode.type === 'link') {\n wireEvents(dom, graph, graphNode, domNode, instance);\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, linkUpdate(dom, domNode));\n }\n }\n return instance;\n }\n\n case 'reactive-list':\n case 'conditional': {\n // The server rendered the initial children (built into the graph at\n // compile time from the initial signal state). Adopt them positionally,\n // then subscribe for future signal changes — the same keyed reconciler as\n // the browser drives subsequent updates against the adopted instances.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n hydrateChildren(ctx, graphNode, instance, domNode, path);\n wireReactiveList(ctx, graphNode, instance, domNode);\n return instance;\n }\n\n case 'portal': {\n // The server rendered the portal's children INLINE inside the anchor\n // (no body on the server). Adopt the anchor, then — before positional\n // child hydration — relocate those inline children into a fresh\n // document.body container so their live location matches the browser\n // mount path exactly (and there is no positional mismatch). Hydrate the\n // children against the body container, then wire any overlay behavior.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n const body = dom.body();\n let target: Element = domNode;\n if (body !== null) {\n const portalContainer = dom.createElement('div');\n dom.setAttribute(portalContainer, 'data-streetui-portal-container', '');\n // `childNodes` returns a snapshot array, so moving during iteration is\n // safe. appendChild re-parents each node out of the anchor.\n for (const child of dom.childNodes(domNode)) {\n dom.appendChild(portalContainer, child);\n }\n dom.appendChild(body, portalContainer);\n instance.trackCleanup(() => dom.removeChild(body, portalContainer));\n target = portalContainer;\n }\n hydrateChildren(ctx, graphNode, instance, target, path);\n wireOverlayBehavior(ctx, graphNode, instance, target);\n return instance;\n }\n\n case 'head': {\n // The server emitted this node's metadata into `<head>` (via renderHead)\n // and left a neutral empty anchor here. Adopt the anchor, then wire the\n // head behavior: the HeadManager adopts the server `[data-streetui-head-\n // key]` tags on first apply so re-asserting this contribution produces no\n // duplicates. No children to hydrate.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n wireHeadBehavior(ctx, graphNode, instance);\n return instance;\n }\n\n default: {\n // Structural nodes: container / section / page / form / list / list-item.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n if (graphNode.type === 'form') {\n wireEvents(dom, graph, graphNode, domNode, instance);\n }\n // Hydration boundary (a \"slot\" such as the router outlet): adopt the\n // element itself but leave its existing children untouched — neither\n // hydrated by this pass nor removed as surplus. Something else (e.g. the\n // router) owns and will hydrate the content already inside it. Without\n // this, an empty-in-the-graph slot would strip the server-rendered\n // content it is meant to preserve.\n if (graphNode.getProp('_hydrationBoundary') === true) {\n return instance;\n }\n hydrateChildren(ctx, graphNode, instance, domNode, path);\n if (graphNode.type === 'component') wireComponentBehavior(ctx, graphNode, instance);\n return instance;\n }\n }\n}\n\n// ── Child matching + local mismatch recovery ───────────────────────────────────\n\n/**\n * Positionally match a parent's expected child graph nodes against the actual\n * child *elements* in the DOM. Matching children are hydrated in place; a\n * mismatch (wrong tag or a missing element) triggers a local repair — the fresh\n * subtree is mounted and spliced into the correct position — without disturbing\n * sibling subtrees. Surplus DOM elements are removed.\n */\nfunction hydrateChildren(\n ctx: RenderContext,\n parentGraphNode: GraphNode,\n parentInstance: NodeInstance,\n parentDom: Element,\n parentPath: string,\n): void {\n const expected = parentGraphNode.children;\n const actual = elementChildren(ctx, parentDom);\n let cursor = 0;\n\n // The human-readable `path` is only ever consumed by hydration diagnostics,\n // which are inert unless a sink is attached. Building the\n // `${parentPath} / ${type}[${i}]` string for every child would allocate one\n // throwaway string per node on the hot path (10k+ on a large tree) for output\n // that is discarded in production. Gate the construction on the sink being\n // present; when it is absent, thread the (meaningless-but-unused) parent path\n // through unchanged so nested calls stay allocation-free too.\n const diag = ctx.hydrationDiagnostics !== undefined;\n\n for (let i = 0; i < expected.length; i++) {\n const childNode = expected[i]!;\n const want = expectedTag(ctx, childNode);\n const childPath = diag ? `${parentPath} / ${childNode.type}[${i}]` : parentPath;\n const actualEl = actual[cursor];\n\n if (\n actualEl !== undefined &&\n ctx.dom.isElement(actualEl) &&\n ctx.dom.tagName(actualEl) === want\n ) {\n // Match — adopt the existing element.\n const inst = hydrateNode(ctx, childNode, actualEl, childPath);\n parentInstance.addChild(inst);\n cursor++;\n } else {\n // Mismatch or missing — repair only this subtree. Mount fresh, then move\n // it into the correct position ahead of the offending/absent node.\n const ref = actualEl ?? null;\n const inst = mountFreshAt(ctx, childNode, parentDom, ref);\n parentInstance.addChild(inst);\n if (actualEl !== undefined) {\n // Drop the mismatched element that the fresh node replaces.\n const found = ctx.dom.isElement(actualEl) ? ctx.dom.tagName(actualEl) : null;\n reportHydrationDiagnostic(ctx, {\n type: 'tag-mismatch',\n expected: want,\n found,\n path: childPath,\n nodeId: childNode.id,\n nodeType: childNode.type,\n action: 'mounted fresh subtree in place',\n });\n ctx.dom.removeChild(parentDom, actualEl);\n cursor++;\n } else {\n reportHydrationDiagnostic(ctx, {\n type: 'missing-element',\n expected: want,\n found: null,\n path: childPath,\n nodeId: childNode.id,\n nodeType: childNode.type,\n action: 'mounted fresh subtree',\n });\n }\n }\n }\n\n // Remove any surplus server elements the graph no longer expects.\n for (let i = cursor; i < actual.length; i++) {\n const surplus = actual[i]!;\n reportHydrationDiagnostic(ctx, {\n type: 'surplus-element',\n expected: null,\n found: ctx.dom.isElement(surplus) ? ctx.dom.tagName(surplus) : null,\n path: `${parentPath} / [surplus ${i}]`,\n nodeId: null,\n nodeType: null,\n action: 'removed surplus server element',\n });\n ctx.dom.removeChild(parentDom, surplus);\n }\n}\n\n/**\n * Emit a hydration diagnostic through the (optional) sink. When no sink is\n * attached this is a single cheap `undefined` check — the production default.\n */\nfunction reportHydrationDiagnostic(\n ctx: RenderContext,\n d: {\n type: 'tag-mismatch' | 'missing-element' | 'surplus-element';\n expected: string | null;\n found: string | null;\n path: string;\n nodeId: string | null;\n nodeType: string | null;\n action: string;\n },\n): void {\n const sink = ctx.hydrationDiagnostics;\n if (sink === undefined) return;\n sink.report({ ...d, message: formatHydrationDiagnostic(d) });\n}\n\n/** Mount a fresh subtree for `node` and splice it before `ref` (or append). */\nfunction mountFreshAt(\n ctx: RenderContext,\n node: GraphNode,\n parentDom: Element,\n ref: Node | null,\n): NodeInstance {\n // mountNode appends the new subtree at the end of parentDom.\n const inst = mountNode(ctx, node, parentDom);\n if (ref !== null) {\n ctx.dom.insertBefore(parentDom, inst.domNode, ref);\n }\n return inst;\n}\n\n/** The element (not text/comment) children of a node, in order. */\nfunction elementChildren(ctx: RenderContext, parent: Element): Element[] {\n const out: Element[] = [];\n for (const node of ctx.dom.childNodes(parent)) {\n if (ctx.dom.isElement(node)) out.push(node);\n }\n return out;\n}\n\n/** The HTML tag a graph node is expected to occupy in the DOM. */\nfunction expectedTag(ctx: RenderContext, graphNode: GraphNode): string {\n switch (graphNode.type) {\n case 'text':\n return 'span';\n case 'heading': {\n const level = (graphNode.getProp('level') as number | undefined) ?? 1;\n return `h${level}`;\n }\n case 'input':\n return 'input';\n case 'image':\n return 'img';\n case 'link':\n return 'a';\n case 'button':\n return 'button';\n default:\n // reactive-list → ul, conditional → div, structural → resolveTag.\n return resolveTag(graphNode.type);\n }\n}\n","/**\n * StreetRenderHandle — the live handle returned by both `mount` and `hydrate`.\n *\n * Owns teardown for a mounted/hydrated application: disposes every NodeInstance\n * (removing event listeners and signal subscriptions) and clears the container\n * through the DOM adapter (never raw browser globals), so the same handle works\n * for browser and — in principle — server-driven teardown.\n */\n\nimport type { RenderHandle } from '@streetui/runtime';\nimport type { RenderContext } from './render-context.js';\nimport type { NodeInstance } from './node-instance.js';\n\nexport class StreetRenderHandle implements RenderHandle {\n private _disposed = false;\n private readonly _ctx: RenderContext;\n private readonly _rootInstance: NodeInstance;\n\n constructor(ctx: RenderContext, rootInstance: NodeInstance) {\n this._ctx = ctx;\n this._rootInstance = rootInstance;\n }\n\n flush(): void {\n if (this._disposed) return;\n // Signal subscriptions fire synchronously in StreetUI's state system;\n // flush() is a no-op at the renderer level — the DOM is already up to date\n // unless the scheduler is batching, in which case the scheduler calls\n // flush() after draining its queue.\n }\n\n unmount(): void {\n if (this._disposed) return;\n this._disposed = true;\n\n // Dispose all node instances (removes event listeners, signal subscriptions).\n this._rootInstance.dispose();\n\n // Remove all children from the container. Routed through the DOM adapter\n // (never `container.firstChild`/`removeChild`) so the teardown path is\n // server-safe.\n const dom = this._ctx.dom;\n const container = this._ctx.container;\n for (const child of dom.childNodes(container)) {\n dom.removeChild(container, child);\n }\n\n this._ctx.instances.clear();\n }\n}\n","/**\n * StreetUI Renderer — framework-owned DOM renderer.\n *\n * No React. No Vue. No virtual-dom. No external rendering library.\n *\n * Pipeline:\n * CompiledApplication\n * → mountGraph (creates all DOM nodes)\n * → signal subscriptions drive patchNode (targeted updates)\n * → flush() propagates any pending scheduler jobs\n * → unmount() disposes everything\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\nimport { BrowserDOMAdapter } from '@streetui/dom';\nimport type { CompiledApplication } from '@streetui/compiler';\nimport type { StreetRenderer, RenderHandle } from '@streetui/runtime';\nimport { createRenderContext } from './render-context.js';\nimport { mountGraph } from './mount.js';\nimport { hydrateGraph } from './hydrate.js';\nimport { StreetRenderHandle } from './render-handle.js';\nimport type { NodeInstance } from './node-instance.js';\nimport type { HydrationDiagnosticSink } from './hydration-diagnostics.js';\n\nexport interface StreetRendererOptions {\n /** Override the DOM adapter (e.g. for testing). Defaults to BrowserDOMAdapter. */\n readonly domAdapter?: DOMAdapter;\n /**\n * Optional dev-only sink that observes hydration mismatch repairs. Attach one\n * to surface server/client divergences during development; leave it unset in\n * production so hydration does no extra work.\n */\n readonly hydrationDiagnostics?: HydrationDiagnosticSink;\n}\n\nexport class StreetRendererImpl implements StreetRenderer {\n private readonly _dom: DOMAdapter;\n private readonly _hydrationDiagnostics?: HydrationDiagnosticSink;\n\n constructor(options: StreetRendererOptions = {}) {\n this._dom = options.domAdapter ?? new BrowserDOMAdapter();\n if (options.hydrationDiagnostics !== undefined) {\n this._hydrationDiagnostics = options.hydrationDiagnostics;\n }\n }\n\n mount(compiled: CompiledApplication, container: Element): RenderHandle {\n const ctx = createRenderContext(this._dom, compiled.graph, container);\n\n // Initial mount — creates the full DOM tree\n const rootInstance = mountGraph(ctx);\n\n // Wire all signal subscriptions so that signal → DOM patches happen automatically\n this._wireSignals(ctx, rootInstance);\n\n return new StreetRenderHandle(ctx, rootInstance);\n }\n\n /**\n * Hydrate a container that already holds server-rendered HTML for this\n * application. Instead of recreating the DOM, it walks the semantic graph\n * against the existing nodes, adopting matching elements and attaching\n * behavior (events + signal subscriptions). Mismatched subtrees are locally\n * replaced. Returns the same handle type as `mount`.\n */\n hydrate(compiled: CompiledApplication, container: Element): RenderHandle {\n const ctx = createRenderContext(\n this._dom,\n compiled.graph,\n container,\n this._hydrationDiagnostics,\n );\n const rootInstance = hydrateGraph(ctx);\n this._wireSignals(ctx, rootInstance);\n return new StreetRenderHandle(ctx, rootInstance);\n }\n\n private _wireSignals(\n ctx: ReturnType<typeof createRenderContext>,\n rootInstance: NodeInstance,\n ): void {\n // Each NodeInstance already wired its own signals in mountNode via wireSignalBindings.\n // This method is a hook for any cross-cutting signal concerns at the renderer level.\n // Currently no-op — individual mount calls handle their own subscriptions.\n void ctx;\n void rootInstance;\n }\n}\n\n/**\n * Create the default StreetUI renderer using the browser's DOM APIs.\n */\nexport function createRenderer(options?: StreetRendererOptions): StreetRendererImpl {\n return new StreetRendererImpl(options);\n}\n","/**\n * Static graph analysis (v1.2, spec §3/§12/§14).\n *\n * A single post-order walk over the Semantic Application Graph that classifies\n * every node as static (no bound signals, no events, not a reactive\n * region) or dynamic, and rolls that up into whole-static-subtree flags. This\n * is COMPILE-TIME metadata only — it introduces no virtual DOM, no second tree\n * and no runtime reactive system. It is consumed by:\n * - the hydration path, to skip per-node attribute/text re-verification on\n * provably-static subtrees (§12), and\n * - the diagnostic compiler-inspection report (§14).\n *\n * The renderer's initial-mount fast path does not need this map: it already\n * skips reactive wiring per node via cheap `events.length`/`stateRefs.length`\n * guards. Keeping the analysis out of the mount hot path avoids adding lookup\n * cost (and keeps the shipped runtime lean).\n */\n\nimport type { NodeId } from '@streetui/core';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\n\n/** Prop keys whose bound signal drives text content rather than an attribute. */\nconst TEXT_PROP_KEYS: ReadonlySet<string> = new Set(['text', 'label', 'value']);\n\nexport interface NodeAnalysis {\n /** No bound signals, no events, and not a reactive-list/conditional region. */\n readonly isStatic: boolean;\n /** This node is static AND every descendant is a static subtree. */\n readonly isStaticSubtree: boolean;\n /** A signal is bound to this node's text/label/value content. */\n readonly hasDynamicText: boolean;\n /** A signal is bound to a non-content prop (a reactive attribute). */\n readonly hasDynamicAttr: boolean;\n /** This node wires one or more DOM event handlers. */\n readonly hasEvents: boolean;\n /** This node is a keyed reactive list. */\n readonly isList: boolean;\n /** This node is a conditional (0..1 branch) region. */\n readonly isConditional: boolean;\n}\n\nexport interface GraphAnalysisSummary {\n readonly totalNodes: number;\n readonly staticNodes: number;\n readonly staticSubtrees: number;\n readonly dynamicTextNodes: number;\n readonly dynamicAttrNodes: number;\n readonly eventNodes: number;\n readonly lists: number;\n readonly conditionals: number;\n}\n\nexport interface GraphAnalysis {\n readonly nodes: ReadonlyMap<NodeId, NodeAnalysis>;\n readonly summary: GraphAnalysisSummary;\n}\n\n/**\n * Analyze a fully-built graph. O(n) single post-order pass; allocates one small\n * record per node. Safe to skip entirely when neither hydration nor diagnostics\n * need it.\n */\nexport function analyzeGraph(graph: ApplicationGraph): GraphAnalysis {\n const nodes = new Map<NodeId, NodeAnalysis>();\n const summary = {\n totalNodes: 0, staticNodes: 0, staticSubtrees: 0, dynamicTextNodes: 0,\n dynamicAttrNodes: 0, eventNodes: 0, lists: 0, conditionals: 0,\n };\n\n const visit = (node: GraphNode): boolean => {\n // Post-order: children first so subtree rollup is exact.\n let allChildrenStatic = true;\n for (const child of node.children) {\n const childSubtreeStatic = visit(child);\n if (!childSubtreeStatic) allChildrenStatic = false;\n }\n\n let hasDynamicText = false;\n let hasDynamicAttr = false;\n for (const ref of node.stateRefs) {\n if (TEXT_PROP_KEYS.has(ref.propKey)) hasDynamicText = true;\n else hasDynamicAttr = true;\n }\n const hasEvents = node.events.length > 0;\n const isList = node.type === 'reactive-list';\n const isConditional = node.type === 'conditional';\n // A portal relocates its children to a different DOM location (document.body)\n // at mount time, so its subtree is never a contiguous inline static blob.\n // Treating it as dynamic stops the static-subtree rollup at the portal, so\n // both SSR and hydration always take the real portal mount/hydrate branch\n // (which does the relocation) rather than emitting/adopting a raw HTML blob.\n const isPortal = node.type === 'portal';\n // A component owns per-instance lifecycle wiring (a `__component__<id>`\n // cleanup handler read at mount/hydrate). Treating it as dynamic stops the\n // static-subtree rollup at the component boundary so it always takes the\n // real mount/hydrate branch (which wires cleanups) instead of collapsing\n // into a serialized raw-HTML blob that would drop that per-instance wiring.\n const isComponent = node.type === 'component';\n // A `head` node contributes document metadata via a `__head__<id>` handler\n // wired at mount/hydrate (`wireHeadBehavior`). Treating it as dynamic stops\n // the static-subtree rollup at the head boundary so it always takes the real\n // mount/hydrate branch (which registers/cleans up the contribution) instead\n // of collapsing into a serialized raw-HTML blob that would drop that wiring.\n const isHead = node.type === 'head';\n const isStatic =\n node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional && !isPortal && !isComponent && !isHead;\n const isStaticSubtree = isStatic && allChildrenStatic;\n\n nodes.set(node.id, {\n isStatic, isStaticSubtree, hasDynamicText, hasDynamicAttr,\n hasEvents, isList, isConditional,\n });\n\n summary.totalNodes += 1;\n if (isStatic) summary.staticNodes += 1;\n if (isStaticSubtree) summary.staticSubtrees += 1;\n if (hasDynamicText) summary.dynamicTextNodes += 1;\n if (hasDynamicAttr) summary.dynamicAttrNodes += 1;\n if (hasEvents) summary.eventNodes += 1;\n if (isList) summary.lists += 1;\n if (isConditional) summary.conditionals += 1;\n\n return isStaticSubtree;\n };\n\n visit(graph.root);\n return { nodes, summary };\n}\n","/**\n * Diagnostic compiler-inspection mode (v1.2, spec §14).\n *\n * Produces a machine-readable (and optionally text-formatted) description of\n * what the compiler understands about an application: which nodes are static\n * vs dynamic, which carry dynamic text or attributes, which wire events, and\n * which are conditional regions or keyed lists — plus the hydration metadata\n * derived from that classification.\n *\n * This is a DIAGNOSTIC tool. It is not part of the runtime, is not consulted\n * during mount, and is tree-shakeable out of any app that never calls it.\n */\n\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport { analyzeGraph, type GraphAnalysisSummary } from './analyze.js';\n\nexport interface InspectedCompilationNode {\n readonly id: string;\n readonly type: string;\n readonly depth: number;\n readonly classification: 'static' | 'static-subtree-root' | 'dynamic';\n readonly dynamicText: boolean;\n readonly dynamicAttrs: boolean;\n readonly events: readonly string[];\n readonly boundProps: readonly string[];\n readonly isList: boolean;\n readonly isConditional: boolean;\n /** Hydration hint: how the hydration path should treat this node. */\n readonly hydration: 'adopt-static' | 'verify-dynamic';\n}\n\nexport interface CompilerInspection {\n readonly name: string;\n readonly version: string;\n readonly summary: GraphAnalysisSummary & {\n /** Fraction of nodes provably static (0..1). */\n readonly staticRatio: number;\n };\n readonly nodes: readonly InspectedCompilationNode[];\n}\n\n/**\n * Inspect a compiled/built graph and return a structured diagnostic report.\n * Purely observational — never mutates the graph.\n */\nexport function inspectCompilation(graph: ApplicationGraph): CompilerInspection {\n const analysis = analyzeGraph(graph);\n const nodes: InspectedCompilationNode[] = [];\n\n const walk = (node: GraphNode, depth: number): void => {\n const a = analysis.nodes.get(node.id);\n if (a !== undefined) {\n const classification: InspectedCompilationNode['classification'] = a.isStaticSubtree\n ? 'static-subtree-root'\n : a.isStatic\n ? 'static'\n : 'dynamic';\n nodes.push({\n id: node.id,\n type: node.type,\n depth,\n classification,\n dynamicText: a.hasDynamicText,\n dynamicAttrs: a.hasDynamicAttr,\n events: node.events.map((e) => e.type),\n boundProps: node.stateRefs.map((r) => r.propKey),\n isList: a.isList,\n isConditional: a.isConditional,\n hydration: a.isStaticSubtree ? 'adopt-static' : 'verify-dynamic',\n });\n }\n for (const child of node.children) walk(child, depth + 1);\n };\n walk(graph.root, 0);\n\n const staticRatio =\n analysis.summary.totalNodes === 0\n ? 0\n : analysis.summary.staticNodes / analysis.summary.totalNodes;\n\n return {\n name: graph.name,\n version: graph.version,\n summary: { ...analysis.summary, staticRatio: +staticRatio.toFixed(4) },\n nodes,\n };\n}\n\n/** Render an inspection as a compact human-readable text report. */\nexport function formatInspection(inspection: CompilerInspection): string {\n const s = inspection.summary;\n const lines: string[] = [];\n lines.push(`StreetUI compiler inspection — ${inspection.name} v${inspection.version}`);\n lines.push(\n ` nodes=${s.totalNodes} static=${s.staticNodes} ` +\n `staticSubtrees=${s.staticSubtrees} dynamicText=${s.dynamicTextNodes} ` +\n `dynamicAttrs=${s.dynamicAttrNodes} events=${s.eventNodes} ` +\n `lists=${s.lists} conditionals=${s.conditionals} ` +\n `staticRatio=${(s.staticRatio * 100).toFixed(1)}%`,\n );\n for (const n of inspection.nodes) {\n const flags: string[] = [];\n if (n.dynamicText) flags.push('text');\n if (n.dynamicAttrs) flags.push('attr:' + n.boundProps.join(','));\n if (n.events.length > 0) flags.push('on:' + n.events.join(','));\n if (n.isList) flags.push('list');\n if (n.isConditional) flags.push('cond');\n lines.push(\n ` ${' '.repeat(n.depth)}${n.type}#${n.id} [${n.classification}]` +\n (flags.length > 0 ? ` {${flags.join(' ')}}` : ''),\n );\n }\n return lines.join('\\n');\n}\n","/**\n * Static SSR Plan (v1.7, spec §4/§6) — internal.\n *\n * A compiler-derived plan that precomputes the verbatim HTML of every *maximal\n * static subtree* in an application graph. During SSR, the renderer emits that\n * precomputed string directly (via `ServerDOMAdapter.createRawHTML`) instead of\n * recursively constructing a `ServerElement`/`ServerText`/`NodeInstance` for\n * every node in the subtree. On the 10k-row `/users` corpus, ~100% of the node\n * mass lives in 10,000 static 8-node row subtrees, so collapsing each row into\n * one precomputed string removes the bulk of the mount-phase construction work.\n *\n * Design constraints honoured here:\n * - §3 REUSE the existing compiler analysis (`analyzeGraph`) to classify nodes;\n * no new/expensive analysis, and nothing runs during normal `compile()`.\n * - §5/§15 Only *maximal static-subtree roots* are collapsed. A dynamic region\n * (reactive-list container, conditional, dynamic-text/attr node) is never\n * treated as static — the list itself stays dynamic; only the provably-static\n * subtree *inside* each repeated item is precomputed.\n * - §8 The precomputed HTML is produced by the SAME mount + serialize pipeline\n * as the runtime path, so full-render output is byte-identical.\n * - §19 The plan retains ONLY strings keyed by GraphNode.id. No ServerDOM node,\n * NodeInstance or application object is retained (the throwaway build tree is\n * disposed + cleared). The per-app cache is a WeakMap, so a plan is released\n * when its CompiledApplication is collected.\n * - §24 Everything here is internal: not re-exported from the `streetui` or\n * `streetui/server` runtime barrels.\n *\n * This module is only ever imported by the SSR entry (`renderToString`), which\n * is itself reachable solely through the server path, so it tree-shakes out of\n * client bundles (§20, verified by bundle measurement).\n */\n\nimport type { NodeId } from '@streetui/core';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport type { CompiledApplication } from '@streetui/compiler';\nimport { analyzeGraph } from '@streetui/compiler/diagnostics';\nimport { ServerDOMAdapter } from '@streetui/dom';\nimport { createRenderContext } from './render-context.js';\nimport { mountNode } from './mount.js';\n\n/**\n * Internal representation of the static SSR plan: maximal static-subtree root\n * GraphNode.id → its precomputed, verbatim outer HTML. A plain `Map<string,\n * string>` is deliberate — it holds no DOM/application references (§19).\n */\nexport type StaticSSRPlan = ReadonlyMap<NodeId, string>;\n\n/**\n * Collect the ids of every *maximal* static-subtree root under `graph`.\n *\n * Walk from the root; when a node is itself a whole static subtree, it is a\n * maximal root — record it and stop (its static descendants are subsumed).\n * Otherwise descend into its children, so a dynamic node's individually-static\n * children are still captured (the mixed-tree case, §5). The `application` root\n * is never recorded: it maps onto the render container rather than emitting its\n * own element, so we always descend past it into its real top-level children.\n */\nfunction collectMaximalStaticRoots(graph: ApplicationGraph): GraphNode[] {\n const analysis = analyzeGraph(graph);\n const roots: GraphNode[] = [];\n\n const walk = (node: GraphNode): void => {\n if (node.type !== 'application') {\n const a = analysis.nodes.get(node.id);\n if (a !== undefined && a.isStaticSubtree) {\n roots.push(node);\n return;\n }\n }\n for (const child of node.children) walk(child);\n };\n\n walk(graph.root);\n return roots;\n}\n\n/**\n * Serialize the outer HTML of a single static subtree using the exact runtime\n * mount + serialize pipeline (so the bytes match a full render). The throwaway\n * tree is disposed immediately, so nothing is retained.\n */\nfunction serializeStaticSubtree(\n dom: ServerDOMAdapter,\n graph: ApplicationGraph,\n root: GraphNode,\n): string {\n const container = dom.createElement('div');\n // No `staticHTML` on this ctx → mountNode builds the subtree fully.\n const ctx = createRenderContext(dom, graph, container);\n const instance = mountNode(ctx, root, container);\n const html = dom.serializeInner(container);\n // Tear down (static subtrees open no subscriptions, but keep symmetry with\n // renderToString's lifecycle) and drop all references.\n instance.dispose();\n ctx.instances.clear();\n return html;\n}\n\n/**\n * Build the static SSR plan for a compiled application. O(n) analysis + one\n * mount/serialize per maximal static subtree. Returns an empty map when the app\n * has no static subtrees (e.g. a highly-dynamic page) — the SSR path then\n * behaves exactly as v1.6.\n */\nexport function buildStaticSSRPlan(compiled: CompiledApplication): StaticSSRPlan {\n const graph = compiled.graph;\n const roots = collectMaximalStaticRoots(graph);\n const plan = new Map<NodeId, string>();\n if (roots.length === 0) return plan;\n\n const dom = new ServerDOMAdapter();\n for (const root of roots) {\n plan.set(root.id, serializeStaticSubtree(dom, graph, root));\n }\n return plan;\n}\n\n/**\n * Per-application plan cache. A WeakMap keyed by the CompiledApplication so a\n * plan is built once and reused across renders, and is released together with\n * the compiled app it belongs to — no long-lived retention of app state (§19).\n */\nconst PLAN_CACHE = new WeakMap<CompiledApplication, StaticSSRPlan>();\n\n/** Get the cached static SSR plan for a compiled app, building it on first use. */\nexport function getStaticSSRPlan(compiled: CompiledApplication): StaticSSRPlan {\n let plan = PLAN_CACHE.get(compiled);\n if (plan === undefined) {\n plan = buildStaticSSRPlan(compiled);\n PLAN_CACHE.set(compiled, plan);\n }\n return plan;\n}\n","/**\n * Server-side rendering — `renderToString`.\n *\n * Runs the *exact same* mount pipeline used in the browser (`mountGraph`), but\n * against a `ServerDOMAdapter` that builds a lightweight in-memory node tree\n * instead of a real browser DOM. The tree is then serialized to a normal HTML\n * string. Because both browser and server share the DSL → Compiler → Graph →\n * Runtime → Renderer pipeline, there is no second, SSR-specific renderer and no\n * virtual DOM.\n *\n * Lifecycle (v0.4 rule #20): the initial synchronous mount may open signal\n * subscriptions (via `wireSignalBindings`/`wireReactiveList`). On the server\n * those would be live forever, so once the HTML is serialized we dispose the\n * root instance — tearing down every subscription and listener. SSR therefore\n * has a *render* lifecycle only; the live *runtime* lifecycle is established\n * later on the client by `hydrate`.\n */\n\nimport { ServerDOMAdapter } from '@streetui/dom';\nimport type { CompiledApplication } from '@streetui/compiler';\nimport { createRenderContext } from './render-context.js';\nimport { mountGraph } from './mount.js';\nimport { getStaticSSRPlan } from './static-ssr-plan.js';\n\nexport interface RenderToStringOptions {\n /**\n * Override the server DOM adapter (rarely needed). Defaults to a fresh\n * `ServerDOMAdapter` per call so concurrent renders never share state.\n */\n readonly domAdapter?: ServerDOMAdapter;\n /**\n * @internal — testing/benchmark knob for the v1.7 static SSR plan.\n *\n * `undefined` (default): use the per-app cached plan (build once, reuse).\n * `null`: disable the plan entirely — the exact v1.6 runtime mount path, used\n * by the byte-identity gate and A/B benchmark as the \"legacy\" baseline.\n * a map: use this explicit plan.\n *\n * Not part of the supported public API; output is byte-identical regardless\n * of this value (§8).\n */\n readonly staticPlan?: ReadonlyMap<string, string> | null;\n}\n\n/**\n * Render a compiled StreetUI application to an HTML string.\n *\n * The returned markup contains only the application's own elements (the\n * synthetic container is not emitted), so callers embed it wherever they mount\n * on the client — e.g. inside `<div id=\"app\">…</div>`.\n */\nexport function renderToString(\n compiled: CompiledApplication,\n options: RenderToStringOptions = {},\n): string {\n const dom = options.domAdapter ?? new ServerDOMAdapter();\n\n // Resolve the v1.7 static SSR plan: cached-by-default, `null` forces the v1.6\n // path, an explicit map is used as-is. Only maximal static-subtree roots are\n // collapsed; dynamic regions still mount through the runtime path (§5).\n const plan =\n options.staticPlan === null\n ? undefined\n : (options.staticPlan ?? getStaticSSRPlan(compiled));\n const staticHTML = plan !== undefined && plan.size > 0 ? plan : undefined;\n\n // Synthetic container — the application root maps onto it, and the app's\n // top-level nodes are appended directly into it (mirroring browser mount).\n const container = dom.createElement('div');\n\n const ctx = createRenderContext(dom, compiled.graph, container, undefined, staticHTML);\n const rootInstance = mountGraph(ctx);\n\n const html = dom.serializeInner(container);\n\n // Tear down any subscriptions/listeners opened during mount — the server has\n // no live runtime. (rule #20)\n rootInstance.dispose();\n ctx.instances.clear();\n\n return html;\n}\n","/**\n * StreetUI Test Renderer.\n *\n * Renders a StreetApp into a real (happy-dom / jsdom) DOM container\n * and exposes query helpers so tests can assert on structure/content\n * without importing the browser renderer directly.\n */\n\nimport { resetIdCounter } from '@streetui/core';\nimport { compile } from '@streetui/compiler';\nimport type { StreetApp } from '@streetui/dsl';\nimport { BrowserDOMAdapter } from '@streetui/dom';\nimport { createRenderer } from '@streetui/renderer';\nimport type { RenderHandle } from '@streetui/runtime';\n\nexport interface RenderResult {\n /** The root container element that was rendered into. */\n readonly container: HTMLElement;\n /** Unmount and clean up the render. */\n unmount(): void;\n /** Query a single element (throws if missing). */\n getByTag<K extends keyof HTMLElementTagNameMap>(tag: K): HTMLElementTagNameMap[K];\n /** Query all elements by tag. */\n getAllByTag<K extends keyof HTMLElementTagNameMap>(tag: K): Array<HTMLElementTagNameMap[K]>;\n /** Query by text content (partial match). */\n getByText(text: string): Element;\n /** Query all elements whose text content includes the given string. */\n getAllByText(text: string): Element[];\n /** Raw querySelector. */\n query(selector: string): Element | null;\n /** Raw querySelectorAll. */\n queryAll(selector: string): Element[];\n /** Assert element exists; return it. */\n find(selector: string): Element;\n /** Force a flush of any pending scheduler work. */\n flush(): void;\n /** The underlying render handle. */\n readonly handle: RenderHandle;\n}\n\n/**\n * Render a StreetApp into a detached DOM container.\n * Uses the real StreetUI renderer backed by happy-dom/jsdom.\n */\nexport function render(app: StreetApp): RenderResult {\n const compiled = compile(app);\n const container = document.createElement('div');\n document.body.appendChild(container);\n\n const renderer = createRenderer({ domAdapter: new BrowserDOMAdapter() });\n const handle = renderer.mount(compiled, container);\n\n return {\n container,\n handle,\n unmount() {\n handle.unmount();\n if (container.parentNode !== null) {\n container.parentNode.removeChild(container);\n }\n },\n flush() {\n handle.flush();\n },\n getByTag<K extends keyof HTMLElementTagNameMap>(tag: K): HTMLElementTagNameMap[K] {\n const el = container.querySelector(tag);\n if (el === null) {\n throw new Error(`[StreetUI Testing] Element <${tag}> not found in render output`);\n }\n return el as HTMLElementTagNameMap[K];\n },\n getAllByTag<K extends keyof HTMLElementTagNameMap>(tag: K): Array<HTMLElementTagNameMap[K]> {\n return Array.from(container.querySelectorAll(tag)) as Array<HTMLElementTagNameMap[K]>;\n },\n getByText(text: string): Element {\n const all = Array.from(container.querySelectorAll('*'));\n const match = all.find(el =>\n el.children.length === 0 && el.textContent?.includes(text),\n );\n if (match === undefined) {\n throw new Error(`[StreetUI Testing] No element with text \"${text}\" found`);\n }\n return match;\n },\n getAllByText(text: string): Element[] {\n return Array.from(container.querySelectorAll('*')).filter(el =>\n el.textContent?.includes(text),\n );\n },\n query(selector: string): Element | null {\n return container.querySelector(selector);\n },\n queryAll(selector: string): Element[] {\n return Array.from(container.querySelectorAll(selector));\n },\n find(selector: string): Element {\n const el = container.querySelector(selector);\n if (el === null) {\n throw new Error(`[StreetUI Testing] Selector \"${selector}\" matched nothing`);\n }\n return el;\n },\n };\n}\n\n/** Render and automatically clean up after the test. */\nexport function renderOnce(\n app: StreetApp,\n testFn: (result: RenderResult) => void | Promise<void>,\n): Promise<void> {\n const result = render(app);\n return Promise.resolve(testFn(result)).finally(() => {\n result.unmount();\n resetIdCounter();\n });\n}\n","/**\n * StreetUI update scheduler.\n *\n * Responsibilities:\n * - Queue update callbacks\n * - Batch synchronous enqueues into a single microtask flush\n * - Guarantee ordering: higher priority jobs flush first\n * - Prevent duplicate work for the same job key\n * - Allow synchronous flush for tests\n */\n\nexport type Priority = 'immediate' | 'normal' | 'idle';\n\nconst PRIORITY_ORDER: Record<Priority, number> = {\n immediate: 0,\n normal: 1,\n idle: 2,\n};\n\nexport interface Job {\n /** Unique key — if another job with the same key is already queued, it is replaced. */\n readonly key: string;\n readonly priority: Priority;\n readonly fn: () => void;\n}\n\n/**\n * Optional error-reporting hook (v0.9 §26/§27). Structurally compatible with\n * `@streetui/core`'s `DiagnosticSink` (the `error` method) so an application can\n * route swallowed scheduler-job failures through its own logger instead of the\n * default `console.error`. Kept as a local structural type so the scheduler\n * stays dependency-free; no network, no telemetry. When unset, behaviour is\n * exactly as before.\n */\nexport interface SchedulerDiagnostics {\n error?(message: string, context?: unknown): void;\n}\n\nexport class Scheduler {\n private readonly _queue: Map<string, Job> = new Map();\n private _flushScheduled = false;\n private _flushing = false;\n private _diagnostics: SchedulerDiagnostics | undefined = undefined;\n\n /**\n * Install an optional diagnostic sink for swallowed job errors. Pass\n * `undefined` to restore the default `console.error` reporting. Additive and\n * opt-in — the scheduler never sends anything anywhere on its own.\n */\n setDiagnostics(sink: SchedulerDiagnostics | undefined): void {\n this._diagnostics = sink;\n }\n\n /** Total jobs currently queued. */\n get size(): number {\n return this._queue.size;\n }\n\n /** True if a flush has been scheduled but not yet executed. */\n get isPending(): boolean {\n return this._flushScheduled;\n }\n\n /**\n * Enqueue a job. If a job with the same key exists, the new one replaces it\n * (allowing callers to coalesce repeated updates for the same node).\n */\n schedule(job: Job): void {\n this._queue.set(job.key, job);\n if (!this._flushScheduled && !this._flushing) {\n this._flushScheduled = true;\n this._scheduleMicrotask();\n }\n }\n\n /** Schedule multiple jobs atomically. */\n scheduleAll(jobs: readonly Job[]): void {\n for (const job of jobs) {\n this._queue.set(job.key, job);\n }\n if (!this._flushScheduled && !this._flushing && this._queue.size > 0) {\n this._flushScheduled = true;\n this._scheduleMicrotask();\n }\n }\n\n /**\n * Cancel a queued job by key. No-op if not queued.\n */\n cancel(key: string): void {\n this._queue.delete(key);\n }\n\n /**\n * Synchronously flush all queued jobs (sorted by priority).\n * Useful in tests and for immediate rendering.\n */\n flush(): void {\n if (this._flushing) return;\n this._flushScheduled = false;\n this._flushing = true;\n\n const jobs = Array.from(this._queue.values()).sort(\n (a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority],\n );\n this._queue.clear();\n\n try {\n for (const job of jobs) {\n try {\n job.fn();\n } catch (err) {\n // Isolate job failures — report and continue so remaining jobs still run.\n if (this._diagnostics?.error) {\n this._diagnostics.error(`Scheduler job \"${job.key}\" threw`, err);\n } else {\n console.error(`[Scheduler] Job \"${job.key}\" threw:`, err);\n }\n }\n }\n } finally {\n this._flushing = false;\n }\n }\n\n /** Clear all pending jobs without executing them. */\n clear(): void {\n this._queue.clear();\n this._flushScheduled = false;\n }\n\n private _scheduleMicrotask(): void {\n Promise.resolve().then(() => {\n if (this._flushScheduled) {\n this.flush();\n }\n });\n }\n}\n\n/** The shared global scheduler instance. */\nexport const scheduler = new Scheduler();\n\n/** Convenience: schedule a normal-priority job. */\nexport function scheduleUpdate(key: string, fn: () => void): void {\n scheduler.schedule({ key, priority: 'normal', fn });\n}\n\n/** Convenience: schedule an immediate-priority job. */\nexport function scheduleImmediate(key: string, fn: () => void): void {\n scheduler.schedule({ key, priority: 'immediate', fn });\n}\n\n/** Convenience: flush the global scheduler synchronously. */\nexport function flushSync(): void {\n scheduler.flush();\n}\n","/**\n * Higher-level testing helpers: role/text queries, update flushing, async\n * waiting, and a first-class SSR → hydrate → assert workflow.\n *\n * These build on the same real renderer the app uses — no private-graph access,\n * no second assertion framework. They exist so a test does not have to\n * reimplement server-render/hydrate plumbing or poll for async resource state\n * by hand.\n */\n\nimport { resetIdCounter } from '@streetui/core';\nimport { flushSync } from '@streetui/scheduler';\nimport { compile } from '@streetui/compiler';\nimport type { StreetApp } from '@streetui/dsl';\nimport { BrowserDOMAdapter } from '@streetui/dom';\nimport {\n createRenderer,\n renderToString,\n type HydrationDiagnostic,\n createHydrationDiagnosticCollector,\n} from '@streetui/renderer';\nimport type { RenderHandle } from '@streetui/runtime';\n\n// ── Update flushing & async waiting ─────────────────────────────────────────\n\n/**\n * Flush all pending scheduler work, then yield once to the microtask queue so\n * promise-driven updates (e.g. a resolved `resource` loader) are applied. Await\n * this after triggering a change that schedules a DOM patch.\n */\nexport async function flushUpdates(): Promise<void> {\n flushSync();\n await Promise.resolve();\n flushSync();\n}\n\nexport interface WaitForOptions {\n /** Give up after this many milliseconds (default 1000). */\n readonly timeout?: number;\n /** Delay between attempts in milliseconds (default 10). */\n readonly interval?: number;\n}\n\n/**\n * Poll `check` until it returns a truthy value (or stops throwing), flushing\n * updates between attempts. Rejects with the last error/tiemout after the\n * deadline. Use for assertions that become true only after async work settles.\n */\nexport async function waitFor<T>(\n check: () => T,\n options: WaitForOptions = {},\n): Promise<T> {\n const timeout = options.timeout ?? 1000;\n const interval = options.interval ?? 10;\n const deadline = Date.now() + timeout;\n let lastError: unknown;\n\n for (;;) {\n await flushUpdates();\n try {\n const result = check();\n if (result) return result;\n lastError = new Error('[StreetUI Testing] waitFor: condition was falsy');\n } catch (err) {\n lastError = err;\n }\n if (Date.now() >= deadline) {\n throw lastError instanceof Error\n ? lastError\n : new Error(String(lastError));\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n}\n\n// ── Interaction helpers (§20) ───────────────────────────────────────────────\n\n/** A minimal writable-boolean seam (an overlay `open` signal, typically). */\nexport interface BooleanControl {\n set(value: boolean): void;\n}\n\n/** Focus `el` (no-op if it exposes no `focus`). Intentful wrapper for tests. */\nexport function focus(el: Element): void {\n (el as unknown as { focus?: () => void }).focus?.();\n}\n\n/** Blur `el` (no-op if it exposes no `blur`). */\nexport function blur(el: Element): void {\n (el as unknown as { blur?: () => void }).blur?.();\n}\n\n/**\n * Dispatch a bubbling, cancelable `keydown` for `key` on `el` (defaulting to the\n * currently-focused element). Extra `init` fields (e.g. `{ shiftKey: true }`)\n * are forwarded. Use for keyboard-interaction assertions (Escape, Tab, arrows).\n */\nexport function pressKey(\n key: string,\n el: Element | null = document.activeElement,\n init: KeyboardEventInit = {},\n): void {\n if (el === null) return;\n el.dispatchEvent(\n new KeyboardEvent('keydown', { key, bubbles: true, cancelable: true, ...init }),\n );\n}\n\n/**\n * Simulate a pointer interaction OUTSIDE `container` — a `mousedown` + `click`\n * on `document.body` (or `target` if given). Drives \"click-away to dismiss\"\n * behaviour without the test constructing events by hand. If `target` is inside\n * `container` this throws, so a mistake is loud rather than a silent no-op.\n */\nexport function clickOutside(container: Element, target: Element = document.body): void {\n if (container.contains(target)) {\n throw new Error('[StreetUI Testing] clickOutside: target is inside the container');\n }\n target.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));\n target.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));\n}\n\n/**\n * Open an overlay by flipping its `open` control to `true`, then flush so the\n * panel mounts and its enter/focus wiring runs. Overlay visibility is app-owned\n * state (§18) — a plain signal — so this is a thin, intentful wrapper over\n * `set(true)` + {@link flushUpdates}.\n */\nexport async function openOverlay(open: BooleanControl): Promise<void> {\n open.set(true);\n await flushUpdates();\n}\n\n/** Close an overlay by flipping its `open` control to `false`, then flush. */\nexport async function closeOverlay(open: BooleanControl): Promise<void> {\n open.set(false);\n await flushUpdates();\n}\n\n/**\n * Settle a CSS transition on `el` deterministically: dispatch the\n * `transitionend` the controller listens for (happy-dom fires none of its own),\n * then flush pending work so any deferred leave-teardown (DOM removal, dispose,\n * detach) completes. Await this after toggling a transitioned element to assert\n * its post-animation state without depending on the fallback timeout.\n */\nexport async function waitForTransition(el: Element): Promise<void> {\n el.dispatchEvent(new Event('transitionend', { bubbles: true }));\n await flushUpdates();\n}\n\n// ── Text / role queries (container-scoped) ──────────────────────────────────\n\n/** Find the first leaf element whose text content includes `text`. */\nexport function findByText(container: Element, text: string): Element {\n const match = Array.from(container.querySelectorAll('*')).find(\n (el) => el.children.length === 0 && (el.textContent?.includes(text) ?? false),\n );\n if (match === undefined) {\n throw new Error(`[StreetUI Testing] No element with text \"${text}\" found`);\n }\n return match;\n}\n\nexport interface ByRoleOptions {\n /** Restrict to elements whose accessible name includes this string. */\n readonly name?: string;\n}\n\n/** The implicit ARIA role for a plain HTML element, when it has one. */\nfunction implicitRole(el: Element): string | null {\n const tag = el.tagName.toLowerCase();\n switch (tag) {\n case 'button':\n return 'button';\n case 'a':\n return el.hasAttribute('href') ? 'link' : null;\n case 'nav':\n return 'navigation';\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n return 'heading';\n case 'input': {\n const type = (el.getAttribute('type') ?? 'text').toLowerCase();\n if (type === 'checkbox') return 'checkbox';\n if (type === 'radio') return 'radio';\n if (type === 'button' || type === 'submit') return 'button';\n return 'textbox';\n }\n case 'form':\n return 'form';\n default:\n return null;\n }\n}\n\n/** The accessible name approximation for an element (aria-label or text). */\nfunction accessibleName(el: Element): string {\n return (el.getAttribute('aria-label') ?? el.textContent ?? '').trim();\n}\n\n/**\n * Find all elements matching an ARIA `role` — explicit `role=\"…\"` first, then\n * the element's implicit role. Optionally filter by accessible name.\n */\nexport function findAllByRole(\n container: Element,\n role: string,\n options: ByRoleOptions = {},\n): Element[] {\n const all = Array.from(container.querySelectorAll('*'));\n return all.filter((el) => {\n const explicit = el.getAttribute('role');\n const matches = explicit === role || (explicit === null && implicitRole(el) === role);\n if (!matches) return false;\n if (options.name !== undefined) {\n return accessibleName(el).includes(options.name);\n }\n return true;\n });\n}\n\n/** Find the single element matching a role (throws if none/ambiguous). */\nexport function findByRole(\n container: Element,\n role: string,\n options: ByRoleOptions = {},\n): Element {\n const matches = findAllByRole(container, role, options);\n if (matches.length === 0) {\n const named = options.name !== undefined ? ` with name \"${options.name}\"` : '';\n throw new Error(`[StreetUI Testing] No element with role \"${role}\"${named} found`);\n }\n if (matches.length > 1) {\n throw new Error(\n `[StreetUI Testing] Found ${matches.length} elements with role \"${role}\" — refine with { name }`,\n );\n }\n return matches[0]!;\n}\n\n// ── First-class SSR → hydrate → assert workflow ─────────────────────────────\n\nexport interface HydrateTestOptions {\n /** Collect hydration mismatch diagnostics (dev-style) during hydration. */\n readonly collectDiagnostics?: boolean;\n}\n\nexport interface HydrateTestResult {\n /** The container holding the server HTML, now hydrated live. */\n readonly container: HTMLElement;\n /** The server-produced HTML string (before hydration). */\n readonly serverHtml: string;\n /** The live render handle from hydration. */\n readonly handle: RenderHandle;\n /** Hydration mismatch diagnostics (empty unless collectDiagnostics + a real mismatch). */\n readonly diagnostics: readonly HydrationDiagnostic[];\n /** Flush pending scheduler work. */\n flush(): void;\n /** Unmount and detach the container. */\n unmount(): void;\n}\n\n/**\n * Render `build` on the \"server\" to HTML, mount that HTML into a container,\n * then hydrate the SAME app against it — exactly the production SSR path. The\n * builder is invoked twice (server then client) with `resetIdCounter` between,\n * so deterministic ids line up. Assert node identity, behavior, and (optionally)\n * that hydration reported no mismatches.\n */\nexport function renderServerThenHydrate(\n build: () => StreetApp,\n options: HydrateTestOptions = {},\n): HydrateTestResult {\n resetIdCounter();\n const serverHtml = renderToString(compile(build()));\n\n const container = document.createElement('div');\n container.innerHTML = serverHtml;\n document.body.appendChild(container);\n\n const collector = options.collectDiagnostics === true\n ? createHydrationDiagnosticCollector()\n : undefined;\n\n resetIdCounter();\n const renderer = createRenderer({\n domAdapter: new BrowserDOMAdapter(),\n ...(collector !== undefined ? { hydrationDiagnostics: collector.sink } : {}),\n });\n const handle = renderer.hydrate(compile(build()), container);\n\n return {\n container,\n serverHtml,\n handle,\n diagnostics: collector?.diagnostics ?? [],\n flush() {\n handle.flush();\n },\n unmount() {\n handle.unmount();\n if (container.parentNode !== null) container.parentNode.removeChild(container);\n },\n };\n}\n","/**\n * Transition configuration (§2, §4).\n *\n * A `TransitionConfig` is a pure, declarative description of a CSS class-based\n * enter/leave transition — the engine choice for this milestone. It contains NO\n * DOM references, NO timers and NO browser-only APIs, so it is safe to build on\n * the server (where it is simply ignored — see the renderer's SSR guard) and to\n * carry on a graph handler (`__transition__<nodeId>`) alongside the existing\n * `__overlay__`/`__component__` descriptors.\n *\n * The class model follows the widely-understood enter/leave convention:\n *\n * enter: [enterActive (+ enter) whole phase] · enterFrom (start) → enterTo (end)\n * leave: [leaveActive (+ leave) whole phase] · leaveFrom (start) → leaveTo (end)\n *\n * `name` is a shorthand that expands to `${name}-enter-from`,\n * `${name}-enter-active`, `${name}-enter-to` and the leave equivalents; explicit\n * class fields override the derived ones. Because the classes are just strings,\n * SSR output is deterministic (no class is applied on the server at all — the\n * controller is browser-only), satisfying §4/§21.\n */\nexport interface TransitionConfig {\n /** Shorthand base: expands to `${name}-enter-from`, `${name}-enter-active`, … */\n readonly name?: string;\n /** Class(es) present for the whole enter phase (in addition to `enterActive`). */\n readonly enter?: string;\n /** Class(es) applied at the start of enter, removed on the next frame. */\n readonly enterFrom?: string;\n /** Class(es) present for the whole enter phase (where the CSS `transition` lives). */\n readonly enterActive?: string;\n /** Class(es) added on the next frame, removed when enter completes. */\n readonly enterTo?: string;\n /** Class(es) present for the whole leave phase (in addition to `leaveActive`). */\n readonly leave?: string;\n /** Class(es) applied at the start of leave, removed on the next frame. */\n readonly leaveFrom?: string;\n /** Class(es) present for the whole leave phase (where the CSS `transition` lives). */\n readonly leaveActive?: string;\n /** Class(es) added on the next frame, removed when leave completes. */\n readonly leaveTo?: string;\n /**\n * Also animate the very first appearance (initial mount). Hydration never\n * animates appear (the DOM is already present and correct); this only affects\n * fresh browser mounts. Defaults to false.\n */\n readonly appear?: boolean;\n /**\n * Fallback completion timeout in milliseconds. A transition normally completes\n * on the element's `transitionend`/`animationend`. This timeout is the safety\n * net for (a) transitions that fire no such event and (b) test DOMs like\n * happy-dom that dispatch no transition events at all — making tests\n * deterministic without a real browser (§24). Defaults to 1000. Use a small\n * value (or 0 → next macrotask) in tests.\n */\n readonly duration?: number;\n}\n\n/**\n * The resolved, ready-to-apply form of a {@link TransitionConfig}: each phase's\n * classes are pre-split into arrays so the controller applies/removes them with\n * no per-run string parsing. Produced once by {@link resolveTransition} at wire\n * time (browser only).\n */\nexport interface ResolvedTransition {\n /** enter classes present for the whole phase (base `enter` + `enterActive`). */\n readonly enterActive: readonly string[];\n /** enter start classes (removed next frame). */\n readonly enterFrom: readonly string[];\n /** enter end classes (added next frame). */\n readonly enterTo: readonly string[];\n readonly leaveActive: readonly string[];\n readonly leaveFrom: readonly string[];\n readonly leaveTo: readonly string[];\n readonly appear: boolean;\n readonly duration: number;\n}\n\n/** Split a class string on whitespace into a de-duplicated array (empty-safe). */\nfunction classes(value: string | undefined): string[] {\n if (value === undefined) return [];\n const out: string[] = [];\n for (const token of value.split(/\\s+/)) {\n if (token.length > 0 && !out.includes(token)) out.push(token);\n }\n return out;\n}\n\n/** Merge two class arrays, preserving order and dropping duplicates. */\nfunction merge(a: string[], b: string[]): string[] {\n const out = [...a];\n for (const token of b) if (!out.includes(token)) out.push(token);\n return out;\n}\n\n/**\n * Resolve a {@link TransitionConfig} into applied class arrays. The `name`\n * shorthand supplies defaults; any explicit field overrides the derived class\n * for that phase-slot (still merged with `enter`/`leave` base classes).\n */\nexport function resolveTransition(config: TransitionConfig): ResolvedTransition {\n const n = config.name;\n const enterActive = merge(\n classes(config.enter),\n classes(config.enterActive ?? (n !== undefined ? `${n}-enter-active` : undefined)),\n );\n const leaveActive = merge(\n classes(config.leave),\n classes(config.leaveActive ?? (n !== undefined ? `${n}-leave-active` : undefined)),\n );\n return {\n enterActive,\n enterFrom: classes(config.enterFrom ?? (n !== undefined ? `${n}-enter-from` : undefined)),\n enterTo: classes(config.enterTo ?? (n !== undefined ? `${n}-enter-to` : undefined)),\n leaveActive,\n leaveFrom: classes(config.leaveFrom ?? (n !== undefined ? `${n}-leave-from` : undefined)),\n leaveTo: classes(config.leaveTo ?? (n !== undefined ? `${n}-leave-to` : undefined)),\n appear: config.appear ?? false,\n duration: config.duration ?? 1000,\n };\n}\n\n/** Runtime brand check for a transition descriptor value. */\nexport function isTransitionConfig(value: unknown): value is TransitionConfig {\n if (value === null || typeof value !== 'object') return false;\n const o = value as Record<string, unknown>;\n // A config is meaningful only if it carries at least one class source.\n return (\n typeof o['name'] === 'string' ||\n typeof o['enter'] === 'string' ||\n typeof o['enterActive'] === 'string' ||\n typeof o['enterFrom'] === 'string' ||\n typeof o['leave'] === 'string' ||\n typeof o['leaveActive'] === 'string' ||\n typeof o['leaveFrom'] === 'string'\n );\n}\n","/**\n * Document head / metadata model (2.0 §1–§3).\n *\n * `head({...})` is a first-class StreetUI primitive for declaring document\n * metadata — title, meta, link, canonical, Open Graph, Twitter/X, robots,\n * theme-color and favicon. It is NOT a copy of another framework's API: it is\n * expressed on StreetUI's own component/graph model. A `head()` call creates a\n * `'head'` graph node (rendered as a neutral inline anchor, like a portal) and\n * registers a `__head__<nodeId>` descriptor — exactly the handler-registry\n * convention used by `__overlay__`/`__transition__`/`__component__`. The\n * renderer reads that descriptor to:\n *\n * • apply the contribution to `document.head` on the browser\n * (`wireHeadBehavior`), adopting server-emitted tags on hydration so there\n * are no duplicates, and cleaning up its own tags on unmount / route change;\n * • emit only the active graph's merged metadata as an HTML string on the\n * server (`renderHead`).\n *\n * This module is pure and DOM-free (like `transition.ts`): it defines the config\n * shape and normalises it into an ordered list of {@link HeadEntry} with stable\n * *dedup keys*. All merge/precedence/DOM work happens in the renderer, keyed by\n * these entries.\n *\n * ── Deduplication & precedence (§3) ──────────────────────────────────────────\n * Every entry carries a `dedupKey`. When several `head()` nodes are live at once\n * (e.g. an app-level default, a route-level `head()`, and a component-level\n * `head()`), the renderer merges all of their entries and, for each `dedupKey`,\n * the LAST contribution in document order wins. Document order is pre-order DFS\n * = mount order, so a `head()` declared deeper/later (a route or a component\n * nested inside the app shell) deterministically overrides an app-level default\n * for the same key. Removing that node (navigating away, unmounting the\n * component) re-exposes the previously-shadowed default. `<title>` and each\n * single-instance meta/link (description, robots, theme-color, viewport,\n * charset, canonical, favicon, and each og: or twitter: property) collapse to one\n * effective tag; generic `meta[]`/`link[]` array entries are keyed by their\n * identifying attributes so independent tags coexist.\n */\n\nimport type { ReadonlySignal, Signal } from '@streetui/state';\n\n/** A head value that may be a literal string or a reactive signal of a string. */\nexport type BindableString = string | ReadonlySignal<string> | Signal<string>;\n\n/** A single `<meta>` descriptor. Provide exactly one identifying key. */\nexport interface MetaDescriptor {\n /** `name=\"…\"` (e.g. \"description\", \"robots\", \"theme-color\", \"twitter:card\"). */\n readonly name?: string;\n /** `property=\"…\"` (e.g. \"og:title\", \"og:image\") — the Open Graph convention. */\n readonly property?: string;\n /** `http-equiv=\"…\"` (e.g. \"content-security-policy\"). */\n readonly httpEquiv?: string;\n /** `charset=\"…\"` (e.g. \"utf-8\"). Standalone; no `content`. */\n readonly charset?: string;\n /** The tag's `content`. May be reactive. */\n readonly content?: BindableString;\n}\n\n/** A single `<link>` descriptor. `rel`+`href` identify it. */\nexport interface LinkDescriptor {\n readonly rel: string;\n readonly href: string;\n readonly sizes?: string;\n readonly type?: string;\n readonly media?: string;\n readonly as?: string;\n readonly crossorigin?: string;\n readonly hreflang?: string;\n}\n\n/**\n * Declarative document metadata. Every field is optional; convenience fields\n * (title/description/canonical/robots/themeColor/viewport/charset/favicon/\n * openGraph/twitter) expand into the same normalized entries as the raw\n * `meta`/`link` arrays, with single-instance dedup keys so a later `head()`\n * cleanly overrides an earlier one.\n */\nexport interface HeadMetadata {\n /** `<title>` text. May be reactive. Single-instance (dedup key `title`). */\n readonly title?: BindableString;\n /** `<meta name=\"description\">`. May be reactive. */\n readonly description?: BindableString;\n /** `<link rel=\"canonical\">` href. */\n readonly canonical?: string;\n /** `<meta name=\"robots\">` (e.g. \"index,follow\" / \"noindex\"). */\n readonly robots?: string;\n /** `<meta name=\"theme-color\">`. */\n readonly themeColor?: string;\n /** `<meta name=\"viewport\">`. */\n readonly viewport?: string;\n /** `<meta charset>`. */\n readonly charset?: string;\n /** Favicon: a shorthand for `<link rel=\"icon\">`. String = href, or a full descriptor. */\n readonly favicon?: string | LinkDescriptor;\n /** Open Graph properties — each key `k` becomes `<meta property=\"og:k\">`. Values may be reactive. */\n readonly openGraph?: Readonly<Record<string, BindableString>>;\n /** Twitter/X card properties — each key `k` becomes `<meta name=\"twitter:k\">`. Values may be reactive. */\n readonly twitter?: Readonly<Record<string, BindableString>>;\n /** Raw `<meta>` tags (for anything the convenience fields don't cover). */\n readonly meta?: readonly MetaDescriptor[];\n /** Raw `<link>` tags (stylesheets, preload, alternate, etc.). */\n readonly link?: readonly LinkDescriptor[];\n /** `<base href>` — single-instance. */\n readonly base?: string;\n}\n\n/**\n * A normalized head tag: one `<title>`, `<meta>`, `<link>` or `<base>`. Attr\n * values and the title's text may still be reactive (`BindableString`); the\n * renderer peeks them for SSR and subscribes to them on the browser. `dedupKey`\n * is what the merge collapses on.\n */\nexport interface HeadEntry {\n readonly tag: 'title' | 'meta' | 'link' | 'base';\n readonly dedupKey: string;\n /** Static + reactive attributes (no `undefined` values). */\n readonly attrs: Readonly<Record<string, BindableString>>;\n /** Text content — only meaningful for `tag === 'title'`. */\n readonly text?: BindableString;\n}\n\n/** The value a `__head__<id>` handler returns: this node's ordered contribution. */\nexport interface HeadContribution {\n readonly entries: readonly HeadEntry[];\n}\n\nfunction metaDedupKey(m: MetaDescriptor): string | undefined {\n if (m.charset !== undefined) return 'meta:charset';\n if (m.name !== undefined) return `meta:name=${m.name}`;\n if (m.property !== undefined) return `meta:property=${m.property}`;\n if (m.httpEquiv !== undefined) return `meta:http-equiv=${m.httpEquiv}`;\n return undefined;\n}\n\nfunction metaAttrs(m: MetaDescriptor): Record<string, BindableString> {\n const attrs: Record<string, BindableString> = {};\n if (m.charset !== undefined) attrs['charset'] = m.charset;\n if (m.name !== undefined) attrs['name'] = m.name;\n if (m.property !== undefined) attrs['property'] = m.property;\n if (m.httpEquiv !== undefined) attrs['http-equiv'] = m.httpEquiv;\n if (m.content !== undefined) attrs['content'] = m.content;\n return attrs;\n}\n\nfunction linkAttrs(l: LinkDescriptor): Record<string, BindableString> {\n const attrs: Record<string, BindableString> = { rel: l.rel, href: l.href };\n if (l.sizes !== undefined) attrs['sizes'] = l.sizes;\n if (l.type !== undefined) attrs['type'] = l.type;\n if (l.media !== undefined) attrs['media'] = l.media;\n if (l.as !== undefined) attrs['as'] = l.as;\n if (l.crossorigin !== undefined) attrs['crossorigin'] = l.crossorigin;\n if (l.hreflang !== undefined) attrs['hreflang'] = l.hreflang;\n return attrs;\n}\n\n/**\n * Normalise a {@link HeadMetadata} into an ordered list of {@link HeadEntry}.\n * Emission order within one `head()` is: charset → base → title → description →\n * canonical → robots → theme-color → viewport → favicon → openGraph → twitter →\n * explicit meta[] → explicit link[]. (Merge across nodes is document order; this\n * per-node order only affects the sequence of same-priority tags.)\n */\nexport function resolveHead(config: HeadMetadata): HeadContribution {\n const entries: HeadEntry[] = [];\n\n if (config.charset !== undefined) {\n entries.push({ tag: 'meta', dedupKey: 'meta:charset', attrs: { charset: config.charset } });\n }\n if (config.base !== undefined) {\n entries.push({ tag: 'base', dedupKey: 'base', attrs: { href: config.base } });\n }\n if (config.title !== undefined) {\n entries.push({ tag: 'title', dedupKey: 'title', attrs: {}, text: config.title });\n }\n if (config.description !== undefined) {\n entries.push({\n tag: 'meta',\n dedupKey: 'meta:name=description',\n attrs: { name: 'description', content: config.description },\n });\n }\n if (config.canonical !== undefined) {\n entries.push({\n tag: 'link',\n dedupKey: 'link:rel=canonical',\n attrs: { rel: 'canonical', href: config.canonical },\n });\n }\n if (config.robots !== undefined) {\n entries.push({\n tag: 'meta',\n dedupKey: 'meta:name=robots',\n attrs: { name: 'robots', content: config.robots },\n });\n }\n if (config.themeColor !== undefined) {\n entries.push({\n tag: 'meta',\n dedupKey: 'meta:name=theme-color',\n attrs: { name: 'theme-color', content: config.themeColor },\n });\n }\n if (config.viewport !== undefined) {\n entries.push({\n tag: 'meta',\n dedupKey: 'meta:name=viewport',\n attrs: { name: 'viewport', content: config.viewport },\n });\n }\n if (config.favicon !== undefined) {\n const l: LinkDescriptor =\n typeof config.favicon === 'string' ? { rel: 'icon', href: config.favicon } : config.favicon;\n // Favicons are single-instance by rel (rel=icon), so a later head() replaces\n // an earlier icon rather than stacking a second one.\n entries.push({ tag: 'link', dedupKey: `link:rel=${l.rel}`, attrs: linkAttrs(l) });\n }\n if (config.openGraph !== undefined) {\n for (const key of Object.keys(config.openGraph)) {\n const property = `og:${key}`;\n entries.push({\n tag: 'meta',\n dedupKey: `meta:property=${property}`,\n attrs: { property, content: config.openGraph[key]! },\n });\n }\n }\n if (config.twitter !== undefined) {\n for (const key of Object.keys(config.twitter)) {\n const name = `twitter:${key}`;\n entries.push({\n tag: 'meta',\n dedupKey: `meta:name=${name}`,\n attrs: { name, content: config.twitter[key]! },\n });\n }\n }\n if (config.meta !== undefined) {\n for (const m of config.meta) {\n const key = metaDedupKey(m);\n if (key === undefined) continue; // a meta with no identifying attribute is dropped\n entries.push({ tag: 'meta', dedupKey: key, attrs: metaAttrs(m) });\n }\n }\n if (config.link !== undefined) {\n for (const l of config.link) {\n // Generic links are keyed by rel+href so multiple independent links coexist\n // (unlike canonical/icon which are single-instance by rel).\n entries.push({ tag: 'link', dedupKey: `link:rel=${l.rel}:href=${l.href}`, attrs: linkAttrs(l) });\n }\n }\n\n return { entries };\n}\n\n/** Runtime brand check for a head-contribution descriptor value. */\nexport function isHeadContribution(value: unknown): value is HeadContribution {\n return (\n value !== null &&\n typeof value === 'object' &&\n Array.isArray((value as Record<string, unknown>)['entries'])\n );\n}\n","/**\n * StreetUI reactive signals — framework-owned reactivity, no external libraries.\n *\n * Architecture:\n * Signal<T> — writable, holds a value, notifies on change\n * DerivedSignal<T> — read-only, lazily computed from other signals\n * effect() — side-effect that re-runs when dependencies change\n * batch() — run multiple updates before notifying\n */\n\nexport type Subscriber<T> = (value: T) => void;\nexport type Unsubscribe = () => void;\n\n// ── Tracking ──────────────────────────────────────────────────────────────────\n\n/**\n * Any reactive source that can have downstream consumers attached.\n * Both Signal and DerivedSignal implement this.\n */\nexport interface ReactiveSource<T> {\n get(): T;\n peek(): T;\n subscribe(fn: Subscriber<T>): Unsubscribe;\n /** Internal: remove a downstream consumer. */\n _removeConsumer(consumer: ReactiveConsumer): void;\n}\n\n/**\n * A downstream consumer (DerivedSignal or Effect) that can be invalidated\n * and can register itself as depending on a source.\n */\nexport interface ReactiveConsumer {\n _invalidate(): void;\n /** Internal: called by a source to register a dependency. */\n _addSource(src: ReactiveSource<unknown>): void;\n}\n\n/** The active consumer being tracked during a computation. */\nlet _activeConsumer: ReactiveConsumer | null = null;\n\nfunction withConsumer<T>(consumer: ReactiveConsumer, fn: () => T): T {\n const prev = _activeConsumer;\n _activeConsumer = consumer;\n try {\n return fn();\n } finally {\n _activeConsumer = prev;\n }\n}\n\n// ── Batch state (must be before Signal class so .set() can reference it) ──────\n\n/** Depth counter — batches nest; only the outermost flush propagates. */\nlet _batchDepth = 0;\n\ninterface PendingFlush {\n signal: Signal<unknown>;\n value: unknown;\n}\n\n/**\n * Keyed by signal identity — last-write-wins for each signal within a batch.\n * An ordered Map preserves first-seen insertion order for stable flush sequence.\n */\nconst _pendingFlushes = new Map<Signal<unknown>, PendingFlush>();\n\nfunction _enqueueBatchFlush(sig: Signal<unknown>, value: unknown): void {\n _pendingFlushes.set(sig, { signal: sig, value });\n}\n\nfunction _drainBatch(): void {\n const flushes = [..._pendingFlushes.values()];\n _pendingFlushes.clear();\n for (const { signal: sig, value } of flushes) {\n sig._flushBatch(value);\n }\n}\n\n// ── Signal ────────────────────────────────────────────────────────────────────\n\nexport interface ReadonlySignal<T> {\n get(): T;\n peek(): T;\n subscribe(fn: Subscriber<T>): Unsubscribe;\n}\n\nexport class Signal<T> implements ReactiveSource<T>, ReadonlySignal<T> {\n protected _value: T;\n private readonly _subscribers: Set<Subscriber<T>> = new Set();\n private readonly _consumers: Set<ReactiveConsumer> = new Set();\n\n constructor(initial: T) {\n this._value = initial;\n }\n\n get(): T {\n if (_activeConsumer !== null) {\n this._consumers.add(_activeConsumer);\n _activeConsumer._addSource(this as ReactiveSource<unknown>);\n }\n return this._value;\n }\n\n peek(): T {\n return this._value;\n }\n\n set(value: T): void {\n if (Object.is(this._value, value)) return;\n this._value = value;\n if (_batchDepth > 0) {\n // Defer notification until the batch flushes.\n // The stored value is always the latest (last-write-wins for same signal).\n _enqueueBatchFlush(this as unknown as Signal<unknown>, value);\n } else {\n this._flush(value);\n }\n }\n\n update(fn: (current: T) => T): void {\n this.set(fn(this._value));\n }\n\n subscribe(fn: Subscriber<T>): Unsubscribe {\n this._subscribers.add(fn);\n return () => { this._subscribers.delete(fn); };\n }\n\n _removeConsumer(consumer: ReactiveConsumer): void {\n this._consumers.delete(consumer);\n }\n\n /**\n * Called by the batch machinery after the batch has completed.\n * Notifies subscribers with the final coalesced value.\n */\n _flushBatch(value: unknown): void {\n this._flush(value as T);\n }\n\n private _flush(value: T): void {\n for (const sub of [...this._subscribers]) sub(value);\n for (const consumer of [...this._consumers]) consumer._invalidate();\n }\n\n /**\n * @internal DevTools inspection only. The number of live observers\n * (direct subscribers plus derived/effect consumers). Read-only; never\n * mutates reactive state.\n */\n _observerCount(): number {\n return this._subscribers.size + this._consumers.size;\n }\n}\n\n// ── DerivedSignal ─────────────────────────────────────────────────────────────\n\nexport class DerivedSignal<T> implements ReactiveSource<T>, ReactiveConsumer, ReadonlySignal<T> {\n private _value: T | undefined = undefined;\n private _dirty = true;\n private _disposed = false;\n private readonly _fn: () => T;\n private readonly _subscribers: Set<Subscriber<T>> = new Set();\n /** All upstream sources this derived currently reads from. */\n private readonly _sources: Set<ReactiveSource<unknown>> = new Set();\n /** Downstream consumers that depend on this derived. */\n private readonly _consumers: Set<ReactiveConsumer> = new Set();\n\n constructor(fn: () => T) {\n this._fn = fn;\n }\n\n get(): T {\n // Register this derived with the outer consumer if any\n if (_activeConsumer !== null) {\n this._consumers.add(_activeConsumer);\n _activeConsumer._addSource(this as ReactiveSource<unknown>);\n }\n if (this._dirty) this._recompute();\n return this._value as T;\n }\n\n peek(): T {\n if (this._dirty) this._recompute();\n return this._value as T;\n }\n\n subscribe(fn: Subscriber<T>): Unsubscribe {\n // Eagerly compute so sources track this derived as a consumer\n if (this._dirty) this._recompute();\n this._subscribers.add(fn);\n return () => { this._subscribers.delete(fn); };\n }\n\n _addSource(src: ReactiveSource<unknown>): void {\n this._sources.add(src);\n }\n\n _removeConsumer(consumer: ReactiveConsumer): void {\n this._consumers.delete(consumer);\n }\n\n _invalidate(): void {\n if (this._disposed) return;\n this._dirty = true;\n const newVal = this.peek(); // recompute\n for (const sub of [...this._subscribers]) sub(newVal);\n for (const consumer of [...this._consumers]) consumer._invalidate();\n }\n\n private _recompute(): void {\n // Detach from all current sources before re-tracking\n for (const src of this._sources) src._removeConsumer(this);\n this._sources.clear();\n\n this._value = withConsumer(this, this._fn);\n this._dirty = false;\n }\n\n dispose(): void {\n this._disposed = true;\n for (const src of this._sources) src._removeConsumer(this);\n this._sources.clear();\n this._subscribers.clear();\n this._consumers.clear();\n }\n\n /**\n * @internal DevTools inspection only. Live observers (subscribers plus\n * downstream consumers). Read-only.\n */\n _observerCount(): number {\n return this._subscribers.size + this._consumers.size;\n }\n}\n\n// ── effect ────────────────────────────────────────────────────────────────────\n\nclass Effect implements ReactiveConsumer {\n private readonly _fn: () => void | (() => void);\n private _cleanup: (() => void) | undefined = undefined;\n private _disposed = false;\n private readonly _sources: Set<ReactiveSource<unknown>> = new Set();\n\n constructor(fn: () => void | (() => void)) {\n this._fn = fn;\n this._run();\n }\n\n _addSource(src: ReactiveSource<unknown>): void {\n this._sources.add(src);\n }\n\n _invalidate(): void {\n if (this._disposed) return;\n this._run();\n }\n\n private _run(): void {\n // Detach from all current sources before re-tracking\n for (const src of this._sources) src._removeConsumer(this);\n this._sources.clear();\n\n if (typeof this._cleanup === 'function') this._cleanup();\n const result = withConsumer(this, this._fn);\n this._cleanup = typeof result === 'function' ? result : undefined;\n }\n\n dispose(): void {\n this._disposed = true;\n for (const src of this._sources) src._removeConsumer(this);\n this._sources.clear();\n if (typeof this._cleanup === 'function') this._cleanup();\n this._cleanup = undefined;\n }\n}\n\n// ── Public API ─────────────────────────────────────────────────────────────────\n\nexport function signal<T>(initial: T): Signal<T> {\n return new Signal(initial);\n}\n\nexport function derived<T>(fn: () => T): DerivedSignal<T> {\n return new DerivedSignal(fn);\n}\n\nexport function effect(fn: () => void | (() => void)): Unsubscribe {\n const e = new Effect(fn);\n return () => e.dispose();\n}\n\n/**\n * Run multiple signal updates as an atomic batch.\n *\n * Within the callback, calls to signal.set() are deferred — each signal\n * accumulates its latest value. When the outermost batch() returns,\n * each modified signal fires its subscribers exactly once with the final\n * value. Nested batch() calls are supported; the flush only runs when the\n * outermost batch exits.\n *\n * Example:\n * batch(() => {\n * count.set(1);\n * count.set(2);\n * count.set(3);\n * });\n * // subscribers see count = 3 exactly once\n */\nexport function batch(fn: () => void): void {\n _batchDepth++;\n try {\n fn();\n } finally {\n _batchDepth--;\n if (_batchDepth === 0) {\n _drainBatch();\n }\n }\n}\n\n/** True when inside a batch() call. Useful for advanced scheduling integration. */\nexport function isBatching(): boolean {\n return _batchDepth > 0;\n}\n\n// ── Inspection (read-only, DevTools-facing) ─────────────────────────────────\n\n/** Whether a signal is writable (`signal()`) or computed (`derived()`). */\nexport type SignalKind = 'writable' | 'derived';\n\n/** Classify a reactive value as writable or derived. */\nexport function signalKind(source: ReadonlySignal<unknown>): SignalKind {\n return source instanceof DerivedSignal ? 'derived' : 'writable';\n}\n\n/**\n * The number of live observers on a signal — direct subscribers plus derived\n * or effect consumers — or `undefined` if the source does not expose the count.\n * Read-only; safe for DevTools. Never mutates reactive state.\n */\nexport function observerCount(source: ReadonlySignal<unknown>): number | undefined {\n const maybe = source as { _observerCount?: () => number };\n return typeof maybe._observerCount === 'function' ? maybe._observerCount() : undefined;\n}\n","/**\n * DSL builder implementations.\n *\n * Each builder wraps a GraphNode and provides the fluent API\n * for constructing the Semantic Application Graph via the DSL.\n *\n * Builders do NOT render anything — they only build the graph.\n */\n\nimport { ApplicationGraph, GraphNode, type Props } from '@streetui/graph';\nimport type {\n ContentDSL,\n ContainerDSL,\n SectionDSL,\n PageDSL,\n FormDSL,\n ListDSL,\n AppDSL,\n HeadingOptions,\n TextOptions,\n ButtonOptions,\n InputOptions,\n LinkOptions,\n ImageOptions,\n ContainerOptions,\n SectionOptions,\n FormOptions,\n ListOptions,\n PortalOptions,\n OverlayOptions,\n A11yOptions,\n Bindable,\n BindableText,\n TextValue,\n ErrorBoundaryOptions,\n ErrorSource,\n AsyncBoundaryBranches,\n PageBuilder,\n SectionBuilder,\n ContainerBuilder as ContainerBuilderFn,\n FormBuilder,\n ListBuilder,\n} from './dsl-types.js';\nimport type {\n ComponentContext,\n ComponentDefinition,\n ComponentRender,\n} from './component.js';\nimport type { TransitionConfig } from './transition.js';\nimport { resolveTransition } from './transition.js';\nimport type { HeadMetadata } from './head.js';\nimport { resolveHead } from './head.js';\nimport type { WhenOptions } from './dsl-types.js';\nimport { signal, derived, effect, type Signal, type ReadonlySignal, type Resource } from '@streetui/state';\n\n/**\n * A single reactive-list reconciliation descriptor (spec §15).\n *\n * Emitted by the `__listplan__<nodeId>` handler on every list change. `key` is\n * the item's identity-only reconciliation key (cheap to compute); `item` is the\n * source value *reference* used for identity short-circuiting; `sig()` computes\n * the content signature on demand (only when the reference changed); `build()`\n * materialises the full item subtree on demand (only for new/changed rows).\n */\nexport interface ListPlanEntry {\n readonly key: string;\n readonly item: unknown;\n readonly sig: () => string;\n readonly build: () => GraphNode;\n}\n\n// ── Signal helpers ────────────────────────────────────────────────────────────\n\nfunction isSignal(v: unknown): v is Signal<unknown> | ReadonlySignal<unknown> {\n return (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as Record<string, unknown>)['get'] === 'function' &&\n typeof (v as Record<string, unknown>)['subscribe'] === 'function'\n );\n}\n\n/** Register a signal binding on the node and return the current static value. */\nfunction bindValue<T>(\n graph: ApplicationGraph,\n node: GraphNode,\n propKey: string,\n value: Bindable<T>,\n): T {\n if (isSignal(value)) {\n const signalId = `${node.id}:${propKey}`;\n node.stateRefs.push({ signalId, propKey });\n graph.registerHandler(`__signal__${signalId}`, value as unknown as () => unknown);\n return (value as ReadonlySignal<T>).peek();\n }\n return value as T;\n}\n\n// ── Helper to build Props from ContainerOptions ───────────────────────────────\n\n/**\n * Copy accessibility options onto a props bag as their corresponding HTML/ARIA\n * attribute names. Values are written as strings (booleans become \"true\"/\"false\"\n * rather than being dropped) so ARIA state attributes render literally. These\n * flow to the DOM via the renderer's generic attribute pass — no ARIA-specific\n * renderer code is involved.\n */\nfunction applyA11yProps(props: Props, options: A11yOptions): void {\n if (options.role !== undefined) props['role'] = options.role;\n if (options.tabIndex !== undefined) props['tabindex'] = String(options.tabIndex);\n if (options.ariaLabel !== undefined) props['aria-label'] = options.ariaLabel;\n if (options.ariaLabelledBy !== undefined) props['aria-labelledby'] = options.ariaLabelledBy;\n if (options.ariaDescribedBy !== undefined) props['aria-describedby'] = options.ariaDescribedBy;\n if (options.ariaExpanded !== undefined) props['aria-expanded'] = String(options.ariaExpanded);\n if (options.ariaControls !== undefined) props['aria-controls'] = options.ariaControls;\n if (options.ariaHidden !== undefined) props['aria-hidden'] = String(options.ariaHidden);\n if (options.ariaLive !== undefined) props['aria-live'] = options.ariaLive;\n if (options.ariaCurrent !== undefined) props['aria-current'] = String(options.ariaCurrent);\n if (options.ariaInvalid !== undefined) props['aria-invalid'] = String(options.ariaInvalid);\n if (options.ariaRequired !== undefined) props['aria-required'] = String(options.ariaRequired);\n if (options.ariaModal !== undefined) props['aria-modal'] = String(options.ariaModal);\n if (options.ariaOwns !== undefined) props['aria-owns'] = options.ariaOwns;\n if (options.ariaActiveDescendant !== undefined) props['aria-activedescendant'] = options.ariaActiveDescendant;\n if (options.ariaHasPopup !== undefined) props['aria-haspopup'] = String(options.ariaHasPopup);\n if (options.ariaSelected !== undefined) props['aria-selected'] = String(options.ariaSelected);\n}\n\n/**\n * Register a `__transition__<nodeId>` descriptor for an element that opts into a\n * CSS class-based enter/leave transition (§2). Mirrors the `__overlay__` /\n * `__component__` handler pattern: the renderer reads it (browser only) to run\n * enter on mount and to defer removal/dispose until leave completes. Pure config\n * — no DOM, no timers — so it is inert on the server and pruned by\n * `graph._unregisterNodeHandlers` (§23). A no-op when no transition is supplied.\n */\nfunction registerTransition(\n graph: ApplicationGraph,\n node: GraphNode,\n config: TransitionConfig | undefined,\n): void {\n if (config === undefined) return;\n // Resolve to the pre-split class arrays at wire time so the renderer's\n // controller consumes a plain `ResolvedTransition` and never re-parses class\n // strings per run — and so the renderer needs no compile-time dependency on\n // this DSL package (it reads the descriptor structurally, exactly like\n // `__overlay__`/`__component__`).\n const resolved = resolveTransition(config);\n graph.registerHandler(\n `__transition__${node.id}`,\n (() => resolved) as unknown as () => unknown,\n );\n}\n\nfunction containerProps(options: ContainerOptions): Props {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n if (options.key !== undefined) props['key'] = options.key;\n applyA11yProps(props, options);\n return props;\n}\n\n// ── Reactive-list item keying ──────────────────────────────────────────────────\n//\n// The `listOf` DSL signature does not take an explicit key extractor, so we\n// derive a stable reconciliation key from each item. The key combines an\n// *identity* part (so reordering the same items reuses their DOM nodes) with a\n// *value signature* (so an item whose data changed is treated as a fresh node\n// and re-rendered rather than silently kept stale by the shallow reconciler).\n\nfunction itemIdentity(item: unknown, index: number): string {\n if (item !== null && typeof item === 'object') {\n const obj = item as Record<string, unknown>;\n if ('id' in obj) return `id:${String(obj['id'])}`;\n if ('key' in obj) return `key:${String(obj['key'])}`;\n return `idx:${index}`;\n }\n return `val:${String(item)}`;\n}\n\nfunction itemValueSignature(item: unknown): string {\n try {\n return JSON.stringify(item) ?? String(item);\n } catch {\n return String(item);\n }\n}\n\n/** Content signature used to detect in-place data changes of a stable item. */\nexport function reactiveListItemSignature(item: unknown): string {\n return itemValueSignature(item);\n}\n\n/** Stable, identity-only reconciliation key for a reactive-list item. */\nexport function reactiveListItemKey(item: unknown, index: number): string {\n return itemIdentity(item, index);\n}\n\n// ── Overlay kind configuration ──────────────────────────────────────────────────\n//\n// Each overlay builder (dialog/popover/tooltip/dropdown/toast) is the same\n// portal + `when(open, …)` panel + focus/keyboard behavior, differing only in\n// ARIA role, modality, whether it takes focus, and its escape/restore defaults.\n// This table captures those differences; `_overlay` does the shared assembly.\n\ninterface OverlayKindConfig {\n /** Default ARIA role for the panel. */\n readonly role: string;\n /** Trap + contain focus (modal semantics). */\n readonly modal: boolean;\n /** Move focus into the panel when it opens. */\n readonly takesFocus: boolean;\n /** Wire arrow/Home/End/Enter/Space roving-focus navigation (role=\"menu\"). */\n readonly menu?: boolean;\n /** Emit `aria-modal=\"true\"` on the panel. */\n readonly ariaModal: boolean;\n /** Emit an `aria-live` region on the panel (announcements). */\n readonly ariaLive?: 'polite' | 'assertive';\n /** Default for `closeOnEscape` when the caller does not specify it. */\n readonly defaultCloseOnEscape: boolean;\n /** Default for `restoreFocus` when the caller does not specify it. */\n readonly defaultRestoreFocus: boolean;\n}\n\nconst OVERLAY_KINDS = {\n dialog: {\n role: 'dialog', modal: true, takesFocus: true, ariaModal: true,\n defaultCloseOnEscape: true, defaultRestoreFocus: true,\n },\n popover: {\n role: 'dialog', modal: false, takesFocus: true, ariaModal: false,\n defaultCloseOnEscape: true, defaultRestoreFocus: true,\n },\n tooltip: {\n role: 'tooltip', modal: false, takesFocus: false, ariaModal: false,\n defaultCloseOnEscape: false, defaultRestoreFocus: false,\n },\n dropdown: {\n role: 'menu', modal: false, takesFocus: true, menu: true, ariaModal: false,\n defaultCloseOnEscape: true, defaultRestoreFocus: true,\n },\n toast: {\n role: 'status', modal: false, takesFocus: false, ariaModal: false,\n ariaLive: 'polite', defaultCloseOnEscape: false, defaultRestoreFocus: false,\n },\n} as const satisfies Record<string, OverlayKindConfig>;\n\n/** The opaque descriptor the renderer reads from `__overlay__<portalId>`. */\ninterface OverlayBehaviorDescriptor {\n readonly open: ReadonlySignal<boolean>;\n readonly modal: boolean;\n readonly takesFocus: boolean;\n readonly menu: boolean;\n readonly closeOnEscape: boolean;\n readonly restoreFocus: boolean;\n readonly initialFocusId?: string;\n readonly onClose?: () => void;\n}\n\n// ── Base content builder ──────────────────────────────────────────────────────\n\nclass ContentBuilderBase implements ContentDSL {\n constructor(\n protected readonly _node: GraphNode,\n protected readonly _graph: ApplicationGraph,\n ) {}\n\n heading(text: BindableText, options: HeadingOptions = {}): void {\n const props: Props = { level: options.level ?? 1 };\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('heading', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'text', text);\n node.setProp('text', resolved);\n }\n\n text(content: BindableText, options: TextOptions = {}): void {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('text', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'text', content);\n node.setProp('text', resolved);\n }\n\n button(label: BindableText, options: ButtonOptions = {}): void {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('button', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'label', label);\n node.setProp('label', resolved);\n if (options.disabled !== undefined) {\n const resolvedDisabled = bindValue(this._graph, node, 'disabled', options.disabled);\n node.setProp('disabled', resolvedDisabled);\n }\n if (options.onClick !== undefined) {\n const handlerKey = `click:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onClick as () => unknown);\n node.addEvent({ type: 'click', handlerKey });\n }\n }\n\n input(options: InputOptions = {}): void {\n const props: Props = {};\n props['inputType'] = options.type ?? 'text';\n if (options.placeholder !== undefined) props['placeholder'] = options.placeholder;\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const nodeOpts: { key?: string; props: Props; parent: GraphNode } = {\n props,\n parent: this._node,\n };\n if (options.id !== undefined) nodeOpts.key = options.id;\n const node = this._graph.createNode('input', nodeOpts);\n\n // Two-way `bind` expands to a value binding + an input write-back. The type\n // system (BoundInputOptions vs ControlledInputOptions) guarantees `bind` is\n // never combined with explicit `value`/`onInput`, so there is no ambiguity.\n const bindSignal = options.bind;\n const valueBindable: Bindable<string> | undefined =\n bindSignal !== undefined ? bindSignal : options.value;\n const inputHandler: ((value: string) => void) | undefined =\n bindSignal !== undefined ? (v: string) => bindSignal.set(v) : options.onInput;\n\n if (valueBindable !== undefined) {\n const resolved = bindValue(this._graph, node, 'value', valueBindable);\n node.setProp('value', resolved);\n }\n if (options.disabled !== undefined) {\n const resolved = bindValue(this._graph, node, 'disabled', options.disabled);\n node.setProp('disabled', resolved);\n }\n if (inputHandler !== undefined) {\n const handlerKey = `input:${node.id}`;\n this._graph.registerHandler(handlerKey, inputHandler as () => unknown);\n node.addEvent({ type: 'input', handlerKey });\n }\n if (options.onChange !== undefined) {\n const handlerKey = `change:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onChange as () => unknown);\n node.addEvent({ type: 'change', handlerKey });\n }\n }\n\n image(options: ImageOptions): void {\n const props: Props = {\n src: options.src,\n alt: options.alt,\n };\n if (options.width !== undefined) props['width'] = options.width;\n if (options.height !== undefined) props['height'] = options.height;\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const nodeOpts: { key?: string; props: Props; parent: GraphNode } = {\n props,\n parent: this._node,\n };\n if (options.id !== undefined) nodeOpts.key = options.id;\n this._graph.createNode('image', nodeOpts);\n }\n\n link(label: BindableText, options: LinkOptions): void {\n const props: Props = {\n href: options.href,\n external: options.external ?? false,\n };\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('link', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'label', label);\n node.setProp('label', resolved);\n if (options.onClick !== undefined) {\n const handlerKey = `click:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onClick as () => unknown);\n node.addEvent({ type: 'click', handlerKey });\n }\n }\n}\n\n// ── Container builder ─────────────────────────────────────────────────────────\n\nclass ContainerBuilderBase extends ContentBuilderBase implements ContainerDSL {\n section(key: string, builder: SectionBuilder, options: SectionOptions = {}): void {\n const node = this._graph.createNode('section', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(this._graph, node, options.transition);\n builder(new SectionBuilderImpl(node, this._graph));\n }\n\n container(key: string, builder: ContainerBuilderFn, options: ContainerOptions = {}): void {\n const node = this._graph.createNode('container', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(this._graph, node, options.transition);\n builder(new ContainerBuilderImpl(node, this._graph));\n }\n\n list(key: string, builder: ListBuilder, options: ListOptions = {}): void {\n const node = this._graph.createNode('list', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(this._graph, node, options.transition);\n builder(new ListBuilderImpl(node, this._graph));\n }\n\n listOf<T>(\n key: string,\n items: Signal<T[]> | ReadonlySignal<T[]>,\n renderItem: (item: T, index: number, content: ContentDSL) => void,\n options: ListOptions = {},\n ): void {\n const graph = this._graph;\n const node = graph.createNode('reactive-list', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(graph, node, options.transition);\n\n // Register the driving signal so the runtime/renderer can subscribe to it.\n const signalId = `${node.id}:items`;\n node.stateRefs.push({ signalId, propKey: 'items' });\n graph.registerHandler(`__signal__${signalId}`, items as unknown as () => unknown);\n\n // Build a single detached list-item subtree for one item. The item's\n // reconciliation `key` is identity-only, and its value signature is stored\n // in the internal `_sig` prop so the renderer can detect (and apply a\n // targeted update for) a data change on an item whose identity is stable.\n const buildItem = (item: T, index: number): GraphNode => {\n const itemKey = reactiveListItemKey(item, index);\n const itemNode = graph.createNode('list-item', {\n key: itemKey,\n // `_item` records the source item *reference* so the reconciler can\n // short-circuit unchanged rows by identity (no signature hashing); `_sig`\n // is the content signature used to detect an in-place data change when the\n // reference differs. Both are internal metadata (leading `_`) and never\n // reach the DOM.\n props: {\n key: itemKey,\n _sig: reactiveListItemSignature(item),\n // The item reference is stored as opaque internal metadata (never\n // rendered); cast through `unknown` since `T` is not a `PropValue`.\n _item: item as unknown as Props[string],\n },\n });\n renderItem(item, index, new ContainerBuilderImpl(itemNode, graph));\n // Per-item enter/leave transition (§7). Registered on every item node so a\n // freshly-built row (append/prepend/change) carries it; keyed identity is\n // unaffected because the transition descriptor is keyed by node id and the\n // row's reconciliation key is derived separately.\n registerTransition(graph, itemNode, options.itemTransition);\n return itemNode;\n };\n\n // Lazy reconciliation plan (spec §15 — the measured keyed-list hot path).\n //\n // Instead of eagerly rebuilding all N item GraphNodes (and hashing every item\n // with JSON.stringify) on *every* emission — the dominant cost of the old\n // `buildAll` path — the renderer receives lightweight descriptors and only\n // materialises a subtree for rows that are genuinely new or whose data\n // actually changed. `key` is cheap (identity only); `sig()` and `build()` are\n // thunks the reconciler calls on demand.\n const buildPlan = (raw: unknown): ListPlanEntry[] => {\n const arr = Array.isArray(raw) ? (raw as T[]) : [];\n const plan: ListPlanEntry[] = new Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i]!;\n const index = i;\n plan[i] = {\n key: reactiveListItemKey(item, index),\n item,\n sig: () => reactiveListItemSignature(item),\n build: () => buildItem(item, index),\n };\n }\n return plan;\n };\n graph.registerHandler(`__listplan__${node.id}`, buildPlan as unknown as () => unknown);\n\n // Build the initial children into the graph so the first mount renders them.\n const current = isSignal(items)\n ? (items as ReadonlySignal<T[]>).peek()\n : (items as unknown as T[]);\n const initial = Array.isArray(current) ? current : [];\n initial.forEach((item, i) => {\n node.appendChild(buildItem(item, i));\n });\n }\n\n form(key: string, builder: FormBuilder, options: FormOptions = {}): void {\n const props: Props = containerProps(options);\n const node = this._graph.createNode('form', {\n key,\n parent: this._node,\n props,\n });\n registerTransition(this._graph, node, options.transition);\n if (options.onSubmit !== undefined) {\n const handlerKey = `submit:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onSubmit as () => unknown);\n node.addEvent({ type: 'submit', handlerKey });\n }\n builder(new FormBuilderImpl(node, this._graph));\n }\n\n when(\n condition: Bindable<boolean>,\n builder: ContainerBuilderFn,\n elseBuilder?: ContainerBuilderFn,\n options: WhenOptions = {},\n ): void {\n const graph = this._graph;\n // A dedicated 'conditional' node reuses the reactive-list reconciliation\n // machinery (same signal subscription + keyed reconcile) but renders as a\n // neutral <div> rather than a <ul>. It holds zero or one child branch.\n const node = graph.createNode('conditional', {\n parent: this._node,\n props: containerProps({}),\n });\n\n // A transition on a `when` applies to whichever branch is mounted/removed\n // (§2). `appear` promotes the transition to a config that also animates the\n // branch present on the very first mount; the renderer distinguishes appear\n // from a reactive enter via the descriptor's `appear` flag.\n const branchTransition: TransitionConfig | undefined =\n options.transition !== undefined && options.appear === true\n ? { ...options.transition, appear: true }\n : options.transition;\n\n // Build the active branch as a single keyed container. Distinct keys for the\n // then/else branches make a flip a clean swap under the keyed reconciler.\n const buildBranch = (build: ContainerBuilderFn, tag: 'then' | 'else'): GraphNode => {\n const branchKey = `when-${tag}:${node.id}`;\n const branch = graph.createNode('container', {\n key: branchKey,\n props: { key: branchKey },\n });\n registerTransition(graph, branch, branchTransition);\n build(new ContainerBuilderImpl(branch, graph));\n return branch;\n };\n\n const buildAll = (raw: unknown): GraphNode[] => {\n if (raw) return [buildBranch(builder, 'then')];\n return elseBuilder !== undefined ? [buildBranch(elseBuilder, 'else')] : [];\n };\n\n if (isSignal(condition)) {\n const signalId = `${node.id}:items`;\n node.stateRefs.push({ signalId, propKey: 'items' });\n graph.registerHandler(`__signal__${signalId}`, condition as unknown as () => unknown);\n graph.registerHandler(`__listbuild__${node.id}`, buildAll as unknown as () => unknown);\n const current = (condition as ReadonlySignal<boolean>).peek();\n for (const child of buildAll(current)) node.appendChild(child);\n } else {\n // Static condition — resolve once at build time, no reactive wiring.\n for (const child of buildAll(condition)) node.appendChild(child);\n }\n }\n\n errorBoundary(\n id: string,\n builder: ContainerBuilderFn,\n options: ErrorBoundaryOptions,\n ): void {\n // Normalise the observed error source(s) into an array.\n const sources: ErrorSource[] =\n options.source === undefined\n ? []\n : Array.isArray(options.source)\n ? [...options.source]\n : [options.source];\n\n // The boundary's own captured error (from a synchronous build throw) and a\n // retry nonce that forces a re-evaluation even when the boolean is unchanged.\n const localError = signal<unknown>(undefined);\n const retryNonce = signal<number>(0);\n\n const readError = (): unknown => {\n const local = localError.peek();\n if (local !== undefined && local !== null) return local;\n for (const s of sources) {\n const e = s.peek();\n if (e !== undefined && e !== null) return e;\n }\n return undefined;\n };\n\n // Reactive condition: true while an error is present. Reads every input so a\n // change in any source (or a retry) re-runs the conditional.\n const hasError = derived<boolean>(() => {\n retryNonce.get();\n localError.get();\n for (const s of sources) s.get();\n return readError() !== undefined;\n });\n\n const retry = (): void => {\n localError.set(undefined);\n options.onRetry?.();\n // Force the body branch to re-attempt even if no observed value changed.\n retryNonce.update((n) => n + 1);\n };\n\n // Wrap in a container so the whole boundary is addressable and disposes as a\n // unit. `when` provides the reactive body↔fallback swap (and its cleanup).\n this.container(id, (c) => {\n c.when(\n hasError,\n // Error state → fallback. The fallback branch mounts exactly when the\n // boundary enters its error state, so this is also where the optional\n // `onError` reporting hook fires (observe-only; §6/§7).\n (fb) => {\n const currentError = readError();\n options.onError?.(currentError);\n options.fallback(fb, currentError, retry);\n },\n // Healthy state → body, guarded against synchronous build throws.\n (body) => {\n try {\n builder(body);\n } catch (err) {\n // Surface the throw as the boundary's error on the next microtask\n // (deferred to avoid re-entrant reconciliation during this build).\n queueMicrotask(() => localError.set(err));\n }\n },\n );\n }, { id });\n }\n\n asyncBoundary<T>(\n key: string,\n res: Resource<T>,\n branches: AsyncBoundaryBranches<T>,\n ): void {\n // Pure sugar over `resource` + `when` — no second async system, no new node\n // type, no renderer wiring. Three mutually-exclusive, exhaustive reactive\n // conditions select the live branch. Error wins; then resolved data (kept\n // visible during a refetch); then loading/idle.\n const isError = derived<boolean>(() => res.status.get() === 'error');\n const showSuccess = derived<boolean>(\n () => res.status.get() !== 'error' && res.data.get() !== undefined,\n );\n const showLoading = derived<boolean>(\n () => res.status.get() !== 'error' && res.data.get() === undefined,\n );\n // Narrow the data signal to `T` for the success branch. Only read inside the\n // success branch, where `data` is guaranteed present.\n const dataSignal = derived<T>(() => res.data.get() as T);\n const retry = (): void => {\n void res.refetch();\n };\n\n this.container(key, (c) => {\n c.when(isError, (fb) => branches.error?.(fb, res.error.peek(), retry));\n c.when(showSuccess, (sb) => branches.success(sb, dataSignal));\n c.when(showLoading, (lb) => branches.loading?.(lb));\n }, { key });\n }\n\n // ── Portals & overlays ──────────────────────────────────────────────────────\n\n portal(key: string, builder: ContainerBuilderFn, options: PortalOptions = {}): void {\n const node = this._graph.createNode('portal', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n builder(new ContainerBuilderImpl(node, this._graph));\n }\n\n /**\n * Declare document metadata (2.0 §1–§3). Creates a `'head'` node — a neutral,\n * empty inline anchor at this position (one node / one element, so positional\n * hydration is preserved) — and registers a `__head__<id>` descriptor holding\n * this call's normalized, dedup-keyed {@link resolveHead} contribution. The\n * renderer applies it to `document.head` on the browser (adopting server tags\n * on hydration, cleaning up on unmount / route change) and emits the active\n * graph's merged metadata as a string on the server (`renderHead`).\n *\n * Multiple `head()` nodes may be live at once (app default + route + component)\n * — the renderer merges them and, per dedup key, the last in document order\n * wins (see head.ts). No new render path: this reuses the same graph-node +\n * handler-registry convention as overlays/transitions/components.\n */\n head(metadata: HeadMetadata): void {\n const node = this._graph.createNode('head', {\n parent: this._node,\n props: { 'data-streetui-head-anchor': '' },\n });\n const contribution = resolveHead(metadata);\n this._graph.registerHandler(\n `__head__${node.id}`,\n (() => contribution) as unknown as () => unknown,\n );\n }\n\n /**\n * Shared assembly for every overlay kind: a `portal` node whose single child\n * is a `when(open, panel)` conditional. The panel container carries the\n * kind's ARIA semantics; `builder` fills it. An `__overlay__<portalId>`\n * descriptor is registered so the renderer wires focus/keyboard behavior to\n * the same `open` signal that drives the panel. Reuses existing primitives\n * (portal + when + container) — no new render path.\n */\n private _overlay(\n kind: OverlayKindConfig,\n key: string,\n options: OverlayOptions,\n builder: ContainerBuilderFn,\n ): void {\n const graph = this._graph;\n const portalNode = graph.createNode('portal', {\n key,\n parent: this._node,\n props: { key },\n });\n\n // Resolve `open` to a signal we can both bind (drives the panel's `when`)\n // and hand to the renderer (drives focus behavior). A literal is wrapped so\n // the panel still mounts/unmounts through the same reactive path.\n const openBindable = options.open;\n const openSignal: ReadonlySignal<boolean> = isSignal(openBindable)\n ? (openBindable as ReadonlySignal<boolean>)\n : signal(openBindable as boolean);\n\n // Panel a11y semantics (kind defaults, overridable via options).\n const panelOptions: ContainerOptions = {\n role: options.role ?? kind.role,\n ...(kind.ariaModal ? { ariaModal: true } : {}),\n ...(kind.ariaLive !== undefined ? { ariaLive: kind.ariaLive } : {}),\n ...(options.class !== undefined ? { class: options.class } : {}),\n ...(options.ariaLabel !== undefined ? { ariaLabel: options.ariaLabel } : {}),\n ...(options.ariaLabelledBy !== undefined ? { ariaLabelledBy: options.ariaLabelledBy } : {}),\n ...(options.ariaDescribedBy !== undefined ? { ariaDescribedBy: options.ariaDescribedBy } : {}),\n };\n\n const portalBuilder = new ContainerBuilderImpl(portalNode, graph);\n portalBuilder.when(\n openSignal,\n (panelHost) => {\n panelHost.container(`${key}__panel`, builder, panelOptions);\n },\n undefined,\n // Overlay open/close rides the panel's `when`; a transition animates the\n // panel in on open and — via the reconciler's deferred-leave — plays the\n // leave before the panel is removed (§10). Focus is restored at close-\n // request time (see wireOverlayBehavior), so it never stays trapped inside\n // a panel that is animating away.\n options.transition !== undefined ? { transition: options.transition } : {},\n );\n\n const descriptor: OverlayBehaviorDescriptor = {\n open: openSignal,\n modal: kind.modal,\n takesFocus: kind.takesFocus,\n menu: kind.menu ?? false,\n closeOnEscape: options.closeOnEscape ?? kind.defaultCloseOnEscape,\n restoreFocus: options.restoreFocus ?? kind.defaultRestoreFocus,\n ...(options.initialFocusId !== undefined ? { initialFocusId: options.initialFocusId } : {}),\n ...(options.onClose !== undefined ? { onClose: options.onClose } : {}),\n };\n graph.registerHandler(\n `__overlay__${portalNode.id}`,\n (() => descriptor) as unknown as () => unknown,\n );\n }\n\n dialog(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.dialog, key, options, builder);\n }\n\n popover(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.popover, key, options, builder);\n }\n\n tooltip(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.tooltip, key, options, builder);\n }\n\n dropdown(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.dropdown, key, options, builder);\n }\n\n toast(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.toast, key, options, builder);\n }\n\n // ── Components ────────────────────────────────────────────────────────────\n\n /**\n * Instantiate a reusable component (§3–§9). Creates a `'component'` node\n * (rendered as a `<div>` wrapper — preserves the one-node/one-element\n * positional-hydration invariant), then runs `def.setup(props, ctx)`\n * synchronously to obtain the render function and fills the component's own\n * container scope with it — structurally identical to `container`/\n * `errorBoundary`. Cleanups the setup registers via `ctx.effect`/\n * `ctx.onCleanup` are collected into a closure and exposed to the renderer\n * through a `__component__<id>` handler (mirroring `__overlay__`); the mount/\n * hydrate paths read it and route each into `NodeInstance.trackCleanup`, so\n * teardown runs (children-first) when the component leaves the graph.\n *\n * `setup` runs once per instance here at build time. When this component sits\n * inside a keyed list / conditional, a rebuild disposes the old instance\n * (running its cleanups + pruning its `__component__` entry) and re-runs this\n * method for the new node — so re-invocation is safe and leak-free.\n */\n component<P>(\n key: string,\n def: ComponentDefinition<P>,\n props: P,\n children?: ContainerBuilderFn,\n ): void {\n const graph = this._graph;\n const node = graph.createNode('component', {\n key,\n parent: this._node,\n // `data-streetui-component` is a non-underscore prop, so it reaches the\n // DOM as an attribute and is visible to DevTools (§21) — unlike the\n // internal `_`-prefixed metadata the renderer hides.\n props: { key, 'data-streetui-component': def.name },\n });\n\n // Ownership collector: every teardown the setup registers lands here and is\n // handed to the NodeInstance at mount.\n const cleanups: Array<() => void> = [];\n const ctx: ComponentContext = {\n key,\n onCleanup(fn: () => void): void {\n cleanups.push(fn);\n },\n effect(fn: () => void | (() => void)): void {\n // Reuse the EXISTING reactive engine (§8) — no new reactivity. The\n // effect runs immediately (build time, like errorBoundary's derived);\n // its unsubscribe is owned by this component.\n cleanups.push(effect(fn));\n },\n renderChildren(content: ContainerDSL): void {\n if (children !== undefined) children(content);\n },\n };\n\n // Run setup to get the render function, guarding a synchronous throw the\n // same way errorBoundary does (defer so we never re-enter reconciliation\n // during this build). A component wrapped in an errorBoundary still surfaces\n // the error through the boundary's observed sources.\n let render: ComponentRender;\n try {\n render = def.setup(props, ctx);\n render(new ContainerBuilderImpl(node, graph));\n } catch (err) {\n queueMicrotask(() => {\n throw err;\n });\n }\n\n if (cleanups.length > 0) {\n graph.registerHandler(\n `__component__${node.id}`,\n (() => cleanups) as unknown as () => unknown,\n );\n }\n }\n}\n\n// ── Concrete builder implementations ─────────────────────────────────────────\n\nexport class SectionBuilderImpl extends ContainerBuilderBase implements SectionDSL {}\nexport class ContainerBuilderImpl extends ContainerBuilderBase implements ContainerDSL {}\nexport class FormBuilderImpl extends ContainerBuilderBase implements FormDSL {}\n\nexport class ListBuilderImpl extends ContentBuilderBase implements ListDSL {\n item(key: string, builder: ContainerBuilderFn, options: ContainerOptions = {}): void {\n const node = this._graph.createNode('list-item', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(this._graph, node, options.transition);\n builder(new ContainerBuilderImpl(node, this._graph));\n }\n}\n\nexport class PageBuilderImpl extends ContainerBuilderBase implements PageDSL {}\n\n// ── App builder ───────────────────────────────────────────────────────────────\n\nexport class AppBuilder implements AppDSL {\n constructor(private readonly _graph: ApplicationGraph) {}\n\n page(key: string, builder: PageBuilder): void {\n const node = this._graph.createNode('page', {\n key,\n parent: this._graph.root,\n props: { key },\n });\n builder(new PageBuilderImpl(node, this._graph));\n }\n}\n","/**\n * Semantic Application Graph nodes.\n *\n * Every element in a StreetUI application is represented as a GraphNode.\n * Nodes form a tree: each has an optional parent and an ordered list of children.\n */\n\nimport { generateNodeId, type NodeId, type SemanticNodeType } from '@streetui/core';\n\n// ── Property values ───────────────────────────────────────────────────────────\n\nexport type PropValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | string[]\n | number[]\n | Record<string, unknown>;\n\nexport type Props = Record<string, PropValue>;\n\n// ── Event descriptors ─────────────────────────────────────────────────────────\n\nexport interface EventDescriptor {\n readonly type: string;\n /** Reference key into the application's handler registry. */\n readonly handlerKey: string;\n}\n\n// ── State references ──────────────────────────────────────────────────────────\n\nexport interface StateRef {\n /** ID of the signal/store this node's property is bound to. */\n readonly signalId: string;\n /** The prop key on this node that is bound. */\n readonly propKey: string;\n}\n\n// ── The core graph node ───────────────────────────────────────────────────────\n\nexport interface GraphNodeData {\n readonly id: NodeId;\n readonly type: SemanticNodeType;\n readonly key: string | undefined;\n props: Props;\n events: EventDescriptor[];\n stateRefs: StateRef[];\n children: GraphNode[];\n parent: GraphNode | null;\n}\n\nexport class GraphNode implements GraphNodeData {\n readonly id: NodeId;\n readonly type: SemanticNodeType;\n readonly key: string | undefined;\n props: Props;\n events: EventDescriptor[];\n stateRefs: StateRef[];\n children: GraphNode[];\n parent: GraphNode | null;\n\n constructor(\n type: SemanticNodeType,\n options: {\n id?: NodeId;\n key?: string;\n props?: Props;\n events?: EventDescriptor[];\n stateRefs?: StateRef[];\n } = {},\n ) {\n this.type = type;\n this.id = options.id ?? generateNodeId(type);\n this.key = options.key;\n this.props = options.props ?? {};\n this.events = options.events ?? [];\n this.stateRefs = options.stateRefs ?? [];\n this.children = [];\n this.parent = null;\n }\n\n // ── Child management ────────────────────────────────────────────────────────\n\n appendChild(child: GraphNode): void {\n if (child.parent !== null) {\n child.parent.removeChild(child);\n }\n child.parent = this;\n this.children.push(child);\n }\n\n insertBefore(child: GraphNode, reference: GraphNode): void {\n const idx = this.children.indexOf(reference);\n if (idx === -1) {\n this.appendChild(child);\n return;\n }\n if (child.parent !== null) {\n child.parent.removeChild(child);\n }\n child.parent = this;\n this.children.splice(idx, 0, child);\n }\n\n removeChild(child: GraphNode): void {\n const idx = this.children.indexOf(child);\n if (idx === -1) return;\n this.children.splice(idx, 1);\n child.parent = null;\n }\n\n replaceChild(newChild: GraphNode, oldChild: GraphNode): void {\n const idx = this.children.indexOf(oldChild);\n if (idx === -1) {\n throw new Error(`GraphNode.replaceChild: oldChild is not a child of this node`);\n }\n if (newChild.parent !== null) {\n newChild.parent.removeChild(newChild);\n }\n oldChild.parent = null;\n newChild.parent = this;\n this.children.splice(idx, 1, newChild);\n }\n\n // ── Prop helpers ────────────────────────────────────────────────────────────\n\n setProp(key: string, value: PropValue): void {\n this.props = { ...this.props, [key]: value };\n }\n\n getProp<T extends PropValue = PropValue>(key: string): T | undefined {\n return this.props[key] as T | undefined;\n }\n\n // ── Event helpers ───────────────────────────────────────────────────────────\n\n addEvent(descriptor: EventDescriptor): void {\n this.events.push(descriptor);\n }\n\n removeEvent(type: string): void {\n this.events = this.events.filter(e => e.type !== type);\n }\n\n // ── Queries ─────────────────────────────────────────────────────────────────\n\n get isLeaf(): boolean {\n return this.children.length === 0;\n }\n\n get depth(): number {\n let d = 0;\n let node: GraphNode | null = this.parent;\n while (node !== null) {\n d++;\n node = node.parent;\n }\n return d;\n }\n\n get root(): GraphNode {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let node: GraphNode = this;\n while (node.parent !== null) {\n node = node.parent;\n }\n return node;\n }\n\n /** Shallow clone — does not clone children. */\n shallowClone(): GraphNode {\n const opts: { key?: string; props: Props; events: EventDescriptor[]; stateRefs: StateRef[] } = {\n props: { ...this.props },\n events: [...this.events],\n stateRefs: [...this.stateRefs],\n };\n if (this.key !== undefined) opts.key = this.key;\n return new GraphNode(this.type, opts);\n }\n}\n","/**\n * The Semantic Application Graph.\n *\n * Holds the application root node and all its descendants.\n * Supports traversal, lookup by ID, validation, and serialization.\n */\n\nimport { type NodeId, DiagnosticCollector } from '@streetui/core';\nimport { GraphNode, type Props, type EventDescriptor } from './graph-node.js';\n\nexport interface ApplicationGraphOptions {\n readonly name: string;\n readonly version?: string;\n}\n\nexport interface HandlerFn {\n (...args: unknown[]): unknown;\n}\n\nexport class ApplicationGraph {\n readonly root: GraphNode;\n readonly name: string;\n readonly version: string;\n private readonly _nodeIndex: Map<NodeId, GraphNode> = new Map();\n /** Handler registry — maps handlerKey → actual function */\n readonly handlers: Map<string, HandlerFn> = new Map();\n\n constructor(options: ApplicationGraphOptions) {\n this.name = options.name;\n this.version = options.version ?? '0.0.1';\n this.root = new GraphNode('application', { props: { name: options.name } });\n this._nodeIndex.set(this.root.id, this.root);\n }\n\n // ── Node creation & attachment ────────────────────────────────────────────\n\n createNode(\n type: GraphNode['type'],\n options: { key?: string; props?: Props; parent?: GraphNode } = {},\n ): GraphNode {\n const nodeOpts: { key?: string; props?: Props } = {};\n if (options.key !== undefined) nodeOpts.key = options.key;\n if (options.props !== undefined) nodeOpts.props = options.props;\n const node = new GraphNode(type, nodeOpts);\n this._nodeIndex.set(node.id, node);\n if (options.parent !== undefined) {\n options.parent.appendChild(node);\n }\n return node;\n }\n\n attachNode(node: GraphNode, parent: GraphNode): void {\n this._nodeIndex.set(node.id, node);\n parent.appendChild(node);\n }\n\n detachNode(node: GraphNode): void {\n if (node.parent !== null) {\n node.parent.removeChild(node);\n }\n this._removeFromIndex(node);\n }\n\n private _removeFromIndex(node: GraphNode): void {\n this._nodeIndex.delete(node.id);\n this._unregisterNodeHandlers(node);\n for (const child of node.children) {\n this._removeFromIndex(child);\n }\n }\n\n /**\n * Remove every handler-registry entry owned by a single node. A node owns:\n * - one entry per event descriptor (its `handlerKey`),\n * - one `__signal__<signalId>` entry per state ref (signalIds are namespaced\n * by node id, so they are never shared between nodes), and\n * - a `__listbuild__<id>` entry if it is a reactive-list.\n * Called for every node in a detached subtree so removing list items (or\n * discarding freshly-built-but-unadopted item subtrees) leaves no stale\n * registrations behind.\n */\n private _unregisterNodeHandlers(node: GraphNode): void {\n for (const event of node.events) {\n this.handlers.delete(event.handlerKey);\n }\n for (const ref of node.stateRefs) {\n this.handlers.delete(`__signal__${ref.signalId}`);\n }\n this.handlers.delete(`__listbuild__${node.id}`);\n this.handlers.delete(`__listplan__${node.id}`);\n this.handlers.delete(`__overlay__${node.id}`);\n this.handlers.delete(`__component__${node.id}`);\n this.handlers.delete(`__transition__${node.id}`);\n this.handlers.delete(`__head__${node.id}`);\n }\n\n // ── Handler registry ──────────────────────────────────────────────────────\n\n registerHandler(key: string, fn: HandlerFn): void {\n this.handlers.set(key, fn);\n }\n\n getHandler(key: string): HandlerFn | undefined {\n return this.handlers.get(key);\n }\n\n /** True if a handler is currently registered under `key`. Inspection helper. */\n hasHandler(key: string): boolean {\n return this.handlers.has(key);\n }\n\n /** Number of currently-registered handlers. Inspection helper. */\n get handlerCount(): number {\n return this.handlers.size;\n }\n\n // ── Lookup ────────────────────────────────────────────────────────────────\n\n findById(id: NodeId): GraphNode | undefined {\n return this._nodeIndex.get(id);\n }\n\n findAll(predicate: (node: GraphNode) => boolean): GraphNode[] {\n const results: GraphNode[] = [];\n this._walk(this.root, node => {\n if (predicate(node)) results.push(node);\n });\n return results;\n }\n\n findByType(type: GraphNode['type']): GraphNode[] {\n return this.findAll(n => n.type === type);\n }\n\n // ── Traversal ─────────────────────────────────────────────────────────────\n\n walk(visitor: (node: GraphNode, depth: number) => void): void {\n this._walk(this.root, visitor, 0);\n }\n\n private _walk(\n node: GraphNode,\n visitor: (node: GraphNode, depth: number) => void,\n depth: number = 0,\n ): void {\n visitor(node, depth);\n for (const child of node.children) {\n this._walk(child, visitor, depth + 1);\n }\n }\n\n get nodeCount(): number {\n return this._nodeIndex.size;\n }\n\n // ── Validation ────────────────────────────────────────────────────────────\n\n validate(): DiagnosticCollector {\n const dc = new DiagnosticCollector();\n\n this.walk((node) => {\n // Validate event handler references exist\n for (const event of node.events) {\n if (!this.handlers.has(event.handlerKey)) {\n dc.warn(\n 'GRAPH_MISSING_HANDLER',\n `Node \"${node.id}\" references handler \"${event.handlerKey}\" which is not registered`,\n { nodeId: node.id },\n );\n }\n }\n\n // Validate page nodes are direct children of root\n if (node.type === 'page' && node.parent?.type !== 'application') {\n dc.error(\n 'GRAPH_PAGE_DEPTH',\n `Page node \"${node.id}\" must be a direct child of the application root`,\n { nodeId: node.id },\n );\n }\n });\n\n return dc;\n }\n\n // ── Serialization ─────────────────────────────────────────────────────────\n\n serialize(): SerializedGraph {\n return {\n name: this.name,\n version: this.version,\n root: this._serializeNode(this.root),\n };\n }\n\n private _serializeNode(node: GraphNode): SerializedNode {\n const result: SerializedNode = {\n id: node.id,\n type: node.type,\n key: node.key,\n props: node.props,\n events: node.events,\n stateRefs: node.stateRefs,\n children: node.children.map(c => this._serializeNode(c)),\n };\n return result;\n }\n}\n\nexport interface SerializedNode {\n readonly id: string;\n readonly type: string;\n readonly key: string | undefined;\n readonly props: Props;\n readonly events: EventDescriptor[];\n readonly stateRefs: unknown[];\n readonly children: SerializedNode[];\n}\n\nexport interface SerializedGraph {\n readonly name: string;\n readonly version: string;\n readonly root: SerializedNode;\n}\n","/**\n * StreetUI DSL entry point.\n *\n * Usage:\n * import { streetui } from '@streetui/dsl';\n *\n * const app = streetui.app({ name: 'My App' });\n * app.page('home', page => {\n * page.section('hero', section => {\n * section.heading('Welcome');\n * section.button('Click me', { onClick: () => {} });\n * });\n * });\n *\n * const graph = app.build();\n */\n\nimport { ApplicationGraph } from '@streetui/graph';\nimport { AppBuilder } from './builders.js';\n\nexport interface AppOptions {\n readonly name: string;\n readonly version?: string;\n}\n\nexport class StreetApp {\n private readonly _graph: ApplicationGraph;\n private readonly _builder: AppBuilder;\n\n constructor(options: AppOptions) {\n const graphOpts: { name: string; version?: string } = { name: options.name };\n if (options.version !== undefined) graphOpts.version = options.version;\n this._graph = new ApplicationGraph(graphOpts);\n this._builder = new AppBuilder(this._graph);\n }\n\n page(key: string, builder: Parameters<AppBuilder['page']>[1]): this {\n this._builder.page(key, builder);\n return this;\n }\n\n /** Compile to ApplicationGraph — validates and returns the graph. */\n build(): ApplicationGraph {\n const dc = this._graph.validate();\n dc.throwIfErrors();\n return this._graph;\n }\n\n /** Access graph before building (useful for inspection). */\n get graph(): ApplicationGraph {\n return this._graph;\n }\n}\n\nexport interface StreetUI {\n app(options: AppOptions): StreetApp;\n}\n\nexport const streetui: StreetUI = {\n app(options: AppOptions): StreetApp {\n return new StreetApp(options);\n },\n};\n","/**\n * Component-focused testing helpers (§22).\n *\n * These extend `streetui/testing` for the component model. Following the spec's\n * \"add only the ones that are actually useful\" directive, this module ships the\n * helpers that remove real boilerplate and OMITS the ones that would be\n * misleading in this architecture:\n *\n * • renderComponent — mount a single component in a throwaway host app.\n * • hydrateComponent — SSR-then-hydrate that same host (the §11/§12 seam).\n * • findComponent / findAllComponents / getComponentName — locate component\n * instances by their inspectable `data-streetui-component` name.\n * • trigger — dispatch a bubbling DOM event (click/input/keydown…).\n *\n * Deliberately NOT provided:\n * • getComponentProps — props are passed to `setup` and captured by closure;\n * they are not reified on the node (only the definition *name* is), so a\n * prop-reading helper would either lie or require a private-graph backdoor.\n * Assert on rendered output (or a signal you own) instead.\n * • awaitResource — `waitFor(...)` and `flushUpdates()` already settle\n * async resource state; a resource-specific alias would be redundant.\n */\n\nimport { streetui, type ComponentDefinition, type ContainerBuilder } from '@streetui/dsl';\nimport { render, type RenderResult } from './test-renderer.js';\nimport { renderServerThenHydrate, type HydrateTestResult, type HydrateTestOptions } from './helpers.js';\n\n/** The attribute the DSL writes for a component's inspectable name. */\nconst COMPONENT_ATTR = 'data-streetui-component';\n\nexport interface RenderComponentResult extends RenderResult {\n /** The component's root `<div>` wrapper element. */\n readonly component: HTMLElement;\n}\n\n/**\n * Build a throwaway single-page host app whose only content is `def` rendered\n * with `props` (and optional `children`), mount it, and return the usual\n * `RenderResult` plus the component's root element. Use for unit-testing one\n * component without hand-writing an app+page wrapper each time.\n */\nexport function renderComponent<P>(\n def: ComponentDefinition<P>,\n props: P,\n children?: ContainerBuilder,\n): RenderComponentResult {\n const app = streetui.app({ name: `test:${def.name}` });\n app.page('host', (page) => {\n page.component('root', def, props, children);\n });\n const result = render(app);\n const component = result.container.querySelector<HTMLElement>(`[${COMPONENT_ATTR}]`);\n if (component === null) {\n throw new Error(`[StreetUI Testing] renderComponent: no component element rendered for \"${def.name}\"`);\n }\n return { ...result, component };\n}\n\n/**\n * SSR-render then hydrate a single component in a host app — the production\n * server→client seam (§11/§12). `build` must return `{ def, props, children? }`;\n * it is invoked twice (server then client) with id-counter reset between, so a\n * component that owns per-instance signals lines up positionally on hydration.\n */\nexport function hydrateComponent<P>(\n build: () => { def: ComponentDefinition<P>; props: P; children?: ContainerBuilder },\n options: HydrateTestOptions = {},\n): HydrateTestResult {\n return renderServerThenHydrate(() => {\n const { def, props, children } = build();\n const app = streetui.app({ name: `test:${def.name}` });\n app.page('host', (page) => page.component('root', def, props, children));\n return app;\n }, options);\n}\n\n/** All component instances under `container`, optionally filtered by name. */\nexport function findAllComponents(container: Element, name?: string): HTMLElement[] {\n const selector = name === undefined\n ? `[${COMPONENT_ATTR}]`\n : `[${COMPONENT_ATTR}=\"${name}\"]`;\n return Array.from(container.querySelectorAll<HTMLElement>(selector));\n}\n\n/** The single component instance under `container` (throws if none/ambiguous). */\nexport function findComponent(container: Element, name?: string): HTMLElement {\n const matches = findAllComponents(container, name);\n const named = name !== undefined ? ` named \"${name}\"` : '';\n if (matches.length === 0) {\n throw new Error(`[StreetUI Testing] No component${named} found`);\n }\n if (matches.length > 1) {\n throw new Error(\n `[StreetUI Testing] Found ${matches.length} components${named} — pass a name to disambiguate`,\n );\n }\n return matches[0]!;\n}\n\n/** Read a component element's definition name, or `null` if `el` is not one. */\nexport function getComponentName(el: Element): string | null {\n return el.getAttribute(COMPONENT_ATTR);\n}\n\n/**\n * Dispatch a bubbling, cancelable DOM event of `type` on `el`. Thin wrapper over\n * `dispatchEvent` so tests read intentfully (`trigger(btn, 'click')`) without\n * constructing `Event`/`KeyboardEvent` objects by hand. Extra `init` fields\n * (e.g. `{ key: 'Escape' }`) are forwarded to the appropriate event ctor.\n */\nexport function trigger(el: Element, type: string, init: Record<string, unknown> = {}): void {\n const base = { bubbles: true, cancelable: true, ...init };\n let event: Event;\n if (type.startsWith('key')) {\n event = new KeyboardEvent(type, base as KeyboardEventInit);\n } else if (type.startsWith('mouse') || type === 'click' || type === 'dblclick') {\n event = new MouseEvent(type, base as MouseEventInit);\n } else if (type === 'input' || type === 'change') {\n event = new Event(type, base);\n } else {\n event = new Event(type, base);\n }\n el.dispatchEvent(event);\n}\n","/**\n * The single authoritative StreetUI framework version.\n *\n * This constant is the one source of truth for the version of the shipped\n * `streetui` package. It is kept in lock-step with this package's\n * `package.json` `version` field and with the bundled CLI's reported version\n * (`streetui --version`) — the consolidated test-suite pins all three to the\n * same coordinated release so they can never silently drift apart.\n */\nexport const VERSION = '2.0.0';\n"],"mappings":"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","names":["classes","instance","el","tag","render"]}
1
+ {"version":3,"sources":["../src/testing.ts","../../core/src/identity.ts","../../core/src/lifecycle.ts","../../core/src/diagnostics.ts","../../compiler/src/validation/validator.ts","../../compiler/src/transform/transform.ts","../../compiler/src/compile.ts","../../dom/src/browser-adapter.ts","../../dom/src/server-node.ts","../../dom/src/server-adapter.ts","../../dom/src/focus.ts","../../renderer/src/render-context.ts","../../renderer/src/node-instance.ts","../../renderer/src/attributes.ts","../../renderer/src/events.ts","../../renderer/src/tag-map.ts","../../renderer/src/patch.ts","../../renderer/src/reconciliation.ts","../../renderer/src/transition.ts","../../renderer/src/head.ts","../../renderer/src/mount.ts","../../renderer/src/hydration-diagnostics.ts","../../renderer/src/hydrate.ts","../../renderer/src/render-handle.ts","../../renderer/src/renderer.ts","../../compiler/src/analysis/analyze.ts","../../compiler/src/analysis/inspect.ts","../../renderer/src/static-ssr-plan.ts","../../renderer/src/ssr.ts","../../testing/src/test-renderer.ts","../../scheduler/src/scheduler.ts","../../testing/src/helpers.ts","../../dsl/src/transition.ts","../../dsl/src/head.ts","../../state/src/signal.ts","../../dsl/src/builders.ts","../../graph/src/graph-node.ts","../../graph/src/graph.ts","../../dsl/src/dsl.ts","../../testing/src/component.ts","../src/version.ts"],"sourcesContent":["/**\n * `streetui/testing` — testing utilities for StreetUI applications.\n *\n * A curated entry for the already-implemented testing helpers (render,\n * findByRole, waitFor, renderServerThenHydrate, …). It lives on its own subpath\n * so that test-only helpers stay out of the main runtime barrel — and so the\n * one cross-package name collision (`RenderResult`, shared with the CLI's render\n * types) is resolved cleanly: the testing `RenderResult` is reachable only from\n * here.\n *\n * ```ts\n * import { render, findByRole, waitFor } from 'streetui/testing';\n * ```\n */\nexport * from '@streetui/testing';\n\n// Opt-in compiler diagnostics (spec §14): static-graph analysis + inspection.\n// Exposed on the diagnostic subpath so they stay OUT of the runtime barrel\n// (`streetui`), keeping the shipped client bundle lean (§6/§7).\nexport * from '@streetui/compiler/diagnostics';\n\n// Re-export the framework version for parity with the main entry.\nexport { VERSION } from './version.js';\n","/**\n * Node and application identity utilities.\n * Every node in the semantic graph has a stable, unique identity.\n */\n\nlet _counter = 0;\n\n/** Generate a framework-internal monotonic integer ID. */\nexport function nextId(): number {\n return ++_counter;\n}\n\n/** Reset the counter (test use only). */\nexport function resetIdCounter(): void {\n _counter = 0;\n}\n\n/** Opaque branded type for node IDs. */\nexport type NodeId = string & { readonly __brand: 'NodeId' };\n\n/** Create a NodeId from a string (must be unique at call site). */\nexport function createNodeId(value: string): NodeId {\n return value as NodeId;\n}\n\n/** Generate a fresh, unique NodeId. */\nexport function generateNodeId(prefix: string = 'node'): NodeId {\n return createNodeId(`${prefix}:${nextId()}`);\n}\n\n/** Parse the prefix from a NodeId. */\nexport function nodeIdPrefix(id: NodeId): string {\n const colon = id.indexOf(':');\n return colon === -1 ? id : id.slice(0, colon);\n}\n\n/** Branded type for application IDs. */\nexport type ApplicationId = string & { readonly __brand: 'ApplicationId' };\n\n/** Generate a fresh application ID. */\nexport function generateApplicationId(name: string): ApplicationId {\n return `app:${name}:${nextId()}` as ApplicationId;\n}\n","/**\n * Application and component lifecycle primitives.\n *\n * Lifecycle phases:\n * created → mounted → active ⇄ updating → unmounting → destroyed\n */\n\nexport type LifecyclePhase =\n | 'created'\n | 'mounted'\n | 'active'\n | 'updating'\n | 'unmounting'\n | 'destroyed';\n\nexport type LifecycleHook = () => void | Promise<void>;\n\nexport class Lifecycle {\n private _phase: LifecyclePhase = 'created';\n private readonly _hooks: Map<LifecyclePhase, LifecycleHook[]> = new Map();\n\n get phase(): LifecyclePhase {\n return this._phase;\n }\n\n get isMounted(): boolean {\n return this._phase === 'mounted' || this._phase === 'active' || this._phase === 'updating';\n }\n\n get isDestroyed(): boolean {\n return this._phase === 'destroyed';\n }\n\n on(phase: LifecyclePhase, hook: LifecycleHook): () => void {\n const hooks = this._hooks.get(phase) ?? [];\n hooks.push(hook);\n this._hooks.set(phase, hooks);\n return () => {\n const current = this._hooks.get(phase);\n if (current !== undefined) {\n const idx = current.indexOf(hook);\n if (idx !== -1) current.splice(idx, 1);\n }\n };\n }\n\n async transition(to: LifecyclePhase): Promise<void> {\n this._phase = to;\n const hooks = this._hooks.get(to) ?? [];\n for (const hook of hooks) {\n await hook();\n }\n }\n\n onMount(hook: LifecycleHook): () => void {\n return this.on('mounted', hook);\n }\n\n onUnmount(hook: LifecycleHook): () => void {\n return this.on('unmounting', hook);\n }\n\n onDestroy(hook: LifecycleHook): () => void {\n return this.on('destroyed', hook);\n }\n}\n\n/** A simple cleanup registry — collect teardown functions and run them all at once. */\nexport class CleanupRegistry {\n private readonly _fns: Array<() => void> = [];\n\n add(fn: () => void): void {\n this._fns.push(fn);\n }\n\n run(): void {\n for (const fn of this._fns) {\n try {\n fn();\n } catch {\n // Best-effort cleanup; don't let one failure block others\n }\n }\n this._fns.length = 0;\n }\n}\n","/**\n * Framework diagnostics — structured errors, warnings, and hints\n * that flow through the compiler, validator, and runtime.\n */\n\nexport type DiagnosticSeverity = 'error' | 'warning' | 'info';\n\nexport interface DiagnosticLocation {\n readonly file?: string;\n readonly line?: number;\n readonly column?: number;\n readonly nodeId?: string;\n}\n\nexport interface Diagnostic {\n readonly severity: DiagnosticSeverity;\n readonly code: string;\n readonly message: string;\n readonly location: DiagnosticLocation | undefined;\n readonly cause: unknown;\n}\n\nexport class DiagnosticError extends Error {\n readonly diagnostics: readonly Diagnostic[];\n\n constructor(diagnostics: readonly Diagnostic[]) {\n const summary = diagnostics\n .filter(d => d.severity === 'error')\n .map(d => `[${d.code}] ${d.message}`)\n .join('\\n');\n super(`StreetUI diagnostics:\\n${summary}`);\n this.name = 'DiagnosticError';\n this.diagnostics = diagnostics;\n }\n}\n\nexport class DiagnosticCollector {\n private readonly _diagnostics: Diagnostic[] = [];\n\n get diagnostics(): readonly Diagnostic[] {\n return this._diagnostics;\n }\n\n get hasErrors(): boolean {\n return this._diagnostics.some(d => d.severity === 'error');\n }\n\n get hasWarnings(): boolean {\n return this._diagnostics.some(d => d.severity === 'warning');\n }\n\n error(\n code: string,\n message: string,\n location?: DiagnosticLocation,\n cause?: unknown,\n ): void {\n this._diagnostics.push({ severity: 'error', code, message, location: location ?? undefined, cause: cause ?? undefined });\n }\n\n warn(\n code: string,\n message: string,\n location?: DiagnosticLocation,\n ): void {\n this._diagnostics.push({ severity: 'warning', code, message, location: location ?? undefined, cause: undefined });\n }\n\n info(\n code: string,\n message: string,\n location?: DiagnosticLocation,\n ): void {\n this._diagnostics.push({ severity: 'info', code, message, location: location ?? undefined, cause: undefined });\n }\n\n merge(other: DiagnosticCollector): void {\n for (const d of other.diagnostics) {\n this._diagnostics.push(d);\n }\n }\n\n throwIfErrors(): void {\n if (this.hasErrors) {\n throw new DiagnosticError(this._diagnostics);\n }\n }\n\n clear(): void {\n this._diagnostics.length = 0;\n }\n}\n\n/** Format a single diagnostic as a human-readable string. */\nexport function formatDiagnostic(d: Diagnostic): string {\n const loc = d.location !== undefined\n ? ` (${[d.location.file, d.location.line, d.location.column]\n .filter(Boolean)\n .join(':')})`\n : '';\n return `[${d.severity.toUpperCase()}] ${d.code}: ${d.message}${loc}`;\n}\n","/**\n * Compiler-phase validation of the ApplicationGraph.\n *\n * This runs after the DSL has built the graph but before the runtime\n * receives a CompiledApplication. More checks live here than in the\n * graph's own validate() because the compiler has broader context.\n */\n\nimport { DiagnosticCollector } from '@streetui/core';\nimport { ApplicationGraph, GraphNode } from '@streetui/graph';\n\nexport function validateGraph(graph: ApplicationGraph): DiagnosticCollector {\n const dc = new DiagnosticCollector();\n\n // Merge built-in graph validations\n dc.merge(graph.validate());\n\n // Must have at least one page\n const pages = graph.findByType('page');\n if (pages.length === 0) {\n dc.warn(\n 'COMPILER_NO_PAGES',\n 'Application has no pages defined. At least one page is recommended.',\n );\n }\n\n // Walk and validate individual nodes\n graph.walk((node) => {\n validateNode(node, dc);\n });\n\n return dc;\n}\n\nfunction validateNode(node: GraphNode, dc: DiagnosticCollector): void {\n switch (node.type) {\n case 'heading': {\n const text = node.getProp('text');\n if (text === undefined || text === '') {\n dc.warn('COMPILER_EMPTY_HEADING', `Heading node \"${node.id}\" has no text content`, {\n nodeId: node.id,\n });\n }\n break;\n }\n case 'image': {\n const src = node.getProp('src');\n const alt = node.getProp('alt');\n if (!src) {\n dc.error('COMPILER_IMAGE_NO_SRC', `Image node \"${node.id}\" is missing src`, {\n nodeId: node.id,\n });\n }\n if (!alt) {\n dc.warn('COMPILER_IMAGE_NO_ALT', `Image node \"${node.id}\" is missing alt text`, {\n nodeId: node.id,\n });\n }\n break;\n }\n case 'link': {\n const href = node.getProp('href');\n if (!href) {\n dc.error('COMPILER_LINK_NO_HREF', `Link node \"${node.id}\" is missing href`, {\n nodeId: node.id,\n });\n }\n break;\n }\n default:\n break;\n }\n}\n","/**\n * Graph transformation pass.\n *\n * After validation, the transformer prepares the graph for the runtime by:\n * - Resolving implicit defaults (e.g. heading level defaults to 1)\n * - Normalizing prop names\n * - Assigning deterministic render keys where missing\n * - Flattening / hoisting where beneficial\n */\n\nimport { ApplicationGraph, GraphNode } from '@streetui/graph';\n\nexport function transformGraph(graph: ApplicationGraph): void {\n graph.walk((node, depth) => {\n applyDefaults(node);\n ensureRenderKey(node, depth);\n });\n}\n\nfunction applyDefaults(node: GraphNode): void {\n switch (node.type) {\n case 'heading': {\n if (node.getProp('level') === undefined) {\n node.setProp('level', 1);\n }\n break;\n }\n case 'input': {\n if (node.getProp('inputType') === undefined) {\n node.setProp('inputType', 'text');\n }\n break;\n }\n case 'link': {\n if (node.getProp('external') === undefined) {\n node.setProp('external', false);\n }\n break;\n }\n default:\n break;\n }\n}\n\nfunction ensureRenderKey(node: GraphNode, depth: number): void {\n if (node.getProp('_renderKey') === undefined) {\n const key = node.key ?? `${node.type}:${node.id}:${depth}`;\n node.setProp('_renderKey', key);\n }\n}\n","/**\n * StreetUI compiler entry point.\n *\n * Pipeline:\n * StreetApp (DSL)\n * → ApplicationGraph (build)\n * → validate\n * → transform\n * → CompiledApplication\n */\n\nimport { DiagnosticCollector } from '@streetui/core';\nimport { type ApplicationGraph } from '@streetui/graph';\nimport { type StreetApp } from '@streetui/dsl';\nimport { validateGraph } from './validation/validator.js';\nimport { transformGraph } from './transform/transform.js';\n\nexport interface CompiledApplication {\n /** The fully built, validated, and transformed graph. */\n readonly graph: ApplicationGraph;\n /** Diagnostics accumulated during compilation. */\n readonly diagnostics: DiagnosticCollector;\n /** Metadata */\n readonly name: string;\n readonly version: string;\n readonly compiledAt: number;\n}\n\nexport interface CompileOptions {\n /** If true, compilation throws on errors. Defaults to true. */\n readonly strict?: boolean;\n /** If true, also throw on warnings. Defaults to false. */\n readonly strictWarnings?: boolean;\n}\n\n/**\n * Compile a StreetApp DSL definition into a CompiledApplication\n * ready for the runtime to execute.\n */\nexport function compile(\n app: StreetApp,\n options: CompileOptions = {},\n): CompiledApplication {\n const strict = options.strict ?? true;\n const strictWarnings = options.strictWarnings ?? false;\n const dc = new DiagnosticCollector();\n\n // 1. Build the graph from the DSL\n const graph = app.graph;\n\n // 2. Validate\n const validationDc = validateGraph(graph);\n dc.merge(validationDc);\n\n if (strict && dc.hasErrors) {\n dc.throwIfErrors();\n }\n if (strictWarnings && dc.hasWarnings) {\n throw new Error(\n `[StreetUI Compiler] Compilation failed: warnings treated as errors.\\n` +\n dc.diagnostics\n .filter(d => d.severity === 'warning')\n .map(d => ` [${d.code}] ${d.message}`)\n .join('\\n'),\n );\n }\n\n // 3. Transform\n transformGraph(graph);\n\n return {\n graph,\n diagnostics: dc,\n name: graph.name,\n version: graph.version,\n compiledAt: Date.now(),\n };\n}\n\n/**\n * Compile from a pre-built ApplicationGraph (used when the graph\n * was constructed programmatically rather than through the DSL).\n */\nexport function compileGraph(\n graph: ApplicationGraph,\n options: CompileOptions = {},\n): CompiledApplication {\n const strict = options.strict ?? true;\n const dc = new DiagnosticCollector();\n\n const validationDc = validateGraph(graph);\n dc.merge(validationDc);\n\n if (strict && dc.hasErrors) {\n dc.throwIfErrors();\n }\n\n transformGraph(graph);\n\n return {\n graph,\n diagnostics: dc,\n name: graph.name,\n version: graph.version,\n compiledAt: Date.now(),\n };\n}\n","/**\n * Browser implementation of DOMAdapter — delegates directly to browser APIs.\n */\n\nimport type { DOMAdapter } from './adapter.js';\n\nexport class BrowserDOMAdapter implements DOMAdapter {\n createElement(tag: string, ns?: string): Element {\n if (ns !== undefined) {\n return document.createElementNS(ns, tag);\n }\n return document.createElement(tag);\n }\n\n createTextNode(data: string): Text {\n return document.createTextNode(data);\n }\n\n createComment(data: string): Comment {\n return document.createComment(data);\n }\n\n createFragment(): DocumentFragment {\n return document.createDocumentFragment();\n }\n\n appendChild(parent: Node, child: Node): void {\n parent.appendChild(child);\n }\n\n insertBefore(parent: Node, child: Node, reference: Node | null): void {\n parent.insertBefore(child, reference);\n }\n\n removeChild(parent: Node, child: Node): void {\n parent.removeChild(child);\n }\n\n replaceChild(parent: Node, newChild: Node, oldChild: Node): void {\n parent.replaceChild(newChild, oldChild);\n }\n\n setAttribute(element: Element, name: string, value: string): void {\n element.setAttribute(name, value);\n }\n\n removeAttribute(element: Element, name: string): void {\n element.removeAttribute(name);\n }\n\n getAttribute(element: Element, name: string): string | null {\n return element.getAttribute(name);\n }\n\n setProperty(element: Element, name: string, value: unknown): void {\n (element as unknown as Record<string, unknown>)[name] = value;\n }\n\n setTextContent(node: Node, text: string): void {\n node.textContent = text;\n }\n\n getTextContent(node: Node): string | null {\n return node.textContent;\n }\n\n addEventListener(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n ): void {\n target.addEventListener(type, handler, options);\n }\n\n removeEventListener(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: EventListenerOptions,\n ): void {\n target.removeEventListener(type, handler, options);\n }\n\n querySelector(root: Element | Document, selector: string): Element | null {\n return root.querySelector(selector);\n }\n\n querySelectorAll(root: Element | Document, selector: string): NodeListOf<Element> {\n return root.querySelectorAll(selector);\n }\n\n getElementById(id: string): Element | null {\n return document.getElementById(id);\n }\n\n focus(element: Element): void {\n (element as unknown as { focus?: () => void }).focus?.();\n }\n\n body(): Element | null {\n return document.body ?? null;\n }\n\n head(): Element | null {\n return document.head ?? null;\n }\n\n activeElement(): Element | null {\n return document.activeElement ?? null;\n }\n\n contains(ancestor: Element, node: Node): boolean {\n return ancestor.contains(node);\n }\n\n matches(element: Element, selector: string): boolean {\n return typeof element.matches === 'function' && element.matches(selector);\n }\n\n isElement(node: Node): node is Element {\n return node.nodeType === Node.ELEMENT_NODE;\n }\n\n isTextNode(node: Node): node is Text {\n return node.nodeType === Node.TEXT_NODE;\n }\n\n tagName(element: Element): string {\n return element.tagName.toLowerCase();\n }\n\n parentNode(node: Node): Node | null {\n return node.parentNode;\n }\n\n nextSibling(node: Node): Node | null {\n return node.nextSibling;\n }\n\n firstChild(node: Node): Node | null {\n return node.firstChild;\n }\n\n childNodes(node: Node): Node[] {\n return Array.from(node.childNodes);\n }\n}\n\n// `/* @__PURE__ */`: convenience singleton, unreferenced by internal runtime\n// paths. Marking construction pure lets bundlers drop it when unused instead of\n// retaining it (and the BrowserDOMAdapter class) as an import-time side effect.\nexport const browserDOMAdapter = /* @__PURE__ */ new BrowserDOMAdapter();\n","/**\n * Server-side DOM node model.\n *\n * A tiny, dependency-free tree of plain objects that mirrors just enough of the\n * browser DOM for StreetUI's renderer to build a tree on the server and\n * serialize it to an HTML string. There is NO browser global here — these are\n * ordinary classes usable in any JavaScript environment (Node, workers, tests).\n *\n * The renderer never touches these types directly; it goes through the\n * `DOMAdapter` interface, and `ServerDOMAdapter` translates adapter calls into\n * operations on this model.\n */\n\nexport type ServerNodeKind = 'element' | 'text' | 'comment' | 'fragment' | 'raw';\n\nexport interface ServerNode {\n readonly kind: ServerNodeKind;\n parent: ServerParent | null;\n}\n\nexport type ServerParent = ServerElement | ServerFragment;\n\n/** A minimal inline-style holder mirroring `element.style.setProperty`. */\nexport class ServerStyle {\n readonly declarations = new Map<string, string>();\n setProperty(name: string, value: string): void {\n this.declarations.set(name, value);\n }\n get isEmpty(): boolean {\n return this.declarations.size === 0;\n }\n toCss(): string {\n return [...this.declarations.entries()].map(([k, v]) => `${k}: ${v}`).join('; ');\n }\n}\n\nexport class ServerText implements ServerNode {\n readonly kind = 'text' as const;\n parent: ServerParent | null = null;\n data: string;\n constructor(data: string) {\n this.data = data;\n }\n}\n\nexport class ServerComment implements ServerNode {\n readonly kind = 'comment' as const;\n parent: ServerParent | null = null;\n data: string;\n constructor(data: string) {\n this.data = data;\n }\n}\n\nexport class ServerFragment implements ServerNode {\n readonly kind = 'fragment' as const;\n parent: ServerParent | null = null;\n readonly children: ServerNode[] = [];\n}\n\n/**\n * A pre-serialized, verbatim HTML fragment (v1.7 static SSR plan).\n *\n * Emitted for provably-static subtrees whose HTML the compiler-derived static\n * SSR plan already computed once. Serializing this node copies its stored\n * string directly — it allocates no ServerElement/ServerText, no attribute Map\n * and no children array for the collapsed subtree. The stored `html` is\n * produced by the exact same mount + serialize pipeline as the runtime path, so\n * the output is byte-identical (the v1.7 byte-identity gate proves this).\n *\n * This node is SSR-only: it is created solely via `ServerDOMAdapter.createRawHTML`\n * on the server render path and never appears in a browser build.\n */\nexport class ServerRawHTML implements ServerNode {\n readonly kind = 'raw' as const;\n parent: ServerParent | null = null;\n readonly html: string;\n constructor(html: string) {\n this.html = html;\n }\n}\n\nexport class ServerElement implements ServerNode {\n readonly kind = 'element' as const;\n parent: ServerParent | null = null;\n readonly tagName: string;\n readonly attributes = new Map<string, string>();\n readonly children: ServerNode[] = [];\n\n // Lazily-allocated stores. On the 10k-row SSR corpus ~0% of elements carry JS\n // properties or inline styles (measured, §5: 1 of 80,029 elements uses\n // `properties`, 0 use `style`), so eagerly allocating a `properties` Map plus\n // a `ServerStyle` (which itself holds a Map) per element wasted ~240k\n // allocations per /users render — all in the dominant mount phase. These are\n // created on first WRITE via the `properties`/`style` getters; the serializer\n // reads the raw `_properties`/`_style` fields so a READ never forces an\n // allocation. Output is byte-identical: an unset store previously serialized\n // to nothing (empty `properties.has(...)` / `style.isEmpty`), and a null store\n // is skipped the same way.\n _properties: Map<string, unknown> | null = null;\n _style: ServerStyle | null = null;\n\n constructor(tagName: string) {\n this.tagName = tagName.toLowerCase();\n }\n\n /** JS properties set via `setProperty` (e.g. input `value`, `checked`). Allocated on first access. */\n get properties(): Map<string, unknown> {\n return (this._properties ??= new Map());\n }\n\n /** Inline-style holder mirroring `element.style`. Allocated on first access. */\n get style(): ServerStyle {\n return (this._style ??= new ServerStyle());\n }\n}\n\n// ── HTML serialization ─────────────────────────────────────────────────────────\n\n/**\n * HTML \"void\" elements — self-closing, never given a closing tag or children.\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n]);\n\n/**\n * Element properties that should be reflected into the serialized HTML so the\n * hydrated DOM carries the same initial state. `value`/`checked` matter for\n * form controls whose live state is a JS property, not an attribute.\n */\nconst SERIALIZED_PROPERTIES: Record<string, 'attr' | 'boolean'> = {\n value: 'attr',\n checked: 'boolean',\n selected: 'boolean',\n};\n\n/**\n * Precomputed `[name, kind]` pairs of SERIALIZED_PROPERTIES. Hoisted to module\n * scope so `serializeAttributes` does not allocate a fresh entries array for\n * every element serialized (measured hot: ~80k elements on the 10k-row route).\n */\nconst SERIALIZED_PROPERTY_ENTRIES: ReadonlyArray<readonly [string, 'attr' | 'boolean']> =\n Object.entries(SERIALIZED_PROPERTIES) as Array<[string, 'attr' | 'boolean']>;\n\n// Fast-path escaping. The chained `.replace(/…/g, …)` form makes 3–4 full\n// passes and allocates an intermediate string per pass even when nothing needs\n// escaping. These variants scan once and, in the overwhelmingly common case of\n// no special character, return the input unchanged (zero allocation). Output is\n// byte-identical to the chained form (verified over the real SSR corpus).\nconst TEXT_SPECIAL = /[&<>]/;\nconst ATTR_SPECIAL = /[&<>\"]/;\n\n/** Escape text node content. */\nexport function escapeHtmlText(value: string): string {\n if (!TEXT_SPECIAL.test(value)) return value;\n let out = '';\n let last = 0;\n for (let i = 0; i < value.length; i++) {\n let esc: string;\n switch (value.charCodeAt(i)) {\n case 38: esc = '&amp;'; break; // &\n case 60: esc = '&lt;'; break; // <\n case 62: esc = '&gt;'; break; // >\n default: continue;\n }\n out += value.slice(last, i) + esc;\n last = i + 1;\n }\n return out + value.slice(last);\n}\n\n/** Escape a double-quoted attribute value. */\nexport function escapeHtmlAttr(value: string): string {\n if (!ATTR_SPECIAL.test(value)) return value;\n let out = '';\n let last = 0;\n for (let i = 0; i < value.length; i++) {\n let esc: string;\n switch (value.charCodeAt(i)) {\n case 38: esc = '&amp;'; break; // &\n case 60: esc = '&lt;'; break; // <\n case 62: esc = '&gt;'; break; // >\n case 34: esc = '&quot;'; break; // \"\n default: continue;\n }\n out += value.slice(last, i) + esc;\n last = i + 1;\n }\n return out + value.slice(last);\n}\n\nfunction serializeAttributes(el: ServerElement): string {\n const parts: string[] = [];\n\n for (const [name, value] of el.attributes) {\n if (value === '') {\n parts.push(` ${name}`);\n } else {\n parts.push(` ${name}=\"${escapeHtmlAttr(value)}\"`);\n }\n }\n\n // Read the raw backing field (may be null): most elements have no JS\n // properties, so skipping the whole loop avoids touching a store that was\n // never allocated (§5).\n const props = el._properties;\n if (props !== null) {\n for (const [name, kind] of SERIALIZED_PROPERTY_ENTRIES) {\n if (!props.has(name)) continue;\n if (el.attributes.has(name)) continue; // an explicit attribute already won\n const raw = props.get(name);\n if (kind === 'boolean') {\n if (raw === true) parts.push(` ${name}`);\n } else {\n if (raw !== undefined && raw !== null) {\n parts.push(` ${name}=\"${escapeHtmlAttr(String(raw))}\"`);\n }\n }\n }\n }\n\n const style = el._style;\n if (style !== null && !style.isEmpty && !el.attributes.has('style')) {\n parts.push(` style=\"${escapeHtmlAttr(style.toCss())}\"`);\n }\n\n return parts.join('');\n}\n\n/** Serialize a single server node (element/text/comment/fragment/raw) to HTML. */\nexport function serializeServerNode(node: ServerNode): string {\n switch (node.kind) {\n case 'text':\n return escapeHtmlText((node as ServerText).data);\n case 'comment':\n return `<!--${(node as ServerComment).data}-->`;\n case 'fragment':\n return serializeChildren(node as ServerFragment);\n case 'raw':\n // Verbatim: the string was produced by this same serializer for a static\n // subtree, so it is already correctly escaped. Copy it as-is (§8).\n return (node as ServerRawHTML).html;\n case 'element': {\n const el = node as ServerElement;\n const tag = el.tagName;\n const attrs = serializeAttributes(el);\n if (VOID_ELEMENTS.has(tag)) {\n return `<${tag}${attrs}>`;\n }\n return `<${tag}${attrs}>${serializeChildren(el)}</${tag}>`;\n }\n }\n}\n\n/** Serialize the children of an element or fragment (its \"inner HTML\"). */\nexport function serializeChildren(node: ServerElement | ServerFragment): string {\n let out = '';\n for (const child of node.children) {\n out += serializeServerNode(child);\n }\n return out;\n}\n","/**\n * Server implementation of `DOMAdapter`.\n *\n * Builds a lightweight in-memory tree (see `server-node.ts`) instead of touching\n * a real browser DOM, then lets the caller serialize it to an HTML string. It is\n * completely free of browser globals, so the exact same renderer that runs in\n * the browser can produce HTML on the server.\n *\n * The `DOMAdapter` interface is typed against the lib DOM types (`Element`,\n * `Node`, `Text`, …). Our server nodes structurally stand in for those at\n * runtime, so the boundary uses `as unknown as` casts in one place. Everything\n * inside operates on the real server-node model.\n */\n\nimport type { DOMAdapter } from './adapter.js';\nimport {\n ServerElement,\n ServerText,\n ServerComment,\n ServerFragment,\n ServerRawHTML,\n serializeChildren,\n serializeServerNode,\n type ServerNode,\n type ServerParent,\n} from './server-node.js';\n\nfunction asServer(node: unknown): ServerNode {\n return node as unknown as ServerNode;\n}\nfunction asParent(node: unknown): ServerParent {\n return node as unknown as ServerParent;\n}\n\nexport class ServerDOMAdapter implements DOMAdapter {\n createElement(tag: string, _ns?: string): Element {\n return new ServerElement(tag) as unknown as Element;\n }\n\n createTextNode(data: string): Text {\n return new ServerText(data) as unknown as Text;\n }\n\n createComment(data: string): Comment {\n return new ServerComment(data) as unknown as Comment;\n }\n\n createFragment(): DocumentFragment {\n return new ServerFragment() as unknown as DocumentFragment;\n }\n\n /**\n * Create a verbatim pre-serialized HTML node (v1.7 static SSR plan, §6).\n * Server-only: the browser adapter does not implement this, and the renderer\n * fast path only invokes it when a static SSR plan is present (SSR). The\n * stored HTML was produced by this same serializer, so it is emitted as-is.\n */\n createRawHTML(html: string): Node {\n return new ServerRawHTML(html) as unknown as Node;\n }\n\n appendChild(parent: Node, child: Node): void {\n const p = asParent(parent);\n const c = asServer(child);\n this._detach(c);\n c.parent = p;\n p.children.push(c);\n }\n\n insertBefore(parent: Node, child: Node, reference: Node | null): void {\n const p = asParent(parent);\n const c = asServer(child);\n this._detach(c);\n c.parent = p;\n if (reference === null) {\n p.children.push(c);\n return;\n }\n const ref = asServer(reference);\n const idx = p.children.indexOf(ref);\n if (idx === -1) p.children.push(c);\n else p.children.splice(idx, 0, c);\n }\n\n removeChild(parent: Node, child: Node): void {\n const p = asParent(parent);\n const c = asServer(child);\n const idx = p.children.indexOf(c);\n if (idx !== -1) {\n p.children.splice(idx, 1);\n c.parent = null;\n }\n }\n\n replaceChild(parent: Node, newChild: Node, oldChild: Node): void {\n const p = asParent(parent);\n const nc = asServer(newChild);\n const oc = asServer(oldChild);\n const idx = p.children.indexOf(oc);\n if (idx === -1) return;\n this._detach(nc);\n nc.parent = p;\n p.children.splice(idx, 1, nc);\n oc.parent = null;\n }\n\n private _detach(node: ServerNode): void {\n if (node.parent !== null) {\n const siblings = node.parent.children;\n const idx = siblings.indexOf(node);\n if (idx !== -1) siblings.splice(idx, 1);\n node.parent = null;\n }\n }\n\n setAttribute(element: Element, name: string, value: string): void {\n (element as unknown as ServerElement).attributes.set(name, value);\n }\n\n removeAttribute(element: Element, name: string): void {\n (element as unknown as ServerElement).attributes.delete(name);\n }\n\n getAttribute(element: Element, name: string): string | null {\n return (element as unknown as ServerElement).attributes.get(name) ?? null;\n }\n\n setProperty(element: Element, name: string, value: unknown): void {\n (element as unknown as ServerElement).properties.set(name, value);\n }\n\n setTextContent(node: Node, text: string): void {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n const el = n as ServerElement | ServerFragment;\n el.children.length = 0;\n const t = new ServerText(text);\n t.parent = el;\n el.children.push(t);\n } else if (n.kind === 'text') {\n (n as ServerText).data = text;\n }\n }\n\n getTextContent(node: Node): string | null {\n const n = asServer(node);\n if (n.kind === 'text') return (n as ServerText).data;\n if (n.kind === 'element' || n.kind === 'fragment') {\n let out = '';\n for (const c of (n as ServerElement | ServerFragment).children) {\n out += this.getTextContent(c as unknown as Node) ?? '';\n }\n return out;\n }\n return null;\n }\n\n // Server nodes never dispatch events — listeners are a no-op on the server.\n addEventListener(): void {\n /* no-op on the server */\n }\n removeEventListener(): void {\n /* no-op on the server */\n }\n\n querySelector(): Element | null {\n return null;\n }\n querySelectorAll(): NodeListOf<Element> {\n return [] as unknown as NodeListOf<Element>;\n }\n getElementById(): Element | null {\n return null;\n }\n\n focus(): void {\n // No focus concept on the server — intentional no-op (SSR-safe).\n }\n\n body(): Element | null {\n // No document on the server — portals degrade to inline rendering.\n return null;\n }\n\n head(): Element | null {\n // No document on the server — head metadata is emitted as a string by\n // `renderHead()` instead of being applied to a live document.head.\n return null;\n }\n\n activeElement(): Element | null {\n return null;\n }\n\n contains(_ancestor: Element, _node: Node): boolean {\n return false;\n }\n\n matches(_element: Element, _selector: string): boolean {\n return false;\n }\n\n isElement(node: Node): node is Element {\n return asServer(node).kind === 'element';\n }\n\n isTextNode(node: Node): node is Text {\n return asServer(node).kind === 'text';\n }\n\n tagName(element: Element): string {\n return (element as unknown as ServerElement).tagName;\n }\n\n parentNode(node: Node): Node | null {\n return (asServer(node).parent as unknown as Node | null) ?? null;\n }\n\n nextSibling(node: Node): Node | null {\n const n = asServer(node);\n const parent = n.parent;\n if (parent === null) return null;\n const idx = parent.children.indexOf(n);\n if (idx === -1 || idx + 1 >= parent.children.length) return null;\n return parent.children[idx + 1] as unknown as Node;\n }\n\n firstChild(node: Node): Node | null {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n const el = n as ServerElement | ServerFragment;\n return (el.children[0] as unknown as Node) ?? null;\n }\n return null;\n }\n\n childNodes(node: Node): Node[] {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n return (n as ServerElement | ServerFragment).children as unknown as Node[];\n }\n return [];\n }\n\n // ── Server-only ────────────────────────────────────────────────────────────\n\n /** Serialize a node's children (\"inner HTML\") to an HTML string. */\n serializeInner(node: Node): string {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n return serializeChildren(n as ServerElement | ServerFragment);\n }\n return '';\n }\n\n /** Serialize a node (including itself) to an HTML string. */\n serializeOuter(node: Node): string {\n return serializeServerNode(asServer(node));\n }\n}\n\n// `/* @__PURE__ */`: this singleton is a convenience export only (no internal\n// runtime path references it). Marking construction pure lets bundlers drop it —\n// and with it the whole server serializer chain (serializeServerNode/escape/\n// VOID_ELEMENTS) — out of client bundles that never import SSR. Without this,\n// the un-annotated `new` is treated as a side effect and retained everywhere.\nexport const serverDOMAdapter = /* @__PURE__ */ new ServerDOMAdapter();\n","/**\n * Focus helpers built on the {@link DOMAdapter} abstraction.\n *\n * These are the minimal, genuinely-useful focus operations an app needs:\n * focus a specific element (e.g. the first field when a route or modal opens)\n * or focus the first focusable element inside a container (e.g. move focus\n * into a dialog). Both go through the adapter, so they are no-ops on the server\n * (`ServerDOMAdapter.querySelector` returns null / `focus` does nothing) and\n * therefore safe to call from universal code.\n */\n\nimport type { DOMAdapter } from './adapter.js';\n\n/** Default selector for natively focusable / tabbable elements. */\nexport const FOCUSABLE_SELECTOR =\n 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Focus the element with the given id, scoped to `root`.\n * Returns true if an element was found and focused.\n */\nexport function focusById(dom: DOMAdapter, root: Element | Document, id: string): boolean {\n const el = dom.querySelector(root, `[id=\"${id}\"]`);\n if (el === null) return false;\n dom.focus(el);\n return true;\n}\n\n/**\n * Focus the first focusable element inside `container`.\n * Returns true if a focusable element was found and focused.\n */\nexport function focusFirst(\n dom: DOMAdapter,\n container: Element | Document,\n selector: string = FOCUSABLE_SELECTOR,\n): boolean {\n const el = dom.querySelector(container, selector);\n if (el === null) return false;\n dom.focus(el);\n return true;\n}\n\n/**\n * Ordered list of focusable/tabbable descendants of `container`.\n * Re-checks each candidate against the selector so elements disabled after the\n * initial query (e.g. a button toggled to `disabled`) are excluded.\n */\nexport function getFocusable(\n dom: DOMAdapter,\n container: Element,\n selector: string = FOCUSABLE_SELECTOR,\n): Element[] {\n return Array.from(dom.querySelectorAll(container, selector)).filter((el) =>\n dom.matches(el, selector),\n );\n}\n\n/**\n * Capture the currently-focused element so it can be restored later (e.g. when\n * a dialog closes). Returns null on the server or when nothing is focused.\n */\nexport function saveFocus(dom: DOMAdapter): Element | null {\n return dom.activeElement();\n}\n\n/** Restore focus to a previously {@link saveFocus}-d element. No-op if null. */\nexport function restoreFocus(dom: DOMAdapter, saved: Element | null): void {\n if (saved !== null) dom.focus(saved);\n}\n\n/**\n * Move focus into `container` on open: the element with id `initialFocusId` if\n * given and present, otherwise the first focusable element. Server-safe no-op.\n */\nexport function focusInitial(\n dom: DOMAdapter,\n container: Element,\n initialFocusId?: string,\n): void {\n if (initialFocusId !== undefined && focusById(dom, container, initialFocusId)) return;\n focusFirst(dom, container);\n}\n\n/**\n * Trap Tab / Shift+Tab focus within `container` (wrap-around at both ends).\n * Attaches a keydown listener to the container and returns a cleanup function\n * that detaches it. Server-safe: `addEventListener` is a no-op, and the returned\n * cleanup is still callable.\n */\nexport function trapFocus(dom: DOMAdapter, container: Element): () => void {\n const onKeydown = ((event: KeyboardEvent): void => {\n if (event.key !== 'Tab') return;\n const items = getFocusable(dom, container);\n if (items.length === 0) {\n event.preventDefault();\n return;\n }\n const first = items[0]!;\n const last = items[items.length - 1]!;\n const active = dom.activeElement();\n if (active === null || !dom.contains(container, active)) {\n event.preventDefault();\n dom.focus(first);\n } else if (event.shiftKey && active === first) {\n event.preventDefault();\n dom.focus(last);\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n dom.focus(first);\n }\n }) as EventListener;\n dom.addEventListener(container, 'keydown', onKeydown);\n return () => dom.removeEventListener(container, 'keydown', onKeydown);\n}\n\n/**\n * Modal containment: if focus moves to an element outside `container`, redirect\n * it back inside. Listens on the document body (focusin bubbles there) and\n * returns a cleanup function. Server-safe no-op (body() is null).\n *\n * Nested modals (§16): every active containment pushes its container onto a\n * module-level stack, and a handler only redirects while ITS container is the\n * top of the stack — i.e. the most recently opened modal. This is the framework's\n * minimal \"focus owner\" concept: because overlay panels are relocated to\n * body-level portals (siblings, not descendants), two overlapping `containFocus`\n * handlers would otherwise fight over every `focusin`. The stack makes exactly\n * one owner authoritative at a time; cleanup pops it so the previous modal\n * resumes ownership. State is internal and torn down on cleanup — nothing is\n * retained on the graph (§18).\n */\nconst containmentStack: Element[] = [];\n\nexport function containFocus(dom: DOMAdapter, container: Element): () => void {\n const body = dom.body();\n if (body === null) return () => {};\n containmentStack.push(container);\n const onFocusIn = ((event: FocusEvent): void => {\n // Only the topmost owner enforces containment (nested-modal correctness).\n if (containmentStack[containmentStack.length - 1] !== container) return;\n const target = event.target as Node | null;\n if (target !== null && !dom.contains(container, target)) {\n focusFirst(dom, container);\n }\n }) as EventListener;\n dom.addEventListener(body, 'focusin', onFocusIn);\n return () => {\n dom.removeEventListener(body, 'focusin', onFocusIn);\n const index = containmentStack.lastIndexOf(container);\n if (index !== -1) containmentStack.splice(index, 1);\n };\n}\n\n/**\n * Invoke `handler` when Escape is pressed while focus is within `target`.\n * Returns a cleanup function. Server-safe no-op.\n */\nexport function onEscape(dom: DOMAdapter, target: Element, handler: () => void): () => void {\n const onKeydown = ((event: KeyboardEvent): void => {\n if (event.key === 'Escape') handler();\n }) as EventListener;\n dom.addEventListener(target, 'keydown', onKeydown);\n return () => dom.removeEventListener(target, 'keydown', onKeydown);\n}\n\n/**\n * Roving-focus keyboard navigation for a menu (role=\"menu\") container: the\n * arrow keys move focus between the container's focusable items (wrap-around at\n * both ends), Home/End jump to the first/last item, and Enter/Space activate\n * the currently-focused item (a native `click`, so an item's `onClick` fires).\n * `Tab` and `Escape` are deliberately left alone — the overlay layer wires\n * Escape-to-close separately and a menu does not trap Tab.\n *\n * Items are re-queried on every key (via {@link getFocusable}) so a menu whose\n * items change reactively is always navigated against the live set, and items\n * disabled after mount are skipped. Attaches a keydown listener to the\n * container and returns a cleanup function. Server-safe: `addEventListener` is\n * a no-op and the returned cleanup is still callable.\n */\nexport function rovingMenu(\n dom: DOMAdapter,\n container: Element,\n selector: string = FOCUSABLE_SELECTOR,\n): () => void {\n const onKeydown = ((event: KeyboardEvent): void => {\n const key = event.key;\n const isActivate = key === 'Enter' || key === ' ' || key === 'Spacebar';\n const isMove =\n key === 'ArrowDown' || key === 'ArrowUp' || key === 'Home' || key === 'End';\n if (!isActivate && !isMove) return;\n\n const items = getFocusable(dom, container, selector);\n if (items.length === 0) return;\n const active = dom.activeElement();\n const index = active === null ? -1 : items.indexOf(active);\n\n if (isActivate) {\n // Activating a menu item only makes sense when one is focused; otherwise\n // let the event fall through unchanged.\n if (index < 0) return;\n event.preventDefault();\n (items[index] as unknown as { click?: () => void }).click?.();\n return;\n }\n\n event.preventDefault();\n let next: number;\n if (key === 'Home') next = 0;\n else if (key === 'End') next = items.length - 1;\n else if (key === 'ArrowDown') next = index < 0 ? 0 : (index + 1) % items.length;\n else next = index <= 0 ? items.length - 1 : index - 1; // ArrowUp\n dom.focus(items[next]!);\n }) as EventListener;\n dom.addEventListener(container, 'keydown', onKeydown);\n return () => dom.removeEventListener(container, 'keydown', onKeydown);\n}\n\n","/**\n * RenderContext — shared state for a single mount operation.\n *\n * Passed through the render pipeline so every sub-function has access\n * to the DOM adapter, graph, and instance map without prop-drilling.\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport type { NodeInstance } from './node-instance.js';\nimport type { HydrationDiagnosticSink } from './hydration-diagnostics.js';\nimport type { HeadManager } from './head.js';\n\nexport interface RenderContext {\n readonly dom: DOMAdapter;\n readonly graph: ApplicationGraph;\n /** Maps GraphNode.id → its live NodeInstance */\n readonly instances: Map<string, NodeInstance>;\n /** The root container element. */\n readonly container: Element;\n /**\n * Optional dev-only sink that observes hydration mismatch repairs. When\n * absent (the default) the hydration path does no extra work — this is how\n * DevTools/diagnostics stay off the production runtime path.\n */\n readonly hydrationDiagnostics?: HydrationDiagnosticSink;\n /**\n * Optional SSR-only static-subtree plan (v1.7). Maps a maximal\n * static-subtree root GraphNode.id → its precomputed, verbatim HTML string.\n * Present only on the server render path when a plan has been built; on the\n * browser mount path it is always `undefined`, so the client hot path is\n * unaffected (a single `=== undefined` check short-circuits). When a mounted\n * node's id is in this map, the renderer emits the precomputed HTML via\n * `dom.createRawHTML` instead of recursively constructing the subtree.\n */\n readonly staticHTML?: ReadonlyMap<string, string>;\n /**\n * Lazily-created coordinator for `head()` metadata nodes (2.0 §1). Created on\n * first `wireHeadBehavior` call on the browser (never on the server, where\n * `dom.head()` is null and `renderHead` emits the metadata instead). Mutable\n * because it is attached on demand; a render with no `head()` nodes never\n * allocates one.\n */\n head?: HeadManager;\n}\n\nexport function createRenderContext(\n dom: DOMAdapter,\n graph: ApplicationGraph,\n container: Element,\n hydrationDiagnostics?: HydrationDiagnosticSink,\n staticHTML?: ReadonlyMap<string, string>,\n): RenderContext {\n return {\n dom,\n graph,\n instances: new Map(),\n container,\n ...(hydrationDiagnostics !== undefined ? { hydrationDiagnostics } : {}),\n ...(staticHTML !== undefined ? { staticHTML } : {}),\n };\n}\n","/**\n * NodeInstance — the renderer's live counterpart to a GraphNode.\n *\n * Tracks the actual DOM node(s), all signal subscriptions that drive\n * targeted DOM updates, and DOM event listener teardowns.\n */\n\nimport { CleanupRegistry } from '@streetui/core';\nimport type { GraphNode } from '@streetui/graph';\nimport type { ReadonlySignal } from '@streetui/state';\n\nexport class NodeInstance {\n readonly graphNode: GraphNode;\n /** The primary DOM node for this instance (element or text node). */\n domNode: Node;\n readonly children: NodeInstance[] = [];\n readonly cleanup: CleanupRegistry = new CleanupRegistry();\n\n constructor(graphNode: GraphNode, domNode: Node) {\n this.graphNode = graphNode;\n this.domNode = domNode;\n }\n\n addChild(child: NodeInstance): void {\n this.children.push(child);\n }\n\n /** Subscribe to a signal; auto-cleanup on unmount. */\n trackSignal<T>(sig: ReadonlySignal<T>, handler: (v: T) => void): void {\n const unsub = sig.subscribe(handler);\n this.cleanup.add(unsub);\n }\n\n /** Register a raw cleanup fn (DOM event removal, etc.). */\n trackCleanup(fn: () => void): void {\n this.cleanup.add(fn);\n }\n\n dispose(): void {\n for (const child of this.children) {\n child.dispose();\n }\n this.cleanup.run();\n }\n}\n","/**\n * Attribute and property application helpers.\n *\n * Decides whether a prop should be set as a DOM attribute or a JS property,\n * handling special cases (boolean attrs, event-like props, style, class).\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\n\n// Properties that must be set as JS object properties, not HTML attributes\nconst DOM_PROPERTIES = new Set([\n 'value', 'checked', 'selected', 'indeterminate',\n 'innerHTML', 'textContent', 'innerText',\n 'scrollTop', 'scrollLeft',\n]);\n\n// Boolean attributes — present means true, absent means false\nconst BOOLEAN_ATTRS = new Set([\n 'disabled', 'readonly', 'required', 'checked', 'selected',\n 'multiple', 'autofocus', 'autoplay', 'controls', 'default',\n 'defer', 'formnovalidate', 'hidden', 'ismap', 'loop',\n 'novalidate', 'open', 'reversed', 'scoped', 'seamless',\n]);\n\nexport function applyProp(\n dom: DOMAdapter,\n element: Element,\n name: string,\n value: unknown,\n): void {\n // Skip internal renderer metadata\n if (name.startsWith('_')) return;\n // Skip event handlers (handled separately)\n if (name.startsWith('on')) return;\n\n if (DOM_PROPERTIES.has(name)) {\n dom.setProperty(element, name, value);\n return;\n }\n\n if (BOOLEAN_ATTRS.has(name)) {\n if (value === true || value === '' || value === name) {\n dom.setAttribute(element, name, '');\n } else {\n dom.removeAttribute(element, name);\n }\n return;\n }\n\n if (name === 'class' || name === 'className') {\n dom.setAttribute(element, 'class', String(value ?? ''));\n return;\n }\n\n if (name === 'style' && typeof value === 'object' && value !== null) {\n const el = element as HTMLElement;\n const styles = value as Record<string, string>;\n for (const [k, v] of Object.entries(styles)) {\n el.style.setProperty(k, v);\n }\n return;\n }\n\n if (value === null || value === undefined || value === false) {\n dom.removeAttribute(element, name);\n return;\n }\n\n dom.setAttribute(element, name, String(value));\n}\n\nexport function patchProp(\n dom: DOMAdapter,\n element: Element,\n name: string,\n oldValue: unknown,\n newValue: unknown,\n): void {\n if (Object.is(oldValue, newValue)) return;\n applyProp(dom, element, name, newValue);\n}\n","/**\n * Event wiring for the renderer.\n *\n * Given a GraphNode with event descriptors, this wires DOM listeners\n * that call the handlers stored in the graph's handler registry.\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport type { NodeInstance } from './node-instance.js';\n\nexport function wireEvents(\n dom: DOMAdapter,\n graph: ApplicationGraph,\n node: GraphNode,\n element: Element,\n instance: NodeInstance,\n): void {\n // Fast exit for event-free nodes — avoids allocating a for-of iterator over\n // an empty array on every node during a large mount/hydrate.\n if (node.events.length === 0) return;\n for (const eventDesc of node.events) {\n const handler = graph.getHandler(eventDesc.handlerKey);\n if (handler === undefined) continue;\n\n const domListener: EventListener = (domEvent: Event) => {\n // For input events, pass the current value as first arg\n if (eventDesc.type === 'input' || eventDesc.type === 'change') {\n const input = domEvent.target as HTMLInputElement;\n (handler as (v: string) => void)(input.value);\n } else if (eventDesc.type === 'submit') {\n domEvent.preventDefault();\n (handler as (e: Event) => void)(domEvent);\n } else {\n (handler as () => void)();\n }\n };\n\n dom.addEventListener(element, eventDesc.type, domListener);\n instance.trackCleanup(() => {\n dom.removeEventListener(element, eventDesc.type, domListener);\n });\n }\n}\n","/**\n * Maps semantic node types to HTML tag names.\n */\n\nimport type { SemanticNodeType } from '@streetui/core';\n\nconst TAG_MAP: Partial<Record<SemanticNodeType, string>> = {\n application: 'div',\n page: 'div',\n section: 'section',\n container: 'div',\n heading: 'h1',\n text: 'span',\n button: 'button',\n input: 'input',\n form: 'form',\n list: 'ul',\n 'list-item': 'li',\n image: 'img',\n link: 'a',\n component: 'div',\n slot: 'div',\n fragment: 'div',\n 'reactive-list': 'ul',\n // A portal renders as a neutral inline anchor <div> at its declaration site;\n // its children are relocated to a document.body container on the browser\n // (see the portal branch in mount.ts). On the server (no body) it renders\n // inline, so the anchor tag is what SSR/hydration positionally match on.\n portal: 'div',\n // A `head()` node renders as a neutral, empty inline anchor <div> at its\n // declaration site (like a portal anchor). Its actual contribution — title/\n // meta/link/etc. — is applied to `document.head` by `wireHeadBehavior` on the\n // browser, and emitted separately by `renderHead()` on the server. Keeping a\n // one-node/one-element anchor preserves positional hydration.\n head: 'div',\n};\n\nexport function resolveTag(type: SemanticNodeType): string {\n return TAG_MAP[type] ?? 'div';\n}\n","/**\n * Patch — targeted DOM updates driven by signal changes.\n *\n * When a signal fires, we look up the NodeInstance and apply\n * only the changed prop — no full re-render, no tree diffing.\n */\n\nimport type { RenderContext } from './render-context.js';\nimport type { GraphNode } from '@streetui/graph';\nimport { applyProp, patchProp } from './attributes.js';\n\nexport function patchNode(\n ctx: RenderContext,\n graphNode: GraphNode,\n propKey: string,\n newValue: unknown,\n): void {\n const instance = ctx.instances.get(graphNode.id);\n if (instance === undefined) return;\n\n const domNode = instance.domNode;\n if (!ctx.dom.isElement(domNode)) return;\n\n const oldValue = graphNode.getProp(propKey);\n\n switch (propKey) {\n case 'text':\n if (!Object.is(oldValue, newValue)) {\n ctx.dom.setTextContent(domNode, String(newValue ?? ''));\n graphNode.setProp('text', String(newValue ?? ''));\n }\n break;\n case 'label':\n if (!Object.is(oldValue, newValue)) {\n ctx.dom.setTextContent(domNode, String(newValue ?? ''));\n graphNode.setProp('label', String(newValue ?? ''));\n }\n break;\n case 'disabled':\n if (newValue === true) {\n ctx.dom.setAttribute(domNode, 'disabled', '');\n } else {\n ctx.dom.removeAttribute(domNode, 'disabled');\n }\n graphNode.setProp('disabled', Boolean(newValue));\n break;\n case 'value':\n if (!Object.is(oldValue, newValue)) {\n ctx.dom.setProperty(domNode, 'value', String(newValue ?? ''));\n graphNode.setProp('value', String(newValue ?? ''));\n }\n break;\n default:\n patchProp(ctx.dom, domNode, propKey, oldValue, newValue);\n graphNode.setProp(propKey, newValue as string);\n break;\n }\n}\n","/**\n * Reconciliation — diff-based child list updates.\n *\n * When the children of a node change (e.g. a list driven by state),\n * this reconciler:\n * 1. Matches old instances to new graph nodes by key\n * 2. Reuses matched instances (updates their props)\n * 3. Applies a targeted content update to a reused item whose data changed\n * 4. Creates new instances for additions\n * 5. Removes stale instances (and prunes their handler registrations)\n * 6. Moves DOM nodes to match new order\n *\n * This is keyed reconciliation over the semantic graph — there is no virtual\n * DOM. A reused item keeps its own DOM element; only its changed content is\n * updated in place (falling back to remounting a subtree only where its shape\n * actually changed).\n */\n\nimport type { RenderContext } from './render-context.js';\nimport type { GraphNode } from '@streetui/graph';\nimport type { NodeInstance } from './node-instance.js';\nimport type { TransitionHooks } from './transition.js';\nimport { patchNode } from './patch.js';\n\nexport type MountFn = (node: GraphNode, parent: Element) => NodeInstance;\n\nexport interface ReconcileResult {\n /** Instances in the new order. */\n instances: NodeInstance[];\n /** Instances that were removed and must be disposed. */\n removed: NodeInstance[];\n /**\n * GraphNodes freshly materialised during this reconcile (new rows + rebuilt\n * changed rows). The caller detaches any of these that were not adopted as a\n * live instance's graph node, so no orphan subtree lingers in the graph index.\n */\n built?: GraphNode[];\n}\n\n/**\n * A lazy reconciliation descriptor for one reactive-list row (mirrors the DSL's\n * `ListPlanEntry`). `sig()` and `build()` are only invoked for rows that are\n * genuinely new or whose source reference changed — the whole point of the\n * plan path (spec §15).\n */\nexport interface PlanEntry {\n readonly key: string;\n readonly item: unknown;\n readonly sig: () => string;\n readonly build: () => GraphNode;\n}\n\n/**\n * Reconcile children of a container element against a new list of graph nodes.\n *\n * @param ctx Render context\n * @param parentDom The DOM parent element\n * @param oldInstances Current child instances (in order)\n * @param newNodes New graph children (in desired order)\n * @param mountFn Factory to create a new NodeInstance for a graph node\n */\nexport function reconcileChildren(\n ctx: RenderContext,\n parentDom: Element,\n oldInstances: NodeInstance[],\n newNodes: readonly GraphNode[],\n mountFn: MountFn,\n hooks?: TransitionHooks,\n): ReconcileResult {\n // Build key → old instance map\n const oldByKey = new Map<string, NodeInstance>();\n for (const inst of oldInstances) {\n const key = inst.graphNode.key ?? inst.graphNode.id;\n oldByKey.set(key, inst);\n }\n\n const newInstances: NodeInstance[] = [];\n const usedKeys = new Set<string>();\n\n for (const newNode of newNodes) {\n const key = newNode.key ?? newNode.id;\n const existing = oldByKey.get(key);\n\n if (existing !== undefined) {\n // Reuse — identity is stable, so the DOM element is preserved.\n usedKeys.add(key);\n const oldSig = existing.graphNode.getProp('_sig');\n const newSig = newNode.getProp('_sig');\n patchExistingInstance(ctx, existing, newNode);\n // Data changed but identity did not → targeted content update in place.\n if (!Object.is(oldSig, newSig)) {\n reconcileItemChildren(ctx, existing, newNode, mountFn);\n }\n newInstances.push(existing);\n } else {\n // Leave→enter cancellation (§6): if this key is currently animating out,\n // reclaim its live instance instead of mounting a duplicate.\n const reclaimed = hooks?.takeLeaving(key);\n if (reclaimed !== undefined) {\n patchExistingInstance(ctx, reclaimed, newNode);\n reconcileItemChildren(ctx, reclaimed, newNode, mountFn);\n hooks?.onEnter(reclaimed);\n newInstances.push(reclaimed);\n } else {\n // New — create and mount, then play its enter animation (if any).\n const inst = mountFn(newNode, parentDom);\n hooks?.onEnter(inst);\n newInstances.push(inst);\n }\n }\n }\n\n // Determine + remove stale instances. A removed instance that carries a\n // transition has its DOM-remove + dispose deferred to leave-animation end by\n // `beginLeave` (which then also forgets + detaches it), so it is excluded from\n // `removed` and the caller does not tear it down (§3/§7).\n const removed: NodeInstance[] = [];\n for (const inst of oldInstances) {\n const key = inst.graphNode.key ?? inst.graphNode.id;\n if (usedKeys.has(key)) continue;\n if (hooks !== undefined && hooks.beginLeave(inst)) continue;\n const parent = ctx.dom.parentNode(inst.domNode);\n if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);\n inst.dispose();\n removed.push(inst);\n }\n\n // Reorder DOM nodes to match new order\n reorderDom(ctx, parentDom, newInstances);\n\n return { instances: newInstances, removed };\n}\n\n/**\n * Plan-based keyed reconciliation (spec §15 — the optimised reactive-list path).\n *\n * Identical observable result to {@link reconcileChildren}, but driven by lazy\n * {@link PlanEntry} descriptors instead of a pre-built array of GraphNodes:\n *\n * - a reused row whose `item` reference is unchanged does **zero** work — no\n * signature hash, no subtree build, no prop patch (the common case for\n * append / prepend / remove / reorder / reverse, where existing item objects\n * keep their identity);\n * - a reused row whose reference changed hashes lazily and, only on a real\n * signature change, materialises a fresh subtree for a targeted in-place\n * content update;\n * - a genuinely new key builds + mounts exactly one subtree.\n *\n * DOM reordering uses a longest-increasing-subsequence pass so the number of\n * moves is minimal (e.g. a prepend into a 10k list moves 1 node, not 10k).\n */\nexport function reconcileChildrenByPlan(\n ctx: RenderContext,\n parentDom: Element,\n oldInstances: NodeInstance[],\n plan: readonly PlanEntry[],\n mountFn: MountFn,\n hooks?: TransitionHooks,\n): ReconcileResult {\n const oldByKey = new Map<string, NodeInstance>();\n for (const inst of oldInstances) {\n oldByKey.set(inst.graphNode.key ?? inst.graphNode.id, inst);\n }\n\n const newInstances: NodeInstance[] = [];\n const usedKeys = new Set<string>();\n const built: GraphNode[] = [];\n\n for (const entry of plan) {\n const existing = oldByKey.get(entry.key);\n if (existing !== undefined) {\n usedKeys.add(entry.key);\n const oldItem = existing.graphNode.getProp('_item');\n // Identity short-circuit: same reference ⇒ data cannot have changed.\n if (!Object.is(oldItem, entry.item)) {\n const newSig = entry.sig();\n const oldSig = existing.graphNode.getProp('_sig');\n if (!Object.is(oldSig, newSig)) {\n const freshNode = entry.build();\n built.push(freshNode);\n patchExistingInstance(ctx, existing, freshNode);\n reconcileItemChildren(ctx, existing, freshNode, mountFn);\n existing.graphNode.setProp('_sig', newSig);\n }\n // Cache the new reference so the next pass can short-circuit again.\n existing.graphNode.setProp('_item', entry.item as never);\n }\n newInstances.push(existing);\n } else {\n // Leave→enter reclaim (§6/§7): a key removed then re-added mid-leave keeps\n // its identity and its live DOM node rather than mounting a duplicate.\n const reclaimed = hooks?.takeLeaving(entry.key);\n if (reclaimed !== undefined) {\n const freshNode = entry.build();\n built.push(freshNode);\n patchExistingInstance(ctx, reclaimed, freshNode);\n reconcileItemChildren(ctx, reclaimed, freshNode, mountFn);\n reclaimed.graphNode.setProp('_sig', freshNode.getProp('_sig') as never);\n reclaimed.graphNode.setProp('_item', entry.item as never);\n hooks?.onEnter(reclaimed);\n newInstances.push(reclaimed);\n } else {\n const freshNode = entry.build();\n built.push(freshNode);\n const inst = mountFn(freshNode, parentDom);\n hooks?.onEnter(inst);\n newInstances.push(inst);\n }\n }\n }\n\n // Determine + remove stale instances. Transitioned rows defer their whole\n // teardown chain to leave-animation end (§7) and are excluded from `removed`.\n const removed: NodeInstance[] = [];\n for (const inst of oldInstances) {\n const key = inst.graphNode.key ?? inst.graphNode.id;\n if (usedKeys.has(key)) continue;\n if (hooks !== undefined && hooks.beginLeave(inst)) continue;\n const parent = ctx.dom.parentNode(inst.domNode);\n if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);\n inst.dispose();\n removed.push(inst);\n }\n\n // Minimal-move reorder to the desired order.\n reorderDomMinimal(ctx, parentDom, oldInstances, newInstances);\n\n return { instances: newInstances, removed, built };\n}\n\n/**\n * Minimal-move DOM reorder.\n *\n * Reused nodes retain their previous DOM slots and newly-mounted nodes sit at\n * the end. We compute the longest increasing subsequence of the reused nodes'\n * previous positions; those are already in correct relative order and stay put.\n * Every other node is inserted before its right-hand neighbour, walking\n * right-to-left. This yields exactly (n − |LIS|) `insertBefore` calls — the\n * minimum — instead of the O(n) sweep the naive reorder performs on a prepend.\n */\nfunction reorderDomMinimal(\n ctx: RenderContext,\n parentDom: Element,\n oldInstances: NodeInstance[],\n newInstances: NodeInstance[],\n): void {\n const n = newInstances.length;\n if (n === 0) return;\n\n const oldIndexOf = new Map<NodeInstance, number>();\n for (let i = 0; i < oldInstances.length; i++) oldIndexOf.set(oldInstances[i]!, i);\n\n const source = new Array<number>(n);\n let moved = false;\n let lastSeen = -1;\n for (let i = 0; i < n; i++) {\n const oi = oldIndexOf.get(newInstances[i]!);\n if (oi === undefined) {\n source[i] = -1; // freshly mounted row\n moved = true;\n } else {\n source[i] = oi;\n if (oi < lastSeen) moved = true; // an out-of-order reused row exists\n else lastSeen = oi;\n }\n }\n\n // Fast path: nothing is out of order and there are no new rows to reposition.\n if (!moved) return;\n\n const keep = longestIncreasingSubsequence(source);\n\n let refNode: Node | null = null;\n for (let i = n - 1; i >= 0; i--) {\n const domNode = newInstances[i]!.domNode;\n if (source[i] === -1 || !keep.has(i)) {\n if (ctx.dom.nextSibling(domNode) !== refNode) {\n ctx.dom.insertBefore(parentDom, domNode, refNode);\n }\n }\n refNode = domNode;\n }\n}\n\n/**\n * Indices (into `source`) forming a longest strictly-increasing subsequence,\n * ignoring `-1` entries (new rows, which always move). O(n log n) with\n * predecessor reconstruction.\n */\nfunction longestIncreasingSubsequence(source: readonly number[]): Set<number> {\n const keep = new Set<number>();\n const n = source.length;\n const tails: number[] = []; // tails[k] = source-index of smallest tail of an LIS of length k+1\n const prev = new Array<number>(n).fill(-1);\n\n for (let i = 0; i < n; i++) {\n const v = source[i]!;\n if (v < 0) continue;\n let lo = 0;\n let hi = tails.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (source[tails[mid]!]! < v) lo = mid + 1;\n else hi = mid;\n }\n if (lo > 0) prev[i] = tails[lo - 1]!;\n tails[lo] = i;\n }\n\n let idx = tails.length > 0 ? tails[tails.length - 1]! : -1;\n while (idx >= 0) {\n keep.add(idx);\n idx = prev[idx]!;\n }\n return keep;\n}\n\n/**\n * Targeted in-place content update for a reused list item whose data changed.\n *\n * The item's DOM element is kept; only its contents are updated. Children are\n * matched positionally against the freshly-built subtree:\n * - same node type at a position → the existing child is reused and its props\n * are patched in place (e.g. a text node's text is rewritten), then we\n * recurse into its children;\n * - different type / new position → the fresh child node is reparented onto the\n * live item node and mounted;\n * - surplus old children → disposed, with DOM, subscriptions, listeners and\n * handler registrations all torn down.\n *\n * This deliberately reuses the same keyed/positional strategy rather than a\n * virtual DOM, and never destroys the item element itself.\n */\nfunction reconcileItemChildren(\n ctx: RenderContext,\n itemInstance: NodeInstance,\n newItemNode: GraphNode,\n mountFn: MountFn,\n): void {\n const el = itemInstance.domNode;\n if (!ctx.dom.isElement(el)) return;\n\n const oldChildren = [...itemInstance.children];\n const newChildNodes = [...newItemNode.children];\n const nextChildren: NodeInstance[] = [];\n const kept = new Set<NodeInstance>();\n\n for (let i = 0; i < newChildNodes.length; i++) {\n const newChild = newChildNodes[i]!;\n const oldChild = oldChildren[i];\n\n if (oldChild !== undefined && oldChild.graphNode.type === newChild.type) {\n // Reuse in place — patch this node's props and recurse into descendants.\n patchExistingInstance(ctx, oldChild, newChild);\n reconcileItemChildren(ctx, oldChild, newChild, mountFn);\n nextChildren.push(oldChild);\n kept.add(oldChild);\n } else {\n // Structural change at this position — mount the fresh child. Reparent it\n // out of the freshly-built subtree so the wholesale detach of the\n // unadopted item node (in mount.ts) does not remove this now-live node.\n itemInstance.graphNode.appendChild(newChild);\n const inst = mountFn(newChild, el);\n nextChildren.push(inst);\n }\n }\n\n // Dispose old children that were not reused (surplus or type-mismatched).\n for (const old of oldChildren) {\n if (kept.has(old)) continue;\n const parent = ctx.dom.parentNode(old.domNode);\n if (parent !== null) ctx.dom.removeChild(parent, old.domNode);\n old.dispose();\n forgetInstanceTree(ctx, old);\n ctx.graph.detachNode(old.graphNode);\n }\n\n // Restore correct DOM order within the item element.\n reorderDom(ctx, el, nextChildren);\n\n // Sync the live instance's children.\n itemInstance.children.length = 0;\n for (const c of nextChildren) itemInstance.children.push(c);\n\n // Keep the graph model's item children consistent with the reconciled order.\n for (const c of [...itemInstance.graphNode.children]) {\n itemInstance.graphNode.removeChild(c);\n }\n for (const c of nextChildren) itemInstance.graphNode.appendChild(c.graphNode);\n}\n\n/** Move a parent's DOM children to match the given instance order (minimal moves). */\nfunction reorderDom(\n ctx: RenderContext,\n parentDom: Element,\n instances: NodeInstance[],\n): void {\n let referenceNode: Node | null = null;\n for (let i = instances.length - 1; i >= 0; i--) {\n const inst = instances[i];\n if (inst === undefined) continue;\n const domNode = inst.domNode;\n const currentNext = ctx.dom.nextSibling(domNode);\n if (currentNext !== referenceNode) {\n ctx.dom.insertBefore(parentDom, domNode, referenceNode);\n }\n referenceNode = domNode;\n }\n}\n\n/** Recursively drop an instance subtree from the renderer's instance index. */\nfunction forgetInstanceTree(ctx: RenderContext, instance: NodeInstance): void {\n ctx.instances.delete(instance.graphNode.id);\n for (const child of instance.children) forgetInstanceTree(ctx, child);\n}\n\nfunction patchExistingInstance(\n ctx: RenderContext,\n instance: NodeInstance,\n newNode: GraphNode,\n): void {\n const oldNode = instance.graphNode;\n for (const [key, newVal] of Object.entries(newNode.props)) {\n const oldVal = oldNode.getProp(key);\n if (!Object.is(oldVal, newVal)) {\n patchNode(ctx, instance.graphNode, key, newVal);\n }\n }\n}\n","/**\n * CSS class-based enter/leave transition controller (§2–§8).\n *\n * This is the browser-only runtime that consumes the `__transition__<nodeId>`\n * descriptor the DSL registers (a pre-resolved {@link ResolvedTransitionLike}).\n * It is deliberately structural about that descriptor — like the renderer's\n * `__overlay__`/`__component__` handling — so the renderer takes NO compile-time\n * dependency on the DSL package.\n *\n * Engine (confirmed decision): CSS classes, no Web Animations API, no\n * browser-only API referenced at module scope. Every timer / rAF / event\n * binding is reached lazily through `globalThis` and only ever runs when\n * `dom.body() !== null` (the same SSR guard `wireOverlayBehavior` uses), so:\n * - server output is byte-identical (nothing here runs during SSR — §21);\n * - happy-dom, which dispatches no `transitionend`/`animationend`, still\n * completes deterministically via the fallback timeout (§24).\n *\n * The controller is created once per reactive container instance (reactive-list\n * or conditional) so its `leaving` map survives across reconcile passes — that\n * is what makes leave→enter reclaim (§6) and keyed-identity list leave (§7)\n * correct.\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport type { NodeInstance } from './node-instance.js';\n\n/**\n * The renderer's structural view of the resolved transition the DSL stores in\n * `__transition__<id>`. Mirrors `@streetui/dsl`'s `ResolvedTransition` without\n * importing it (no renderer→dsl dependency).\n */\nexport interface ResolvedTransitionLike {\n readonly enterActive: readonly string[];\n readonly enterFrom: readonly string[];\n readonly enterTo: readonly string[];\n readonly leaveActive: readonly string[];\n readonly leaveFrom: readonly string[];\n readonly leaveTo: readonly string[];\n readonly appear: boolean;\n readonly duration: number;\n}\n\n/**\n * Hooks handed to the reconciler so it can (a) reclaim an instance that is\n * mid-leave when its key re-enters (leave→enter cancellation), (b) defer the\n * remove/dispose/forget/detach chain for a leaving instance until its animation\n * ends, and (c) play the enter animation for a freshly-inserted instance. When\n * no transition applies (or we are on the server) every hook degrades to the\n * pre-transition synchronous behaviour.\n */\nexport interface TransitionHooks {\n /**\n * If an instance for `key` is currently animating out, cancel its leave and\n * return it for reuse; otherwise undefined. The caller re-mounts nothing and\n * reuses the returned instance's live DOM node.\n */\n takeLeaving(key: string): NodeInstance | undefined;\n /**\n * Begin a leave animation for a removed instance. Returns true when the whole\n * teardown chain has been deferred to animation-end (caller must NOT remove,\n * dispose, forget or detach it), or false when there is no transition / no\n * browser and the caller should tear it down synchronously as before.\n */\n beginLeave(inst: NodeInstance): boolean;\n /** Play the enter animation for a freshly-inserted (or reclaimed) instance. */\n onEnter(inst: NodeInstance): void;\n}\n\n/** Read the pre-resolved transition descriptor for a node, if any. */\nexport function getResolvedTransition(\n graph: ApplicationGraph,\n nodeId: string,\n): ResolvedTransitionLike | undefined {\n const fn = graph.getHandler(`__transition__${nodeId}`) as\n | (() => ResolvedTransitionLike)\n | undefined;\n return fn === undefined ? undefined : fn();\n}\n\n// ── Browser-global access (lazy, never at module scope) ──────────────────────\n\ninterface RafHost {\n requestAnimationFrame?: (cb: () => void) => number;\n setTimeout: (cb: () => void, ms: number) => unknown;\n clearTimeout: (h: unknown) => void;\n}\n\nfunction host(): RafHost {\n return globalThis as unknown as RafHost;\n}\n\n/** Schedule a callback for the next frame (falls back to a macrotask). */\nfunction nextFrame(cb: () => void): void {\n const h = host();\n const raf = h.requestAnimationFrame;\n if (typeof raf === 'function') {\n // Double rAF: ensures the \"from\" classes have been painted before we flip\n // to the \"to\" classes, so the transition actually runs in real browsers.\n raf(() => raf(cb));\n } else {\n h.setTimeout(cb, 0);\n }\n}\n\n// ── Class list manipulation via the adapter (no classList dependency) ─────────\n\nfunction splitClass(value: string | null): string[] {\n if (value === null) return [];\n const out: string[] = [];\n for (const t of value.split(/\\s+/)) if (t.length > 0) out.push(t);\n return out;\n}\n\nfunction addClasses(dom: DOMAdapter, el: Element, classes: readonly string[]): void {\n if (classes.length === 0) return;\n const current = splitClass(dom.getAttribute(el, 'class'));\n let changed = false;\n for (const c of classes) {\n if (!current.includes(c)) {\n current.push(c);\n changed = true;\n }\n }\n if (changed) dom.setAttribute(el, 'class', current.join(' '));\n}\n\nfunction removeClasses(dom: DOMAdapter, el: Element, classes: readonly string[]): void {\n if (classes.length === 0) return;\n const current = splitClass(dom.getAttribute(el, 'class'));\n const next = current.filter((c) => !classes.includes(c));\n if (next.length !== current.length) {\n if (next.length === 0) dom.removeAttribute(el, 'class');\n else dom.setAttribute(el, 'class', next.join(' '));\n }\n}\n\n/**\n * One running enter-or-leave animation on a single element. Owns exactly one set\n * of DOM listeners + one fallback timer, and guarantees `settle`/`cancel` run\n * their cleanup at most once — no stale callbacks, no duplicate listeners, no\n * duplicate cleanup (§6).\n */\ninterface Run {\n /** Force the animation to its end synchronously (used by cancellation). */\n cancel(): void;\n}\n\nfunction startRun(\n dom: DOMAdapter,\n el: Element,\n active: readonly string[],\n from: readonly string[],\n to: readonly string[],\n duration: number,\n onDone: () => void,\n): Run {\n const h = host();\n let finished = false;\n let timer: unknown = null;\n\n const onEvent = ((e: Event): void => {\n // Ignore bubbling transition/animation events from descendants.\n if (e.target !== el) return;\n finish();\n }) as EventListener;\n\n const detach = (): void => {\n dom.removeEventListener(el, 'transitionend', onEvent);\n dom.removeEventListener(el, 'animationend', onEvent);\n if (timer !== null) {\n h.clearTimeout(timer);\n timer = null;\n }\n };\n\n const finish = (): void => {\n if (finished) return;\n finished = true;\n detach();\n // Clear all transition classes so the element rests in its natural state.\n removeClasses(dom, el, active);\n removeClasses(dom, el, to);\n removeClasses(dom, el, from);\n onDone();\n };\n\n // Phase 1: apply the starting + active classes immediately.\n addClasses(dom, el, from);\n addClasses(dom, el, active);\n\n dom.addEventListener(el, 'transitionend', onEvent);\n dom.addEventListener(el, 'animationend', onEvent);\n // Fallback completion: the safety net for elements that fire no transition\n // event (and the ONLY completion signal under happy-dom, where tests set a\n // small duration). 0 → next macrotask.\n timer = h.setTimeout(finish, duration);\n\n // Phase 2: on the next frame flip from → to so the CSS transition runs.\n nextFrame(() => {\n if (finished) return;\n removeClasses(dom, el, from);\n addClasses(dom, el, to);\n });\n\n return {\n cancel: () => {\n // Cancel = settle immediately (removes classes, clears listeners/timer)\n // but WITHOUT invoking onDone, so a cancelled leave never finalizes the\n // node it was about to destroy.\n if (finished) return;\n finished = true;\n detach();\n removeClasses(dom, el, active);\n removeClasses(dom, el, to);\n removeClasses(dom, el, from);\n },\n };\n}\n\ninterface LeavingEntry {\n readonly inst: NodeInstance;\n readonly run: Run;\n}\n\n/** Which half of a transition to play on a bare element. */\nexport type TransitionPhase = 'enter' | 'leave';\n\n/**\n * Play one enter/leave transition on a bare DOM element, outside the keyed\n * reconciler — the seam the router uses for route leave/enter (§9) and any other\n * consumer that owns a single host element rather than a reactive container.\n *\n * Reuses the exact same {@link startRun} mechanics as list/conditional\n * transitions (from+active applied immediately, next-frame flip to `to`,\n * completion on transitionend/animationend or the fallback timer), so there is\n * one transition engine, not two. The returned handle's `cancel()` settles the\n * run immediately WITHOUT invoking `onDone` — the caller uses it to abort an\n * in-flight enter when the same host is about to start leaving (rapid\n * navigation), avoiding overlapping runs/duplicate listeners on one element.\n *\n * On the server (or any non-element target) there is nothing to animate, so\n * `onDone` runs synchronously and `cancel()` is a no-op — the caller's teardown\n * still happens exactly once.\n */\nexport function runElementTransition(\n dom: DOMAdapter,\n el: Element,\n rt: ResolvedTransitionLike,\n phase: TransitionPhase,\n onDone: () => void,\n): { cancel(): void } {\n if (dom.body() === null || !dom.isElement(el)) {\n onDone();\n return { cancel: () => {} };\n }\n const active = phase === 'enter' ? rt.enterActive : rt.leaveActive;\n const from = phase === 'enter' ? rt.enterFrom : rt.leaveFrom;\n const to = phase === 'enter' ? rt.enterTo : rt.leaveTo;\n return startRun(dom, el, active, from, to, rt.duration, onDone);\n}\n\n\n/**\n * Per-container transition controller. One instance is created for each\n * reactive-list / conditional NodeInstance in {@link wireReactiveList}; its\n * `leaving` map persists across every reconcile of that container.\n */\nexport class TransitionController {\n private readonly leaving = new Map<string, LeavingEntry>();\n\n constructor(\n private readonly dom: DOMAdapter,\n private readonly graph: ApplicationGraph,\n /** Full teardown of a leaving instance (remove + dispose + forget + detach). */\n private readonly finalize: (inst: NodeInstance) => void,\n ) {}\n\n /** True only in a real DOM environment (browser). */\n private get browser(): boolean {\n return this.dom.body() !== null;\n }\n\n private keyOf(inst: NodeInstance): string {\n return inst.graphNode.key ?? inst.graphNode.id;\n }\n\n private resolved(node: GraphNode): ResolvedTransitionLike | undefined {\n return getResolvedTransition(this.graph, node.id);\n }\n\n /** Run the enter animation for `inst` if it carries a transition (browser only). */\n enter(inst: NodeInstance): void {\n if (!this.browser) return;\n const rt = this.resolved(inst.graphNode);\n if (rt === undefined) return;\n const el = inst.domNode;\n if (!this.dom.isElement(el)) return;\n startRun(this.dom, el, rt.enterActive, rt.enterFrom, rt.enterTo, rt.duration, () => {\n /* enter has no teardown; classes already cleared by the run */\n });\n }\n\n /**\n * Play `appear` for any initial child that opted into it (fresh browser mount\n * only — hydration must never animate appear, §22, and this is called only on\n * the mount path).\n */\n appear(children: readonly NodeInstance[]): void {\n if (!this.browser) return;\n for (const child of children) {\n const rt = this.resolved(child.graphNode);\n if (rt !== undefined && rt.appear) this.enter(child);\n }\n }\n\n hooks(): TransitionHooks {\n return {\n takeLeaving: (key) => {\n const entry = this.leaving.get(key);\n if (entry === undefined) return undefined;\n entry.run.cancel(); // leave→enter: stop the leave, keep the live node\n this.leaving.delete(key);\n return entry.inst;\n },\n beginLeave: (inst) => {\n if (!this.browser) return false;\n const rt = this.resolved(inst.graphNode);\n if (rt === undefined) return false;\n const el = inst.domNode;\n if (!this.dom.isElement(el)) return false;\n const key = this.keyOf(inst);\n // If a prior leave for this key is somehow still running, settle it.\n const prior = this.leaving.get(key);\n if (prior !== undefined) prior.run.cancel();\n const run = startRun(\n this.dom,\n el,\n rt.leaveActive,\n rt.leaveFrom,\n rt.leaveTo,\n rt.duration,\n () => {\n // Only finalize if THIS run is still the registered one (it may have\n // been reclaimed by a re-entering key, which cancels without done).\n const current = this.leaving.get(key);\n if (current !== undefined && current.run === run) {\n this.leaving.delete(key);\n this.finalize(inst);\n }\n },\n );\n this.leaving.set(key, { inst, run });\n return true;\n },\n onEnter: (inst) => this.enter(inst),\n };\n }\n}\n","/**\n * Document head / metadata runtime (2.0 §1–§3).\n *\n * Two entry points, sharing the normalized {@link HeadEntry} model the DSL's\n * `head()` produces (mirrored here as a local structural type so the renderer\n * takes no compile-time dependency on the DSL package — the same convention as\n * the overlay/component descriptors):\n *\n * • `wireHeadBehavior(ctx, node, instance)` — BROWSER. Reads the\n * `__head__<id>` descriptor, registers this node's contribution with a\n * per-render {@link HeadManager} (created lazily on `ctx`), subscribes to any\n * reactive attr/text signals, and tracks cleanup on the NodeInstance so the\n * contribution is withdrawn (and the manager re-applies the merged result)\n * when the node unmounts or the route changes. Server-safe: when\n * `dom.head()` is null (SSR) it is a no-op.\n *\n * • `renderHead(compiled)` — SERVER. Walks the compiled graph in document\n * order, merges every live `head()` contribution (last-in-document-order\n * wins per dedup key — §3), and serializes the effective tags to an HTML\n * string for the caller to place inside `<head>`. Only the active graph is\n * walked, so only active-route metadata is emitted (§2). Each tag carries\n * `data-streetui-head` + `data-streetui-head-key=\"…\"` so the browser adopts\n * it on hydration instead of creating a duplicate.\n */\n\nimport type { GraphNode, ApplicationGraph } from '@streetui/graph';\nimport { ServerDOMAdapter } from '@streetui/dom';\nimport type { CompiledApplication } from '@streetui/compiler';\nimport type { DOMAdapter } from '@streetui/dom';\nimport type { RenderContext } from './render-context.js';\nimport type { NodeInstance } from './node-instance.js';\n\n/** The marker attribute stamped on every framework-managed head tag. */\nconst HEAD_MARKER = 'data-streetui-head';\n/** The attribute carrying a tag's dedup key, so hydration can match server tags. */\nconst HEAD_KEY = 'data-streetui-head-key';\n\n// ── Structural mirror of the DSL's head entry model ─────────────────────────────\n\ninterface HeadEntryLike {\n readonly tag: 'title' | 'meta' | 'link' | 'base';\n readonly dedupKey: string;\n readonly attrs: Readonly<Record<string, unknown>>;\n readonly text?: unknown;\n}\ninterface HeadContributionLike {\n readonly entries: readonly HeadEntryLike[];\n}\n\ninterface SignalLike {\n subscribe: (fn: (v: unknown) => void) => () => void;\n peek: () => unknown;\n}\n\nfunction isSignalLike(v: unknown): v is SignalLike {\n return (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as Record<string, unknown>)['subscribe'] === 'function' &&\n typeof (v as Record<string, unknown>)['peek'] === 'function'\n );\n}\n\n/** Read a bindable value to its current string (peeking a signal, else stringifying). */\nfunction readValue(v: unknown): string {\n if (isSignalLike(v)) return String(v.peek() ?? '');\n return String(v ?? '');\n}\n\n/** A fully-resolved head tag: concrete strings, ready to write to the DOM/serialize. */\ninterface ResolvedTag {\n readonly tag: 'title' | 'meta' | 'link' | 'base';\n readonly attrs: Record<string, string>;\n readonly text?: string;\n}\n\nfunction resolveEntry(entry: HeadEntryLike): ResolvedTag {\n const attrs: Record<string, string> = {};\n for (const key of Object.keys(entry.attrs)) {\n attrs[key] = readValue(entry.attrs[key]);\n }\n const resolved: ResolvedTag = { tag: entry.tag, attrs };\n if (entry.tag === 'title') {\n return { ...resolved, text: readValue(entry.text) };\n }\n return resolved;\n}\n\n// ── Browser head manager ────────────────────────────────────────────────────────\n\ninterface AppliedRecord {\n el: Element;\n attrKeys: Set<string>;\n tag: string;\n}\n\n/**\n * Coordinates every live `head()` node's contribution into a single\n * `document.head`. One instance per render (lazily created on `ctx`). Merges by\n * dedup key with last-in-document-order winning, and applies the minimal diff to\n * the DOM on every register/unregister/signal change. Adopts server-emitted tags\n * on the first apply so hydration produces no duplicates.\n */\nexport class HeadManager {\n private readonly _dom: DOMAdapter;\n private readonly _head: Element;\n private readonly _contributions = new Map<string, { order: number; entries: readonly HeadEntryLike[] }>();\n private readonly _applied = new Map<string, AppliedRecord>();\n private _order = 0;\n private _adopted = false;\n\n constructor(dom: DOMAdapter, head: Element) {\n this._dom = dom;\n this._head = head;\n }\n\n /** Register (or replace) a node's contribution and re-apply the merged result. */\n register(nodeId: string, entries: readonly HeadEntryLike[]): void {\n this._contributions.set(nodeId, { order: this._order++, entries });\n this.apply();\n }\n\n /** Withdraw a node's contribution (unmount / route change) and re-apply. */\n unregister(nodeId: string): void {\n if (this._contributions.delete(nodeId)) this.apply();\n }\n\n /** Recompute the merged head and patch `document.head` to match. */\n apply(): void {\n if (!this._adopted) {\n this._adoptServerTags();\n this._adopted = true;\n }\n\n // Merge: iterate contributions in document order; per dedup key the last\n // writer wins (§3). Within a contribution, later entries win too.\n const ordered = [...this._contributions.values()].sort((a, b) => a.order - b.order);\n const merged = new Map<string, ResolvedTag>();\n for (const contribution of ordered) {\n for (const entry of contribution.entries) {\n merged.set(entry.dedupKey, resolveEntry(entry));\n }\n }\n\n // Upsert desired tags.\n for (const [key, desired] of merged) {\n const existing = this._applied.get(key);\n if (existing !== undefined && existing.tag === desired.tag) {\n this._reconcileAttrs(existing, desired);\n } else {\n if (existing !== undefined) {\n // Tag kind changed for this key (rare) — drop the old element.\n this._dom.removeChild(this._head, existing.el);\n this._applied.delete(key);\n }\n const el = this._createTag(key, desired);\n this._dom.appendChild(this._head, el);\n this._applied.set(key, { el, attrKeys: new Set(Object.keys(desired.attrs)), tag: desired.tag });\n }\n }\n\n // Remove managed tags no longer desired.\n for (const [key, record] of [...this._applied]) {\n if (!merged.has(key)) {\n this._dom.removeChild(this._head, record.el);\n this._applied.delete(key);\n }\n }\n }\n\n private _createTag(key: string, desired: ResolvedTag): Element {\n const el = this._dom.createElement(desired.tag);\n this._dom.setAttribute(el, HEAD_MARKER, '');\n this._dom.setAttribute(el, HEAD_KEY, key);\n for (const attr of Object.keys(desired.attrs)) {\n this._dom.setAttribute(el, attr, desired.attrs[attr]!);\n }\n if (desired.tag === 'title') this._dom.setTextContent(el, desired.text ?? '');\n return el;\n }\n\n private _reconcileAttrs(record: AppliedRecord, desired: ResolvedTag): void {\n const nextKeys = new Set(Object.keys(desired.attrs));\n // Remove attrs that are no longer present.\n for (const attr of record.attrKeys) {\n if (!nextKeys.has(attr)) this._dom.removeAttribute(record.el, attr);\n }\n // Set/overwrite desired attrs (idempotent when unchanged — matters on the\n // hydration adopt path, where the element is a server tag being re-asserted).\n for (const attr of nextKeys) {\n this._dom.setAttribute(record.el, attr, desired.attrs[attr]!);\n }\n if (desired.tag === 'title') this._dom.setTextContent(record.el, desired.text ?? '');\n record.attrKeys = nextKeys;\n }\n\n /**\n * Seed `_applied` from server-emitted `[data-streetui-head-key]` tags already\n * in `document.head`. The subsequent diff reuses these elements when the\n * client desires the same key (no duplicate), rewrites them if the value\n * changed, or removes them if the client graph no longer wants them.\n */\n private _adoptServerTags(): void {\n for (const child of this._dom.childNodes(this._head)) {\n if (!this._dom.isElement(child)) continue;\n const el = child as Element;\n const key = this._dom.getAttribute(el, HEAD_KEY);\n if (key === null) continue;\n this._applied.set(key, {\n el,\n attrKeys: new Set(this._attrNames(el)),\n tag: this._dom.tagName(el),\n });\n }\n }\n\n /** The framework-managed attribute names currently on a server tag. */\n private _attrNames(el: Element): string[] {\n // We cannot enumerate a live element's attributes through the minimal\n // DOMAdapter surface, so we re-assert from the desired set on first apply\n // (see `_reconcileAttrs`, which sets desired keys and removes only tracked\n // ones). Tracking the marker keys is enough to keep them from lingering.\n const names: string[] = [];\n if (this._dom.getAttribute(el, HEAD_MARKER) !== null) names.push(HEAD_MARKER);\n if (this._dom.getAttribute(el, HEAD_KEY) !== null) names.push(HEAD_KEY);\n return names;\n }\n}\n\n/** Lazily get (or create) the render's HeadManager. Null on the server. */\nfunction getHeadManager(ctx: RenderContext): HeadManager | null {\n const head = ctx.dom.head();\n if (head === null) return null; // server render pass — renderHead handles SSR\n const mutable = ctx as { head?: HeadManager };\n if (mutable.head === undefined) mutable.head = new HeadManager(ctx.dom, head);\n return mutable.head;\n}\n\n/**\n * Wire a mounted/hydrated `head` node's contribution into `document.head`.\n * Server-safe (no-op when there is no document). Shared by the mount and hydrate\n * paths so both establish identical ownership + cleanup.\n */\nexport function wireHeadBehavior(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n): void {\n const manager = getHeadManager(ctx);\n if (manager === null) return;\n\n const descFn = ctx.graph.getHandler(`__head__${graphNode.id}`) as\n | (() => HeadContributionLike)\n | undefined;\n if (descFn === undefined) return;\n\n const contribution = descFn();\n const nodeId = graphNode.id;\n manager.register(nodeId, contribution.entries);\n\n // Subscribe to any reactive attr/text signals; a change re-applies the merged\n // head. All subscriptions + the contribution withdrawal are tracked on the\n // instance, so a route change / unmount tears them down and re-applies.\n for (const entry of contribution.entries) {\n for (const attrKey of Object.keys(entry.attrs)) {\n const v = entry.attrs[attrKey];\n if (isSignalLike(v)) {\n instance.trackCleanup(v.subscribe(() => manager.apply()));\n }\n }\n if (isSignalLike(entry.text)) {\n instance.trackCleanup(entry.text.subscribe(() => manager.apply()));\n }\n }\n\n instance.trackCleanup(() => manager.unregister(nodeId));\n}\n\n// ── Server-side head emission ─────────────────────────────────────────────────\n\n/**\n * Render the active graph's merged document metadata to an HTML string suitable\n * for placing inside `<head>`. Walks the graph in document order, merges every\n * `head()` contribution (last-in-document-order wins per dedup key), and\n * serializes each effective tag with the `data-streetui-head` marker so the\n * browser adopts it on hydration. Returns `''` when the app declares no metadata\n * — so apps that never call `head()` emit nothing extra and existing SSR output\n * is unchanged.\n */\nexport function renderHead(compiled: CompiledApplication): string {\n const graph: ApplicationGraph = compiled.graph;\n\n const merged = new Map<string, ResolvedTag>();\n graph.walk((node) => {\n if (node.type !== 'head') return;\n const descFn = graph.getHandler(`__head__${node.id}`) as\n | (() => HeadContributionLike)\n | undefined;\n if (descFn === undefined) return;\n for (const entry of descFn().entries) {\n merged.set(entry.dedupKey, resolveEntry(entry));\n }\n });\n\n if (merged.size === 0) return '';\n\n const dom = new ServerDOMAdapter();\n let out = '';\n for (const [key, desired] of merged) {\n const el = dom.createElement(desired.tag);\n dom.setAttribute(el, HEAD_MARKER, '');\n dom.setAttribute(el, HEAD_KEY, key);\n for (const attr of Object.keys(desired.attrs)) {\n dom.setAttribute(el, attr, desired.attrs[attr]!);\n }\n if (desired.tag === 'title') dom.setTextContent(el, desired.text ?? '');\n out += dom.serializeOuter(el);\n }\n return out;\n}\n","/**\n * Initial mount — creates DOM nodes for every GraphNode and\n * attaches them into the container.\n *\n * This is a recursive depth-first walk. For each GraphNode:\n * 1. Create the DOM element (or text node)\n * 2. Apply props/attributes\n * 3. Wire events\n * 4. Wire signal subscriptions for reactive props\n * 5. Recurse into children\n * 6. Insert into the DOM\n */\n\nimport type { GraphNode, ApplicationGraph } from '@streetui/graph';\nimport type { DOMAdapter } from '@streetui/dom';\nimport {\n focusInitial,\n trapFocus,\n containFocus,\n onEscape,\n rovingMenu,\n saveFocus,\n restoreFocus,\n} from '@streetui/dom';\nimport type { RenderContext } from './render-context.js';\nimport { NodeInstance } from './node-instance.js';\nimport { applyProp } from './attributes.js';\nimport { wireEvents } from './events.js';\nimport { resolveTag } from './tag-map.js';\nimport {\n reconcileChildren,\n reconcileChildrenByPlan,\n type PlanEntry,\n} from './reconciliation.js';\nimport { TransitionController, type TransitionHooks } from './transition.js';\nimport { wireHeadBehavior } from './head.js';\n\n/**\n * Prop keys handled by the per-type mount branches (or reserved internals), so\n * `applyNodeProps` must skip them to avoid double-applying. This set is\n * invariant across nodes, so it is hoisted to module scope: allocating it once\n * (rather than per node) removes N Set allocations per mount/SSR pass and the\n * GC pressure they create. Treat as read-only — never mutate.\n */\nconst SKIP_PROP_KEYS: ReadonlySet<string> = new Set([\n 'text', 'label', 'level', 'inputType', 'src', 'alt', 'href', 'external',\n 'value', 'placeholder', 'disabled', '_renderKey', 'key', 'name',\n]);\n\nexport function mountGraph(ctx: RenderContext): NodeInstance {\n return mountNode(ctx, ctx.graph.root, ctx.container);\n}\n\nexport function mountNode(\n ctx: RenderContext,\n graphNode: GraphNode,\n parentDom: Node,\n): NodeInstance {\n const { dom, graph } = ctx;\n\n // ── v1.7 static SSR fast path (SSR-only) ──────────────────────────────────\n // When a compiler-derived static SSR plan is present (server render only)\n // and this node is a maximal static-subtree root, emit its precomputed HTML\n // verbatim instead of recursively constructing ServerElement/ServerText/\n // NodeInstance for the whole subtree. `ctx.staticHTML` is always undefined on\n // the browser path, so this is a single short-circuiting check there — the\n // client hot path and its semantics are untouched (§5/§6/§23). The stored\n // string is produced by this same mount+serialize pipeline, so output is\n // byte-identical (§8). We still register ONE NodeInstance for the root so the\n // parent's children bookkeeping and post-render dispose behave normally.\n const staticHTML = ctx.staticHTML;\n if (staticHTML !== undefined && dom.createRawHTML !== undefined) {\n const precomputed = staticHTML.get(graphNode.id);\n if (precomputed !== undefined) {\n const raw = dom.createRawHTML(precomputed);\n dom.appendChild(parentDom, raw);\n const instance = new NodeInstance(graphNode, raw);\n ctx.instances.set(graphNode.id, instance);\n return instance;\n }\n }\n\n // The application root node maps to the container itself — don't create a duplicate element\n if (graphNode.type === 'application') {\n const instance = new NodeInstance(graphNode, parentDom);\n ctx.instances.set(graphNode.id, instance);\n for (const child of graphNode.children) {\n const childInstance = mountNode(ctx, child, parentDom);\n instance.addChild(childInstance);\n }\n return instance;\n }\n\n // Text-only nodes render as a <span> containing a text node\n if (graphNode.type === 'text') {\n const text = String(graphNode.getProp('text') ?? '');\n const el = dom.createElement('span');\n const textNode = dom.createTextNode(text);\n dom.appendChild(el, textNode);\n applyNodeProps(ctx, graphNode, el);\n\n // Create the live instance up front and reuse it for event wiring. The\n // previous code allocated a throwaway NodeInstance solely to satisfy\n // wireEvents' signature, wasting one NodeInstance (+ its children array and\n // CleanupRegistry) per text node — pure GC pressure on the hottest mount\n // path. wireEvents/wireSignalBindings each early-return on empty arrays.\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n // Reactive text binding — only build the update closure when the node has\n // bindings. wireSignalBindings early-returns on empty stateRefs, so for a\n // static text node (the common case in a large initial render) the\n // textUpdate closure would be allocated and thrown away: avoidable GC\n // pressure on the hottest mount path.\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, textUpdate(dom, el, textNode));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Heading nodes\n if (graphNode.type === 'heading') {\n const level = (graphNode.getProp('level') as number | undefined) ?? 1;\n const tag = `h${level}` as string;\n const el = dom.createElement(tag);\n const text = String(graphNode.getProp('text') ?? '');\n dom.setTextContent(el, text);\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, headingUpdate(dom, el));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Input nodes\n if (graphNode.type === 'input') {\n const el = dom.createElement('input') as HTMLInputElement;\n const inputType = String(graphNode.getProp('inputType') ?? 'text');\n dom.setAttribute(el, 'type', inputType);\n const placeholder = graphNode.getProp('placeholder');\n if (placeholder !== undefined) dom.setAttribute(el, 'placeholder', String(placeholder));\n const value = graphNode.getProp('value');\n if (value !== undefined) dom.setProperty(el, 'value', String(value));\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, inputUpdate(dom, el));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Image nodes\n if (graphNode.type === 'image') {\n const el = dom.createElement('img') as HTMLImageElement;\n const src = graphNode.getProp('src');\n const alt = graphNode.getProp('alt');\n if (src !== undefined) dom.setAttribute(el, 'src', String(src));\n if (alt !== undefined) dom.setAttribute(el, 'alt', String(alt));\n const width = graphNode.getProp('width');\n const height = graphNode.getProp('height');\n if (width !== undefined) dom.setAttribute(el, 'width', String(width));\n if (height !== undefined) dom.setAttribute(el, 'height', String(height));\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Link nodes\n if (graphNode.type === 'link') {\n const el = dom.createElement('a') as HTMLAnchorElement;\n const href = graphNode.getProp('href');\n const label = graphNode.getProp('label');\n const external = graphNode.getProp('external');\n if (href !== undefined) dom.setAttribute(el, 'href', String(href));\n if (label !== undefined) dom.setTextContent(el, String(label));\n if (external === true) {\n dom.setAttribute(el, 'target', '_blank');\n dom.setAttribute(el, 'rel', 'noopener noreferrer');\n }\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n // A link's label/href may be bound to signals (e.g. i18n `t()` in nav). Wire\n // the same signal-binding path buttons use so the text updates reactively.\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, linkUpdate(dom, el));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Button nodes\n if (graphNode.type === 'button') {\n const el = dom.createElement('button') as HTMLButtonElement;\n const label = graphNode.getProp('label');\n if (label !== undefined) dom.setTextContent(el, String(label));\n const disabled = graphNode.getProp('disabled');\n if (disabled === true) dom.setAttribute(el, 'disabled', '');\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, el, instance);\n\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, buttonUpdate(dom, el));\n }\n\n dom.appendChild(parentDom, el);\n return instance;\n }\n\n // Reactive list / conditional — a container whose children are driven by a\n // Signal. Initial child subtrees are already built into the graph by the DSL;\n // on signal change we reconcile the freshly-built desired children against the\n // live DOM using the keyed reconciler (no virtual DOM). A `conditional` uses\n // the identical machinery but renders as a neutral <div> holding 0..1 branch.\n if (graphNode.type === 'reactive-list' || graphNode.type === 'conditional') {\n const tag = resolveTag(graphNode.type);\n const el = dom.createElement(tag);\n applyNodeProps(ctx, graphNode, el);\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n\n for (const child of graphNode.children) {\n const childInstance = mountNode(ctx, child, el);\n instance.addChild(childInstance);\n }\n\n dom.appendChild(parentDom, el);\n wireReactiveList(ctx, graphNode, instance, el, true);\n return instance;\n }\n\n // Portal — a container whose children are relocated to a different DOM\n // location (document.body) on the browser, while a neutral inline anchor\n // stays at the declaration site. On the server there is no body, so the\n // children render inline in the anchor (deterministic HTML; hydration then\n // relocates them). This is the substrate for overlays (dialog/popover/…):\n // `wireOverlayBehavior` reads an optional `__overlay__<id>` descriptor and,\n // when present, wires focus trap/restore/containment/escape to the open\n // signal. A plain portal has no descriptor, so overlay wiring is a no-op.\n if (graphNode.type === 'portal') {\n const anchor = dom.createElement(resolveTag('portal'));\n dom.setAttribute(anchor, 'data-streetui-portal', '');\n applyNodeProps(ctx, graphNode, anchor);\n const instance = new NodeInstance(graphNode, anchor);\n ctx.instances.set(graphNode.id, instance);\n\n const body = dom.body();\n let target: Element = anchor; // SSR / no body → render inline in the anchor\n if (body !== null) {\n const portalContainer = dom.createElement('div');\n dom.setAttribute(portalContainer, 'data-streetui-portal-container', '');\n dom.appendChild(body, portalContainer);\n instance.trackCleanup(() => dom.removeChild(body, portalContainer));\n target = portalContainer;\n }\n\n for (const child of graphNode.children) {\n instance.addChild(mountNode(ctx, child, target));\n }\n\n dom.appendChild(parentDom, anchor);\n wireOverlayBehavior(ctx, graphNode, instance, target);\n return instance;\n }\n\n // Head — a metadata node (title/meta/link/base). Renders as a neutral inline\n // anchor at the declaration site (like a portal), while its contribution is\n // applied to `document.head` by `wireHeadBehavior` (browser) or emitted by\n // `renderHead` (server). No visible children; the anchor keeps hydration\n // structurally aligned with the SSR output.\n if (graphNode.type === 'head') {\n const anchor = dom.createElement(resolveTag('head'));\n dom.setAttribute(anchor, 'data-streetui-head-anchor', '');\n applyNodeProps(ctx, graphNode, anchor);\n const instance = new NodeInstance(graphNode, anchor);\n ctx.instances.set(graphNode.id, instance);\n\n dom.appendChild(parentDom, anchor);\n wireHeadBehavior(ctx, graphNode, instance);\n return instance;\n }\n\n // Container / section / page / form / list / list-item — structural nodes\n const tag = resolveTag(graphNode.type);\n const el = dom.createElement(tag);\n applyNodeProps(ctx, graphNode, el);\n\n // Surface a reactive-list item's stable, identity-only reconciliation key as a\n // public `data-streetui-key` attribute (e.g. \"id:1\"). This exposes only the\n // identity part — never the internal `_sig` value signature, signal ids or\n // graph node ids — so a row is directly selectable and its identity is\n // inspectable across reorders and in-place data updates.\n if (graphNode.type === 'list-item') {\n const itemKey = graphNode.getProp('key');\n if (itemKey !== undefined) {\n dom.setAttribute(el, 'data-streetui-key', String(itemKey));\n }\n }\n\n const instance = new NodeInstance(graphNode, el);\n ctx.instances.set(graphNode.id, instance);\n\n // wire form submit (reuse the live instance rather than a throwaway)\n if (graphNode.type === 'form') {\n wireEvents(dom, graph, graphNode, el, instance);\n }\n\n // Recurse into children\n for (const child of graphNode.children) {\n const childInstance = mountNode(ctx, child, el);\n instance.addChild(childInstance);\n }\n\n dom.appendChild(parentDom, el);\n if (graphNode.type === 'component') wireComponentBehavior(ctx, graphNode, instance);\n return instance;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/**\n * Per-node-type reactive-binding factories. Each returns the `onUpdate`\n * callback that `wireSignalBindings` invokes when a bound signal changes.\n * Extracted so both the browser mount path and the hydration path apply the\n * exact same DOM mutation semantics for each prop — no duplicated rendering\n * logic.\n */\nexport function textUpdate(\n dom: DOMAdapter,\n el: Element,\n textNode: Text,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'text') {\n dom.setTextContent(textNode, String(value ?? ''));\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function headingUpdate(\n dom: DOMAdapter,\n el: Element,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'text') {\n dom.setTextContent(el, String(value ?? ''));\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function inputUpdate(\n dom: DOMAdapter,\n el: Element,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'value') {\n dom.setProperty(el, 'value', String(value ?? ''));\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function buttonUpdate(\n dom: DOMAdapter,\n el: Element,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'label') {\n dom.setTextContent(el, String(value ?? ''));\n } else if (propKey === 'disabled') {\n if (value === true) {\n dom.setAttribute(el, 'disabled', '');\n } else {\n dom.removeAttribute(el, 'disabled');\n }\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function linkUpdate(\n dom: DOMAdapter,\n el: Element,\n): (propKey: string, value: unknown) => void {\n return (propKey, value) => {\n if (propKey === 'label') {\n dom.setTextContent(el, String(value ?? ''));\n } else if (propKey === 'href') {\n dom.setAttribute(el, 'href', String(value ?? ''));\n } else {\n applyProp(dom, el, propKey, value);\n }\n };\n}\n\nexport function applyNodeProps(ctx: RenderContext, graphNode: GraphNode, el: Element): void {\n // Iterate own enumerable keys directly rather than via Object.entries, which\n // allocates a wrapper array plus one [key,value] tuple per prop — measurable\n // GC pressure when multiplied across every node in a large initial render.\n const props = graphNode.props;\n for (const key in props) {\n if (!Object.hasOwn(props, key)) continue;\n if (SKIP_PROP_KEYS.has(key)) continue;\n applyProp(ctx.dom, el, key, props[key]);\n }\n}\n\nexport function wireSignalBindings(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n onUpdate: (propKey: string, value: unknown) => void,\n): void {\n // Fast exit for the common non-reactive node — avoids allocating a for-of\n // iterator over an empty stateRefs array on every static node.\n if (graphNode.stateRefs.length === 0) return;\n for (const stateRef of graphNode.stateRefs) {\n const signalKey = `__signal__${stateRef.signalId}`;\n const maybeSig = ctx.graph.getHandler(signalKey) as\n | { subscribe: (fn: (v: unknown) => void) => () => void; peek: () => unknown }\n | undefined;\n if (maybeSig === undefined || typeof maybeSig.subscribe !== 'function') continue;\n\n // Subscribe directly — avoids the ReadonlySignal<T> generic variance issue\n const unsub = maybeSig.subscribe((value) => {\n onUpdate(stateRef.propKey, value);\n });\n instance.trackCleanup(unsub);\n }\n}\n\n// ── Reactive list wiring ────────────────────────────────────────────────────────\n\ntype ListBuildFn = (items: unknown) => GraphNode[];\ntype ListPlanFn = (items: unknown) => PlanEntry[];\n\n/**\n * Subscribe a reactive-list instance to its driving signal. On each change the\n * DSL-registered plan factory produces lightweight per-row descriptors, which\n * are reconciled against the live DOM with the keyed, minimal-move reconciler\n * (spec §15). A `conditional` node has no plan handler and falls back to the\n * eager build factory (it only ever renders 0..1 branch, so eager is fine).\n */\nexport function wireReactiveList(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n el: Element,\n runAppear = false,\n): void {\n const plan = ctx.graph.getHandler(`__listplan__${graphNode.id}`) as\n | ListPlanFn\n | undefined;\n const build = ctx.graph.getHandler(`__listbuild__${graphNode.id}`) as\n | ListBuildFn\n | undefined;\n if (plan === undefined && build === undefined) return;\n\n // One transition controller per reactive container, created here so its\n // leaving-instance map survives across every reconcile of this container\n // (that persistence is what makes leave→enter reclaim and keyed list-leave\n // correct — §6/§7). `finalize` runs the full deferred teardown chain when a\n // leave animation completes: DOM-remove + dispose + forget + detach, exactly\n // the work the synchronous path splits between the reconciler and the two\n // reconcile* helpers below. On the server (no body) the controller's hooks\n // no-op, so SSR is unchanged (§21).\n const controller = new TransitionController(ctx.dom, ctx.graph, (leaving) => {\n // Full teardown at leave-animation end — the same four steps the synchronous\n // path splits between the reconciler (DOM-remove + dispose) and this helper\n // (forget + detach). Deferred here because `beginLeave` excluded this\n // instance from `result.removed`, so nothing else will tear it down.\n const parent = ctx.dom.parentNode(leaving.domNode);\n if (parent !== null) ctx.dom.removeChild(parent, leaving.domNode);\n leaving.dispose();\n forgetInstance(ctx, leaving);\n ctx.graph.detachNode(leaving.graphNode);\n });\n const hooks = controller.hooks();\n\n // `appear`: animate any initial child that opted in — but ONLY on a fresh\n // browser mount, never on hydration (§22: the DOM is already present and\n // correct, so appear must not run). The hydrate path calls this with\n // `runAppear` omitted (false).\n if (runAppear) controller.appear(instance.children);\n\n for (const stateRef of graphNode.stateRefs) {\n if (stateRef.propKey !== 'items') continue;\n const sig = ctx.graph.getHandler(`__signal__${stateRef.signalId}`) as\n | { subscribe: (fn: (v: unknown) => void) => () => void }\n | undefined;\n if (sig === undefined || typeof sig.subscribe !== 'function') continue;\n\n const unsub = sig.subscribe((value) => {\n if (plan !== undefined) {\n reconcileReactiveListByPlan(ctx, graphNode, instance, el, plan(value), hooks);\n } else {\n reconcileReactiveList(ctx, graphNode, instance, el, build!(value), hooks);\n }\n });\n instance.trackCleanup(unsub);\n }\n}\n\nfunction reconcileReactiveListByPlan(\n ctx: RenderContext,\n listNode: GraphNode,\n listInstance: NodeInstance,\n listEl: Element,\n plan: PlanEntry[],\n hooks: TransitionHooks,\n): void {\n const oldInstances = [...listInstance.children];\n const result = reconcileChildrenByPlan(\n ctx,\n listEl,\n oldInstances,\n plan,\n (node, parent) => mountNode(ctx, node, parent),\n hooks,\n );\n\n // Sync the live instance's children to the reconciled order.\n listInstance.children.length = 0;\n for (const inst of result.instances) listInstance.children.push(inst);\n\n // Forget removed instances, and drop their graph nodes.\n for (const removed of result.removed) {\n forgetInstance(ctx, removed);\n ctx.graph.detachNode(removed.graphNode);\n }\n // Detach any freshly-built subtree that was not adopted as a live instance\n // (e.g. the top node of a rebuilt changed row, whose live instance keeps its\n // original graph node).\n const adopted = new Set(result.instances.map((i) => i.graphNode));\n for (const node of result.built ?? []) {\n if (!adopted.has(node)) ctx.graph.detachNode(node);\n }\n\n // Keep the graph model consistent: list node children match the new order.\n for (const child of [...listNode.children]) listNode.removeChild(child);\n for (const inst of result.instances) listNode.appendChild(inst.graphNode);\n}\n\nfunction reconcileReactiveList(\n ctx: RenderContext,\n listNode: GraphNode,\n listInstance: NodeInstance,\n listEl: Element,\n newNodes: GraphNode[],\n hooks: TransitionHooks,\n): void {\n const oldInstances = [...listInstance.children];\n const result = reconcileChildren(\n ctx,\n listEl,\n oldInstances,\n newNodes,\n (node, parent) => mountNode(ctx, node, parent),\n hooks,\n );\n\n // Sync the live instance's children to the reconciled order.\n listInstance.children.length = 0;\n for (const inst of result.instances) listInstance.children.push(inst);\n\n // Forget removed instances from the renderer index, and drop their graph\n // nodes (and any un-adopted freshly-built duplicates) from the graph index.\n for (const removed of result.removed) {\n forgetInstance(ctx, removed);\n ctx.graph.detachNode(removed.graphNode);\n }\n const adopted = new Set(result.instances.map((i) => i.graphNode));\n for (const built of newNodes) {\n if (!adopted.has(built)) ctx.graph.detachNode(built);\n }\n\n // Keep the graph model consistent: list node children match the new order.\n for (const child of [...listNode.children]) listNode.removeChild(child);\n for (const inst of result.instances) listNode.appendChild(inst.graphNode);\n}\n\n/** Recursively remove an instance subtree from the renderer's instance index. */\nfunction forgetInstance(ctx: RenderContext, instance: NodeInstance): void {\n ctx.instances.delete(instance.graphNode.id);\n for (const child of instance.children) forgetInstance(ctx, child);\n}\n\n// ── Overlay behavior wiring ─────────────────────────────────────────────────────\n\n/**\n * Opaque overlay descriptor, read from the `__overlay__<portalId>` handler that\n * the DSL registers for dialog/popover/tooltip/dropdown/toast. Declared here as\n * a local structural type (mirroring the list plan/build handler pattern) so the\n * renderer never takes a compile-time dependency on the DSL package.\n */\ninterface OverlayBehavior {\n /** Reactive open/visibility state — the same signal that drives the panel's `when()`. */\n readonly open: {\n subscribe: (fn: (v: boolean) => void) => () => void;\n peek: () => unknown;\n };\n /** Trap Tab focus within, and redirect escaped focus back inside (modal semantics). */\n readonly modal: boolean;\n /** Move focus into the panel when it opens. */\n readonly takesFocus: boolean;\n /** Wire arrow/Home/End/Enter/Space roving-focus navigation (role=\"menu\"). */\n readonly menu: boolean;\n /** Escape key invokes `onClose`. */\n readonly closeOnEscape: boolean;\n /** Restore focus to the pre-open element on close. */\n readonly restoreFocus: boolean;\n /** id of the element to focus first when opening. */\n readonly initialFocusId?: string;\n /** Requested-close callback (Escape). The app flips its own open signal here. */\n readonly onClose?: () => void;\n}\n\n/**\n * Attach overlay focus/keyboard behavior to a mounted portal. Server-safe: on\n * the server `dom.body()` is null so this returns immediately (SSR emits inert\n * markup, no focus concept). A plain portal has no `__overlay__` descriptor, so\n * this also returns immediately — the behavior is purely additive.\n *\n * The panel is mounted/unmounted by the portal's inner `when(open, …)`, whose\n * signal subscription is registered *before* this one (the conditional child is\n * mounted earlier in the portal branch). Signal subscribers fire synchronously\n * in subscription order, so on open→true the panel DOM exists before we move\n * focus into it, and on open→false the panel is torn down before we restore\n * focus. All listeners are tracked on the instance and torn down on unmount.\n */\nexport function wireOverlayBehavior(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n target: Element,\n): void {\n const { dom, graph } = ctx;\n if (dom.body() === null) return; // server / no DOM environment\n\n const descFn = graph.getHandler(`__overlay__${graphNode.id}`) as\n | (() => OverlayBehavior)\n | undefined;\n if (descFn === undefined) return; // plain portal — no overlay behavior\n\n const desc = descFn();\n const openSig = desc.open;\n if (openSig === undefined || typeof openSig.subscribe !== 'function') return;\n\n let active: Array<() => void> = [];\n let saved: Element | null = null;\n\n const teardown = (): void => {\n for (const fn of active) fn();\n active = [];\n };\n\n const onOpenChange = (isOpen: boolean): void => {\n if (isOpen) {\n if (desc.restoreFocus) saved = saveFocus(dom);\n // Establish containment/roving BEFORE moving focus in, so that when a\n // nested modal opens it becomes the authoritative focus owner before its\n // initial focus fires — otherwise the outer modal's still-active\n // containment would pull that focus back out (§16).\n if (desc.modal) {\n active.push(trapFocus(dom, target));\n active.push(containFocus(dom, target));\n }\n if (desc.menu) {\n active.push(rovingMenu(dom, target));\n }\n if (desc.takesFocus) focusInitial(dom, target, desc.initialFocusId);\n if (desc.closeOnEscape && desc.onClose !== undefined) {\n active.push(onEscape(dom, target, desc.onClose));\n }\n } else {\n teardown();\n if (desc.restoreFocus && saved !== null) {\n restoreFocus(dom, saved);\n saved = null;\n }\n }\n };\n\n const unsub = openSig.subscribe(onOpenChange);\n instance.trackCleanup(unsub);\n instance.trackCleanup(teardown);\n\n // `subscribe` fires only on change; an overlay that is open on initial mount\n // has its panel already built into the graph, so run the open path now.\n if (openSig.peek() === true) onOpenChange(true);\n}\n\n/**\n * Wire a component instance's lifecycle (§9). Reads the optional\n * `__component__<id>` descriptor — an array of teardown callbacks the DSL's\n * `component()` collected from the setup's `ctx.effect`/`ctx.onCleanup` — and\n * routes each into `NodeInstance.trackCleanup`, so they run (children-first)\n * when the component leaves the graph. Shared by the mount and hydrate paths so\n * both attach identical ownership. A `'component'` node with no cleanups (no\n * effects/resources) registers no descriptor and this is a no-op.\n */\nexport function wireComponentBehavior(\n ctx: RenderContext,\n graphNode: GraphNode,\n instance: NodeInstance,\n): void {\n const fn = ctx.graph.getHandler(`__component__${graphNode.id}`) as\n | (() => Array<() => void>)\n | undefined;\n if (fn === undefined) return;\n for (const cleanup of fn()) instance.trackCleanup(cleanup);\n}\n","/**\n * Hydration diagnostics — dev-only, opt-in explanations of hydration mismatches.\n *\n * Hydration is self-repairing: when the server-rendered DOM does not match the\n * graph at a position, the renderer mounts a fresh subtree in place and drops\n * the offending element (see `hydrateChildren` in `hydrate.ts`). That recovery\n * is silent by design — a local mismatch must never tear down the whole app.\n *\n * During development, though, a silent repair hides a real problem (usually a\n * server/client divergence). A `HydrationDiagnosticSink` can be attached to the\n * renderer to *observe* those repairs without changing them: for every mismatch\n * the renderer reports what it expected, what it found, where, and what it did\n * to recover. Nothing is thrown, nothing is mutated differently, and when no\n * sink is attached there is zero additional work on the hydration path.\n */\n\n/** What kind of divergence the hydrator encountered at a position. */\nexport type HydrationMismatchType =\n | 'tag-mismatch' // an element existed but was the wrong tag\n | 'missing-element' // the graph expected a child the DOM did not provide\n | 'surplus-element'; // the DOM had a child the graph no longer expects\n\n/** A single, fully-described hydration divergence and the repair taken. */\nexport interface HydrationDiagnostic {\n /** The category of mismatch. */\n readonly type: HydrationMismatchType;\n /** The tag the graph expected at this position (null for a surplus element). */\n readonly expected: string | null;\n /** The tag actually found in the server DOM (null for a missing element). */\n readonly found: string | null;\n /** A human-readable path to the position, e.g. `app / page[0] / section[1]`. */\n readonly path: string;\n /** The graph node id involved, when one exists (null for surplus DOM). */\n readonly nodeId: string | null;\n /** The semantic node type involved, when one exists (null for surplus DOM). */\n readonly nodeType: string | null;\n /** The recovery action the renderer performed. */\n readonly action: string;\n /** A single-line, developer-facing summary of the whole diagnostic. */\n readonly message: string;\n}\n\n/**\n * Receives hydration diagnostics as they are discovered. Kept intentionally\n * tiny so any logger — `console`, a test collector, a `DiagnosticSink` — can\n * satisfy it. Implementations must not throw.\n */\nexport interface HydrationDiagnosticSink {\n report(diagnostic: HydrationDiagnostic): void;\n}\n\n/** Build the canonical one-line message for a diagnostic. */\nexport function formatHydrationDiagnostic(\n d: Omit<HydrationDiagnostic, 'message'>,\n): string {\n const at = ` at ${d.path}`;\n switch (d.type) {\n case 'tag-mismatch':\n return `Hydration mismatch${at} — Expected: ${d.expected} / Found: ${d.found} / Action: ${d.action}`;\n case 'missing-element':\n return `Hydration mismatch${at} — Expected: ${d.expected} / Found: (nothing) / Action: ${d.action}`;\n case 'surplus-element':\n return `Hydration mismatch${at} — Expected: (nothing) / Found: ${d.found} / Action: ${d.action}`;\n }\n}\n\n/**\n * A ready-made sink that accumulates diagnostics into an array — the shape most\n * useful for tests and for a DevTools panel. The returned `diagnostics` array is\n * appended to in-place as repairs happen.\n */\nexport function createHydrationDiagnosticCollector(): {\n readonly sink: HydrationDiagnosticSink;\n readonly diagnostics: HydrationDiagnostic[];\n} {\n const diagnostics: HydrationDiagnostic[] = [];\n return {\n diagnostics,\n sink: {\n report(d) {\n diagnostics.push(d);\n },\n },\n };\n}\n\n/**\n * A sink that forwards each diagnostic to a `console`-like logger as a single\n * warning line. Handy default when you just want the messages surfaced in dev.\n */\nexport function consoleHydrationDiagnosticSink(\n logger: { warn(message: string): void } = console,\n): HydrationDiagnosticSink {\n return {\n report(d) {\n logger.warn(d.message);\n },\n };\n}\n","/**\n * Hydration — attach a live StreetUI runtime to server-rendered HTML.\n *\n * `hydrate` walks the semantic application graph top-down against the DOM that\n * the server already produced. For every graph node it *adopts* the matching\n * existing element (creating a `NodeInstance` that points at it) and attaches\n * behavior — event listeners and signal subscriptions — using the exact same\n * helpers the browser mount path uses (`wireEvents`, `wireSignalBindings`,\n * `wireReactiveList`, and the per-type update factories). Nothing is recreated\n * when the DOM matches.\n *\n * Matching is positional and works because every non-application graph node\n * maps to exactly one element (see mount.ts). When the element at a position\n * does not match the expected tag (or is missing), only that subtree is\n * repaired: the fresh subtree is mounted and spliced into place, leaving the\n * rest of the hydrated tree untouched. A local mismatch never tears down the\n * whole app.\n */\n\nimport type { GraphNode } from '@streetui/graph';\nimport type { RenderContext } from './render-context.js';\nimport { NodeInstance } from './node-instance.js';\nimport { wireEvents } from './events.js';\nimport { resolveTag } from './tag-map.js';\nimport { formatHydrationDiagnostic } from './hydration-diagnostics.js';\nimport { wireHeadBehavior } from './head.js';\nimport {\n mountNode,\n wireSignalBindings,\n wireReactiveList,\n wireOverlayBehavior,\n wireComponentBehavior,\n textUpdate,\n headingUpdate,\n inputUpdate,\n buttonUpdate,\n linkUpdate,\n} from './mount.js';\n\n/** Hydrate the whole application graph against `ctx.container`. */\nexport function hydrateGraph(ctx: RenderContext): NodeInstance {\n const root = ctx.graph.root;\n // The application root maps to the container itself (no element of its own),\n // exactly as in mountNode.\n const instance = new NodeInstance(root, ctx.container);\n ctx.instances.set(root.id, instance);\n hydrateChildren(ctx, root, instance, ctx.container, 'app');\n return instance;\n}\n\n/**\n * Adopt `domNode` as the live element for `graphNode` and attach behavior.\n * The caller has already verified `domNode` matches `graphNode` (right tag).\n * `path` is the human-readable position used only for dev diagnostics.\n */\nfunction hydrateNode(\n ctx: RenderContext,\n graphNode: GraphNode,\n domNode: Element,\n path: string,\n): NodeInstance {\n const { dom, graph } = ctx;\n\n switch (graphNode.type) {\n case 'text': {\n // <span> with an inner text node. Adopt the text node (or create one if\n // the server markup somehow lacks it).\n let textNode = dom.firstChild(domNode);\n if (textNode === null || !dom.isTextNode(textNode)) {\n const created = dom.createTextNode(String(graphNode.getProp('text') ?? ''));\n dom.appendChild(domNode, created);\n textNode = created;\n }\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, domNode, instance);\n // Only build the per-type update closure when the node actually has\n // reactive bindings. wireSignalBindings early-returns on an empty\n // stateRefs list, so for a static node the `textUpdate(...)` closure would\n // be allocated and immediately discarded — pure GC pressure on the hot\n // hydration path, where the vast majority of nodes are static.\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, textUpdate(dom, domNode, textNode as Text));\n }\n return instance;\n }\n\n case 'heading': {\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, domNode, instance);\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, headingUpdate(dom, domNode));\n }\n return instance;\n }\n\n case 'input': {\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n // The controlled value is already present in the server HTML (reflected as\n // the `value` attribute). Re-assert it as a live property so the element's\n // current value matches the bound signal exactly.\n const value = graphNode.getProp('value');\n if (value !== undefined) dom.setProperty(domNode, 'value', String(value));\n wireEvents(dom, graph, graphNode, domNode, instance);\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, inputUpdate(dom, domNode));\n }\n return instance;\n }\n\n case 'button': {\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n wireEvents(dom, graph, graphNode, domNode, instance);\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, buttonUpdate(dom, domNode));\n }\n return instance;\n }\n\n case 'image':\n case 'link': {\n // Leaf elements. Links may carry click handlers and — like buttons — a\n // label/href bound to a signal (e.g. i18n `t()` in nav), so wire the same\n // reactive binding path after adopting the server node.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n if (graphNode.type === 'link') {\n wireEvents(dom, graph, graphNode, domNode, instance);\n if (graphNode.stateRefs.length !== 0) {\n wireSignalBindings(ctx, graphNode, instance, linkUpdate(dom, domNode));\n }\n }\n return instance;\n }\n\n case 'reactive-list':\n case 'conditional': {\n // The server rendered the initial children (built into the graph at\n // compile time from the initial signal state). Adopt them positionally,\n // then subscribe for future signal changes — the same keyed reconciler as\n // the browser drives subsequent updates against the adopted instances.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n hydrateChildren(ctx, graphNode, instance, domNode, path);\n wireReactiveList(ctx, graphNode, instance, domNode);\n return instance;\n }\n\n case 'portal': {\n // The server rendered the portal's children INLINE inside the anchor\n // (no body on the server). Adopt the anchor, then — before positional\n // child hydration — relocate those inline children into a fresh\n // document.body container so their live location matches the browser\n // mount path exactly (and there is no positional mismatch). Hydrate the\n // children against the body container, then wire any overlay behavior.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n const body = dom.body();\n let target: Element = domNode;\n if (body !== null) {\n const portalContainer = dom.createElement('div');\n dom.setAttribute(portalContainer, 'data-streetui-portal-container', '');\n // `childNodes` returns a snapshot array, so moving during iteration is\n // safe. appendChild re-parents each node out of the anchor.\n for (const child of dom.childNodes(domNode)) {\n dom.appendChild(portalContainer, child);\n }\n dom.appendChild(body, portalContainer);\n instance.trackCleanup(() => dom.removeChild(body, portalContainer));\n target = portalContainer;\n }\n hydrateChildren(ctx, graphNode, instance, target, path);\n wireOverlayBehavior(ctx, graphNode, instance, target);\n return instance;\n }\n\n case 'head': {\n // The server emitted this node's metadata into `<head>` (via renderHead)\n // and left a neutral empty anchor here. Adopt the anchor, then wire the\n // head behavior: the HeadManager adopts the server `[data-streetui-head-\n // key]` tags on first apply so re-asserting this contribution produces no\n // duplicates. No children to hydrate.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n wireHeadBehavior(ctx, graphNode, instance);\n return instance;\n }\n\n default: {\n // Structural nodes: container / section / page / form / list / list-item.\n const instance = new NodeInstance(graphNode, domNode);\n ctx.instances.set(graphNode.id, instance);\n if (graphNode.type === 'form') {\n wireEvents(dom, graph, graphNode, domNode, instance);\n }\n // Hydration boundary (a \"slot\" such as the router outlet): adopt the\n // element itself but leave its existing children untouched — neither\n // hydrated by this pass nor removed as surplus. Something else (e.g. the\n // router) owns and will hydrate the content already inside it. Without\n // this, an empty-in-the-graph slot would strip the server-rendered\n // content it is meant to preserve.\n if (graphNode.getProp('_hydrationBoundary') === true) {\n return instance;\n }\n hydrateChildren(ctx, graphNode, instance, domNode, path);\n if (graphNode.type === 'component') wireComponentBehavior(ctx, graphNode, instance);\n return instance;\n }\n }\n}\n\n// ── Child matching + local mismatch recovery ───────────────────────────────────\n\n/**\n * Positionally match a parent's expected child graph nodes against the actual\n * child *elements* in the DOM. Matching children are hydrated in place; a\n * mismatch (wrong tag or a missing element) triggers a local repair — the fresh\n * subtree is mounted and spliced into the correct position — without disturbing\n * sibling subtrees. Surplus DOM elements are removed.\n */\nfunction hydrateChildren(\n ctx: RenderContext,\n parentGraphNode: GraphNode,\n parentInstance: NodeInstance,\n parentDom: Element,\n parentPath: string,\n): void {\n const expected = parentGraphNode.children;\n const actual = elementChildren(ctx, parentDom);\n let cursor = 0;\n\n // The human-readable `path` is only ever consumed by hydration diagnostics,\n // which are inert unless a sink is attached. Building the\n // `${parentPath} / ${type}[${i}]` string for every child would allocate one\n // throwaway string per node on the hot path (10k+ on a large tree) for output\n // that is discarded in production. Gate the construction on the sink being\n // present; when it is absent, thread the (meaningless-but-unused) parent path\n // through unchanged so nested calls stay allocation-free too.\n const diag = ctx.hydrationDiagnostics !== undefined;\n\n for (let i = 0; i < expected.length; i++) {\n const childNode = expected[i]!;\n const want = expectedTag(ctx, childNode);\n const childPath = diag ? `${parentPath} / ${childNode.type}[${i}]` : parentPath;\n const actualEl = actual[cursor];\n\n if (\n actualEl !== undefined &&\n ctx.dom.isElement(actualEl) &&\n ctx.dom.tagName(actualEl) === want\n ) {\n // Match — adopt the existing element.\n const inst = hydrateNode(ctx, childNode, actualEl, childPath);\n parentInstance.addChild(inst);\n cursor++;\n } else {\n // Mismatch or missing — repair only this subtree. Mount fresh, then move\n // it into the correct position ahead of the offending/absent node.\n const ref = actualEl ?? null;\n const inst = mountFreshAt(ctx, childNode, parentDom, ref);\n parentInstance.addChild(inst);\n if (actualEl !== undefined) {\n // Drop the mismatched element that the fresh node replaces.\n const found = ctx.dom.isElement(actualEl) ? ctx.dom.tagName(actualEl) : null;\n reportHydrationDiagnostic(ctx, {\n type: 'tag-mismatch',\n expected: want,\n found,\n path: childPath,\n nodeId: childNode.id,\n nodeType: childNode.type,\n action: 'mounted fresh subtree in place',\n });\n ctx.dom.removeChild(parentDom, actualEl);\n cursor++;\n } else {\n reportHydrationDiagnostic(ctx, {\n type: 'missing-element',\n expected: want,\n found: null,\n path: childPath,\n nodeId: childNode.id,\n nodeType: childNode.type,\n action: 'mounted fresh subtree',\n });\n }\n }\n }\n\n // Remove any surplus server elements the graph no longer expects.\n for (let i = cursor; i < actual.length; i++) {\n const surplus = actual[i]!;\n reportHydrationDiagnostic(ctx, {\n type: 'surplus-element',\n expected: null,\n found: ctx.dom.isElement(surplus) ? ctx.dom.tagName(surplus) : null,\n path: `${parentPath} / [surplus ${i}]`,\n nodeId: null,\n nodeType: null,\n action: 'removed surplus server element',\n });\n ctx.dom.removeChild(parentDom, surplus);\n }\n}\n\n/**\n * Emit a hydration diagnostic through the (optional) sink. When no sink is\n * attached this is a single cheap `undefined` check — the production default.\n */\nfunction reportHydrationDiagnostic(\n ctx: RenderContext,\n d: {\n type: 'tag-mismatch' | 'missing-element' | 'surplus-element';\n expected: string | null;\n found: string | null;\n path: string;\n nodeId: string | null;\n nodeType: string | null;\n action: string;\n },\n): void {\n const sink = ctx.hydrationDiagnostics;\n if (sink === undefined) return;\n sink.report({ ...d, message: formatHydrationDiagnostic(d) });\n}\n\n/** Mount a fresh subtree for `node` and splice it before `ref` (or append). */\nfunction mountFreshAt(\n ctx: RenderContext,\n node: GraphNode,\n parentDom: Element,\n ref: Node | null,\n): NodeInstance {\n // mountNode appends the new subtree at the end of parentDom.\n const inst = mountNode(ctx, node, parentDom);\n if (ref !== null) {\n ctx.dom.insertBefore(parentDom, inst.domNode, ref);\n }\n return inst;\n}\n\n/** The element (not text/comment) children of a node, in order. */\nfunction elementChildren(ctx: RenderContext, parent: Element): Element[] {\n const out: Element[] = [];\n for (const node of ctx.dom.childNodes(parent)) {\n if (ctx.dom.isElement(node)) out.push(node);\n }\n return out;\n}\n\n/** The HTML tag a graph node is expected to occupy in the DOM. */\nfunction expectedTag(ctx: RenderContext, graphNode: GraphNode): string {\n switch (graphNode.type) {\n case 'text':\n return 'span';\n case 'heading': {\n const level = (graphNode.getProp('level') as number | undefined) ?? 1;\n return `h${level}`;\n }\n case 'input':\n return 'input';\n case 'image':\n return 'img';\n case 'link':\n return 'a';\n case 'button':\n return 'button';\n default:\n // reactive-list → ul, conditional → div, structural → resolveTag.\n return resolveTag(graphNode.type);\n }\n}\n","/**\n * StreetRenderHandle — the live handle returned by both `mount` and `hydrate`.\n *\n * Owns teardown for a mounted/hydrated application: disposes every NodeInstance\n * (removing event listeners and signal subscriptions) and clears the container\n * through the DOM adapter (never raw browser globals), so the same handle works\n * for browser and — in principle — server-driven teardown.\n */\n\nimport type { RenderHandle } from '@streetui/runtime';\nimport type { RenderContext } from './render-context.js';\nimport type { NodeInstance } from './node-instance.js';\n\nexport class StreetRenderHandle implements RenderHandle {\n private _disposed = false;\n private readonly _ctx: RenderContext;\n private readonly _rootInstance: NodeInstance;\n\n constructor(ctx: RenderContext, rootInstance: NodeInstance) {\n this._ctx = ctx;\n this._rootInstance = rootInstance;\n }\n\n flush(): void {\n if (this._disposed) return;\n // Signal subscriptions fire synchronously in StreetUI's state system;\n // flush() is a no-op at the renderer level — the DOM is already up to date\n // unless the scheduler is batching, in which case the scheduler calls\n // flush() after draining its queue.\n }\n\n unmount(): void {\n if (this._disposed) return;\n this._disposed = true;\n\n // Dispose all node instances (removes event listeners, signal subscriptions).\n this._rootInstance.dispose();\n\n // Remove all children from the container. Routed through the DOM adapter\n // (never `container.firstChild`/`removeChild`) so the teardown path is\n // server-safe.\n const dom = this._ctx.dom;\n const container = this._ctx.container;\n for (const child of dom.childNodes(container)) {\n dom.removeChild(container, child);\n }\n\n this._ctx.instances.clear();\n }\n}\n","/**\n * StreetUI Renderer — framework-owned DOM renderer.\n *\n * No React. No Vue. No virtual-dom. No external rendering library.\n *\n * Pipeline:\n * CompiledApplication\n * → mountGraph (creates all DOM nodes)\n * → signal subscriptions drive patchNode (targeted updates)\n * → flush() propagates any pending scheduler jobs\n * → unmount() disposes everything\n */\n\nimport type { DOMAdapter } from '@streetui/dom';\nimport { BrowserDOMAdapter } from '@streetui/dom';\nimport type { CompiledApplication } from '@streetui/compiler';\nimport type { StreetRenderer, RenderHandle } from '@streetui/runtime';\nimport { createRenderContext } from './render-context.js';\nimport { mountGraph } from './mount.js';\nimport { hydrateGraph } from './hydrate.js';\nimport { StreetRenderHandle } from './render-handle.js';\nimport type { NodeInstance } from './node-instance.js';\nimport type { HydrationDiagnosticSink } from './hydration-diagnostics.js';\n\nexport interface StreetRendererOptions {\n /** Override the DOM adapter (e.g. for testing). Defaults to BrowserDOMAdapter. */\n readonly domAdapter?: DOMAdapter;\n /**\n * Optional dev-only sink that observes hydration mismatch repairs. Attach one\n * to surface server/client divergences during development; leave it unset in\n * production so hydration does no extra work.\n */\n readonly hydrationDiagnostics?: HydrationDiagnosticSink;\n}\n\nexport class StreetRendererImpl implements StreetRenderer {\n private readonly _dom: DOMAdapter;\n private readonly _hydrationDiagnostics?: HydrationDiagnosticSink;\n\n constructor(options: StreetRendererOptions = {}) {\n this._dom = options.domAdapter ?? new BrowserDOMAdapter();\n if (options.hydrationDiagnostics !== undefined) {\n this._hydrationDiagnostics = options.hydrationDiagnostics;\n }\n }\n\n mount(compiled: CompiledApplication, container: Element): RenderHandle {\n const ctx = createRenderContext(this._dom, compiled.graph, container);\n\n // Initial mount — creates the full DOM tree\n const rootInstance = mountGraph(ctx);\n\n // Wire all signal subscriptions so that signal → DOM patches happen automatically\n this._wireSignals(ctx, rootInstance);\n\n return new StreetRenderHandle(ctx, rootInstance);\n }\n\n /**\n * Hydrate a container that already holds server-rendered HTML for this\n * application. Instead of recreating the DOM, it walks the semantic graph\n * against the existing nodes, adopting matching elements and attaching\n * behavior (events + signal subscriptions). Mismatched subtrees are locally\n * replaced. Returns the same handle type as `mount`.\n */\n hydrate(compiled: CompiledApplication, container: Element): RenderHandle {\n const ctx = createRenderContext(\n this._dom,\n compiled.graph,\n container,\n this._hydrationDiagnostics,\n );\n const rootInstance = hydrateGraph(ctx);\n this._wireSignals(ctx, rootInstance);\n return new StreetRenderHandle(ctx, rootInstance);\n }\n\n private _wireSignals(\n ctx: ReturnType<typeof createRenderContext>,\n rootInstance: NodeInstance,\n ): void {\n // Each NodeInstance already wired its own signals in mountNode via wireSignalBindings.\n // This method is a hook for any cross-cutting signal concerns at the renderer level.\n // Currently no-op — individual mount calls handle their own subscriptions.\n void ctx;\n void rootInstance;\n }\n}\n\n/**\n * Create the default StreetUI renderer using the browser's DOM APIs.\n */\nexport function createRenderer(options?: StreetRendererOptions): StreetRendererImpl {\n return new StreetRendererImpl(options);\n}\n","/**\n * Static graph analysis (v1.2, spec §3/§12/§14).\n *\n * A single post-order walk over the Semantic Application Graph that classifies\n * every node as static (no bound signals, no events, not a reactive\n * region) or dynamic, and rolls that up into whole-static-subtree flags. This\n * is COMPILE-TIME metadata only — it introduces no virtual DOM, no second tree\n * and no runtime reactive system. It is consumed by:\n * - the hydration path, to skip per-node attribute/text re-verification on\n * provably-static subtrees (§12), and\n * - the diagnostic compiler-inspection report (§14).\n *\n * The renderer's initial-mount fast path does not need this map: it already\n * skips reactive wiring per node via cheap `events.length`/`stateRefs.length`\n * guards. Keeping the analysis out of the mount hot path avoids adding lookup\n * cost (and keeps the shipped runtime lean).\n */\n\nimport type { NodeId } from '@streetui/core';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\n\n/** Prop keys whose bound signal drives text content rather than an attribute. */\nconst TEXT_PROP_KEYS: ReadonlySet<string> = new Set(['text', 'label', 'value']);\n\nexport interface NodeAnalysis {\n /** No bound signals, no events, and not a reactive-list/conditional region. */\n readonly isStatic: boolean;\n /** This node is static AND every descendant is a static subtree. */\n readonly isStaticSubtree: boolean;\n /** A signal is bound to this node's text/label/value content. */\n readonly hasDynamicText: boolean;\n /** A signal is bound to a non-content prop (a reactive attribute). */\n readonly hasDynamicAttr: boolean;\n /** This node wires one or more DOM event handlers. */\n readonly hasEvents: boolean;\n /** This node is a keyed reactive list. */\n readonly isList: boolean;\n /** This node is a conditional (0..1 branch) region. */\n readonly isConditional: boolean;\n}\n\nexport interface GraphAnalysisSummary {\n readonly totalNodes: number;\n readonly staticNodes: number;\n readonly staticSubtrees: number;\n readonly dynamicTextNodes: number;\n readonly dynamicAttrNodes: number;\n readonly eventNodes: number;\n readonly lists: number;\n readonly conditionals: number;\n}\n\nexport interface GraphAnalysis {\n readonly nodes: ReadonlyMap<NodeId, NodeAnalysis>;\n readonly summary: GraphAnalysisSummary;\n}\n\n/**\n * Analyze a fully-built graph. O(n) single post-order pass; allocates one small\n * record per node. Safe to skip entirely when neither hydration nor diagnostics\n * need it.\n */\nexport function analyzeGraph(graph: ApplicationGraph): GraphAnalysis {\n const nodes = new Map<NodeId, NodeAnalysis>();\n const summary = {\n totalNodes: 0, staticNodes: 0, staticSubtrees: 0, dynamicTextNodes: 0,\n dynamicAttrNodes: 0, eventNodes: 0, lists: 0, conditionals: 0,\n };\n\n const visit = (node: GraphNode): boolean => {\n // Post-order: children first so subtree rollup is exact.\n let allChildrenStatic = true;\n for (const child of node.children) {\n const childSubtreeStatic = visit(child);\n if (!childSubtreeStatic) allChildrenStatic = false;\n }\n\n let hasDynamicText = false;\n let hasDynamicAttr = false;\n for (const ref of node.stateRefs) {\n if (TEXT_PROP_KEYS.has(ref.propKey)) hasDynamicText = true;\n else hasDynamicAttr = true;\n }\n const hasEvents = node.events.length > 0;\n const isList = node.type === 'reactive-list';\n const isConditional = node.type === 'conditional';\n // A portal relocates its children to a different DOM location (document.body)\n // at mount time, so its subtree is never a contiguous inline static blob.\n // Treating it as dynamic stops the static-subtree rollup at the portal, so\n // both SSR and hydration always take the real portal mount/hydrate branch\n // (which does the relocation) rather than emitting/adopting a raw HTML blob.\n const isPortal = node.type === 'portal';\n // A component owns per-instance lifecycle wiring (a `__component__<id>`\n // cleanup handler read at mount/hydrate). Treating it as dynamic stops the\n // static-subtree rollup at the component boundary so it always takes the\n // real mount/hydrate branch (which wires cleanups) instead of collapsing\n // into a serialized raw-HTML blob that would drop that per-instance wiring.\n const isComponent = node.type === 'component';\n // A `head` node contributes document metadata via a `__head__<id>` handler\n // wired at mount/hydrate (`wireHeadBehavior`). Treating it as dynamic stops\n // the static-subtree rollup at the head boundary so it always takes the real\n // mount/hydrate branch (which registers/cleans up the contribution) instead\n // of collapsing into a serialized raw-HTML blob that would drop that wiring.\n const isHead = node.type === 'head';\n const isStatic =\n node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional && !isPortal && !isComponent && !isHead;\n const isStaticSubtree = isStatic && allChildrenStatic;\n\n nodes.set(node.id, {\n isStatic, isStaticSubtree, hasDynamicText, hasDynamicAttr,\n hasEvents, isList, isConditional,\n });\n\n summary.totalNodes += 1;\n if (isStatic) summary.staticNodes += 1;\n if (isStaticSubtree) summary.staticSubtrees += 1;\n if (hasDynamicText) summary.dynamicTextNodes += 1;\n if (hasDynamicAttr) summary.dynamicAttrNodes += 1;\n if (hasEvents) summary.eventNodes += 1;\n if (isList) summary.lists += 1;\n if (isConditional) summary.conditionals += 1;\n\n return isStaticSubtree;\n };\n\n visit(graph.root);\n return { nodes, summary };\n}\n","/**\n * Diagnostic compiler-inspection mode (v1.2, spec §14).\n *\n * Produces a machine-readable (and optionally text-formatted) description of\n * what the compiler understands about an application: which nodes are static\n * vs dynamic, which carry dynamic text or attributes, which wire events, and\n * which are conditional regions or keyed lists — plus the hydration metadata\n * derived from that classification.\n *\n * This is a DIAGNOSTIC tool. It is not part of the runtime, is not consulted\n * during mount, and is tree-shakeable out of any app that never calls it.\n */\n\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport { analyzeGraph, type GraphAnalysisSummary } from './analyze.js';\n\nexport interface InspectedCompilationNode {\n readonly id: string;\n readonly type: string;\n readonly depth: number;\n readonly classification: 'static' | 'static-subtree-root' | 'dynamic';\n readonly dynamicText: boolean;\n readonly dynamicAttrs: boolean;\n readonly events: readonly string[];\n readonly boundProps: readonly string[];\n readonly isList: boolean;\n readonly isConditional: boolean;\n /** Hydration hint: how the hydration path should treat this node. */\n readonly hydration: 'adopt-static' | 'verify-dynamic';\n}\n\nexport interface CompilerInspection {\n readonly name: string;\n readonly version: string;\n readonly summary: GraphAnalysisSummary & {\n /** Fraction of nodes provably static (0..1). */\n readonly staticRatio: number;\n };\n readonly nodes: readonly InspectedCompilationNode[];\n}\n\n/**\n * Inspect a compiled/built graph and return a structured diagnostic report.\n * Purely observational — never mutates the graph.\n */\nexport function inspectCompilation(graph: ApplicationGraph): CompilerInspection {\n const analysis = analyzeGraph(graph);\n const nodes: InspectedCompilationNode[] = [];\n\n const walk = (node: GraphNode, depth: number): void => {\n const a = analysis.nodes.get(node.id);\n if (a !== undefined) {\n const classification: InspectedCompilationNode['classification'] = a.isStaticSubtree\n ? 'static-subtree-root'\n : a.isStatic\n ? 'static'\n : 'dynamic';\n nodes.push({\n id: node.id,\n type: node.type,\n depth,\n classification,\n dynamicText: a.hasDynamicText,\n dynamicAttrs: a.hasDynamicAttr,\n events: node.events.map((e) => e.type),\n boundProps: node.stateRefs.map((r) => r.propKey),\n isList: a.isList,\n isConditional: a.isConditional,\n hydration: a.isStaticSubtree ? 'adopt-static' : 'verify-dynamic',\n });\n }\n for (const child of node.children) walk(child, depth + 1);\n };\n walk(graph.root, 0);\n\n const staticRatio =\n analysis.summary.totalNodes === 0\n ? 0\n : analysis.summary.staticNodes / analysis.summary.totalNodes;\n\n return {\n name: graph.name,\n version: graph.version,\n summary: { ...analysis.summary, staticRatio: +staticRatio.toFixed(4) },\n nodes,\n };\n}\n\n/** Render an inspection as a compact human-readable text report. */\nexport function formatInspection(inspection: CompilerInspection): string {\n const s = inspection.summary;\n const lines: string[] = [];\n lines.push(`StreetUI compiler inspection — ${inspection.name} v${inspection.version}`);\n lines.push(\n ` nodes=${s.totalNodes} static=${s.staticNodes} ` +\n `staticSubtrees=${s.staticSubtrees} dynamicText=${s.dynamicTextNodes} ` +\n `dynamicAttrs=${s.dynamicAttrNodes} events=${s.eventNodes} ` +\n `lists=${s.lists} conditionals=${s.conditionals} ` +\n `staticRatio=${(s.staticRatio * 100).toFixed(1)}%`,\n );\n for (const n of inspection.nodes) {\n const flags: string[] = [];\n if (n.dynamicText) flags.push('text');\n if (n.dynamicAttrs) flags.push('attr:' + n.boundProps.join(','));\n if (n.events.length > 0) flags.push('on:' + n.events.join(','));\n if (n.isList) flags.push('list');\n if (n.isConditional) flags.push('cond');\n lines.push(\n ` ${' '.repeat(n.depth)}${n.type}#${n.id} [${n.classification}]` +\n (flags.length > 0 ? ` {${flags.join(' ')}}` : ''),\n );\n }\n return lines.join('\\n');\n}\n","/**\n * Static SSR Plan (v1.7, spec §4/§6) — internal.\n *\n * A compiler-derived plan that precomputes the verbatim HTML of every *maximal\n * static subtree* in an application graph. During SSR, the renderer emits that\n * precomputed string directly (via `ServerDOMAdapter.createRawHTML`) instead of\n * recursively constructing a `ServerElement`/`ServerText`/`NodeInstance` for\n * every node in the subtree. On the 10k-row `/users` corpus, ~100% of the node\n * mass lives in 10,000 static 8-node row subtrees, so collapsing each row into\n * one precomputed string removes the bulk of the mount-phase construction work.\n *\n * Design constraints honoured here:\n * - §3 REUSE the existing compiler analysis (`analyzeGraph`) to classify nodes;\n * no new/expensive analysis, and nothing runs during normal `compile()`.\n * - §5/§15 Only *maximal static-subtree roots* are collapsed. A dynamic region\n * (reactive-list container, conditional, dynamic-text/attr node) is never\n * treated as static — the list itself stays dynamic; only the provably-static\n * subtree *inside* each repeated item is precomputed.\n * - §8 The precomputed HTML is produced by the SAME mount + serialize pipeline\n * as the runtime path, so full-render output is byte-identical.\n * - §19 The plan retains ONLY strings keyed by GraphNode.id. No ServerDOM node,\n * NodeInstance or application object is retained (the throwaway build tree is\n * disposed + cleared). The per-app cache is a WeakMap, so a plan is released\n * when its CompiledApplication is collected.\n * - §24 Everything here is internal: not re-exported from the `streetui` or\n * `streetui/server` runtime barrels.\n *\n * This module is only ever imported by the SSR entry (`renderToString`), which\n * is itself reachable solely through the server path, so it tree-shakes out of\n * client bundles (§20, verified by bundle measurement).\n */\n\nimport type { NodeId } from '@streetui/core';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport type { CompiledApplication } from '@streetui/compiler';\nimport { analyzeGraph } from '@streetui/compiler/diagnostics';\nimport { ServerDOMAdapter } from '@streetui/dom';\nimport { createRenderContext } from './render-context.js';\nimport { mountNode } from './mount.js';\n\n/**\n * Internal representation of the static SSR plan: maximal static-subtree root\n * GraphNode.id → its precomputed, verbatim outer HTML. A plain `Map<string,\n * string>` is deliberate — it holds no DOM/application references (§19).\n */\nexport type StaticSSRPlan = ReadonlyMap<NodeId, string>;\n\n/**\n * Collect the ids of every *maximal* static-subtree root under `graph`.\n *\n * Walk from the root; when a node is itself a whole static subtree, it is a\n * maximal root — record it and stop (its static descendants are subsumed).\n * Otherwise descend into its children, so a dynamic node's individually-static\n * children are still captured (the mixed-tree case, §5). The `application` root\n * is never recorded: it maps onto the render container rather than emitting its\n * own element, so we always descend past it into its real top-level children.\n */\nfunction collectMaximalStaticRoots(graph: ApplicationGraph): GraphNode[] {\n const analysis = analyzeGraph(graph);\n const roots: GraphNode[] = [];\n\n const walk = (node: GraphNode): void => {\n if (node.type !== 'application') {\n const a = analysis.nodes.get(node.id);\n if (a !== undefined && a.isStaticSubtree) {\n roots.push(node);\n return;\n }\n }\n for (const child of node.children) walk(child);\n };\n\n walk(graph.root);\n return roots;\n}\n\n/**\n * Serialize the outer HTML of a single static subtree using the exact runtime\n * mount + serialize pipeline (so the bytes match a full render). The throwaway\n * tree is disposed immediately, so nothing is retained.\n */\nfunction serializeStaticSubtree(\n dom: ServerDOMAdapter,\n graph: ApplicationGraph,\n root: GraphNode,\n): string {\n const container = dom.createElement('div');\n // No `staticHTML` on this ctx → mountNode builds the subtree fully.\n const ctx = createRenderContext(dom, graph, container);\n const instance = mountNode(ctx, root, container);\n const html = dom.serializeInner(container);\n // Tear down (static subtrees open no subscriptions, but keep symmetry with\n // renderToString's lifecycle) and drop all references.\n instance.dispose();\n ctx.instances.clear();\n return html;\n}\n\n/**\n * Build the static SSR plan for a compiled application. O(n) analysis + one\n * mount/serialize per maximal static subtree. Returns an empty map when the app\n * has no static subtrees (e.g. a highly-dynamic page) — the SSR path then\n * behaves exactly as v1.6.\n */\nexport function buildStaticSSRPlan(compiled: CompiledApplication): StaticSSRPlan {\n const graph = compiled.graph;\n const roots = collectMaximalStaticRoots(graph);\n const plan = new Map<NodeId, string>();\n if (roots.length === 0) return plan;\n\n const dom = new ServerDOMAdapter();\n for (const root of roots) {\n plan.set(root.id, serializeStaticSubtree(dom, graph, root));\n }\n return plan;\n}\n\n/**\n * Per-application plan cache. A WeakMap keyed by the CompiledApplication so a\n * plan is built once and reused across renders, and is released together with\n * the compiled app it belongs to — no long-lived retention of app state (§19).\n */\nconst PLAN_CACHE = new WeakMap<CompiledApplication, StaticSSRPlan>();\n\n/** Get the cached static SSR plan for a compiled app, building it on first use. */\nexport function getStaticSSRPlan(compiled: CompiledApplication): StaticSSRPlan {\n let plan = PLAN_CACHE.get(compiled);\n if (plan === undefined) {\n plan = buildStaticSSRPlan(compiled);\n PLAN_CACHE.set(compiled, plan);\n }\n return plan;\n}\n","/**\n * Server-side rendering — `renderToString`.\n *\n * Runs the *exact same* mount pipeline used in the browser (`mountGraph`), but\n * against a `ServerDOMAdapter` that builds a lightweight in-memory node tree\n * instead of a real browser DOM. The tree is then serialized to a normal HTML\n * string. Because both browser and server share the DSL → Compiler → Graph →\n * Runtime → Renderer pipeline, there is no second, SSR-specific renderer and no\n * virtual DOM.\n *\n * Lifecycle (v0.4 rule #20): the initial synchronous mount may open signal\n * subscriptions (via `wireSignalBindings`/`wireReactiveList`). On the server\n * those would be live forever, so once the HTML is serialized we dispose the\n * root instance — tearing down every subscription and listener. SSR therefore\n * has a *render* lifecycle only; the live *runtime* lifecycle is established\n * later on the client by `hydrate`.\n */\n\nimport { ServerDOMAdapter } from '@streetui/dom';\nimport type { CompiledApplication } from '@streetui/compiler';\nimport { createRenderContext } from './render-context.js';\nimport { mountGraph } from './mount.js';\nimport { getStaticSSRPlan } from './static-ssr-plan.js';\n\nexport interface RenderToStringOptions {\n /**\n * Override the server DOM adapter (rarely needed). Defaults to a fresh\n * `ServerDOMAdapter` per call so concurrent renders never share state.\n */\n readonly domAdapter?: ServerDOMAdapter;\n /**\n * @internal — testing/benchmark knob for the v1.7 static SSR plan.\n *\n * `undefined` (default): use the per-app cached plan (build once, reuse).\n * `null`: disable the plan entirely — the exact v1.6 runtime mount path, used\n * by the byte-identity gate and A/B benchmark as the \"legacy\" baseline.\n * a map: use this explicit plan.\n *\n * Not part of the supported public API; output is byte-identical regardless\n * of this value (§8).\n */\n readonly staticPlan?: ReadonlyMap<string, string> | null;\n}\n\n/**\n * Render a compiled StreetUI application to an HTML string.\n *\n * The returned markup contains only the application's own elements (the\n * synthetic container is not emitted), so callers embed it wherever they mount\n * on the client — e.g. inside `<div id=\"app\">…</div>`.\n */\nexport function renderToString(\n compiled: CompiledApplication,\n options: RenderToStringOptions = {},\n): string {\n const dom = options.domAdapter ?? new ServerDOMAdapter();\n\n // Resolve the v1.7 static SSR plan: cached-by-default, `null` forces the v1.6\n // path, an explicit map is used as-is. Only maximal static-subtree roots are\n // collapsed; dynamic regions still mount through the runtime path (§5).\n const plan =\n options.staticPlan === null\n ? undefined\n : (options.staticPlan ?? getStaticSSRPlan(compiled));\n const staticHTML = plan !== undefined && plan.size > 0 ? plan : undefined;\n\n // Synthetic container — the application root maps onto it, and the app's\n // top-level nodes are appended directly into it (mirroring browser mount).\n const container = dom.createElement('div');\n\n const ctx = createRenderContext(dom, compiled.graph, container, undefined, staticHTML);\n const rootInstance = mountGraph(ctx);\n\n const html = dom.serializeInner(container);\n\n // Tear down any subscriptions/listeners opened during mount — the server has\n // no live runtime. (rule #20)\n rootInstance.dispose();\n ctx.instances.clear();\n\n return html;\n}\n","/**\n * StreetUI Test Renderer.\n *\n * Renders a StreetApp into a real (happy-dom / jsdom) DOM container\n * and exposes query helpers so tests can assert on structure/content\n * without importing the browser renderer directly.\n */\n\nimport { resetIdCounter } from '@streetui/core';\nimport { compile } from '@streetui/compiler';\nimport type { StreetApp } from '@streetui/dsl';\nimport { BrowserDOMAdapter } from '@streetui/dom';\nimport { createRenderer } from '@streetui/renderer';\nimport type { RenderHandle } from '@streetui/runtime';\n\nexport interface RenderResult {\n /** The root container element that was rendered into. */\n readonly container: HTMLElement;\n /** Unmount and clean up the render. */\n unmount(): void;\n /** Query a single element (throws if missing). */\n getByTag<K extends keyof HTMLElementTagNameMap>(tag: K): HTMLElementTagNameMap[K];\n /** Query all elements by tag. */\n getAllByTag<K extends keyof HTMLElementTagNameMap>(tag: K): Array<HTMLElementTagNameMap[K]>;\n /** Query by text content (partial match). */\n getByText(text: string): Element;\n /** Query all elements whose text content includes the given string. */\n getAllByText(text: string): Element[];\n /** Raw querySelector. */\n query(selector: string): Element | null;\n /** Raw querySelectorAll. */\n queryAll(selector: string): Element[];\n /** Assert element exists; return it. */\n find(selector: string): Element;\n /** Force a flush of any pending scheduler work. */\n flush(): void;\n /** The underlying render handle. */\n readonly handle: RenderHandle;\n}\n\n/**\n * Render a StreetApp into a detached DOM container.\n * Uses the real StreetUI renderer backed by happy-dom/jsdom.\n */\nexport function render(app: StreetApp): RenderResult {\n const compiled = compile(app);\n const container = document.createElement('div');\n document.body.appendChild(container);\n\n const renderer = createRenderer({ domAdapter: new BrowserDOMAdapter() });\n const handle = renderer.mount(compiled, container);\n\n return {\n container,\n handle,\n unmount() {\n handle.unmount();\n if (container.parentNode !== null) {\n container.parentNode.removeChild(container);\n }\n },\n flush() {\n handle.flush();\n },\n getByTag<K extends keyof HTMLElementTagNameMap>(tag: K): HTMLElementTagNameMap[K] {\n const el = container.querySelector(tag);\n if (el === null) {\n throw new Error(`[StreetUI Testing] Element <${tag}> not found in render output`);\n }\n return el as HTMLElementTagNameMap[K];\n },\n getAllByTag<K extends keyof HTMLElementTagNameMap>(tag: K): Array<HTMLElementTagNameMap[K]> {\n return Array.from(container.querySelectorAll(tag)) as Array<HTMLElementTagNameMap[K]>;\n },\n getByText(text: string): Element {\n const all = Array.from(container.querySelectorAll('*'));\n const match = all.find(el =>\n el.children.length === 0 && el.textContent?.includes(text),\n );\n if (match === undefined) {\n throw new Error(`[StreetUI Testing] No element with text \"${text}\" found`);\n }\n return match;\n },\n getAllByText(text: string): Element[] {\n return Array.from(container.querySelectorAll('*')).filter(el =>\n el.textContent?.includes(text),\n );\n },\n query(selector: string): Element | null {\n return container.querySelector(selector);\n },\n queryAll(selector: string): Element[] {\n return Array.from(container.querySelectorAll(selector));\n },\n find(selector: string): Element {\n const el = container.querySelector(selector);\n if (el === null) {\n throw new Error(`[StreetUI Testing] Selector \"${selector}\" matched nothing`);\n }\n return el;\n },\n };\n}\n\n/** Render and automatically clean up after the test. */\nexport function renderOnce(\n app: StreetApp,\n testFn: (result: RenderResult) => void | Promise<void>,\n): Promise<void> {\n const result = render(app);\n return Promise.resolve(testFn(result)).finally(() => {\n result.unmount();\n resetIdCounter();\n });\n}\n","/**\n * StreetUI update scheduler.\n *\n * Responsibilities:\n * - Queue update callbacks\n * - Batch synchronous enqueues into a single microtask flush\n * - Guarantee ordering: higher priority jobs flush first\n * - Prevent duplicate work for the same job key\n * - Allow synchronous flush for tests\n */\n\nexport type Priority = 'immediate' | 'normal' | 'idle';\n\nconst PRIORITY_ORDER: Record<Priority, number> = {\n immediate: 0,\n normal: 1,\n idle: 2,\n};\n\nexport interface Job {\n /** Unique key — if another job with the same key is already queued, it is replaced. */\n readonly key: string;\n readonly priority: Priority;\n readonly fn: () => void;\n}\n\n/**\n * Optional error-reporting hook (v0.9 §26/§27). Structurally compatible with\n * `@streetui/core`'s `DiagnosticSink` (the `error` method) so an application can\n * route swallowed scheduler-job failures through its own logger instead of the\n * default `console.error`. Kept as a local structural type so the scheduler\n * stays dependency-free; no network, no telemetry. When unset, behaviour is\n * exactly as before.\n */\nexport interface SchedulerDiagnostics {\n error?(message: string, context?: unknown): void;\n}\n\nexport class Scheduler {\n private readonly _queue: Map<string, Job> = new Map();\n private _flushScheduled = false;\n private _flushing = false;\n private _diagnostics: SchedulerDiagnostics | undefined = undefined;\n\n /**\n * Install an optional diagnostic sink for swallowed job errors. Pass\n * `undefined` to restore the default `console.error` reporting. Additive and\n * opt-in — the scheduler never sends anything anywhere on its own.\n */\n setDiagnostics(sink: SchedulerDiagnostics | undefined): void {\n this._diagnostics = sink;\n }\n\n /** Total jobs currently queued. */\n get size(): number {\n return this._queue.size;\n }\n\n /** True if a flush has been scheduled but not yet executed. */\n get isPending(): boolean {\n return this._flushScheduled;\n }\n\n /**\n * Enqueue a job. If a job with the same key exists, the new one replaces it\n * (allowing callers to coalesce repeated updates for the same node).\n */\n schedule(job: Job): void {\n this._queue.set(job.key, job);\n if (!this._flushScheduled && !this._flushing) {\n this._flushScheduled = true;\n this._scheduleMicrotask();\n }\n }\n\n /** Schedule multiple jobs atomically. */\n scheduleAll(jobs: readonly Job[]): void {\n for (const job of jobs) {\n this._queue.set(job.key, job);\n }\n if (!this._flushScheduled && !this._flushing && this._queue.size > 0) {\n this._flushScheduled = true;\n this._scheduleMicrotask();\n }\n }\n\n /**\n * Cancel a queued job by key. No-op if not queued.\n */\n cancel(key: string): void {\n this._queue.delete(key);\n }\n\n /**\n * Synchronously flush all queued jobs (sorted by priority).\n * Useful in tests and for immediate rendering.\n */\n flush(): void {\n if (this._flushing) return;\n this._flushScheduled = false;\n this._flushing = true;\n\n const jobs = Array.from(this._queue.values()).sort(\n (a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority],\n );\n this._queue.clear();\n\n try {\n for (const job of jobs) {\n try {\n job.fn();\n } catch (err) {\n // Isolate job failures — report and continue so remaining jobs still run.\n if (this._diagnostics?.error) {\n this._diagnostics.error(`Scheduler job \"${job.key}\" threw`, err);\n } else {\n console.error(`[Scheduler] Job \"${job.key}\" threw:`, err);\n }\n }\n }\n } finally {\n this._flushing = false;\n }\n }\n\n /** Clear all pending jobs without executing them. */\n clear(): void {\n this._queue.clear();\n this._flushScheduled = false;\n }\n\n private _scheduleMicrotask(): void {\n Promise.resolve().then(() => {\n if (this._flushScheduled) {\n this.flush();\n }\n });\n }\n}\n\n/** The shared global scheduler instance. */\nexport const scheduler = new Scheduler();\n\n/** Convenience: schedule a normal-priority job. */\nexport function scheduleUpdate(key: string, fn: () => void): void {\n scheduler.schedule({ key, priority: 'normal', fn });\n}\n\n/** Convenience: schedule an immediate-priority job. */\nexport function scheduleImmediate(key: string, fn: () => void): void {\n scheduler.schedule({ key, priority: 'immediate', fn });\n}\n\n/** Convenience: flush the global scheduler synchronously. */\nexport function flushSync(): void {\n scheduler.flush();\n}\n","/**\n * Higher-level testing helpers: role/text queries, update flushing, async\n * waiting, and a first-class SSR → hydrate → assert workflow.\n *\n * These build on the same real renderer the app uses — no private-graph access,\n * no second assertion framework. They exist so a test does not have to\n * reimplement server-render/hydrate plumbing or poll for async resource state\n * by hand.\n */\n\nimport { resetIdCounter } from '@streetui/core';\nimport { flushSync } from '@streetui/scheduler';\nimport { compile } from '@streetui/compiler';\nimport type { StreetApp } from '@streetui/dsl';\nimport { BrowserDOMAdapter } from '@streetui/dom';\nimport {\n createRenderer,\n renderToString,\n type HydrationDiagnostic,\n createHydrationDiagnosticCollector,\n} from '@streetui/renderer';\nimport type { RenderHandle } from '@streetui/runtime';\n\n// ── Update flushing & async waiting ─────────────────────────────────────────\n\n/**\n * Flush all pending scheduler work, then yield once to the microtask queue so\n * promise-driven updates (e.g. a resolved `resource` loader) are applied. Await\n * this after triggering a change that schedules a DOM patch.\n */\nexport async function flushUpdates(): Promise<void> {\n flushSync();\n await Promise.resolve();\n flushSync();\n}\n\nexport interface WaitForOptions {\n /** Give up after this many milliseconds (default 1000). */\n readonly timeout?: number;\n /** Delay between attempts in milliseconds (default 10). */\n readonly interval?: number;\n}\n\n/**\n * Poll `check` until it returns a truthy value (or stops throwing), flushing\n * updates between attempts. Rejects with the last error/tiemout after the\n * deadline. Use for assertions that become true only after async work settles.\n */\nexport async function waitFor<T>(\n check: () => T,\n options: WaitForOptions = {},\n): Promise<T> {\n const timeout = options.timeout ?? 1000;\n const interval = options.interval ?? 10;\n const deadline = Date.now() + timeout;\n let lastError: unknown;\n\n for (;;) {\n await flushUpdates();\n try {\n const result = check();\n if (result) return result;\n lastError = new Error('[StreetUI Testing] waitFor: condition was falsy');\n } catch (err) {\n lastError = err;\n }\n if (Date.now() >= deadline) {\n throw lastError instanceof Error\n ? lastError\n : new Error(String(lastError));\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n}\n\n// ── Interaction helpers (§20) ───────────────────────────────────────────────\n\n/** A minimal writable-boolean seam (an overlay `open` signal, typically). */\nexport interface BooleanControl {\n set(value: boolean): void;\n}\n\n/** Focus `el` (no-op if it exposes no `focus`). Intentful wrapper for tests. */\nexport function focus(el: Element): void {\n (el as unknown as { focus?: () => void }).focus?.();\n}\n\n/** Blur `el` (no-op if it exposes no `blur`). */\nexport function blur(el: Element): void {\n (el as unknown as { blur?: () => void }).blur?.();\n}\n\n/**\n * Dispatch a bubbling, cancelable `keydown` for `key` on `el` (defaulting to the\n * currently-focused element). Extra `init` fields (e.g. `{ shiftKey: true }`)\n * are forwarded. Use for keyboard-interaction assertions (Escape, Tab, arrows).\n */\nexport function pressKey(\n key: string,\n el: Element | null = document.activeElement,\n init: KeyboardEventInit = {},\n): void {\n if (el === null) return;\n el.dispatchEvent(\n new KeyboardEvent('keydown', { key, bubbles: true, cancelable: true, ...init }),\n );\n}\n\n/**\n * Simulate a pointer interaction OUTSIDE `container` — a `mousedown` + `click`\n * on `document.body` (or `target` if given). Drives \"click-away to dismiss\"\n * behaviour without the test constructing events by hand. If `target` is inside\n * `container` this throws, so a mistake is loud rather than a silent no-op.\n */\nexport function clickOutside(container: Element, target: Element = document.body): void {\n if (container.contains(target)) {\n throw new Error('[StreetUI Testing] clickOutside: target is inside the container');\n }\n target.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));\n target.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));\n}\n\n/**\n * Open an overlay by flipping its `open` control to `true`, then flush so the\n * panel mounts and its enter/focus wiring runs. Overlay visibility is app-owned\n * state (§18) — a plain signal — so this is a thin, intentful wrapper over\n * `set(true)` + {@link flushUpdates}.\n */\nexport async function openOverlay(open: BooleanControl): Promise<void> {\n open.set(true);\n await flushUpdates();\n}\n\n/** Close an overlay by flipping its `open` control to `false`, then flush. */\nexport async function closeOverlay(open: BooleanControl): Promise<void> {\n open.set(false);\n await flushUpdates();\n}\n\n/**\n * Settle a CSS transition on `el` deterministically: dispatch the\n * `transitionend` the controller listens for (happy-dom fires none of its own),\n * then flush pending work so any deferred leave-teardown (DOM removal, dispose,\n * detach) completes. Await this after toggling a transitioned element to assert\n * its post-animation state without depending on the fallback timeout.\n */\nexport async function waitForTransition(el: Element): Promise<void> {\n el.dispatchEvent(new Event('transitionend', { bubbles: true }));\n await flushUpdates();\n}\n\n// ── Text / role queries (container-scoped) ──────────────────────────────────\n\n/** Find the first leaf element whose text content includes `text`. */\nexport function findByText(container: Element, text: string): Element {\n const match = Array.from(container.querySelectorAll('*')).find(\n (el) => el.children.length === 0 && (el.textContent?.includes(text) ?? false),\n );\n if (match === undefined) {\n throw new Error(`[StreetUI Testing] No element with text \"${text}\" found`);\n }\n return match;\n}\n\nexport interface ByRoleOptions {\n /** Restrict to elements whose accessible name includes this string. */\n readonly name?: string;\n}\n\n/** The implicit ARIA role for a plain HTML element, when it has one. */\nfunction implicitRole(el: Element): string | null {\n const tag = el.tagName.toLowerCase();\n switch (tag) {\n case 'button':\n return 'button';\n case 'a':\n return el.hasAttribute('href') ? 'link' : null;\n case 'nav':\n return 'navigation';\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n return 'heading';\n case 'input': {\n const type = (el.getAttribute('type') ?? 'text').toLowerCase();\n if (type === 'checkbox') return 'checkbox';\n if (type === 'radio') return 'radio';\n if (type === 'button' || type === 'submit') return 'button';\n return 'textbox';\n }\n case 'form':\n return 'form';\n default:\n return null;\n }\n}\n\n/** The accessible name approximation for an element (aria-label or text). */\nfunction accessibleName(el: Element): string {\n return (el.getAttribute('aria-label') ?? el.textContent ?? '').trim();\n}\n\n/**\n * Find all elements matching an ARIA `role` — explicit `role=\"…\"` first, then\n * the element's implicit role. Optionally filter by accessible name.\n */\nexport function findAllByRole(\n container: Element,\n role: string,\n options: ByRoleOptions = {},\n): Element[] {\n const all = Array.from(container.querySelectorAll('*'));\n return all.filter((el) => {\n const explicit = el.getAttribute('role');\n const matches = explicit === role || (explicit === null && implicitRole(el) === role);\n if (!matches) return false;\n if (options.name !== undefined) {\n return accessibleName(el).includes(options.name);\n }\n return true;\n });\n}\n\n/** Find the single element matching a role (throws if none/ambiguous). */\nexport function findByRole(\n container: Element,\n role: string,\n options: ByRoleOptions = {},\n): Element {\n const matches = findAllByRole(container, role, options);\n if (matches.length === 0) {\n const named = options.name !== undefined ? ` with name \"${options.name}\"` : '';\n throw new Error(`[StreetUI Testing] No element with role \"${role}\"${named} found`);\n }\n if (matches.length > 1) {\n throw new Error(\n `[StreetUI Testing] Found ${matches.length} elements with role \"${role}\" — refine with { name }`,\n );\n }\n return matches[0]!;\n}\n\n// ── First-class SSR → hydrate → assert workflow ─────────────────────────────\n\nexport interface HydrateTestOptions {\n /** Collect hydration mismatch diagnostics (dev-style) during hydration. */\n readonly collectDiagnostics?: boolean;\n}\n\nexport interface HydrateTestResult {\n /** The container holding the server HTML, now hydrated live. */\n readonly container: HTMLElement;\n /** The server-produced HTML string (before hydration). */\n readonly serverHtml: string;\n /** The live render handle from hydration. */\n readonly handle: RenderHandle;\n /** Hydration mismatch diagnostics (empty unless collectDiagnostics + a real mismatch). */\n readonly diagnostics: readonly HydrationDiagnostic[];\n /** Flush pending scheduler work. */\n flush(): void;\n /** Unmount and detach the container. */\n unmount(): void;\n}\n\n/**\n * Render `build` on the \"server\" to HTML, mount that HTML into a container,\n * then hydrate the SAME app against it — exactly the production SSR path. The\n * builder is invoked twice (server then client) with `resetIdCounter` between,\n * so deterministic ids line up. Assert node identity, behavior, and (optionally)\n * that hydration reported no mismatches.\n */\nexport function renderServerThenHydrate(\n build: () => StreetApp,\n options: HydrateTestOptions = {},\n): HydrateTestResult {\n resetIdCounter();\n const serverHtml = renderToString(compile(build()));\n\n const container = document.createElement('div');\n container.innerHTML = serverHtml;\n document.body.appendChild(container);\n\n const collector = options.collectDiagnostics === true\n ? createHydrationDiagnosticCollector()\n : undefined;\n\n resetIdCounter();\n const renderer = createRenderer({\n domAdapter: new BrowserDOMAdapter(),\n ...(collector !== undefined ? { hydrationDiagnostics: collector.sink } : {}),\n });\n const handle = renderer.hydrate(compile(build()), container);\n\n return {\n container,\n serverHtml,\n handle,\n diagnostics: collector?.diagnostics ?? [],\n flush() {\n handle.flush();\n },\n unmount() {\n handle.unmount();\n if (container.parentNode !== null) container.parentNode.removeChild(container);\n },\n };\n}\n","/**\n * Transition configuration (§2, §4).\n *\n * A `TransitionConfig` is a pure, declarative description of a CSS class-based\n * enter/leave transition — the engine choice for this milestone. It contains NO\n * DOM references, NO timers and NO browser-only APIs, so it is safe to build on\n * the server (where it is simply ignored — see the renderer's SSR guard) and to\n * carry on a graph handler (`__transition__<nodeId>`) alongside the existing\n * `__overlay__`/`__component__` descriptors.\n *\n * The class model follows the widely-understood enter/leave convention:\n *\n * enter: [enterActive (+ enter) whole phase] · enterFrom (start) → enterTo (end)\n * leave: [leaveActive (+ leave) whole phase] · leaveFrom (start) → leaveTo (end)\n *\n * `name` is a shorthand that expands to `${name}-enter-from`,\n * `${name}-enter-active`, `${name}-enter-to` and the leave equivalents; explicit\n * class fields override the derived ones. Because the classes are just strings,\n * SSR output is deterministic (no class is applied on the server at all — the\n * controller is browser-only), satisfying §4/§21.\n */\nexport interface TransitionConfig {\n /** Shorthand base: expands to `${name}-enter-from`, `${name}-enter-active`, … */\n readonly name?: string;\n /** Class(es) present for the whole enter phase (in addition to `enterActive`). */\n readonly enter?: string;\n /** Class(es) applied at the start of enter, removed on the next frame. */\n readonly enterFrom?: string;\n /** Class(es) present for the whole enter phase (where the CSS `transition` lives). */\n readonly enterActive?: string;\n /** Class(es) added on the next frame, removed when enter completes. */\n readonly enterTo?: string;\n /** Class(es) present for the whole leave phase (in addition to `leaveActive`). */\n readonly leave?: string;\n /** Class(es) applied at the start of leave, removed on the next frame. */\n readonly leaveFrom?: string;\n /** Class(es) present for the whole leave phase (where the CSS `transition` lives). */\n readonly leaveActive?: string;\n /** Class(es) added on the next frame, removed when leave completes. */\n readonly leaveTo?: string;\n /**\n * Also animate the very first appearance (initial mount). Hydration never\n * animates appear (the DOM is already present and correct); this only affects\n * fresh browser mounts. Defaults to false.\n */\n readonly appear?: boolean;\n /**\n * Fallback completion timeout in milliseconds. A transition normally completes\n * on the element's `transitionend`/`animationend`. This timeout is the safety\n * net for (a) transitions that fire no such event and (b) test DOMs like\n * happy-dom that dispatch no transition events at all — making tests\n * deterministic without a real browser (§24). Defaults to 1000. Use a small\n * value (or 0 → next macrotask) in tests.\n */\n readonly duration?: number;\n}\n\n/**\n * The resolved, ready-to-apply form of a {@link TransitionConfig}: each phase's\n * classes are pre-split into arrays so the controller applies/removes them with\n * no per-run string parsing. Produced once by {@link resolveTransition} at wire\n * time (browser only).\n */\nexport interface ResolvedTransition {\n /** enter classes present for the whole phase (base `enter` + `enterActive`). */\n readonly enterActive: readonly string[];\n /** enter start classes (removed next frame). */\n readonly enterFrom: readonly string[];\n /** enter end classes (added next frame). */\n readonly enterTo: readonly string[];\n readonly leaveActive: readonly string[];\n readonly leaveFrom: readonly string[];\n readonly leaveTo: readonly string[];\n readonly appear: boolean;\n readonly duration: number;\n}\n\n/** Split a class string on whitespace into a de-duplicated array (empty-safe). */\nfunction classes(value: string | undefined): string[] {\n if (value === undefined) return [];\n const out: string[] = [];\n for (const token of value.split(/\\s+/)) {\n if (token.length > 0 && !out.includes(token)) out.push(token);\n }\n return out;\n}\n\n/** Merge two class arrays, preserving order and dropping duplicates. */\nfunction merge(a: string[], b: string[]): string[] {\n const out = [...a];\n for (const token of b) if (!out.includes(token)) out.push(token);\n return out;\n}\n\n/**\n * Resolve a {@link TransitionConfig} into applied class arrays. The `name`\n * shorthand supplies defaults; any explicit field overrides the derived class\n * for that phase-slot (still merged with `enter`/`leave` base classes).\n */\nexport function resolveTransition(config: TransitionConfig): ResolvedTransition {\n const n = config.name;\n const enterActive = merge(\n classes(config.enter),\n classes(config.enterActive ?? (n !== undefined ? `${n}-enter-active` : undefined)),\n );\n const leaveActive = merge(\n classes(config.leave),\n classes(config.leaveActive ?? (n !== undefined ? `${n}-leave-active` : undefined)),\n );\n return {\n enterActive,\n enterFrom: classes(config.enterFrom ?? (n !== undefined ? `${n}-enter-from` : undefined)),\n enterTo: classes(config.enterTo ?? (n !== undefined ? `${n}-enter-to` : undefined)),\n leaveActive,\n leaveFrom: classes(config.leaveFrom ?? (n !== undefined ? `${n}-leave-from` : undefined)),\n leaveTo: classes(config.leaveTo ?? (n !== undefined ? `${n}-leave-to` : undefined)),\n appear: config.appear ?? false,\n duration: config.duration ?? 1000,\n };\n}\n\n/** Runtime brand check for a transition descriptor value. */\nexport function isTransitionConfig(value: unknown): value is TransitionConfig {\n if (value === null || typeof value !== 'object') return false;\n const o = value as Record<string, unknown>;\n // A config is meaningful only if it carries at least one class source.\n return (\n typeof o['name'] === 'string' ||\n typeof o['enter'] === 'string' ||\n typeof o['enterActive'] === 'string' ||\n typeof o['enterFrom'] === 'string' ||\n typeof o['leave'] === 'string' ||\n typeof o['leaveActive'] === 'string' ||\n typeof o['leaveFrom'] === 'string'\n );\n}\n","/**\n * Document head / metadata model (2.0 §1–§3).\n *\n * `head({...})` is a first-class StreetUI primitive for declaring document\n * metadata — title, meta, link, canonical, Open Graph, Twitter/X, robots,\n * theme-color and favicon. It is NOT a copy of another framework's API: it is\n * expressed on StreetUI's own component/graph model. A `head()` call creates a\n * `'head'` graph node (rendered as a neutral inline anchor, like a portal) and\n * registers a `__head__<nodeId>` descriptor — exactly the handler-registry\n * convention used by `__overlay__`/`__transition__`/`__component__`. The\n * renderer reads that descriptor to:\n *\n * • apply the contribution to `document.head` on the browser\n * (`wireHeadBehavior`), adopting server-emitted tags on hydration so there\n * are no duplicates, and cleaning up its own tags on unmount / route change;\n * • emit only the active graph's merged metadata as an HTML string on the\n * server (`renderHead`).\n *\n * This module is pure and DOM-free (like `transition.ts`): it defines the config\n * shape and normalises it into an ordered list of {@link HeadEntry} with stable\n * *dedup keys*. All merge/precedence/DOM work happens in the renderer, keyed by\n * these entries.\n *\n * ── Deduplication & precedence (§3) ──────────────────────────────────────────\n * Every entry carries a `dedupKey`. When several `head()` nodes are live at once\n * (e.g. an app-level default, a route-level `head()`, and a component-level\n * `head()`), the renderer merges all of their entries and, for each `dedupKey`,\n * the LAST contribution in document order wins. Document order is pre-order DFS\n * = mount order, so a `head()` declared deeper/later (a route or a component\n * nested inside the app shell) deterministically overrides an app-level default\n * for the same key. Removing that node (navigating away, unmounting the\n * component) re-exposes the previously-shadowed default. `<title>` and each\n * single-instance meta/link (description, robots, theme-color, viewport,\n * charset, canonical, favicon, and each og: or twitter: property) collapse to one\n * effective tag; generic `meta[]`/`link[]` array entries are keyed by their\n * identifying attributes so independent tags coexist.\n */\n\nimport type { ReadonlySignal, Signal } from '@streetui/state';\n\n/** A head value that may be a literal string or a reactive signal of a string. */\nexport type BindableString = string | ReadonlySignal<string> | Signal<string>;\n\n/** A single `<meta>` descriptor. Provide exactly one identifying key. */\nexport interface MetaDescriptor {\n /** `name=\"…\"` (e.g. \"description\", \"robots\", \"theme-color\", \"twitter:card\"). */\n readonly name?: string;\n /** `property=\"…\"` (e.g. \"og:title\", \"og:image\") — the Open Graph convention. */\n readonly property?: string;\n /** `http-equiv=\"…\"` (e.g. \"content-security-policy\"). */\n readonly httpEquiv?: string;\n /** `charset=\"…\"` (e.g. \"utf-8\"). Standalone; no `content`. */\n readonly charset?: string;\n /** The tag's `content`. May be reactive. */\n readonly content?: BindableString;\n}\n\n/** A single `<link>` descriptor. `rel`+`href` identify it. */\nexport interface LinkDescriptor {\n readonly rel: string;\n readonly href: string;\n readonly sizes?: string;\n readonly type?: string;\n readonly media?: string;\n readonly as?: string;\n readonly crossorigin?: string;\n readonly hreflang?: string;\n}\n\n/**\n * Declarative document metadata. Every field is optional; convenience fields\n * (title/description/canonical/robots/themeColor/viewport/charset/favicon/\n * openGraph/twitter) expand into the same normalized entries as the raw\n * `meta`/`link` arrays, with single-instance dedup keys so a later `head()`\n * cleanly overrides an earlier one.\n */\nexport interface HeadMetadata {\n /** `<title>` text. May be reactive. Single-instance (dedup key `title`). */\n readonly title?: BindableString;\n /** `<meta name=\"description\">`. May be reactive. */\n readonly description?: BindableString;\n /** `<link rel=\"canonical\">` href. */\n readonly canonical?: string;\n /** `<meta name=\"robots\">` (e.g. \"index,follow\" / \"noindex\"). */\n readonly robots?: string;\n /** `<meta name=\"theme-color\">`. */\n readonly themeColor?: string;\n /** `<meta name=\"viewport\">`. */\n readonly viewport?: string;\n /** `<meta charset>`. */\n readonly charset?: string;\n /** Favicon: a shorthand for `<link rel=\"icon\">`. String = href, or a full descriptor. */\n readonly favicon?: string | LinkDescriptor;\n /** Open Graph properties — each key `k` becomes `<meta property=\"og:k\">`. Values may be reactive. */\n readonly openGraph?: Readonly<Record<string, BindableString>>;\n /** Twitter/X card properties — each key `k` becomes `<meta name=\"twitter:k\">`. Values may be reactive. */\n readonly twitter?: Readonly<Record<string, BindableString>>;\n /** Raw `<meta>` tags (for anything the convenience fields don't cover). */\n readonly meta?: readonly MetaDescriptor[];\n /** Raw `<link>` tags (stylesheets, preload, alternate, etc.). */\n readonly link?: readonly LinkDescriptor[];\n /** `<base href>` — single-instance. */\n readonly base?: string;\n}\n\n/**\n * A normalized head tag: one `<title>`, `<meta>`, `<link>` or `<base>`. Attr\n * values and the title's text may still be reactive (`BindableString`); the\n * renderer peeks them for SSR and subscribes to them on the browser. `dedupKey`\n * is what the merge collapses on.\n */\nexport interface HeadEntry {\n readonly tag: 'title' | 'meta' | 'link' | 'base';\n readonly dedupKey: string;\n /** Static + reactive attributes (no `undefined` values). */\n readonly attrs: Readonly<Record<string, BindableString>>;\n /** Text content — only meaningful for `tag === 'title'`. */\n readonly text?: BindableString;\n}\n\n/** The value a `__head__<id>` handler returns: this node's ordered contribution. */\nexport interface HeadContribution {\n readonly entries: readonly HeadEntry[];\n}\n\nfunction metaDedupKey(m: MetaDescriptor): string | undefined {\n if (m.charset !== undefined) return 'meta:charset';\n if (m.name !== undefined) return `meta:name=${m.name}`;\n if (m.property !== undefined) return `meta:property=${m.property}`;\n if (m.httpEquiv !== undefined) return `meta:http-equiv=${m.httpEquiv}`;\n return undefined;\n}\n\nfunction metaAttrs(m: MetaDescriptor): Record<string, BindableString> {\n const attrs: Record<string, BindableString> = {};\n if (m.charset !== undefined) attrs['charset'] = m.charset;\n if (m.name !== undefined) attrs['name'] = m.name;\n if (m.property !== undefined) attrs['property'] = m.property;\n if (m.httpEquiv !== undefined) attrs['http-equiv'] = m.httpEquiv;\n if (m.content !== undefined) attrs['content'] = m.content;\n return attrs;\n}\n\nfunction linkAttrs(l: LinkDescriptor): Record<string, BindableString> {\n const attrs: Record<string, BindableString> = { rel: l.rel, href: l.href };\n if (l.sizes !== undefined) attrs['sizes'] = l.sizes;\n if (l.type !== undefined) attrs['type'] = l.type;\n if (l.media !== undefined) attrs['media'] = l.media;\n if (l.as !== undefined) attrs['as'] = l.as;\n if (l.crossorigin !== undefined) attrs['crossorigin'] = l.crossorigin;\n if (l.hreflang !== undefined) attrs['hreflang'] = l.hreflang;\n return attrs;\n}\n\n/**\n * Normalise a {@link HeadMetadata} into an ordered list of {@link HeadEntry}.\n * Emission order within one `head()` is: charset → base → title → description →\n * canonical → robots → theme-color → viewport → favicon → openGraph → twitter →\n * explicit meta[] → explicit link[]. (Merge across nodes is document order; this\n * per-node order only affects the sequence of same-priority tags.)\n */\nexport function resolveHead(config: HeadMetadata): HeadContribution {\n const entries: HeadEntry[] = [];\n\n if (config.charset !== undefined) {\n entries.push({ tag: 'meta', dedupKey: 'meta:charset', attrs: { charset: config.charset } });\n }\n if (config.base !== undefined) {\n entries.push({ tag: 'base', dedupKey: 'base', attrs: { href: config.base } });\n }\n if (config.title !== undefined) {\n entries.push({ tag: 'title', dedupKey: 'title', attrs: {}, text: config.title });\n }\n if (config.description !== undefined) {\n entries.push({\n tag: 'meta',\n dedupKey: 'meta:name=description',\n attrs: { name: 'description', content: config.description },\n });\n }\n if (config.canonical !== undefined) {\n entries.push({\n tag: 'link',\n dedupKey: 'link:rel=canonical',\n attrs: { rel: 'canonical', href: config.canonical },\n });\n }\n if (config.robots !== undefined) {\n entries.push({\n tag: 'meta',\n dedupKey: 'meta:name=robots',\n attrs: { name: 'robots', content: config.robots },\n });\n }\n if (config.themeColor !== undefined) {\n entries.push({\n tag: 'meta',\n dedupKey: 'meta:name=theme-color',\n attrs: { name: 'theme-color', content: config.themeColor },\n });\n }\n if (config.viewport !== undefined) {\n entries.push({\n tag: 'meta',\n dedupKey: 'meta:name=viewport',\n attrs: { name: 'viewport', content: config.viewport },\n });\n }\n if (config.favicon !== undefined) {\n const l: LinkDescriptor =\n typeof config.favicon === 'string' ? { rel: 'icon', href: config.favicon } : config.favicon;\n // Favicons are single-instance by rel (rel=icon), so a later head() replaces\n // an earlier icon rather than stacking a second one.\n entries.push({ tag: 'link', dedupKey: `link:rel=${l.rel}`, attrs: linkAttrs(l) });\n }\n if (config.openGraph !== undefined) {\n for (const key of Object.keys(config.openGraph)) {\n const property = `og:${key}`;\n entries.push({\n tag: 'meta',\n dedupKey: `meta:property=${property}`,\n attrs: { property, content: config.openGraph[key]! },\n });\n }\n }\n if (config.twitter !== undefined) {\n for (const key of Object.keys(config.twitter)) {\n const name = `twitter:${key}`;\n entries.push({\n tag: 'meta',\n dedupKey: `meta:name=${name}`,\n attrs: { name, content: config.twitter[key]! },\n });\n }\n }\n if (config.meta !== undefined) {\n for (const m of config.meta) {\n const key = metaDedupKey(m);\n if (key === undefined) continue; // a meta with no identifying attribute is dropped\n entries.push({ tag: 'meta', dedupKey: key, attrs: metaAttrs(m) });\n }\n }\n if (config.link !== undefined) {\n for (const l of config.link) {\n // Generic links are keyed by rel+href so multiple independent links coexist\n // (unlike canonical/icon which are single-instance by rel).\n entries.push({ tag: 'link', dedupKey: `link:rel=${l.rel}:href=${l.href}`, attrs: linkAttrs(l) });\n }\n }\n\n return { entries };\n}\n\n/** Runtime brand check for a head-contribution descriptor value. */\nexport function isHeadContribution(value: unknown): value is HeadContribution {\n return (\n value !== null &&\n typeof value === 'object' &&\n Array.isArray((value as Record<string, unknown>)['entries'])\n );\n}\n","/**\n * StreetUI reactive signals — framework-owned reactivity, no external libraries.\n *\n * Architecture:\n * Signal<T> — writable, holds a value, notifies on change\n * DerivedSignal<T> — read-only, lazily computed from other signals\n * effect() — side-effect that re-runs when dependencies change\n * batch() — run multiple updates before notifying\n */\n\nexport type Subscriber<T> = (value: T) => void;\nexport type Unsubscribe = () => void;\n\n// ── Tracking ──────────────────────────────────────────────────────────────────\n\n/**\n * Any reactive source that can have downstream consumers attached.\n * Both Signal and DerivedSignal implement this.\n */\nexport interface ReactiveSource<T> {\n get(): T;\n peek(): T;\n subscribe(fn: Subscriber<T>): Unsubscribe;\n /** Internal: remove a downstream consumer. */\n _removeConsumer(consumer: ReactiveConsumer): void;\n}\n\n/**\n * A downstream consumer (DerivedSignal or Effect) that can be invalidated\n * and can register itself as depending on a source.\n */\nexport interface ReactiveConsumer {\n _invalidate(): void;\n /** Internal: called by a source to register a dependency. */\n _addSource(src: ReactiveSource<unknown>): void;\n}\n\n/** The active consumer being tracked during a computation. */\nlet _activeConsumer: ReactiveConsumer | null = null;\n\nfunction withConsumer<T>(consumer: ReactiveConsumer, fn: () => T): T {\n const prev = _activeConsumer;\n _activeConsumer = consumer;\n try {\n return fn();\n } finally {\n _activeConsumer = prev;\n }\n}\n\n// ── Batch state (must be before Signal class so .set() can reference it) ──────\n\n/** Depth counter — batches nest; only the outermost flush propagates. */\nlet _batchDepth = 0;\n\ninterface PendingFlush {\n signal: Signal<unknown>;\n value: unknown;\n}\n\n/**\n * Keyed by signal identity — last-write-wins for each signal within a batch.\n * An ordered Map preserves first-seen insertion order for stable flush sequence.\n */\nconst _pendingFlushes = new Map<Signal<unknown>, PendingFlush>();\n\nfunction _enqueueBatchFlush(sig: Signal<unknown>, value: unknown): void {\n _pendingFlushes.set(sig, { signal: sig, value });\n}\n\nfunction _drainBatch(): void {\n const flushes = [..._pendingFlushes.values()];\n _pendingFlushes.clear();\n for (const { signal: sig, value } of flushes) {\n sig._flushBatch(value);\n }\n}\n\n// ── Signal ────────────────────────────────────────────────────────────────────\n\nexport interface ReadonlySignal<T> {\n get(): T;\n peek(): T;\n subscribe(fn: Subscriber<T>): Unsubscribe;\n}\n\nexport class Signal<T> implements ReactiveSource<T>, ReadonlySignal<T> {\n protected _value: T;\n private readonly _subscribers: Set<Subscriber<T>> = new Set();\n private readonly _consumers: Set<ReactiveConsumer> = new Set();\n\n constructor(initial: T) {\n this._value = initial;\n }\n\n get(): T {\n if (_activeConsumer !== null) {\n this._consumers.add(_activeConsumer);\n _activeConsumer._addSource(this as ReactiveSource<unknown>);\n }\n return this._value;\n }\n\n peek(): T {\n return this._value;\n }\n\n set(value: T): void {\n if (Object.is(this._value, value)) return;\n this._value = value;\n if (_batchDepth > 0) {\n // Defer notification until the batch flushes.\n // The stored value is always the latest (last-write-wins for same signal).\n _enqueueBatchFlush(this as unknown as Signal<unknown>, value);\n } else {\n this._flush(value);\n }\n }\n\n update(fn: (current: T) => T): void {\n this.set(fn(this._value));\n }\n\n subscribe(fn: Subscriber<T>): Unsubscribe {\n this._subscribers.add(fn);\n return () => { this._subscribers.delete(fn); };\n }\n\n _removeConsumer(consumer: ReactiveConsumer): void {\n this._consumers.delete(consumer);\n }\n\n /**\n * Called by the batch machinery after the batch has completed.\n * Notifies subscribers with the final coalesced value.\n */\n _flushBatch(value: unknown): void {\n this._flush(value as T);\n }\n\n private _flush(value: T): void {\n for (const sub of [...this._subscribers]) sub(value);\n for (const consumer of [...this._consumers]) consumer._invalidate();\n }\n\n /**\n * @internal DevTools inspection only. The number of live observers\n * (direct subscribers plus derived/effect consumers). Read-only; never\n * mutates reactive state.\n */\n _observerCount(): number {\n return this._subscribers.size + this._consumers.size;\n }\n}\n\n// ── DerivedSignal ─────────────────────────────────────────────────────────────\n\nexport class DerivedSignal<T> implements ReactiveSource<T>, ReactiveConsumer, ReadonlySignal<T> {\n private _value: T | undefined = undefined;\n private _dirty = true;\n private _disposed = false;\n private readonly _fn: () => T;\n private readonly _subscribers: Set<Subscriber<T>> = new Set();\n /** All upstream sources this derived currently reads from. */\n private readonly _sources: Set<ReactiveSource<unknown>> = new Set();\n /** Downstream consumers that depend on this derived. */\n private readonly _consumers: Set<ReactiveConsumer> = new Set();\n\n constructor(fn: () => T) {\n this._fn = fn;\n }\n\n get(): T {\n // Register this derived with the outer consumer if any\n if (_activeConsumer !== null) {\n this._consumers.add(_activeConsumer);\n _activeConsumer._addSource(this as ReactiveSource<unknown>);\n }\n if (this._dirty) this._recompute();\n return this._value as T;\n }\n\n peek(): T {\n if (this._dirty) this._recompute();\n return this._value as T;\n }\n\n subscribe(fn: Subscriber<T>): Unsubscribe {\n // Eagerly compute so sources track this derived as a consumer\n if (this._dirty) this._recompute();\n this._subscribers.add(fn);\n return () => { this._subscribers.delete(fn); };\n }\n\n _addSource(src: ReactiveSource<unknown>): void {\n this._sources.add(src);\n }\n\n _removeConsumer(consumer: ReactiveConsumer): void {\n this._consumers.delete(consumer);\n }\n\n _invalidate(): void {\n if (this._disposed) return;\n this._dirty = true;\n const newVal = this.peek(); // recompute\n for (const sub of [...this._subscribers]) sub(newVal);\n for (const consumer of [...this._consumers]) consumer._invalidate();\n }\n\n private _recompute(): void {\n // Detach from all current sources before re-tracking\n for (const src of this._sources) src._removeConsumer(this);\n this._sources.clear();\n\n this._value = withConsumer(this, this._fn);\n this._dirty = false;\n }\n\n dispose(): void {\n this._disposed = true;\n for (const src of this._sources) src._removeConsumer(this);\n this._sources.clear();\n this._subscribers.clear();\n this._consumers.clear();\n }\n\n /**\n * @internal DevTools inspection only. Live observers (subscribers plus\n * downstream consumers). Read-only.\n */\n _observerCount(): number {\n return this._subscribers.size + this._consumers.size;\n }\n}\n\n// ── effect ────────────────────────────────────────────────────────────────────\n\nclass Effect implements ReactiveConsumer {\n private readonly _fn: () => void | (() => void);\n private _cleanup: (() => void) | undefined = undefined;\n private _disposed = false;\n private readonly _sources: Set<ReactiveSource<unknown>> = new Set();\n\n constructor(fn: () => void | (() => void)) {\n this._fn = fn;\n this._run();\n }\n\n _addSource(src: ReactiveSource<unknown>): void {\n this._sources.add(src);\n }\n\n _invalidate(): void {\n if (this._disposed) return;\n this._run();\n }\n\n private _run(): void {\n // Detach from all current sources before re-tracking\n for (const src of this._sources) src._removeConsumer(this);\n this._sources.clear();\n\n if (typeof this._cleanup === 'function') this._cleanup();\n const result = withConsumer(this, this._fn);\n this._cleanup = typeof result === 'function' ? result : undefined;\n }\n\n dispose(): void {\n this._disposed = true;\n for (const src of this._sources) src._removeConsumer(this);\n this._sources.clear();\n if (typeof this._cleanup === 'function') this._cleanup();\n this._cleanup = undefined;\n }\n}\n\n// ── Public API ─────────────────────────────────────────────────────────────────\n\nexport function signal<T>(initial: T): Signal<T> {\n return new Signal(initial);\n}\n\nexport function derived<T>(fn: () => T): DerivedSignal<T> {\n return new DerivedSignal(fn);\n}\n\nexport function effect(fn: () => void | (() => void)): Unsubscribe {\n const e = new Effect(fn);\n return () => e.dispose();\n}\n\n/**\n * Run multiple signal updates as an atomic batch.\n *\n * Within the callback, calls to signal.set() are deferred — each signal\n * accumulates its latest value. When the outermost batch() returns,\n * each modified signal fires its subscribers exactly once with the final\n * value. Nested batch() calls are supported; the flush only runs when the\n * outermost batch exits.\n *\n * Example:\n * batch(() => {\n * count.set(1);\n * count.set(2);\n * count.set(3);\n * });\n * // subscribers see count = 3 exactly once\n */\nexport function batch(fn: () => void): void {\n _batchDepth++;\n try {\n fn();\n } finally {\n _batchDepth--;\n if (_batchDepth === 0) {\n _drainBatch();\n }\n }\n}\n\n/** True when inside a batch() call. Useful for advanced scheduling integration. */\nexport function isBatching(): boolean {\n return _batchDepth > 0;\n}\n\n// ── Inspection (read-only, DevTools-facing) ─────────────────────────────────\n\n/** Whether a signal is writable (`signal()`) or computed (`derived()`). */\nexport type SignalKind = 'writable' | 'derived';\n\n/** Classify a reactive value as writable or derived. */\nexport function signalKind(source: ReadonlySignal<unknown>): SignalKind {\n return source instanceof DerivedSignal ? 'derived' : 'writable';\n}\n\n/**\n * The number of live observers on a signal — direct subscribers plus derived\n * or effect consumers — or `undefined` if the source does not expose the count.\n * Read-only; safe for DevTools. Never mutates reactive state.\n */\nexport function observerCount(source: ReadonlySignal<unknown>): number | undefined {\n const maybe = source as { _observerCount?: () => number };\n return typeof maybe._observerCount === 'function' ? maybe._observerCount() : undefined;\n}\n","/**\n * DSL builder implementations.\n *\n * Each builder wraps a GraphNode and provides the fluent API\n * for constructing the Semantic Application Graph via the DSL.\n *\n * Builders do NOT render anything — they only build the graph.\n */\n\nimport { ApplicationGraph, GraphNode, type Props } from '@streetui/graph';\nimport type {\n ContentDSL,\n ContainerDSL,\n SectionDSL,\n PageDSL,\n FormDSL,\n ListDSL,\n AppDSL,\n HeadingOptions,\n TextOptions,\n ButtonOptions,\n InputOptions,\n LinkOptions,\n ImageOptions,\n ContainerOptions,\n SectionOptions,\n FormOptions,\n ListOptions,\n PortalOptions,\n OverlayOptions,\n A11yOptions,\n Bindable,\n BindableText,\n TextValue,\n ErrorBoundaryOptions,\n ErrorSource,\n AsyncBoundaryBranches,\n PageBuilder,\n SectionBuilder,\n ContainerBuilder as ContainerBuilderFn,\n FormBuilder,\n ListBuilder,\n} from './dsl-types.js';\nimport type {\n ComponentContext,\n ComponentDefinition,\n ComponentRender,\n} from './component.js';\nimport type { TransitionConfig } from './transition.js';\nimport { resolveTransition } from './transition.js';\nimport type { HeadMetadata } from './head.js';\nimport { resolveHead } from './head.js';\nimport type { WhenOptions } from './dsl-types.js';\nimport { signal, derived, effect, type Signal, type ReadonlySignal, type Resource } from '@streetui/state';\n\n/**\n * A single reactive-list reconciliation descriptor (spec §15).\n *\n * Emitted by the `__listplan__<nodeId>` handler on every list change. `key` is\n * the item's identity-only reconciliation key (cheap to compute); `item` is the\n * source value *reference* used for identity short-circuiting; `sig()` computes\n * the content signature on demand (only when the reference changed); `build()`\n * materialises the full item subtree on demand (only for new/changed rows).\n */\nexport interface ListPlanEntry {\n readonly key: string;\n readonly item: unknown;\n readonly sig: () => string;\n readonly build: () => GraphNode;\n}\n\n// ── Signal helpers ────────────────────────────────────────────────────────────\n\nfunction isSignal(v: unknown): v is Signal<unknown> | ReadonlySignal<unknown> {\n return (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as Record<string, unknown>)['get'] === 'function' &&\n typeof (v as Record<string, unknown>)['subscribe'] === 'function'\n );\n}\n\n/** Register a signal binding on the node and return the current static value. */\nfunction bindValue<T>(\n graph: ApplicationGraph,\n node: GraphNode,\n propKey: string,\n value: Bindable<T>,\n): T {\n if (isSignal(value)) {\n const signalId = `${node.id}:${propKey}`;\n node.stateRefs.push({ signalId, propKey });\n graph.registerHandler(`__signal__${signalId}`, value as unknown as () => unknown);\n return (value as ReadonlySignal<T>).peek();\n }\n return value as T;\n}\n\n// ── Helper to build Props from ContainerOptions ───────────────────────────────\n\n/**\n * Copy accessibility options onto a props bag as their corresponding HTML/ARIA\n * attribute names. Values are written as strings (booleans become \"true\"/\"false\"\n * rather than being dropped) so ARIA state attributes render literally. These\n * flow to the DOM via the renderer's generic attribute pass — no ARIA-specific\n * renderer code is involved.\n */\nfunction applyA11yProps(props: Props, options: A11yOptions): void {\n if (options.role !== undefined) props['role'] = options.role;\n if (options.tabIndex !== undefined) props['tabindex'] = String(options.tabIndex);\n if (options.ariaLabel !== undefined) props['aria-label'] = options.ariaLabel;\n if (options.ariaLabelledBy !== undefined) props['aria-labelledby'] = options.ariaLabelledBy;\n if (options.ariaDescribedBy !== undefined) props['aria-describedby'] = options.ariaDescribedBy;\n if (options.ariaExpanded !== undefined) props['aria-expanded'] = String(options.ariaExpanded);\n if (options.ariaControls !== undefined) props['aria-controls'] = options.ariaControls;\n if (options.ariaHidden !== undefined) props['aria-hidden'] = String(options.ariaHidden);\n if (options.ariaLive !== undefined) props['aria-live'] = options.ariaLive;\n if (options.ariaCurrent !== undefined) props['aria-current'] = String(options.ariaCurrent);\n if (options.ariaInvalid !== undefined) props['aria-invalid'] = String(options.ariaInvalid);\n if (options.ariaRequired !== undefined) props['aria-required'] = String(options.ariaRequired);\n if (options.ariaModal !== undefined) props['aria-modal'] = String(options.ariaModal);\n if (options.ariaOwns !== undefined) props['aria-owns'] = options.ariaOwns;\n if (options.ariaActiveDescendant !== undefined) props['aria-activedescendant'] = options.ariaActiveDescendant;\n if (options.ariaHasPopup !== undefined) props['aria-haspopup'] = String(options.ariaHasPopup);\n if (options.ariaSelected !== undefined) props['aria-selected'] = String(options.ariaSelected);\n}\n\n/**\n * Register a `__transition__<nodeId>` descriptor for an element that opts into a\n * CSS class-based enter/leave transition (§2). Mirrors the `__overlay__` /\n * `__component__` handler pattern: the renderer reads it (browser only) to run\n * enter on mount and to defer removal/dispose until leave completes. Pure config\n * — no DOM, no timers — so it is inert on the server and pruned by\n * `graph._unregisterNodeHandlers` (§23). A no-op when no transition is supplied.\n */\nfunction registerTransition(\n graph: ApplicationGraph,\n node: GraphNode,\n config: TransitionConfig | undefined,\n): void {\n if (config === undefined) return;\n // Resolve to the pre-split class arrays at wire time so the renderer's\n // controller consumes a plain `ResolvedTransition` and never re-parses class\n // strings per run — and so the renderer needs no compile-time dependency on\n // this DSL package (it reads the descriptor structurally, exactly like\n // `__overlay__`/`__component__`).\n const resolved = resolveTransition(config);\n graph.registerHandler(\n `__transition__${node.id}`,\n (() => resolved) as unknown as () => unknown,\n );\n}\n\nfunction containerProps(options: ContainerOptions): Props {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n if (options.key !== undefined) props['key'] = options.key;\n applyA11yProps(props, options);\n return props;\n}\n\n// ── Reactive-list item keying ──────────────────────────────────────────────────\n//\n// The `listOf` DSL signature does not take an explicit key extractor, so we\n// derive a stable reconciliation key from each item. The key combines an\n// *identity* part (so reordering the same items reuses their DOM nodes) with a\n// *value signature* (so an item whose data changed is treated as a fresh node\n// and re-rendered rather than silently kept stale by the shallow reconciler).\n\nfunction itemIdentity(item: unknown, index: number): string {\n if (item !== null && typeof item === 'object') {\n const obj = item as Record<string, unknown>;\n if ('id' in obj) return `id:${String(obj['id'])}`;\n if ('key' in obj) return `key:${String(obj['key'])}`;\n return `idx:${index}`;\n }\n return `val:${String(item)}`;\n}\n\nfunction itemValueSignature(item: unknown): string {\n try {\n return JSON.stringify(item) ?? String(item);\n } catch {\n return String(item);\n }\n}\n\n/** Content signature used to detect in-place data changes of a stable item. */\nexport function reactiveListItemSignature(item: unknown): string {\n return itemValueSignature(item);\n}\n\n/** Stable, identity-only reconciliation key for a reactive-list item. */\nexport function reactiveListItemKey(item: unknown, index: number): string {\n return itemIdentity(item, index);\n}\n\n// ── Overlay kind configuration ──────────────────────────────────────────────────\n//\n// Each overlay builder (dialog/popover/tooltip/dropdown/toast) is the same\n// portal + `when(open, …)` panel + focus/keyboard behavior, differing only in\n// ARIA role, modality, whether it takes focus, and its escape/restore defaults.\n// This table captures those differences; `_overlay` does the shared assembly.\n\ninterface OverlayKindConfig {\n /** Default ARIA role for the panel. */\n readonly role: string;\n /** Trap + contain focus (modal semantics). */\n readonly modal: boolean;\n /** Move focus into the panel when it opens. */\n readonly takesFocus: boolean;\n /** Wire arrow/Home/End/Enter/Space roving-focus navigation (role=\"menu\"). */\n readonly menu?: boolean;\n /** Emit `aria-modal=\"true\"` on the panel. */\n readonly ariaModal: boolean;\n /** Emit an `aria-live` region on the panel (announcements). */\n readonly ariaLive?: 'polite' | 'assertive';\n /** Default for `closeOnEscape` when the caller does not specify it. */\n readonly defaultCloseOnEscape: boolean;\n /** Default for `restoreFocus` when the caller does not specify it. */\n readonly defaultRestoreFocus: boolean;\n}\n\nconst OVERLAY_KINDS = {\n dialog: {\n role: 'dialog', modal: true, takesFocus: true, ariaModal: true,\n defaultCloseOnEscape: true, defaultRestoreFocus: true,\n },\n popover: {\n role: 'dialog', modal: false, takesFocus: true, ariaModal: false,\n defaultCloseOnEscape: true, defaultRestoreFocus: true,\n },\n tooltip: {\n role: 'tooltip', modal: false, takesFocus: false, ariaModal: false,\n defaultCloseOnEscape: false, defaultRestoreFocus: false,\n },\n dropdown: {\n role: 'menu', modal: false, takesFocus: true, menu: true, ariaModal: false,\n defaultCloseOnEscape: true, defaultRestoreFocus: true,\n },\n toast: {\n role: 'status', modal: false, takesFocus: false, ariaModal: false,\n ariaLive: 'polite', defaultCloseOnEscape: false, defaultRestoreFocus: false,\n },\n} as const satisfies Record<string, OverlayKindConfig>;\n\n/** The opaque descriptor the renderer reads from `__overlay__<portalId>`. */\ninterface OverlayBehaviorDescriptor {\n readonly open: ReadonlySignal<boolean>;\n readonly modal: boolean;\n readonly takesFocus: boolean;\n readonly menu: boolean;\n readonly closeOnEscape: boolean;\n readonly restoreFocus: boolean;\n readonly initialFocusId?: string;\n readonly onClose?: () => void;\n}\n\n// ── Base content builder ──────────────────────────────────────────────────────\n\nclass ContentBuilderBase implements ContentDSL {\n constructor(\n protected readonly _node: GraphNode,\n protected readonly _graph: ApplicationGraph,\n ) {}\n\n heading(text: BindableText, options: HeadingOptions = {}): void {\n const props: Props = { level: options.level ?? 1 };\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('heading', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'text', text);\n node.setProp('text', resolved);\n }\n\n text(content: BindableText, options: TextOptions = {}): void {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('text', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'text', content);\n node.setProp('text', resolved);\n }\n\n button(label: BindableText, options: ButtonOptions = {}): void {\n const props: Props = {};\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('button', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'label', label);\n node.setProp('label', resolved);\n if (options.disabled !== undefined) {\n const resolvedDisabled = bindValue(this._graph, node, 'disabled', options.disabled);\n node.setProp('disabled', resolvedDisabled);\n }\n if (options.onClick !== undefined) {\n const handlerKey = `click:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onClick as () => unknown);\n node.addEvent({ type: 'click', handlerKey });\n }\n }\n\n input(options: InputOptions = {}): void {\n const props: Props = {};\n props['inputType'] = options.type ?? 'text';\n if (options.placeholder !== undefined) props['placeholder'] = options.placeholder;\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const nodeOpts: { key?: string; props: Props; parent: GraphNode } = {\n props,\n parent: this._node,\n };\n if (options.id !== undefined) nodeOpts.key = options.id;\n const node = this._graph.createNode('input', nodeOpts);\n\n // Two-way `bind` expands to a value binding + an input write-back. The type\n // system (BoundInputOptions vs ControlledInputOptions) guarantees `bind` is\n // never combined with explicit `value`/`onInput`, so there is no ambiguity.\n const bindSignal = options.bind;\n const valueBindable: Bindable<string> | undefined =\n bindSignal !== undefined ? bindSignal : options.value;\n const inputHandler: ((value: string) => void) | undefined =\n bindSignal !== undefined ? (v: string) => bindSignal.set(v) : options.onInput;\n\n if (valueBindable !== undefined) {\n const resolved = bindValue(this._graph, node, 'value', valueBindable);\n node.setProp('value', resolved);\n }\n if (options.disabled !== undefined) {\n const resolved = bindValue(this._graph, node, 'disabled', options.disabled);\n node.setProp('disabled', resolved);\n }\n if (inputHandler !== undefined) {\n const handlerKey = `input:${node.id}`;\n this._graph.registerHandler(handlerKey, inputHandler as () => unknown);\n node.addEvent({ type: 'input', handlerKey });\n }\n if (options.onChange !== undefined) {\n const handlerKey = `change:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onChange as () => unknown);\n node.addEvent({ type: 'change', handlerKey });\n }\n }\n\n image(options: ImageOptions): void {\n const props: Props = {\n src: options.src,\n alt: options.alt,\n };\n if (options.width !== undefined) props['width'] = options.width;\n if (options.height !== undefined) props['height'] = options.height;\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const nodeOpts: { key?: string; props: Props; parent: GraphNode } = {\n props,\n parent: this._node,\n };\n if (options.id !== undefined) nodeOpts.key = options.id;\n this._graph.createNode('image', nodeOpts);\n }\n\n link(label: BindableText, options: LinkOptions): void {\n const props: Props = {\n href: options.href,\n external: options.external ?? false,\n };\n if (options.class !== undefined) props['class'] = options.class;\n if (options.id !== undefined) props['id'] = options.id;\n applyA11yProps(props, options);\n const node = this._graph.createNode('link', { parent: this._node, props });\n const resolved = bindValue<TextValue>(this._graph, node, 'label', label);\n node.setProp('label', resolved);\n if (options.onClick !== undefined) {\n const handlerKey = `click:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onClick as () => unknown);\n node.addEvent({ type: 'click', handlerKey });\n }\n }\n}\n\n// ── Container builder ─────────────────────────────────────────────────────────\n\nclass ContainerBuilderBase extends ContentBuilderBase implements ContainerDSL {\n section(key: string, builder: SectionBuilder, options: SectionOptions = {}): void {\n const node = this._graph.createNode('section', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(this._graph, node, options.transition);\n builder(new SectionBuilderImpl(node, this._graph));\n }\n\n container(key: string, builder: ContainerBuilderFn, options: ContainerOptions = {}): void {\n const node = this._graph.createNode('container', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(this._graph, node, options.transition);\n builder(new ContainerBuilderImpl(node, this._graph));\n }\n\n list(key: string, builder: ListBuilder, options: ListOptions = {}): void {\n const node = this._graph.createNode('list', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(this._graph, node, options.transition);\n builder(new ListBuilderImpl(node, this._graph));\n }\n\n listOf<T>(\n key: string,\n items: Signal<T[]> | ReadonlySignal<T[]>,\n renderItem: (item: T, index: number, content: ContentDSL) => void,\n options: ListOptions = {},\n ): void {\n const graph = this._graph;\n const node = graph.createNode('reactive-list', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(graph, node, options.transition);\n\n // Register the driving signal so the runtime/renderer can subscribe to it.\n const signalId = `${node.id}:items`;\n node.stateRefs.push({ signalId, propKey: 'items' });\n graph.registerHandler(`__signal__${signalId}`, items as unknown as () => unknown);\n\n // Build a single detached list-item subtree for one item. The item's\n // reconciliation `key` is identity-only, and its value signature is stored\n // in the internal `_sig` prop so the renderer can detect (and apply a\n // targeted update for) a data change on an item whose identity is stable.\n const buildItem = (item: T, index: number): GraphNode => {\n const itemKey = reactiveListItemKey(item, index);\n const itemNode = graph.createNode('list-item', {\n key: itemKey,\n // `_item` records the source item *reference* so the reconciler can\n // short-circuit unchanged rows by identity (no signature hashing); `_sig`\n // is the content signature used to detect an in-place data change when the\n // reference differs. Both are internal metadata (leading `_`) and never\n // reach the DOM.\n props: {\n key: itemKey,\n _sig: reactiveListItemSignature(item),\n // The item reference is stored as opaque internal metadata (never\n // rendered); cast through `unknown` since `T` is not a `PropValue`.\n _item: item as unknown as Props[string],\n },\n });\n renderItem(item, index, new ContainerBuilderImpl(itemNode, graph));\n // Per-item enter/leave transition (§7). Registered on every item node so a\n // freshly-built row (append/prepend/change) carries it; keyed identity is\n // unaffected because the transition descriptor is keyed by node id and the\n // row's reconciliation key is derived separately.\n registerTransition(graph, itemNode, options.itemTransition);\n return itemNode;\n };\n\n // Lazy reconciliation plan (spec §15 — the measured keyed-list hot path).\n //\n // Instead of eagerly rebuilding all N item GraphNodes (and hashing every item\n // with JSON.stringify) on *every* emission — the dominant cost of the old\n // `buildAll` path — the renderer receives lightweight descriptors and only\n // materialises a subtree for rows that are genuinely new or whose data\n // actually changed. `key` is cheap (identity only); `sig()` and `build()` are\n // thunks the reconciler calls on demand.\n const buildPlan = (raw: unknown): ListPlanEntry[] => {\n const arr = Array.isArray(raw) ? (raw as T[]) : [];\n const plan: ListPlanEntry[] = new Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i]!;\n const index = i;\n plan[i] = {\n key: reactiveListItemKey(item, index),\n item,\n sig: () => reactiveListItemSignature(item),\n build: () => buildItem(item, index),\n };\n }\n return plan;\n };\n graph.registerHandler(`__listplan__${node.id}`, buildPlan as unknown as () => unknown);\n\n // Build the initial children into the graph so the first mount renders them.\n const current = isSignal(items)\n ? (items as ReadonlySignal<T[]>).peek()\n : (items as unknown as T[]);\n const initial = Array.isArray(current) ? current : [];\n initial.forEach((item, i) => {\n node.appendChild(buildItem(item, i));\n });\n }\n\n form(key: string, builder: FormBuilder, options: FormOptions = {}): void {\n const props: Props = containerProps(options);\n const node = this._graph.createNode('form', {\n key,\n parent: this._node,\n props,\n });\n registerTransition(this._graph, node, options.transition);\n if (options.onSubmit !== undefined) {\n const handlerKey = `submit:${node.id}`;\n this._graph.registerHandler(handlerKey, options.onSubmit as () => unknown);\n node.addEvent({ type: 'submit', handlerKey });\n }\n builder(new FormBuilderImpl(node, this._graph));\n }\n\n when(\n condition: Bindable<boolean>,\n builder: ContainerBuilderFn,\n elseBuilder?: ContainerBuilderFn,\n options: WhenOptions = {},\n ): void {\n const graph = this._graph;\n // A dedicated 'conditional' node reuses the reactive-list reconciliation\n // machinery (same signal subscription + keyed reconcile) but renders as a\n // neutral <div> rather than a <ul>. It holds zero or one child branch.\n const node = graph.createNode('conditional', {\n parent: this._node,\n props: containerProps({}),\n });\n\n // A transition on a `when` applies to whichever branch is mounted/removed\n // (§2). `appear` promotes the transition to a config that also animates the\n // branch present on the very first mount; the renderer distinguishes appear\n // from a reactive enter via the descriptor's `appear` flag.\n const branchTransition: TransitionConfig | undefined =\n options.transition !== undefined && options.appear === true\n ? { ...options.transition, appear: true }\n : options.transition;\n\n // Build the active branch as a single keyed container. Distinct keys for the\n // then/else branches make a flip a clean swap under the keyed reconciler.\n const buildBranch = (build: ContainerBuilderFn, tag: 'then' | 'else'): GraphNode => {\n const branchKey = `when-${tag}:${node.id}`;\n const branch = graph.createNode('container', {\n key: branchKey,\n props: { key: branchKey },\n });\n registerTransition(graph, branch, branchTransition);\n build(new ContainerBuilderImpl(branch, graph));\n return branch;\n };\n\n const buildAll = (raw: unknown): GraphNode[] => {\n if (raw) return [buildBranch(builder, 'then')];\n return elseBuilder !== undefined ? [buildBranch(elseBuilder, 'else')] : [];\n };\n\n if (isSignal(condition)) {\n const signalId = `${node.id}:items`;\n node.stateRefs.push({ signalId, propKey: 'items' });\n graph.registerHandler(`__signal__${signalId}`, condition as unknown as () => unknown);\n graph.registerHandler(`__listbuild__${node.id}`, buildAll as unknown as () => unknown);\n const current = (condition as ReadonlySignal<boolean>).peek();\n for (const child of buildAll(current)) node.appendChild(child);\n } else {\n // Static condition — resolve once at build time, no reactive wiring.\n for (const child of buildAll(condition)) node.appendChild(child);\n }\n }\n\n errorBoundary(\n id: string,\n builder: ContainerBuilderFn,\n options: ErrorBoundaryOptions,\n ): void {\n // Normalise the observed error source(s) into an array.\n const sources: ErrorSource[] =\n options.source === undefined\n ? []\n : Array.isArray(options.source)\n ? [...options.source]\n : [options.source];\n\n // The boundary's own captured error (from a synchronous build throw) and a\n // retry nonce that forces a re-evaluation even when the boolean is unchanged.\n const localError = signal<unknown>(undefined);\n const retryNonce = signal<number>(0);\n\n const readError = (): unknown => {\n const local = localError.peek();\n if (local !== undefined && local !== null) return local;\n for (const s of sources) {\n const e = s.peek();\n if (e !== undefined && e !== null) return e;\n }\n return undefined;\n };\n\n // Reactive condition: true while an error is present. Reads every input so a\n // change in any source (or a retry) re-runs the conditional.\n const hasError = derived<boolean>(() => {\n retryNonce.get();\n localError.get();\n for (const s of sources) s.get();\n return readError() !== undefined;\n });\n\n const retry = (): void => {\n localError.set(undefined);\n options.onRetry?.();\n // Force the body branch to re-attempt even if no observed value changed.\n retryNonce.update((n) => n + 1);\n };\n\n // Wrap in a container so the whole boundary is addressable and disposes as a\n // unit. `when` provides the reactive body↔fallback swap (and its cleanup).\n this.container(id, (c) => {\n c.when(\n hasError,\n // Error state → fallback. The fallback branch mounts exactly when the\n // boundary enters its error state, so this is also where the optional\n // `onError` reporting hook fires (observe-only; §6/§7).\n (fb) => {\n const currentError = readError();\n options.onError?.(currentError);\n options.fallback(fb, currentError, retry);\n },\n // Healthy state → body, guarded against synchronous build throws.\n (body) => {\n try {\n builder(body);\n } catch (err) {\n // Surface the throw as the boundary's error on the next microtask\n // (deferred to avoid re-entrant reconciliation during this build).\n queueMicrotask(() => localError.set(err));\n }\n },\n );\n }, { id });\n }\n\n asyncBoundary<T>(\n key: string,\n res: Resource<T>,\n branches: AsyncBoundaryBranches<T>,\n ): void {\n // Pure sugar over `resource` + `when` — no second async system, no new node\n // type, no renderer wiring. Three mutually-exclusive, exhaustive reactive\n // conditions select the live branch. Error wins; then resolved data (kept\n // visible during a refetch); then loading/idle.\n const isError = derived<boolean>(() => res.status.get() === 'error');\n const showSuccess = derived<boolean>(\n () => res.status.get() !== 'error' && res.data.get() !== undefined,\n );\n const showLoading = derived<boolean>(\n () => res.status.get() !== 'error' && res.data.get() === undefined,\n );\n // Narrow the data signal to `T` for the success branch. Only read inside the\n // success branch, where `data` is guaranteed present.\n const dataSignal = derived<T>(() => res.data.get() as T);\n const retry = (): void => {\n void res.refetch();\n };\n\n this.container(key, (c) => {\n c.when(isError, (fb) => branches.error?.(fb, res.error.peek(), retry));\n c.when(showSuccess, (sb) => branches.success(sb, dataSignal));\n c.when(showLoading, (lb) => branches.loading?.(lb));\n }, { key });\n }\n\n // ── Portals & overlays ──────────────────────────────────────────────────────\n\n portal(key: string, builder: ContainerBuilderFn, options: PortalOptions = {}): void {\n const node = this._graph.createNode('portal', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n builder(new ContainerBuilderImpl(node, this._graph));\n }\n\n /**\n * Declare document metadata (2.0 §1–§3). Creates a `'head'` node — a neutral,\n * empty inline anchor at this position (one node / one element, so positional\n * hydration is preserved) — and registers a `__head__<id>` descriptor holding\n * this call's normalized, dedup-keyed {@link resolveHead} contribution. The\n * renderer applies it to `document.head` on the browser (adopting server tags\n * on hydration, cleaning up on unmount / route change) and emits the active\n * graph's merged metadata as a string on the server (`renderHead`).\n *\n * Multiple `head()` nodes may be live at once (app default + route + component)\n * — the renderer merges them and, per dedup key, the last in document order\n * wins (see head.ts). No new render path: this reuses the same graph-node +\n * handler-registry convention as overlays/transitions/components.\n */\n head(metadata: HeadMetadata): void {\n const node = this._graph.createNode('head', {\n parent: this._node,\n props: { 'data-streetui-head-anchor': '' },\n });\n const contribution = resolveHead(metadata);\n this._graph.registerHandler(\n `__head__${node.id}`,\n (() => contribution) as unknown as () => unknown,\n );\n }\n\n /**\n * Shared assembly for every overlay kind: a `portal` node whose single child\n * is a `when(open, panel)` conditional. The panel container carries the\n * kind's ARIA semantics; `builder` fills it. An `__overlay__<portalId>`\n * descriptor is registered so the renderer wires focus/keyboard behavior to\n * the same `open` signal that drives the panel. Reuses existing primitives\n * (portal + when + container) — no new render path.\n */\n private _overlay(\n kind: OverlayKindConfig,\n key: string,\n options: OverlayOptions,\n builder: ContainerBuilderFn,\n ): void {\n const graph = this._graph;\n const portalNode = graph.createNode('portal', {\n key,\n parent: this._node,\n props: { key },\n });\n\n // Resolve `open` to a signal we can both bind (drives the panel's `when`)\n // and hand to the renderer (drives focus behavior). A literal is wrapped so\n // the panel still mounts/unmounts through the same reactive path.\n const openBindable = options.open;\n const openSignal: ReadonlySignal<boolean> = isSignal(openBindable)\n ? (openBindable as ReadonlySignal<boolean>)\n : signal(openBindable as boolean);\n\n // Panel a11y semantics (kind defaults, overridable via options).\n const panelOptions: ContainerOptions = {\n role: options.role ?? kind.role,\n ...(kind.ariaModal ? { ariaModal: true } : {}),\n ...(kind.ariaLive !== undefined ? { ariaLive: kind.ariaLive } : {}),\n ...(options.class !== undefined ? { class: options.class } : {}),\n ...(options.ariaLabel !== undefined ? { ariaLabel: options.ariaLabel } : {}),\n ...(options.ariaLabelledBy !== undefined ? { ariaLabelledBy: options.ariaLabelledBy } : {}),\n ...(options.ariaDescribedBy !== undefined ? { ariaDescribedBy: options.ariaDescribedBy } : {}),\n };\n\n const portalBuilder = new ContainerBuilderImpl(portalNode, graph);\n portalBuilder.when(\n openSignal,\n (panelHost) => {\n panelHost.container(`${key}__panel`, builder, panelOptions);\n },\n undefined,\n // Overlay open/close rides the panel's `when`; a transition animates the\n // panel in on open and — via the reconciler's deferred-leave — plays the\n // leave before the panel is removed (§10). Focus is restored at close-\n // request time (see wireOverlayBehavior), so it never stays trapped inside\n // a panel that is animating away.\n options.transition !== undefined ? { transition: options.transition } : {},\n );\n\n const descriptor: OverlayBehaviorDescriptor = {\n open: openSignal,\n modal: kind.modal,\n takesFocus: kind.takesFocus,\n menu: kind.menu ?? false,\n closeOnEscape: options.closeOnEscape ?? kind.defaultCloseOnEscape,\n restoreFocus: options.restoreFocus ?? kind.defaultRestoreFocus,\n ...(options.initialFocusId !== undefined ? { initialFocusId: options.initialFocusId } : {}),\n ...(options.onClose !== undefined ? { onClose: options.onClose } : {}),\n };\n graph.registerHandler(\n `__overlay__${portalNode.id}`,\n (() => descriptor) as unknown as () => unknown,\n );\n }\n\n dialog(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.dialog, key, options, builder);\n }\n\n popover(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.popover, key, options, builder);\n }\n\n tooltip(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.tooltip, key, options, builder);\n }\n\n dropdown(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.dropdown, key, options, builder);\n }\n\n toast(key: string, options: OverlayOptions, builder: ContainerBuilderFn): void {\n this._overlay(OVERLAY_KINDS.toast, key, options, builder);\n }\n\n // ── Components ────────────────────────────────────────────────────────────\n\n /**\n * Instantiate a reusable component (§3–§9). Creates a `'component'` node\n * (rendered as a `<div>` wrapper — preserves the one-node/one-element\n * positional-hydration invariant), then runs `def.setup(props, ctx)`\n * synchronously to obtain the render function and fills the component's own\n * container scope with it — structurally identical to `container`/\n * `errorBoundary`. Cleanups the setup registers via `ctx.effect`/\n * `ctx.onCleanup` are collected into a closure and exposed to the renderer\n * through a `__component__<id>` handler (mirroring `__overlay__`); the mount/\n * hydrate paths read it and route each into `NodeInstance.trackCleanup`, so\n * teardown runs (children-first) when the component leaves the graph.\n *\n * `setup` runs once per instance here at build time. When this component sits\n * inside a keyed list / conditional, a rebuild disposes the old instance\n * (running its cleanups + pruning its `__component__` entry) and re-runs this\n * method for the new node — so re-invocation is safe and leak-free.\n */\n component<P>(\n key: string,\n def: ComponentDefinition<P>,\n props: P,\n children?: ContainerBuilderFn,\n ): void {\n const graph = this._graph;\n const node = graph.createNode('component', {\n key,\n parent: this._node,\n // `data-streetui-component` is a non-underscore prop, so it reaches the\n // DOM as an attribute and is visible to DevTools (§21) — unlike the\n // internal `_`-prefixed metadata the renderer hides.\n props: { key, 'data-streetui-component': def.name },\n });\n\n // Ownership collector: every teardown the setup registers lands here and is\n // handed to the NodeInstance at mount.\n const cleanups: Array<() => void> = [];\n const ctx: ComponentContext = {\n key,\n onCleanup(fn: () => void): void {\n cleanups.push(fn);\n },\n effect(fn: () => void | (() => void)): void {\n // Reuse the EXISTING reactive engine (§8) — no new reactivity. The\n // effect runs immediately (build time, like errorBoundary's derived);\n // its unsubscribe is owned by this component.\n cleanups.push(effect(fn));\n },\n renderChildren(content: ContainerDSL): void {\n if (children !== undefined) children(content);\n },\n };\n\n // Run setup to get the render function, guarding a synchronous throw the\n // same way errorBoundary does (defer so we never re-enter reconciliation\n // during this build). A component wrapped in an errorBoundary still surfaces\n // the error through the boundary's observed sources.\n let render: ComponentRender;\n try {\n render = def.setup(props, ctx);\n render(new ContainerBuilderImpl(node, graph));\n } catch (err) {\n queueMicrotask(() => {\n throw err;\n });\n }\n\n if (cleanups.length > 0) {\n graph.registerHandler(\n `__component__${node.id}`,\n (() => cleanups) as unknown as () => unknown,\n );\n }\n }\n}\n\n// ── Concrete builder implementations ─────────────────────────────────────────\n\nexport class SectionBuilderImpl extends ContainerBuilderBase implements SectionDSL {}\nexport class ContainerBuilderImpl extends ContainerBuilderBase implements ContainerDSL {}\nexport class FormBuilderImpl extends ContainerBuilderBase implements FormDSL {}\n\nexport class ListBuilderImpl extends ContentBuilderBase implements ListDSL {\n item(key: string, builder: ContainerBuilderFn, options: ContainerOptions = {}): void {\n const node = this._graph.createNode('list-item', {\n key,\n parent: this._node,\n props: containerProps(options),\n });\n registerTransition(this._graph, node, options.transition);\n builder(new ContainerBuilderImpl(node, this._graph));\n }\n}\n\nexport class PageBuilderImpl extends ContainerBuilderBase implements PageDSL {}\n\n// ── App builder ───────────────────────────────────────────────────────────────\n\nexport class AppBuilder implements AppDSL {\n constructor(private readonly _graph: ApplicationGraph) {}\n\n page(key: string, builder: PageBuilder): void {\n const node = this._graph.createNode('page', {\n key,\n parent: this._graph.root,\n props: { key },\n });\n builder(new PageBuilderImpl(node, this._graph));\n }\n}\n","/**\n * Semantic Application Graph nodes.\n *\n * Every element in a StreetUI application is represented as a GraphNode.\n * Nodes form a tree: each has an optional parent and an ordered list of children.\n */\n\nimport { generateNodeId, type NodeId, type SemanticNodeType } from '@streetui/core';\n\n// ── Property values ───────────────────────────────────────────────────────────\n\nexport type PropValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | string[]\n | number[]\n | Record<string, unknown>;\n\nexport type Props = Record<string, PropValue>;\n\n// ── Event descriptors ─────────────────────────────────────────────────────────\n\nexport interface EventDescriptor {\n readonly type: string;\n /** Reference key into the application's handler registry. */\n readonly handlerKey: string;\n}\n\n// ── State references ──────────────────────────────────────────────────────────\n\nexport interface StateRef {\n /** ID of the signal/store this node's property is bound to. */\n readonly signalId: string;\n /** The prop key on this node that is bound. */\n readonly propKey: string;\n}\n\n// ── The core graph node ───────────────────────────────────────────────────────\n\nexport interface GraphNodeData {\n readonly id: NodeId;\n readonly type: SemanticNodeType;\n readonly key: string | undefined;\n props: Props;\n events: EventDescriptor[];\n stateRefs: StateRef[];\n children: GraphNode[];\n parent: GraphNode | null;\n}\n\nexport class GraphNode implements GraphNodeData {\n readonly id: NodeId;\n readonly type: SemanticNodeType;\n readonly key: string | undefined;\n props: Props;\n events: EventDescriptor[];\n stateRefs: StateRef[];\n children: GraphNode[];\n parent: GraphNode | null;\n\n constructor(\n type: SemanticNodeType,\n options: {\n id?: NodeId;\n key?: string;\n props?: Props;\n events?: EventDescriptor[];\n stateRefs?: StateRef[];\n } = {},\n ) {\n this.type = type;\n this.id = options.id ?? generateNodeId(type);\n this.key = options.key;\n this.props = options.props ?? {};\n this.events = options.events ?? [];\n this.stateRefs = options.stateRefs ?? [];\n this.children = [];\n this.parent = null;\n }\n\n // ── Child management ────────────────────────────────────────────────────────\n\n appendChild(child: GraphNode): void {\n if (child.parent !== null) {\n child.parent.removeChild(child);\n }\n child.parent = this;\n this.children.push(child);\n }\n\n insertBefore(child: GraphNode, reference: GraphNode): void {\n const idx = this.children.indexOf(reference);\n if (idx === -1) {\n this.appendChild(child);\n return;\n }\n if (child.parent !== null) {\n child.parent.removeChild(child);\n }\n child.parent = this;\n this.children.splice(idx, 0, child);\n }\n\n removeChild(child: GraphNode): void {\n const idx = this.children.indexOf(child);\n if (idx === -1) return;\n this.children.splice(idx, 1);\n child.parent = null;\n }\n\n replaceChild(newChild: GraphNode, oldChild: GraphNode): void {\n const idx = this.children.indexOf(oldChild);\n if (idx === -1) {\n throw new Error(`GraphNode.replaceChild: oldChild is not a child of this node`);\n }\n if (newChild.parent !== null) {\n newChild.parent.removeChild(newChild);\n }\n oldChild.parent = null;\n newChild.parent = this;\n this.children.splice(idx, 1, newChild);\n }\n\n // ── Prop helpers ────────────────────────────────────────────────────────────\n\n setProp(key: string, value: PropValue): void {\n this.props = { ...this.props, [key]: value };\n }\n\n getProp<T extends PropValue = PropValue>(key: string): T | undefined {\n return this.props[key] as T | undefined;\n }\n\n // ── Event helpers ───────────────────────────────────────────────────────────\n\n addEvent(descriptor: EventDescriptor): void {\n this.events.push(descriptor);\n }\n\n removeEvent(type: string): void {\n this.events = this.events.filter(e => e.type !== type);\n }\n\n // ── Queries ─────────────────────────────────────────────────────────────────\n\n get isLeaf(): boolean {\n return this.children.length === 0;\n }\n\n get depth(): number {\n let d = 0;\n let node: GraphNode | null = this.parent;\n while (node !== null) {\n d++;\n node = node.parent;\n }\n return d;\n }\n\n get root(): GraphNode {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let node: GraphNode = this;\n while (node.parent !== null) {\n node = node.parent;\n }\n return node;\n }\n\n /** Shallow clone — does not clone children. */\n shallowClone(): GraphNode {\n const opts: { key?: string; props: Props; events: EventDescriptor[]; stateRefs: StateRef[] } = {\n props: { ...this.props },\n events: [...this.events],\n stateRefs: [...this.stateRefs],\n };\n if (this.key !== undefined) opts.key = this.key;\n return new GraphNode(this.type, opts);\n }\n}\n","/**\n * The Semantic Application Graph.\n *\n * Holds the application root node and all its descendants.\n * Supports traversal, lookup by ID, validation, and serialization.\n */\n\nimport { type NodeId, DiagnosticCollector } from '@streetui/core';\nimport { GraphNode, type Props, type EventDescriptor } from './graph-node.js';\n\nexport interface ApplicationGraphOptions {\n readonly name: string;\n readonly version?: string;\n}\n\nexport interface HandlerFn {\n (...args: unknown[]): unknown;\n}\n\nexport class ApplicationGraph {\n readonly root: GraphNode;\n readonly name: string;\n readonly version: string;\n private readonly _nodeIndex: Map<NodeId, GraphNode> = new Map();\n /** Handler registry — maps handlerKey → actual function */\n readonly handlers: Map<string, HandlerFn> = new Map();\n\n constructor(options: ApplicationGraphOptions) {\n this.name = options.name;\n this.version = options.version ?? '0.0.1';\n this.root = new GraphNode('application', { props: { name: options.name } });\n this._nodeIndex.set(this.root.id, this.root);\n }\n\n // ── Node creation & attachment ────────────────────────────────────────────\n\n createNode(\n type: GraphNode['type'],\n options: { key?: string; props?: Props; parent?: GraphNode } = {},\n ): GraphNode {\n const nodeOpts: { key?: string; props?: Props } = {};\n if (options.key !== undefined) nodeOpts.key = options.key;\n if (options.props !== undefined) nodeOpts.props = options.props;\n const node = new GraphNode(type, nodeOpts);\n this._nodeIndex.set(node.id, node);\n if (options.parent !== undefined) {\n options.parent.appendChild(node);\n }\n return node;\n }\n\n attachNode(node: GraphNode, parent: GraphNode): void {\n this._nodeIndex.set(node.id, node);\n parent.appendChild(node);\n }\n\n detachNode(node: GraphNode): void {\n if (node.parent !== null) {\n node.parent.removeChild(node);\n }\n this._removeFromIndex(node);\n }\n\n private _removeFromIndex(node: GraphNode): void {\n this._nodeIndex.delete(node.id);\n this._unregisterNodeHandlers(node);\n for (const child of node.children) {\n this._removeFromIndex(child);\n }\n }\n\n /**\n * Remove every handler-registry entry owned by a single node. A node owns:\n * - one entry per event descriptor (its `handlerKey`),\n * - one `__signal__<signalId>` entry per state ref (signalIds are namespaced\n * by node id, so they are never shared between nodes), and\n * - a `__listbuild__<id>` entry if it is a reactive-list.\n * Called for every node in a detached subtree so removing list items (or\n * discarding freshly-built-but-unadopted item subtrees) leaves no stale\n * registrations behind.\n */\n private _unregisterNodeHandlers(node: GraphNode): void {\n for (const event of node.events) {\n this.handlers.delete(event.handlerKey);\n }\n for (const ref of node.stateRefs) {\n this.handlers.delete(`__signal__${ref.signalId}`);\n }\n this.handlers.delete(`__listbuild__${node.id}`);\n this.handlers.delete(`__listplan__${node.id}`);\n this.handlers.delete(`__overlay__${node.id}`);\n this.handlers.delete(`__component__${node.id}`);\n this.handlers.delete(`__transition__${node.id}`);\n this.handlers.delete(`__head__${node.id}`);\n }\n\n // ── Handler registry ──────────────────────────────────────────────────────\n\n registerHandler(key: string, fn: HandlerFn): void {\n this.handlers.set(key, fn);\n }\n\n getHandler(key: string): HandlerFn | undefined {\n return this.handlers.get(key);\n }\n\n /** True if a handler is currently registered under `key`. Inspection helper. */\n hasHandler(key: string): boolean {\n return this.handlers.has(key);\n }\n\n /** Number of currently-registered handlers. Inspection helper. */\n get handlerCount(): number {\n return this.handlers.size;\n }\n\n // ── Lookup ────────────────────────────────────────────────────────────────\n\n findById(id: NodeId): GraphNode | undefined {\n return this._nodeIndex.get(id);\n }\n\n findAll(predicate: (node: GraphNode) => boolean): GraphNode[] {\n const results: GraphNode[] = [];\n this._walk(this.root, node => {\n if (predicate(node)) results.push(node);\n });\n return results;\n }\n\n findByType(type: GraphNode['type']): GraphNode[] {\n return this.findAll(n => n.type === type);\n }\n\n // ── Traversal ─────────────────────────────────────────────────────────────\n\n walk(visitor: (node: GraphNode, depth: number) => void): void {\n this._walk(this.root, visitor, 0);\n }\n\n private _walk(\n node: GraphNode,\n visitor: (node: GraphNode, depth: number) => void,\n depth: number = 0,\n ): void {\n visitor(node, depth);\n for (const child of node.children) {\n this._walk(child, visitor, depth + 1);\n }\n }\n\n get nodeCount(): number {\n return this._nodeIndex.size;\n }\n\n // ── Validation ────────────────────────────────────────────────────────────\n\n validate(): DiagnosticCollector {\n const dc = new DiagnosticCollector();\n\n this.walk((node) => {\n // Validate event handler references exist\n for (const event of node.events) {\n if (!this.handlers.has(event.handlerKey)) {\n dc.warn(\n 'GRAPH_MISSING_HANDLER',\n `Node \"${node.id}\" references handler \"${event.handlerKey}\" which is not registered`,\n { nodeId: node.id },\n );\n }\n }\n\n // Validate page nodes are direct children of root\n if (node.type === 'page' && node.parent?.type !== 'application') {\n dc.error(\n 'GRAPH_PAGE_DEPTH',\n `Page node \"${node.id}\" must be a direct child of the application root`,\n { nodeId: node.id },\n );\n }\n });\n\n return dc;\n }\n\n // ── Serialization ─────────────────────────────────────────────────────────\n\n serialize(): SerializedGraph {\n return {\n name: this.name,\n version: this.version,\n root: this._serializeNode(this.root),\n };\n }\n\n private _serializeNode(node: GraphNode): SerializedNode {\n const result: SerializedNode = {\n id: node.id,\n type: node.type,\n key: node.key,\n props: node.props,\n events: node.events,\n stateRefs: node.stateRefs,\n children: node.children.map(c => this._serializeNode(c)),\n };\n return result;\n }\n}\n\nexport interface SerializedNode {\n readonly id: string;\n readonly type: string;\n readonly key: string | undefined;\n readonly props: Props;\n readonly events: EventDescriptor[];\n readonly stateRefs: unknown[];\n readonly children: SerializedNode[];\n}\n\nexport interface SerializedGraph {\n readonly name: string;\n readonly version: string;\n readonly root: SerializedNode;\n}\n","/**\n * StreetUI DSL entry point.\n *\n * Usage:\n * import { streetui } from '@streetui/dsl';\n *\n * const app = streetui.app({ name: 'My App' });\n * app.page('home', page => {\n * page.section('hero', section => {\n * section.heading('Welcome');\n * section.button('Click me', { onClick: () => {} });\n * });\n * });\n *\n * const graph = app.build();\n */\n\nimport { ApplicationGraph } from '@streetui/graph';\nimport { AppBuilder } from './builders.js';\n\nexport interface AppOptions {\n readonly name: string;\n readonly version?: string;\n}\n\nexport class StreetApp {\n private readonly _graph: ApplicationGraph;\n private readonly _builder: AppBuilder;\n\n constructor(options: AppOptions) {\n const graphOpts: { name: string; version?: string } = { name: options.name };\n if (options.version !== undefined) graphOpts.version = options.version;\n this._graph = new ApplicationGraph(graphOpts);\n this._builder = new AppBuilder(this._graph);\n }\n\n page(key: string, builder: Parameters<AppBuilder['page']>[1]): this {\n this._builder.page(key, builder);\n return this;\n }\n\n /** Compile to ApplicationGraph — validates and returns the graph. */\n build(): ApplicationGraph {\n const dc = this._graph.validate();\n dc.throwIfErrors();\n return this._graph;\n }\n\n /** Access graph before building (useful for inspection). */\n get graph(): ApplicationGraph {\n return this._graph;\n }\n}\n\nexport interface StreetUI {\n app(options: AppOptions): StreetApp;\n}\n\nexport const streetui: StreetUI = {\n app(options: AppOptions): StreetApp {\n return new StreetApp(options);\n },\n};\n","/**\n * Component-focused testing helpers (§22).\n *\n * These extend `streetui/testing` for the component model. Following the spec's\n * \"add only the ones that are actually useful\" directive, this module ships the\n * helpers that remove real boilerplate and OMITS the ones that would be\n * misleading in this architecture:\n *\n * • renderComponent — mount a single component in a throwaway host app.\n * • hydrateComponent — SSR-then-hydrate that same host (the §11/§12 seam).\n * • findComponent / findAllComponents / getComponentName — locate component\n * instances by their inspectable `data-streetui-component` name.\n * • trigger — dispatch a bubbling DOM event (click/input/keydown…).\n *\n * Deliberately NOT provided:\n * • getComponentProps — props are passed to `setup` and captured by closure;\n * they are not reified on the node (only the definition *name* is), so a\n * prop-reading helper would either lie or require a private-graph backdoor.\n * Assert on rendered output (or a signal you own) instead.\n * • awaitResource — `waitFor(...)` and `flushUpdates()` already settle\n * async resource state; a resource-specific alias would be redundant.\n */\n\nimport { streetui, type ComponentDefinition, type ContainerBuilder } from '@streetui/dsl';\nimport { render, type RenderResult } from './test-renderer.js';\nimport { renderServerThenHydrate, type HydrateTestResult, type HydrateTestOptions } from './helpers.js';\n\n/** The attribute the DSL writes for a component's inspectable name. */\nconst COMPONENT_ATTR = 'data-streetui-component';\n\nexport interface RenderComponentResult extends RenderResult {\n /** The component's root `<div>` wrapper element. */\n readonly component: HTMLElement;\n}\n\n/**\n * Build a throwaway single-page host app whose only content is `def` rendered\n * with `props` (and optional `children`), mount it, and return the usual\n * `RenderResult` plus the component's root element. Use for unit-testing one\n * component without hand-writing an app+page wrapper each time.\n */\nexport function renderComponent<P>(\n def: ComponentDefinition<P>,\n props: P,\n children?: ContainerBuilder,\n): RenderComponentResult {\n const app = streetui.app({ name: `test:${def.name}` });\n app.page('host', (page) => {\n page.component('root', def, props, children);\n });\n const result = render(app);\n const component = result.container.querySelector<HTMLElement>(`[${COMPONENT_ATTR}]`);\n if (component === null) {\n throw new Error(`[StreetUI Testing] renderComponent: no component element rendered for \"${def.name}\"`);\n }\n return { ...result, component };\n}\n\n/**\n * SSR-render then hydrate a single component in a host app — the production\n * server→client seam (§11/§12). `build` must return `{ def, props, children? }`;\n * it is invoked twice (server then client) with id-counter reset between, so a\n * component that owns per-instance signals lines up positionally on hydration.\n */\nexport function hydrateComponent<P>(\n build: () => { def: ComponentDefinition<P>; props: P; children?: ContainerBuilder },\n options: HydrateTestOptions = {},\n): HydrateTestResult {\n return renderServerThenHydrate(() => {\n const { def, props, children } = build();\n const app = streetui.app({ name: `test:${def.name}` });\n app.page('host', (page) => page.component('root', def, props, children));\n return app;\n }, options);\n}\n\n/** All component instances under `container`, optionally filtered by name. */\nexport function findAllComponents(container: Element, name?: string): HTMLElement[] {\n const selector = name === undefined\n ? `[${COMPONENT_ATTR}]`\n : `[${COMPONENT_ATTR}=\"${name}\"]`;\n return Array.from(container.querySelectorAll<HTMLElement>(selector));\n}\n\n/** The single component instance under `container` (throws if none/ambiguous). */\nexport function findComponent(container: Element, name?: string): HTMLElement {\n const matches = findAllComponents(container, name);\n const named = name !== undefined ? ` named \"${name}\"` : '';\n if (matches.length === 0) {\n throw new Error(`[StreetUI Testing] No component${named} found`);\n }\n if (matches.length > 1) {\n throw new Error(\n `[StreetUI Testing] Found ${matches.length} components${named} — pass a name to disambiguate`,\n );\n }\n return matches[0]!;\n}\n\n/** Read a component element's definition name, or `null` if `el` is not one. */\nexport function getComponentName(el: Element): string | null {\n return el.getAttribute(COMPONENT_ATTR);\n}\n\n/**\n * Dispatch a bubbling, cancelable DOM event of `type` on `el`. Thin wrapper over\n * `dispatchEvent` so tests read intentfully (`trigger(btn, 'click')`) without\n * constructing `Event`/`KeyboardEvent` objects by hand. Extra `init` fields\n * (e.g. `{ key: 'Escape' }`) are forwarded to the appropriate event ctor.\n */\nexport function trigger(el: Element, type: string, init: Record<string, unknown> = {}): void {\n const base = { bubbles: true, cancelable: true, ...init };\n let event: Event;\n if (type.startsWith('key')) {\n event = new KeyboardEvent(type, base as KeyboardEventInit);\n } else if (type.startsWith('mouse') || type === 'click' || type === 'dblclick') {\n event = new MouseEvent(type, base as MouseEventInit);\n } else if (type === 'input' || type === 'change') {\n event = new Event(type, base);\n } else {\n event = new Event(type, base);\n }\n el.dispatchEvent(event);\n}\n","/**\n * The single authoritative StreetUI framework version.\n *\n * This constant is the one source of truth for the version of the shipped\n * `streetui` package. It is kept in lock-step with this package's\n * `package.json` `version` field and with the bundled CLI's reported version\n * (`streetui --version`) — the consolidated test-suite pins all three to the\n * same coordinated release so they can never silently drift apart.\n */\nexport const VERSION = '2.2.0';\n"],"mappings":"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","names":["classes","instance","el","tag","render"]}