@anvia/react
v0.8.10
Published
React hooks and client transports for Anvia applications.
Readme
@anvia/react
React hooks and client transports for Anvia applications.
import { useChat } from "@anvia/react";
import { useState } from "react";
export function Chat() {
const chat = useChat({ endpoint: "/api/chat" });
const [input, setInput] = useState("");
return (
<form
onSubmit={(event) => {
event.preventDefault();
void chat.sendMessage(input);
setInput("");
}}
>
<div>
{chat.messages.map((message) => (
<p key={message.id}>
{message.parts
.filter((part) => part.type === "text")
.map((part) => part.text)
.join("")}
</p>
))}
</div>
<input value={input} onChange={(event) => setInput(event.target.value)} />
<button disabled={chat.status === "streaming"}>Send</button>
</form>
);
}Exports
readJsonlStream(stream)parses newline-delimited JSON streams.readSseStream(stream)parses Server-Sent Events with JSONdata:payloads.fetchEventStream(url, options)fetches JSONL or SSE streams asAsyncIterable.createFetchTransport(options)creates anEventTransport; it defaults to POST JSON and omits implicit bodies for GET/HEAD.createChatTransport(options)creates the default fetch-backed chat transport.useChat(options)managesUIMessage[]chat state from anyEventTransport, including optional human-input approval/question state and opt-in stream resume.useCompletion(options)appends completion turns intoUIMessage[]state and exposes derivedcompletiontext.useSmoothStreamText(content, options)smooths an append-only string for display without changing stream events or message state.
Default hook requests use one shared wire shape:
type UIStreamRequest = {
messages: Message[];
stream: true;
metadata?: JsonValue;
};Hooks convert their local UIMessage[] state into core messages before sending. Custom
createRequest callbacks receive { messages, uiMessages, coreMessages }, where messages and
uiMessages are UI-shaped for compatibility and coreMessages is the default wire payload.
The shared boundary is:
type EventTransport<TRequest, TEvent> = {
send(request: TRequest, options?: TransportOptions): AsyncIterable<TEvent>;
};Default hooks can consume raw createCompletionStream(...) events, raw agent stream events, or
UIStreamEvent records. A completion endpoint can return:
createEventStream(createCompletionStream(model, { messages: body.messages }));For chat streams that should survive navigation or reload, pair useChat({ resume: { key } }) with
an endpoint that returns createEventStream(events, { resumable: { id, store } }) and handles
resume bodies containing { resume: { streamId, after } }.
