"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeHandler = void 0;
const Holder_1 = require("../../../../../Class/Holder");
const Waiter_1 = require("../../../../../Waiter");
const id_1 = require("../../../../../util/id");
const _ids_1 = require("../../../../_ids");
const makeHandler = (system, push) => {
    const { cache: { requests, responses }, } = system;
    return async (req) => {
        let url;
        do {
            url = `${(0, id_1.uuid)()}`;
        } while (requests[url]);
        const waiter = new Waiter_1.Waiter();
        requests[url] = req;
        responses[url] = waiter;
        push(url);
        const response = await waiter.once();
        delete requests[url];
        delete responses[url];
        return response;
    };
};
exports.makeHandler = makeHandler;
class Listen0 extends Holder_1.Holder {
    constructor(system) {
        super({
            fi: ['server', 'port'],
            fo: [],
            i: [],
            o: ['url'],
        }, {
            input: {
                server: {
                    ref: true,
                },
            },
            output: {},
        }, system, _ids_1.ID_LISTEN_0, 'close');
    }
    async f({ server, port }, done, fail) {
        if (port < 1 || port > 65535) {
            fail('invalid out-of-range port');
            return;
        }
        const handler = (0, exports.makeHandler)(this.__system, (url) => {
            this._output.url.push(url);
        });
        try {
            this._unlisten = server.listen(port, handler, (err) => {
                fail(err);
            });
        }
        catch (err) {
            fail(err.message);
        }
    }
    d() {
        if (this._unlisten) {
            this._unlisten();
            this._unlisten = undefined;
        }
    }
}
exports.default = Listen0;
//# sourceMappingURL=index.js.map