Single File Component (.aihu) runtime — registers custom elements compiled by @aihu/compiler.
_ensureA11yStylesfunction _ensureA11yStyles(): void_hmrReplacefunction _hmrReplace(element: HTMLElement, newSetup: Setup): void_inSsrLifecyclefunction _inSsrLifecycle(): booleanIs a server render currently running setup on this thread?
_registerAgentDispatcherfunction _registerAgentDispatcher( element: Element | null | undefined, dispatcher: InstanceAgentDispatcher, ): voidRegister a mounted instance's agent dispatcher.
_registerAgentServerBindingfunction _registerAgentServerBinding( element: Element | null | undefined, binding: InstanceAgentServerBinding, ): voidRegister a mounted instance's FULL server agent binding.
_setHydratefunction _setHydrate(fn: HydrateFn | null): void_setMountfunction _setMount(fn: MountFn): void_setSignalfunction _setSignal(s: typeof SignalFactory): void_takeAgentDispatcherfunction _takeAgentDispatcher( element: Element | null | undefined, ): InstanceAgentDispatcher | undefinedLook up the instance dispatcher registered for `element` (the mounted host custom element).
_takeAgentServerBindingfunction _takeAgentServerBinding( element: Element | null | undefined, ): InstanceAgentServerBinding | undefinedTake (read) the server binding registered for `element`.
_withOwnerContextfunction _withOwnerContext<R>(node: object, fn: () => R): R_withSsrLifecyclefunction _withSsrLifecycle<R>(fn: () => R): RRun `fn` inside a server-render lifecycle window.
announcefunction announce(message: string): voidProgrammatic ARIA announcement.
createFocusTrapfunction createFocusTrap( active: boolean | (() => boolean), returnFocus: boolean, initialFocus: string | null, childFn: () => Branch, ): BranchFocus-trap boundary.
createResourcefunction createResource<T>(factory: () => Promise<T>): ResourceHandle<T>Create a reactive resource backed by an async `factory`.
createStreamfunction createStream(factory: () => Promise<ReadableStream<string> | null>): StreamHandleCreate a reactive stream handle backed by a `ReadableStream<string>` factory.
defineComponentfunction defineComponent(setupOrOptions: Setup | ComponentOptions): typeof HTMLElementdefineElementfunction defineElement( name: string, Ctor: typeof HTMLElement, options?: DefineOptions, ): voidonAdoptfunction _onAdopt(fn: () => void): voidonAttributeChangefunction _onAttributeChange( fn: (name: string, oldValue: string | null, newValue: string | null) => void, ): voidonCleanupfunction _onCleanup(fn: () => void): voidonCommitfunction _onCommit(fn: () => void | (() => void)): voidRun `fn` after the browser's next layout opportunity, before paint.
onMountfunction _onMount(fn: () => void | (() => void)): void__aihu_cpathconst __aihu_cpath = (p: string): string => …Comment-safe path for structural markers — the walker's `_commentPath` (`-` → `_` so arbitrary list keys can't terminate the comment early).
__aihu_eattrconst __aihu_eattr = (v: unknown): string => …Attribute-value escape (`&` and `"`), the walker's `escapeAttr`.
__aihu_keyconst __aihu_key = (v: unknown): string => …List-item key normalization — the walker's `String(key).replace(/\./g, '_')` (dots would splice into the path grammar; see `_structuralSubtrees` in
__aihu_sattrconst __aihu_sattr = (k: string, v: unknown): string => …One serialized attribute (` k="v"` / ` k` / nothing), mirroring the walker's `serializeAttrs` value rules for a RESOLVED value: functions (event handlers) never serialize, `true` renders the bare attribute, `false`/`undefined` render nothing, everything else stringifies escaped.
__aihu_schildconst __aihu_schild = (tag: string, attrsHtml: string, opts?: SsrChildRenderOpts): string => …Render a referenced child component, or emit the empty element unchanged.
__aihu_stextconst __aihu_stext = (v: unknown): string => …Escaped text hole for a REACTIVE leaf — the walker reads `String(get())`, so `null`/`undefined` stringify ("null"/"undefined"), exactly like a client-side reactive text binding would render them.
__aihu_stext0const __aihu_stext0 = (v: unknown): string => …Escaped text hole for an EAGER leaf — the walker's `leafText` renders nullish static values as the empty string.
_hydrateOnVisibleconst _hydrateOnVisible = (element: HTMLElement, hydrate: () => void): void => …_isSerializableAttrNameconst _isSerializableAttrName = (k: string): boolean => …Is `k` safe to serialize as an attribute name?
_MAX_CHILD_BYTESconst _MAX_CHILD_BYTESTotal child markup allowed per top-level render.
_MAX_CHILD_DEPTHconst _MAX_CHILD_DEPTHBelt-and-braces bound on nesting.
_ssrChildWrapconst _ssrChildWrap = (tag: string, attrsHtml: string, mod: SsrChildModule, inner: string, hydratable: boolean): string => …Wrap a child's rendered INNER markup in its host element.
SHADOW_ROOT_MODEconst SHADOW_ROOT_MODEThe DOM `ShadowRootMode` aihu attaches with — the SINGLE SOURCE for that value across the whole framework.
ComponentOptionsinterface ComponentOptions<A extends ReadonlyArray<string> = ReadonlyArray<string>> {
attrs?: A
/**
* R1 ($prop reactivity, template-syntax-v2 round 5): rich per-prop
* metadata bag describing the Lit-style `attribute` / `reflect` /
* `converter` lowering. When non-empty, the runtime synthesizes
* `observedAttributes` from prop entries with `attribute !== false`,
* wires `attributeChangedCallback`, allocates one `Signal` per prop
* initialized to `value`, defines a JS property accessor on the class
* prototype, and (when `reflect: true`) reflects signal writes back to
* the attribute with a re-entrancy guard.
*
* Value flows through to the setup function via `ctx.props.<name>`,
* a per-name `Signal<unknown>`. Setup callers are expected to read via
* the signal-getter call (e.g. `props.title()`); writes via
* `props.title.set(...)` or via the JS property accessor on the host
* element (`el.title = newValue`) flow back through the same signal.
*/
props?: PropsConfig
/**
* Recipe class-extension (master spec §9.4): the generated element class
* extends this base custom-element class instead of `HTMLElement`, so the
* base's `connectedCallback` (role/ARIA/keyboard, form-control inheritance,
* cross-piece context provision) runs on the host. Emitted by the compiler's
* `$extends:` macro. Options-form only — base-extending recipes always carry
* `$prop` declarations, so they compile to the options-form. The base's
* `connectedCallback` runs BEFORE the template mounts (so a context-providing
* primitive registers before its slotted child pieces upgrade), and its
* `disconnectedCallback` runs on teardown; `observedAttributes` are unioned
* and `attributeChangedCallback` is forwarded to the base.
*/
base?: typeof HTMLElement
setup: (ctx: SetupContext & AttrContext<A> & PropsContext) => Branch | Leaf
}Options passed to the overloaded `defineComponent` when typed `observedAttributes` + per-attribute signals are desired.
DefineOptionsinterface DefineOptions {
shadowMode?: ShadowMode
/**
* D5 `$form` — register as a form-associated custom element. The flag has to
* reach the constructor BEFORE `customElements.define` runs: the definition
* algorithm reads `formAssociated` off the constructor once, at define time,
* so assigning the static afterwards is silently ignored.
*/
formAssociated?: boolean
/**
* Light-DOM leaf flip (LDF §10 step 3) — the compiler-computed 8-hex-char
* scope id this component's authored CSS is `@scope`d to
* (`aihu-css-core`'s `light_scope.rs`). `define-element.ts`'s `wrapClass`
* stamps it as `data-a="<id>"` on the element itself at construction time,
* ONLY when `shadowMode` is `'light'` — a shadow-mode component has no use
* for it (shadow DOM already provides real scoping).
*/
lightScopeId?: string
}InstanceAgentDispatcherinterface InstanceAgentDispatcher {
readonly tag: string
/** opaqueId → action invoker (called with the positional args array). */
readonly actions: Record<string, (args: unknown[]) => unknown>
/** opaqueId → read accessor (current signal value). */
readonly reads: Record<string, () => unknown>
/** opaqueId → write accessor. */
readonly writes: Record<string, (value: unknown) => void>
}The instance-bound dispatcher shape.
InstanceAgentServerBindinginterface InstanceAgentServerBinding {
readonly tag: string
/** memberName → action invoker (called with the positional args array). */
readonly actions: Record<string, (args: unknown) => unknown>
/** memberName → read accessor (current signal/computed value). */
readonly reads: Record<string, () => unknown>
/** memberName → write accessor (prop signal setter). */
readonly writes: Record<string, (value: unknown) => void>
/** `$scope` from the `@agent` block, or undefined when unscoped. */
readonly scope: string | undefined
/** `$rate-limit` as `'<n>/min'`, or undefined when unlimited. */
readonly rateLimit: string | undefined
}The full, per-instance agent binding the SERVER build injects into the setup body.
PropDefinterface PropDef {
value?: unknown
attribute?: boolean | string
reflect?: boolean
converter?: (raw: string | null) => unknown
}R1 — single `$prop` definition.
PropSignalinterface PropSignal {
(): unknown
set(v: unknown): void
}R1 — per-prop signal handle exposed to setup.
ResourceHandleinterface ResourceHandle<T> {
/** True while a fetch is in flight (initial load or a refetch). */
readonly loading: boolean
/** The latest resolved value, or `null` before the first success. */
readonly data: T | null
/** The error from the most recent failed run, or `null`. */
readonly error: Error | null
/** Re-run the factory. Resolves when the run settles. */
refetch(): Promise<void>
}SetupContextinterface SetupContext {
readonly host: ShadowRoot | Element
readonly element: HTMLElement
readonly connected: () => boolean
}Context passed to a `defineComponent` setup function.
SsrChildModuleinterface SsrChildModule {
/** The compiled string renderer, `__ssrString(props, opts)`. */
readonly __ssrString?: (props: unknown, opts?: SsrChildRenderOpts) => string
/**
* The module's default export — the host-less `__ssr` factory the server
* target emits (`export default __ssr`), which builds an arbor tree from a
* setup run with empty props.
*
* Declared here purely so `@aihu/server`'s walker can reach it under
* `AIHU_SSR_STRING=0`, where the point is NOT to use the compiled string
* renderer. Nothing in this module calls it — it is synchronous to build but
* the walk over its result is async, and everything here is synchronous by
* construction. `unknown` rather than a factory type because that is all this
* module can honestly assert about it.
*/
readonly default?: unknown
/** `__aihu_light_scope__` — the compiler-assigned light-DOM scope id. */
readonly __aihu_light_scope__?: string
/**
* `__aihu_shadow__` (#770). aihu's OWN vocabulary — `'light' | 'shadow'` —
* never the DOM's `ShadowRootMode`.
*/
readonly __aihu_shadow__?: ShadowMode
/**
* `__aihu_css__` — the component's own CSS as a plain string.
*
* Used ONLY on the shadow path, where it is inlined as `<style>` inside the
* declarative template. A shadow root is style-isolated by construction, so
* prerendered markup whose styles are not inside it paints unstyled until the
* component's chunk loads — the #754 failure, where content rendering ahead
* of its scoped CSS pushed the LCP element below the fold.
*
* Light-DOM children ignore it: their rules arrive through the app
* stylesheet's `@scope([data-a=…])` blocks (#758).
*/
readonly __aihu_css__?: string
}A compiled `--target server` module, as far as child rendering cares.
SsrChildRenderOptsinterface SsrChildRenderOpts {
readonly hydratable?: boolean
readonly lightScopeId?: string
/**
* tag → compiled module, PRE-RESOLVED by the caller (SSG prerender or the
* Workers handler). A Map and not a callback on purpose: module loading is
* async while this path is synchronous, and hoisting resolution to the caller
* is what lets the compiled fast path survive child rendering at all. It is
* also where the cycle guard belongs — once, over the whole graph, at build
* time, rather than at every render.
*/
readonly children?: ReadonlyMap<string, SsrChildModule>
/** @internal Recursion depth, incremented per nested child. */
readonly __depth?: number
/**
* @internal Per-render memo of already-serialized children, keyed by tag +
* hydration mode.
*
* Bounds FAN-OUT, which the depth cap alone does not. A depth cap limits how
* DEEP the recursion goes, not how WIDE: with each of 14 components
* referencing the next three times, a perfectly acyclic graph expands to
* 3^13 renders — measured at 67 MB of output in 0.2 s, and tens of GB a few
* components later. The cycle guard cannot see this either, because
* `__aihu_child_tags__` is a SET while the emitter emits one call per
* reference site.
*
* Safe because a child render is deterministic within one top-level render:
* it always receives `{}` props, `lightScopeId: ''`, and the same registry,
* and its tree restarts at ROOT_PATH behind its own `data-aihu-ssr` boundary,
* so two reference sites legitimately produce identical inner markup. Scoped
* PER RENDER, not module-global — component setup can read stores or context
* that differ between requests.
*/
readonly __memo?: Map<string, string>
/**
* @internal Remaining child expansions for this top-level render.
*
* The memo bounds the WORK of fan-out; it cannot bound the OUTPUT. Three
* references repeated 13 deep is 3^13 reference sites, and each legitimately
* emits the child's markup — memoized, that is 89 MB in 16 ms rather than
* 67 MB in 217 ms. Faster, and still a build-killer.
*
* So the budget counts BYTES, not expansions. Counting expansions does not
* work once the memo exists: only one render happens per tag, but each
* RETURNS three times its child's string, so output grows exponentially
* while the render count stays linear — measured at 89 MB from 14 renders.
* Bytes are the thing that actually gets large, so bytes are what is bounded.
*
* Past the budget a reference renders as the empty element it rendered before
* this feature existed: degraded, loudly reported, and finite.
*/
readonly __budget?: { bytes: number; reported: boolean }
}The opts a compiled `__ssrString` accepts, plus the child registry.
StreamHandleinterface StreamHandle {
readonly value: string
readonly delta: string
readonly status: StreamStatus
readonly error: Error | null
start(
source?: ReadableStream<string> | (() => Promise<ReadableStream<string> | null>),
): Promise<void>
stop(): void
}PropsConfigtype PropsConfig = Record<string, PropDef>Setuptype Setup = (ctx: SetupContext) => Branch | LeafA `defineComponent` setup function: receives a `SetupContext`, returns the arbor tree to mount.
ShadowModetype ShadowMode = 'light' | 'shadow'Rendering mode for the custom element — a BINARY choice (DA4 #437).
StreamStatustype StreamStatus = 'idle' | 'streaming' | 'done' | 'error'