/** * Minimal, runtime-agnostic HTML parser for the SSR renderer. * * This is intentionally a small, linear scanner rather than a full HTML5 * tokenizer. It is sufficient for templates authored against the `bQuery` * directive vocabulary (HTML fragments, common void/raw elements, attributes) * and lets the SSR pipeline run on Bun, Deno and Node without depending on a * `DOMParser` polyfill. * * Output: a tiny virtual node tree (`SSRNode`) compatible with the pluggable * DOM adapter API used by `renderer.ts`. * * @module bquery/ssr * @internal */ const VOID_ELEMENTS = new Set([ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr', ]); const RAW_TEXT_ELEMENTS = new Set(['script', 'style', 'textarea', 'title']); /** A DOM-free node structure produced by `parseTemplate()`. */ export type SSRNode = SSRElement | SSRText | SSRComment | SSRDocumentFragment; export interface SSRElement { type: 'element'; tag: string; attributes: Record; /** Order-preserving attribute list (so output is deterministic). */ attributeOrder: string[]; children: SSRNode[]; /** Whether this element should be serialised as a void element. */ void: boolean; /** Whether the children are raw (e.g. `