UNPKG

proteus-js-client

Version:

Proteus JavaScript Client

297 lines (236 loc) 10 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _rsocketTypes = require('rsocket-types'); var _rsocketFlowable = require('rsocket-flowable'); var _rsocketCore = require('rsocket-core'); var _rsocketRpcCore = require('rsocket-rpc-core'); var _invariant = require('fbjs/lib/invariant'); var _invariant2 = _interopRequireDefault(_invariant); var _rsocket = require('./rsocket'); var _frames = require('./frames'); var _rsocketWebsocketClient = require('rsocket-websocket-client'); var _rsocketWebsocketClient2 = _interopRequireDefault(_rsocketWebsocketClient); var _ConnectionId = require('./frames/ConnectionId'); var _ConnectionId2 = _interopRequireDefault(_ConnectionId); var _AdditionalFlags = require('./frames/AdditionalFlags'); var _AdditionalFlags2 = _interopRequireDefault(_AdditionalFlags); var _v = require('uuid/v4'); var _v2 = _interopRequireDefault(_v); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Copyright (c) 2017-present, Netifi Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ 'use-strict'; var Proteus = function () { function Proteus(group, tags, proteusClient, requestHandler) { var _this = this; _classCallCheck(this, Proteus); this._client = proteusClient; this._group = group; this._tags = tags; this._connect = function () { if (_this._connection) { return _rsocketFlowable.Single.of(_this._connection); } else if (_this._connecting) { return new _rsocketFlowable.Single(function (subscriber) { _this._connecting.subscribe(subscriber); }); } else { /** * This is a useful Publisher implementation that wraps could feasibly wrap the Single type ** */ /** * Might be useful to clean up and contribute back or put in a utility or something ** */ _this._connecting = function () { var _subscribers = []; var _connection = void 0; var _error = void 0; var _completed = false; return { onComplete: function onComplete(connection) { // Memoize for future subscribers _completed = true; _connection = connection; _subscribers.map(function (subscriber) { if (subscriber.onComplete) { subscriber.onComplete(connection); } }); }, onError: function onError(error) { _completed = true; _error = error; _subscribers.map(function (subscriber) { if (subscriber.onError) { subscriber.onError(error); } }); }, onSubscribe: function onSubscribe(cancel) { _subscribers.map(function (subscriber) { if (subscriber.onSubscribe) { subscriber.onSubscribe(cancel); } }); }, subscribe: function subscribe(subscriber) { if (_completed) { subscriber.onSubscribe(); subscriber.onComplete(_connection); } else if (_error) { subscriber.onSubscribe(); subscriber.onError(_error); } else { _subscribers.push(subscriber); if (subscriber.onSubscribe) { subscriber.onSubscribe(function () { var idx = _subscribers.indexOf(subscriber); if (idx > -1) { _subscribers.splice(idx, 1); } }); } } } }; }(); _this._connecting.subscribe({ onComplete: function onComplete(connection) { _this._connection = connection; }, onError: function onError(err) { console.warn('An error has occurred while connecting:'); console.warn(err); }, onSubscribe: function onSubscribe(cancel) { // do nothing } }); setTimeout(function () { return proteusClient.connect().subscribe(_this._connecting); }, _this.calculateRetryDuration()); return _this._connecting; } }; this._requestHandler = requestHandler; } Proteus.prototype.myGroup = function myGroup() { return this._group; }; Proteus.prototype.myTags = function myTags() { return this._tags; }; Proteus.prototype.broadcast = function broadcast(group, tags) { return _rsocket.DeferredConnectingRSocket.broadcast(group, tags, this._connect); }; Proteus.prototype.group = function (_group) { function group(_x, _x2) { return _group.apply(this, arguments); } group.toString = function () { return _group.toString(); }; return group; }(function (group, tags) { return _rsocket.DeferredConnectingRSocket.group(group, tags, this._connect); }); Proteus.prototype.destination = function (_destination) { function destination(_x3, _x4) { return _destination.apply(this, arguments); } destination.toString = function () { return _destination.toString(); }; return destination; }(function (destination, group) { return _rsocket.DeferredConnectingRSocket.group(group, { 'com.netifi.destination': destination }, this._connect); }); Proteus.prototype.addService = function addService(service, handler) { this._requestHandler.addService(service, handler); }; Proteus.prototype.close = function close() { this._client.close(); }; Proteus.prototype.calculateRetryDuration = function calculateRetryDuration() { var currentTs = Date.now(); var oldTs = this._lastConnectionAttemptTs || 0; var calculatedDuration = Math.min(this._attempts, 30); if (currentTs - oldTs > 60000) { this._attempts = 0; } this._lastConnectionAttemptTs = currentTs; this._attempts++; return calculatedDuration * 1000; }; Proteus.create = function create(config) { (0, _invariant2.default)(config && config.setup && config.setup.accessKey && config.setup.accessToken && config.transport, 'Proteus: Falsey config is invalid. At minimum transport config, group, access key, and access token are required.'); (0, _invariant2.default)(config.transport.connection || config.transport.url, 'Proteus: Transport config must supply a connection or a URL'); // default to GUID-y destination ID var destination = config.setup.destination !== undefined ? config.setup.destination : (0, _v2.default)(); var tags = config.setup.tags !== undefined ? _extends({ 'com.netifi.destination': destination }, config.setup.tags) : { 'com.netifi.destination': destination }; var keepAlive = config.setup.keepAlive !== undefined ? config.setup.keepAlive : 60000; /* 60s in ms */ var lifetime = config.setup.lifetime !== undefined ? config.setup.lifetime : 360000; /* 360s in ms */ var accessKey = config.setup.accessKey; var accessToken = Buffer.from(config.setup.accessToken, 'base64'); /* If a connectionId is not provided, seed it */ var connectionIdSeed = typeof config.setup.connectionId !== 'undefined' ? config.setup.connectionId : Date.now().toString(); var connectionId = new _ConnectionId2.default(connectionIdSeed); var additionalFlagsLiteral = _extends({ public: false }, config.setup.additionalFlags); var additionalFlags = new _AdditionalFlags2.default(additionalFlagsLiteral); var transport = config.transport.connection !== undefined ? config.transport.connection : new _rsocketWebsocketClient2.default({ url: config.transport.url ? config.transport.url : 'ws://', wsCreator: config.transport.wsCreator }, _rsocketCore.BufferEncoders); var requestHandler = new _rsocketRpcCore.RequestHandlingRSocket(); var responder = new _rsocket.UnwrappingRSocket(requestHandler); var metadata = (0, _frames.encodeFrame)({ type: _frames.FrameTypes.DESTINATION_SETUP, majorVersion: null, minorVersion: null, group: config.setup.group, tags: tags, accessKey: accessKey, accessToken: accessToken, connectionId: connectionId, additionalFlags: additionalFlags }); var finalConfig = { setup: { keepAlive: keepAlive, lifetime: lifetime, metadata: metadata, connectionId: connectionId, additionalFlags: additionalFlags }, transport: transport, responder: responder }; if (config.responder !== undefined) { finalConfig.responder = config.responder; } if (config.serializers !== undefined) { finalConfig.serializers = config.serializers; } var client = new _rsocketRpcCore.RpcClient(finalConfig); return new Proteus(config.setup.group, tags, client, requestHandler); }; return Proteus; }(); exports.default = Proteus;