'use client'; import { use, useEffect, useId, useState } from 'react'; import { useTheme } from 'next-themes'; const cache = new Map>(); function cachePromise(key: string, fn: () => Promise): Promise { const cached = cache.get(key); if (cached) return cached as Promise; const promise = fn(); cache.set(key, promise); return promise; } export function Mermaid({ chart }: { chart: string }) { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); if (!mounted) return null; return ; } function MermaidContent({ chart }: { chart: string }) { const id = useId().replace(/:/g, '_'); const { resolvedTheme } = useTheme(); const { default: mermaid } = use( cachePromise('mermaid', () => import('mermaid')), ); mermaid.initialize({ startOnLoad: false, securityLevel: 'strict', fontFamily: 'inherit', theme: resolvedTheme === 'dark' ? 'dark' : 'default', }); const { svg, bindFunctions } = use( cachePromise(`${chart}-${resolvedTheme}`, () => mermaid.render(id, chart.replaceAll('\\n', '\n')), ), ); return (
{ if (container) bindFunctions?.(container); }} dangerouslySetInnerHTML={{ __html: svg }} /> ); }