@ragbits/api-client 0.0.2 → 0.0.3
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/README.md +252 -58
- package/dist/index.cjs +9 -0
- package/dist/index.d.ts +3 -220
- package/dist/index.js +8 -0
- package/dist/{index.d.cts → types.d.ts} +50 -69
- package/package.json +5 -4
- package/eslint.config.js +0 -21
- package/prettier.config.js +0 -6
- package/src/index.ts +0 -213
- package/src/test/RagbitsClient.test.ts +0 -484
- package/src/test/mocks/handlers.ts +0 -98
- package/src/test/setup.ts +0 -23
- package/src/test/types.test.ts +0 -35
- package/src/test/utils.ts +0 -28
- package/src/types.ts +0 -259
- package/tsconfig.json +0 -16
- package/vitest.config.ts +0 -20
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { RJSFSchema } from '@rjsf/utils';
|
|
2
|
-
|
|
3
2
|
/**
|
|
4
3
|
* Message roles for chat conversations
|
|
5
4
|
*/
|
|
6
|
-
declare enum MessageRole {
|
|
5
|
+
export declare enum MessageRole {
|
|
7
6
|
USER = "user",
|
|
8
7
|
ASSISTANT = "assistant",
|
|
9
8
|
SYSTEM = "system"
|
|
@@ -11,7 +10,7 @@ declare enum MessageRole {
|
|
|
11
10
|
/**
|
|
12
11
|
* Message structure for chat conversations
|
|
13
12
|
*/
|
|
14
|
-
interface Message {
|
|
13
|
+
export interface Message {
|
|
15
14
|
role: MessageRole;
|
|
16
15
|
content: string;
|
|
17
16
|
id?: string;
|
|
@@ -19,7 +18,7 @@ interface Message {
|
|
|
19
18
|
/**
|
|
20
19
|
* Reference structure for document references
|
|
21
20
|
*/
|
|
22
|
-
interface Reference {
|
|
21
|
+
export interface Reference {
|
|
23
22
|
title: string;
|
|
24
23
|
content: string;
|
|
25
24
|
url?: string;
|
|
@@ -27,28 +26,42 @@ interface Reference {
|
|
|
27
26
|
/**
|
|
28
27
|
* Response types from the API
|
|
29
28
|
*/
|
|
30
|
-
declare enum ChatResponseType {
|
|
29
|
+
export declare enum ChatResponseType {
|
|
31
30
|
MESSAGE = "message",
|
|
32
31
|
REFERENCE = "reference",
|
|
33
32
|
STATE_UPDATE = "state_update",
|
|
34
33
|
TEXT = "text",
|
|
35
34
|
MESSAGE_ID = "message_id",
|
|
36
|
-
CONVERSATION_ID = "conversation_id"
|
|
35
|
+
CONVERSATION_ID = "conversation_id",
|
|
36
|
+
LIVE_UPDATE = "live_update",
|
|
37
|
+
FOLLOWUP_MESSAGES = "followup_messages"
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
40
|
* Feedback types for user feedback
|
|
40
41
|
*/
|
|
41
|
-
declare enum FeedbackType {
|
|
42
|
+
export declare enum FeedbackType {
|
|
42
43
|
LIKE = "like",
|
|
43
44
|
DISLIKE = "dislike"
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
47
|
* Server state interface for state updates
|
|
47
48
|
*/
|
|
48
|
-
interface ServerState {
|
|
49
|
+
export interface ServerState {
|
|
49
50
|
state: Record<string, unknown>;
|
|
50
51
|
signature: string;
|
|
51
52
|
}
|
|
53
|
+
export declare enum LiveUpdateType {
|
|
54
|
+
START = "START",
|
|
55
|
+
FINISH = "FINISH"
|
|
56
|
+
}
|
|
57
|
+
export interface LiveUpdate {
|
|
58
|
+
update_id: string;
|
|
59
|
+
type: LiveUpdateType;
|
|
60
|
+
content: {
|
|
61
|
+
label: string;
|
|
62
|
+
description?: string;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
52
65
|
/**
|
|
53
66
|
* Specific chat response types
|
|
54
67
|
*/
|
|
@@ -72,14 +85,22 @@ interface StateUpdateChatResponse {
|
|
|
72
85
|
type: ChatResponseType.STATE_UPDATE;
|
|
73
86
|
content: ServerState;
|
|
74
87
|
}
|
|
88
|
+
interface LiveUpdateChatResponse {
|
|
89
|
+
type: ChatResponseType.LIVE_UPDATE;
|
|
90
|
+
content: LiveUpdate;
|
|
91
|
+
}
|
|
92
|
+
interface FollowupMessagesChatResponse {
|
|
93
|
+
type: ChatResponseType.FOLLOWUP_MESSAGES;
|
|
94
|
+
content: string[];
|
|
95
|
+
}
|
|
75
96
|
/**
|
|
76
97
|
* Typed chat response union
|
|
77
98
|
*/
|
|
78
|
-
type TypedChatResponse = TextChatResponse | ReferenceChatResponse | MessageIdChatResponse | ConversationIdChatResponse | StateUpdateChatResponse;
|
|
99
|
+
export type TypedChatResponse = TextChatResponse | ReferenceChatResponse | MessageIdChatResponse | ConversationIdChatResponse | StateUpdateChatResponse | LiveUpdateChatResponse | FollowupMessagesChatResponse;
|
|
79
100
|
/**
|
|
80
101
|
* Base chat request to the API
|
|
81
102
|
*/
|
|
82
|
-
interface ChatRequest {
|
|
103
|
+
export interface ChatRequest {
|
|
83
104
|
message: string;
|
|
84
105
|
history: Message[];
|
|
85
106
|
context?: Record<string, unknown>;
|
|
@@ -87,7 +108,7 @@ interface ChatRequest {
|
|
|
87
108
|
/**
|
|
88
109
|
* Feedback request to the API
|
|
89
110
|
*/
|
|
90
|
-
interface FeedbackRequest {
|
|
111
|
+
export interface FeedbackRequest {
|
|
91
112
|
message_id: string;
|
|
92
113
|
feedback: FeedbackType;
|
|
93
114
|
payload: Record<string, unknown> | null;
|
|
@@ -95,13 +116,13 @@ interface FeedbackRequest {
|
|
|
95
116
|
/**
|
|
96
117
|
* Feedback response from the API
|
|
97
118
|
*/
|
|
98
|
-
interface FeedbackResponse {
|
|
119
|
+
export interface FeedbackResponse {
|
|
99
120
|
status: string;
|
|
100
121
|
}
|
|
101
122
|
/**
|
|
102
123
|
* UI customization configuration
|
|
103
124
|
*/
|
|
104
|
-
interface UICustomization {
|
|
125
|
+
export interface UICustomization {
|
|
105
126
|
header: {
|
|
106
127
|
title?: string;
|
|
107
128
|
subtitle?: string;
|
|
@@ -112,7 +133,7 @@ interface UICustomization {
|
|
|
112
133
|
/**
|
|
113
134
|
* Configuration response from the API
|
|
114
135
|
*/
|
|
115
|
-
interface ConfigResponse {
|
|
136
|
+
export interface ConfigResponse {
|
|
116
137
|
feedback: {
|
|
117
138
|
like: {
|
|
118
139
|
enabled: boolean;
|
|
@@ -128,13 +149,13 @@ interface ConfigResponse {
|
|
|
128
149
|
/**
|
|
129
150
|
* Configuration for the client
|
|
130
151
|
*/
|
|
131
|
-
interface ClientConfig {
|
|
152
|
+
export interface ClientConfig {
|
|
132
153
|
baseUrl?: string;
|
|
133
154
|
}
|
|
134
155
|
/**
|
|
135
156
|
* Callbacks for handling streaming responses
|
|
136
157
|
*/
|
|
137
|
-
interface StreamCallbacks<T, E = Error> {
|
|
158
|
+
export interface StreamCallbacks<T, E = Error> {
|
|
138
159
|
onMessage: (data: T) => void | Promise<void>;
|
|
139
160
|
onError: (error: E) => void | Promise<void>;
|
|
140
161
|
onClose?: () => void | Promise<void>;
|
|
@@ -142,7 +163,7 @@ interface StreamCallbacks<T, E = Error> {
|
|
|
142
163
|
/**
|
|
143
164
|
* Regular API endpoint definitions with their request/response types
|
|
144
165
|
*/
|
|
145
|
-
interface ApiEndpoints {
|
|
166
|
+
export interface ApiEndpoints {
|
|
146
167
|
'/api/config': {
|
|
147
168
|
method: 'GET';
|
|
148
169
|
request: never;
|
|
@@ -157,7 +178,7 @@ interface ApiEndpoints {
|
|
|
157
178
|
/**
|
|
158
179
|
* Streaming API endpoint definitions with their request/stream response types
|
|
159
180
|
*/
|
|
160
|
-
interface StreamingEndpoints {
|
|
181
|
+
export interface StreamingEndpoints {
|
|
161
182
|
'/api/chat': {
|
|
162
183
|
method: 'POST';
|
|
163
184
|
request: ChatRequest;
|
|
@@ -167,39 +188,39 @@ interface StreamingEndpoints {
|
|
|
167
188
|
/**
|
|
168
189
|
* Extract endpoint paths as a union type
|
|
169
190
|
*/
|
|
170
|
-
type ApiEndpointPath = keyof ApiEndpoints;
|
|
191
|
+
export type ApiEndpointPath = keyof ApiEndpoints;
|
|
171
192
|
/**
|
|
172
193
|
* Extract streaming endpoint paths as a union type
|
|
173
194
|
*/
|
|
174
|
-
type StreamingEndpointPath = keyof StreamingEndpoints;
|
|
195
|
+
export type StreamingEndpointPath = keyof StreamingEndpoints;
|
|
175
196
|
/**
|
|
176
197
|
* Extract request type for a specific API endpoint
|
|
177
198
|
*/
|
|
178
|
-
type ApiEndpointRequest<T extends ApiEndpointPath> = ApiEndpoints[T]['request'];
|
|
199
|
+
export type ApiEndpointRequest<T extends ApiEndpointPath> = ApiEndpoints[T]['request'];
|
|
179
200
|
/**
|
|
180
201
|
* Extract response type for a specific API endpoint
|
|
181
202
|
*/
|
|
182
|
-
type ApiEndpointResponse<T extends ApiEndpointPath> = ApiEndpoints[T]['response'];
|
|
203
|
+
export type ApiEndpointResponse<T extends ApiEndpointPath> = ApiEndpoints[T]['response'];
|
|
183
204
|
/**
|
|
184
205
|
* Extract HTTP method for a specific API endpoint
|
|
185
206
|
*/
|
|
186
|
-
type ApiEndpointMethod<T extends ApiEndpointPath> = ApiEndpoints[T]['method'];
|
|
207
|
+
export type ApiEndpointMethod<T extends ApiEndpointPath> = ApiEndpoints[T]['method'];
|
|
187
208
|
/**
|
|
188
209
|
* Extract request type for a specific streaming endpoint
|
|
189
210
|
*/
|
|
190
|
-
type StreamingEndpointRequest<T extends StreamingEndpointPath> = StreamingEndpoints[T]['request'];
|
|
211
|
+
export type StreamingEndpointRequest<T extends StreamingEndpointPath> = StreamingEndpoints[T]['request'];
|
|
191
212
|
/**
|
|
192
213
|
* Extract stream response type for a specific streaming endpoint
|
|
193
214
|
*/
|
|
194
|
-
type StreamingEndpointStream<T extends StreamingEndpointPath> = StreamingEndpoints[T]['stream'];
|
|
215
|
+
export type StreamingEndpointStream<T extends StreamingEndpointPath> = StreamingEndpoints[T]['stream'];
|
|
195
216
|
/**
|
|
196
217
|
* Extract HTTP method for a specific streaming endpoint
|
|
197
218
|
*/
|
|
198
|
-
type StreamingEndpointMethod<T extends StreamingEndpointPath> = StreamingEndpoints[T]['method'];
|
|
219
|
+
export type StreamingEndpointMethod<T extends StreamingEndpointPath> = StreamingEndpoints[T]['method'];
|
|
199
220
|
/**
|
|
200
221
|
* Generic request options for API endpoints with typed methods and body
|
|
201
222
|
*/
|
|
202
|
-
interface TypedApiRequestOptions<T extends ApiEndpointPath> {
|
|
223
|
+
export interface TypedApiRequestOptions<T extends ApiEndpointPath> {
|
|
203
224
|
method?: ApiEndpointMethod<T>;
|
|
204
225
|
body?: ApiEndpointRequest<T> extends never ? undefined : ApiEndpointRequest<T>;
|
|
205
226
|
headers?: Record<string, string>;
|
|
@@ -208,50 +229,10 @@ interface TypedApiRequestOptions<T extends ApiEndpointPath> {
|
|
|
208
229
|
/**
|
|
209
230
|
* Typed request options for specific streaming endpoints
|
|
210
231
|
*/
|
|
211
|
-
interface TypedStreamRequestOptions<T extends StreamingEndpointPath> {
|
|
232
|
+
export interface TypedStreamRequestOptions<T extends StreamingEndpointPath> {
|
|
212
233
|
method?: StreamingEndpointMethod<T>;
|
|
213
234
|
body?: StreamingEndpointRequest<T>;
|
|
214
235
|
headers?: Record<string, string>;
|
|
215
236
|
signal?: AbortSignal;
|
|
216
237
|
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Client for communicating with the Ragbits API
|
|
220
|
-
*/
|
|
221
|
-
declare class RagbitsClient {
|
|
222
|
-
private readonly baseUrl;
|
|
223
|
-
/**
|
|
224
|
-
* @param config - Configuration object
|
|
225
|
-
*/
|
|
226
|
-
constructor(config?: ClientConfig);
|
|
227
|
-
/**
|
|
228
|
-
* Get the base URL used by this client
|
|
229
|
-
*/
|
|
230
|
-
getBaseUrl(): string;
|
|
231
|
-
/**
|
|
232
|
-
* Build full API URL from path
|
|
233
|
-
* @private
|
|
234
|
-
*/
|
|
235
|
-
private _buildApiUrl;
|
|
236
|
-
/**
|
|
237
|
-
* Make a request to the API
|
|
238
|
-
* @private
|
|
239
|
-
*/
|
|
240
|
-
private _makeRequest;
|
|
241
|
-
/**
|
|
242
|
-
* Method to make API requests to known endpoints only
|
|
243
|
-
* @param endpoint - API endpoint path (must be predefined)
|
|
244
|
-
* @param options - Typed request options for the specific endpoint
|
|
245
|
-
*/
|
|
246
|
-
makeRequest<T extends ApiEndpointPath>(endpoint: T, options?: TypedApiRequestOptions<T>): Promise<ApiEndpointResponse<T>>;
|
|
247
|
-
/**
|
|
248
|
-
* Method for streaming requests to known endpoints only
|
|
249
|
-
* @param endpoint - Streaming endpoint path (must be predefined)
|
|
250
|
-
* @param data - Request data
|
|
251
|
-
* @param callbacks - Stream callbacks
|
|
252
|
-
* @param signal - Optional AbortSignal for cancelling the request
|
|
253
|
-
*/
|
|
254
|
-
makeStreamRequest<T extends StreamingEndpointPath>(endpoint: T, data: StreamingEndpointRequest<T>, callbacks: StreamCallbacks<StreamingEndpointStream<T>>, signal?: AbortSignal): () => void;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export { type ApiEndpointMethod, type ApiEndpointPath, type ApiEndpointRequest, type ApiEndpointResponse, type ApiEndpoints, type ChatRequest, ChatResponseType, type ClientConfig, type ConfigResponse, type FeedbackRequest, type FeedbackResponse, FeedbackType, type Message, MessageRole, RagbitsClient, type Reference, type ServerState, type StreamCallbacks, type StreamingEndpointMethod, type StreamingEndpointPath, type StreamingEndpointRequest, type StreamingEndpointStream, type StreamingEndpoints, type TypedApiRequestOptions, type TypedChatResponse, type TypedStreamRequestOptions, type UICustomization };
|
|
238
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ragbits/api-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "JavaScript client for the Ragbits API",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -14,14 +14,15 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "tsup src/index.ts --format cjs,esm --
|
|
18
|
-
"dev": "
|
|
17
|
+
"build": "npm run clean && tsup src/index.ts --format cjs,esm && tsc --emitDeclarationOnly --declaration --project tsconfig.json",
|
|
18
|
+
"dev": "tsc -b . --watch",
|
|
19
19
|
"test": "vitest",
|
|
20
20
|
"test:run": "vitest run",
|
|
21
21
|
"test:coverage": "vitest run --coverage",
|
|
22
22
|
"lint": "eslint .",
|
|
23
23
|
"format": "prettier --write .",
|
|
24
|
-
"format:check": "prettier --check ."
|
|
24
|
+
"format:check": "prettier --check .",
|
|
25
|
+
"clean": "rm -rf ./dist"
|
|
25
26
|
},
|
|
26
27
|
"keywords": [
|
|
27
28
|
"ragbits",
|
package/eslint.config.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import js from '@eslint/js'
|
|
2
|
-
import globals from 'globals'
|
|
3
|
-
import tseslint from 'typescript-eslint'
|
|
4
|
-
|
|
5
|
-
export default tseslint.config(
|
|
6
|
-
{ ignores: ['dist', 'coverage'] },
|
|
7
|
-
{
|
|
8
|
-
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
9
|
-
files: ['**/*.{ts,tsx}'],
|
|
10
|
-
languageOptions: {
|
|
11
|
-
ecmaVersion: 2020,
|
|
12
|
-
globals: globals.node,
|
|
13
|
-
},
|
|
14
|
-
rules: {
|
|
15
|
-
'@typescript-eslint/no-unused-vars': [
|
|
16
|
-
'error',
|
|
17
|
-
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
|
|
18
|
-
],
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
)
|
package/prettier.config.js
DELETED
package/src/index.ts
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ClientConfig,
|
|
3
|
-
StreamCallbacks,
|
|
4
|
-
ApiEndpointPath,
|
|
5
|
-
ApiEndpointResponse,
|
|
6
|
-
TypedApiRequestOptions,
|
|
7
|
-
StreamingEndpointPath,
|
|
8
|
-
StreamingEndpointRequest,
|
|
9
|
-
StreamingEndpointStream,
|
|
10
|
-
} from './types'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Client for communicating with the Ragbits API
|
|
14
|
-
*/
|
|
15
|
-
export class RagbitsClient {
|
|
16
|
-
private readonly baseUrl: string
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @param config - Configuration object
|
|
20
|
-
*/
|
|
21
|
-
constructor(config: ClientConfig = {}) {
|
|
22
|
-
this.baseUrl = config.baseUrl || 'http://127.0.0.1:8000'
|
|
23
|
-
|
|
24
|
-
// Validate the base URL
|
|
25
|
-
try {
|
|
26
|
-
new URL(this.baseUrl)
|
|
27
|
-
} catch {
|
|
28
|
-
throw new Error(
|
|
29
|
-
`Invalid base URL: ${this.baseUrl}. Please provide a valid URL.`
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (this.baseUrl.endsWith('/')) {
|
|
34
|
-
this.baseUrl = this.baseUrl.slice(0, -1)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Get the base URL used by this client
|
|
40
|
-
*/
|
|
41
|
-
getBaseUrl(): string {
|
|
42
|
-
return this.baseUrl
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Build full API URL from path
|
|
47
|
-
* @private
|
|
48
|
-
*/
|
|
49
|
-
private _buildApiUrl(path: string): string {
|
|
50
|
-
return `${this.baseUrl}${path}`
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Make a request to the API
|
|
55
|
-
* @private
|
|
56
|
-
*/
|
|
57
|
-
private async _makeRequest(
|
|
58
|
-
url: string,
|
|
59
|
-
options: RequestInit = {}
|
|
60
|
-
): Promise<Response> {
|
|
61
|
-
const defaultOptions: RequestInit = {
|
|
62
|
-
headers: {
|
|
63
|
-
'Content-Type': 'application/json',
|
|
64
|
-
},
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const response = await fetch(url, { ...defaultOptions, ...options })
|
|
68
|
-
if (!response.ok) {
|
|
69
|
-
throw new Error(`HTTP error! status: ${response.status}`)
|
|
70
|
-
}
|
|
71
|
-
return response
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Method to make API requests to known endpoints only
|
|
76
|
-
* @param endpoint - API endpoint path (must be predefined)
|
|
77
|
-
* @param options - Typed request options for the specific endpoint
|
|
78
|
-
*/
|
|
79
|
-
async makeRequest<T extends ApiEndpointPath>(
|
|
80
|
-
endpoint: T,
|
|
81
|
-
options?: TypedApiRequestOptions<T>
|
|
82
|
-
): Promise<ApiEndpointResponse<T>> {
|
|
83
|
-
const {
|
|
84
|
-
method = 'GET',
|
|
85
|
-
body,
|
|
86
|
-
headers = {},
|
|
87
|
-
...restOptions
|
|
88
|
-
} = options || {}
|
|
89
|
-
|
|
90
|
-
const requestOptions: RequestInit = {
|
|
91
|
-
method,
|
|
92
|
-
headers,
|
|
93
|
-
...restOptions, // This will include signal and other fetch options
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (body && method !== 'GET') {
|
|
97
|
-
requestOptions.body =
|
|
98
|
-
typeof body === 'string' ? body : JSON.stringify(body)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const response = await this._makeRequest(
|
|
102
|
-
this._buildApiUrl(endpoint),
|
|
103
|
-
requestOptions
|
|
104
|
-
)
|
|
105
|
-
return response.json()
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Method for streaming requests to known endpoints only
|
|
110
|
-
* @param endpoint - Streaming endpoint path (must be predefined)
|
|
111
|
-
* @param data - Request data
|
|
112
|
-
* @param callbacks - Stream callbacks
|
|
113
|
-
* @param signal - Optional AbortSignal for cancelling the request
|
|
114
|
-
*/
|
|
115
|
-
makeStreamRequest<T extends StreamingEndpointPath>(
|
|
116
|
-
endpoint: T,
|
|
117
|
-
data: StreamingEndpointRequest<T>,
|
|
118
|
-
callbacks: StreamCallbacks<StreamingEndpointStream<T>>,
|
|
119
|
-
signal?: AbortSignal
|
|
120
|
-
): () => void {
|
|
121
|
-
let isCancelled = false
|
|
122
|
-
|
|
123
|
-
const processStream = async (response: Response): Promise<void> => {
|
|
124
|
-
const reader = response.body
|
|
125
|
-
?.pipeThrough(new TextDecoderStream())
|
|
126
|
-
.getReader()
|
|
127
|
-
|
|
128
|
-
if (!reader) {
|
|
129
|
-
throw new Error('Response body is null')
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
while (!isCancelled && !signal?.aborted) {
|
|
133
|
-
try {
|
|
134
|
-
const { value, done } = await reader.read()
|
|
135
|
-
if (done) {
|
|
136
|
-
callbacks.onClose?.()
|
|
137
|
-
break
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const lines = value.split('\n')
|
|
141
|
-
for (const line of lines) {
|
|
142
|
-
if (!line.startsWith('data: ')) continue
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
const jsonString = line.replace('data: ', '').trim()
|
|
146
|
-
const parsedData = JSON.parse(
|
|
147
|
-
jsonString
|
|
148
|
-
) as StreamingEndpointStream<T>
|
|
149
|
-
await callbacks.onMessage(parsedData)
|
|
150
|
-
} catch (parseError) {
|
|
151
|
-
console.error('Error parsing JSON:', parseError)
|
|
152
|
-
await callbacks.onError(
|
|
153
|
-
new Error('Error processing server response')
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
} catch (streamError) {
|
|
158
|
-
console.error('Stream error:', streamError)
|
|
159
|
-
await callbacks.onError(new Error('Error reading stream'))
|
|
160
|
-
break
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const startStream = async (): Promise<void> => {
|
|
166
|
-
try {
|
|
167
|
-
const response = await fetch(this._buildApiUrl(endpoint), {
|
|
168
|
-
method: 'POST',
|
|
169
|
-
headers: {
|
|
170
|
-
'Content-Type': 'application/json',
|
|
171
|
-
Accept: 'text/event-stream',
|
|
172
|
-
},
|
|
173
|
-
body: JSON.stringify(data),
|
|
174
|
-
signal,
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
if (!response.ok) {
|
|
178
|
-
throw new Error(`HTTP error! status: ${response.status}`)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
await processStream(response)
|
|
182
|
-
} catch (error) {
|
|
183
|
-
if (signal?.aborted) {
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
console.error('Request error:', error)
|
|
188
|
-
const errorMessage =
|
|
189
|
-
error instanceof Error
|
|
190
|
-
? error.message
|
|
191
|
-
: 'Error connecting to server'
|
|
192
|
-
await callbacks.onError(new Error(errorMessage))
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
try {
|
|
197
|
-
startStream()
|
|
198
|
-
} catch (error) {
|
|
199
|
-
const errorMessage =
|
|
200
|
-
error instanceof Error
|
|
201
|
-
? error.message
|
|
202
|
-
: 'Failed to start stream'
|
|
203
|
-
callbacks.onError(new Error(errorMessage))
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return () => {
|
|
207
|
-
isCancelled = true
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Re-export types
|
|
213
|
-
export * from './types'
|