@toruslabs/broadcast-channel
Advanced tools
Comparing version 5.0.2 to 6.0.0
@@ -8,3 +8,2 @@ "use strict"; | ||
}); | ||
exports.addStorageEventListener = addStorageEventListener; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -15,2 +14,3 @@ exports.canBeUsed = canBeUsed; | ||
exports["default"] = void 0; | ||
exports.getSocketInstance = getSocketInstance; | ||
exports.keccak256 = keccak256; | ||
@@ -21,2 +21,3 @@ exports.microSeconds = void 0; | ||
exports.removeStorageEventListener = removeStorageEventListener; | ||
exports.setupSocketConnection = setupSocketConnection; | ||
exports.storageKey = storageKey; | ||
@@ -61,3 +62,3 @@ exports.type = void 0; | ||
exports.type = type; | ||
var SOCKET_CONN_INSTANCES = {}; | ||
var SOCKET_CONN_INSTANCE = null; | ||
@@ -75,12 +76,11 @@ function storageKey(channelName) { | ||
return new Promise(function (res, rej) { | ||
(0, _util.sleep)().then( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() { | ||
var key, channelEncPrivKey, encData, socketConn, _setMessage, currentAttempts, waitingInterval; | ||
return _regenerator["default"].wrap(function _callee3$(_context3) { | ||
(0, _util.sleep)().then( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { | ||
var key, channelEncPrivKey, encData; | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
key = storageKey(channelState.channelName); | ||
channelEncPrivKey = keccak256(key); | ||
_context3.next = 4; | ||
_context.next = 4; | ||
return (0, _metadataHelpers.encryptData)(channelEncPrivKey.toString('hex'), { | ||
@@ -94,98 +94,35 @@ token: (0, _util.randomToken)(), | ||
case 4: | ||
encData = _context3.sent; | ||
socketConn = SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
encData = _context.sent; | ||
_context.t0 = fetch; | ||
_context.t1 = channelState.serverUrl + '/channel/set'; | ||
_context.t2 = JSON; | ||
_context.t3 = (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex'); | ||
_context.t4 = encData; | ||
_context.next = 12; | ||
return (0, _eccrypto.sign)(channelEncPrivKey, keccak256(encData)); | ||
_setMessage = /*#__PURE__*/function () { | ||
var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.t0 = fetch; | ||
_context.t1 = channelState.serverUrl + '/channel/set'; | ||
_context.t2 = JSON; | ||
_context.t3 = (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex'); | ||
_context.t4 = encData; | ||
_context.next = 7; | ||
return (0, _eccrypto.sign)(channelEncPrivKey, keccak256(encData)); | ||
case 12: | ||
_context.t5 = _context.sent.toString('hex'); | ||
_context.t6 = { | ||
key: _context.t3, | ||
data: _context.t4, | ||
signature: _context.t5 | ||
}; | ||
_context.t7 = _context.t2.stringify.call(_context.t2, _context.t6); | ||
_context.t8 = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
}; | ||
_context.t9 = { | ||
method: 'POST', | ||
body: _context.t7, | ||
headers: _context.t8 | ||
}; | ||
return _context.abrupt("return", (0, _context.t0)(_context.t1, _context.t9).then(res)["catch"](rej)); | ||
case 7: | ||
_context.t5 = _context.sent.toString('hex'); | ||
_context.t6 = { | ||
key: _context.t3, | ||
data: _context.t4, | ||
signature: _context.t5 | ||
}; | ||
_context.t7 = _context.t2.stringify.call(_context.t2, _context.t6); | ||
_context.t8 = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
}; | ||
_context.t9 = { | ||
method: 'POST', | ||
body: _context.t7, | ||
headers: _context.t8 | ||
}; | ||
return _context.abrupt("return", (0, _context.t0)(_context.t1, _context.t9).then(res)["catch"](rej)); | ||
case 13: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return function _setMessage() { | ||
return _ref2.apply(this, arguments); | ||
}; | ||
}(); | ||
if (!(socketConn && socketConn.connected)) { | ||
_context3.next = 9; | ||
break; | ||
} | ||
return _context3.abrupt("return", _setMessage()); | ||
case 9: | ||
currentAttempts = 0; | ||
waitingInterval = window.setInterval( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { | ||
return _regenerator["default"].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (!(currentAttempts >= 5)) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
window.clearInterval(waitingInterval); | ||
return _context2.abrupt("return", rej(new Error('Could not post message after 5 attempts to socket channel'))); | ||
case 3: | ||
if (!(socketConn && socketConn.connected)) { | ||
_context2.next = 8; | ||
break; | ||
} | ||
window.clearInterval(waitingInterval); | ||
return _context2.abrupt("return", _setMessage()); | ||
case 8: | ||
currentAttempts++; | ||
case 9: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
})), 500); | ||
case 11: | ||
case 18: | ||
case "end": | ||
return _context3.stop(); | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee3); | ||
}, _callee); | ||
}))); | ||
@@ -195,5 +132,7 @@ }); | ||
function addStorageEventListener(channelName, serverUrl, fn) { | ||
var key = storageKey(channelName); | ||
var channelEncPrivKey = keccak256(key); | ||
function getSocketInstance(serverUrl) { | ||
if (SOCKET_CONN_INSTANCE) { | ||
return SOCKET_CONN_INSTANCE; | ||
} | ||
var SOCKET_CONN = (0, _socket.io)(serverUrl, { | ||
@@ -206,6 +145,67 @@ transports: ['websocket', 'polling'], | ||
}); | ||
SOCKET_CONN.on('connect_error', function (err) { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
_util.log.error('connect error', err); | ||
}); | ||
SOCKET_CONN.on('connect', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { | ||
var engine; | ||
return _regenerator["default"].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
engine = SOCKET_CONN.io.engine; | ||
_util.log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
engine.once('upgrade', function () { | ||
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket) | ||
_util.log.debug('upgraded', engine.transport.name); // in most cases, prints "websocket" | ||
}); | ||
engine.once('close', function (reason) { | ||
// called when the underlying connection is closed | ||
_util.log.debug('connection closed', reason); | ||
}); | ||
case 4: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
}))); | ||
SOCKET_CONN.on('error', function (err) { | ||
_util.log.error('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.on('disconnect', function () { | ||
_util.log.debug('socket disconnected'); | ||
}); | ||
SOCKET_CONN_INSTANCE = SOCKET_CONN; | ||
return SOCKET_CONN; | ||
} | ||
function setupSocketConnection(serverUrl, channelName, fn) { | ||
var socketConn = getSocketInstance(serverUrl); | ||
var key = storageKey(channelName); | ||
var channelEncPrivKey = keccak256(key); | ||
var channelPubKey = (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex'); | ||
if (socketConn.connected) { | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
} else { | ||
socketConn.once('connect', function () { | ||
_util.log.debug('connected with socket'); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
}); | ||
} | ||
var visibilityListener = function visibilityListener() { | ||
// if channel is closed, then remove the listener. | ||
if (!SOCKET_CONN_INSTANCES[channelName]) { | ||
if (!socketConn) { | ||
document.removeEventListener('visibilitychange', visibilityListener); | ||
@@ -216,16 +216,16 @@ return; | ||
if (!SOCKET_CONN.connected && document.visibilityState === 'visible') { | ||
SOCKET_CONN.once('connect', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4() { | ||
return _regenerator["default"].wrap(function _callee4$(_context4) { | ||
if (!socketConn.connected && document.visibilityState === 'visible') { | ||
socketConn.once('connect', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() { | ||
return _regenerator["default"].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
SOCKET_CONN.emit('check_auth_status', (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex')); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
case 1: | ||
case "end": | ||
return _context4.stop(); | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee4); | ||
}, _callee3); | ||
}))); | ||
@@ -236,90 +236,49 @@ } | ||
var listener = /*#__PURE__*/function () { | ||
var _ref5 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(ev) { | ||
var _ref4 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(ev) { | ||
var decData; | ||
return _regenerator["default"].wrap(function _callee5$(_context5) { | ||
return _regenerator["default"].wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
_context5.prev = 0; | ||
_context5.next = 3; | ||
_context4.prev = 0; | ||
_context4.next = 3; | ||
return (0, _metadataHelpers.decryptData)(channelEncPrivKey.toString('hex'), ev); | ||
case 3: | ||
decData = _context5.sent; | ||
decData = _context4.sent; | ||
_util.log.info(decData); | ||
fn(decData); | ||
_context5.next = 10; | ||
_context4.next = 11; | ||
break; | ||
case 7: | ||
_context5.prev = 7; | ||
_context5.t0 = _context5["catch"](0); | ||
case 8: | ||
_context4.prev = 8; | ||
_context4.t0 = _context4["catch"](0); | ||
_util.log.error(_context5.t0); | ||
_util.log.error(_context4.t0); | ||
case 10: | ||
case 11: | ||
case "end": | ||
return _context5.stop(); | ||
return _context4.stop(); | ||
} | ||
} | ||
}, _callee5, null, [[0, 7]]); | ||
}, _callee4, null, [[0, 8]]); | ||
})); | ||
return function listener(_x) { | ||
return _ref5.apply(this, arguments); | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}(); | ||
SOCKET_CONN.on('connect_error', function () { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
}); | ||
SOCKET_CONN.on('connect', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6() { | ||
var engine; | ||
return _regenerator["default"].wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_util.log.debug('connected with socket'); | ||
SOCKET_CONN.emit('check_auth_status', (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex')); | ||
engine = SOCKET_CONN.io.engine; | ||
_util.log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
engine.once('upgrade', function () { | ||
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket) | ||
_util.log.debug('upgraded', engine.transport.name); // in most cases, prints "websocket" | ||
}); | ||
engine.on('close', function (reason) { | ||
// called when the underlying connection is closed | ||
_util.log.debug('connection closed', reason); | ||
}); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
} | ||
}, _callee6); | ||
}))); | ||
SOCKET_CONN.on('error', function (err) { | ||
_util.log.debug('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.once('disconnect', function () { | ||
_util.log.debug('socket disconnected'); | ||
if (SOCKET_CONN_INSTANCES[channelName]) visibilityListener(); | ||
}); | ||
SOCKET_CONN.on('success', listener); | ||
socketConn.on(channelPubKey + "_success", listener); | ||
document.addEventListener('visibilitychange', visibilityListener); | ||
SOCKET_CONN_INSTANCES[channelName] = SOCKET_CONN; | ||
return listener; | ||
return socketConn; | ||
} | ||
function removeStorageEventListener(channelState) { | ||
if (SOCKET_CONN_INSTANCES[channelState.channelName]) SOCKET_CONN_INSTANCES[channelState.channelName].disconnect(); | ||
function removeStorageEventListener() { | ||
if (SOCKET_CONN_INSTANCE) { | ||
SOCKET_CONN_INSTANCE.disconnect(); | ||
} | ||
} | ||
@@ -349,11 +308,11 @@ | ||
}; | ||
state.listener = addStorageEventListener(channelName, options.server.url, function (msgObj) { | ||
setupSocketConnection(options.server.url, channelName, function (msgObj) { | ||
if (!state.messagesCallback) return; // no listener | ||
if (msgObj.uuid === uuid) return; // own message | ||
if (msgObj.uuid === state.uuid) return; // own message | ||
if (!msgObj.token || eMIs.has(msgObj.token)) return; // already emitted | ||
if (!msgObj.token || state.eMIs.has(msgObj.token)) return; // already emitted | ||
// if (msgObj.data.time && msgObj.data.time < state.messagesCallbackTime) return; // too old | ||
eMIs.add(msgObj.token); | ||
state.eMIs.add(msgObj.token); | ||
state.messagesCallback(msgObj.data); | ||
@@ -364,9 +323,8 @@ }); | ||
function close(channelState) { | ||
// give 2 sec for all msgs which are in transit to be consumed | ||
function close() {// give 2 sec for all msgs which are in transit to be consumed | ||
// by receiver. | ||
window.setTimeout(function () { | ||
removeStorageEventListener(channelState); | ||
delete SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
}, 1000); | ||
// window.setTimeout(() => { | ||
// removeStorageEventListener(channelState); | ||
// SOCKET_CONN_INSTANCE = null; | ||
// }, 1000); | ||
} | ||
@@ -373,0 +331,0 @@ |
@@ -26,3 +26,3 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; | ||
export var type = 'server'; | ||
var SOCKET_CONN_INSTANCES = {}; | ||
var SOCKET_CONN_INSTANCE = null; | ||
export function storageKey(channelName) { | ||
@@ -38,12 +38,11 @@ return KEY_PREFIX + channelName; | ||
return new Promise(function (res, rej) { | ||
sleep().then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() { | ||
var key, channelEncPrivKey, encData, socketConn, _setMessage, currentAttempts, waitingInterval; | ||
return _regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
sleep().then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { | ||
var key, channelEncPrivKey, encData; | ||
return _regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
key = storageKey(channelState.channelName); | ||
channelEncPrivKey = keccak256(key); | ||
_context3.next = 4; | ||
_context.next = 4; | ||
return encryptData(channelEncPrivKey.toString('hex'), { | ||
@@ -57,104 +56,43 @@ token: randomToken(), | ||
case 4: | ||
encData = _context3.sent; | ||
socketConn = SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
encData = _context.sent; | ||
_context.t0 = fetch; | ||
_context.t1 = channelState.serverUrl + '/channel/set'; | ||
_context.t2 = JSON; | ||
_context.t3 = getPublic(channelEncPrivKey).toString('hex'); | ||
_context.t4 = encData; | ||
_context.next = 12; | ||
return sign(channelEncPrivKey, keccak256(encData)); | ||
_setMessage = /*#__PURE__*/function () { | ||
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { | ||
return _regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.t0 = fetch; | ||
_context.t1 = channelState.serverUrl + '/channel/set'; | ||
_context.t2 = JSON; | ||
_context.t3 = getPublic(channelEncPrivKey).toString('hex'); | ||
_context.t4 = encData; | ||
_context.next = 7; | ||
return sign(channelEncPrivKey, keccak256(encData)); | ||
case 12: | ||
_context.t5 = _context.sent.toString('hex'); | ||
_context.t6 = { | ||
key: _context.t3, | ||
data: _context.t4, | ||
signature: _context.t5 | ||
}; | ||
_context.t7 = _context.t2.stringify.call(_context.t2, _context.t6); | ||
_context.t8 = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
}; | ||
_context.t9 = { | ||
method: 'POST', | ||
body: _context.t7, | ||
headers: _context.t8 | ||
}; | ||
return _context.abrupt("return", (0, _context.t0)(_context.t1, _context.t9).then(res)["catch"](rej)); | ||
case 7: | ||
_context.t5 = _context.sent.toString('hex'); | ||
_context.t6 = { | ||
key: _context.t3, | ||
data: _context.t4, | ||
signature: _context.t5 | ||
}; | ||
_context.t7 = _context.t2.stringify.call(_context.t2, _context.t6); | ||
_context.t8 = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
}; | ||
_context.t9 = { | ||
method: 'POST', | ||
body: _context.t7, | ||
headers: _context.t8 | ||
}; | ||
return _context.abrupt("return", (0, _context.t0)(_context.t1, _context.t9).then(res)["catch"](rej)); | ||
case 13: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return function _setMessage() { | ||
return _ref2.apply(this, arguments); | ||
}; | ||
}(); | ||
if (!(socketConn && socketConn.connected)) { | ||
_context3.next = 9; | ||
break; | ||
} | ||
return _context3.abrupt("return", _setMessage()); | ||
case 9: | ||
currentAttempts = 0; | ||
waitingInterval = window.setInterval( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { | ||
return _regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (!(currentAttempts >= 5)) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
window.clearInterval(waitingInterval); | ||
return _context2.abrupt("return", rej(new Error('Could not post message after 5 attempts to socket channel'))); | ||
case 3: | ||
if (!(socketConn && socketConn.connected)) { | ||
_context2.next = 8; | ||
break; | ||
} | ||
window.clearInterval(waitingInterval); | ||
return _context2.abrupt("return", _setMessage()); | ||
case 8: | ||
currentAttempts++; | ||
case 9: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
})), 500); | ||
case 11: | ||
case 18: | ||
case "end": | ||
return _context3.stop(); | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee3); | ||
}, _callee); | ||
}))); | ||
}); | ||
} | ||
export function addStorageEventListener(channelName, serverUrl, fn) { | ||
var key = storageKey(channelName); | ||
var channelEncPrivKey = keccak256(key); | ||
export function getSocketInstance(serverUrl) { | ||
if (SOCKET_CONN_INSTANCE) { | ||
return SOCKET_CONN_INSTANCE; | ||
} | ||
var SOCKET_CONN = io(serverUrl, { | ||
@@ -167,6 +105,60 @@ transports: ['websocket', 'polling'], | ||
}); | ||
SOCKET_CONN.on('connect_error', function (err) { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
log.error('connect error', err); | ||
}); | ||
SOCKET_CONN.on('connect', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { | ||
var engine; | ||
return _regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
engine = SOCKET_CONN.io.engine; | ||
log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
engine.once('upgrade', function () { | ||
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket) | ||
log.debug('upgraded', engine.transport.name); // in most cases, prints "websocket" | ||
}); | ||
engine.once('close', function (reason) { | ||
// called when the underlying connection is closed | ||
log.debug('connection closed', reason); | ||
}); | ||
case 4: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
}))); | ||
SOCKET_CONN.on('error', function (err) { | ||
log.error('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.on('disconnect', function () { | ||
log.debug('socket disconnected'); | ||
}); | ||
SOCKET_CONN_INSTANCE = SOCKET_CONN; | ||
return SOCKET_CONN; | ||
} | ||
export function setupSocketConnection(serverUrl, channelName, fn) { | ||
var socketConn = getSocketInstance(serverUrl); | ||
var key = storageKey(channelName); | ||
var channelEncPrivKey = keccak256(key); | ||
var channelPubKey = getPublic(channelEncPrivKey).toString('hex'); | ||
if (socketConn.connected) { | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
} else { | ||
socketConn.once('connect', function () { | ||
log.debug('connected with socket'); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
}); | ||
} | ||
var visibilityListener = function visibilityListener() { | ||
// if channel is closed, then remove the listener. | ||
if (!SOCKET_CONN_INSTANCES[channelName]) { | ||
if (!socketConn) { | ||
document.removeEventListener('visibilitychange', visibilityListener); | ||
@@ -177,16 +169,16 @@ return; | ||
if (!SOCKET_CONN.connected && document.visibilityState === 'visible') { | ||
SOCKET_CONN.once('connect', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() { | ||
return _regeneratorRuntime.wrap(function _callee4$(_context4) { | ||
if (!socketConn.connected && document.visibilityState === 'visible') { | ||
socketConn.once('connect', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() { | ||
return _regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
SOCKET_CONN.emit('check_auth_status', getPublic(channelEncPrivKey).toString('hex')); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
case 1: | ||
case "end": | ||
return _context4.stop(); | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee4); | ||
}, _callee3); | ||
}))); | ||
@@ -197,82 +189,45 @@ } | ||
var listener = /*#__PURE__*/function () { | ||
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(ev) { | ||
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(ev) { | ||
var decData; | ||
return _regeneratorRuntime.wrap(function _callee5$(_context5) { | ||
return _regeneratorRuntime.wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
_context5.prev = 0; | ||
_context5.next = 3; | ||
_context4.prev = 0; | ||
_context4.next = 3; | ||
return decryptData(channelEncPrivKey.toString('hex'), ev); | ||
case 3: | ||
decData = _context5.sent; | ||
decData = _context4.sent; | ||
log.info(decData); | ||
fn(decData); | ||
_context5.next = 10; | ||
_context4.next = 11; | ||
break; | ||
case 7: | ||
_context5.prev = 7; | ||
_context5.t0 = _context5["catch"](0); | ||
log.error(_context5.t0); | ||
case 8: | ||
_context4.prev = 8; | ||
_context4.t0 = _context4["catch"](0); | ||
log.error(_context4.t0); | ||
case 10: | ||
case 11: | ||
case "end": | ||
return _context5.stop(); | ||
return _context4.stop(); | ||
} | ||
} | ||
}, _callee5, null, [[0, 7]]); | ||
}, _callee4, null, [[0, 8]]); | ||
})); | ||
return function listener(_x) { | ||
return _ref5.apply(this, arguments); | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}(); | ||
SOCKET_CONN.on('connect_error', function () { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
}); | ||
SOCKET_CONN.on('connect', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() { | ||
var engine; | ||
return _regeneratorRuntime.wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
log.debug('connected with socket'); | ||
SOCKET_CONN.emit('check_auth_status', getPublic(channelEncPrivKey).toString('hex')); | ||
engine = SOCKET_CONN.io.engine; | ||
log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
engine.once('upgrade', function () { | ||
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket) | ||
log.debug('upgraded', engine.transport.name); // in most cases, prints "websocket" | ||
}); | ||
engine.on('close', function (reason) { | ||
// called when the underlying connection is closed | ||
log.debug('connection closed', reason); | ||
}); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
} | ||
}, _callee6); | ||
}))); | ||
SOCKET_CONN.on('error', function (err) { | ||
log.debug('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.once('disconnect', function () { | ||
log.debug('socket disconnected'); | ||
if (SOCKET_CONN_INSTANCES[channelName]) visibilityListener(); | ||
}); | ||
SOCKET_CONN.on('success', listener); | ||
socketConn.on(channelPubKey + "_success", listener); | ||
document.addEventListener('visibilitychange', visibilityListener); | ||
SOCKET_CONN_INSTANCES[channelName] = SOCKET_CONN; | ||
return listener; | ||
return socketConn; | ||
} | ||
export function removeStorageEventListener(channelState) { | ||
if (SOCKET_CONN_INSTANCES[channelState.channelName]) SOCKET_CONN_INSTANCES[channelState.channelName].disconnect(); | ||
export function removeStorageEventListener() { | ||
if (SOCKET_CONN_INSTANCE) { | ||
SOCKET_CONN_INSTANCE.disconnect(); | ||
} | ||
} | ||
@@ -301,11 +256,11 @@ export function create(channelName, options) { | ||
}; | ||
state.listener = addStorageEventListener(channelName, options.server.url, function (msgObj) { | ||
setupSocketConnection(options.server.url, channelName, function (msgObj) { | ||
if (!state.messagesCallback) return; // no listener | ||
if (msgObj.uuid === uuid) return; // own message | ||
if (msgObj.uuid === state.uuid) return; // own message | ||
if (!msgObj.token || eMIs.has(msgObj.token)) return; // already emitted | ||
if (!msgObj.token || state.eMIs.has(msgObj.token)) return; // already emitted | ||
// if (msgObj.data.time && msgObj.data.time < state.messagesCallbackTime) return; // too old | ||
eMIs.add(msgObj.token); | ||
state.eMIs.add(msgObj.token); | ||
state.messagesCallback(msgObj.data); | ||
@@ -315,9 +270,8 @@ }); | ||
} | ||
export function close(channelState) { | ||
// give 2 sec for all msgs which are in transit to be consumed | ||
export function close() {// give 2 sec for all msgs which are in transit to be consumed | ||
// by receiver. | ||
window.setTimeout(function () { | ||
removeStorageEventListener(channelState); | ||
delete SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
}, 1000); | ||
// window.setTimeout(() => { | ||
// removeStorageEventListener(channelState); | ||
// SOCKET_CONN_INSTANCE = null; | ||
// }, 1000); | ||
} | ||
@@ -324,0 +278,0 @@ export function onMessage(channelState, fn, time) { |
@@ -26,3 +26,3 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; | ||
export var type = 'server'; | ||
var SOCKET_CONN_INSTANCES = {}; | ||
var SOCKET_CONN_INSTANCE = null; | ||
export function storageKey(channelName) { | ||
@@ -38,12 +38,11 @@ return KEY_PREFIX + channelName; | ||
return new Promise(function (res, rej) { | ||
sleep().then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() { | ||
var key, channelEncPrivKey, encData, socketConn, _setMessage, currentAttempts, waitingInterval; | ||
return _regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
sleep().then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { | ||
var key, channelEncPrivKey, encData; | ||
return _regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
key = storageKey(channelState.channelName); | ||
channelEncPrivKey = keccak256(key); | ||
_context3.next = 4; | ||
_context.next = 4; | ||
return encryptData(channelEncPrivKey.toString('hex'), { | ||
@@ -57,104 +56,43 @@ token: randomToken(), | ||
case 4: | ||
encData = _context3.sent; | ||
socketConn = SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
encData = _context.sent; | ||
_context.t0 = fetch; | ||
_context.t1 = channelState.serverUrl + '/channel/set'; | ||
_context.t2 = JSON; | ||
_context.t3 = getPublic(channelEncPrivKey).toString('hex'); | ||
_context.t4 = encData; | ||
_context.next = 12; | ||
return sign(channelEncPrivKey, keccak256(encData)); | ||
_setMessage = /*#__PURE__*/function () { | ||
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { | ||
return _regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.t0 = fetch; | ||
_context.t1 = channelState.serverUrl + '/channel/set'; | ||
_context.t2 = JSON; | ||
_context.t3 = getPublic(channelEncPrivKey).toString('hex'); | ||
_context.t4 = encData; | ||
_context.next = 7; | ||
return sign(channelEncPrivKey, keccak256(encData)); | ||
case 12: | ||
_context.t5 = _context.sent.toString('hex'); | ||
_context.t6 = { | ||
key: _context.t3, | ||
data: _context.t4, | ||
signature: _context.t5 | ||
}; | ||
_context.t7 = _context.t2.stringify.call(_context.t2, _context.t6); | ||
_context.t8 = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
}; | ||
_context.t9 = { | ||
method: 'POST', | ||
body: _context.t7, | ||
headers: _context.t8 | ||
}; | ||
return _context.abrupt("return", (0, _context.t0)(_context.t1, _context.t9).then(res)["catch"](rej)); | ||
case 7: | ||
_context.t5 = _context.sent.toString('hex'); | ||
_context.t6 = { | ||
key: _context.t3, | ||
data: _context.t4, | ||
signature: _context.t5 | ||
}; | ||
_context.t7 = _context.t2.stringify.call(_context.t2, _context.t6); | ||
_context.t8 = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
}; | ||
_context.t9 = { | ||
method: 'POST', | ||
body: _context.t7, | ||
headers: _context.t8 | ||
}; | ||
return _context.abrupt("return", (0, _context.t0)(_context.t1, _context.t9).then(res)["catch"](rej)); | ||
case 13: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return function _setMessage() { | ||
return _ref2.apply(this, arguments); | ||
}; | ||
}(); | ||
if (!(socketConn && socketConn.connected)) { | ||
_context3.next = 9; | ||
break; | ||
} | ||
return _context3.abrupt("return", _setMessage()); | ||
case 9: | ||
currentAttempts = 0; | ||
waitingInterval = window.setInterval( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { | ||
return _regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (!(currentAttempts >= 5)) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
window.clearInterval(waitingInterval); | ||
return _context2.abrupt("return", rej(new Error('Could not post message after 5 attempts to socket channel'))); | ||
case 3: | ||
if (!(socketConn && socketConn.connected)) { | ||
_context2.next = 8; | ||
break; | ||
} | ||
window.clearInterval(waitingInterval); | ||
return _context2.abrupt("return", _setMessage()); | ||
case 8: | ||
currentAttempts++; | ||
case 9: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
})), 500); | ||
case 11: | ||
case 18: | ||
case "end": | ||
return _context3.stop(); | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee3); | ||
}, _callee); | ||
}))); | ||
}); | ||
} | ||
export function addStorageEventListener(channelName, serverUrl, fn) { | ||
var key = storageKey(channelName); | ||
var channelEncPrivKey = keccak256(key); | ||
export function getSocketInstance(serverUrl) { | ||
if (SOCKET_CONN_INSTANCE) { | ||
return SOCKET_CONN_INSTANCE; | ||
} | ||
var SOCKET_CONN = io(serverUrl, { | ||
@@ -167,6 +105,60 @@ transports: ['websocket', 'polling'], | ||
}); | ||
SOCKET_CONN.on('connect_error', function (err) { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
log.error('connect error', err); | ||
}); | ||
SOCKET_CONN.on('connect', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { | ||
var engine; | ||
return _regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
engine = SOCKET_CONN.io.engine; | ||
log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
engine.once('upgrade', function () { | ||
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket) | ||
log.debug('upgraded', engine.transport.name); // in most cases, prints "websocket" | ||
}); | ||
engine.once('close', function (reason) { | ||
// called when the underlying connection is closed | ||
log.debug('connection closed', reason); | ||
}); | ||
case 4: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
}))); | ||
SOCKET_CONN.on('error', function (err) { | ||
log.error('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.on('disconnect', function () { | ||
log.debug('socket disconnected'); | ||
}); | ||
SOCKET_CONN_INSTANCE = SOCKET_CONN; | ||
return SOCKET_CONN; | ||
} | ||
export function setupSocketConnection(serverUrl, channelName, fn) { | ||
var socketConn = getSocketInstance(serverUrl); | ||
var key = storageKey(channelName); | ||
var channelEncPrivKey = keccak256(key); | ||
var channelPubKey = getPublic(channelEncPrivKey).toString('hex'); | ||
if (socketConn.connected) { | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
} else { | ||
socketConn.once('connect', function () { | ||
log.debug('connected with socket'); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
}); | ||
} | ||
var visibilityListener = function visibilityListener() { | ||
// if channel is closed, then remove the listener. | ||
if (!SOCKET_CONN_INSTANCES[channelName]) { | ||
if (!socketConn) { | ||
document.removeEventListener('visibilitychange', visibilityListener); | ||
@@ -177,16 +169,16 @@ return; | ||
if (!SOCKET_CONN.connected && document.visibilityState === 'visible') { | ||
SOCKET_CONN.once('connect', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() { | ||
return _regeneratorRuntime.wrap(function _callee4$(_context4) { | ||
if (!socketConn.connected && document.visibilityState === 'visible') { | ||
socketConn.once('connect', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() { | ||
return _regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
SOCKET_CONN.emit('check_auth_status', getPublic(channelEncPrivKey).toString('hex')); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
case 1: | ||
case "end": | ||
return _context4.stop(); | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee4); | ||
}, _callee3); | ||
}))); | ||
@@ -197,82 +189,45 @@ } | ||
var listener = /*#__PURE__*/function () { | ||
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(ev) { | ||
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(ev) { | ||
var decData; | ||
return _regeneratorRuntime.wrap(function _callee5$(_context5) { | ||
return _regeneratorRuntime.wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
_context5.prev = 0; | ||
_context5.next = 3; | ||
_context4.prev = 0; | ||
_context4.next = 3; | ||
return decryptData(channelEncPrivKey.toString('hex'), ev); | ||
case 3: | ||
decData = _context5.sent; | ||
decData = _context4.sent; | ||
log.info(decData); | ||
fn(decData); | ||
_context5.next = 10; | ||
_context4.next = 11; | ||
break; | ||
case 7: | ||
_context5.prev = 7; | ||
_context5.t0 = _context5["catch"](0); | ||
log.error(_context5.t0); | ||
case 8: | ||
_context4.prev = 8; | ||
_context4.t0 = _context4["catch"](0); | ||
log.error(_context4.t0); | ||
case 10: | ||
case 11: | ||
case "end": | ||
return _context5.stop(); | ||
return _context4.stop(); | ||
} | ||
} | ||
}, _callee5, null, [[0, 7]]); | ||
}, _callee4, null, [[0, 8]]); | ||
})); | ||
return function listener(_x) { | ||
return _ref5.apply(this, arguments); | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}(); | ||
SOCKET_CONN.on('connect_error', function () { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
}); | ||
SOCKET_CONN.on('connect', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() { | ||
var engine; | ||
return _regeneratorRuntime.wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
log.debug('connected with socket'); | ||
SOCKET_CONN.emit('check_auth_status', getPublic(channelEncPrivKey).toString('hex')); | ||
engine = SOCKET_CONN.io.engine; | ||
log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
engine.once('upgrade', function () { | ||
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket) | ||
log.debug('upgraded', engine.transport.name); // in most cases, prints "websocket" | ||
}); | ||
engine.on('close', function (reason) { | ||
// called when the underlying connection is closed | ||
log.debug('connection closed', reason); | ||
}); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
} | ||
}, _callee6); | ||
}))); | ||
SOCKET_CONN.on('error', function (err) { | ||
log.debug('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.once('disconnect', function () { | ||
log.debug('socket disconnected'); | ||
if (SOCKET_CONN_INSTANCES[channelName]) visibilityListener(); | ||
}); | ||
SOCKET_CONN.on('success', listener); | ||
socketConn.on(channelPubKey + "_success", listener); | ||
document.addEventListener('visibilitychange', visibilityListener); | ||
SOCKET_CONN_INSTANCES[channelName] = SOCKET_CONN; | ||
return listener; | ||
return socketConn; | ||
} | ||
export function removeStorageEventListener(channelState) { | ||
if (SOCKET_CONN_INSTANCES[channelState.channelName]) SOCKET_CONN_INSTANCES[channelState.channelName].disconnect(); | ||
export function removeStorageEventListener() { | ||
if (SOCKET_CONN_INSTANCE) { | ||
SOCKET_CONN_INSTANCE.disconnect(); | ||
} | ||
} | ||
@@ -301,11 +256,11 @@ export function create(channelName, options) { | ||
}; | ||
state.listener = addStorageEventListener(channelName, options.server.url, function (msgObj) { | ||
setupSocketConnection(options.server.url, channelName, function (msgObj) { | ||
if (!state.messagesCallback) return; // no listener | ||
if (msgObj.uuid === uuid) return; // own message | ||
if (msgObj.uuid === state.uuid) return; // own message | ||
if (!msgObj.token || eMIs.has(msgObj.token)) return; // already emitted | ||
if (!msgObj.token || state.eMIs.has(msgObj.token)) return; // already emitted | ||
// if (msgObj.data.time && msgObj.data.time < state.messagesCallbackTime) return; // too old | ||
eMIs.add(msgObj.token); | ||
state.eMIs.add(msgObj.token); | ||
state.messagesCallback(msgObj.data); | ||
@@ -315,9 +270,8 @@ }); | ||
} | ||
export function close(channelState) { | ||
// give 2 sec for all msgs which are in transit to be consumed | ||
export function close() {// give 2 sec for all msgs which are in transit to be consumed | ||
// by receiver. | ||
window.setTimeout(function () { | ||
removeStorageEventListener(channelState); | ||
delete SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
}, 1000); | ||
// window.setTimeout(() => { | ||
// removeStorageEventListener(channelState); | ||
// SOCKET_CONN_INSTANCE = null; | ||
// }, 1000); | ||
} | ||
@@ -324,0 +278,0 @@ export function onMessage(channelState, fn, time) { |
@@ -8,3 +8,2 @@ "use strict"; | ||
}); | ||
exports.addStorageEventListener = addStorageEventListener; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -15,2 +14,3 @@ exports.canBeUsed = canBeUsed; | ||
exports["default"] = void 0; | ||
exports.getSocketInstance = getSocketInstance; | ||
exports.keccak256 = keccak256; | ||
@@ -21,2 +21,3 @@ exports.microSeconds = void 0; | ||
exports.removeStorageEventListener = removeStorageEventListener; | ||
exports.setupSocketConnection = setupSocketConnection; | ||
exports.storageKey = storageKey; | ||
@@ -61,3 +62,3 @@ exports.type = void 0; | ||
exports.type = type; | ||
var SOCKET_CONN_INSTANCES = {}; | ||
var SOCKET_CONN_INSTANCE = null; | ||
@@ -75,12 +76,11 @@ function storageKey(channelName) { | ||
return new Promise(function (res, rej) { | ||
(0, _util.sleep)().then( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() { | ||
var key, channelEncPrivKey, encData, socketConn, _setMessage, currentAttempts, waitingInterval; | ||
return _regenerator["default"].wrap(function _callee3$(_context3) { | ||
(0, _util.sleep)().then( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { | ||
var key, channelEncPrivKey, encData; | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
key = storageKey(channelState.channelName); | ||
channelEncPrivKey = keccak256(key); | ||
_context3.next = 4; | ||
_context.next = 4; | ||
return (0, _metadataHelpers.encryptData)(channelEncPrivKey.toString('hex'), { | ||
@@ -94,98 +94,35 @@ token: (0, _util.randomToken)(), | ||
case 4: | ||
encData = _context3.sent; | ||
socketConn = SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
encData = _context.sent; | ||
_context.t0 = fetch; | ||
_context.t1 = channelState.serverUrl + '/channel/set'; | ||
_context.t2 = JSON; | ||
_context.t3 = (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex'); | ||
_context.t4 = encData; | ||
_context.next = 12; | ||
return (0, _eccrypto.sign)(channelEncPrivKey, keccak256(encData)); | ||
_setMessage = /*#__PURE__*/function () { | ||
var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.t0 = fetch; | ||
_context.t1 = channelState.serverUrl + '/channel/set'; | ||
_context.t2 = JSON; | ||
_context.t3 = (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex'); | ||
_context.t4 = encData; | ||
_context.next = 7; | ||
return (0, _eccrypto.sign)(channelEncPrivKey, keccak256(encData)); | ||
case 12: | ||
_context.t5 = _context.sent.toString('hex'); | ||
_context.t6 = { | ||
key: _context.t3, | ||
data: _context.t4, | ||
signature: _context.t5 | ||
}; | ||
_context.t7 = _context.t2.stringify.call(_context.t2, _context.t6); | ||
_context.t8 = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
}; | ||
_context.t9 = { | ||
method: 'POST', | ||
body: _context.t7, | ||
headers: _context.t8 | ||
}; | ||
return _context.abrupt("return", (0, _context.t0)(_context.t1, _context.t9).then(res)["catch"](rej)); | ||
case 7: | ||
_context.t5 = _context.sent.toString('hex'); | ||
_context.t6 = { | ||
key: _context.t3, | ||
data: _context.t4, | ||
signature: _context.t5 | ||
}; | ||
_context.t7 = _context.t2.stringify.call(_context.t2, _context.t6); | ||
_context.t8 = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
}; | ||
_context.t9 = { | ||
method: 'POST', | ||
body: _context.t7, | ||
headers: _context.t8 | ||
}; | ||
return _context.abrupt("return", (0, _context.t0)(_context.t1, _context.t9).then(res)["catch"](rej)); | ||
case 13: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return function _setMessage() { | ||
return _ref2.apply(this, arguments); | ||
}; | ||
}(); | ||
if (!(socketConn && socketConn.connected)) { | ||
_context3.next = 9; | ||
break; | ||
} | ||
return _context3.abrupt("return", _setMessage()); | ||
case 9: | ||
currentAttempts = 0; | ||
waitingInterval = window.setInterval( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { | ||
return _regenerator["default"].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (!(currentAttempts >= 5)) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
window.clearInterval(waitingInterval); | ||
return _context2.abrupt("return", rej(new Error('Could not post message after 5 attempts to socket channel'))); | ||
case 3: | ||
if (!(socketConn && socketConn.connected)) { | ||
_context2.next = 8; | ||
break; | ||
} | ||
window.clearInterval(waitingInterval); | ||
return _context2.abrupt("return", _setMessage()); | ||
case 8: | ||
currentAttempts++; | ||
case 9: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
})), 500); | ||
case 11: | ||
case 18: | ||
case "end": | ||
return _context3.stop(); | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee3); | ||
}, _callee); | ||
}))); | ||
@@ -195,5 +132,7 @@ }); | ||
function addStorageEventListener(channelName, serverUrl, fn) { | ||
var key = storageKey(channelName); | ||
var channelEncPrivKey = keccak256(key); | ||
function getSocketInstance(serverUrl) { | ||
if (SOCKET_CONN_INSTANCE) { | ||
return SOCKET_CONN_INSTANCE; | ||
} | ||
var SOCKET_CONN = (0, _socket.io)(serverUrl, { | ||
@@ -206,6 +145,67 @@ transports: ['websocket', 'polling'], | ||
}); | ||
SOCKET_CONN.on('connect_error', function (err) { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
_util.log.error('connect error', err); | ||
}); | ||
SOCKET_CONN.on('connect', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { | ||
var engine; | ||
return _regenerator["default"].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
engine = SOCKET_CONN.io.engine; | ||
_util.log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
engine.once('upgrade', function () { | ||
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket) | ||
_util.log.debug('upgraded', engine.transport.name); // in most cases, prints "websocket" | ||
}); | ||
engine.once('close', function (reason) { | ||
// called when the underlying connection is closed | ||
_util.log.debug('connection closed', reason); | ||
}); | ||
case 4: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
}))); | ||
SOCKET_CONN.on('error', function (err) { | ||
_util.log.error('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.on('disconnect', function () { | ||
_util.log.debug('socket disconnected'); | ||
}); | ||
SOCKET_CONN_INSTANCE = SOCKET_CONN; | ||
return SOCKET_CONN; | ||
} | ||
function setupSocketConnection(serverUrl, channelName, fn) { | ||
var socketConn = getSocketInstance(serverUrl); | ||
var key = storageKey(channelName); | ||
var channelEncPrivKey = keccak256(key); | ||
var channelPubKey = (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex'); | ||
if (socketConn.connected) { | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
} else { | ||
socketConn.once('connect', function () { | ||
_util.log.debug('connected with socket'); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
}); | ||
} | ||
var visibilityListener = function visibilityListener() { | ||
// if channel is closed, then remove the listener. | ||
if (!SOCKET_CONN_INSTANCES[channelName]) { | ||
if (!socketConn) { | ||
document.removeEventListener('visibilitychange', visibilityListener); | ||
@@ -216,16 +216,16 @@ return; | ||
if (!SOCKET_CONN.connected && document.visibilityState === 'visible') { | ||
SOCKET_CONN.once('connect', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4() { | ||
return _regenerator["default"].wrap(function _callee4$(_context4) { | ||
if (!socketConn.connected && document.visibilityState === 'visible') { | ||
socketConn.once('connect', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() { | ||
return _regenerator["default"].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
SOCKET_CONN.emit('check_auth_status', (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex')); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
case 1: | ||
case "end": | ||
return _context4.stop(); | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee4); | ||
}, _callee3); | ||
}))); | ||
@@ -236,90 +236,49 @@ } | ||
var listener = /*#__PURE__*/function () { | ||
var _ref5 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(ev) { | ||
var _ref4 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(ev) { | ||
var decData; | ||
return _regenerator["default"].wrap(function _callee5$(_context5) { | ||
return _regenerator["default"].wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
_context5.prev = 0; | ||
_context5.next = 3; | ||
_context4.prev = 0; | ||
_context4.next = 3; | ||
return (0, _metadataHelpers.decryptData)(channelEncPrivKey.toString('hex'), ev); | ||
case 3: | ||
decData = _context5.sent; | ||
decData = _context4.sent; | ||
_util.log.info(decData); | ||
fn(decData); | ||
_context5.next = 10; | ||
_context4.next = 11; | ||
break; | ||
case 7: | ||
_context5.prev = 7; | ||
_context5.t0 = _context5["catch"](0); | ||
case 8: | ||
_context4.prev = 8; | ||
_context4.t0 = _context4["catch"](0); | ||
_util.log.error(_context5.t0); | ||
_util.log.error(_context4.t0); | ||
case 10: | ||
case 11: | ||
case "end": | ||
return _context5.stop(); | ||
return _context4.stop(); | ||
} | ||
} | ||
}, _callee5, null, [[0, 7]]); | ||
}, _callee4, null, [[0, 8]]); | ||
})); | ||
return function listener(_x) { | ||
return _ref5.apply(this, arguments); | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}(); | ||
SOCKET_CONN.on('connect_error', function () { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
}); | ||
SOCKET_CONN.on('connect', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6() { | ||
var engine; | ||
return _regenerator["default"].wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_util.log.debug('connected with socket'); | ||
SOCKET_CONN.emit('check_auth_status', (0, _eccrypto.getPublic)(channelEncPrivKey).toString('hex')); | ||
engine = SOCKET_CONN.io.engine; | ||
_util.log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
engine.once('upgrade', function () { | ||
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket) | ||
_util.log.debug('upgraded', engine.transport.name); // in most cases, prints "websocket" | ||
}); | ||
engine.on('close', function (reason) { | ||
// called when the underlying connection is closed | ||
_util.log.debug('connection closed', reason); | ||
}); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
} | ||
}, _callee6); | ||
}))); | ||
SOCKET_CONN.on('error', function (err) { | ||
_util.log.debug('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.once('disconnect', function () { | ||
_util.log.debug('socket disconnected'); | ||
if (SOCKET_CONN_INSTANCES[channelName]) visibilityListener(); | ||
}); | ||
SOCKET_CONN.on('success', listener); | ||
socketConn.on(channelPubKey + "_success", listener); | ||
document.addEventListener('visibilitychange', visibilityListener); | ||
SOCKET_CONN_INSTANCES[channelName] = SOCKET_CONN; | ||
return listener; | ||
return socketConn; | ||
} | ||
function removeStorageEventListener(channelState) { | ||
if (SOCKET_CONN_INSTANCES[channelState.channelName]) SOCKET_CONN_INSTANCES[channelState.channelName].disconnect(); | ||
function removeStorageEventListener() { | ||
if (SOCKET_CONN_INSTANCE) { | ||
SOCKET_CONN_INSTANCE.disconnect(); | ||
} | ||
} | ||
@@ -349,11 +308,11 @@ | ||
}; | ||
state.listener = addStorageEventListener(channelName, options.server.url, function (msgObj) { | ||
setupSocketConnection(options.server.url, channelName, function (msgObj) { | ||
if (!state.messagesCallback) return; // no listener | ||
if (msgObj.uuid === uuid) return; // own message | ||
if (msgObj.uuid === state.uuid) return; // own message | ||
if (!msgObj.token || eMIs.has(msgObj.token)) return; // already emitted | ||
if (!msgObj.token || state.eMIs.has(msgObj.token)) return; // already emitted | ||
// if (msgObj.data.time && msgObj.data.time < state.messagesCallbackTime) return; // too old | ||
eMIs.add(msgObj.token); | ||
state.eMIs.add(msgObj.token); | ||
state.messagesCallback(msgObj.data); | ||
@@ -364,9 +323,8 @@ }); | ||
function close(channelState) { | ||
// give 2 sec for all msgs which are in transit to be consumed | ||
function close() {// give 2 sec for all msgs which are in transit to be consumed | ||
// by receiver. | ||
window.setTimeout(function () { | ||
removeStorageEventListener(channelState); | ||
delete SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
}, 1000); | ||
// window.setTimeout(() => { | ||
// removeStorageEventListener(channelState); | ||
// SOCKET_CONN_INSTANCE = null; | ||
// }, 1000); | ||
} | ||
@@ -373,0 +331,0 @@ |
{ | ||
"name": "@toruslabs/broadcast-channel", | ||
"version": "5.0.2", | ||
"version": "6.0.0", | ||
"description": "A BroadcastChannel that works in New Browsers, Old Browsers, WebWorkers", | ||
@@ -5,0 +5,0 @@ "exports": { |
@@ -29,3 +29,3 @@ /** | ||
const SOCKET_CONN_INSTANCES = {}; | ||
let SOCKET_CONN_INSTANCE = null; | ||
@@ -51,34 +51,15 @@ export function storageKey(channelName) { | ||
}); | ||
const socketConn = SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
const _setMessage = async () => { | ||
return fetch(channelState.serverUrl + '/channel/set', { | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
key: getPublic(channelEncPrivKey).toString('hex'), | ||
data: encData, | ||
signature: (await sign(channelEncPrivKey, keccak256(encData))).toString('hex'), | ||
}), | ||
headers: { | ||
'Content-Type': 'application/json; charset=utf-8', | ||
}, | ||
}) | ||
.then(res) | ||
.catch(rej); | ||
}; | ||
if (socketConn && socketConn.connected) { | ||
return _setMessage(); | ||
} | ||
let currentAttempts = 0; | ||
const waitingInterval = window.setInterval(async () => { | ||
if (currentAttempts >= 5) { | ||
window.clearInterval(waitingInterval); | ||
return rej(new Error('Could not post message after 5 attempts to socket channel')); | ||
} | ||
if (socketConn && socketConn.connected) { | ||
window.clearInterval(waitingInterval); | ||
return _setMessage(); | ||
} else { | ||
currentAttempts++; | ||
} | ||
}, 500); | ||
return fetch(channelState.serverUrl + '/channel/set', { | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
key: getPublic(channelEncPrivKey).toString('hex'), | ||
data: encData, | ||
signature: (await sign(channelEncPrivKey, keccak256(encData))).toString('hex'), | ||
}), | ||
headers: { | ||
'Content-Type': 'application/json; charset=utf-8', | ||
}, | ||
}) | ||
.then(res) | ||
.catch(rej); | ||
}); | ||
@@ -88,5 +69,6 @@ }); | ||
export function addStorageEventListener(channelName, serverUrl, fn) { | ||
const key = storageKey(channelName); | ||
const channelEncPrivKey = keccak256(key); | ||
export function getSocketInstance(serverUrl) { | ||
if (SOCKET_CONN_INSTANCE) { | ||
return SOCKET_CONN_INSTANCE; | ||
} | ||
const SOCKET_CONN = io(serverUrl, { | ||
@@ -98,30 +80,9 @@ transports: ['websocket', 'polling'], // use WebSocket first, if available | ||
}); | ||
const visibilityListener = () => { | ||
// if channel is closed, then remove the listener. | ||
if (!SOCKET_CONN_INSTANCES[channelName]) { | ||
document.removeEventListener('visibilitychange', visibilityListener); | ||
return; | ||
} | ||
// if not connected, then wait for connection and ping server for latest msg. | ||
if (!SOCKET_CONN.connected && document.visibilityState === 'visible') { | ||
SOCKET_CONN.once('connect', async () => { | ||
SOCKET_CONN.emit('check_auth_status', getPublic(channelEncPrivKey).toString('hex')); | ||
}); | ||
} | ||
}; | ||
const listener = async (ev) => { | ||
try { | ||
const decData = await decryptData(channelEncPrivKey.toString('hex'), ev); | ||
fn(decData); | ||
} catch (error) { | ||
log.error(error); | ||
} | ||
}; | ||
SOCKET_CONN.on('connect_error', () => { | ||
SOCKET_CONN.on('connect_error', (err) => { | ||
// revert to classic upgrade | ||
SOCKET_CONN.io.opts.transports = ['polling', 'websocket']; | ||
log.error('connect error', err); | ||
}); | ||
SOCKET_CONN.on('connect', async () => { | ||
log.debug('connected with socket'); | ||
SOCKET_CONN.emit('check_auth_status', getPublic(channelEncPrivKey).toString('hex')); | ||
const { engine } = SOCKET_CONN.io; | ||
@@ -133,3 +94,3 @@ log.debug('initially connected to', engine.transport.name); // in most cases, prints "polling" | ||
}); | ||
engine.on('close', (reason) => { | ||
engine.once('close', (reason) => { | ||
// called when the underlying connection is closed | ||
@@ -141,17 +102,62 @@ log.debug('connection closed', reason); | ||
SOCKET_CONN.on('error', (err) => { | ||
log.debug('socket errored', err); | ||
log.error('socket errored', err); | ||
SOCKET_CONN.disconnect(); | ||
}); | ||
SOCKET_CONN.once('disconnect', () => { | ||
SOCKET_CONN.on('disconnect', () => { | ||
log.debug('socket disconnected'); | ||
if (SOCKET_CONN_INSTANCES[channelName]) visibilityListener(); | ||
}); | ||
SOCKET_CONN_INSTANCE = SOCKET_CONN; | ||
return SOCKET_CONN; | ||
} | ||
SOCKET_CONN.on('success', listener); | ||
export function setupSocketConnection(serverUrl, channelName, fn) { | ||
const socketConn = getSocketInstance(serverUrl); | ||
const key = storageKey(channelName); | ||
const channelEncPrivKey = keccak256(key); | ||
const channelPubKey = getPublic(channelEncPrivKey).toString('hex'); | ||
if (socketConn.connected) { | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
} else { | ||
socketConn.once('connect', () => { | ||
log.debug('connected with socket'); | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
}); | ||
} | ||
const visibilityListener = () => { | ||
// if channel is closed, then remove the listener. | ||
if (!socketConn) { | ||
document.removeEventListener('visibilitychange', visibilityListener); | ||
return; | ||
} | ||
// if not connected, then wait for connection and ping server for latest msg. | ||
if (!socketConn.connected && document.visibilityState === 'visible') { | ||
socketConn.once('connect', async () => { | ||
socketConn.emit('check_auth_status', channelPubKey); | ||
}); | ||
} | ||
}; | ||
const listener = async (ev) => { | ||
try { | ||
const decData = await decryptData(channelEncPrivKey.toString('hex'), ev); | ||
log.info(decData); | ||
fn(decData); | ||
} catch (error) { | ||
log.error(error); | ||
} | ||
}; | ||
socketConn.on(`${channelPubKey}_success`, listener); | ||
document.addEventListener('visibilitychange', visibilityListener); | ||
SOCKET_CONN_INSTANCES[channelName] = SOCKET_CONN; | ||
return listener; | ||
return socketConn; | ||
} | ||
export function removeStorageEventListener(channelState) { | ||
if (SOCKET_CONN_INSTANCES[channelState.channelName]) SOCKET_CONN_INSTANCES[channelState.channelName].disconnect(); | ||
export function removeStorageEventListener() { | ||
if (SOCKET_CONN_INSTANCE) { | ||
SOCKET_CONN_INSTANCE.disconnect(); | ||
} | ||
} | ||
@@ -181,9 +187,9 @@ | ||
state.listener = addStorageEventListener(channelName, options.server.url, (msgObj) => { | ||
setupSocketConnection(options.server.url, channelName, (msgObj) => { | ||
if (!state.messagesCallback) return; // no listener | ||
if (msgObj.uuid === uuid) return; // own message | ||
if (!msgObj.token || eMIs.has(msgObj.token)) return; // already emitted | ||
if (msgObj.uuid === state.uuid) return; // own message | ||
if (!msgObj.token || state.eMIs.has(msgObj.token)) return; // already emitted | ||
// if (msgObj.data.time && msgObj.data.time < state.messagesCallbackTime) return; // too old | ||
eMIs.add(msgObj.token); | ||
state.eMIs.add(msgObj.token); | ||
state.messagesCallback(msgObj.data); | ||
@@ -195,9 +201,9 @@ }); | ||
export function close(channelState) { | ||
export function close() { | ||
// give 2 sec for all msgs which are in transit to be consumed | ||
// by receiver. | ||
window.setTimeout(() => { | ||
removeStorageEventListener(channelState); | ||
delete SOCKET_CONN_INSTANCES[channelState.channelName]; | ||
}, 1000); | ||
// window.setTimeout(() => { | ||
// removeStorageEventListener(channelState); | ||
// SOCKET_CONN_INSTANCE = null; | ||
// }, 1000); | ||
} | ||
@@ -204,0 +210,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1858888
39383