UNPKG

landstrasse

Version:

Strongly typed WAMP Client for browsers

140 lines 6.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const AbstractProcessor_1 = require("./AbstractProcessor"); const deferred_1 = require("../util/deferred"); const logger_1 = require("../util/logger"); const MessageTypes_1 = require("../types/messages/MessageTypes"); class Caller extends AbstractProcessor_1.default { constructor() { super(...arguments); Object.defineProperty(this, "_pendingCalls", { enumerable: true, configurable: true, writable: true, value: new Map() }); } static getFeatures() { return { caller: { features: { progressive_call_results: true, call_timeout: true, call_canceling: true, caller_identification: true, sharded_registration: true, }, }, }; } call(uri, args, kwArgs, details) { if (this._closed) { return [ Promise.reject('Caller closed.'), () => Promise.resolve(), ]; } const withProgress = !!(details === null || details === void 0 ? void 0 : details.receive_progress); const requestId = this.idGenerators.session.id(); const message = [MessageTypes_1.EWampMessageID.CALL, requestId, details || {}, uri, args || [], kwArgs || {}]; this.logger.log(logger_1.LogLevel.DEBUG, `Calling \`${uri}\` (request id: ${requestId}).`, args, kwArgs, details); const executor = () => __awaiter(this, void 0, void 0, function* () { const result = new deferred_1.default(); this._pendingCalls.set(requestId, [result, withProgress]); try { yield this.sender(message); } catch (err) { this.logger.log(logger_1.LogLevel.WARNING, `Call to \`${uri}\` failed.`, err); this._pendingCalls.delete(requestId); throw err; } return yield result.promise; }); const cancel = (killMode) => this.cancel(requestId, killMode); return [executor(), cancel]; } cancel(requestId, killMode) { return __awaiter(this, void 0, void 0, function* () { if (this._closed) { throw new Error('Caller closed.'); } const call = this._pendingCalls.get(requestId); if (!call) { throw new Error('Unexpected cancellation (unable to find the related call).'); } const msg = [MessageTypes_1.EWampMessageID.CANCEL, requestId, { mode: killMode || '' }]; this.logger.log(logger_1.LogLevel.DEBUG, `Cancelling call ${requestId}.`); yield this.sender(msg); }); } // // - Handlers. // onMessage(msg) { if (msg[0] === MessageTypes_1.EWampMessageID.RESULT) { const requestId = msg[1]; if (!this._pendingCalls.has(requestId)) { this.violator('Unexpected result received (unable to find the related call).'); return true; } const [callRequest, awaitedProgress] = this._pendingCalls.get(requestId); const details = msg[2] || {}; const resultArgs = msg[3] || []; const resultKwargs = msg[4] || {}; let result = null; if (resultArgs.length > 1 || Object.keys(resultKwargs).length > 0) { result = { args: resultArgs, kwargs: resultKwargs }; } else if (resultArgs.length > 0) { result = resultArgs[0]; } if (details.progress) { this.logger.log(logger_1.LogLevel.DEBUG, `Received call progress for call ${requestId}.`, result); if (!awaitedProgress) { this.violator('Unexpected progress received for a call without progress requested.'); return true; } const nextCallRequest = new deferred_1.default(); callRequest.resolve({ result, next: nextCallRequest.promise }); this._pendingCalls.set(requestId, [nextCallRequest, true]); } else { this.logger.log(logger_1.LogLevel.DEBUG, `Received result for call ${requestId}.`, result); callRequest.resolve(result); this._pendingCalls.delete(requestId); } return true; } if (msg[0] === MessageTypes_1.EWampMessageID.ERROR && msg[1] === MessageTypes_1.EWampMessageID.CALL) { const requestId = msg[2]; if (!this._pendingCalls.has(requestId)) { this.violator('Unexpected call error received (unable to find the related call).'); return true; } const [callRequest] = this._pendingCalls.get(requestId); this.logger.log(logger_1.LogLevel.WARNING, `Received \`${msg[4].toString()}\` error for call ${requestId}.`); this._pendingCalls.delete(requestId); callRequest.reject(new Error(msg[4])); return true; } return false; } onClose() { this._pendingCalls.forEach(([request]) => { request.reject(new Error('closing')); }); this._pendingCalls.clear(); } } exports.default = Caller; //# sourceMappingURL=caller.js.map