UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

1 lines 5.08 kB
{"version":3,"file":"useStreamMermaid.mjs","names":[],"sources":["../../src/hooks/useStreamMermaid.ts"],"sourcesContent":["'use client';\n\nimport { useTheme } from 'antd-style';\nimport type { MermaidConfig } from 'mermaid';\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { createMermaidConfig, loadMermaid } from './useMermaid';\n\n/**\n * 流式 Mermaid 渲染 - 支持内容逐步更新\n */\nexport const useStreamMermaid = (\n content: string,\n {\n enabled = true,\n id,\n theme: customTheme,\n }: {\n enabled?: boolean;\n id: string;\n theme?: MermaidConfig['theme'];\n },\n): string => {\n const theme = useTheme();\n const [data, setData] = useState<string>('');\n const previousContentRef = useRef<string>('');\n const latestContentRef = useRef(content);\n const renderTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n // 提取主题相关配置到 useMemo 中\n const mermaidConfig = useMemo(\n () => createMermaidConfig(theme, customTheme),\n [\n theme.fontFamilyCode,\n theme.isDarkMode,\n theme.colorTextDescription,\n theme.fontFamily,\n theme.colorTextSecondary,\n theme.colorBgContainer,\n theme.colorInfoBg,\n theme.colorInfoText,\n theme.geekblue,\n theme.colorWarning,\n theme.colorSuccess,\n theme.colorError,\n theme.colorBorder,\n theme.colorInfoBorder,\n theme.colorSuccessBorder,\n theme.colorSuccessBg,\n theme.colorSuccessText,\n theme.colorText,\n customTheme,\n ],\n );\n\n // Update latest content ref\n useEffect(() => {\n latestContentRef.current = content;\n }, [content]);\n\n // Debounced rendering for streaming content\n useEffect(() => {\n if (!enabled) {\n setData('');\n previousContentRef.current = '';\n const timeoutId = renderTimeoutRef.current;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n return;\n }\n\n const currentContent = latestContentRef.current;\n\n // Skip if content hasn't changed\n if (currentContent === previousContentRef.current && data) {\n return;\n }\n\n // Clear previous timeout\n const timeoutId = renderTimeoutRef.current;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n // Debounce rendering for streaming content (wait 300ms after last change)\n renderTimeoutRef.current = setTimeout(async () => {\n const contentToRender = latestContentRef.current;\n\n // Skip if content changed during debounce\n if (contentToRender !== currentContent) {\n return;\n }\n\n try {\n const mermaidInstance = await loadMermaid();\n if (!mermaidInstance) return;\n\n // 验证语法\n const isValid = await mermaidInstance.parse(contentToRender);\n\n if (isValid) {\n // 初始化并渲染\n mermaidInstance.initialize(mermaidConfig);\n const { svg } = await mermaidInstance.render(id, contentToRender);\n\n // Only update if content hasn't changed during rendering\n if (latestContentRef.current === contentToRender) {\n setData(svg);\n previousContentRef.current = contentToRender;\n }\n }\n } catch (error_) {\n // Silently handle errors during streaming\n // Only log if this is the final content\n if (contentToRender === latestContentRef.current) {\n console.error('Mermaid 解析错误:', error_);\n }\n }\n }, 300);\n\n return () => {\n const timeoutId = renderTimeoutRef.current;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n };\n }, [enabled, content, id, mermaidConfig, data]);\n\n return data;\n};\n"],"mappings":";;;;;;;;AAWA,MAAa,oBACX,SACA,EACE,UAAU,MACV,IACA,OAAO,kBAME;CACX,MAAM,QAAQ,SAAS;CACvB,MAAM,CAAC,MAAM,WAAW,SAAiB,EAAE;CAC3C,MAAM,qBAAqB,OAAe,EAAE;CAC5C,MAAM,mBAAmB,OAAO,OAAO;CACvC,MAAM,mBAAmB,OAAkD,KAAA,CAAS;CAGpF,MAAM,gBAAgB,cACd,oBAAoB,OAAO,WAAW,GAC5C;EACE,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN;CACF,CACF;CAGA,gBAAgB;EACd,iBAAiB,UAAU;CAC7B,GAAG,CAAC,OAAO,CAAC;CAGZ,gBAAgB;EACd,IAAI,CAAC,SAAS;GACZ,QAAQ,EAAE;GACV,mBAAmB,UAAU;GAC7B,MAAM,YAAY,iBAAiB;GACnC,IAAI,WACF,aAAa,SAAS;GAExB;EACF;EAEA,MAAM,iBAAiB,iBAAiB;EAGxC,IAAI,mBAAmB,mBAAmB,WAAW,MACnD;EAIF,MAAM,YAAY,iBAAiB;EACnC,IAAI,WACF,aAAa,SAAS;EAIxB,iBAAiB,UAAU,WAAW,YAAY;GAChD,MAAM,kBAAkB,iBAAiB;GAGzC,IAAI,oBAAoB,gBACtB;GAGF,IAAI;IACF,MAAM,kBAAkB,MAAM,YAAY;IAC1C,IAAI,CAAC,iBAAiB;IAKtB,IAAI,MAFkB,gBAAgB,MAAM,eAAe,GAE9C;KAEX,gBAAgB,WAAW,aAAa;KACxC,MAAM,EAAE,QAAQ,MAAM,gBAAgB,OAAO,IAAI,eAAe;KAGhE,IAAI,iBAAiB,YAAY,iBAAiB;MAChD,QAAQ,GAAG;MACX,mBAAmB,UAAU;KAC/B;IACF;GACF,SAAS,QAAQ;IAGf,IAAI,oBAAoB,iBAAiB,SACvC,QAAQ,MAAM,iBAAiB,MAAM;GAEzC;EACF,GAAG,GAAG;EAEN,aAAa;GACX,MAAM,YAAY,iBAAiB;GACnC,IAAI,WACF,aAAa,SAAS;EAE1B;CACF,GAAG;EAAC;EAAS;EAAS;EAAI;EAAe;CAAI,CAAC;CAE9C,OAAO;AACT"}