@tashiscool/stream 0.1.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/jsonl.js ADDED
@@ -0,0 +1,104 @@
1
+ /**
2
+ * JSONL Streaming
3
+ * Parse and serialize JSONL (JSON Lines) streams
4
+ */
5
+ /**
6
+ * Streams objects as JSONL (JSON Lines) to an HTTP response.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * app.get('/events', (req, res) => {
11
+ * streamJsonLines(res, async function* () {
12
+ * for (const event of events) {
13
+ * yield event;
14
+ * }
15
+ * });
16
+ * });
17
+ * ```
18
+ */
19
+ export function streamJsonLines(res, generator) {
20
+ res.setHeader('Content-Type', 'application/x-ndjson');
21
+ res.setHeader('Transfer-Encoding', 'chunked');
22
+ res.setHeader('Cache-Control', 'no-cache');
23
+ res.setHeader('Connection', 'keep-alive');
24
+ (async () => {
25
+ try {
26
+ for await (const item of generator()) {
27
+ const line = JSON.stringify(item) + '\n';
28
+ res.write(line);
29
+ }
30
+ }
31
+ finally {
32
+ res.end();
33
+ }
34
+ })();
35
+ }
36
+ /**
37
+ * Parses a JSONL stream from a fetch Response.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const response = await fetch('/events');
42
+ * for await (const event of parseJsonLines(response)) {
43
+ * handleEvent(event);
44
+ * }
45
+ * ```
46
+ */
47
+ export async function* parseJsonLines(response) {
48
+ if (!response.body) {
49
+ throw new Error('Response body is null');
50
+ }
51
+ const reader = response.body.getReader();
52
+ const decoder = new TextDecoder('utf-8');
53
+ let buffer = '';
54
+ try {
55
+ while (true) {
56
+ const { done, value } = await reader.read();
57
+ if (done) {
58
+ break;
59
+ }
60
+ buffer += decoder.decode(value, { stream: true });
61
+ // Split by newlines and process complete lines
62
+ const lines = buffer.split('\n');
63
+ buffer = lines.pop() || ''; // Keep incomplete line in buffer
64
+ for (const line of lines) {
65
+ const trimmed = line.trim();
66
+ if (trimmed) {
67
+ try {
68
+ yield JSON.parse(trimmed);
69
+ }
70
+ catch {
71
+ // Skip invalid JSON lines
72
+ console.warn('Invalid JSONL line:', trimmed.slice(0, 100));
73
+ }
74
+ }
75
+ }
76
+ }
77
+ // Process any remaining content in buffer
78
+ const trimmed = buffer.trim();
79
+ if (trimmed) {
80
+ try {
81
+ yield JSON.parse(trimmed);
82
+ }
83
+ catch {
84
+ console.warn('Invalid JSONL line:', trimmed.slice(0, 100));
85
+ }
86
+ }
87
+ }
88
+ finally {
89
+ reader.releaseLock();
90
+ }
91
+ }
92
+ /**
93
+ * Serializes an object to a JSONL line
94
+ */
95
+ export function toJsonLine(obj) {
96
+ return JSON.stringify(obj) + '\n';
97
+ }
98
+ /**
99
+ * Parses a single JSONL line
100
+ */
101
+ export function fromJsonLine(line) {
102
+ return JSON.parse(line.trim());
103
+ }
104
+ //# sourceMappingURL=jsonl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../src/jsonl.ts"],"names":[],"mappings":"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"}
package/dist/mux.d.ts ADDED
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Stream Multiplexer
3
+ * Merge multiple async streams with stable ordering and cursor support
4
+ */
5
+ /**
6
+ * Stream event with metadata
7
+ */
8
+ export interface StreamEvent<T = unknown> {
9
+ /** Event ID for cursor tracking */
10
+ id: string;
11
+ /** Source stream identifier */
12
+ source: string;
13
+ /** Sequence number within source */
14
+ seq: number;
15
+ /** Event timestamp */
16
+ timestamp: number;
17
+ /** Event type */
18
+ type: 'delta' | 'tool_call' | 'tool_result' | 'json' | 'error' | 'done';
19
+ /** Event payload */
20
+ data: T;
21
+ }
22
+ /**
23
+ * Cursor for stream position tracking
24
+ */
25
+ export interface StreamCursor {
26
+ /** Event ID to resume from */
27
+ eventId: string;
28
+ /** Source positions */
29
+ positions: Record<string, number>;
30
+ /** Timestamp */
31
+ timestamp: number;
32
+ }
33
+ /**
34
+ * Mux options
35
+ */
36
+ export interface MuxOptions {
37
+ /** Resume from cursor */
38
+ cursor?: string | StreamCursor | null;
39
+ /** Buffer size for ordering */
40
+ bufferSize?: number;
41
+ /** Timeout for out-of-order events (ms) */
42
+ orderingTimeoutMs?: number;
43
+ /** Generate event IDs */
44
+ generateId?: () => string;
45
+ }
46
+ /**
47
+ * Named async iterable
48
+ */
49
+ export interface NamedStream<T = unknown> {
50
+ name: string;
51
+ stream: AsyncIterable<T>;
52
+ }
53
+ /**
54
+ * Parse cursor from string or object
55
+ */
56
+ export declare function parseCursor(cursor: string | StreamCursor): StreamCursor;
57
+ /**
58
+ * Serialize cursor to string
59
+ */
60
+ export declare function serializeCursor(cursor: StreamCursor): string;
61
+ /**
62
+ * Create cursor from current state
63
+ */
64
+ export declare function createCursor(eventId: string, positions: Record<string, number>): StreamCursor;
65
+ /**
66
+ * Multiplex multiple async iterables into a single ordered stream
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const llmStream = getOpenAIStream();
71
+ * const toolStream = getToolResultStream();
72
+ *
73
+ * const combined = mux([
74
+ * { name: 'llm', stream: llmStream },
75
+ * { name: 'tools', stream: toolStream },
76
+ * ], { cursor: request.headers.get('x-cursor') });
77
+ *
78
+ * for await (const event of combined) {
79
+ * console.log(event.source, event.data);
80
+ * }
81
+ * ```
82
+ */
83
+ export declare function mux<T>(streams: NamedStream<T>[], options?: MuxOptions): AsyncGenerator<StreamEvent<T>, void, unknown>;
84
+ /**
85
+ * Simple array-based multiplexer for basic use cases
86
+ */
87
+ export declare function muxSimple<T>(...streams: AsyncIterable<T>[]): AsyncGenerator<T, void, unknown>;
88
+ /**
89
+ * Create a replayable stream with buffer
90
+ */
91
+ export declare function createReplayableStream<T>(source: AsyncIterable<T>, bufferSize?: number): {
92
+ stream: () => AsyncGenerator<StreamEvent<T>>;
93
+ replay: (cursor: string | StreamCursor) => AsyncGenerator<StreamEvent<T>>;
94
+ getBuffer: () => StreamEvent<T>[];
95
+ getCursor: () => string;
96
+ };
97
+ /**
98
+ * Transform stream events
99
+ */
100
+ export declare function mapEvents<T, U>(stream: AsyncIterable<StreamEvent<T>>, fn: (event: StreamEvent<T>) => StreamEvent<U> | null): AsyncGenerator<StreamEvent<U>>;
101
+ /**
102
+ * Filter stream events
103
+ */
104
+ export declare function filterEvents<T>(stream: AsyncIterable<StreamEvent<T>>, predicate: (event: StreamEvent<T>) => boolean): AsyncGenerator<StreamEvent<T>>;
105
+ /**
106
+ * Combine delta events into complete messages
107
+ */
108
+ export declare function accumulateDeltas<T extends {
109
+ delta?: string;
110
+ text?: string;
111
+ }>(stream: AsyncIterable<StreamEvent<T>>): AsyncGenerator<StreamEvent<T & {
112
+ accumulated: string;
113
+ }>>;
114
+ //# sourceMappingURL=mux.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mux.d.ts","sourceRoot":"","sources":["../src/mux.ts"],"names":[],"mappings":"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"}
package/dist/mux.js ADDED
@@ -0,0 +1,310 @@
1
+ /**
2
+ * Stream Multiplexer
3
+ * Merge multiple async streams with stable ordering and cursor support
4
+ */
5
+ /**
6
+ * Generate unique event ID
7
+ */
8
+ function defaultGenerateId() {
9
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
10
+ }
11
+ /**
12
+ * Parse cursor from string or object
13
+ */
14
+ export function parseCursor(cursor) {
15
+ if (typeof cursor === 'string') {
16
+ try {
17
+ return JSON.parse(atob(cursor));
18
+ }
19
+ catch {
20
+ return {
21
+ eventId: cursor,
22
+ positions: {},
23
+ timestamp: 0,
24
+ };
25
+ }
26
+ }
27
+ return cursor;
28
+ }
29
+ /**
30
+ * Serialize cursor to string
31
+ */
32
+ export function serializeCursor(cursor) {
33
+ return btoa(JSON.stringify(cursor));
34
+ }
35
+ /**
36
+ * Create cursor from current state
37
+ */
38
+ export function createCursor(eventId, positions) {
39
+ return {
40
+ eventId,
41
+ positions,
42
+ timestamp: Date.now(),
43
+ };
44
+ }
45
+ /**
46
+ * Multiplex multiple async iterables into a single ordered stream
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const llmStream = getOpenAIStream();
51
+ * const toolStream = getToolResultStream();
52
+ *
53
+ * const combined = mux([
54
+ * { name: 'llm', stream: llmStream },
55
+ * { name: 'tools', stream: toolStream },
56
+ * ], { cursor: request.headers.get('x-cursor') });
57
+ *
58
+ * for await (const event of combined) {
59
+ * console.log(event.source, event.data);
60
+ * }
61
+ * ```
62
+ */
63
+ export async function* mux(streams, options = {}) {
64
+ const { cursor: cursorInput, bufferSize = 100, generateId = defaultGenerateId, } = options;
65
+ // Parse cursor if provided
66
+ const cursor = cursorInput
67
+ ? parseCursor(cursorInput)
68
+ : null;
69
+ const startPositions = cursor?.positions || {};
70
+ // State tracking
71
+ const state = {
72
+ positions: {},
73
+ lastEventId: '',
74
+ buffer: [],
75
+ };
76
+ // Initialize positions
77
+ for (const { name } of streams) {
78
+ state.positions[name] = startPositions[name] || 0;
79
+ }
80
+ // Track active iterators
81
+ const iterators = streams.map(({ name, stream }) => ({
82
+ name,
83
+ iterator: stream[Symbol.asyncIterator](),
84
+ done: false,
85
+ seq: state.positions[name] || 0,
86
+ }));
87
+ const iteratorStates = iterators.map((it) => ({
88
+ ...it,
89
+ pending: null,
90
+ }));
91
+ // Start or get pending promise for an iterator
92
+ function getOrStartNext(state) {
93
+ if (state.pending)
94
+ return state.pending;
95
+ state.pending = (async () => {
96
+ try {
97
+ const result = await state.iterator.next();
98
+ if (result.done) {
99
+ state.done = true;
100
+ return null;
101
+ }
102
+ state.seq++;
103
+ return { name: state.name, value: result.value, seq: state.seq };
104
+ }
105
+ catch (error) {
106
+ state.done = true;
107
+ throw error;
108
+ }
109
+ })();
110
+ return state.pending;
111
+ }
112
+ // Pull from all streams concurrently
113
+ async function pullNext() {
114
+ while (true) {
115
+ const pending = iteratorStates.filter((it) => !it.done);
116
+ if (pending.length === 0)
117
+ return null;
118
+ // Create wrapper promises that identify which iterator resolved
119
+ const promises = pending.map((state, idx) => getOrStartNext(state).then((result) => ({ idx, state, result })));
120
+ const { idx, state, result } = await Promise.race(promises);
121
+ // Clear the pending promise for the iterator that resolved
122
+ state.pending = null;
123
+ // If this iterator had a value, return it
124
+ if (result !== null) {
125
+ return result;
126
+ }
127
+ // Otherwise, this iterator is done, loop to race remaining iterators
128
+ }
129
+ }
130
+ // Check if we should skip (for resume)
131
+ function shouldSkip(name, seq) {
132
+ const startSeq = startPositions[name] || 0;
133
+ return seq <= startSeq;
134
+ }
135
+ // Main loop
136
+ while (true) {
137
+ const result = await pullNext();
138
+ if (!result)
139
+ break;
140
+ const { name, value, seq } = result;
141
+ state.positions[name] = seq;
142
+ // Skip if resuming and before cursor position
143
+ if (shouldSkip(name, seq)) {
144
+ continue;
145
+ }
146
+ // Create event
147
+ const eventId = generateId();
148
+ const event = {
149
+ id: eventId,
150
+ source: name,
151
+ seq,
152
+ timestamp: Date.now(),
153
+ type: detectEventType(value),
154
+ data: value,
155
+ };
156
+ state.lastEventId = eventId;
157
+ // Buffer management
158
+ state.buffer.push(event);
159
+ if (state.buffer.length > bufferSize) {
160
+ state.buffer.shift();
161
+ }
162
+ yield event;
163
+ }
164
+ }
165
+ /**
166
+ * Detect event type from data
167
+ */
168
+ function detectEventType(data) {
169
+ if (data === null || data === undefined) {
170
+ return 'done';
171
+ }
172
+ if (typeof data === 'object') {
173
+ const obj = data;
174
+ if ('error' in obj)
175
+ return 'error';
176
+ if ('tool_call' in obj || 'function_call' in obj)
177
+ return 'tool_call';
178
+ if ('tool_result' in obj || 'function_result' in obj)
179
+ return 'tool_result';
180
+ if (typeof obj === 'object' && !('delta' in obj) && !('text' in obj)) {
181
+ return 'json';
182
+ }
183
+ }
184
+ return 'delta';
185
+ }
186
+ /**
187
+ * Simple array-based multiplexer for basic use cases
188
+ */
189
+ export async function* muxSimple(...streams) {
190
+ const iterators = streams.map((s) => ({
191
+ iterator: s[Symbol.asyncIterator](),
192
+ done: false,
193
+ pending: null,
194
+ }));
195
+ function getOrStartNext(state) {
196
+ if (state.pending)
197
+ return state.pending;
198
+ state.pending = (async () => {
199
+ const result = await state.iterator.next();
200
+ if (result.done) {
201
+ state.done = true;
202
+ return null;
203
+ }
204
+ return { value: result.value };
205
+ })();
206
+ return state.pending;
207
+ }
208
+ while (true) {
209
+ const pending = iterators.filter((it) => !it.done);
210
+ if (pending.length === 0)
211
+ break;
212
+ const promises = pending.map((state) => getOrStartNext(state).then((result) => ({ state, result })));
213
+ const { state, result } = await Promise.race(promises);
214
+ state.pending = null;
215
+ if (result !== null) {
216
+ yield result.value;
217
+ }
218
+ // If result is null, the iterator is done, loop continues with remaining
219
+ }
220
+ }
221
+ /**
222
+ * Create a replayable stream with buffer
223
+ */
224
+ export function createReplayableStream(source, bufferSize = 1000) {
225
+ const buffer = [];
226
+ let seq = 0;
227
+ let consumed = false;
228
+ async function* stream() {
229
+ if (consumed) {
230
+ throw new Error('Stream already consumed. Use replay() instead.');
231
+ }
232
+ consumed = true;
233
+ for await (const data of source) {
234
+ seq++;
235
+ const event = {
236
+ id: `${Date.now()}-${seq}`,
237
+ source: 'main',
238
+ seq,
239
+ timestamp: Date.now(),
240
+ type: detectEventType(data),
241
+ data,
242
+ };
243
+ buffer.push(event);
244
+ if (buffer.length > bufferSize) {
245
+ buffer.shift();
246
+ }
247
+ yield event;
248
+ }
249
+ }
250
+ async function* replay(cursor) {
251
+ const parsed = parseCursor(cursor);
252
+ const startSeq = parsed.positions['main'] || 0;
253
+ for (const event of buffer) {
254
+ if (event.seq > startSeq) {
255
+ yield event;
256
+ }
257
+ }
258
+ }
259
+ function getBuffer() {
260
+ return [...buffer];
261
+ }
262
+ function getCursor() {
263
+ if (buffer.length === 0)
264
+ return '';
265
+ const lastEvent = buffer[buffer.length - 1];
266
+ return serializeCursor(createCursor(lastEvent.id, { main: lastEvent.seq }));
267
+ }
268
+ return { stream, replay, getBuffer, getCursor };
269
+ }
270
+ /**
271
+ * Transform stream events
272
+ */
273
+ export async function* mapEvents(stream, fn) {
274
+ for await (const event of stream) {
275
+ const mapped = fn(event);
276
+ if (mapped)
277
+ yield mapped;
278
+ }
279
+ }
280
+ /**
281
+ * Filter stream events
282
+ */
283
+ export async function* filterEvents(stream, predicate) {
284
+ for await (const event of stream) {
285
+ if (predicate(event))
286
+ yield event;
287
+ }
288
+ }
289
+ /**
290
+ * Combine delta events into complete messages
291
+ */
292
+ export async function* accumulateDeltas(stream) {
293
+ let accumulated = '';
294
+ for await (const event of stream) {
295
+ if (event.type === 'delta') {
296
+ const delta = event.data.delta ||
297
+ event.data.text ||
298
+ '';
299
+ accumulated += delta;
300
+ }
301
+ yield {
302
+ ...event,
303
+ data: {
304
+ ...event.data,
305
+ accumulated,
306
+ },
307
+ };
308
+ }
309
+ }
310
+ //# sourceMappingURL=mux.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mux.js","sourceRoot":"","sources":["../src/mux.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * HTTP Response Utilities
3
+ * Stream to Response helpers for various protocols
4
+ */
5
+ import type { StreamEvent } from './mux.js';
6
+ /**
7
+ * Stream protocol
8
+ */
9
+ export type StreamProtocol = 'sse' | 'jsonl' | 'raw';
10
+ /**
11
+ * Response options
12
+ */
13
+ export interface StreamResponseOptions {
14
+ /** Custom headers */
15
+ headers?: Record<string, string>;
16
+ /** Include cursor in response */
17
+ includeCursor?: boolean;
18
+ /** Cursor header name */
19
+ cursorHeader?: string;
20
+ /** On error callback */
21
+ onError?: (error: Error) => void;
22
+ /** On complete callback */
23
+ onComplete?: () => void;
24
+ /** Signal for abort */
25
+ signal?: AbortSignal;
26
+ }
27
+ /**
28
+ * Protocol encoder
29
+ */
30
+ export interface ProtocolEncoder<T = unknown> {
31
+ /** Content-Type header */
32
+ contentType: string;
33
+ /** Encode event to string/bytes */
34
+ encode: (event: StreamEvent<T>) => string;
35
+ /** End marker (if any) */
36
+ end?: string;
37
+ }
38
+ /**
39
+ * Server-Sent Events encoder
40
+ */
41
+ export declare function sse<T = unknown>(): ProtocolEncoder<T>;
42
+ /**
43
+ * JSON Lines encoder
44
+ */
45
+ export declare function jsonl<T = unknown>(): ProtocolEncoder<T>;
46
+ /**
47
+ * Raw text encoder (just the data)
48
+ */
49
+ export declare function raw<T = unknown>(): ProtocolEncoder<T>;
50
+ /**
51
+ * Create a Web API Response from an async stream
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * export async function POST(req: Request) {
56
+ * const stream = getOpenAIStream();
57
+ * return streamToResponse(stream, sse());
58
+ * }
59
+ * ```
60
+ */
61
+ export declare function streamToResponse<T>(stream: AsyncIterable<StreamEvent<T>>, encoder: ProtocolEncoder<T>, options?: StreamResponseOptions): Response;
62
+ /**
63
+ * Create a simple text streaming response
64
+ */
65
+ export declare function textStreamResponse(stream: AsyncIterable<string>, options?: Omit<StreamResponseOptions, 'includeCursor'>): Response;
66
+ /**
67
+ * Parse SSE stream from Response
68
+ */
69
+ export declare function parseSSEResponse<T = unknown>(response: Response): AsyncGenerator<StreamEvent<T>>;
70
+ /**
71
+ * Parse JSONL stream from Response
72
+ */
73
+ export declare function parseJSONLResponse<T = unknown>(response: Response): AsyncGenerator<StreamEvent<T>>;
74
+ /**
75
+ * Node.js ServerResponse adapter
76
+ */
77
+ export interface NodeServerResponse {
78
+ writeHead(statusCode: number, headers: Record<string, string>): void;
79
+ write(chunk: string): boolean;
80
+ end(): void;
81
+ on(event: 'close', listener: () => void): void;
82
+ }
83
+ /**
84
+ * Stream to Node.js ServerResponse
85
+ */
86
+ export declare function streamToNodeResponse<T>(stream: AsyncIterable<StreamEvent<T>>, res: NodeServerResponse, encoder: ProtocolEncoder<T>, options?: StreamResponseOptions): Promise<void>;
87
+ /**
88
+ * Create AI-compatible event from various formats
89
+ */
90
+ export declare function createAIEvent<T>(data: T, options?: {
91
+ source?: string;
92
+ type?: StreamEvent['type'];
93
+ id?: string;
94
+ }): StreamEvent<T>;
95
+ /**
96
+ * Convert simple async string stream to event stream
97
+ */
98
+ export declare function toEventStream(stream: AsyncIterable<string>, source?: string): AsyncGenerator<StreamEvent<{
99
+ delta: string;
100
+ }>>;
101
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"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"}