example of SSE streaming

master
Avraham Sakal 2 months ago
parent 2d35a4683b
commit 18411402f5

@ -32,7 +32,12 @@ import {
useMutation, useMutation,
useQuery, useQuery,
} from "@tanstack/react-query"; } from "@tanstack/react-query";
import { createTRPCClient, httpBatchLink } from "@trpc/client"; import {
createTRPCClient,
httpBatchLink,
httpSubscriptionLink,
splitLink,
} from "@trpc/client";
import type { AppRouter } from "../trpc/router.js"; import type { AppRouter } from "../trpc/router.js";
function makeQueryClient() { function makeQueryClient() {
@ -74,10 +79,17 @@ export default function LayoutDefault({
const [trpc] = useState(() => const [trpc] = useState(() =>
createTRPCClient<AppRouter>({ createTRPCClient<AppRouter>({
links: [ links: [
httpBatchLink({ splitLink({
// uses the httpSubscriptionLink for subscriptions
condition: (op) => op.type === "subscription",
true: httpSubscriptionLink({
url: "/api/trpc",
}),
false: httpBatchLink({
url: "/api/trpc", url: "/api/trpc",
methodOverride: "POST", methodOverride: "POST",
}), }),
}),
], ],
}) })
); );

@ -1,25 +1,33 @@
import { Card, Textarea } from "@mantine/core"; import { Card, Textarea } from "@mantine/core";
import { useState } from "react"; import { useState } from "react";
import { useTRPC } from "../../trpc/client"; import { useTRPCClient } from "../../trpc/client";
export default function ChatPage() { export default function ChatPage() {
const [inputMessage, setInputMessage] = useState(""); const [inputMessage, setInputMessage] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [outputMessage, setOutputMessage] = useState(""); const [outputMessage, setOutputMessage] = useState("");
const trpc = useTRPC(); const trpc = useTRPCClient();
async function handleSendMessage() { async function handleSendMessage() {
setLoading(true); setLoading(true);
const response = await trpc.chat.streamMessage.subscribe(
const subscription = trpc.chat.streamMessage.subscribe(
{ {
message: inputMessage, message: inputMessage,
}, },
{} {
); onData(value) {
for await (const chunk of response) { setOutputMessage((prevOutputMessage) => prevOutputMessage + value);
setOutputMessage(chunk); },
} onError(error) {
console.error(error);
},
onComplete() {
subscription.unsubscribe();
setLoading(false); setLoading(false);
},
}
);
} }
return ( return (
<div> <div>
@ -33,6 +41,7 @@ export default function ChatPage() {
onKeyDown={async (e) => { onKeyDown={async (e) => {
if (e.key === "Enter") { if (e.key === "Enter") {
e.preventDefault(); e.preventDefault();
handleSendMessage();
} }
}} }}
/> />

Loading…
Cancel
Save