"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageStream = void 0;
const omit_1 = __importDefault(require("lodash/omit"));
const PushPipeline_1 = require("../utils/PushPipeline");
const Message_1 = require("./../Message");
/**
 * Provides asynchronous iteration with
 * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of | for await .. of}.
 */
class MessageStream {
    pipeline;
    /** @internal */
    onFinally;
    /** @internal */
    onBeforeFinally;
    /** @internal */
    onError;
    /** @internal */
    constructor(pipeline) {
        this.pipeline = pipeline ?? new PushPipeline_1.PushPipeline();
        this.onFinally = this.pipeline.onFinally;
        this.onBeforeFinally = this.pipeline.onBeforeFinally;
        this.onError = this.pipeline.onError;
    }
    /**
     * Attach a legacy onMessage handler and consume if necessary.
     * onMessage is passed parsed content as first arument, and streamMessage as second argument.
     * @internal
     */
    useLegacyOnMessageHandler(onMessage) {
        this.pipeline.onMessage.listen(async (streamMessage) => {
            const msg = (0, Message_1.convertStreamMessageToMessage)(streamMessage);
            await onMessage(msg.content, (0, omit_1.default)(msg, 'content'));
        });
        this.pipeline.flow();
        return this;
    }
    async *[Symbol.asyncIterator]() {
        for await (const msg of this.pipeline) {
            yield (0, Message_1.convertStreamMessageToMessage)(msg);
        }
    }
    /*
     * The methods below are used to control or observe the pipeline.
     * TODO We should refactor the pipeline handling so that a MessageStream producer
     * (e.g. SubscriptionSession or Resends) creates a PushPipeline (or similar) data structure,
     * and calls these methods for that pipeline. Here in MessageStream we'd see the object
     * as Pipeline interface. Ideally here in MessageStream we'd use the pipeline only to get
     * an async iterator when [Symbol.asyncIterator]() is called for this MessageStream.
     * When the we have done the refactoring, all/most other methods below could be removed.
     */
    /** @internal */
    async push(item) {
        await this.pipeline.push(item);
    }
    /** @internal */
    pipe(fn) {
        return this.pipeline.pipe(fn);
    }
    /** @internal */
    async handleError(err) {
        await this.pipeline.handleError(err);
    }
    /** @internal */
    end(err) {
        this.pipeline.end(err);
    }
    /** @internal */
    isDone() {
        return this.pipeline.isDone();
    }
    /** @internal */
    return() {
        return this.pipeline.return();
    }
}
exports.MessageStream = MessageStream;
//# sourceMappingURL=MessageStream.js.map