Source: core/agg-room.js

/** @module core/agg-room */
import {AggHouseRoomError, AggHouseUnavailableError} from '../types/error';

/** Class that controls one aggregator. */
class AggRoom {
    /**
     * Initialize an AggRoom.
     * @param {!Aggregator} aggregator The aggregator to manage.
     * @param {!AggHouse} aggHouse The AggHouse instance.
     * @throws {AggHouseUnavailableError} Throw an error when aggregator house
     * is not available.
     */
    constructor(aggregator, aggHouse) {
        /** @private {!AggHouse} */
        this.aggHouse_ = aggHouse;

        /** @private {!Array<Class>} */
        this.classIds_ = aggregator.classes;

        /** @private {boolean} */
        this.isDisposed_ = false;

        /** @private {string} */
        this.name_ = aggregator.name;

        /** @private {string} */
        this.version_ = aggregator.version;

        /** @private {Worker} */
        this.worker_ = null;

        if (this.aggHouse_.getConfig('serverMode')) {
            throw new AggHouseUnavailableError('To be implemented.');
            // TODO(zacy1): Implement server mode behavior.
        } else {
            let workerURL = URL.createObjectURL(new Blob(
                ['(', aggregator.worker.toString(), ')()'],
                {type: 'application/javascript'}
            ));
            this.worker_ = new Worker(workerURL);
            URL.revokeObjectURL(workerURL);
        }

        this.worker_.onmessage = (e) => this.saveData_(e);
    }

    /**
     * Get aggregator name.
     * @return {string} Name of the aggregator this AggRoom manages.
     */
    get name() {
        return this.name_;
    }

    /**
     * Get aggregator version.
     * @return {string} version string of the aggregator this AggRoom manages.
     */
    get version() {
        return this.version_;
    }

    /**
     * Save data sent by the aggregator.
     * @param {Event} e Event sent by aggregator.
     * @private
     */
    saveData_(e) {
        let data = JSON.parse(e.data[0]);
        let isAppending = e.data[1];
        this.aggHouse_.updateData(this.name, data, isAppending);
    }

    /**
     * Check if the aggregator is responsible for some class.
     * @param {number} classId ID of class to check.
     * @return {boolean} Responsible or not.
     */
    containsClass(classId) {
        return this.classIds_.includes(0) || this.classIds_.includes(classId);
    }

    /**
     * Send updated input to aggregator.
     * @param {Object} input Input data.
     * @throws {AggHouseRoomError} Throw an error when update is sent to a
     * disposed AggRoom.
     */
    sendUpdate(input) {
        if (this.isDisposed_) {
            throw new AggHouseRoomError('AggRoom ' + this.toString() +
                ' has been disposed.');
        }
        this.worker_.postMessage(input);
    }

    /**
     * Dispose worker.
     */
    dispose() {
        this.worker_.terminate();
        this.isDisposed_ = true;
    }

    /**
     * Get AggHouse info string.
     * @return {string} AggHouse info string.
     * @override
     */
    toString() {
        return this.name + '(version ' + this.version + ')';
    }
}

export default AggRoom;