/**
 * Stream wrapper class inspired by OpenAI SDK
 * Provides utilities for working with async iterables
 */
export class Stream {
    iterator;
    controller;
    consumed = false;
    constructor(iterator, controller) {
        this.iterator = iterator;
        this.controller = controller;
    }
    /**
     * Create a Stream from an async generator
     */
    static fromAsyncIterable(iterable, controller) {
        return new Stream(() => iterable[Symbol.asyncIterator](), controller);
    }
    [Symbol.asyncIterator]() {
        if (this.consumed) {
            throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
        }
        this.consumed = true;
        return this.iterator();
    }
    /**
     * Splits the stream into two streams which can be
     * independently read from at different speeds.
     */
    tee() {
        const left = [];
        const right = [];
        const iterator = this.iterator();
        const teeIterator = (queue) => {
            return {
                next: () => {
                    if (queue.length === 0) {
                        const result = iterator.next();
                        left.push(result);
                        right.push(result);
                    }
                    return queue.shift();
                }
            };
        };
        return [
            new Stream(() => teeIterator(left), this.controller),
            new Stream(() => teeIterator(right), this.controller)
        ];
    }
    /**
     * Collect all chunks into an array
     */
    async toArray() {
        const result = [];
        for await (const chunk of this) {
            result.push(chunk);
        }
        return result;
    }
    /**
     * Abort the underlying stream
     */
    abort() {
        this.controller?.abort();
    }
}
