landstrasse
Version:
Strongly typed WAMP Client for browsers
138 lines • 5.95 kB
JavaScript
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());
});
};
import AbstractProcessor from './AbstractProcessor';
import Deferred from '../util/deferred';
import { LogLevel } from '../util/logger';
import { EWampMessageID } from '../types/messages/MessageTypes';
class Caller extends AbstractProcessor {
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 = [EWampMessageID.CALL, requestId, details || {}, uri, args || [], kwArgs || {}];
this.logger.log(LogLevel.DEBUG, `Calling \`${uri}\` (request id: ${requestId}).`, args, kwArgs, details);
const executor = () => __awaiter(this, void 0, void 0, function* () {
const result = new Deferred();
this._pendingCalls.set(requestId, [result, withProgress]);
try {
yield this.sender(message);
}
catch (err) {
this.logger.log(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 = [EWampMessageID.CANCEL, requestId, { mode: killMode || '' }];
this.logger.log(LogLevel.DEBUG, `Cancelling call ${requestId}.`);
yield this.sender(msg);
});
}
//
// - Handlers.
//
onMessage(msg) {
if (msg[0] === 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(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();
callRequest.resolve({ result, next: nextCallRequest.promise });
this._pendingCalls.set(requestId, [nextCallRequest, true]);
}
else {
this.logger.log(LogLevel.DEBUG, `Received result for call ${requestId}.`, result);
callRequest.resolve(result);
this._pendingCalls.delete(requestId);
}
return true;
}
if (msg[0] === EWampMessageID.ERROR && msg[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(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();
}
}
export default Caller;
//# sourceMappingURL=caller.js.map