@anvia/server 1.1.4 → 1.2.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/dist/index.js CHANGED
@@ -1,3 +1,15 @@
1
+ import {
2
+ createEventStreamResponse,
3
+ createJsonlStream,
4
+ createMemoryResumableStreamStore,
5
+ createResumableStream,
6
+ createSseStream,
7
+ encodeEventStreamResponse,
8
+ errorEvent,
9
+ resumeEventStreamResponse,
10
+ resumeStreamEvents
11
+ } from "./chunk-E2M7MXTL.js";
12
+
1
13
  // src/client-response.ts
2
14
  import {
3
15
  CLIENT_STREAM_PROTOCOL,
@@ -5,436 +17,6 @@ import {
5
17
  createClientId,
6
18
  parseClientStreamEvent
7
19
  } from "@anvia/client";
8
-
9
- // src/errors.ts
10
- import { isJsonValue } from "@anvia/client";
11
- function errorEvent(error) {
12
- return {
13
- type: "error",
14
- error: serializeError(error)
15
- };
16
- }
17
- function serializeError(error) {
18
- if (error instanceof Error) {
19
- const serialized = {
20
- name: error.name,
21
- message: error.message
22
- };
23
- const code = error.code;
24
- if (typeof code === "string") {
25
- serialized.code = code;
26
- }
27
- const retryable = error.retryable;
28
- if (typeof retryable === "boolean") {
29
- serialized.retryable = retryable;
30
- }
31
- if (isJsonValue(error.details)) {
32
- serialized.details = error.details;
33
- }
34
- return serialized;
35
- }
36
- if (!isJsonValue(error)) {
37
- return { message: String(error) };
38
- }
39
- return error;
40
- }
41
-
42
- // src/jsonl.ts
43
- function createJsonlStream(options) {
44
- const encoder = new TextEncoder();
45
- const iterator = options.events[Symbol.asyncIterator]();
46
- const serialize = options.serialize ?? serializeJson;
47
- return new ReadableStream({
48
- async pull(controller) {
49
- try {
50
- const next = await iterator.next();
51
- if (next.done === true) {
52
- controller.close();
53
- return;
54
- }
55
- controller.enqueue(encoder.encode(`${serialize(next.value)}
56
- `));
57
- } catch (error) {
58
- controller.enqueue(encoder.encode(`${serialize(errorEvent(error))}
59
- `));
60
- controller.close();
61
- }
62
- },
63
- async cancel() {
64
- await iterator.return?.();
65
- }
66
- });
67
- }
68
- function serializeJson(value) {
69
- return JSON.stringify(value);
70
- }
71
-
72
- // src/resumable.ts
73
- function createResumableStream(options) {
74
- const streamId = options.id;
75
- let openPromise;
76
- function start() {
77
- if (openPromise !== void 0) {
78
- return openPromise;
79
- }
80
- openPromise = options.store.open({ streamId }).then(() => void 0);
81
- void drainResumableStream(options.events, options, openPromise);
82
- return openPromise;
83
- }
84
- return {
85
- async *[Symbol.asyncIterator]() {
86
- await start();
87
- yield* resumeStreamEvents({ id: streamId, store: options.store });
88
- }
89
- };
90
- }
91
- async function* resumeStreamEvents(options) {
92
- const streamId = options.id;
93
- yield { type: "stream_start", streamId, eventId: 0 };
94
- const subscribeInput = { streamId };
95
- if (options.after !== void 0) {
96
- subscribeInput.after = options.after;
97
- }
98
- for await (const record of options.store.subscribe(subscribeInput)) {
99
- yield recordToEnvelope(record);
100
- }
101
- const state = await options.store.status({ streamId });
102
- yield stateToEndEnvelope(streamId, state);
103
- }
104
- function createMemoryResumableStreamStore() {
105
- const streams = /* @__PURE__ */ new Map();
106
- function state(stream) {
107
- if (stream === void 0) {
108
- return { status: "missing", lastEventId: 0 };
109
- }
110
- return {
111
- status: stream.status,
112
- lastEventId: stream.records.at(-1)?.eventId ?? 0
113
- };
114
- }
115
- return {
116
- async open(input) {
117
- const existing = streams.get(input.streamId);
118
- if (existing !== void 0) {
119
- closeSubscribers(existing);
120
- }
121
- const stream = {
122
- records: [],
123
- status: "running",
124
- subscribers: /* @__PURE__ */ new Set()
125
- };
126
- streams.set(input.streamId, stream);
127
- return state(stream);
128
- },
129
- async append(input) {
130
- const stream = streams.get(input.streamId);
131
- if (stream === void 0) {
132
- throw new Error(`Resumable stream "${input.streamId}" is not open`);
133
- }
134
- if (stream.status !== "running") {
135
- throw new Error(`Resumable stream "${input.streamId}" is already ${stream.status}`);
136
- }
137
- const record = {
138
- streamId: input.streamId,
139
- eventId: stream.records.length + 1,
140
- event: input.event,
141
- createdAt: /* @__PURE__ */ new Date()
142
- };
143
- stream.records.push(record);
144
- for (const subscriber of stream.subscribers) {
145
- if (record.eventId > subscriber.after) {
146
- subscriber.queue.enqueue(record);
147
- }
148
- }
149
- return record;
150
- },
151
- subscribe(input) {
152
- const after = input.after ?? 0;
153
- return {
154
- [Symbol.asyncIterator]() {
155
- const stream = streams.get(input.streamId);
156
- const queue = createAsyncQueue();
157
- if (stream === void 0) {
158
- queue.close();
159
- return queue[Symbol.asyncIterator]();
160
- }
161
- for (const record of stream.records) {
162
- if (record.eventId > after) {
163
- queue.enqueue(record);
164
- }
165
- }
166
- if (stream.status !== "running") {
167
- queue.close();
168
- return queue[Symbol.asyncIterator]();
169
- }
170
- const subscriber = { after, queue };
171
- stream.subscribers.add(subscriber);
172
- const iterator = queue[Symbol.asyncIterator]();
173
- return {
174
- next: () => iterator.next(),
175
- async return() {
176
- stream.subscribers.delete(subscriber);
177
- queue.close();
178
- return { value: void 0, done: true };
179
- }
180
- };
181
- }
182
- };
183
- },
184
- async status(input) {
185
- return state(streams.get(input.streamId));
186
- },
187
- async close(input) {
188
- const stream = streams.get(input.streamId);
189
- if (stream === void 0) {
190
- return { status: input.status, lastEventId: 0 };
191
- }
192
- stream.status = input.status;
193
- closeSubscribers(stream);
194
- return state(stream);
195
- }
196
- };
197
- }
198
- async function drainResumableStream(events, options, openPromise) {
199
- const streamId = options.id;
200
- try {
201
- await openPromise;
202
- for await (const event of events) {
203
- await options.store.append({ streamId, event });
204
- }
205
- await options.store.close({ streamId, status: "completed" });
206
- } catch (error) {
207
- const event = errorEvent(error);
208
- try {
209
- await options.store.append({ streamId, event });
210
- } catch {
211
- }
212
- try {
213
- await options.store.close({ streamId, status: "error" });
214
- } catch {
215
- }
216
- }
217
- }
218
- function recordToEnvelope(record) {
219
- return {
220
- type: "stream_event",
221
- streamId: record.streamId,
222
- eventId: record.eventId,
223
- event: record.event
224
- };
225
- }
226
- function stateToEndEnvelope(streamId, state) {
227
- return {
228
- type: "stream_end",
229
- streamId,
230
- eventId: state.lastEventId,
231
- status: state.status
232
- };
233
- }
234
- function closeSubscribers(stream) {
235
- for (const subscriber of stream.subscribers) {
236
- subscriber.queue.close();
237
- }
238
- stream.subscribers.clear();
239
- }
240
- function createAsyncQueue() {
241
- const values = [];
242
- const waiters = [];
243
- let closed = false;
244
- let error;
245
- function flush() {
246
- while (waiters.length > 0 && values.length > 0) {
247
- const waiter = waiters.shift();
248
- const value = values.shift();
249
- waiter?.resolve({ value, done: false });
250
- }
251
- if (values.length > 0 || waiters.length === 0 || !closed) {
252
- return;
253
- }
254
- while (waiters.length > 0) {
255
- const waiter = waiters.shift();
256
- if (waiter === void 0) {
257
- continue;
258
- }
259
- if (error !== void 0) {
260
- waiter.reject(error);
261
- } else {
262
- waiter.resolve({ value: void 0, done: true });
263
- }
264
- }
265
- }
266
- return {
267
- enqueue(value) {
268
- if (closed) {
269
- return;
270
- }
271
- values.push(value);
272
- flush();
273
- },
274
- close() {
275
- closed = true;
276
- flush();
277
- },
278
- throw(thrown) {
279
- closed = true;
280
- error = thrown;
281
- flush();
282
- },
283
- [Symbol.asyncIterator]() {
284
- return {
285
- next() {
286
- if (values.length > 0) {
287
- const value = values.shift();
288
- return Promise.resolve({ value, done: false });
289
- }
290
- if (error !== void 0) {
291
- return Promise.reject(error);
292
- }
293
- if (closed) {
294
- return Promise.resolve({ value: void 0, done: true });
295
- }
296
- return new Promise((resolve, reject) => {
297
- waiters.push({ resolve, reject });
298
- });
299
- }
300
- };
301
- }
302
- };
303
- }
304
-
305
- // src/sse.ts
306
- function createSseStream(options) {
307
- validateSseOptions(options);
308
- const encoder = new TextEncoder();
309
- const iterator = options.events[Symbol.asyncIterator]();
310
- const serialize = options.serialize ?? serializeJson2;
311
- return new ReadableStream({
312
- start(controller) {
313
- if (options.retry !== void 0) {
314
- controller.enqueue(encoder.encode(`retry: ${options.retry}
315
-
316
- `));
317
- }
318
- },
319
- async pull(controller) {
320
- try {
321
- const next = await iterator.next();
322
- if (next.done === true) {
323
- controller.close();
324
- return;
325
- }
326
- controller.enqueue(
327
- encoder.encode(formatSseEvent(next.value, serialize, options.eventName))
328
- );
329
- } catch (error) {
330
- const event = errorEvent(error);
331
- controller.enqueue(encoder.encode(formatSseEvent(event, serialize, options.eventName)));
332
- controller.close();
333
- }
334
- },
335
- async cancel() {
336
- await iterator.return?.();
337
- }
338
- });
339
- }
340
- function formatSseEvent(event, serialize, eventName) {
341
- const name = typeof eventName === "function" ? eventName(event) : eventName;
342
- const lines = [];
343
- if (name !== void 0 && name.length > 0) {
344
- validateSseEventName(name);
345
- lines.push(`event: ${name}`);
346
- }
347
- for (const line of serialize(event).split(/\r?\n/)) {
348
- lines.push(`data: ${line}`);
349
- }
350
- lines.push("", "");
351
- return lines.join("\n");
352
- }
353
- function serializeJson2(value) {
354
- return JSON.stringify(value);
355
- }
356
- function validateSseOptions(options) {
357
- if (options.retry !== void 0 && !isValidRetry(options.retry)) {
358
- throw new TypeError("SSE retry must be a finite non-negative integer");
359
- }
360
- if (typeof options.eventName === "string") {
361
- validateSseEventName(options.eventName);
362
- }
363
- }
364
- function isValidRetry(value) {
365
- return Number.isFinite(value) && Number.isInteger(value) && value >= 0;
366
- }
367
- function validateSseEventName(name) {
368
- for (const character of name) {
369
- const code = character.charCodeAt(0);
370
- if (code === 0 || code === 10 || code === 13) {
371
- throw new TypeError("SSE event names must not contain null bytes or line breaks");
372
- }
373
- }
374
- }
375
-
376
- // src/response.ts
377
- function createEventStreamResponse(options) {
378
- const eventsForResponse = options.resumable === void 0 ? options.events : createResumableStream({ events: options.events, ...options.resumable });
379
- return encodeEventStreamResponse({
380
- events: eventsForResponse,
381
- ...copyResponseOptions(options)
382
- });
383
- }
384
- function resumeEventStreamResponse(options) {
385
- return encodeEventStreamResponse({
386
- events: resumeStreamEvents({
387
- id: options.streamId,
388
- after: options.after,
389
- store: options.store
390
- }),
391
- ...copyResponseOptions(options)
392
- });
393
- }
394
- function encodeEventStreamResponse(options) {
395
- const format = options.format ?? "jsonl";
396
- const headers = new Headers(options.headers);
397
- if (!headers.has("cache-control")) {
398
- headers.set("cache-control", "no-cache, no-transform");
399
- }
400
- if (!headers.has("connection")) {
401
- headers.set("connection", "keep-alive");
402
- }
403
- if (!headers.has("x-accel-buffering")) {
404
- headers.set("x-accel-buffering", "no");
405
- }
406
- const body = format === "sse" ? createSseStream({ events: options.events, ...options.sse }) : createJsonlStream({ events: options.events, ...options.jsonl });
407
- if (!headers.has("content-type")) {
408
- headers.set(
409
- "content-type",
410
- format === "sse" ? "text/event-stream; charset=utf-8" : "application/x-ndjson; charset=utf-8"
411
- );
412
- }
413
- const responseInit = { headers };
414
- if (options.status !== void 0) {
415
- responseInit.status = options.status;
416
- }
417
- if (options.statusText !== void 0) {
418
- responseInit.statusText = options.statusText;
419
- }
420
- return new Response(body, responseInit);
421
- }
422
- function copyResponseOptions(options) {
423
- const next = {};
424
- if (options.format !== void 0) next.format = options.format;
425
- if (options.headers !== void 0) next.headers = options.headers;
426
- if (options.status !== void 0) next.status = options.status;
427
- if (options.statusText !== void 0) next.statusText = options.statusText;
428
- if (options.jsonl !== void 0) {
429
- next.jsonl = options.jsonl;
430
- }
431
- if (options.sse !== void 0) {
432
- next.sse = options.sse;
433
- }
434
- return next;
435
- }
436
-
437
- // src/client-response.ts
438
20
  function createClientStreamResponse(options) {
439
21
  const frames = options.resumable === void 0 ? frameClientStream(
440
22
  options.events,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client-response.ts","../src/errors.ts","../src/jsonl.ts","../src/resumable.ts","../src/sse.ts","../src/response.ts"],"sourcesContent":["import {\n CLIENT_STREAM_PROTOCOL,\n type ClientDataMap,\n type ClientDataSchemas,\n type ClientMetadata,\n type ClientMetadataSchema,\n ClientProtocolError,\n type ClientStream,\n type ClientStreamEvent,\n type ClientStreamFrame,\n createClientId,\n parseClientStreamEvent,\n} from \"@anvia/client\";\nimport { encodeEventStreamResponse } from \"./response\";\nimport type { EventStreamFormat, ResumableStreamStore } from \"./types\";\n\ntype ClientResponseOptions<Metadata extends ClientMetadata, Data extends ClientDataMap> = {\n format?: EventStreamFormat;\n headers?: HeadersInit;\n status?: number;\n statusText?: string;\n metadataSchema?: ClientMetadataSchema<Metadata>;\n dataSchemas?: ClientDataSchemas<Data>;\n sse?: { retry?: number };\n};\n\nexport type ClientResumableEvent<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n> = {\n protocol: typeof CLIENT_STREAM_PROTOCOL;\n event: ClientStreamEvent<Metadata, Data>;\n};\n\nexport type CreateClientStreamResponseOptions<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n> = ClientResponseOptions<Metadata, Data> & {\n events: ClientStream<Metadata, Data>;\n streamId?: string;\n resumable?: {\n streamId: string;\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>;\n };\n};\n\nexport type ResumeClientStreamResponseOptions<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n> = ClientResponseOptions<Metadata, Data> & {\n streamId: string;\n after: number;\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>;\n};\n\nexport function createClientStreamResponse<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n>(options: CreateClientStreamResponseOptions<Metadata, Data>): Response {\n const frames =\n options.resumable === undefined\n ? frameClientStream(\n options.events,\n options.streamId ?? createClientId(\"stream\"),\n options.metadataSchema,\n options.dataSchemas,\n )\n : frameResumableClientStream(\n options.events,\n options.resumable.streamId,\n options.resumable.store,\n options.metadataSchema,\n options.dataSchemas,\n );\n return clientResponse(frames, options);\n}\n\nexport function resumeClientStreamResponse<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n>(options: ResumeClientStreamResponseOptions<Metadata, Data>): Response {\n return clientResponse(\n resumeClientFrames(\n options.streamId,\n options.after,\n options.store,\n options.metadataSchema,\n options.dataSchemas,\n ),\n options,\n );\n}\n\nfunction frameClientStream<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n events: ClientStream<Metadata, Data>,\n streamId: string,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): AsyncIterable<ClientStreamFrame<Metadata, Data>> {\n return propagateCancellation(events, (source) => ({\n async *[Symbol.asyncIterator]() {\n yield {\n type: \"stream_start\",\n protocol: CLIENT_STREAM_PROTOCOL,\n streamId,\n eventId: 0,\n resumable: false,\n } satisfies ClientStreamFrame<Metadata, Data>;\n let eventId = 0;\n let status: \"completed\" | \"error\" = \"completed\";\n try {\n for await (const value of source) {\n const event = parseEvent(value, metadataSchema, dataSchemas);\n eventId += 1;\n yield {\n type: \"stream_event\",\n streamId,\n eventId,\n event,\n } satisfies ClientStreamFrame<Metadata, Data>;\n }\n } catch {\n status = \"error\";\n }\n yield { type: \"stream_end\", streamId, eventId, status } satisfies ClientStreamFrame<\n Metadata,\n Data\n >;\n },\n }));\n}\n\nfunction frameResumableClientStream<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n events: ClientStream<Metadata, Data>,\n streamId: string,\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): AsyncIterable<ClientStreamFrame<Metadata, Data>> {\n let open: Promise<void> | undefined;\n function start(): Promise<void> {\n if (open !== undefined) return open;\n open = store.open({ streamId }).then(() => undefined);\n void drainClientStream(events, streamId, store, metadataSchema, dataSchemas, open);\n return open;\n }\n return {\n async *[Symbol.asyncIterator]() {\n try {\n await start();\n } catch {\n yield startFrame<Metadata, Data>(streamId, true);\n yield endFrame<Metadata, Data>(streamId, 0, \"error\");\n return;\n }\n yield* resumeClientFrames(streamId, 0, store, metadataSchema, dataSchemas);\n },\n };\n}\n\nasync function drainClientStream<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n events: ClientStream<Metadata, Data>,\n streamId: string,\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n open: Promise<void>,\n): Promise<void> {\n try {\n await open;\n for await (const value of events) {\n await store.append({\n streamId,\n event: {\n protocol: CLIENT_STREAM_PROTOCOL,\n event: parseEvent(value, metadataSchema, dataSchemas),\n },\n });\n }\n await store.close({ streamId, status: \"completed\" });\n } catch {\n try {\n await store.close({ streamId, status: \"error\" });\n } catch {\n // A failed store open has no stream to close.\n }\n }\n}\n\nasync function* resumeClientFrames<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n streamId: string,\n after: number,\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): AsyncIterable<ClientStreamFrame<Metadata, Data>> {\n yield startFrame<Metadata, Data>(streamId, true);\n let eventId = after;\n let invalid = false;\n try {\n for await (const record of store.subscribe({ streamId, after })) {\n const event = parseResumableEvent(record.event, metadataSchema, dataSchemas);\n eventId = record.eventId;\n yield { type: \"stream_event\", streamId, eventId, event };\n }\n } catch {\n invalid = true;\n }\n\n try {\n const state = await store.status({ streamId });\n const status = invalid || state.status === \"running\" ? \"error\" : state.status;\n yield endFrame<Metadata, Data>(streamId, Math.max(eventId, state.lastEventId), status);\n } catch {\n yield endFrame<Metadata, Data>(streamId, eventId, \"error\");\n }\n}\n\nfunction parseResumableEvent<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n value: unknown,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): ClientStreamEvent<Metadata, Data> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ClientProtocolError(\"Invalid client resumable record.\", value);\n }\n const record = value as { protocol?: unknown; event?: unknown };\n if (record.protocol === \"anvia.client.v1\") {\n throw new ClientProtocolError(\"Client resumable protocol v1 is not supported.\", value);\n }\n if (record.protocol !== CLIENT_STREAM_PROTOCOL || !(\"event\" in record)) {\n throw new ClientProtocolError(\n \"Client resumable records must use the current client protocol.\",\n value,\n );\n }\n return parseEvent(record.event, metadataSchema, dataSchemas);\n}\n\nfunction parseEvent<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n value: unknown,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): ClientStreamEvent<Metadata, Data> {\n const options: Parameters<typeof parseClientStreamEvent<Metadata, Data>>[1] = {};\n if (metadataSchema !== undefined) options.metadataSchema = metadataSchema;\n if (dataSchemas !== undefined) options.dataSchemas = dataSchemas;\n return parseClientStreamEvent<Metadata, Data>(value, options);\n}\n\nfunction startFrame<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n streamId: string,\n resumable: boolean,\n): ClientStreamFrame<Metadata, Data> {\n return {\n type: \"stream_start\",\n protocol: CLIENT_STREAM_PROTOCOL,\n streamId,\n eventId: 0,\n resumable,\n };\n}\n\nfunction endFrame<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n streamId: string,\n eventId: number,\n status: \"completed\" | \"error\" | \"missing\",\n): ClientStreamFrame<Metadata, Data> {\n return { type: \"stream_end\", streamId, eventId, status };\n}\n\nfunction clientResponse<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n frames: AsyncIterable<ClientStreamFrame<Metadata, Data>>,\n options: ClientResponseOptions<Metadata, Data>,\n): Response {\n const headers = new Headers(options.headers);\n headers.set(\"x-anvia-stream-protocol\", CLIENT_STREAM_PROTOCOL);\n const responseOptions: Parameters<typeof encodeEventStreamResponse>[0] = {\n events: frames,\n headers,\n };\n if (options.format !== undefined) responseOptions.format = options.format;\n if (options.status !== undefined) responseOptions.status = options.status;\n if (options.statusText !== undefined) responseOptions.statusText = options.statusText;\n if (options.sse !== undefined) responseOptions.sse = options.sse;\n return encodeEventStreamResponse(responseOptions);\n}\n\nfunction propagateCancellation<TSource, TOutput>(\n source: AsyncIterable<TSource>,\n transform: (source: AsyncIterable<TSource>) => AsyncIterable<TOutput>,\n): AsyncIterable<TOutput> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<TOutput> {\n const sourceIterator = source[Symbol.asyncIterator]();\n const sharedSource: AsyncIterable<TSource> = {\n [Symbol.asyncIterator]: () => sourceIterator,\n };\n const outputIterator = transform(sharedSource)[Symbol.asyncIterator]();\n let returned = false;\n\n return {\n next: () => outputIterator.next(),\n async return(): Promise<IteratorResult<TOutput>> {\n if (returned) return { done: true, value: undefined };\n returned = true;\n const sourceReturn = sourceIterator.return?.();\n const outputReturn = outputIterator.return?.();\n await Promise.all([sourceReturn, outputReturn]);\n return { done: true, value: undefined };\n },\n };\n },\n };\n}\n","import { isJsonValue } from \"@anvia/client\";\nimport type { EventStreamErrorEvent } from \"./types\";\n\nexport function errorEvent(error: unknown): EventStreamErrorEvent {\n return {\n type: \"error\",\n error: serializeError(error),\n };\n}\n\nfunction serializeError(error: unknown): unknown {\n if (error instanceof Error) {\n const serialized: {\n name: string;\n message: string;\n code?: string;\n retryable?: boolean;\n details?: unknown;\n } = {\n name: error.name,\n message: error.message,\n };\n // Runtime-specific Error subclasses (for example bun:sqlite's SqliteError)\n // can keep diagnostic fields such as `code` on the prototype, where\n // JSON.stringify drops them. Copy the protocol's diagnostic fields\n // explicitly so the wire payload stays valid and diagnosable.\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"string\") {\n serialized.code = code;\n }\n const retryable = (error as { retryable?: unknown }).retryable;\n if (typeof retryable === \"boolean\") {\n serialized.retryable = retryable;\n }\n if (isJsonValue((error as { details?: unknown }).details)) {\n serialized.details = (error as { details?: unknown }).details;\n }\n return serialized;\n }\n\n if (!isJsonValue(error)) {\n // A thrown non-Error that is not JSON-safe would serialize as `{}` or lose\n // its diagnostics entirely; degrade to a string payload instead.\n return { message: String(error) };\n }\n return error;\n}\n","import { errorEvent } from \"./errors\";\nimport type { JsonlStreamOptions } from \"./types\";\n\nexport function createJsonlStream<TEvent>(\n options: JsonlStreamOptions<TEvent> & { events: AsyncIterable<TEvent> },\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const iterator = options.events[Symbol.asyncIterator]();\n const serialize = options.serialize ?? serializeJson;\n\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const next = await iterator.next();\n if (next.done === true) {\n controller.close();\n return;\n }\n\n controller.enqueue(encoder.encode(`${serialize(next.value)}\\n`));\n } catch (error) {\n controller.enqueue(encoder.encode(`${serialize(errorEvent(error))}\\n`));\n controller.close();\n }\n },\n async cancel() {\n await iterator.return?.();\n },\n });\n}\n\nfunction serializeJson(value: unknown): string {\n return JSON.stringify(value);\n}\n","import { errorEvent } from \"./errors\";\nimport type {\n CreateResumableStreamOptions,\n ResumableStreamEnvelope,\n ResumableStreamRecord,\n ResumableStreamState,\n ResumableStreamStatus,\n ResumableStreamStore,\n ResumableStreamSubscribeInput,\n ResumeStreamEventsOptions,\n} from \"./types\";\n\ntype Subscriber<TEvent> = {\n after: number;\n queue: AsyncQueue<ResumableStreamRecord<TEvent>>;\n};\n\ntype MemoryStream<TEvent> = {\n records: ResumableStreamRecord<TEvent>[];\n status: ResumableStreamStatus;\n subscribers: Set<Subscriber<TEvent>>;\n};\n\ntype AsyncQueue<T> = AsyncIterable<T> & {\n enqueue(value: T): void;\n close(): void;\n throw(error: unknown): void;\n};\n\nexport function createResumableStream<TEvent>(\n options: CreateResumableStreamOptions<TEvent> & { events: AsyncIterable<TEvent> },\n): AsyncIterable<ResumableStreamEnvelope<TEvent>> {\n const streamId = options.id;\n let openPromise: Promise<void> | undefined;\n\n function start(): Promise<void> {\n if (openPromise !== undefined) {\n return openPromise;\n }\n\n openPromise = options.store.open({ streamId }).then(() => undefined);\n void drainResumableStream(options.events, options, openPromise);\n return openPromise;\n }\n\n return {\n async *[Symbol.asyncIterator]() {\n await start();\n yield* resumeStreamEvents({ id: streamId, store: options.store });\n },\n };\n}\n\nexport async function* resumeStreamEvents<TEvent>(\n options: ResumeStreamEventsOptions<TEvent>,\n): AsyncIterable<ResumableStreamEnvelope<TEvent>> {\n const streamId = options.id;\n yield { type: \"stream_start\", streamId, eventId: 0 };\n\n const subscribeInput: ResumableStreamSubscribeInput = { streamId };\n if (options.after !== undefined) {\n subscribeInput.after = options.after;\n }\n for await (const record of options.store.subscribe(subscribeInput)) {\n yield recordToEnvelope(record);\n }\n\n const state = await options.store.status({ streamId });\n yield stateToEndEnvelope<TEvent>(streamId, state);\n}\n\nexport function createMemoryResumableStreamStore<TEvent = unknown>(): ResumableStreamStore<TEvent> {\n const streams = new Map<string, MemoryStream<TEvent>>();\n\n function state(stream: MemoryStream<TEvent> | undefined): ResumableStreamState {\n if (stream === undefined) {\n return { status: \"missing\", lastEventId: 0 };\n }\n return {\n status: stream.status,\n lastEventId: stream.records.at(-1)?.eventId ?? 0,\n };\n }\n\n return {\n async open(input) {\n const existing = streams.get(input.streamId);\n if (existing !== undefined) {\n closeSubscribers(existing);\n }\n\n const stream: MemoryStream<TEvent> = {\n records: [],\n status: \"running\",\n subscribers: new Set(),\n };\n streams.set(input.streamId, stream);\n return state(stream);\n },\n\n async append(input) {\n const stream = streams.get(input.streamId);\n if (stream === undefined) {\n throw new Error(`Resumable stream \"${input.streamId}\" is not open`);\n }\n if (stream.status !== \"running\") {\n throw new Error(`Resumable stream \"${input.streamId}\" is already ${stream.status}`);\n }\n\n const record: ResumableStreamRecord<TEvent> = {\n streamId: input.streamId,\n eventId: stream.records.length + 1,\n event: input.event,\n createdAt: new Date(),\n };\n stream.records.push(record);\n\n for (const subscriber of stream.subscribers) {\n if (record.eventId > subscriber.after) {\n subscriber.queue.enqueue(record);\n }\n }\n\n return record;\n },\n\n subscribe(input) {\n const after = input.after ?? 0;\n return {\n [Symbol.asyncIterator](): AsyncIterator<ResumableStreamRecord<TEvent>> {\n const stream = streams.get(input.streamId);\n const queue = createAsyncQueue<ResumableStreamRecord<TEvent>>();\n if (stream === undefined) {\n queue.close();\n return queue[Symbol.asyncIterator]();\n }\n\n for (const record of stream.records) {\n if (record.eventId > after) {\n queue.enqueue(record);\n }\n }\n\n if (stream.status !== \"running\") {\n queue.close();\n return queue[Symbol.asyncIterator]();\n }\n\n const subscriber: Subscriber<TEvent> = { after, queue };\n stream.subscribers.add(subscriber);\n const iterator = queue[Symbol.asyncIterator]();\n\n return {\n next: () => iterator.next(),\n async return() {\n stream.subscribers.delete(subscriber);\n queue.close();\n return { value: undefined, done: true };\n },\n };\n },\n };\n },\n\n async status(input) {\n return state(streams.get(input.streamId));\n },\n\n async close(input) {\n const stream = streams.get(input.streamId);\n if (stream === undefined) {\n return { status: input.status, lastEventId: 0 };\n }\n stream.status = input.status;\n closeSubscribers(stream);\n return state(stream);\n },\n };\n}\n\nasync function drainResumableStream<TEvent>(\n events: AsyncIterable<TEvent>,\n options: CreateResumableStreamOptions<TEvent>,\n openPromise: Promise<void>,\n): Promise<void> {\n const streamId = options.id;\n try {\n await openPromise;\n for await (const event of events) {\n await options.store.append({ streamId, event });\n }\n await options.store.close({ streamId, status: \"completed\" });\n } catch (error) {\n const event = errorEvent(error);\n try {\n await options.store.append({ streamId, event });\n } catch {\n // The response iterator reports store-open failures; avoid a background rejection.\n }\n try {\n await options.store.close({ streamId, status: \"error\" });\n } catch {\n // The store may not have opened.\n }\n }\n}\n\nfunction recordToEnvelope<TEvent>(\n record: ResumableStreamRecord<TEvent>,\n): ResumableStreamEnvelope<TEvent> {\n return {\n type: \"stream_event\",\n streamId: record.streamId,\n eventId: record.eventId,\n event: record.event,\n };\n}\n\nfunction stateToEndEnvelope<TEvent>(\n streamId: string,\n state: ResumableStreamState,\n): ResumableStreamEnvelope<TEvent> {\n return {\n type: \"stream_end\",\n streamId,\n eventId: state.lastEventId,\n status: state.status,\n };\n}\n\nfunction closeSubscribers<TEvent>(stream: MemoryStream<TEvent>): void {\n for (const subscriber of stream.subscribers) {\n subscriber.queue.close();\n }\n stream.subscribers.clear();\n}\n\nfunction createAsyncQueue<T>(): AsyncQueue<T> {\n const values: T[] = [];\n const waiters: Array<{\n resolve: (result: IteratorResult<T>) => void;\n reject: (error: unknown) => void;\n }> = [];\n let closed = false;\n let error: unknown;\n\n function flush(): void {\n while (waiters.length > 0 && values.length > 0) {\n const waiter = waiters.shift();\n const value = values.shift() as T;\n waiter?.resolve({ value, done: false });\n }\n\n if (values.length > 0 || waiters.length === 0 || !closed) {\n return;\n }\n\n while (waiters.length > 0) {\n const waiter = waiters.shift();\n if (waiter === undefined) {\n continue;\n }\n if (error !== undefined) {\n waiter.reject(error);\n } else {\n waiter.resolve({ value: undefined, done: true });\n }\n }\n }\n\n return {\n enqueue(value) {\n if (closed) {\n return;\n }\n values.push(value);\n flush();\n },\n close() {\n closed = true;\n flush();\n },\n throw(thrown) {\n closed = true;\n error = thrown;\n flush();\n },\n [Symbol.asyncIterator]() {\n return {\n next() {\n if (values.length > 0) {\n const value = values.shift() as T;\n return Promise.resolve({ value, done: false });\n }\n if (error !== undefined) {\n return Promise.reject(error);\n }\n if (closed) {\n return Promise.resolve({ value: undefined, done: true });\n }\n return new Promise((resolve, reject) => {\n waiters.push({ resolve, reject });\n });\n },\n };\n },\n };\n}\n","import { errorEvent } from \"./errors\";\nimport type { EventStreamErrorEvent, SseStreamOptions } from \"./types\";\n\nexport function createSseStream<TEvent>(\n options: SseStreamOptions<TEvent> & { events: AsyncIterable<TEvent> },\n): ReadableStream<Uint8Array> {\n validateSseOptions(options);\n const encoder = new TextEncoder();\n const iterator = options.events[Symbol.asyncIterator]();\n const serialize = options.serialize ?? serializeJson;\n\n return new ReadableStream<Uint8Array>({\n start(controller) {\n if (options.retry !== undefined) {\n controller.enqueue(encoder.encode(`retry: ${options.retry}\\n\\n`));\n }\n },\n async pull(controller) {\n try {\n const next = await iterator.next();\n if (next.done === true) {\n controller.close();\n return;\n }\n\n controller.enqueue(\n encoder.encode(formatSseEvent(next.value, serialize, options.eventName)),\n );\n } catch (error) {\n const event = errorEvent(error);\n controller.enqueue(encoder.encode(formatSseEvent(event, serialize, options.eventName)));\n controller.close();\n }\n },\n async cancel() {\n await iterator.return?.();\n },\n });\n}\n\nfunction formatSseEvent<TEvent>(\n event: TEvent | EventStreamErrorEvent,\n serialize: (event: TEvent | EventStreamErrorEvent) => string,\n eventName: SseStreamOptions<TEvent>[\"eventName\"],\n): string {\n const name = typeof eventName === \"function\" ? eventName(event) : eventName;\n const lines: string[] = [];\n\n if (name !== undefined && name.length > 0) {\n validateSseEventName(name);\n lines.push(`event: ${name}`);\n }\n\n for (const line of serialize(event).split(/\\r?\\n/)) {\n lines.push(`data: ${line}`);\n }\n\n lines.push(\"\", \"\");\n return lines.join(\"\\n\");\n}\n\nfunction serializeJson(value: unknown): string {\n return JSON.stringify(value);\n}\n\nfunction validateSseOptions<TEvent>(options: SseStreamOptions<TEvent>): void {\n if (options.retry !== undefined && !isValidRetry(options.retry)) {\n throw new TypeError(\"SSE retry must be a finite non-negative integer\");\n }\n if (typeof options.eventName === \"string\") {\n validateSseEventName(options.eventName);\n }\n}\n\nfunction isValidRetry(value: number): boolean {\n return Number.isFinite(value) && Number.isInteger(value) && value >= 0;\n}\n\nfunction validateSseEventName(name: string): void {\n for (const character of name) {\n const code = character.charCodeAt(0);\n if (code === 0 || code === 10 || code === 13) {\n throw new TypeError(\"SSE event names must not contain null bytes or line breaks\");\n }\n }\n}\n","import { createJsonlStream } from \"./jsonl\";\nimport { createResumableStream, resumeStreamEvents } from \"./resumable\";\nimport { createSseStream } from \"./sse\";\nimport type {\n CreateEventStreamResponseOptions,\n EventStreamFormat,\n JsonlStreamOptions,\n ResumableStreamEnvelope,\n ResumeEventStreamResponseOptions,\n SseStreamOptions,\n} from \"./types\";\n\ntype ResponseStreamEvent<TEvent> = TEvent | ResumableStreamEnvelope<TEvent>;\n\ntype EventStreamResponseOptions<TEvent> = {\n format?: EventStreamFormat;\n headers?: HeadersInit;\n status?: number;\n statusText?: string;\n jsonl?: JsonlStreamOptions<ResponseStreamEvent<TEvent>>;\n sse?: SseStreamOptions<ResponseStreamEvent<TEvent>>;\n};\n\nexport function createEventStreamResponse<TEvent>(\n options: CreateEventStreamResponseOptions<TEvent> & { events: AsyncIterable<TEvent> },\n): Response {\n const eventsForResponse: AsyncIterable<ResponseStreamEvent<TEvent>> =\n options.resumable === undefined\n ? (options.events as AsyncIterable<ResponseStreamEvent<TEvent>>)\n : createResumableStream({ events: options.events, ...options.resumable });\n\n return encodeEventStreamResponse({\n events: eventsForResponse,\n ...copyResponseOptions(options),\n });\n}\n\nexport function resumeEventStreamResponse<TEvent>(\n options: ResumeEventStreamResponseOptions<TEvent>,\n): Response {\n return encodeEventStreamResponse({\n events: resumeStreamEvents({\n id: options.streamId,\n after: options.after,\n store: options.store,\n }),\n ...copyResponseOptions(options),\n });\n}\n\nexport function encodeEventStreamResponse<TEvent>(\n options: EventStreamResponseOptions<TEvent> & {\n events: AsyncIterable<ResponseStreamEvent<TEvent>>;\n },\n): Response {\n const format = options.format ?? \"jsonl\";\n const headers = new Headers(options.headers);\n\n if (!headers.has(\"cache-control\")) {\n headers.set(\"cache-control\", \"no-cache, no-transform\");\n }\n if (!headers.has(\"connection\")) {\n headers.set(\"connection\", \"keep-alive\");\n }\n if (!headers.has(\"x-accel-buffering\")) {\n headers.set(\"x-accel-buffering\", \"no\");\n }\n\n const body =\n format === \"sse\"\n ? createSseStream({ events: options.events, ...options.sse })\n : createJsonlStream({ events: options.events, ...options.jsonl });\n\n if (!headers.has(\"content-type\")) {\n headers.set(\n \"content-type\",\n format === \"sse\" ? \"text/event-stream; charset=utf-8\" : \"application/x-ndjson; charset=utf-8\",\n );\n }\n\n const responseInit: ResponseInit = { headers };\n if (options.status !== undefined) {\n responseInit.status = options.status;\n }\n if (options.statusText !== undefined) {\n responseInit.statusText = options.statusText;\n }\n\n return new Response(body, responseInit);\n}\n\nfunction copyResponseOptions<TEvent>(options: {\n format?: EventStreamFormat;\n headers?: HeadersInit;\n status?: number;\n statusText?: string;\n jsonl?: unknown;\n sse?: unknown;\n}): EventStreamResponseOptions<TEvent> {\n const next: EventStreamResponseOptions<TEvent> = {};\n if (options.format !== undefined) next.format = options.format;\n if (options.headers !== undefined) next.headers = options.headers;\n if (options.status !== undefined) next.status = options.status;\n if (options.statusText !== undefined) next.statusText = options.statusText;\n if (options.jsonl !== undefined) {\n next.jsonl = options.jsonl as JsonlStreamOptions<ResponseStreamEvent<TEvent>>;\n }\n if (options.sse !== undefined) {\n next.sse = options.sse as SseStreamOptions<ResponseStreamEvent<TEvent>>;\n }\n return next;\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EAKA;AAAA,EAIA;AAAA,EACA;AAAA,OACK;;;ACZP,SAAS,mBAAmB;AAGrB,SAAS,WAAW,OAAuC;AAChE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,eAAe,KAAK;AAAA,EAC7B;AACF;AAEA,SAAS,eAAe,OAAyB;AAC/C,MAAI,iBAAiB,OAAO;AAC1B,UAAM,aAMF;AAAA,MACF,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,IACjB;AAKA,UAAM,OAAQ,MAA6B;AAC3C,QAAI,OAAO,SAAS,UAAU;AAC5B,iBAAW,OAAO;AAAA,IACpB;AACA,UAAM,YAAa,MAAkC;AACrD,QAAI,OAAO,cAAc,WAAW;AAClC,iBAAW,YAAY;AAAA,IACzB;AACA,QAAI,YAAa,MAAgC,OAAO,GAAG;AACzD,iBAAW,UAAW,MAAgC;AAAA,IACxD;AACA,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,YAAY,KAAK,GAAG;AAGvB,WAAO,EAAE,SAAS,OAAO,KAAK,EAAE;AAAA,EAClC;AACA,SAAO;AACT;;;AC3CO,SAAS,kBACd,SAC4B;AAC5B,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,WAAW,QAAQ,OAAO,OAAO,aAAa,EAAE;AACtD,QAAM,YAAY,QAAQ,aAAa;AAEvC,SAAO,IAAI,eAA2B;AAAA,IACpC,MAAM,KAAK,YAAY;AACrB,UAAI;AACF,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAI,KAAK,SAAS,MAAM;AACtB,qBAAW,MAAM;AACjB;AAAA,QACF;AAEA,mBAAW,QAAQ,QAAQ,OAAO,GAAG,UAAU,KAAK,KAAK,CAAC;AAAA,CAAI,CAAC;AAAA,MACjE,SAAS,OAAO;AACd,mBAAW,QAAQ,QAAQ,OAAO,GAAG,UAAU,WAAW,KAAK,CAAC,CAAC;AAAA,CAAI,CAAC;AACtE,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,IACA,MAAM,SAAS;AACb,YAAM,SAAS,SAAS;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;AAEA,SAAS,cAAc,OAAwB;AAC7C,SAAO,KAAK,UAAU,KAAK;AAC7B;;;ACJO,SAAS,sBACd,SACgD;AAChD,QAAM,WAAW,QAAQ;AACzB,MAAI;AAEJ,WAAS,QAAuB;AAC9B,QAAI,gBAAgB,QAAW;AAC7B,aAAO;AAAA,IACT;AAEA,kBAAc,QAAQ,MAAM,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,MAAM,MAAS;AACnE,SAAK,qBAAqB,QAAQ,QAAQ,SAAS,WAAW;AAC9D,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,QAAQ,OAAO,aAAa,IAAI;AAC9B,YAAM,MAAM;AACZ,aAAO,mBAAmB,EAAE,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAAA,IAClE;AAAA,EACF;AACF;AAEA,gBAAuB,mBACrB,SACgD;AAChD,QAAM,WAAW,QAAQ;AACzB,QAAM,EAAE,MAAM,gBAAgB,UAAU,SAAS,EAAE;AAEnD,QAAM,iBAAgD,EAAE,SAAS;AACjE,MAAI,QAAQ,UAAU,QAAW;AAC/B,mBAAe,QAAQ,QAAQ;AAAA,EACjC;AACA,mBAAiB,UAAU,QAAQ,MAAM,UAAU,cAAc,GAAG;AAClE,UAAM,iBAAiB,MAAM;AAAA,EAC/B;AAEA,QAAM,QAAQ,MAAM,QAAQ,MAAM,OAAO,EAAE,SAAS,CAAC;AACrD,QAAM,mBAA2B,UAAU,KAAK;AAClD;AAEO,SAAS,mCAAmF;AACjG,QAAM,UAAU,oBAAI,IAAkC;AAEtD,WAAS,MAAM,QAAgE;AAC7E,QAAI,WAAW,QAAW;AACxB,aAAO,EAAE,QAAQ,WAAW,aAAa,EAAE;AAAA,IAC7C;AACA,WAAO;AAAA,MACL,QAAQ,OAAO;AAAA,MACf,aAAa,OAAO,QAAQ,GAAG,EAAE,GAAG,WAAW;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,KAAK,OAAO;AAChB,YAAM,WAAW,QAAQ,IAAI,MAAM,QAAQ;AAC3C,UAAI,aAAa,QAAW;AAC1B,yBAAiB,QAAQ;AAAA,MAC3B;AAEA,YAAM,SAA+B;AAAA,QACnC,SAAS,CAAC;AAAA,QACV,QAAQ;AAAA,QACR,aAAa,oBAAI,IAAI;AAAA,MACvB;AACA,cAAQ,IAAI,MAAM,UAAU,MAAM;AAClC,aAAO,MAAM,MAAM;AAAA,IACrB;AAAA,IAEA,MAAM,OAAO,OAAO;AAClB,YAAM,SAAS,QAAQ,IAAI,MAAM,QAAQ;AACzC,UAAI,WAAW,QAAW;AACxB,cAAM,IAAI,MAAM,qBAAqB,MAAM,QAAQ,eAAe;AAAA,MACpE;AACA,UAAI,OAAO,WAAW,WAAW;AAC/B,cAAM,IAAI,MAAM,qBAAqB,MAAM,QAAQ,gBAAgB,OAAO,MAAM,EAAE;AAAA,MACpF;AAEA,YAAM,SAAwC;AAAA,QAC5C,UAAU,MAAM;AAAA,QAChB,SAAS,OAAO,QAAQ,SAAS;AAAA,QACjC,OAAO,MAAM;AAAA,QACb,WAAW,oBAAI,KAAK;AAAA,MACtB;AACA,aAAO,QAAQ,KAAK,MAAM;AAE1B,iBAAW,cAAc,OAAO,aAAa;AAC3C,YAAI,OAAO,UAAU,WAAW,OAAO;AACrC,qBAAW,MAAM,QAAQ,MAAM;AAAA,QACjC;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,UAAU,OAAO;AACf,YAAM,QAAQ,MAAM,SAAS;AAC7B,aAAO;AAAA,QACL,CAAC,OAAO,aAAa,IAAkD;AACrE,gBAAM,SAAS,QAAQ,IAAI,MAAM,QAAQ;AACzC,gBAAM,QAAQ,iBAAgD;AAC9D,cAAI,WAAW,QAAW;AACxB,kBAAM,MAAM;AACZ,mBAAO,MAAM,OAAO,aAAa,EAAE;AAAA,UACrC;AAEA,qBAAW,UAAU,OAAO,SAAS;AACnC,gBAAI,OAAO,UAAU,OAAO;AAC1B,oBAAM,QAAQ,MAAM;AAAA,YACtB;AAAA,UACF;AAEA,cAAI,OAAO,WAAW,WAAW;AAC/B,kBAAM,MAAM;AACZ,mBAAO,MAAM,OAAO,aAAa,EAAE;AAAA,UACrC;AAEA,gBAAM,aAAiC,EAAE,OAAO,MAAM;AACtD,iBAAO,YAAY,IAAI,UAAU;AACjC,gBAAM,WAAW,MAAM,OAAO,aAAa,EAAE;AAE7C,iBAAO;AAAA,YACL,MAAM,MAAM,SAAS,KAAK;AAAA,YAC1B,MAAM,SAAS;AACb,qBAAO,YAAY,OAAO,UAAU;AACpC,oBAAM,MAAM;AACZ,qBAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AAAA,YACxC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,OAAO,OAAO;AAClB,aAAO,MAAM,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAAA,IAC1C;AAAA,IAEA,MAAM,MAAM,OAAO;AACjB,YAAM,SAAS,QAAQ,IAAI,MAAM,QAAQ;AACzC,UAAI,WAAW,QAAW;AACxB,eAAO,EAAE,QAAQ,MAAM,QAAQ,aAAa,EAAE;AAAA,MAChD;AACA,aAAO,SAAS,MAAM;AACtB,uBAAiB,MAAM;AACvB,aAAO,MAAM,MAAM;AAAA,IACrB;AAAA,EACF;AACF;AAEA,eAAe,qBACb,QACA,SACA,aACe;AACf,QAAM,WAAW,QAAQ;AACzB,MAAI;AACF,UAAM;AACN,qBAAiB,SAAS,QAAQ;AAChC,YAAM,QAAQ,MAAM,OAAO,EAAE,UAAU,MAAM,CAAC;AAAA,IAChD;AACA,UAAM,QAAQ,MAAM,MAAM,EAAE,UAAU,QAAQ,YAAY,CAAC;AAAA,EAC7D,SAAS,OAAO;AACd,UAAM,QAAQ,WAAW,KAAK;AAC9B,QAAI;AACF,YAAM,QAAQ,MAAM,OAAO,EAAE,UAAU,MAAM,CAAC;AAAA,IAChD,QAAQ;AAAA,IAER;AACA,QAAI;AACF,YAAM,QAAQ,MAAM,MAAM,EAAE,UAAU,QAAQ,QAAQ,CAAC;AAAA,IACzD,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,SAAS,iBACP,QACiC;AACjC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,OAAO;AAAA,IACjB,SAAS,OAAO;AAAA,IAChB,OAAO,OAAO;AAAA,EAChB;AACF;AAEA,SAAS,mBACP,UACA,OACiC;AACjC,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,SAAS,MAAM;AAAA,IACf,QAAQ,MAAM;AAAA,EAChB;AACF;AAEA,SAAS,iBAAyB,QAAoC;AACpE,aAAW,cAAc,OAAO,aAAa;AAC3C,eAAW,MAAM,MAAM;AAAA,EACzB;AACA,SAAO,YAAY,MAAM;AAC3B;AAEA,SAAS,mBAAqC;AAC5C,QAAM,SAAc,CAAC;AACrB,QAAM,UAGD,CAAC;AACN,MAAI,SAAS;AACb,MAAI;AAEJ,WAAS,QAAc;AACrB,WAAO,QAAQ,SAAS,KAAK,OAAO,SAAS,GAAG;AAC9C,YAAM,SAAS,QAAQ,MAAM;AAC7B,YAAM,QAAQ,OAAO,MAAM;AAC3B,cAAQ,QAAQ,EAAE,OAAO,MAAM,MAAM,CAAC;AAAA,IACxC;AAEA,QAAI,OAAO,SAAS,KAAK,QAAQ,WAAW,KAAK,CAAC,QAAQ;AACxD;AAAA,IACF;AAEA,WAAO,QAAQ,SAAS,GAAG;AACzB,YAAM,SAAS,QAAQ,MAAM;AAC7B,UAAI,WAAW,QAAW;AACxB;AAAA,MACF;AACA,UAAI,UAAU,QAAW;AACvB,eAAO,OAAO,KAAK;AAAA,MACrB,OAAO;AACL,eAAO,QAAQ,EAAE,OAAO,QAAW,MAAM,KAAK,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ,OAAO;AACb,UAAI,QAAQ;AACV;AAAA,MACF;AACA,aAAO,KAAK,KAAK;AACjB,YAAM;AAAA,IACR;AAAA,IACA,QAAQ;AACN,eAAS;AACT,YAAM;AAAA,IACR;AAAA,IACA,MAAM,QAAQ;AACZ,eAAS;AACT,cAAQ;AACR,YAAM;AAAA,IACR;AAAA,IACA,CAAC,OAAO,aAAa,IAAI;AACvB,aAAO;AAAA,QACL,OAAO;AACL,cAAI,OAAO,SAAS,GAAG;AACrB,kBAAM,QAAQ,OAAO,MAAM;AAC3B,mBAAO,QAAQ,QAAQ,EAAE,OAAO,MAAM,MAAM,CAAC;AAAA,UAC/C;AACA,cAAI,UAAU,QAAW;AACvB,mBAAO,QAAQ,OAAO,KAAK;AAAA,UAC7B;AACA,cAAI,QAAQ;AACV,mBAAO,QAAQ,QAAQ,EAAE,OAAO,QAAW,MAAM,KAAK,CAAC;AAAA,UACzD;AACA,iBAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,oBAAQ,KAAK,EAAE,SAAS,OAAO,CAAC;AAAA,UAClC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AChTO,SAAS,gBACd,SAC4B;AAC5B,qBAAmB,OAAO;AAC1B,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,WAAW,QAAQ,OAAO,OAAO,aAAa,EAAE;AACtD,QAAM,YAAY,QAAQ,aAAaA;AAEvC,SAAO,IAAI,eAA2B;AAAA,IACpC,MAAM,YAAY;AAChB,UAAI,QAAQ,UAAU,QAAW;AAC/B,mBAAW,QAAQ,QAAQ,OAAO,UAAU,QAAQ,KAAK;AAAA;AAAA,CAAM,CAAC;AAAA,MAClE;AAAA,IACF;AAAA,IACA,MAAM,KAAK,YAAY;AACrB,UAAI;AACF,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAI,KAAK,SAAS,MAAM;AACtB,qBAAW,MAAM;AACjB;AAAA,QACF;AAEA,mBAAW;AAAA,UACT,QAAQ,OAAO,eAAe,KAAK,OAAO,WAAW,QAAQ,SAAS,CAAC;AAAA,QACzE;AAAA,MACF,SAAS,OAAO;AACd,cAAM,QAAQ,WAAW,KAAK;AAC9B,mBAAW,QAAQ,QAAQ,OAAO,eAAe,OAAO,WAAW,QAAQ,SAAS,CAAC,CAAC;AACtF,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,IACA,MAAM,SAAS;AACb,YAAM,SAAS,SAAS;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;AAEA,SAAS,eACP,OACA,WACA,WACQ;AACR,QAAM,OAAO,OAAO,cAAc,aAAa,UAAU,KAAK,IAAI;AAClE,QAAM,QAAkB,CAAC;AAEzB,MAAI,SAAS,UAAa,KAAK,SAAS,GAAG;AACzC,yBAAqB,IAAI;AACzB,UAAM,KAAK,UAAU,IAAI,EAAE;AAAA,EAC7B;AAEA,aAAW,QAAQ,UAAU,KAAK,EAAE,MAAM,OAAO,GAAG;AAClD,UAAM,KAAK,SAAS,IAAI,EAAE;AAAA,EAC5B;AAEA,QAAM,KAAK,IAAI,EAAE;AACjB,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAASA,eAAc,OAAwB;AAC7C,SAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,SAAS,mBAA2B,SAAyC;AAC3E,MAAI,QAAQ,UAAU,UAAa,CAAC,aAAa,QAAQ,KAAK,GAAG;AAC/D,UAAM,IAAI,UAAU,iDAAiD;AAAA,EACvE;AACA,MAAI,OAAO,QAAQ,cAAc,UAAU;AACzC,yBAAqB,QAAQ,SAAS;AAAA,EACxC;AACF;AAEA,SAAS,aAAa,OAAwB;AAC5C,SAAO,OAAO,SAAS,KAAK,KAAK,OAAO,UAAU,KAAK,KAAK,SAAS;AACvE;AAEA,SAAS,qBAAqB,MAAoB;AAChD,aAAW,aAAa,MAAM;AAC5B,UAAM,OAAO,UAAU,WAAW,CAAC;AACnC,QAAI,SAAS,KAAK,SAAS,MAAM,SAAS,IAAI;AAC5C,YAAM,IAAI,UAAU,4DAA4D;AAAA,IAClF;AAAA,EACF;AACF;;;AC9DO,SAAS,0BACd,SACU;AACV,QAAM,oBACJ,QAAQ,cAAc,SACjB,QAAQ,SACT,sBAAsB,EAAE,QAAQ,QAAQ,QAAQ,GAAG,QAAQ,UAAU,CAAC;AAE5E,SAAO,0BAA0B;AAAA,IAC/B,QAAQ;AAAA,IACR,GAAG,oBAAoB,OAAO;AAAA,EAChC,CAAC;AACH;AAEO,SAAS,0BACd,SACU;AACV,SAAO,0BAA0B;AAAA,IAC/B,QAAQ,mBAAmB;AAAA,MACzB,IAAI,QAAQ;AAAA,MACZ,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,IACjB,CAAC;AAAA,IACD,GAAG,oBAAoB,OAAO;AAAA,EAChC,CAAC;AACH;AAEO,SAAS,0BACd,SAGU;AACV,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAE3C,MAAI,CAAC,QAAQ,IAAI,eAAe,GAAG;AACjC,YAAQ,IAAI,iBAAiB,wBAAwB;AAAA,EACvD;AACA,MAAI,CAAC,QAAQ,IAAI,YAAY,GAAG;AAC9B,YAAQ,IAAI,cAAc,YAAY;AAAA,EACxC;AACA,MAAI,CAAC,QAAQ,IAAI,mBAAmB,GAAG;AACrC,YAAQ,IAAI,qBAAqB,IAAI;AAAA,EACvC;AAEA,QAAM,OACJ,WAAW,QACP,gBAAgB,EAAE,QAAQ,QAAQ,QAAQ,GAAG,QAAQ,IAAI,CAAC,IAC1D,kBAAkB,EAAE,QAAQ,QAAQ,QAAQ,GAAG,QAAQ,MAAM,CAAC;AAEpE,MAAI,CAAC,QAAQ,IAAI,cAAc,GAAG;AAChC,YAAQ;AAAA,MACN;AAAA,MACA,WAAW,QAAQ,qCAAqC;AAAA,IAC1D;AAAA,EACF;AAEA,QAAM,eAA6B,EAAE,QAAQ;AAC7C,MAAI,QAAQ,WAAW,QAAW;AAChC,iBAAa,SAAS,QAAQ;AAAA,EAChC;AACA,MAAI,QAAQ,eAAe,QAAW;AACpC,iBAAa,aAAa,QAAQ;AAAA,EACpC;AAEA,SAAO,IAAI,SAAS,MAAM,YAAY;AACxC;AAEA,SAAS,oBAA4B,SAOE;AACrC,QAAM,OAA2C,CAAC;AAClD,MAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,MAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAC1D,MAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,MAAI,QAAQ,eAAe,OAAW,MAAK,aAAa,QAAQ;AAChE,MAAI,QAAQ,UAAU,QAAW;AAC/B,SAAK,QAAQ,QAAQ;AAAA,EACvB;AACA,MAAI,QAAQ,QAAQ,QAAW;AAC7B,SAAK,MAAM,QAAQ;AAAA,EACrB;AACA,SAAO;AACT;;;ALxDO,SAAS,2BAGd,SAAsE;AACtE,QAAM,SACJ,QAAQ,cAAc,SAClB;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ,YAAY,eAAe,QAAQ;AAAA,IAC3C,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,IACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ,UAAU;AAAA,IAClB,QAAQ,UAAU;AAAA,IAClB,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACN,SAAO,eAAe,QAAQ,OAAO;AACvC;AAEO,SAAS,2BAGd,SAAsE;AACtE,SAAO;AAAA,IACL;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,kBACP,QACA,UACA,gBACA,aACkD;AAClD,SAAO,sBAAsB,QAAQ,CAAC,YAAY;AAAA,IAChD,QAAQ,OAAO,aAAa,IAAI;AAC9B,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,UAAU;AAAA,QACV;AAAA,QACA,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AACA,UAAI,UAAU;AACd,UAAI,SAAgC;AACpC,UAAI;AACF,yBAAiB,SAAS,QAAQ;AAChC,gBAAM,QAAQ,WAAW,OAAO,gBAAgB,WAAW;AAC3D,qBAAW;AACX,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,QAAQ;AACN,iBAAS;AAAA,MACX;AACA,YAAM,EAAE,MAAM,cAAc,UAAU,SAAS,OAAO;AAAA,IAIxD;AAAA,EACF,EAAE;AACJ;AAEA,SAAS,2BACP,QACA,UACA,OACA,gBACA,aACkD;AAClD,MAAI;AACJ,WAAS,QAAuB;AAC9B,QAAI,SAAS,OAAW,QAAO;AAC/B,WAAO,MAAM,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,MAAM,MAAS;AACpD,SAAK,kBAAkB,QAAQ,UAAU,OAAO,gBAAgB,aAAa,IAAI;AACjF,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,QAAQ,OAAO,aAAa,IAAI;AAC9B,UAAI;AACF,cAAM,MAAM;AAAA,MACd,QAAQ;AACN,cAAM,WAA2B,UAAU,IAAI;AAC/C,cAAM,SAAyB,UAAU,GAAG,OAAO;AACnD;AAAA,MACF;AACA,aAAO,mBAAmB,UAAU,GAAG,OAAO,gBAAgB,WAAW;AAAA,IAC3E;AAAA,EACF;AACF;AAEA,eAAe,kBACb,QACA,UACA,OACA,gBACA,aACA,MACe;AACf,MAAI;AACF,UAAM;AACN,qBAAiB,SAAS,QAAQ;AAChC,YAAM,MAAM,OAAO;AAAA,QACjB;AAAA,QACA,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO,WAAW,OAAO,gBAAgB,WAAW;AAAA,QACtD;AAAA,MACF,CAAC;AAAA,IACH;AACA,UAAM,MAAM,MAAM,EAAE,UAAU,QAAQ,YAAY,CAAC;AAAA,EACrD,QAAQ;AACN,QAAI;AACF,YAAM,MAAM,MAAM,EAAE,UAAU,QAAQ,QAAQ,CAAC;AAAA,IACjD,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,gBAAgB,mBACd,UACA,OACA,OACA,gBACA,aACkD;AAClD,QAAM,WAA2B,UAAU,IAAI;AAC/C,MAAI,UAAU;AACd,MAAI,UAAU;AACd,MAAI;AACF,qBAAiB,UAAU,MAAM,UAAU,EAAE,UAAU,MAAM,CAAC,GAAG;AAC/D,YAAM,QAAQ,oBAAoB,OAAO,OAAO,gBAAgB,WAAW;AAC3E,gBAAU,OAAO;AACjB,YAAM,EAAE,MAAM,gBAAgB,UAAU,SAAS,MAAM;AAAA,IACzD;AAAA,EACF,QAAQ;AACN,cAAU;AAAA,EACZ;AAEA,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM,OAAO,EAAE,SAAS,CAAC;AAC7C,UAAM,SAAS,WAAW,MAAM,WAAW,YAAY,UAAU,MAAM;AACvE,UAAM,SAAyB,UAAU,KAAK,IAAI,SAAS,MAAM,WAAW,GAAG,MAAM;AAAA,EACvF,QAAQ;AACN,UAAM,SAAyB,UAAU,SAAS,OAAO;AAAA,EAC3D;AACF;AAEA,SAAS,oBACP,OACA,gBACA,aACmC;AACnC,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACvE,UAAM,IAAI,oBAAoB,oCAAoC,KAAK;AAAA,EACzE;AACA,QAAM,SAAS;AACf,MAAI,OAAO,aAAa,mBAAmB;AACzC,UAAM,IAAI,oBAAoB,kDAAkD,KAAK;AAAA,EACvF;AACA,MAAI,OAAO,aAAa,0BAA0B,EAAE,WAAW,SAAS;AACtE,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO,WAAW,OAAO,OAAO,gBAAgB,WAAW;AAC7D;AAEA,SAAS,WACP,OACA,gBACA,aACmC;AACnC,QAAM,UAAwE,CAAC;AAC/E,MAAI,mBAAmB,OAAW,SAAQ,iBAAiB;AAC3D,MAAI,gBAAgB,OAAW,SAAQ,cAAc;AACrD,SAAO,uBAAuC,OAAO,OAAO;AAC9D;AAEA,SAAS,WACP,UACA,WACmC;AACnC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,SACP,UACA,SACA,QACmC;AACnC,SAAO,EAAE,MAAM,cAAc,UAAU,SAAS,OAAO;AACzD;AAEA,SAAS,eACP,QACA,SACU;AACV,QAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAC3C,UAAQ,IAAI,2BAA2B,sBAAsB;AAC7D,QAAM,kBAAmE;AAAA,IACvE,QAAQ;AAAA,IACR;AAAA,EACF;AACA,MAAI,QAAQ,WAAW,OAAW,iBAAgB,SAAS,QAAQ;AACnE,MAAI,QAAQ,WAAW,OAAW,iBAAgB,SAAS,QAAQ;AACnE,MAAI,QAAQ,eAAe,OAAW,iBAAgB,aAAa,QAAQ;AAC3E,MAAI,QAAQ,QAAQ,OAAW,iBAAgB,MAAM,QAAQ;AAC7D,SAAO,0BAA0B,eAAe;AAClD;AAEA,SAAS,sBACP,QACA,WACwB;AACxB,SAAO;AAAA,IACL,CAAC,OAAO,aAAa,IAA4B;AAC/C,YAAM,iBAAiB,OAAO,OAAO,aAAa,EAAE;AACpD,YAAM,eAAuC;AAAA,QAC3C,CAAC,OAAO,aAAa,GAAG,MAAM;AAAA,MAChC;AACA,YAAM,iBAAiB,UAAU,YAAY,EAAE,OAAO,aAAa,EAAE;AACrE,UAAI,WAAW;AAEf,aAAO;AAAA,QACL,MAAM,MAAM,eAAe,KAAK;AAAA,QAChC,MAAM,SAA2C;AAC/C,cAAI,SAAU,QAAO,EAAE,MAAM,MAAM,OAAO,OAAU;AACpD,qBAAW;AACX,gBAAM,eAAe,eAAe,SAAS;AAC7C,gBAAM,eAAe,eAAe,SAAS;AAC7C,gBAAM,QAAQ,IAAI,CAAC,cAAc,YAAY,CAAC;AAC9C,iBAAO,EAAE,MAAM,MAAM,OAAO,OAAU;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":["serializeJson"]}
1
+ {"version":3,"sources":["../src/client-response.ts"],"sourcesContent":["import {\n CLIENT_STREAM_PROTOCOL,\n type ClientDataMap,\n type ClientDataSchemas,\n type ClientMetadata,\n type ClientMetadataSchema,\n ClientProtocolError,\n type ClientStream,\n type ClientStreamEvent,\n type ClientStreamFrame,\n createClientId,\n parseClientStreamEvent,\n} from \"@anvia/client\";\nimport { encodeEventStreamResponse } from \"./response\";\nimport type { EventStreamFormat, ResumableStreamStore } from \"./types\";\n\ntype ClientResponseOptions<Metadata extends ClientMetadata, Data extends ClientDataMap> = {\n format?: EventStreamFormat;\n headers?: HeadersInit;\n status?: number;\n statusText?: string;\n metadataSchema?: ClientMetadataSchema<Metadata>;\n dataSchemas?: ClientDataSchemas<Data>;\n sse?: { retry?: number };\n};\n\nexport type ClientResumableEvent<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n> = {\n protocol: typeof CLIENT_STREAM_PROTOCOL;\n event: ClientStreamEvent<Metadata, Data>;\n};\n\nexport type CreateClientStreamResponseOptions<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n> = ClientResponseOptions<Metadata, Data> & {\n events: ClientStream<Metadata, Data>;\n streamId?: string;\n resumable?: {\n streamId: string;\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>;\n };\n};\n\nexport type ResumeClientStreamResponseOptions<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n> = ClientResponseOptions<Metadata, Data> & {\n streamId: string;\n after: number;\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>;\n};\n\nexport function createClientStreamResponse<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n>(options: CreateClientStreamResponseOptions<Metadata, Data>): Response {\n const frames =\n options.resumable === undefined\n ? frameClientStream(\n options.events,\n options.streamId ?? createClientId(\"stream\"),\n options.metadataSchema,\n options.dataSchemas,\n )\n : frameResumableClientStream(\n options.events,\n options.resumable.streamId,\n options.resumable.store,\n options.metadataSchema,\n options.dataSchemas,\n );\n return clientResponse(frames, options);\n}\n\nexport function resumeClientStreamResponse<\n Metadata extends ClientMetadata = ClientMetadata,\n Data extends ClientDataMap = ClientDataMap,\n>(options: ResumeClientStreamResponseOptions<Metadata, Data>): Response {\n return clientResponse(\n resumeClientFrames(\n options.streamId,\n options.after,\n options.store,\n options.metadataSchema,\n options.dataSchemas,\n ),\n options,\n );\n}\n\nfunction frameClientStream<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n events: ClientStream<Metadata, Data>,\n streamId: string,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): AsyncIterable<ClientStreamFrame<Metadata, Data>> {\n return propagateCancellation(events, (source) => ({\n async *[Symbol.asyncIterator]() {\n yield {\n type: \"stream_start\",\n protocol: CLIENT_STREAM_PROTOCOL,\n streamId,\n eventId: 0,\n resumable: false,\n } satisfies ClientStreamFrame<Metadata, Data>;\n let eventId = 0;\n let status: \"completed\" | \"error\" = \"completed\";\n try {\n for await (const value of source) {\n const event = parseEvent(value, metadataSchema, dataSchemas);\n eventId += 1;\n yield {\n type: \"stream_event\",\n streamId,\n eventId,\n event,\n } satisfies ClientStreamFrame<Metadata, Data>;\n }\n } catch {\n status = \"error\";\n }\n yield { type: \"stream_end\", streamId, eventId, status } satisfies ClientStreamFrame<\n Metadata,\n Data\n >;\n },\n }));\n}\n\nfunction frameResumableClientStream<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n events: ClientStream<Metadata, Data>,\n streamId: string,\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): AsyncIterable<ClientStreamFrame<Metadata, Data>> {\n let open: Promise<void> | undefined;\n function start(): Promise<void> {\n if (open !== undefined) return open;\n open = store.open({ streamId }).then(() => undefined);\n void drainClientStream(events, streamId, store, metadataSchema, dataSchemas, open);\n return open;\n }\n return {\n async *[Symbol.asyncIterator]() {\n try {\n await start();\n } catch {\n yield startFrame<Metadata, Data>(streamId, true);\n yield endFrame<Metadata, Data>(streamId, 0, \"error\");\n return;\n }\n yield* resumeClientFrames(streamId, 0, store, metadataSchema, dataSchemas);\n },\n };\n}\n\nasync function drainClientStream<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n events: ClientStream<Metadata, Data>,\n streamId: string,\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n open: Promise<void>,\n): Promise<void> {\n try {\n await open;\n for await (const value of events) {\n await store.append({\n streamId,\n event: {\n protocol: CLIENT_STREAM_PROTOCOL,\n event: parseEvent(value, metadataSchema, dataSchemas),\n },\n });\n }\n await store.close({ streamId, status: \"completed\" });\n } catch {\n try {\n await store.close({ streamId, status: \"error\" });\n } catch {\n // A failed store open has no stream to close.\n }\n }\n}\n\nasync function* resumeClientFrames<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n streamId: string,\n after: number,\n store: ResumableStreamStore<ClientResumableEvent<Metadata, Data>>,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): AsyncIterable<ClientStreamFrame<Metadata, Data>> {\n yield startFrame<Metadata, Data>(streamId, true);\n let eventId = after;\n let invalid = false;\n try {\n for await (const record of store.subscribe({ streamId, after })) {\n const event = parseResumableEvent(record.event, metadataSchema, dataSchemas);\n eventId = record.eventId;\n yield { type: \"stream_event\", streamId, eventId, event };\n }\n } catch {\n invalid = true;\n }\n\n try {\n const state = await store.status({ streamId });\n const status = invalid || state.status === \"running\" ? \"error\" : state.status;\n yield endFrame<Metadata, Data>(streamId, Math.max(eventId, state.lastEventId), status);\n } catch {\n yield endFrame<Metadata, Data>(streamId, eventId, \"error\");\n }\n}\n\nfunction parseResumableEvent<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n value: unknown,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): ClientStreamEvent<Metadata, Data> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ClientProtocolError(\"Invalid client resumable record.\", value);\n }\n const record = value as { protocol?: unknown; event?: unknown };\n if (record.protocol === \"anvia.client.v1\") {\n throw new ClientProtocolError(\"Client resumable protocol v1 is not supported.\", value);\n }\n if (record.protocol !== CLIENT_STREAM_PROTOCOL || !(\"event\" in record)) {\n throw new ClientProtocolError(\n \"Client resumable records must use the current client protocol.\",\n value,\n );\n }\n return parseEvent(record.event, metadataSchema, dataSchemas);\n}\n\nfunction parseEvent<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n value: unknown,\n metadataSchema: ClientMetadataSchema<Metadata> | undefined,\n dataSchemas: ClientDataSchemas<Data> | undefined,\n): ClientStreamEvent<Metadata, Data> {\n const options: Parameters<typeof parseClientStreamEvent<Metadata, Data>>[1] = {};\n if (metadataSchema !== undefined) options.metadataSchema = metadataSchema;\n if (dataSchemas !== undefined) options.dataSchemas = dataSchemas;\n return parseClientStreamEvent<Metadata, Data>(value, options);\n}\n\nfunction startFrame<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n streamId: string,\n resumable: boolean,\n): ClientStreamFrame<Metadata, Data> {\n return {\n type: \"stream_start\",\n protocol: CLIENT_STREAM_PROTOCOL,\n streamId,\n eventId: 0,\n resumable,\n };\n}\n\nfunction endFrame<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n streamId: string,\n eventId: number,\n status: \"completed\" | \"error\" | \"missing\",\n): ClientStreamFrame<Metadata, Data> {\n return { type: \"stream_end\", streamId, eventId, status };\n}\n\nfunction clientResponse<Metadata extends ClientMetadata, Data extends ClientDataMap>(\n frames: AsyncIterable<ClientStreamFrame<Metadata, Data>>,\n options: ClientResponseOptions<Metadata, Data>,\n): Response {\n const headers = new Headers(options.headers);\n headers.set(\"x-anvia-stream-protocol\", CLIENT_STREAM_PROTOCOL);\n const responseOptions: Parameters<typeof encodeEventStreamResponse>[0] = {\n events: frames,\n headers,\n };\n if (options.format !== undefined) responseOptions.format = options.format;\n if (options.status !== undefined) responseOptions.status = options.status;\n if (options.statusText !== undefined) responseOptions.statusText = options.statusText;\n if (options.sse !== undefined) responseOptions.sse = options.sse;\n return encodeEventStreamResponse(responseOptions);\n}\n\nfunction propagateCancellation<TSource, TOutput>(\n source: AsyncIterable<TSource>,\n transform: (source: AsyncIterable<TSource>) => AsyncIterable<TOutput>,\n): AsyncIterable<TOutput> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<TOutput> {\n const sourceIterator = source[Symbol.asyncIterator]();\n const sharedSource: AsyncIterable<TSource> = {\n [Symbol.asyncIterator]: () => sourceIterator,\n };\n const outputIterator = transform(sharedSource)[Symbol.asyncIterator]();\n let returned = false;\n\n return {\n next: () => outputIterator.next(),\n async return(): Promise<IteratorResult<TOutput>> {\n if (returned) return { done: true, value: undefined };\n returned = true;\n const sourceReturn = sourceIterator.return?.();\n const outputReturn = outputIterator.return?.();\n await Promise.all([sourceReturn, outputReturn]);\n return { done: true, value: undefined };\n },\n };\n },\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anvia/server",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "Server-side client protocol and generic event stream responses for Anvia.",
5
5
  "author": "anvia",
6
6
  "license": "MIT",
@@ -22,21 +22,32 @@
22
22
  ".": {
23
23
  "types": "./dist/index.d.ts",
24
24
  "import": "./dist/index.js"
25
+ },
26
+ "./durable": {
27
+ "types": "./dist/durable.d.ts",
28
+ "import": "./dist/durable.js"
25
29
  }
26
30
  },
27
31
  "devDependencies": {
28
32
  "@types/node": "^24.9.1",
29
- "@vitest/coverage-v8": "4.1.5",
33
+ "@vitest/coverage-v8": "4.1.11",
30
34
  "tsup": "^8.5.0",
31
35
  "typescript": "^5.9.3",
32
- "vitest": "^4.0.8",
33
- "@anvia/client": "1.2.0"
36
+ "vitest": "^4.1.11",
37
+ "@anvia/client": "1.3.0",
38
+ "@anvia/durable": "0.1.1"
34
39
  },
35
40
  "peerDependencies": {
36
- "@anvia/client": "^1.2.0"
41
+ "@anvia/client": "^1.3.0",
42
+ "@anvia/durable": "^0.1.1"
43
+ },
44
+ "peerDependenciesMeta": {
45
+ "@anvia/durable": {
46
+ "optional": true
47
+ }
37
48
  },
38
49
  "scripts": {
39
- "build": "tsup src/index.ts --format esm --dts --sourcemap --clean",
50
+ "build": "tsup src/index.ts src/durable.ts --format esm --dts --sourcemap --clean",
40
51
  "coverage": "vitest run --coverage",
41
52
  "test": "vitest run",
42
53
  "typecheck": "tsc --noEmit"