# 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;