T
TanStack15mo ago
metropolitan-bronze

How would I manage a streamed response from the server?

I am effectively making a chatbot. If you were to imagine it in "plain JS", it might look like this:
async function createStream(reader: ReadableStreamDefaultReader<string>): AsyncGenerator<string, undefined, undefined> {
const { value, done } = await reader.read();
if (done) return;
yield value;
yield* await createStream(reader);
}

async function stream(reader: ReadableStreamDefaultReader<string>) {
const iterator = createStream(reader);
for await (const line of iterator) {
updateDOMSomehow(line);
}
}

function sendMessage(prompt: string) {
const response = await fetch("/api/v2/chat", {
method: 'POST',
body: JSON.stringify({ prompt }),
});
if (!response.ok || !response.body) {
throw new Error(response.statusText ?? "Something unexpected went wrong");
}
const reader = response.body.pipeThrough(new TextDecoderStream())
return stream(reader);
}
async function createStream(reader: ReadableStreamDefaultReader<string>): AsyncGenerator<string, undefined, undefined> {
const { value, done } = await reader.read();
if (done) return;
yield value;
yield* await createStream(reader);
}

async function stream(reader: ReadableStreamDefaultReader<string>) {
const iterator = createStream(reader);
for await (const line of iterator) {
updateDOMSomehow(line);
}
}

function sendMessage(prompt: string) {
const response = await fetch("/api/v2/chat", {
method: 'POST',
body: JSON.stringify({ prompt }),
});
if (!response.ok || !response.body) {
throw new Error(response.statusText ?? "Something unexpected went wrong");
}
const reader = response.body.pipeThrough(new TextDecoderStream())
return stream(reader);
}
Here's the problem: when I have that in a mutation, I would ideally like to stream it to the appropriate "chat bubble" so it can update the response. i.e.,
interface ChatBubbleProps {
// assuming I somehow "return" the response from the mutation
stream?: Response | undefined;
}

function ChatBubble({ stream }: ChatBubbleProps) {
const [content, setContent] = useState('');
useEffect(() => {
if (stream) {
streamResponse(stream, setContent);
}
}, [stream]);
// ...
}
interface ChatBubbleProps {
// assuming I somehow "return" the response from the mutation
stream?: Response | undefined;
}

function ChatBubble({ stream }: ChatBubbleProps) {
const [content, setContent] = useState('');
useEffect(() => {
if (stream) {
streamResponse(stream, setContent);
}
}, [stream]);
// ...
}
The problem I'm having is: how would you connect this with useMutation?
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?