/** * Splits a markdown string into stable top-level blocks + an in-progress tail. * * During streaming, completed blocks are stable (their content never changes * once the block ends), so we can memoize per-block ReactMarkdown renders and * only re-render the tail on every commit. * * Rules: * - Blocks are separated by one or more blank lines that appear OUTSIDE fenced * code blocks. * - An unterminated fenced code block at the end is included in the tail so * it re-renders as the fence grows. * - Joining completedBlocks with "\n\n" + tail re-produces the original text * (modulo collapsed blank-line sequences, which don't affect rendered output). */ export interface MarkdownBlockSplit { /** Fully-terminated top-level blocks. Each element is the raw markdown for * one block (no leading/trailing blank lines). These are stable once the * block ends: the streaming source never changes a completed block. */ completedBlocks: string[]; /** The current in-progress block (may be an unterminated fence, partial * list, etc.). Empty string when the text ends cleanly on a blank line. */ tail: string; } /** * Split `text` into completed top-level markdown blocks and a trailing * in-progress tail. * * The split is purely syntactic (blank-line-based with fence awareness) and * does NOT parse full markdown AST — this keeps it synchronous and O(n). */ export declare function splitMarkdownBlocks(text: string): MarkdownBlockSplit; /** * Rejoin a split result back into the original text (for final render parity). * Blocks are joined with double newlines; tail is appended with a double * newline separator when both parts are non-empty. */ export declare function joinMarkdownBlocks({ completedBlocks, tail, }: MarkdownBlockSplit): string; //# sourceMappingURL=markdown-block-split.d.ts.map