@bloks/link-session-manager
Advanced tools
Comparing version 0.2.615 to 0.2.616
/** | ||
* proton-link-session-manager v0.2.615 | ||
* proton-link-session-manager v0.2.616 | ||
* https://github.com/greymass/proton-link-session-manager | ||
@@ -4,0 +4,0 @@ * |
375
lib/index.js
/** | ||
* proton-link-session-manager v0.2.615 | ||
* proton-link-session-manager v0.2.616 | ||
* https://github.com/greymass/proton-link-session-manager | ||
@@ -42,3 +42,2 @@ * | ||
var eosio = require('@greymass/eosio'); | ||
var WebSocket = require('isomorphic-ws'); | ||
var uuid = require('uuid'); | ||
@@ -51,3 +50,2 @@ var signingRequest = require('@bloks/signing-request'); | ||
var WebSocket__default = /*#__PURE__*/_interopDefaultLegacy(WebSocket); | ||
var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib); | ||
@@ -110,2 +108,248 @@ | ||
var RobustWebSocket = /** @class */ (function () { | ||
function RobustWebSocket(url, userOptions) { | ||
var e_1, _a; | ||
this.attempts = 0; | ||
this.reconnects = -1; | ||
this.reconnectWhenOnlineAgain = false; | ||
this.explicitlyClosed = false; | ||
this.pendingReconnect = undefined; | ||
this.connectivityEventsAttached = false; | ||
this.binaryType = 'blob'; | ||
this.opts = { | ||
// the time to wait before a successful connection | ||
// before the attempt is considered to have timed out | ||
timeout: 4000, | ||
// Given a CloseEvent or OnlineEvent and the RobustWebSocket state, | ||
// should a reconnect be attempted? Return the number of milliseconds to wait | ||
// to reconnect (or null or undefined to not), rather than true or false | ||
shouldReconnect: function (event, ws) { | ||
if (event.code === 1008 || event.code === 1011) | ||
return; | ||
return [0, 3000, 10000][ws.attempts]; | ||
}, | ||
// Flag to control whether attachement to navigator online/offline events | ||
// should be disabled. | ||
ignoreConnectivityEvents: false, | ||
// Create and connect the WebSocket when the instance is instantiated. | ||
// Defaults to true to match standard WebSocket behavior | ||
automaticOpen: true, | ||
handle1000: false, | ||
}; | ||
this.url = url; | ||
this.opts = Object.assign({}, this.opts, typeof userOptions === 'function' ? { shouldReconnect: userOptions } : userOptions); | ||
if (typeof this.opts.timeout !== 'number') { | ||
throw new Error('timeout must be the number of milliseconds to timeout a connection attempt'); | ||
} | ||
if (typeof this.opts.shouldReconnect !== 'function') { | ||
throw new Error('shouldReconnect must be a function that returns the number of milliseconds to wait for a reconnect attempt, or null or undefined to not reconnect.'); | ||
} | ||
var _loop_1 = function (readOnlyProp) { | ||
Object.defineProperty(this_1, readOnlyProp, { | ||
get: function () { | ||
return this.realWs[readOnlyProp]; | ||
}, | ||
}); | ||
}; | ||
var this_1 = this; | ||
try { | ||
for (var _b = tslib.__values([ | ||
'bufferedAmount', | ||
'url', | ||
'readyState', | ||
'protocol', | ||
'extensions', | ||
]), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var readOnlyProp = _c.value; | ||
_loop_1(readOnlyProp); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
if (this.opts.automaticOpen) { | ||
this.newWebSocket(this.url); | ||
} | ||
} | ||
RobustWebSocket.prototype.newWebSocket = function (url) { | ||
var e_2, _a; | ||
var _this = this; | ||
// New websocket | ||
var newUrl = typeof url === 'function' ? url(this) : url; | ||
this.pendingReconnect = null; | ||
this.realWs = new WebSocket(newUrl); | ||
this.realWs.binaryType = this.binaryType; | ||
this.attempts++; | ||
this.dispatchEvent(Object.assign(new CustomEvent('connecting'), { | ||
attempts: this.attempts, | ||
reconnects: this.reconnects, | ||
})); | ||
this.connectTimeout = setTimeout(function () { | ||
_this.connectTimeout = null; | ||
_this.detachConnectivityEvents(); | ||
_this.dispatchEvent(Object.assign(new CustomEvent('timeout'), { | ||
attempts: _this.attempts, | ||
reconnects: _this.reconnects, | ||
})); | ||
}, this.opts.timeout); | ||
var _loop_2 = function (stdEvent) { | ||
this_2.realWs.addEventListener(stdEvent, function (event) { | ||
_this.dispatchEvent(event); | ||
var cb = _this['on' + stdEvent]; | ||
if (typeof cb === 'function') { | ||
// eslint-disable-next-line prefer-spread, prefer-rest-params | ||
return cb.apply(_this, arguments); | ||
} | ||
}); | ||
}; | ||
var this_2 = this; | ||
try { | ||
for (var _b = tslib.__values(['open', 'close', 'message', 'error', 'ping']), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var stdEvent = _c.value; | ||
_loop_2(stdEvent); | ||
} | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
if (!this.opts.ignoreConnectivityEvents) { | ||
this.attachConnectivityEvents(); | ||
} | ||
}; | ||
RobustWebSocket.prototype.clearPendingReconnectIfNeeded = function () { | ||
if (this.pendingReconnect) { | ||
clearTimeout(this.pendingReconnect); | ||
this.pendingReconnect = undefined; | ||
} | ||
}; | ||
RobustWebSocket.prototype.ononline = function (event) { | ||
if (this.reconnectWhenOnlineAgain) { | ||
this.clearPendingReconnectIfNeeded(); | ||
this.reconnect(event); | ||
} | ||
}; | ||
RobustWebSocket.prototype.onoffline = function () { | ||
this.reconnectWhenOnlineAgain = true; | ||
if (this.realWs) { | ||
this.realWs.close(1000); | ||
} | ||
}; | ||
RobustWebSocket.prototype.detachConnectivityEvents = function () { | ||
if (this.connectivityEventsAttached) { | ||
global.removeEventListener('online', this.ononline); | ||
global.removeEventListener('offline', this.onoffline); | ||
this.connectivityEventsAttached = false; | ||
} | ||
}; | ||
RobustWebSocket.prototype.attachConnectivityEvents = function () { | ||
if (!this.connectivityEventsAttached) { | ||
global.addEventListener('online', this.ononline); | ||
global.addEventListener('offline', this.onoffline); | ||
this.connectivityEventsAttached = true; | ||
} | ||
}; | ||
RobustWebSocket.prototype.send = function () { | ||
if (this.realWs) { | ||
// eslint-disable-next-line prefer-spread, prefer-rest-params | ||
return this.realWs.send.apply(this.realWs, arguments); | ||
} | ||
}; | ||
RobustWebSocket.prototype.close = function (code, reason) { | ||
if (typeof code !== 'number') { | ||
reason = code; | ||
code = 1000; | ||
} | ||
this.clearPendingReconnectIfNeeded(); | ||
this.reconnectWhenOnlineAgain = false; | ||
this.explicitlyClosed = true; | ||
this.detachConnectivityEvents(); | ||
if (this.realWs) { | ||
return this.realWs.close(code, reason); | ||
} | ||
}; | ||
RobustWebSocket.prototype.open = function () { | ||
if (this.realWs && | ||
this.realWs.readyState !== WebSocket.OPEN && | ||
this.realWs.readyState !== WebSocket.CONNECTING) { | ||
this.clearPendingReconnectIfNeeded(); | ||
this.reconnectWhenOnlineAgain = false; | ||
this.explicitlyClosed = false; | ||
this.newWebSocket(this.url); | ||
} | ||
}; | ||
RobustWebSocket.prototype.reconnect = function (event) { | ||
if ((!this.opts.handle1000 && event.code === 1000) || this.explicitlyClosed) { | ||
this.attempts = 0; | ||
return; | ||
} | ||
if (navigator.onLine === false) { | ||
this.reconnectWhenOnlineAgain = true; | ||
return; | ||
} | ||
var delay = this.opts.shouldReconnect(event, this); | ||
if (typeof delay === 'number') { | ||
this.pendingReconnect = setTimeout(this.newWebSocket, delay); | ||
} | ||
}; | ||
Object.defineProperty(RobustWebSocket.prototype, "listeners", { | ||
get: function () { | ||
var _this = this; | ||
return { | ||
open: [ | ||
function (event) { | ||
if (_this.connectTimeout) { | ||
clearTimeout(_this.connectTimeout); | ||
_this.connectTimeout = undefined; | ||
} | ||
event.reconnects = ++_this.reconnects; | ||
event.attempts = _this.attempts; | ||
_this.attempts = 0; | ||
_this.reconnectWhenOnlineAgain = false; | ||
}, | ||
], | ||
close: [this.reconnect], | ||
}; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
// Taken from MDN https://developer.mozilla.org/en-US/docs/Web/API/EventTarget | ||
RobustWebSocket.prototype.addEventListener = function (type, callback) { | ||
if (!(type in this.listeners)) { | ||
this.listeners[type] = []; | ||
} | ||
this.listeners[type].push(callback); | ||
}; | ||
RobustWebSocket.prototype.RremoveEventListener = function (type, callback) { | ||
if (!(type in this.listeners)) { | ||
return; | ||
} | ||
var stack = this.listeners[type]; | ||
for (var i = 0, l = stack.length; i < l; i++) { | ||
if (stack[i] === callback) { | ||
stack.splice(i, 1); | ||
return; | ||
} | ||
} | ||
}; | ||
RobustWebSocket.prototype.dispatchEvent = function (event) { | ||
if (!(event.type in this.listeners)) { | ||
return; | ||
} | ||
var stack = this.listeners[event.type]; | ||
for (var i = 0, l = stack.length; i < l; i++) { | ||
stack[i].call(this, event); | ||
} | ||
}; | ||
return RobustWebSocket; | ||
}()); | ||
var ProtonLinkSessionManagerSession = /** @class */ (function () { | ||
@@ -275,7 +519,7 @@ function ProtonLinkSessionManagerSession(network, actor, permission, publicKey, name, created, lastUsed) { | ||
var linkUrl = "wss://" + _this.storage.linkUrl + "/" + _this.storage.linkId; | ||
var socket = new WebSocket__default['default'](linkUrl); | ||
socket.onopen = function (event) { | ||
var ws = new RobustWebSocket(linkUrl); | ||
var onSocketEvent = function (type, event) { | ||
try { | ||
if (_this.handler && _this.handler.onSocketEvent) { | ||
_this.handler.onSocketEvent('onopen', event); | ||
_this.handler.onSocketEvent(type, event); | ||
} | ||
@@ -286,104 +530,22 @@ } | ||
} | ||
manager.connecting = false; | ||
manager.heartbeat(); | ||
manager.ready = true; | ||
}; | ||
ws.addEventListener('open', function (event) { | ||
onSocketEvent('onopen', event); | ||
resolve(manager.socket); | ||
}; | ||
socket.onmessage = function (message) { | ||
try { | ||
if (_this.handler && _this.handler.onSocketEvent) { | ||
_this.handler.onSocketEvent('onmessage', message); | ||
} | ||
manager.handleRequest(message.data); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}; | ||
socket.onerror = function (err) { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onerror', err); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
manager.ready = false; | ||
switch (err.code) { | ||
case 'ENOTFOUND': | ||
case 'ECONNREFUSED': { | ||
var wait = backoff(manager.retries); | ||
manager.retry = setTimeout(function () { | ||
try { | ||
manager.retries++; | ||
clearInterval(manager.pingTimeout); | ||
manager.connect(); | ||
} | ||
catch (error) { | ||
console.log('error caught', error); | ||
} | ||
}, wait); | ||
break; | ||
} | ||
default: { | ||
clearInterval(manager.pingTimeout); | ||
reject(err); | ||
break; | ||
} | ||
} | ||
}; | ||
socket.onclose = function (event) { | ||
var _this = this; | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onclose', event); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
// add variable about whether this is enabled beyond connecting | ||
manager.connecting = false; | ||
if (event.code !== 1000 && event.code !== 4001) { | ||
var wait = backoff(manager.retries); | ||
manager.retry = setTimeout(function () { return tslib.__awaiter(_this, void 0, void 0, function () { | ||
var error_1; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
manager.retries++; | ||
return [4 /*yield*/, manager.disconnect()]; | ||
case 1: | ||
_a.sent(); | ||
clearInterval(manager.pingTimeout); | ||
manager.connect(); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
error_1 = _a.sent(); | ||
console.log('error caught', error_1); | ||
return [3 /*break*/, 3]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }, wait); | ||
} | ||
}; | ||
socket.addEventListener('ping', function (event) { | ||
console.log('PING'); | ||
// Reset retries on successful ping | ||
manager.retries = 0; | ||
try { | ||
if (_this.handler && _this.handler.onSocketEvent) { | ||
_this.handler.onSocketEvent('onping', event); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
manager.heartbeat(); | ||
}); | ||
ws.addEventListener('message', function (event) { | ||
onSocketEvent('onmessage', event); | ||
manager.handleRequest(event.data); | ||
}); | ||
ws.addEventListener('error', function (event) { | ||
onSocketEvent('onerror', event); | ||
}); | ||
ws.addEventListener('close', function (event) { | ||
onSocketEvent('onclose', event); | ||
}); | ||
ws.addEventListener('ping', function (event) { | ||
onSocketEvent('onping', event); | ||
manager.socket.send('pong'); | ||
}); | ||
manager.socket = socket; | ||
manager.socket = ws; | ||
}).catch(function (error) { | ||
@@ -432,5 +594,2 @@ console.log('SessionManager connect: caught error in promise', error.message, error.code, manager.retries); | ||
}()); | ||
function backoff(n) { | ||
return Math.min(Math.pow(n * 100, 2) / 1000, 5000); | ||
} | ||
@@ -437,0 +596,0 @@ exports.LinkCreate = LinkCreate; |
/** | ||
* proton-link-session-manager v0.2.615 | ||
* proton-link-session-manager v0.2.616 | ||
* https://github.com/greymass/proton-link-session-manager | ||
@@ -38,3 +38,2 @@ * | ||
import { Struct, Checksum256, Name, PublicKey, Checksum512, Serializer, Bytes, PrivateKey } from '@greymass/eosio'; | ||
import WebSocket from 'isomorphic-ws'; | ||
import { v4 } from 'uuid'; | ||
@@ -85,2 +84,211 @@ import { SigningRequest } from '@bloks/signing-request'; | ||
class RobustWebSocket { | ||
constructor(url, userOptions) { | ||
this.attempts = 0; | ||
this.reconnects = -1; | ||
this.reconnectWhenOnlineAgain = false; | ||
this.explicitlyClosed = false; | ||
this.pendingReconnect = undefined; | ||
this.connectivityEventsAttached = false; | ||
this.binaryType = 'blob'; | ||
this.opts = { | ||
// the time to wait before a successful connection | ||
// before the attempt is considered to have timed out | ||
timeout: 4000, | ||
// Given a CloseEvent or OnlineEvent and the RobustWebSocket state, | ||
// should a reconnect be attempted? Return the number of milliseconds to wait | ||
// to reconnect (or null or undefined to not), rather than true or false | ||
shouldReconnect: function (event, ws) { | ||
if (event.code === 1008 || event.code === 1011) | ||
return; | ||
return [0, 3000, 10000][ws.attempts]; | ||
}, | ||
// Flag to control whether attachement to navigator online/offline events | ||
// should be disabled. | ||
ignoreConnectivityEvents: false, | ||
// Create and connect the WebSocket when the instance is instantiated. | ||
// Defaults to true to match standard WebSocket behavior | ||
automaticOpen: true, | ||
handle1000: false, | ||
}; | ||
this.url = url; | ||
this.opts = Object.assign({}, this.opts, typeof userOptions === 'function' ? { shouldReconnect: userOptions } : userOptions); | ||
if (typeof this.opts.timeout !== 'number') { | ||
throw new Error('timeout must be the number of milliseconds to timeout a connection attempt'); | ||
} | ||
if (typeof this.opts.shouldReconnect !== 'function') { | ||
throw new Error('shouldReconnect must be a function that returns the number of milliseconds to wait for a reconnect attempt, or null or undefined to not reconnect.'); | ||
} | ||
for (const readOnlyProp of [ | ||
'bufferedAmount', | ||
'url', | ||
'readyState', | ||
'protocol', | ||
'extensions', | ||
]) { | ||
Object.defineProperty(this, readOnlyProp, { | ||
get: function () { | ||
return this.realWs[readOnlyProp]; | ||
}, | ||
}); | ||
} | ||
if (this.opts.automaticOpen) { | ||
this.newWebSocket(this.url); | ||
} | ||
} | ||
newWebSocket(url) { | ||
// New websocket | ||
const newUrl = typeof url === 'function' ? url(this) : url; | ||
this.pendingReconnect = null; | ||
this.realWs = new WebSocket(newUrl); | ||
this.realWs.binaryType = this.binaryType; | ||
this.attempts++; | ||
this.dispatchEvent(Object.assign(new CustomEvent('connecting'), { | ||
attempts: this.attempts, | ||
reconnects: this.reconnects, | ||
})); | ||
this.connectTimeout = setTimeout(() => { | ||
this.connectTimeout = null; | ||
this.detachConnectivityEvents(); | ||
this.dispatchEvent(Object.assign(new CustomEvent('timeout'), { | ||
attempts: this.attempts, | ||
reconnects: this.reconnects, | ||
})); | ||
}, this.opts.timeout); | ||
for (const stdEvent of ['open', 'close', 'message', 'error', 'ping']) { | ||
this.realWs.addEventListener(stdEvent, (event) => { | ||
this.dispatchEvent(event); | ||
const cb = this['on' + stdEvent]; | ||
if (typeof cb === 'function') { | ||
// eslint-disable-next-line prefer-spread, prefer-rest-params | ||
return cb.apply(this, arguments); | ||
} | ||
}); | ||
} | ||
if (!this.opts.ignoreConnectivityEvents) { | ||
this.attachConnectivityEvents(); | ||
} | ||
} | ||
clearPendingReconnectIfNeeded() { | ||
if (this.pendingReconnect) { | ||
clearTimeout(this.pendingReconnect); | ||
this.pendingReconnect = undefined; | ||
} | ||
} | ||
ononline(event) { | ||
if (this.reconnectWhenOnlineAgain) { | ||
this.clearPendingReconnectIfNeeded(); | ||
this.reconnect(event); | ||
} | ||
} | ||
onoffline() { | ||
this.reconnectWhenOnlineAgain = true; | ||
if (this.realWs) { | ||
this.realWs.close(1000); | ||
} | ||
} | ||
detachConnectivityEvents() { | ||
if (this.connectivityEventsAttached) { | ||
global.removeEventListener('online', this.ononline); | ||
global.removeEventListener('offline', this.onoffline); | ||
this.connectivityEventsAttached = false; | ||
} | ||
} | ||
attachConnectivityEvents() { | ||
if (!this.connectivityEventsAttached) { | ||
global.addEventListener('online', this.ononline); | ||
global.addEventListener('offline', this.onoffline); | ||
this.connectivityEventsAttached = true; | ||
} | ||
} | ||
send() { | ||
if (this.realWs) { | ||
// eslint-disable-next-line prefer-spread, prefer-rest-params | ||
return this.realWs.send.apply(this.realWs, arguments); | ||
} | ||
} | ||
close(code, reason) { | ||
if (typeof code !== 'number') { | ||
reason = code; | ||
code = 1000; | ||
} | ||
this.clearPendingReconnectIfNeeded(); | ||
this.reconnectWhenOnlineAgain = false; | ||
this.explicitlyClosed = true; | ||
this.detachConnectivityEvents(); | ||
if (this.realWs) { | ||
return this.realWs.close(code, reason); | ||
} | ||
} | ||
open() { | ||
if (this.realWs && | ||
this.realWs.readyState !== WebSocket.OPEN && | ||
this.realWs.readyState !== WebSocket.CONNECTING) { | ||
this.clearPendingReconnectIfNeeded(); | ||
this.reconnectWhenOnlineAgain = false; | ||
this.explicitlyClosed = false; | ||
this.newWebSocket(this.url); | ||
} | ||
} | ||
reconnect(event) { | ||
if ((!this.opts.handle1000 && event.code === 1000) || this.explicitlyClosed) { | ||
this.attempts = 0; | ||
return; | ||
} | ||
if (navigator.onLine === false) { | ||
this.reconnectWhenOnlineAgain = true; | ||
return; | ||
} | ||
const delay = this.opts.shouldReconnect(event, this); | ||
if (typeof delay === 'number') { | ||
this.pendingReconnect = setTimeout(this.newWebSocket, delay); | ||
} | ||
} | ||
get listeners() { | ||
return { | ||
open: [ | ||
(event) => { | ||
if (this.connectTimeout) { | ||
clearTimeout(this.connectTimeout); | ||
this.connectTimeout = undefined; | ||
} | ||
event.reconnects = ++this.reconnects; | ||
event.attempts = this.attempts; | ||
this.attempts = 0; | ||
this.reconnectWhenOnlineAgain = false; | ||
}, | ||
], | ||
close: [this.reconnect], | ||
}; | ||
} | ||
// Taken from MDN https://developer.mozilla.org/en-US/docs/Web/API/EventTarget | ||
addEventListener(type, callback) { | ||
if (!(type in this.listeners)) { | ||
this.listeners[type] = []; | ||
} | ||
this.listeners[type].push(callback); | ||
} | ||
RremoveEventListener(type, callback) { | ||
if (!(type in this.listeners)) { | ||
return; | ||
} | ||
const stack = this.listeners[type]; | ||
for (let i = 0, l = stack.length; i < l; i++) { | ||
if (stack[i] === callback) { | ||
stack.splice(i, 1); | ||
return; | ||
} | ||
} | ||
} | ||
dispatchEvent(event) { | ||
if (!(event.type in this.listeners)) { | ||
return; | ||
} | ||
const stack = this.listeners[event.type]; | ||
for (let i = 0, l = stack.length; i < l; i++) { | ||
stack[i].call(this, event); | ||
} | ||
} | ||
} | ||
class ProtonLinkSessionManagerSession { | ||
@@ -236,7 +444,7 @@ constructor(network, actor, permission, publicKey, name, created, lastUsed) { | ||
const linkUrl = `wss://${this.storage.linkUrl}/${this.storage.linkId}`; | ||
const socket = new WebSocket(linkUrl); | ||
socket.onopen = (event) => { | ||
const ws = new RobustWebSocket(linkUrl); | ||
const onSocketEvent = (type, event) => { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onopen', event); | ||
this.handler.onSocketEvent(type, event); | ||
} | ||
@@ -247,93 +455,22 @@ } | ||
} | ||
manager.connecting = false; | ||
manager.heartbeat(); | ||
manager.ready = true; | ||
}; | ||
ws.addEventListener('open', (event) => { | ||
onSocketEvent('onopen', event); | ||
resolve(manager.socket); | ||
}; | ||
socket.onmessage = (message) => { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onmessage', message); | ||
} | ||
manager.handleRequest(message.data); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}; | ||
socket.onerror = function (err) { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onerror', err); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
manager.ready = false; | ||
switch (err.code) { | ||
case 'ENOTFOUND': | ||
case 'ECONNREFUSED': { | ||
const wait = backoff(manager.retries); | ||
manager.retry = setTimeout(() => { | ||
try { | ||
manager.retries++; | ||
clearInterval(manager.pingTimeout); | ||
manager.connect(); | ||
} | ||
catch (error) { | ||
console.log('error caught', error); | ||
} | ||
}, wait); | ||
break; | ||
} | ||
default: { | ||
clearInterval(manager.pingTimeout); | ||
reject(err); | ||
break; | ||
} | ||
} | ||
}; | ||
socket.onclose = function (event) { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onclose', event); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
// add variable about whether this is enabled beyond connecting | ||
manager.connecting = false; | ||
if (event.code !== 1000 && event.code !== 4001) { | ||
const wait = backoff(manager.retries); | ||
manager.retry = setTimeout(async () => { | ||
try { | ||
manager.retries++; | ||
await manager.disconnect(); | ||
clearInterval(manager.pingTimeout); | ||
manager.connect(); | ||
} | ||
catch (error) { | ||
console.log('error caught', error); | ||
} | ||
}, wait); | ||
} | ||
}; | ||
socket.addEventListener('ping', (event) => { | ||
console.log('PING'); | ||
// Reset retries on successful ping | ||
manager.retries = 0; | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onping', event); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
manager.heartbeat(); | ||
}); | ||
ws.addEventListener('message', (event) => { | ||
onSocketEvent('onmessage', event); | ||
manager.handleRequest(event.data); | ||
}); | ||
ws.addEventListener('error', (event) => { | ||
onSocketEvent('onerror', event); | ||
}); | ||
ws.addEventListener('close', (event) => { | ||
onSocketEvent('onclose', event); | ||
}); | ||
ws.addEventListener('ping', (event) => { | ||
onSocketEvent('onping', event); | ||
manager.socket.send('pong'); | ||
}); | ||
manager.socket = socket; | ||
manager.socket = ws; | ||
}).catch((error) => { | ||
@@ -371,7 +508,4 @@ console.log('SessionManager connect: caught error in promise', error.message, error.code, manager.retries); | ||
} | ||
function backoff(n) { | ||
return Math.min(Math.pow(n * 100, 2) / 1000, 5000); | ||
} | ||
export { LinkCreate, LinkInfo, ProtonLinkSessionManager, ProtonLinkSessionManagerSession, ProtonLinkSessionManagerStorage, SealedMessage, unsealMessage }; | ||
//# sourceMappingURL=index.m.js.map |
{ | ||
"name": "@bloks/link-session-manager", | ||
"description": "Session management for signature providers when receiving requests using the Anchor Link protocol", | ||
"version": "0.2.615", | ||
"version": "0.2.616", | ||
"homepage": "https://github.com/greymass/proton-link-session-manager", | ||
@@ -6,0 +6,0 @@ "license": "BSD-3-Clause", |
import WebSocket from 'isomorphic-ws' | ||
import RobustWebSocket from './websocket' | ||
import { | ||
@@ -110,7 +111,8 @@ Bytes, | ||
const linkUrl = `wss://${this.storage.linkUrl}/${this.storage.linkId}` | ||
const socket = new WebSocket(linkUrl) | ||
socket.onopen = (event) => { | ||
const ws = new RobustWebSocket(linkUrl) | ||
const onSocketEvent = (type: string, event: any) => { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onopen', event) | ||
this.handler.onSocketEvent(type, event) | ||
} | ||
@@ -120,87 +122,28 @@ } catch (e) { | ||
} | ||
manager.connecting = false | ||
manager.heartbeat() | ||
manager.ready = true | ||
} | ||
ws.addEventListener('open', (event) => { | ||
onSocketEvent('onopen', event) | ||
resolve(manager.socket) | ||
} | ||
socket.onmessage = (message: any) => { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onmessage', message) | ||
} | ||
manager.handleRequest(message.data) | ||
} catch (e) { | ||
reject(e) | ||
} | ||
} | ||
socket.onerror = function (err) { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onerror', err) | ||
} | ||
} catch (e) { | ||
reject(e) | ||
} | ||
manager.ready = false | ||
switch (err.code) { | ||
case 'ENOTFOUND': | ||
case 'ECONNREFUSED': { | ||
const wait = backoff(manager.retries) | ||
manager.retry = setTimeout(() => { | ||
try { | ||
manager.retries++ | ||
clearInterval(manager.pingTimeout) | ||
manager.connect() | ||
} catch (error) { | ||
console.log('error caught', error) | ||
} | ||
}, wait) | ||
break | ||
} | ||
default: { | ||
clearInterval(manager.pingTimeout) | ||
reject(err) | ||
break | ||
} | ||
} | ||
} | ||
socket.onclose = function (event) { | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onclose', event) | ||
} | ||
} catch (e) { | ||
reject(e) | ||
} | ||
// add variable about whether this is enabled beyond connecting | ||
manager.connecting = false | ||
if (event.code !== 1000 && event.code !== 4001) { | ||
const wait = backoff(manager.retries) | ||
manager.retry = setTimeout(async () => { | ||
try { | ||
manager.retries++ | ||
await manager.disconnect() | ||
clearInterval(manager.pingTimeout) | ||
manager.connect() | ||
} catch (error) { | ||
console.log('error caught', error) | ||
} | ||
}, wait) | ||
} | ||
} | ||
socket.addEventListener('ping', (event) => { | ||
console.log('PING') | ||
// Reset retries on successful ping | ||
manager.retries = 0 | ||
try { | ||
if (this.handler && this.handler.onSocketEvent) { | ||
this.handler.onSocketEvent('onping', event) | ||
} | ||
} catch (e) { | ||
reject(e) | ||
} | ||
manager.heartbeat() | ||
}) | ||
ws.addEventListener('message', (event) => { | ||
onSocketEvent('onmessage', event) | ||
manager.handleRequest(event.data) | ||
}) | ||
ws.addEventListener('error', (event) => { | ||
onSocketEvent('onerror', event) | ||
}) | ||
ws.addEventListener('close', (event) => { | ||
onSocketEvent('onclose', event) | ||
}) | ||
ws.addEventListener('ping', (event) => { | ||
onSocketEvent('onping', event) | ||
manager.socket.send('pong') | ||
}) | ||
manager.socket = socket | ||
manager.socket = ws | ||
}).catch((error) => { | ||
@@ -207,0 +150,0 @@ console.log( |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
104376
14
1795