fixes and better mermaid
This commit is contained in:
83
App.tsx
83
App.tsx
@ -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">
|
||||
|
Reference in New Issue
Block a user