Waiting for complete diagram...
'; return } const processedContent = rawContent .split('\n') .map((line) => { const trimmedLine = line.trim() if (trimmedLine.startsWith('subgraph')) { const parts = trimmedLine.split(' ') if (parts.length > 1) { const title = parts.slice(1).join(' ').replace(/["']/g, '') return `subgraph "${title}"` } } return trimmedLine }) .filter((line) => !line.trim().startsWith('linkStyle')) .join('\n') const mermaidId = `mermaid-${Date.now()}` mermaid .render(mermaidId, processedContent) .then(({ svg, bindFunctions }) => { // Check ref and hasRendered state again inside async callback if (mermaidRef.current === container && !hasRendered) { container.innerHTML = svg setHasRendered(true) // Mark as rendered successfully if (bindFunctions) { try { bindFunctions(container) } catch (bindError) { console.error('Mermaid bindFunctions error:', bindError) container.innerHTML += 'Diagram interactions might be limited.
' } } } else if (mermaidRef.current !== container) { console.log('Mermaid container changed before rendering completed.') } }) .catch((error) => { console.error('Mermaid rendering promise error (debounced):', error) console.error('Failed content (debounced):', processedContent) if (mermaidRef.current === container) { const errorMessage = error instanceof Error ? error.message : String(error) const errorPre = document.createElement('pre') errorPre.className = 'text-red-500 text-xs whitespace-pre-wrap break-words' errorPre.textContent = `Mermaid diagram error: ${errorMessage}\n\nContent:\n${processedContent}` container.innerHTML = '' container.appendChild(errorPre) } }) } catch (error) { console.error('Mermaid synchronous error (debounced):', error) console.error('Failed content (debounced):', String(children)) if (mermaidRef.current === container) { const errorMessage = error instanceof Error ? error.message : String(error) const errorPre = document.createElement('pre') errorPre.className = 'text-red-500 text-xs whitespace-pre-wrap break-words' errorPre.textContent = `Mermaid diagram setup error: ${errorMessage}` container.innerHTML = '' container.appendChild(errorPre) } } }, 300) // Debounce delay } // Cleanup function to clear the timer on unmount or before re-running effect return () => { if (debounceTimerRef.current) { clearTimeout(debounceTimerRef.current) } } // Dependencies: renderAsDiagram ensures effect runs when diagram should be shown. // Dependencies include all values used inside the effect to satisfy exhaustive-deps. // The !hasRendered check prevents re-execution of render logic after success. }, [renderAsDiagram, hasRendered, language, children, theme]) // Add children and theme back // For large JSON, skip syntax highlighting completely and use a simple pre tag if (isLargeJsonBlock) { return (
{contentStr}
)
}
// Render based on language type
// If it's a mermaid language block and rendering as diagram is not requested (e.g., incomplete stream), display as plain text
if (language === 'mermaid' && !renderAsDiagram) {
return (
{children}
)
}
)
// Assign display name for React DevTools
CodeHighlight.displayName = 'CodeHighlight'