ai.matey.react.stream 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/cjs/index.js +28 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/stream-context.js +193 -0
- package/dist/cjs/stream-context.js.map +1 -0
- package/dist/cjs/stream-text.js +104 -0
- package/dist/cjs/stream-text.js.map +1 -0
- package/dist/cjs/stream-utils.js +236 -0
- package/dist/cjs/stream-utils.js.map +1 -0
- package/dist/esm/index.js +14 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/stream-context.js +188 -0
- package/dist/esm/stream-context.js.map +1 -0
- package/dist/esm/stream-text.js +100 -0
- package/dist/esm/stream-text.js.map +1 -0
- package/dist/esm/stream-utils.js +228 -0
- package/dist/esm/stream-utils.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/stream-context.d.ts +104 -0
- package/dist/types/stream-context.d.ts.map +1 -0
- package/dist/types/stream-text.d.ts +89 -0
- package/dist/types/stream-text.d.ts.map +1 -0
- package/dist/types/stream-utils.d.ts +81 -0
- package/dist/types/stream-utils.d.ts.map +1 -0
- package/package.json +77 -0
- package/readme.md +192 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamText Component
|
|
3
|
+
*
|
|
4
|
+
* React component for rendering streaming text with typing effect.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { type ReactNode } from 'react';
|
|
9
|
+
/**
|
|
10
|
+
* StreamText props.
|
|
11
|
+
*/
|
|
12
|
+
export interface StreamTextProps {
|
|
13
|
+
/** Text to display */
|
|
14
|
+
text: string;
|
|
15
|
+
/** Whether streaming is active */
|
|
16
|
+
isStreaming?: boolean;
|
|
17
|
+
/** Show cursor while streaming */
|
|
18
|
+
showCursor?: boolean;
|
|
19
|
+
/** Cursor character */
|
|
20
|
+
cursor?: string;
|
|
21
|
+
/** Cursor blink interval in ms */
|
|
22
|
+
cursorBlinkInterval?: number;
|
|
23
|
+
/** Custom className */
|
|
24
|
+
className?: string;
|
|
25
|
+
/** Custom render function */
|
|
26
|
+
renderText?: (text: string) => ReactNode;
|
|
27
|
+
/** Children to render after text */
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* StreamText - Display streaming text with optional cursor.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* import { StreamText } from 'ai.matey.react.stream';
|
|
36
|
+
*
|
|
37
|
+
* function ChatMessage({ text, isStreaming }) {
|
|
38
|
+
* return (
|
|
39
|
+
* <StreamText
|
|
40
|
+
* text={text}
|
|
41
|
+
* isStreaming={isStreaming}
|
|
42
|
+
* showCursor={true}
|
|
43
|
+
* />
|
|
44
|
+
* );
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function StreamText({ text, isStreaming, showCursor, cursor, cursorBlinkInterval, className, renderText, children, }: StreamTextProps): import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
/**
|
|
50
|
+
* TypeWriter props.
|
|
51
|
+
*/
|
|
52
|
+
export interface TypeWriterProps {
|
|
53
|
+
/** Text to type */
|
|
54
|
+
text: string;
|
|
55
|
+
/** Typing speed in ms per character */
|
|
56
|
+
speed?: number;
|
|
57
|
+
/** Delay before starting in ms */
|
|
58
|
+
delay?: number;
|
|
59
|
+
/** Called when typing completes */
|
|
60
|
+
onComplete?: () => void;
|
|
61
|
+
/** Custom className */
|
|
62
|
+
className?: string;
|
|
63
|
+
/** Show cursor */
|
|
64
|
+
showCursor?: boolean;
|
|
65
|
+
/** Cursor character */
|
|
66
|
+
cursor?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* TypeWriter - Display text with typewriter effect.
|
|
70
|
+
*
|
|
71
|
+
* Simulates typing effect for non-streaming text.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* import { TypeWriter } from 'ai.matey.react.stream';
|
|
76
|
+
*
|
|
77
|
+
* function WelcomeMessage() {
|
|
78
|
+
* return (
|
|
79
|
+
* <TypeWriter
|
|
80
|
+
* text="Welcome to AI Matey!"
|
|
81
|
+
* speed={50}
|
|
82
|
+
* onComplete={() => console.log('Done typing')}
|
|
83
|
+
* />
|
|
84
|
+
* );
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare function TypeWriter({ text, speed, delay, onComplete, className, showCursor, cursor, }: TypeWriterProps): import("react/jsx-runtime").JSX.Element;
|
|
89
|
+
//# sourceMappingURL=stream-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-text.d.ts","sourceRoot":"","sources":["../../src/stream-text.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kCAAkC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IACzC,oCAAoC;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,WAAmB,EACnB,UAAiB,EACjB,MAAY,EACZ,mBAAyB,EACzB,SAAS,EACT,UAAU,EACV,QAAQ,GACT,EAAE,eAAe,2CAsCjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,KAAU,EACV,KAAS,EACT,UAAU,EACV,SAAS,EACT,UAAiB,EACjB,MAAY,GACb,EAAE,eAAe,2CAyCjB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream Utilities
|
|
3
|
+
*
|
|
4
|
+
* Helper functions for working with streams in React.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Options for creating a text stream.
|
|
10
|
+
*/
|
|
11
|
+
export interface CreateTextStreamOptions {
|
|
12
|
+
/** Called for each chunk */
|
|
13
|
+
onChunk?: (chunk: string) => void;
|
|
14
|
+
/** Called when stream completes */
|
|
15
|
+
onComplete?: (fullText: string) => void;
|
|
16
|
+
/** Called on error */
|
|
17
|
+
onError?: (error: Error) => void;
|
|
18
|
+
/** Abort signal */
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create a controlled text stream from a fetch response.
|
|
23
|
+
*
|
|
24
|
+
* @param response - Fetch response with streaming body
|
|
25
|
+
* @param options - Stream options
|
|
26
|
+
* @returns Promise resolving to full text
|
|
27
|
+
*/
|
|
28
|
+
export declare function createTextStream(response: Response, options?: CreateTextStreamOptions): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Parse Server-Sent Events (SSE) stream.
|
|
31
|
+
*
|
|
32
|
+
* @param response - Fetch response with SSE body
|
|
33
|
+
* @param options - Stream options
|
|
34
|
+
* @returns Async generator yielding parsed events
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseSSEStream(response: Response, options?: {
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
}): AsyncGenerator<SSEEvent, void, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* SSE Event structure.
|
|
41
|
+
*/
|
|
42
|
+
export interface SSEEvent {
|
|
43
|
+
/** Event type */
|
|
44
|
+
event?: string;
|
|
45
|
+
/** Event data */
|
|
46
|
+
data: string;
|
|
47
|
+
/** Event ID */
|
|
48
|
+
id?: string;
|
|
49
|
+
/** Retry interval */
|
|
50
|
+
retry?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Transform a ReadableStream with a function.
|
|
54
|
+
*
|
|
55
|
+
* @param stream - Source stream
|
|
56
|
+
* @param transform - Transform function
|
|
57
|
+
* @returns Transformed stream
|
|
58
|
+
*/
|
|
59
|
+
export declare function transformStream<T, U>(stream: ReadableStream<T>, transform: (chunk: T) => U | Promise<U>): ReadableStream<U>;
|
|
60
|
+
/**
|
|
61
|
+
* Merge multiple streams into one.
|
|
62
|
+
*
|
|
63
|
+
* @param streams - Streams to merge
|
|
64
|
+
* @returns Merged stream
|
|
65
|
+
*/
|
|
66
|
+
export declare function mergeStreams<T>(...streams: ReadableStream<T>[]): ReadableStream<T>;
|
|
67
|
+
/**
|
|
68
|
+
* Create a stream from an async iterable.
|
|
69
|
+
*
|
|
70
|
+
* @param iterable - Async iterable source
|
|
71
|
+
* @returns ReadableStream
|
|
72
|
+
*/
|
|
73
|
+
export declare function fromAsyncIterable<T>(iterable: AsyncIterable<T>): ReadableStream<T>;
|
|
74
|
+
/**
|
|
75
|
+
* Convert a ReadableStream to an async iterable.
|
|
76
|
+
*
|
|
77
|
+
* @param stream - ReadableStream source
|
|
78
|
+
* @returns Async iterable
|
|
79
|
+
*/
|
|
80
|
+
export declare function toAsyncIterable<T>(stream: ReadableStream<T>): AsyncGenerator<T, void, unknown>;
|
|
81
|
+
//# sourceMappingURL=stream-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-utils.d.ts","sourceRoot":"","sources":["../../src/stream-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,4BAA4B;IAC5B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,mCAAmC;IACnC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,sBAAsB;IACtB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,mBAAmB;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,MAAM,CAAC,CAoCjB;AAED;;;;;;GAMG;AACH,wBAAuB,cAAc,CACnC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACrC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAgDzC;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAiCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAClC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EACzB,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACtC,cAAc,CAAC,CAAC,CAAC,CAmBnB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,CAiClF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAkBlF;AAED;;;;;GAKG;AACH,wBAAuB,eAAe,CAAC,CAAC,EACtC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAgBlC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai.matey.react.stream",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "React streaming utilities for AI Matey - StreamProvider, StreamContext",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/cjs/index.js",
|
|
7
|
+
"module": "./dist/esm/index.js",
|
|
8
|
+
"types": "./dist/types/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/types/index.d.ts",
|
|
13
|
+
"default": "./dist/esm/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/types/index.d.ts",
|
|
17
|
+
"default": "./dist/cjs/index.js"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"readme.md",
|
|
24
|
+
"CHANGELOG.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "npm run build:esm && npm run build:cjs && npm run build:types",
|
|
29
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
30
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
31
|
+
"build:types": "tsc -p tsconfig.types.json",
|
|
32
|
+
"clean": "rm -rf dist",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"test": "vitest run"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"ai.matey.types": "*",
|
|
38
|
+
"ai.matey.react.core": "*"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": ">=18.0.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependenciesMeta": {
|
|
44
|
+
"react": {
|
|
45
|
+
"optional": false
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/react": "^18.2.0",
|
|
50
|
+
"react": "^18.2.0",
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"vitest": "^3.2.4"
|
|
53
|
+
},
|
|
54
|
+
"keywords": [
|
|
55
|
+
"ai",
|
|
56
|
+
"llm",
|
|
57
|
+
"react",
|
|
58
|
+
"streaming",
|
|
59
|
+
"context",
|
|
60
|
+
"provider",
|
|
61
|
+
"ai-matey"
|
|
62
|
+
],
|
|
63
|
+
"author": "AI Matey",
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"homepage": "https://github.com/johnhenry/ai.matey#readme",
|
|
66
|
+
"bugs": {
|
|
67
|
+
"url": "https://github.com/johnhenry/ai.matey/issues"
|
|
68
|
+
},
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "git+https://github.com/johnhenry/ai.matey.git",
|
|
72
|
+
"directory": "packages/react-stream"
|
|
73
|
+
},
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=18.0.0"
|
|
76
|
+
}
|
|
77
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# ai.matey.react.stream
|
|
2
|
+
|
|
3
|
+
React components and utilities for streaming AI responses.
|
|
4
|
+
|
|
5
|
+
Part of the [ai.matey](https://github.com/johnhenry/ai.matey) monorepo.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install ai.matey.react.stream
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { StreamProvider, useStreamContext, StreamText } from 'ai.matey.react.stream';
|
|
17
|
+
|
|
18
|
+
// Wrap your app with StreamProvider
|
|
19
|
+
function App() {
|
|
20
|
+
return (
|
|
21
|
+
<StreamProvider maxStreams={10}>
|
|
22
|
+
<ChatComponent />
|
|
23
|
+
</StreamProvider>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Use streaming in components
|
|
28
|
+
function ChatComponent() {
|
|
29
|
+
const { startStream, appendToStream, completeStream, getStream } = useStreamContext();
|
|
30
|
+
const [streamId, setStreamId] = useState<string | null>(null);
|
|
31
|
+
|
|
32
|
+
const handleSend = async () => {
|
|
33
|
+
const id = `msg-${Date.now()}`;
|
|
34
|
+
setStreamId(id);
|
|
35
|
+
startStream(id);
|
|
36
|
+
|
|
37
|
+
const response = await fetch('/api/chat', { method: 'POST' });
|
|
38
|
+
const reader = response.body?.getReader();
|
|
39
|
+
const decoder = new TextDecoder();
|
|
40
|
+
|
|
41
|
+
while (reader) {
|
|
42
|
+
const { done, value } = await reader.read();
|
|
43
|
+
if (done) break;
|
|
44
|
+
appendToStream(id, decoder.decode(value));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
completeStream(id);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const stream = streamId ? getStream(streamId) : null;
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div>
|
|
54
|
+
{stream && (
|
|
55
|
+
<StreamText
|
|
56
|
+
text={stream.text}
|
|
57
|
+
isStreaming={stream.isStreaming}
|
|
58
|
+
showCursor={true}
|
|
59
|
+
/>
|
|
60
|
+
)}
|
|
61
|
+
<button onClick={handleSend}>Send</button>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Exports
|
|
68
|
+
|
|
69
|
+
### Components
|
|
70
|
+
|
|
71
|
+
- `StreamProvider` - Context provider for stream state management
|
|
72
|
+
- `StreamText` - Display streaming text with cursor
|
|
73
|
+
- `TypeWriter` - Typewriter effect for static text
|
|
74
|
+
|
|
75
|
+
### Hooks
|
|
76
|
+
|
|
77
|
+
- `useStreamContext` - Access stream management functions
|
|
78
|
+
- `useStreamState` - Get state for a specific stream
|
|
79
|
+
|
|
80
|
+
### Utilities
|
|
81
|
+
|
|
82
|
+
- `createTextStream` - Create controlled text stream from fetch response
|
|
83
|
+
- `parseSSEStream` - Parse Server-Sent Events
|
|
84
|
+
- `transformStream` - Transform stream data
|
|
85
|
+
- `mergeStreams` - Merge multiple streams
|
|
86
|
+
- `fromAsyncIterable` - Convert async iterable to stream
|
|
87
|
+
- `toAsyncIterable` - Convert stream to async iterable
|
|
88
|
+
|
|
89
|
+
### Types
|
|
90
|
+
|
|
91
|
+
- `StreamState`, `StreamContextValue`, `StreamProviderProps`
|
|
92
|
+
- `StreamTextProps`, `TypeWriterProps`
|
|
93
|
+
- `CreateTextStreamOptions`, `SSEEvent`
|
|
94
|
+
|
|
95
|
+
## API Reference
|
|
96
|
+
|
|
97
|
+
### StreamProvider
|
|
98
|
+
|
|
99
|
+
Context provider for managing multiple concurrent streams.
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<StreamProvider maxStreams={100}>
|
|
103
|
+
{children}
|
|
104
|
+
</StreamProvider>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Props:**
|
|
108
|
+
- `maxStreams` - Maximum streams to keep (default: 100, oldest completed removed when exceeded)
|
|
109
|
+
|
|
110
|
+
### useStreamContext
|
|
111
|
+
|
|
112
|
+
Access stream management functions.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
const {
|
|
116
|
+
streams, // Map<string, StreamState> - All streams
|
|
117
|
+
getStream, // (id: string) => StreamState | undefined
|
|
118
|
+
startStream, // (id: string, metadata?: object) => void
|
|
119
|
+
updateStream, // (id: string, text: string) => void - Replace text
|
|
120
|
+
appendToStream, // (id: string, chunk: string) => void - Append text
|
|
121
|
+
completeStream, // (id: string) => void - Mark complete
|
|
122
|
+
setStreamError, // (id: string, error: Error) => void
|
|
123
|
+
removeStream, // (id: string) => void
|
|
124
|
+
clearAllStreams, // () => void
|
|
125
|
+
} = useStreamContext();
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### useStreamState
|
|
129
|
+
|
|
130
|
+
Get state for a specific stream by ID.
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
const stream = useStreamState('message-1');
|
|
134
|
+
// stream: { id, text, isStreaming, error, metadata } | undefined
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### StreamText
|
|
138
|
+
|
|
139
|
+
Display streaming text with optional blinking cursor.
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
<StreamText
|
|
143
|
+
text="Hello world"
|
|
144
|
+
isStreaming={true}
|
|
145
|
+
showCursor={true} // Show cursor while streaming
|
|
146
|
+
cursor="▋" // Cursor character
|
|
147
|
+
cursorBlinkInterval={500} // Blink speed in ms
|
|
148
|
+
className="my-class"
|
|
149
|
+
renderText={(text) => <Markdown>{text}</Markdown>}
|
|
150
|
+
/>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### TypeWriter
|
|
154
|
+
|
|
155
|
+
Simulate typing effect for non-streaming text.
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<TypeWriter
|
|
159
|
+
text="Welcome to AI Matey!"
|
|
160
|
+
speed={30} // ms per character
|
|
161
|
+
delay={500} // ms before starting
|
|
162
|
+
showCursor={true}
|
|
163
|
+
cursor="▋"
|
|
164
|
+
onComplete={() => console.log('Done!')}
|
|
165
|
+
/>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Stream Utilities
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import {
|
|
172
|
+
createTextStream,
|
|
173
|
+
parseSSEStream,
|
|
174
|
+
fromAsyncIterable,
|
|
175
|
+
} from 'ai.matey.react.stream';
|
|
176
|
+
|
|
177
|
+
// Create text stream from fetch response
|
|
178
|
+
const text = await createTextStream(response, {
|
|
179
|
+
onChunk: (chunk) => console.log(chunk),
|
|
180
|
+
onComplete: (fullText) => console.log('Done:', fullText),
|
|
181
|
+
signal: abortController.signal,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Parse SSE events
|
|
185
|
+
for await (const event of parseSSEStream(response)) {
|
|
186
|
+
console.log(event.data); // { type: 'data' | 'event', data: string }
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT - see [LICENSE](./LICENSE) for details.
|