"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _1 = require("../../../../../Class/$");
const Semifunctional_1 = require("../../../../../Class/Semifunctional");
const evaluate_1 = require("../../../../../spec/evaluate");
const stringify_1 = require("../../../../../spec/stringify");
const _ids_1 = require("../../../../_ids");
class LocalChannel extends Semifunctional_1.Semifunctional {
    constructor(system) {
        super({
            fi: ['channel'],
            fo: ['port'],
            i: ['close'],
            o: [],
        }, {
            output: {
                port: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_LOCAL_CHANNEL);
        this._bc = null;
    }
    f({ channel }, done) {
        const { api: { channel: { local }, }, } = this.__system;
        this._bc = local({ channel });
        const bc = this._bc;
        const port = new (class Port extends _1.$ {
            constructor(system) {
                super(system);
                this.__ = ['P'];
                this._unlisten = bc.addListener('message', (event) => {
                    const { specs, classes } = this.__system;
                    const { data } = event;
                    const _data = (0, evaluate_1.evaluate)(data, specs, classes);
                    this.emit('message', _data);
                });
                this.addListener('destroy', () => {
                    this._unlisten();
                    this._unlisten = undefined;
                });
            }
            send(data) {
                const _data = (0, stringify_1.stringify)(data);
                bc.postMessage(_data);
                return;
            }
        })(this.__system);
        done({ port });
    }
    d() {
        if (this._bc) {
            this._bc.close();
        }
    }
}
exports.default = LocalChannel;
//# sourceMappingURL=index.js.map