import { useEffect, useId, useRef, useState } from 'react'; import { DiagramLoader } from './DiagramLoader.js'; import { useInView } from './useInView.js'; /** * D2 compiles to SVG via a WASM build in the browser — same reasoning as `Mermaid`: doing * this at build time would mean shipping a browser (Playwright) as an install dependency of * a documentation CLI. Diagrams are absent from the prerendered HTML; page text is not. */ export function D2({ chart }: { chart: string }) { const id = useId().replace(/[^a-zA-Z0-9]/g, ''); const container = useRef(null); const inView = useInView(container); const [svg, setSvg] = useState(); const [error, setError] = useState(); useEffect(() => { // D2's compile/render pass is synchronous WASM work and can't be interrupted, so a large // diagram freezes the main thread — including any pending navigation — the moment it // starts. Waiting until the diagram is actually scrolled into view keeps that off the // critical path of landing on the page. if (!inView) return; let cancelled = false; void (async () => { try { const { D2: D2Compiler } = await import('@terrastruct/d2'); const dark = document.documentElement.classList.contains('dark'); const compiler = new D2Compiler(); const { diagram, renderOptions } = await compiler.compile(chart, { options: { themeID: dark ? 300 : 0 }, }); const rendered = await compiler.render(diagram, { ...renderOptions, salt: id }); if (!cancelled) setSvg(rendered); } catch (cause) { if (!cancelled) setError(cause instanceof Error ? cause.message : String(cause)); } })(); return () => { cancelled = true; }; }, [inView, chart, id]); if (error !== undefined) { return (
        {`Could not render this diagram: ${error}`}
      
); } return (
{svg === undefined ? ( inView ? ( ) : (
{chart}
) ) : undefined}
); } export default D2;