broadcast-channel
Advanced tools
Comparing version 4.18.1 to 4.19.0
@@ -6,2 +6,6 @@ # CHANGELOG | ||
## 4.19.0 (28 December 2022) | ||
- Updated dependencies | ||
## 4.18.1 (31 October 2022) | ||
@@ -8,0 +12,0 @@ |
@@ -49,3 +49,3 @@ "use strict"; | ||
/** | ||
* Unsend message promises | ||
* Unsent message promises | ||
* where the sending is still in progress | ||
@@ -111,3 +111,3 @@ * @type {Set<Promise>} | ||
/** | ||
* In the past when this error appeared, it was realy hard to debug. | ||
* In the past when this error appeared, it was really hard to debug. | ||
* So now we log the msg together with the error so it at least | ||
@@ -200,3 +200,3 @@ * gives some clue about where in your application this happens. | ||
// add/remove to unsend messages list | ||
// add/remove to unsent messages list | ||
broadcastChannel._uMP.add(sendPromise); | ||
@@ -247,4 +247,4 @@ sendPromise["catch"]().then(function () { | ||
* Getting the current time in JavaScript has no good precision. | ||
* So instead of only listening to events that happend 'after' the listener | ||
* was added, we also listen to events that happended 100ms before it. | ||
* So instead of only listening to events that happened 'after' the listener | ||
* was added, we also listen to events that happened 100ms before it. | ||
* This ensures that when another process, like a WebWorker, sends events | ||
@@ -276,3 +276,3 @@ * we do not miss them out because their timestamp is a bit off compared to the main process. | ||
if (channel._iL && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
// no one is listening, stop subscribing | ||
channel._iL = false; | ||
@@ -279,0 +279,0 @@ var time = channel.method.microSeconds(); |
@@ -70,3 +70,3 @@ "use strict"; | ||
/** | ||
* Already applying more then once, | ||
* Already applying more than once, | ||
* -> wait for the apply queue to be finished. | ||
@@ -104,6 +104,4 @@ */ | ||
}); | ||
var recieved = []; | ||
var handleMessage = function handleMessage(msg) { | ||
if (msg.context === 'leader' && msg.token != _this2.token) { | ||
recieved.push(msg); | ||
if (msg.action === 'apply') { | ||
@@ -132,3 +130,3 @@ // other is applying | ||
* not critical process is waiting for it. | ||
* When this is true, we give the other intances | ||
* When this is true, we give the other instances | ||
* more time to answer to messages in the election cycle. | ||
@@ -140,3 +138,3 @@ * This makes it less likely to elect duplicate leaders. | ||
var waitForAnswerTime = isFromFallbackInterval ? _this2._options.responseTime * 4 : _this2._options.responseTime; | ||
var applyPromise = _sendMessage(_this2, 'apply') // send out that this one is applying | ||
return _sendMessage(_this2, 'apply') // send out that this one is applying | ||
.then(function () { | ||
@@ -168,3 +166,2 @@ return Promise.race([(0, _util.sleep)(waitForAnswerTime), stopCriteriaPromise.then(function () { | ||
}); | ||
return applyPromise; | ||
}; | ||
@@ -171,0 +168,0 @@ this._aplQC = this._aplQC + 1; |
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
var _typeof = require("@babel/runtime/helpers/typeof"); | ||
@@ -9,6 +8,6 @@ Object.defineProperty(exports, "__esModule", { | ||
exports.chooseMethod = chooseMethod; | ||
var _native = _interopRequireDefault(require("./methods/native.js")); | ||
var _indexedDb = _interopRequireDefault(require("./methods/indexed-db.js")); | ||
var _localstorage = _interopRequireDefault(require("./methods/localstorage.js")); | ||
var _simulate = _interopRequireDefault(require("./methods/simulate.js")); | ||
var _native = require("./methods/native.js"); | ||
var _indexedDb = require("./methods/indexed-db.js"); | ||
var _localstorage = require("./methods/localstorage.js"); | ||
var _simulate = require("./methods/simulate.js"); | ||
var NodeMethod = _interopRequireWildcard(require("./methods/node.js")); | ||
@@ -20,5 +19,5 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } | ||
// order is important | ||
var METHODS = [_native["default"], | ||
var METHODS = [_native.NativeMethod, | ||
// fastest | ||
_indexedDb["default"], _localstorage["default"]]; | ||
_indexedDb.IndexedDBMethod, _localstorage.LocalstorageMethod]; | ||
function chooseMethod(options) { | ||
@@ -34,3 +33,3 @@ var chooseMethods = [].concat(options.methods, METHODS).filter(Boolean); | ||
// only use simulate-method if directly chosen | ||
return _simulate["default"]; | ||
return _simulate.SimulateMethod; | ||
} | ||
@@ -45,3 +44,3 @@ var ret = chooseMethods.find(function (m) { | ||
* if no webworker support is needed, | ||
* remove idb from the list so that localstorage is been chosen | ||
* remove idb from the list so that localstorage will be chosen | ||
*/ | ||
@@ -56,5 +55,5 @@ if (!options.webWorkerSupport) { | ||
}); | ||
if (!useMethod) throw new Error("No useable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
if (!useMethod) throw new Error("No usable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
return m.type; | ||
})));else return useMethod; | ||
} |
/** | ||
* if you really need this method, | ||
* implement it | ||
* implement it! | ||
*/ | ||
"use strict"; |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.TRANSACTION_SETTINGS = void 0; | ||
exports.TRANSACTION_SETTINGS = exports.IndexedDBMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -15,3 +15,2 @@ exports.canBeUsed = canBeUsed; | ||
exports.createDatabase = createDatabase; | ||
exports["default"] = void 0; | ||
exports.getAllMessages = getAllMessages; | ||
@@ -93,3 +92,3 @@ exports.getIdb = getIdb; | ||
}; | ||
var dbPromise = new Promise(function (res, rej) { | ||
return new Promise(function (res, rej) { | ||
openRequest.onerror = function (ev) { | ||
@@ -102,3 +101,2 @@ return rej(ev); | ||
}); | ||
return dbPromise; | ||
} | ||
@@ -235,3 +233,2 @@ | ||
res(ret); | ||
return; | ||
} | ||
@@ -266,3 +263,3 @@ } else { | ||
eMIs: new _obliviousSet.ObliviousSet(options.idb.ttl * 2), | ||
// ensures we do not read messages in parrallel | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: _util.PROMISE_RESOLVED_VOID, | ||
@@ -321,3 +318,3 @@ messagesCallback: null, | ||
/** | ||
* there is a bug in iOS where the msgObj can be undefined some times | ||
* there is a bug in iOS where the msgObj can be undefined sometimes | ||
* so we filter them out | ||
@@ -367,7 +364,3 @@ * @link https://github.com/pubkey/broadcast-channel/issues/19 | ||
function canBeUsed() { | ||
var idb = getIdb(); | ||
if (!idb) { | ||
return false; | ||
} | ||
return true; | ||
return !!getIdb(); | ||
} | ||
@@ -377,3 +370,3 @@ function averageResponseTime(options) { | ||
} | ||
var _default = { | ||
var IndexedDBMethod = { | ||
create: create, | ||
@@ -388,2 +381,2 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.IndexedDBMethod = IndexedDBMethod; |
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.LocalstorageMethod = void 0; | ||
exports.addStorageEventListener = addStorageEventListener; | ||
@@ -12,3 +13,2 @@ exports.averageResponseTime = averageResponseTime; | ||
exports.create = create; | ||
exports["default"] = void 0; | ||
exports.getLocalStorage = getLocalStorage; | ||
@@ -26,4 +26,4 @@ exports.microSeconds = void 0; | ||
* A localStorage-only method which uses localstorage and its 'storage'-event | ||
* This does not work inside of webworkers because they have no access to locastorage | ||
* This is basically implemented to support IE9 or your grandmothers toaster. | ||
* This does not work inside webworkers because they have no access to localstorage | ||
* This is basically implemented to support IE9 or your grandmother's toaster. | ||
* @link https://caniuse.com/#feat=namevalue-storage | ||
@@ -165,3 +165,3 @@ * @link https://caniuse.com/#feat=indexeddb | ||
} | ||
var _default = { | ||
var LocalstorageMethod = { | ||
create: create, | ||
@@ -176,2 +176,2 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.LocalstorageMethod = LocalstorageMethod; |
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.NativeMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -11,3 +12,3 @@ exports.canBeUsed = canBeUsed; | ||
exports.create = create; | ||
exports.microSeconds = exports["default"] = void 0; | ||
exports.microSeconds = void 0; | ||
exports.onMessage = onMessage; | ||
@@ -66,3 +67,3 @@ exports.postMessage = postMessage; | ||
} | ||
var _default = { | ||
var NativeMethod = { | ||
create: create, | ||
@@ -77,2 +78,2 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.NativeMethod = NativeMethod; |
@@ -118,15 +118,13 @@ "use strict"; | ||
return _regenerator["default"].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!ENSURE_BASE_FOLDER_EXISTS_PROMISE) { | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = mkdir(TMP_FOLDER_BASE)["catch"](function () { | ||
return null; | ||
}); | ||
} | ||
return _context3.abrupt("return", ENSURE_BASE_FOLDER_EXISTS_PROMISE); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
while (1) switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!ENSURE_BASE_FOLDER_EXISTS_PROMISE) { | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = mkdir(TMP_FOLDER_BASE)["catch"](function () { | ||
return null; | ||
}); | ||
} | ||
return _context3.abrupt("return", ENSURE_BASE_FOLDER_EXISTS_PROMISE); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
@@ -148,31 +146,29 @@ }, _callee3); | ||
return _regenerator["default"].wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
_context4.next = 3; | ||
return ensureBaseFolderExists(); | ||
case 3: | ||
_context4.next = 5; | ||
return mkdir(paths.channelBase)["catch"](function () { | ||
return null; | ||
}); | ||
case 5: | ||
_context4.next = 7; | ||
return Promise.all([mkdir(paths.readers)["catch"](function () { | ||
return null; | ||
}), mkdir(paths.messages)["catch"](function () { | ||
return null; | ||
})]); | ||
case 7: | ||
// set permissions so other users can use the same channel | ||
chmodValue = '777'; | ||
_context4.next = 10; | ||
return Promise.all([chmod(paths.channelBase, chmodValue), chmod(paths.readers, chmodValue), chmod(paths.messages, chmodValue)])["catch"](function () { | ||
return null; | ||
}); | ||
case 10: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
while (1) switch (_context4.prev = _context4.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
_context4.next = 3; | ||
return ensureBaseFolderExists(); | ||
case 3: | ||
_context4.next = 5; | ||
return mkdir(paths.channelBase)["catch"](function () { | ||
return null; | ||
}); | ||
case 5: | ||
_context4.next = 7; | ||
return Promise.all([mkdir(paths.readers)["catch"](function () { | ||
return null; | ||
}), mkdir(paths.messages)["catch"](function () { | ||
return null; | ||
})]); | ||
case 7: | ||
// set permissions so other users can use the same channel | ||
chmodValue = '777'; | ||
_context4.next = 10; | ||
return Promise.all([chmod(paths.channelBase, chmodValue), chmod(paths.readers, chmodValue), chmod(paths.messages, chmodValue)])["catch"](function () { | ||
return null; | ||
}); | ||
case 10: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
@@ -189,21 +185,19 @@ }, _callee4); | ||
return _regenerator["default"].wrap(function _callee5$(_context5) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(!TMP_FOLDER_BASE || TMP_FOLDER_BASE === '' || TMP_FOLDER_BASE === '/')) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
throw new Error('BroadcastChannel.clearNodeFolder(): path is wrong'); | ||
case 2: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
_context5.next = 5; | ||
return removeDir(TMP_FOLDER_BASE); | ||
case 5: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
return _context5.abrupt("return", true); | ||
case 7: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
while (1) switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(!TMP_FOLDER_BASE || TMP_FOLDER_BASE === '' || TMP_FOLDER_BASE === '/')) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
throw new Error('BroadcastChannel.clearNodeFolder(): path is wrong'); | ||
case 2: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
_context5.next = 5; | ||
return removeDir(TMP_FOLDER_BASE); | ||
case 5: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
return _context5.abrupt("return", true); | ||
case 7: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
@@ -221,4 +215,3 @@ }, _callee5); | ||
paths = paths || getPaths(channelName); | ||
var socketPath = _path["default"].join(paths.readers, readerUuid + '.json'); | ||
return socketPath; | ||
return _path["default"].join(paths.readers, readerUuid + '.json'); | ||
} | ||
@@ -251,17 +244,15 @@ | ||
return _regenerator["default"].wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_context6.next = 2; | ||
return ensureBaseFolderExists(); | ||
case 2: | ||
_context6.next = 4; | ||
return readdir(TMP_FOLDER_BASE); | ||
case 4: | ||
folders = _context6.sent; | ||
return _context6.abrupt("return", folders.length); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
while (1) switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_context6.next = 2; | ||
return ensureBaseFolderExists(); | ||
case 2: | ||
_context6.next = 4; | ||
return readdir(TMP_FOLDER_BASE); | ||
case 4: | ||
folders = _context6.sent; | ||
return _context6.abrupt("return", folders.length); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
@@ -281,30 +272,27 @@ }, _callee6); | ||
_connectionError = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7(originalError) { | ||
var count, addObj, text, newError; | ||
var count, addObj, text; | ||
return _regenerator["default"].wrap(function _callee7$(_context7) { | ||
while (1) { | ||
switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return countChannelFolders(); | ||
case 2: | ||
count = _context7.sent; | ||
if (!(count < 30)) { | ||
_context7.next = 5; | ||
break; | ||
} | ||
return _context7.abrupt("return", originalError); | ||
case 5: | ||
addObj = {}; | ||
Object.entries(originalError).forEach(function (_ref3) { | ||
var k = _ref3[0], | ||
v = _ref3[1]; | ||
return addObj[k] = v; | ||
}); | ||
text = 'BroadcastChannel.create(): error: ' + 'This might happen if you have created to many channels, ' + 'like when you use BroadcastChannel in unit-tests.' + 'Try using BroadcastChannel.clearNodeFolder() to clear the tmp-folder before each test.' + 'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
newError = new Error(text + ': ' + JSON.stringify(addObj, null, 2)); | ||
return _context7.abrupt("return", newError); | ||
case 10: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
while (1) switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return countChannelFolders(); | ||
case 2: | ||
count = _context7.sent; | ||
if (!(count < 30)) { | ||
_context7.next = 5; | ||
break; | ||
} | ||
return _context7.abrupt("return", originalError); | ||
case 5: | ||
addObj = {}; | ||
Object.entries(originalError).forEach(function (_ref3) { | ||
var k = _ref3[0], | ||
v = _ref3[1]; | ||
return addObj[k] = v; | ||
}); | ||
text = 'BroadcastChannel.create(): error: ' + 'This might happen if you have created to many channels, ' + 'like when you use BroadcastChannel in unit-tests.' + 'Try using BroadcastChannel.clearNodeFolder() to clear the tmp-folder before each test.' + 'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
return _context7.abrupt("return", new Error(text + ': ' + JSON.stringify(addObj, null, 2))); | ||
case 9: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
@@ -322,80 +310,74 @@ }, _callee7); | ||
return _regenerator["default"].wrap(function _callee10$(_context10) { | ||
while (1) { | ||
switch (_context10.prev = _context10.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid, paths); | ||
emitter = new _events["default"].EventEmitter(); | ||
server = _net["default"].createServer(function (stream) { | ||
stream.on('end', function () {}); | ||
stream.on('data', function (msg) { | ||
emitter.emit('data', msg.toString()); | ||
}); | ||
while (1) switch (_context10.prev = _context10.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid, paths); | ||
emitter = new _events["default"].EventEmitter(); | ||
server = _net["default"].createServer(function (stream) { | ||
stream.on('end', function () {}); | ||
stream.on('data', function (msg) { | ||
emitter.emit('data', msg.toString()); | ||
}); | ||
_context10.next = 5; | ||
return new Promise(function (resolve, reject) { | ||
server.on('error', /*#__PURE__*/function () { | ||
var _ref4 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(err) { | ||
var useErr; | ||
return _regenerator["default"].wrap(function _callee8$(_context8) { | ||
while (1) { | ||
switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return connectionError(err); | ||
case 2: | ||
useErr = _context8.sent; | ||
reject(useErr); | ||
case 4: | ||
case "end": | ||
return _context8.stop(); | ||
}); | ||
_context10.next = 5; | ||
return new Promise(function (resolve, reject) { | ||
server.on('error', /*#__PURE__*/function () { | ||
var _ref4 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(err) { | ||
var useErr; | ||
return _regenerator["default"].wrap(function _callee8$(_context8) { | ||
while (1) switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return connectionError(err); | ||
case 2: | ||
useErr = _context8.sent; | ||
reject(useErr); | ||
case 4: | ||
case "end": | ||
return _context8.stop(); | ||
} | ||
}, _callee8); | ||
})); | ||
return function (_x26) { | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}()); | ||
server.listen(pathToSocket, /*#__PURE__*/function () { | ||
var _ref5 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9(err, res) { | ||
var useErr; | ||
return _regenerator["default"].wrap(function _callee9$(_context9) { | ||
while (1) switch (_context9.prev = _context9.next) { | ||
case 0: | ||
if (!err) { | ||
_context9.next = 7; | ||
break; | ||
} | ||
} | ||
}, _callee8); | ||
})); | ||
return function (_x26) { | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}()); | ||
server.listen(pathToSocket, /*#__PURE__*/function () { | ||
var _ref5 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9(err, res) { | ||
var useErr; | ||
return _regenerator["default"].wrap(function _callee9$(_context9) { | ||
while (1) { | ||
switch (_context9.prev = _context9.next) { | ||
case 0: | ||
if (!err) { | ||
_context9.next = 7; | ||
break; | ||
} | ||
_context9.next = 3; | ||
return connectionError(err); | ||
case 3: | ||
useErr = _context9.sent; | ||
reject(useErr); | ||
_context9.next = 8; | ||
break; | ||
case 7: | ||
resolve(res); | ||
case 8: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
} | ||
}, _callee9); | ||
})); | ||
return function (_x27, _x28) { | ||
return _ref5.apply(this, arguments); | ||
}; | ||
}()); | ||
}); | ||
case 5: | ||
return _context10.abrupt("return", { | ||
path: pathToSocket, | ||
emitter: emitter, | ||
server: server | ||
}); | ||
case 6: | ||
case "end": | ||
return _context10.stop(); | ||
} | ||
_context9.next = 3; | ||
return connectionError(err); | ||
case 3: | ||
useErr = _context9.sent; | ||
reject(useErr); | ||
_context9.next = 8; | ||
break; | ||
case 7: | ||
resolve(res); | ||
case 8: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
}, _callee9); | ||
})); | ||
return function (_x27, _x28) { | ||
return _ref5.apply(this, arguments); | ||
}; | ||
}()); | ||
}); | ||
case 5: | ||
return _context10.abrupt("return", { | ||
path: pathToSocket, | ||
emitter: emitter, | ||
server: server | ||
}); | ||
case 6: | ||
case "end": | ||
return _context10.stop(); | ||
} | ||
@@ -418,19 +400,17 @@ }, _callee10); | ||
return _regenerator["default"].wrap(function _callee11$(_context11) { | ||
while (1) { | ||
switch (_context11.prev = _context11.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid); | ||
client = new _net["default"].Socket(); | ||
return _context11.abrupt("return", new Promise(function (res, rej) { | ||
client.connect(pathToSocket, function () { | ||
return res(client); | ||
}); | ||
client.on('error', function (err) { | ||
return rej(err); | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context11.stop(); | ||
} | ||
while (1) switch (_context11.prev = _context11.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid); | ||
client = new _net["default"].Socket(); | ||
return _context11.abrupt("return", new Promise(function (res, rej) { | ||
client.connect(pathToSocket, function () { | ||
return res(client); | ||
}); | ||
client.on('error', function (err) { | ||
return rej(err); | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context11.stop(); | ||
} | ||
@@ -473,23 +453,21 @@ }, _callee11); | ||
return _regenerator["default"].wrap(function _callee12$(_context12) { | ||
while (1) { | ||
switch (_context12.prev = _context12.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
readersPath = paths.readers; | ||
_context12.next = 4; | ||
return readdir(readersPath); | ||
case 4: | ||
files = _context12.sent; | ||
return _context12.abrupt("return", files.map(function (file) { | ||
return file.split('.'); | ||
}).filter(function (split) { | ||
return split[1] === 'json'; | ||
}) // do not scan .socket-files | ||
.map(function (split) { | ||
return split[0]; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
while (1) switch (_context12.prev = _context12.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
readersPath = paths.readers; | ||
_context12.next = 4; | ||
return readdir(readersPath); | ||
case 4: | ||
files = _context12.sent; | ||
return _context12.abrupt("return", files.map(function (file) { | ||
return file.split('.'); | ||
}).filter(function (split) { | ||
return split[1] === 'json'; | ||
}) // do not scan .socket-files | ||
.map(function (split) { | ||
return split[0]; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
@@ -505,14 +483,11 @@ }, _callee12); | ||
_messagePath = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee13(channelName, time, token, writerUuid) { | ||
var fileName, msgPath; | ||
var fileName; | ||
return _regenerator["default"].wrap(function _callee13$(_context13) { | ||
while (1) { | ||
switch (_context13.prev = _context13.next) { | ||
case 0: | ||
fileName = time + '_' + writerUuid + '_' + token + '.json'; | ||
msgPath = _path["default"].join(getPaths(channelName).messages, fileName); | ||
return _context13.abrupt("return", msgPath); | ||
case 3: | ||
case "end": | ||
return _context13.stop(); | ||
} | ||
while (1) switch (_context13.prev = _context13.next) { | ||
case 0: | ||
fileName = time + '_' + writerUuid + '_' + token + '.json'; | ||
return _context13.abrupt("return", _path["default"].join(getPaths(channelName).messages, fileName)); | ||
case 2: | ||
case "end": | ||
return _context13.stop(); | ||
} | ||
@@ -530,25 +505,23 @@ }, _callee13); | ||
return _regenerator["default"].wrap(function _callee14$(_context14) { | ||
while (1) { | ||
switch (_context14.prev = _context14.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
messagesPath = paths.messages; | ||
_context14.next = 4; | ||
return readdir(messagesPath); | ||
case 4: | ||
files = _context14.sent; | ||
return _context14.abrupt("return", files.map(function (file) { | ||
var fileName = file.split('.')[0]; | ||
var split = fileName.split('_'); | ||
return { | ||
path: _path["default"].join(messagesPath, file), | ||
time: parseInt(split[0]), | ||
senderUuid: split[1], | ||
token: split[2] | ||
}; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context14.stop(); | ||
} | ||
while (1) switch (_context14.prev = _context14.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
messagesPath = paths.messages; | ||
_context14.next = 4; | ||
return readdir(messagesPath); | ||
case 4: | ||
files = _context14.sent; | ||
return _context14.abrupt("return", files.map(function (file) { | ||
var fileName = file.split('.')[0]; | ||
var split = fileName.split('_'); | ||
return { | ||
path: _path["default"].join(messagesPath, file), | ||
time: parseInt(split[0]), | ||
senderUuid: split[1], | ||
token: split[2] | ||
}; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context14.stop(); | ||
} | ||
@@ -578,20 +551,18 @@ }, _callee14); | ||
_cleanOldMessages = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee15(messageObjects, ttl) { | ||
var olderThen; | ||
var olderThan; | ||
return _regenerator["default"].wrap(function _callee15$(_context15) { | ||
while (1) { | ||
switch (_context15.prev = _context15.next) { | ||
case 0: | ||
olderThen = microSeconds() - ttl * 1000; // convert ttl to microseconds | ||
_context15.next = 3; | ||
return Promise.all(messageObjects.filter(function (obj) { | ||
return obj.time < olderThen; | ||
}).map(function (obj) { | ||
return unlink(obj.path)["catch"](function () { | ||
return null; | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context15.stop(); | ||
} | ||
while (1) switch (_context15.prev = _context15.next) { | ||
case 0: | ||
olderThan = microSeconds() - ttl * 1000; // convert ttl to microseconds | ||
_context15.next = 3; | ||
return Promise.all(messageObjects.filter(function (obj) { | ||
return obj.time < olderThan; | ||
}).map(function (obj) { | ||
return unlink(obj.path)["catch"](function () { | ||
return null; | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context15.stop(); | ||
} | ||
@@ -625,73 +596,71 @@ }, _callee15); | ||
return _regenerator["default"].wrap(function _callee16$(_context16) { | ||
while (1) { | ||
switch (_context16.prev = _context16.next) { | ||
case 0: | ||
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {}; | ||
options = (0, _options.fillOptionsWithDefaults)(options); | ||
time = microSeconds(); | ||
paths = getPaths(channelName); | ||
ensureFolderExistsPromise = ensureFoldersExist(channelName, paths); | ||
uuid = (0, _util2.randomToken)(); | ||
state = { | ||
time: time, | ||
channelName: channelName, | ||
options: options, | ||
uuid: uuid, | ||
paths: paths, | ||
// contains all messages that have been emitted before | ||
emittedMessagesIds: new _obliviousSet.ObliviousSet(options.node.ttl * 2), | ||
/** | ||
* Used to ensure we do not write too many files at once | ||
* which could throw an error. | ||
* Must always be smaller then options.node.maxParallelWrites | ||
*/ | ||
writeFileQueue: new _pQueue["default"]({ | ||
concurrency: options.node.maxParallelWrites | ||
}), | ||
messagesCallbackTime: null, | ||
messagesCallback: null, | ||
// ensures we do not read messages in parrallel | ||
writeBlockPromise: _util2.PROMISE_RESOLVED_VOID, | ||
otherReaderClients: {}, | ||
// ensure if process crashes, everything is cleaned up | ||
removeUnload: (0, _unload.add)(function () { | ||
return close(state); | ||
}), | ||
closed: false | ||
}; | ||
if (!OTHER_INSTANCES[channelName]) OTHER_INSTANCES[channelName] = []; | ||
OTHER_INSTANCES[channelName].push(state); | ||
_context16.next = 11; | ||
return ensureFolderExistsPromise; | ||
case 11: | ||
_context16.next = 13; | ||
return Promise.all([createSocketEventEmitter(channelName, uuid, paths), createSocketInfoFile(channelName, uuid, paths), refreshReaderClients(state)]); | ||
case 13: | ||
_yield$Promise$all = _context16.sent; | ||
socketEE = _yield$Promise$all[0]; | ||
infoFilePath = _yield$Promise$all[1]; | ||
state.socketEE = socketEE; | ||
state.infoFilePath = infoFilePath; | ||
while (1) switch (_context16.prev = _context16.next) { | ||
case 0: | ||
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {}; | ||
options = (0, _options.fillOptionsWithDefaults)(options); | ||
time = microSeconds(); | ||
paths = getPaths(channelName); | ||
ensureFolderExistsPromise = ensureFoldersExist(channelName, paths); | ||
uuid = (0, _util2.randomToken)(); | ||
state = { | ||
time: time, | ||
channelName: channelName, | ||
options: options, | ||
uuid: uuid, | ||
paths: paths, | ||
// contains all messages that have been emitted before | ||
emittedMessagesIds: new _obliviousSet.ObliviousSet(options.node.ttl * 2), | ||
/** | ||
* Used to ensure we do not write too many files at once | ||
* which could throw an error. | ||
* Must always be smaller than options.node.maxParallelWrites | ||
*/ | ||
writeFileQueue: new _pQueue["default"]({ | ||
concurrency: options.node.maxParallelWrites | ||
}), | ||
messagesCallbackTime: null, | ||
messagesCallback: null, | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: _util2.PROMISE_RESOLVED_VOID, | ||
otherReaderClients: {}, | ||
// ensure if process crashes, everything is cleaned up | ||
removeUnload: (0, _unload.add)(function () { | ||
return close(state); | ||
}), | ||
closed: false | ||
}; | ||
if (!OTHER_INSTANCES[channelName]) OTHER_INSTANCES[channelName] = []; | ||
OTHER_INSTANCES[channelName].push(state); | ||
_context16.next = 11; | ||
return ensureFolderExistsPromise; | ||
case 11: | ||
_context16.next = 13; | ||
return Promise.all([createSocketEventEmitter(channelName, uuid, paths), createSocketInfoFile(channelName, uuid, paths), refreshReaderClients(state)]); | ||
case 13: | ||
_yield$Promise$all = _context16.sent; | ||
socketEE = _yield$Promise$all[0]; | ||
infoFilePath = _yield$Promise$all[1]; | ||
state.socketEE = socketEE; | ||
state.infoFilePath = infoFilePath; | ||
// when new message comes in, we read it and emit it | ||
socketEE.emitter.on('data', function (data) { | ||
// if the socket is used fast, it may appear that multiple messages are flushed at once | ||
// so we have to split them before | ||
var singleOnes = data.split('|'); | ||
singleOnes.filter(function (single) { | ||
return single !== ''; | ||
}).forEach(function (single) { | ||
try { | ||
var obj = JSON.parse(single); | ||
handleMessagePing(state, obj); | ||
} catch (err) { | ||
throw new Error('could not parse data: ' + single); | ||
} | ||
}); | ||
// when new message comes in, we read it and emit it | ||
socketEE.emitter.on('data', function (data) { | ||
// if the socket is used fast, it may appear that multiple messages are flushed at once | ||
// so we have to split them before | ||
var singleOnes = data.split('|'); | ||
singleOnes.filter(function (single) { | ||
return single !== ''; | ||
}).forEach(function (single) { | ||
try { | ||
var obj = JSON.parse(single); | ||
handleMessagePing(state, obj); | ||
} catch (err) { | ||
throw new Error('could not parse data: ' + single); | ||
} | ||
}); | ||
return _context16.abrupt("return", state); | ||
case 20: | ||
case "end": | ||
return _context16.stop(); | ||
} | ||
}); | ||
return _context16.abrupt("return", state); | ||
case 20: | ||
case "end": | ||
return _context16.stop(); | ||
} | ||
@@ -728,55 +697,53 @@ }, _callee16); | ||
return _regenerator["default"].wrap(function _callee17$(_context17) { | ||
while (1) { | ||
switch (_context17.prev = _context17.next) { | ||
case 0: | ||
while (1) switch (_context17.prev = _context17.next) { | ||
case 0: | ||
if (state.messagesCallback) { | ||
_context17.next = 2; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 2: | ||
if (msgObj) { | ||
_context17.next = 8; | ||
break; | ||
} | ||
_context17.next = 5; | ||
return getAllMessages(state.channelName, state.paths); | ||
case 5: | ||
messages = _context17.sent; | ||
_context17.next = 9; | ||
break; | ||
case 8: | ||
// get single message | ||
messages = [getSingleMessage(state.channelName, msgObj, state.paths)]; | ||
case 9: | ||
useMessages = messages.filter(function (msgObj) { | ||
return _filterMessage(msgObj, state); | ||
}).sort(function (msgObjA, msgObjB) { | ||
return msgObjA.time - msgObjB.time; | ||
}); // sort by time | ||
// if no listener or message, so not do anything | ||
if (!(!useMessages.length || !state.messagesCallback)) { | ||
_context17.next = 12; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 12: | ||
_context17.next = 14; | ||
return Promise.all(useMessages.map(function (msgObj) { | ||
return readMessage(msgObj).then(function (content) { | ||
return msgObj.content = content; | ||
}); | ||
})); | ||
case 14: | ||
useMessages.forEach(function (msgObj) { | ||
state.emittedMessagesIds.add(msgObj.token); | ||
if (state.messagesCallback) { | ||
_context17.next = 2; | ||
break; | ||
// emit to subscribers | ||
state.messagesCallback(msgObj.content.data); | ||
} | ||
return _context17.abrupt("return"); | ||
case 2: | ||
if (msgObj) { | ||
_context17.next = 8; | ||
break; | ||
} | ||
_context17.next = 5; | ||
return getAllMessages(state.channelName, state.paths); | ||
case 5: | ||
messages = _context17.sent; | ||
_context17.next = 9; | ||
break; | ||
case 8: | ||
// get single message | ||
messages = [getSingleMessage(state.channelName, msgObj, state.paths)]; | ||
case 9: | ||
useMessages = messages.filter(function (msgObj) { | ||
return _filterMessage(msgObj, state); | ||
}).sort(function (msgObjA, msgObjB) { | ||
return msgObjA.time - msgObjB.time; | ||
}); // sort by time | ||
// if no listener or message, so not do anything | ||
if (!(!useMessages.length || !state.messagesCallback)) { | ||
_context17.next = 12; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 12: | ||
_context17.next = 14; | ||
return Promise.all(useMessages.map(function (msgObj) { | ||
return readMessage(msgObj).then(function (content) { | ||
return msgObj.content = content; | ||
}); | ||
})); | ||
case 14: | ||
useMessages.forEach(function (msgObj) { | ||
state.emittedMessagesIds.add(msgObj.token); | ||
if (state.messagesCallback) { | ||
// emit to subscribers | ||
state.messagesCallback(msgObj.content.data); | ||
} | ||
}); | ||
case 15: | ||
case "end": | ||
return _context17.stop(); | ||
} | ||
}); | ||
case 15: | ||
case "end": | ||
return _context17.stop(); | ||
} | ||
@@ -795,20 +762,18 @@ }, _callee17); | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.prev = 0; | ||
_context.next = 3; | ||
return channelState.otherReaderClients[readerUuid].destroy(); | ||
case 3: | ||
_context.next = 7; | ||
break; | ||
case 5: | ||
_context.prev = 5; | ||
_context.t0 = _context["catch"](0); | ||
case 7: | ||
delete channelState.otherReaderClients[readerUuid]; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
while (1) switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.prev = 0; | ||
_context.next = 3; | ||
return channelState.otherReaderClients[readerUuid].destroy(); | ||
case 3: | ||
_context.next = 7; | ||
break; | ||
case 5: | ||
_context.prev = 5; | ||
_context.t0 = _context["catch"](0); | ||
case 7: | ||
delete channelState.otherReaderClients[readerUuid]; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
@@ -833,33 +798,31 @@ }, _callee, null, [[0, 5]]); | ||
return _regenerator["default"].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
if (!channelState.closed) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
case 3: | ||
_context2.prev = 3; | ||
_context2.next = 6; | ||
return openClientConnection(channelState.channelName, readerUuid); | ||
case 6: | ||
client = _context2.sent; | ||
channelState.otherReaderClients[readerUuid] = client; | ||
_context2.next = 12; | ||
while (1) switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
if (!channelState.closed) { | ||
_context2.next = 3; | ||
break; | ||
case 10: | ||
_context2.prev = 10; | ||
_context2.t0 = _context2["catch"](3); | ||
case 12: | ||
_context2.next = 16; | ||
break; | ||
case 14: | ||
_context2.prev = 14; | ||
_context2.t1 = _context2["catch"](0); | ||
case 16: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
return _context2.abrupt("return"); | ||
case 3: | ||
_context2.prev = 3; | ||
_context2.next = 6; | ||
return openClientConnection(channelState.channelName, readerUuid); | ||
case 6: | ||
client = _context2.sent; | ||
channelState.otherReaderClients[readerUuid] = client; | ||
_context2.next = 12; | ||
break; | ||
case 10: | ||
_context2.prev = 10; | ||
_context2.t0 = _context2["catch"](3); | ||
case 12: | ||
_context2.next = 16; | ||
break; | ||
case 14: | ||
_context2.prev = 14; | ||
_context2.t1 = _context2["catch"](0); | ||
case 16: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
@@ -892,58 +855,54 @@ }, _callee2, null, [[0, 14], [3, 10]]); | ||
return _regenerator["default"].wrap(function _callee19$(_context19) { | ||
while (1) { | ||
switch (_context19.prev = _context19.next) { | ||
case 0: | ||
writePromise = channelState.writeFileQueue.add(function () { | ||
return writeMessage(channelState.channelName, channelState.uuid, messageJson, channelState.paths); | ||
}); | ||
channelState.writeBlockPromise = channelState.writeBlockPromise.then( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee18() { | ||
var _yield$Promise$all2, msgObj, pingStr, writeToReadersPromise; | ||
return _regenerator["default"].wrap(function _callee18$(_context18) { | ||
while (1) { | ||
switch (_context18.prev = _context18.next) { | ||
case 0: | ||
_context18.next = 2; | ||
return new Promise(function (res) { | ||
return setTimeout(res, 0); | ||
}); | ||
case 2: | ||
_context18.next = 4; | ||
return Promise.all([writePromise, refreshReaderClients(channelState)]); | ||
case 4: | ||
_yield$Promise$all2 = _context18.sent; | ||
msgObj = _yield$Promise$all2[0]; | ||
emitOverFastPath(channelState, msgObj, messageJson); | ||
pingStr = '{"t":' + msgObj.time + ',"u":"' + msgObj.uuid + '","to":"' + msgObj.token + '"}|'; | ||
writeToReadersPromise = Promise.all(Object.values(channelState.otherReaderClients).filter(function (client) { | ||
return client.writable; | ||
}) // client might have closed in between | ||
.map(function (client) { | ||
return new Promise(function (res) { | ||
client.write(pingStr, res); | ||
}); | ||
})); | ||
/** | ||
* clean up old messages | ||
* to not waste resources on cleaning up, | ||
* only if random-int matches, we clean up old messages | ||
*/ | ||
if ((0, _util2.randomInt)(0, 20) === 0) { | ||
/* await */ | ||
getAllMessages(channelState.channelName, channelState.paths).then(function (allMessages) { | ||
return cleanOldMessages(allMessages, channelState.options.node.ttl); | ||
}); | ||
} | ||
return _context18.abrupt("return", writeToReadersPromise); | ||
case 11: | ||
case "end": | ||
return _context18.stop(); | ||
while (1) switch (_context19.prev = _context19.next) { | ||
case 0: | ||
writePromise = channelState.writeFileQueue.add(function () { | ||
return writeMessage(channelState.channelName, channelState.uuid, messageJson, channelState.paths); | ||
}); | ||
channelState.writeBlockPromise = channelState.writeBlockPromise.then( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee18() { | ||
var _yield$Promise$all2, msgObj, pingStr, writeToReadersPromise; | ||
return _regenerator["default"].wrap(function _callee18$(_context18) { | ||
while (1) switch (_context18.prev = _context18.next) { | ||
case 0: | ||
_context18.next = 2; | ||
return new Promise(function (res) { | ||
return setTimeout(res, 0); | ||
}); | ||
case 2: | ||
_context18.next = 4; | ||
return Promise.all([writePromise, refreshReaderClients(channelState)]); | ||
case 4: | ||
_yield$Promise$all2 = _context18.sent; | ||
msgObj = _yield$Promise$all2[0]; | ||
emitOverFastPath(channelState, msgObj, messageJson); | ||
pingStr = '{"t":' + msgObj.time + ',"u":"' + msgObj.uuid + '","to":"' + msgObj.token + '"}|'; | ||
writeToReadersPromise = Promise.all(Object.values(channelState.otherReaderClients).filter(function (client) { | ||
return client.writable; | ||
}) // client might have closed in between | ||
.map(function (client) { | ||
return new Promise(function (res) { | ||
client.write(pingStr, res); | ||
}); | ||
})); | ||
/** | ||
* clean up old messages | ||
* to not waste resources on cleaning up, | ||
* only if random-int matches, we clean up old messages | ||
*/ | ||
if ((0, _util2.randomInt)(0, 20) === 0) { | ||
/* await */ | ||
getAllMessages(channelState.channelName, channelState.paths).then(function (allMessages) { | ||
return cleanOldMessages(allMessages, channelState.options.node.ttl); | ||
}); | ||
} | ||
} | ||
}, _callee18); | ||
}))); | ||
return _context19.abrupt("return", channelState.writeBlockPromise); | ||
case 3: | ||
case "end": | ||
return _context19.stop(); | ||
} | ||
return _context18.abrupt("return", writeToReadersPromise); | ||
case 11: | ||
case "end": | ||
return _context18.stop(); | ||
} | ||
}, _callee18); | ||
}))); | ||
return _context19.abrupt("return", channelState.writeBlockPromise); | ||
case 3: | ||
case "end": | ||
return _context19.stop(); | ||
} | ||
@@ -985,3 +944,3 @@ }, _callee19); | ||
function close(channelState) { | ||
if (channelState.closed) return; | ||
if (channelState.closed) return _util2.PROMISE_RESOLVED_VOID; | ||
channelState.closed = true; | ||
@@ -1017,14 +976,10 @@ channelState.emittedMessagesIds.clear(); | ||
function canBeUsed() { | ||
if (typeof _fs["default"].mkdir === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return typeof _fs["default"].mkdir === 'function'; | ||
} | ||
/** | ||
* on node we use a relatively height averageResponseTime, | ||
* on node we use a relatively high averageResponseTime, | ||
* because the file-io might be in use. | ||
* Also it is more important that the leader-election is reliable, | ||
* then to have a fast election. | ||
* than to have a fast election. | ||
*/ | ||
@@ -1031,0 +986,0 @@ function averageResponseTime() { |
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.SimulateMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -11,3 +12,3 @@ exports.canBeUsed = canBeUsed; | ||
exports.create = create; | ||
exports.microSeconds = exports["default"] = void 0; | ||
exports.microSeconds = void 0; | ||
exports.onMessage = onMessage; | ||
@@ -59,3 +60,3 @@ exports.postMessage = postMessage; | ||
} | ||
var _default = { | ||
var SimulateMethod = { | ||
create: create, | ||
@@ -70,2 +71,2 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.SimulateMethod = SimulateMethod; |
@@ -16,7 +16,3 @@ "use strict"; | ||
function isPromise(obj) { | ||
if (obj && typeof obj.then === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return obj && typeof obj.then === 'function'; | ||
} | ||
@@ -23,0 +19,0 @@ var PROMISE_RESOLVED_FALSE = Promise.resolve(false); |
@@ -41,3 +41,3 @@ import { isPromise, PROMISE_RESOLVED_FALSE, PROMISE_RESOLVED_VOID } from './util.js'; | ||
/** | ||
* Unsend message promises | ||
* Unsent message promises | ||
* where the sending is still in progress | ||
@@ -102,3 +102,3 @@ * @type {Set<Promise>} | ||
/** | ||
* In the past when this error appeared, it was realy hard to debug. | ||
* In the past when this error appeared, it was really hard to debug. | ||
* So now we log the msg together with the error so it at least | ||
@@ -191,3 +191,3 @@ * gives some clue about where in your application this happens. | ||
// add/remove to unsend messages list | ||
// add/remove to unsent messages list | ||
broadcastChannel._uMP.add(sendPromise); | ||
@@ -238,4 +238,4 @@ sendPromise["catch"]().then(function () { | ||
* Getting the current time in JavaScript has no good precision. | ||
* So instead of only listening to events that happend 'after' the listener | ||
* was added, we also listen to events that happended 100ms before it. | ||
* So instead of only listening to events that happened 'after' the listener | ||
* was added, we also listen to events that happened 100ms before it. | ||
* This ensures that when another process, like a WebWorker, sends events | ||
@@ -267,3 +267,3 @@ * we do not miss them out because their timestamp is a bit off compared to the main process. | ||
if (channel._iL && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
// no one is listening, stop subscribing | ||
channel._iL = false; | ||
@@ -270,0 +270,0 @@ var time = channel.method.microSeconds(); |
@@ -63,3 +63,3 @@ import { sleep, randomToken, PROMISE_RESOLVED_VOID, PROMISE_RESOLVED_TRUE } from './util.js'; | ||
/** | ||
* Already applying more then once, | ||
* Already applying more than once, | ||
* -> wait for the apply queue to be finished. | ||
@@ -97,6 +97,4 @@ */ | ||
}); | ||
var recieved = []; | ||
var handleMessage = function handleMessage(msg) { | ||
if (msg.context === 'leader' && msg.token != _this2.token) { | ||
recieved.push(msg); | ||
if (msg.action === 'apply') { | ||
@@ -125,3 +123,3 @@ // other is applying | ||
* not critical process is waiting for it. | ||
* When this is true, we give the other intances | ||
* When this is true, we give the other instances | ||
* more time to answer to messages in the election cycle. | ||
@@ -133,3 +131,3 @@ * This makes it less likely to elect duplicate leaders. | ||
var waitForAnswerTime = isFromFallbackInterval ? _this2._options.responseTime * 4 : _this2._options.responseTime; | ||
var applyPromise = _sendMessage(_this2, 'apply') // send out that this one is applying | ||
return _sendMessage(_this2, 'apply') // send out that this one is applying | ||
.then(function () { | ||
@@ -161,3 +159,2 @@ return Promise.race([sleep(waitForAnswerTime), stopCriteriaPromise.then(function () { | ||
}); | ||
return applyPromise; | ||
}; | ||
@@ -164,0 +161,0 @@ this._aplQC = this._aplQC + 1; |
@@ -1,5 +0,5 @@ | ||
import NativeMethod from './methods/native.js'; | ||
import IndexeDbMethod from './methods/indexed-db.js'; | ||
import LocalstorageMethod from './methods/localstorage.js'; | ||
import SimulateMethod from './methods/simulate.js'; | ||
import { NativeMethod } from './methods/native.js'; | ||
import { IndexedDBMethod } from './methods/indexed-db.js'; | ||
import { LocalstorageMethod } from './methods/localstorage.js'; | ||
import { SimulateMethod } from './methods/simulate.js'; | ||
// the line below will be removed from es5/browser builds | ||
@@ -10,3 +10,3 @@ | ||
// fastest | ||
IndexeDbMethod, LocalstorageMethod]; | ||
IndexedDBMethod, LocalstorageMethod]; | ||
export function chooseMethod(options) { | ||
@@ -31,3 +31,3 @@ var chooseMethods = [].concat(options.methods, METHODS).filter(Boolean); | ||
* if no webworker support is needed, | ||
* remove idb from the list so that localstorage is been chosen | ||
* remove idb from the list so that localstorage will be chosen | ||
*/ | ||
@@ -42,5 +42,5 @@ if (!options.webWorkerSupport) { | ||
}); | ||
if (!useMethod) throw new Error("No useable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
if (!useMethod) throw new Error("No usable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
return m.type; | ||
})));else return useMethod; | ||
} |
/** | ||
* if you really need this method, | ||
* implement it | ||
* implement it! | ||
*/ |
@@ -64,3 +64,3 @@ /** | ||
}; | ||
var dbPromise = new Promise(function (res, rej) { | ||
return new Promise(function (res, rej) { | ||
openRequest.onerror = function (ev) { | ||
@@ -73,3 +73,2 @@ return rej(ev); | ||
}); | ||
return dbPromise; | ||
} | ||
@@ -206,3 +205,2 @@ | ||
res(ret); | ||
return; | ||
} | ||
@@ -237,3 +235,3 @@ } else { | ||
eMIs: new ObliviousSet(options.idb.ttl * 2), | ||
// ensures we do not read messages in parrallel | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: PROMISE_RESOLVED_VOID, | ||
@@ -292,3 +290,3 @@ messagesCallback: null, | ||
/** | ||
* there is a bug in iOS where the msgObj can be undefined some times | ||
* there is a bug in iOS where the msgObj can be undefined sometimes | ||
* so we filter them out | ||
@@ -338,7 +336,3 @@ * @link https://github.com/pubkey/broadcast-channel/issues/19 | ||
export function canBeUsed() { | ||
var idb = getIdb(); | ||
if (!idb) { | ||
return false; | ||
} | ||
return true; | ||
return !!getIdb(); | ||
} | ||
@@ -348,3 +342,3 @@ export function averageResponseTime(options) { | ||
} | ||
export default { | ||
export var IndexedDBMethod = { | ||
create: create, | ||
@@ -351,0 +345,0 @@ close: close, |
/** | ||
* A localStorage-only method which uses localstorage and its 'storage'-event | ||
* This does not work inside of webworkers because they have no access to locastorage | ||
* This is basically implemented to support IE9 or your grandmothers toaster. | ||
* This does not work inside webworkers because they have no access to localstorage | ||
* This is basically implemented to support IE9 or your grandmother's toaster. | ||
* @link https://caniuse.com/#feat=namevalue-storage | ||
@@ -142,3 +142,3 @@ * @link https://caniuse.com/#feat=indexeddb | ||
} | ||
export default { | ||
export var LocalstorageMethod = { | ||
create: create, | ||
@@ -145,0 +145,0 @@ close: close, |
@@ -49,3 +49,3 @@ import { microSeconds as micro, PROMISE_RESOLVED_VOID } from '../util.js'; | ||
} | ||
export default { | ||
export var NativeMethod = { | ||
create: create, | ||
@@ -52,0 +52,0 @@ close: close, |
@@ -82,15 +82,13 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; | ||
return _regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!ENSURE_BASE_FOLDER_EXISTS_PROMISE) { | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = mkdir(TMP_FOLDER_BASE)["catch"](function () { | ||
return null; | ||
}); | ||
} | ||
return _context3.abrupt("return", ENSURE_BASE_FOLDER_EXISTS_PROMISE); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
while (1) switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!ENSURE_BASE_FOLDER_EXISTS_PROMISE) { | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = mkdir(TMP_FOLDER_BASE)["catch"](function () { | ||
return null; | ||
}); | ||
} | ||
return _context3.abrupt("return", ENSURE_BASE_FOLDER_EXISTS_PROMISE); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
@@ -113,31 +111,29 @@ }, _callee3); | ||
return _regeneratorRuntime.wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
_context4.next = 3; | ||
return ensureBaseFolderExists(); | ||
case 3: | ||
_context4.next = 5; | ||
return mkdir(paths.channelBase)["catch"](function () { | ||
return null; | ||
}); | ||
case 5: | ||
_context4.next = 7; | ||
return Promise.all([mkdir(paths.readers)["catch"](function () { | ||
return null; | ||
}), mkdir(paths.messages)["catch"](function () { | ||
return null; | ||
})]); | ||
case 7: | ||
// set permissions so other users can use the same channel | ||
chmodValue = '777'; | ||
_context4.next = 10; | ||
return Promise.all([chmod(paths.channelBase, chmodValue), chmod(paths.readers, chmodValue), chmod(paths.messages, chmodValue)])["catch"](function () { | ||
return null; | ||
}); | ||
case 10: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
while (1) switch (_context4.prev = _context4.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
_context4.next = 3; | ||
return ensureBaseFolderExists(); | ||
case 3: | ||
_context4.next = 5; | ||
return mkdir(paths.channelBase)["catch"](function () { | ||
return null; | ||
}); | ||
case 5: | ||
_context4.next = 7; | ||
return Promise.all([mkdir(paths.readers)["catch"](function () { | ||
return null; | ||
}), mkdir(paths.messages)["catch"](function () { | ||
return null; | ||
})]); | ||
case 7: | ||
// set permissions so other users can use the same channel | ||
chmodValue = '777'; | ||
_context4.next = 10; | ||
return Promise.all([chmod(paths.channelBase, chmodValue), chmod(paths.readers, chmodValue), chmod(paths.messages, chmodValue)])["catch"](function () { | ||
return null; | ||
}); | ||
case 10: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
@@ -154,21 +150,19 @@ }, _callee4); | ||
return _regeneratorRuntime.wrap(function _callee5$(_context5) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(!TMP_FOLDER_BASE || TMP_FOLDER_BASE === '' || TMP_FOLDER_BASE === '/')) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
throw new Error('BroadcastChannel.clearNodeFolder(): path is wrong'); | ||
case 2: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
_context5.next = 5; | ||
return removeDir(TMP_FOLDER_BASE); | ||
case 5: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
return _context5.abrupt("return", true); | ||
case 7: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
while (1) switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(!TMP_FOLDER_BASE || TMP_FOLDER_BASE === '' || TMP_FOLDER_BASE === '/')) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
throw new Error('BroadcastChannel.clearNodeFolder(): path is wrong'); | ||
case 2: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
_context5.next = 5; | ||
return removeDir(TMP_FOLDER_BASE); | ||
case 5: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
return _context5.abrupt("return", true); | ||
case 7: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
@@ -186,4 +180,3 @@ }, _callee5); | ||
paths = paths || getPaths(channelName); | ||
var socketPath = path.join(paths.readers, readerUuid + '.json'); | ||
return socketPath; | ||
return path.join(paths.readers, readerUuid + '.json'); | ||
} | ||
@@ -216,17 +209,15 @@ | ||
return _regeneratorRuntime.wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_context6.next = 2; | ||
return ensureBaseFolderExists(); | ||
case 2: | ||
_context6.next = 4; | ||
return readdir(TMP_FOLDER_BASE); | ||
case 4: | ||
folders = _context6.sent; | ||
return _context6.abrupt("return", folders.length); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
while (1) switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_context6.next = 2; | ||
return ensureBaseFolderExists(); | ||
case 2: | ||
_context6.next = 4; | ||
return readdir(TMP_FOLDER_BASE); | ||
case 4: | ||
folders = _context6.sent; | ||
return _context6.abrupt("return", folders.length); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
@@ -246,30 +237,27 @@ }, _callee6); | ||
_connectionError = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(originalError) { | ||
var count, addObj, text, newError; | ||
var count, addObj, text; | ||
return _regeneratorRuntime.wrap(function _callee7$(_context7) { | ||
while (1) { | ||
switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return countChannelFolders(); | ||
case 2: | ||
count = _context7.sent; | ||
if (!(count < 30)) { | ||
_context7.next = 5; | ||
break; | ||
} | ||
return _context7.abrupt("return", originalError); | ||
case 5: | ||
addObj = {}; | ||
Object.entries(originalError).forEach(function (_ref3) { | ||
var k = _ref3[0], | ||
v = _ref3[1]; | ||
return addObj[k] = v; | ||
}); | ||
text = 'BroadcastChannel.create(): error: ' + 'This might happen if you have created to many channels, ' + 'like when you use BroadcastChannel in unit-tests.' + 'Try using BroadcastChannel.clearNodeFolder() to clear the tmp-folder before each test.' + 'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
newError = new Error(text + ': ' + JSON.stringify(addObj, null, 2)); | ||
return _context7.abrupt("return", newError); | ||
case 10: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
while (1) switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return countChannelFolders(); | ||
case 2: | ||
count = _context7.sent; | ||
if (!(count < 30)) { | ||
_context7.next = 5; | ||
break; | ||
} | ||
return _context7.abrupt("return", originalError); | ||
case 5: | ||
addObj = {}; | ||
Object.entries(originalError).forEach(function (_ref3) { | ||
var k = _ref3[0], | ||
v = _ref3[1]; | ||
return addObj[k] = v; | ||
}); | ||
text = 'BroadcastChannel.create(): error: ' + 'This might happen if you have created to many channels, ' + 'like when you use BroadcastChannel in unit-tests.' + 'Try using BroadcastChannel.clearNodeFolder() to clear the tmp-folder before each test.' + 'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
return _context7.abrupt("return", new Error(text + ': ' + JSON.stringify(addObj, null, 2))); | ||
case 9: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
@@ -287,80 +275,74 @@ }, _callee7); | ||
return _regeneratorRuntime.wrap(function _callee10$(_context10) { | ||
while (1) { | ||
switch (_context10.prev = _context10.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid, paths); | ||
emitter = new events.EventEmitter(); | ||
server = net.createServer(function (stream) { | ||
stream.on('end', function () {}); | ||
stream.on('data', function (msg) { | ||
emitter.emit('data', msg.toString()); | ||
}); | ||
while (1) switch (_context10.prev = _context10.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid, paths); | ||
emitter = new events.EventEmitter(); | ||
server = net.createServer(function (stream) { | ||
stream.on('end', function () {}); | ||
stream.on('data', function (msg) { | ||
emitter.emit('data', msg.toString()); | ||
}); | ||
_context10.next = 5; | ||
return new Promise(function (resolve, reject) { | ||
server.on('error', /*#__PURE__*/function () { | ||
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(err) { | ||
var useErr; | ||
return _regeneratorRuntime.wrap(function _callee8$(_context8) { | ||
while (1) { | ||
switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return connectionError(err); | ||
case 2: | ||
useErr = _context8.sent; | ||
reject(useErr); | ||
case 4: | ||
case "end": | ||
return _context8.stop(); | ||
}); | ||
_context10.next = 5; | ||
return new Promise(function (resolve, reject) { | ||
server.on('error', /*#__PURE__*/function () { | ||
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(err) { | ||
var useErr; | ||
return _regeneratorRuntime.wrap(function _callee8$(_context8) { | ||
while (1) switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return connectionError(err); | ||
case 2: | ||
useErr = _context8.sent; | ||
reject(useErr); | ||
case 4: | ||
case "end": | ||
return _context8.stop(); | ||
} | ||
}, _callee8); | ||
})); | ||
return function (_x26) { | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}()); | ||
server.listen(pathToSocket, /*#__PURE__*/function () { | ||
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(err, res) { | ||
var useErr; | ||
return _regeneratorRuntime.wrap(function _callee9$(_context9) { | ||
while (1) switch (_context9.prev = _context9.next) { | ||
case 0: | ||
if (!err) { | ||
_context9.next = 7; | ||
break; | ||
} | ||
} | ||
}, _callee8); | ||
})); | ||
return function (_x26) { | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}()); | ||
server.listen(pathToSocket, /*#__PURE__*/function () { | ||
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(err, res) { | ||
var useErr; | ||
return _regeneratorRuntime.wrap(function _callee9$(_context9) { | ||
while (1) { | ||
switch (_context9.prev = _context9.next) { | ||
case 0: | ||
if (!err) { | ||
_context9.next = 7; | ||
break; | ||
} | ||
_context9.next = 3; | ||
return connectionError(err); | ||
case 3: | ||
useErr = _context9.sent; | ||
reject(useErr); | ||
_context9.next = 8; | ||
break; | ||
case 7: | ||
resolve(res); | ||
case 8: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
} | ||
}, _callee9); | ||
})); | ||
return function (_x27, _x28) { | ||
return _ref5.apply(this, arguments); | ||
}; | ||
}()); | ||
}); | ||
case 5: | ||
return _context10.abrupt("return", { | ||
path: pathToSocket, | ||
emitter: emitter, | ||
server: server | ||
}); | ||
case 6: | ||
case "end": | ||
return _context10.stop(); | ||
} | ||
_context9.next = 3; | ||
return connectionError(err); | ||
case 3: | ||
useErr = _context9.sent; | ||
reject(useErr); | ||
_context9.next = 8; | ||
break; | ||
case 7: | ||
resolve(res); | ||
case 8: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
}, _callee9); | ||
})); | ||
return function (_x27, _x28) { | ||
return _ref5.apply(this, arguments); | ||
}; | ||
}()); | ||
}); | ||
case 5: | ||
return _context10.abrupt("return", { | ||
path: pathToSocket, | ||
emitter: emitter, | ||
server: server | ||
}); | ||
case 6: | ||
case "end": | ||
return _context10.stop(); | ||
} | ||
@@ -384,19 +366,17 @@ }, _callee10); | ||
return _regeneratorRuntime.wrap(function _callee11$(_context11) { | ||
while (1) { | ||
switch (_context11.prev = _context11.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid); | ||
client = new net.Socket(); | ||
return _context11.abrupt("return", new Promise(function (res, rej) { | ||
client.connect(pathToSocket, function () { | ||
return res(client); | ||
}); | ||
client.on('error', function (err) { | ||
return rej(err); | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context11.stop(); | ||
} | ||
while (1) switch (_context11.prev = _context11.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid); | ||
client = new net.Socket(); | ||
return _context11.abrupt("return", new Promise(function (res, rej) { | ||
client.connect(pathToSocket, function () { | ||
return res(client); | ||
}); | ||
client.on('error', function (err) { | ||
return rej(err); | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context11.stop(); | ||
} | ||
@@ -439,23 +419,21 @@ }, _callee11); | ||
return _regeneratorRuntime.wrap(function _callee12$(_context12) { | ||
while (1) { | ||
switch (_context12.prev = _context12.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
readersPath = paths.readers; | ||
_context12.next = 4; | ||
return readdir(readersPath); | ||
case 4: | ||
files = _context12.sent; | ||
return _context12.abrupt("return", files.map(function (file) { | ||
return file.split('.'); | ||
}).filter(function (split) { | ||
return split[1] === 'json'; | ||
}) // do not scan .socket-files | ||
.map(function (split) { | ||
return split[0]; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
while (1) switch (_context12.prev = _context12.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
readersPath = paths.readers; | ||
_context12.next = 4; | ||
return readdir(readersPath); | ||
case 4: | ||
files = _context12.sent; | ||
return _context12.abrupt("return", files.map(function (file) { | ||
return file.split('.'); | ||
}).filter(function (split) { | ||
return split[1] === 'json'; | ||
}) // do not scan .socket-files | ||
.map(function (split) { | ||
return split[0]; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
@@ -471,14 +449,11 @@ }, _callee12); | ||
_messagePath = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13(channelName, time, token, writerUuid) { | ||
var fileName, msgPath; | ||
var fileName; | ||
return _regeneratorRuntime.wrap(function _callee13$(_context13) { | ||
while (1) { | ||
switch (_context13.prev = _context13.next) { | ||
case 0: | ||
fileName = time + '_' + writerUuid + '_' + token + '.json'; | ||
msgPath = path.join(getPaths(channelName).messages, fileName); | ||
return _context13.abrupt("return", msgPath); | ||
case 3: | ||
case "end": | ||
return _context13.stop(); | ||
} | ||
while (1) switch (_context13.prev = _context13.next) { | ||
case 0: | ||
fileName = time + '_' + writerUuid + '_' + token + '.json'; | ||
return _context13.abrupt("return", path.join(getPaths(channelName).messages, fileName)); | ||
case 2: | ||
case "end": | ||
return _context13.stop(); | ||
} | ||
@@ -496,25 +471,23 @@ }, _callee13); | ||
return _regeneratorRuntime.wrap(function _callee14$(_context14) { | ||
while (1) { | ||
switch (_context14.prev = _context14.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
messagesPath = paths.messages; | ||
_context14.next = 4; | ||
return readdir(messagesPath); | ||
case 4: | ||
files = _context14.sent; | ||
return _context14.abrupt("return", files.map(function (file) { | ||
var fileName = file.split('.')[0]; | ||
var split = fileName.split('_'); | ||
return { | ||
path: path.join(messagesPath, file), | ||
time: parseInt(split[0]), | ||
senderUuid: split[1], | ||
token: split[2] | ||
}; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context14.stop(); | ||
} | ||
while (1) switch (_context14.prev = _context14.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
messagesPath = paths.messages; | ||
_context14.next = 4; | ||
return readdir(messagesPath); | ||
case 4: | ||
files = _context14.sent; | ||
return _context14.abrupt("return", files.map(function (file) { | ||
var fileName = file.split('.')[0]; | ||
var split = fileName.split('_'); | ||
return { | ||
path: path.join(messagesPath, file), | ||
time: parseInt(split[0]), | ||
senderUuid: split[1], | ||
token: split[2] | ||
}; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context14.stop(); | ||
} | ||
@@ -544,20 +517,18 @@ }, _callee14); | ||
_cleanOldMessages = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee15(messageObjects, ttl) { | ||
var olderThen; | ||
var olderThan; | ||
return _regeneratorRuntime.wrap(function _callee15$(_context15) { | ||
while (1) { | ||
switch (_context15.prev = _context15.next) { | ||
case 0: | ||
olderThen = microSeconds() - ttl * 1000; // convert ttl to microseconds | ||
_context15.next = 3; | ||
return Promise.all(messageObjects.filter(function (obj) { | ||
return obj.time < olderThen; | ||
}).map(function (obj) { | ||
return unlink(obj.path)["catch"](function () { | ||
return null; | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context15.stop(); | ||
} | ||
while (1) switch (_context15.prev = _context15.next) { | ||
case 0: | ||
olderThan = microSeconds() - ttl * 1000; // convert ttl to microseconds | ||
_context15.next = 3; | ||
return Promise.all(messageObjects.filter(function (obj) { | ||
return obj.time < olderThan; | ||
}).map(function (obj) { | ||
return unlink(obj.path)["catch"](function () { | ||
return null; | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context15.stop(); | ||
} | ||
@@ -590,73 +561,71 @@ }, _callee15); | ||
return _regeneratorRuntime.wrap(function _callee16$(_context16) { | ||
while (1) { | ||
switch (_context16.prev = _context16.next) { | ||
case 0: | ||
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {}; | ||
options = fillOptionsWithDefaults(options); | ||
time = microSeconds(); | ||
paths = getPaths(channelName); | ||
ensureFolderExistsPromise = ensureFoldersExist(channelName, paths); | ||
uuid = randomToken(); | ||
state = { | ||
time: time, | ||
channelName: channelName, | ||
options: options, | ||
uuid: uuid, | ||
paths: paths, | ||
// contains all messages that have been emitted before | ||
emittedMessagesIds: new ObliviousSet(options.node.ttl * 2), | ||
/** | ||
* Used to ensure we do not write too many files at once | ||
* which could throw an error. | ||
* Must always be smaller then options.node.maxParallelWrites | ||
*/ | ||
writeFileQueue: new PQueue({ | ||
concurrency: options.node.maxParallelWrites | ||
}), | ||
messagesCallbackTime: null, | ||
messagesCallback: null, | ||
// ensures we do not read messages in parrallel | ||
writeBlockPromise: PROMISE_RESOLVED_VOID, | ||
otherReaderClients: {}, | ||
// ensure if process crashes, everything is cleaned up | ||
removeUnload: unloadAdd(function () { | ||
return close(state); | ||
}), | ||
closed: false | ||
}; | ||
if (!OTHER_INSTANCES[channelName]) OTHER_INSTANCES[channelName] = []; | ||
OTHER_INSTANCES[channelName].push(state); | ||
_context16.next = 11; | ||
return ensureFolderExistsPromise; | ||
case 11: | ||
_context16.next = 13; | ||
return Promise.all([createSocketEventEmitter(channelName, uuid, paths), createSocketInfoFile(channelName, uuid, paths), refreshReaderClients(state)]); | ||
case 13: | ||
_yield$Promise$all = _context16.sent; | ||
socketEE = _yield$Promise$all[0]; | ||
infoFilePath = _yield$Promise$all[1]; | ||
state.socketEE = socketEE; | ||
state.infoFilePath = infoFilePath; | ||
while (1) switch (_context16.prev = _context16.next) { | ||
case 0: | ||
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {}; | ||
options = fillOptionsWithDefaults(options); | ||
time = microSeconds(); | ||
paths = getPaths(channelName); | ||
ensureFolderExistsPromise = ensureFoldersExist(channelName, paths); | ||
uuid = randomToken(); | ||
state = { | ||
time: time, | ||
channelName: channelName, | ||
options: options, | ||
uuid: uuid, | ||
paths: paths, | ||
// contains all messages that have been emitted before | ||
emittedMessagesIds: new ObliviousSet(options.node.ttl * 2), | ||
/** | ||
* Used to ensure we do not write too many files at once | ||
* which could throw an error. | ||
* Must always be smaller than options.node.maxParallelWrites | ||
*/ | ||
writeFileQueue: new PQueue({ | ||
concurrency: options.node.maxParallelWrites | ||
}), | ||
messagesCallbackTime: null, | ||
messagesCallback: null, | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: PROMISE_RESOLVED_VOID, | ||
otherReaderClients: {}, | ||
// ensure if process crashes, everything is cleaned up | ||
removeUnload: unloadAdd(function () { | ||
return close(state); | ||
}), | ||
closed: false | ||
}; | ||
if (!OTHER_INSTANCES[channelName]) OTHER_INSTANCES[channelName] = []; | ||
OTHER_INSTANCES[channelName].push(state); | ||
_context16.next = 11; | ||
return ensureFolderExistsPromise; | ||
case 11: | ||
_context16.next = 13; | ||
return Promise.all([createSocketEventEmitter(channelName, uuid, paths), createSocketInfoFile(channelName, uuid, paths), refreshReaderClients(state)]); | ||
case 13: | ||
_yield$Promise$all = _context16.sent; | ||
socketEE = _yield$Promise$all[0]; | ||
infoFilePath = _yield$Promise$all[1]; | ||
state.socketEE = socketEE; | ||
state.infoFilePath = infoFilePath; | ||
// when new message comes in, we read it and emit it | ||
socketEE.emitter.on('data', function (data) { | ||
// if the socket is used fast, it may appear that multiple messages are flushed at once | ||
// so we have to split them before | ||
var singleOnes = data.split('|'); | ||
singleOnes.filter(function (single) { | ||
return single !== ''; | ||
}).forEach(function (single) { | ||
try { | ||
var obj = JSON.parse(single); | ||
handleMessagePing(state, obj); | ||
} catch (err) { | ||
throw new Error('could not parse data: ' + single); | ||
} | ||
}); | ||
// when new message comes in, we read it and emit it | ||
socketEE.emitter.on('data', function (data) { | ||
// if the socket is used fast, it may appear that multiple messages are flushed at once | ||
// so we have to split them before | ||
var singleOnes = data.split('|'); | ||
singleOnes.filter(function (single) { | ||
return single !== ''; | ||
}).forEach(function (single) { | ||
try { | ||
var obj = JSON.parse(single); | ||
handleMessagePing(state, obj); | ||
} catch (err) { | ||
throw new Error('could not parse data: ' + single); | ||
} | ||
}); | ||
return _context16.abrupt("return", state); | ||
case 20: | ||
case "end": | ||
return _context16.stop(); | ||
} | ||
}); | ||
return _context16.abrupt("return", state); | ||
case 20: | ||
case "end": | ||
return _context16.stop(); | ||
} | ||
@@ -694,55 +663,53 @@ }, _callee16); | ||
return _regeneratorRuntime.wrap(function _callee17$(_context17) { | ||
while (1) { | ||
switch (_context17.prev = _context17.next) { | ||
case 0: | ||
while (1) switch (_context17.prev = _context17.next) { | ||
case 0: | ||
if (state.messagesCallback) { | ||
_context17.next = 2; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 2: | ||
if (msgObj) { | ||
_context17.next = 8; | ||
break; | ||
} | ||
_context17.next = 5; | ||
return getAllMessages(state.channelName, state.paths); | ||
case 5: | ||
messages = _context17.sent; | ||
_context17.next = 9; | ||
break; | ||
case 8: | ||
// get single message | ||
messages = [getSingleMessage(state.channelName, msgObj, state.paths)]; | ||
case 9: | ||
useMessages = messages.filter(function (msgObj) { | ||
return _filterMessage(msgObj, state); | ||
}).sort(function (msgObjA, msgObjB) { | ||
return msgObjA.time - msgObjB.time; | ||
}); // sort by time | ||
// if no listener or message, so not do anything | ||
if (!(!useMessages.length || !state.messagesCallback)) { | ||
_context17.next = 12; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 12: | ||
_context17.next = 14; | ||
return Promise.all(useMessages.map(function (msgObj) { | ||
return readMessage(msgObj).then(function (content) { | ||
return msgObj.content = content; | ||
}); | ||
})); | ||
case 14: | ||
useMessages.forEach(function (msgObj) { | ||
state.emittedMessagesIds.add(msgObj.token); | ||
if (state.messagesCallback) { | ||
_context17.next = 2; | ||
break; | ||
// emit to subscribers | ||
state.messagesCallback(msgObj.content.data); | ||
} | ||
return _context17.abrupt("return"); | ||
case 2: | ||
if (msgObj) { | ||
_context17.next = 8; | ||
break; | ||
} | ||
_context17.next = 5; | ||
return getAllMessages(state.channelName, state.paths); | ||
case 5: | ||
messages = _context17.sent; | ||
_context17.next = 9; | ||
break; | ||
case 8: | ||
// get single message | ||
messages = [getSingleMessage(state.channelName, msgObj, state.paths)]; | ||
case 9: | ||
useMessages = messages.filter(function (msgObj) { | ||
return _filterMessage(msgObj, state); | ||
}).sort(function (msgObjA, msgObjB) { | ||
return msgObjA.time - msgObjB.time; | ||
}); // sort by time | ||
// if no listener or message, so not do anything | ||
if (!(!useMessages.length || !state.messagesCallback)) { | ||
_context17.next = 12; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 12: | ||
_context17.next = 14; | ||
return Promise.all(useMessages.map(function (msgObj) { | ||
return readMessage(msgObj).then(function (content) { | ||
return msgObj.content = content; | ||
}); | ||
})); | ||
case 14: | ||
useMessages.forEach(function (msgObj) { | ||
state.emittedMessagesIds.add(msgObj.token); | ||
if (state.messagesCallback) { | ||
// emit to subscribers | ||
state.messagesCallback(msgObj.content.data); | ||
} | ||
}); | ||
case 15: | ||
case "end": | ||
return _context17.stop(); | ||
} | ||
}); | ||
case 15: | ||
case "end": | ||
return _context17.stop(); | ||
} | ||
@@ -761,20 +728,18 @@ }, _callee17); | ||
return _regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.prev = 0; | ||
_context.next = 3; | ||
return channelState.otherReaderClients[readerUuid].destroy(); | ||
case 3: | ||
_context.next = 7; | ||
break; | ||
case 5: | ||
_context.prev = 5; | ||
_context.t0 = _context["catch"](0); | ||
case 7: | ||
delete channelState.otherReaderClients[readerUuid]; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
while (1) switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.prev = 0; | ||
_context.next = 3; | ||
return channelState.otherReaderClients[readerUuid].destroy(); | ||
case 3: | ||
_context.next = 7; | ||
break; | ||
case 5: | ||
_context.prev = 5; | ||
_context.t0 = _context["catch"](0); | ||
case 7: | ||
delete channelState.otherReaderClients[readerUuid]; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
@@ -799,33 +764,31 @@ }, _callee, null, [[0, 5]]); | ||
return _regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
if (!channelState.closed) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
case 3: | ||
_context2.prev = 3; | ||
_context2.next = 6; | ||
return openClientConnection(channelState.channelName, readerUuid); | ||
case 6: | ||
client = _context2.sent; | ||
channelState.otherReaderClients[readerUuid] = client; | ||
_context2.next = 12; | ||
while (1) switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
if (!channelState.closed) { | ||
_context2.next = 3; | ||
break; | ||
case 10: | ||
_context2.prev = 10; | ||
_context2.t0 = _context2["catch"](3); | ||
case 12: | ||
_context2.next = 16; | ||
break; | ||
case 14: | ||
_context2.prev = 14; | ||
_context2.t1 = _context2["catch"](0); | ||
case 16: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
return _context2.abrupt("return"); | ||
case 3: | ||
_context2.prev = 3; | ||
_context2.next = 6; | ||
return openClientConnection(channelState.channelName, readerUuid); | ||
case 6: | ||
client = _context2.sent; | ||
channelState.otherReaderClients[readerUuid] = client; | ||
_context2.next = 12; | ||
break; | ||
case 10: | ||
_context2.prev = 10; | ||
_context2.t0 = _context2["catch"](3); | ||
case 12: | ||
_context2.next = 16; | ||
break; | ||
case 14: | ||
_context2.prev = 14; | ||
_context2.t1 = _context2["catch"](0); | ||
case 16: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
@@ -859,58 +822,54 @@ }, _callee2, null, [[0, 14], [3, 10]]); | ||
return _regeneratorRuntime.wrap(function _callee19$(_context19) { | ||
while (1) { | ||
switch (_context19.prev = _context19.next) { | ||
case 0: | ||
writePromise = channelState.writeFileQueue.add(function () { | ||
return writeMessage(channelState.channelName, channelState.uuid, messageJson, channelState.paths); | ||
}); | ||
channelState.writeBlockPromise = channelState.writeBlockPromise.then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee18() { | ||
var _yield$Promise$all2, msgObj, pingStr, writeToReadersPromise; | ||
return _regeneratorRuntime.wrap(function _callee18$(_context18) { | ||
while (1) { | ||
switch (_context18.prev = _context18.next) { | ||
case 0: | ||
_context18.next = 2; | ||
return new Promise(function (res) { | ||
return setTimeout(res, 0); | ||
}); | ||
case 2: | ||
_context18.next = 4; | ||
return Promise.all([writePromise, refreshReaderClients(channelState)]); | ||
case 4: | ||
_yield$Promise$all2 = _context18.sent; | ||
msgObj = _yield$Promise$all2[0]; | ||
emitOverFastPath(channelState, msgObj, messageJson); | ||
pingStr = '{"t":' + msgObj.time + ',"u":"' + msgObj.uuid + '","to":"' + msgObj.token + '"}|'; | ||
writeToReadersPromise = Promise.all(Object.values(channelState.otherReaderClients).filter(function (client) { | ||
return client.writable; | ||
}) // client might have closed in between | ||
.map(function (client) { | ||
return new Promise(function (res) { | ||
client.write(pingStr, res); | ||
}); | ||
})); | ||
/** | ||
* clean up old messages | ||
* to not waste resources on cleaning up, | ||
* only if random-int matches, we clean up old messages | ||
*/ | ||
if (randomInt(0, 20) === 0) { | ||
/* await */ | ||
getAllMessages(channelState.channelName, channelState.paths).then(function (allMessages) { | ||
return cleanOldMessages(allMessages, channelState.options.node.ttl); | ||
}); | ||
} | ||
return _context18.abrupt("return", writeToReadersPromise); | ||
case 11: | ||
case "end": | ||
return _context18.stop(); | ||
while (1) switch (_context19.prev = _context19.next) { | ||
case 0: | ||
writePromise = channelState.writeFileQueue.add(function () { | ||
return writeMessage(channelState.channelName, channelState.uuid, messageJson, channelState.paths); | ||
}); | ||
channelState.writeBlockPromise = channelState.writeBlockPromise.then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee18() { | ||
var _yield$Promise$all2, msgObj, pingStr, writeToReadersPromise; | ||
return _regeneratorRuntime.wrap(function _callee18$(_context18) { | ||
while (1) switch (_context18.prev = _context18.next) { | ||
case 0: | ||
_context18.next = 2; | ||
return new Promise(function (res) { | ||
return setTimeout(res, 0); | ||
}); | ||
case 2: | ||
_context18.next = 4; | ||
return Promise.all([writePromise, refreshReaderClients(channelState)]); | ||
case 4: | ||
_yield$Promise$all2 = _context18.sent; | ||
msgObj = _yield$Promise$all2[0]; | ||
emitOverFastPath(channelState, msgObj, messageJson); | ||
pingStr = '{"t":' + msgObj.time + ',"u":"' + msgObj.uuid + '","to":"' + msgObj.token + '"}|'; | ||
writeToReadersPromise = Promise.all(Object.values(channelState.otherReaderClients).filter(function (client) { | ||
return client.writable; | ||
}) // client might have closed in between | ||
.map(function (client) { | ||
return new Promise(function (res) { | ||
client.write(pingStr, res); | ||
}); | ||
})); | ||
/** | ||
* clean up old messages | ||
* to not waste resources on cleaning up, | ||
* only if random-int matches, we clean up old messages | ||
*/ | ||
if (randomInt(0, 20) === 0) { | ||
/* await */ | ||
getAllMessages(channelState.channelName, channelState.paths).then(function (allMessages) { | ||
return cleanOldMessages(allMessages, channelState.options.node.ttl); | ||
}); | ||
} | ||
} | ||
}, _callee18); | ||
}))); | ||
return _context19.abrupt("return", channelState.writeBlockPromise); | ||
case 3: | ||
case "end": | ||
return _context19.stop(); | ||
} | ||
return _context18.abrupt("return", writeToReadersPromise); | ||
case 11: | ||
case "end": | ||
return _context18.stop(); | ||
} | ||
}, _callee18); | ||
}))); | ||
return _context19.abrupt("return", channelState.writeBlockPromise); | ||
case 3: | ||
case "end": | ||
return _context19.stop(); | ||
} | ||
@@ -952,3 +911,3 @@ }, _callee19); | ||
export function close(channelState) { | ||
if (channelState.closed) return; | ||
if (channelState.closed) return PROMISE_RESOLVED_VOID; | ||
channelState.closed = true; | ||
@@ -984,14 +943,10 @@ channelState.emittedMessagesIds.clear(); | ||
export function canBeUsed() { | ||
if (typeof fs.mkdir === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return typeof fs.mkdir === 'function'; | ||
} | ||
/** | ||
* on node we use a relatively height averageResponseTime, | ||
* on node we use a relatively high averageResponseTime, | ||
* because the file-io might be in use. | ||
* Also it is more important that the leader-election is reliable, | ||
* then to have a fast election. | ||
* than to have a fast election. | ||
*/ | ||
@@ -998,0 +953,0 @@ export function averageResponseTime() { |
@@ -42,3 +42,3 @@ import { microSeconds as micro } from '../util.js'; | ||
} | ||
export default { | ||
export var SimulateMethod = { | ||
create: create, | ||
@@ -45,0 +45,0 @@ close: close, |
@@ -5,7 +5,3 @@ /** | ||
export function isPromise(obj) { | ||
if (obj && typeof obj.then === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return obj && typeof obj.then === 'function'; | ||
} | ||
@@ -12,0 +8,0 @@ export var PROMISE_RESOLVED_FALSE = Promise.resolve(false); |
@@ -41,3 +41,3 @@ import { isPromise, PROMISE_RESOLVED_FALSE, PROMISE_RESOLVED_VOID } from './util.js'; | ||
/** | ||
* Unsend message promises | ||
* Unsent message promises | ||
* where the sending is still in progress | ||
@@ -102,3 +102,3 @@ * @type {Set<Promise>} | ||
/** | ||
* In the past when this error appeared, it was realy hard to debug. | ||
* In the past when this error appeared, it was really hard to debug. | ||
* So now we log the msg together with the error so it at least | ||
@@ -191,3 +191,3 @@ * gives some clue about where in your application this happens. | ||
// add/remove to unsend messages list | ||
// add/remove to unsent messages list | ||
broadcastChannel._uMP.add(sendPromise); | ||
@@ -238,4 +238,4 @@ sendPromise["catch"]().then(function () { | ||
* Getting the current time in JavaScript has no good precision. | ||
* So instead of only listening to events that happend 'after' the listener | ||
* was added, we also listen to events that happended 100ms before it. | ||
* So instead of only listening to events that happened 'after' the listener | ||
* was added, we also listen to events that happened 100ms before it. | ||
* This ensures that when another process, like a WebWorker, sends events | ||
@@ -267,3 +267,3 @@ * we do not miss them out because their timestamp is a bit off compared to the main process. | ||
if (channel._iL && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
// no one is listening, stop subscribing | ||
channel._iL = false; | ||
@@ -270,0 +270,0 @@ var time = channel.method.microSeconds(); |
@@ -63,3 +63,3 @@ import { sleep, randomToken, PROMISE_RESOLVED_VOID, PROMISE_RESOLVED_TRUE } from './util.js'; | ||
/** | ||
* Already applying more then once, | ||
* Already applying more than once, | ||
* -> wait for the apply queue to be finished. | ||
@@ -97,6 +97,4 @@ */ | ||
}); | ||
var recieved = []; | ||
var handleMessage = function handleMessage(msg) { | ||
if (msg.context === 'leader' && msg.token != _this2.token) { | ||
recieved.push(msg); | ||
if (msg.action === 'apply') { | ||
@@ -125,3 +123,3 @@ // other is applying | ||
* not critical process is waiting for it. | ||
* When this is true, we give the other intances | ||
* When this is true, we give the other instances | ||
* more time to answer to messages in the election cycle. | ||
@@ -133,3 +131,3 @@ * This makes it less likely to elect duplicate leaders. | ||
var waitForAnswerTime = isFromFallbackInterval ? _this2._options.responseTime * 4 : _this2._options.responseTime; | ||
var applyPromise = _sendMessage(_this2, 'apply') // send out that this one is applying | ||
return _sendMessage(_this2, 'apply') // send out that this one is applying | ||
.then(function () { | ||
@@ -161,3 +159,2 @@ return Promise.race([sleep(waitForAnswerTime), stopCriteriaPromise.then(function () { | ||
}); | ||
return applyPromise; | ||
}; | ||
@@ -164,0 +161,0 @@ this._aplQC = this._aplQC + 1; |
@@ -1,5 +0,5 @@ | ||
import NativeMethod from './methods/native.js'; | ||
import IndexeDbMethod from './methods/indexed-db.js'; | ||
import LocalstorageMethod from './methods/localstorage.js'; | ||
import SimulateMethod from './methods/simulate.js'; | ||
import { NativeMethod } from './methods/native.js'; | ||
import { IndexedDBMethod } from './methods/indexed-db.js'; | ||
import { LocalstorageMethod } from './methods/localstorage.js'; | ||
import { SimulateMethod } from './methods/simulate.js'; | ||
// the line below will be removed from es5/browser builds | ||
@@ -11,3 +11,3 @@ import * as NodeMethod from './methods/node.js'; | ||
// fastest | ||
IndexeDbMethod, LocalstorageMethod]; | ||
IndexedDBMethod, LocalstorageMethod]; | ||
export function chooseMethod(options) { | ||
@@ -33,3 +33,3 @@ var chooseMethods = [].concat(options.methods, METHODS).filter(Boolean); | ||
* if no webworker support is needed, | ||
* remove idb from the list so that localstorage is been chosen | ||
* remove idb from the list so that localstorage will be chosen | ||
*/ | ||
@@ -44,5 +44,5 @@ if (!options.webWorkerSupport) { | ||
}); | ||
if (!useMethod) throw new Error("No useable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
if (!useMethod) throw new Error("No usable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
return m.type; | ||
})));else return useMethod; | ||
} |
/** | ||
* if you really need this method, | ||
* implement it | ||
* implement it! | ||
*/ |
@@ -64,3 +64,3 @@ /** | ||
}; | ||
var dbPromise = new Promise(function (res, rej) { | ||
return new Promise(function (res, rej) { | ||
openRequest.onerror = function (ev) { | ||
@@ -73,3 +73,2 @@ return rej(ev); | ||
}); | ||
return dbPromise; | ||
} | ||
@@ -206,3 +205,2 @@ | ||
res(ret); | ||
return; | ||
} | ||
@@ -237,3 +235,3 @@ } else { | ||
eMIs: new ObliviousSet(options.idb.ttl * 2), | ||
// ensures we do not read messages in parrallel | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: PROMISE_RESOLVED_VOID, | ||
@@ -292,3 +290,3 @@ messagesCallback: null, | ||
/** | ||
* there is a bug in iOS where the msgObj can be undefined some times | ||
* there is a bug in iOS where the msgObj can be undefined sometimes | ||
* so we filter them out | ||
@@ -338,7 +336,3 @@ * @link https://github.com/pubkey/broadcast-channel/issues/19 | ||
export function canBeUsed() { | ||
var idb = getIdb(); | ||
if (!idb) { | ||
return false; | ||
} | ||
return true; | ||
return !!getIdb(); | ||
} | ||
@@ -348,3 +342,3 @@ export function averageResponseTime(options) { | ||
} | ||
export default { | ||
export var IndexedDBMethod = { | ||
create: create, | ||
@@ -351,0 +345,0 @@ close: close, |
/** | ||
* A localStorage-only method which uses localstorage and its 'storage'-event | ||
* This does not work inside of webworkers because they have no access to locastorage | ||
* This is basically implemented to support IE9 or your grandmothers toaster. | ||
* This does not work inside webworkers because they have no access to localstorage | ||
* This is basically implemented to support IE9 or your grandmother's toaster. | ||
* @link https://caniuse.com/#feat=namevalue-storage | ||
@@ -142,3 +142,3 @@ * @link https://caniuse.com/#feat=indexeddb | ||
} | ||
export default { | ||
export var LocalstorageMethod = { | ||
create: create, | ||
@@ -145,0 +145,0 @@ close: close, |
@@ -49,3 +49,3 @@ import { microSeconds as micro, PROMISE_RESOLVED_VOID } from '../util.js'; | ||
} | ||
export default { | ||
export var NativeMethod = { | ||
create: create, | ||
@@ -52,0 +52,0 @@ close: close, |
@@ -82,15 +82,13 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; | ||
return _regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!ENSURE_BASE_FOLDER_EXISTS_PROMISE) { | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = mkdir(TMP_FOLDER_BASE)["catch"](function () { | ||
return null; | ||
}); | ||
} | ||
return _context3.abrupt("return", ENSURE_BASE_FOLDER_EXISTS_PROMISE); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
while (1) switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!ENSURE_BASE_FOLDER_EXISTS_PROMISE) { | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = mkdir(TMP_FOLDER_BASE)["catch"](function () { | ||
return null; | ||
}); | ||
} | ||
return _context3.abrupt("return", ENSURE_BASE_FOLDER_EXISTS_PROMISE); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
@@ -113,31 +111,29 @@ }, _callee3); | ||
return _regeneratorRuntime.wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
_context4.next = 3; | ||
return ensureBaseFolderExists(); | ||
case 3: | ||
_context4.next = 5; | ||
return mkdir(paths.channelBase)["catch"](function () { | ||
return null; | ||
}); | ||
case 5: | ||
_context4.next = 7; | ||
return Promise.all([mkdir(paths.readers)["catch"](function () { | ||
return null; | ||
}), mkdir(paths.messages)["catch"](function () { | ||
return null; | ||
})]); | ||
case 7: | ||
// set permissions so other users can use the same channel | ||
chmodValue = '777'; | ||
_context4.next = 10; | ||
return Promise.all([chmod(paths.channelBase, chmodValue), chmod(paths.readers, chmodValue), chmod(paths.messages, chmodValue)])["catch"](function () { | ||
return null; | ||
}); | ||
case 10: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
while (1) switch (_context4.prev = _context4.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
_context4.next = 3; | ||
return ensureBaseFolderExists(); | ||
case 3: | ||
_context4.next = 5; | ||
return mkdir(paths.channelBase)["catch"](function () { | ||
return null; | ||
}); | ||
case 5: | ||
_context4.next = 7; | ||
return Promise.all([mkdir(paths.readers)["catch"](function () { | ||
return null; | ||
}), mkdir(paths.messages)["catch"](function () { | ||
return null; | ||
})]); | ||
case 7: | ||
// set permissions so other users can use the same channel | ||
chmodValue = '777'; | ||
_context4.next = 10; | ||
return Promise.all([chmod(paths.channelBase, chmodValue), chmod(paths.readers, chmodValue), chmod(paths.messages, chmodValue)])["catch"](function () { | ||
return null; | ||
}); | ||
case 10: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
@@ -154,21 +150,19 @@ }, _callee4); | ||
return _regeneratorRuntime.wrap(function _callee5$(_context5) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(!TMP_FOLDER_BASE || TMP_FOLDER_BASE === '' || TMP_FOLDER_BASE === '/')) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
throw new Error('BroadcastChannel.clearNodeFolder(): path is wrong'); | ||
case 2: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
_context5.next = 5; | ||
return removeDir(TMP_FOLDER_BASE); | ||
case 5: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
return _context5.abrupt("return", true); | ||
case 7: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
while (1) switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(!TMP_FOLDER_BASE || TMP_FOLDER_BASE === '' || TMP_FOLDER_BASE === '/')) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
throw new Error('BroadcastChannel.clearNodeFolder(): path is wrong'); | ||
case 2: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
_context5.next = 5; | ||
return removeDir(TMP_FOLDER_BASE); | ||
case 5: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
return _context5.abrupt("return", true); | ||
case 7: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
@@ -186,4 +180,3 @@ }, _callee5); | ||
paths = paths || getPaths(channelName); | ||
var socketPath = path.join(paths.readers, readerUuid + '.json'); | ||
return socketPath; | ||
return path.join(paths.readers, readerUuid + '.json'); | ||
} | ||
@@ -216,17 +209,15 @@ | ||
return _regeneratorRuntime.wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_context6.next = 2; | ||
return ensureBaseFolderExists(); | ||
case 2: | ||
_context6.next = 4; | ||
return readdir(TMP_FOLDER_BASE); | ||
case 4: | ||
folders = _context6.sent; | ||
return _context6.abrupt("return", folders.length); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
while (1) switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_context6.next = 2; | ||
return ensureBaseFolderExists(); | ||
case 2: | ||
_context6.next = 4; | ||
return readdir(TMP_FOLDER_BASE); | ||
case 4: | ||
folders = _context6.sent; | ||
return _context6.abrupt("return", folders.length); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
@@ -246,30 +237,27 @@ }, _callee6); | ||
_connectionError = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(originalError) { | ||
var count, addObj, text, newError; | ||
var count, addObj, text; | ||
return _regeneratorRuntime.wrap(function _callee7$(_context7) { | ||
while (1) { | ||
switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return countChannelFolders(); | ||
case 2: | ||
count = _context7.sent; | ||
if (!(count < 30)) { | ||
_context7.next = 5; | ||
break; | ||
} | ||
return _context7.abrupt("return", originalError); | ||
case 5: | ||
addObj = {}; | ||
Object.entries(originalError).forEach(function (_ref3) { | ||
var k = _ref3[0], | ||
v = _ref3[1]; | ||
return addObj[k] = v; | ||
}); | ||
text = 'BroadcastChannel.create(): error: ' + 'This might happen if you have created to many channels, ' + 'like when you use BroadcastChannel in unit-tests.' + 'Try using BroadcastChannel.clearNodeFolder() to clear the tmp-folder before each test.' + 'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
newError = new Error(text + ': ' + JSON.stringify(addObj, null, 2)); | ||
return _context7.abrupt("return", newError); | ||
case 10: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
while (1) switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return countChannelFolders(); | ||
case 2: | ||
count = _context7.sent; | ||
if (!(count < 30)) { | ||
_context7.next = 5; | ||
break; | ||
} | ||
return _context7.abrupt("return", originalError); | ||
case 5: | ||
addObj = {}; | ||
Object.entries(originalError).forEach(function (_ref3) { | ||
var k = _ref3[0], | ||
v = _ref3[1]; | ||
return addObj[k] = v; | ||
}); | ||
text = 'BroadcastChannel.create(): error: ' + 'This might happen if you have created to many channels, ' + 'like when you use BroadcastChannel in unit-tests.' + 'Try using BroadcastChannel.clearNodeFolder() to clear the tmp-folder before each test.' + 'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
return _context7.abrupt("return", new Error(text + ': ' + JSON.stringify(addObj, null, 2))); | ||
case 9: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
@@ -287,80 +275,74 @@ }, _callee7); | ||
return _regeneratorRuntime.wrap(function _callee10$(_context10) { | ||
while (1) { | ||
switch (_context10.prev = _context10.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid, paths); | ||
emitter = new events.EventEmitter(); | ||
server = net.createServer(function (stream) { | ||
stream.on('end', function () {}); | ||
stream.on('data', function (msg) { | ||
emitter.emit('data', msg.toString()); | ||
}); | ||
while (1) switch (_context10.prev = _context10.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid, paths); | ||
emitter = new events.EventEmitter(); | ||
server = net.createServer(function (stream) { | ||
stream.on('end', function () {}); | ||
stream.on('data', function (msg) { | ||
emitter.emit('data', msg.toString()); | ||
}); | ||
_context10.next = 5; | ||
return new Promise(function (resolve, reject) { | ||
server.on('error', /*#__PURE__*/function () { | ||
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(err) { | ||
var useErr; | ||
return _regeneratorRuntime.wrap(function _callee8$(_context8) { | ||
while (1) { | ||
switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return connectionError(err); | ||
case 2: | ||
useErr = _context8.sent; | ||
reject(useErr); | ||
case 4: | ||
case "end": | ||
return _context8.stop(); | ||
}); | ||
_context10.next = 5; | ||
return new Promise(function (resolve, reject) { | ||
server.on('error', /*#__PURE__*/function () { | ||
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(err) { | ||
var useErr; | ||
return _regeneratorRuntime.wrap(function _callee8$(_context8) { | ||
while (1) switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return connectionError(err); | ||
case 2: | ||
useErr = _context8.sent; | ||
reject(useErr); | ||
case 4: | ||
case "end": | ||
return _context8.stop(); | ||
} | ||
}, _callee8); | ||
})); | ||
return function (_x26) { | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}()); | ||
server.listen(pathToSocket, /*#__PURE__*/function () { | ||
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(err, res) { | ||
var useErr; | ||
return _regeneratorRuntime.wrap(function _callee9$(_context9) { | ||
while (1) switch (_context9.prev = _context9.next) { | ||
case 0: | ||
if (!err) { | ||
_context9.next = 7; | ||
break; | ||
} | ||
} | ||
}, _callee8); | ||
})); | ||
return function (_x26) { | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}()); | ||
server.listen(pathToSocket, /*#__PURE__*/function () { | ||
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(err, res) { | ||
var useErr; | ||
return _regeneratorRuntime.wrap(function _callee9$(_context9) { | ||
while (1) { | ||
switch (_context9.prev = _context9.next) { | ||
case 0: | ||
if (!err) { | ||
_context9.next = 7; | ||
break; | ||
} | ||
_context9.next = 3; | ||
return connectionError(err); | ||
case 3: | ||
useErr = _context9.sent; | ||
reject(useErr); | ||
_context9.next = 8; | ||
break; | ||
case 7: | ||
resolve(res); | ||
case 8: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
} | ||
}, _callee9); | ||
})); | ||
return function (_x27, _x28) { | ||
return _ref5.apply(this, arguments); | ||
}; | ||
}()); | ||
}); | ||
case 5: | ||
return _context10.abrupt("return", { | ||
path: pathToSocket, | ||
emitter: emitter, | ||
server: server | ||
}); | ||
case 6: | ||
case "end": | ||
return _context10.stop(); | ||
} | ||
_context9.next = 3; | ||
return connectionError(err); | ||
case 3: | ||
useErr = _context9.sent; | ||
reject(useErr); | ||
_context9.next = 8; | ||
break; | ||
case 7: | ||
resolve(res); | ||
case 8: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
}, _callee9); | ||
})); | ||
return function (_x27, _x28) { | ||
return _ref5.apply(this, arguments); | ||
}; | ||
}()); | ||
}); | ||
case 5: | ||
return _context10.abrupt("return", { | ||
path: pathToSocket, | ||
emitter: emitter, | ||
server: server | ||
}); | ||
case 6: | ||
case "end": | ||
return _context10.stop(); | ||
} | ||
@@ -384,19 +366,17 @@ }, _callee10); | ||
return _regeneratorRuntime.wrap(function _callee11$(_context11) { | ||
while (1) { | ||
switch (_context11.prev = _context11.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid); | ||
client = new net.Socket(); | ||
return _context11.abrupt("return", new Promise(function (res, rej) { | ||
client.connect(pathToSocket, function () { | ||
return res(client); | ||
}); | ||
client.on('error', function (err) { | ||
return rej(err); | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context11.stop(); | ||
} | ||
while (1) switch (_context11.prev = _context11.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid); | ||
client = new net.Socket(); | ||
return _context11.abrupt("return", new Promise(function (res, rej) { | ||
client.connect(pathToSocket, function () { | ||
return res(client); | ||
}); | ||
client.on('error', function (err) { | ||
return rej(err); | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context11.stop(); | ||
} | ||
@@ -439,23 +419,21 @@ }, _callee11); | ||
return _regeneratorRuntime.wrap(function _callee12$(_context12) { | ||
while (1) { | ||
switch (_context12.prev = _context12.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
readersPath = paths.readers; | ||
_context12.next = 4; | ||
return readdir(readersPath); | ||
case 4: | ||
files = _context12.sent; | ||
return _context12.abrupt("return", files.map(function (file) { | ||
return file.split('.'); | ||
}).filter(function (split) { | ||
return split[1] === 'json'; | ||
}) // do not scan .socket-files | ||
.map(function (split) { | ||
return split[0]; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
while (1) switch (_context12.prev = _context12.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
readersPath = paths.readers; | ||
_context12.next = 4; | ||
return readdir(readersPath); | ||
case 4: | ||
files = _context12.sent; | ||
return _context12.abrupt("return", files.map(function (file) { | ||
return file.split('.'); | ||
}).filter(function (split) { | ||
return split[1] === 'json'; | ||
}) // do not scan .socket-files | ||
.map(function (split) { | ||
return split[0]; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
@@ -471,14 +449,11 @@ }, _callee12); | ||
_messagePath = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13(channelName, time, token, writerUuid) { | ||
var fileName, msgPath; | ||
var fileName; | ||
return _regeneratorRuntime.wrap(function _callee13$(_context13) { | ||
while (1) { | ||
switch (_context13.prev = _context13.next) { | ||
case 0: | ||
fileName = time + '_' + writerUuid + '_' + token + '.json'; | ||
msgPath = path.join(getPaths(channelName).messages, fileName); | ||
return _context13.abrupt("return", msgPath); | ||
case 3: | ||
case "end": | ||
return _context13.stop(); | ||
} | ||
while (1) switch (_context13.prev = _context13.next) { | ||
case 0: | ||
fileName = time + '_' + writerUuid + '_' + token + '.json'; | ||
return _context13.abrupt("return", path.join(getPaths(channelName).messages, fileName)); | ||
case 2: | ||
case "end": | ||
return _context13.stop(); | ||
} | ||
@@ -496,25 +471,23 @@ }, _callee13); | ||
return _regeneratorRuntime.wrap(function _callee14$(_context14) { | ||
while (1) { | ||
switch (_context14.prev = _context14.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
messagesPath = paths.messages; | ||
_context14.next = 4; | ||
return readdir(messagesPath); | ||
case 4: | ||
files = _context14.sent; | ||
return _context14.abrupt("return", files.map(function (file) { | ||
var fileName = file.split('.')[0]; | ||
var split = fileName.split('_'); | ||
return { | ||
path: path.join(messagesPath, file), | ||
time: parseInt(split[0]), | ||
senderUuid: split[1], | ||
token: split[2] | ||
}; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context14.stop(); | ||
} | ||
while (1) switch (_context14.prev = _context14.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
messagesPath = paths.messages; | ||
_context14.next = 4; | ||
return readdir(messagesPath); | ||
case 4: | ||
files = _context14.sent; | ||
return _context14.abrupt("return", files.map(function (file) { | ||
var fileName = file.split('.')[0]; | ||
var split = fileName.split('_'); | ||
return { | ||
path: path.join(messagesPath, file), | ||
time: parseInt(split[0]), | ||
senderUuid: split[1], | ||
token: split[2] | ||
}; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context14.stop(); | ||
} | ||
@@ -544,20 +517,18 @@ }, _callee14); | ||
_cleanOldMessages = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee15(messageObjects, ttl) { | ||
var olderThen; | ||
var olderThan; | ||
return _regeneratorRuntime.wrap(function _callee15$(_context15) { | ||
while (1) { | ||
switch (_context15.prev = _context15.next) { | ||
case 0: | ||
olderThen = microSeconds() - ttl * 1000; // convert ttl to microseconds | ||
_context15.next = 3; | ||
return Promise.all(messageObjects.filter(function (obj) { | ||
return obj.time < olderThen; | ||
}).map(function (obj) { | ||
return unlink(obj.path)["catch"](function () { | ||
return null; | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context15.stop(); | ||
} | ||
while (1) switch (_context15.prev = _context15.next) { | ||
case 0: | ||
olderThan = microSeconds() - ttl * 1000; // convert ttl to microseconds | ||
_context15.next = 3; | ||
return Promise.all(messageObjects.filter(function (obj) { | ||
return obj.time < olderThan; | ||
}).map(function (obj) { | ||
return unlink(obj.path)["catch"](function () { | ||
return null; | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context15.stop(); | ||
} | ||
@@ -590,73 +561,71 @@ }, _callee15); | ||
return _regeneratorRuntime.wrap(function _callee16$(_context16) { | ||
while (1) { | ||
switch (_context16.prev = _context16.next) { | ||
case 0: | ||
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {}; | ||
options = fillOptionsWithDefaults(options); | ||
time = microSeconds(); | ||
paths = getPaths(channelName); | ||
ensureFolderExistsPromise = ensureFoldersExist(channelName, paths); | ||
uuid = randomToken(); | ||
state = { | ||
time: time, | ||
channelName: channelName, | ||
options: options, | ||
uuid: uuid, | ||
paths: paths, | ||
// contains all messages that have been emitted before | ||
emittedMessagesIds: new ObliviousSet(options.node.ttl * 2), | ||
/** | ||
* Used to ensure we do not write too many files at once | ||
* which could throw an error. | ||
* Must always be smaller then options.node.maxParallelWrites | ||
*/ | ||
writeFileQueue: new PQueue({ | ||
concurrency: options.node.maxParallelWrites | ||
}), | ||
messagesCallbackTime: null, | ||
messagesCallback: null, | ||
// ensures we do not read messages in parrallel | ||
writeBlockPromise: PROMISE_RESOLVED_VOID, | ||
otherReaderClients: {}, | ||
// ensure if process crashes, everything is cleaned up | ||
removeUnload: unloadAdd(function () { | ||
return close(state); | ||
}), | ||
closed: false | ||
}; | ||
if (!OTHER_INSTANCES[channelName]) OTHER_INSTANCES[channelName] = []; | ||
OTHER_INSTANCES[channelName].push(state); | ||
_context16.next = 11; | ||
return ensureFolderExistsPromise; | ||
case 11: | ||
_context16.next = 13; | ||
return Promise.all([createSocketEventEmitter(channelName, uuid, paths), createSocketInfoFile(channelName, uuid, paths), refreshReaderClients(state)]); | ||
case 13: | ||
_yield$Promise$all = _context16.sent; | ||
socketEE = _yield$Promise$all[0]; | ||
infoFilePath = _yield$Promise$all[1]; | ||
state.socketEE = socketEE; | ||
state.infoFilePath = infoFilePath; | ||
while (1) switch (_context16.prev = _context16.next) { | ||
case 0: | ||
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {}; | ||
options = fillOptionsWithDefaults(options); | ||
time = microSeconds(); | ||
paths = getPaths(channelName); | ||
ensureFolderExistsPromise = ensureFoldersExist(channelName, paths); | ||
uuid = randomToken(); | ||
state = { | ||
time: time, | ||
channelName: channelName, | ||
options: options, | ||
uuid: uuid, | ||
paths: paths, | ||
// contains all messages that have been emitted before | ||
emittedMessagesIds: new ObliviousSet(options.node.ttl * 2), | ||
/** | ||
* Used to ensure we do not write too many files at once | ||
* which could throw an error. | ||
* Must always be smaller than options.node.maxParallelWrites | ||
*/ | ||
writeFileQueue: new PQueue({ | ||
concurrency: options.node.maxParallelWrites | ||
}), | ||
messagesCallbackTime: null, | ||
messagesCallback: null, | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: PROMISE_RESOLVED_VOID, | ||
otherReaderClients: {}, | ||
// ensure if process crashes, everything is cleaned up | ||
removeUnload: unloadAdd(function () { | ||
return close(state); | ||
}), | ||
closed: false | ||
}; | ||
if (!OTHER_INSTANCES[channelName]) OTHER_INSTANCES[channelName] = []; | ||
OTHER_INSTANCES[channelName].push(state); | ||
_context16.next = 11; | ||
return ensureFolderExistsPromise; | ||
case 11: | ||
_context16.next = 13; | ||
return Promise.all([createSocketEventEmitter(channelName, uuid, paths), createSocketInfoFile(channelName, uuid, paths), refreshReaderClients(state)]); | ||
case 13: | ||
_yield$Promise$all = _context16.sent; | ||
socketEE = _yield$Promise$all[0]; | ||
infoFilePath = _yield$Promise$all[1]; | ||
state.socketEE = socketEE; | ||
state.infoFilePath = infoFilePath; | ||
// when new message comes in, we read it and emit it | ||
socketEE.emitter.on('data', function (data) { | ||
// if the socket is used fast, it may appear that multiple messages are flushed at once | ||
// so we have to split them before | ||
var singleOnes = data.split('|'); | ||
singleOnes.filter(function (single) { | ||
return single !== ''; | ||
}).forEach(function (single) { | ||
try { | ||
var obj = JSON.parse(single); | ||
handleMessagePing(state, obj); | ||
} catch (err) { | ||
throw new Error('could not parse data: ' + single); | ||
} | ||
}); | ||
// when new message comes in, we read it and emit it | ||
socketEE.emitter.on('data', function (data) { | ||
// if the socket is used fast, it may appear that multiple messages are flushed at once | ||
// so we have to split them before | ||
var singleOnes = data.split('|'); | ||
singleOnes.filter(function (single) { | ||
return single !== ''; | ||
}).forEach(function (single) { | ||
try { | ||
var obj = JSON.parse(single); | ||
handleMessagePing(state, obj); | ||
} catch (err) { | ||
throw new Error('could not parse data: ' + single); | ||
} | ||
}); | ||
return _context16.abrupt("return", state); | ||
case 20: | ||
case "end": | ||
return _context16.stop(); | ||
} | ||
}); | ||
return _context16.abrupt("return", state); | ||
case 20: | ||
case "end": | ||
return _context16.stop(); | ||
} | ||
@@ -694,55 +663,53 @@ }, _callee16); | ||
return _regeneratorRuntime.wrap(function _callee17$(_context17) { | ||
while (1) { | ||
switch (_context17.prev = _context17.next) { | ||
case 0: | ||
while (1) switch (_context17.prev = _context17.next) { | ||
case 0: | ||
if (state.messagesCallback) { | ||
_context17.next = 2; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 2: | ||
if (msgObj) { | ||
_context17.next = 8; | ||
break; | ||
} | ||
_context17.next = 5; | ||
return getAllMessages(state.channelName, state.paths); | ||
case 5: | ||
messages = _context17.sent; | ||
_context17.next = 9; | ||
break; | ||
case 8: | ||
// get single message | ||
messages = [getSingleMessage(state.channelName, msgObj, state.paths)]; | ||
case 9: | ||
useMessages = messages.filter(function (msgObj) { | ||
return _filterMessage(msgObj, state); | ||
}).sort(function (msgObjA, msgObjB) { | ||
return msgObjA.time - msgObjB.time; | ||
}); // sort by time | ||
// if no listener or message, so not do anything | ||
if (!(!useMessages.length || !state.messagesCallback)) { | ||
_context17.next = 12; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 12: | ||
_context17.next = 14; | ||
return Promise.all(useMessages.map(function (msgObj) { | ||
return readMessage(msgObj).then(function (content) { | ||
return msgObj.content = content; | ||
}); | ||
})); | ||
case 14: | ||
useMessages.forEach(function (msgObj) { | ||
state.emittedMessagesIds.add(msgObj.token); | ||
if (state.messagesCallback) { | ||
_context17.next = 2; | ||
break; | ||
// emit to subscribers | ||
state.messagesCallback(msgObj.content.data); | ||
} | ||
return _context17.abrupt("return"); | ||
case 2: | ||
if (msgObj) { | ||
_context17.next = 8; | ||
break; | ||
} | ||
_context17.next = 5; | ||
return getAllMessages(state.channelName, state.paths); | ||
case 5: | ||
messages = _context17.sent; | ||
_context17.next = 9; | ||
break; | ||
case 8: | ||
// get single message | ||
messages = [getSingleMessage(state.channelName, msgObj, state.paths)]; | ||
case 9: | ||
useMessages = messages.filter(function (msgObj) { | ||
return _filterMessage(msgObj, state); | ||
}).sort(function (msgObjA, msgObjB) { | ||
return msgObjA.time - msgObjB.time; | ||
}); // sort by time | ||
// if no listener or message, so not do anything | ||
if (!(!useMessages.length || !state.messagesCallback)) { | ||
_context17.next = 12; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 12: | ||
_context17.next = 14; | ||
return Promise.all(useMessages.map(function (msgObj) { | ||
return readMessage(msgObj).then(function (content) { | ||
return msgObj.content = content; | ||
}); | ||
})); | ||
case 14: | ||
useMessages.forEach(function (msgObj) { | ||
state.emittedMessagesIds.add(msgObj.token); | ||
if (state.messagesCallback) { | ||
// emit to subscribers | ||
state.messagesCallback(msgObj.content.data); | ||
} | ||
}); | ||
case 15: | ||
case "end": | ||
return _context17.stop(); | ||
} | ||
}); | ||
case 15: | ||
case "end": | ||
return _context17.stop(); | ||
} | ||
@@ -761,20 +728,18 @@ }, _callee17); | ||
return _regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.prev = 0; | ||
_context.next = 3; | ||
return channelState.otherReaderClients[readerUuid].destroy(); | ||
case 3: | ||
_context.next = 7; | ||
break; | ||
case 5: | ||
_context.prev = 5; | ||
_context.t0 = _context["catch"](0); | ||
case 7: | ||
delete channelState.otherReaderClients[readerUuid]; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
while (1) switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.prev = 0; | ||
_context.next = 3; | ||
return channelState.otherReaderClients[readerUuid].destroy(); | ||
case 3: | ||
_context.next = 7; | ||
break; | ||
case 5: | ||
_context.prev = 5; | ||
_context.t0 = _context["catch"](0); | ||
case 7: | ||
delete channelState.otherReaderClients[readerUuid]; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
@@ -799,33 +764,31 @@ }, _callee, null, [[0, 5]]); | ||
return _regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
if (!channelState.closed) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
case 3: | ||
_context2.prev = 3; | ||
_context2.next = 6; | ||
return openClientConnection(channelState.channelName, readerUuid); | ||
case 6: | ||
client = _context2.sent; | ||
channelState.otherReaderClients[readerUuid] = client; | ||
_context2.next = 12; | ||
while (1) switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
if (!channelState.closed) { | ||
_context2.next = 3; | ||
break; | ||
case 10: | ||
_context2.prev = 10; | ||
_context2.t0 = _context2["catch"](3); | ||
case 12: | ||
_context2.next = 16; | ||
break; | ||
case 14: | ||
_context2.prev = 14; | ||
_context2.t1 = _context2["catch"](0); | ||
case 16: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
return _context2.abrupt("return"); | ||
case 3: | ||
_context2.prev = 3; | ||
_context2.next = 6; | ||
return openClientConnection(channelState.channelName, readerUuid); | ||
case 6: | ||
client = _context2.sent; | ||
channelState.otherReaderClients[readerUuid] = client; | ||
_context2.next = 12; | ||
break; | ||
case 10: | ||
_context2.prev = 10; | ||
_context2.t0 = _context2["catch"](3); | ||
case 12: | ||
_context2.next = 16; | ||
break; | ||
case 14: | ||
_context2.prev = 14; | ||
_context2.t1 = _context2["catch"](0); | ||
case 16: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
@@ -859,58 +822,54 @@ }, _callee2, null, [[0, 14], [3, 10]]); | ||
return _regeneratorRuntime.wrap(function _callee19$(_context19) { | ||
while (1) { | ||
switch (_context19.prev = _context19.next) { | ||
case 0: | ||
writePromise = channelState.writeFileQueue.add(function () { | ||
return writeMessage(channelState.channelName, channelState.uuid, messageJson, channelState.paths); | ||
}); | ||
channelState.writeBlockPromise = channelState.writeBlockPromise.then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee18() { | ||
var _yield$Promise$all2, msgObj, pingStr, writeToReadersPromise; | ||
return _regeneratorRuntime.wrap(function _callee18$(_context18) { | ||
while (1) { | ||
switch (_context18.prev = _context18.next) { | ||
case 0: | ||
_context18.next = 2; | ||
return new Promise(function (res) { | ||
return setTimeout(res, 0); | ||
}); | ||
case 2: | ||
_context18.next = 4; | ||
return Promise.all([writePromise, refreshReaderClients(channelState)]); | ||
case 4: | ||
_yield$Promise$all2 = _context18.sent; | ||
msgObj = _yield$Promise$all2[0]; | ||
emitOverFastPath(channelState, msgObj, messageJson); | ||
pingStr = '{"t":' + msgObj.time + ',"u":"' + msgObj.uuid + '","to":"' + msgObj.token + '"}|'; | ||
writeToReadersPromise = Promise.all(Object.values(channelState.otherReaderClients).filter(function (client) { | ||
return client.writable; | ||
}) // client might have closed in between | ||
.map(function (client) { | ||
return new Promise(function (res) { | ||
client.write(pingStr, res); | ||
}); | ||
})); | ||
/** | ||
* clean up old messages | ||
* to not waste resources on cleaning up, | ||
* only if random-int matches, we clean up old messages | ||
*/ | ||
if (randomInt(0, 20) === 0) { | ||
/* await */ | ||
getAllMessages(channelState.channelName, channelState.paths).then(function (allMessages) { | ||
return cleanOldMessages(allMessages, channelState.options.node.ttl); | ||
}); | ||
} | ||
return _context18.abrupt("return", writeToReadersPromise); | ||
case 11: | ||
case "end": | ||
return _context18.stop(); | ||
while (1) switch (_context19.prev = _context19.next) { | ||
case 0: | ||
writePromise = channelState.writeFileQueue.add(function () { | ||
return writeMessage(channelState.channelName, channelState.uuid, messageJson, channelState.paths); | ||
}); | ||
channelState.writeBlockPromise = channelState.writeBlockPromise.then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee18() { | ||
var _yield$Promise$all2, msgObj, pingStr, writeToReadersPromise; | ||
return _regeneratorRuntime.wrap(function _callee18$(_context18) { | ||
while (1) switch (_context18.prev = _context18.next) { | ||
case 0: | ||
_context18.next = 2; | ||
return new Promise(function (res) { | ||
return setTimeout(res, 0); | ||
}); | ||
case 2: | ||
_context18.next = 4; | ||
return Promise.all([writePromise, refreshReaderClients(channelState)]); | ||
case 4: | ||
_yield$Promise$all2 = _context18.sent; | ||
msgObj = _yield$Promise$all2[0]; | ||
emitOverFastPath(channelState, msgObj, messageJson); | ||
pingStr = '{"t":' + msgObj.time + ',"u":"' + msgObj.uuid + '","to":"' + msgObj.token + '"}|'; | ||
writeToReadersPromise = Promise.all(Object.values(channelState.otherReaderClients).filter(function (client) { | ||
return client.writable; | ||
}) // client might have closed in between | ||
.map(function (client) { | ||
return new Promise(function (res) { | ||
client.write(pingStr, res); | ||
}); | ||
})); | ||
/** | ||
* clean up old messages | ||
* to not waste resources on cleaning up, | ||
* only if random-int matches, we clean up old messages | ||
*/ | ||
if (randomInt(0, 20) === 0) { | ||
/* await */ | ||
getAllMessages(channelState.channelName, channelState.paths).then(function (allMessages) { | ||
return cleanOldMessages(allMessages, channelState.options.node.ttl); | ||
}); | ||
} | ||
} | ||
}, _callee18); | ||
}))); | ||
return _context19.abrupt("return", channelState.writeBlockPromise); | ||
case 3: | ||
case "end": | ||
return _context19.stop(); | ||
} | ||
return _context18.abrupt("return", writeToReadersPromise); | ||
case 11: | ||
case "end": | ||
return _context18.stop(); | ||
} | ||
}, _callee18); | ||
}))); | ||
return _context19.abrupt("return", channelState.writeBlockPromise); | ||
case 3: | ||
case "end": | ||
return _context19.stop(); | ||
} | ||
@@ -952,3 +911,3 @@ }, _callee19); | ||
export function close(channelState) { | ||
if (channelState.closed) return; | ||
if (channelState.closed) return PROMISE_RESOLVED_VOID; | ||
channelState.closed = true; | ||
@@ -984,14 +943,10 @@ channelState.emittedMessagesIds.clear(); | ||
export function canBeUsed() { | ||
if (typeof fs.mkdir === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return typeof fs.mkdir === 'function'; | ||
} | ||
/** | ||
* on node we use a relatively height averageResponseTime, | ||
* on node we use a relatively high averageResponseTime, | ||
* because the file-io might be in use. | ||
* Also it is more important that the leader-election is reliable, | ||
* then to have a fast election. | ||
* than to have a fast election. | ||
*/ | ||
@@ -998,0 +953,0 @@ export function averageResponseTime() { |
@@ -42,3 +42,3 @@ import { microSeconds as micro } from '../util.js'; | ||
} | ||
export default { | ||
export var SimulateMethod = { | ||
create: create, | ||
@@ -45,0 +45,0 @@ close: close, |
@@ -5,7 +5,3 @@ /** | ||
export function isPromise(obj) { | ||
if (obj && typeof obj.then === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return obj && typeof obj.then === 'function'; | ||
} | ||
@@ -12,0 +8,0 @@ export var PROMISE_RESOLVED_FALSE = Promise.resolve(false); |
@@ -49,3 +49,3 @@ "use strict"; | ||
/** | ||
* Unsend message promises | ||
* Unsent message promises | ||
* where the sending is still in progress | ||
@@ -111,3 +111,3 @@ * @type {Set<Promise>} | ||
/** | ||
* In the past when this error appeared, it was realy hard to debug. | ||
* In the past when this error appeared, it was really hard to debug. | ||
* So now we log the msg together with the error so it at least | ||
@@ -200,3 +200,3 @@ * gives some clue about where in your application this happens. | ||
// add/remove to unsend messages list | ||
// add/remove to unsent messages list | ||
broadcastChannel._uMP.add(sendPromise); | ||
@@ -247,4 +247,4 @@ sendPromise["catch"]().then(function () { | ||
* Getting the current time in JavaScript has no good precision. | ||
* So instead of only listening to events that happend 'after' the listener | ||
* was added, we also listen to events that happended 100ms before it. | ||
* So instead of only listening to events that happened 'after' the listener | ||
* was added, we also listen to events that happened 100ms before it. | ||
* This ensures that when another process, like a WebWorker, sends events | ||
@@ -276,3 +276,3 @@ * we do not miss them out because their timestamp is a bit off compared to the main process. | ||
if (channel._iL && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
// no one is listening, stop subscribing | ||
channel._iL = false; | ||
@@ -279,0 +279,0 @@ var time = channel.method.microSeconds(); |
@@ -50,3 +50,3 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ | ||
/** | ||
* Unsend message promises | ||
* Unsent message promises | ||
* where the sending is still in progress | ||
@@ -112,3 +112,3 @@ * @type {Set<Promise>} | ||
/** | ||
* In the past when this error appeared, it was realy hard to debug. | ||
* In the past when this error appeared, it was really hard to debug. | ||
* So now we log the msg together with the error so it at least | ||
@@ -201,3 +201,3 @@ * gives some clue about where in your application this happens. | ||
// add/remove to unsend messages list | ||
// add/remove to unsent messages list | ||
broadcastChannel._uMP.add(sendPromise); | ||
@@ -248,4 +248,4 @@ sendPromise["catch"]().then(function () { | ||
* Getting the current time in JavaScript has no good precision. | ||
* So instead of only listening to events that happend 'after' the listener | ||
* was added, we also listen to events that happended 100ms before it. | ||
* So instead of only listening to events that happened 'after' the listener | ||
* was added, we also listen to events that happened 100ms before it. | ||
* This ensures that when another process, like a WebWorker, sends events | ||
@@ -277,3 +277,3 @@ * we do not miss them out because their timestamp is a bit off compared to the main process. | ||
if (channel._iL && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
// no one is listening, stop subscribing | ||
channel._iL = false; | ||
@@ -426,3 +426,3 @@ var time = channel.method.microSeconds(); | ||
/** | ||
* Already applying more then once, | ||
* Already applying more than once, | ||
* -> wait for the apply queue to be finished. | ||
@@ -460,6 +460,4 @@ */ | ||
}); | ||
var recieved = []; | ||
var handleMessage = function handleMessage(msg) { | ||
if (msg.context === 'leader' && msg.token != _this2.token) { | ||
recieved.push(msg); | ||
if (msg.action === 'apply') { | ||
@@ -488,3 +486,3 @@ // other is applying | ||
* not critical process is waiting for it. | ||
* When this is true, we give the other intances | ||
* When this is true, we give the other instances | ||
* more time to answer to messages in the election cycle. | ||
@@ -496,3 +494,3 @@ * This makes it less likely to elect duplicate leaders. | ||
var waitForAnswerTime = isFromFallbackInterval ? _this2._options.responseTime * 4 : _this2._options.responseTime; | ||
var applyPromise = _sendMessage(_this2, 'apply') // send out that this one is applying | ||
return _sendMessage(_this2, 'apply') // send out that this one is applying | ||
.then(function () { | ||
@@ -524,3 +522,2 @@ return Promise.race([(0, _util.sleep)(waitForAnswerTime), stopCriteriaPromise.then(function () { | ||
}); | ||
return applyPromise; | ||
}; | ||
@@ -695,6 +692,5 @@ this._aplQC = this._aplQC + 1; | ||
} | ||
},{"./util.js":12,"unload":19}],6:[function(require,module,exports){ | ||
},{"./util.js":12,"unload":18}],6:[function(require,module,exports){ | ||
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
var _typeof = require("@babel/runtime/helpers/typeof"); | ||
@@ -705,6 +701,6 @@ Object.defineProperty(exports, "__esModule", { | ||
exports.chooseMethod = chooseMethod; | ||
var _native = _interopRequireDefault(require("./methods/native.js")); | ||
var _indexedDb = _interopRequireDefault(require("./methods/indexed-db.js")); | ||
var _localstorage = _interopRequireDefault(require("./methods/localstorage.js")); | ||
var _simulate = _interopRequireDefault(require("./methods/simulate.js")); | ||
var _native = require("./methods/native.js"); | ||
var _indexedDb = require("./methods/indexed-db.js"); | ||
var _localstorage = require("./methods/localstorage.js"); | ||
var _simulate = require("./methods/simulate.js"); | ||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } | ||
@@ -715,5 +711,5 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } | ||
// order is important | ||
var METHODS = [_native["default"], | ||
var METHODS = [_native.NativeMethod, | ||
// fastest | ||
_indexedDb["default"], _localstorage["default"]]; | ||
_indexedDb.IndexedDBMethod, _localstorage.LocalstorageMethod]; | ||
function chooseMethod(options) { | ||
@@ -728,3 +724,3 @@ var chooseMethods = [].concat(options.methods, METHODS).filter(Boolean); | ||
// only use simulate-method if directly chosen | ||
return _simulate["default"]; | ||
return _simulate.SimulateMethod; | ||
} | ||
@@ -739,3 +735,3 @@ var ret = chooseMethods.find(function (m) { | ||
* if no webworker support is needed, | ||
* remove idb from the list so that localstorage is been chosen | ||
* remove idb from the list so that localstorage will be chosen | ||
*/ | ||
@@ -750,7 +746,7 @@ if (!options.webWorkerSupport) { | ||
}); | ||
if (!useMethod) throw new Error("No useable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
if (!useMethod) throw new Error("No usable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
return m.type; | ||
})));else return useMethod; | ||
} | ||
},{"./methods/indexed-db.js":7,"./methods/localstorage.js":8,"./methods/native.js":9,"./methods/simulate.js":10,"@babel/runtime/helpers/interopRequireDefault":13,"@babel/runtime/helpers/typeof":14}],7:[function(require,module,exports){ | ||
},{"./methods/indexed-db.js":7,"./methods/localstorage.js":8,"./methods/native.js":9,"./methods/simulate.js":10,"@babel/runtime/helpers/typeof":13}],7:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -761,3 +757,3 @@ | ||
}); | ||
exports.TRANSACTION_SETTINGS = void 0; | ||
exports.TRANSACTION_SETTINGS = exports.IndexedDBMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -770,3 +766,2 @@ exports.canBeUsed = canBeUsed; | ||
exports.createDatabase = createDatabase; | ||
exports["default"] = void 0; | ||
exports.getAllMessages = getAllMessages; | ||
@@ -848,3 +843,3 @@ exports.getIdb = getIdb; | ||
}; | ||
var dbPromise = new Promise(function (res, rej) { | ||
return new Promise(function (res, rej) { | ||
openRequest.onerror = function (ev) { | ||
@@ -857,3 +852,2 @@ return rej(ev); | ||
}); | ||
return dbPromise; | ||
} | ||
@@ -990,3 +984,2 @@ | ||
res(ret); | ||
return; | ||
} | ||
@@ -1021,3 +1014,3 @@ } else { | ||
eMIs: new _obliviousSet.ObliviousSet(options.idb.ttl * 2), | ||
// ensures we do not read messages in parrallel | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: _util.PROMISE_RESOLVED_VOID, | ||
@@ -1076,3 +1069,3 @@ messagesCallback: null, | ||
/** | ||
* there is a bug in iOS where the msgObj can be undefined some times | ||
* there is a bug in iOS where the msgObj can be undefined sometimes | ||
* so we filter them out | ||
@@ -1122,7 +1115,3 @@ * @link https://github.com/pubkey/broadcast-channel/issues/19 | ||
function canBeUsed() { | ||
var idb = getIdb(); | ||
if (!idb) { | ||
return false; | ||
} | ||
return true; | ||
return !!getIdb(); | ||
} | ||
@@ -1132,3 +1121,3 @@ function averageResponseTime(options) { | ||
} | ||
var _default = { | ||
var IndexedDBMethod = { | ||
create: create, | ||
@@ -1143,4 +1132,4 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
},{"../options.js":11,"../util.js":12,"oblivious-set":17}],8:[function(require,module,exports){ | ||
exports.IndexedDBMethod = IndexedDBMethod; | ||
},{"../options.js":11,"../util.js":12,"oblivious-set":15}],8:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -1151,2 +1140,3 @@ | ||
}); | ||
exports.LocalstorageMethod = void 0; | ||
exports.addStorageEventListener = addStorageEventListener; | ||
@@ -1157,3 +1147,2 @@ exports.averageResponseTime = averageResponseTime; | ||
exports.create = create; | ||
exports["default"] = void 0; | ||
exports.getLocalStorage = getLocalStorage; | ||
@@ -1171,4 +1160,4 @@ exports.microSeconds = void 0; | ||
* A localStorage-only method which uses localstorage and its 'storage'-event | ||
* This does not work inside of webworkers because they have no access to locastorage | ||
* This is basically implemented to support IE9 or your grandmothers toaster. | ||
* This does not work inside webworkers because they have no access to localstorage | ||
* This is basically implemented to support IE9 or your grandmother's toaster. | ||
* @link https://caniuse.com/#feat=namevalue-storage | ||
@@ -1310,3 +1299,3 @@ * @link https://caniuse.com/#feat=indexeddb | ||
} | ||
var _default = { | ||
var LocalstorageMethod = { | ||
create: create, | ||
@@ -1321,4 +1310,4 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
},{"../options.js":11,"../util.js":12,"oblivious-set":17}],9:[function(require,module,exports){ | ||
exports.LocalstorageMethod = LocalstorageMethod; | ||
},{"../options.js":11,"../util.js":12,"oblivious-set":15}],9:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -1329,2 +1318,3 @@ | ||
}); | ||
exports.NativeMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -1334,3 +1324,3 @@ exports.canBeUsed = canBeUsed; | ||
exports.create = create; | ||
exports.microSeconds = exports["default"] = void 0; | ||
exports.microSeconds = void 0; | ||
exports.onMessage = onMessage; | ||
@@ -1389,3 +1379,3 @@ exports.postMessage = postMessage; | ||
} | ||
var _default = { | ||
var NativeMethod = { | ||
create: create, | ||
@@ -1400,3 +1390,3 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.NativeMethod = NativeMethod; | ||
},{"../util.js":12}],10:[function(require,module,exports){ | ||
@@ -1408,2 +1398,3 @@ "use strict"; | ||
}); | ||
exports.SimulateMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -1413,3 +1404,3 @@ exports.canBeUsed = canBeUsed; | ||
exports.create = create; | ||
exports.microSeconds = exports["default"] = void 0; | ||
exports.microSeconds = void 0; | ||
exports.onMessage = onMessage; | ||
@@ -1461,3 +1452,3 @@ exports.postMessage = postMessage; | ||
} | ||
var _default = { | ||
var SimulateMethod = { | ||
create: create, | ||
@@ -1472,3 +1463,3 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.SimulateMethod = SimulateMethod; | ||
},{"../util.js":12}],11:[function(require,module,exports){ | ||
@@ -1530,7 +1521,3 @@ "use strict"; | ||
function isPromise(obj) { | ||
if (obj && typeof obj.then === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return obj && typeof obj.then === 'function'; | ||
} | ||
@@ -1583,9 +1570,2 @@ var PROMISE_RESOLVED_FALSE = Promise.resolve(false); | ||
},{}],13:[function(require,module,exports){ | ||
function _interopRequireDefault(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
"default": obj | ||
}; | ||
} | ||
module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports; | ||
},{}],14:[function(require,module,exports){ | ||
function _typeof(obj) { | ||
@@ -1601,9 +1581,5 @@ "@babel/helpers - typeof"; | ||
module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports; | ||
},{}],14:[function(require,module,exports){ | ||
},{}],15:[function(require,module,exports){ | ||
},{}],16:[function(require,module,exports){ | ||
module.exports = false; | ||
},{}],17:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -1686,3 +1662,189 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
},{}],18:[function(require,module,exports){ | ||
},{}],16:[function(require,module,exports){ | ||
// shim for using process in browser | ||
var process = module.exports = {}; | ||
// cached from whatever global is present so that test runners that stub it | ||
// don't break things. But we need to wrap it in a try catch in case it is | ||
// wrapped in strict mode code which doesn't define any globals. It's inside a | ||
// function because try/catches deoptimize in certain engines. | ||
var cachedSetTimeout; | ||
var cachedClearTimeout; | ||
function defaultSetTimout() { | ||
throw new Error('setTimeout has not been defined'); | ||
} | ||
function defaultClearTimeout () { | ||
throw new Error('clearTimeout has not been defined'); | ||
} | ||
(function () { | ||
try { | ||
if (typeof setTimeout === 'function') { | ||
cachedSetTimeout = setTimeout; | ||
} else { | ||
cachedSetTimeout = defaultSetTimout; | ||
} | ||
} catch (e) { | ||
cachedSetTimeout = defaultSetTimout; | ||
} | ||
try { | ||
if (typeof clearTimeout === 'function') { | ||
cachedClearTimeout = clearTimeout; | ||
} else { | ||
cachedClearTimeout = defaultClearTimeout; | ||
} | ||
} catch (e) { | ||
cachedClearTimeout = defaultClearTimeout; | ||
} | ||
} ()) | ||
function runTimeout(fun) { | ||
if (cachedSetTimeout === setTimeout) { | ||
//normal enviroments in sane situations | ||
return setTimeout(fun, 0); | ||
} | ||
// if setTimeout wasn't available but was latter defined | ||
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { | ||
cachedSetTimeout = setTimeout; | ||
return setTimeout(fun, 0); | ||
} | ||
try { | ||
// when when somebody has screwed with setTimeout but no I.E. maddness | ||
return cachedSetTimeout(fun, 0); | ||
} catch(e){ | ||
try { | ||
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally | ||
return cachedSetTimeout.call(null, fun, 0); | ||
} catch(e){ | ||
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error | ||
return cachedSetTimeout.call(this, fun, 0); | ||
} | ||
} | ||
} | ||
function runClearTimeout(marker) { | ||
if (cachedClearTimeout === clearTimeout) { | ||
//normal enviroments in sane situations | ||
return clearTimeout(marker); | ||
} | ||
// if clearTimeout wasn't available but was latter defined | ||
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { | ||
cachedClearTimeout = clearTimeout; | ||
return clearTimeout(marker); | ||
} | ||
try { | ||
// when when somebody has screwed with setTimeout but no I.E. maddness | ||
return cachedClearTimeout(marker); | ||
} catch (e){ | ||
try { | ||
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally | ||
return cachedClearTimeout.call(null, marker); | ||
} catch (e){ | ||
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. | ||
// Some versions of I.E. have different rules for clearTimeout vs setTimeout | ||
return cachedClearTimeout.call(this, marker); | ||
} | ||
} | ||
} | ||
var queue = []; | ||
var draining = false; | ||
var currentQueue; | ||
var queueIndex = -1; | ||
function cleanUpNextTick() { | ||
if (!draining || !currentQueue) { | ||
return; | ||
} | ||
draining = false; | ||
if (currentQueue.length) { | ||
queue = currentQueue.concat(queue); | ||
} else { | ||
queueIndex = -1; | ||
} | ||
if (queue.length) { | ||
drainQueue(); | ||
} | ||
} | ||
function drainQueue() { | ||
if (draining) { | ||
return; | ||
} | ||
var timeout = runTimeout(cleanUpNextTick); | ||
draining = true; | ||
var len = queue.length; | ||
while(len) { | ||
currentQueue = queue; | ||
queue = []; | ||
while (++queueIndex < len) { | ||
if (currentQueue) { | ||
currentQueue[queueIndex].run(); | ||
} | ||
} | ||
queueIndex = -1; | ||
len = queue.length; | ||
} | ||
currentQueue = null; | ||
draining = false; | ||
runClearTimeout(timeout); | ||
} | ||
process.nextTick = function (fun) { | ||
var args = new Array(arguments.length - 1); | ||
if (arguments.length > 1) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
args[i - 1] = arguments[i]; | ||
} | ||
} | ||
queue.push(new Item(fun, args)); | ||
if (queue.length === 1 && !draining) { | ||
runTimeout(drainQueue); | ||
} | ||
}; | ||
// v8 likes predictible objects | ||
function Item(fun, array) { | ||
this.fun = fun; | ||
this.array = array; | ||
} | ||
Item.prototype.run = function () { | ||
this.fun.apply(null, this.array); | ||
}; | ||
process.title = 'browser'; | ||
process.browser = true; | ||
process.env = {}; | ||
process.argv = []; | ||
process.version = ''; // empty string to avoid regexp issues | ||
process.versions = {}; | ||
function noop() {} | ||
process.on = noop; | ||
process.addListener = noop; | ||
process.once = noop; | ||
process.off = noop; | ||
process.removeListener = noop; | ||
process.removeAllListeners = noop; | ||
process.emit = noop; | ||
process.prependListener = noop; | ||
process.prependOnceListener = noop; | ||
process.listeners = function (name) { return [] } | ||
process.binding = function (name) { | ||
throw new Error('process.binding is not supported'); | ||
}; | ||
process.cwd = function () { return '/' }; | ||
process.chdir = function (dir) { | ||
throw new Error('process.chdir is not supported'); | ||
}; | ||
process.umask = function() { return 0; }; | ||
},{}],17:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -1693,7 +1855,18 @@ | ||
}); | ||
exports["default"] = void 0; | ||
exports.addBrowser = addBrowser; | ||
/* global WorkerGlobalScope */ | ||
/* global WorkerGlobalScope */ | ||
function add(fn) { | ||
if (typeof WorkerGlobalScope === 'function' && self instanceof WorkerGlobalScope) {// this is run inside of a webworker | ||
function addBrowser(fn) { | ||
if (typeof WorkerGlobalScope === 'function' && self instanceof WorkerGlobalScope) { | ||
/** | ||
* Because killing a worker does directly stop the excution | ||
* of the code, our only chance is to overwrite the close function | ||
* which could work some times. | ||
* @link https://stackoverflow.com/q/72903255/3443137 | ||
*/ | ||
var oldClose = self.close.bind(self); | ||
self.close = function () { | ||
fn(); | ||
return oldClose(); | ||
}; | ||
} else { | ||
@@ -1704,10 +1877,13 @@ /** | ||
*/ | ||
if (typeof window.addEventListener !== 'function') return; | ||
if (typeof window.addEventListener !== 'function') { | ||
return; | ||
} | ||
/** | ||
* for normal browser-windows, we use the beforeunload-event | ||
*/ | ||
window.addEventListener('beforeunload', function () { | ||
fn(); | ||
}, true); | ||
/** | ||
@@ -1717,3 +1893,2 @@ * for iframes, we have to use the unload-event | ||
*/ | ||
window.addEventListener('unload', function () { | ||
@@ -1723,2 +1898,3 @@ fn(); | ||
} | ||
/** | ||
@@ -1728,14 +1904,7 @@ * TODO add fallback for safari-mobile | ||
*/ | ||
} | ||
var _default = { | ||
add: add | ||
}; | ||
exports["default"] = _default; | ||
},{}],19:[function(require,module,exports){ | ||
},{}],18:[function(require,module,exports){ | ||
(function (process){(function (){ | ||
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -1748,22 +1917,25 @@ value: true | ||
exports.runAll = runAll; | ||
var _detectNode = _interopRequireDefault(require("detect-node")); | ||
var _browser = _interopRequireDefault(require("./browser.js")); | ||
var _node = _interopRequireDefault(require("./node.js")); | ||
var USE_METHOD = _detectNode["default"] ? _node["default"] : _browser["default"]; | ||
var _browser = require("./browser.js"); | ||
var _node = require("./node.js"); | ||
/** | ||
* Use the code directly to prevent import problems | ||
* with the detect-node package. | ||
* @link https://github.com/iliakan/detect-node/blob/master/index.js | ||
*/ | ||
var isNode = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]'; | ||
var USE_METHOD = isNode ? _node.addNode : _browser.addBrowser; | ||
var LISTENERS = new Set(); | ||
var startedListening = false; | ||
function startListening() { | ||
if (startedListening) return; | ||
if (startedListening) { | ||
return; | ||
} | ||
startedListening = true; | ||
USE_METHOD.add(runAll); | ||
USE_METHOD(runAll); | ||
} | ||
function add(fn) { | ||
startListening(); | ||
if (typeof fn !== 'function') throw new Error('Listener is no function'); | ||
if (typeof fn !== 'function') { | ||
throw new Error('Listener is no function'); | ||
} | ||
LISTENERS.add(fn); | ||
@@ -1781,3 +1953,2 @@ var addReturn = { | ||
} | ||
function runAll() { | ||
@@ -1791,10 +1962,9 @@ var promises = []; | ||
} | ||
function removeAll() { | ||
LISTENERS.clear(); | ||
} | ||
function getSize() { | ||
return LISTENERS.size; | ||
} | ||
},{"./browser.js":18,"./node.js":15,"@babel/runtime/helpers/interopRequireDefault":13,"detect-node":16}]},{},[2]); | ||
}).call(this)}).call(this,require('_process')) | ||
},{"./browser.js":17,"./node.js":14,"_process":16}]},{},[2]); |
@@ -1,1 +0,1 @@ | ||
!function o(r,i,s){function a(t,e){if(!i[t]){if(!r[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(u)return u(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}n=i[t]={exports:{}},r[t][0].call(n.exports,function(e){return a(r[t][1][e]||e)},n,n.exports,o,r,i,s)}return i[t].exports}for(var u="function"==typeof require&&require,e=0;e<s.length;e++)a(s[e]);return a}({1:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.OPEN_BROADCAST_CHANNELS=n.BroadcastChannel=void 0,n.clearNodeFolder=function(e){e=(0,a.fillOptionsWithDefaults)(e);e=(0,s.chooseMethod)(e);return"node"===e.type?e.clearNodeFolder().then(function(){return!0}):i.PROMISE_RESOLVED_FALSE},n.enforceOptions=function(e){r=e};function o(e,t){var n;this.id=c++,u.add(this),this.name=e,r&&(t=r),this.options=(0,a.fillOptionsWithDefaults)(t),this.method=(0,s.chooseMethod)(this.options),this._iL=!1,this._onML=null,this._addEL={message:[],internal:[]},this._uMP=new Set,this._befC=[],this._prepP=null,e=(n=this).method.create(n.name,n.options),(0,i.isPromise)(e)?(n._prepP=e).then(function(e){n._state=e}):n._state=e}var r,i=e("./util.js"),s=e("./method-chooser.js"),a=e("./options.js"),u=new Set,c=(n.OPEN_BROADCAST_CHANNELS=u,0);function d(t,e,n){var o={time:t.method.microSeconds(),type:e,data:n};return(t._prepP||i.PROMISE_RESOLVED_VOID).then(function(){var e=t.method.postMessage(t._state,o);return t._uMP.add(e),e.catch().then(function(){return t._uMP.delete(e)}),e})}function l(e){return 0<e._addEL.message.length||0<e._addEL.internal.length}function f(e,t,n){e._addEL[t].push(n);var o,r,i=e;!i._iL&&l(i)&&(o=function(n){i._addEL[n.type].forEach(function(e){var t=e.time-1e5;n.time>=t&&e.fn(n.data)})},r=i.method.microSeconds(),i._prepP?i._prepP.then(function(){i._iL=!0,i.method.onMessage(i._state,o,r)}):(i._iL=!0,i.method.onMessage(i._state,o,r)))}function h(e,t,n){e._addEL[t]=e._addEL[t].filter(function(e){return e!==n});t=e;t._iL&&!l(t)&&(t._iL=!1,e=t.method.microSeconds(),t.method.onMessage(t._state,null,e))}(n.BroadcastChannel=o)._pubkey=!0,o.prototype={postMessage:function(e){if(this.closed)throw new Error("BroadcastChannel.postMessage(): Cannot post message after channel has closed "+JSON.stringify(e));return d(this,"message",e)},postInternal:function(e){return d(this,"internal",e)},set onmessage(e){var t={time:this.method.microSeconds(),fn:e};h(this,"message",this._onML),e&&"function"==typeof e?(this._onML=t,f(this,"message",t)):this._onML=null},addEventListener:function(e,t){var n=this.method.microSeconds();f(this,e,{time:n,fn:t})},removeEventListener:function(e,t){var n=this._addEL[e].find(function(e){return e.fn===t});h(this,e,n)},close:function(){var e,t=this;if(!this.closed)return u.delete(this),this.closed=!0,e=this._prepP||i.PROMISE_RESOLVED_VOID,this._onML=null,this._addEL.message=[],e.then(function(){return Promise.all(Array.from(t._uMP))}).then(function(){return Promise.all(t._befC.map(function(e){return e()}))}).then(function(){return t.method.close(t._state)})},get type(){return this.method.type},get isClosed(){return this.closed}}},{"./method-chooser.js":6,"./options.js":11,"./util.js":12}],2:[function(e,t,n){"use strict";var e=e("./index.es5.js"),o=e.BroadcastChannel,e=e.createLeaderElection;window.BroadcastChannel2=o,window.createLeaderElection=e},{"./index.es5.js":3}],3:[function(e,t,n){"use strict";e=e("./index.js");t.exports={BroadcastChannel:e.BroadcastChannel,createLeaderElection:e.createLeaderElection,clearNodeFolder:e.clearNodeFolder,enforceOptions:e.enforceOptions,beLeader:e.beLeader}},{"./index.js":4}],4:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),Object.defineProperty(n,"BroadcastChannel",{enumerable:!0,get:function(){return o.BroadcastChannel}}),Object.defineProperty(n,"OPEN_BROADCAST_CHANNELS",{enumerable:!0,get:function(){return o.OPEN_BROADCAST_CHANNELS}}),Object.defineProperty(n,"beLeader",{enumerable:!0,get:function(){return r.beLeader}}),Object.defineProperty(n,"clearNodeFolder",{enumerable:!0,get:function(){return o.clearNodeFolder}}),Object.defineProperty(n,"createLeaderElection",{enumerable:!0,get:function(){return r.createLeaderElection}}),Object.defineProperty(n,"enforceOptions",{enumerable:!0,get:function(){return o.enforceOptions}});var o=e("./broadcast-channel.js"),r=e("./leader-election.js")},{"./broadcast-channel.js":1,"./leader-election.js":5}],5:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.beLeader=d,n.createLeaderElection=function(e,t){if(e._leaderElector)throw new Error("BroadcastChannel already has a leader-elector");t=function(e,t){e=e||{};(e=JSON.parse(JSON.stringify(e))).fallbackInterval||(e.fallbackInterval=3e3);e.responseTime||(e.responseTime=t.method.averageResponseTime(t.options));return e}(t,e);var n=new r(e,t);return e._befC.push(function(){return n.die()}),e._leaderElector=n};var u=e("./util.js"),o=e("unload"),r=function(e,t){function n(e){"leader"===e.context&&("death"===e.action&&(o.hasLeader=!1),"tell"===e.action)&&(o.hasLeader=!0)}var o=this;this.broadcastChannel=e,this._options=t,this.isLeader=!1,this.hasLeader=!1,this.isDead=!1,this.token=(0,u.randomToken)(),this._aplQ=u.PROMISE_RESOLVED_VOID,this._aplQC=0,this._unl=[],this._lstns=[],this._dpL=function(){},this._dpLC=!1;this.broadcastChannel.addEventListener("internal",n),this._lstns.push(n)};function c(e,t){t={context:"leader",action:t,token:e.token};return e.broadcastChannel.postInternal(t)}function d(t){t.isLeader=!0,t.hasLeader=!0;function e(e){"leader"===e.context&&"apply"===e.action&&c(t,"tell"),"leader"!==e.context||"tell"!==e.action||t._dpLC||(t._dpLC=!0,t._dpL(),c(t,"tell"))}var n=(0,o.add)(function(){return t.die()});t._unl.push(n);return t.broadcastChannel.addEventListener("internal",e),t._lstns.push(e),c(t,"tell")}r.prototype={applyOnce:function(s){var a=this;return this.isLeader?(0,u.sleep)(0,!0):this.isDead?(0,u.sleep)(0,!1):1<this._aplQC?this._aplQ:(this._aplQC=this._aplQC+1,this._aplQ=this._aplQ.then(function(){return a.isLeader?u.PROMISE_RESOLVED_TRUE:(t=!1,e=new Promise(function(e){n=function(){t=!0,e()}}),o=[],a.broadcastChannel.addEventListener("internal",r=function(e){"leader"===e.context&&e.token!=a.token&&(o.push(e),"apply"===e.action&&e.token>a.token&&n(),"tell"===e.action)&&(n(),a.hasLeader=!0)}),i=s?4*a._options.responseTime:a._options.responseTime,c(a,"apply").then(function(){return Promise.race([(0,u.sleep)(i),e.then(function(){return Promise.reject(new Error)})])}).then(function(){return c(a,"apply")}).then(function(){return Promise.race([(0,u.sleep)(i),e.then(function(){return Promise.reject(new Error)})])}).catch(function(){}).then(function(){return a.broadcastChannel.removeEventListener("internal",r),!t&&d(a).then(function(){return!0})}));var t,n,e,o,r,i}).then(function(){a._aplQC=a._aplQC-1}),this._aplQ.then(function(){return a.isLeader}))},awaitLeadership:function(){return this._aLP||(this._aLP=function(r){if(r.isLeader)return u.PROMISE_RESOLVED_VOID;return new Promise(function(e){var t=!1;function n(){t||(t=!0,r.broadcastChannel.removeEventListener("internal",o),e(!0))}r.applyOnce().then(function(){r.isLeader&&n()});(function e(){return(0,u.sleep)(r._options.fallbackInterval).then(function(){if(!r.isDead&&!t)return r.isLeader?void n():r.applyOnce(!0).then(function(){(r.isLeader?n:e)()})})})();var o=function(e){"leader"===e.context&&"death"===e.action&&(r.hasLeader=!1,r.applyOnce().then(function(){r.isLeader&&n()}))};r.broadcastChannel.addEventListener("internal",o),r._lstns.push(o)})}(this)),this._aLP},set onduplicate(e){this._dpL=e},die:function(){var t=this;return this._lstns.forEach(function(e){return t.broadcastChannel.removeEventListener("internal",e)}),this._lstns=[],this._unl.forEach(function(e){return e.remove()}),this._unl=[],this.isLeader&&(this.hasLeader=!1,this.isLeader=!1),this.isDead=!0,c(this,"death")}}},{"./util.js":12,unload:19}],6:[function(e,t,n){"use strict";var o=e("@babel/runtime/helpers/interopRequireDefault"),n=(e("@babel/runtime/helpers/typeof"),Object.defineProperty(n,"__esModule",{value:!0}),n.chooseMethod=function(t){var e=[].concat(t.methods,a).filter(Boolean);if(t.type){if("simulate"===t.type)return s.default;var n=e.find(function(e){return e.type===t.type});if(n)return n;throw new Error("method-type "+t.type+" not found")}t.webWorkerSupport||(e=e.filter(function(e){return"idb"!==e.type}));n=e.find(function(e){return e.canBeUsed()});{if(n)return n;throw new Error("No useable method found in "+JSON.stringify(a.map(function(e){return e.type})))}},o(e("./methods/native.js"))),r=o(e("./methods/indexed-db.js")),i=o(e("./methods/localstorage.js")),s=o(e("./methods/simulate.js"));var a=[n.default,r.default,i.default]},{"./methods/indexed-db.js":7,"./methods/localstorage.js":8,"./methods/native.js":9,"./methods/simulate.js":10,"@babel/runtime/helpers/interopRequireDefault":13,"@babel/runtime/helpers/typeof":14}],7:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.TRANSACTION_SETTINGS=void 0,n.averageResponseTime=w,n.canBeUsed=S,n.cleanOldMessages=v,n.close=g,n.commitIndexedDBTransaction=l,n.create=b,n.createDatabase=u,n.default=void 0,n.getAllMessages=function(e){var n=e.transaction(c,"readonly",d),o=n.objectStore(c),r=[];return new Promise(function(t){o.openCursor().onsuccess=function(e){e=e.target.result;e?(r.push(e.value),e.continue()):(l(n),t(r))}})},n.getIdb=a,n.getMessagesHigherThan=h,n.getOldMessages=m,n.microSeconds=void 0,n.onMessage=y,n.postMessage=E,n.removeMessagesById=p,n.type=void 0,n.writeMessage=f;var r=e("../util.js"),i=e("oblivious-set"),s=e("../options.js"),e=r.microSeconds,o=(n.microSeconds=e,"pubkey.broadcast-channel-0-"),c="messages",d={durability:"relaxed"};n.TRANSACTION_SETTINGS=d;function a(){if("undefined"!=typeof indexedDB)return indexedDB;if("undefined"!=typeof window){if(void 0!==window.mozIndexedDB)return window.mozIndexedDB;if(void 0!==window.webkitIndexedDB)return window.webkitIndexedDB;if(void 0!==window.msIndexedDB)return window.msIndexedDB}return!1}function l(e){e.commit&&e.commit()}function u(e){var n=a().open(o+e);return n.onupgradeneeded=function(e){e.target.result.createObjectStore(c,{keyPath:"id",autoIncrement:!0})},new Promise(function(e,t){n.onerror=function(e){return t(e)},n.onsuccess=function(){e(n.result)}})}function f(e,t,n){var o={uuid:t,time:(new Date).getTime(),data:n},r=e.transaction([c],"readwrite",d);return new Promise(function(e,t){r.oncomplete=function(){return e()},r.onerror=function(e){return t(e)},r.objectStore(c).add(o),l(r)})}function h(e,o){var r,i=e.transaction(c,"readonly",d),s=i.objectStore(c),a=[],u=IDBKeyRange.bound(o+1,1/0);return s.getAll?(r=s.getAll(u),new Promise(function(t,n){r.onerror=function(e){return n(e)},r.onsuccess=function(e){t(e.target.result)}})):new Promise(function(t,n){var e=function(){try{return u=IDBKeyRange.bound(o+1,1/0),s.openCursor(u)}catch(e){return s.openCursor()}}();e.onerror=function(e){return n(e)},e.onsuccess=function(e){e=e.target.result;e?e.value.id<o+1?e.continue(o+1):(a.push(e.value),e.continue()):(l(i),t(a))}})}function p(e,t){var n;return e.closed?Promise.resolve([]):(n=e.db.transaction(c,"readwrite",d).objectStore(c),Promise.all(t.map(function(e){var t=n.delete(e);return new Promise(function(e){t.onsuccess=function(){return e()}})})))}function m(e,t){var o=(new Date).getTime()-t,r=e.transaction(c,"readonly",d),i=r.objectStore(c),s=[];return new Promise(function(n){i.openCursor().onsuccess=function(e){var t,e=e.target.result;e?(t=e.value).time<o?(s.push(t),e.continue()):(l(r),n(s)):n(s)}})}function v(t){return m(t.db,t.options.idb.ttl).then(function(e){return p(t,e.map(function(e){return e.id}))})}function b(n,o){return o=(0,s.fillOptionsWithDefaults)(o),u(n).then(function(e){var t={closed:!1,lastCursorId:0,channelName:n,options:o,uuid:(0,r.randomToken)(),eMIs:new i.ObliviousSet(2*o.idb.ttl),writeBlockPromise:r.PROMISE_RESOLVED_VOID,messagesCallback:null,readQueuePromises:[],db:e};return e.onclose=function(){t.closed=!0,o.idb.onclose&&o.idb.onclose()},function e(t){if(t.closed)return;_(t).then(function(){return(0,r.sleep)(t.options.idb.fallbackInterval)}).then(function(){return e(t)})}(t),t})}function _(n){return!n.closed&&n.messagesCallback?h(n.db,n.lastCursorId).then(function(e){return e.filter(function(e){return!!e}).map(function(e){return e.id>n.lastCursorId&&(n.lastCursorId=e.id),e}).filter(function(e){return t=n,(e=e).uuid!==t.uuid&&!(t.eMIs.has(e.id)||e.data.time<t.messagesCallbackTime);var t}).sort(function(e,t){return e.time-t.time}).forEach(function(e){n.messagesCallback&&(n.eMIs.add(e.id),n.messagesCallback(e.data))}),r.PROMISE_RESOLVED_VOID}):r.PROMISE_RESOLVED_VOID}function g(e){e.closed=!0,e.db.close()}function E(e,t){return e.writeBlockPromise=e.writeBlockPromise.then(function(){return f(e.db,e.uuid,t)}).then(function(){0===(0,r.randomInt)(0,10)&&v(e)}),e.writeBlockPromise}function y(e,t,n){e.messagesCallbackTime=n,e.messagesCallback=t,_(e)}function S(){return!!a()}function w(e){return 2*e.idb.fallbackInterval}n.type="idb",n.default={create:b,close:g,onMessage:y,postMessage:E,canBeUsed:S,type:"idb",averageResponseTime:w,microSeconds:e}},{"../options.js":11,"../util.js":12,"oblivious-set":17}],8:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.addStorageEventListener=l,n.averageResponseTime=b,n.canBeUsed=v,n.close=p,n.create=h,n.default=void 0,n.getLocalStorage=u,n.microSeconds=void 0,n.onMessage=m,n.postMessage=d,n.removeStorageEventListener=f,n.storageKey=c,n.type=void 0;var i=e("oblivious-set"),s=e("../options.js"),a=e("../util.js"),e=a.microSeconds,r=(n.microSeconds=e,"pubkey.broadcastChannel-"),o="localstorage";function u(){var e;if("undefined"==typeof window)return null;try{e=window.localStorage,e=window["ie8-eventlistener/storage"]||window.localStorage}catch(e){}return e}function c(e){return r+e}function d(r,i){return new Promise(function(o){(0,a.sleep)().then(function(){var e=c(r.channelName),t={token:(0,a.randomToken)(),time:(new Date).getTime(),data:i,uuid:r.uuid},t=JSON.stringify(t),n=(u().setItem(e,t),document.createEvent("Event"));n.initEvent("storage",!0,!0),n.key=e,n.newValue=t,window.dispatchEvent(n),o()})})}function l(e,t){function n(e){e.key===o&&t(JSON.parse(e.newValue))}var o=r+e;return window.addEventListener("storage",n),n}function f(e){window.removeEventListener("storage",e)}function h(e,t){var n,o,r;if(t=(0,s.fillOptionsWithDefaults)(t),v())return n=(0,a.randomToken)(),o=new i.ObliviousSet(t.localstorage.removeTimeout),(r={channelName:e,uuid:n,eMIs:o}).listener=l(e,function(e){!r.messagesCallback||e.uuid===n||!e.token||o.has(e.token)||e.data.time&&e.data.time<r.messagesCallbackTime||(o.add(e.token),r.messagesCallback(e.data))}),r;throw new Error("BroadcastChannel: localstorage cannot be used")}function p(e){f(e.listener)}function m(e,t,n){e.messagesCallbackTime=n,e.messagesCallback=t}function v(){var e=u();if(!e)return!1;try{var t="__broadcastchannel_check";e.setItem(t,"works"),e.removeItem(t)}catch(e){return!1}return!0}function b(){var e=navigator.userAgent.toLowerCase();return e.includes("safari")&&!e.includes("chrome")?240:120}n.type=o,n.default={create:h,close:p,onMessage:m,postMessage:d,canBeUsed:v,type:o,averageResponseTime:b,microSeconds:e}},{"../options.js":11,"../util.js":12,"oblivious-set":17}],9:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.averageResponseTime=c,n.canBeUsed=u,n.close=i,n.create=r,n.microSeconds=n.default=void 0,n.onMessage=a,n.postMessage=s,n.type=void 0;var o=e("../util.js"),e=o.microSeconds;n.microSeconds=e;function r(e){var t={messagesCallback:null,bc:new BroadcastChannel(e),subFns:[]};return t.bc.onmessage=function(e){t.messagesCallback&&t.messagesCallback(e.data)},t}function i(e){e.bc.close(),e.subFns=[]}function s(e,t){try{return e.bc.postMessage(t,!1),o.PROMISE_RESOLVED_VOID}catch(e){return Promise.reject(e)}}function a(e,t){e.messagesCallback=t}function u(){if("undefined"==typeof window)return!1;if("function"!=typeof BroadcastChannel)return!1;if(BroadcastChannel._pubkey)throw new Error("BroadcastChannel: Do not overwrite window.BroadcastChannel with this module, this is not a polyfill");return!0}function c(){return 150}n.type="native",n.default={create:r,close:i,onMessage:a,postMessage:s,canBeUsed:u,type:"native",averageResponseTime:c,microSeconds:e}},{"../util.js":12}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.averageResponseTime=d,n.canBeUsed=c,n.close=s,n.create=i,n.microSeconds=n.default=void 0,n.onMessage=u,n.postMessage=a,n.type=void 0;var e=e("../util.js").microSeconds,o=(n.microSeconds=e,"simulate"),r=(n.type=o,new Set);function i(e){e={name:e,messagesCallback:null};return r.add(e),e}function s(e){r.delete(e)}function a(t,n){return new Promise(function(e){return setTimeout(function(){Array.from(r).filter(function(e){return e.name===t.name}).filter(function(e){return e!==t}).filter(function(e){return!!e.messagesCallback}).forEach(function(e){return e.messagesCallback(n)}),e()},5)})}function u(e,t){e.messagesCallback=t}function c(){return!0}function d(){return 5}n.default={create:i,close:s,onMessage:u,postMessage:a,canBeUsed:c,type:o,averageResponseTime:d,microSeconds:e}},{"../util.js":12}],11:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.fillOptionsWithDefaults=function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},t=JSON.parse(JSON.stringify(e));void 0===t.webWorkerSupport&&(t.webWorkerSupport=!0);t.idb||(t.idb={});t.idb.ttl||(t.idb.ttl=45e3);t.idb.fallbackInterval||(t.idb.fallbackInterval=150);e.idb&&"function"==typeof e.idb.onclose&&(t.idb.onclose=e.idb.onclose);t.localstorage||(t.localstorage={});t.localstorage.removeTimeout||(t.localstorage.removeTimeout=6e4);e.methods&&(t.methods=e.methods);t.node||(t.node={});t.node.ttl||(t.node.ttl=12e4);t.node.maxParallelWrites||(t.node.maxParallelWrites=2048);void 0===t.node.useFastPath&&(t.node.useFastPath=!0);return t}},{}],12:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.PROMISE_RESOLVED_VOID=n.PROMISE_RESOLVED_TRUE=n.PROMISE_RESOLVED_FALSE=void 0,n.isPromise=function(e){return!(!e||"function"!=typeof e.then)},n.microSeconds=function(){var e=(new Date).getTime();return e===r?1e3*e+ ++i:(i=0,1e3*(r=e))},n.randomInt=function(e,t){return Math.floor(Math.random()*(t-e+1)+e)},n.randomToken=function(){return Math.random().toString(36).substring(2)},n.sleep=function(t,n){t=t||0;return new Promise(function(e){return setTimeout(function(){return e(n)},t)})};var o=Promise.resolve(!1),o=(n.PROMISE_RESOLVED_FALSE=o,Promise.resolve(!0)),o=(n.PROMISE_RESOLVED_TRUE=o,Promise.resolve());n.PROMISE_RESOLVED_VOID=o;var r=0,i=0},{}],13:[function(e,t,n){t.exports=function(e){return e&&e.__esModule?e:{default:e}},t.exports.__esModule=!0,t.exports.default=t.exports},{}],14:[function(e,t,n){function o(e){return t.exports=o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t.exports.__esModule=!0,t.exports.default=t.exports,o(e)}t.exports=o,t.exports.__esModule=!0,t.exports.default=t.exports},{}],15:[function(e,t,n){},{}],16:[function(e,t,n){t.exports=!1},{}],17:[function(e,t,n){"use strict";function o(e){this.ttl=e,this.map=new Map,this._to=!1}function r(e){for(var t=i()-e.ttl,n=e.map[Symbol.iterator]();;){var o=n.next().value;if(!o)return;var r=o[0];if(!(o[1]<t))return;e.map.delete(r)}}function i(){return(new Date).getTime()}Object.defineProperty(n,"__esModule",{value:!0}),n.now=n.removeTooOldValues=n.ObliviousSet=void 0,o.prototype.has=function(e){return this.map.has(e)},o.prototype.add=function(e){var t=this;this.map.set(e,i()),this._to||(this._to=!0,setTimeout(function(){t._to=!1,r(t)},0))},o.prototype.clear=function(){this.map.clear()},n.ObliviousSet=o,n.removeTooOldValues=r,n.now=i},{}],18:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default={add:function(e){"function"==typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope||"function"==typeof window.addEventListener&&(window.addEventListener("beforeunload",function(){e()},!0),window.addEventListener("unload",function(){e()},!0))}}},{}],19:[function(e,t,n){"use strict";var o=e("@babel/runtime/helpers/interopRequireDefault"),n=(Object.defineProperty(n,"__esModule",{value:!0}),n.add=function(e){if(a||(a=!0,i.add(u)),"function"!=typeof e)throw new Error("Listener is no function");return s.add(e),{remove:function(){return s.delete(e)},run:function(){return s.delete(e),e()}}},n.getSize=function(){return s.size},n.removeAll=function(){s.clear()},n.runAll=u,o(e("detect-node"))),r=o(e("./browser.js")),o=o(e("./node.js")),i=(n.default?o:r).default,s=new Set,a=!1;function u(){var t=[];return s.forEach(function(e){t.push(e()),s.delete(e)}),Promise.all(t)}},{"./browser.js":18,"./node.js":15,"@babel/runtime/helpers/interopRequireDefault":13,"detect-node":16}]},{},[2]); | ||
!function o(r,i,s){function a(t,e){if(!i[t]){if(!r[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(u)return u(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}n=i[t]={exports:{}},r[t][0].call(n.exports,function(e){return a(r[t][1][e]||e)},n,n.exports,o,r,i,s)}return i[t].exports}for(var u="function"==typeof require&&require,e=0;e<s.length;e++)a(s[e]);return a}({1:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.OPEN_BROADCAST_CHANNELS=n.BroadcastChannel=void 0,n.clearNodeFolder=function(e){e=(0,a.fillOptionsWithDefaults)(e);e=(0,s.chooseMethod)(e);return"node"===e.type?e.clearNodeFolder().then(function(){return!0}):i.PROMISE_RESOLVED_FALSE},n.enforceOptions=function(e){r=e};function o(e,t){var n;this.id=c++,u.add(this),this.name=e,r&&(t=r),this.options=(0,a.fillOptionsWithDefaults)(t),this.method=(0,s.chooseMethod)(this.options),this._iL=!1,this._onML=null,this._addEL={message:[],internal:[]},this._uMP=new Set,this._befC=[],this._prepP=null,e=(n=this).method.create(n.name,n.options),(0,i.isPromise)(e)?(n._prepP=e).then(function(e){n._state=e}):n._state=e}var r,i=e("./util.js"),s=e("./method-chooser.js"),a=e("./options.js"),u=new Set,c=(n.OPEN_BROADCAST_CHANNELS=u,0);function l(t,e,n){var o={time:t.method.microSeconds(),type:e,data:n};return(t._prepP||i.PROMISE_RESOLVED_VOID).then(function(){var e=t.method.postMessage(t._state,o);return t._uMP.add(e),e.catch().then(function(){return t._uMP.delete(e)}),e})}function d(e){return 0<e._addEL.message.length||0<e._addEL.internal.length}function f(e,t,n){e._addEL[t].push(n);var o,r,i=e;!i._iL&&d(i)&&(o=function(n){i._addEL[n.type].forEach(function(e){var t=e.time-1e5;n.time>=t&&e.fn(n.data)})},r=i.method.microSeconds(),i._prepP?i._prepP.then(function(){i._iL=!0,i.method.onMessage(i._state,o,r)}):(i._iL=!0,i.method.onMessage(i._state,o,r)))}function h(e,t,n){e._addEL[t]=e._addEL[t].filter(function(e){return e!==n});t=e;t._iL&&!d(t)&&(t._iL=!1,e=t.method.microSeconds(),t.method.onMessage(t._state,null,e))}(n.BroadcastChannel=o)._pubkey=!0,o.prototype={postMessage:function(e){if(this.closed)throw new Error("BroadcastChannel.postMessage(): Cannot post message after channel has closed "+JSON.stringify(e));return l(this,"message",e)},postInternal:function(e){return l(this,"internal",e)},set onmessage(e){var t={time:this.method.microSeconds(),fn:e};h(this,"message",this._onML),e&&"function"==typeof e?(this._onML=t,f(this,"message",t)):this._onML=null},addEventListener:function(e,t){var n=this.method.microSeconds();f(this,e,{time:n,fn:t})},removeEventListener:function(e,t){var n=this._addEL[e].find(function(e){return e.fn===t});h(this,e,n)},close:function(){var e,t=this;if(!this.closed)return u.delete(this),this.closed=!0,e=this._prepP||i.PROMISE_RESOLVED_VOID,this._onML=null,this._addEL.message=[],e.then(function(){return Promise.all(Array.from(t._uMP))}).then(function(){return Promise.all(t._befC.map(function(e){return e()}))}).then(function(){return t.method.close(t._state)})},get type(){return this.method.type},get isClosed(){return this.closed}}},{"./method-chooser.js":6,"./options.js":11,"./util.js":12}],2:[function(e,t,n){"use strict";var e=e("./index.es5.js"),o=e.BroadcastChannel,e=e.createLeaderElection;window.BroadcastChannel2=o,window.createLeaderElection=e},{"./index.es5.js":3}],3:[function(e,t,n){"use strict";e=e("./index.js");t.exports={BroadcastChannel:e.BroadcastChannel,createLeaderElection:e.createLeaderElection,clearNodeFolder:e.clearNodeFolder,enforceOptions:e.enforceOptions,beLeader:e.beLeader}},{"./index.js":4}],4:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),Object.defineProperty(n,"BroadcastChannel",{enumerable:!0,get:function(){return o.BroadcastChannel}}),Object.defineProperty(n,"OPEN_BROADCAST_CHANNELS",{enumerable:!0,get:function(){return o.OPEN_BROADCAST_CHANNELS}}),Object.defineProperty(n,"beLeader",{enumerable:!0,get:function(){return r.beLeader}}),Object.defineProperty(n,"clearNodeFolder",{enumerable:!0,get:function(){return o.clearNodeFolder}}),Object.defineProperty(n,"createLeaderElection",{enumerable:!0,get:function(){return r.createLeaderElection}}),Object.defineProperty(n,"enforceOptions",{enumerable:!0,get:function(){return o.enforceOptions}});var o=e("./broadcast-channel.js"),r=e("./leader-election.js")},{"./broadcast-channel.js":1,"./leader-election.js":5}],5:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.beLeader=c,n.createLeaderElection=function(e,t){if(e._leaderElector)throw new Error("BroadcastChannel already has a leader-elector");t=function(e,t){e=e||{};(e=JSON.parse(JSON.stringify(e))).fallbackInterval||(e.fallbackInterval=3e3);e.responseTime||(e.responseTime=t.method.averageResponseTime(t.options));return e}(t,e);var n=new r(e,t);return e._befC.push(function(){return n.die()}),e._leaderElector=n};var a=e("./util.js"),o=e("unload"),r=function(e,t){function n(e){"leader"===e.context&&("death"===e.action&&(o.hasLeader=!1),"tell"===e.action)&&(o.hasLeader=!0)}var o=this;this.broadcastChannel=e,this._options=t,this.isLeader=!1,this.hasLeader=!1,this.isDead=!1,this.token=(0,a.randomToken)(),this._aplQ=a.PROMISE_RESOLVED_VOID,this._aplQC=0,this._unl=[],this._lstns=[],this._dpL=function(){},this._dpLC=!1;this.broadcastChannel.addEventListener("internal",n),this._lstns.push(n)};function u(e,t){t={context:"leader",action:t,token:e.token};return e.broadcastChannel.postInternal(t)}function c(t){t.isLeader=!0,t.hasLeader=!0;function e(e){"leader"===e.context&&"apply"===e.action&&u(t,"tell"),"leader"!==e.context||"tell"!==e.action||t._dpLC||(t._dpLC=!0,t._dpL(),u(t,"tell"))}var n=(0,o.add)(function(){return t.die()});t._unl.push(n);return t.broadcastChannel.addEventListener("internal",e),t._lstns.push(e),u(t,"tell")}r.prototype={applyOnce:function(i){var s=this;return this.isLeader?(0,a.sleep)(0,!0):this.isDead?(0,a.sleep)(0,!1):1<this._aplQC?this._aplQ:(this._aplQC=this._aplQC+1,this._aplQ=this._aplQ.then(function(){return s.isLeader?a.PROMISE_RESOLVED_TRUE:(t=!1,e=new Promise(function(e){n=function(){t=!0,e()}}),s.broadcastChannel.addEventListener("internal",o=function(e){"leader"===e.context&&e.token!=s.token&&("apply"===e.action&&e.token>s.token&&n(),"tell"===e.action)&&(n(),s.hasLeader=!0)}),r=i?4*s._options.responseTime:s._options.responseTime,u(s,"apply").then(function(){return Promise.race([(0,a.sleep)(r),e.then(function(){return Promise.reject(new Error)})])}).then(function(){return u(s,"apply")}).then(function(){return Promise.race([(0,a.sleep)(r),e.then(function(){return Promise.reject(new Error)})])}).catch(function(){}).then(function(){return s.broadcastChannel.removeEventListener("internal",o),!t&&c(s).then(function(){return!0})}));var t,n,e,o,r}).then(function(){s._aplQC=s._aplQC-1}),this._aplQ.then(function(){return s.isLeader}))},awaitLeadership:function(){return this._aLP||(this._aLP=function(r){if(r.isLeader)return a.PROMISE_RESOLVED_VOID;return new Promise(function(e){var t=!1;function n(){t||(t=!0,r.broadcastChannel.removeEventListener("internal",o),e(!0))}r.applyOnce().then(function(){r.isLeader&&n()});(function e(){return(0,a.sleep)(r._options.fallbackInterval).then(function(){if(!r.isDead&&!t)return r.isLeader?void n():r.applyOnce(!0).then(function(){(r.isLeader?n:e)()})})})();var o=function(e){"leader"===e.context&&"death"===e.action&&(r.hasLeader=!1,r.applyOnce().then(function(){r.isLeader&&n()}))};r.broadcastChannel.addEventListener("internal",o),r._lstns.push(o)})}(this)),this._aLP},set onduplicate(e){this._dpL=e},die:function(){var t=this;return this._lstns.forEach(function(e){return t.broadcastChannel.removeEventListener("internal",e)}),this._lstns=[],this._unl.forEach(function(e){return e.remove()}),this._unl=[],this.isLeader&&(this.hasLeader=!1,this.isLeader=!1),this.isDead=!0,u(this,"death")}}},{"./util.js":12,unload:18}],6:[function(e,t,n){"use strict";e("@babel/runtime/helpers/typeof");Object.defineProperty(n,"__esModule",{value:!0}),n.chooseMethod=function(t){var e=[].concat(t.methods,s).filter(Boolean);if(t.type){if("simulate"===t.type)return i.SimulateMethod;var n=e.find(function(e){return e.type===t.type});if(n)return n;throw new Error("method-type "+t.type+" not found")}t.webWorkerSupport||(e=e.filter(function(e){return"idb"!==e.type}));n=e.find(function(e){return e.canBeUsed()});{if(n)return n;throw new Error("No usable method found in "+JSON.stringify(s.map(function(e){return e.type})))}};var n=e("./methods/native.js"),o=e("./methods/indexed-db.js"),r=e("./methods/localstorage.js"),i=e("./methods/simulate.js");var s=[n.NativeMethod,o.IndexedDBMethod,r.LocalstorageMethod]},{"./methods/indexed-db.js":7,"./methods/localstorage.js":8,"./methods/native.js":9,"./methods/simulate.js":10,"@babel/runtime/helpers/typeof":13}],7:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.TRANSACTION_SETTINGS=n.IndexedDBMethod=void 0,n.averageResponseTime=S,n.canBeUsed=E,n.cleanOldMessages=v,n.close=g,n.commitIndexedDBTransaction=d,n.create=b,n.createDatabase=u,n.getAllMessages=function(e){var n=e.transaction(c,"readonly",l),o=n.objectStore(c),r=[];return new Promise(function(t){o.openCursor().onsuccess=function(e){e=e.target.result;e?(r.push(e.value),e.continue()):(d(n),t(r))}})},n.getIdb=a,n.getMessagesHigherThan=h,n.getOldMessages=m,n.microSeconds=void 0,n.onMessage=w,n.postMessage=y,n.removeMessagesById=p,n.type=void 0,n.writeMessage=f;var r=e("../util.js"),i=e("oblivious-set"),s=e("../options.js"),e=r.microSeconds,o=(n.microSeconds=e,"pubkey.broadcast-channel-0-"),c="messages",l={durability:"relaxed"};n.TRANSACTION_SETTINGS=l;function a(){if("undefined"!=typeof indexedDB)return indexedDB;if("undefined"!=typeof window){if(void 0!==window.mozIndexedDB)return window.mozIndexedDB;if(void 0!==window.webkitIndexedDB)return window.webkitIndexedDB;if(void 0!==window.msIndexedDB)return window.msIndexedDB}return!1}function d(e){e.commit&&e.commit()}function u(e){var n=a().open(o+e);return n.onupgradeneeded=function(e){e.target.result.createObjectStore(c,{keyPath:"id",autoIncrement:!0})},new Promise(function(e,t){n.onerror=function(e){return t(e)},n.onsuccess=function(){e(n.result)}})}function f(e,t,n){var o={uuid:t,time:(new Date).getTime(),data:n},r=e.transaction([c],"readwrite",l);return new Promise(function(e,t){r.oncomplete=function(){return e()},r.onerror=function(e){return t(e)},r.objectStore(c).add(o),d(r)})}function h(e,o){var r,i=e.transaction(c,"readonly",l),s=i.objectStore(c),a=[],u=IDBKeyRange.bound(o+1,1/0);return s.getAll?(r=s.getAll(u),new Promise(function(t,n){r.onerror=function(e){return n(e)},r.onsuccess=function(e){t(e.target.result)}})):new Promise(function(t,n){var e=function(){try{return u=IDBKeyRange.bound(o+1,1/0),s.openCursor(u)}catch(e){return s.openCursor()}}();e.onerror=function(e){return n(e)},e.onsuccess=function(e){e=e.target.result;e?e.value.id<o+1?e.continue(o+1):(a.push(e.value),e.continue()):(d(i),t(a))}})}function p(e,t){var n;return e.closed?Promise.resolve([]):(n=e.db.transaction(c,"readwrite",l).objectStore(c),Promise.all(t.map(function(e){var t=n.delete(e);return new Promise(function(e){t.onsuccess=function(){return e()}})})))}function m(e,t){var o=(new Date).getTime()-t,r=e.transaction(c,"readonly",l),i=r.objectStore(c),s=[];return new Promise(function(n){i.openCursor().onsuccess=function(e){var t,e=e.target.result;e?(t=e.value).time<o?(s.push(t),e.continue()):(d(r),n(s)):n(s)}})}function v(t){return m(t.db,t.options.idb.ttl).then(function(e){return p(t,e.map(function(e){return e.id}))})}function b(n,o){return o=(0,s.fillOptionsWithDefaults)(o),u(n).then(function(e){var t={closed:!1,lastCursorId:0,channelName:n,options:o,uuid:(0,r.randomToken)(),eMIs:new i.ObliviousSet(2*o.idb.ttl),writeBlockPromise:r.PROMISE_RESOLVED_VOID,messagesCallback:null,readQueuePromises:[],db:e};return e.onclose=function(){t.closed=!0,o.idb.onclose&&o.idb.onclose()},function e(t){if(t.closed)return;_(t).then(function(){return(0,r.sleep)(t.options.idb.fallbackInterval)}).then(function(){return e(t)})}(t),t})}function _(n){return!n.closed&&n.messagesCallback?h(n.db,n.lastCursorId).then(function(e){return e.filter(function(e){return!!e}).map(function(e){return e.id>n.lastCursorId&&(n.lastCursorId=e.id),e}).filter(function(e){return t=n,(e=e).uuid!==t.uuid&&!(t.eMIs.has(e.id)||e.data.time<t.messagesCallbackTime);var t}).sort(function(e,t){return e.time-t.time}).forEach(function(e){n.messagesCallback&&(n.eMIs.add(e.id),n.messagesCallback(e.data))}),r.PROMISE_RESOLVED_VOID}):r.PROMISE_RESOLVED_VOID}function g(e){e.closed=!0,e.db.close()}function y(e,t){return e.writeBlockPromise=e.writeBlockPromise.then(function(){return f(e.db,e.uuid,t)}).then(function(){0===(0,r.randomInt)(0,10)&&v(e)}),e.writeBlockPromise}function w(e,t,n){e.messagesCallbackTime=n,e.messagesCallback=t,_(e)}function E(){return!!a()}function S(e){return 2*e.idb.fallbackInterval}n.type="idb",n.IndexedDBMethod={create:b,close:g,onMessage:w,postMessage:y,canBeUsed:E,type:"idb",averageResponseTime:S,microSeconds:e}},{"../options.js":11,"../util.js":12,"oblivious-set":15}],8:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.LocalstorageMethod=void 0,n.addStorageEventListener=d,n.averageResponseTime=b,n.canBeUsed=v,n.close=p,n.create=h,n.getLocalStorage=u,n.microSeconds=void 0,n.onMessage=m,n.postMessage=l,n.removeStorageEventListener=f,n.storageKey=c,n.type=void 0;var i=e("oblivious-set"),s=e("../options.js"),a=e("../util.js"),e=a.microSeconds,r=(n.microSeconds=e,"pubkey.broadcastChannel-"),o="localstorage";function u(){var e;if("undefined"==typeof window)return null;try{e=window.localStorage,e=window["ie8-eventlistener/storage"]||window.localStorage}catch(e){}return e}function c(e){return r+e}function l(r,i){return new Promise(function(o){(0,a.sleep)().then(function(){var e=c(r.channelName),t={token:(0,a.randomToken)(),time:(new Date).getTime(),data:i,uuid:r.uuid},t=JSON.stringify(t),n=(u().setItem(e,t),document.createEvent("Event"));n.initEvent("storage",!0,!0),n.key=e,n.newValue=t,window.dispatchEvent(n),o()})})}function d(e,t){function n(e){e.key===o&&t(JSON.parse(e.newValue))}var o=r+e;return window.addEventListener("storage",n),n}function f(e){window.removeEventListener("storage",e)}function h(e,t){var n,o,r;if(t=(0,s.fillOptionsWithDefaults)(t),v())return n=(0,a.randomToken)(),o=new i.ObliviousSet(t.localstorage.removeTimeout),(r={channelName:e,uuid:n,eMIs:o}).listener=d(e,function(e){!r.messagesCallback||e.uuid===n||!e.token||o.has(e.token)||e.data.time&&e.data.time<r.messagesCallbackTime||(o.add(e.token),r.messagesCallback(e.data))}),r;throw new Error("BroadcastChannel: localstorage cannot be used")}function p(e){f(e.listener)}function m(e,t,n){e.messagesCallbackTime=n,e.messagesCallback=t}function v(){var e=u();if(!e)return!1;try{var t="__broadcastchannel_check";e.setItem(t,"works"),e.removeItem(t)}catch(e){return!1}return!0}function b(){var e=navigator.userAgent.toLowerCase();return e.includes("safari")&&!e.includes("chrome")?240:120}n.type=o,n.LocalstorageMethod={create:h,close:p,onMessage:m,postMessage:l,canBeUsed:v,type:o,averageResponseTime:b,microSeconds:e}},{"../options.js":11,"../util.js":12,"oblivious-set":15}],9:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.NativeMethod=void 0,n.averageResponseTime=c,n.canBeUsed=u,n.close=i,n.create=r,n.microSeconds=void 0,n.onMessage=a,n.postMessage=s,n.type=void 0;var o=e("../util.js"),e=o.microSeconds;n.microSeconds=e;function r(e){var t={messagesCallback:null,bc:new BroadcastChannel(e),subFns:[]};return t.bc.onmessage=function(e){t.messagesCallback&&t.messagesCallback(e.data)},t}function i(e){e.bc.close(),e.subFns=[]}function s(e,t){try{return e.bc.postMessage(t,!1),o.PROMISE_RESOLVED_VOID}catch(e){return Promise.reject(e)}}function a(e,t){e.messagesCallback=t}function u(){if("undefined"==typeof window)return!1;if("function"!=typeof BroadcastChannel)return!1;if(BroadcastChannel._pubkey)throw new Error("BroadcastChannel: Do not overwrite window.BroadcastChannel with this module, this is not a polyfill");return!0}function c(){return 150}n.type="native",n.NativeMethod={create:r,close:i,onMessage:a,postMessage:s,canBeUsed:u,type:"native",averageResponseTime:c,microSeconds:e}},{"../util.js":12}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.SimulateMethod=void 0,n.averageResponseTime=l,n.canBeUsed=c,n.close=s,n.create=i,n.microSeconds=void 0,n.onMessage=u,n.postMessage=a,n.type=void 0;var e=e("../util.js").microSeconds,o=(n.microSeconds=e,"simulate"),r=(n.type=o,new Set);function i(e){e={name:e,messagesCallback:null};return r.add(e),e}function s(e){r.delete(e)}function a(t,n){return new Promise(function(e){return setTimeout(function(){Array.from(r).filter(function(e){return e.name===t.name}).filter(function(e){return e!==t}).filter(function(e){return!!e.messagesCallback}).forEach(function(e){return e.messagesCallback(n)}),e()},5)})}function u(e,t){e.messagesCallback=t}function c(){return!0}function l(){return 5}n.SimulateMethod={create:i,close:s,onMessage:u,postMessage:a,canBeUsed:c,type:o,averageResponseTime:l,microSeconds:e}},{"../util.js":12}],11:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.fillOptionsWithDefaults=function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},t=JSON.parse(JSON.stringify(e));void 0===t.webWorkerSupport&&(t.webWorkerSupport=!0);t.idb||(t.idb={});t.idb.ttl||(t.idb.ttl=45e3);t.idb.fallbackInterval||(t.idb.fallbackInterval=150);e.idb&&"function"==typeof e.idb.onclose&&(t.idb.onclose=e.idb.onclose);t.localstorage||(t.localstorage={});t.localstorage.removeTimeout||(t.localstorage.removeTimeout=6e4);e.methods&&(t.methods=e.methods);t.node||(t.node={});t.node.ttl||(t.node.ttl=12e4);t.node.maxParallelWrites||(t.node.maxParallelWrites=2048);void 0===t.node.useFastPath&&(t.node.useFastPath=!0);return t}},{}],12:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.PROMISE_RESOLVED_VOID=n.PROMISE_RESOLVED_TRUE=n.PROMISE_RESOLVED_FALSE=void 0,n.isPromise=function(e){return e&&"function"==typeof e.then},n.microSeconds=function(){var e=(new Date).getTime();return e===r?1e3*e+ ++i:(i=0,1e3*(r=e))},n.randomInt=function(e,t){return Math.floor(Math.random()*(t-e+1)+e)},n.randomToken=function(){return Math.random().toString(36).substring(2)},n.sleep=function(t,n){t=t||0;return new Promise(function(e){return setTimeout(function(){return e(n)},t)})};var o=Promise.resolve(!1),o=(n.PROMISE_RESOLVED_FALSE=o,Promise.resolve(!0)),o=(n.PROMISE_RESOLVED_TRUE=o,Promise.resolve());n.PROMISE_RESOLVED_VOID=o;var r=0,i=0},{}],13:[function(e,t,n){function o(e){return t.exports=o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t.exports.__esModule=!0,t.exports.default=t.exports,o(e)}t.exports=o,t.exports.__esModule=!0,t.exports.default=t.exports},{}],14:[function(e,t,n){},{}],15:[function(e,t,n){"use strict";function o(e){this.ttl=e,this.map=new Map,this._to=!1}function r(e){for(var t=i()-e.ttl,n=e.map[Symbol.iterator]();;){var o=n.next().value;if(!o)return;var r=o[0];if(!(o[1]<t))return;e.map.delete(r)}}function i(){return(new Date).getTime()}Object.defineProperty(n,"__esModule",{value:!0}),n.now=n.removeTooOldValues=n.ObliviousSet=void 0,o.prototype.has=function(e){return this.map.has(e)},o.prototype.add=function(e){var t=this;this.map.set(e,i()),this._to||(this._to=!0,setTimeout(function(){t._to=!1,r(t)},0))},o.prototype.clear=function(){this.map.clear()},n.ObliviousSet=o,n.removeTooOldValues=r,n.now=i},{}],16:[function(e,t,n){var o,r,t=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}try{o="function"==typeof setTimeout?setTimeout:i}catch(e){o=i}try{r="function"==typeof clearTimeout?clearTimeout:s}catch(e){r=s}function a(t){if(o===setTimeout)return setTimeout(t,0);if((o===i||!o)&&setTimeout)return(o=setTimeout)(t,0);try{return o(t,0)}catch(e){try{return o.call(null,t,0)}catch(e){return o.call(this,t,0)}}}var u,c=[],l=!1,d=-1;function f(){l&&u&&(l=!1,u.length?c=u.concat(c):d=-1,c.length)&&h()}function h(){if(!l){for(var e=a(f),t=(l=!0,c.length);t;){for(u=c,c=[];++d<t;)u&&u[d].run();d=-1,t=c.length}u=null,l=!1,!function(t){if(r===clearTimeout)return clearTimeout(t);if((r===s||!r)&&clearTimeout)return(r=clearTimeout)(t);try{r(t)}catch(e){try{return r.call(null,t)}catch(e){return r.call(this,t)}}}(e)}}function p(e,t){this.fun=e,this.array=t}function m(){}t.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new p(e,t)),1!==c.length||l||a(h)},p.prototype.run=function(){this.fun.apply(null,this.array)},t.title="browser",t.browser=!0,t.env={},t.argv=[],t.version="",t.versions={},t.on=m,t.addListener=m,t.once=m,t.off=m,t.removeListener=m,t.removeAllListeners=m,t.emit=m,t.prependListener=m,t.prependOnceListener=m,t.listeners=function(e){return[]},t.binding=function(e){throw new Error("process.binding is not supported")},t.cwd=function(){return"/"},t.chdir=function(e){throw new Error("process.chdir is not supported")},t.umask=function(){return 0}},{}],17:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.addBrowser=function(e){{var t;"function"==typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?(t=self.close.bind(self),self.close=function(){return e(),t()}):"function"==typeof window.addEventListener&&(window.addEventListener("beforeunload",function(){e()},!0),window.addEventListener("unload",function(){e()},!0))}}},{}],18:[function(a,e,u){!function(s){!function(){"use strict";Object.defineProperty(u,"__esModule",{value:!0}),u.add=function(e){if(r||(r=!0,n(i)),"function"!=typeof e)throw new Error("Listener is no function");return o.add(e),{remove:function(){return o.delete(e)},run:function(){return o.delete(e),e()}}},u.getSize=function(){return o.size},u.removeAll=function(){o.clear()},u.runAll=i;var e=a("./browser.js"),t=a("./node.js"),n="[object process]"===Object.prototype.toString.call(void 0!==s?s:0)?t.addNode:e.addBrowser,o=new Set,r=!1;function i(){var t=[];return o.forEach(function(e){t.push(e()),o.delete(e)}),Promise.all(t)}}.call(this)}.call(this,a("_process"))},{"./browser.js":17,"./node.js":14,_process:16}]},{},[2]); |
@@ -70,3 +70,3 @@ "use strict"; | ||
/** | ||
* Already applying more then once, | ||
* Already applying more than once, | ||
* -> wait for the apply queue to be finished. | ||
@@ -104,6 +104,4 @@ */ | ||
}); | ||
var recieved = []; | ||
var handleMessage = function handleMessage(msg) { | ||
if (msg.context === 'leader' && msg.token != _this2.token) { | ||
recieved.push(msg); | ||
if (msg.action === 'apply') { | ||
@@ -132,3 +130,3 @@ // other is applying | ||
* not critical process is waiting for it. | ||
* When this is true, we give the other intances | ||
* When this is true, we give the other instances | ||
* more time to answer to messages in the election cycle. | ||
@@ -140,3 +138,3 @@ * This makes it less likely to elect duplicate leaders. | ||
var waitForAnswerTime = isFromFallbackInterval ? _this2._options.responseTime * 4 : _this2._options.responseTime; | ||
var applyPromise = _sendMessage(_this2, 'apply') // send out that this one is applying | ||
return _sendMessage(_this2, 'apply') // send out that this one is applying | ||
.then(function () { | ||
@@ -168,3 +166,2 @@ return Promise.race([(0, _util.sleep)(waitForAnswerTime), stopCriteriaPromise.then(function () { | ||
}); | ||
return applyPromise; | ||
}; | ||
@@ -171,0 +168,0 @@ this._aplQC = this._aplQC + 1; |
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
var _typeof = require("@babel/runtime/helpers/typeof"); | ||
@@ -9,6 +8,6 @@ Object.defineProperty(exports, "__esModule", { | ||
exports.chooseMethod = chooseMethod; | ||
var _native = _interopRequireDefault(require("./methods/native.js")); | ||
var _indexedDb = _interopRequireDefault(require("./methods/indexed-db.js")); | ||
var _localstorage = _interopRequireDefault(require("./methods/localstorage.js")); | ||
var _simulate = _interopRequireDefault(require("./methods/simulate.js")); | ||
var _native = require("./methods/native.js"); | ||
var _indexedDb = require("./methods/indexed-db.js"); | ||
var _localstorage = require("./methods/localstorage.js"); | ||
var _simulate = require("./methods/simulate.js"); | ||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } | ||
@@ -19,5 +18,5 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } | ||
// order is important | ||
var METHODS = [_native["default"], | ||
var METHODS = [_native.NativeMethod, | ||
// fastest | ||
_indexedDb["default"], _localstorage["default"]]; | ||
_indexedDb.IndexedDBMethod, _localstorage.LocalstorageMethod]; | ||
function chooseMethod(options) { | ||
@@ -32,3 +31,3 @@ var chooseMethods = [].concat(options.methods, METHODS).filter(Boolean); | ||
// only use simulate-method if directly chosen | ||
return _simulate["default"]; | ||
return _simulate.SimulateMethod; | ||
} | ||
@@ -43,3 +42,3 @@ var ret = chooseMethods.find(function (m) { | ||
* if no webworker support is needed, | ||
* remove idb from the list so that localstorage is been chosen | ||
* remove idb from the list so that localstorage will be chosen | ||
*/ | ||
@@ -54,5 +53,5 @@ if (!options.webWorkerSupport) { | ||
}); | ||
if (!useMethod) throw new Error("No useable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
if (!useMethod) throw new Error("No usable method found in " + JSON.stringify(METHODS.map(function (m) { | ||
return m.type; | ||
})));else return useMethod; | ||
} |
/** | ||
* if you really need this method, | ||
* implement it | ||
* implement it! | ||
*/ | ||
"use strict"; |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.TRANSACTION_SETTINGS = void 0; | ||
exports.TRANSACTION_SETTINGS = exports.IndexedDBMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -15,3 +15,2 @@ exports.canBeUsed = canBeUsed; | ||
exports.createDatabase = createDatabase; | ||
exports["default"] = void 0; | ||
exports.getAllMessages = getAllMessages; | ||
@@ -93,3 +92,3 @@ exports.getIdb = getIdb; | ||
}; | ||
var dbPromise = new Promise(function (res, rej) { | ||
return new Promise(function (res, rej) { | ||
openRequest.onerror = function (ev) { | ||
@@ -102,3 +101,2 @@ return rej(ev); | ||
}); | ||
return dbPromise; | ||
} | ||
@@ -235,3 +233,2 @@ | ||
res(ret); | ||
return; | ||
} | ||
@@ -266,3 +263,3 @@ } else { | ||
eMIs: new _obliviousSet.ObliviousSet(options.idb.ttl * 2), | ||
// ensures we do not read messages in parrallel | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: _util.PROMISE_RESOLVED_VOID, | ||
@@ -321,3 +318,3 @@ messagesCallback: null, | ||
/** | ||
* there is a bug in iOS where the msgObj can be undefined some times | ||
* there is a bug in iOS where the msgObj can be undefined sometimes | ||
* so we filter them out | ||
@@ -367,7 +364,3 @@ * @link https://github.com/pubkey/broadcast-channel/issues/19 | ||
function canBeUsed() { | ||
var idb = getIdb(); | ||
if (!idb) { | ||
return false; | ||
} | ||
return true; | ||
return !!getIdb(); | ||
} | ||
@@ -377,3 +370,3 @@ function averageResponseTime(options) { | ||
} | ||
var _default = { | ||
var IndexedDBMethod = { | ||
create: create, | ||
@@ -388,2 +381,2 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.IndexedDBMethod = IndexedDBMethod; |
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.LocalstorageMethod = void 0; | ||
exports.addStorageEventListener = addStorageEventListener; | ||
@@ -12,3 +13,2 @@ exports.averageResponseTime = averageResponseTime; | ||
exports.create = create; | ||
exports["default"] = void 0; | ||
exports.getLocalStorage = getLocalStorage; | ||
@@ -26,4 +26,4 @@ exports.microSeconds = void 0; | ||
* A localStorage-only method which uses localstorage and its 'storage'-event | ||
* This does not work inside of webworkers because they have no access to locastorage | ||
* This is basically implemented to support IE9 or your grandmothers toaster. | ||
* This does not work inside webworkers because they have no access to localstorage | ||
* This is basically implemented to support IE9 or your grandmother's toaster. | ||
* @link https://caniuse.com/#feat=namevalue-storage | ||
@@ -165,3 +165,3 @@ * @link https://caniuse.com/#feat=indexeddb | ||
} | ||
var _default = { | ||
var LocalstorageMethod = { | ||
create: create, | ||
@@ -176,2 +176,2 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.LocalstorageMethod = LocalstorageMethod; |
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.NativeMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -11,3 +12,3 @@ exports.canBeUsed = canBeUsed; | ||
exports.create = create; | ||
exports.microSeconds = exports["default"] = void 0; | ||
exports.microSeconds = void 0; | ||
exports.onMessage = onMessage; | ||
@@ -66,3 +67,3 @@ exports.postMessage = postMessage; | ||
} | ||
var _default = { | ||
var NativeMethod = { | ||
create: create, | ||
@@ -77,2 +78,2 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.NativeMethod = NativeMethod; |
@@ -118,15 +118,13 @@ "use strict"; | ||
return _regenerator["default"].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!ENSURE_BASE_FOLDER_EXISTS_PROMISE) { | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = mkdir(TMP_FOLDER_BASE)["catch"](function () { | ||
return null; | ||
}); | ||
} | ||
return _context3.abrupt("return", ENSURE_BASE_FOLDER_EXISTS_PROMISE); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
while (1) switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!ENSURE_BASE_FOLDER_EXISTS_PROMISE) { | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = mkdir(TMP_FOLDER_BASE)["catch"](function () { | ||
return null; | ||
}); | ||
} | ||
return _context3.abrupt("return", ENSURE_BASE_FOLDER_EXISTS_PROMISE); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
@@ -148,31 +146,29 @@ }, _callee3); | ||
return _regenerator["default"].wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
_context4.next = 3; | ||
return ensureBaseFolderExists(); | ||
case 3: | ||
_context4.next = 5; | ||
return mkdir(paths.channelBase)["catch"](function () { | ||
return null; | ||
}); | ||
case 5: | ||
_context4.next = 7; | ||
return Promise.all([mkdir(paths.readers)["catch"](function () { | ||
return null; | ||
}), mkdir(paths.messages)["catch"](function () { | ||
return null; | ||
})]); | ||
case 7: | ||
// set permissions so other users can use the same channel | ||
chmodValue = '777'; | ||
_context4.next = 10; | ||
return Promise.all([chmod(paths.channelBase, chmodValue), chmod(paths.readers, chmodValue), chmod(paths.messages, chmodValue)])["catch"](function () { | ||
return null; | ||
}); | ||
case 10: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
while (1) switch (_context4.prev = _context4.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
_context4.next = 3; | ||
return ensureBaseFolderExists(); | ||
case 3: | ||
_context4.next = 5; | ||
return mkdir(paths.channelBase)["catch"](function () { | ||
return null; | ||
}); | ||
case 5: | ||
_context4.next = 7; | ||
return Promise.all([mkdir(paths.readers)["catch"](function () { | ||
return null; | ||
}), mkdir(paths.messages)["catch"](function () { | ||
return null; | ||
})]); | ||
case 7: | ||
// set permissions so other users can use the same channel | ||
chmodValue = '777'; | ||
_context4.next = 10; | ||
return Promise.all([chmod(paths.channelBase, chmodValue), chmod(paths.readers, chmodValue), chmod(paths.messages, chmodValue)])["catch"](function () { | ||
return null; | ||
}); | ||
case 10: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
@@ -189,21 +185,19 @@ }, _callee4); | ||
return _regenerator["default"].wrap(function _callee5$(_context5) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(!TMP_FOLDER_BASE || TMP_FOLDER_BASE === '' || TMP_FOLDER_BASE === '/')) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
throw new Error('BroadcastChannel.clearNodeFolder(): path is wrong'); | ||
case 2: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
_context5.next = 5; | ||
return removeDir(TMP_FOLDER_BASE); | ||
case 5: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
return _context5.abrupt("return", true); | ||
case 7: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
while (1) switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(!TMP_FOLDER_BASE || TMP_FOLDER_BASE === '' || TMP_FOLDER_BASE === '/')) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
throw new Error('BroadcastChannel.clearNodeFolder(): path is wrong'); | ||
case 2: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
_context5.next = 5; | ||
return removeDir(TMP_FOLDER_BASE); | ||
case 5: | ||
ENSURE_BASE_FOLDER_EXISTS_PROMISE = null; | ||
return _context5.abrupt("return", true); | ||
case 7: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
@@ -221,4 +215,3 @@ }, _callee5); | ||
paths = paths || getPaths(channelName); | ||
var socketPath = _path["default"].join(paths.readers, readerUuid + '.json'); | ||
return socketPath; | ||
return _path["default"].join(paths.readers, readerUuid + '.json'); | ||
} | ||
@@ -251,17 +244,15 @@ | ||
return _regenerator["default"].wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_context6.next = 2; | ||
return ensureBaseFolderExists(); | ||
case 2: | ||
_context6.next = 4; | ||
return readdir(TMP_FOLDER_BASE); | ||
case 4: | ||
folders = _context6.sent; | ||
return _context6.abrupt("return", folders.length); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
while (1) switch (_context6.prev = _context6.next) { | ||
case 0: | ||
_context6.next = 2; | ||
return ensureBaseFolderExists(); | ||
case 2: | ||
_context6.next = 4; | ||
return readdir(TMP_FOLDER_BASE); | ||
case 4: | ||
folders = _context6.sent; | ||
return _context6.abrupt("return", folders.length); | ||
case 6: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
@@ -281,30 +272,27 @@ }, _callee6); | ||
_connectionError = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7(originalError) { | ||
var count, addObj, text, newError; | ||
var count, addObj, text; | ||
return _regenerator["default"].wrap(function _callee7$(_context7) { | ||
while (1) { | ||
switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return countChannelFolders(); | ||
case 2: | ||
count = _context7.sent; | ||
if (!(count < 30)) { | ||
_context7.next = 5; | ||
break; | ||
} | ||
return _context7.abrupt("return", originalError); | ||
case 5: | ||
addObj = {}; | ||
Object.entries(originalError).forEach(function (_ref3) { | ||
var k = _ref3[0], | ||
v = _ref3[1]; | ||
return addObj[k] = v; | ||
}); | ||
text = 'BroadcastChannel.create(): error: ' + 'This might happen if you have created to many channels, ' + 'like when you use BroadcastChannel in unit-tests.' + 'Try using BroadcastChannel.clearNodeFolder() to clear the tmp-folder before each test.' + 'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
newError = new Error(text + ': ' + JSON.stringify(addObj, null, 2)); | ||
return _context7.abrupt("return", newError); | ||
case 10: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
while (1) switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return countChannelFolders(); | ||
case 2: | ||
count = _context7.sent; | ||
if (!(count < 30)) { | ||
_context7.next = 5; | ||
break; | ||
} | ||
return _context7.abrupt("return", originalError); | ||
case 5: | ||
addObj = {}; | ||
Object.entries(originalError).forEach(function (_ref3) { | ||
var k = _ref3[0], | ||
v = _ref3[1]; | ||
return addObj[k] = v; | ||
}); | ||
text = 'BroadcastChannel.create(): error: ' + 'This might happen if you have created to many channels, ' + 'like when you use BroadcastChannel in unit-tests.' + 'Try using BroadcastChannel.clearNodeFolder() to clear the tmp-folder before each test.' + 'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
return _context7.abrupt("return", new Error(text + ': ' + JSON.stringify(addObj, null, 2))); | ||
case 9: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
@@ -322,80 +310,74 @@ }, _callee7); | ||
return _regenerator["default"].wrap(function _callee10$(_context10) { | ||
while (1) { | ||
switch (_context10.prev = _context10.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid, paths); | ||
emitter = new _events["default"].EventEmitter(); | ||
server = _net["default"].createServer(function (stream) { | ||
stream.on('end', function () {}); | ||
stream.on('data', function (msg) { | ||
emitter.emit('data', msg.toString()); | ||
}); | ||
while (1) switch (_context10.prev = _context10.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid, paths); | ||
emitter = new _events["default"].EventEmitter(); | ||
server = _net["default"].createServer(function (stream) { | ||
stream.on('end', function () {}); | ||
stream.on('data', function (msg) { | ||
emitter.emit('data', msg.toString()); | ||
}); | ||
_context10.next = 5; | ||
return new Promise(function (resolve, reject) { | ||
server.on('error', /*#__PURE__*/function () { | ||
var _ref4 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(err) { | ||
var useErr; | ||
return _regenerator["default"].wrap(function _callee8$(_context8) { | ||
while (1) { | ||
switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return connectionError(err); | ||
case 2: | ||
useErr = _context8.sent; | ||
reject(useErr); | ||
case 4: | ||
case "end": | ||
return _context8.stop(); | ||
}); | ||
_context10.next = 5; | ||
return new Promise(function (resolve, reject) { | ||
server.on('error', /*#__PURE__*/function () { | ||
var _ref4 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(err) { | ||
var useErr; | ||
return _regenerator["default"].wrap(function _callee8$(_context8) { | ||
while (1) switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return connectionError(err); | ||
case 2: | ||
useErr = _context8.sent; | ||
reject(useErr); | ||
case 4: | ||
case "end": | ||
return _context8.stop(); | ||
} | ||
}, _callee8); | ||
})); | ||
return function (_x26) { | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}()); | ||
server.listen(pathToSocket, /*#__PURE__*/function () { | ||
var _ref5 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9(err, res) { | ||
var useErr; | ||
return _regenerator["default"].wrap(function _callee9$(_context9) { | ||
while (1) switch (_context9.prev = _context9.next) { | ||
case 0: | ||
if (!err) { | ||
_context9.next = 7; | ||
break; | ||
} | ||
} | ||
}, _callee8); | ||
})); | ||
return function (_x26) { | ||
return _ref4.apply(this, arguments); | ||
}; | ||
}()); | ||
server.listen(pathToSocket, /*#__PURE__*/function () { | ||
var _ref5 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9(err, res) { | ||
var useErr; | ||
return _regenerator["default"].wrap(function _callee9$(_context9) { | ||
while (1) { | ||
switch (_context9.prev = _context9.next) { | ||
case 0: | ||
if (!err) { | ||
_context9.next = 7; | ||
break; | ||
} | ||
_context9.next = 3; | ||
return connectionError(err); | ||
case 3: | ||
useErr = _context9.sent; | ||
reject(useErr); | ||
_context9.next = 8; | ||
break; | ||
case 7: | ||
resolve(res); | ||
case 8: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
} | ||
}, _callee9); | ||
})); | ||
return function (_x27, _x28) { | ||
return _ref5.apply(this, arguments); | ||
}; | ||
}()); | ||
}); | ||
case 5: | ||
return _context10.abrupt("return", { | ||
path: pathToSocket, | ||
emitter: emitter, | ||
server: server | ||
}); | ||
case 6: | ||
case "end": | ||
return _context10.stop(); | ||
} | ||
_context9.next = 3; | ||
return connectionError(err); | ||
case 3: | ||
useErr = _context9.sent; | ||
reject(useErr); | ||
_context9.next = 8; | ||
break; | ||
case 7: | ||
resolve(res); | ||
case 8: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
}, _callee9); | ||
})); | ||
return function (_x27, _x28) { | ||
return _ref5.apply(this, arguments); | ||
}; | ||
}()); | ||
}); | ||
case 5: | ||
return _context10.abrupt("return", { | ||
path: pathToSocket, | ||
emitter: emitter, | ||
server: server | ||
}); | ||
case 6: | ||
case "end": | ||
return _context10.stop(); | ||
} | ||
@@ -418,19 +400,17 @@ }, _callee10); | ||
return _regenerator["default"].wrap(function _callee11$(_context11) { | ||
while (1) { | ||
switch (_context11.prev = _context11.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid); | ||
client = new _net["default"].Socket(); | ||
return _context11.abrupt("return", new Promise(function (res, rej) { | ||
client.connect(pathToSocket, function () { | ||
return res(client); | ||
}); | ||
client.on('error', function (err) { | ||
return rej(err); | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context11.stop(); | ||
} | ||
while (1) switch (_context11.prev = _context11.next) { | ||
case 0: | ||
pathToSocket = socketPath(channelName, readerUuid); | ||
client = new _net["default"].Socket(); | ||
return _context11.abrupt("return", new Promise(function (res, rej) { | ||
client.connect(pathToSocket, function () { | ||
return res(client); | ||
}); | ||
client.on('error', function (err) { | ||
return rej(err); | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context11.stop(); | ||
} | ||
@@ -473,23 +453,21 @@ }, _callee11); | ||
return _regenerator["default"].wrap(function _callee12$(_context12) { | ||
while (1) { | ||
switch (_context12.prev = _context12.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
readersPath = paths.readers; | ||
_context12.next = 4; | ||
return readdir(readersPath); | ||
case 4: | ||
files = _context12.sent; | ||
return _context12.abrupt("return", files.map(function (file) { | ||
return file.split('.'); | ||
}).filter(function (split) { | ||
return split[1] === 'json'; | ||
}) // do not scan .socket-files | ||
.map(function (split) { | ||
return split[0]; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
while (1) switch (_context12.prev = _context12.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
readersPath = paths.readers; | ||
_context12.next = 4; | ||
return readdir(readersPath); | ||
case 4: | ||
files = _context12.sent; | ||
return _context12.abrupt("return", files.map(function (file) { | ||
return file.split('.'); | ||
}).filter(function (split) { | ||
return split[1] === 'json'; | ||
}) // do not scan .socket-files | ||
.map(function (split) { | ||
return split[0]; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
@@ -505,14 +483,11 @@ }, _callee12); | ||
_messagePath = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee13(channelName, time, token, writerUuid) { | ||
var fileName, msgPath; | ||
var fileName; | ||
return _regenerator["default"].wrap(function _callee13$(_context13) { | ||
while (1) { | ||
switch (_context13.prev = _context13.next) { | ||
case 0: | ||
fileName = time + '_' + writerUuid + '_' + token + '.json'; | ||
msgPath = _path["default"].join(getPaths(channelName).messages, fileName); | ||
return _context13.abrupt("return", msgPath); | ||
case 3: | ||
case "end": | ||
return _context13.stop(); | ||
} | ||
while (1) switch (_context13.prev = _context13.next) { | ||
case 0: | ||
fileName = time + '_' + writerUuid + '_' + token + '.json'; | ||
return _context13.abrupt("return", _path["default"].join(getPaths(channelName).messages, fileName)); | ||
case 2: | ||
case "end": | ||
return _context13.stop(); | ||
} | ||
@@ -530,25 +505,23 @@ }, _callee13); | ||
return _regenerator["default"].wrap(function _callee14$(_context14) { | ||
while (1) { | ||
switch (_context14.prev = _context14.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
messagesPath = paths.messages; | ||
_context14.next = 4; | ||
return readdir(messagesPath); | ||
case 4: | ||
files = _context14.sent; | ||
return _context14.abrupt("return", files.map(function (file) { | ||
var fileName = file.split('.')[0]; | ||
var split = fileName.split('_'); | ||
return { | ||
path: _path["default"].join(messagesPath, file), | ||
time: parseInt(split[0]), | ||
senderUuid: split[1], | ||
token: split[2] | ||
}; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context14.stop(); | ||
} | ||
while (1) switch (_context14.prev = _context14.next) { | ||
case 0: | ||
paths = paths || getPaths(channelName); | ||
messagesPath = paths.messages; | ||
_context14.next = 4; | ||
return readdir(messagesPath); | ||
case 4: | ||
files = _context14.sent; | ||
return _context14.abrupt("return", files.map(function (file) { | ||
var fileName = file.split('.')[0]; | ||
var split = fileName.split('_'); | ||
return { | ||
path: _path["default"].join(messagesPath, file), | ||
time: parseInt(split[0]), | ||
senderUuid: split[1], | ||
token: split[2] | ||
}; | ||
})); | ||
case 6: | ||
case "end": | ||
return _context14.stop(); | ||
} | ||
@@ -578,20 +551,18 @@ }, _callee14); | ||
_cleanOldMessages = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee15(messageObjects, ttl) { | ||
var olderThen; | ||
var olderThan; | ||
return _regenerator["default"].wrap(function _callee15$(_context15) { | ||
while (1) { | ||
switch (_context15.prev = _context15.next) { | ||
case 0: | ||
olderThen = microSeconds() - ttl * 1000; // convert ttl to microseconds | ||
_context15.next = 3; | ||
return Promise.all(messageObjects.filter(function (obj) { | ||
return obj.time < olderThen; | ||
}).map(function (obj) { | ||
return unlink(obj.path)["catch"](function () { | ||
return null; | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context15.stop(); | ||
} | ||
while (1) switch (_context15.prev = _context15.next) { | ||
case 0: | ||
olderThan = microSeconds() - ttl * 1000; // convert ttl to microseconds | ||
_context15.next = 3; | ||
return Promise.all(messageObjects.filter(function (obj) { | ||
return obj.time < olderThan; | ||
}).map(function (obj) { | ||
return unlink(obj.path)["catch"](function () { | ||
return null; | ||
}); | ||
})); | ||
case 3: | ||
case "end": | ||
return _context15.stop(); | ||
} | ||
@@ -625,73 +596,71 @@ }, _callee15); | ||
return _regenerator["default"].wrap(function _callee16$(_context16) { | ||
while (1) { | ||
switch (_context16.prev = _context16.next) { | ||
case 0: | ||
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {}; | ||
options = (0, _options.fillOptionsWithDefaults)(options); | ||
time = microSeconds(); | ||
paths = getPaths(channelName); | ||
ensureFolderExistsPromise = ensureFoldersExist(channelName, paths); | ||
uuid = (0, _util2.randomToken)(); | ||
state = { | ||
time: time, | ||
channelName: channelName, | ||
options: options, | ||
uuid: uuid, | ||
paths: paths, | ||
// contains all messages that have been emitted before | ||
emittedMessagesIds: new _obliviousSet.ObliviousSet(options.node.ttl * 2), | ||
/** | ||
* Used to ensure we do not write too many files at once | ||
* which could throw an error. | ||
* Must always be smaller then options.node.maxParallelWrites | ||
*/ | ||
writeFileQueue: new _pQueue["default"]({ | ||
concurrency: options.node.maxParallelWrites | ||
}), | ||
messagesCallbackTime: null, | ||
messagesCallback: null, | ||
// ensures we do not read messages in parrallel | ||
writeBlockPromise: _util2.PROMISE_RESOLVED_VOID, | ||
otherReaderClients: {}, | ||
// ensure if process crashes, everything is cleaned up | ||
removeUnload: (0, _unload.add)(function () { | ||
return close(state); | ||
}), | ||
closed: false | ||
}; | ||
if (!OTHER_INSTANCES[channelName]) OTHER_INSTANCES[channelName] = []; | ||
OTHER_INSTANCES[channelName].push(state); | ||
_context16.next = 11; | ||
return ensureFolderExistsPromise; | ||
case 11: | ||
_context16.next = 13; | ||
return Promise.all([createSocketEventEmitter(channelName, uuid, paths), createSocketInfoFile(channelName, uuid, paths), refreshReaderClients(state)]); | ||
case 13: | ||
_yield$Promise$all = _context16.sent; | ||
socketEE = _yield$Promise$all[0]; | ||
infoFilePath = _yield$Promise$all[1]; | ||
state.socketEE = socketEE; | ||
state.infoFilePath = infoFilePath; | ||
while (1) switch (_context16.prev = _context16.next) { | ||
case 0: | ||
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {}; | ||
options = (0, _options.fillOptionsWithDefaults)(options); | ||
time = microSeconds(); | ||
paths = getPaths(channelName); | ||
ensureFolderExistsPromise = ensureFoldersExist(channelName, paths); | ||
uuid = (0, _util2.randomToken)(); | ||
state = { | ||
time: time, | ||
channelName: channelName, | ||
options: options, | ||
uuid: uuid, | ||
paths: paths, | ||
// contains all messages that have been emitted before | ||
emittedMessagesIds: new _obliviousSet.ObliviousSet(options.node.ttl * 2), | ||
/** | ||
* Used to ensure we do not write too many files at once | ||
* which could throw an error. | ||
* Must always be smaller than options.node.maxParallelWrites | ||
*/ | ||
writeFileQueue: new _pQueue["default"]({ | ||
concurrency: options.node.maxParallelWrites | ||
}), | ||
messagesCallbackTime: null, | ||
messagesCallback: null, | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: _util2.PROMISE_RESOLVED_VOID, | ||
otherReaderClients: {}, | ||
// ensure if process crashes, everything is cleaned up | ||
removeUnload: (0, _unload.add)(function () { | ||
return close(state); | ||
}), | ||
closed: false | ||
}; | ||
if (!OTHER_INSTANCES[channelName]) OTHER_INSTANCES[channelName] = []; | ||
OTHER_INSTANCES[channelName].push(state); | ||
_context16.next = 11; | ||
return ensureFolderExistsPromise; | ||
case 11: | ||
_context16.next = 13; | ||
return Promise.all([createSocketEventEmitter(channelName, uuid, paths), createSocketInfoFile(channelName, uuid, paths), refreshReaderClients(state)]); | ||
case 13: | ||
_yield$Promise$all = _context16.sent; | ||
socketEE = _yield$Promise$all[0]; | ||
infoFilePath = _yield$Promise$all[1]; | ||
state.socketEE = socketEE; | ||
state.infoFilePath = infoFilePath; | ||
// when new message comes in, we read it and emit it | ||
socketEE.emitter.on('data', function (data) { | ||
// if the socket is used fast, it may appear that multiple messages are flushed at once | ||
// so we have to split them before | ||
var singleOnes = data.split('|'); | ||
singleOnes.filter(function (single) { | ||
return single !== ''; | ||
}).forEach(function (single) { | ||
try { | ||
var obj = JSON.parse(single); | ||
handleMessagePing(state, obj); | ||
} catch (err) { | ||
throw new Error('could not parse data: ' + single); | ||
} | ||
}); | ||
// when new message comes in, we read it and emit it | ||
socketEE.emitter.on('data', function (data) { | ||
// if the socket is used fast, it may appear that multiple messages are flushed at once | ||
// so we have to split them before | ||
var singleOnes = data.split('|'); | ||
singleOnes.filter(function (single) { | ||
return single !== ''; | ||
}).forEach(function (single) { | ||
try { | ||
var obj = JSON.parse(single); | ||
handleMessagePing(state, obj); | ||
} catch (err) { | ||
throw new Error('could not parse data: ' + single); | ||
} | ||
}); | ||
return _context16.abrupt("return", state); | ||
case 20: | ||
case "end": | ||
return _context16.stop(); | ||
} | ||
}); | ||
return _context16.abrupt("return", state); | ||
case 20: | ||
case "end": | ||
return _context16.stop(); | ||
} | ||
@@ -728,55 +697,53 @@ }, _callee16); | ||
return _regenerator["default"].wrap(function _callee17$(_context17) { | ||
while (1) { | ||
switch (_context17.prev = _context17.next) { | ||
case 0: | ||
while (1) switch (_context17.prev = _context17.next) { | ||
case 0: | ||
if (state.messagesCallback) { | ||
_context17.next = 2; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 2: | ||
if (msgObj) { | ||
_context17.next = 8; | ||
break; | ||
} | ||
_context17.next = 5; | ||
return getAllMessages(state.channelName, state.paths); | ||
case 5: | ||
messages = _context17.sent; | ||
_context17.next = 9; | ||
break; | ||
case 8: | ||
// get single message | ||
messages = [getSingleMessage(state.channelName, msgObj, state.paths)]; | ||
case 9: | ||
useMessages = messages.filter(function (msgObj) { | ||
return _filterMessage(msgObj, state); | ||
}).sort(function (msgObjA, msgObjB) { | ||
return msgObjA.time - msgObjB.time; | ||
}); // sort by time | ||
// if no listener or message, so not do anything | ||
if (!(!useMessages.length || !state.messagesCallback)) { | ||
_context17.next = 12; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 12: | ||
_context17.next = 14; | ||
return Promise.all(useMessages.map(function (msgObj) { | ||
return readMessage(msgObj).then(function (content) { | ||
return msgObj.content = content; | ||
}); | ||
})); | ||
case 14: | ||
useMessages.forEach(function (msgObj) { | ||
state.emittedMessagesIds.add(msgObj.token); | ||
if (state.messagesCallback) { | ||
_context17.next = 2; | ||
break; | ||
// emit to subscribers | ||
state.messagesCallback(msgObj.content.data); | ||
} | ||
return _context17.abrupt("return"); | ||
case 2: | ||
if (msgObj) { | ||
_context17.next = 8; | ||
break; | ||
} | ||
_context17.next = 5; | ||
return getAllMessages(state.channelName, state.paths); | ||
case 5: | ||
messages = _context17.sent; | ||
_context17.next = 9; | ||
break; | ||
case 8: | ||
// get single message | ||
messages = [getSingleMessage(state.channelName, msgObj, state.paths)]; | ||
case 9: | ||
useMessages = messages.filter(function (msgObj) { | ||
return _filterMessage(msgObj, state); | ||
}).sort(function (msgObjA, msgObjB) { | ||
return msgObjA.time - msgObjB.time; | ||
}); // sort by time | ||
// if no listener or message, so not do anything | ||
if (!(!useMessages.length || !state.messagesCallback)) { | ||
_context17.next = 12; | ||
break; | ||
} | ||
return _context17.abrupt("return"); | ||
case 12: | ||
_context17.next = 14; | ||
return Promise.all(useMessages.map(function (msgObj) { | ||
return readMessage(msgObj).then(function (content) { | ||
return msgObj.content = content; | ||
}); | ||
})); | ||
case 14: | ||
useMessages.forEach(function (msgObj) { | ||
state.emittedMessagesIds.add(msgObj.token); | ||
if (state.messagesCallback) { | ||
// emit to subscribers | ||
state.messagesCallback(msgObj.content.data); | ||
} | ||
}); | ||
case 15: | ||
case "end": | ||
return _context17.stop(); | ||
} | ||
}); | ||
case 15: | ||
case "end": | ||
return _context17.stop(); | ||
} | ||
@@ -795,20 +762,18 @@ }, _callee17); | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.prev = 0; | ||
_context.next = 3; | ||
return channelState.otherReaderClients[readerUuid].destroy(); | ||
case 3: | ||
_context.next = 7; | ||
break; | ||
case 5: | ||
_context.prev = 5; | ||
_context.t0 = _context["catch"](0); | ||
case 7: | ||
delete channelState.otherReaderClients[readerUuid]; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
while (1) switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.prev = 0; | ||
_context.next = 3; | ||
return channelState.otherReaderClients[readerUuid].destroy(); | ||
case 3: | ||
_context.next = 7; | ||
break; | ||
case 5: | ||
_context.prev = 5; | ||
_context.t0 = _context["catch"](0); | ||
case 7: | ||
delete channelState.otherReaderClients[readerUuid]; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
@@ -833,33 +798,31 @@ }, _callee, null, [[0, 5]]); | ||
return _regenerator["default"].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
if (!channelState.closed) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
case 3: | ||
_context2.prev = 3; | ||
_context2.next = 6; | ||
return openClientConnection(channelState.channelName, readerUuid); | ||
case 6: | ||
client = _context2.sent; | ||
channelState.otherReaderClients[readerUuid] = client; | ||
_context2.next = 12; | ||
while (1) switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
if (!channelState.closed) { | ||
_context2.next = 3; | ||
break; | ||
case 10: | ||
_context2.prev = 10; | ||
_context2.t0 = _context2["catch"](3); | ||
case 12: | ||
_context2.next = 16; | ||
break; | ||
case 14: | ||
_context2.prev = 14; | ||
_context2.t1 = _context2["catch"](0); | ||
case 16: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
return _context2.abrupt("return"); | ||
case 3: | ||
_context2.prev = 3; | ||
_context2.next = 6; | ||
return openClientConnection(channelState.channelName, readerUuid); | ||
case 6: | ||
client = _context2.sent; | ||
channelState.otherReaderClients[readerUuid] = client; | ||
_context2.next = 12; | ||
break; | ||
case 10: | ||
_context2.prev = 10; | ||
_context2.t0 = _context2["catch"](3); | ||
case 12: | ||
_context2.next = 16; | ||
break; | ||
case 14: | ||
_context2.prev = 14; | ||
_context2.t1 = _context2["catch"](0); | ||
case 16: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
@@ -892,58 +855,54 @@ }, _callee2, null, [[0, 14], [3, 10]]); | ||
return _regenerator["default"].wrap(function _callee19$(_context19) { | ||
while (1) { | ||
switch (_context19.prev = _context19.next) { | ||
case 0: | ||
writePromise = channelState.writeFileQueue.add(function () { | ||
return writeMessage(channelState.channelName, channelState.uuid, messageJson, channelState.paths); | ||
}); | ||
channelState.writeBlockPromise = channelState.writeBlockPromise.then( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee18() { | ||
var _yield$Promise$all2, msgObj, pingStr, writeToReadersPromise; | ||
return _regenerator["default"].wrap(function _callee18$(_context18) { | ||
while (1) { | ||
switch (_context18.prev = _context18.next) { | ||
case 0: | ||
_context18.next = 2; | ||
return new Promise(function (res) { | ||
return setTimeout(res, 0); | ||
}); | ||
case 2: | ||
_context18.next = 4; | ||
return Promise.all([writePromise, refreshReaderClients(channelState)]); | ||
case 4: | ||
_yield$Promise$all2 = _context18.sent; | ||
msgObj = _yield$Promise$all2[0]; | ||
emitOverFastPath(channelState, msgObj, messageJson); | ||
pingStr = '{"t":' + msgObj.time + ',"u":"' + msgObj.uuid + '","to":"' + msgObj.token + '"}|'; | ||
writeToReadersPromise = Promise.all(Object.values(channelState.otherReaderClients).filter(function (client) { | ||
return client.writable; | ||
}) // client might have closed in between | ||
.map(function (client) { | ||
return new Promise(function (res) { | ||
client.write(pingStr, res); | ||
}); | ||
})); | ||
/** | ||
* clean up old messages | ||
* to not waste resources on cleaning up, | ||
* only if random-int matches, we clean up old messages | ||
*/ | ||
if ((0, _util2.randomInt)(0, 20) === 0) { | ||
/* await */ | ||
getAllMessages(channelState.channelName, channelState.paths).then(function (allMessages) { | ||
return cleanOldMessages(allMessages, channelState.options.node.ttl); | ||
}); | ||
} | ||
return _context18.abrupt("return", writeToReadersPromise); | ||
case 11: | ||
case "end": | ||
return _context18.stop(); | ||
while (1) switch (_context19.prev = _context19.next) { | ||
case 0: | ||
writePromise = channelState.writeFileQueue.add(function () { | ||
return writeMessage(channelState.channelName, channelState.uuid, messageJson, channelState.paths); | ||
}); | ||
channelState.writeBlockPromise = channelState.writeBlockPromise.then( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee18() { | ||
var _yield$Promise$all2, msgObj, pingStr, writeToReadersPromise; | ||
return _regenerator["default"].wrap(function _callee18$(_context18) { | ||
while (1) switch (_context18.prev = _context18.next) { | ||
case 0: | ||
_context18.next = 2; | ||
return new Promise(function (res) { | ||
return setTimeout(res, 0); | ||
}); | ||
case 2: | ||
_context18.next = 4; | ||
return Promise.all([writePromise, refreshReaderClients(channelState)]); | ||
case 4: | ||
_yield$Promise$all2 = _context18.sent; | ||
msgObj = _yield$Promise$all2[0]; | ||
emitOverFastPath(channelState, msgObj, messageJson); | ||
pingStr = '{"t":' + msgObj.time + ',"u":"' + msgObj.uuid + '","to":"' + msgObj.token + '"}|'; | ||
writeToReadersPromise = Promise.all(Object.values(channelState.otherReaderClients).filter(function (client) { | ||
return client.writable; | ||
}) // client might have closed in between | ||
.map(function (client) { | ||
return new Promise(function (res) { | ||
client.write(pingStr, res); | ||
}); | ||
})); | ||
/** | ||
* clean up old messages | ||
* to not waste resources on cleaning up, | ||
* only if random-int matches, we clean up old messages | ||
*/ | ||
if ((0, _util2.randomInt)(0, 20) === 0) { | ||
/* await */ | ||
getAllMessages(channelState.channelName, channelState.paths).then(function (allMessages) { | ||
return cleanOldMessages(allMessages, channelState.options.node.ttl); | ||
}); | ||
} | ||
} | ||
}, _callee18); | ||
}))); | ||
return _context19.abrupt("return", channelState.writeBlockPromise); | ||
case 3: | ||
case "end": | ||
return _context19.stop(); | ||
} | ||
return _context18.abrupt("return", writeToReadersPromise); | ||
case 11: | ||
case "end": | ||
return _context18.stop(); | ||
} | ||
}, _callee18); | ||
}))); | ||
return _context19.abrupt("return", channelState.writeBlockPromise); | ||
case 3: | ||
case "end": | ||
return _context19.stop(); | ||
} | ||
@@ -985,3 +944,3 @@ }, _callee19); | ||
function close(channelState) { | ||
if (channelState.closed) return; | ||
if (channelState.closed) return _util2.PROMISE_RESOLVED_VOID; | ||
channelState.closed = true; | ||
@@ -1017,14 +976,10 @@ channelState.emittedMessagesIds.clear(); | ||
function canBeUsed() { | ||
if (typeof _fs["default"].mkdir === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return typeof _fs["default"].mkdir === 'function'; | ||
} | ||
/** | ||
* on node we use a relatively height averageResponseTime, | ||
* on node we use a relatively high averageResponseTime, | ||
* because the file-io might be in use. | ||
* Also it is more important that the leader-election is reliable, | ||
* then to have a fast election. | ||
* than to have a fast election. | ||
*/ | ||
@@ -1031,0 +986,0 @@ function averageResponseTime() { |
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.SimulateMethod = void 0; | ||
exports.averageResponseTime = averageResponseTime; | ||
@@ -11,3 +12,3 @@ exports.canBeUsed = canBeUsed; | ||
exports.create = create; | ||
exports.microSeconds = exports["default"] = void 0; | ||
exports.microSeconds = void 0; | ||
exports.onMessage = onMessage; | ||
@@ -59,3 +60,3 @@ exports.postMessage = postMessage; | ||
} | ||
var _default = { | ||
var SimulateMethod = { | ||
create: create, | ||
@@ -70,2 +71,2 @@ close: close, | ||
}; | ||
exports["default"] = _default; | ||
exports.SimulateMethod = SimulateMethod; |
@@ -16,7 +16,3 @@ "use strict"; | ||
function isPromise(obj) { | ||
if (obj && typeof obj.then === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return obj && typeof obj.then === 'function'; | ||
} | ||
@@ -23,0 +19,0 @@ var PROMISE_RESOLVED_FALSE = Promise.resolve(false); |
{ | ||
"name": "broadcast-channel", | ||
"version": "4.18.1", | ||
"description": "A BroadcastChannel that works in New Browsers, Old Browsers, WebWorkers and NodeJs", | ||
"version": "4.19.0", | ||
"description": "A BroadcastChannel that works in New Browsers, Old Browsers, WebWorkers and NodeJs and iframes", | ||
"exports": { | ||
@@ -88,7 +88,7 @@ ".": { | ||
"dependencies": { | ||
"@babel/runtime": "^7.16.0", | ||
"@babel/runtime": "7.20.7", | ||
"oblivious-set": "1.1.1", | ||
"p-queue": "6.6.2", | ||
"rimraf": "3.0.2", | ||
"unload": "2.3.1" | ||
"unload": "2.4.0" | ||
}, | ||
@@ -116,2 +116,3 @@ "devDependencies": { | ||
"cross-env": "7.0.3", | ||
"detect-node": "2.1.0", | ||
"eslint": "8.26.0", | ||
@@ -118,0 +119,0 @@ "gzip-size-cli": "5.1.0", |
@@ -53,3 +53,3 @@ import { | ||
/** | ||
* Unsend message promises | ||
* Unsent message promises | ||
* where the sending is still in progress | ||
@@ -115,3 +115,3 @@ * @type {Set<Promise>} | ||
/** | ||
* In the past when this error appeared, it was realy hard to debug. | ||
* In the past when this error appeared, it was really hard to debug. | ||
* So now we log the msg together with the error so it at least | ||
@@ -204,3 +204,3 @@ * gives some clue about where in your application this happens. | ||
// add/remove to unsend messages list | ||
// add/remove to unsent messages list | ||
broadcastChannel._uMP.add(sendPromise); | ||
@@ -257,4 +257,4 @@ sendPromise | ||
* Getting the current time in JavaScript has no good precision. | ||
* So instead of only listening to events that happend 'after' the listener | ||
* was added, we also listen to events that happended 100ms before it. | ||
* So instead of only listening to events that happened 'after' the listener | ||
* was added, we also listen to events that happened 100ms before it. | ||
* This ensures that when another process, like a WebWorker, sends events | ||
@@ -297,3 +297,3 @@ * we do not miss them out because their timestamp is a bit off compared to the main process. | ||
if (channel._iL && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
// no one is listening, stop subscribing | ||
channel._iL = false; | ||
@@ -300,0 +300,0 @@ const time = channel.method.microSeconds(); |
@@ -75,3 +75,3 @@ import { | ||
/** | ||
* Already applying more then once, | ||
* Already applying more than once, | ||
* -> wait for the apply queue to be finished. | ||
@@ -109,6 +109,4 @@ */ | ||
}); | ||
const recieved = []; | ||
const handleMessage = (msg) => { | ||
if (msg.context === 'leader' && msg.token != this.token) { | ||
recieved.push(msg); | ||
if (msg.action === 'apply') { | ||
@@ -138,3 +136,3 @@ // other is applying | ||
* not critical process is waiting for it. | ||
* When this is true, we give the other intances | ||
* When this is true, we give the other instances | ||
* more time to answer to messages in the election cycle. | ||
@@ -147,3 +145,3 @@ * This makes it less likely to elect duplicate leaders. | ||
const applyPromise = _sendMessage(this, 'apply') // send out that this one is applying | ||
return _sendMessage(this, 'apply') // send out that this one is applying | ||
.then(() => Promise.race([ | ||
@@ -171,3 +169,2 @@ sleep(waitForAnswerTime), | ||
}); | ||
return applyPromise; | ||
}; | ||
@@ -174,0 +171,0 @@ this._aplQC = this._aplQC + 1; |
@@ -1,5 +0,5 @@ | ||
import NativeMethod from './methods/native.js'; | ||
import IndexeDbMethod from './methods/indexed-db.js'; | ||
import LocalstorageMethod from './methods/localstorage.js'; | ||
import SimulateMethod from './methods/simulate.js'; | ||
import { NativeMethod } from './methods/native.js'; | ||
import { IndexedDBMethod } from './methods/indexed-db.js'; | ||
import { LocalstorageMethod } from './methods/localstorage.js'; | ||
import { SimulateMethod } from './methods/simulate.js'; | ||
// the line below will be removed from es5/browser builds | ||
@@ -11,3 +11,3 @@ import * as NodeMethod from './methods/node.js'; | ||
NativeMethod, // fastest | ||
IndexeDbMethod, | ||
IndexedDBMethod, | ||
LocalstorageMethod | ||
@@ -35,3 +35,3 @@ ]; | ||
* if no webworker support is needed, | ||
* remove idb from the list so that localstorage is been chosen | ||
* remove idb from the list so that localstorage will be chosen | ||
*/ | ||
@@ -44,5 +44,5 @@ if (!options.webWorkerSupport) { | ||
if (!useMethod) | ||
throw new Error(`No useable method found in ${JSON.stringify(METHODS.map(m => m.type))}`); | ||
throw new Error(`No usable method found in ${JSON.stringify(METHODS.map(m => m.type))}`); | ||
else | ||
return useMethod; | ||
} |
/** | ||
* if you really need this method, | ||
* implement it | ||
* implement it! | ||
*/ |
@@ -80,3 +80,3 @@ /** | ||
}; | ||
const dbPromise = new Promise((res, rej) => { | ||
return new Promise((res, rej) => { | ||
openRequest.onerror = ev => rej(ev); | ||
@@ -87,4 +87,2 @@ openRequest.onsuccess = () => { | ||
}); | ||
return dbPromise; | ||
} | ||
@@ -227,3 +225,2 @@ | ||
res(ret); | ||
return; | ||
} | ||
@@ -263,3 +260,3 @@ } else { | ||
eMIs: new ObliviousSet(options.idb.ttl * 2), | ||
// ensures we do not read messages in parrallel | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: PROMISE_RESOLVED_VOID, | ||
@@ -325,3 +322,3 @@ messagesCallback: null, | ||
/** | ||
* there is a bug in iOS where the msgObj can be undefined some times | ||
* there is a bug in iOS where the msgObj can be undefined sometimes | ||
* so we filter them out | ||
@@ -380,7 +377,3 @@ * @link https://github.com/pubkey/broadcast-channel/issues/19 | ||
export function canBeUsed() { | ||
const idb = getIdb(); | ||
if (!idb) { | ||
return false; | ||
} | ||
return true; | ||
return !!getIdb(); | ||
} | ||
@@ -392,3 +385,3 @@ | ||
export default { | ||
export const IndexedDBMethod = { | ||
create, | ||
@@ -395,0 +388,0 @@ close, |
/** | ||
* A localStorage-only method which uses localstorage and its 'storage'-event | ||
* This does not work inside of webworkers because they have no access to locastorage | ||
* This is basically implemented to support IE9 or your grandmothers toaster. | ||
* This does not work inside webworkers because they have no access to localstorage | ||
* This is basically implemented to support IE9 or your grandmother's toaster. | ||
* @link https://caniuse.com/#feat=namevalue-storage | ||
@@ -173,3 +173,3 @@ * @link https://caniuse.com/#feat=indexeddb | ||
export default { | ||
export const LocalstorageMethod = { | ||
create, | ||
@@ -176,0 +176,0 @@ close, |
@@ -65,3 +65,3 @@ import { | ||
export default { | ||
export const NativeMethod = { | ||
create, | ||
@@ -68,0 +68,0 @@ close, |
@@ -155,7 +155,6 @@ /** | ||
paths = paths || getPaths(channelName); | ||
const socketPath = path.join( | ||
return path.join( | ||
paths.readers, | ||
readerUuid + '.json' | ||
); | ||
return socketPath; | ||
} | ||
@@ -193,3 +192,3 @@ | ||
// we only show the augmented message if there are more then 30 channels | ||
// we only show the augmented message if there are more than 30 channels | ||
// because we then assume that BroadcastChannel is used in unit-tests | ||
@@ -205,4 +204,3 @@ if (count < 30) return originalError; | ||
'See https://github.com/pubkey/broadcast-channel#clear-tmp-folder'; | ||
const newError = new Error(text + ': ' + JSON.stringify(addObj, null, 2)); | ||
return newError; | ||
return new Error(text + ': ' + JSON.stringify(addObj, null, 2)); | ||
} | ||
@@ -313,7 +311,6 @@ | ||
const msgPath = path.join( | ||
return path.join( | ||
getPaths(channelName).messages, | ||
fileName | ||
); | ||
return msgPath; | ||
} | ||
@@ -362,6 +359,6 @@ | ||
export async function cleanOldMessages(messageObjects, ttl) { | ||
const olderThen = microSeconds() - (ttl * 1000); // convert ttl to microseconds | ||
const olderThan = microSeconds() - (ttl * 1000); // convert ttl to microseconds | ||
await Promise.all( | ||
messageObjects | ||
.filter(obj => obj.time < olderThen) | ||
.filter(obj => obj.time < olderThan) | ||
.map(obj => unlink(obj.path).catch(() => null)) | ||
@@ -395,3 +392,3 @@ ); | ||
* which could throw an error. | ||
* Must always be smaller then options.node.maxParallelWrites | ||
* Must always be smaller than options.node.maxParallelWrites | ||
*/ | ||
@@ -401,3 +398,3 @@ writeFileQueue: new PQueue({ concurrency: options.node.maxParallelWrites }), | ||
messagesCallback: null, | ||
// ensures we do not read messages in parrallel | ||
// ensures we do not read messages in parallel | ||
writeBlockPromise: PROMISE_RESOLVED_VOID, | ||
@@ -535,3 +532,3 @@ otherReaderClients: {}, | ||
// this can throw when the cleanup of another channel was interrupted | ||
// or the socket-file does not exits yet | ||
// or the socket-file does not exist yet | ||
} | ||
@@ -638,3 +635,3 @@ } catch (err) { | ||
export function close(channelState) { | ||
if (channelState.closed) return; | ||
if (channelState.closed) return PROMISE_RESOLVED_VOID; | ||
channelState.closed = true; | ||
@@ -675,14 +672,10 @@ channelState.emittedMessagesIds.clear(); | ||
export function canBeUsed() { | ||
if (typeof fs.mkdir === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return typeof fs.mkdir === 'function'; | ||
} | ||
/** | ||
* on node we use a relatively height averageResponseTime, | ||
* on node we use a relatively high averageResponseTime, | ||
* because the file-io might be in use. | ||
* Also it is more important that the leader-election is reliable, | ||
* then to have a fast election. | ||
* than to have a fast election. | ||
*/ | ||
@@ -689,0 +682,0 @@ export function averageResponseTime() { |
@@ -50,3 +50,3 @@ import { | ||
export default { | ||
export const SimulateMethod = { | ||
create, | ||
@@ -53,0 +53,0 @@ close, |
@@ -5,8 +5,4 @@ /** | ||
export function isPromise(obj) { | ||
if (obj && | ||
typeof obj.then === 'function') { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return obj && | ||
typeof obj.then === 'function'; | ||
} | ||
@@ -13,0 +9,0 @@ |
@@ -65,3 +65,3 @@ declare type MethodType = 'node' | 'idb' | 'native' | 'localstorage' | 'simulate'; | ||
// not defined in the offical standard | ||
// not defined in the official standard | ||
addEventListener(type: EventContext, handler: OnMessageHandler<T>): void; | ||
@@ -68,0 +68,0 @@ removeEventListener(type: EventContext, handler: OnMessageHandler<T>): void; |
@@ -40,3 +40,3 @@ import { | ||
* True if this or another instance is leader. | ||
* False if there is not leader at the moment | ||
* False if there is no leader at the moment | ||
* and we must wait for the election cycle. | ||
@@ -43,0 +43,0 @@ */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
503560
51
13060
10
+ Added@babel/runtime@7.20.7(transitive)
+ Addedregenerator-runtime@0.13.11(transitive)
+ Addedunload@2.4.0(transitive)
- Removed@babel/runtime@7.25.6(transitive)
- Removeddetect-node@2.1.0(transitive)
- Removedregenerator-runtime@0.14.1(transitive)
- Removedunload@2.3.1(transitive)
Updated@babel/runtime@7.20.7
Updatedunload@2.4.0