/** * Observe an aelea `I$Node` subtree and resolve it into a plain * `ResolvedNode` tree on demand — styles and attributes as string records, * children as `ResolvedNode | string`, no streams. Renderer-agnostic: the * resolved tree can be projected to takumi, React, server HTML, etc. * * Design: the observer keeps *live* mutable state (per-channel style/attr * maps, an ordered list of child tokens) and bumps a dirty signal as * behaviors fire. It does **not** build a snapshot per event — `materialize` * walks the live state once, when the caller asks. `renderToImage` settles * the tree (deterministically, via the scheduler's idle signal) and then * materializes a single time, so a burst of behavior emissions during mount * costs O(emits) bookkeeping rather than O(emits × tree-size) clones. */ import { type IStream } from '../stream/index.js'; import type { I$Node, I$Scheduler } from '../ui/index.js'; export interface ResolvedNode { tag: string; style: Record; attributes: Record; children: Array; } export interface IManifestObserver extends Disposable { /** Walk current live state into a plain tree, or `null` if nothing mounted yet. */ materialize(): ResolvedNode | null; } interface IManifestHandlers { onDirty(): void; onError(error: unknown): void; } /** * Subscribe `$root` and expose a live observer over the resolved tree. * Re-subscribes the whole tree if the root stream emits a new node. */ export declare function observeManifest($root: I$Node, scheduler: I$Scheduler, handlers: IManifestHandlers): IManifestObserver; /** * Stream of `ResolvedNode` snapshots of `$node`. Emits a coalesced snapshot * (one per microtask batch) on mount and on every subsequent change. Most * callers want `renderToImage`, which settles deterministically and * materializes once; this is for authors driving their own projection. */ export declare function snapshotStream($node: I$Node, scheduler?: I$Scheduler): IStream; export {};