/** * Component render engine — takes JSON component trees and produces DOM. * * The engine uses a registry of render functions keyed by component type. * Each render function receives the JSON node and a render context, * and returns an HTMLElement (or DocumentFragment). */ import type { Store } from './state.js'; import type { EvalScope } from './rx.js'; import type { DispatchContext, McpTransport, ToastEvent, ActionJSON } from './actions.js'; /** * Recursively normalise object keys from snake_case to camelCase. * Accepts both formats so the renderer works with TS and Python output. * Keys starting with '$' are left unchanged. */ export declare function normalizeNode>(node: T): T; export interface ComponentNode { type: string; id?: string; cssClass?: string; onMount?: ActionJSON | ActionJSON[]; children?: ComponentNode[]; [key: string]: unknown; } export interface RenderContext { store: Store; scope: EvalScope; transport?: McpTransport; rerender: () => void; onToast?: (toast: ToastEvent) => void; /** Replace the current view with a new prefab wire payload (server-rendered pattern). */ remount?: (data: Record) => void; defs?: Record; templates?: Record; slots?: Record; destroyRegistry?: DestroyRegistry; } /** Result of a render function that includes a cleanup callback. */ export interface RenderResult { element: HTMLElement | DocumentFragment; destroy: () => void; } export type RenderFnReturn = HTMLElement | DocumentFragment | RenderResult; export type RenderFn = (node: ComponentNode, ctx: RenderContext) => RenderFnReturn; /** Tracks destroy callbacks for mounted components within a render cycle. */ export declare class DestroyRegistry { private callbacks; /** Register a destroy callback. */ track(cb: () => void): void; /** Call all registered destroy callbacks and clear the list. */ flush(): void; /** Number of registered callbacks (for testing). */ get size(): number; } /** Register a render function for a component type */ export declare function registerComponent(type: string, fn: RenderFn): void; /** Get a render function (or fallback) */ export declare function getRenderer(type: string): RenderFn | undefined; /** * Render a component node to DOM. * Looks up the renderer by type; falls back to a generic div. */ export declare function renderNode(node: ComponentNode, ctx: RenderContext): HTMLElement | DocumentFragment; /** * Render all children of a node into a parent element. * Handles If/Elif/Else chains: only the first matching branch renders. */ export declare function renderChildren(node: ComponentNode, parent: HTMLElement, ctx: RenderContext): void; /** * Render an array of child nodes into a parent, handling If/Elif/Else chains. * Exported so ForEach and other manual-loop renderers can use it. */ export declare function renderChildArray(children: ComponentNode[], parent: HTMLElement | DocumentFragment, ctx: RenderContext): void; /** Resolve a possibly-reactive string value */ export declare function resolveStr(value: unknown, ctx: RenderContext): string; /** Resolve a possibly-reactive value, keeping original type */ export declare function resolveValue(value: unknown, ctx: RenderContext): unknown; /** Create a DispatchContext from RenderContext */ export declare function makeDispatchCtx(ctx: RenderContext): DispatchContext; /** Create an element with a CSS class */ export declare function el(tag: string, className?: string): HTMLElement; /** Set text content on an element */ export declare function text(element: HTMLElement, content: string): HTMLElement; //# sourceMappingURL=engine.d.ts.map