/** Result returned by a block identifier when it matches. */ export interface IdentifyResult { raw: string; attrs?: Record; /** * Line index to continue scanning from. Must be greater than the `index` * the identifier was called with and no greater than `lines.length`; * `identifyBlocks` throws a RangeError otherwise, since a non-advancing * index would hang the scanner. */ nextIndex: number; } /** * Block handler — pure rendering + serialization. * * Deliberately DOM-free: editing UI lives in `editor/` and is registered * separately via `registerEditor()`. Keeping the two apart is what allows * `./block` to be consumed by SSR and other non-DOM runtimes without * pulling `lib.dom` into the consumer's type-check. */ export interface BlockHandler { /** Render raw markdown to HTML string. Pure, no DOM. SSR-safe. */ render(raw: string, attrs?: Record): string; /** Serialize back to markdown. Pure. */ serialize(raw: string, attrs?: Record): string; /** * Try to identify this block starting at `lines[index]`. * Return null if the line doesn't start this block type. * Custom identifiers run before built-in detection. */ identify?: (lines: string[], index: number) => IdentifyResult | null; }