1- // Replaced `marked` block-splitting with the incremental parser from `@lixpi/markdown-stream-parser`.
2- // The parser allows us to detect "block defining" segments as the stream progresses. We feed the
3- // entire markdown string in one go (since this util is synchronous) and collect a new block every
4- // time the parser notifies us that the current segment starts a fresh block.
5- import { MarkdownStreamParser } from '@lixpi/markdown-stream-parser' ;
61import type { Element , Root } from 'hast' ;
2+ import { marked } from 'marked' ;
73import {
84 createContext ,
95 memo ,
@@ -21,55 +17,9 @@ import { cn } from '@/lib/utils';
2117import { CodeBlock } from './code-block' ;
2218import * as styles from './markdown.css' ;
2319
24- // Re-use a single parser instance across calls to avoid the overhead of
25- // constructing and tearing down a temporary one every render. We keep this
26- // module-scoped so it lives for the lifetime of the bundle (or until a hot
27- // reload), and we scope it with a unique ID that is unlikely to clash with
28- // any other consumer inside the app.
29- const MARKDOWN_SPLITTER_PARSER_ID = 'markdown-splitter' ;
30- const sharedMarkdownParser = MarkdownStreamParser . getInstance (
31- MARKDOWN_SPLITTER_PARSER_ID
32- ) ;
33-
3420function parseMarkdownIntoBlocks ( markdown : string ) : string [ ] {
35- // Early-out for empty strings – prevents the parser from creating an instance needlessly.
36- if ( ! markdown ) return [ '' ] ;
37-
38- // Reuse our shared parser instance. We subscribe/unsubscribe on every call so
39- // we still don't leak any listeners or cross-contaminate block buffers
40- // between invocations.
41- const parser = sharedMarkdownParser ;
42-
43- const blocks : string [ ] = [ ] ;
44- let current = '' ;
45-
46- const unsubscribe = parser . subscribeToTokenParse ( ( parsedSegment : any ) => {
47- // We only care about streaming tokens that carry a segment payload
48- if ( parsedSegment . status !== 'STREAMING' || ! parsedSegment . segment ) {
49- return ;
50- }
51-
52- const { segment : segContent , isBlockDefining } = parsedSegment . segment ;
53-
54- if ( isBlockDefining && current ) {
55- // Push the buffered block (if any) and start a new one
56- blocks . push ( current ) ;
57- current = '' ;
58- }
59-
60- current += segContent ;
61- } ) ;
62-
63- // Begin parsing → feed → end & flush
64- parser . startParsing ( ) ;
65- parser . parseToken ( markdown ) ;
66- parser . stopParsing ( ) ;
67-
68- unsubscribe ( ) ;
69-
70- if ( current ) blocks . push ( current ) ;
71-
72- return blocks ;
21+ const tokens = marked . lexer ( markdown ) ;
22+ return tokens . map ( token => token . raw ) ;
7323}
7424
7525function remarkStripFootnoteRefs ( ) {
0 commit comments