@hocuspocus/provider 3.0.8-rc.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hocuspocus-provider.cjs +56 -495
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +56 -495
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/node_modules/@tiptap/pm/model/index.d.ts +1 -0
- package/dist/node_modules/@tiptap/pm/state/index.d.ts +1 -0
- package/dist/node_modules/@tiptap/pm/transform/index.d.ts +1 -0
- package/dist/node_modules/@tiptap/pm/view/index.d.ts +1 -0
- package/dist/packages/extension-redis/src/Redis.d.ts +8 -9
- package/dist/packages/provider/src/HocuspocusProviderWebsocket.d.ts +6 -16
- package/dist/packages/provider/src/MessageSender.d.ts +2 -3
- package/package.json +2 -2
- package/src/HocuspocusProviderWebsocket.ts +486 -498
- package/src/MessageSender.ts +15 -21
|
@@ -67,37 +67,6 @@ const create$2 = () => new Set();
|
|
|
67
67
|
*/
|
|
68
68
|
const from = Array.from;
|
|
69
69
|
|
|
70
|
-
/**
|
|
71
|
-
* Utility module to work with strings.
|
|
72
|
-
*
|
|
73
|
-
* @module string
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
const fromCharCode = String.fromCharCode;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @param {string} s
|
|
80
|
-
* @return {string}
|
|
81
|
-
*/
|
|
82
|
-
const toLowerCase = s => s.toLowerCase();
|
|
83
|
-
|
|
84
|
-
const trimLeftRegex = /^\s*/g;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @param {string} s
|
|
88
|
-
* @return {string}
|
|
89
|
-
*/
|
|
90
|
-
const trimLeft = s => s.replace(trimLeftRegex, '');
|
|
91
|
-
|
|
92
|
-
const fromCamelCaseRegex = /([A-Z])/g;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* @param {string} s
|
|
96
|
-
* @param {string} separator
|
|
97
|
-
* @return {string}
|
|
98
|
-
*/
|
|
99
|
-
const fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, match => `${separator}${toLowerCase(match)}`));
|
|
100
|
-
|
|
101
70
|
/**
|
|
102
71
|
* @param {string} str
|
|
103
72
|
* @return {Uint8Array}
|
|
@@ -749,22 +718,6 @@ class Observable {
|
|
|
749
718
|
*/
|
|
750
719
|
const keys = Object.keys;
|
|
751
720
|
|
|
752
|
-
/**
|
|
753
|
-
* @todo implement mapToArray & map
|
|
754
|
-
*
|
|
755
|
-
* @template R
|
|
756
|
-
* @param {Object<string,any>} obj
|
|
757
|
-
* @param {function(any,string):R} f
|
|
758
|
-
* @return {Array<R>}
|
|
759
|
-
*/
|
|
760
|
-
const map = (obj, f) => {
|
|
761
|
-
const results = [];
|
|
762
|
-
for (const key in obj) {
|
|
763
|
-
results.push(f(obj[key], key));
|
|
764
|
-
}
|
|
765
|
-
return results
|
|
766
|
-
};
|
|
767
|
-
|
|
768
721
|
/**
|
|
769
722
|
* @deprecated use object.size instead
|
|
770
723
|
* @param {Object<string,any>} obj
|
|
@@ -878,16 +831,6 @@ const equalityDeep = (a, b) => {
|
|
|
878
831
|
return true
|
|
879
832
|
};
|
|
880
833
|
|
|
881
|
-
/**
|
|
882
|
-
* @template V
|
|
883
|
-
* @template {V} OPTS
|
|
884
|
-
*
|
|
885
|
-
* @param {V} value
|
|
886
|
-
* @param {Array<OPTS>} options
|
|
887
|
-
*/
|
|
888
|
-
// @ts-ignore
|
|
889
|
-
const isOneOf = (value, options) => options.includes(value);
|
|
890
|
-
|
|
891
834
|
/**
|
|
892
835
|
* @module awareness-protocol
|
|
893
836
|
*/
|
|
@@ -1188,37 +1131,6 @@ class EventEmitter {
|
|
|
1188
1131
|
}
|
|
1189
1132
|
}
|
|
1190
1133
|
|
|
1191
|
-
/**
|
|
1192
|
-
* Utility module to work with urls.
|
|
1193
|
-
*
|
|
1194
|
-
* @module url
|
|
1195
|
-
*/
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
/**
|
|
1199
|
-
* @param {Object<string,string>} params
|
|
1200
|
-
* @return {string}
|
|
1201
|
-
*/
|
|
1202
|
-
const encodeQueryParams = params =>
|
|
1203
|
-
map(params, (val, key) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`).join('&');
|
|
1204
|
-
|
|
1205
|
-
var MessageType;
|
|
1206
|
-
(function (MessageType) {
|
|
1207
|
-
MessageType[MessageType["Sync"] = 0] = "Sync";
|
|
1208
|
-
MessageType[MessageType["Awareness"] = 1] = "Awareness";
|
|
1209
|
-
MessageType[MessageType["Auth"] = 2] = "Auth";
|
|
1210
|
-
MessageType[MessageType["QueryAwareness"] = 3] = "QueryAwareness";
|
|
1211
|
-
MessageType[MessageType["Stateless"] = 5] = "Stateless";
|
|
1212
|
-
MessageType[MessageType["CLOSE"] = 7] = "CLOSE";
|
|
1213
|
-
MessageType[MessageType["SyncStatus"] = 8] = "SyncStatus";
|
|
1214
|
-
})(MessageType || (MessageType = {}));
|
|
1215
|
-
var WebSocketStatus;
|
|
1216
|
-
(function (WebSocketStatus) {
|
|
1217
|
-
WebSocketStatus["Connecting"] = "connecting";
|
|
1218
|
-
WebSocketStatus["Connected"] = "connected";
|
|
1219
|
-
WebSocketStatus["Disconnected"] = "disconnected";
|
|
1220
|
-
})(WebSocketStatus || (WebSocketStatus = {}));
|
|
1221
|
-
|
|
1222
1134
|
class IncomingMessage {
|
|
1223
1135
|
constructor(data) {
|
|
1224
1136
|
this.data = data;
|
|
@@ -1251,6 +1163,23 @@ class IncomingMessage {
|
|
|
1251
1163
|
}
|
|
1252
1164
|
}
|
|
1253
1165
|
|
|
1166
|
+
var MessageType;
|
|
1167
|
+
(function (MessageType) {
|
|
1168
|
+
MessageType[MessageType["Sync"] = 0] = "Sync";
|
|
1169
|
+
MessageType[MessageType["Awareness"] = 1] = "Awareness";
|
|
1170
|
+
MessageType[MessageType["Auth"] = 2] = "Auth";
|
|
1171
|
+
MessageType[MessageType["QueryAwareness"] = 3] = "QueryAwareness";
|
|
1172
|
+
MessageType[MessageType["Stateless"] = 5] = "Stateless";
|
|
1173
|
+
MessageType[MessageType["CLOSE"] = 7] = "CLOSE";
|
|
1174
|
+
MessageType[MessageType["SyncStatus"] = 8] = "SyncStatus";
|
|
1175
|
+
})(MessageType || (MessageType = {}));
|
|
1176
|
+
var WebSocketStatus;
|
|
1177
|
+
(function (WebSocketStatus) {
|
|
1178
|
+
WebSocketStatus["Connecting"] = "connecting";
|
|
1179
|
+
WebSocketStatus["Connected"] = "connected";
|
|
1180
|
+
WebSocketStatus["Disconnected"] = "disconnected";
|
|
1181
|
+
})(WebSocketStatus || (WebSocketStatus = {}));
|
|
1182
|
+
|
|
1254
1183
|
class OutgoingMessage {
|
|
1255
1184
|
constructor() {
|
|
1256
1185
|
this.encoder = createEncoder();
|
|
@@ -1281,14 +1210,10 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1281
1210
|
super();
|
|
1282
1211
|
this.messageQueue = [];
|
|
1283
1212
|
this.configuration = {
|
|
1284
|
-
url:
|
|
1213
|
+
url: "",
|
|
1285
1214
|
// @ts-ignore
|
|
1286
1215
|
document: undefined,
|
|
1287
1216
|
WebSocketPolyfill: undefined,
|
|
1288
|
-
parameters: {},
|
|
1289
|
-
connect: true,
|
|
1290
|
-
broadcast: true,
|
|
1291
|
-
forceSyncInterval: false,
|
|
1292
1217
|
// TODO: this should depend on awareness.outdatedTime
|
|
1293
1218
|
messageReconnectTimeout: 30000,
|
|
1294
1219
|
// 1 second
|
|
@@ -1335,23 +1260,20 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1335
1260
|
this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill
|
|
1336
1261
|
? configuration.WebSocketPolyfill
|
|
1337
1262
|
: WebSocket;
|
|
1338
|
-
this.on(
|
|
1339
|
-
this.on(
|
|
1340
|
-
this.on(
|
|
1341
|
-
this.on(
|
|
1342
|
-
this.on(
|
|
1343
|
-
this.on(
|
|
1344
|
-
this.on(
|
|
1345
|
-
this.on(
|
|
1346
|
-
this.on(
|
|
1347
|
-
this.on(
|
|
1348
|
-
this.on(
|
|
1349
|
-
this.on(
|
|
1350
|
-
this.on(
|
|
1263
|
+
this.on("open", this.configuration.onOpen);
|
|
1264
|
+
this.on("open", this.onOpen.bind(this));
|
|
1265
|
+
this.on("connect", this.configuration.onConnect);
|
|
1266
|
+
this.on("message", this.configuration.onMessage);
|
|
1267
|
+
this.on("outgoingMessage", this.configuration.onOutgoingMessage);
|
|
1268
|
+
this.on("status", this.configuration.onStatus);
|
|
1269
|
+
this.on("disconnect", this.configuration.onDisconnect);
|
|
1270
|
+
this.on("close", this.configuration.onClose);
|
|
1271
|
+
this.on("destroy", this.configuration.onDestroy);
|
|
1272
|
+
this.on("awarenessUpdate", this.configuration.onAwarenessUpdate);
|
|
1273
|
+
this.on("awarenessChange", this.configuration.onAwarenessChange);
|
|
1274
|
+
this.on("close", this.onClose.bind(this));
|
|
1275
|
+
this.on("message", this.onMessage.bind(this));
|
|
1351
1276
|
this.intervals.connectionChecker = setInterval(this.checkConnection.bind(this), this.configuration.messageReconnectTimeout / 10);
|
|
1352
|
-
if (typeof configuration.connect !== 'undefined') {
|
|
1353
|
-
this.shouldConnect = configuration.connect;
|
|
1354
|
-
}
|
|
1355
1277
|
if (!this.shouldConnect) {
|
|
1356
1278
|
return;
|
|
1357
1279
|
}
|
|
@@ -1366,13 +1288,16 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1366
1288
|
if (this.status === WebSocketStatus.Disconnected && this.shouldConnect) {
|
|
1367
1289
|
this.connect();
|
|
1368
1290
|
}
|
|
1369
|
-
if (this.receivedOnOpenPayload &&
|
|
1291
|
+
if (this.receivedOnOpenPayload &&
|
|
1292
|
+
this.status === WebSocketStatus.Connected) {
|
|
1370
1293
|
provider.onOpen(this.receivedOnOpenPayload);
|
|
1371
1294
|
}
|
|
1372
1295
|
}
|
|
1373
1296
|
detach(provider) {
|
|
1374
1297
|
if (this.configuration.providerMap.has(provider.configuration.name)) {
|
|
1375
|
-
provider.send(CloseMessage, {
|
|
1298
|
+
provider.send(CloseMessage, {
|
|
1299
|
+
documentName: provider.configuration.name,
|
|
1300
|
+
});
|
|
1376
1301
|
this.configuration.providerMap.delete(provider.configuration.name);
|
|
1377
1302
|
}
|
|
1378
1303
|
}
|
|
@@ -1401,7 +1326,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1401
1326
|
maxDelay: this.configuration.maxDelay,
|
|
1402
1327
|
jitter: this.configuration.jitter,
|
|
1403
1328
|
timeout: this.configuration.timeout,
|
|
1404
|
-
beforeAttempt: context => {
|
|
1329
|
+
beforeAttempt: (context) => {
|
|
1405
1330
|
if (!this.shouldConnect || cancelAttempt) {
|
|
1406
1331
|
context.abort();
|
|
1407
1332
|
}
|
|
@@ -1409,7 +1334,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1409
1334
|
}).catch((error) => {
|
|
1410
1335
|
// If we aborted the connection attempt then don’t throw an error
|
|
1411
1336
|
// ref: https://github.com/lifeomic/attempt/blob/master/src/index.ts#L136
|
|
1412
|
-
if (error && error.code !==
|
|
1337
|
+
if (error && error.code !== "ATTEMPT_ABORTED") {
|
|
1413
1338
|
throw error;
|
|
1414
1339
|
}
|
|
1415
1340
|
});
|
|
@@ -1427,9 +1352,9 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1427
1352
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
1428
1353
|
attachWebSocketListeners(ws, reject) {
|
|
1429
1354
|
const { identifier } = ws;
|
|
1430
|
-
const onMessageHandler = (payload) => this.emit(
|
|
1431
|
-
const onCloseHandler = (payload) => this.emit(
|
|
1432
|
-
const onOpenHandler = (payload) => this.emit(
|
|
1355
|
+
const onMessageHandler = (payload) => this.emit("message", payload);
|
|
1356
|
+
const onCloseHandler = (payload) => this.emit("close", { event: payload });
|
|
1357
|
+
const onOpenHandler = (payload) => this.emit("open", payload);
|
|
1433
1358
|
const onErrorHandler = (err) => {
|
|
1434
1359
|
reject(err);
|
|
1435
1360
|
};
|
|
@@ -1440,7 +1365,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1440
1365
|
error: onErrorHandler,
|
|
1441
1366
|
};
|
|
1442
1367
|
const handlers = this.webSocketHandlers[ws.identifier];
|
|
1443
|
-
Object.keys(handlers).forEach(name => {
|
|
1368
|
+
Object.keys(handlers).forEach((name) => {
|
|
1444
1369
|
ws.addEventListener(name, handlers[name]);
|
|
1445
1370
|
});
|
|
1446
1371
|
}
|
|
@@ -1450,7 +1375,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1450
1375
|
}
|
|
1451
1376
|
const { identifier } = this.webSocket;
|
|
1452
1377
|
const handlers = this.webSocketHandlers[identifier];
|
|
1453
|
-
Object.keys(handlers).forEach(name => {
|
|
1378
|
+
Object.keys(handlers).forEach((name) => {
|
|
1454
1379
|
var _a;
|
|
1455
1380
|
(_a = this.webSocket) === null || _a === void 0 ? void 0 : _a.removeEventListener(name, handlers[name]);
|
|
1456
1381
|
delete this.webSocketHandlers[identifier];
|
|
@@ -1468,13 +1393,13 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1468
1393
|
this.identifier += 1;
|
|
1469
1394
|
// Init the WebSocket connection
|
|
1470
1395
|
const ws = new this.configuration.WebSocketPolyfill(this.url);
|
|
1471
|
-
ws.binaryType =
|
|
1396
|
+
ws.binaryType = "arraybuffer";
|
|
1472
1397
|
ws.identifier = this.identifier;
|
|
1473
1398
|
this.attachWebSocketListeners(ws, reject);
|
|
1474
1399
|
this.webSocket = ws;
|
|
1475
1400
|
// Reset the status
|
|
1476
1401
|
this.status = WebSocketStatus.Connecting;
|
|
1477
|
-
this.emit(
|
|
1402
|
+
this.emit("status", { status: WebSocketStatus.Connecting });
|
|
1478
1403
|
// Store resolve/reject for later use
|
|
1479
1404
|
this.connectionAttempt = {
|
|
1480
1405
|
resolve,
|
|
@@ -1495,9 +1420,9 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1495
1420
|
this.connectionAttempt.resolve();
|
|
1496
1421
|
this.connectionAttempt = null;
|
|
1497
1422
|
this.status = WebSocketStatus.Connected;
|
|
1498
|
-
this.emit(
|
|
1499
|
-
this.emit(
|
|
1500
|
-
this.messageQueue.forEach(message => this.send(message));
|
|
1423
|
+
this.emit("status", { status: WebSocketStatus.Connected });
|
|
1424
|
+
this.emit("connect");
|
|
1425
|
+
this.messageQueue.forEach((message) => this.send(message));
|
|
1501
1426
|
this.messageQueue = [];
|
|
1502
1427
|
}
|
|
1503
1428
|
}
|
|
@@ -1520,8 +1445,8 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1520
1445
|
return;
|
|
1521
1446
|
}
|
|
1522
1447
|
// Don’t close the connection when a message was received recently
|
|
1523
|
-
if (this.configuration.messageReconnectTimeout
|
|
1524
|
-
|
|
1448
|
+
if (this.configuration.messageReconnectTimeout >=
|
|
1449
|
+
getUnixTime() - this.lastMessageReceived) {
|
|
1525
1450
|
return;
|
|
1526
1451
|
}
|
|
1527
1452
|
// No message received in a long time, not even your own
|
|
@@ -1533,7 +1458,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1533
1458
|
this.onClose({
|
|
1534
1459
|
event: {
|
|
1535
1460
|
code: 4408,
|
|
1536
|
-
reason:
|
|
1461
|
+
reason: "forced",
|
|
1537
1462
|
},
|
|
1538
1463
|
});
|
|
1539
1464
|
this.closeTries = 0;
|
|
@@ -1545,14 +1470,13 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1545
1470
|
}
|
|
1546
1471
|
// Ensure that the URL never ends with /
|
|
1547
1472
|
get serverUrl() {
|
|
1548
|
-
while (this.configuration.url[this.configuration.url.length - 1] ===
|
|
1473
|
+
while (this.configuration.url[this.configuration.url.length - 1] === "/") {
|
|
1549
1474
|
return this.configuration.url.slice(0, this.configuration.url.length - 1);
|
|
1550
1475
|
}
|
|
1551
1476
|
return this.configuration.url;
|
|
1552
1477
|
}
|
|
1553
1478
|
get url() {
|
|
1554
|
-
|
|
1555
|
-
return `${this.serverUrl}${encodedParams.length === 0 ? '' : `?${encodedParams}`}`;
|
|
1479
|
+
return this.serverUrl;
|
|
1556
1480
|
}
|
|
1557
1481
|
disconnect() {
|
|
1558
1482
|
this.shouldConnect = false;
|
|
@@ -1585,8 +1509,8 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1585
1509
|
}
|
|
1586
1510
|
// Let’s update the connection status.
|
|
1587
1511
|
this.status = WebSocketStatus.Disconnected;
|
|
1588
|
-
this.emit(
|
|
1589
|
-
this.emit(
|
|
1512
|
+
this.emit("status", { status: WebSocketStatus.Disconnected });
|
|
1513
|
+
this.emit("disconnect", { event });
|
|
1590
1514
|
// trigger connect if no retry is running and we want to have a connection
|
|
1591
1515
|
if (!this.cancelWebsocketRetry && this.shouldConnect) {
|
|
1592
1516
|
setTimeout(() => {
|
|
@@ -1595,7 +1519,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
1595
1519
|
}
|
|
1596
1520
|
}
|
|
1597
1521
|
destroy() {
|
|
1598
|
-
this.emit(
|
|
1522
|
+
this.emit("destroy");
|
|
1599
1523
|
clearInterval(this.intervals.connectionChecker);
|
|
1600
1524
|
// If there is still a connection attempt outstanding then we should stop
|
|
1601
1525
|
// it before calling disconnect, otherwise it will be rejected in the onClose
|
|
@@ -1818,366 +1742,6 @@ class MessageReceiver {
|
|
|
1818
1742
|
}
|
|
1819
1743
|
}
|
|
1820
1744
|
|
|
1821
|
-
/**
|
|
1822
|
-
* Often used conditions.
|
|
1823
|
-
*
|
|
1824
|
-
* @module conditions
|
|
1825
|
-
*/
|
|
1826
|
-
|
|
1827
|
-
/**
|
|
1828
|
-
* @template T
|
|
1829
|
-
* @param {T|null|undefined} v
|
|
1830
|
-
* @return {T|null}
|
|
1831
|
-
*/
|
|
1832
|
-
/* c8 ignore next */
|
|
1833
|
-
const undefinedToNull = v => v === undefined ? null : v;
|
|
1834
|
-
|
|
1835
|
-
/* eslint-env browser */
|
|
1836
|
-
|
|
1837
|
-
/**
|
|
1838
|
-
* Isomorphic variable storage.
|
|
1839
|
-
*
|
|
1840
|
-
* Uses LocalStorage in the browser and falls back to in-memory storage.
|
|
1841
|
-
*
|
|
1842
|
-
* @module storage
|
|
1843
|
-
*/
|
|
1844
|
-
|
|
1845
|
-
/* c8 ignore start */
|
|
1846
|
-
class VarStoragePolyfill {
|
|
1847
|
-
constructor () {
|
|
1848
|
-
this.map = new Map();
|
|
1849
|
-
}
|
|
1850
|
-
|
|
1851
|
-
/**
|
|
1852
|
-
* @param {string} key
|
|
1853
|
-
* @param {any} newValue
|
|
1854
|
-
*/
|
|
1855
|
-
setItem (key, newValue) {
|
|
1856
|
-
this.map.set(key, newValue);
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
/**
|
|
1860
|
-
* @param {string} key
|
|
1861
|
-
*/
|
|
1862
|
-
getItem (key) {
|
|
1863
|
-
return this.map.get(key)
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
/* c8 ignore stop */
|
|
1867
|
-
|
|
1868
|
-
/**
|
|
1869
|
-
* @type {any}
|
|
1870
|
-
*/
|
|
1871
|
-
let _localStorage = new VarStoragePolyfill();
|
|
1872
|
-
let usePolyfill = true;
|
|
1873
|
-
|
|
1874
|
-
/* c8 ignore start */
|
|
1875
|
-
try {
|
|
1876
|
-
// if the same-origin rule is violated, accessing localStorage might thrown an error
|
|
1877
|
-
if (typeof localStorage !== 'undefined' && localStorage) {
|
|
1878
|
-
_localStorage = localStorage;
|
|
1879
|
-
usePolyfill = false;
|
|
1880
|
-
}
|
|
1881
|
-
} catch (e) { }
|
|
1882
|
-
/* c8 ignore stop */
|
|
1883
|
-
|
|
1884
|
-
/**
|
|
1885
|
-
* This is basically localStorage in browser, or a polyfill in nodejs
|
|
1886
|
-
*/
|
|
1887
|
-
/* c8 ignore next */
|
|
1888
|
-
const varStorage = _localStorage;
|
|
1889
|
-
|
|
1890
|
-
/**
|
|
1891
|
-
* A polyfill for `addEventListener('storage', event => {..})` that does nothing if the polyfill is being used.
|
|
1892
|
-
*
|
|
1893
|
-
* @param {function({ key: string, newValue: string, oldValue: string }): void} eventHandler
|
|
1894
|
-
* @function
|
|
1895
|
-
*/
|
|
1896
|
-
/* c8 ignore next */
|
|
1897
|
-
const onChange = eventHandler => usePolyfill || addEventListener('storage', /** @type {any} */ (eventHandler));
|
|
1898
|
-
|
|
1899
|
-
/**
|
|
1900
|
-
* A polyfill for `removeEventListener('storage', event => {..})` that does nothing if the polyfill is being used.
|
|
1901
|
-
*
|
|
1902
|
-
* @param {function({ key: string, newValue: string, oldValue: string }): void} eventHandler
|
|
1903
|
-
* @function
|
|
1904
|
-
*/
|
|
1905
|
-
/* c8 ignore next */
|
|
1906
|
-
const offChange = eventHandler => usePolyfill || removeEventListener('storage', /** @type {any} */ (eventHandler));
|
|
1907
|
-
|
|
1908
|
-
/**
|
|
1909
|
-
* Isomorphic module to work access the environment (query params, env variables).
|
|
1910
|
-
*
|
|
1911
|
-
* @module environment
|
|
1912
|
-
*/
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
/* c8 ignore next 2 */
|
|
1916
|
-
// @ts-ignore
|
|
1917
|
-
const isNode = typeof process !== 'undefined' && process.release && /node|io\.js/.test(process.release.name) && Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
|
|
1918
|
-
|
|
1919
|
-
/* c8 ignore next */
|
|
1920
|
-
const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && !isNode;
|
|
1921
|
-
|
|
1922
|
-
/**
|
|
1923
|
-
* @type {Map<string,string>}
|
|
1924
|
-
*/
|
|
1925
|
-
let params;
|
|
1926
|
-
|
|
1927
|
-
/* c8 ignore start */
|
|
1928
|
-
const computeParams = () => {
|
|
1929
|
-
if (params === undefined) {
|
|
1930
|
-
if (isNode) {
|
|
1931
|
-
params = create();
|
|
1932
|
-
const pargs = process.argv;
|
|
1933
|
-
let currParamName = null;
|
|
1934
|
-
for (let i = 0; i < pargs.length; i++) {
|
|
1935
|
-
const parg = pargs[i];
|
|
1936
|
-
if (parg[0] === '-') {
|
|
1937
|
-
if (currParamName !== null) {
|
|
1938
|
-
params.set(currParamName, '');
|
|
1939
|
-
}
|
|
1940
|
-
currParamName = parg;
|
|
1941
|
-
} else {
|
|
1942
|
-
if (currParamName !== null) {
|
|
1943
|
-
params.set(currParamName, parg);
|
|
1944
|
-
currParamName = null;
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
if (currParamName !== null) {
|
|
1949
|
-
params.set(currParamName, '');
|
|
1950
|
-
}
|
|
1951
|
-
// in ReactNative for example this would not be true (unless connected to the Remote Debugger)
|
|
1952
|
-
} else if (typeof location === 'object') {
|
|
1953
|
-
params = create(); // eslint-disable-next-line no-undef
|
|
1954
|
-
(location.search || '?').slice(1).split('&').forEach((kv) => {
|
|
1955
|
-
if (kv.length !== 0) {
|
|
1956
|
-
const [key, value] = kv.split('=');
|
|
1957
|
-
params.set(`--${fromCamelCase(key, '-')}`, value);
|
|
1958
|
-
params.set(`-${fromCamelCase(key, '-')}`, value);
|
|
1959
|
-
}
|
|
1960
|
-
});
|
|
1961
|
-
} else {
|
|
1962
|
-
params = create();
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
return params
|
|
1966
|
-
};
|
|
1967
|
-
/* c8 ignore stop */
|
|
1968
|
-
|
|
1969
|
-
/**
|
|
1970
|
-
* @param {string} name
|
|
1971
|
-
* @return {boolean}
|
|
1972
|
-
*/
|
|
1973
|
-
/* c8 ignore next */
|
|
1974
|
-
const hasParam = (name) => computeParams().has(name);
|
|
1975
|
-
|
|
1976
|
-
/**
|
|
1977
|
-
* @param {string} name
|
|
1978
|
-
* @return {string|null}
|
|
1979
|
-
*/
|
|
1980
|
-
/* c8 ignore next 4 */
|
|
1981
|
-
const getVariable = (name) =>
|
|
1982
|
-
isNode
|
|
1983
|
-
? undefinedToNull(process.env[name.toUpperCase().replaceAll('-', '_')])
|
|
1984
|
-
: undefinedToNull(varStorage.getItem(name));
|
|
1985
|
-
|
|
1986
|
-
/**
|
|
1987
|
-
* @param {string} name
|
|
1988
|
-
* @return {boolean}
|
|
1989
|
-
*/
|
|
1990
|
-
/* c8 ignore next 2 */
|
|
1991
|
-
const hasConf = (name) =>
|
|
1992
|
-
hasParam('--' + name) || getVariable(name) !== null;
|
|
1993
|
-
|
|
1994
|
-
/* c8 ignore next */
|
|
1995
|
-
hasConf('production');
|
|
1996
|
-
|
|
1997
|
-
/* c8 ignore next 2 */
|
|
1998
|
-
const forceColor = isNode &&
|
|
1999
|
-
isOneOf(process.env.FORCE_COLOR, ['true', '1', '2']);
|
|
2000
|
-
|
|
2001
|
-
/* c8 ignore start */
|
|
2002
|
-
/**
|
|
2003
|
-
* Color is enabled by default if the terminal supports it.
|
|
2004
|
-
*
|
|
2005
|
-
* Explicitly enable color using `--color` parameter
|
|
2006
|
-
* Disable color using `--no-color` parameter or using `NO_COLOR=1` environment variable.
|
|
2007
|
-
* `FORCE_COLOR=1` enables color and takes precedence over all.
|
|
2008
|
-
*/
|
|
2009
|
-
forceColor || (
|
|
2010
|
-
!hasParam('--no-colors') && // @todo deprecate --no-colors
|
|
2011
|
-
!hasConf('no-color') &&
|
|
2012
|
-
(!isNode || process.stdout.isTTY) && (
|
|
2013
|
-
!isNode ||
|
|
2014
|
-
hasParam('--color') ||
|
|
2015
|
-
getVariable('COLORTERM') !== null ||
|
|
2016
|
-
(getVariable('TERM') || '').includes('color')
|
|
2017
|
-
)
|
|
2018
|
-
);
|
|
2019
|
-
/* c8 ignore stop */
|
|
2020
|
-
|
|
2021
|
-
/**
|
|
2022
|
-
* Utility functions to work with buffers (Uint8Array).
|
|
2023
|
-
*
|
|
2024
|
-
* @module buffer
|
|
2025
|
-
*/
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
/**
|
|
2029
|
-
* @param {number} len
|
|
2030
|
-
*/
|
|
2031
|
-
const createUint8ArrayFromLen = len => new Uint8Array(len);
|
|
2032
|
-
|
|
2033
|
-
/**
|
|
2034
|
-
* Create Uint8Array with initial content from buffer
|
|
2035
|
-
*
|
|
2036
|
-
* @param {ArrayBuffer} buffer
|
|
2037
|
-
* @param {number} byteOffset
|
|
2038
|
-
* @param {number} length
|
|
2039
|
-
*/
|
|
2040
|
-
const createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length) => new Uint8Array(buffer, byteOffset, length);
|
|
2041
|
-
|
|
2042
|
-
/**
|
|
2043
|
-
* Create Uint8Array with initial content from buffer
|
|
2044
|
-
*
|
|
2045
|
-
* @param {ArrayBuffer} buffer
|
|
2046
|
-
*/
|
|
2047
|
-
const createUint8ArrayFromArrayBuffer = buffer => new Uint8Array(buffer);
|
|
2048
|
-
|
|
2049
|
-
/* c8 ignore start */
|
|
2050
|
-
/**
|
|
2051
|
-
* @param {Uint8Array} bytes
|
|
2052
|
-
* @return {string}
|
|
2053
|
-
*/
|
|
2054
|
-
const toBase64Browser = bytes => {
|
|
2055
|
-
let s = '';
|
|
2056
|
-
for (let i = 0; i < bytes.byteLength; i++) {
|
|
2057
|
-
s += fromCharCode(bytes[i]);
|
|
2058
|
-
}
|
|
2059
|
-
// eslint-disable-next-line no-undef
|
|
2060
|
-
return btoa(s)
|
|
2061
|
-
};
|
|
2062
|
-
/* c8 ignore stop */
|
|
2063
|
-
|
|
2064
|
-
/**
|
|
2065
|
-
* @param {Uint8Array} bytes
|
|
2066
|
-
* @return {string}
|
|
2067
|
-
*/
|
|
2068
|
-
const toBase64Node = bytes => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64');
|
|
2069
|
-
|
|
2070
|
-
/* c8 ignore start */
|
|
2071
|
-
/**
|
|
2072
|
-
* @param {string} s
|
|
2073
|
-
* @return {Uint8Array}
|
|
2074
|
-
*/
|
|
2075
|
-
const fromBase64Browser = s => {
|
|
2076
|
-
// eslint-disable-next-line no-undef
|
|
2077
|
-
const a = atob(s);
|
|
2078
|
-
const bytes = createUint8ArrayFromLen(a.length);
|
|
2079
|
-
for (let i = 0; i < a.length; i++) {
|
|
2080
|
-
bytes[i] = a.charCodeAt(i);
|
|
2081
|
-
}
|
|
2082
|
-
return bytes
|
|
2083
|
-
};
|
|
2084
|
-
/* c8 ignore stop */
|
|
2085
|
-
|
|
2086
|
-
/**
|
|
2087
|
-
* @param {string} s
|
|
2088
|
-
*/
|
|
2089
|
-
const fromBase64Node = s => {
|
|
2090
|
-
const buf = Buffer.from(s, 'base64');
|
|
2091
|
-
return createUint8ArrayViewFromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength)
|
|
2092
|
-
};
|
|
2093
|
-
|
|
2094
|
-
/* c8 ignore next */
|
|
2095
|
-
const toBase64 = isBrowser ? toBase64Browser : toBase64Node;
|
|
2096
|
-
|
|
2097
|
-
/* c8 ignore next */
|
|
2098
|
-
const fromBase64 = isBrowser ? fromBase64Browser : fromBase64Node;
|
|
2099
|
-
|
|
2100
|
-
/* eslint-env browser */
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
/**
|
|
2104
|
-
* @typedef {Object} Channel
|
|
2105
|
-
* @property {Set<function(any, any):any>} Channel.subs
|
|
2106
|
-
* @property {any} Channel.bc
|
|
2107
|
-
*/
|
|
2108
|
-
|
|
2109
|
-
/**
|
|
2110
|
-
* @type {Map<string, Channel>}
|
|
2111
|
-
*/
|
|
2112
|
-
const channels = new Map();
|
|
2113
|
-
|
|
2114
|
-
/* c8 ignore start */
|
|
2115
|
-
class LocalStoragePolyfill {
|
|
2116
|
-
/**
|
|
2117
|
-
* @param {string} room
|
|
2118
|
-
*/
|
|
2119
|
-
constructor (room) {
|
|
2120
|
-
this.room = room;
|
|
2121
|
-
/**
|
|
2122
|
-
* @type {null|function({data:ArrayBuffer}):void}
|
|
2123
|
-
*/
|
|
2124
|
-
this.onmessage = null;
|
|
2125
|
-
/**
|
|
2126
|
-
* @param {any} e
|
|
2127
|
-
*/
|
|
2128
|
-
this._onChange = e => e.key === room && this.onmessage !== null && this.onmessage({ data: fromBase64(e.newValue || '') });
|
|
2129
|
-
onChange(this._onChange);
|
|
2130
|
-
}
|
|
2131
|
-
|
|
2132
|
-
/**
|
|
2133
|
-
* @param {ArrayBuffer} buf
|
|
2134
|
-
*/
|
|
2135
|
-
postMessage (buf) {
|
|
2136
|
-
varStorage.setItem(this.room, toBase64(createUint8ArrayFromArrayBuffer(buf)));
|
|
2137
|
-
}
|
|
2138
|
-
|
|
2139
|
-
close () {
|
|
2140
|
-
offChange(this._onChange);
|
|
2141
|
-
}
|
|
2142
|
-
}
|
|
2143
|
-
/* c8 ignore stop */
|
|
2144
|
-
|
|
2145
|
-
// Use BroadcastChannel or Polyfill
|
|
2146
|
-
/* c8 ignore next */
|
|
2147
|
-
const BC = typeof BroadcastChannel === 'undefined' ? LocalStoragePolyfill : BroadcastChannel;
|
|
2148
|
-
|
|
2149
|
-
/**
|
|
2150
|
-
* @param {string} room
|
|
2151
|
-
* @return {Channel}
|
|
2152
|
-
*/
|
|
2153
|
-
const getChannel = room =>
|
|
2154
|
-
setIfUndefined(channels, room, () => {
|
|
2155
|
-
const subs = create$2();
|
|
2156
|
-
const bc = new BC(room);
|
|
2157
|
-
/**
|
|
2158
|
-
* @param {{data:ArrayBuffer}} e
|
|
2159
|
-
*/
|
|
2160
|
-
/* c8 ignore next */
|
|
2161
|
-
bc.onmessage = e => subs.forEach(sub => sub(e.data, 'broadcastchannel'));
|
|
2162
|
-
return {
|
|
2163
|
-
bc, subs
|
|
2164
|
-
}
|
|
2165
|
-
});
|
|
2166
|
-
|
|
2167
|
-
/**
|
|
2168
|
-
* Publish data to all subscribers (including subscribers on this tab)
|
|
2169
|
-
*
|
|
2170
|
-
* @function
|
|
2171
|
-
* @param {string} room
|
|
2172
|
-
* @param {any} data
|
|
2173
|
-
* @param {any} [origin]
|
|
2174
|
-
*/
|
|
2175
|
-
const publish = (room, data, origin = null) => {
|
|
2176
|
-
const c = getChannel(room);
|
|
2177
|
-
c.bc.postMessage(data);
|
|
2178
|
-
c.subs.forEach(sub => sub(data, origin));
|
|
2179
|
-
};
|
|
2180
|
-
|
|
2181
1745
|
class MessageSender {
|
|
2182
1746
|
constructor(Message, args = {}) {
|
|
2183
1747
|
this.message = new Message();
|
|
@@ -2189,9 +1753,6 @@ class MessageSender {
|
|
|
2189
1753
|
send(webSocket) {
|
|
2190
1754
|
webSocket === null || webSocket === void 0 ? void 0 : webSocket.send(this.create());
|
|
2191
1755
|
}
|
|
2192
|
-
broadcast(channel) {
|
|
2193
|
-
publish(channel, this.create());
|
|
2194
|
-
}
|
|
2195
1756
|
}
|
|
2196
1757
|
|
|
2197
1758
|
class AuthenticationMessage extends OutgoingMessage {
|