(markdown: string)
| 522 | } |
| 523 | |
| 524 | function parseIntoBlocks(markdown: string): ParsedBlock[] { |
| 525 | try { |
| 526 | // Use Streamdown's built-in parser for consistency |
| 527 | const blocks = parseMarkdownIntoBlocks(markdown) |
| 528 | // Track occurrences of each content hash to handle duplicates |
| 529 | const seen = new Map<string, number>() |
| 530 | return blocks.map((content) => { |
| 531 | const baseKey = hashString(content) |
| 532 | const occurrence = seen.get(baseKey) ?? 0 |
| 533 | seen.set(baseKey, occurrence + 1) |
| 534 | const key = occurrence > 0 ? `${baseKey}-${occurrence}` : baseKey |
| 535 | return { content, key } |
| 536 | }) |
| 537 | } catch { |
| 538 | // Fallback: return entire content as single block |
| 539 | return [{ content: markdown, key: `fallback-${hashString(markdown)}` }] |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | // Individual block - only re-renders when its content changes |
| 544 | const MemoizedMarkdownBlock = memo( |
no test coverage detected