"use client" import React, { useEffect, useState } from "react" import * as smd from "streaming-markdown" interface AiSearchProps { searchQuery: string } const AiSearch: React.FC = (props: { searchQuery: string }) => { const [error, setError] = useState("") let root_el = React.useRef(null) let [parser, md_el] = React.useMemo(() => { let md_el = document.createElement("div") let renderer = smd.default_renderer(md_el) let parser = smd.parser(renderer) return [parser, md_el] }, []) useEffect(() => { if (root_el.current) { root_el.current.appendChild(md_el) } }, [md_el]) useEffect(() => { let 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() while (true) { let res = await reader.read() if (res.value) { let text = decoder.decode(res.value) smd.parser_write(parser, text) } if (res.done) { smd.parser_end(parser) break } } } }, [props.searchQuery, parser]) return (

✨ This is what I have found:

{error}

) } export default AiSearch