@anvia/client 1.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Indra Zulfi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @anvia/client
2
+
3
+ Framework-neutral client protocol, transports, message conversion, and stream state for Anvia.
4
+
5
+ `@anvia/core` owns native completion and Agent events. `@anvia/client` owns the public wire boundary:
6
+
7
+ ```ts
8
+ import { completionToClientStream, parseClientStreamRequest } from "@anvia/client";
9
+ import { streamCompletion } from "@anvia/core";
10
+
11
+ const request = parseClientStreamRequest(await httpRequest.json());
12
+ const events = completionToClientStream({
13
+ events: streamCompletion({ model, messages: request.messages }),
14
+ });
15
+ ```
16
+
17
+ The request carries core `Message[]`; client-side `UIMessage[]` never crosses the server boundary.
18
+ The response uses `ClientStreamEvent` records inside an always-framed `anvia.client.v2` stream.
19
+
20
+ ## Public API
21
+
22
+ - `completionToClientStream({ events, ...options })` adapts native completion events.
23
+ - `agentToClientStream({ events, ...options })` adapts native Agent events, including nested-agent
24
+ scope.
25
+ - `parseClientStreamRequest`, `parseClientStreamEvent`, and `parseClientStreamFrame` validate public
26
+ input at runtime.
27
+ - `createHttpClientTransport(options)` consumes framed JSONL or SSE responses and validates the
28
+ protocol header, frame order, stream identity, and event IDs.
29
+ - `createDirectClientTransport({ handler })` provides the same framed contract without HTTP.
30
+ - `messagesToUIMessages` and `uiMessagesToMessages` explicitly convert server messages and UI
31
+ state.
32
+ - `applyClientStreamEvent(messages, event)` applies canonical events to `UIMessage[]` state.
33
+ - `parseUIMessage` and `parseUIMessages` validate externally loaded UI state.
34
+
35
+ Tool-call start, delta, and end events are automatic when the provider exposes streamed arguments.
36
+ Errors are masked by default. Use `mapError` only at the server adapter boundary when an application
37
+ intentionally exposes a safe error shape. Non-JSON outputs require an explicit `mapOutput`; returning
38
+ `undefined` intentionally omits the output, while returning `null` exposes JSON `null`.
39
+
40
+ `UIMessage.metadata` remains application-owned and round-trips unchanged. Runtime details such as
41
+ run ID, usage, context usage, status, and trace correlation are stored separately in
42
+ `UIMessage.generation`.
43
+
44
+ Application-specific stream data is explicit and schema-validated:
45
+
46
+ ```ts
47
+ type AppData = {
48
+ citation_preview: { title: string; url: string };
49
+ };
50
+
51
+ const transport = createHttpClientTransport<ClientStreamRequest, AppData>({
52
+ endpoint: "/api/chat",
53
+ dataSchemas: {
54
+ citation_preview: citationPreviewSchema,
55
+ },
56
+ });
57
+ ```
58
+
59
+ Low-level generic JSONL/SSE readers and event transports are available from
60
+ `@anvia/client/transport`. They do not imply the Anvia client protocol; use them only for endpoints
61
+ that intentionally expose a different event contract.
@@ -0,0 +1,201 @@
1
+ // src/transport/streams.ts
2
+ async function* readJsonlStream(stream) {
3
+ const reader = stream.getReader();
4
+ const decoder = new TextDecoder();
5
+ let buffer = "";
6
+ let completed = false;
7
+ try {
8
+ while (true) {
9
+ const next = await reader.read();
10
+ if (next.done) {
11
+ completed = true;
12
+ break;
13
+ }
14
+ buffer += decoder.decode(next.value, { stream: true });
15
+ const lines = buffer.split(/\r?\n/);
16
+ buffer = lines.pop() ?? "";
17
+ for (const line of lines) {
18
+ const value2 = line.trim();
19
+ if (value2.length > 0) yield JSON.parse(value2);
20
+ }
21
+ }
22
+ buffer += decoder.decode();
23
+ const value = buffer.trim();
24
+ if (value.length > 0) yield JSON.parse(value);
25
+ } finally {
26
+ if (!completed) await cancelReader(reader);
27
+ reader.releaseLock();
28
+ }
29
+ }
30
+ async function* readSseStream(stream) {
31
+ const reader = stream.getReader();
32
+ const decoder = new TextDecoder();
33
+ let buffer = "";
34
+ let data = [];
35
+ let completed = false;
36
+ function parseLine(line) {
37
+ if (line === "") {
38
+ const complete = data.length === 0 ? void 0 : data.join("\n");
39
+ data = [];
40
+ return complete;
41
+ }
42
+ if (line.startsWith(":")) return void 0;
43
+ const separator = line.indexOf(":");
44
+ const field = separator === -1 ? line : line.slice(0, separator);
45
+ const value = separator === -1 ? "" : line.slice(separator + 1).replace(/^ /, "");
46
+ if (field === "data") data.push(value);
47
+ return void 0;
48
+ }
49
+ try {
50
+ while (true) {
51
+ const next = await reader.read();
52
+ if (next.done) {
53
+ completed = true;
54
+ break;
55
+ }
56
+ buffer += decoder.decode(next.value, { stream: true });
57
+ const lines = buffer.split(/\r?\n/);
58
+ buffer = lines.pop() ?? "";
59
+ for (const line of lines) {
60
+ const complete = parseLine(line);
61
+ if (complete !== void 0) yield JSON.parse(complete);
62
+ }
63
+ }
64
+ buffer += decoder.decode();
65
+ if (buffer.length > 0) {
66
+ const complete = parseLine(buffer);
67
+ if (complete !== void 0) yield JSON.parse(complete);
68
+ }
69
+ if (data.length > 0) yield JSON.parse(data.join("\n"));
70
+ } finally {
71
+ if (!completed) await cancelReader(reader);
72
+ reader.releaseLock();
73
+ }
74
+ }
75
+ async function cancelReader(reader) {
76
+ try {
77
+ await reader.cancel();
78
+ } catch {
79
+ }
80
+ }
81
+
82
+ // src/transport/fetch.ts
83
+ var EventStreamHttpError = class extends Error {
84
+ constructor(response, body) {
85
+ super(`Event stream request failed with status ${response.status}`);
86
+ this.response = response;
87
+ this.body = body;
88
+ this.name = "EventStreamHttpError";
89
+ }
90
+ response;
91
+ body;
92
+ };
93
+ async function* fetchEventStream(options) {
94
+ const fetchImpl = options.fetch ?? globalThis.fetch;
95
+ if (fetchImpl === void 0) throw new Error("fetchEventStream requires a fetch implementation.");
96
+ const response = await fetchImpl(options.input, fetchOptions(options));
97
+ if (!response.ok) throw new EventStreamHttpError(response, await response.text());
98
+ options.validateResponse?.(response);
99
+ if (response.body === null) throw new Error("Event stream response does not include a body.");
100
+ const format = options.format === void 0 || options.format === "auto" ? inferEventStreamFormat(response.headers.get("content-type")) : options.format;
101
+ if (format === "sse") {
102
+ yield* readSseStream(response.body);
103
+ } else {
104
+ yield* readJsonlStream(response.body);
105
+ }
106
+ }
107
+ function fetchOptions(options) {
108
+ const {
109
+ input: _input,
110
+ format: _format,
111
+ fetch: _fetch,
112
+ validateResponse: _validate,
113
+ ...init
114
+ } = options;
115
+ return init;
116
+ }
117
+ function inferEventStreamFormat(contentType) {
118
+ return contentType?.toLowerCase().includes("text/event-stream") ? "sse" : "jsonl";
119
+ }
120
+
121
+ // src/transport/event-transport.ts
122
+ function createFetchEventTransport(options) {
123
+ return {
124
+ async *send(transportOptions) {
125
+ const endpoint = typeof options.endpoint === "function" ? options.endpoint(transportOptions) : options.endpoint;
126
+ const requestHeaders = await resolveHeaders(options.headers, transportOptions);
127
+ const headers = mergeHeaders(requestHeaders, transportOptions.headers);
128
+ const method = options.method ?? "POST";
129
+ const body = await resolveBody(options.body, transportOptions, headers, method);
130
+ const init = {
131
+ ...options.init,
132
+ input: endpoint,
133
+ method,
134
+ headers,
135
+ format: options.format ?? "auto"
136
+ };
137
+ if (body !== void 0) init.body = body;
138
+ if (transportOptions.abortSignal !== void 0) init.signal = transportOptions.abortSignal;
139
+ if (options.fetch !== void 0) init.fetch = options.fetch;
140
+ if (options.validateResponse !== void 0) init.validateResponse = options.validateResponse;
141
+ for await (const event of fetchEventStream(init)) {
142
+ yield options.mapEvent === void 0 ? event : options.mapEvent(event);
143
+ }
144
+ }
145
+ };
146
+ }
147
+ function createDirectEventTransport(options) {
148
+ return {
149
+ async *send(context) {
150
+ const iterator = options.handler(context)[Symbol.asyncIterator]();
151
+ let closePromise;
152
+ const close = () => {
153
+ closePromise ??= Promise.resolve(iterator.return?.());
154
+ return closePromise;
155
+ };
156
+ const onAbort = () => {
157
+ void close();
158
+ };
159
+ context.abortSignal?.addEventListener("abort", onAbort, { once: true });
160
+ try {
161
+ while (!context.abortSignal?.aborted) {
162
+ const next = await iterator.next();
163
+ if (next.done) break;
164
+ yield next.value;
165
+ }
166
+ } finally {
167
+ context.abortSignal?.removeEventListener("abort", onAbort);
168
+ await close();
169
+ }
170
+ }
171
+ };
172
+ }
173
+ async function resolveHeaders(headers, context) {
174
+ return typeof headers === "function" ? headers(context) : headers;
175
+ }
176
+ async function resolveBody(body, context, headers, method) {
177
+ if (body !== void 0) return body({ ...context, headers });
178
+ if (method.toUpperCase() === "GET" || method.toUpperCase() === "HEAD") return void 0;
179
+ if (!headers.has("content-type")) headers.set("content-type", "application/json");
180
+ return JSON.stringify(context.request);
181
+ }
182
+ function mergeHeaders(...values) {
183
+ const headers = new Headers();
184
+ for (const value of values) {
185
+ if (value === void 0) continue;
186
+ new Headers(value).forEach((headerValue, key) => {
187
+ headers.set(key, headerValue);
188
+ });
189
+ }
190
+ return headers;
191
+ }
192
+
193
+ export {
194
+ readJsonlStream,
195
+ readSseStream,
196
+ EventStreamHttpError,
197
+ fetchEventStream,
198
+ createFetchEventTransport,
199
+ createDirectEventTransport
200
+ };
201
+ //# sourceMappingURL=chunk-2KGXQZWA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/transport/streams.ts","../src/transport/fetch.ts","../src/transport/event-transport.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 let completed = false;\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done) {\n completed = true;\n break;\n }\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n const value = line.trim();\n if (value.length > 0) yield JSON.parse(value) as TEvent;\n }\n }\n buffer += decoder.decode();\n const value = buffer.trim();\n if (value.length > 0) yield JSON.parse(value) as TEvent;\n } finally {\n if (!completed) await cancelReader(reader);\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 data: string[] = [];\n let completed = false;\n\n function parseLine(line: string): string | undefined {\n if (line === \"\") {\n const complete = data.length === 0 ? undefined : data.join(\"\\n\");\n data = [];\n return complete;\n }\n if (line.startsWith(\":\")) return undefined;\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 if (field === \"data\") data.push(value);\n return undefined;\n }\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done) {\n completed = true;\n break;\n }\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n const complete = parseLine(line);\n if (complete !== undefined) yield JSON.parse(complete) as TEvent;\n }\n }\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const complete = parseLine(buffer);\n if (complete !== undefined) yield JSON.parse(complete) as TEvent;\n }\n if (data.length > 0) yield JSON.parse(data.join(\"\\n\")) as TEvent;\n } finally {\n if (!completed) await cancelReader(reader);\n reader.releaseLock();\n }\n}\n\nasync function cancelReader(reader: ReadableStreamDefaultReader<Uint8Array>): Promise<void> {\n try {\n await reader.cancel();\n } catch {\n // The request may already have been aborted by its owner.\n }\n}\n","import { readJsonlStream, readSseStream } from \"./streams\";\nimport type { EventStreamFormat } from \"./types\";\n\nexport type FetchEventStreamOptions = Omit<RequestInit, \"headers\"> & {\n input: string | URL | Request;\n format?: EventStreamFormat | \"auto\";\n fetch?: typeof fetch;\n headers?: HeadersInit;\n validateResponse?: (response: Response) => void;\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 options: FetchEventStreamOptions,\n): AsyncIterable<TEvent> {\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (fetchImpl === undefined) throw new Error(\"fetchEventStream requires a fetch implementation.\");\n\n const response = await fetchImpl(options.input, fetchOptions(options));\n if (!response.ok) throw new EventStreamHttpError(response, await response.text());\n options.validateResponse?.(response);\n if (response.body === null) throw new Error(\"Event stream response does not include a body.\");\n\n const format =\n options.format === undefined || options.format === \"auto\"\n ? inferEventStreamFormat(response.headers.get(\"content-type\"))\n : options.format;\n if (format === \"sse\") {\n yield* readSseStream<TEvent>(response.body);\n } else {\n yield* readJsonlStream<TEvent>(response.body);\n }\n}\n\nfunction fetchOptions(options: FetchEventStreamOptions): RequestInit {\n const {\n input: _input,\n format: _format,\n fetch: _fetch,\n validateResponse: _validate,\n ...init\n } = 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, EventTransportSendOptions } from \"./types\";\n\nexport type EventTransportContext<TRequest> = EventTransportSendOptions<TRequest>;\n\nexport type EventTransportBodyContext<TRequest> = Omit<\n EventTransportContext<TRequest>,\n \"headers\"\n> & {\n headers: Headers;\n};\n\nexport type CreateFetchEventTransportOptions<TRequest, TEvent> = {\n endpoint: string | URL | ((context: EventTransportContext<TRequest>) => string | URL);\n method?: string;\n format?: EventStreamFormat | \"auto\";\n fetch?: typeof fetch;\n headers?:\n | HeadersInit\n | ((context: EventTransportContext<TRequest>) => HeadersInit | Promise<HeadersInit>);\n body?: (\n context: EventTransportBodyContext<TRequest>,\n ) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;\n init?: Omit<RequestInit, \"body\" | \"headers\" | \"method\" | \"signal\">;\n mapEvent?: (event: unknown) => TEvent;\n validateResponse?: (response: Response) => void;\n};\n\nexport function createFetchEventTransport<TRequest, TEvent = unknown>(\n options: CreateFetchEventTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return {\n async *send(transportOptions) {\n const endpoint =\n typeof options.endpoint === \"function\"\n ? options.endpoint(transportOptions)\n : options.endpoint;\n const requestHeaders = await resolveHeaders(options.headers, transportOptions);\n const headers = mergeHeaders(requestHeaders, transportOptions.headers);\n const method = options.method ?? \"POST\";\n const body = await resolveBody(options.body, transportOptions, headers, method);\n const init: FetchEventStreamOptions = {\n ...options.init,\n input: endpoint,\n method,\n headers,\n format: options.format ?? \"auto\",\n };\n if (body !== undefined) init.body = body;\n if (transportOptions.abortSignal !== undefined) init.signal = transportOptions.abortSignal;\n if (options.fetch !== undefined) init.fetch = options.fetch;\n if (options.validateResponse !== undefined) init.validateResponse = options.validateResponse;\n\n for await (const event of fetchEventStream<unknown>(init)) {\n yield options.mapEvent === undefined ? (event as TEvent) : options.mapEvent(event);\n }\n },\n };\n}\n\nexport function createDirectEventTransport<TRequest, TEvent>(options: {\n handler(context: EventTransportContext<TRequest>): AsyncIterable<TEvent>;\n}): EventTransport<TRequest, TEvent> {\n return {\n async *send(context) {\n const iterator = options.handler(context)[Symbol.asyncIterator]();\n let closePromise: Promise<unknown> | undefined;\n const close = () => {\n closePromise ??= Promise.resolve(iterator.return?.());\n return closePromise;\n };\n const onAbort = () => {\n void close();\n };\n context.abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n try {\n while (!context.abortSignal?.aborted) {\n const next = await iterator.next();\n if (next.done) break;\n yield next.value;\n }\n } finally {\n context.abortSignal?.removeEventListener(\"abort\", onAbort);\n await close();\n }\n },\n };\n}\n\nasync function resolveHeaders<TRequest>(\n headers: CreateFetchEventTransportOptions<TRequest, unknown>[\"headers\"],\n context: EventTransportContext<TRequest>,\n): Promise<HeadersInit | undefined> {\n return typeof headers === \"function\" ? headers(context) : headers;\n}\n\nasync function resolveBody<TRequest>(\n body: CreateFetchEventTransportOptions<TRequest, unknown>[\"body\"],\n context: EventTransportContext<TRequest>,\n headers: Headers,\n method: string,\n): Promise<BodyInit | null | undefined> {\n if (body !== undefined) return body({ ...context, headers });\n if (method.toUpperCase() === \"GET\" || method.toUpperCase() === \"HEAD\") return undefined;\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n return JSON.stringify(context.request);\n}\n\nfunction mergeHeaders(...values: Array<HeadersInit | undefined>): Headers {\n const headers = new Headers();\n for (const value of values) {\n if (value === undefined) continue;\n new Headers(value).forEach((headerValue, key) => {\n headers.set(key, headerValue);\n });\n }\n return headers;\n}\n"],"mappings":";AAAA,gBAAuB,gBACrB,QACuB;AACvB,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AACb,MAAI,YAAY;AAEhB,MAAI;AACF,WAAO,MAAM;AACX,YAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,UAAI,KAAK,MAAM;AACb,oBAAY;AACZ;AAAA,MACF;AACA,gBAAU,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;AACrD,YAAM,QAAQ,OAAO,MAAM,OAAO;AAClC,eAAS,MAAM,IAAI,KAAK;AACxB,iBAAW,QAAQ,OAAO;AACxB,cAAMA,SAAQ,KAAK,KAAK;AACxB,YAAIA,OAAM,SAAS,EAAG,OAAM,KAAK,MAAMA,MAAK;AAAA,MAC9C;AAAA,IACF;AACA,cAAU,QAAQ,OAAO;AACzB,UAAM,QAAQ,OAAO,KAAK;AAC1B,QAAI,MAAM,SAAS,EAAG,OAAM,KAAK,MAAM,KAAK;AAAA,EAC9C,UAAE;AACA,QAAI,CAAC,UAAW,OAAM,aAAa,MAAM;AACzC,WAAO,YAAY;AAAA,EACrB;AACF;AAEA,gBAAuB,cACrB,QACuB;AACvB,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AACb,MAAI,OAAiB,CAAC;AACtB,MAAI,YAAY;AAEhB,WAAS,UAAU,MAAkC;AACnD,QAAI,SAAS,IAAI;AACf,YAAM,WAAW,KAAK,WAAW,IAAI,SAAY,KAAK,KAAK,IAAI;AAC/D,aAAO,CAAC;AACR,aAAO;AAAA,IACT;AACA,QAAI,KAAK,WAAW,GAAG,EAAG,QAAO;AACjC,UAAM,YAAY,KAAK,QAAQ,GAAG;AAClC,UAAM,QAAQ,cAAc,KAAK,OAAO,KAAK,MAAM,GAAG,SAAS;AAC/D,UAAM,QAAQ,cAAc,KAAK,KAAK,KAAK,MAAM,YAAY,CAAC,EAAE,QAAQ,MAAM,EAAE;AAChF,QAAI,UAAU,OAAQ,MAAK,KAAK,KAAK;AACrC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,MAAM;AACX,YAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,UAAI,KAAK,MAAM;AACb,oBAAY;AACZ;AAAA,MACF;AACA,gBAAU,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;AACrD,YAAM,QAAQ,OAAO,MAAM,OAAO;AAClC,eAAS,MAAM,IAAI,KAAK;AACxB,iBAAW,QAAQ,OAAO;AACxB,cAAM,WAAW,UAAU,IAAI;AAC/B,YAAI,aAAa,OAAW,OAAM,KAAK,MAAM,QAAQ;AAAA,MACvD;AAAA,IACF;AACA,cAAU,QAAQ,OAAO;AACzB,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,WAAW,UAAU,MAAM;AACjC,UAAI,aAAa,OAAW,OAAM,KAAK,MAAM,QAAQ;AAAA,IACvD;AACA,QAAI,KAAK,SAAS,EAAG,OAAM,KAAK,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,EACvD,UAAE;AACA,QAAI,CAAC,UAAW,OAAM,aAAa,MAAM;AACzC,WAAO,YAAY;AAAA,EACrB;AACF;AAEA,eAAe,aAAa,QAAgE;AAC1F,MAAI;AACF,UAAM,OAAO,OAAO;AAAA,EACtB,QAAQ;AAAA,EAER;AACF;;;AC7EO,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,SACuB;AACvB,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,MAAI,cAAc,OAAW,OAAM,IAAI,MAAM,mDAAmD;AAEhG,QAAM,WAAW,MAAM,UAAU,QAAQ,OAAO,aAAa,OAAO,CAAC;AACrE,MAAI,CAAC,SAAS,GAAI,OAAM,IAAI,qBAAqB,UAAU,MAAM,SAAS,KAAK,CAAC;AAChF,UAAQ,mBAAmB,QAAQ;AACnC,MAAI,SAAS,SAAS,KAAM,OAAM,IAAI,MAAM,gDAAgD;AAE5F,QAAM,SACJ,QAAQ,WAAW,UAAa,QAAQ,WAAW,SAC/C,uBAAuB,SAAS,QAAQ,IAAI,cAAc,CAAC,IAC3D,QAAQ;AACd,MAAI,WAAW,OAAO;AACpB,WAAO,cAAsB,SAAS,IAAI;AAAA,EAC5C,OAAO;AACL,WAAO,gBAAwB,SAAS,IAAI;AAAA,EAC9C;AACF;AAEA,SAAS,aAAa,SAA+C;AACnE,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,GAAG;AAAA,EACL,IAAI;AACJ,SAAO;AACT;AAEA,SAAS,uBAAuB,aAA+C;AAC7E,SAAO,aAAa,YAAY,EAAE,SAAS,mBAAmB,IAAI,QAAQ;AAC5E;;;AC5BO,SAAS,0BACd,SACkC;AAClC,SAAO;AAAA,IACL,OAAO,KAAK,kBAAkB;AAC5B,YAAM,WACJ,OAAO,QAAQ,aAAa,aACxB,QAAQ,SAAS,gBAAgB,IACjC,QAAQ;AACd,YAAM,iBAAiB,MAAM,eAAe,QAAQ,SAAS,gBAAgB;AAC7E,YAAM,UAAU,aAAa,gBAAgB,iBAAiB,OAAO;AACrE,YAAM,SAAS,QAAQ,UAAU;AACjC,YAAM,OAAO,MAAM,YAAY,QAAQ,MAAM,kBAAkB,SAAS,MAAM;AAC9E,YAAM,OAAgC;AAAA,QACpC,GAAG,QAAQ;AAAA,QACX,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,QAAQ,QAAQ,UAAU;AAAA,MAC5B;AACA,UAAI,SAAS,OAAW,MAAK,OAAO;AACpC,UAAI,iBAAiB,gBAAgB,OAAW,MAAK,SAAS,iBAAiB;AAC/E,UAAI,QAAQ,UAAU,OAAW,MAAK,QAAQ,QAAQ;AACtD,UAAI,QAAQ,qBAAqB,OAAW,MAAK,mBAAmB,QAAQ;AAE5E,uBAAiB,SAAS,iBAA0B,IAAI,GAAG;AACzD,cAAM,QAAQ,aAAa,SAAa,QAAmB,QAAQ,SAAS,KAAK;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,2BAA6C,SAExB;AACnC,SAAO;AAAA,IACL,OAAO,KAAK,SAAS;AACnB,YAAM,WAAW,QAAQ,QAAQ,OAAO,EAAE,OAAO,aAAa,EAAE;AAChE,UAAI;AACJ,YAAM,QAAQ,MAAM;AAClB,yBAAiB,QAAQ,QAAQ,SAAS,SAAS,CAAC;AACpD,eAAO;AAAA,MACT;AACA,YAAM,UAAU,MAAM;AACpB,aAAK,MAAM;AAAA,MACb;AACA,cAAQ,aAAa,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACtE,UAAI;AACF,eAAO,CAAC,QAAQ,aAAa,SAAS;AACpC,gBAAM,OAAO,MAAM,SAAS,KAAK;AACjC,cAAI,KAAK,KAAM;AACf,gBAAM,KAAK;AAAA,QACb;AAAA,MACF,UAAE;AACA,gBAAQ,aAAa,oBAAoB,SAAS,OAAO;AACzD,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,eACb,SACA,SACkC;AAClC,SAAO,OAAO,YAAY,aAAa,QAAQ,OAAO,IAAI;AAC5D;AAEA,eAAe,YACb,MACA,SACA,SACA,QACsC;AACtC,MAAI,SAAS,OAAW,QAAO,KAAK,EAAE,GAAG,SAAS,QAAQ,CAAC;AAC3D,MAAI,OAAO,YAAY,MAAM,SAAS,OAAO,YAAY,MAAM,OAAQ,QAAO;AAC9E,MAAI,CAAC,QAAQ,IAAI,cAAc,EAAG,SAAQ,IAAI,gBAAgB,kBAAkB;AAChF,SAAO,KAAK,UAAU,QAAQ,OAAO;AACvC;AAEA,SAAS,gBAAgB,QAAiD;AACxE,QAAM,UAAU,IAAI,QAAQ;AAC5B,aAAW,SAAS,QAAQ;AAC1B,QAAI,UAAU,OAAW;AACzB,QAAI,QAAQ,KAAK,EAAE,QAAQ,CAAC,aAAa,QAAQ;AAC/C,cAAQ,IAAI,KAAK,WAAW;AAAA,IAC9B,CAAC;AAAA,EACH;AACA,SAAO;AACT;","names":["value"]}
@@ -0,0 +1,31 @@
1
+ type EventStreamFormat = "jsonl" | "sse";
2
+ type EventTransportSendOptions<TRequest> = {
3
+ request: TRequest;
4
+ abortSignal?: AbortSignal;
5
+ headers?: HeadersInit;
6
+ };
7
+ type EventTransport<TRequest, TEvent> = {
8
+ send(options: EventTransportSendOptions<TRequest>): AsyncIterable<TEvent>;
9
+ };
10
+
11
+ type EventTransportContext<TRequest> = EventTransportSendOptions<TRequest>;
12
+ type EventTransportBodyContext<TRequest> = Omit<EventTransportContext<TRequest>, "headers"> & {
13
+ headers: Headers;
14
+ };
15
+ type CreateFetchEventTransportOptions<TRequest, TEvent> = {
16
+ endpoint: string | URL | ((context: EventTransportContext<TRequest>) => string | URL);
17
+ method?: string;
18
+ format?: EventStreamFormat | "auto";
19
+ fetch?: typeof fetch;
20
+ headers?: HeadersInit | ((context: EventTransportContext<TRequest>) => HeadersInit | Promise<HeadersInit>);
21
+ body?: (context: EventTransportBodyContext<TRequest>) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;
22
+ init?: Omit<RequestInit, "body" | "headers" | "method" | "signal">;
23
+ mapEvent?: (event: unknown) => TEvent;
24
+ validateResponse?: (response: Response) => void;
25
+ };
26
+ declare function createFetchEventTransport<TRequest, TEvent = unknown>(options: CreateFetchEventTransportOptions<TRequest, TEvent>): EventTransport<TRequest, TEvent>;
27
+ declare function createDirectEventTransport<TRequest, TEvent>(options: {
28
+ handler(context: EventTransportContext<TRequest>): AsyncIterable<TEvent>;
29
+ }): EventTransport<TRequest, TEvent>;
30
+
31
+ export { type CreateFetchEventTransportOptions as C, type EventStreamFormat as E, type EventTransport as a, type EventTransportSendOptions as b, createDirectEventTransport as c, createFetchEventTransport as d };