constructor()

in remote/object-remoting-proxy.js [83:261]


    constructor(communicator, path, ownCommunicator, proxyId) {
        if (utils.isNullOrUndefined(communicator)) {
            throw new Error("communicator must be provided.");
        }

        if (!utils.isNullOrUndefined(path) && !utils.isString(path)) {
            throw new Error("path must be a string.");
        }

        /** @type {Donuts.Remote.ObjectResolver} */
        this._resolver = undefined;

        /**
         * @private
         * @readonly
         * @type {string}
         */
        this._id = proxyId || random.generateUid(6);

        /**
         * @private
         * @type {Donuts.Remote.ICommunicator}
         */
        this._communicator = communicator;

        /**
         * @private
         * @readonly
         * @type {boolean}
         */
        this.ownCommunicator = ownCommunicator === true;

        /**
         * @private
         * @readonly
         * @type {Donuts.Remote.IRoutePattern}
         */
        this._routePattern = new StringPattern(path || "/object-remoting-proxy");

        /**
         * @private
         * @readonly
         * @type {Object.<Donuts.Remote.ProxyAction, Donuts.Remote.AsyncRequestHandler>}
         */
        this.messageHandlers = Object.create(null);

        /**
         * @private
         * @readonly
         * @type {import("./data-info-manager").DataInfoManager}
         */
        this.dataInfoManager = new DataInfoManager(this);

        /**
         * @private
         * @param {Donuts.Remote.ICommunicator} communicator
         * @param {Donuts.Remote.IRoutePathInfo} pathInfo
         * @param {Donuts.Remote.IProxyMessage} proxyMsg
         * @returns {Promise<*>}
         */
        this.onMessage = (communicator, pathInfo, proxyMsg) => {
            if (!isProxyMessage(proxyMsg)) {
                // Log Error.
                return Promise.resolve();
            }

            /** @type {Donuts.Remote.AsyncRequestHandler} */
            const asyncRequestHandler = this.messageHandlers[proxyMsg.action];

            if (!asyncRequestHandler) {
                // Log Error.
                return Promise.resolve();
            }

            return asyncRequestHandler(communicator, pathInfo, proxyMsg);
        }

        /**
         * @private
         * @param {Donuts.Remote.ICommunicator} communicator
         * @param {Donuts.Remote.IRoutePathInfo} pathInfo
         * @param {Donuts.Remote.IResourceGetPropertyMessage} msg
         * @returns {Promise<*>}
         */
        this.onGetPropertyAsync = async (communicator, pathInfo, msg) => {
            const target = this.dataInfoManager.get(msg.refId);

            if (target === undefined) {
                throw new Error(`Target (${msg.refId}) doesn't exist.`);
            }

            return this.dataInfoManager.toDataInfo(target[msg.property]);
        }

        /**
         * @private
         * @param {Donuts.Remote.ICommunicator} communicator
         * @param {Donuts.Remote.IRoutePathInfo} pathInfo
         * @param {Donuts.Remote.IResourceSetPropertyMessage} msg
         * @returns {Promise<*>}
         */
        this.onSetPropertyAsync = async (communicator, pathInfo, msg) => {
            const target = this.dataInfoManager.get(msg.refId);

            if (target === undefined) {
                throw new Error(`Target (${msg.refId}) doesn't exist.`);
            }

            target[msg.property] = this.dataInfoManager.realizeDataInfo(msg.value);

            return true;
        }

        /**
         * @private
         * @param {Donuts.Remote.ICommunicator} communicator
         * @param {Donuts.Remote.IRoutePathInfo} pathInfo
         * @param {Donuts.Remote.IResourceApplyMessage} msg
         * @returns {Promise<*>}
         */
        this.onApplyAsync = async (communicator, pathInfo, msg) => {
            /** @type {Function} */
            const target = this.dataInfoManager.get(msg.refId);

            if (target === undefined) {
                throw new Error(`Target (${msg.refId}) doesn't exist.`);
            }

            if (typeof target !== "function") {
                throw new Error(`Target (${msg.refId}) is not a function which cannot be applied.`);
            }

            /** @type {Array.<*>} */
            const args = [];

            for (const argDataInfo of msg.args) {
                args.push(this.dataInfoManager.realizeDataInfo(argDataInfo));
            }

            /** @type {*} */
            const result = await target.apply(this.dataInfoManager.realizeDataInfo(msg.thisArg), args);

            return this.dataInfoManager.toDataInfo(result);
        }

        /**
         * @private
         * @param {Donuts.Remote.ICommunicator} communicator
         * @param {Donuts.Remote.IRoutePathInfo} pathInfo
         * @param {Donuts.Remote.IResourceRequestMessage} msg
         * @returns {Promise<*>}
         */
        this.onRequestResourceAsync = async (communicator, pathInfo, msg) => {
            /** @type {Array.<*>} */
            const extraArgs = [];

            for (const extraArgDataInfo of msg.extraArgs) {
                extraArgs.push(this.dataInfoManager.realizeDataInfo(extraArgDataInfo));
            }

            const target = await this.resolveAsync(msg.identifier, ...extraArgs);

            return this.dataInfoManager.toDataInfo(target);
        }

        /**
         * @private
         * @param {Donuts.Remote.ICommunicator} communicator
         * @param {Donuts.Remote.IRoutePathInfo} pathInfo
         * @param {Donuts.Remote.IResourceReleaseMessage} msg
         * @returns {Promise<*>}
         */
        this.onReleaseResourceAsync = async (communicator, pathInfo, msg) => {
            await this.dataInfoManager.delDataInfo(msg.refId);
        }

        this.initializeMessageHandlers();
        this.communicator.map(this.routePattern, this.onMessage);
    }