landstrasse
Version:
Strongly typed WAMP Client for browsers
183 lines • 8.06 kB
JavaScript
"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 registration_1 = require("./generic/registration");
const call_1 = require("./generic/call");
const logger_1 = require("../../util/logger");
const map_1 = require("../../util/map");
const MessageTypes_1 = require("../../types/messages/MessageTypes");
class Callee extends AbstractProcessor_1.default {
constructor() {
super(...arguments);
Object.defineProperty(this, "_registrations", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "_runningCalls", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "_registrationRequests", {
enumerable: true,
configurable: true,
writable: true,
value: new map_1.default(MessageTypes_1.EWampMessageID.REGISTER, MessageTypes_1.EWampMessageID.REGISTERED)
});
Object.defineProperty(this, "_unregistrationsRequests", {
enumerable: true,
configurable: true,
writable: true,
value: new map_1.default(MessageTypes_1.EWampMessageID.UNREGISTER, MessageTypes_1.EWampMessageID.UNREGISTERED, ([, , details]) => {
if (!details) {
return [false, 'Invalid unregistration (missing registration details).'];
}
const id = details.registration;
const registration = this._registrations.get(id);
if (!registration) {
return [false, `Unexpected unregistration (unknown registration id ${id}).`];
}
this._registrations.delete(id);
registration.unregisteredDeferred.resolve();
return [true, ''];
})
});
}
static getFeatures() {
return {
callee: {
progressive_call_results: true,
call_timeout: true,
call_canceling: true,
caller_identification: true,
call_trustlevels: true,
pattern_based_registration: true,
sharded_registration: true,
shared_registration: true,
},
};
}
register(uri, handler, options) {
return __awaiter(this, void 0, void 0, function* () {
if (this._closed) {
return Promise.reject('Callee closed.');
}
const requestId = this.idGenerators.session.id();
const message = [MessageTypes_1.EWampMessageID.REGISTER, requestId, options || {}, uri];
const request = this._registrationRequests.add(requestId);
this.logger.log(logger_1.LogLevel.DEBUG, `Registering \`${uri}\` (request id: ${requestId}).`, options);
try {
yield this.sender(message);
}
catch (err) {
this._registrationRequests.reject(requestId, err);
throw err;
}
const [, , registrationId] = yield request;
const registration = new registration_1.default(registrationId, uri, handler, (registration) => __awaiter(this, void 0, void 0, function* () { return yield this.unregister(registration); }));
this._registrations.set(registrationId, registration);
return registration;
});
}
unregister(registration) {
return __awaiter(this, void 0, void 0, function* () {
if (this._closed) {
throw new Error('Callee closed.');
}
const requestId = this.idGenerators.session.id();
const message = [MessageTypes_1.EWampMessageID.UNREGISTER, requestId, registration.id];
const request = this._unregistrationsRequests.add(requestId);
try {
try {
yield this.sender(message);
}
catch (err) {
this._unregistrationsRequests.reject(requestId, err);
throw err;
}
yield request;
this._registrations.delete(registration.id);
registration.unregisteredDeferred.resolve();
}
catch (e) {
registration.unregisteredDeferred.reject(e);
}
});
}
//
// - Handlers.
//
onMessage(msg) {
const handled = [this._registrationRequests, this._unregistrationsRequests].some((pendingRequests) => {
const [handled, success, error] = pendingRequests.handle(msg);
if (handled && !success) {
this.violator(error);
}
return handled;
});
if (handled) {
return true;
}
if (msg[0] === MessageTypes_1.EWampMessageID.INVOCATION) {
const [, requestId, registrationId, details, args, kwArgs] = msg;
const registration = this._registrations.get(registrationId);
if (!registration) {
this.violator('Unexpected invocation (unable to find the related registration).');
return true;
}
this.logger.log(logger_1.LogLevel.DEBUG, `Call received for registration \`${registration.uri}\` (request id: ${requestId}).`, args, kwArgs, details);
const actualDetails = Object.assign({}, (details || {}));
if (!actualDetails.procedure) {
actualDetails.procedure = registration.uri;
}
const call = new call_1.default(registration.handler, args || [], kwArgs || {}, details || {}, requestId, (cid, msgToSend, finished) => __awaiter(this, void 0, void 0, function* () {
if (finished) {
this._runningCalls.delete(cid);
}
if (!this._closed) {
yield this.sender(msgToSend);
}
}), this.violator, this.logger);
this._runningCalls.set(requestId, call);
return true;
}
if (msg[0] === MessageTypes_1.EWampMessageID.INTERRUPT) {
const callId = msg[1];
const call = this._runningCalls.get(callId);
if (!call) {
this.violator('Unexpected interrupt (unable to find the related invocation).');
return true;
}
this.logger.log(logger_1.LogLevel.DEBUG, `Received cancellation request for invocation (invocation id: ${callId}).`);
call.cancel();
return true;
}
return false;
}
onClose() {
this._registrationRequests.close();
this._unregistrationsRequests.close();
// - Running invocations.
this._runningCalls.forEach((pendingCall) => { pendingCall.cancel(); });
this._runningCalls.clear();
// - Registrations.
this._registrations.forEach((registration) => {
registration.unregisteredDeferred.reject(new Error('closing'));
});
this._registrations.clear();
}
}
exports.default = Callee;
//# sourceMappingURL=index.js.map