import * as React from "react" import * as smd from "streaming-markdown" interface AiSearchProps { searchQuery: string } const AiSearch: React.FC = (props: { searchQuery: string }) => { const [error, setError] = React.useState("") const root_el = React.useRef(null) const [parser, md_el] = React.useMemo(() => { const md_el = document.createElement("div") const renderer = smd.default_renderer(md_el) const parser = smd.parser(renderer) return [parser, md_el] }, []) React.useEffect(() => { if (root_el.current) { root_el.current.appendChild(md_el) } }, [md_el]) React.useEffect(() => { const question = props.searchQuery fetchData() async function fetchData() { let response: Response try { response = await fetch("/api/search-stream", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ question: question }), }) } catch (error) { console.error("Error fetching data:", error) setError("Error fetching data") return } if (!response.body) { console.error("Response has no body") setError("Response has no body") return } const reader = response.body.getReader() const decoder = new TextDecoder() let done = false while (!done) { const res = await reader.read() if (res.value) { const text = decoder.decode(res.value) smd.parser_write(parser, text) } if (res.done) { smd.parser_end(parser) done = true } } } }, [props.searchQuery, parser]) return (

✨ This is what I have found:

{error}

) } export default AiSearch