@vielzeug/ore 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ore.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ore.cjs","names":[],"sources":["../src/directives/classMap.ts","../src/_dev.ts","../src/errors.ts","../src/types/bindings.ts","../src/utils/dom.ts","../src/directives/each.ts","../src/directives/live.ts","../src/directives/model.ts","../src/directives/raw.ts","../src/directives/styleMap.ts","../src/directives/when.ts","../src/runtime.ts","../src/forms/field.ts","../src/context.ts","../src/forms/context.ts","../src/props.ts","../src/types.ts","../src/utils/css.ts","../src/base-element.ts","../src/define.ts","../src/slots.ts","../src/utils/aria.ts","../src/host-bind.ts","../src/aria.ts","../src/utils/emit.ts","../src/template/bindings.ts","../src/utils/event-modifiers.ts","../src/template/compiler.ts","../src/template/instantiator.ts","../src/utils/id.ts","../src/observers/intersection-observe.ts","../src/observers/media-observe.ts","../src/observers/mutation-observe.ts","../src/observers/resize-observe.ts"],"sourcesContent":["import { computed, isReactive, type Readable } from '@vielzeug/ripple';\n\n/**\n * Produces a reactive string of class names from an object map.\n *\n * Each key is a class name. Its value may be:\n * - a static `boolean`\n * - a `Signal<boolean>`\n * - a getter `() => boolean`\n *\n * Returns a `Reactive<string>` that can be used directly in a template\n * class attribute:\n *\n * @example\n * ```ts\n * html`<div class=\"${classMap({ active: isActive, hidden: () => !isVisible.value })}\"></div>`\n * ```\n */\nexport const classMap = (map: Record<string, (() => boolean) | Readable<boolean> | boolean>): Readable<string> => {\n return computed(() =>\n Object.entries(map)\n .filter(([, v]) => (typeof v === 'function' ? v() : isReactive(v) ? v.value : v))\n // Strip whitespace from each key — spaces would inject extra class tokens.\n .map(([k]) => k.replace(/\\s+/g, ''))\n .filter(Boolean)\n .join(' '),\n );\n};\n","const isDev = !(globalThis as { __ORE_PROD__?: boolean }).__ORE_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/ore] ${msg}`);\n}\n\n/** @internal */\nexport function error(msg: string, ...args: unknown[]): void {\n if (isDev) console.error(`[@vielzeug/ore] ${msg}`, ...args);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n","import { error as logError } from './_dev';\n\n// ─── Structured error types ───────────────────────────────────────────────────\n\n/** Base class for all Ore errors. Use `instanceof OreError` to catch any Ore-originated error. */\nexport class OreError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is OreError {\n return err instanceof OreError;\n }\n}\n\n/** Thrown when Ore API is called incorrectly (e.g. outside setup, duplicate define, invalid prop). */\nexport class OreApiError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * Thrown when an internal invariant fails — e.g. compiled template metadata no\n * longer matching the DOM it was cloned from. Distinct from `OreApiError`: this\n * is never the caller's fault, it signals a bug in ore itself. See `invariant()`.\n */\nexport class OreInternalError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * The phase in which a component error occurred.\n * - `'setup'` — synchronous setup() threw\n * - `'async-setup'` — async setup() promise rejected\n * - `'mounted'` — an onMounted callback threw\n * - `'form-reset'` — an onFormReset callback threw\n */\nexport type OreErrorPhase = 'async-setup' | 'form-reset' | 'mounted' | 'setup';\n\n/**\n * Structured error thrown by the Ore runtime when component setup fails.\n * Provides component name and original cause for debugging.\n */\nexport class OreLifecycleError extends OreError {\n readonly component: string;\n readonly phase: OreErrorPhase;\n\n constructor(message: string, options: { cause: Error; component: string; phase: OreErrorPhase }) {\n super(message, { cause: options.cause });\n this.component = options.component;\n this.phase = options.phase;\n }\n}\n\n/**\n * Report a runtime error via the ore:error event and console.\n */\nexport function reportRuntimeError(error: OreLifecycleError, element: HTMLElement): void {\n logError(`<${error.component}> setup error (phase: ${error.phase}):`, error.cause);\n\n element.dispatchEvent(\n new CustomEvent('ore:error', {\n bubbles: true,\n composed: true,\n detail: error,\n }),\n );\n}\n\n// ─── Error message constants ─────────────────────────────────────────────────\n\n/** Thrown by `waitFor` and `waitForEvent` in the testing sub-path when a condition is not met within the timeout. */\nexport class OreTimeoutError extends OreError {}\n\nexport const ORE_ERRORS = {\n defineDuplicate: (tag: string): string => `define('${tag}') called twice — custom element already registered`,\n defineFieldRequiresFormAssociated: (tag: string): string =>\n `useField() requires define('${tag}', { formAssociated: true })`,\n defineRequiresTag: 'define() requires a tag name',\n eachDuplicateKey: (key: string, index: number): string => `each() received duplicate key \"${key}\" at index ${index}`,\n injectStrictFailed: (key: string, tag: string): string => `injectStrict() could not resolve key \"${key}\" in <${tag}>`,\n invalidDynamicTagName: (tagName: string): string =>\n `html\\`...\\`: dynamic tag name \"${tagName}\" is not a valid HTML element name`,\n invariantViolated: (message: string): string => `invariant violated: ${message}`,\n lifecycleOutsideSetup: 'Lifecycle hooks must be called during component setup',\n mismatchedDynamicCloseTag: 'html`...`: dynamic closing tag has no matching dynamic opening tag',\n propInvalidReflect: 'Structured props cannot use reflect:true — use prop.json() with reflect:false',\n validationFailed: (tag: string, errors: string[]): string => `Validation failed for <${tag}>:\\n${errors.join('\\n')}`,\n} as const;\n\n/**\n * Assert an internal invariant that must always hold — e.g. compiled template\n * metadata staying in sync with the DOM it was cloned from. A failed invariant\n * means a bug in ore itself, never user input, so it throws `OreInternalError`\n * unconditionally (every build, never gated like `_dev.ts`'s `warn()`).\n *\n * Narrowing caveat: `asserts condition` only narrows the exact expression\n * passed in. Assign to a local `const` first — `invariant(el.parentNode, msg)`\n * does not narrow later reads of `el.parentNode`.\n */\nexport function invariant(condition: unknown, message: string): asserts condition {\n if (!condition) throw new OreInternalError(ORE_ERRORS.invariantViolated(message));\n}\n","/**\n * Core type definitions for the template binding and rendering system.\n *\n * All bindings reference actual DOM nodes directly (no UID-based lookup).\n * This eliminates the TreeWalker indexing pass and the string-based ID remapping\n * that the previous design required.\n */\n\nimport { type Readable, signal, type Signal } from '@vielzeug/ripple';\n\n// ─── REF TYPES ───────────────────────────────────────────────────────────────\n\nexport type Ref<T extends Element> = Signal<T | null>;\n\nexport function ref<T extends Element>(): Ref<T> {\n return signal<T | null>(null);\n}\n\nexport type RefCallback<T extends Element> = (el: T | null) => void;\n\n// ─── BINDING VARIANTS ────────────────────────────────────────────────────────\n// All bindings hold direct references to the DOM node they manage.\n\nexport type TextBinding = {\n node: Text;\n signal: Readable<unknown>;\n type: 'text';\n};\n\n/**\n * Minimal prop metadata needed by the attr binding layer.\n * Populated at binding creation time from propRegistry, so template-bindings.ts\n * has no direct dependency on props.ts.\n */\nexport type AttrPropMeta = {\n parse: (v: string | null) => unknown;\n reflect: boolean;\n signal: { value: unknown };\n};\n\ntype AttrBaseFields = {\n el: HTMLElement;\n /**\n * When true the binding uses live-write semantics: stale app-state writes are\n * skipped if the DOM value has diverged from the last programmatic write.\n */\n live?: true;\n mode: 'attr' | 'bool';\n name: string;\n /** Pre-resolved prop metadata (if the target element is an ore component). */\n propMeta?: AttrPropMeta;\n type: 'attr';\n};\n\n/** Attribute binding with a static value (no signal). */\nexport type AttrStaticBinding = AttrBaseFields & { value: unknown };\n\n/** Attribute binding driven by a reactive signal. */\nexport type AttrReactiveBinding = AttrBaseFields & { signal: Readable<unknown> };\n\nexport type AttrBinding = AttrStaticBinding | AttrReactiveBinding;\n\nexport type EventBinding = {\n el: HTMLElement;\n handler: (e: Event) => void;\n name: string;\n options?: AddEventListenerOptions;\n type: 'event';\n};\n\nexport type RefBinding = {\n el: HTMLElement;\n ref: Ref<Element> | RefCallback<Element>;\n type: 'ref';\n};\n\n/** Value types a reactive HTML slot can produce. */\nexport type HtmlBindingValue = HTMLResult | string | number | boolean | null | undefined;\n\nexport type HtmlBinding = {\n anchor: Comment;\n signal: Readable<HtmlBindingValue[]>;\n type: 'html';\n};\n\nexport type DirectiveBinding = {\n anchor: Comment;\n directive: DirectiveResult;\n type: 'directive';\n};\n\n/** Element-spread binding applied by model() and similar helpers. */\nexport type SpreadBinding = {\n el: HTMLElement;\n spread: SpreadObject;\n type: 'spread';\n};\n\nexport type Binding =\n TextBinding | AttrBinding | EventBinding | RefBinding | HtmlBinding | DirectiveBinding | SpreadBinding;\n\n// ─── BRAND UTILITY ───────────────────────────────────────────────────────────\n// Cross-realm–safe brand for branded types. Avoids repeating the symbol+guard boilerplate.\n\nconst makeBrand = <T extends object>(key: string) => {\n const BRAND = Symbol.for(key);\n const stamp = (obj: T): T => Object.assign(obj, { [BRAND]: true });\n const is = (value: unknown): value is T => typeof value === 'object' && value !== null && BRAND in (value as object);\n\n return { is, stamp };\n};\n\n// ─── DIRECTIVE RESULT ────────────────────────────────────────────────────────\n\nexport type DirectiveResult = {\n mount: (anchor: Comment, registerCleanup: (fn: () => void) => void) => void;\n};\n\nconst directiveBrand = makeBrand<DirectiveResult>('ore:directive');\n\n/**\n * Creates a registered DirectiveResult. All directive factories must use this\n * function — only objects created here pass `isDirectiveResult()`.\n */\nexport const createDirectiveResult = (mount: DirectiveResult['mount']): DirectiveResult =>\n directiveBrand.stamp({ mount });\n\nexport const isDirectiveResult = directiveBrand.is;\n\n// ─── SPREAD OBJECT ───────────────────────────────────────────────────────────\n// Returned by model() and similar helpers that apply multiple bindings to one element.\n\nexport type SpreadObject = {\n apply(el: HTMLElement, registerCleanup: (fn: () => void) => void): void;\n};\n\nconst spreadBrand = makeBrand<SpreadObject>('ore:spread');\n\n/**\n * Creates a registered SpreadObject. Used by model() to attach multiple bindings\n * (value sync + input event) to an element via a single template expression.\n */\nexport const createSpreadObject = (apply: SpreadObject['apply']): SpreadObject => spreadBrand.stamp({ apply });\n\nexport const isSpreadObject = spreadBrand.is;\n\n// ─── HTML RESULT ─────────────────────────────────────────────────────────────\n\n/**\n * The output of an `html` tagged template call.\n *\n * Each `html` call produces an independent fragment — there is no shared mutable\n * state between instances, so the same template can be safely rendered multiple\n * times (e.g. inside `each()`).\n */\nexport interface HTMLResult {\n /** The DOM fragment ready to insert into the document. Consumed on insertion. */\n readonly fragment: DocumentFragment;\n /** Wire up reactive effects to the fragment's nodes. Call after insertion. */\n apply(registerCleanup: (fn: () => void) => void): void;\n /**\n * Insert the fragment before `anchor` (or append to `parent` when no anchor)\n * and immediately wire up all reactive effects.\n *\n * This is the preferred single-step API — it is impossible to forget calling\n * `apply` separately. Use the lower-level `fragment` + `apply` only when you\n * need precise control over insertion (e.g. inside directive implementations).\n */\n mount(parent: ParentNode, anchor: Node | null, registerCleanup: (fn: () => void) => void): Node[];\n}\n\nconst htmlResultBrand = makeBrand<HTMLResult>('ore:html-result');\n\nexport const isHtmlResult = htmlResultBrand.is;\n\nexport function createHtmlResult(\n fragment: DocumentFragment,\n applyFn: (registerCleanup: (fn: () => void) => void) => void,\n): HTMLResult {\n const mount = (parent: ParentNode, anchor: Node | null, registerCleanup: (fn: () => void) => void): Node[] => {\n const nodes = Array.from(fragment.childNodes);\n\n parent.insertBefore(fragment, anchor);\n applyFn(registerCleanup);\n\n return nodes;\n };\n\n return htmlResultBrand.stamp({ apply: applyFn, fragment, mount });\n}\n","/**\n * Low-level DOM utilities used throughout the runtime and binding layers.\n */\n\nimport { warn } from '../_dev';\n\nexport const runAll = (fns: (() => void)[]): void => {\n for (let i = fns.length - 1; i >= 0; i--) fns[i]!();\n};\n\nexport const removeNodes = (nodes: Node[]): void => {\n for (const node of nodes) {\n (node as ChildNode).remove();\n }\n};\n\n/**\n * HTML attributes that accept URLs. Values bound to these attributes are\n * checked for dangerous schemes before being set.\n *\n * `srcdoc` is deliberately excluded: it holds raw HTML (not a URL), so scheme\n * checking doesn't apply — it's blocked unconditionally below, alongside `on*`.\n */\nconst URL_ATTRS = new Set([\n 'action',\n 'cite',\n 'codebase',\n 'data',\n 'formaction',\n 'href',\n 'manifest',\n 'ping',\n 'poster',\n 'src',\n 'xlink:href',\n]);\n\n/**\n * Schemes that execute JavaScript or can embed arbitrary HTML. Blocked\n * unconditionally in URL-accepting attributes.\n * Covers: javascript:, vbscript:, blob:, and data: variants that carry HTML/XML\n * or script-capable SVG. Plain data: image URIs (e.g. data:image/png) are\n * intentionally allowed.\n */\nconst DANGEROUS_SCHEME_RE =\n /^\\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\\/(?:html|svg\\+xml)|application\\/(?:xhtml|xml)))/i;\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n const lowerName = name.toLowerCase();\n\n if (/^on[a-z]/i.test(name)) {\n warn(\n `Blocked setAttribute(\"${name}\", ...) — inline event handler attributes are not supported. Use @${name.slice(2)} binding syntax instead.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (lowerName === 'srcdoc') {\n warn(\n `Blocked setAttribute(\"srcdoc\", ...) — \"srcdoc\" holds raw HTML, not a URL, and is not supported via attribute binding. Use raw() with a registered sanitizer if you need to inject trusted HTML.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n\n return;\n }\n\n const strVal = val === true ? 'true' : String(val);\n\n if (URL_ATTRS.has(lowerName) && DANGEROUS_SCHEME_RE.test(strVal)) {\n warn(\n `Blocked dangerous URL scheme in attribute \"${name}\". Only safe URLs are permitted in URL-accepting attributes.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n el.setAttribute(name, strVal);\n};\n\nexport const listen = (\n el: EventTarget | null | undefined,\n name: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n): (() => void) => {\n if (!el) return () => {};\n\n const listener: EventListener = handler;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nexport const isStructuredValue = (value: unknown): value is object =>\n Array.isArray(value) || (typeof value === 'object' && value !== null);\n","import { batch, computed, effect as rawEffect, type Readable, signal, type Signal, untrack } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { invariant, OreApiError, ORE_ERRORS } from '../errors';\nimport { createDirectiveResult, type DirectiveResult, type HTMLResult } from '../types/bindings';\nimport { removeNodes, runAll } from '../utils/dom';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ntype MaybeReactiveArray<T> = Readable<T[]> | (() => T[]) | T[];\n\ntype ItemEntry<T> = {\n cleanups: (() => void)[];\n data: Signal<T>;\n index: Signal<number>;\n /** The key used to identify this entry. */\n key: string;\n nodes: Node[];\n};\n\n// ─── Item lifecycle ───────────────────────────────────────────────────────────\n\nconst createItem = <T>(\n item: T,\n index: number,\n render: (item: Readable<T>, index: Readable<number>) => HTMLResult,\n parent: ParentNode,\n insertBefore: Node,\n): ItemEntry<T> => {\n const dataSignal: Signal<T> = signal(item);\n const indexSignal: Signal<number> = signal(index);\n\n const result = render(dataSignal, indexSignal);\n const cleanups: (() => void)[] = [];\n const nodes = result.mount(parent, insertBefore, (fn) => cleanups.push(fn));\n\n return { cleanups, data: dataSignal, index: indexSignal, key: '', nodes };\n};\n\nconst removeItem = <T>(entry: ItemEntry<T>): void => {\n runAll(entry.cleanups);\n removeNodes(entry.nodes);\n};\n\n// ─── Reconciler ───────────────────────────────────────────────────────────────\n\n/**\n * Reconciles the live item map (mutated in-place) against the next array.\n * Stale entries are removed and destroyed; new entries are created and inserted.\n * Existing entries are updated in-place via signal writes.\n * Returns the ordered list of entries matching nextList.\n */\nconst reconcileItems = <T>(\n itemsMap: Map<string, ItemEntry<T>>,\n next: T[],\n keyFn: (item: T, index: number) => string | number,\n render: (item: Readable<T>, index: Readable<number>) => HTMLResult,\n parent: ParentNode,\n endMarker: Node,\n): ItemEntry<T>[] => {\n const nextKeys: string[] = [];\n const nextKeySet = new Set<string>();\n\n for (let i = 0; i < next.length; i++) {\n const key = String(keyFn(next[i], i));\n\n if (nextKeySet.has(key)) throw new OreApiError(ORE_ERRORS.eachDuplicateKey(key, i));\n\n nextKeySet.add(key);\n nextKeys.push(key);\n }\n\n // Remove stale entries from the map\n for (const [key, entry] of itemsMap) {\n if (!nextKeySet.has(key)) {\n removeItem(entry);\n itemsMap.delete(key);\n }\n }\n\n // Build the next ordered list: update existing items, create new ones\n const nextOrdered: ItemEntry<T>[] = [];\n\n for (let i = 0; i < next.length; i++) {\n const key = nextKeys[i];\n const existing = itemsMap.get(key);\n\n if (existing) {\n batch(() => {\n existing.data.value = next[i];\n existing.index.value = i;\n });\n nextOrdered.push(existing);\n } else {\n const entry = untrack(() => createItem(next[i], i, render, parent, endMarker));\n\n entry.key = key;\n itemsMap.set(key, entry);\n nextOrdered.push(entry);\n }\n }\n\n // DOM ordering: right-to-left pass — move any item not already adjacent to cursor.\n // O(n) DOM operations in the worst case; optimal for the typical small list sizes\n // encountered in UI components (tabs, options, menu items).\n let cursor: Node = endMarker;\n\n for (let j = nextOrdered.length - 1; j >= 0; j--) {\n const entry = nextOrdered[j];\n const firstNode = entry.nodes[0];\n\n if (firstNode && firstNode !== cursor.previousSibling) {\n for (const node of entry.nodes) parent.insertBefore(node, cursor);\n }\n\n cursor = firstNode ?? cursor;\n }\n\n return nextOrdered;\n};\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Renders a keyed list of items as a `DirectiveResult`.\n *\n * Each item is rendered by the provided render function.\n * Items are reused by key when the list changes; only stale items are destroyed.\n *\n * The render function receives a `Readable<T>` signal and a `Readable<number>` index\n * signal. Use `item.value` to read the current item inside reactive expressions:\n *\n * ```ts\n * html`${each(items, (item) => item.id, (item) => html`<li>${() => item.value.name}</li>`)}`\n * ```\n *\n * **Plain array:** when a plain `T[]` is passed (not a signal or getter), it is\n * treated as a one-time static render. Mutations to the original array are not\n * tracked. Pass a `Signal<T[]>` or `() => T[]` for reactive lists.\n *\n * **Optional fallback:** the fourth argument renders when the list is empty.\n *\n * **Key choice:** pass a stable item identifier (e.g. `item.id`), never the\n * array index — an index-based key reassigns to a different item whenever the\n * list is reordered or an item is inserted/removed before it, causing full\n * item teardown/recreation instead of the in-place update `each()` is built\n * for. Duplicate keys within one render throw immediately (see `eachDuplicateKey`).\n */\nexport function each<T>(\n list: MaybeReactiveArray<T>,\n keyFn: (item: T, index: number) => string | number,\n render: (item: Readable<T>, index: Readable<number>) => HTMLResult,\n fallback?: () => HTMLResult,\n): DirectiveResult {\n const listSignal = Array.isArray(list)\n ? signal(list as T[])\n : typeof list === 'function'\n ? computed(list as () => T[])\n : list;\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const parent = anchor.parentNode;\n\n invariant(parent, 'each() anchor comment has no parent node');\n\n const endMarker = document.createComment('each/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n let itemsMap = new Map<string, ItemEntry<T>>();\n let itemsOrdered: ItemEntry<T>[] = [];\n let fallbackNodes: Node[] | null = null;\n let fallbackCleanups: (() => void)[] = [];\n\n const mountFallback = (): void => {\n if (!fallback) return;\n\n const result = fallback();\n\n fallbackNodes = result.mount(parent, endMarker, (fn) => fallbackCleanups.push(fn));\n };\n\n const clearFallback = (): void => {\n if (fallbackNodes) {\n runAll(fallbackCleanups);\n removeNodes(fallbackNodes);\n fallbackNodes = null;\n fallbackCleanups = [];\n }\n };\n\n const sub = rawEffect(() => {\n const nextList = listSignal.value ?? [];\n\n if (nextList.length === 0) {\n for (const entry of untrack(() => itemsOrdered)) removeItem(entry);\n itemsMap = new Map();\n itemsOrdered = [];\n\n if (!fallbackNodes) untrack(mountFallback);\n\n return;\n }\n\n clearFallback();\n\n try {\n itemsOrdered = untrack(() => reconcileItems(itemsMap, nextList, keyFn, render, parent, endMarker));\n } catch (err) {\n warn(`each() reconciliation error: ${err instanceof Error ? err.message : String(err)}`);\n\n for (const entry of itemsMap.values()) removeItem(entry);\n itemsMap = new Map();\n itemsOrdered = [];\n }\n });\n\n registerCleanup(() => sub.dispose());\n registerCleanup(() => {\n clearFallback();\n for (const entry of itemsOrdered) removeItem(entry);\n endMarker.remove();\n });\n });\n}\n","import type { Readable } from '@vielzeug/ripple';\n\nconst LIVE_BRAND: unique symbol = Symbol.for('ore:live');\n\n/**\n * A branded signal that tells the attribute binding engine to skip writing when\n * the DOM value has diverged from the last programmatically-written value.\n * Created via live(signal) — pass a signal directly rather than wrapping a value.\n *\n * @example\n * html`<input :value=\"${live(model)}\" />`\n */\nexport type LiveSignal<T> = Readable<T> & { readonly [LIVE_BRAND]: true };\n\n// WeakSet tracks which signal objects have been marked live — zero allocation on call.\nlet liveSignals = new WeakSet<object>();\n\n/**\n * Marks a signal binding as \"live\" so stale app-state writes never clobber\n * in-progress user input.\n *\n * For form controls: if the current DOM value diverges from the last write made\n * by this binding, subsequent app-state writes are silently dropped until the\n * DOM value matches the incoming value or no prior write has been recorded.\n */\nexport const live = <T>(source: Readable<T>): LiveSignal<T> => {\n liveSignals.add(source as object);\n\n return source as LiveSignal<T>;\n};\n\nexport const isLiveSignal = (value: unknown): value is LiveSignal<unknown> =>\n typeof value === 'object' && value !== null && liveSignals.has(value as object);\n\n/** @internal Reset live signal registry. Called by cleanup() for test isolation. */\nexport const _resetLiveSignals = (): void => {\n liveSignals = new WeakSet();\n};\n","import { effect as rawEffect, type Signal } from '@vielzeug/ripple';\n\nimport { createSpreadObject, type SpreadObject } from '../types/bindings';\nimport { listen } from '../utils/dom';\n\n/**\n * Two-way binding spread for form inputs.\n * Syncs the signal value to the element's DOM value and back.\n *\n * Supports `type=\"text\"` (default), `type=\"number\"`, `type=\"range\"`,\n * `type=\"checkbox\"`, `<select>` (single-select), and\n * `<select multiple>` (multi-select, `Signal<string[]>`).\n *\n * @example\n * ```ts\n * const name = signal('');\n * html`<input type=\"text\" ${model(name)} />`\n *\n * const count = signal(0);\n * html`<input type=\"number\" ${model(count)} />`\n *\n * const checked = signal(false);\n * html`<input type=\"checkbox\" ${model(checked)} />`\n *\n * const selected = signal<string[]>([]);\n * html`<select multiple ${model(selected)}><option value=\"a\">A</option></select>`\n * ```\n */\nexport function model<T extends string | number | boolean | null>(source: Signal<T>): SpreadObject;\nexport function model(source: Signal<string[]>): SpreadObject;\nexport function model<T extends string | number | boolean | null | string[]>(source: Signal<T>): SpreadObject {\n return createSpreadObject((el, registerCleanup) => {\n const input = el as HTMLInputElement;\n const isCheckbox = input.type === 'checkbox';\n const isNumeric = input.type === 'number' || input.type === 'range';\n const isSelect = el instanceof HTMLSelectElement;\n const isMultiSelect = isSelect && (el as HTMLSelectElement).multiple;\n\n // Signal → DOM\n const sub = rawEffect(() => {\n const v = source.value;\n\n if (isMultiSelect) {\n const selected = Array.isArray(v) ? (v as string[]) : [];\n const selectEl = el as HTMLSelectElement;\n\n for (const opt of selectEl.options) {\n opt.selected = selected.includes(opt.value);\n }\n } else if (isCheckbox) {\n input.checked = Boolean(v);\n } else {\n (el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).value =\n v == null ? '' : String(v as string | number | boolean | null);\n }\n });\n\n registerCleanup(() => sub.dispose());\n\n // DOM → Signal\n // <select> fires 'change'; text/number/range/textarea/checkbox fire 'input'.\n const eventName = isSelect ? 'change' : 'input';\n\n registerCleanup(\n listen(el, eventName, (e: Event) => {\n const target = e.target as HTMLInputElement;\n\n if (isMultiSelect) {\n const selectEl = e.target as HTMLSelectElement;\n const values = Array.from(selectEl.selectedOptions).map((opt) => opt.value);\n\n (source as Signal<string[]>).value = values;\n } else if (isCheckbox) {\n source.value = target.checked as T;\n } else if (isNumeric) {\n source.value = (target.value === '' ? 0 : Number(target.value)) as T;\n } else {\n source.value = target.value as T;\n }\n }),\n );\n });\n}\n","import { computed, effect as rawEffect, isReactive, type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { invariant } from '../errors';\nimport { createDirectiveResult, type DirectiveResult } from '../types/bindings';\nimport { removeNodes } from '../utils/dom';\n\ntype RawSanitizer = (html: string) => string;\n\nlet _sanitizer: RawSanitizer | null = null;\nlet _warned = false;\n\nexport const setRawSanitizer = (fn: RawSanitizer | null): void => {\n _sanitizer = fn;\n\n if (!fn) _warned = false;\n};\n\n/** @internal */\nexport const _resetRawSanitizer = (): void => {\n _sanitizer = null;\n _warned = false;\n};\n\nconst sanitize = (value: string): string => {\n if (_sanitizer) return _sanitizer(value);\n\n if (value && !_warned) {\n _warned = true;\n warn(\n 'raw() was called without a sanitizer registered. ' +\n 'Passing user-supplied HTML directly to raw() is an XSS risk. ' +\n 'Register a sanitizer with setRawSanitizer() — e.g. setRawSanitizer(DOMPURIFY.sanitize).',\n );\n }\n\n return value;\n};\n\nconst parseRaw = (html: string, parent: ParentNode, insertBefore: Node): Node[] => {\n const tpl = document.createElement('template');\n\n tpl.innerHTML = html;\n\n const nodes = Array.from(tpl.content.cloneNode(true).childNodes);\n\n for (const node of nodes) parent.insertBefore(node, insertBefore);\n\n return nodes;\n};\n\n/**\n * Renders a trusted HTML string without escaping as a DirectiveResult.\n * Only use with content you control — passing user-supplied strings\n * directly is an XSS risk. Register a sanitizer with setRawSanitizer()\n * to add a runtime safety net.\n *\n * Supports static strings, signals, and getter functions `() => string`.\n * When reactive, the DOM is updated in-place whenever the value changes.\n */\nexport function raw(value: (() => string) | string | Signal<string> | Readable<string>): DirectiveResult {\n if (typeof value === 'function') {\n const c = computed(value);\n\n return createDirectiveResult((anchor, registerCleanup) => {\n registerCleanup(() => c.dispose());\n raw(c).mount(anchor, registerCleanup);\n });\n }\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const parent = anchor.parentNode;\n\n invariant(parent, 'raw() anchor comment has no parent node');\n\n const endMarker = document.createComment('raw/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n if (isReactive(value)) {\n let currentNodes: Node[] = [];\n const src = value as Readable<string>;\n\n const stop = rawEffect(() => {\n removeNodes(currentNodes);\n currentNodes = parseRaw(sanitize(src.value), parent, endMarker);\n });\n\n registerCleanup(() => stop.dispose());\n registerCleanup(() => {\n removeNodes(currentNodes);\n endMarker.remove();\n });\n } else {\n parseRaw(sanitize(value), parent, endMarker);\n\n registerCleanup(() => endMarker.remove());\n }\n });\n}\n","import { computed, isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { toKebab } from '../utils/dom';\n\ntype StyleInput =\n | string\n | number\n | null\n | undefined\n | false\n | (() => string | number | null | undefined | false)\n | Readable<string | number | null | undefined | false>;\n\nconst toStyleValue = (value: StyleInput): string => {\n const resolved = typeof value === 'function' ? value() : isReactive(value) ? value.value : value;\n\n if (resolved == null || resolved === false) return '';\n\n // Strip characters that can break out of a CSS declaration in inline styles.\n // Semicolons end the current declaration; braces are meaningful in stylesheets\n // but not inline style values and signal injection attempts.\n return String(resolved).replace(/[;{}]/g, '');\n};\n\n// Strip characters that can break out of a CSS declaration in inline styles.\n// This is applied to both property names and values: semicolons end declarations\n// and braces are meaningful in stylesheet rules (but not inline style values).\nconst UNSAFE_CSS_CHARS = /[;{}]/g;\n\n/**\n * Builds a reactive inline style string from a style object.\n *\n * Takes a record of CSS property names (camelCase) with values that can be:\n * - Static strings/numbers\n * - Functions that return strings/numbers\n * - Signals for reactive updates\n *\n * @example\n * ```ts\n * const color = signal('red');\n * const size = signal(16);\n *\n * html`<div :style=${styleMap({\n * backgroundColor: color,\n * width: () => `${size.value}px`,\n * padding: '10px'\n * })}></div>`\n * ```\n */\nexport const styleMap = (record: Record<string, StyleInput>): Readable<string> => {\n return computed(() => {\n const declarations: string[] = [];\n\n for (const [name, input] of Object.entries(record)) {\n const value = toStyleValue(input);\n\n if (!value) continue;\n\n const safeName = toKebab(name).replace(UNSAFE_CSS_CHARS, '');\n\n if (!safeName) continue;\n\n declarations.push(`${safeName}:${value}`);\n }\n\n return declarations.join(';');\n });\n};\n","import { computed, effect as rawEffect, isReactive, type Readable, untrack } from '@vielzeug/ripple';\n\nimport type { RegisterCleanup } from '../template';\n\nimport { invariant } from '../errors';\nimport { createDirectiveResult, type DirectiveResult, type HTMLResult, isHtmlResult } from '../types/bindings';\nimport { removeNodes, runAll } from '../utils/dom';\n\ntype MaybeReactive<T> = T | (() => T) | Readable<T>;\n\ntype WhenRenderable = HTMLResult | null | undefined | false;\n\nconst NO_PARENT_MSG = 'when() anchor comment has no parent node';\n\nconst mountBranch = (\n result: HTMLResult,\n parent: ParentNode,\n insertBefore: Node,\n registerCleanup: RegisterCleanup,\n): Node[] => result.mount(parent, insertBefore, registerCleanup);\n\n/**\n * Conditionally renders one of two branches as a `DirectiveResult`.\n *\n * The condition may be a boolean, signal, or getter function.\n * When the condition changes, the current branch is cleaned up and\n * the new branch is mounted in its place.\n *\n * @example\n * ```ts\n * html`${when(isLoggedIn, () => html`<p>Welcome</p>`, () => html`<p>Log in</p>`)}`\n * ```\n */\nexport function when(\n condition: MaybeReactive<boolean>,\n truthy: () => WhenRenderable,\n falsy?: () => WhenRenderable,\n): DirectiveResult {\n if (typeof condition !== 'function' && !isReactive(condition)) {\n return createDirectiveResult((anchor, registerCleanup) => {\n const branch = condition ? truthy() : falsy ? falsy() : null;\n\n if (!branch || !isHtmlResult(branch)) return;\n\n const parent = anchor.parentNode;\n\n invariant(parent, NO_PARENT_MSG);\n\n const nodes = mountBranch(branch, parent, anchor, registerCleanup);\n\n registerCleanup(() => removeNodes(nodes));\n });\n }\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const ownedComputed = typeof condition === 'function' ? computed(condition as () => boolean) : null;\n const conditionSignal = ownedComputed ?? (condition as Readable<boolean>);\n\n if (ownedComputed) registerCleanup(() => ownedComputed.dispose());\n\n const parent = anchor.parentNode;\n\n invariant(parent, NO_PARENT_MSG);\n\n const endMarker = document.createComment('when/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n let currentNodes: Node[] = [];\n let currentCleanups: (() => void)[] = [];\n\n const sub = rawEffect(() => {\n const next = conditionSignal.value;\n\n runAll(currentCleanups);\n removeNodes(currentNodes);\n currentCleanups = [];\n currentNodes = [];\n\n const branch = next ? truthy() : falsy ? falsy() : null;\n\n if (!branch || !isHtmlResult(branch)) return;\n\n const branchCleanups: (() => void)[] = [];\n\n currentNodes = untrack(() => mountBranch(branch, parent, endMarker, (fn) => branchCleanups.push(fn)));\n currentCleanups = branchCleanups;\n });\n\n registerCleanup(() => sub.dispose());\n registerCleanup(() => {\n runAll(currentCleanups);\n removeNodes(currentNodes);\n endMarker.remove();\n });\n });\n}\n","/**\n * Component runtime — implicit \"current component\" context plus every lifecycle\n * hook a `setup()` function can call.\n *\n * Design note: hooks are plain module-level functions (not a bag/context object\n * passed into `setup`). They resolve the active component through a single\n * module-level pointer (`currentContext`), set for the duration of `setup()` and\n * of each queued `onMounted` callback. This is the same mechanism React/Vue/Solid\n * use for their composable hooks — it lets any helper function (not just the\n * top-level `setup()` body) call `onMounted`/`onCleanup`/`bind`/... directly,\n * with no context object to thread through every layer of a composable.\n */\nimport {\n type CleanupFn,\n effect as _effect,\n type EffectCallback,\n onCleanup as _onCleanup,\n type Readable,\n} from '@vielzeug/ripple';\n\nimport { OreApiError, ORE_ERRORS } from './errors';\nimport { listen as listenInternal } from './utils/dom';\n\n// ─── Runtime context ──────────────────────────────────────────────────────────\n// A single context object carries both the host element and mount callbacks,\n// eliminating two parallel globals that were always set together.\n\nexport type OnMountedCallback = () => CleanupFn | void;\nexport type OnFormResetCallback = () => void;\n\nexport type RuntimeContext = {\n element: HTMLElement;\n formResetCallbacks: OnFormResetCallback[];\n mountCallbacks: OnMountedCallback[];\n};\n\nlet currentContext: RuntimeContext | null = null;\n\n/** @internal Execute fn with a given runtime context active. */\nexport const runWithContext = <T>(ctx: RuntimeContext, fn: () => T): T => {\n const prev = currentContext;\n\n currentContext = ctx;\n\n try {\n return fn();\n } finally {\n currentContext = prev;\n }\n};\n\n/**\n * Returns the current runtime context, throwing a consistently-worded error\n * (naming the calling API) if called outside `setup()`. Every lifecycle/context\n * hook below routes through this — it's the single place that decides both\n * \"are we inside setup?\" and what the resulting error looks like, so the error\n * message is never worse for one hook than another.\n * @internal\n */\nexport const requireSetupContext = (api: string): RuntimeContext => {\n if (currentContext) return currentContext;\n\n throw new OreApiError(`${api}: ${ORE_ERRORS.lifecycleOutsideSetup}`);\n};\n\n/**\n * Returns the current component's host element.\n * Only valid synchronously during component `setup()` (or inside a composable\n * called from it) — throws otherwise.\n */\nexport const getHost = (): HTMLElement => requireSetupContext('getHost').element;\n\nexport const tryRegisterCleanup = (fn: CleanupFn): boolean => {\n if (!currentContext) return false;\n\n _onCleanup(fn);\n\n return true;\n};\n\n/**\n * Register a cleanup function to run on component disconnect.\n * Must be called synchronously during component setup or inside scope.run().\n */\nexport const onCleanup = _onCleanup;\n\n/**\n * Register work to run after the component template mounts to the DOM.\n * Multiple callbacks run in registration order.\n */\nexport const onMounted = (fn: OnMountedCallback): void => {\n requireSetupContext('onMounted').mountCallbacks.push(fn);\n};\n\n/**\n * Register work to run when the ancestor `<form>` is reset (native `formResetCallback`,\n * only fires for `formAssociated: true` components). Multiple callbacks run in\n * registration order, every time the form resets — unlike `onMounted`, this isn't a\n * one-shot hook.\n */\nexport const onFormReset = (fn: OnFormResetCallback): void => {\n requireSetupContext('onFormReset').formResetCallbacks.push(fn);\n};\n\n/**\n * Create a reactive effect scoped to the component lifecycle.\n * Automatically cleaned up on component disconnect.\n * Returns a stop function that disposes the effect immediately.\n *\n * Named `watchEffect` (not `watch`) to avoid shadowing `@vielzeug/ripple`'s\n * `watch(source, callback)`, which has different semantics (explicit source,\n * old/new value pair) — the two are commonly imported in the same file.\n */\nexport const watchEffect = (fn: EffectCallback): (() => void) => {\n const sub = _effect(fn);\n const stop = (): void => sub.dispose();\n\n tryRegisterCleanup(stop);\n\n return stop;\n};\n\n/**\n * Attach a scoped event listener that is automatically removed on component disconnect.\n * Silently no-ops when `target` is `null` or `undefined` (safe for reactive targets).\n */\nexport function onEvent<K extends keyof HTMLElementEventMap>(\n target: EventTarget | null | undefined,\n event: K,\n listener: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n): void;\nexport function onEvent(\n target: EventTarget | null | undefined,\n event: string,\n listener: EventListener,\n options?: AddEventListenerOptions,\n): void {\n requireSetupContext('onEvent');\n\n if (!target) return;\n\n const cleanup = listenInternal(target, event, listener, options);\n\n if (!tryRegisterCleanup(cleanup)) cleanup();\n}\n\n/**\n * Watch a ref signal and run a callback when it resolves to a non-null element.\n * The callback's return value is used as a cleanup function.\n */\nexport const onElement = <T extends HTMLElement>(\n ref: Readable<T | null>,\n callback: (el: T) => CleanupFn | undefined | void,\n): (() => void) => {\n return watchEffect(() => {\n const el = ref.value;\n\n if (el) return callback(el);\n });\n};\n","import { type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { OreApiError, ORE_ERRORS } from '../errors';\nimport { getHost, onCleanup, onFormReset, watchEffect } from '../runtime';\n\n/** @internal */\nconst internalsRegistry = new WeakMap<HTMLElement, ElementInternals>();\n\nexport type FormFieldOptions<T = unknown> = {\n disabled?: Readable<boolean>;\n /**\n * The host element to attach `ElementInternals` to.\n * Defaults to the element currently being set up via `getHost()`.\n * Pass this explicitly when calling `useField` from a composable that is\n * not called directly during `setup()` (e.g. a helper factory function).\n */\n el?: HTMLElement;\n /**\n * When `true`, a `null` or `undefined` value is submitted as an empty string\n * (`''`) instead of `null`. This keeps the field's key present in `FormData`\n * even when the value is absent — useful when the server expects the field to\n * always be included.\n *\n * @default false\n */\n emptyStringForNull?: boolean;\n /**\n * Called when the ancestor `<form>` is reset (see `onFormReset`). Use to restore\n * whatever local state backs `value` — `useField` itself owns no field state to reset.\n */\n onReset?: () => void;\n toFormValue?: (value: T) => File | FormData | string | null;\n /**\n * Recomputed reactively and passed straight to `internals.setValidity()` — `null`\n * (or omitting `validity` entirely) means always valid. Pair with `validationMessage`.\n *\n * @example\n * ```ts\n * validity: computed(() => (required.value && isBlank(value.value)) ? { valueMissing: true } : null),\n * validationMessage: computed(() => (required.value && isBlank(value.value)) ? 'Required.' : ''),\n * ```\n */\n validationMessage?: Readable<string>;\n validity?: Readable<ValidityStateFlags | null>;\n value: Signal<T> | Readable<T>;\n};\n\nexport type FormFieldHandle = {\n checkValidity: () => boolean;\n readonly internals: ElementInternals;\n reportValidity: () => boolean;\n setCustomValidity: (message: string) => void;\n setValidity: ElementInternals['setValidity'];\n};\n\nexport const useField = <T = unknown>(options: FormFieldOptions<T>): FormFieldHandle => {\n const host = options.el ?? getHost();\n const ctor = host.constructor as typeof HTMLElement & { formAssociated?: boolean };\n\n if (!ctor.formAssociated) {\n throw new OreApiError(ORE_ERRORS.defineFieldRequiresFormAssociated(host.localName));\n }\n\n if (internalsRegistry.has(host)) {\n throw new OreApiError(`useField() was already called on <${host.localName}>. Call it only once per component.`);\n }\n\n const internals = host.attachInternals();\n\n internalsRegistry.set(host, internals);\n onCleanup(() => internalsRegistry.delete(host));\n\n const toFormValue =\n options.toFormValue ??\n ((v: T): File | FormData | string | null => {\n if (v == null) return options.emptyStringForNull ? '' : null;\n\n if (v instanceof File || v instanceof FormData) return v;\n\n return String(v);\n });\n\n watchEffect(() => {\n internals.setFormValue(toFormValue(options.value.value));\n });\n\n const disabled = options.disabled;\n\n if (disabled) {\n if (!('states' in internals)) {\n warn(\n 'useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.',\n );\n } else {\n const states = internals.states as CustomStateSet;\n\n watchEffect(() => {\n if (disabled.value) states.add('disabled');\n else states.delete('disabled');\n });\n }\n }\n\n if (options.validity) {\n watchEffect(() => {\n const flags = options.validity?.value ?? {};\n // Per spec, ElementInternals.setValidity() throws if any flag is true and message is\n // empty — a caller-supplied `validity` with no matching `validationMessage` would crash\n // this effect in a real browser. Fail safe with a generic message instead of propagating\n // that crash, and say so loudly in dev so the real fix (pass validationMessage) gets made.\n const hasFlag = Object.values(flags).some(Boolean);\n const message = options.validationMessage?.value ?? '';\n\n if (hasFlag && !message) {\n warn(\n 'useField(): `validity` has a truthy flag but `validationMessage` is empty — internals.setValidity() ' +\n 'requires a non-empty message whenever any flag is true. Falling back to a generic message; pass ' +\n '`validationMessage` to customize it.',\n );\n internals.setValidity(flags, 'Invalid value.');\n\n return;\n }\n\n internals.setValidity(flags, message);\n });\n }\n\n if (options.onReset) onFormReset(options.onReset);\n\n const checkValidity = () => internals.checkValidity();\n const reportValidity = () => internals.reportValidity();\n const setCustomValidity = (message: string) =>\n message ? internals.setValidity({ customError: true }, message) : internals.setValidity({});\n\n return {\n checkValidity,\n internals,\n reportValidity,\n setCustomValidity,\n setValidity: internals.setValidity.bind(internals),\n };\n};\n","/**\n * Component context injection API — `inject` / `injectStrict` / `provide` / `createContext`.\n *\n * Context values are stored on the providing element via a WeakMap registry and\n * resolved by walking up the DOM tree (including through shadow boundaries).\n * Providing is done via `provide(key, value)` inside `setup()`.\n */\n\nimport { warn } from './_dev';\nimport { OreApiError, ORE_ERRORS } from './errors';\nimport { getHost, requireSetupContext } from './runtime';\n\nconst contextRegistry = new WeakMap<HTMLElement, Map<InjectionKey<unknown>, unknown>>();\n\nexport type InjectionKey<T> = symbol & {\n readonly __ore_injection_key?: T;\n};\n\n/** @internal Build a linear ancestor chain (including shadow host boundaries). */\nconst buildAncestorChain = (start: HTMLElement): HTMLElement[] => {\n const chain: HTMLElement[] = [];\n let node: Node | null = start;\n\n while (node) {\n if (node instanceof HTMLElement) chain.push(node);\n\n const root = node.getRootNode() as Node;\n\n node = (node as HTMLElement).parentElement ?? (root instanceof ShadowRoot ? root.host : null);\n }\n\n return chain;\n};\n\n/**\n * Register a context value on a specific element.\n * @internal Backs the public `provide()` — do not call directly.\n */\nconst provideOnElement = <T>(el: HTMLElement, key: InjectionKey<T>, value: T): void => {\n const map = contextRegistry.get(el) ?? new Map<InjectionKey<unknown>, unknown>();\n\n // `inject()` memoizes its result per consumer (see resolvedCache below), so a\n // provider swapping the raw value after a descendant already read it would be\n // silently ignored downstream. Provide a `Readable` (signal/computed) instead\n // of a raw value so descendants observe updates through the value itself.\n if (map.has(key)) {\n warn(\n `provide(): key already provided on <${el.localName}> — overwriting. Provide a Readable to update it instead.`,\n );\n }\n\n map.set(key, value);\n contextRegistry.set(el, map);\n};\n\n/**\n * Register a context value on the current component's host element, making it\n * available to descendant components via `inject(key)`.\n *\n * Provide a `Readable` (signal/computed) rather than a raw value if descendants\n * need to observe later changes — `inject()` resolves and caches the value once\n * per consumer, so re-calling `provide()` with a new raw value later is not seen.\n */\nexport const provide = <T>(key: InjectionKey<T>, value: T): void => provideOnElement(getHost(), key, value);\n\nconst NOT_FOUND_SENTINEL = Symbol('inject.not_found');\n\n/** Per-setup-context cache: avoids repeated ancestor walks for the same key. */\nconst resolvedCache = new WeakMap<object, Map<InjectionKey<unknown>, unknown>>();\n\nconst walkAndFind = <T>(element: HTMLElement, key: InjectionKey<T>): T | typeof NOT_FOUND_SENTINEL => {\n const chain = buildAncestorChain(element);\n\n for (const node of chain) {\n const map = contextRegistry.get(node);\n\n if (map?.has(key)) return map.get(key) as T;\n }\n\n return NOT_FOUND_SENTINEL;\n};\n\nexport function inject<T>(key: InjectionKey<T>): T | undefined;\nexport function inject<T>(key: InjectionKey<T>, fallback: T): T;\nexport function inject<T>(key: InjectionKey<T>, ...rest: [T?]): T | undefined {\n const ctx = requireSetupContext('inject');\n\n let cache = resolvedCache.get(ctx);\n\n if (!cache) {\n cache = new Map();\n resolvedCache.set(ctx, cache);\n }\n\n const cacheKey = key as InjectionKey<unknown>;\n\n if (cache.has(cacheKey)) {\n const cached = cache.get(cacheKey);\n\n if (cached === NOT_FOUND_SENTINEL) return rest.length > 0 ? rest[0] : undefined;\n\n return cached as T;\n }\n\n const found = walkAndFind(ctx.element, key);\n\n cache.set(cacheKey, found);\n\n if (found === NOT_FOUND_SENTINEL) return rest.length > 0 ? rest[0] : undefined;\n\n return found;\n}\n\nexport const injectStrict = <T>(key: InjectionKey<T>): T => {\n const resolved = inject<T>(key, NOT_FOUND_SENTINEL as unknown as T);\n\n if (resolved !== (NOT_FOUND_SENTINEL as unknown)) return resolved;\n\n const host = getHost();\n\n throw new OreApiError(ORE_ERRORS.injectStrictFailed(String(key), host.localName));\n};\n\nexport function createContext<T>(description?: string): InjectionKey<T> {\n return Symbol(description) as InjectionKey<T>;\n}\n","import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { createContext } from '../context';\n\n/**\n * Context shape injected by child field components.\n * Contains only what a field needs — not submit/error/status APIs.\n */\nexport type FormFieldContext = {\n /** Whether any field has been touched (interacted with). Set via markDirty(). */\n readonly dirty: Readable<boolean>;\n markDirty(): void;\n /**\n * Register a field's validity signal with the form context.\n * Returns a cleanup function.\n */\n registerField(validity: Readable<boolean>): () => void;\n};\n\n/**\n * Full form controller returned by `createFormContext`.\n * Extends `FormFieldContext` with submission and status APIs.\n */\nexport type FormController = FormFieldContext & {\n /**\n * Clear `dirty` and `error` status signals and invoke `onReset` if provided.\n * Note: this does not reset individual field values — pass an `onReset` callback\n * to handle value restoration.\n */\n clearStatus(): void;\n /** The last submit error, or null if the last submit succeeded. */\n readonly error: Readable<unknown>;\n /** Submit the form programmatically. */\n submit(e?: Event): Promise<void>;\n /** Whether the form is currently submitting. */\n readonly submitting: Readable<boolean>;\n /** Whether all fields in the form are valid. */\n readonly valid: Readable<boolean>;\n};\n\nexport const FORM_CONTEXT_KEY = createContext<FormFieldContext>('ore:form-context');\n\n/**\n * Create a `FormController` for coordinating form state across child field components.\n * Call `provide(FORM_CONTEXT_KEY, form)` to make it available to descendants.\n *\n * @example\n * ```ts\n * define('my-form', {\n * setup(_props) {\n * const form = createFormContext({ onSubmit: async (e) => { ... } });\n * provide(FORM_CONTEXT_KEY, form);\n * return html`<form @submit=${form.submit}><slot></slot></form>`;\n * }\n * });\n * ```\n */\nexport function createFormContext(\n options: {\n onReset?: () => void;\n onSubmit?: (e?: Event) => void | Promise<void>;\n } = {},\n): FormController {\n const fieldValiditySignals = signal<Array<Readable<boolean>>>([]);\n const submitting = signal(false);\n const dirty = signal(false);\n const error = signal<unknown>(null);\n\n // Note: [].every() is vacuously true, so valid is true when no fields are registered.\n // This is intentional — a form with no fields is considered valid (nothing to invalidate it).\n const valid = computed(() => fieldValiditySignals.value.every((s) => s.value));\n\n const submit = async (e?: Event): Promise<void> => {\n e?.preventDefault();\n\n if (submitting.value) return;\n\n submitting.value = true;\n error.value = null;\n\n try {\n await options.onSubmit?.(e);\n dirty.value = false;\n } catch (err) {\n error.value = err;\n } finally {\n submitting.value = false;\n }\n };\n\n const clearStatus = (): void => {\n dirty.value = false;\n error.value = null;\n options.onReset?.();\n };\n\n const markDirty = (): void => {\n dirty.value = true;\n };\n\n const registerField = (validity: Readable<boolean>): (() => void) => {\n fieldValiditySignals.value = [...fieldValiditySignals.value, validity];\n\n return () => {\n fieldValiditySignals.value = fieldValiditySignals.value.filter((s) => s !== validity);\n };\n };\n\n return { clearStatus, dirty, error, markDirty, registerField, submit, submitting, valid };\n}\n","import { type Readable, type Signal, signal } from '@vielzeug/ripple';\n\nimport { warn } from './_dev';\nimport { invariant, OreApiError, ORE_ERRORS } from './errors';\nimport { watchEffect } from './runtime';\nimport { isStructuredValue, setAttr, toKebab } from './utils/dom';\n\nexport type PropsDef<T extends Record<string, unknown>> = {\n // All props must be explicitly defined via prop.* helpers or PropDef objects\n [K in keyof Required<T>]: PropDef<T[K & keyof T]>;\n};\n\nexport type PropDef<T> = { readonly default: T; readonly parse: (value: string | null) => T; reflect?: boolean };\nexport type PropInputDefs = Record<string, PropDef<unknown>>;\n\n/**\n * Prop definition factory — use these helpers for all prop definitions.\n * No implicit type inference; all parser behavior is explicit and intentional.\n */\ntype PropFactory = {\n bool(defaultValue?: boolean): PropDef<boolean>;\n /**\n * JS-only property — never reads from or writes to an HTML attribute.\n * Use for complex objects, arrays, callbacks, or any non-serialisable value.\n *\n * @example\n * ```ts\n * columns: prop.data<DataGridColumn[]>([]),\n * config: prop.data<Options>(),\n * getRowKey: prop.data<(row: T) => string>(),\n * onSelect: prop.data<(item: T) => void>(),\n * ```\n */\n data<T>(): PropDef<T | undefined>;\n data<T>(defaultValue: T): PropDef<T>;\n json<T>(defaultValue: T): PropDef<T>;\n number<T extends number = number>(): PropDef<T | undefined>;\n number<T extends number = number>(defaultValue: number): PropDef<T>;\n oneOf<T extends string | undefined, D extends T = T>(allowed: readonly NonNullable<T>[], defaultValue: D): PropDef<T>;\n string<T extends string = string>(): PropDef<T | undefined>;\n string<T extends string = string>(defaultValue: string): PropDef<T>;\n};\n\n/** @internal JS-only prop implementation — never reads/writes attributes. */\nfunction _jsOnlyProp<T>(defaultValue?: T): PropDef<T | undefined> | PropDef<T> {\n return { default: defaultValue, parse: () => defaultValue, reflect: false } as PropDef<T | undefined>;\n}\n\nexport const prop: PropFactory = {\n /**\n * Boolean prop — reflects its value as a presence-only attribute (toggleAttribute).\n * Reflection is always enabled. To suppress attribute reflection for a boolean,\n * use `prop.data<boolean>(false)` instead.\n */\n bool(defaultValue?: boolean): PropDef<boolean> {\n const def = defaultValue ?? false;\n\n return {\n default: def,\n parse: (value) => value !== null && value !== 'false',\n reflect: true,\n };\n },\n data<T>(defaultValue?: T): PropDef<T | undefined> | PropDef<T> {\n return _jsOnlyProp(defaultValue);\n },\n /**\n * JSON-serialisable prop — the value is stored as a JS object and parsed\n * from the attribute via `JSON.parse`. Reflection is always disabled\n * because serialising complex objects back to attributes on every change\n * would be expensive and produce unreadable HTML.\n *\n * @example\n * ```ts\n * columns: prop.json<Column[]>([]),\n * // attribute: <my-grid columns='[{\"id\":\"name\"}]'>\n * // change not reflected back → attribute stays static after upgrade\n * ```\n */\n json<T>(defaultValue: T): PropDef<T> {\n return {\n default: defaultValue,\n parse: (value) => {\n if (value == null || value === '') return defaultValue;\n\n try {\n return JSON.parse(value) as T;\n } catch {\n return defaultValue;\n }\n },\n reflect: false,\n };\n },\n number<T extends number = number>(defaultValue?: number): PropDef<T> | PropDef<T | undefined> {\n const def = defaultValue !== undefined ? (defaultValue as T) : undefined;\n\n return {\n default: def,\n parse: (value) => {\n if (value == null) return def;\n\n const n = Number(value);\n\n if (Number.isNaN(n)) {\n warn(`prop.number(): attribute value \"${value}\" is not a valid number, using default (${String(def)})`);\n\n return def;\n }\n\n return n as T;\n },\n reflect: true,\n } as PropDef<T> | PropDef<T | undefined>;\n },\n oneOf<T extends string | undefined, D extends T = T>(\n allowed: readonly NonNullable<T>[],\n defaultValue: D,\n ): PropDef<T> {\n return {\n default: defaultValue,\n parse: (value) => (value != null && allowed.includes(value as NonNullable<T>) ? (value as T) : defaultValue),\n reflect: true,\n };\n },\n string<T extends string = string>(defaultValue?: string): PropDef<T> | PropDef<T | undefined> {\n // When no default provided, undefined sentinel → attribute removed when value is absent\n const def = defaultValue !== undefined ? (defaultValue as T) : undefined;\n\n return {\n default: def,\n parse: (value: string | null) => (value == null ? def : (value as T)),\n reflect: true,\n } as PropDef<T> | PropDef<T | undefined>;\n },\n};\n\n/**\n * Define a custom prop with explicit parser and reflection behavior.\n * Use when prop.* helpers don't cover your type.\n *\n * @example\n * ```ts\n * const customProp = (): PropDef<MyCustomType> => ({\n * default: new MyCustomType(),\n * parse: (value) => JSON.parse(value || '{}') as MyCustomType,\n * reflect: false,\n * });\n * ```\n */\n\nconst isPropDef = (value: unknown): value is PropDef<unknown> =>\n typeof value === 'object' && value !== null && 'default' in value && 'parse' in value;\n\n/**\n * Validate and normalize a prop definition.\n * Throws if definition is invalid or incomplete.\n */\nexport function normalizePropDefinition<T>(value: unknown, propName: string): PropDef<T> {\n if (!isPropDef(value)) {\n throw new OreApiError(\n `Prop \"${propName}\" must use a prop.* helper (string/number/bool/json/oneOf). Received: ${typeof value}`,\n );\n }\n\n const descriptor = value as PropDef<T>;\n\n if (!descriptor.parse) {\n throw new OreApiError(`Prop \"${propName}\" must have a parse function. Use prop.* helpers.`);\n }\n\n const reflect = descriptor.reflect ?? false;\n\n // Validate: structured defaults with reflect:true are not allowed\n if (reflect && isStructuredValue(descriptor.default)) {\n throw new OreApiError(`Prop \"${propName}\": ${ORE_ERRORS.propInvalidReflect}`);\n }\n\n return {\n ...descriptor,\n reflect,\n };\n}\n\n/**\n * Validate all prop definitions at define-time.\n * Returns validation error messages or empty array if valid.\n */\nexport function validatePropDefs(defs: Record<string, unknown>): string[] {\n const errors: string[] = [];\n\n for (const [key, value] of Object.entries(defs)) {\n try {\n normalizePropDefinition(value, key);\n } catch (error) {\n errors.push(error instanceof Error ? error.message : String(error));\n }\n }\n\n return errors;\n}\n\ntype PropMeta<T = unknown> = {\n parse: (value: string | null) => T;\n reflect: boolean;\n signal: Signal<T>;\n};\n\nconst propRegistry = new WeakMap<HTMLElement, Map<string, PropMeta<unknown>>>();\n\n/**\n * Look up the registered prop metadata for a given attribute name on an element.\n * Used by the template compiler to resolve prop bindings without exposing the registry.\n */\nexport const getPropMeta = (el: HTMLElement, attrName: string): PropMeta<unknown> | undefined =>\n propRegistry.get(el)?.get(attrName);\n\n/**\n * A framework can hand a prop a raw attribute-style string well after the element\n * has upgraded — e.g. Vue reconciling server-rendered markup against a custom\n * element that auto-upgraded from its SSR attribute before hydration ran, or\n * assigning the pre-upgrade instance property it captured before `registerProp`\n * defined the real accessor. In both cases route the string through the same\n * parser an attribute value would use (so e.g. `size=\"16\"` doesn't end up stored\n * as the string `\"16\"` instead of the number `16`). Already-typed values (objects,\n * functions, booleans, numbers set deliberately as JS properties) pass through untouched.\n */\nconst coerceIncoming = <T>(value: unknown, parse: PropDef<T>['parse']): T =>\n (typeof value === 'string' ? parse(value) : value) as T;\n\n/** @internal Runtime prop registration (called by createProps) */\nconst registerProp = <T>(el: HTMLElement, propName: string, attrName: string, propDef: PropDef<T>): Signal<T> => {\n if (!propRegistry.has(el)) propRegistry.set(el, new Map());\n\n const { default: defaultValue, parse, reflect = false } = propDef;\n const s = signal<T>(defaultValue);\n const hasPreUpgradeProperty = Object.hasOwn(el as unknown as Record<string, unknown>, propName);\n const preUpgradeValue = hasPreUpgradeProperty ? (el as unknown as Record<string, unknown>)[propName] : undefined;\n\n const meta: PropMeta<unknown> = {\n parse,\n reflect,\n signal: s,\n };\n\n if (hasPreUpgradeProperty) {\n delete (el as unknown as Record<string, unknown>)[propName];\n s.value = coerceIncoming(preUpgradeValue, parse);\n } else if (el.hasAttribute(attrName)) {\n s.value = parse(el.getAttribute(attrName)) as T;\n }\n\n const registry = propRegistry.get(el);\n\n invariant(registry, `propRegistry entry missing for <${el.localName}> — registerProp() must create it above`);\n registry.set(attrName, meta);\n\n Object.defineProperty(el, propName, {\n configurable: true,\n enumerable: true,\n get: () => s.value,\n set: (value: T) => {\n s.value = coerceIncoming(value, parse);\n },\n });\n\n if (reflect) {\n watchEffect(() => {\n const v = s.value;\n\n if (v == null) {\n el.removeAttribute(attrName);\n } else if (typeof v === 'boolean') {\n el.toggleAttribute(attrName, v);\n } else {\n setAttr(el, attrName, v);\n }\n });\n }\n\n return s;\n};\n\nexport type InferPropValue<T> = T extends PropDef<infer U> ? U : T;\n\n/**\n * Infer the reactive props object type from a `PropInputDefs` map.\n * Each entry becomes a `Reactive<T>` keyed by the prop name.\n *\n * @example\n * ```ts\n * const propDefs = { count: prop.number(0), label: prop.string('hi') };\n * type Props = InferProps<typeof propDefs>;\n * // => { readonly count: Readable<number>; readonly label: Readable<string> }\n * ```\n */\nexport type InferProps<D extends PropInputDefs> = {\n readonly [K in keyof D]-?: Readable<InferPropValue<D[K]>>;\n};\n\nexport function createProps<D extends PropInputDefs>(el: HTMLElement, defs: D): InferProps<D> {\n const props = {} as Record<string, Signal<unknown>>;\n\n for (const [name, def] of Object.entries(defs)) {\n // defs passed here are already normalized by define(); skip re-normalization.\n const attrName = toKebab(name);\n\n props[name] = registerProp(el, name, attrName, def as PropDef<unknown>);\n }\n\n return props as unknown as InferProps<D>;\n}\n","/**\n * Shared component phase and lifecycle event constants.\n * Extracted to a standalone module to break the circular dependency\n * between registration.ts and errors.ts.\n */\n\n// ─── ComponentPhase ───────────────────────────────────────────────────────────\n\nexport const ComponentPhase = {\n LOADING: 'loading',\n SETUP_DONE: 'setup_done',\n SETUP_RUNNING: 'setup_running',\n UNINITIALIZED: 'uninitialized',\n UNMOUNTED: 'unmounted',\n} as const;\n\nexport type ComponentPhase = (typeof ComponentPhase)[keyof typeof ComponentPhase];\n\n// ─── Lifecycle events ─────────────────────────────────────────────────────────\n\nexport const LIFECYCLE_EVENTS = {\n CONNECT: 'ore:connect',\n DISCONNECT: 'ore:disconnect',\n} as const;\n\nexport type LifecycleEventName = (typeof LIFECYCLE_EVENTS)[keyof typeof LIFECYCLE_EVENTS];\n","/**\n * CSS tagged template utility and CSSStyleSheet caching.\n */\n\nimport { error } from '../_dev';\n\nexport type CSSResult = {\n content: string;\n toString(): string;\n};\n\nconst cssResultBrand = new WeakSet<CSSResult>();\n\nexport const isCssResult = (value: unknown): value is CSSResult =>\n typeof value === 'object' && value !== null && cssResultBrand.has(value as CSSResult);\n\nconst cssResultToString = function (this: CSSResult): string {\n return this.content;\n};\n\nexport const css = (strings: TemplateStringsArray, ...values: Array<CSSResult | string | number>): CSSResult => {\n let content = '';\n\n for (let i = 0; i < strings.length; i++) {\n content += strings[i];\n\n if (i < values.length) {\n const v = values[i];\n\n content += isCssResult(v) ? v.content : String(v);\n }\n }\n\n const result: CSSResult = { content: content.trim(), toString: cssResultToString };\n\n cssResultBrand.add(result);\n\n return result;\n};\n\nconst stylesheetStringCache = new Map<string, CSSStyleSheet>();\n\n/** @internal Clear the stylesheet cache. Used for test isolation and HMR. */\nexport const _clearStylesheetCache = (): void => {\n stylesheetStringCache.clear();\n};\n\nexport const loadStylesheet = (style: string | CSSStyleSheet | CSSResult): CSSStyleSheet => {\n if (style instanceof CSSStyleSheet) return style;\n\n const cssText = typeof style === 'string' ? style : style.content;\n const cached = stylesheetStringCache.get(cssText);\n\n if (cached) return cached;\n\n const sheet = new CSSStyleSheet();\n\n try {\n sheet.replaceSync(cssText);\n } catch (err) {\n error('Style sheet replace failed', err);\n }\n\n stylesheetStringCache.set(cssText, sheet);\n\n return sheet;\n};\n","import { scope as _scope, type Scope, untrack } from '@vielzeug/ripple';\n\nimport type { ComponentDefinition } from './component-types';\n\nimport { warn } from './_dev';\nimport { type OreErrorPhase, OreLifecycleError, reportRuntimeError } from './errors';\nimport { createProps, getPropMeta, type InferProps, type PropInputDefs, type PropsDef } from './props';\nimport {\n type OnFormResetCallback,\n type OnMountedCallback,\n onCleanup,\n type RuntimeContext,\n runWithContext,\n} from './runtime';\nimport { ComponentPhase, LIFECYCLE_EVENTS } from './types';\nimport { type HTMLResult } from './types/bindings';\nimport { loadStylesheet } from './utils/css';\n\n// ─── Internal component state ─────────────────────────────────────────────────\n\ntype ComponentState = {\n /** Registered via `onFormReset()` — persists across mount callbacks, unlike `mountCallbacks`. */\n formResetCallbacks: OnFormResetCallback[];\n /** Incremented on every disconnect — guards both mount callbacks and async setup results. */\n generation: number;\n mountCallbacks: OnMountedCallback[];\n phase: ComponentPhase;\n scope: Scope;\n templateResult: HTMLResult | null;\n};\n\nconst createComponentState = (): ComponentState => ({\n formResetCallbacks: [],\n generation: 0,\n mountCallbacks: [],\n phase: ComponentPhase.UNINITIALIZED,\n scope: _scope(),\n templateResult: null,\n});\n\n// ─── BaseElement ──────────────────────────────────────────────────────────────\n\n/**\n * Phase transitions:\n *\n * ```\n * UNINITIALIZED ──_runSetup()──┬─(sync result)──► SETUP_DONE\n * └─(promise)──────► LOADING ──(resolves)──► SETUP_DONE\n * SETUP_DONE / LOADING ──disconnectedCallback()──► UNMOUNTED ──(reset)──► UNINITIALIZED\n * ```\n *\n * `generation` increments on every disconnect and is captured before an async\n * `setup()` is awaited; if it no longer matches when the promise settles, the\n * element was disconnected (and possibly reconnected) in the meantime and the\n * result is discarded (see `_isStale`).\n *\n * Why this lives on the class instead of a standalone pure reducer: every\n * transition here is triggered by running actual user code (`def.setup()`,\n * `onMounted` callbacks) inside a reactive `scope.run()` + `runWithContext()`\n * — there is no meaningful \"decide the next phase\" step that can be separated\n * from \"run the side-effecting thing that produces the phase change\" without\n * introducing a data-only effect-description layer that this package has no\n * other use for. That's why the methods below stay as direct, readable\n * procedural steps instead of a reducer + effect interpreter.\n */\nexport class BaseElement extends HTMLElement {\n static _definition: ComponentDefinition<any>;\n static _normalizedPropDefs: PropsDef<Record<never, never>> | undefined;\n static formAssociated = false;\n static observedAttributes: string[] = [];\n\n private _component: ComponentState;\n\n constructor() {\n super();\n\n const def = (this.constructor as typeof BaseElement)._definition;\n\n if (def?.shadow !== false) {\n this.attachShadow({ mode: 'open', ...(def?.shadow as Partial<ShadowRootInit> | undefined) });\n }\n\n this._component = createComponentState();\n }\n\n connectedCallback(): void {\n untrack(() => {\n if (this._component.phase === ComponentPhase.UNINITIALIZED) this._runSetup();\n\n this._init();\n });\n this.dispatchEvent(new CustomEvent(LIFECYCLE_EVENTS.CONNECT, { bubbles: false, composed: false }));\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n\n const propMeta = getPropMeta(this, name);\n\n if (!propMeta) return;\n\n const parsed = propMeta.parse(newValue);\n\n if (\n !Object.is(\n untrack(() => propMeta.signal.value),\n parsed,\n )\n )\n propMeta.signal.value = parsed as never;\n }\n\n disconnectedCallback(): void {\n this._component.generation++;\n this._component.phase = ComponentPhase.UNMOUNTED;\n this.dispatchEvent(new CustomEvent(LIFECYCLE_EVENTS.DISCONNECT, { bubbles: false, composed: false }));\n this._component.scope.dispose();\n // Reset mutable fields for next connect, keeping the same object for stable references\n this._component.formResetCallbacks = [];\n this._component.mountCallbacks = [];\n this._component.phase = ComponentPhase.UNINITIALIZED;\n this._component.scope = _scope();\n this._component.templateResult = null;\n }\n\n /**\n * Native form-association lifecycle callback — the browser calls this on every\n * `formAssociated: true` element inside a `<form>` when that form is reset.\n * Runs every `onFormReset()` callback registered during `setup()`.\n */\n formResetCallback(): void {\n for (const callback of this._component.formResetCallbacks) {\n try {\n callback();\n } catch (error) {\n this._handleSetupError(error, 'form-reset');\n }\n }\n }\n\n private _handleSetupError(error: unknown, phase: OreErrorPhase = 'setup'): HTMLResult | void {\n const err = error instanceof Error ? error : new Error(String(error));\n const oreError = new OreLifecycleError(`<${this.localName}> failed during ${this._component.phase} (${phase})`, {\n cause: err,\n component: this.localName,\n phase,\n });\n const def = (this.constructor as typeof BaseElement)._definition;\n\n if (def?.onError) {\n try {\n return def.onError(oreError, this);\n } catch {\n /* fall through */\n }\n }\n\n reportRuntimeError(oreError, this);\n }\n\n private _runSetup(): void {\n this._component.phase = ComponentPhase.SETUP_RUNNING;\n\n const def = (this.constructor as typeof BaseElement)._definition;\n const normalizedPropDefs = (this.constructor as typeof BaseElement)._normalizedPropDefs;\n const ctx: RuntimeContext = { element: this, formResetCallbacks: [], mountCallbacks: [] };\n\n try {\n let setupResult: HTMLResult | null | Promise<HTMLResult | null> | undefined;\n\n this._component.scope.run(() => {\n setupResult = runWithContext(ctx, () => {\n const setupProps = normalizedPropDefs\n ? createProps(this, normalizedPropDefs)\n : ({} as InferProps<PropInputDefs>);\n\n return def.setup(setupProps as InferProps<PropInputDefs>);\n });\n });\n this._component.mountCallbacks.push(...ctx.mountCallbacks);\n this._component.formResetCallbacks.push(...ctx.formResetCallbacks);\n\n if (setupResult != null && typeof (setupResult as Promise<HTMLResult | null>).then === 'function') {\n // Async setup: show loading template immediately, swap when resolved.\n // Store captured mount callbacks; they will be scheduled after the real template mounts.\n const pendingCallbacks = this._component.mountCallbacks.splice(0);\n\n this._component.phase = ComponentPhase.LOADING;\n\n if (def.loading) {\n this._component.templateResult = def.loading();\n }\n\n // Capture the current generation so the async handler can detect staleness:\n // if the element disconnects+reconnects before the promise resolves, generation is\n // incremented and the old promise result must be discarded.\n void this._runSetupAsync(\n setupResult as Promise<HTMLResult | null>,\n pendingCallbacks,\n this._component.generation,\n );\n } else {\n this._component.templateResult = (setupResult as HTMLResult | null) ?? null;\n this._component.phase = ComponentPhase.SETUP_DONE;\n }\n } catch (error) {\n const recoveryTemplate = this._handleSetupError(error);\n\n if (recoveryTemplate) {\n this._component.templateResult = recoveryTemplate;\n this._component.phase = ComponentPhase.SETUP_DONE;\n } else {\n this._component.phase = ComponentPhase.UNINITIALIZED;\n throw error;\n }\n }\n }\n\n /**\n * True once the element has disconnected (and possibly reconnected) since\n * `capturedGeneration` was recorded — an in-flight async `setup()` result\n * arriving after that point is for an instance state that no longer exists.\n */\n private _isStale(capturedGeneration: number): boolean {\n return this._component.generation !== capturedGeneration || !this.isConnected;\n }\n\n private async _runSetupAsync(\n promise: Promise<HTMLResult | null>,\n pendingCallbacks: OnMountedCallback[],\n capturedGeneration: number,\n ): Promise<void> {\n try {\n const result = await promise;\n\n if (this._isStale(capturedGeneration)) {\n warn(`<${this.localName}> async setup result discarded — element disconnected before setup resolved.`);\n\n return;\n }\n\n this._component.templateResult = result ?? null;\n this._component.phase = ComponentPhase.SETUP_DONE;\n this._component.mountCallbacks.push(...pendingCallbacks);\n\n if (result) this._applyResult(result);\n\n this._scheduleMountCallbacks();\n } catch (error) {\n if (this._isStale(capturedGeneration)) {\n warn(`<${this.localName}> async setup error discarded — element disconnected before setup resolved.`);\n\n return;\n }\n\n const recovery = this._handleSetupError(error, 'async-setup');\n\n if (recovery) {\n this._component.templateResult = recovery;\n this._component.phase = ComponentPhase.SETUP_DONE;\n this._applyResult(recovery);\n } else {\n this._component.phase = ComponentPhase.UNINITIALIZED;\n }\n }\n }\n\n private _applyResult(result: HTMLResult | null): void {\n if (!result) return;\n\n const host: Element | ShadowRoot = this.shadowRoot ?? this;\n\n host.replaceChildren(result.fragment);\n this._component.scope.run(() => {\n result.apply(onCleanup);\n });\n }\n\n private _init(): void {\n this._applyStyles();\n this._mountTemplate();\n\n // Only schedule mount callbacks once setup is fully complete (not in LOADING state)\n if (this._component.phase === ComponentPhase.SETUP_DONE) this._scheduleMountCallbacks();\n }\n\n private _applyStyles(): void {\n const def = (this.constructor as typeof BaseElement)._definition;\n\n if (this.shadowRoot && def?.styles?.length) {\n this.shadowRoot.adoptedStyleSheets = def.styles.map(loadStylesheet);\n }\n }\n\n private _mountTemplate(): void {\n const result = this._component.templateResult;\n\n if (!result) return;\n\n this._applyResult(result);\n }\n\n private _scheduleMountCallbacks(): void {\n if (this._component.mountCallbacks.length === 0) return;\n\n const capturedGeneration = this._component.generation;\n\n queueMicrotask(() => {\n if (this._isStale(capturedGeneration)) return;\n\n // Snapshot callbacks so in-loop registrations don't extend this iteration.\n const batch = this._component.mountCallbacks.splice(0);\n\n for (const callback of batch) {\n try {\n const nestedCtx = {\n element: this,\n formResetCallbacks: [] as typeof this._component.formResetCallbacks,\n mountCallbacks: [] as typeof this._component.mountCallbacks,\n };\n\n this._component.scope.run(() => {\n runWithContext(nestedCtx, () => {\n const cleanup = callback();\n\n if (typeof cleanup === 'function') onCleanup(cleanup);\n });\n });\n\n if (nestedCtx.mountCallbacks.length > 0) {\n this._component.mountCallbacks.push(...nestedCtx.mountCallbacks);\n }\n\n if (nestedCtx.formResetCallbacks.length > 0) {\n this._component.formResetCallbacks.push(...nestedCtx.formResetCallbacks);\n }\n } catch (error) {\n this._handleSetupError(error, 'mounted');\n }\n }\n\n // If nested onMounted calls registered new callbacks, schedule them with\n // a fresh token check in the next microtask.\n if (this._component.mountCallbacks.length > 0) {\n this._scheduleMountCallbacks();\n }\n });\n }\n}\n","import type { ComponentDefinition } from './component-types';\n\nimport { BaseElement } from './base-element';\nimport { OreApiError, ORE_ERRORS } from './errors';\nimport {\n type InferProps,\n normalizePropDefinition,\n prop,\n type PropDef,\n type PropInputDefs,\n type PropsDef,\n validatePropDefs,\n} from './props';\nimport { toKebab } from './utils/dom';\n\nexport { prop };\nexport type { InferProps, PropDef, PropInputDefs, PropsDef };\nexport type { HostBindFn } from './host-bind';\n\n/**\n * Define and register a web component.\n *\n * The `setup` function runs once per instance on first connect and returns an\n * `HTMLResult`. All reactive behaviour is expressed through reactive directives\n * inside the template — not by re-evaluating setup itself.\n *\n * Everything besides `props` — lifecycle hooks, host bindings, context, slots,\n * emit — is a free function imported from `@vielzeug/ore` and called directly\n * from inside `setup()` (or from a composable it calls):\n *\n * ```ts\n * import { define, html, prop, onMounted, useEmit, useSlots } from '@vielzeug/ore';\n *\n * define<{ count?: number }>('my-counter', {\n * props: { count: prop.number(0) },\n * setup(props) {\n * const emit = useEmit<{ increment: number }>();\n * const slots = useSlots<'header' | 'footer'>();\n *\n * onMounted(() => console.log('mounted'));\n *\n * return html`<button @click=${() => emit('increment', props.count.value + 1)}>${props.count}</button>`;\n * },\n * });\n * ```\n */\nexport function define<Props extends Record<string, unknown> = Record<never, never>>(\n tag: string,\n definition: ComponentDefinition<Props>,\n): void {\n if (!tag) throw new OreApiError(ORE_ERRORS.defineRequiresTag);\n\n if (customElements.get(tag)) throw new OreApiError(ORE_ERRORS.defineDuplicate(tag));\n\n const { props: propDefs } = definition;\n\n const normalizedPropDefs: PropsDef<Props> | undefined = (() => {\n if (!propDefs) return undefined;\n\n const errors = validatePropDefs(propDefs as Record<string, unknown>);\n\n if (errors.length > 0) throw new OreApiError(ORE_ERRORS.validationFailed(tag, errors));\n\n const normalized: PropInputDefs = {};\n\n for (const [key, def] of Object.entries(propDefs)) {\n normalized[key] = normalizePropDefinition(def, key);\n }\n\n return normalized as PropsDef<Props>;\n })();\n\n const observedAttrs = normalizedPropDefs ? Object.keys(normalizedPropDefs).map(toKebab) : [];\n\n // Named class for DevTools and error messages\n const ComponentClass = class extends BaseElement {\n static override _definition = definition as ComponentDefinition<any>;\n static override _normalizedPropDefs = normalizedPropDefs as PropsDef<Record<never, never>> | undefined;\n static override formAssociated = definition.formAssociated ?? false;\n static override observedAttributes = observedAttrs;\n };\n\n Object.defineProperty(ComponentClass, 'name', { value: tag });\n customElements.define(tag, ComponentClass);\n}\n","/**\n * Slot observation and reactive slot signals.\n *\n * `slots.has(name?)`: Signal<boolean> — whether a named slot has assigned elements.\n * `slots.elements(name?)`: Signal<Element[]> — assigned elements for a slot (flattened).\n */\n\nimport { type Readable, signal, type Signal } from '@vielzeug/ripple';\n\nimport { onCleanup, onMounted, type RuntimeContext, requireSetupContext } from './runtime';\n\nexport type ComponentSlots<SlotNames extends string = string> = {\n elements: (name?: SlotNames) => Readable<Element[]>;\n has: (name?: SlotNames) => Readable<boolean>;\n};\n\nconst SLOT_DEFAULT = 'default';\nconst normalizeSlotName = (slotName: string | null | undefined): string => slotName || SLOT_DEFAULT;\n\nconst createSlots = (host: HTMLElement): ComponentSlots<string> => {\n type SlotEntry = {\n elements: Signal<Element[]>;\n presence: Signal<boolean>;\n };\n\n const slotSignals = new Map<string, SlotEntry>();\n const slotNodesByName = new Map<string, Set<HTMLSlotElement>>();\n const slotCleanupMap = new Map<HTMLSlotElement, () => void>();\n\n const ensureSlotEntry = (normalizedName: string): SlotEntry => {\n let entry = slotSignals.get(normalizedName);\n\n if (!entry) {\n entry = {\n elements: signal<Element[]>([]),\n presence: signal(false),\n };\n slotSignals.set(normalizedName, entry);\n }\n\n return entry;\n };\n\n const areElementsEqual = (prev: Element[], next: Element[]): boolean => {\n if (prev.length !== next.length) return false;\n\n for (let i = 0; i < prev.length; i++) {\n if (prev[i] !== next[i]) return false;\n }\n\n return true;\n };\n\n const recomputeSlot = (name: string): void => {\n const normalized = normalizeSlotName(name);\n const slotsForName = slotNodesByName.get(normalized);\n const assigned: Element[] = [];\n\n if (slotsForName) {\n for (const slotEl of slotsForName) {\n assigned.push(...slotEl.assignedElements({ flatten: true }));\n }\n }\n\n const entry = ensureSlotEntry(normalized);\n\n if (!areElementsEqual(entry.elements.value, assigned)) entry.elements.value = assigned;\n\n const hasElements = assigned.length > 0;\n\n if (entry.presence.value !== hasElements) entry.presence.value = hasElements;\n };\n\n const bindSlot = (slotEl: HTMLSlotElement): void => {\n if (slotCleanupMap.has(slotEl)) return;\n\n const name = normalizeSlotName(slotEl.getAttribute('name'));\n const setForName = slotNodesByName.get(name) ?? new Set<HTMLSlotElement>();\n\n setForName.add(slotEl);\n slotNodesByName.set(name, setForName);\n\n const onChange = () => recomputeSlot(name);\n\n slotEl.addEventListener('slotchange', onChange);\n\n slotCleanupMap.set(slotEl, () => {\n slotEl.removeEventListener('slotchange', onChange);\n });\n\n recomputeSlot(name);\n };\n\n const unbindSlot = (slotEl: HTMLSlotElement): void => {\n const cleanup = slotCleanupMap.get(slotEl);\n\n if (!cleanup) return;\n\n cleanup();\n slotCleanupMap.delete(slotEl);\n\n const name = normalizeSlotName(slotEl.getAttribute('name'));\n const setForName = slotNodesByName.get(name);\n\n if (setForName) {\n setForName.delete(slotEl);\n\n if (setForName.size === 0) slotNodesByName.delete(name);\n }\n\n recomputeSlot(name);\n };\n\n const bindAllSlots = (): void => {\n host.shadowRoot?.querySelectorAll('slot').forEach((slotEl) => bindSlot(slotEl));\n };\n\n const recomputeAllSlots = (): void => {\n for (const name of slotNodesByName.keys()) {\n recomputeSlot(name);\n }\n };\n\n // Watch for dynamically-inserted <slot> elements (e.g. inside when(), each()).\n let observer: MutationObserver | null = null;\n\n // Start MutationObserver immediately in setup so any slots inserted synchronously\n // before the first render are captured without a timing gap.\n if (host.shadowRoot) {\n observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.removedNodes) {\n if (node instanceof HTMLSlotElement) unbindSlot(node);\n }\n }\n\n bindAllSlots();\n recomputeAllSlots();\n });\n observer.observe(host.shadowRoot, { childList: true, subtree: true });\n }\n\n // Bind slots already present in the shadow root (pre-upgrade scenarios)\n // and schedule a post-render pass to pick up slots injected by the template.\n bindAllSlots();\n onMounted(() => {\n bindAllSlots();\n recomputeAllSlots();\n });\n\n onCleanup(() => {\n observer?.disconnect();\n observer = null;\n\n for (const cleanup of slotCleanupMap.values()) cleanup();\n\n slotCleanupMap.clear();\n slotNodesByName.clear();\n slotSignals.clear();\n });\n\n return {\n elements: (name?: string) => ensureSlotEntry(normalizeSlotName(name)).elements,\n has: (name?: string) => ensureSlotEntry(normalizeSlotName(name)).presence,\n };\n};\n\n/** One slot registry per component instance — reused across repeated `useSlots()` calls. */\nconst slotsByContext = new WeakMap<RuntimeContext, ComponentSlots<string>>();\n\n/**\n * Returns reactive slot presence / element signals for the current component.\n * Safe to call multiple times during `setup()` — the underlying slot registry\n * (MutationObserver + `slotchange` listeners) is created once per instance.\n *\n * Pass a `SlotNames` type parameter for typed slot names:\n * ```ts\n * const slots = useSlots<'header' | 'footer'>();\n * slots.has('header'); // typed ✓\n * ```\n */\nexport const useSlots = <SlotNames extends string = string>(): ComponentSlots<SlotNames> => {\n const ctx = requireSetupContext('useSlots');\n let entry = slotsByContext.get(ctx);\n\n if (!entry) {\n entry = createSlots(ctx.element);\n slotsByContext.set(ctx, entry);\n }\n\n return entry as ComponentSlots<SlotNames>;\n};\n","/**\n * Shared ARIA attribute key normalisation helpers.\n *\n * Two flavours are needed across the codebase:\n *\n * - `normalizeAriaKey` — always adds the `aria-` prefix for non-role keys.\n * Used by `syncAria()` where every config key is an ARIA attribute.\n *\n * - `normalizeHostAttrKey` — passes non-ARIA keys through unchanged.\n * Used by `host.bind({ attr: ... })` where keys may be arbitrary HTML attributes.\n */\n\n/** Normalise an aria config key to a full `aria-*` attribute name. */\nexport const normalizeAriaKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', 'expanded' → 'aria-expanded'\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : `aria-${key}`;\n};\n\n/** Normalise a host-bind attr key: aria-camelCase → aria-kebab-case; other keys pass through. */\nexport const normalizeHostAttrKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', other keys unchanged\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : key;\n};\n","/**\n * Host element binding API — reactive attr, class, style, and event bindings\n * applied directly to the component's host element or any target element.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { getHost, tryRegisterCleanup, watchEffect } from './runtime';\nimport { normalizeHostAttrKey } from './utils/aria';\nimport { listen, setAttr, toKebab } from './utils/dom';\n\n/**\n * Describes a reactive or static host binding value.\n */\nexport type HostBindingValue =\n | (() => string | number | boolean | null | undefined)\n | Readable<string | number | boolean | null | undefined>\n | string\n | number\n | boolean\n | null\n | undefined;\n\n/**\n * Configuration for host attribute bindings.\n */\nexport type ReflectConfig = Record<string, HostBindingValue>;\n\ntype HostClassBindingValue = Readable<boolean> | (() => boolean) | boolean;\n// Bivariant callback allows consumers to use narrower event types.\ntype HostEventListener = { bivarianceHack(event: Event): void }['bivarianceHack'];\n\nexport type HostBindConfig = {\n attr?: ReflectConfig;\n class?: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>;\n on?: Record<string, HostEventListener | undefined>;\n style?: Record<string, HostBindingValue>;\n};\n\nexport type BindOptions = AddEventListenerOptions & {\n /**\n * Target element to bind to. Defaults to the host element when called\n * via `bind()`. Pass an explicit element to bind to any other element\n * (e.g. a slotted trigger or an internally-referenced child element).\n * When a target is provided, cleanup is always auto-registered with the\n * component scope if one is active.\n */\n target?: Element;\n};\n\nexport type HostBindFn = (config: HostBindConfig, options?: BindOptions) => () => void;\n\n/**\n * Apply reactive or static bindings to an element's attributes, classes, styles,\n * and events. Defaults to the current component's host element; pass\n * `options.target` to bind to any other element (e.g. a slotted trigger, an\n * internally-referenced child).\n */\nexport const bind: HostBindFn = (config: HostBindConfig, options?: BindOptions): (() => void) => {\n const el = (options?.target as HTMLElement | undefined) ?? getHost();\n const disposers: Array<() => void> = [];\n\n if (config.attr) {\n for (const [key, value] of Object.entries(config.attr)) {\n const name = toHostAttr(key);\n const dispose = applyAttribute(el, name, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.class) {\n disposers.push(applyClassMap(el, config.class));\n }\n\n if (config.style) {\n for (const [key, value] of Object.entries(config.style)) {\n const dispose = applyStyle(el, key, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.on) {\n const { target: _t, ...listenerOptions } = options ?? {};\n\n for (const event of Object.keys(config.on) as Array<keyof typeof config.on>) {\n const listener = config.on[event];\n\n if (!listener) continue;\n\n disposers.push(listen(el, event as string, listener as EventListener, listenerOptions));\n }\n }\n\n const cleanup = (): void => {\n for (const dispose of disposers) dispose();\n };\n\n tryRegisterCleanup(cleanup);\n\n return cleanup;\n};\n\nconst toHostAttr = normalizeHostAttrKey;\n\nconst applyReactiveBinding = (\n value: HostBindingValue,\n updater: (next: string | number | boolean | null | undefined) => void,\n): (() => void) | void => {\n if (typeof value === 'function') {\n return watchEffect(() => updater(value()));\n }\n\n if (isReactive(value)) {\n return watchEffect(() => updater(value.value));\n }\n\n updater(value);\n};\n\nfunction applyAttribute(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n return applyReactiveBinding(value, (next) => setAttr(host, name, next));\n}\n\nconst UNSAFE_CSS_CHARS = /[;{}]/g;\n\nfunction applyStyle(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n const cssName = (name.startsWith('--') ? name : toKebab(name)).replace(UNSAFE_CSS_CHARS, '');\n\n if (!cssName) return;\n\n let owned = false;\n const setStyle = (v: string | number | boolean | null | undefined): void => {\n if (v != null && v !== '') {\n owned = true;\n host.style.setProperty(cssName, String(v).replace(UNSAFE_CSS_CHARS, ''));\n } else if (owned) host.style.removeProperty(cssName);\n };\n\n return applyReactiveBinding(value, setStyle);\n}\n\nfunction applyClassMap(\n host: HTMLElement,\n value: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>,\n): () => void {\n const getMap =\n typeof value === 'function'\n ? value\n : (): Record<string, boolean> => {\n const result: Record<string, boolean> = {};\n\n for (const [cls, entry] of Object.entries(value)) {\n result[cls] = typeof entry === 'function' ? entry() : isReactive(entry) ? entry.value : Boolean(entry);\n }\n\n return result;\n };\n\n let prev = new Set<string>();\n\n const sub = watchEffect(() => {\n const next = new Set<string>();\n\n for (const [cls, active] of Object.entries(getMap())) {\n if (!active) continue;\n\n next.add(cls);\n\n if (!prev.has(cls)) host.classList.add(cls);\n }\n for (const cls of prev) {\n if (!next.has(cls)) host.classList.remove(cls);\n }\n prev = next;\n });\n\n return sub;\n}\n","/**\n * Reactive ARIA attribute sync.\n *\n * `aria()` is a thin wrapper over `bind({ attr })` — the two used to carry\n * independent copies of the same \"static | getter | signal → attribute write\"\n * logic, which had already drifted (this file's writes bypassed the\n * `on*`/dangerous-URL-scheme hardening that `setAttr()` gives every other\n * attribute write in the package). `aria()` now exists purely to normalize\n * bare ARIA property names (`expanded` → `aria-expanded`) before delegating —\n * for attributes that are already fully-qualified, `bind({ attr }, { target })`\n * is equivalent.\n */\n\nimport { bind, type HostBindingValue } from './host-bind';\nimport { normalizeAriaKey } from './utils/aria';\n\nexport type AriaConfig = Record<string, HostBindingValue>;\n\n/**\n * Reactively sync ARIA attributes on any element, auto-cleanup on component\n * disconnect. Returns a cleanup function that removes all reactive bindings.\n */\nexport const aria = (target: Element, config: AriaConfig): (() => void) => {\n const attr: Record<string, HostBindingValue> = {};\n\n for (const [key, value] of Object.entries(config)) attr[normalizeAriaKey(key)] = value;\n\n return bind({ attr }, { target });\n};\n","/**\n * Type-safe custom event emission for components.\n */\n\nimport { getHost } from '../runtime';\n\ntype NoDetail = void | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\ntype StrictEmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): boolean;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): boolean;\n};\n\ntype LooseEmitFn = (event: string, detail?: unknown) => boolean;\n\nexport type EmitFn<T extends Record<string, unknown>> = StrictEmitFn<T> & LooseEmitFn;\n\nconst DEFAULT_FIRE_OPTIONS = { bubbles: true, cancelable: true, composed: false };\n\n/**\n * Returns a typed `emit()` function bound to the current component's host element.\n * Call once during `setup()` — the `Emits` type parameter maps event names to\n * their `detail` payload type.\n *\n * Every event is dispatched `cancelable: true`, and `emit()` returns `dispatchEvent`'s\n * own boolean result — `false` when a listener called `preventDefault()`. Components\n * that need to know whether a listener cancelled an event (e.g. to skip a default\n * action) read this return value directly instead of hand-rolling `dispatchEvent`.\n *\n * @example\n * ```ts\n * type Events = { close: undefined; change: { value: string } };\n *\n * setup(props) {\n * const emit = useEmit<Events>();\n * emit('close');\n *\n * const notCancelled = emit('change', { value: 'ok' });\n * if (notCancelled) props.value.value = 'ok';\n * }\n * ```\n */\nexport const useEmit = <T extends Record<string, unknown> = Record<string, never>>(): EmitFn<T> => {\n const host = getHost();\n\n return ((event: keyof T, ...rest: unknown[]) => {\n const customEventInit = rest.length > 0 ? { ...DEFAULT_FIRE_OPTIONS, detail: rest[0] } : DEFAULT_FIRE_OPTIONS;\n\n return host.dispatchEvent(new CustomEvent<unknown>(String(event), customEventInit));\n }) as EmitFn<T>;\n};\n","/**\n * template/bindings.ts — Runtime binding appliers.\n *\n * Responsibilities:\n * - Apply each Binding variant to the live DOM (text, attr, event, html, ref,\n * directive, spread).\n * - Manage reactive effects and cleanup registration.\n * - Expose `applyBinding()` as the single dispatch entry point.\n */\n\nimport { computed, effect as rawEffect, isReactive, type Readable, untrack } from '@vielzeug/ripple';\n\nimport { isLiveSignal } from '../directives/live';\nimport { invariant } from '../errors';\nimport { getPropMeta } from '../props';\nimport {\n type AttrBinding,\n type AttrPropMeta,\n type Binding,\n type DirectiveBinding,\n type EventBinding,\n type HtmlBinding,\n type HtmlBindingValue,\n isHtmlResult,\n type RefBinding,\n type SpreadBinding,\n type TextBinding,\n} from '../types/bindings';\nimport { isStructuredValue, listen, removeNodes, runAll, setAttr } from '../utils/dom';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type RegisterCleanup = (fn: () => void) => void;\n\n// ─── Signal helpers ───────────────────────────────────────────────────────────\n\nconst signalEffect = (\n signal: Readable<unknown>,\n update: (v: unknown) => void,\n registerCleanup: RegisterCleanup,\n): void => {\n const sub = rawEffect(() => update(signal.value));\n\n registerCleanup(() => sub.dispose());\n};\n\n/**\n * Read a signal safely during scope teardown. Disposed signals and computeds\n * return their last known value (or undefined) without throwing — no try/catch needed.\n */\nconst readSignalSafe = <T>(sig: Readable<T>): T | undefined => sig.value;\n\n// ─── Text ─────────────────────────────────────────────────────────────────────\n\nconst applyTextBinding = (binding: TextBinding, registerCleanup: RegisterCleanup): void => {\n signalEffect(\n binding.signal,\n (v) => {\n binding.node.textContent = String(v ?? '');\n },\n registerCleanup,\n );\n};\n\n// ─── Attributes ───────────────────────────────────────────────────────────────\n\nconst isNativeFormInput = (el: HTMLElement): el is HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement =>\n el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement;\n\ntype LiveWriteState = { last: unknown };\n\nconst applyFormValue = (\n el: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement,\n value: unknown,\n isLive: boolean | undefined,\n state: LiveWriteState,\n): void => {\n const next = value == null ? '' : String(value);\n\n if (isLive && state.last !== undefined && !Object.is(el.value, state.last) && !Object.is(el.value, next)) return;\n\n el.value = next;\n\n if (isLive) state.last = next;\n};\n\nconst applyCheckedValue = (\n el: HTMLInputElement,\n value: unknown,\n isLive: boolean | undefined,\n state: LiveWriteState,\n): void => {\n const next = Boolean(value);\n\n if (isLive && state.last !== undefined && el.checked !== Boolean(state.last) && el.checked !== next) return;\n\n el.checked = next;\n\n if (isLive) state.last = next;\n};\n\nconst syncRegisteredProp = (el: HTMLElement, meta: AttrPropMeta, binding: AttrBinding, value: unknown): void => {\n const parsed = isStructuredValue(value)\n ? value\n : meta.parse(\n binding.mode === 'bool' ? (value ? '' : null) : value == null || value === false ? null : String(value),\n );\n\n if (\n !Object.is(\n untrack(() => meta.signal.value),\n parsed,\n )\n ) {\n meta.signal.value = parsed as never;\n }\n\n if (!meta.reflect) {\n if (isStructuredValue(value)) return;\n\n if (binding.mode === 'bool') el.toggleAttribute(binding.name, Boolean(value));\n else setAttr(el, binding.name, value);\n }\n};\n\nexport const applyAttrBinding = (binding: AttrBinding, registerCleanup: RegisterCleanup): void => {\n const { el, mode, name, propMeta } = binding;\n const liveState: LiveWriteState = { last: undefined };\n\n const update = (value: unknown): void => {\n if (propMeta) {\n syncRegisteredProp(el, propMeta, binding, value);\n\n return;\n }\n\n if (!isReactive(value) && isStructuredValue(value)) {\n if (name !== '__proto__' && name !== 'constructor' && name !== 'prototype') {\n (el as unknown as Record<string, unknown>)[name] = value;\n }\n\n return;\n }\n\n if (name === 'value' && isNativeFormInput(el)) {\n applyFormValue(el, value, binding.live, liveState);\n\n return;\n }\n\n if (name === 'checked' && el instanceof HTMLInputElement) {\n applyCheckedValue(el, value, binding.live, liveState);\n\n return;\n }\n\n if (mode === 'bool') el.toggleAttribute(name, Boolean(value));\n else setAttr(el, name, value);\n };\n\n if ('signal' in binding) {\n signalEffect(binding.signal, update, registerCleanup);\n } else {\n update(binding.value);\n }\n};\n\n// ─── Events ───────────────────────────────────────────────────────────────────\n\nconst applyEventBinding = (binding: EventBinding, registerCleanup: RegisterCleanup): void => {\n registerCleanup(listen(binding.el, binding.name, binding.handler, binding.options));\n};\n\n// ─── Refs ─────────────────────────────────────────────────────────────────────\n\nconst applyRefBinding = (binding: RefBinding, registerCleanup: RegisterCleanup): void => {\n const { el, ref } = binding;\n\n if (typeof ref === 'function') {\n ref(el as never);\n registerCleanup(() => ref(null as never));\n\n return;\n }\n\n ref.value = el as never;\n registerCleanup(() => {\n ref.value = null as never;\n });\n};\n\n// ─── HTML (reactive) ─────────────────────────────────────────────────────────\n\nconst insertHtmlValues = (\n values: HtmlBindingValue[],\n insertBefore: ChildNode,\n registerCleanup: RegisterCleanup,\n): Node[] => {\n const nodes: Node[] = [];\n const parent = insertBefore.parentNode;\n\n invariant(parent, 'html binding anchor has no parent node');\n\n for (const v of values) {\n if (isHtmlResult(v)) {\n const captured = Array.from(v.fragment.childNodes);\n\n parent.insertBefore(v.fragment, insertBefore);\n v.apply(registerCleanup);\n nodes.push(...captured);\n } else if (v != null && v !== false) {\n const text = document.createTextNode(String(v));\n\n parent.insertBefore(text, insertBefore);\n nodes.push(text);\n }\n }\n\n return nodes;\n};\n\nexport const applyHtmlBinding = (binding: HtmlBinding, registerCleanup: RegisterCleanup): void => {\n const { anchor, signal } = binding;\n\n let currentCleanups: (() => void)[] = [];\n const clearCurrent = (): void => {\n runAll(currentCleanups);\n currentCleanups = [];\n };\n let currentNodes: Node[] = [];\n\n const stop = rawEffect(() => {\n const raw = readSignalSafe(signal);\n\n clearCurrent();\n removeNodes(currentNodes);\n currentNodes = [];\n\n if (raw == null || raw.length === 0) return;\n\n untrack(() => {\n currentNodes = insertHtmlValues(raw, anchor, (fn) => currentCleanups.push(fn));\n });\n });\n\n registerCleanup(() => {\n stop.dispose();\n clearCurrent();\n removeNodes(currentNodes);\n });\n};\n\n// ─── Directives ───────────────────────────────────────────────────────────────\n\nconst applyDirectiveBinding = (binding: DirectiveBinding, registerCleanup: RegisterCleanup): void => {\n binding.directive.mount(binding.anchor, registerCleanup);\n};\n\n// ─── Spread ───────────────────────────────────────────────────────────────────\n\nconst applySpreadBinding = (binding: SpreadBinding, registerCleanup: RegisterCleanup): void => {\n binding.spread.apply(binding.el, registerCleanup);\n};\n\n// ─── Binding dispatch ─────────────────────────────────────────────────────────\n\nexport const applyBinding = (binding: Binding, registerCleanup: RegisterCleanup): void => {\n switch (binding.type) {\n case 'attr':\n applyAttrBinding(binding, registerCleanup);\n break;\n case 'directive':\n applyDirectiveBinding(binding, registerCleanup);\n break;\n case 'event':\n applyEventBinding(binding, registerCleanup);\n break;\n case 'html':\n applyHtmlBinding(binding, registerCleanup);\n break;\n case 'ref':\n applyRefBinding(binding, registerCleanup);\n break;\n case 'spread':\n applySpreadBinding(binding, registerCleanup);\n break;\n case 'text':\n applyTextBinding(binding, registerCleanup);\n break;\n }\n};\n\n// ─── Attr binding factory (used by instantiator) ──────────────────────────────\n\nexport const createAttrBindingFromValue = (\n el: HTMLElement,\n mode: 'attr' | 'bool',\n name: string,\n value: unknown,\n): AttrBinding => {\n const propMeta = getPropMeta(el, name) as AttrPropMeta | undefined;\n\n if (isLiveSignal(value)) {\n return { el, live: true, mode, name, propMeta, signal: value as Readable<unknown>, type: 'attr' };\n }\n\n if (typeof value === 'function') {\n return { el, mode, name, propMeta, signal: computed(value as () => unknown), type: 'attr' };\n }\n\n if (isReactive(value)) {\n return { el, mode, name, propMeta, signal: value as Readable<unknown>, type: 'attr' };\n }\n\n return { el, mode, name, propMeta, type: 'attr', value };\n};\n\nexport const resolveStaticText = (value: unknown): string => {\n if (value == null) return '';\n\n return String(value);\n};\n","type EventHandler = (e: Event) => void;\n\nconst behaviorModifiers: Record<string, (h: EventHandler) => EventHandler> = {\n prevent: (h) => (e) => {\n e.preventDefault();\n h(e);\n },\n self: (h) => (e) => {\n if (e.target === e.currentTarget) h(e);\n },\n stop: (h) => (e) => {\n e.stopPropagation();\n h(e);\n },\n};\n\n/**\n * Apply event listener modifiers (prevent, stop, self, capture, once, passive).\n * Behavior modifiers wrap the handler; listener options are extracted separately.\n */\nexport const applyModifiers = (\n handler: EventHandler,\n modifiers: string[],\n): { handler: EventHandler; options?: AddEventListenerOptions } => {\n let wrappedHandler = handler;\n\n for (const modifier of modifiers) {\n const wrap = behaviorModifiers[modifier];\n\n if (wrap) wrappedHandler = wrap(wrappedHandler);\n }\n\n const options: AddEventListenerOptions = {};\n\n if (modifiers.includes('capture')) options.capture = true;\n\n if (modifiers.includes('once')) options.once = true;\n\n if (modifiers.includes('passive')) options.passive = true;\n\n return { handler: wrappedHandler, ...(Object.keys(options).length ? { options } : {}) };\n};\n","/**\n * template/compiler.ts — HTML template string parser and static template cache.\n *\n * Responsibilities:\n * - Parse TemplateStringsArray into slot metadata (slot detection).\n * - Build a cached HTMLTemplateElement with path indices for efficient node lookup.\n * - Expose `getStaticTemplate()` for use by the instantiator.\n */\n\nimport { OreApiError, ORE_ERRORS } from '../errors';\n\n// ─── Slot kinds ───────────────────────────────────────────────────────────────\n// Const object + derived union, same pattern as `ComponentPhase`/`LIFECYCLE_EVENTS`\n// in types.ts — used here (rather than plain string literals) because the kind\n// crosses a module boundary (compiler.ts produces it, instantiator.ts consumes\n// it): importing `SlotKind` gives autocomplete and a single rename point at the\n// consuming site, where a bare string literal wouldn't.\n\nexport const SlotKind = {\n ATTR: 'attr',\n BOOL_ATTR: 'boolAttr',\n CLOSE_TAG: 'closeTag',\n EVENT: 'event',\n NODE: 'node',\n REF: 'ref',\n SPREAD: 'spread',\n TAG_NAME: 'tagname',\n} as const;\n\nexport type DetectedSlotKind = (typeof SlotKind)[keyof typeof SlotKind];\n\ntype DetectedSlot = {\n kind: DetectedSlotKind;\n modifiers?: string[];\n name?: string;\n prefix: string;\n};\n\n// ─── Static template types ────────────────────────────────────────────────────\n\nexport type NodePath = readonly number[];\n\nexport type SlotMeta = {\n commentId?: number;\n elementId?: number;\n kind: DetectedSlotKind;\n mode?: 'attr' | 'bool';\n modifiers?: string[];\n name?: string;\n};\n\nexport type CompiledStaticTemplate = {\n commentPaths: ReadonlyMap<number, NodePath>;\n element: HTMLTemplateElement;\n elementPaths: ReadonlyMap<number, NodePath>;\n slots: SlotMeta[];\n};\n\n// ─── Slot detection regexes ───────────────────────────────────────────────────\n\nconst EVENT_RE = /\\s+@([a-zA-Z_][-a-zA-Z0-9_.-]*)\\s*=\\s*[\"']?$/;\nconst REF_RE = /\\s+ref\\s*=\\s*[\"']?$/;\nconst BOOL_ATTR_RE = /\\s+\\?([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/;\nconst ATTR_RE = /\\s+:?([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/;\n\nconst isInsideStartTag = (str: string): boolean => {\n const lastOpen = str.lastIndexOf('<');\n const lastClose = str.lastIndexOf('>');\n\n if (lastOpen <= lastClose) return false;\n\n // Must not be a closing tag (</...)\n return str[lastOpen + 1] !== '/';\n};\n\nconst detectSlot = (str: string): DetectedSlot => {\n let m: RegExpExecArray | null;\n const trimmed = str.trimEnd();\n\n // Dynamic closing tag: interpolation is the closing tag name, e.g. strings[i] = \"</\"\n if (trimmed.endsWith('</')) {\n return { kind: SlotKind.CLOSE_TAG, prefix: str };\n }\n\n // Dynamic opening tag name: interpolation is the tag name itself, e.g. strings[i] = \"<\"\n if (trimmed.endsWith('<')) {\n return { kind: SlotKind.TAG_NAME, prefix: str };\n }\n\n if ((m = EVENT_RE.exec(str))) {\n const prefix = str.slice(0, -m[0].length);\n const parts = m[1].split('.');\n\n return { kind: SlotKind.EVENT, modifiers: parts.slice(1), name: parts[0], prefix };\n }\n\n if ((m = REF_RE.exec(str))) {\n return { kind: SlotKind.REF, prefix: str.slice(0, -m[0].length) };\n }\n\n if ((m = BOOL_ATTR_RE.exec(str))) {\n return { kind: SlotKind.BOOL_ATTR, name: m[1], prefix: str.slice(0, -m[0].length) };\n }\n\n if ((m = ATTR_RE.exec(str))) {\n return { kind: SlotKind.ATTR, name: m[1], prefix: str.slice(0, -m[0].length) };\n }\n\n if (isInsideStartTag(str)) {\n return { kind: SlotKind.SPREAD, prefix: str.trimEnd() };\n }\n\n return { kind: SlotKind.NODE, prefix: str };\n};\n\n// ─── Static template cache ────────────────────────────────────────────────────\n\nconst templateCache = new WeakMap<TemplateStringsArray, CompiledStaticTemplate>();\n\n/**\n * Pre-process template strings to strip surrounding attribute quotes and the\n * closing `>` that follows a dynamic tag-name slot. This lets the main loop\n * operate on clean strings with no per-iteration state flags.\n */\nconst normalizeTemplateStrings = (strings: TemplateStringsArray): string[] => {\n const out = Array.from(strings);\n\n for (let i = 0; i < out.length - 1; i++) {\n const s = out[i];\n const lastChar = s[s.length - 1];\n\n // Strip wrapping attribute quotes: attr=\"${value}\" → attr=${value}\n if (lastChar === '\"' || lastChar === \"'\") {\n out[i] = s.slice(0, -1);\n\n const next = out[i + 1];\n\n if (next.startsWith(lastChar)) out[i + 1] = next.slice(1);\n }\n\n // Strip leading `>` from the string that follows a dynamic closing tag:\n // </${tagName}> — the `>` is the first character of strings[i+1]\n const cur = out[i];\n\n if (cur.trimEnd().endsWith('</')) {\n const next = out[i + 1];\n\n if (next.startsWith('>')) out[i + 1] = next.slice(1);\n }\n }\n\n return out;\n};\n\nconst walkNode = (\n node: Node,\n path: number[],\n elementPaths: Map<number, NodePath>,\n commentPaths: Map<number, NodePath>,\n): void => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as Element;\n const marker = el.getAttribute('u');\n\n if (marker !== null) {\n elementPaths.set(Number(marker), [...path]);\n el.removeAttribute('u');\n }\n } else if (node.nodeType === Node.COMMENT_NODE) {\n const content = (node as Comment).nodeValue;\n\n if (content !== null && /^\\d+$/.test(content)) {\n commentPaths.set(Number(content), [...path]);\n }\n }\n\n const children = node.childNodes;\n\n for (let i = 0; i < children.length; i++) walkNode(children[i], [...path, i], elementPaths, commentPaths);\n};\n\nconst buildStaticTemplate = (strings: TemplateStringsArray): CompiledStaticTemplate => {\n const normalized = normalizeTemplateStrings(strings);\n let html = '';\n let activeElementId: number | undefined;\n let elementCounter = 0;\n let commentCounter = 0;\n const slots: SlotMeta[] = [];\n const tagNameStack: number[] = [];\n\n for (let i = 0; i < normalized.length - 1; i++) {\n const raw = normalized[i];\n const slot = detectSlot(raw);\n\n if (slot.kind === SlotKind.TAG_NAME) {\n // Dynamic opening tag name: emit a placeholder custom element\n const id = elementCounter++;\n\n activeElementId = id;\n tagNameStack.push(id);\n\n // Remove trailing '<' from prefix and open placeholder element\n const prefixWithoutAngle = raw.replace(/<\\s*$/, '');\n\n html += prefixWithoutAngle + `<ore-dyn-${id} u=\"${id}\"`;\n slots.push({ elementId: id, kind: SlotKind.TAG_NAME });\n } else if (slot.kind === SlotKind.CLOSE_TAG) {\n // Dynamic closing tag: close the matching placeholder element. An empty\n // stack means this closing interpolation has no matching dynamic opener\n // (malformed template) — fail fast instead of silently closing the\n // wrong (or a nonexistent) placeholder element.\n if (tagNameStack.length === 0) {\n throw new OreApiError(ORE_ERRORS.mismatchedDynamicCloseTag);\n }\n\n const id = tagNameStack.pop()!;\n const prefixWithoutClose = raw.replace(/<\\/\\s*$/, '');\n\n html += prefixWithoutClose + `</ore-dyn-${id}>`;\n slots.push({ kind: SlotKind.CLOSE_TAG });\n activeElementId = undefined;\n } else if (slot.kind === SlotKind.NODE) {\n html += slot.prefix + `<!--${commentCounter}-->`;\n slots.push({ commentId: commentCounter, kind: SlotKind.NODE });\n commentCounter++;\n activeElementId = undefined;\n } else {\n const needsNewMarker =\n activeElementId === undefined || slot.prefix.lastIndexOf('<') > slot.prefix.lastIndexOf('>');\n\n if (needsNewMarker) {\n activeElementId = elementCounter++;\n html += `${slot.prefix} u=\"${activeElementId}\"`;\n } else {\n html += slot.prefix;\n }\n\n const mode: 'attr' | 'bool' | undefined =\n slot.kind === SlotKind.BOOL_ATTR ? 'bool' : slot.kind === SlotKind.ATTR ? 'attr' : undefined;\n\n slots.push({ elementId: activeElementId, kind: slot.kind, mode, modifiers: slot.modifiers, name: slot.name });\n }\n }\n\n html += normalized[normalized.length - 1] ?? '';\n\n const tpl = document.createElement('template');\n\n tpl.innerHTML = html;\n\n const elementPaths = new Map<number, NodePath>();\n const commentPaths = new Map<number, NodePath>();\n const topChildren = tpl.content.childNodes;\n\n for (let i = 0; i < topChildren.length; i++) walkNode(topChildren[i], [i], elementPaths, commentPaths);\n\n return { commentPaths, element: tpl, elementPaths, slots };\n};\n\nexport const getStaticTemplate = (strings: TemplateStringsArray): CompiledStaticTemplate => {\n let tpl = templateCache.get(strings);\n\n if (!tpl) {\n tpl = buildStaticTemplate(strings);\n templateCache.set(strings, tpl);\n }\n\n return tpl;\n};\n\n// ─── Path navigation (used by instantiator) ───────────────────────────────────\n\nexport const followPath = (root: Node, path: NodePath): Node => {\n let node: Node = root;\n\n for (const i of path) node = node.childNodes[i];\n\n return node;\n};\n","/**\n * template/instantiator.ts — Template instantiation and the `html` tagged literal.\n *\n * Responsibilities:\n * - Clone a compiled static template and wire up live bindings.\n * - Expose `compileTemplate()` and `html` as the public authoring API.\n */\n\nimport { computed, isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { invariant, ORE_ERRORS, OreApiError } from '../errors';\nimport {\n type Binding,\n createHtmlResult,\n type HtmlBindingValue,\n type HTMLResult,\n isDirectiveResult,\n isHtmlResult,\n isSpreadObject,\n type Ref,\n type RefCallback,\n} from '../types/bindings';\nimport { applyModifiers } from '../utils/event-modifiers';\nimport { applyBinding, createAttrBindingFromValue, resolveStaticText } from './bindings';\nimport { followPath, getStaticTemplate, SlotKind } from './compiler';\n\n// ─── Template instantiation ──────────────────────────────────────────────────\n\n/**\n * Instantiate a compiled template: clone the cached DOM template, navigate\n * to each binding target using pre-recorded paths, and build bindings with\n * direct node references. Returns an HTMLResult whose fragment is ready to insert.\n */\nconst NODE_SLOT_NO_PARENT_MSG = 'html`...`: node-slot comment anchor has no parent node';\n\nexport const compileTemplate = (strings: TemplateStringsArray, values: unknown[]): HTMLResult => {\n const compiled = getStaticTemplate(strings);\n const fragment = compiled.element.content.cloneNode(true) as DocumentFragment;\n const bindings: Binding[] = [];\n // For static HTMLResult embeds: chain their apply calls\n const chainedApplies: Array<(rc: (fn: () => void) => void) => void> = [];\n\n // Phase 1: Resolve all binding targets BEFORE any DOM modifications\n type BoundSlot = { comment?: Comment; el?: HTMLElement; slot: (typeof compiled.slots)[number]; value: unknown };\n\n const boundSlots: BoundSlot[] = compiled.slots.map((slot, i) => {\n const value = values[i];\n\n if (slot.kind === SlotKind.CLOSE_TAG) {\n return { slot, value };\n }\n\n if (slot.kind === SlotKind.NODE) {\n const commentPath = compiled.commentPaths.get(slot.commentId!);\n\n invariant(commentPath, `compiled template is missing a comment path for node slot ${slot.commentId}`);\n\n return { comment: followPath(fragment, commentPath) as Comment, slot, value };\n }\n\n const elementPath = compiled.elementPaths.get(slot.elementId!);\n\n invariant(elementPath, `compiled template is missing an element path for slot ${slot.elementId}`);\n\n return { el: followPath(fragment, elementPath) as HTMLElement, slot, value };\n });\n\n // Phase 2a: Process tagname slots first — replace placeholders with real elements\n const tagReplacements = new Map<HTMLElement, HTMLElement>();\n\n for (const { el, slot, value } of boundSlots) {\n if (slot.kind !== SlotKind.TAG_NAME) continue;\n\n const tagName = String(value);\n\n // Same \"fail immediately, every build\" treatment as each()'s duplicate-key\n // guard: a malformed dynamic tag name is a programming bug in the template,\n // not a runtime race — degrading to a silently-broken partial render would\n // hide it instead of surfacing it at the call site.\n if (!/^[a-z][a-z0-9._-]*$/i.test(tagName)) {\n throw new OreApiError(ORE_ERRORS.invalidDynamicTagName(tagName));\n }\n\n const realEl = document.createElement(tagName);\n\n for (const attr of Array.from(el!.attributes)) realEl.setAttribute(attr.name, attr.value);\n\n while (el!.firstChild) realEl.appendChild(el!.firstChild);\n\n el!.replaceWith(realEl);\n tagReplacements.set(el!, realEl);\n }\n\n // Phase 2b: Build bindings (may modify DOM for static content)\n for (const { comment, el: rawEl, slot, value } of boundSlots) {\n if (slot.kind === SlotKind.TAG_NAME || slot.kind === SlotKind.CLOSE_TAG) continue;\n\n // Resolve element through tagname replacements\n const el = rawEl ? (tagReplacements.get(rawEl) ?? rawEl) : rawEl;\n\n if (slot.kind === SlotKind.NODE) {\n const anchor = comment!;\n\n if (isDirectiveResult(value)) {\n bindings.push({ anchor, directive: value, type: 'directive' });\n continue;\n }\n\n if (isHtmlResult(value)) {\n // Static embed: move fragment children into place, chain apply\n const parent = anchor.parentNode;\n\n invariant(parent, NODE_SLOT_NO_PARENT_MSG);\n\n while (value.fragment.firstChild) parent.insertBefore(value.fragment.firstChild, anchor);\n\n anchor.remove();\n chainedApplies.push(value.apply.bind(value));\n continue;\n }\n\n if (typeof value === 'function') {\n const sig = computed(() => {\n const res = (value as () => unknown)();\n\n return Array.isArray(res) ? (res as HtmlBindingValue[]) : [res as HtmlBindingValue];\n });\n\n bindings.push({ anchor, signal: sig, type: 'html' });\n continue;\n }\n\n if (isReactive(value)) {\n // Always use the html binding for signals — it handles both text values and\n // HTMLResult values, preventing silent \"[object Object]\" corruption when a\n // signal's runtime type changes from null/string to HTMLResult.\n const sig = computed(() => {\n const raw = (value as Readable<HtmlBindingValue | HtmlBindingValue[]>).value;\n\n return Array.isArray(raw) ? (raw as HtmlBindingValue[]) : [raw as HtmlBindingValue];\n });\n\n bindings.push({ anchor, signal: sig, type: 'html' });\n continue;\n }\n\n if (Array.isArray(value)) {\n const parent = anchor.parentNode;\n\n invariant(parent, NODE_SLOT_NO_PARENT_MSG);\n\n for (const item of value) {\n if (isHtmlResult(item)) {\n while (item.fragment.firstChild) parent.insertBefore(item.fragment.firstChild, anchor);\n\n chainedApplies.push(item.apply.bind(item));\n } else {\n parent.insertBefore(document.createTextNode(resolveStaticText(item)), anchor);\n }\n }\n anchor.remove();\n continue;\n }\n\n // Static primitive: replace with text node, no binding\n anchor.replaceWith(document.createTextNode(resolveStaticText(value)));\n continue;\n }\n\n // Element slot\n const target = el!;\n\n if (slot.kind === SlotKind.EVENT) {\n if (typeof value === 'function') {\n const { handler, options } = applyModifiers(value as (e: Event) => void, slot.modifiers ?? []);\n\n bindings.push({ el: target, handler, name: slot.name!, options, type: 'event' });\n } else if (isReactive(value)) {\n const signalValue = value as Readable<unknown>;\n const handler = (e: Event) => {\n const h = signalValue.value;\n\n if (typeof h === 'function') (h as (e: Event) => void)(e);\n };\n const { handler: wrapped, options } = applyModifiers(handler, slot.modifiers ?? []);\n\n bindings.push({ el: target, handler: wrapped, name: slot.name!, options, type: 'event' });\n }\n\n continue;\n }\n\n if (slot.kind === SlotKind.REF) {\n if (value) {\n bindings.push({ el: target, ref: value as Ref<Element> | RefCallback<Element>, type: 'ref' });\n }\n\n continue;\n }\n\n if (slot.kind === SlotKind.SPREAD) {\n if (isSpreadObject(value)) {\n bindings.push({ el: target, spread: value, type: 'spread' });\n }\n\n continue;\n }\n\n // attr / boolAttr\n bindings.push(createAttrBindingFromValue(target, slot.mode ?? 'attr', slot.name!, value));\n }\n\n return createHtmlResult(fragment, (registerCleanup) => {\n for (const binding of bindings) applyBinding(binding, registerCleanup);\n for (const chainedApply of chainedApplies) chainedApply(registerCleanup);\n });\n};\n\nexport const html = (strings: TemplateStringsArray, ...values: unknown[]): HTMLResult =>\n compileTemplate(strings, values);\n","/**\n * Unique ID generation for runtime use (component IDs, label associations, etc.).\n * Template binding no longer uses this for marker IDs — binding targets are resolved\n * via path navigation on cloned template nodes.\n */\n\nlet _idCounter = 0;\nlet _stableCounter = 0;\nconst _tag = Math.random().toString(36).slice(2, 6);\n\n/** @internal Resets both ID counters. Called by testing cleanup(). */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n _stableCounter = 0;\n};\n\nexport const createId = (prefix = 'id'): string => `${prefix}-${++_idCounter}`;\n\n/**\n * Generates a stable, unique ID with an optional semantic prefix.\n * Includes a short random tag to prevent collisions across multiple app instances.\n * Format: `${prefix}-${tag}${counter}` — e.g. `field-a3k21`.\n */\nexport const createStableId = (prefix = 'id'): string => `${prefix}-${_tag}${++_stableCounter}`;\n\n/**\n * Resets the stable ID counter to 0. Use in test `beforeEach` hooks when you need\n * deterministic IDs across test runs.\n */\nexport const resetIdCounter = (): void => {\n _stableCounter = 0;\n};\n","import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\n/**\n * Observes an element's intersection with the viewport (or a given root) via\n * `IntersectionObserver`. Returns a `Reactive` that updates whenever the\n * intersection ratio changes.\n * Must be called inside a `mount()` callback.\n */\nexport const intersectionObserver = (\n el: Element,\n options?: IntersectionObserverInit,\n): Readable<IntersectionObserverEntry | null> => {\n const entry = signal<IntersectionObserverEntry | null>(null);\n const io = new IntersectionObserver(([nextEntry]) => {\n if (nextEntry) entry.value = nextEntry;\n }, options);\n\n io.observe(el);\n onCleanup(() => io.disconnect());\n\n return entry;\n};\n","import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\n/**\n * Observes a CSS media query via `window.matchMedia`. Returns a `Reactive`\n * that is `true` when the query matches and `false` when it does not.\n * Must be called inside a `mount()` callback.\n */\nexport const mediaObserver = (query: string): Readable<boolean> => {\n const mql = window.matchMedia(query);\n const matches = signal(mql.matches);\n const handler = (e: MediaQueryListEvent) => {\n matches.value = e.matches;\n };\n\n mql.addEventListener('change', handler);\n onCleanup(() => mql.removeEventListener('change', handler));\n\n return matches;\n};\n","import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\nexport type MutationObserverValue = {\n entries: MutationRecord[];\n latest: MutationRecord | null;\n};\n\n/**\n * Observes DOM mutations on an element and exposes the latest mutation batch.\n */\nexport const mutationObserver = (\n el: Element,\n options: MutationObserverInit = {\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true,\n },\n): Readable<MutationObserverValue> => {\n const value = signal<MutationObserverValue>({ entries: [], latest: null });\n const observer = new MutationObserver((entries) => {\n value.value = {\n entries,\n latest: entries.length > 0 ? entries[entries.length - 1] : null,\n };\n });\n\n observer.observe(el, options);\n onCleanup(() => observer.disconnect());\n\n return value;\n};\n","import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\n/**\n * Observes an element's content-box size via `ResizeObserver`.\n * Returns a `Reactive` that updates whenever the dimensions change.\n * Must be called inside a `mount()` callback.\n */\nexport const resizeObserver = (el: Element): Readable<{ height: number; width: number }> => {\n const size = signal({ height: 0, width: 0 });\n const ro = new ResizeObserver(([entry]) => {\n if (!entry) return;\n\n const box = entry.contentBoxSize[0];\n\n if (box) size.value = { height: box.blockSize, width: box.inlineSize };\n });\n\n ro.observe(el);\n onCleanup(() => ro.disconnect());\n\n return size;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ore.cjs","names":[],"sources":["../src/directives/classMap.ts","../src/_dev.ts","../src/errors.ts","../src/types/bindings.ts","../src/utils/dom.ts","../src/directives/each.ts","../src/directives/live.ts","../src/directives/model.ts","../src/directives/raw.ts","../src/directives/styleMap.ts","../src/directives/when.ts","../src/runtime.ts","../src/forms/field.ts","../src/context.ts","../src/forms/context.ts","../src/props.ts","../src/types.ts","../src/utils/css.ts","../src/base-element.ts","../src/define.ts","../src/slots.ts","../src/utils/aria.ts","../src/host-bind.ts","../src/aria.ts","../src/utils/emit.ts","../src/template/bindings.ts","../src/utils/event-modifiers.ts","../src/template/compiler.ts","../src/template/instantiator.ts","../src/utils/id.ts","../src/observers/intersection-observe.ts","../src/observers/media-observe.ts","../src/observers/mutation-observe.ts","../src/observers/resize-observe.ts"],"sourcesContent":["import { computed, isReactive, type Readable } from '@vielzeug/ripple';\n\n/**\n * Produces a reactive string of class names from an object map.\n *\n * Each key is a class name. Its value may be:\n * - a static `boolean`\n * - a `Signal<boolean>`\n * - a getter `() => boolean`\n *\n * Returns a `Reactive<string>` that can be used directly in a template\n * class attribute:\n *\n * @example\n * ```ts\n * html`<div class=\"${classMap({ active: isActive, hidden: () => !isVisible.value })}\"></div>`\n * ```\n */\nexport const classMap = (map: Record<string, (() => boolean) | Readable<boolean> | boolean>): Readable<string> => {\n return computed(() =>\n Object.entries(map)\n .filter(([, v]) => (typeof v === 'function' ? v() : isReactive(v) ? v.value : v))\n // Strip whitespace from each key — spaces would inject extra class tokens.\n .map(([k]) => k.replace(/\\s+/g, ''))\n .filter(Boolean)\n .join(' '),\n );\n};\n","const isDev = !(globalThis as { __ORE_PROD__?: boolean }).__ORE_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/ore] ${msg}`);\n}\n\n/** @internal */\nexport function error(msg: string, ...args: unknown[]): void {\n if (isDev) console.error(`[@vielzeug/ore] ${msg}`, ...args);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n","import { error as logError } from './_dev';\n\n// ─── Structured error types ───────────────────────────────────────────────────\n\n/** Base class for all Ore errors. Use `instanceof OreError` to catch any Ore-originated error. */\nexport class OreError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is OreError {\n return err instanceof OreError;\n }\n}\n\n/** Thrown when Ore API is called incorrectly (e.g. outside setup, duplicate define, invalid prop). */\nexport class OreApiError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * Thrown when an internal invariant fails — e.g. compiled template metadata no\n * longer matching the DOM it was cloned from. Distinct from `OreApiError`: this\n * is never the caller's fault, it signals a bug in ore itself. See `invariant()`.\n */\nexport class OreInternalError extends OreError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/**\n * The phase in which a component error occurred.\n * - `'setup'` — synchronous setup() threw\n * - `'async-setup'` — async setup() promise rejected\n * - `'mounted'` — an onMounted callback threw\n * - `'form-reset'` — an onFormReset callback threw\n */\nexport type OreErrorPhase = 'async-setup' | 'form-reset' | 'mounted' | 'setup';\n\n/**\n * Structured error thrown by the Ore runtime when component setup fails.\n * Provides component name and original cause for debugging.\n */\nexport class OreLifecycleError extends OreError {\n readonly component: string;\n readonly phase: OreErrorPhase;\n\n constructor(message: string, options: { cause: Error; component: string; phase: OreErrorPhase }) {\n super(message, { cause: options.cause });\n this.component = options.component;\n this.phase = options.phase;\n }\n}\n\n/**\n * Report a runtime error via the ore:error event and console.\n */\nexport function reportRuntimeError(error: OreLifecycleError, element: HTMLElement): void {\n logError(`<${error.component}> setup error (phase: ${error.phase}):`, error.cause);\n\n element.dispatchEvent(\n new CustomEvent('ore:error', {\n bubbles: true,\n composed: true,\n detail: error,\n }),\n );\n}\n\n// ─── Error message constants ─────────────────────────────────────────────────\n\n/** Thrown by `waitFor` and `waitForEvent` in the testing sub-path when a condition is not met within the timeout. */\nexport class OreTimeoutError extends OreError {}\n\nexport const ORE_ERRORS = {\n defineDuplicate: (tag: string): string => `define('${tag}') called twice — custom element already registered`,\n defineFieldRequiresFormAssociated: (tag: string): string =>\n `useField() requires define('${tag}', { formAssociated: true })`,\n defineRequiresTag: 'define() requires a tag name',\n eachDuplicateKey: (key: string, index: number): string => `each() received duplicate key \"${key}\" at index ${index}`,\n injectStrictFailed: (key: string, tag: string): string => `injectStrict() could not resolve key \"${key}\" in <${tag}>`,\n invalidDynamicTagName: (tagName: string): string =>\n `html\\`...\\`: dynamic tag name \"${tagName}\" is not a valid HTML element name`,\n invariantViolated: (message: string): string => `invariant violated: ${message}`,\n lifecycleOutsideSetup: 'Lifecycle hooks must be called during component setup',\n mismatchedDynamicCloseTag: 'html`...`: dynamic closing tag has no matching dynamic opening tag',\n propInvalidReflect: 'Structured props cannot use reflect:true — use prop.json() with reflect:false',\n validationFailed: (tag: string, errors: string[]): string => `Validation failed for <${tag}>:\\n${errors.join('\\n')}`,\n} as const;\n\n/**\n * Assert an internal invariant that must always hold — e.g. compiled template\n * metadata staying in sync with the DOM it was cloned from. A failed invariant\n * means a bug in ore itself, never user input, so it throws `OreInternalError`\n * unconditionally (every build, never gated like `_dev.ts`'s `warn()`).\n *\n * Narrowing caveat: `asserts condition` only narrows the exact expression\n * passed in. Assign to a local `const` first — `invariant(el.parentNode, msg)`\n * does not narrow later reads of `el.parentNode`.\n */\nexport function invariant(condition: unknown, message: string): asserts condition {\n if (!condition) throw new OreInternalError(ORE_ERRORS.invariantViolated(message));\n}\n","/**\n * Core type definitions for the template binding and rendering system.\n *\n * All bindings reference actual DOM nodes directly (no UID-based lookup).\n * This eliminates the TreeWalker indexing pass and the string-based ID remapping\n * that the previous design required.\n */\n\nimport { type Readable, signal, type Signal } from '@vielzeug/ripple';\n\n// ─── REF TYPES ───────────────────────────────────────────────────────────────\n\nexport type Ref<T extends Element> = Signal<T | null>;\n\nexport function ref<T extends Element>(): Ref<T> {\n return signal<T | null>(null);\n}\n\nexport type RefCallback<T extends Element> = (el: T | null) => void;\n\n// ─── BINDING VARIANTS ────────────────────────────────────────────────────────\n// All bindings hold direct references to the DOM node they manage.\n\nexport type TextBinding = {\n node: Text;\n signal: Readable<unknown>;\n type: 'text';\n};\n\n/**\n * Minimal prop metadata needed by the attr binding layer.\n * Populated at binding creation time from propRegistry, so template-bindings.ts\n * has no direct dependency on props.ts.\n */\nexport type AttrPropMeta = {\n parse: (v: string | null) => unknown;\n reflect: boolean;\n signal: { value: unknown };\n};\n\ntype AttrBaseFields = {\n el: HTMLElement;\n /**\n * When true the binding uses live-write semantics: stale app-state writes are\n * skipped if the DOM value has diverged from the last programmatic write.\n */\n live?: true;\n mode: 'attr' | 'bool';\n name: string;\n /** Pre-resolved prop metadata (if the target element is an ore component). */\n propMeta?: AttrPropMeta;\n type: 'attr';\n};\n\n/** Attribute binding with a static value (no signal). */\nexport type AttrStaticBinding = AttrBaseFields & { value: unknown };\n\n/** Attribute binding driven by a reactive signal. */\nexport type AttrReactiveBinding = AttrBaseFields & { signal: Readable<unknown> };\n\nexport type AttrBinding = AttrStaticBinding | AttrReactiveBinding;\n\nexport type EventBinding = {\n el: HTMLElement;\n handler: (e: Event) => void;\n name: string;\n options?: AddEventListenerOptions;\n type: 'event';\n};\n\nexport type RefBinding = {\n el: HTMLElement;\n ref: Ref<Element> | RefCallback<Element>;\n type: 'ref';\n};\n\n/** Value types a reactive HTML slot can produce. */\nexport type HtmlBindingValue = HTMLResult | string | number | boolean | null | undefined;\n\nexport type HtmlBinding = {\n anchor: Comment;\n signal: Readable<HtmlBindingValue[]>;\n type: 'html';\n};\n\nexport type DirectiveBinding = {\n anchor: Comment;\n directive: DirectiveResult;\n type: 'directive';\n};\n\n/** Element-spread binding applied by model() and similar helpers. */\nexport type SpreadBinding = {\n el: HTMLElement;\n spread: SpreadObject;\n type: 'spread';\n};\n\nexport type Binding =\n TextBinding | AttrBinding | EventBinding | RefBinding | HtmlBinding | DirectiveBinding | SpreadBinding;\n\n// ─── BRAND UTILITY ───────────────────────────────────────────────────────────\n// Cross-realm–safe brand for branded types. Avoids repeating the symbol+guard boilerplate.\n\nconst makeBrand = <T extends object>(key: string) => {\n const BRAND = Symbol.for(key);\n const stamp = (obj: T): T => Object.assign(obj, { [BRAND]: true });\n const is = (value: unknown): value is T => typeof value === 'object' && value !== null && BRAND in (value as object);\n\n return { is, stamp };\n};\n\n// ─── DIRECTIVE RESULT ────────────────────────────────────────────────────────\n\nexport type DirectiveResult = {\n mount: (anchor: Comment, registerCleanup: (fn: () => void) => void) => void;\n};\n\nconst directiveBrand = makeBrand<DirectiveResult>('ore:directive');\n\n/**\n * Creates a registered DirectiveResult. All directive factories must use this\n * function — only objects created here pass `isDirectiveResult()`.\n */\nexport const createDirectiveResult = (mount: DirectiveResult['mount']): DirectiveResult =>\n directiveBrand.stamp({ mount });\n\nexport const isDirectiveResult = directiveBrand.is;\n\n// ─── SPREAD OBJECT ───────────────────────────────────────────────────────────\n// Returned by model() and similar helpers that apply multiple bindings to one element.\n\nexport type SpreadObject = {\n apply(el: HTMLElement, registerCleanup: (fn: () => void) => void): void;\n};\n\nconst spreadBrand = makeBrand<SpreadObject>('ore:spread');\n\n/**\n * Creates a registered SpreadObject. Used by model() to attach multiple bindings\n * (value sync + input event) to an element via a single template expression.\n */\nexport const createSpreadObject = (apply: SpreadObject['apply']): SpreadObject => spreadBrand.stamp({ apply });\n\nexport const isSpreadObject = spreadBrand.is;\n\n// ─── HTML RESULT ─────────────────────────────────────────────────────────────\n\n/**\n * The output of an `html` tagged template call.\n *\n * Each `html` call produces an independent fragment — there is no shared mutable\n * state between instances, so the same template can be safely rendered multiple\n * times (e.g. inside `each()`).\n */\nexport interface HTMLResult {\n /** The DOM fragment ready to insert into the document. Consumed on insertion. */\n readonly fragment: DocumentFragment;\n /** Wire up reactive effects to the fragment's nodes. Call after insertion. */\n apply(registerCleanup: (fn: () => void) => void): void;\n /**\n * Insert the fragment before `anchor` (or append to `parent` when no anchor)\n * and immediately wire up all reactive effects.\n *\n * This is the preferred single-step API — it is impossible to forget calling\n * `apply` separately. Use the lower-level `fragment` + `apply` only when you\n * need precise control over insertion (e.g. inside directive implementations).\n */\n mount(parent: ParentNode, anchor: Node | null, registerCleanup: (fn: () => void) => void): Node[];\n}\n\nconst htmlResultBrand = makeBrand<HTMLResult>('ore:html-result');\n\nexport const isHtmlResult = htmlResultBrand.is;\n\nexport function createHtmlResult(\n fragment: DocumentFragment,\n applyFn: (registerCleanup: (fn: () => void) => void) => void,\n): HTMLResult {\n const mount = (parent: ParentNode, anchor: Node | null, registerCleanup: (fn: () => void) => void): Node[] => {\n const nodes = Array.from(fragment.childNodes);\n\n parent.insertBefore(fragment, anchor);\n applyFn(registerCleanup);\n\n return nodes;\n };\n\n return htmlResultBrand.stamp({ apply: applyFn, fragment, mount });\n}\n","/**\n * Low-level DOM utilities used throughout the runtime and binding layers.\n */\n\nimport { warn } from '../_dev';\n\nexport const runAll = (fns: (() => void)[]): void => {\n for (let i = fns.length - 1; i >= 0; i--) fns[i]!();\n};\n\nexport const removeNodes = (nodes: Node[]): void => {\n for (const node of nodes) {\n (node as ChildNode).remove();\n }\n};\n\n/**\n * HTML attributes that accept URLs. Values bound to these attributes are\n * checked for dangerous schemes before being set.\n *\n * `srcdoc` is deliberately excluded: it holds raw HTML (not a URL), so scheme\n * checking doesn't apply — it's blocked unconditionally below, alongside `on*`.\n */\nconst URL_ATTRS = new Set([\n 'action',\n 'cite',\n 'codebase',\n 'data',\n 'formaction',\n 'href',\n 'manifest',\n 'ping',\n 'poster',\n 'src',\n 'xlink:href',\n]);\n\n/**\n * Schemes that execute JavaScript or can embed arbitrary HTML. Blocked\n * unconditionally in URL-accepting attributes.\n * Covers: javascript:, vbscript:, blob:, and data: variants that carry HTML/XML\n * or script-capable SVG. Plain data: image URIs (e.g. data:image/png) are\n * intentionally allowed.\n */\nconst DANGEROUS_SCHEME_RE =\n /^\\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\\/(?:html|svg\\+xml)|application\\/(?:xhtml|xml)))/i;\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n const lowerName = name.toLowerCase();\n\n if (/^on[a-z]/i.test(name)) {\n warn(\n `Blocked setAttribute(\"${name}\", ...) — inline event handler attributes are not supported. Use @${name.slice(2)} binding syntax instead.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (lowerName === 'srcdoc') {\n warn(\n `Blocked setAttribute(\"srcdoc\", ...) — \"srcdoc\" holds raw HTML, not a URL, and is not supported via attribute binding. Use raw() with a registered sanitizer if you need to inject trusted HTML.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n\n return;\n }\n\n const strVal = val === true ? 'true' : String(val);\n\n if (URL_ATTRS.has(lowerName) && DANGEROUS_SCHEME_RE.test(strVal)) {\n warn(\n `Blocked dangerous URL scheme in attribute \"${name}\". Only safe URLs are permitted in URL-accepting attributes.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n el.setAttribute(name, strVal);\n};\n\nexport const listen = (\n el: EventTarget | null | undefined,\n name: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n): (() => void) => {\n if (!el) return () => {};\n\n const listener: EventListener = handler;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nexport const isStructuredValue = (value: unknown): value is object =>\n Array.isArray(value) || (typeof value === 'object' && value !== null);\n","import { batch, computed, effect as rawEffect, type Readable, signal, type Signal, untrack } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { invariant, OreApiError, ORE_ERRORS } from '../errors';\nimport { createDirectiveResult, type DirectiveResult, type HTMLResult } from '../types/bindings';\nimport { removeNodes, runAll } from '../utils/dom';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ntype MaybeReactiveArray<T> = Readable<T[]> | (() => T[]) | T[];\n\ntype ItemEntry<T> = {\n cleanups: (() => void)[];\n data: Signal<T>;\n index: Signal<number>;\n /** The key used to identify this entry. */\n key: string;\n nodes: Node[];\n};\n\n// ─── Item lifecycle ───────────────────────────────────────────────────────────\n\nconst createItem = <T>(\n item: T,\n index: number,\n render: (item: Readable<T>, index: Readable<number>) => HTMLResult,\n parent: ParentNode,\n insertBefore: Node,\n): ItemEntry<T> => {\n const dataSignal: Signal<T> = signal(item);\n const indexSignal: Signal<number> = signal(index);\n\n const result = render(dataSignal, indexSignal);\n const cleanups: (() => void)[] = [];\n const nodes = result.mount(parent, insertBefore, (fn) => cleanups.push(fn));\n\n return { cleanups, data: dataSignal, index: indexSignal, key: '', nodes };\n};\n\nconst removeItem = <T>(entry: ItemEntry<T>): void => {\n runAll(entry.cleanups);\n removeNodes(entry.nodes);\n};\n\n// ─── Reconciler ───────────────────────────────────────────────────────────────\n\n/**\n * Reconciles the live item map (mutated in-place) against the next array.\n * Stale entries are removed and destroyed; new entries are created and inserted.\n * Existing entries are updated in-place via signal writes.\n * Returns the ordered list of entries matching nextList.\n */\nconst reconcileItems = <T>(\n itemsMap: Map<string, ItemEntry<T>>,\n next: T[],\n keyFn: (item: T, index: number) => string | number,\n render: (item: Readable<T>, index: Readable<number>) => HTMLResult,\n parent: ParentNode,\n endMarker: Node,\n): ItemEntry<T>[] => {\n const nextKeys: string[] = [];\n const nextKeySet = new Set<string>();\n\n for (let i = 0; i < next.length; i++) {\n const key = String(keyFn(next[i], i));\n\n if (nextKeySet.has(key)) throw new OreApiError(ORE_ERRORS.eachDuplicateKey(key, i));\n\n nextKeySet.add(key);\n nextKeys.push(key);\n }\n\n // Remove stale entries from the map\n for (const [key, entry] of itemsMap) {\n if (!nextKeySet.has(key)) {\n removeItem(entry);\n itemsMap.delete(key);\n }\n }\n\n // Build the next ordered list: update existing items, create new ones\n const nextOrdered: ItemEntry<T>[] = [];\n\n for (let i = 0; i < next.length; i++) {\n const key = nextKeys[i];\n const existing = itemsMap.get(key);\n\n if (existing) {\n batch(() => {\n existing.data.value = next[i];\n existing.index.value = i;\n });\n nextOrdered.push(existing);\n } else {\n const entry = untrack(() => createItem(next[i], i, render, parent, endMarker));\n\n entry.key = key;\n itemsMap.set(key, entry);\n nextOrdered.push(entry);\n }\n }\n\n // DOM ordering: right-to-left pass — move any item not already adjacent to cursor.\n // O(n) DOM operations in the worst case; optimal for the typical small list sizes\n // encountered in UI components (tabs, options, menu items).\n let cursor: Node = endMarker;\n\n for (let j = nextOrdered.length - 1; j >= 0; j--) {\n const entry = nextOrdered[j];\n const firstNode = entry.nodes[0];\n\n if (firstNode && firstNode !== cursor.previousSibling) {\n for (const node of entry.nodes) parent.insertBefore(node, cursor);\n }\n\n cursor = firstNode ?? cursor;\n }\n\n return nextOrdered;\n};\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Renders a keyed list of items as a `DirectiveResult`.\n *\n * Each item is rendered by the provided render function.\n * Items are reused by key when the list changes; only stale items are destroyed.\n *\n * The render function receives a `Readable<T>` signal and a `Readable<number>` index\n * signal. Use `item.value` to read the current item inside reactive expressions:\n *\n * ```ts\n * html`${each(items, (item) => item.id, (item) => html`<li>${() => item.value.name}</li>`)}`\n * ```\n *\n * **Plain array:** when a plain `T[]` is passed (not a signal or getter), it is\n * treated as a one-time static render. Mutations to the original array are not\n * tracked. Pass a `Signal<T[]>` or `() => T[]` for reactive lists.\n *\n * **Optional fallback:** the fourth argument renders when the list is empty.\n *\n * **Key choice:** pass a stable item identifier (e.g. `item.id`), never the\n * array index — an index-based key reassigns to a different item whenever the\n * list is reordered or an item is inserted/removed before it, causing full\n * item teardown/recreation instead of the in-place update `each()` is built\n * for. Duplicate keys within one render throw immediately (see `eachDuplicateKey`).\n */\nexport function each<T>(\n list: MaybeReactiveArray<T>,\n keyFn: (item: T, index: number) => string | number,\n render: (item: Readable<T>, index: Readable<number>) => HTMLResult,\n fallback?: () => HTMLResult,\n): DirectiveResult {\n const listSignal = Array.isArray(list)\n ? signal(list as T[])\n : typeof list === 'function'\n ? computed(list as () => T[])\n : list;\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const parent = anchor.parentNode;\n\n invariant(parent, 'each() anchor comment has no parent node');\n\n const endMarker = document.createComment('each/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n let itemsMap = new Map<string, ItemEntry<T>>();\n let itemsOrdered: ItemEntry<T>[] = [];\n let fallbackNodes: Node[] | null = null;\n let fallbackCleanups: (() => void)[] = [];\n\n const mountFallback = (): void => {\n if (!fallback) return;\n\n const result = fallback();\n\n fallbackNodes = result.mount(parent, endMarker, (fn) => fallbackCleanups.push(fn));\n };\n\n const clearFallback = (): void => {\n if (fallbackNodes) {\n runAll(fallbackCleanups);\n removeNodes(fallbackNodes);\n fallbackNodes = null;\n fallbackCleanups = [];\n }\n };\n\n const sub = rawEffect(() => {\n const nextList = listSignal.value ?? [];\n\n if (nextList.length === 0) {\n for (const entry of untrack(() => itemsOrdered)) removeItem(entry);\n itemsMap = new Map();\n itemsOrdered = [];\n\n if (!fallbackNodes) untrack(mountFallback);\n\n return;\n }\n\n clearFallback();\n\n try {\n itemsOrdered = untrack(() => reconcileItems(itemsMap, nextList, keyFn, render, parent, endMarker));\n } catch (err) {\n warn(`each() reconciliation error: ${err instanceof Error ? err.message : String(err)}`);\n\n for (const entry of itemsMap.values()) removeItem(entry);\n itemsMap = new Map();\n itemsOrdered = [];\n }\n });\n\n registerCleanup(() => sub.dispose());\n registerCleanup(() => {\n clearFallback();\n for (const entry of itemsOrdered) removeItem(entry);\n endMarker.remove();\n });\n });\n}\n","import type { Readable } from '@vielzeug/ripple';\n\nconst LIVE_BRAND: unique symbol = Symbol.for('ore:live');\n\n/**\n * A branded signal that tells the attribute binding engine to skip writing when\n * the DOM value has diverged from the last programmatically-written value.\n * Created via live(signal) — pass a signal directly rather than wrapping a value.\n *\n * @example\n * html`<input :value=\"${live(model)}\" />`\n */\nexport type LiveSignal<T> = Readable<T> & { readonly [LIVE_BRAND]: true };\n\n// WeakSet tracks which signal objects have been marked live — zero allocation on call.\nlet liveSignals = new WeakSet<object>();\n\n/**\n * Marks a signal binding as \"live\" so stale app-state writes never clobber\n * in-progress user input.\n *\n * For form controls: if the current DOM value diverges from the last write made\n * by this binding, subsequent app-state writes are silently dropped until the\n * DOM value matches the incoming value or no prior write has been recorded.\n */\nexport const live = <T>(source: Readable<T>): LiveSignal<T> => {\n liveSignals.add(source as object);\n\n return source as LiveSignal<T>;\n};\n\nexport const isLiveSignal = (value: unknown): value is LiveSignal<unknown> =>\n typeof value === 'object' && value !== null && liveSignals.has(value as object);\n\n/** @internal Reset live signal registry. Called by cleanup() for test isolation. */\nexport const _resetLiveSignals = (): void => {\n liveSignals = new WeakSet();\n};\n","import { effect as rawEffect, type Signal } from '@vielzeug/ripple';\n\nimport { createSpreadObject, type SpreadObject } from '../types/bindings';\nimport { listen } from '../utils/dom';\n\n/**\n * Two-way binding spread for form inputs.\n * Syncs the signal value to the element's DOM value and back.\n *\n * Supports `type=\"text\"` (default), `type=\"number\"`, `type=\"range\"`,\n * `type=\"checkbox\"`, `<select>` (single-select), and\n * `<select multiple>` (multi-select, `Signal<string[]>`).\n *\n * @example\n * ```ts\n * const name = signal('');\n * html`<input type=\"text\" ${model(name)} />`\n *\n * const count = signal(0);\n * html`<input type=\"number\" ${model(count)} />`\n *\n * const checked = signal(false);\n * html`<input type=\"checkbox\" ${model(checked)} />`\n *\n * const selected = signal<string[]>([]);\n * html`<select multiple ${model(selected)}><option value=\"a\">A</option></select>`\n * ```\n */\nexport function model<T extends string | number | boolean | null>(source: Signal<T>): SpreadObject;\nexport function model(source: Signal<string[]>): SpreadObject;\nexport function model<T extends string | number | boolean | null | string[]>(source: Signal<T>): SpreadObject {\n return createSpreadObject((el, registerCleanup) => {\n const input = el as HTMLInputElement;\n const isCheckbox = input.type === 'checkbox';\n const isNumeric = input.type === 'number' || input.type === 'range';\n const isSelect = el instanceof HTMLSelectElement;\n const isMultiSelect = isSelect && (el as HTMLSelectElement).multiple;\n\n // Signal → DOM\n const sub = rawEffect(() => {\n const v = source.value;\n\n if (isMultiSelect) {\n const selected = Array.isArray(v) ? (v as string[]) : [];\n const selectEl = el as HTMLSelectElement;\n\n for (const opt of selectEl.options) {\n opt.selected = selected.includes(opt.value);\n }\n } else if (isCheckbox) {\n input.checked = Boolean(v);\n } else {\n (el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).value =\n v == null ? '' : String(v as string | number | boolean | null);\n }\n });\n\n registerCleanup(() => sub.dispose());\n\n // DOM → Signal\n // <select> fires 'change'; text/number/range/textarea/checkbox fire 'input'.\n const eventName = isSelect ? 'change' : 'input';\n\n registerCleanup(\n listen(el, eventName, (e: Event) => {\n const target = e.target as HTMLInputElement;\n\n if (isMultiSelect) {\n const selectEl = e.target as HTMLSelectElement;\n const values = Array.from(selectEl.selectedOptions).map((opt) => opt.value);\n\n (source as Signal<string[]>).value = values;\n } else if (isCheckbox) {\n source.value = target.checked as T;\n } else if (isNumeric) {\n source.value = (target.value === '' ? 0 : Number(target.value)) as T;\n } else {\n source.value = target.value as T;\n }\n }),\n );\n });\n}\n","import { computed, effect as rawEffect, isReactive, type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { invariant } from '../errors';\nimport { createDirectiveResult, type DirectiveResult } from '../types/bindings';\nimport { removeNodes } from '../utils/dom';\n\ntype RawSanitizer = (html: string) => string;\n\nlet _sanitizer: RawSanitizer | null = null;\nlet _warned = false;\n\nexport const setRawSanitizer = (fn: RawSanitizer | null): void => {\n _sanitizer = fn;\n\n if (!fn) _warned = false;\n};\n\n/** @internal */\nexport const _resetRawSanitizer = (): void => {\n _sanitizer = null;\n _warned = false;\n};\n\nconst sanitize = (value: string): string => {\n if (_sanitizer) return _sanitizer(value);\n\n if (value && !_warned) {\n _warned = true;\n warn(\n 'raw() was called without a sanitizer registered. ' +\n 'Passing user-supplied HTML directly to raw() is an XSS risk. ' +\n 'Register a sanitizer with setRawSanitizer() — e.g. setRawSanitizer(DOMPURIFY.sanitize).',\n );\n }\n\n return value;\n};\n\nconst parseRaw = (html: string, parent: ParentNode, insertBefore: Node): Node[] => {\n const tpl = document.createElement('template');\n\n tpl.innerHTML = html;\n\n const nodes = Array.from(tpl.content.cloneNode(true).childNodes);\n\n for (const node of nodes) parent.insertBefore(node, insertBefore);\n\n return nodes;\n};\n\n/**\n * Renders a trusted HTML string without escaping as a DirectiveResult.\n * Only use with content you control — passing user-supplied strings\n * directly is an XSS risk. Register a sanitizer with setRawSanitizer()\n * to add a runtime safety net.\n *\n * Supports static strings, signals, and getter functions `() => string`.\n * When reactive, the DOM is updated in-place whenever the value changes.\n */\nexport function raw(value: (() => string) | string | Signal<string> | Readable<string>): DirectiveResult {\n if (typeof value === 'function') {\n const c = computed(value);\n\n return createDirectiveResult((anchor, registerCleanup) => {\n registerCleanup(() => c.dispose());\n raw(c).mount(anchor, registerCleanup);\n });\n }\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const parent = anchor.parentNode;\n\n invariant(parent, 'raw() anchor comment has no parent node');\n\n const endMarker = document.createComment('raw/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n if (isReactive(value)) {\n let currentNodes: Node[] = [];\n const src = value as Readable<string>;\n\n const stop = rawEffect(() => {\n removeNodes(currentNodes);\n currentNodes = parseRaw(sanitize(src.value), parent, endMarker);\n });\n\n registerCleanup(() => stop.dispose());\n registerCleanup(() => {\n removeNodes(currentNodes);\n endMarker.remove();\n });\n } else {\n parseRaw(sanitize(value), parent, endMarker);\n\n registerCleanup(() => endMarker.remove());\n }\n });\n}\n","import { computed, isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { toKebab } from '../utils/dom';\n\ntype StyleInput =\n | string\n | number\n | null\n | undefined\n | false\n | (() => string | number | null | undefined | false)\n | Readable<string | number | null | undefined | false>;\n\nconst toStyleValue = (value: StyleInput): string => {\n const resolved = typeof value === 'function' ? value() : isReactive(value) ? value.value : value;\n\n if (resolved == null || resolved === false) return '';\n\n // Strip characters that can break out of a CSS declaration in inline styles.\n // Semicolons end the current declaration; braces are meaningful in stylesheets\n // but not inline style values and signal injection attempts.\n return String(resolved).replace(/[;{}]/g, '');\n};\n\n// Strip characters that can break out of a CSS declaration in inline styles.\n// This is applied to both property names and values: semicolons end declarations\n// and braces are meaningful in stylesheet rules (but not inline style values).\nconst UNSAFE_CSS_CHARS = /[;{}]/g;\n\n/**\n * Builds a reactive inline style string from a style object.\n *\n * Takes a record of CSS property names (camelCase) with values that can be:\n * - Static strings/numbers\n * - Functions that return strings/numbers\n * - Signals for reactive updates\n *\n * @example\n * ```ts\n * const color = signal('red');\n * const size = signal(16);\n *\n * html`<div :style=${styleMap({\n * backgroundColor: color,\n * width: () => `${size.value}px`,\n * padding: '10px'\n * })}></div>`\n * ```\n */\nexport const styleMap = (record: Record<string, StyleInput>): Readable<string> => {\n return computed(() => {\n const declarations: string[] = [];\n\n for (const [name, input] of Object.entries(record)) {\n const value = toStyleValue(input);\n\n if (!value) continue;\n\n const safeName = toKebab(name).replace(UNSAFE_CSS_CHARS, '');\n\n if (!safeName) continue;\n\n declarations.push(`${safeName}:${value}`);\n }\n\n return declarations.join(';');\n });\n};\n","import { computed, effect as rawEffect, isReactive, type Readable, untrack } from '@vielzeug/ripple';\n\nimport type { RegisterCleanup } from '../template';\n\nimport { invariant } from '../errors';\nimport { createDirectiveResult, type DirectiveResult, type HTMLResult, isHtmlResult } from '../types/bindings';\nimport { removeNodes, runAll } from '../utils/dom';\n\ntype MaybeReactive<T> = T | (() => T) | Readable<T>;\n\ntype WhenRenderable = HTMLResult | null | undefined | false;\n\nconst NO_PARENT_MSG = 'when() anchor comment has no parent node';\n\nconst mountBranch = (\n result: HTMLResult,\n parent: ParentNode,\n insertBefore: Node,\n registerCleanup: RegisterCleanup,\n): Node[] => result.mount(parent, insertBefore, registerCleanup);\n\n/**\n * Conditionally renders one of two branches as a `DirectiveResult`.\n *\n * The condition may be a boolean, signal, or getter function.\n * When the condition changes, the current branch is cleaned up and\n * the new branch is mounted in its place.\n *\n * @example\n * ```ts\n * html`${when(isLoggedIn, () => html`<p>Welcome</p>`, () => html`<p>Log in</p>`)}`\n * ```\n */\nexport function when(\n condition: MaybeReactive<boolean>,\n truthy: () => WhenRenderable,\n falsy?: () => WhenRenderable,\n): DirectiveResult {\n if (typeof condition !== 'function' && !isReactive(condition)) {\n return createDirectiveResult((anchor, registerCleanup) => {\n const branch = condition ? truthy() : falsy ? falsy() : null;\n\n if (!branch || !isHtmlResult(branch)) return;\n\n const parent = anchor.parentNode;\n\n invariant(parent, NO_PARENT_MSG);\n\n const nodes = mountBranch(branch, parent, anchor, registerCleanup);\n\n registerCleanup(() => removeNodes(nodes));\n });\n }\n\n return createDirectiveResult((anchor, registerCleanup) => {\n const ownedComputed = typeof condition === 'function' ? computed(condition as () => boolean) : null;\n const conditionSignal = ownedComputed ?? (condition as Readable<boolean>);\n\n if (ownedComputed) registerCleanup(() => ownedComputed.dispose());\n\n const parent = anchor.parentNode;\n\n invariant(parent, NO_PARENT_MSG);\n\n const endMarker = document.createComment('when/end');\n\n parent.insertBefore(endMarker, anchor.nextSibling);\n\n let currentNodes: Node[] = [];\n let currentCleanups: (() => void)[] = [];\n\n const sub = rawEffect(() => {\n const next = conditionSignal.value;\n\n runAll(currentCleanups);\n removeNodes(currentNodes);\n currentCleanups = [];\n currentNodes = [];\n\n const branch = next ? truthy() : falsy ? falsy() : null;\n\n if (!branch || !isHtmlResult(branch)) return;\n\n const branchCleanups: (() => void)[] = [];\n\n currentNodes = untrack(() => mountBranch(branch, parent, endMarker, (fn) => branchCleanups.push(fn)));\n currentCleanups = branchCleanups;\n });\n\n registerCleanup(() => sub.dispose());\n registerCleanup(() => {\n runAll(currentCleanups);\n removeNodes(currentNodes);\n endMarker.remove();\n });\n });\n}\n","/**\n * Component runtime — implicit \"current component\" context plus every lifecycle\n * hook a `setup()` function can call.\n *\n * Design note: hooks are plain module-level functions (not a bag/context object\n * passed into `setup`). They resolve the active component through a single\n * module-level pointer (`currentContext`), set for the duration of `setup()` and\n * of each queued `onMounted` callback. This is the same mechanism React/Vue/Solid\n * use for their composable hooks — it lets any helper function (not just the\n * top-level `setup()` body) call `onMounted`/`onCleanup`/`bind`/... directly,\n * with no context object to thread through every layer of a composable.\n */\nimport {\n type CleanupFn,\n effect as _effect,\n type EffectCallback,\n onCleanup as _onCleanup,\n type Readable,\n} from '@vielzeug/ripple';\n\nimport { OreApiError, ORE_ERRORS } from './errors';\nimport { listen as listenInternal } from './utils/dom';\n\n// ─── Runtime context ──────────────────────────────────────────────────────────\n// A single context object carries both the host element and mount callbacks,\n// eliminating two parallel globals that were always set together.\n\nexport type OnMountedCallback = () => CleanupFn | void;\nexport type OnFormResetCallback = () => void;\n\nexport type RuntimeContext = {\n element: HTMLElement;\n formResetCallbacks: OnFormResetCallback[];\n mountCallbacks: OnMountedCallback[];\n};\n\nlet currentContext: RuntimeContext | null = null;\n\n/** @internal Execute fn with a given runtime context active. */\nexport const runWithContext = <T>(ctx: RuntimeContext, fn: () => T): T => {\n const prev = currentContext;\n\n currentContext = ctx;\n\n try {\n return fn();\n } finally {\n currentContext = prev;\n }\n};\n\n/**\n * Returns the current runtime context, throwing a consistently-worded error\n * (naming the calling API) if called outside `setup()`. Every lifecycle/context\n * hook below routes through this — it's the single place that decides both\n * \"are we inside setup?\" and what the resulting error looks like, so the error\n * message is never worse for one hook than another.\n * @internal\n */\nexport const requireSetupContext = (api: string): RuntimeContext => {\n if (currentContext) return currentContext;\n\n throw new OreApiError(`${api}: ${ORE_ERRORS.lifecycleOutsideSetup}`);\n};\n\n/**\n * Returns the current component's host element.\n * Only valid synchronously during component `setup()` (or inside a composable\n * called from it) — throws otherwise.\n */\nexport const getHost = (): HTMLElement => requireSetupContext('getHost').element;\n\nexport const tryRegisterCleanup = (fn: CleanupFn): boolean => {\n if (!currentContext) return false;\n\n _onCleanup(fn);\n\n return true;\n};\n\n/**\n * Register a cleanup function to run on component disconnect.\n * Must be called synchronously during component setup or inside scope.run().\n */\nexport const onCleanup = _onCleanup;\n\n/**\n * Register work to run after the component template mounts to the DOM.\n * Multiple callbacks run in registration order.\n */\nexport const onMounted = (fn: OnMountedCallback): void => {\n requireSetupContext('onMounted').mountCallbacks.push(fn);\n};\n\n/**\n * Register work to run when the ancestor `<form>` is reset (native `formResetCallback`,\n * only fires for `formAssociated: true` components). Multiple callbacks run in\n * registration order, every time the form resets — unlike `onMounted`, this isn't a\n * one-shot hook.\n */\nexport const onFormReset = (fn: OnFormResetCallback): void => {\n requireSetupContext('onFormReset').formResetCallbacks.push(fn);\n};\n\n/**\n * Create a reactive effect scoped to the component lifecycle.\n * Automatically cleaned up on component disconnect.\n * Returns a stop function that disposes the effect immediately.\n *\n * Named `watchEffect` (not `watch`) to avoid shadowing `@vielzeug/ripple`'s\n * `watch(source, callback)`, which has different semantics (explicit source,\n * old/new value pair) — the two are commonly imported in the same file.\n */\nexport const watchEffect = (fn: EffectCallback): (() => void) => {\n const sub = _effect(fn);\n const stop = (): void => sub.dispose();\n\n tryRegisterCleanup(stop);\n\n return stop;\n};\n\n/**\n * Attach a scoped event listener that is automatically removed on component disconnect.\n * Silently no-ops when `target` is `null` or `undefined` (safe for reactive targets).\n */\nexport function onEvent<K extends keyof HTMLElementEventMap>(\n target: EventTarget | null | undefined,\n event: K,\n listener: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n): void;\nexport function onEvent(\n target: EventTarget | null | undefined,\n event: string,\n listener: EventListener,\n options?: AddEventListenerOptions,\n): void {\n requireSetupContext('onEvent');\n\n if (!target) return;\n\n const cleanup = listenInternal(target, event, listener, options);\n\n if (!tryRegisterCleanup(cleanup)) cleanup();\n}\n\n/**\n * Watch a ref signal and run a callback when it resolves to a non-null element.\n * The callback's return value is used as a cleanup function.\n */\nexport const onElement = <T extends HTMLElement>(\n ref: Readable<T | null>,\n callback: (el: T) => CleanupFn | undefined | void,\n): (() => void) => {\n return watchEffect(() => {\n const el = ref.value;\n\n if (el) return callback(el);\n });\n};\n","import { type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { OreApiError, ORE_ERRORS } from '../errors';\nimport { getHost, onCleanup, onFormReset, watchEffect } from '../runtime';\n\n/** @internal */\nconst internalsRegistry = new WeakMap<HTMLElement, ElementInternals>();\n\nexport type FormFieldOptions<T = unknown> = {\n disabled?: Readable<boolean>;\n /**\n * The host element to attach `ElementInternals` to.\n * Defaults to the element currently being set up via `getHost()`.\n * Pass this explicitly when calling `useField` from a composable that is\n * not called directly during `setup()` (e.g. a helper factory function).\n */\n el?: HTMLElement;\n /**\n * When `true`, a `null` or `undefined` value is submitted as an empty string\n * (`''`) instead of `null`. This keeps the field's key present in `FormData`\n * even when the value is absent — useful when the server expects the field to\n * always be included.\n *\n * @default false\n */\n emptyStringForNull?: boolean;\n /**\n * Called when the ancestor `<form>` is reset (see `onFormReset`). Use to restore\n * whatever local state backs `value` — `useField` itself owns no field state to reset.\n */\n onReset?: () => void;\n toFormValue?: (value: T) => File | FormData | string | null;\n /**\n * Recomputed reactively and passed straight to `internals.setValidity()` — `null`\n * (or omitting `validity` entirely) means always valid. Pair with `validationMessage`.\n *\n * @example\n * ```ts\n * validity: computed(() => (required.value && isBlank(value.value)) ? { valueMissing: true } : null),\n * validationMessage: computed(() => (required.value && isBlank(value.value)) ? 'Required.' : ''),\n * ```\n */\n validationMessage?: Readable<string>;\n validity?: Readable<ValidityStateFlags | null>;\n value: Signal<T> | Readable<T>;\n};\n\nexport type FormFieldHandle = {\n checkValidity: () => boolean;\n readonly internals: ElementInternals;\n reportValidity: () => boolean;\n setCustomValidity: (message: string) => void;\n setValidity: ElementInternals['setValidity'];\n};\n\nexport const useField = <T = unknown>(options: FormFieldOptions<T>): FormFieldHandle => {\n const host = options.el ?? getHost();\n const ctor = host.constructor as typeof HTMLElement & { formAssociated?: boolean };\n\n if (!ctor.formAssociated) {\n throw new OreApiError(ORE_ERRORS.defineFieldRequiresFormAssociated(host.localName));\n }\n\n if (internalsRegistry.has(host)) {\n throw new OreApiError(`useField() was already called on <${host.localName}>. Call it only once per component.`);\n }\n\n const internals = host.attachInternals();\n\n internalsRegistry.set(host, internals);\n onCleanup(() => internalsRegistry.delete(host));\n\n const toFormValue =\n options.toFormValue ??\n ((v: T): File | FormData | string | null => {\n if (v == null) return options.emptyStringForNull ? '' : null;\n\n if (v instanceof File || v instanceof FormData) return v;\n\n return String(v);\n });\n\n watchEffect(() => {\n internals.setFormValue(toFormValue(options.value.value));\n });\n\n const disabled = options.disabled;\n\n if (disabled) {\n if (!('states' in internals)) {\n warn(\n 'useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.',\n );\n } else {\n const states = internals.states as CustomStateSet;\n\n watchEffect(() => {\n if (disabled.value) states.add('disabled');\n else states.delete('disabled');\n });\n }\n }\n\n if (options.validity) {\n watchEffect(() => {\n const flags = options.validity?.value ?? {};\n // Per spec, ElementInternals.setValidity() throws if any flag is true and message is\n // empty — a caller-supplied `validity` with no matching `validationMessage` would crash\n // this effect in a real browser. Fail safe with a generic message instead of propagating\n // that crash, and say so loudly in dev so the real fix (pass validationMessage) gets made.\n const hasFlag = Object.values(flags).some(Boolean);\n const message = options.validationMessage?.value ?? '';\n\n if (hasFlag && !message) {\n warn(\n 'useField(): `validity` has a truthy flag but `validationMessage` is empty — internals.setValidity() ' +\n 'requires a non-empty message whenever any flag is true. Falling back to a generic message; pass ' +\n '`validationMessage` to customize it.',\n );\n internals.setValidity(flags, 'Invalid value.');\n\n return;\n }\n\n internals.setValidity(flags, message);\n });\n }\n\n if (options.onReset) onFormReset(options.onReset);\n\n const checkValidity = () => internals.checkValidity();\n const reportValidity = () => internals.reportValidity();\n const setCustomValidity = (message: string) =>\n message ? internals.setValidity({ customError: true }, message) : internals.setValidity({});\n\n return {\n checkValidity,\n internals,\n reportValidity,\n setCustomValidity,\n setValidity: internals.setValidity.bind(internals),\n };\n};\n","/**\n * Component context injection API — `inject` / `injectStrict` / `provide` / `createContext`.\n *\n * Context values are stored on the providing element via a WeakMap registry and\n * resolved by walking up the DOM tree (including through shadow boundaries).\n * Providing is done via `provide(key, value)` inside `setup()`.\n */\n\nimport { warn } from './_dev';\nimport { OreApiError, ORE_ERRORS } from './errors';\nimport { getHost, requireSetupContext } from './runtime';\n\nconst contextRegistry = new WeakMap<HTMLElement, Map<InjectionKey<unknown>, unknown>>();\n\nexport type InjectionKey<T> = symbol & {\n readonly __ore_injection_key?: T;\n};\n\n/** @internal Build a linear ancestor chain (including shadow host boundaries). */\nconst buildAncestorChain = (start: HTMLElement): HTMLElement[] => {\n const chain: HTMLElement[] = [];\n let node: Node | null = start;\n\n while (node) {\n if (node instanceof HTMLElement) chain.push(node);\n\n const root = node.getRootNode() as Node;\n\n node = (node as HTMLElement).parentElement ?? (root instanceof ShadowRoot ? root.host : null);\n }\n\n return chain;\n};\n\n/**\n * Register a context value on a specific element.\n * @internal Backs the public `provide()` — do not call directly.\n */\nconst provideOnElement = <T>(el: HTMLElement, key: InjectionKey<T>, value: T): void => {\n const map = contextRegistry.get(el) ?? new Map<InjectionKey<unknown>, unknown>();\n\n // `inject()` memoizes its result per consumer (see resolvedCache below), so a\n // provider swapping the raw value after a descendant already read it would be\n // silently ignored downstream. Provide a `Readable` (signal/computed) instead\n // of a raw value so descendants observe updates through the value itself.\n if (map.has(key)) {\n warn(\n `provide(): key already provided on <${el.localName}> — overwriting. Provide a Readable to update it instead.`,\n );\n }\n\n map.set(key, value);\n contextRegistry.set(el, map);\n};\n\n/**\n * Register a context value on the current component's host element, making it\n * available to descendant components via `inject(key)`.\n *\n * Provide a `Readable` (signal/computed) rather than a raw value if descendants\n * need to observe later changes — `inject()` resolves and caches the value once\n * per consumer, so re-calling `provide()` with a new raw value later is not seen.\n */\nexport const provide = <T>(key: InjectionKey<T>, value: T): void => provideOnElement(getHost(), key, value);\n\nconst NOT_FOUND_SENTINEL = Symbol('inject.not_found');\n\n/** Per-setup-context cache: avoids repeated ancestor walks for the same key. */\nconst resolvedCache = new WeakMap<object, Map<InjectionKey<unknown>, unknown>>();\n\nconst walkAndFind = <T>(element: HTMLElement, key: InjectionKey<T>): T | typeof NOT_FOUND_SENTINEL => {\n const chain = buildAncestorChain(element);\n\n for (const node of chain) {\n const map = contextRegistry.get(node);\n\n if (map?.has(key)) return map.get(key) as T;\n }\n\n return NOT_FOUND_SENTINEL;\n};\n\nexport function inject<T>(key: InjectionKey<T>): T | undefined;\nexport function inject<T>(key: InjectionKey<T>, fallback: T): T;\nexport function inject<T>(key: InjectionKey<T>, ...rest: [T?]): T | undefined {\n const ctx = requireSetupContext('inject');\n\n let cache = resolvedCache.get(ctx);\n\n if (!cache) {\n cache = new Map();\n resolvedCache.set(ctx, cache);\n }\n\n const cacheKey = key as InjectionKey<unknown>;\n\n if (cache.has(cacheKey)) {\n const cached = cache.get(cacheKey);\n\n if (cached === NOT_FOUND_SENTINEL) return rest.length > 0 ? rest[0] : undefined;\n\n return cached as T;\n }\n\n const found = walkAndFind(ctx.element, key);\n\n cache.set(cacheKey, found);\n\n if (found === NOT_FOUND_SENTINEL) return rest.length > 0 ? rest[0] : undefined;\n\n return found;\n}\n\nexport const injectStrict = <T>(key: InjectionKey<T>): T => {\n const resolved = inject<T>(key, NOT_FOUND_SENTINEL as unknown as T);\n\n if (resolved !== (NOT_FOUND_SENTINEL as unknown)) return resolved;\n\n const host = getHost();\n\n throw new OreApiError(ORE_ERRORS.injectStrictFailed(String(key), host.localName));\n};\n\nexport function createContext<T>(description?: string): InjectionKey<T> {\n return Symbol(description) as InjectionKey<T>;\n}\n","import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { createContext } from '../context';\n\n/**\n * Context shape injected by child field components.\n * Contains only what a field needs — not submit/error/status APIs.\n */\nexport type FormFieldContext = {\n /** Whether any field has been touched (interacted with). Set via markDirty(). */\n readonly dirty: Readable<boolean>;\n markDirty(): void;\n /**\n * Register a field's validity signal with the form context.\n * Returns a cleanup function.\n */\n registerField(validity: Readable<boolean>): () => void;\n};\n\n/**\n * Full form controller returned by `createFormContext`.\n * Extends `FormFieldContext` with submission and status APIs.\n */\nexport type FormController = FormFieldContext & {\n /**\n * Clear `dirty` and `error` status signals and invoke `onReset` if provided.\n * Note: this does not reset individual field values — pass an `onReset` callback\n * to handle value restoration.\n */\n clearStatus(): void;\n /** The last submit error, or null if the last submit succeeded. */\n readonly error: Readable<unknown>;\n /** Submit the form programmatically. */\n submit(e?: Event): Promise<void>;\n /** Whether the form is currently submitting. */\n readonly submitting: Readable<boolean>;\n /** Whether all fields in the form are valid. */\n readonly valid: Readable<boolean>;\n};\n\nexport const FORM_CONTEXT_KEY = createContext<FormFieldContext>('ore:form-context');\n\n/**\n * Create a `FormController` for coordinating form state across child field components.\n * Call `provide(FORM_CONTEXT_KEY, form)` to make it available to descendants.\n *\n * @example\n * ```ts\n * define('my-form', {\n * setup(_props) {\n * const form = createFormContext({ onSubmit: async (e) => { ... } });\n * provide(FORM_CONTEXT_KEY, form);\n * return html`<form @submit=${form.submit}><slot></slot></form>`;\n * }\n * });\n * ```\n */\nexport function createFormContext(\n options: {\n onReset?: () => void;\n onSubmit?: (e?: Event) => void | Promise<void>;\n } = {},\n): FormController {\n const fieldValiditySignals = signal<Array<Readable<boolean>>>([]);\n const submitting = signal(false);\n const dirty = signal(false);\n const error = signal<unknown>(null);\n\n // Note: [].every() is vacuously true, so valid is true when no fields are registered.\n // This is intentional — a form with no fields is considered valid (nothing to invalidate it).\n const valid = computed(() => fieldValiditySignals.value.every((s) => s.value));\n\n const submit = async (e?: Event): Promise<void> => {\n e?.preventDefault();\n\n if (submitting.value) return;\n\n submitting.value = true;\n error.value = null;\n\n try {\n await options.onSubmit?.(e);\n dirty.value = false;\n } catch (err) {\n error.value = err;\n } finally {\n submitting.value = false;\n }\n };\n\n const clearStatus = (): void => {\n dirty.value = false;\n error.value = null;\n options.onReset?.();\n };\n\n const markDirty = (): void => {\n dirty.value = true;\n };\n\n const registerField = (validity: Readable<boolean>): (() => void) => {\n fieldValiditySignals.value = [...fieldValiditySignals.value, validity];\n\n return () => {\n fieldValiditySignals.value = fieldValiditySignals.value.filter((s) => s !== validity);\n };\n };\n\n return { clearStatus, dirty, error, markDirty, registerField, submit, submitting, valid };\n}\n","import { type Readable, type Signal, signal } from '@vielzeug/ripple';\n\nimport { warn } from './_dev';\nimport { invariant, OreApiError, ORE_ERRORS } from './errors';\nimport { watchEffect } from './runtime';\nimport { isStructuredValue, setAttr, toKebab } from './utils/dom';\n\nexport type PropsDef<T extends Record<string, unknown>> = {\n // All props must be explicitly defined via prop.* helpers or PropDef objects\n [K in keyof Required<T>]: PropDef<T[K & keyof T]>;\n};\n\nexport type PropDef<T> = { readonly default: T; readonly parse: (value: string | null) => T; reflect?: boolean };\nexport type PropInputDefs = Record<string, PropDef<unknown>>;\n\n/**\n * Prop definition factory — use these helpers for all prop definitions.\n * No implicit type inference; all parser behavior is explicit and intentional.\n */\ntype PropFactory = {\n bool(defaultValue?: boolean): PropDef<boolean>;\n /**\n * JS-only property — never reads from or writes to an HTML attribute.\n * Use for complex objects, arrays, callbacks, or any non-serialisable value.\n *\n * @example\n * ```ts\n * columns: prop.data<DataGridColumn[]>([]),\n * config: prop.data<Options>(),\n * getRowKey: prop.data<(row: T) => string>(),\n * onSelect: prop.data<(item: T) => void>(),\n * ```\n */\n data<T>(): PropDef<T | undefined>;\n data<T>(defaultValue: T): PropDef<T>;\n json<T>(defaultValue: T): PropDef<T>;\n number<T extends number = number>(): PropDef<T | undefined>;\n number<T extends number = number>(defaultValue: number): PropDef<T>;\n oneOf<T extends string | undefined, D extends T = T>(allowed: readonly NonNullable<T>[], defaultValue: D): PropDef<T>;\n string<T extends string = string>(): PropDef<T | undefined>;\n string<T extends string = string>(defaultValue: string): PropDef<T>;\n};\n\n/** @internal JS-only prop implementation — never reads/writes attributes. */\nfunction _jsOnlyProp<T>(defaultValue?: T): PropDef<T | undefined> | PropDef<T> {\n return { default: defaultValue, parse: () => defaultValue, reflect: false } as PropDef<T | undefined>;\n}\n\nexport const prop: PropFactory = {\n /**\n * Boolean prop — reflects its value as a presence-only attribute (toggleAttribute).\n * Reflection is always enabled. To suppress attribute reflection for a boolean,\n * use `prop.data<boolean>(false)` instead.\n */\n bool(defaultValue?: boolean): PropDef<boolean> {\n const def = defaultValue ?? false;\n\n return {\n default: def,\n parse: (value) => value !== null && value !== 'false',\n reflect: true,\n };\n },\n data<T>(defaultValue?: T): PropDef<T | undefined> | PropDef<T> {\n return _jsOnlyProp(defaultValue);\n },\n /**\n * JSON-serialisable prop — the value is stored as a JS object and parsed\n * from the attribute via `JSON.parse`. Reflection is always disabled\n * because serialising complex objects back to attributes on every change\n * would be expensive and produce unreadable HTML.\n *\n * @example\n * ```ts\n * columns: prop.json<Column[]>([]),\n * // attribute: <my-grid columns='[{\"id\":\"name\"}]'>\n * // change not reflected back → attribute stays static after upgrade\n * ```\n */\n json<T>(defaultValue: T): PropDef<T> {\n return {\n default: defaultValue,\n parse: (value) => {\n if (value == null || value === '') return defaultValue;\n\n try {\n return JSON.parse(value) as T;\n } catch {\n return defaultValue;\n }\n },\n reflect: false,\n };\n },\n number<T extends number = number>(defaultValue?: number): PropDef<T> | PropDef<T | undefined> {\n const def = defaultValue !== undefined ? (defaultValue as T) : undefined;\n\n return {\n default: def,\n parse: (value) => {\n if (value == null) return def;\n\n const n = Number(value);\n\n if (Number.isNaN(n)) {\n warn(`prop.number(): attribute value \"${value}\" is not a valid number, using default (${String(def)})`);\n\n return def;\n }\n\n return n as T;\n },\n reflect: true,\n } as PropDef<T> | PropDef<T | undefined>;\n },\n oneOf<T extends string | undefined, D extends T = T>(\n allowed: readonly NonNullable<T>[],\n defaultValue: D,\n ): PropDef<T> {\n return {\n default: defaultValue,\n parse: (value) => (value != null && allowed.includes(value as NonNullable<T>) ? (value as T) : defaultValue),\n reflect: true,\n };\n },\n string<T extends string = string>(defaultValue?: string): PropDef<T> | PropDef<T | undefined> {\n // When no default provided, undefined sentinel → attribute removed when value is absent\n const def = defaultValue !== undefined ? (defaultValue as T) : undefined;\n\n return {\n default: def,\n parse: (value: string | null) => (value == null ? def : (value as T)),\n reflect: true,\n } as PropDef<T> | PropDef<T | undefined>;\n },\n};\n\nconst isPropDef = (value: unknown): value is PropDef<unknown> =>\n typeof value === 'object' && value !== null && 'default' in value && 'parse' in value;\n\n/**\n * Validate and normalize a prop definition.\n * Throws if definition is invalid or incomplete.\n *\n * Accepts any object shaped like `PropDef` — not just `prop.*` helper output — so you can\n * define a custom prop with explicit parser and reflection behavior when the `prop.*` helpers\n * don't cover your type:\n *\n * ```ts\n * const customProp = (): PropDef<MyCustomType> => ({\n * default: new MyCustomType(),\n * parse: (value) => JSON.parse(value || '{}') as MyCustomType,\n * reflect: false,\n * });\n * ```\n */\nexport function normalizePropDefinition<T>(value: unknown, propName: string): PropDef<T> {\n if (!isPropDef(value)) {\n throw new OreApiError(\n `Prop \"${propName}\" must use a prop.* helper (string/number/bool/json/oneOf). Received: ${typeof value}`,\n );\n }\n\n const descriptor = value as PropDef<T>;\n\n if (!descriptor.parse) {\n throw new OreApiError(`Prop \"${propName}\" must have a parse function. Use prop.* helpers.`);\n }\n\n const reflect = descriptor.reflect ?? false;\n\n // Validate: structured defaults with reflect:true are not allowed\n if (reflect && isStructuredValue(descriptor.default)) {\n throw new OreApiError(`Prop \"${propName}\": ${ORE_ERRORS.propInvalidReflect}`);\n }\n\n return {\n ...descriptor,\n reflect,\n };\n}\n\n/**\n * Validate all prop definitions at define-time.\n * Returns validation error messages or empty array if valid.\n */\nexport function validatePropDefs(defs: Record<string, unknown>): string[] {\n const errors: string[] = [];\n\n for (const [key, value] of Object.entries(defs)) {\n try {\n normalizePropDefinition(value, key);\n } catch (error) {\n errors.push(error instanceof Error ? error.message : String(error));\n }\n }\n\n return errors;\n}\n\ntype PropMeta<T = unknown> = {\n parse: (value: string | null) => T;\n reflect: boolean;\n signal: Signal<T>;\n};\n\nconst propRegistry = new WeakMap<HTMLElement, Map<string, PropMeta<unknown>>>();\n\n/**\n * Look up the registered prop metadata for a given attribute name on an element.\n * Used by the template compiler to resolve prop bindings without exposing the registry.\n */\nexport const getPropMeta = (el: HTMLElement, attrName: string): PropMeta<unknown> | undefined =>\n propRegistry.get(el)?.get(attrName);\n\n/**\n * A framework can hand a prop a raw attribute-style string well after the element\n * has upgraded — e.g. Vue reconciling server-rendered markup against a custom\n * element that auto-upgraded from its SSR attribute before hydration ran, or\n * assigning the pre-upgrade instance property it captured before `registerProp`\n * defined the real accessor. In both cases route the string through the same\n * parser an attribute value would use (so e.g. `size=\"16\"` doesn't end up stored\n * as the string `\"16\"` instead of the number `16`). Already-typed values (objects,\n * functions, booleans, numbers set deliberately as JS properties) pass through untouched.\n */\nconst coerceIncoming = <T>(value: unknown, parse: PropDef<T>['parse']): T =>\n (typeof value === 'string' ? parse(value) : value) as T;\n\n/** @internal Runtime prop registration (called by createProps) */\nconst registerProp = <T>(el: HTMLElement, propName: string, attrName: string, propDef: PropDef<T>): Signal<T> => {\n if (!propRegistry.has(el)) propRegistry.set(el, new Map());\n\n const { default: defaultValue, parse, reflect = false } = propDef;\n const s = signal<T>(defaultValue);\n const hasPreUpgradeProperty = Object.hasOwn(el as unknown as Record<string, unknown>, propName);\n const preUpgradeValue = hasPreUpgradeProperty ? (el as unknown as Record<string, unknown>)[propName] : undefined;\n\n const meta: PropMeta<unknown> = {\n parse,\n reflect,\n signal: s,\n };\n\n if (hasPreUpgradeProperty) {\n delete (el as unknown as Record<string, unknown>)[propName];\n s.value = coerceIncoming(preUpgradeValue, parse);\n } else if (el.hasAttribute(attrName)) {\n s.value = parse(el.getAttribute(attrName)) as T;\n }\n\n const registry = propRegistry.get(el);\n\n invariant(registry, `propRegistry entry missing for <${el.localName}> — registerProp() must create it above`);\n registry.set(attrName, meta);\n\n Object.defineProperty(el, propName, {\n configurable: true,\n enumerable: true,\n get: () => s.value,\n set: (value: T) => {\n s.value = coerceIncoming(value, parse);\n },\n });\n\n if (reflect) {\n watchEffect(() => {\n const v = s.value;\n\n if (v == null) {\n el.removeAttribute(attrName);\n } else if (typeof v === 'boolean') {\n el.toggleAttribute(attrName, v);\n } else {\n setAttr(el, attrName, v);\n }\n });\n }\n\n return s;\n};\n\nexport type InferPropValue<T> = T extends PropDef<infer U> ? U : T;\n\n/**\n * Infer the reactive props object type from a `PropInputDefs` map.\n * Each entry becomes a `Reactive<T>` keyed by the prop name.\n *\n * @example\n * ```ts\n * const propDefs = { count: prop.number(0), label: prop.string('hi') };\n * type Props = InferProps<typeof propDefs>;\n * // => { readonly count: Readable<number>; readonly label: Readable<string> }\n * ```\n */\nexport type InferProps<D extends PropInputDefs> = {\n readonly [K in keyof D]-?: Readable<InferPropValue<D[K]>>;\n};\n\nexport function createProps<D extends PropInputDefs>(el: HTMLElement, defs: D): InferProps<D> {\n const props = {} as Record<string, Signal<unknown>>;\n\n for (const [name, def] of Object.entries(defs)) {\n // defs passed here are already normalized by define(); skip re-normalization.\n const attrName = toKebab(name);\n\n props[name] = registerProp(el, name, attrName, def as PropDef<unknown>);\n }\n\n return props as unknown as InferProps<D>;\n}\n","/**\n * Shared component phase and lifecycle event constants.\n * Extracted to a standalone module to break the circular dependency\n * between registration.ts and errors.ts.\n */\n\n// ─── ComponentPhase ───────────────────────────────────────────────────────────\n\nexport const ComponentPhase = {\n LOADING: 'loading',\n SETUP_DONE: 'setup_done',\n SETUP_RUNNING: 'setup_running',\n UNINITIALIZED: 'uninitialized',\n UNMOUNTED: 'unmounted',\n} as const;\n\nexport type ComponentPhase = (typeof ComponentPhase)[keyof typeof ComponentPhase];\n\n// ─── Lifecycle events ─────────────────────────────────────────────────────────\n\nexport const LIFECYCLE_EVENTS = {\n CONNECT: 'ore:connect',\n DISCONNECT: 'ore:disconnect',\n} as const;\n\nexport type LifecycleEventName = (typeof LIFECYCLE_EVENTS)[keyof typeof LIFECYCLE_EVENTS];\n","/**\n * CSS tagged template utility and CSSStyleSheet caching.\n */\n\nimport { error } from '../_dev';\n\nexport type CSSResult = {\n content: string;\n toString(): string;\n};\n\nconst cssResultBrand = new WeakSet<CSSResult>();\n\nexport const isCssResult = (value: unknown): value is CSSResult =>\n typeof value === 'object' && value !== null && cssResultBrand.has(value as CSSResult);\n\nconst cssResultToString = function (this: CSSResult): string {\n return this.content;\n};\n\nexport const css = (strings: TemplateStringsArray, ...values: Array<CSSResult | string | number>): CSSResult => {\n let content = '';\n\n for (let i = 0; i < strings.length; i++) {\n content += strings[i];\n\n if (i < values.length) {\n const v = values[i];\n\n content += isCssResult(v) ? v.content : String(v);\n }\n }\n\n const result: CSSResult = { content: content.trim(), toString: cssResultToString };\n\n cssResultBrand.add(result);\n\n return result;\n};\n\nconst stylesheetStringCache = new Map<string, CSSStyleSheet>();\n\n/** @internal Clear the stylesheet cache. Used for test isolation and HMR. */\nexport const _clearStylesheetCache = (): void => {\n stylesheetStringCache.clear();\n};\n\nexport const loadStylesheet = (style: string | CSSStyleSheet | CSSResult): CSSStyleSheet => {\n if (style instanceof CSSStyleSheet) return style;\n\n const cssText = typeof style === 'string' ? style : style.content;\n const cached = stylesheetStringCache.get(cssText);\n\n if (cached) return cached;\n\n const sheet = new CSSStyleSheet();\n\n try {\n sheet.replaceSync(cssText);\n } catch (err) {\n error('Style sheet replace failed', err);\n }\n\n stylesheetStringCache.set(cssText, sheet);\n\n return sheet;\n};\n","import { scope as _scope, type Scope, untrack } from '@vielzeug/ripple';\n\nimport type { ComponentDefinition } from './component-types';\n\nimport { warn } from './_dev';\nimport { type OreErrorPhase, OreLifecycleError, reportRuntimeError } from './errors';\nimport { createProps, getPropMeta, type InferProps, type PropInputDefs, type PropsDef } from './props';\nimport {\n type OnFormResetCallback,\n type OnMountedCallback,\n onCleanup,\n type RuntimeContext,\n runWithContext,\n} from './runtime';\nimport { ComponentPhase, LIFECYCLE_EVENTS } from './types';\nimport { type HTMLResult } from './types/bindings';\nimport { loadStylesheet } from './utils/css';\n\n// ─── Internal component state ─────────────────────────────────────────────────\n\ntype ComponentState = {\n /** Registered via `onFormReset()` — persists across mount callbacks, unlike `mountCallbacks`. */\n formResetCallbacks: OnFormResetCallback[];\n /** Incremented on every disconnect — guards both mount callbacks and async setup results. */\n generation: number;\n mountCallbacks: OnMountedCallback[];\n phase: ComponentPhase;\n scope: Scope;\n templateResult: HTMLResult | null;\n};\n\nconst createComponentState = (): ComponentState => ({\n formResetCallbacks: [],\n generation: 0,\n mountCallbacks: [],\n phase: ComponentPhase.UNINITIALIZED,\n scope: _scope(),\n templateResult: null,\n});\n\n// ─── BaseElement ──────────────────────────────────────────────────────────────\n\n/**\n * Phase transitions:\n *\n * ```\n * UNINITIALIZED ──_runSetup()──┬─(sync result)──► SETUP_DONE\n * └─(promise)──────► LOADING ──(resolves)──► SETUP_DONE\n * SETUP_DONE / LOADING ──disconnectedCallback()──► UNMOUNTED ──(reset)──► UNINITIALIZED\n * ```\n *\n * `generation` increments on every disconnect and is captured before an async\n * `setup()` is awaited; if it no longer matches when the promise settles, the\n * element was disconnected (and possibly reconnected) in the meantime and the\n * result is discarded (see `_isStale`).\n *\n * Why this lives on the class instead of a standalone pure reducer: every\n * transition here is triggered by running actual user code (`def.setup()`,\n * `onMounted` callbacks) inside a reactive `scope.run()` + `runWithContext()`\n * — there is no meaningful \"decide the next phase\" step that can be separated\n * from \"run the side-effecting thing that produces the phase change\" without\n * introducing a data-only effect-description layer that this package has no\n * other use for. That's why the methods below stay as direct, readable\n * procedural steps instead of a reducer + effect interpreter.\n */\nexport class BaseElement extends HTMLElement {\n static _definition: ComponentDefinition<any>;\n static _normalizedPropDefs: PropsDef<Record<never, never>> | undefined;\n static formAssociated = false;\n static observedAttributes: string[] = [];\n\n private _component: ComponentState;\n\n constructor() {\n super();\n\n const def = (this.constructor as typeof BaseElement)._definition;\n\n if (def?.shadow !== false) {\n this.attachShadow({ mode: 'open', ...(def?.shadow as Partial<ShadowRootInit> | undefined) });\n }\n\n this._component = createComponentState();\n }\n\n connectedCallback(): void {\n untrack(() => {\n if (this._component.phase === ComponentPhase.UNINITIALIZED) this._runSetup();\n\n this._init();\n });\n this.dispatchEvent(new CustomEvent(LIFECYCLE_EVENTS.CONNECT, { bubbles: false, composed: false }));\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n\n const propMeta = getPropMeta(this, name);\n\n if (!propMeta) return;\n\n const parsed = propMeta.parse(newValue);\n\n if (\n !Object.is(\n untrack(() => propMeta.signal.value),\n parsed,\n )\n )\n propMeta.signal.value = parsed as never;\n }\n\n disconnectedCallback(): void {\n this._component.generation++;\n this._component.phase = ComponentPhase.UNMOUNTED;\n this.dispatchEvent(new CustomEvent(LIFECYCLE_EVENTS.DISCONNECT, { bubbles: false, composed: false }));\n this._component.scope.dispose();\n // Reset mutable fields for next connect, keeping the same object for stable references\n this._component.formResetCallbacks = [];\n this._component.mountCallbacks = [];\n this._component.phase = ComponentPhase.UNINITIALIZED;\n this._component.scope = _scope();\n this._component.templateResult = null;\n }\n\n /**\n * Native form-association lifecycle callback — the browser calls this on every\n * `formAssociated: true` element inside a `<form>` when that form is reset.\n * Runs every `onFormReset()` callback registered during `setup()`.\n */\n formResetCallback(): void {\n for (const callback of this._component.formResetCallbacks) {\n try {\n callback();\n } catch (error) {\n this._handleSetupError(error, 'form-reset');\n }\n }\n }\n\n private _handleSetupError(error: unknown, phase: OreErrorPhase = 'setup'): HTMLResult | void {\n const err = error instanceof Error ? error : new Error(String(error));\n const oreError = new OreLifecycleError(`<${this.localName}> failed during ${this._component.phase} (${phase})`, {\n cause: err,\n component: this.localName,\n phase,\n });\n const def = (this.constructor as typeof BaseElement)._definition;\n\n if (def?.onError) {\n try {\n return def.onError(oreError, this);\n } catch {\n /* fall through */\n }\n }\n\n reportRuntimeError(oreError, this);\n }\n\n private _runSetup(): void {\n this._component.phase = ComponentPhase.SETUP_RUNNING;\n\n const def = (this.constructor as typeof BaseElement)._definition;\n const normalizedPropDefs = (this.constructor as typeof BaseElement)._normalizedPropDefs;\n const ctx: RuntimeContext = { element: this, formResetCallbacks: [], mountCallbacks: [] };\n\n try {\n let setupResult: HTMLResult | null | Promise<HTMLResult | null> | undefined;\n\n this._component.scope.run(() => {\n setupResult = runWithContext(ctx, () => {\n const setupProps = normalizedPropDefs\n ? createProps(this, normalizedPropDefs)\n : ({} as InferProps<PropInputDefs>);\n\n return def.setup(setupProps as InferProps<PropInputDefs>);\n });\n });\n this._component.mountCallbacks.push(...ctx.mountCallbacks);\n this._component.formResetCallbacks.push(...ctx.formResetCallbacks);\n\n if (setupResult != null && typeof (setupResult as Promise<HTMLResult | null>).then === 'function') {\n // Async setup: show loading template immediately, swap when resolved.\n // Store captured mount callbacks; they will be scheduled after the real template mounts.\n const pendingCallbacks = this._component.mountCallbacks.splice(0);\n\n this._component.phase = ComponentPhase.LOADING;\n\n if (def.loading) {\n this._component.templateResult = def.loading();\n }\n\n // Capture the current generation so the async handler can detect staleness:\n // if the element disconnects+reconnects before the promise resolves, generation is\n // incremented and the old promise result must be discarded.\n void this._runSetupAsync(\n setupResult as Promise<HTMLResult | null>,\n pendingCallbacks,\n this._component.generation,\n );\n } else {\n this._component.templateResult = (setupResult as HTMLResult | null) ?? null;\n this._component.phase = ComponentPhase.SETUP_DONE;\n }\n } catch (error) {\n const recoveryTemplate = this._handleSetupError(error);\n\n if (recoveryTemplate) {\n this._component.templateResult = recoveryTemplate;\n this._component.phase = ComponentPhase.SETUP_DONE;\n } else {\n this._component.phase = ComponentPhase.UNINITIALIZED;\n throw error;\n }\n }\n }\n\n /**\n * True once the element has disconnected (and possibly reconnected) since\n * `capturedGeneration` was recorded — an in-flight async `setup()` result\n * arriving after that point is for an instance state that no longer exists.\n */\n private _isStale(capturedGeneration: number): boolean {\n return this._component.generation !== capturedGeneration || !this.isConnected;\n }\n\n private async _runSetupAsync(\n promise: Promise<HTMLResult | null>,\n pendingCallbacks: OnMountedCallback[],\n capturedGeneration: number,\n ): Promise<void> {\n try {\n const result = await promise;\n\n if (this._isStale(capturedGeneration)) {\n warn(`<${this.localName}> async setup result discarded — element disconnected before setup resolved.`);\n\n return;\n }\n\n this._component.templateResult = result ?? null;\n this._component.phase = ComponentPhase.SETUP_DONE;\n this._component.mountCallbacks.push(...pendingCallbacks);\n\n if (result) this._applyResult(result);\n\n this._scheduleMountCallbacks();\n } catch (error) {\n if (this._isStale(capturedGeneration)) {\n warn(`<${this.localName}> async setup error discarded — element disconnected before setup resolved.`);\n\n return;\n }\n\n const recovery = this._handleSetupError(error, 'async-setup');\n\n if (recovery) {\n this._component.templateResult = recovery;\n this._component.phase = ComponentPhase.SETUP_DONE;\n this._applyResult(recovery);\n } else {\n this._component.phase = ComponentPhase.UNINITIALIZED;\n }\n }\n }\n\n private _applyResult(result: HTMLResult | null): void {\n if (!result) return;\n\n const host: Element | ShadowRoot = this.shadowRoot ?? this;\n\n host.replaceChildren(result.fragment);\n this._component.scope.run(() => {\n result.apply(onCleanup);\n });\n }\n\n private _init(): void {\n this._applyStyles();\n this._mountTemplate();\n\n // Only schedule mount callbacks once setup is fully complete (not in LOADING state)\n if (this._component.phase === ComponentPhase.SETUP_DONE) this._scheduleMountCallbacks();\n }\n\n private _applyStyles(): void {\n const def = (this.constructor as typeof BaseElement)._definition;\n\n if (this.shadowRoot && def?.styles?.length) {\n this.shadowRoot.adoptedStyleSheets = def.styles.map(loadStylesheet);\n }\n }\n\n private _mountTemplate(): void {\n const result = this._component.templateResult;\n\n if (!result) return;\n\n this._applyResult(result);\n }\n\n private _scheduleMountCallbacks(): void {\n if (this._component.mountCallbacks.length === 0) return;\n\n const capturedGeneration = this._component.generation;\n\n queueMicrotask(() => {\n if (this._isStale(capturedGeneration)) return;\n\n // Snapshot callbacks so in-loop registrations don't extend this iteration.\n const batch = this._component.mountCallbacks.splice(0);\n\n for (const callback of batch) {\n try {\n const nestedCtx = {\n element: this,\n formResetCallbacks: [] as typeof this._component.formResetCallbacks,\n mountCallbacks: [] as typeof this._component.mountCallbacks,\n };\n\n this._component.scope.run(() => {\n runWithContext(nestedCtx, () => {\n const cleanup = callback();\n\n if (typeof cleanup === 'function') onCleanup(cleanup);\n });\n });\n\n if (nestedCtx.mountCallbacks.length > 0) {\n this._component.mountCallbacks.push(...nestedCtx.mountCallbacks);\n }\n\n if (nestedCtx.formResetCallbacks.length > 0) {\n this._component.formResetCallbacks.push(...nestedCtx.formResetCallbacks);\n }\n } catch (error) {\n this._handleSetupError(error, 'mounted');\n }\n }\n\n // If nested onMounted calls registered new callbacks, schedule them with\n // a fresh token check in the next microtask.\n if (this._component.mountCallbacks.length > 0) {\n this._scheduleMountCallbacks();\n }\n });\n }\n}\n","import type { ComponentDefinition } from './component-types';\n\nimport { BaseElement } from './base-element';\nimport { OreApiError, ORE_ERRORS } from './errors';\nimport {\n type InferProps,\n normalizePropDefinition,\n prop,\n type PropDef,\n type PropInputDefs,\n type PropsDef,\n validatePropDefs,\n} from './props';\nimport { toKebab } from './utils/dom';\n\nexport { prop };\nexport type { InferProps, PropDef, PropInputDefs, PropsDef };\nexport type { HostBindFn } from './host-bind';\n\n/**\n * Define and register a web component.\n *\n * The `setup` function runs once per instance on first connect and returns an\n * `HTMLResult`. All reactive behaviour is expressed through reactive directives\n * inside the template — not by re-evaluating setup itself.\n *\n * Everything besides `props` — lifecycle hooks, host bindings, context, slots,\n * emit — is a free function imported from `@vielzeug/ore` and called directly\n * from inside `setup()` (or from a composable it calls):\n *\n * ```ts\n * import { define, html, prop, onMounted, useEmit, useSlots } from '@vielzeug/ore';\n *\n * define<{ count?: number }>('my-counter', {\n * props: { count: prop.number(0) },\n * setup(props) {\n * const emit = useEmit<{ increment: number }>();\n * const slots = useSlots<'header' | 'footer'>();\n *\n * onMounted(() => console.log('mounted'));\n *\n * return html`<button @click=${() => emit('increment', props.count.value + 1)}>${props.count}</button>`;\n * },\n * });\n * ```\n */\nexport function define<Props extends Record<string, unknown> = Record<never, never>>(\n tag: string,\n definition: ComponentDefinition<Props>,\n): void {\n if (!tag) throw new OreApiError(ORE_ERRORS.defineRequiresTag);\n\n if (customElements.get(tag)) throw new OreApiError(ORE_ERRORS.defineDuplicate(tag));\n\n const { props: propDefs } = definition;\n\n const normalizedPropDefs: PropsDef<Props> | undefined = (() => {\n if (!propDefs) return undefined;\n\n const errors = validatePropDefs(propDefs as Record<string, unknown>);\n\n if (errors.length > 0) throw new OreApiError(ORE_ERRORS.validationFailed(tag, errors));\n\n const normalized: PropInputDefs = {};\n\n for (const [key, def] of Object.entries(propDefs)) {\n normalized[key] = normalizePropDefinition(def, key);\n }\n\n return normalized as PropsDef<Props>;\n })();\n\n const observedAttrs = normalizedPropDefs ? Object.keys(normalizedPropDefs).map(toKebab) : [];\n\n // Named class for DevTools and error messages\n const ComponentClass = class extends BaseElement {\n static override _definition = definition as ComponentDefinition<any>;\n static override _normalizedPropDefs = normalizedPropDefs as PropsDef<Record<never, never>> | undefined;\n static override formAssociated = definition.formAssociated ?? false;\n static override observedAttributes = observedAttrs;\n };\n\n Object.defineProperty(ComponentClass, 'name', { value: tag });\n customElements.define(tag, ComponentClass);\n}\n","/**\n * Slot observation and reactive slot signals.\n *\n * `slots.has(name?)`: Signal<boolean> — whether a named slot has assigned elements.\n * `slots.elements(name?)`: Signal<Element[]> — assigned elements for a slot (flattened).\n */\n\nimport { type Readable, signal, type Signal } from '@vielzeug/ripple';\n\nimport { onCleanup, onMounted, type RuntimeContext, requireSetupContext } from './runtime';\n\nexport type ComponentSlots<SlotNames extends string = string> = {\n elements: (name?: SlotNames) => Readable<Element[]>;\n has: (name?: SlotNames) => Readable<boolean>;\n};\n\nconst SLOT_DEFAULT = 'default';\nconst normalizeSlotName = (slotName: string | null | undefined): string => slotName || SLOT_DEFAULT;\n\nconst createSlots = (host: HTMLElement): ComponentSlots<string> => {\n type SlotEntry = {\n elements: Signal<Element[]>;\n presence: Signal<boolean>;\n };\n\n const slotSignals = new Map<string, SlotEntry>();\n const slotNodesByName = new Map<string, Set<HTMLSlotElement>>();\n const slotCleanupMap = new Map<HTMLSlotElement, () => void>();\n\n const ensureSlotEntry = (normalizedName: string): SlotEntry => {\n let entry = slotSignals.get(normalizedName);\n\n if (!entry) {\n entry = {\n elements: signal<Element[]>([]),\n presence: signal(false),\n };\n slotSignals.set(normalizedName, entry);\n }\n\n return entry;\n };\n\n const areElementsEqual = (prev: Element[], next: Element[]): boolean => {\n if (prev.length !== next.length) return false;\n\n for (let i = 0; i < prev.length; i++) {\n if (prev[i] !== next[i]) return false;\n }\n\n return true;\n };\n\n const recomputeSlot = (name: string): void => {\n const normalized = normalizeSlotName(name);\n const slotsForName = slotNodesByName.get(normalized);\n const assigned: Element[] = [];\n\n if (slotsForName) {\n for (const slotEl of slotsForName) {\n assigned.push(...slotEl.assignedElements({ flatten: true }));\n }\n }\n\n const entry = ensureSlotEntry(normalized);\n\n if (!areElementsEqual(entry.elements.value, assigned)) entry.elements.value = assigned;\n\n const hasElements = assigned.length > 0;\n\n if (entry.presence.value !== hasElements) entry.presence.value = hasElements;\n };\n\n const bindSlot = (slotEl: HTMLSlotElement): void => {\n if (slotCleanupMap.has(slotEl)) return;\n\n const name = normalizeSlotName(slotEl.getAttribute('name'));\n const setForName = slotNodesByName.get(name) ?? new Set<HTMLSlotElement>();\n\n setForName.add(slotEl);\n slotNodesByName.set(name, setForName);\n\n const onChange = () => recomputeSlot(name);\n\n slotEl.addEventListener('slotchange', onChange);\n\n slotCleanupMap.set(slotEl, () => {\n slotEl.removeEventListener('slotchange', onChange);\n });\n\n recomputeSlot(name);\n };\n\n const unbindSlot = (slotEl: HTMLSlotElement): void => {\n const cleanup = slotCleanupMap.get(slotEl);\n\n if (!cleanup) return;\n\n cleanup();\n slotCleanupMap.delete(slotEl);\n\n const name = normalizeSlotName(slotEl.getAttribute('name'));\n const setForName = slotNodesByName.get(name);\n\n if (setForName) {\n setForName.delete(slotEl);\n\n if (setForName.size === 0) slotNodesByName.delete(name);\n }\n\n recomputeSlot(name);\n };\n\n const bindAllSlots = (): void => {\n host.shadowRoot?.querySelectorAll('slot').forEach((slotEl) => bindSlot(slotEl));\n };\n\n const recomputeAllSlots = (): void => {\n for (const name of slotNodesByName.keys()) {\n recomputeSlot(name);\n }\n };\n\n // Watch for dynamically-inserted <slot> elements (e.g. inside when(), each()).\n let observer: MutationObserver | null = null;\n\n // Start MutationObserver immediately in setup so any slots inserted synchronously\n // before the first render are captured without a timing gap.\n if (host.shadowRoot) {\n observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.removedNodes) {\n if (node instanceof HTMLSlotElement) unbindSlot(node);\n }\n }\n\n bindAllSlots();\n recomputeAllSlots();\n });\n observer.observe(host.shadowRoot, { childList: true, subtree: true });\n }\n\n // Bind slots already present in the shadow root (pre-upgrade scenarios)\n // and schedule a post-render pass to pick up slots injected by the template.\n bindAllSlots();\n onMounted(() => {\n bindAllSlots();\n recomputeAllSlots();\n });\n\n onCleanup(() => {\n observer?.disconnect();\n observer = null;\n\n for (const cleanup of slotCleanupMap.values()) cleanup();\n\n slotCleanupMap.clear();\n slotNodesByName.clear();\n slotSignals.clear();\n });\n\n return {\n elements: (name?: string) => ensureSlotEntry(normalizeSlotName(name)).elements,\n has: (name?: string) => ensureSlotEntry(normalizeSlotName(name)).presence,\n };\n};\n\n/** One slot registry per component instance — reused across repeated `useSlots()` calls. */\nconst slotsByContext = new WeakMap<RuntimeContext, ComponentSlots<string>>();\n\n/**\n * Returns reactive slot presence / element signals for the current component.\n * Safe to call multiple times during `setup()` — the underlying slot registry\n * (MutationObserver + `slotchange` listeners) is created once per instance.\n *\n * Pass a `SlotNames` type parameter for typed slot names:\n * ```ts\n * const slots = useSlots<'header' | 'footer'>();\n * slots.has('header'); // typed ✓\n * ```\n */\nexport const useSlots = <SlotNames extends string = string>(): ComponentSlots<SlotNames> => {\n const ctx = requireSetupContext('useSlots');\n let entry = slotsByContext.get(ctx);\n\n if (!entry) {\n entry = createSlots(ctx.element);\n slotsByContext.set(ctx, entry);\n }\n\n return entry as ComponentSlots<SlotNames>;\n};\n","/**\n * Shared ARIA attribute key normalisation helpers.\n *\n * Two flavours are needed across the codebase:\n *\n * - `normalizeAriaKey` — always adds the `aria-` prefix for non-role keys.\n * Used by `syncAria()` where every config key is an ARIA attribute.\n *\n * - `normalizeHostAttrKey` — passes non-ARIA keys through unchanged.\n * Used by `host.bind({ attr: ... })` where keys may be arbitrary HTML attributes.\n */\n\n/** Normalise an aria config key to a full `aria-*` attribute name. */\nexport const normalizeAriaKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', 'expanded' → 'aria-expanded'\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : `aria-${key}`;\n};\n\n/** Normalise a host-bind attr key: aria-camelCase → aria-kebab-case; other keys pass through. */\nexport const normalizeHostAttrKey = (key: string): string => {\n if (key === 'role' || key.startsWith('aria-')) return key;\n\n // 'ariaLabel' → 'aria-label', other keys unchanged\n return key.startsWith('aria') ? `aria-${key.slice(4).toLowerCase()}` : key;\n};\n","/**\n * Host element binding API — reactive attr, class, style, and event bindings\n * applied directly to the component's host element or any target element.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { getHost, tryRegisterCleanup, watchEffect } from './runtime';\nimport { normalizeHostAttrKey } from './utils/aria';\nimport { listen, setAttr, toKebab } from './utils/dom';\n\n/**\n * Describes a reactive or static host binding value.\n */\nexport type HostBindingValue =\n | (() => string | number | boolean | null | undefined)\n | Readable<string | number | boolean | null | undefined>\n | string\n | number\n | boolean\n | null\n | undefined;\n\n/**\n * Configuration for host attribute bindings.\n */\nexport type ReflectConfig = Record<string, HostBindingValue>;\n\ntype HostClassBindingValue = Readable<boolean> | (() => boolean) | boolean;\n// Bivariant callback allows consumers to use narrower event types.\ntype HostEventListener = { bivarianceHack(event: Event): void }['bivarianceHack'];\n\nexport type HostBindConfig = {\n attr?: ReflectConfig;\n class?: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>;\n on?: Record<string, HostEventListener | undefined>;\n style?: Record<string, HostBindingValue>;\n};\n\nexport type BindOptions = AddEventListenerOptions & {\n /**\n * Target element to bind to. Defaults to the host element when called\n * via `bind()`. Pass an explicit element to bind to any other element\n * (e.g. a slotted trigger or an internally-referenced child element).\n * When a target is provided, cleanup is always auto-registered with the\n * component scope if one is active.\n */\n target?: Element;\n};\n\nexport type HostBindFn = (config: HostBindConfig, options?: BindOptions) => () => void;\n\n/**\n * Apply reactive or static bindings to an element's attributes, classes, styles,\n * and events. Defaults to the current component's host element; pass\n * `options.target` to bind to any other element (e.g. a slotted trigger, an\n * internally-referenced child).\n */\nexport const bind: HostBindFn = (config: HostBindConfig, options?: BindOptions): (() => void) => {\n const el = (options?.target as HTMLElement | undefined) ?? getHost();\n const disposers: Array<() => void> = [];\n\n if (config.attr) {\n for (const [key, value] of Object.entries(config.attr)) {\n const name = toHostAttr(key);\n const dispose = applyAttribute(el, name, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.class) {\n disposers.push(applyClassMap(el, config.class));\n }\n\n if (config.style) {\n for (const [key, value] of Object.entries(config.style)) {\n const dispose = applyStyle(el, key, value);\n\n if (dispose) disposers.push(dispose);\n }\n }\n\n if (config.on) {\n const { target: _t, ...listenerOptions } = options ?? {};\n\n for (const event of Object.keys(config.on) as Array<keyof typeof config.on>) {\n const listener = config.on[event];\n\n if (!listener) continue;\n\n disposers.push(listen(el, event as string, listener as EventListener, listenerOptions));\n }\n }\n\n const cleanup = (): void => {\n for (const dispose of disposers) dispose();\n };\n\n tryRegisterCleanup(cleanup);\n\n return cleanup;\n};\n\nconst toHostAttr = normalizeHostAttrKey;\n\nconst applyReactiveBinding = (\n value: HostBindingValue,\n updater: (next: string | number | boolean | null | undefined) => void,\n): (() => void) | void => {\n if (typeof value === 'function') {\n return watchEffect(() => updater(value()));\n }\n\n if (isReactive(value)) {\n return watchEffect(() => updater(value.value));\n }\n\n updater(value);\n};\n\nfunction applyAttribute(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n return applyReactiveBinding(value, (next) => setAttr(host, name, next));\n}\n\nconst UNSAFE_CSS_CHARS = /[;{}]/g;\n\nfunction applyStyle(host: HTMLElement, name: string, value: HostBindingValue): (() => void) | void {\n const cssName = (name.startsWith('--') ? name : toKebab(name)).replace(UNSAFE_CSS_CHARS, '');\n\n if (!cssName) return;\n\n let owned = false;\n const setStyle = (v: string | number | boolean | null | undefined): void => {\n if (v != null && v !== '') {\n owned = true;\n host.style.setProperty(cssName, String(v).replace(UNSAFE_CSS_CHARS, ''));\n } else if (owned) host.style.removeProperty(cssName);\n };\n\n return applyReactiveBinding(value, setStyle);\n}\n\nfunction applyClassMap(\n host: HTMLElement,\n value: (() => Record<string, boolean>) | Record<string, HostClassBindingValue>,\n): () => void {\n const getMap =\n typeof value === 'function'\n ? value\n : (): Record<string, boolean> => {\n const result: Record<string, boolean> = {};\n\n for (const [cls, entry] of Object.entries(value)) {\n result[cls] = typeof entry === 'function' ? entry() : isReactive(entry) ? entry.value : Boolean(entry);\n }\n\n return result;\n };\n\n let prev = new Set<string>();\n\n const sub = watchEffect(() => {\n const next = new Set<string>();\n\n for (const [cls, active] of Object.entries(getMap())) {\n if (!active) continue;\n\n next.add(cls);\n\n if (!prev.has(cls)) host.classList.add(cls);\n }\n for (const cls of prev) {\n if (!next.has(cls)) host.classList.remove(cls);\n }\n prev = next;\n });\n\n return sub;\n}\n","/**\n * Reactive ARIA attribute sync.\n *\n * `aria()` is a thin wrapper over `bind({ attr })` — the two used to carry\n * independent copies of the same \"static | getter | signal → attribute write\"\n * logic, which had already drifted (this file's writes bypassed the\n * `on*`/dangerous-URL-scheme hardening that `setAttr()` gives every other\n * attribute write in the package). `aria()` now exists purely to normalize\n * bare ARIA property names (`expanded` → `aria-expanded`) before delegating —\n * for attributes that are already fully-qualified, `bind({ attr }, { target })`\n * is equivalent.\n */\n\nimport { bind, type HostBindingValue } from './host-bind';\nimport { normalizeAriaKey } from './utils/aria';\n\nexport type AriaConfig = Record<string, HostBindingValue>;\n\n/**\n * Reactively sync ARIA attributes on any element, auto-cleanup on component\n * disconnect. Returns a cleanup function that removes all reactive bindings.\n */\nexport const aria = (target: Element, config: AriaConfig): (() => void) => {\n const attr: Record<string, HostBindingValue> = {};\n\n for (const [key, value] of Object.entries(config)) attr[normalizeAriaKey(key)] = value;\n\n return bind({ attr }, { target });\n};\n","/**\n * Type-safe custom event emission for components.\n */\n\nimport { getHost } from '../runtime';\n\ntype NoDetail = void | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\ntype StrictEmitFn<T extends Record<string, unknown>> = {\n <K extends KeysWithoutDetail<T>>(event: K): boolean;\n <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): boolean;\n};\n\ntype LooseEmitFn = (event: string, detail?: unknown) => boolean;\n\nexport type EmitFn<T extends Record<string, unknown>> = StrictEmitFn<T> & LooseEmitFn;\n\nconst DEFAULT_FIRE_OPTIONS = { bubbles: true, cancelable: true, composed: false };\n\n/**\n * Returns a typed `emit()` function bound to the current component's host element.\n * Call once during `setup()` — the `Emits` type parameter maps event names to\n * their `detail` payload type.\n *\n * Every event is dispatched `cancelable: true`, and `emit()` returns `dispatchEvent`'s\n * own boolean result — `false` when a listener called `preventDefault()`. Components\n * that need to know whether a listener cancelled an event (e.g. to skip a default\n * action) read this return value directly instead of hand-rolling `dispatchEvent`.\n *\n * @example\n * ```ts\n * type Events = { close: undefined; change: { value: string } };\n *\n * setup(props) {\n * const emit = useEmit<Events>();\n * emit('close');\n *\n * const notCancelled = emit('change', { value: 'ok' });\n * if (notCancelled) props.value.value = 'ok';\n * }\n * ```\n */\nexport const useEmit = <T extends Record<string, unknown> = Record<string, never>>(): EmitFn<T> => {\n const host = getHost();\n\n return ((event: keyof T, ...rest: unknown[]) => {\n const customEventInit = rest.length > 0 ? { ...DEFAULT_FIRE_OPTIONS, detail: rest[0] } : DEFAULT_FIRE_OPTIONS;\n\n return host.dispatchEvent(new CustomEvent<unknown>(String(event), customEventInit));\n }) as EmitFn<T>;\n};\n","/**\n * template/bindings.ts — Runtime binding appliers.\n *\n * Responsibilities:\n * - Apply each Binding variant to the live DOM (text, attr, event, html, ref,\n * directive, spread).\n * - Manage reactive effects and cleanup registration.\n * - Expose `applyBinding()` as the single dispatch entry point.\n */\n\nimport { computed, effect as rawEffect, isReactive, type Readable, untrack } from '@vielzeug/ripple';\n\nimport { isLiveSignal } from '../directives/live';\nimport { invariant } from '../errors';\nimport { getPropMeta } from '../props';\nimport {\n type AttrBinding,\n type AttrPropMeta,\n type Binding,\n type DirectiveBinding,\n type EventBinding,\n type HtmlBinding,\n type HtmlBindingValue,\n isHtmlResult,\n type RefBinding,\n type SpreadBinding,\n type TextBinding,\n} from '../types/bindings';\nimport { isStructuredValue, listen, removeNodes, runAll, setAttr } from '../utils/dom';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type RegisterCleanup = (fn: () => void) => void;\n\n// ─── Signal helpers ───────────────────────────────────────────────────────────\n\nconst signalEffect = (\n signal: Readable<unknown>,\n update: (v: unknown) => void,\n registerCleanup: RegisterCleanup,\n): void => {\n const sub = rawEffect(() => update(signal.value));\n\n registerCleanup(() => sub.dispose());\n};\n\n/**\n * Read a signal safely during scope teardown. Disposed signals and computeds\n * return their last known value (or undefined) without throwing — no try/catch needed.\n */\nconst readSignalSafe = <T>(sig: Readable<T>): T | undefined => sig.value;\n\n// ─── Text ─────────────────────────────────────────────────────────────────────\n\nconst applyTextBinding = (binding: TextBinding, registerCleanup: RegisterCleanup): void => {\n signalEffect(\n binding.signal,\n (v) => {\n binding.node.textContent = String(v ?? '');\n },\n registerCleanup,\n );\n};\n\n// ─── Attributes ───────────────────────────────────────────────────────────────\n\nconst isNativeFormInput = (el: HTMLElement): el is HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement =>\n el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement;\n\ntype LiveWriteState = { last: unknown };\n\nconst applyFormValue = (\n el: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement,\n value: unknown,\n isLive: boolean | undefined,\n state: LiveWriteState,\n): void => {\n const next = value == null ? '' : String(value);\n\n if (isLive && state.last !== undefined && !Object.is(el.value, state.last) && !Object.is(el.value, next)) return;\n\n el.value = next;\n\n if (isLive) state.last = next;\n};\n\nconst applyCheckedValue = (\n el: HTMLInputElement,\n value: unknown,\n isLive: boolean | undefined,\n state: LiveWriteState,\n): void => {\n const next = Boolean(value);\n\n if (isLive && state.last !== undefined && el.checked !== Boolean(state.last) && el.checked !== next) return;\n\n el.checked = next;\n\n if (isLive) state.last = next;\n};\n\nconst syncRegisteredProp = (el: HTMLElement, meta: AttrPropMeta, binding: AttrBinding, value: unknown): void => {\n const parsed = isStructuredValue(value)\n ? value\n : meta.parse(\n binding.mode === 'bool' ? (value ? '' : null) : value == null || value === false ? null : String(value),\n );\n\n if (\n !Object.is(\n untrack(() => meta.signal.value),\n parsed,\n )\n ) {\n meta.signal.value = parsed as never;\n }\n\n if (!meta.reflect) {\n if (isStructuredValue(value)) return;\n\n if (binding.mode === 'bool') el.toggleAttribute(binding.name, Boolean(value));\n else setAttr(el, binding.name, value);\n }\n};\n\nexport const applyAttrBinding = (binding: AttrBinding, registerCleanup: RegisterCleanup): void => {\n const { el, mode, name, propMeta } = binding;\n const liveState: LiveWriteState = { last: undefined };\n\n const update = (value: unknown): void => {\n if (propMeta) {\n syncRegisteredProp(el, propMeta, binding, value);\n\n return;\n }\n\n if (!isReactive(value) && isStructuredValue(value)) {\n if (name !== '__proto__' && name !== 'constructor' && name !== 'prototype') {\n (el as unknown as Record<string, unknown>)[name] = value;\n }\n\n return;\n }\n\n if (name === 'value' && isNativeFormInput(el)) {\n applyFormValue(el, value, binding.live, liveState);\n\n return;\n }\n\n if (name === 'checked' && el instanceof HTMLInputElement) {\n applyCheckedValue(el, value, binding.live, liveState);\n\n return;\n }\n\n if (mode === 'bool') el.toggleAttribute(name, Boolean(value));\n else setAttr(el, name, value);\n };\n\n if ('signal' in binding) {\n signalEffect(binding.signal, update, registerCleanup);\n } else {\n update(binding.value);\n }\n};\n\n// ─── Events ───────────────────────────────────────────────────────────────────\n\nconst applyEventBinding = (binding: EventBinding, registerCleanup: RegisterCleanup): void => {\n registerCleanup(listen(binding.el, binding.name, binding.handler, binding.options));\n};\n\n// ─── Refs ─────────────────────────────────────────────────────────────────────\n\nconst applyRefBinding = (binding: RefBinding, registerCleanup: RegisterCleanup): void => {\n const { el, ref } = binding;\n\n if (typeof ref === 'function') {\n ref(el as never);\n registerCleanup(() => ref(null as never));\n\n return;\n }\n\n ref.value = el as never;\n registerCleanup(() => {\n ref.value = null as never;\n });\n};\n\n// ─── HTML (reactive) ─────────────────────────────────────────────────────────\n\nconst insertHtmlValues = (\n values: HtmlBindingValue[],\n insertBefore: ChildNode,\n registerCleanup: RegisterCleanup,\n): Node[] => {\n const nodes: Node[] = [];\n const parent = insertBefore.parentNode;\n\n invariant(parent, 'html binding anchor has no parent node');\n\n for (const v of values) {\n if (isHtmlResult(v)) {\n const captured = Array.from(v.fragment.childNodes);\n\n parent.insertBefore(v.fragment, insertBefore);\n v.apply(registerCleanup);\n nodes.push(...captured);\n } else if (v != null && v !== false) {\n const text = document.createTextNode(String(v));\n\n parent.insertBefore(text, insertBefore);\n nodes.push(text);\n }\n }\n\n return nodes;\n};\n\nexport const applyHtmlBinding = (binding: HtmlBinding, registerCleanup: RegisterCleanup): void => {\n const { anchor, signal } = binding;\n\n let currentCleanups: (() => void)[] = [];\n const clearCurrent = (): void => {\n runAll(currentCleanups);\n currentCleanups = [];\n };\n let currentNodes: Node[] = [];\n\n const stop = rawEffect(() => {\n const raw = readSignalSafe(signal);\n\n clearCurrent();\n removeNodes(currentNodes);\n currentNodes = [];\n\n if (raw == null || raw.length === 0) return;\n\n untrack(() => {\n currentNodes = insertHtmlValues(raw, anchor, (fn) => currentCleanups.push(fn));\n });\n });\n\n registerCleanup(() => {\n stop.dispose();\n clearCurrent();\n removeNodes(currentNodes);\n });\n};\n\n// ─── Directives ───────────────────────────────────────────────────────────────\n\nconst applyDirectiveBinding = (binding: DirectiveBinding, registerCleanup: RegisterCleanup): void => {\n binding.directive.mount(binding.anchor, registerCleanup);\n};\n\n// ─── Spread ───────────────────────────────────────────────────────────────────\n\nconst applySpreadBinding = (binding: SpreadBinding, registerCleanup: RegisterCleanup): void => {\n binding.spread.apply(binding.el, registerCleanup);\n};\n\n// ─── Binding dispatch ─────────────────────────────────────────────────────────\n\nexport const applyBinding = (binding: Binding, registerCleanup: RegisterCleanup): void => {\n switch (binding.type) {\n case 'attr':\n applyAttrBinding(binding, registerCleanup);\n break;\n case 'directive':\n applyDirectiveBinding(binding, registerCleanup);\n break;\n case 'event':\n applyEventBinding(binding, registerCleanup);\n break;\n case 'html':\n applyHtmlBinding(binding, registerCleanup);\n break;\n case 'ref':\n applyRefBinding(binding, registerCleanup);\n break;\n case 'spread':\n applySpreadBinding(binding, registerCleanup);\n break;\n case 'text':\n applyTextBinding(binding, registerCleanup);\n break;\n }\n};\n\n// ─── Attr binding factory (used by instantiator) ──────────────────────────────\n\nexport const createAttrBindingFromValue = (\n el: HTMLElement,\n mode: 'attr' | 'bool',\n name: string,\n value: unknown,\n): AttrBinding => {\n const propMeta = getPropMeta(el, name) as AttrPropMeta | undefined;\n\n if (isLiveSignal(value)) {\n return { el, live: true, mode, name, propMeta, signal: value as Readable<unknown>, type: 'attr' };\n }\n\n if (typeof value === 'function') {\n return { el, mode, name, propMeta, signal: computed(value as () => unknown), type: 'attr' };\n }\n\n if (isReactive(value)) {\n return { el, mode, name, propMeta, signal: value as Readable<unknown>, type: 'attr' };\n }\n\n return { el, mode, name, propMeta, type: 'attr', value };\n};\n\nexport const resolveStaticText = (value: unknown): string => {\n if (value == null) return '';\n\n return String(value);\n};\n","type EventHandler = (e: Event) => void;\n\nconst behaviorModifiers: Record<string, (h: EventHandler) => EventHandler> = {\n prevent: (h) => (e) => {\n e.preventDefault();\n h(e);\n },\n self: (h) => (e) => {\n if (e.target === e.currentTarget) h(e);\n },\n stop: (h) => (e) => {\n e.stopPropagation();\n h(e);\n },\n};\n\n/**\n * Apply event listener modifiers (prevent, stop, self, capture, once, passive).\n * Behavior modifiers wrap the handler; listener options are extracted separately.\n */\nexport const applyModifiers = (\n handler: EventHandler,\n modifiers: string[],\n): { handler: EventHandler; options?: AddEventListenerOptions } => {\n let wrappedHandler = handler;\n\n for (const modifier of modifiers) {\n const wrap = behaviorModifiers[modifier];\n\n if (wrap) wrappedHandler = wrap(wrappedHandler);\n }\n\n const options: AddEventListenerOptions = {};\n\n if (modifiers.includes('capture')) options.capture = true;\n\n if (modifiers.includes('once')) options.once = true;\n\n if (modifiers.includes('passive')) options.passive = true;\n\n return { handler: wrappedHandler, ...(Object.keys(options).length ? { options } : {}) };\n};\n","/**\n * template/compiler.ts — HTML template string parser and static template cache.\n *\n * Responsibilities:\n * - Parse TemplateStringsArray into slot metadata (slot detection).\n * - Build a cached HTMLTemplateElement with path indices for efficient node lookup.\n * - Expose `getStaticTemplate()` for use by the instantiator.\n */\n\nimport { OreApiError, ORE_ERRORS } from '../errors';\n\n// ─── Slot kinds ───────────────────────────────────────────────────────────────\n// Const object + derived union, same pattern as `ComponentPhase`/`LIFECYCLE_EVENTS`\n// in types.ts — used here (rather than plain string literals) because the kind\n// crosses a module boundary (compiler.ts produces it, instantiator.ts consumes\n// it): importing `SlotKind` gives autocomplete and a single rename point at the\n// consuming site, where a bare string literal wouldn't.\n\nexport const SlotKind = {\n ATTR: 'attr',\n BOOL_ATTR: 'boolAttr',\n CLOSE_TAG: 'closeTag',\n EVENT: 'event',\n NODE: 'node',\n REF: 'ref',\n SPREAD: 'spread',\n TAG_NAME: 'tagname',\n} as const;\n\nexport type DetectedSlotKind = (typeof SlotKind)[keyof typeof SlotKind];\n\ntype DetectedSlot = {\n kind: DetectedSlotKind;\n modifiers?: string[];\n name?: string;\n prefix: string;\n};\n\n// ─── Static template types ────────────────────────────────────────────────────\n\nexport type NodePath = readonly number[];\n\nexport type SlotMeta = {\n commentId?: number;\n elementId?: number;\n kind: DetectedSlotKind;\n mode?: 'attr' | 'bool';\n modifiers?: string[];\n name?: string;\n};\n\nexport type CompiledStaticTemplate = {\n commentPaths: ReadonlyMap<number, NodePath>;\n element: HTMLTemplateElement;\n elementPaths: ReadonlyMap<number, NodePath>;\n slots: SlotMeta[];\n};\n\n// ─── Slot detection regexes ───────────────────────────────────────────────────\n\nconst EVENT_RE = /\\s+@([a-zA-Z_][-a-zA-Z0-9_.-]*)\\s*=\\s*[\"']?$/;\nconst REF_RE = /\\s+ref\\s*=\\s*[\"']?$/;\nconst BOOL_ATTR_RE = /\\s+\\?([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/;\nconst ATTR_RE = /\\s+:?([a-zA-Z_][-a-zA-Z0-9_]*)\\s*=\\s*[\"']?$/;\n\nconst isInsideStartTag = (str: string): boolean => {\n const lastOpen = str.lastIndexOf('<');\n const lastClose = str.lastIndexOf('>');\n\n if (lastOpen <= lastClose) return false;\n\n // Must not be a closing tag (</...)\n return str[lastOpen + 1] !== '/';\n};\n\nconst detectSlot = (str: string): DetectedSlot => {\n let m: RegExpExecArray | null;\n const trimmed = str.trimEnd();\n\n // Dynamic closing tag: interpolation is the closing tag name, e.g. strings[i] = \"</\"\n if (trimmed.endsWith('</')) {\n return { kind: SlotKind.CLOSE_TAG, prefix: str };\n }\n\n // Dynamic opening tag name: interpolation is the tag name itself, e.g. strings[i] = \"<\"\n if (trimmed.endsWith('<')) {\n return { kind: SlotKind.TAG_NAME, prefix: str };\n }\n\n if ((m = EVENT_RE.exec(str))) {\n const prefix = str.slice(0, -m[0].length);\n const parts = m[1].split('.');\n\n return { kind: SlotKind.EVENT, modifiers: parts.slice(1), name: parts[0], prefix };\n }\n\n if ((m = REF_RE.exec(str))) {\n return { kind: SlotKind.REF, prefix: str.slice(0, -m[0].length) };\n }\n\n if ((m = BOOL_ATTR_RE.exec(str))) {\n return { kind: SlotKind.BOOL_ATTR, name: m[1], prefix: str.slice(0, -m[0].length) };\n }\n\n if ((m = ATTR_RE.exec(str))) {\n return { kind: SlotKind.ATTR, name: m[1], prefix: str.slice(0, -m[0].length) };\n }\n\n if (isInsideStartTag(str)) {\n return { kind: SlotKind.SPREAD, prefix: str.trimEnd() };\n }\n\n return { kind: SlotKind.NODE, prefix: str };\n};\n\n// ─── Static template cache ────────────────────────────────────────────────────\n\nconst templateCache = new WeakMap<TemplateStringsArray, CompiledStaticTemplate>();\n\n/**\n * Pre-process template strings to strip surrounding attribute quotes and the\n * closing `>` that follows a dynamic tag-name slot. This lets the main loop\n * operate on clean strings with no per-iteration state flags.\n */\nconst normalizeTemplateStrings = (strings: TemplateStringsArray): string[] => {\n const out = Array.from(strings);\n\n for (let i = 0; i < out.length - 1; i++) {\n const s = out[i];\n const lastChar = s[s.length - 1];\n\n // Strip wrapping attribute quotes: attr=\"${value}\" → attr=${value}\n if (lastChar === '\"' || lastChar === \"'\") {\n out[i] = s.slice(0, -1);\n\n const next = out[i + 1];\n\n if (next.startsWith(lastChar)) out[i + 1] = next.slice(1);\n }\n\n // Strip leading `>` from the string that follows a dynamic closing tag:\n // </${tagName}> — the `>` is the first character of strings[i+1]\n const cur = out[i];\n\n if (cur.trimEnd().endsWith('</')) {\n const next = out[i + 1];\n\n if (next.startsWith('>')) out[i + 1] = next.slice(1);\n }\n }\n\n return out;\n};\n\nconst walkNode = (\n node: Node,\n path: number[],\n elementPaths: Map<number, NodePath>,\n commentPaths: Map<number, NodePath>,\n): void => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as Element;\n const marker = el.getAttribute('u');\n\n if (marker !== null) {\n elementPaths.set(Number(marker), [...path]);\n el.removeAttribute('u');\n }\n } else if (node.nodeType === Node.COMMENT_NODE) {\n const content = (node as Comment).nodeValue;\n\n if (content !== null && /^\\d+$/.test(content)) {\n commentPaths.set(Number(content), [...path]);\n }\n }\n\n const children = node.childNodes;\n\n for (let i = 0; i < children.length; i++) walkNode(children[i], [...path, i], elementPaths, commentPaths);\n};\n\nconst buildStaticTemplate = (strings: TemplateStringsArray): CompiledStaticTemplate => {\n const normalized = normalizeTemplateStrings(strings);\n let html = '';\n let activeElementId: number | undefined;\n let elementCounter = 0;\n let commentCounter = 0;\n const slots: SlotMeta[] = [];\n const tagNameStack: number[] = [];\n\n for (let i = 0; i < normalized.length - 1; i++) {\n const raw = normalized[i];\n const slot = detectSlot(raw);\n\n if (slot.kind === SlotKind.TAG_NAME) {\n // Dynamic opening tag name: emit a placeholder custom element\n const id = elementCounter++;\n\n activeElementId = id;\n tagNameStack.push(id);\n\n // Remove trailing '<' from prefix and open placeholder element\n const prefixWithoutAngle = raw.replace(/<\\s*$/, '');\n\n html += prefixWithoutAngle + `<ore-dyn-${id} u=\"${id}\"`;\n slots.push({ elementId: id, kind: SlotKind.TAG_NAME });\n } else if (slot.kind === SlotKind.CLOSE_TAG) {\n // Dynamic closing tag: close the matching placeholder element. An empty\n // stack means this closing interpolation has no matching dynamic opener\n // (malformed template) — fail fast instead of silently closing the\n // wrong (or a nonexistent) placeholder element.\n if (tagNameStack.length === 0) {\n throw new OreApiError(ORE_ERRORS.mismatchedDynamicCloseTag);\n }\n\n const id = tagNameStack.pop()!;\n const prefixWithoutClose = raw.replace(/<\\/\\s*$/, '');\n\n html += prefixWithoutClose + `</ore-dyn-${id}>`;\n slots.push({ kind: SlotKind.CLOSE_TAG });\n activeElementId = undefined;\n } else if (slot.kind === SlotKind.NODE) {\n html += slot.prefix + `<!--${commentCounter}-->`;\n slots.push({ commentId: commentCounter, kind: SlotKind.NODE });\n commentCounter++;\n activeElementId = undefined;\n } else {\n const needsNewMarker =\n activeElementId === undefined || slot.prefix.lastIndexOf('<') > slot.prefix.lastIndexOf('>');\n\n if (needsNewMarker) {\n activeElementId = elementCounter++;\n html += `${slot.prefix} u=\"${activeElementId}\"`;\n } else {\n html += slot.prefix;\n }\n\n const mode: 'attr' | 'bool' | undefined =\n slot.kind === SlotKind.BOOL_ATTR ? 'bool' : slot.kind === SlotKind.ATTR ? 'attr' : undefined;\n\n slots.push({ elementId: activeElementId, kind: slot.kind, mode, modifiers: slot.modifiers, name: slot.name });\n }\n }\n\n html += normalized[normalized.length - 1] ?? '';\n\n const tpl = document.createElement('template');\n\n tpl.innerHTML = html;\n\n const elementPaths = new Map<number, NodePath>();\n const commentPaths = new Map<number, NodePath>();\n const topChildren = tpl.content.childNodes;\n\n for (let i = 0; i < topChildren.length; i++) walkNode(topChildren[i], [i], elementPaths, commentPaths);\n\n return { commentPaths, element: tpl, elementPaths, slots };\n};\n\nexport const getStaticTemplate = (strings: TemplateStringsArray): CompiledStaticTemplate => {\n let tpl = templateCache.get(strings);\n\n if (!tpl) {\n tpl = buildStaticTemplate(strings);\n templateCache.set(strings, tpl);\n }\n\n return tpl;\n};\n\n// ─── Path navigation (used by instantiator) ───────────────────────────────────\n\nexport const followPath = (root: Node, path: NodePath): Node => {\n let node: Node = root;\n\n for (const i of path) node = node.childNodes[i];\n\n return node;\n};\n","/**\n * template/instantiator.ts — Template instantiation and the `html` tagged literal.\n *\n * Responsibilities:\n * - Clone a compiled static template and wire up live bindings.\n * - Expose `compileTemplate()` and `html` as the public authoring API.\n */\n\nimport { computed, isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { invariant, ORE_ERRORS, OreApiError } from '../errors';\nimport {\n type Binding,\n createHtmlResult,\n type HtmlBindingValue,\n type HTMLResult,\n isDirectiveResult,\n isHtmlResult,\n isSpreadObject,\n type Ref,\n type RefCallback,\n} from '../types/bindings';\nimport { applyModifiers } from '../utils/event-modifiers';\nimport { applyBinding, createAttrBindingFromValue, resolveStaticText } from './bindings';\nimport { followPath, getStaticTemplate, SlotKind } from './compiler';\n\n// ─── Template instantiation ──────────────────────────────────────────────────\n\n/**\n * Instantiate a compiled template: clone the cached DOM template, navigate\n * to each binding target using pre-recorded paths, and build bindings with\n * direct node references. Returns an HTMLResult whose fragment is ready to insert.\n */\nconst NODE_SLOT_NO_PARENT_MSG = 'html`...`: node-slot comment anchor has no parent node';\n\nexport const compileTemplate = (strings: TemplateStringsArray, values: unknown[]): HTMLResult => {\n const compiled = getStaticTemplate(strings);\n const fragment = compiled.element.content.cloneNode(true) as DocumentFragment;\n const bindings: Binding[] = [];\n // For static HTMLResult embeds: chain their apply calls\n const chainedApplies: Array<(rc: (fn: () => void) => void) => void> = [];\n\n // Phase 1: Resolve all binding targets BEFORE any DOM modifications\n type BoundSlot = { comment?: Comment; el?: HTMLElement; slot: (typeof compiled.slots)[number]; value: unknown };\n\n const boundSlots: BoundSlot[] = compiled.slots.map((slot, i) => {\n const value = values[i];\n\n if (slot.kind === SlotKind.CLOSE_TAG) {\n return { slot, value };\n }\n\n if (slot.kind === SlotKind.NODE) {\n const commentPath = compiled.commentPaths.get(slot.commentId!);\n\n invariant(commentPath, `compiled template is missing a comment path for node slot ${slot.commentId}`);\n\n return { comment: followPath(fragment, commentPath) as Comment, slot, value };\n }\n\n const elementPath = compiled.elementPaths.get(slot.elementId!);\n\n invariant(elementPath, `compiled template is missing an element path for slot ${slot.elementId}`);\n\n return { el: followPath(fragment, elementPath) as HTMLElement, slot, value };\n });\n\n // Phase 2a: Process tagname slots first — replace placeholders with real elements\n const tagReplacements = new Map<HTMLElement, HTMLElement>();\n\n for (const { el, slot, value } of boundSlots) {\n if (slot.kind !== SlotKind.TAG_NAME) continue;\n\n const tagName = String(value);\n\n // Same \"fail immediately, every build\" treatment as each()'s duplicate-key\n // guard: a malformed dynamic tag name is a programming bug in the template,\n // not a runtime race — degrading to a silently-broken partial render would\n // hide it instead of surfacing it at the call site.\n if (!/^[a-z][a-z0-9._-]*$/i.test(tagName)) {\n throw new OreApiError(ORE_ERRORS.invalidDynamicTagName(tagName));\n }\n\n const realEl = document.createElement(tagName);\n\n for (const attr of Array.from(el!.attributes)) realEl.setAttribute(attr.name, attr.value);\n\n while (el!.firstChild) realEl.appendChild(el!.firstChild);\n\n el!.replaceWith(realEl);\n tagReplacements.set(el!, realEl);\n }\n\n // Phase 2b: Build bindings (may modify DOM for static content)\n for (const { comment, el: rawEl, slot, value } of boundSlots) {\n if (slot.kind === SlotKind.TAG_NAME || slot.kind === SlotKind.CLOSE_TAG) continue;\n\n // Resolve element through tagname replacements\n const el = rawEl ? (tagReplacements.get(rawEl) ?? rawEl) : rawEl;\n\n if (slot.kind === SlotKind.NODE) {\n const anchor = comment!;\n\n if (isDirectiveResult(value)) {\n bindings.push({ anchor, directive: value, type: 'directive' });\n continue;\n }\n\n if (isHtmlResult(value)) {\n // Static embed: move fragment children into place, chain apply\n const parent = anchor.parentNode;\n\n invariant(parent, NODE_SLOT_NO_PARENT_MSG);\n\n while (value.fragment.firstChild) parent.insertBefore(value.fragment.firstChild, anchor);\n\n anchor.remove();\n chainedApplies.push(value.apply.bind(value));\n continue;\n }\n\n if (typeof value === 'function') {\n const sig = computed(() => {\n const res = (value as () => unknown)();\n\n return Array.isArray(res) ? (res as HtmlBindingValue[]) : [res as HtmlBindingValue];\n });\n\n bindings.push({ anchor, signal: sig, type: 'html' });\n continue;\n }\n\n if (isReactive(value)) {\n // Always use the html binding for signals — it handles both text values and\n // HTMLResult values, preventing silent \"[object Object]\" corruption when a\n // signal's runtime type changes from null/string to HTMLResult.\n const sig = computed(() => {\n const raw = (value as Readable<HtmlBindingValue | HtmlBindingValue[]>).value;\n\n return Array.isArray(raw) ? (raw as HtmlBindingValue[]) : [raw as HtmlBindingValue];\n });\n\n bindings.push({ anchor, signal: sig, type: 'html' });\n continue;\n }\n\n if (Array.isArray(value)) {\n const parent = anchor.parentNode;\n\n invariant(parent, NODE_SLOT_NO_PARENT_MSG);\n\n for (const item of value) {\n if (isHtmlResult(item)) {\n while (item.fragment.firstChild) parent.insertBefore(item.fragment.firstChild, anchor);\n\n chainedApplies.push(item.apply.bind(item));\n } else {\n parent.insertBefore(document.createTextNode(resolveStaticText(item)), anchor);\n }\n }\n anchor.remove();\n continue;\n }\n\n // Static primitive: replace with text node, no binding\n anchor.replaceWith(document.createTextNode(resolveStaticText(value)));\n continue;\n }\n\n // Element slot\n const target = el!;\n\n if (slot.kind === SlotKind.EVENT) {\n if (typeof value === 'function') {\n const { handler, options } = applyModifiers(value as (e: Event) => void, slot.modifiers ?? []);\n\n bindings.push({ el: target, handler, name: slot.name!, options, type: 'event' });\n } else if (isReactive(value)) {\n const signalValue = value as Readable<unknown>;\n const handler = (e: Event) => {\n const h = signalValue.value;\n\n if (typeof h === 'function') (h as (e: Event) => void)(e);\n };\n const { handler: wrapped, options } = applyModifiers(handler, slot.modifiers ?? []);\n\n bindings.push({ el: target, handler: wrapped, name: slot.name!, options, type: 'event' });\n }\n\n continue;\n }\n\n if (slot.kind === SlotKind.REF) {\n if (value) {\n bindings.push({ el: target, ref: value as Ref<Element> | RefCallback<Element>, type: 'ref' });\n }\n\n continue;\n }\n\n if (slot.kind === SlotKind.SPREAD) {\n if (isSpreadObject(value)) {\n bindings.push({ el: target, spread: value, type: 'spread' });\n }\n\n continue;\n }\n\n // attr / boolAttr\n bindings.push(createAttrBindingFromValue(target, slot.mode ?? 'attr', slot.name!, value));\n }\n\n return createHtmlResult(fragment, (registerCleanup) => {\n for (const binding of bindings) applyBinding(binding, registerCleanup);\n for (const chainedApply of chainedApplies) chainedApply(registerCleanup);\n });\n};\n\nexport const html = (strings: TemplateStringsArray, ...values: unknown[]): HTMLResult =>\n compileTemplate(strings, values);\n","/**\n * Unique ID generation for runtime use (component IDs, label associations, etc.).\n * Template binding no longer uses this for marker IDs — binding targets are resolved\n * via path navigation on cloned template nodes.\n */\n\nlet _idCounter = 0;\nlet _stableCounter = 0;\nconst _tag = Math.random().toString(36).slice(2, 6);\n\n/** @internal Resets both ID counters. Called by testing cleanup(). */\nexport const _resetIdCounter = (): void => {\n _idCounter = 0;\n _stableCounter = 0;\n};\n\nexport const createId = (prefix = 'id'): string => `${prefix}-${++_idCounter}`;\n\n/**\n * Generates a stable, unique ID with an optional semantic prefix.\n * Includes a short random tag to prevent collisions across multiple app instances.\n * Format: `${prefix}-${tag}${counter}` — e.g. `field-a3k21`.\n */\nexport const createStableId = (prefix = 'id'): string => `${prefix}-${_tag}${++_stableCounter}`;\n\n/**\n * Resets the stable ID counter to 0. Use in test `beforeEach` hooks when you need\n * deterministic IDs across test runs.\n */\nexport const resetIdCounter = (): void => {\n _stableCounter = 0;\n};\n","import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\n/**\n * Observes an element's intersection with the viewport (or a given root) via\n * `IntersectionObserver`. Returns a `Reactive` that updates whenever the\n * intersection ratio changes.\n * Must be called inside a `mount()` callback.\n */\nexport const intersectionObserver = (\n el: Element,\n options?: IntersectionObserverInit,\n): Readable<IntersectionObserverEntry | null> => {\n const entry = signal<IntersectionObserverEntry | null>(null);\n const io = new IntersectionObserver(([nextEntry]) => {\n if (nextEntry) entry.value = nextEntry;\n }, options);\n\n io.observe(el);\n onCleanup(() => io.disconnect());\n\n return entry;\n};\n","import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\n/**\n * Observes a CSS media query via `window.matchMedia`. Returns a `Reactive`\n * that is `true` when the query matches and `false` when it does not.\n * Must be called inside a `mount()` callback.\n */\nexport const mediaObserver = (query: string): Readable<boolean> => {\n const mql = window.matchMedia(query);\n const matches = signal(mql.matches);\n const handler = (e: MediaQueryListEvent) => {\n matches.value = e.matches;\n };\n\n mql.addEventListener('change', handler);\n onCleanup(() => mql.removeEventListener('change', handler));\n\n return matches;\n};\n","import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\nexport type MutationObserverValue = {\n entries: MutationRecord[];\n latest: MutationRecord | null;\n};\n\n/**\n * Observes DOM mutations on an element and exposes the latest mutation batch.\n */\nexport const mutationObserver = (\n el: Element,\n options: MutationObserverInit = {\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true,\n },\n): Readable<MutationObserverValue> => {\n const value = signal<MutationObserverValue>({ entries: [], latest: null });\n const observer = new MutationObserver((entries) => {\n value.value = {\n entries,\n latest: entries.length > 0 ? entries[entries.length - 1] : null,\n };\n });\n\n observer.observe(el, options);\n onCleanup(() => observer.disconnect());\n\n return value;\n};\n","import { type Readable, signal, onCleanup } from '@vielzeug/ripple';\n\n/**\n * Observes an element's content-box size via `ResizeObserver`.\n * Returns a `Reactive` that updates whenever the dimensions change.\n * Must be called inside a `mount()` callback.\n */\nexport const resizeObserver = (el: Element): Readable<{ height: number; width: number }> => {\n const size = signal({ height: 0, width: 0 });\n const ro = new ResizeObserver(([entry]) => {\n if (!entry) return;\n\n const box = entry.contentBoxSize[0];\n\n if (box) size.value = { height: box.blockSize, width: box.inlineSize };\n });\n\n ro.observe(el);\n onCleanup(() => ro.disconnect());\n\n return size;\n};\n"],"mappings":"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"}