@ragbits/api-client 0.0.3 → 1.4.0-dev.202512021005
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 +51 -101
- package/__tests__/mocks/handlers.ts +98 -0
- package/__tests__/setup.ts +23 -0
- package/__tests__/utils.ts +45 -0
- package/dist/autogen.types.d.ts +495 -0
- package/dist/index.cjs +149 -55
- package/dist/index.d.ts +14 -5
- package/dist/index.js +146 -53
- package/dist/types.d.ts +38 -198
- package/package.json +8 -4
package/dist/index.cjs
CHANGED
|
@@ -20,42 +20,40 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
23
|
+
AuthType: () => AuthType,
|
|
24
24
|
FeedbackType: () => FeedbackType,
|
|
25
25
|
LiveUpdateType: () => LiveUpdateType,
|
|
26
26
|
MessageRole: () => MessageRole,
|
|
27
|
-
RagbitsClient: () => RagbitsClient
|
|
27
|
+
RagbitsClient: () => RagbitsClient,
|
|
28
|
+
TaskStatus: () => TaskStatus
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(index_exports);
|
|
30
31
|
|
|
31
|
-
// src/types.ts
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
LiveUpdateType2["FINISH"] = "FINISH";
|
|
57
|
-
return LiveUpdateType2;
|
|
58
|
-
})(LiveUpdateType || {});
|
|
32
|
+
// src/autogen.types.ts
|
|
33
|
+
var FeedbackType = {
|
|
34
|
+
Like: "like",
|
|
35
|
+
Dislike: "dislike"
|
|
36
|
+
};
|
|
37
|
+
var LiveUpdateType = {
|
|
38
|
+
Start: "START",
|
|
39
|
+
Finish: "FINISH"
|
|
40
|
+
};
|
|
41
|
+
var MessageRole = {
|
|
42
|
+
User: "user",
|
|
43
|
+
Assistant: "assistant",
|
|
44
|
+
System: "system"
|
|
45
|
+
};
|
|
46
|
+
var TaskStatus = {
|
|
47
|
+
Pending: "pending",
|
|
48
|
+
InProgress: "in_progress",
|
|
49
|
+
Completed: "completed",
|
|
50
|
+
Failed: "failed",
|
|
51
|
+
Cancelled: "cancelled",
|
|
52
|
+
Retrying: "retrying"
|
|
53
|
+
};
|
|
54
|
+
var AuthType = {
|
|
55
|
+
Credentials: "credentials"
|
|
56
|
+
};
|
|
59
57
|
|
|
60
58
|
// src/index.ts
|
|
61
59
|
var RagbitsClient = class {
|
|
@@ -63,7 +61,15 @@ var RagbitsClient = class {
|
|
|
63
61
|
* @param config - Configuration object
|
|
64
62
|
*/
|
|
65
63
|
constructor(config = {}) {
|
|
66
|
-
this.
|
|
64
|
+
this.chunkQueue = /* @__PURE__ */ new Map();
|
|
65
|
+
this.baseUrl = config.baseUrl ?? "";
|
|
66
|
+
this.auth = config.auth;
|
|
67
|
+
if (this.baseUrl.endsWith("/")) {
|
|
68
|
+
this.baseUrl = this.baseUrl.slice(0, -1);
|
|
69
|
+
}
|
|
70
|
+
if (!this.baseUrl) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
67
73
|
try {
|
|
68
74
|
new URL(this.baseUrl);
|
|
69
75
|
} catch {
|
|
@@ -71,9 +77,6 @@ var RagbitsClient = class {
|
|
|
71
77
|
`Invalid base URL: ${this.baseUrl}. Please provide a valid URL.`
|
|
72
78
|
);
|
|
73
79
|
}
|
|
74
|
-
if (this.baseUrl.endsWith("/")) {
|
|
75
|
-
this.baseUrl = this.baseUrl.slice(0, -1);
|
|
76
|
-
}
|
|
77
80
|
}
|
|
78
81
|
/**
|
|
79
82
|
* Get the base URL used by this client
|
|
@@ -93,12 +96,20 @@ var RagbitsClient = class {
|
|
|
93
96
|
* @private
|
|
94
97
|
*/
|
|
95
98
|
async _makeRequest(url, options = {}) {
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
const defaultHeaders = {
|
|
100
|
+
"Content-Type": "application/json"
|
|
101
|
+
};
|
|
102
|
+
const headers = {
|
|
103
|
+
...defaultHeaders,
|
|
104
|
+
...this.normalizeHeaders(options.headers)
|
|
100
105
|
};
|
|
101
|
-
|
|
106
|
+
if (this.auth?.getToken) {
|
|
107
|
+
headers["Authorization"] = `Bearer ${this.auth.getToken()}`;
|
|
108
|
+
}
|
|
109
|
+
const response = await fetch(url, { ...options, headers });
|
|
110
|
+
if (response.status === 401) {
|
|
111
|
+
this.auth?.onUnauthorized?.();
|
|
112
|
+
}
|
|
102
113
|
if (!response.ok) {
|
|
103
114
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
104
115
|
}
|
|
@@ -106,7 +117,7 @@ var RagbitsClient = class {
|
|
|
106
117
|
}
|
|
107
118
|
/**
|
|
108
119
|
* Method to make API requests to known endpoints only
|
|
109
|
-
* @param endpoint - API endpoint path
|
|
120
|
+
* @param endpoint - API endpoint path
|
|
110
121
|
* @param options - Typed request options for the specific endpoint
|
|
111
122
|
*/
|
|
112
123
|
async makeRequest(endpoint, options) {
|
|
@@ -126,25 +137,26 @@ var RagbitsClient = class {
|
|
|
126
137
|
requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
|
|
127
138
|
}
|
|
128
139
|
const response = await this._makeRequest(
|
|
129
|
-
this._buildApiUrl(endpoint),
|
|
140
|
+
this._buildApiUrl(endpoint.toString()),
|
|
130
141
|
requestOptions
|
|
131
142
|
);
|
|
132
143
|
return response.json();
|
|
133
144
|
}
|
|
134
145
|
/**
|
|
135
146
|
* Method for streaming requests to known endpoints only
|
|
136
|
-
* @param endpoint - Streaming endpoint path
|
|
147
|
+
* @param endpoint - Streaming endpoint path
|
|
137
148
|
* @param data - Request data
|
|
138
149
|
* @param callbacks - Stream callbacks
|
|
139
150
|
* @param signal - Optional AbortSignal for cancelling the request
|
|
140
151
|
*/
|
|
141
|
-
makeStreamRequest(endpoint, data, callbacks, signal) {
|
|
152
|
+
makeStreamRequest(endpoint, data, callbacks, signal, customHeaders) {
|
|
142
153
|
let isCancelled = false;
|
|
143
154
|
const processStream = async (response) => {
|
|
144
155
|
const reader = response.body?.pipeThrough(new TextDecoderStream()).getReader();
|
|
145
156
|
if (!reader) {
|
|
146
157
|
throw new Error("Response body is null");
|
|
147
158
|
}
|
|
159
|
+
let buffer = "";
|
|
148
160
|
while (!isCancelled && !signal?.aborted) {
|
|
149
161
|
try {
|
|
150
162
|
const { value, done } = await reader.read();
|
|
@@ -152,7 +164,9 @@ var RagbitsClient = class {
|
|
|
152
164
|
callbacks.onClose?.();
|
|
153
165
|
break;
|
|
154
166
|
}
|
|
155
|
-
|
|
167
|
+
buffer += value;
|
|
168
|
+
const lines = buffer.split("\n");
|
|
169
|
+
buffer = lines.pop() ?? "";
|
|
156
170
|
for (const line of lines) {
|
|
157
171
|
if (!line.startsWith("data: ")) continue;
|
|
158
172
|
try {
|
|
@@ -160,7 +174,14 @@ var RagbitsClient = class {
|
|
|
160
174
|
const parsedData = JSON.parse(
|
|
161
175
|
jsonString
|
|
162
176
|
);
|
|
177
|
+
if (parsedData.type === "chunked_content") {
|
|
178
|
+
this.handleChunkedContent(parsedData, callbacks);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
163
181
|
await callbacks.onMessage(parsedData);
|
|
182
|
+
await new Promise(
|
|
183
|
+
(resolve) => setTimeout(resolve, 0)
|
|
184
|
+
);
|
|
164
185
|
} catch (parseError) {
|
|
165
186
|
console.error("Error parsing JSON:", parseError);
|
|
166
187
|
await callbacks.onError(
|
|
@@ -169,6 +190,9 @@ var RagbitsClient = class {
|
|
|
169
190
|
}
|
|
170
191
|
}
|
|
171
192
|
} catch (streamError) {
|
|
193
|
+
if (signal?.aborted) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
172
196
|
console.error("Stream error:", streamError);
|
|
173
197
|
await callbacks.onError(new Error("Error reading stream"));
|
|
174
198
|
break;
|
|
@@ -177,15 +201,29 @@ var RagbitsClient = class {
|
|
|
177
201
|
};
|
|
178
202
|
const startStream = async () => {
|
|
179
203
|
try {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
204
|
+
const defaultHeaders = {
|
|
205
|
+
"Content-Type": "application/json",
|
|
206
|
+
Accept: "text/event-stream"
|
|
207
|
+
};
|
|
208
|
+
const headers = {
|
|
209
|
+
...defaultHeaders,
|
|
210
|
+
...customHeaders
|
|
211
|
+
};
|
|
212
|
+
if (this.auth?.getToken) {
|
|
213
|
+
headers["Authorization"] = `Bearer ${this.auth.getToken()}`;
|
|
214
|
+
}
|
|
215
|
+
const response = await fetch(
|
|
216
|
+
this._buildApiUrl(endpoint.toString()),
|
|
217
|
+
{
|
|
218
|
+
method: "POST",
|
|
219
|
+
headers,
|
|
220
|
+
body: JSON.stringify(data),
|
|
221
|
+
signal
|
|
222
|
+
}
|
|
223
|
+
);
|
|
224
|
+
if (response.status === 401) {
|
|
225
|
+
this.auth?.onUnauthorized?.();
|
|
226
|
+
}
|
|
189
227
|
if (!response.ok) {
|
|
190
228
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
191
229
|
}
|
|
@@ -209,12 +247,68 @@ var RagbitsClient = class {
|
|
|
209
247
|
isCancelled = true;
|
|
210
248
|
};
|
|
211
249
|
}
|
|
250
|
+
normalizeHeaders(init) {
|
|
251
|
+
if (!init) return {};
|
|
252
|
+
if (init instanceof Headers) {
|
|
253
|
+
return Object.fromEntries(init.entries());
|
|
254
|
+
}
|
|
255
|
+
if (Array.isArray(init)) {
|
|
256
|
+
return Object.fromEntries(init);
|
|
257
|
+
}
|
|
258
|
+
return init;
|
|
259
|
+
}
|
|
260
|
+
async handleChunkedContent(data, callbacks) {
|
|
261
|
+
const response = data;
|
|
262
|
+
const content = response.content;
|
|
263
|
+
const {
|
|
264
|
+
content_type: contentType,
|
|
265
|
+
id,
|
|
266
|
+
chunk_index: chunkIndex,
|
|
267
|
+
total_chunks: totalChunks,
|
|
268
|
+
mime_type: mimeType,
|
|
269
|
+
data: chunkData
|
|
270
|
+
} = content;
|
|
271
|
+
if (!this.chunkQueue.has(id)) {
|
|
272
|
+
this.chunkQueue.set(id, {
|
|
273
|
+
chunks: /* @__PURE__ */ new Map(),
|
|
274
|
+
totalChunks,
|
|
275
|
+
mimeType
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
const imageInfo = this.chunkQueue.get(id);
|
|
279
|
+
imageInfo.chunks.set(chunkIndex, chunkData);
|
|
280
|
+
if (imageInfo.chunks.size !== totalChunks) return;
|
|
281
|
+
const sortedChunks = Array.from(
|
|
282
|
+
{ length: totalChunks },
|
|
283
|
+
(_, i) => imageInfo.chunks.get(i)
|
|
284
|
+
);
|
|
285
|
+
const completeBase64 = sortedChunks.join("");
|
|
286
|
+
try {
|
|
287
|
+
atob(completeBase64);
|
|
288
|
+
} catch (e) {
|
|
289
|
+
this.chunkQueue.delete(id);
|
|
290
|
+
console.error("\u274C Invalid base64 data: ", e);
|
|
291
|
+
await callbacks.onError(new Error("Error reading stream"));
|
|
292
|
+
}
|
|
293
|
+
if (contentType === "image") {
|
|
294
|
+
const completeImageResponse = {
|
|
295
|
+
type: "image",
|
|
296
|
+
content: {
|
|
297
|
+
id,
|
|
298
|
+
url: `${imageInfo.mimeType},${completeBase64}`
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
await callbacks.onMessage(completeImageResponse);
|
|
302
|
+
}
|
|
303
|
+
this.chunkQueue.delete(id);
|
|
304
|
+
}
|
|
212
305
|
};
|
|
213
306
|
// Annotate the CommonJS export names for ESM import in node:
|
|
214
307
|
0 && (module.exports = {
|
|
215
|
-
|
|
308
|
+
AuthType,
|
|
216
309
|
FeedbackType,
|
|
217
310
|
LiveUpdateType,
|
|
218
311
|
MessageRole,
|
|
219
|
-
RagbitsClient
|
|
312
|
+
RagbitsClient,
|
|
313
|
+
TaskStatus
|
|
220
314
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { ClientConfig, StreamCallbacks,
|
|
1
|
+
import type { ClientConfig, StreamCallbacks, BaseApiEndpoints, EndpointDefinition, EndpointResponse, RequestOptions, BaseStreamingEndpoints, EndpointRequest } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Client for communicating with the Ragbits API
|
|
4
4
|
*/
|
|
5
5
|
export declare class RagbitsClient {
|
|
6
6
|
private readonly baseUrl;
|
|
7
|
+
private readonly auth;
|
|
8
|
+
private chunkQueue;
|
|
7
9
|
/**
|
|
8
10
|
* @param config - Configuration object
|
|
9
11
|
*/
|
|
@@ -24,17 +26,24 @@ export declare class RagbitsClient {
|
|
|
24
26
|
private _makeRequest;
|
|
25
27
|
/**
|
|
26
28
|
* Method to make API requests to known endpoints only
|
|
27
|
-
* @param endpoint - API endpoint path
|
|
29
|
+
* @param endpoint - API endpoint path
|
|
28
30
|
* @param options - Typed request options for the specific endpoint
|
|
29
31
|
*/
|
|
30
|
-
makeRequest<
|
|
32
|
+
makeRequest<Endpoints extends {
|
|
33
|
+
[K in keyof Endpoints]: EndpointDefinition;
|
|
34
|
+
} = BaseApiEndpoints, URL extends keyof Endpoints = keyof Endpoints>(endpoint: URL, options?: RequestOptions<URL, Endpoints>): Promise<EndpointResponse<URL, Endpoints>>;
|
|
31
35
|
/**
|
|
32
36
|
* Method for streaming requests to known endpoints only
|
|
33
|
-
* @param endpoint - Streaming endpoint path
|
|
37
|
+
* @param endpoint - Streaming endpoint path
|
|
34
38
|
* @param data - Request data
|
|
35
39
|
* @param callbacks - Stream callbacks
|
|
36
40
|
* @param signal - Optional AbortSignal for cancelling the request
|
|
37
41
|
*/
|
|
38
|
-
makeStreamRequest<
|
|
42
|
+
makeStreamRequest<Endpoints extends {
|
|
43
|
+
[K in keyof Endpoints]: EndpointDefinition;
|
|
44
|
+
} = BaseStreamingEndpoints, URL extends keyof Endpoints = keyof Endpoints>(endpoint: URL, data: EndpointRequest<URL, Endpoints>, callbacks: StreamCallbacks<EndpointResponse<URL, Endpoints>>, signal?: AbortSignal, customHeaders?: Record<string, string>): () => void;
|
|
45
|
+
private normalizeHeaders;
|
|
46
|
+
private handleChunkedContent;
|
|
39
47
|
}
|
|
40
48
|
export * from './types';
|
|
49
|
+
export * from './autogen.types';
|
package/dist/index.js
CHANGED
|
@@ -1,31 +1,28 @@
|
|
|
1
|
-
// src/types.ts
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
LiveUpdateType2["FINISH"] = "FINISH";
|
|
27
|
-
return LiveUpdateType2;
|
|
28
|
-
})(LiveUpdateType || {});
|
|
1
|
+
// src/autogen.types.ts
|
|
2
|
+
var FeedbackType = {
|
|
3
|
+
Like: "like",
|
|
4
|
+
Dislike: "dislike"
|
|
5
|
+
};
|
|
6
|
+
var LiveUpdateType = {
|
|
7
|
+
Start: "START",
|
|
8
|
+
Finish: "FINISH"
|
|
9
|
+
};
|
|
10
|
+
var MessageRole = {
|
|
11
|
+
User: "user",
|
|
12
|
+
Assistant: "assistant",
|
|
13
|
+
System: "system"
|
|
14
|
+
};
|
|
15
|
+
var TaskStatus = {
|
|
16
|
+
Pending: "pending",
|
|
17
|
+
InProgress: "in_progress",
|
|
18
|
+
Completed: "completed",
|
|
19
|
+
Failed: "failed",
|
|
20
|
+
Cancelled: "cancelled",
|
|
21
|
+
Retrying: "retrying"
|
|
22
|
+
};
|
|
23
|
+
var AuthType = {
|
|
24
|
+
Credentials: "credentials"
|
|
25
|
+
};
|
|
29
26
|
|
|
30
27
|
// src/index.ts
|
|
31
28
|
var RagbitsClient = class {
|
|
@@ -33,7 +30,15 @@ var RagbitsClient = class {
|
|
|
33
30
|
* @param config - Configuration object
|
|
34
31
|
*/
|
|
35
32
|
constructor(config = {}) {
|
|
36
|
-
this.
|
|
33
|
+
this.chunkQueue = /* @__PURE__ */ new Map();
|
|
34
|
+
this.baseUrl = config.baseUrl ?? "";
|
|
35
|
+
this.auth = config.auth;
|
|
36
|
+
if (this.baseUrl.endsWith("/")) {
|
|
37
|
+
this.baseUrl = this.baseUrl.slice(0, -1);
|
|
38
|
+
}
|
|
39
|
+
if (!this.baseUrl) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
37
42
|
try {
|
|
38
43
|
new URL(this.baseUrl);
|
|
39
44
|
} catch {
|
|
@@ -41,9 +46,6 @@ var RagbitsClient = class {
|
|
|
41
46
|
`Invalid base URL: ${this.baseUrl}. Please provide a valid URL.`
|
|
42
47
|
);
|
|
43
48
|
}
|
|
44
|
-
if (this.baseUrl.endsWith("/")) {
|
|
45
|
-
this.baseUrl = this.baseUrl.slice(0, -1);
|
|
46
|
-
}
|
|
47
49
|
}
|
|
48
50
|
/**
|
|
49
51
|
* Get the base URL used by this client
|
|
@@ -63,12 +65,20 @@ var RagbitsClient = class {
|
|
|
63
65
|
* @private
|
|
64
66
|
*/
|
|
65
67
|
async _makeRequest(url, options = {}) {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const defaultHeaders = {
|
|
69
|
+
"Content-Type": "application/json"
|
|
70
|
+
};
|
|
71
|
+
const headers = {
|
|
72
|
+
...defaultHeaders,
|
|
73
|
+
...this.normalizeHeaders(options.headers)
|
|
70
74
|
};
|
|
71
|
-
|
|
75
|
+
if (this.auth?.getToken) {
|
|
76
|
+
headers["Authorization"] = `Bearer ${this.auth.getToken()}`;
|
|
77
|
+
}
|
|
78
|
+
const response = await fetch(url, { ...options, headers });
|
|
79
|
+
if (response.status === 401) {
|
|
80
|
+
this.auth?.onUnauthorized?.();
|
|
81
|
+
}
|
|
72
82
|
if (!response.ok) {
|
|
73
83
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
74
84
|
}
|
|
@@ -76,7 +86,7 @@ var RagbitsClient = class {
|
|
|
76
86
|
}
|
|
77
87
|
/**
|
|
78
88
|
* Method to make API requests to known endpoints only
|
|
79
|
-
* @param endpoint - API endpoint path
|
|
89
|
+
* @param endpoint - API endpoint path
|
|
80
90
|
* @param options - Typed request options for the specific endpoint
|
|
81
91
|
*/
|
|
82
92
|
async makeRequest(endpoint, options) {
|
|
@@ -96,25 +106,26 @@ var RagbitsClient = class {
|
|
|
96
106
|
requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
|
|
97
107
|
}
|
|
98
108
|
const response = await this._makeRequest(
|
|
99
|
-
this._buildApiUrl(endpoint),
|
|
109
|
+
this._buildApiUrl(endpoint.toString()),
|
|
100
110
|
requestOptions
|
|
101
111
|
);
|
|
102
112
|
return response.json();
|
|
103
113
|
}
|
|
104
114
|
/**
|
|
105
115
|
* Method for streaming requests to known endpoints only
|
|
106
|
-
* @param endpoint - Streaming endpoint path
|
|
116
|
+
* @param endpoint - Streaming endpoint path
|
|
107
117
|
* @param data - Request data
|
|
108
118
|
* @param callbacks - Stream callbacks
|
|
109
119
|
* @param signal - Optional AbortSignal for cancelling the request
|
|
110
120
|
*/
|
|
111
|
-
makeStreamRequest(endpoint, data, callbacks, signal) {
|
|
121
|
+
makeStreamRequest(endpoint, data, callbacks, signal, customHeaders) {
|
|
112
122
|
let isCancelled = false;
|
|
113
123
|
const processStream = async (response) => {
|
|
114
124
|
const reader = response.body?.pipeThrough(new TextDecoderStream()).getReader();
|
|
115
125
|
if (!reader) {
|
|
116
126
|
throw new Error("Response body is null");
|
|
117
127
|
}
|
|
128
|
+
let buffer = "";
|
|
118
129
|
while (!isCancelled && !signal?.aborted) {
|
|
119
130
|
try {
|
|
120
131
|
const { value, done } = await reader.read();
|
|
@@ -122,7 +133,9 @@ var RagbitsClient = class {
|
|
|
122
133
|
callbacks.onClose?.();
|
|
123
134
|
break;
|
|
124
135
|
}
|
|
125
|
-
|
|
136
|
+
buffer += value;
|
|
137
|
+
const lines = buffer.split("\n");
|
|
138
|
+
buffer = lines.pop() ?? "";
|
|
126
139
|
for (const line of lines) {
|
|
127
140
|
if (!line.startsWith("data: ")) continue;
|
|
128
141
|
try {
|
|
@@ -130,7 +143,14 @@ var RagbitsClient = class {
|
|
|
130
143
|
const parsedData = JSON.parse(
|
|
131
144
|
jsonString
|
|
132
145
|
);
|
|
146
|
+
if (parsedData.type === "chunked_content") {
|
|
147
|
+
this.handleChunkedContent(parsedData, callbacks);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
133
150
|
await callbacks.onMessage(parsedData);
|
|
151
|
+
await new Promise(
|
|
152
|
+
(resolve) => setTimeout(resolve, 0)
|
|
153
|
+
);
|
|
134
154
|
} catch (parseError) {
|
|
135
155
|
console.error("Error parsing JSON:", parseError);
|
|
136
156
|
await callbacks.onError(
|
|
@@ -139,6 +159,9 @@ var RagbitsClient = class {
|
|
|
139
159
|
}
|
|
140
160
|
}
|
|
141
161
|
} catch (streamError) {
|
|
162
|
+
if (signal?.aborted) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
142
165
|
console.error("Stream error:", streamError);
|
|
143
166
|
await callbacks.onError(new Error("Error reading stream"));
|
|
144
167
|
break;
|
|
@@ -147,15 +170,29 @@ var RagbitsClient = class {
|
|
|
147
170
|
};
|
|
148
171
|
const startStream = async () => {
|
|
149
172
|
try {
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
173
|
+
const defaultHeaders = {
|
|
174
|
+
"Content-Type": "application/json",
|
|
175
|
+
Accept: "text/event-stream"
|
|
176
|
+
};
|
|
177
|
+
const headers = {
|
|
178
|
+
...defaultHeaders,
|
|
179
|
+
...customHeaders
|
|
180
|
+
};
|
|
181
|
+
if (this.auth?.getToken) {
|
|
182
|
+
headers["Authorization"] = `Bearer ${this.auth.getToken()}`;
|
|
183
|
+
}
|
|
184
|
+
const response = await fetch(
|
|
185
|
+
this._buildApiUrl(endpoint.toString()),
|
|
186
|
+
{
|
|
187
|
+
method: "POST",
|
|
188
|
+
headers,
|
|
189
|
+
body: JSON.stringify(data),
|
|
190
|
+
signal
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
if (response.status === 401) {
|
|
194
|
+
this.auth?.onUnauthorized?.();
|
|
195
|
+
}
|
|
159
196
|
if (!response.ok) {
|
|
160
197
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
161
198
|
}
|
|
@@ -179,11 +216,67 @@ var RagbitsClient = class {
|
|
|
179
216
|
isCancelled = true;
|
|
180
217
|
};
|
|
181
218
|
}
|
|
219
|
+
normalizeHeaders(init) {
|
|
220
|
+
if (!init) return {};
|
|
221
|
+
if (init instanceof Headers) {
|
|
222
|
+
return Object.fromEntries(init.entries());
|
|
223
|
+
}
|
|
224
|
+
if (Array.isArray(init)) {
|
|
225
|
+
return Object.fromEntries(init);
|
|
226
|
+
}
|
|
227
|
+
return init;
|
|
228
|
+
}
|
|
229
|
+
async handleChunkedContent(data, callbacks) {
|
|
230
|
+
const response = data;
|
|
231
|
+
const content = response.content;
|
|
232
|
+
const {
|
|
233
|
+
content_type: contentType,
|
|
234
|
+
id,
|
|
235
|
+
chunk_index: chunkIndex,
|
|
236
|
+
total_chunks: totalChunks,
|
|
237
|
+
mime_type: mimeType,
|
|
238
|
+
data: chunkData
|
|
239
|
+
} = content;
|
|
240
|
+
if (!this.chunkQueue.has(id)) {
|
|
241
|
+
this.chunkQueue.set(id, {
|
|
242
|
+
chunks: /* @__PURE__ */ new Map(),
|
|
243
|
+
totalChunks,
|
|
244
|
+
mimeType
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
const imageInfo = this.chunkQueue.get(id);
|
|
248
|
+
imageInfo.chunks.set(chunkIndex, chunkData);
|
|
249
|
+
if (imageInfo.chunks.size !== totalChunks) return;
|
|
250
|
+
const sortedChunks = Array.from(
|
|
251
|
+
{ length: totalChunks },
|
|
252
|
+
(_, i) => imageInfo.chunks.get(i)
|
|
253
|
+
);
|
|
254
|
+
const completeBase64 = sortedChunks.join("");
|
|
255
|
+
try {
|
|
256
|
+
atob(completeBase64);
|
|
257
|
+
} catch (e) {
|
|
258
|
+
this.chunkQueue.delete(id);
|
|
259
|
+
console.error("\u274C Invalid base64 data: ", e);
|
|
260
|
+
await callbacks.onError(new Error("Error reading stream"));
|
|
261
|
+
}
|
|
262
|
+
if (contentType === "image") {
|
|
263
|
+
const completeImageResponse = {
|
|
264
|
+
type: "image",
|
|
265
|
+
content: {
|
|
266
|
+
id,
|
|
267
|
+
url: `${imageInfo.mimeType},${completeBase64}`
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
await callbacks.onMessage(completeImageResponse);
|
|
271
|
+
}
|
|
272
|
+
this.chunkQueue.delete(id);
|
|
273
|
+
}
|
|
182
274
|
};
|
|
183
275
|
export {
|
|
184
|
-
|
|
276
|
+
AuthType,
|
|
185
277
|
FeedbackType,
|
|
186
278
|
LiveUpdateType,
|
|
187
279
|
MessageRole,
|
|
188
|
-
RagbitsClient
|
|
280
|
+
RagbitsClient,
|
|
281
|
+
TaskStatus
|
|
189
282
|
};
|