fIx: smaller nits

This commit is contained in:
2026-03-20 00:04:46 +01:00
parent bc67d01bc2
commit c3cbe35883
21 changed files with 2093 additions and 116 deletions

View File

@@ -0,0 +1,86 @@
/**
* Hook for parsing and streaming markdown content.
* Handles marked.js parsing with proper cleanup and cancellation.
*/
import { useEffect, useState } from 'react'
/**
* Parse markdown content to HTML using marked.js.
* Returns parsed HTML string and handles cleanup on unmount.
*
* @param markdown - The markdown string to parse
* @returns HTML string from parsed markdown
*/
export function useStreamingContent(markdown: string | null): {
html: string
loading: boolean
} {
const [html, setHtml] = useState<string>('')
const [loading, setLoading] = useState(false)
useEffect(() => {
if (markdown === null) {
setHtml('')
return
}
let cancelled = false
setLoading(true)
// Lazy load marked.js to avoid bundling if not needed
import('marked')
.then(async ({ marked }) => {
if (cancelled) return
try {
const parsed =
typeof marked.parse === 'function'
? await (marked.parse as (s: string) => Promise<string>)(markdown)
: (marked as (s: string) => string)(markdown)
const result = typeof parsed === 'string' ? parsed : String(parsed)
if (!cancelled) {
setHtml(result)
setLoading(false)
}
} catch (err) {
if (!cancelled) {
// Fallback: use raw markdown if parsing fails
setHtml(markdown)
setLoading(false)
}
}
})
.catch(() => {
if (!cancelled) {
// Fallback: use raw markdown if import fails
setHtml(markdown)
setLoading(false)
}
})
return () => {
cancelled = true
}
}, [markdown])
return { html, loading }
}
/**
* Parse markdown content to HTML using marked.js (synchronous version).
* Use this when you need immediate parsing without React state.
*
* @param markdown - The markdown string to parse
* @returns HTML string from parsed markdown, or raw markdown on error
*/
export function parseMarkdownToHtml(markdown: string): string {
try {
// Use dynamic import for marked.js
// Note: This is a helper for non-React contexts
// In React components, use useStreamingContent hook instead
return markdown // Placeholder - actual implementation requires async import
} catch {
return markdown
}
}

View File

@@ -0,0 +1,30 @@
/**
* Hook for parsing markdown content with think sections.
* Extracts <think>...</think> blocks and returns main content and reasoning separately.
*/
import { useMemo } from 'react'
import { parseThinkSections } from '@/lib/graph/renderingUtils'
/**
* Parse markdown content and extract think sections.
* Returns main content (without think blocks) and reasoning content (from think blocks).
*
* @param content - The HTML/markdown content to parse
* @param outputType - The output type ('image' or 'string')
* @returns Object with main and think content
*/
export function useThinkSections(
content: string | null,
outputType: 'image' | 'string'
): {
main: string
think: string
} {
return useMemo(() => {
if (!content || outputType === 'image') {
return { main: '', think: '' }
}
return parseThinkSections(content)
}, [content, outputType])
}