@johnhenry/aimatey-react-stream
v0.1.6
Published
React streaming utilities for Aimatey - StreamProvider, StreamContext
Maintainers
Readme
@johnhenry/aimatey-react-stream
Note: Previously published as
[email protected].
React components and utilities for streaming AI responses.
Part of the aimatey monorepo.
Installation
npm install @johnhenry/aimatey-react-streamQuick Start
import { StreamProvider, useStreamContext, StreamText } from '@johnhenry/aimatey-react-stream';
// Wrap your app with StreamProvider
function App() {
return (
<StreamProvider maxStreams={10}>
<ChatComponent />
</StreamProvider>
);
}
// Use streaming in components
function ChatComponent() {
const { startStream, appendToStream, completeStream, getStream } = useStreamContext();
const [streamId, setStreamId] = useState<string | null>(null);
const handleSend = async () => {
const id = `msg-${Date.now()}`;
setStreamId(id);
startStream(id);
const response = await fetch('/api/chat', { method: 'POST' });
const reader = response.body?.getReader();
const decoder = new TextDecoder();
while (reader) {
const { done, value } = await reader.read();
if (done) break;
appendToStream(id, decoder.decode(value));
}
completeStream(id);
};
const stream = streamId ? getStream(streamId) : null;
return (
<div>
{stream && (
<StreamText
text={stream.text}
isStreaming={stream.isStreaming}
showCursor={true}
/>
)}
<button onClick={handleSend}>Send</button>
</div>
);
}Exports
Components
StreamProvider- Context provider for stream state managementStreamText- Display streaming text with cursorTypeWriter- Typewriter effect for static text
Hooks
useStreamContext- Access stream management functionsuseStreamState- Get state for a specific stream
Utilities
createTextStream- Create controlled text stream from fetch responseparseSSEStream- Parse Server-Sent EventstransformStream- Transform stream datamergeStreams- Merge multiple streamsfromAsyncIterable- Convert async iterable to streamtoAsyncIterable- Convert stream to async iterable
Types
StreamState,StreamContextValue,StreamProviderPropsStreamTextProps,TypeWriterPropsCreateTextStreamOptions,SSEEvent
API Reference
StreamProvider
Context provider for managing multiple concurrent streams.
<StreamProvider maxStreams={100}>
{children}
</StreamProvider>Props:
maxStreams- Maximum streams to keep (default: 100, oldest completed removed when exceeded)
useStreamContext
Access stream management functions.
const {
streams, // Map<string, StreamState> - All streams
getStream, // (id: string) => StreamState | undefined
startStream, // (id: string, metadata?: object) => void
updateStream, // (id: string, text: string) => void - Replace text
appendToStream, // (id: string, chunk: string) => void - Append text
completeStream, // (id: string) => void - Mark complete
setStreamError, // (id: string, error: Error) => void
removeStream, // (id: string) => void
clearAllStreams, // () => void
} = useStreamContext();useStreamState
Get state for a specific stream by ID.
const stream = useStreamState('message-1');
// stream: { id, text, isStreaming, error, metadata } | undefinedStreamText
Display streaming text with optional blinking cursor.
<StreamText
text="Hello world"
isStreaming={true}
showCursor={true} // Show cursor while streaming
cursor="▋" // Cursor character
cursorBlinkInterval={500} // Blink speed in ms
className="my-class"
renderText={(text) => <Markdown>{text}</Markdown>}
/>TypeWriter
Simulate typing effect for non-streaming text.
<TypeWriter
text="Welcome to Aimatey!"
speed={30} // ms per character
delay={500} // ms before starting
showCursor={true}
cursor="▋"
onComplete={() => console.log('Done!')}
/>Stream Utilities
import {
createTextStream,
parseSSEStream,
fromAsyncIterable,
} from '@johnhenry/aimatey-react-stream';
// Create text stream from fetch response
const text = await createTextStream(response, {
onChunk: (chunk) => console.log(chunk),
onComplete: (fullText) => console.log('Done:', fullText),
signal: abortController.signal,
});
// Parse SSE events
for await (const event of parseSSEStream(response)) {
console.log(event.data); // { type: 'data' | 'event', data: string }
}License
MIT - see LICENSE for details.
