fixes and better mermaid

This commit is contained in:
2025-07-09 14:20:45 +02:00
parent 43a7647a9c
commit cb069a45be
3 changed files with 67 additions and 25 deletions

83
App.tsx
View File

@ -27,37 +27,51 @@ import mermaid from 'mermaid';
const extractJson = (text: string): any => {
let jsonString = text.trim();
// Remove BOM and other invisible characters
jsonString = jsonString.replace(/^\uFEFF/, ''); // Remove BOM
jsonString = jsonString.replace(/^[\u200B-\u200D\uFEFF]/g, ''); // Remove zero-width characters
const fenceRegex = /^```(?:json)?\s*\n?(.*?)\n?\s*```$/s;
const match = jsonString.match(fenceRegex);
if (match && match[1]) {
jsonString = match[1].trim();
}
const lastBracket = jsonString.lastIndexOf('}');
if (lastBracket === -1) {
throw new Error("No closing brace '}' found in API response.");
}
let openBraceCount = 0;
let firstBracket = -1;
for (let i = lastBracket; i >= 0; i--) {
if (jsonString[i] === '}') {
openBraceCount++;
} else if (jsonString[i] === '{') {
openBraceCount--;
// Try to parse directly first (most common case)
try {
return JSON.parse(jsonString);
} catch (directParseError) {
// If direct parsing fails, try the bracket extraction method
const lastBracket = jsonString.lastIndexOf('}');
if (lastBracket === -1) {
throw new Error("No closing brace '}' found in API response.");
}
if (openBraceCount === 0) {
firstBracket = i;
break;
let openBraceCount = 0;
let firstBracket = -1;
for (let i = lastBracket; i >= 0; i--) {
if (jsonString[i] === '}') {
openBraceCount++;
} else if (jsonString[i] === '{') {
openBraceCount--;
}
if (openBraceCount === 0) {
firstBracket = i;
break;
}
}
if (firstBracket === -1) {
throw new Error("Could not find matching opening brace '{' in API response.");
}
const finalJsonString = jsonString.substring(firstBracket, lastBracket + 1);
try {
return JSON.parse(finalJsonString);
} catch (finalParseError) {
throw new Error(`JSON parsing failed: ${finalParseError.message}. Raw text: ${jsonString.substring(0, 100)}...`);
}
}
if (firstBracket === -1) {
throw new Error("Could not find matching opening brace '{' in API response.");
}
const finalJsonString = jsonString.substring(firstBracket, lastBracket + 1);
return JSON.parse(finalJsonString);
};
@ -184,15 +198,23 @@ const MermaidDiagram: React.FC<{ value: string; onChange: (value: string) => voi
useEffect(() => {
if (value.trim()) {
const renderDiagram = async () => {
renderCountRef.current += 1;
const uniqueId = `mermaid-diagram-${renderCountRef.current}`;
try {
setError('');
renderCountRef.current += 1;
const uniqueId = `mermaid-diagram-${renderCountRef.current}`;
setDiagramHtml('');
const { svg } = await mermaid.render(uniqueId, value);
setDiagramHtml(svg);
} catch (err) {
setError(err instanceof Error ? err.message : 'Mermaid diagram rendering failed');
setDiagramHtml('');
} finally {
// Clean up the DOM element that mermaid might have created
const element = document.getElementById(uniqueId);
if (element && element.parentNode) {
element.parentNode.removeChild(element);
}
}
};
renderDiagram();
@ -201,6 +223,19 @@ const MermaidDiagram: React.FC<{ value: string; onChange: (value: string) => voi
setError('');
}
}, [value]);
// Cleanup function to remove any lingering mermaid elements
useEffect(() => {
return () => {
// Clean up any mermaid elements that might be left in the DOM
const mermaidElements = document.querySelectorAll('[id^="mermaid-diagram-"]');
mermaidElements.forEach(element => {
if (element.parentNode) {
element.parentNode.removeChild(element);
}
});
};
}, []);
return (
<div className="space-y-3">