"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transport = exports.makeTransport = void 0;
function makeTransport() {
    const generators = new Map();
    return {
        isReady(generator) {
            handle(generator);
            return true;
        },
        onReady(generator, callback) {
            handle(generator);
            const handler = generators.get(generator);
            handler.readyListener = callback;
            return () => (handler.readyListener = undefined);
        },
        onMessage(generator, callback) {
            handle(generator);
            const handler = generators.get(generator);
            handler.messageListener = callback;
            return () => (handler.messageListener = undefined);
        },
        onClose(generator, callback) {
            handle(generator);
            const handler = generators.get(generator);
            handler.closeListener = callback;
            return () => (handler.closeListener = undefined);
        },
        onError(generator, callback) {
            handle(generator);
            const handler = generators.get(generator);
            handler.errorListener = callback;
            return () => (handler.errorListener = undefined);
        },
        send(generator, data) {
            handle(generator);
            const handler = generators.get(generator);
            handler.queue.push(data);
        },
    };
    async function handle(generator) {
        var _a, _b, _c;
        if (generators.get(generator))
            return;
        const handler = { queue: [] };
        generators.set(generator, handler);
        let running = true;
        (_a = handler.readyListener) === null || _a === void 0 ? void 0 : _a.call(handler);
        while (running) {
            try {
                const outgoing = [...handler.queue];
                const result = await generator.next(outgoing);
                handler.queue = handler.queue.filter(data => !outgoing.includes(data));
                result.value.forEach(value => { var _a; return (_a = handler.messageListener) === null || _a === void 0 ? void 0 : _a.call(handler, value); });
                if (result.done) {
                    running = false;
                    (_b = handler.closeListener) === null || _b === void 0 ? void 0 : _b.call(handler);
                }
            }
            catch (error) {
                running = false;
                (_c = handler.errorListener) === null || _c === void 0 ? void 0 : _c.call(handler, error);
            }
        }
    }
}
exports.makeTransport = makeTransport;
exports.transport = makeTransport();
exports.default = exports.transport;
