"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const AsyncWorker_1 = require("../../../../../../../AsyncWorker");
const Functional_1 = require("../../../../../../../Class/Functional");
const STRING_1 = require("../../../../../../../constant/STRING");
const local_1 = require("../../../../../../../process/share/local");
const RemotePort_1 = require("../../../../../../../RemotePort");
const wrap_1 = require("../../../../../../../wrap");
const _ids_1 = require("../../../../../../_ids");
class LocalGraph extends Functional_1.Functional {
    constructor(system) {
        super({
            i: ['id'],
            o: ['graph'],
        }, {
            output: {
                graph: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_LOCAL_GRAPH);
        this.__ = ['U'];
        this._connected = false;
        this._close = () => {
            if (this._connected) {
                this._remote_port.close();
                this._target_channel.close();
                (0, local_1.stopBroadcastTarget)(this._id);
                this._id = undefined;
                this._target_channel = undefined;
            }
        };
    }
    f({ id: source_id }, done) {
        if (!(0, local_1.hasLocalBroadcastSource)(source_id)) {
            this.err('cannot find local graph');
            return;
        }
        this._connected = true;
        const { id, channel } = (0, local_1.startBroadcastTarget)();
        this._id = id;
        this._target_channel = channel;
        const name = (0, local_1.localBroadcastTargetName)(id);
        const source_channel_name = (0, local_1.localBroadcastSourceName)(source_id);
        const source_channel = new BroadcastChannel(source_channel_name);
        this._source_channel = source_channel;
        source_channel.postMessage({ type: STRING_1.CONNECT, data: name });
        const port = {
            send: (data) => {
                channel.postMessage(data);
            },
            onmessage(data) { },
            onerror() {
                // console.log('onerror')
            },
            terminate() {
                // console.log('terminate')
            },
        };
        channel.onmessage = (event) => {
            const { data } = event;
            const { type, data: _data } = data;
            switch (type) {
                case STRING_1.EXEC:
                    {
                        port.onmessage({ data: _data });
                    }
                    break;
                case STRING_1.TERMINATE:
                    {
                        this._close();
                    }
                    break;
            }
        };
        const remote_port = new RemotePort_1.RemotePort(port);
        this._remote_port = remote_port;
        const $graph = (0, AsyncWorker_1.AsyncWorkerGraph)(remote_port);
        const graph = (0, wrap_1.$wrap)(this.__system, $graph, ['U', 'C', 'G']);
        done({ graph });
    }
    d() {
        if (this._connected) {
            this._source_channel.postMessage({ type: STRING_1.DISCONNECT, data: this._id });
        }
        this._close();
    }
}
exports.default = LocalGraph;
//# sourceMappingURL=index.js.map