@anvia/react 0.2.0 → 0.3.1
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/dist/index.d.ts +21 -17
- package/dist/index.js +111 -101
- package/dist/index.js.map +1 -1
- package/package.json +7 -1
package/dist/index.d.ts
CHANGED
|
@@ -6,21 +6,6 @@ type TransportOptions = {
|
|
|
6
6
|
type EventTransport<TRequest, TEvent> = {
|
|
7
7
|
send(request: TRequest, options?: TransportOptions): AsyncIterable<TEvent>;
|
|
8
8
|
};
|
|
9
|
-
type FetchEventStreamOptions = Omit<RequestInit, "headers"> & {
|
|
10
|
-
format?: EventStreamFormat;
|
|
11
|
-
fetch?: typeof fetch;
|
|
12
|
-
headers?: HeadersInit;
|
|
13
|
-
};
|
|
14
|
-
type CreateFetchTransportOptions<TRequest, TEvent> = {
|
|
15
|
-
endpoint: string | URL | ((request: TRequest) => string | URL);
|
|
16
|
-
method?: string;
|
|
17
|
-
format?: EventStreamFormat;
|
|
18
|
-
fetch?: typeof fetch;
|
|
19
|
-
headers?: HeadersInit | ((request: TRequest) => HeadersInit | Promise<HeadersInit>);
|
|
20
|
-
body?: (request: TRequest) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;
|
|
21
|
-
init?: Omit<RequestInit, "body" | "headers" | "method" | "signal">;
|
|
22
|
-
mapEvent?: (event: unknown) => TEvent;
|
|
23
|
-
};
|
|
24
9
|
type ChatRole = "system" | "user" | "assistant" | "tool";
|
|
25
10
|
type ChatMessage = {
|
|
26
11
|
id: string;
|
|
@@ -57,16 +42,35 @@ type UseChatResult<TEvent = unknown, TMessage extends ChatMessage = ChatMessage>
|
|
|
57
42
|
error: unknown;
|
|
58
43
|
text: string;
|
|
59
44
|
};
|
|
45
|
+
|
|
46
|
+
type FetchEventStreamOptions = Omit<RequestInit, "headers"> & {
|
|
47
|
+
format?: EventStreamFormat;
|
|
48
|
+
fetch?: typeof fetch;
|
|
49
|
+
headers?: HeadersInit;
|
|
50
|
+
};
|
|
60
51
|
declare class EventStreamHttpError extends Error {
|
|
61
52
|
readonly response: Response;
|
|
62
53
|
readonly body: string;
|
|
63
54
|
constructor(response: Response, body: string);
|
|
64
55
|
}
|
|
56
|
+
declare function fetchEventStream<TEvent>(input: string | URL | Request, options?: FetchEventStreamOptions): AsyncIterable<TEvent>;
|
|
57
|
+
|
|
65
58
|
declare function readJsonlStream<TEvent>(stream: ReadableStream<Uint8Array>): AsyncIterable<TEvent>;
|
|
66
59
|
declare function readSseStream<TEvent>(stream: ReadableStream<Uint8Array>): AsyncIterable<TEvent>;
|
|
67
|
-
|
|
60
|
+
|
|
61
|
+
type CreateFetchTransportOptions<TRequest, TEvent> = {
|
|
62
|
+
endpoint: string | URL | ((request: TRequest) => string | URL);
|
|
63
|
+
method?: string;
|
|
64
|
+
format?: EventStreamFormat;
|
|
65
|
+
fetch?: typeof fetch;
|
|
66
|
+
headers?: HeadersInit | ((request: TRequest) => HeadersInit | Promise<HeadersInit>);
|
|
67
|
+
body?: (request: TRequest) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;
|
|
68
|
+
init?: Omit<RequestInit, "body" | "headers" | "method" | "signal">;
|
|
69
|
+
mapEvent?: (event: unknown) => TEvent;
|
|
70
|
+
};
|
|
68
71
|
declare function createFetchTransport<TRequest, TEvent = unknown>(options: CreateFetchTransportOptions<TRequest, TEvent>): EventTransport<TRequest, TEvent>;
|
|
69
|
-
declare function createChatTransport<TRequest
|
|
72
|
+
declare function createChatTransport<TRequest, TEvent = unknown>(options: CreateFetchTransportOptions<TRequest, TEvent>): EventTransport<TRequest, TEvent>;
|
|
73
|
+
|
|
70
74
|
declare function useChat<TRequest = DefaultChatRequest, TEvent = unknown, TMessage extends ChatMessage = ChatMessage>(options?: UseChatOptions<TRequest, TEvent, TMessage>): UseChatResult<TEvent, TMessage>;
|
|
71
75
|
|
|
72
76
|
export { type ChatMessage, type ChatRole, type CreateFetchTransportOptions, type DefaultChatRequest, type EventStreamFormat, EventStreamHttpError, type EventTransport, type FetchEventStreamOptions, type TransportOptions, type UseChatOptions, type UseChatResult, type UseChatStatus, createChatTransport, createFetchTransport, fetchEventStream, readJsonlStream, readSseStream, useChat };
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
var EventStreamHttpError = class extends Error {
|
|
4
|
-
constructor(response, body) {
|
|
5
|
-
super(`Event stream request failed with status ${response.status}`);
|
|
6
|
-
this.response = response;
|
|
7
|
-
this.body = body;
|
|
8
|
-
this.name = "EventStreamHttpError";
|
|
9
|
-
}
|
|
10
|
-
response;
|
|
11
|
-
body;
|
|
12
|
-
};
|
|
1
|
+
// src/streams.ts
|
|
13
2
|
async function* readJsonlStream(stream) {
|
|
14
3
|
const reader = stream.getReader();
|
|
15
4
|
const decoder = new TextDecoder();
|
|
@@ -21,7 +10,7 @@ async function* readJsonlStream(stream) {
|
|
|
21
10
|
break;
|
|
22
11
|
}
|
|
23
12
|
buffer += decoder.decode(next.value, { stream: true });
|
|
24
|
-
const lines = buffer.split(
|
|
13
|
+
const lines = buffer.split(/\r?\n/);
|
|
25
14
|
buffer = lines.pop() ?? "";
|
|
26
15
|
for (const line of lines) {
|
|
27
16
|
const trimmed2 = line.trim();
|
|
@@ -77,6 +66,43 @@ async function* readSseStream(stream) {
|
|
|
77
66
|
reader.releaseLock();
|
|
78
67
|
}
|
|
79
68
|
}
|
|
69
|
+
function createEmptySseEvent() {
|
|
70
|
+
return { data: [] };
|
|
71
|
+
}
|
|
72
|
+
function parseSseLine(line, event) {
|
|
73
|
+
if (line === "") {
|
|
74
|
+
const data = flushSseEvent(event);
|
|
75
|
+
return data === void 0 ? { event: createEmptySseEvent(), complete: true } : { event: createEmptySseEvent(), complete: true, data };
|
|
76
|
+
}
|
|
77
|
+
if (line.startsWith(":")) {
|
|
78
|
+
return { event };
|
|
79
|
+
}
|
|
80
|
+
const separator = line.indexOf(":");
|
|
81
|
+
const field = separator === -1 ? line : line.slice(0, separator);
|
|
82
|
+
const value = separator === -1 ? "" : line.slice(separator + 1).replace(/^ /, "");
|
|
83
|
+
if (field === "data") {
|
|
84
|
+
event.data.push(value);
|
|
85
|
+
}
|
|
86
|
+
return { event };
|
|
87
|
+
}
|
|
88
|
+
function flushSseEvent(event) {
|
|
89
|
+
if (event.data.length === 0) {
|
|
90
|
+
return void 0;
|
|
91
|
+
}
|
|
92
|
+
return event.data.join("\n");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/fetch.ts
|
|
96
|
+
var EventStreamHttpError = class extends Error {
|
|
97
|
+
constructor(response, body) {
|
|
98
|
+
super(`Event stream request failed with status ${response.status}`);
|
|
99
|
+
this.response = response;
|
|
100
|
+
this.body = body;
|
|
101
|
+
this.name = "EventStreamHttpError";
|
|
102
|
+
}
|
|
103
|
+
response;
|
|
104
|
+
body;
|
|
105
|
+
};
|
|
80
106
|
async function* fetchEventStream(input, options = {}) {
|
|
81
107
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
82
108
|
if (fetchImpl === void 0) {
|
|
@@ -96,6 +122,15 @@ async function* fetchEventStream(input, options = {}) {
|
|
|
96
122
|
}
|
|
97
123
|
yield* readJsonlStream(response.body);
|
|
98
124
|
}
|
|
125
|
+
function fetchOptions(options) {
|
|
126
|
+
const { format: _format, fetch: _fetch, ...init } = options;
|
|
127
|
+
return init;
|
|
128
|
+
}
|
|
129
|
+
function inferEventStreamFormat(contentType) {
|
|
130
|
+
return contentType?.toLowerCase().includes("text/event-stream") ? "sse" : "jsonl";
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/transport.ts
|
|
99
134
|
function createFetchTransport(options) {
|
|
100
135
|
return {
|
|
101
136
|
async *send(request, transportOptions = {}) {
|
|
@@ -128,6 +163,69 @@ function createFetchTransport(options) {
|
|
|
128
163
|
function createChatTransport(options) {
|
|
129
164
|
return createFetchTransport(options);
|
|
130
165
|
}
|
|
166
|
+
async function resolveHeaders(headers, request) {
|
|
167
|
+
return typeof headers === "function" ? headers(request) : headers;
|
|
168
|
+
}
|
|
169
|
+
async function resolveBody(body, request, headers) {
|
|
170
|
+
if (body !== void 0) {
|
|
171
|
+
return body(request);
|
|
172
|
+
}
|
|
173
|
+
if (!headers.has("content-type")) {
|
|
174
|
+
headers.set("content-type", "application/json");
|
|
175
|
+
}
|
|
176
|
+
return JSON.stringify(request);
|
|
177
|
+
}
|
|
178
|
+
function mergeHeaders(...values) {
|
|
179
|
+
const headers = new Headers();
|
|
180
|
+
for (const value of values) {
|
|
181
|
+
if (value === void 0) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
new Headers(value).forEach((headerValue, key) => {
|
|
185
|
+
headers.set(key, headerValue);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return headers;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/use-chat.ts
|
|
192
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
193
|
+
|
|
194
|
+
// src/chat-defaults.ts
|
|
195
|
+
function defaultCreateRequest(input, messages) {
|
|
196
|
+
return {
|
|
197
|
+
message: input,
|
|
198
|
+
history: messages.slice(0, -1),
|
|
199
|
+
stream: true
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function createMessage(role, content) {
|
|
203
|
+
return {
|
|
204
|
+
id: createId(),
|
|
205
|
+
role,
|
|
206
|
+
content
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function defaultEventToDelta(event) {
|
|
210
|
+
if (!isRecord(event)) {
|
|
211
|
+
return void 0;
|
|
212
|
+
}
|
|
213
|
+
return event.type === "text_delta" && typeof event.delta === "string" ? event.delta : void 0;
|
|
214
|
+
}
|
|
215
|
+
function defaultEventToFinal(event) {
|
|
216
|
+
if (!isRecord(event)) {
|
|
217
|
+
return void 0;
|
|
218
|
+
}
|
|
219
|
+
return event.type === "final" && typeof event.output === "string" ? event.output : void 0;
|
|
220
|
+
}
|
|
221
|
+
function createId() {
|
|
222
|
+
return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);
|
|
223
|
+
}
|
|
224
|
+
function isRecord(value) {
|
|
225
|
+
return typeof value === "object" && value !== null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/use-chat.ts
|
|
131
229
|
function useChat(options = {}) {
|
|
132
230
|
const [messages, setMessages] = useState(() => [...options.initialMessages ?? []]);
|
|
133
231
|
const [events, setEvents] = useState([]);
|
|
@@ -265,94 +363,6 @@ function useChat(options = {}) {
|
|
|
265
363
|
text
|
|
266
364
|
};
|
|
267
365
|
}
|
|
268
|
-
function fetchOptions(options) {
|
|
269
|
-
const { format: _format, fetch: _fetch, ...init } = options;
|
|
270
|
-
return init;
|
|
271
|
-
}
|
|
272
|
-
function inferEventStreamFormat(contentType) {
|
|
273
|
-
return contentType?.toLowerCase().includes("text/event-stream") ? "sse" : "jsonl";
|
|
274
|
-
}
|
|
275
|
-
function createEmptySseEvent() {
|
|
276
|
-
return { data: [] };
|
|
277
|
-
}
|
|
278
|
-
function parseSseLine(line, event) {
|
|
279
|
-
if (line === "") {
|
|
280
|
-
const data = flushSseEvent(event);
|
|
281
|
-
return data === void 0 ? { event: createEmptySseEvent(), complete: true } : { event: createEmptySseEvent(), complete: true, data };
|
|
282
|
-
}
|
|
283
|
-
if (line.startsWith(":")) {
|
|
284
|
-
return { event };
|
|
285
|
-
}
|
|
286
|
-
const separator = line.indexOf(":");
|
|
287
|
-
const field = separator === -1 ? line : line.slice(0, separator);
|
|
288
|
-
const value = separator === -1 ? "" : line.slice(separator + 1).replace(/^ /, "");
|
|
289
|
-
if (field === "data") {
|
|
290
|
-
event.data.push(value);
|
|
291
|
-
}
|
|
292
|
-
return { event };
|
|
293
|
-
}
|
|
294
|
-
function flushSseEvent(event) {
|
|
295
|
-
if (event.data.length === 0) {
|
|
296
|
-
return void 0;
|
|
297
|
-
}
|
|
298
|
-
return event.data.join("\n");
|
|
299
|
-
}
|
|
300
|
-
async function resolveHeaders(headers, request) {
|
|
301
|
-
return typeof headers === "function" ? headers(request) : headers;
|
|
302
|
-
}
|
|
303
|
-
async function resolveBody(body, request, headers) {
|
|
304
|
-
if (body !== void 0) {
|
|
305
|
-
return body(request);
|
|
306
|
-
}
|
|
307
|
-
if (!headers.has("content-type")) {
|
|
308
|
-
headers.set("content-type", "application/json");
|
|
309
|
-
}
|
|
310
|
-
return JSON.stringify(request);
|
|
311
|
-
}
|
|
312
|
-
function mergeHeaders(...values) {
|
|
313
|
-
const headers = new Headers();
|
|
314
|
-
for (const value of values) {
|
|
315
|
-
if (value === void 0) {
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
new Headers(value).forEach((headerValue, key) => {
|
|
319
|
-
headers.set(key, headerValue);
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
return headers;
|
|
323
|
-
}
|
|
324
|
-
function defaultCreateRequest(input, messages) {
|
|
325
|
-
return {
|
|
326
|
-
message: input,
|
|
327
|
-
history: messages.slice(0, -1),
|
|
328
|
-
stream: true
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
function createMessage(role, content) {
|
|
332
|
-
return {
|
|
333
|
-
id: createId(),
|
|
334
|
-
role,
|
|
335
|
-
content
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
function createId() {
|
|
339
|
-
return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);
|
|
340
|
-
}
|
|
341
|
-
function defaultEventToDelta(event) {
|
|
342
|
-
if (!isRecord(event)) {
|
|
343
|
-
return void 0;
|
|
344
|
-
}
|
|
345
|
-
return event.type === "text_delta" && typeof event.delta === "string" ? event.delta : void 0;
|
|
346
|
-
}
|
|
347
|
-
function defaultEventToFinal(event) {
|
|
348
|
-
if (!isRecord(event)) {
|
|
349
|
-
return void 0;
|
|
350
|
-
}
|
|
351
|
-
return event.type === "final" && typeof event.output === "string" ? event.output : void 0;
|
|
352
|
-
}
|
|
353
|
-
function isRecord(value) {
|
|
354
|
-
return typeof value === "object" && value !== null;
|
|
355
|
-
}
|
|
356
366
|
function isAbortError(error) {
|
|
357
367
|
return error instanceof DOMException && error.name === "AbortError";
|
|
358
368
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nexport type EventStreamFormat = \"jsonl\" | \"sse\";\n\nexport type TransportOptions = {\n signal?: AbortSignal;\n headers?: HeadersInit;\n};\n\nexport type EventTransport<TRequest, TEvent> = {\n send(request: TRequest, options?: TransportOptions): AsyncIterable<TEvent>;\n};\n\nexport type FetchEventStreamOptions = Omit<RequestInit, \"headers\"> & {\n format?: EventStreamFormat;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n};\n\nexport type CreateFetchTransportOptions<TRequest, TEvent> = {\n endpoint: string | URL | ((request: TRequest) => string | URL);\n method?: string;\n format?: EventStreamFormat;\n fetch?: typeof fetch;\n headers?: HeadersInit | ((request: TRequest) => HeadersInit | Promise<HeadersInit>);\n body?: (request: TRequest) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;\n init?: Omit<RequestInit, \"body\" | \"headers\" | \"method\" | \"signal\">;\n mapEvent?: (event: unknown) => TEvent;\n};\n\nexport type ChatRole = \"system\" | \"user\" | \"assistant\" | \"tool\";\n\nexport type ChatMessage = {\n id: string;\n role: ChatRole;\n content: string;\n metadata?: unknown;\n};\n\nexport type DefaultChatRequest = {\n message: string;\n history: ChatMessage[];\n stream: true;\n};\n\nexport type UseChatStatus = \"idle\" | \"streaming\" | \"error\";\n\nexport type UseChatOptions<\n TRequest = DefaultChatRequest,\n TEvent = unknown,\n TMessage extends ChatMessage = ChatMessage,\n> = {\n transport?: EventTransport<TRequest, TEvent>;\n endpoint?: string | URL;\n format?: EventStreamFormat;\n initialMessages?: TMessage[];\n createRequest?: (input: string, messages: TMessage[]) => TRequest;\n eventToDelta?: (event: TEvent) => string | undefined;\n eventToFinal?: (event: TEvent) => string | undefined;\n onEvent?: (event: TEvent) => void;\n onError?: (error: unknown) => void;\n};\n\nexport type UseChatResult<TEvent = unknown, TMessage extends ChatMessage = ChatMessage> = {\n messages: TMessage[];\n events: TEvent[];\n input: string;\n setInput(input: string): void;\n send(input?: string): Promise<void>;\n stop(): void;\n reset(messages?: TMessage[]): void;\n status: UseChatStatus;\n error: unknown;\n text: string;\n};\n\nexport class EventStreamHttpError extends Error {\n constructor(\n readonly response: Response,\n readonly body: string,\n ) {\n super(`Event stream request failed with status ${response.status}`);\n this.name = \"EventStreamHttpError\";\n }\n}\n\nexport async function* readJsonlStream<TEvent>(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<TEvent> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done === true) {\n break;\n }\n\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.length > 0) {\n yield JSON.parse(trimmed) as TEvent;\n }\n }\n }\n\n buffer += decoder.decode();\n const trimmed = buffer.trim();\n if (trimmed.length > 0) {\n yield JSON.parse(trimmed) as TEvent;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport async function* readSseStream<TEvent>(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<TEvent> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let event = createEmptySseEvent();\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done === true) {\n break;\n }\n\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const parsed = parseSseLine(line, event);\n event = parsed.event;\n if (parsed.complete === true && parsed.data !== undefined) {\n yield JSON.parse(parsed.data) as TEvent;\n }\n }\n }\n\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const parsed = parseSseLine(buffer, event);\n event = parsed.event;\n if (parsed.complete === true && parsed.data !== undefined) {\n yield JSON.parse(parsed.data) as TEvent;\n }\n }\n const data = flushSseEvent(event);\n if (data !== undefined) {\n yield JSON.parse(data) as TEvent;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport async function* fetchEventStream<TEvent>(\n input: string | URL | Request,\n options: FetchEventStreamOptions = {},\n): AsyncIterable<TEvent> {\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (fetchImpl === undefined) {\n throw new Error(\"fetchEventStream requires a fetch implementation\");\n }\n\n const response = await fetchImpl(input, fetchOptions(options));\n if (!response.ok) {\n throw new EventStreamHttpError(response, await response.text());\n }\n if (response.body === null) {\n throw new Error(\"Event stream response does not include a body\");\n }\n\n const format = options.format ?? inferEventStreamFormat(response.headers.get(\"content-type\"));\n if (format === \"sse\") {\n yield* readSseStream<TEvent>(response.body);\n return;\n }\n\n yield* readJsonlStream<TEvent>(response.body);\n}\n\nexport function createFetchTransport<TRequest, TEvent = unknown>(\n options: CreateFetchTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return {\n async *send(request, transportOptions = {}) {\n const endpoint =\n typeof options.endpoint === \"function\" ? options.endpoint(request) : options.endpoint;\n const requestHeaders = await resolveHeaders(options.headers, request);\n const headers = mergeHeaders(requestHeaders, transportOptions.headers);\n const method = options.method ?? \"POST\";\n const body = await resolveBody(options.body, request, headers);\n const init: FetchEventStreamOptions = {\n ...(options.init ?? {}),\n method,\n headers,\n format: options.format ?? \"jsonl\",\n };\n\n if (body !== undefined) {\n init.body = body;\n }\n if (transportOptions.signal !== undefined) {\n init.signal = transportOptions.signal;\n }\n if (options.fetch !== undefined) {\n init.fetch = options.fetch;\n }\n\n for await (const event of fetchEventStream<unknown>(endpoint, init)) {\n yield options.mapEvent === undefined ? (event as TEvent) : options.mapEvent(event);\n }\n },\n };\n}\n\nexport function createChatTransport<TRequest = DefaultChatRequest, TEvent = unknown>(\n options: CreateFetchTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return createFetchTransport(options);\n}\n\nexport function useChat<\n TRequest = DefaultChatRequest,\n TEvent = unknown,\n TMessage extends ChatMessage = ChatMessage,\n>(options: UseChatOptions<TRequest, TEvent, TMessage> = {}): UseChatResult<TEvent, TMessage> {\n const [messages, setMessages] = useState<TMessage[]>(() => [...(options.initialMessages ?? [])]);\n const [events, setEvents] = useState<TEvent[]>([]);\n const [input, setInput] = useState(\"\");\n const [status, setStatus] = useState<UseChatStatus>(\"idle\");\n const [error, setError] = useState<unknown>();\n const abortRef = useRef<AbortController | undefined>(undefined);\n const messagesRef = useRef(messages);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const transport = useMemo(() => {\n if (options.transport !== undefined) {\n return options.transport;\n }\n if (options.endpoint === undefined) {\n return undefined;\n }\n\n return createChatTransport<TRequest, TEvent>({\n endpoint: options.endpoint,\n format: options.format ?? \"jsonl\",\n });\n }, [options.transport, options.endpoint, options.format]);\n\n const createRequest = options.createRequest ?? defaultCreateRequest<TRequest, TMessage>;\n const eventToDelta = options.eventToDelta ?? defaultEventToDelta<TEvent>;\n const eventToFinal = options.eventToFinal ?? defaultEventToFinal<TEvent>;\n\n const appendAssistantText = useCallback((assistantId: string, text: string) => {\n setMessages((current) =>\n current.map((message) =>\n message.id === assistantId\n ? ({ ...message, content: `${message.content}${text}` } as TMessage)\n : message,\n ),\n );\n }, []);\n\n const replaceAssistantText = useCallback((assistantId: string, text: string) => {\n setMessages((current) =>\n current.map((message) =>\n message.id === assistantId ? ({ ...message, content: text } as TMessage) : message,\n ),\n );\n }, []);\n\n const send = useCallback(\n async (nextInput?: string) => {\n if (transport === undefined) {\n throw new Error(\"useChat requires either transport or endpoint\");\n }\n\n const content = nextInput ?? input;\n if (content.trim().length === 0) {\n return;\n }\n\n abortRef.current?.abort();\n const abortController = new AbortController();\n abortRef.current = abortController;\n\n const userMessage = createMessage<TMessage>(\"user\", content);\n const assistantMessage = createMessage<TMessage>(\"assistant\", \"\");\n const requestMessages = [...messagesRef.current, userMessage];\n const request = createRequest(content, requestMessages);\n\n setInput(\"\");\n setError(undefined);\n setStatus(\"streaming\");\n setEvents([]);\n setMessages([...requestMessages, assistantMessage]);\n\n try {\n for await (const event of transport.send(request, { signal: abortController.signal })) {\n setEvents((current) => [...current, event]);\n options.onEvent?.(event);\n\n const delta = eventToDelta(event);\n if (delta !== undefined && delta.length > 0) {\n appendAssistantText(assistantMessage.id, delta);\n }\n\n const final = eventToFinal(event);\n if (final !== undefined) {\n replaceAssistantText(assistantMessage.id, final);\n }\n }\n\n if (!abortController.signal.aborted) {\n setStatus(\"idle\");\n }\n } catch (caught) {\n if (isAbortError(caught)) {\n setStatus(\"idle\");\n return;\n }\n\n setError(caught);\n setStatus(\"error\");\n options.onError?.(caught);\n } finally {\n if (abortRef.current === abortController) {\n abortRef.current = undefined;\n }\n }\n },\n [\n appendAssistantText,\n createRequest,\n eventToDelta,\n eventToFinal,\n input,\n options,\n replaceAssistantText,\n transport,\n ],\n );\n\n const stop = useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = undefined;\n setStatus(\"idle\");\n }, []);\n\n const reset = useCallback((nextMessages?: TMessage[]) => {\n const resetMessages = nextMessages ?? [];\n messagesRef.current = resetMessages;\n abortRef.current?.abort();\n abortRef.current = undefined;\n setMessages(resetMessages);\n setEvents([]);\n setError(undefined);\n setInput(\"\");\n setStatus(\"idle\");\n }, []);\n\n const text = messages\n .filter((message) => message.role === \"assistant\")\n .map((message) => message.content)\n .join(\"\");\n\n return {\n messages,\n events,\n input,\n setInput,\n send,\n stop,\n reset,\n status,\n error,\n text,\n };\n}\n\nfunction fetchOptions(options: FetchEventStreamOptions): RequestInit {\n const { format: _format, fetch: _fetch, ...init } = options;\n return init;\n}\n\nfunction inferEventStreamFormat(contentType: string | null): EventStreamFormat {\n return contentType?.toLowerCase().includes(\"text/event-stream\") ? \"sse\" : \"jsonl\";\n}\n\nfunction createEmptySseEvent(): { data: string[] } {\n return { data: [] };\n}\n\nfunction parseSseLine(\n line: string,\n event: { data: string[] },\n): { event: { data: string[] }; complete?: true; data?: string } {\n if (line === \"\") {\n const data = flushSseEvent(event);\n return data === undefined\n ? { event: createEmptySseEvent(), complete: true }\n : { event: createEmptySseEvent(), complete: true, data };\n }\n\n if (line.startsWith(\":\")) {\n return { event };\n }\n\n const separator = line.indexOf(\":\");\n const field = separator === -1 ? line : line.slice(0, separator);\n const value = separator === -1 ? \"\" : line.slice(separator + 1).replace(/^ /, \"\");\n\n if (field === \"data\") {\n event.data.push(value);\n }\n\n return { event };\n}\n\nfunction flushSseEvent(event: { data: string[] }): string | undefined {\n if (event.data.length === 0) {\n return undefined;\n }\n\n return event.data.join(\"\\n\");\n}\n\nasync function resolveHeaders<TRequest>(\n headers: CreateFetchTransportOptions<TRequest, unknown>[\"headers\"],\n request: TRequest,\n): Promise<HeadersInit | undefined> {\n return typeof headers === \"function\" ? headers(request) : headers;\n}\n\nasync function resolveBody<TRequest>(\n body: CreateFetchTransportOptions<TRequest, unknown>[\"body\"],\n request: TRequest,\n headers: Headers,\n): Promise<BodyInit | null | undefined> {\n if (body !== undefined) {\n return body(request);\n }\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return JSON.stringify(request);\n}\n\nfunction mergeHeaders(...values: (HeadersInit | undefined)[]): Headers {\n const headers = new Headers();\n\n for (const value of values) {\n if (value === undefined) {\n continue;\n }\n new Headers(value).forEach((headerValue, key) => {\n headers.set(key, headerValue);\n });\n }\n\n return headers;\n}\n\nfunction defaultCreateRequest<TRequest, TMessage extends ChatMessage>(\n input: string,\n messages: TMessage[],\n): TRequest {\n return {\n message: input,\n history: messages.slice(0, -1),\n stream: true,\n } as TRequest;\n}\n\nfunction createMessage<TMessage extends ChatMessage>(role: ChatRole, content: string): TMessage {\n return {\n id: createId(),\n role,\n content,\n } as TMessage;\n}\n\nfunction createId(): string {\n return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);\n}\n\nfunction defaultEventToDelta<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"text_delta\" && typeof event.delta === \"string\" ? event.delta : undefined;\n}\n\nfunction defaultEventToFinal<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"final\" && typeof event.output === \"string\" ? event.output : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n"],"mappings":"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","names":["trimmed","text"]}
|
|
1
|
+
{"version":3,"sources":["../src/streams.ts","../src/fetch.ts","../src/transport.ts","../src/use-chat.ts","../src/chat-defaults.ts"],"sourcesContent":["export async function* readJsonlStream<TEvent>(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<TEvent> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done === true) {\n break;\n }\n\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.length > 0) {\n yield JSON.parse(trimmed) as TEvent;\n }\n }\n }\n\n buffer += decoder.decode();\n const trimmed = buffer.trim();\n if (trimmed.length > 0) {\n yield JSON.parse(trimmed) as TEvent;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport async function* readSseStream<TEvent>(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<TEvent> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let event = createEmptySseEvent();\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done === true) {\n break;\n }\n\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const parsed = parseSseLine(line, event);\n event = parsed.event;\n if (parsed.complete === true && parsed.data !== undefined) {\n yield JSON.parse(parsed.data) as TEvent;\n }\n }\n }\n\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const parsed = parseSseLine(buffer, event);\n event = parsed.event;\n if (parsed.complete === true && parsed.data !== undefined) {\n yield JSON.parse(parsed.data) as TEvent;\n }\n }\n const data = flushSseEvent(event);\n if (data !== undefined) {\n yield JSON.parse(data) as TEvent;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction createEmptySseEvent(): { data: string[] } {\n return { data: [] };\n}\n\nfunction parseSseLine(\n line: string,\n event: { data: string[] },\n): { event: { data: string[] }; complete?: true; data?: string } {\n if (line === \"\") {\n const data = flushSseEvent(event);\n return data === undefined\n ? { event: createEmptySseEvent(), complete: true }\n : { event: createEmptySseEvent(), complete: true, data };\n }\n\n if (line.startsWith(\":\")) {\n return { event };\n }\n\n const separator = line.indexOf(\":\");\n const field = separator === -1 ? line : line.slice(0, separator);\n const value = separator === -1 ? \"\" : line.slice(separator + 1).replace(/^ /, \"\");\n\n if (field === \"data\") {\n event.data.push(value);\n }\n\n return { event };\n}\n\nfunction flushSseEvent(event: { data: string[] }): string | undefined {\n if (event.data.length === 0) {\n return undefined;\n }\n\n return event.data.join(\"\\n\");\n}\n","import { readJsonlStream, readSseStream } from \"./streams\";\nimport type { EventStreamFormat } from \"./types\";\n\nexport type FetchEventStreamOptions = Omit<RequestInit, \"headers\"> & {\n format?: EventStreamFormat;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n};\n\nexport class EventStreamHttpError extends Error {\n constructor(\n readonly response: Response,\n readonly body: string,\n ) {\n super(`Event stream request failed with status ${response.status}`);\n this.name = \"EventStreamHttpError\";\n }\n}\n\nexport async function* fetchEventStream<TEvent>(\n input: string | URL | Request,\n options: FetchEventStreamOptions = {},\n): AsyncIterable<TEvent> {\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (fetchImpl === undefined) {\n throw new Error(\"fetchEventStream requires a fetch implementation\");\n }\n\n const response = await fetchImpl(input, fetchOptions(options));\n if (!response.ok) {\n throw new EventStreamHttpError(response, await response.text());\n }\n if (response.body === null) {\n throw new Error(\"Event stream response does not include a body\");\n }\n\n const format = options.format ?? inferEventStreamFormat(response.headers.get(\"content-type\"));\n if (format === \"sse\") {\n yield* readSseStream<TEvent>(response.body);\n return;\n }\n\n yield* readJsonlStream<TEvent>(response.body);\n}\n\nfunction fetchOptions(options: FetchEventStreamOptions): RequestInit {\n const { format: _format, fetch: _fetch, ...init } = options;\n return init;\n}\n\nfunction inferEventStreamFormat(contentType: string | null): EventStreamFormat {\n return contentType?.toLowerCase().includes(\"text/event-stream\") ? \"sse\" : \"jsonl\";\n}\n","import { type FetchEventStreamOptions, fetchEventStream } from \"./fetch\";\nimport type { EventStreamFormat, EventTransport } from \"./types\";\n\nexport type CreateFetchTransportOptions<TRequest, TEvent> = {\n endpoint: string | URL | ((request: TRequest) => string | URL);\n method?: string;\n format?: EventStreamFormat;\n fetch?: typeof fetch;\n headers?: HeadersInit | ((request: TRequest) => HeadersInit | Promise<HeadersInit>);\n body?: (request: TRequest) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;\n init?: Omit<RequestInit, \"body\" | \"headers\" | \"method\" | \"signal\">;\n mapEvent?: (event: unknown) => TEvent;\n};\n\nexport function createFetchTransport<TRequest, TEvent = unknown>(\n options: CreateFetchTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return {\n async *send(request, transportOptions = {}) {\n const endpoint =\n typeof options.endpoint === \"function\" ? options.endpoint(request) : options.endpoint;\n const requestHeaders = await resolveHeaders(options.headers, request);\n const headers = mergeHeaders(requestHeaders, transportOptions.headers);\n const method = options.method ?? \"POST\";\n const body = await resolveBody(options.body, request, headers);\n const init: FetchEventStreamOptions = {\n ...(options.init ?? {}),\n method,\n headers,\n format: options.format ?? \"jsonl\",\n };\n\n if (body !== undefined) {\n init.body = body;\n }\n if (transportOptions.signal !== undefined) {\n init.signal = transportOptions.signal;\n }\n if (options.fetch !== undefined) {\n init.fetch = options.fetch;\n }\n\n for await (const event of fetchEventStream<unknown>(endpoint, init)) {\n yield options.mapEvent === undefined ? (event as TEvent) : options.mapEvent(event);\n }\n },\n };\n}\n\nexport function createChatTransport<TRequest, TEvent = unknown>(\n options: CreateFetchTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return createFetchTransport(options);\n}\n\nasync function resolveHeaders<TRequest>(\n headers: CreateFetchTransportOptions<TRequest, unknown>[\"headers\"],\n request: TRequest,\n): Promise<HeadersInit | undefined> {\n return typeof headers === \"function\" ? headers(request) : headers;\n}\n\nasync function resolveBody<TRequest>(\n body: CreateFetchTransportOptions<TRequest, unknown>[\"body\"],\n request: TRequest,\n headers: Headers,\n): Promise<BodyInit | null | undefined> {\n if (body !== undefined) {\n return body(request);\n }\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return JSON.stringify(request);\n}\n\nfunction mergeHeaders(...values: (HeadersInit | undefined)[]): Headers {\n const headers = new Headers();\n\n for (const value of values) {\n if (value === undefined) {\n continue;\n }\n new Headers(value).forEach((headerValue, key) => {\n headers.set(key, headerValue);\n });\n }\n\n return headers;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport {\n createMessage,\n defaultCreateRequest,\n defaultEventToDelta,\n defaultEventToFinal,\n} from \"./chat-defaults\";\nimport { createChatTransport } from \"./transport\";\nimport type { ChatMessage, DefaultChatRequest, UseChatOptions, UseChatResult } from \"./types\";\n\nexport function useChat<\n TRequest = DefaultChatRequest,\n TEvent = unknown,\n TMessage extends ChatMessage = ChatMessage,\n>(options: UseChatOptions<TRequest, TEvent, TMessage> = {}): UseChatResult<TEvent, TMessage> {\n const [messages, setMessages] = useState<TMessage[]>(() => [...(options.initialMessages ?? [])]);\n const [events, setEvents] = useState<TEvent[]>([]);\n const [input, setInput] = useState(\"\");\n const [status, setStatus] = useState<UseChatResult<TEvent, TMessage>[\"status\"]>(\"idle\");\n const [error, setError] = useState<unknown>();\n const abortRef = useRef<AbortController | undefined>(undefined);\n const messagesRef = useRef(messages);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const transport = useMemo(() => {\n if (options.transport !== undefined) {\n return options.transport;\n }\n if (options.endpoint === undefined) {\n return undefined;\n }\n\n return createChatTransport<TRequest, TEvent>({\n endpoint: options.endpoint,\n format: options.format ?? \"jsonl\",\n });\n }, [options.transport, options.endpoint, options.format]);\n\n const createRequest = options.createRequest ?? defaultCreateRequest<TRequest, TMessage>;\n const eventToDelta = options.eventToDelta ?? defaultEventToDelta<TEvent>;\n const eventToFinal = options.eventToFinal ?? defaultEventToFinal<TEvent>;\n\n const appendAssistantText = useCallback((assistantId: string, text: string) => {\n setMessages((current) =>\n current.map((message) =>\n message.id === assistantId\n ? ({ ...message, content: `${message.content}${text}` } as TMessage)\n : message,\n ),\n );\n }, []);\n\n const replaceAssistantText = useCallback((assistantId: string, text: string) => {\n setMessages((current) =>\n current.map((message) =>\n message.id === assistantId ? ({ ...message, content: text } as TMessage) : message,\n ),\n );\n }, []);\n\n const send = useCallback(\n async (nextInput?: string) => {\n if (transport === undefined) {\n throw new Error(\"useChat requires either transport or endpoint\");\n }\n\n const content = nextInput ?? input;\n if (content.trim().length === 0) {\n return;\n }\n\n abortRef.current?.abort();\n const abortController = new AbortController();\n abortRef.current = abortController;\n\n const userMessage = createMessage<TMessage>(\"user\", content);\n const assistantMessage = createMessage<TMessage>(\"assistant\", \"\");\n const requestMessages = [...messagesRef.current, userMessage];\n const request = createRequest(content, requestMessages);\n\n setInput(\"\");\n setError(undefined);\n setStatus(\"streaming\");\n setEvents([]);\n setMessages([...requestMessages, assistantMessage]);\n\n try {\n for await (const event of transport.send(request, { signal: abortController.signal })) {\n setEvents((current) => [...current, event]);\n options.onEvent?.(event);\n\n const delta = eventToDelta(event);\n if (delta !== undefined && delta.length > 0) {\n appendAssistantText(assistantMessage.id, delta);\n }\n\n const final = eventToFinal(event);\n if (final !== undefined) {\n replaceAssistantText(assistantMessage.id, final);\n }\n }\n\n if (!abortController.signal.aborted) {\n setStatus(\"idle\");\n }\n } catch (caught) {\n if (isAbortError(caught)) {\n setStatus(\"idle\");\n return;\n }\n\n setError(caught);\n setStatus(\"error\");\n options.onError?.(caught);\n } finally {\n if (abortRef.current === abortController) {\n abortRef.current = undefined;\n }\n }\n },\n [\n appendAssistantText,\n createRequest,\n eventToDelta,\n eventToFinal,\n input,\n options,\n replaceAssistantText,\n transport,\n ],\n );\n\n const stop = useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = undefined;\n setStatus(\"idle\");\n }, []);\n\n const reset = useCallback((nextMessages?: TMessage[]) => {\n const resetMessages = nextMessages ?? [];\n messagesRef.current = resetMessages;\n abortRef.current?.abort();\n abortRef.current = undefined;\n setMessages(resetMessages);\n setEvents([]);\n setError(undefined);\n setInput(\"\");\n setStatus(\"idle\");\n }, []);\n\n const text = messages\n .filter((message) => message.role === \"assistant\")\n .map((message) => message.content)\n .join(\"\");\n\n return {\n messages,\n events,\n input,\n setInput,\n send,\n stop,\n reset,\n status,\n error,\n text,\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n","import type { ChatMessage, ChatRole, DefaultChatRequest } from \"./types\";\n\nexport function defaultCreateRequest<TRequest, TMessage extends ChatMessage>(\n input: string,\n messages: TMessage[],\n): TRequest {\n return {\n message: input,\n history: messages.slice(0, -1),\n stream: true,\n } as DefaultChatRequest as TRequest;\n}\n\nexport function createMessage<TMessage extends ChatMessage>(\n role: ChatRole,\n content: string,\n): TMessage {\n return {\n id: createId(),\n role,\n content,\n } as TMessage;\n}\n\nexport function defaultEventToDelta<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"text_delta\" && typeof event.delta === \"string\" ? event.delta : undefined;\n}\n\nexport function defaultEventToFinal<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"final\" && typeof event.output === \"string\" ? event.output : undefined;\n}\n\nfunction createId(): string {\n return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n"],"mappings":";AAAA,gBAAuB,gBACrB,QACuB;AACvB,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AAEb,MAAI;AACF,WAAO,MAAM;AACX,YAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,UAAI,KAAK,SAAS,MAAM;AACtB;AAAA,MACF;AAEA,gBAAU,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;AACrD,YAAM,QAAQ,OAAO,MAAM,OAAO;AAClC,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,cAAMA,WAAU,KAAK,KAAK;AAC1B,YAAIA,SAAQ,SAAS,GAAG;AACtB,gBAAM,KAAK,MAAMA,QAAO;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAEA,cAAU,QAAQ,OAAO;AACzB,UAAM,UAAU,OAAO,KAAK;AAC5B,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,KAAK,MAAM,OAAO;AAAA,IAC1B;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACF;AAEA,gBAAuB,cACrB,QACuB;AACvB,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AACb,MAAI,QAAQ,oBAAoB;AAEhC,MAAI;AACF,WAAO,MAAM;AACX,YAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,UAAI,KAAK,SAAS,MAAM;AACtB;AAAA,MACF;AAEA,gBAAU,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;AACrD,YAAM,QAAQ,OAAO,MAAM,OAAO;AAClC,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,cAAM,SAAS,aAAa,MAAM,KAAK;AACvC,gBAAQ,OAAO;AACf,YAAI,OAAO,aAAa,QAAQ,OAAO,SAAS,QAAW;AACzD,gBAAM,KAAK,MAAM,OAAO,IAAI;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAEA,cAAU,QAAQ,OAAO;AACzB,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,SAAS,aAAa,QAAQ,KAAK;AACzC,cAAQ,OAAO;AACf,UAAI,OAAO,aAAa,QAAQ,OAAO,SAAS,QAAW;AACzD,cAAM,KAAK,MAAM,OAAO,IAAI;AAAA,MAC9B;AAAA,IACF;AACA,UAAM,OAAO,cAAc,KAAK;AAChC,QAAI,SAAS,QAAW;AACtB,YAAM,KAAK,MAAM,IAAI;AAAA,IACvB;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACF;AAEA,SAAS,sBAA0C;AACjD,SAAO,EAAE,MAAM,CAAC,EAAE;AACpB;AAEA,SAAS,aACP,MACA,OAC+D;AAC/D,MAAI,SAAS,IAAI;AACf,UAAM,OAAO,cAAc,KAAK;AAChC,WAAO,SAAS,SACZ,EAAE,OAAO,oBAAoB,GAAG,UAAU,KAAK,IAC/C,EAAE,OAAO,oBAAoB,GAAG,UAAU,MAAM,KAAK;AAAA,EAC3D;AAEA,MAAI,KAAK,WAAW,GAAG,GAAG;AACxB,WAAO,EAAE,MAAM;AAAA,EACjB;AAEA,QAAM,YAAY,KAAK,QAAQ,GAAG;AAClC,QAAM,QAAQ,cAAc,KAAK,OAAO,KAAK,MAAM,GAAG,SAAS;AAC/D,QAAM,QAAQ,cAAc,KAAK,KAAK,KAAK,MAAM,YAAY,CAAC,EAAE,QAAQ,MAAM,EAAE;AAEhF,MAAI,UAAU,QAAQ;AACpB,UAAM,KAAK,KAAK,KAAK;AAAA,EACvB;AAEA,SAAO,EAAE,MAAM;AACjB;AAEA,SAAS,cAAc,OAA+C;AACpE,MAAI,MAAM,KAAK,WAAW,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,KAAK,KAAK,IAAI;AAC7B;;;AC5GO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YACW,UACA,MACT;AACA,UAAM,2CAA2C,SAAS,MAAM,EAAE;AAHzD;AACA;AAGT,SAAK,OAAO;AAAA,EACd;AAAA,EALW;AAAA,EACA;AAKb;AAEA,gBAAuB,iBACrB,OACA,UAAmC,CAAC,GACb;AACvB,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,MAAI,cAAc,QAAW;AAC3B,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,QAAM,WAAW,MAAM,UAAU,OAAO,aAAa,OAAO,CAAC;AAC7D,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,qBAAqB,UAAU,MAAM,SAAS,KAAK,CAAC;AAAA,EAChE;AACA,MAAI,SAAS,SAAS,MAAM;AAC1B,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,QAAM,SAAS,QAAQ,UAAU,uBAAuB,SAAS,QAAQ,IAAI,cAAc,CAAC;AAC5F,MAAI,WAAW,OAAO;AACpB,WAAO,cAAsB,SAAS,IAAI;AAC1C;AAAA,EACF;AAEA,SAAO,gBAAwB,SAAS,IAAI;AAC9C;AAEA,SAAS,aAAa,SAA+C;AACnE,QAAM,EAAE,QAAQ,SAAS,OAAO,QAAQ,GAAG,KAAK,IAAI;AACpD,SAAO;AACT;AAEA,SAAS,uBAAuB,aAA+C;AAC7E,SAAO,aAAa,YAAY,EAAE,SAAS,mBAAmB,IAAI,QAAQ;AAC5E;;;ACtCO,SAAS,qBACd,SACkC;AAClC,SAAO;AAAA,IACL,OAAO,KAAK,SAAS,mBAAmB,CAAC,GAAG;AAC1C,YAAM,WACJ,OAAO,QAAQ,aAAa,aAAa,QAAQ,SAAS,OAAO,IAAI,QAAQ;AAC/E,YAAM,iBAAiB,MAAM,eAAe,QAAQ,SAAS,OAAO;AACpE,YAAM,UAAU,aAAa,gBAAgB,iBAAiB,OAAO;AACrE,YAAM,SAAS,QAAQ,UAAU;AACjC,YAAM,OAAO,MAAM,YAAY,QAAQ,MAAM,SAAS,OAAO;AAC7D,YAAM,OAAgC;AAAA,QACpC,GAAI,QAAQ,QAAQ,CAAC;AAAA,QACrB;AAAA,QACA;AAAA,QACA,QAAQ,QAAQ,UAAU;AAAA,MAC5B;AAEA,UAAI,SAAS,QAAW;AACtB,aAAK,OAAO;AAAA,MACd;AACA,UAAI,iBAAiB,WAAW,QAAW;AACzC,aAAK,SAAS,iBAAiB;AAAA,MACjC;AACA,UAAI,QAAQ,UAAU,QAAW;AAC/B,aAAK,QAAQ,QAAQ;AAAA,MACvB;AAEA,uBAAiB,SAAS,iBAA0B,UAAU,IAAI,GAAG;AACnE,cAAM,QAAQ,aAAa,SAAa,QAAmB,QAAQ,SAAS,KAAK;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,oBACd,SACkC;AAClC,SAAO,qBAAqB,OAAO;AACrC;AAEA,eAAe,eACb,SACA,SACkC;AAClC,SAAO,OAAO,YAAY,aAAa,QAAQ,OAAO,IAAI;AAC5D;AAEA,eAAe,YACb,MACA,SACA,SACsC;AACtC,MAAI,SAAS,QAAW;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AAEA,MAAI,CAAC,QAAQ,IAAI,cAAc,GAAG;AAChC,YAAQ,IAAI,gBAAgB,kBAAkB;AAAA,EAChD;AAEA,SAAO,KAAK,UAAU,OAAO;AAC/B;AAEA,SAAS,gBAAgB,QAA8C;AACrE,QAAM,UAAU,IAAI,QAAQ;AAE5B,aAAW,SAAS,QAAQ;AAC1B,QAAI,UAAU,QAAW;AACvB;AAAA,IACF;AACA,QAAI,QAAQ,KAAK,EAAE,QAAQ,CAAC,aAAa,QAAQ;AAC/C,cAAQ,IAAI,KAAK,WAAW;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC3FA,SAAS,aAAa,WAAW,SAAS,QAAQ,gBAAgB;;;ACE3D,SAAS,qBACd,OACA,UACU;AACV,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,SAAS,MAAM,GAAG,EAAE;AAAA,IAC7B,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,cACd,MACA,SACU;AACV,SAAO;AAAA,IACL,IAAI,SAAS;AAAA,IACb;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,oBAA4B,OAAmC;AAC7E,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,SAAS,gBAAgB,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AACxF;AAEO,SAAS,oBAA4B,OAAmC;AAC7E,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,SAAS,WAAW,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AACrF;AAEA,SAAS,WAAmB;AAC1B,SAAO,WAAW,QAAQ,aAAa,KAAK,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC;AAChF;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;;;ADnCO,SAAS,QAId,UAAsD,CAAC,GAAoC;AAC3F,QAAM,CAAC,UAAU,WAAW,IAAI,SAAqB,MAAM,CAAC,GAAI,QAAQ,mBAAmB,CAAC,CAAE,CAAC;AAC/F,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAmB,CAAC,CAAC;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAoD,MAAM;AACtF,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAkB;AAC5C,QAAM,WAAW,OAAoC,MAAS;AAC9D,QAAM,cAAc,OAAO,QAAQ;AAEnC,YAAU,MAAM;AACd,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,QAAQ,CAAC;AAEb,YAAU,MAAM;AACd,WAAO,MAAM;AACX,eAAS,SAAS,MAAM;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,QAAQ,MAAM;AAC9B,QAAI,QAAQ,cAAc,QAAW;AACnC,aAAO,QAAQ;AAAA,IACjB;AACA,QAAI,QAAQ,aAAa,QAAW;AAClC,aAAO;AAAA,IACT;AAEA,WAAO,oBAAsC;AAAA,MAC3C,UAAU,QAAQ;AAAA,MAClB,QAAQ,QAAQ,UAAU;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,WAAW,QAAQ,UAAU,QAAQ,MAAM,CAAC;AAExD,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,eAAe,QAAQ,gBAAgB;AAE7C,QAAM,sBAAsB,YAAY,CAAC,aAAqBC,UAAiB;AAC7E;AAAA,MAAY,CAAC,YACX,QAAQ;AAAA,QAAI,CAAC,YACX,QAAQ,OAAO,cACV,EAAE,GAAG,SAAS,SAAS,GAAG,QAAQ,OAAO,GAAGA,KAAI,GAAG,IACpD;AAAA,MACN;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,uBAAuB,YAAY,CAAC,aAAqBA,UAAiB;AAC9E;AAAA,MAAY,CAAC,YACX,QAAQ;AAAA,QAAI,CAAC,YACX,QAAQ,OAAO,cAAe,EAAE,GAAG,SAAS,SAASA,MAAK,IAAiB;AAAA,MAC7E;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO;AAAA,IACX,OAAO,cAAuB;AAC5B,UAAI,cAAc,QAAW;AAC3B,cAAM,IAAI,MAAM,+CAA+C;AAAA,MACjE;AAEA,YAAM,UAAU,aAAa;AAC7B,UAAI,QAAQ,KAAK,EAAE,WAAW,GAAG;AAC/B;AAAA,MACF;AAEA,eAAS,SAAS,MAAM;AACxB,YAAM,kBAAkB,IAAI,gBAAgB;AAC5C,eAAS,UAAU;AAEnB,YAAM,cAAc,cAAwB,QAAQ,OAAO;AAC3D,YAAM,mBAAmB,cAAwB,aAAa,EAAE;AAChE,YAAM,kBAAkB,CAAC,GAAG,YAAY,SAAS,WAAW;AAC5D,YAAM,UAAU,cAAc,SAAS,eAAe;AAEtD,eAAS,EAAE;AACX,eAAS,MAAS;AAClB,gBAAU,WAAW;AACrB,gBAAU,CAAC,CAAC;AACZ,kBAAY,CAAC,GAAG,iBAAiB,gBAAgB,CAAC;AAElD,UAAI;AACF,yBAAiB,SAAS,UAAU,KAAK,SAAS,EAAE,QAAQ,gBAAgB,OAAO,CAAC,GAAG;AACrF,oBAAU,CAAC,YAAY,CAAC,GAAG,SAAS,KAAK,CAAC;AAC1C,kBAAQ,UAAU,KAAK;AAEvB,gBAAM,QAAQ,aAAa,KAAK;AAChC,cAAI,UAAU,UAAa,MAAM,SAAS,GAAG;AAC3C,gCAAoB,iBAAiB,IAAI,KAAK;AAAA,UAChD;AAEA,gBAAM,QAAQ,aAAa,KAAK;AAChC,cAAI,UAAU,QAAW;AACvB,iCAAqB,iBAAiB,IAAI,KAAK;AAAA,UACjD;AAAA,QACF;AAEA,YAAI,CAAC,gBAAgB,OAAO,SAAS;AACnC,oBAAU,MAAM;AAAA,QAClB;AAAA,MACF,SAAS,QAAQ;AACf,YAAI,aAAa,MAAM,GAAG;AACxB,oBAAU,MAAM;AAChB;AAAA,QACF;AAEA,iBAAS,MAAM;AACf,kBAAU,OAAO;AACjB,gBAAQ,UAAU,MAAM;AAAA,MAC1B,UAAE;AACA,YAAI,SAAS,YAAY,iBAAiB;AACxC,mBAAS,UAAU;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,YAAY,MAAM;AAC7B,aAAS,SAAS,MAAM;AACxB,aAAS,UAAU;AACnB,cAAU,MAAM;AAAA,EAClB,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,YAAY,CAAC,iBAA8B;AACvD,UAAM,gBAAgB,gBAAgB,CAAC;AACvC,gBAAY,UAAU;AACtB,aAAS,SAAS,MAAM;AACxB,aAAS,UAAU;AACnB,gBAAY,aAAa;AACzB,cAAU,CAAC,CAAC;AACZ,aAAS,MAAS;AAClB,aAAS,EAAE;AACX,cAAU,MAAM;AAAA,EAClB,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO,SACV,OAAO,CAAC,YAAY,QAAQ,SAAS,WAAW,EAChD,IAAI,CAAC,YAAY,QAAQ,OAAO,EAChC,KAAK,EAAE;AAEV,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,aAAa,OAAyB;AAC7C,SAAO,iBAAiB,gBAAgB,MAAM,SAAS;AACzD;","names":["trimmed","text"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anvia/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "React hooks and client transports for Anvia applications.",
|
|
5
5
|
"author": "anvia",
|
|
6
6
|
"maintainer": "Indra Zulfi",
|
|
@@ -29,15 +29,21 @@
|
|
|
29
29
|
"react": ">=18"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
+
"@testing-library/react": "^16.3.2",
|
|
32
33
|
"@types/node": "^24.9.1",
|
|
33
34
|
"@types/react": "^19.2.14",
|
|
35
|
+
"@types/react-dom": "^19.2.3",
|
|
36
|
+
"@vitest/coverage-v8": "4.1.5",
|
|
37
|
+
"happy-dom": "20.9.0",
|
|
34
38
|
"react": "^19.2.6",
|
|
39
|
+
"react-dom": "19.2.6",
|
|
35
40
|
"tsup": "^8.5.0",
|
|
36
41
|
"typescript": "^5.9.3",
|
|
37
42
|
"vitest": "^4.0.8"
|
|
38
43
|
},
|
|
39
44
|
"scripts": {
|
|
40
45
|
"build": "tsup src/index.ts --format esm --dts --sourcemap --clean --external react",
|
|
46
|
+
"coverage": "vitest run --coverage",
|
|
41
47
|
"test": "vitest run",
|
|
42
48
|
"typecheck": "tsc --noEmit"
|
|
43
49
|
}
|