landstrasse
Version:
Strongly typed WAMP Client for browsers
161 lines • 6.97 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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const logger_1 = require("../../../util/logger");
const WampError_1 = require("../../../error/WampError");
const SerializationError_1 = require("../../../error/SerializationError");
const deferred_1 = require("../../../util/deferred");
const MessageTypes_1 = require("../../../types/messages/MessageTypes");
class Call {
constructor(handler, args, kwArgs, details, callId, sender, violator, logger) {
Object.defineProperty(this, "callId", {
enumerable: true,
configurable: true,
writable: true,
value: callId
});
Object.defineProperty(this, "sender", {
enumerable: true,
configurable: true,
writable: true,
value: sender
});
Object.defineProperty(this, "violator", {
enumerable: true,
configurable: true,
writable: true,
value: violator
});
Object.defineProperty(this, "logger", {
enumerable: true,
configurable: true,
writable: true,
value: logger
});
Object.defineProperty(this, "progress", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "cancelled", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "_cancelledDeferred", {
enumerable: true,
configurable: true,
writable: true,
value: new deferred_1.default()
});
args = args || [];
kwArgs = kwArgs || {};
details = details || {};
details.onCancel = this._cancelledDeferred.promise;
this.progress = details && !!details.receive_progress;
// We want to actively catch rejected cancel promises.
// Rejecting this cancel promise means, that the call wasn't canceled
// and completed, so dropping any error is fine here.
this._cancelledDeferred.promise.catch(() => { });
const handle = () => {
handler(args, kwArgs, details)
.then((res) => this.onHandlerResult(res), (err) => this.onHandlerError(err))
.catch((e) => this.violator(`Failed to send: ${e}`));
};
setTimeout(handle, 0);
}
cancel() {
if (this.cancelled) {
return;
}
this.cancelled = true;
this._cancelledDeferred.resolve();
}
//
// - Handlers.
//
onHandlerResult(response) {
return __awaiter(this, void 0, void 0, function* () {
let _response;
if (typeof response !== 'object' || response === null || !('result' in response)) {
_response = { result: response };
}
else {
_response = response;
}
const { result, next } = _response;
const isFinished = !next;
if (isFinished || this.progress) {
const message = [
MessageTypes_1.EWampMessageID.YIELD,
this.callId,
{ progress: !!_response.next && this.progress },
];
if (typeof result === 'object' && result !== null && ('args' in result || 'kwargs' in result)) {
const { args, kwargs } = result;
const isValidArgs = !args || Array.isArray(args);
const isValidKwargs = !kwargs || typeof kwargs === 'object';
if (!isValidArgs || !isValidKwargs) {
this.logger.log(logger_1.LogLevel.WARNING, `Invalid result for call id "${this.callId}", sending error.`, [isValidArgs, args], [isValidKwargs, kwargs]);
return this.onHandlerError(new WampError_1.default('wamp.error.runtime_error'));
}
const hasKwargs = kwargs && Object.keys(kwargs).length;
if (args.length || hasKwargs) {
message.push(args);
if (hasKwargs) {
message.push(kwargs);
}
}
}
else {
message.push([result]);
}
try {
yield this.sender(this.callId, message, isFinished);
}
catch (err) {
if (err instanceof SerializationError_1.default) {
this.logger.log(logger_1.LogLevel.WARNING, `Serialization for call id "${this.callId}" failed, sending error.`);
yield this.onHandlerError(new WampError_1.default('wamp.error.serialization-error'));
}
}
this.logger.log(logger_1.LogLevel.DEBUG, `Call id "${this.callId}", sending yield.`);
}
if (next) {
next
.then((_response) => this.onHandlerResult(_response), (error) => this.onHandlerError(error))
.catch((e) => this.violator(`Failed to send: ${e}`));
}
});
}
onHandlerError(err) {
return __awaiter(this, void 0, void 0, function* () {
let wampError = null;
if (typeof err === 'string' || err instanceof String) {
wampError = new WampError_1.default(err);
}
else if (err instanceof WampError_1.default) {
wampError = err;
}
else {
this.logger.log(logger_1.LogLevel.WARNING, 'A runtime error occurred.', err);
wampError = new WampError_1.default('wamp.error.runtime_error', [err]);
}
const errorMessage = wampError.toErrorMessage(this.callId);
this.logger.log(logger_1.LogLevel.DEBUG, `Call id "${this.callId}", sending error "${wampError.errorUri}".`);
yield this.sender(this.callId, errorMessage, true);
});
}
}
exports.default = Call;
//# sourceMappingURL=call.js.map