import { Browser, launch } from 'puppeteer' let browserPromise: Promise | null = null function getBrowser() { if (!browserPromise) { browserPromise = launch({ headless: true }) } return browserPromise } /** * Closes the Puppeteer browser instance if it exists. * This function is useful for cleaning up resources when the application is shutting down or when the browser is no longer needed. */ export async function closeMermaidBrowser() { if (browserPromise) { const browser = await browserPromise await browser.close() browserPromise = null } } const cache = new Map() /** * Renders a Mermaid chart to SVG using Puppeteer and caches the result. * @param chart - The Mermaid chart definition as a string. * @returns A promise that resolves to the rendered SVG string. */ export async function renderMermaidToSvg(chart: string): Promise { const cached = cache.get(chart) if (cached) return cached const browser = await getBrowser() const page = await browser.newPage() try { await page.setContent(`
`) await page.addScriptTag({ url: 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js', }) const svg = await page.evaluate(async (source) => { // @ts-expect-error mermaid is loaded globally via the script tag above window.mermaid.initialize({ startOnLoad: false, theme: 'neutral' }) // @ts-expect-error same as above const { svg: renderedSvg } = await window.mermaid.render('mermaid-diagram', source) return renderedSvg }, chart) cache.set(chart, svg) return svg } finally { await page.close() } }