@anvia/client 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -70
- package/dist/chunk-63JX2QNP.js +86 -0
- package/dist/chunk-63JX2QNP.js.map +1 -0
- package/dist/{chunk-2KGXQZWA.js → chunk-HZZDET2H.js} +5 -83
- package/dist/chunk-HZZDET2H.js.map +1 -0
- package/dist/durable.d.ts +64 -0
- package/dist/durable.js +242 -0
- package/dist/durable.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/transport/index.js +4 -2
- package/package.json +16 -5
- package/dist/chunk-2KGXQZWA.js.map +0 -1
package/dist/transport/index.js
CHANGED
|
@@ -2,10 +2,12 @@ import {
|
|
|
2
2
|
EventStreamHttpError,
|
|
3
3
|
createDirectEventTransport,
|
|
4
4
|
createFetchEventTransport,
|
|
5
|
-
fetchEventStream
|
|
5
|
+
fetchEventStream
|
|
6
|
+
} from "../chunk-HZZDET2H.js";
|
|
7
|
+
import {
|
|
6
8
|
readJsonlStream,
|
|
7
9
|
readSseStream
|
|
8
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-63JX2QNP.js";
|
|
9
11
|
export {
|
|
10
12
|
EventStreamHttpError,
|
|
11
13
|
createDirectEventTransport,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anvia/client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Framework-neutral client protocol, transports, and UI message state for Anvia.",
|
|
5
5
|
"author": "anvia",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,20 +26,31 @@
|
|
|
26
26
|
"./transport": {
|
|
27
27
|
"types": "./dist/transport/index.d.ts",
|
|
28
28
|
"import": "./dist/transport/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./durable": {
|
|
31
|
+
"types": "./dist/durable.d.ts",
|
|
32
|
+
"import": "./dist/durable.js"
|
|
29
33
|
}
|
|
30
34
|
},
|
|
31
35
|
"devDependencies": {
|
|
32
36
|
"@types/node": "^24.9.1",
|
|
33
37
|
"tsup": "^8.5.0",
|
|
34
38
|
"typescript": "^5.9.3",
|
|
35
|
-
"vitest": "^4.
|
|
36
|
-
"@anvia/core": "1.
|
|
39
|
+
"vitest": "^4.1.11",
|
|
40
|
+
"@anvia/core": "1.7.0",
|
|
41
|
+
"@anvia/durable": "0.1.1"
|
|
37
42
|
},
|
|
38
43
|
"peerDependencies": {
|
|
39
|
-
"@anvia/core": "^1.
|
|
44
|
+
"@anvia/core": "^1.7.0",
|
|
45
|
+
"@anvia/durable": "^0.1.1"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"@anvia/durable": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
40
51
|
},
|
|
41
52
|
"scripts": {
|
|
42
|
-
"build": "tsup src/index.ts src/transport/index.ts --format esm --dts --sourcemap --clean",
|
|
53
|
+
"build": "tsup src/index.ts src/transport/index.ts src/durable.ts --format esm --dts --sourcemap --clean",
|
|
43
54
|
"coverage": "vitest run --coverage",
|
|
44
55
|
"test": "vitest run",
|
|
45
56
|
"typecheck": "tsc --noEmit"
|
|
@@ -1 +0,0 @@
|
|
|
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":"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","names":["value"]}
|