@hocuspocus/provider 1.0.0-alpha.4 → 1.0.0-alpha.40
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.js → hocuspocus-provider.cjs} +362 -186
- package/dist/hocuspocus-provider.cjs.map +1 -0
- package/dist/hocuspocus-provider.esm.js +359 -181
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/packages/common/src/CloseEvents.d.ts +23 -0
- package/dist/packages/common/src/auth.d.ts +6 -0
- package/dist/packages/common/src/awarenessStatesToArray.d.ts +3 -0
- package/dist/packages/common/src/index.d.ts +4 -0
- package/dist/packages/common/src/types.d.ts +10 -0
- package/dist/packages/extension-database/src/Database.d.ts +30 -0
- package/dist/packages/extension-database/src/index.d.ts +1 -0
- package/dist/packages/extension-logger/src/Logger.d.ts +67 -0
- package/dist/packages/extension-logger/src/index.d.ts +1 -0
- package/dist/packages/{monitor → extension-monitor}/src/Collector.d.ts +4 -5
- package/dist/packages/{monitor → extension-monitor}/src/Dashboard.d.ts +2 -2
- package/dist/packages/{monitor → extension-monitor}/src/Storage.d.ts +0 -0
- package/dist/packages/{monitor → extension-monitor}/src/index.d.ts +3 -5
- package/dist/packages/extension-redis/src/Redis.d.ts +98 -0
- package/dist/packages/extension-redis/src/index.d.ts +1 -0
- package/dist/packages/extension-sqlite/src/SQLite.d.ts +26 -0
- package/dist/packages/extension-sqlite/src/index.d.ts +1 -0
- package/dist/packages/extension-throttle/src/index.d.ts +24 -0
- package/dist/packages/{webhook → extension-webhook}/src/index.d.ts +5 -11
- package/dist/packages/provider/src/EventEmitter.d.ts +1 -1
- package/dist/packages/provider/src/HocuspocusCloudProvider.d.ts +11 -0
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +116 -32
- package/dist/packages/provider/src/IncomingMessage.d.ts +9 -6
- package/dist/packages/provider/src/MessageReceiver.d.ts +3 -2
- package/dist/packages/provider/src/MessageSender.d.ts +4 -9
- package/dist/packages/provider/src/OutgoingMessage.d.ts +5 -4
- package/dist/packages/provider/src/OutgoingMessages/AuthenticationMessage.d.ts +7 -0
- package/dist/packages/provider/src/OutgoingMessages/UpdateMessage.d.ts +1 -2
- package/dist/packages/provider/src/index.d.ts +1 -1
- package/dist/packages/provider/src/types.d.ts +54 -2
- package/dist/packages/server/src/Connection.d.ts +16 -7
- package/dist/packages/server/src/Debugger.d.ts +14 -0
- package/dist/packages/server/src/Document.d.ts +11 -5
- package/dist/packages/server/src/Hocuspocus.d.ts +63 -17
- package/dist/packages/server/src/IncomingMessage.d.ts +11 -7
- package/dist/packages/server/src/MessageReceiver.d.ts +13 -0
- package/dist/packages/server/src/OutgoingMessage.d.ts +6 -0
- package/dist/packages/server/src/index.d.ts +6 -0
- package/dist/packages/server/src/types.d.ts +168 -26
- package/dist/{demos/backend/src/create-document.d.ts → playground/backend/src/default.d.ts} +0 -0
- package/dist/{demos → playground}/backend/src/express.d.ts +0 -0
- package/dist/{demos → playground}/backend/src/koa.d.ts +0 -0
- package/dist/{demos/backend/src/minimal.d.ts → playground/backend/src/load-document.d.ts} +0 -0
- package/dist/{demos → playground}/backend/src/monitor.d.ts +0 -0
- package/dist/{demos/backend/src/webhook.d.ts → playground/backend/src/redis.d.ts} +0 -0
- package/dist/playground/backend/src/slow.d.ts +1 -0
- package/dist/playground/backend/src/webhook.d.ts +1 -0
- package/dist/tests/extension-database/fetch.d.ts +1 -0
- package/dist/tests/extension-logger/onListen.d.ts +1 -0
- package/dist/tests/extension-redis/closeConnections.d.ts +1 -0
- package/dist/tests/extension-redis/getConnectionCount.d.ts +1 -0
- package/dist/tests/extension-redis/getDocumentsCount.d.ts +1 -0
- package/dist/tests/extension-redis/onAwarenessChange.d.ts +1 -0
- package/dist/tests/extension-redis/onChange.d.ts +1 -0
- package/dist/tests/extension-redis/onStoreDocument.d.ts +1 -0
- package/dist/tests/extension-throttle/configuration.d.ts +1 -0
- package/dist/tests/provider/configuration.d.ts +1 -0
- package/dist/tests/provider/observe.d.ts +1 -0
- package/dist/tests/provider/observeDeep.d.ts +1 -0
- package/dist/tests/provider/onAuthenticated.d.ts +1 -0
- package/dist/tests/provider/onAuthenticationFailed.d.ts +1 -0
- package/dist/tests/provider/onAwarenessChange.d.ts +1 -0
- package/dist/tests/provider/onAwarenessUpdate.d.ts +1 -0
- package/dist/tests/provider/onClose.d.ts +1 -0
- package/dist/tests/provider/onConnect.d.ts +1 -0
- package/dist/tests/provider/onDisconnect.d.ts +1 -0
- package/dist/tests/provider/onMessage.d.ts +1 -0
- package/dist/tests/provider/onOpen.d.ts +1 -0
- package/dist/tests/provider/onSynced.d.ts +1 -0
- package/dist/tests/server/address.d.ts +1 -0
- package/dist/tests/server/afterStoreDocument.d.ts +1 -0
- package/dist/tests/server/closeConnections.d.ts +1 -0
- package/dist/tests/server/getConnectionsCount.d.ts +1 -0
- package/dist/tests/server/getDocumentName.d.ts +1 -0
- package/dist/tests/server/getDocumentsCount.d.ts +1 -0
- package/dist/tests/server/getMessageLogs.d.ts +1 -0
- package/dist/tests/server/listen.d.ts +1 -0
- package/dist/tests/server/onAuthenticate.d.ts +1 -0
- package/dist/tests/server/onAwarenessUpdate.d.ts +1 -0
- package/dist/tests/server/onChange.d.ts +1 -0
- package/dist/tests/server/onConfigure.d.ts +1 -0
- package/dist/tests/server/onConnect.d.ts +1 -0
- package/dist/tests/server/onDestroy.d.ts +1 -0
- package/dist/tests/server/onDisconnect.d.ts +1 -0
- package/dist/tests/server/onListen.d.ts +1 -0
- package/dist/tests/server/onLoadDocument.d.ts +1 -0
- package/dist/tests/server/onRequest.d.ts +1 -0
- package/dist/tests/server/onStoreDocument.d.ts +1 -0
- package/dist/tests/server/onUpgrade.d.ts +1 -0
- package/dist/tests/server/requiresAuthentication.d.ts +1 -0
- package/dist/tests/transformer/TiptapTransformer.d.ts +1 -0
- package/dist/tests/utils/createDirectory.d.ts +1 -0
- package/dist/tests/utils/flushRedis.d.ts +1 -0
- package/dist/tests/utils/index.d.ts +8 -0
- package/dist/tests/utils/newHocuspocus.d.ts +2 -0
- package/dist/tests/utils/newHocuspocusProvider.d.ts +3 -0
- package/dist/tests/utils/randomInteger.d.ts +1 -0
- package/dist/tests/utils/redisConnectionSettings.d.ts +4 -0
- package/dist/tests/utils/removeDirectory.d.ts +1 -0
- package/dist/tests/utils/retryableAssertion.d.ts +2 -0
- package/dist/tests/utils/sleep.d.ts +1 -0
- package/package.json +15 -11
- package/src/EventEmitter.ts +1 -1
- package/src/HocuspocusCloudProvider.ts +34 -0
- package/src/HocuspocusProvider.ts +389 -159
- package/src/IncomingMessage.ts +35 -11
- package/src/MessageReceiver.ts +56 -24
- package/src/MessageSender.ts +5 -17
- package/src/OutgoingMessage.ts +9 -9
- package/src/OutgoingMessages/AuthenticationMessage.ts +21 -0
- package/src/OutgoingMessages/AwarenessMessage.ts +1 -1
- package/src/OutgoingMessages/SyncStepOneMessage.ts +0 -1
- package/src/OutgoingMessages/UpdateMessage.ts +4 -4
- package/src/index.ts +1 -1
- package/src/types.ts +70 -3
- package/CHANGELOG.md +0 -24
- package/dist/hocuspocus-provider.js.map +0 -1
- package/dist/packages/logger/src/index.d.ts +0 -13
- package/dist/packages/provider/src/utils/awarenessStatesToArray.d.ts +0 -4
- package/dist/packages/provider/src/utils/index.d.ts +0 -1
- package/dist/packages/redis/src/Redis.d.ts +0 -22
- package/dist/packages/redis/src/RedisCluster.d.ts +0 -4
- package/dist/packages/redis/src/index.d.ts +0 -2
- package/dist/packages/rocksdb/src/index.d.ts +0 -30
- package/dist/packages/server/src/CloseEvents.d.ts +0 -3
- package/dist/packages/throttle/src/index.d.ts +0 -28
- package/src/utils/awarenessStatesToArray.ts +0 -8
- package/src/utils/index.ts +0 -1
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var Y = require('yjs');
|
|
6
|
+
var attempt = require('@lifeomic/attempt');
|
|
7
|
+
var common = require('@hocuspocus/common');
|
|
6
8
|
|
|
7
9
|
function _interopNamespace(e) {
|
|
8
10
|
if (e && e.__esModule) return e;
|
|
@@ -13,14 +15,12 @@ function _interopNamespace(e) {
|
|
|
13
15
|
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
16
|
Object.defineProperty(n, k, d.get ? d : {
|
|
15
17
|
enumerable: true,
|
|
16
|
-
get: function () {
|
|
17
|
-
return e[k];
|
|
18
|
-
}
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
n[
|
|
23
|
+
n["default"] = e;
|
|
24
24
|
return Object.freeze(n);
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -284,8 +284,6 @@ hasConf('production');
|
|
|
284
284
|
*/
|
|
285
285
|
|
|
286
286
|
const floor = Math.floor;
|
|
287
|
-
const round = Math.round;
|
|
288
|
-
const log10 = Math.log10;
|
|
289
287
|
|
|
290
288
|
/**
|
|
291
289
|
* @function
|
|
@@ -1398,23 +1396,26 @@ class EventEmitter {
|
|
|
1398
1396
|
}
|
|
1399
1397
|
}
|
|
1400
1398
|
|
|
1401
|
-
exports.MessageType = void 0;
|
|
1402
|
-
(function (MessageType) {
|
|
1403
|
-
MessageType[MessageType["Sync"] = 0] = "Sync";
|
|
1404
|
-
MessageType[MessageType["Awareness"] = 1] = "Awareness";
|
|
1405
|
-
MessageType[MessageType["Auth"] = 2] = "Auth";
|
|
1406
|
-
MessageType[MessageType["QueryAwareness"] = 3] = "QueryAwareness";
|
|
1407
|
-
})(exports.MessageType || (exports.MessageType = {}));
|
|
1408
|
-
|
|
1409
1399
|
class IncomingMessage {
|
|
1410
1400
|
constructor(data) {
|
|
1411
1401
|
this.data = data;
|
|
1412
1402
|
this.encoder = createEncoder();
|
|
1413
1403
|
this.decoder = createDecoder(new Uint8Array(this.data));
|
|
1414
|
-
this.type = readVarUint(this.decoder);
|
|
1415
1404
|
}
|
|
1416
|
-
|
|
1417
|
-
return
|
|
1405
|
+
readVarUint() {
|
|
1406
|
+
return readVarUint(this.decoder);
|
|
1407
|
+
}
|
|
1408
|
+
readVarUint8Array() {
|
|
1409
|
+
return readVarUint8Array(this.decoder);
|
|
1410
|
+
}
|
|
1411
|
+
writeVarUint(type) {
|
|
1412
|
+
return writeVarUint(this.encoder, type);
|
|
1413
|
+
}
|
|
1414
|
+
writeVarUint8Array(data) {
|
|
1415
|
+
return writeVarUint8Array(this.encoder, data);
|
|
1416
|
+
}
|
|
1417
|
+
length() {
|
|
1418
|
+
return length$1(this.encoder);
|
|
1418
1419
|
}
|
|
1419
1420
|
}
|
|
1420
1421
|
|
|
@@ -1545,32 +1546,45 @@ const readSyncMessage = (decoder, encoder, doc, transactionOrigin) => {
|
|
|
1545
1546
|
return messageType
|
|
1546
1547
|
};
|
|
1547
1548
|
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1549
|
+
exports.MessageType = void 0;
|
|
1550
|
+
(function (MessageType) {
|
|
1551
|
+
MessageType[MessageType["Sync"] = 0] = "Sync";
|
|
1552
|
+
MessageType[MessageType["Awareness"] = 1] = "Awareness";
|
|
1553
|
+
MessageType[MessageType["Auth"] = 2] = "Auth";
|
|
1554
|
+
MessageType[MessageType["QueryAwareness"] = 3] = "QueryAwareness";
|
|
1555
|
+
})(exports.MessageType || (exports.MessageType = {}));
|
|
1556
|
+
exports.WebSocketStatus = void 0;
|
|
1557
|
+
(function (WebSocketStatus) {
|
|
1558
|
+
WebSocketStatus["Connecting"] = "connecting";
|
|
1559
|
+
WebSocketStatus["Connected"] = "connected";
|
|
1560
|
+
WebSocketStatus["Disconnected"] = "disconnected";
|
|
1561
|
+
})(exports.WebSocketStatus || (exports.WebSocketStatus = {}));
|
|
1555
1562
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
}
|
|
1563
|
+
class OutgoingMessage {
|
|
1564
|
+
constructor() {
|
|
1565
|
+
this.encoder = createEncoder();
|
|
1566
|
+
}
|
|
1567
|
+
get(args) {
|
|
1568
|
+
return args.encoder;
|
|
1569
|
+
}
|
|
1570
|
+
toUint8Array() {
|
|
1571
|
+
return toUint8Array(this.encoder);
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1567
1574
|
|
|
1568
1575
|
class MessageReceiver {
|
|
1569
1576
|
constructor(message) {
|
|
1577
|
+
this.broadcasted = false;
|
|
1570
1578
|
this.message = message;
|
|
1571
1579
|
}
|
|
1580
|
+
setBroadcasted(value) {
|
|
1581
|
+
this.broadcasted = value;
|
|
1582
|
+
return this;
|
|
1583
|
+
}
|
|
1572
1584
|
apply(provider, emitSynced = true) {
|
|
1573
|
-
|
|
1585
|
+
const { message } = this;
|
|
1586
|
+
const type = message.readVarUint();
|
|
1587
|
+
switch (type) {
|
|
1574
1588
|
case exports.MessageType.Sync:
|
|
1575
1589
|
this.applySyncMessage(provider, emitSynced);
|
|
1576
1590
|
break;
|
|
@@ -1584,31 +1598,49 @@ class MessageReceiver {
|
|
|
1584
1598
|
this.applyQueryAwarenessMessage(provider);
|
|
1585
1599
|
break;
|
|
1586
1600
|
default:
|
|
1587
|
-
throw new Error(`Can’t apply unknown type
|
|
1601
|
+
throw new Error(`Can’t apply message of unknown type: ${type}`);
|
|
1602
|
+
}
|
|
1603
|
+
// Reply
|
|
1604
|
+
if (message.length() > 1) {
|
|
1605
|
+
if (this.broadcasted) {
|
|
1606
|
+
// TODO: Some weird TypeScript error
|
|
1607
|
+
// @ts-ignore
|
|
1608
|
+
provider.broadcast(OutgoingMessage, { encoder: message.encoder });
|
|
1609
|
+
}
|
|
1610
|
+
else {
|
|
1611
|
+
// TODO: Some weird TypeScript error
|
|
1612
|
+
// @ts-ignore
|
|
1613
|
+
provider.send(OutgoingMessage, { encoder: message.encoder });
|
|
1614
|
+
}
|
|
1588
1615
|
}
|
|
1589
|
-
return this.message.encoder;
|
|
1590
1616
|
}
|
|
1591
1617
|
applySyncMessage(provider, emitSynced) {
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1618
|
+
const { message } = this;
|
|
1619
|
+
message.writeVarUint(exports.MessageType.Sync);
|
|
1620
|
+
// Apply update
|
|
1621
|
+
const syncMessageType = readSyncMessage(message.decoder, message.encoder, provider.document, provider);
|
|
1622
|
+
// Synced once we receive Step2
|
|
1623
|
+
if (emitSynced && (syncMessageType === messageYjsSyncStep2)) {
|
|
1595
1624
|
provider.synced = true;
|
|
1596
1625
|
}
|
|
1626
|
+
if (syncMessageType === messageYjsUpdate || syncMessageType === messageYjsSyncStep2) {
|
|
1627
|
+
if (provider.unsyncedChanges > 0) {
|
|
1628
|
+
provider.unsyncedChanges -= 1;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1597
1631
|
}
|
|
1598
1632
|
applyAwarenessMessage(provider) {
|
|
1599
|
-
|
|
1633
|
+
const { message } = this;
|
|
1634
|
+
applyAwarenessUpdate(provider.awareness, message.readVarUint8Array(), provider);
|
|
1600
1635
|
}
|
|
1601
|
-
// TODO: This isn’t really used. Needs to be implemented in the server, or removed here.
|
|
1602
1636
|
applyAuthMessage(provider) {
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
(provider, reason) => {
|
|
1606
|
-
console.warn(`Permission denied to access ${provider.url}.\n${reason}`);
|
|
1607
|
-
});
|
|
1637
|
+
const { message } = this;
|
|
1638
|
+
common.readAuthMessage(message.decoder, provider.permissionDeniedHandler.bind(provider), provider.authenticatedHandler.bind(provider));
|
|
1608
1639
|
}
|
|
1609
1640
|
applyQueryAwarenessMessage(provider) {
|
|
1610
|
-
|
|
1611
|
-
|
|
1641
|
+
const { message } = this;
|
|
1642
|
+
message.writeVarUint(exports.MessageType.Awareness);
|
|
1643
|
+
message.writeVarUint8Array(encodeAwarenessUpdate(provider.awareness, Array.from(provider.awareness.getStates().keys())));
|
|
1612
1644
|
}
|
|
1613
1645
|
}
|
|
1614
1646
|
|
|
@@ -1628,18 +1660,6 @@ class MessageSender {
|
|
|
1628
1660
|
}
|
|
1629
1661
|
}
|
|
1630
1662
|
|
|
1631
|
-
class OutgoingMessage {
|
|
1632
|
-
constructor() {
|
|
1633
|
-
this.encoder = createEncoder();
|
|
1634
|
-
}
|
|
1635
|
-
get name() {
|
|
1636
|
-
if (typeof this.type === 'number') {
|
|
1637
|
-
return exports.MessageType[this.type];
|
|
1638
|
-
}
|
|
1639
|
-
throw new Error('Type for outgoing message not set.');
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
1663
|
class SyncStepOneMessage extends OutgoingMessage {
|
|
1644
1664
|
constructor() {
|
|
1645
1665
|
super(...arguments);
|
|
@@ -1684,6 +1704,22 @@ class QueryAwarenessMessage extends OutgoingMessage {
|
|
|
1684
1704
|
}
|
|
1685
1705
|
}
|
|
1686
1706
|
|
|
1707
|
+
class AuthenticationMessage extends OutgoingMessage {
|
|
1708
|
+
constructor() {
|
|
1709
|
+
super(...arguments);
|
|
1710
|
+
this.type = exports.MessageType.Auth;
|
|
1711
|
+
this.description = 'Authentication';
|
|
1712
|
+
}
|
|
1713
|
+
get(args) {
|
|
1714
|
+
if (typeof args.token === 'undefined') {
|
|
1715
|
+
throw new Error('The authentication message requires `token` as an argument.');
|
|
1716
|
+
}
|
|
1717
|
+
writeVarUint(this.encoder, this.type);
|
|
1718
|
+
common.writeAuthentication(this.encoder, args.token);
|
|
1719
|
+
return this.encoder;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1687
1723
|
class AwarenessMessage extends OutgoingMessage {
|
|
1688
1724
|
constructor() {
|
|
1689
1725
|
super(...arguments);
|
|
@@ -1723,107 +1759,210 @@ class UpdateMessage extends OutgoingMessage {
|
|
|
1723
1759
|
}
|
|
1724
1760
|
}
|
|
1725
1761
|
|
|
1726
|
-
var awarenessStatesToArray = (states) => {
|
|
1727
|
-
return Array.from(states.entries()).map(([key, value]) => {
|
|
1728
|
-
return {
|
|
1729
|
-
clientId: key,
|
|
1730
|
-
...value,
|
|
1731
|
-
};
|
|
1732
|
-
});
|
|
1733
|
-
};
|
|
1734
|
-
|
|
1735
|
-
// @ts-nocheck
|
|
1736
|
-
exports.WebSocketStatus = void 0;
|
|
1737
|
-
(function (WebSocketStatus) {
|
|
1738
|
-
WebSocketStatus["Connecting"] = "connecting";
|
|
1739
|
-
WebSocketStatus["Connected"] = "connected";
|
|
1740
|
-
WebSocketStatus["Disconnected"] = "disconnected";
|
|
1741
|
-
})(exports.WebSocketStatus || (exports.WebSocketStatus = {}));
|
|
1742
1762
|
class HocuspocusProvider extends EventEmitter {
|
|
1743
|
-
constructor(
|
|
1763
|
+
constructor(configuration) {
|
|
1744
1764
|
super();
|
|
1745
|
-
this.
|
|
1746
|
-
url: '',
|
|
1765
|
+
this.configuration = {
|
|
1747
1766
|
name: '',
|
|
1767
|
+
url: '',
|
|
1768
|
+
// @ts-ignore
|
|
1769
|
+
document: undefined,
|
|
1770
|
+
// @ts-ignore
|
|
1771
|
+
awareness: undefined,
|
|
1772
|
+
WebSocketPolyfill: undefined,
|
|
1773
|
+
token: null,
|
|
1748
1774
|
parameters: {},
|
|
1749
|
-
debug: false,
|
|
1750
1775
|
connect: true,
|
|
1776
|
+
broadcast: true,
|
|
1751
1777
|
forceSyncInterval: false,
|
|
1752
|
-
reconnectTimeoutBase: 1200,
|
|
1753
|
-
maxReconnectTimeout: 2500,
|
|
1754
1778
|
// TODO: this should depend on awareness.outdatedTime
|
|
1755
1779
|
messageReconnectTimeout: 30000,
|
|
1780
|
+
// 1 second
|
|
1781
|
+
delay: 1000,
|
|
1782
|
+
// instant
|
|
1783
|
+
initialDelay: 0,
|
|
1784
|
+
// double the delay each time
|
|
1785
|
+
factor: 2,
|
|
1786
|
+
// unlimited retries
|
|
1787
|
+
maxAttempts: 0,
|
|
1788
|
+
// wait at least 1 second
|
|
1789
|
+
minDelay: 1000,
|
|
1790
|
+
// at least every 30 seconds
|
|
1791
|
+
maxDelay: 30000,
|
|
1792
|
+
// randomize
|
|
1793
|
+
jitter: true,
|
|
1794
|
+
// retry forever
|
|
1795
|
+
timeout: 0,
|
|
1796
|
+
onAuthenticated: () => null,
|
|
1797
|
+
onAuthenticationFailed: () => null,
|
|
1756
1798
|
onOpen: () => null,
|
|
1757
1799
|
onConnect: () => null,
|
|
1758
1800
|
onMessage: () => null,
|
|
1759
1801
|
onOutgoingMessage: () => null,
|
|
1802
|
+
onStatus: () => null,
|
|
1760
1803
|
onSynced: () => null,
|
|
1761
1804
|
onDisconnect: () => null,
|
|
1762
1805
|
onClose: () => null,
|
|
1763
1806
|
onDestroy: () => null,
|
|
1807
|
+
onAwarenessUpdate: () => null,
|
|
1764
1808
|
onAwarenessChange: () => null,
|
|
1809
|
+
quiet: false,
|
|
1765
1810
|
};
|
|
1766
1811
|
this.subscribedToBroadcastChannel = false;
|
|
1767
1812
|
this.webSocket = null;
|
|
1768
1813
|
this.shouldConnect = true;
|
|
1769
1814
|
this.status = exports.WebSocketStatus.Disconnected;
|
|
1770
|
-
this.failedConnectionAttempts = 0;
|
|
1771
1815
|
this.isSynced = false;
|
|
1816
|
+
this.unsyncedChanges = 0;
|
|
1817
|
+
this.isAuthenticated = false;
|
|
1772
1818
|
this.lastMessageReceived = 0;
|
|
1773
1819
|
this.mux = createMutex();
|
|
1774
1820
|
this.intervals = {
|
|
1775
1821
|
forceSync: null,
|
|
1776
1822
|
connectionChecker: null,
|
|
1777
1823
|
};
|
|
1778
|
-
this.
|
|
1779
|
-
this.
|
|
1780
|
-
this.
|
|
1781
|
-
this.
|
|
1782
|
-
this.
|
|
1783
|
-
this.
|
|
1784
|
-
this.
|
|
1785
|
-
this.
|
|
1786
|
-
this.on('
|
|
1787
|
-
this.on('
|
|
1788
|
-
this.on('
|
|
1789
|
-
this.on('
|
|
1790
|
-
this.on('
|
|
1791
|
-
this.on('
|
|
1824
|
+
this.connectionAttempt = null;
|
|
1825
|
+
this.boundConnect = this.connect.bind(this);
|
|
1826
|
+
this.boundBeforeUnload = this.beforeUnload.bind(this);
|
|
1827
|
+
this.boundBroadcastChannelSubscriber = this.broadcastChannelSubscriber.bind(this);
|
|
1828
|
+
this.setConfiguration(configuration);
|
|
1829
|
+
this.configuration.document = configuration.document ? configuration.document : new Y__namespace.Doc();
|
|
1830
|
+
this.configuration.awareness = configuration.awareness ? configuration.awareness : new Awareness(this.document);
|
|
1831
|
+
this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill ? configuration.WebSocketPolyfill : WebSocket;
|
|
1832
|
+
this.on('open', this.configuration.onOpen);
|
|
1833
|
+
this.on('authenticated', this.configuration.onAuthenticated);
|
|
1834
|
+
this.on('authenticationFailed', this.configuration.onAuthenticationFailed);
|
|
1835
|
+
this.on('connect', this.configuration.onConnect);
|
|
1836
|
+
this.on('message', this.configuration.onMessage);
|
|
1837
|
+
this.on('outgoingMessage', this.configuration.onOutgoingMessage);
|
|
1838
|
+
this.on('synced', this.configuration.onSynced);
|
|
1839
|
+
this.on('status', this.configuration.onStatus);
|
|
1840
|
+
this.on('disconnect', this.configuration.onDisconnect);
|
|
1841
|
+
this.on('close', this.configuration.onClose);
|
|
1842
|
+
this.on('destroy', this.configuration.onDestroy);
|
|
1843
|
+
this.on('awarenessUpdate', this.configuration.onAwarenessUpdate);
|
|
1844
|
+
this.on('awarenessChange', this.configuration.onAwarenessChange);
|
|
1845
|
+
this.awareness.on('update', () => {
|
|
1846
|
+
this.emit('awarenessUpdate', { states: common.awarenessStatesToArray(this.awareness.getStates()) });
|
|
1847
|
+
});
|
|
1792
1848
|
this.awareness.on('change', () => {
|
|
1793
|
-
this.emit('awarenessChange', {
|
|
1794
|
-
states: awarenessStatesToArray(this.awareness.getStates()),
|
|
1795
|
-
});
|
|
1849
|
+
this.emit('awarenessChange', { states: common.awarenessStatesToArray(this.awareness.getStates()) });
|
|
1796
1850
|
});
|
|
1797
|
-
this.intervals.connectionChecker = setInterval(this.checkConnection.bind(this), this.options.messageReconnectTimeout / 10);
|
|
1798
1851
|
this.document.on('update', this.documentUpdateHandler.bind(this));
|
|
1799
1852
|
this.awareness.on('update', this.awarenessUpdateHandler.bind(this));
|
|
1800
|
-
this.
|
|
1801
|
-
|
|
1802
|
-
|
|
1853
|
+
this.registerEventListeners();
|
|
1854
|
+
this.intervals.connectionChecker = setInterval(this.checkConnection.bind(this), this.configuration.messageReconnectTimeout / 10);
|
|
1855
|
+
if (this.configuration.forceSyncInterval) {
|
|
1856
|
+
this.intervals.forceSync = setInterval(this.forceSync.bind(this), this.configuration.forceSyncInterval);
|
|
1803
1857
|
}
|
|
1804
|
-
if (
|
|
1805
|
-
this.connect
|
|
1858
|
+
if (typeof configuration.connect !== 'undefined') {
|
|
1859
|
+
this.shouldConnect = configuration.connect;
|
|
1806
1860
|
}
|
|
1861
|
+
if (!this.shouldConnect) {
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1864
|
+
this.connect();
|
|
1865
|
+
}
|
|
1866
|
+
setConfiguration(configuration = {}) {
|
|
1867
|
+
this.configuration = { ...this.configuration, ...configuration };
|
|
1868
|
+
}
|
|
1869
|
+
async connect() {
|
|
1870
|
+
if (this.status === exports.WebSocketStatus.Connected) {
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
this.unsyncedChanges = 0; // set to 0 in case we got reconnected
|
|
1874
|
+
this.shouldConnect = true;
|
|
1875
|
+
this.subscribeToBroadcastChannel();
|
|
1876
|
+
try {
|
|
1877
|
+
await attempt.retry(this.createWebSocketConnection.bind(this), {
|
|
1878
|
+
delay: this.configuration.delay,
|
|
1879
|
+
initialDelay: this.configuration.initialDelay,
|
|
1880
|
+
factor: this.configuration.factor,
|
|
1881
|
+
maxAttempts: this.configuration.maxAttempts,
|
|
1882
|
+
minDelay: this.configuration.minDelay,
|
|
1883
|
+
maxDelay: this.configuration.maxDelay,
|
|
1884
|
+
jitter: this.configuration.jitter,
|
|
1885
|
+
timeout: this.configuration.timeout,
|
|
1886
|
+
beforeAttempt: context => {
|
|
1887
|
+
if (!this.shouldConnect) {
|
|
1888
|
+
context.abort();
|
|
1889
|
+
}
|
|
1890
|
+
},
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
1893
|
+
catch (error) {
|
|
1894
|
+
// If we aborted the connection attempt then don’t throw an error
|
|
1895
|
+
// ref: https://github.com/lifeomic/attempt/blob/master/src/index.ts#L136
|
|
1896
|
+
if (error && error.code !== 'ATTEMPT_ABORTED') {
|
|
1897
|
+
throw error;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
createWebSocketConnection() {
|
|
1902
|
+
return new Promise((resolve, reject) => {
|
|
1903
|
+
// Init the WebSocket connection
|
|
1904
|
+
const ws = new this.configuration.WebSocketPolyfill(this.url);
|
|
1905
|
+
ws.binaryType = 'arraybuffer';
|
|
1906
|
+
ws.onmessage = this.onMessage.bind(this);
|
|
1907
|
+
ws.onclose = this.onClose.bind(this);
|
|
1908
|
+
ws.onopen = this.onOpen.bind(this);
|
|
1909
|
+
ws.onerror = (err) => {
|
|
1910
|
+
reject(err);
|
|
1911
|
+
};
|
|
1912
|
+
this.webSocket = ws;
|
|
1913
|
+
// Reset the status
|
|
1914
|
+
this.synced = false;
|
|
1915
|
+
this.status = exports.WebSocketStatus.Connecting;
|
|
1916
|
+
this.emit('status', { status: exports.WebSocketStatus.Connecting });
|
|
1917
|
+
// Store resolve/reject for later use
|
|
1918
|
+
this.connectionAttempt = {
|
|
1919
|
+
resolve,
|
|
1920
|
+
reject,
|
|
1921
|
+
};
|
|
1922
|
+
});
|
|
1923
|
+
}
|
|
1924
|
+
resolveConnectionAttempt() {
|
|
1925
|
+
var _a;
|
|
1926
|
+
(_a = this.connectionAttempt) === null || _a === void 0 ? void 0 : _a.resolve();
|
|
1927
|
+
this.connectionAttempt = null;
|
|
1928
|
+
this.status = exports.WebSocketStatus.Connected;
|
|
1929
|
+
this.emit('status', { status: exports.WebSocketStatus.Connected });
|
|
1930
|
+
this.emit('connect');
|
|
1931
|
+
}
|
|
1932
|
+
stopConnectionAttempt() {
|
|
1933
|
+
this.connectionAttempt = null;
|
|
1807
1934
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1935
|
+
rejectConnectionAttempt() {
|
|
1936
|
+
var _a;
|
|
1937
|
+
(_a = this.connectionAttempt) === null || _a === void 0 ? void 0 : _a.reject();
|
|
1938
|
+
this.connectionAttempt = null;
|
|
1810
1939
|
}
|
|
1811
1940
|
get document() {
|
|
1812
|
-
return this.
|
|
1941
|
+
return this.configuration.document;
|
|
1813
1942
|
}
|
|
1814
1943
|
get awareness() {
|
|
1815
|
-
return this.
|
|
1944
|
+
return this.configuration.awareness;
|
|
1945
|
+
}
|
|
1946
|
+
get hasUnsyncedChanges() {
|
|
1947
|
+
return this.unsyncedChanges > 0;
|
|
1816
1948
|
}
|
|
1817
1949
|
checkConnection() {
|
|
1950
|
+
var _a;
|
|
1951
|
+
// Don’t check the connection when it’s not even established
|
|
1818
1952
|
if (this.status !== exports.WebSocketStatus.Connected) {
|
|
1819
1953
|
return;
|
|
1820
1954
|
}
|
|
1821
|
-
|
|
1955
|
+
// Don’t close then connection while waiting for the first message
|
|
1956
|
+
if (!this.lastMessageReceived) {
|
|
1957
|
+
return;
|
|
1958
|
+
}
|
|
1959
|
+
// Don’t close the connection when a message was received recently
|
|
1960
|
+
if (this.configuration.messageReconnectTimeout >= getUnixTime() - this.lastMessageReceived) {
|
|
1822
1961
|
return;
|
|
1823
1962
|
}
|
|
1824
1963
|
// No message received in a long time, not even your own
|
|
1825
1964
|
// Awareness updates, which are updated every 15 seconds.
|
|
1826
|
-
this.webSocket.close();
|
|
1965
|
+
(_a = this.webSocket) === null || _a === void 0 ? void 0 : _a.close();
|
|
1827
1966
|
}
|
|
1828
1967
|
forceSync() {
|
|
1829
1968
|
if (!this.webSocket) {
|
|
@@ -1831,18 +1970,21 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
1831
1970
|
}
|
|
1832
1971
|
this.send(SyncStepOneMessage, { document: this.document });
|
|
1833
1972
|
}
|
|
1834
|
-
|
|
1973
|
+
beforeUnload() {
|
|
1974
|
+
removeAwarenessStates(this.awareness, [this.document.clientID], 'window unload');
|
|
1975
|
+
}
|
|
1976
|
+
registerEventListeners() {
|
|
1835
1977
|
if (typeof window === 'undefined') {
|
|
1836
1978
|
return;
|
|
1837
1979
|
}
|
|
1838
|
-
window.addEventListener('
|
|
1839
|
-
|
|
1840
|
-
});
|
|
1980
|
+
window.addEventListener('online', this.boundConnect);
|
|
1981
|
+
window.addEventListener('beforeunload', this.boundBeforeUnload);
|
|
1841
1982
|
}
|
|
1842
1983
|
documentUpdateHandler(update, origin) {
|
|
1843
1984
|
if (origin === this) {
|
|
1844
1985
|
return;
|
|
1845
1986
|
}
|
|
1987
|
+
this.unsyncedChanges += 1;
|
|
1846
1988
|
this.send(UpdateMessage, { update }, true);
|
|
1847
1989
|
}
|
|
1848
1990
|
awarenessUpdateHandler({ added, updated, removed }, origin) {
|
|
@@ -1852,16 +1994,26 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
1852
1994
|
clients: changedClients,
|
|
1853
1995
|
}, true);
|
|
1854
1996
|
}
|
|
1997
|
+
permissionDeniedHandler(reason) {
|
|
1998
|
+
this.emit('authenticationFailed', { reason });
|
|
1999
|
+
this.isAuthenticated = false;
|
|
2000
|
+
this.shouldConnect = false;
|
|
2001
|
+
}
|
|
2002
|
+
authenticatedHandler() {
|
|
2003
|
+
this.isAuthenticated = true;
|
|
2004
|
+
this.emit('authenticated');
|
|
2005
|
+
this.startSync();
|
|
2006
|
+
}
|
|
1855
2007
|
// Ensure that the URL always ends with /
|
|
1856
2008
|
get serverUrl() {
|
|
1857
|
-
while (this.
|
|
1858
|
-
return this.
|
|
2009
|
+
while (this.configuration.url[this.configuration.url.length - 1] === '/') {
|
|
2010
|
+
return this.configuration.url.slice(0, this.configuration.url.length - 1);
|
|
1859
2011
|
}
|
|
1860
|
-
return this.
|
|
2012
|
+
return this.configuration.url;
|
|
1861
2013
|
}
|
|
1862
2014
|
get url() {
|
|
1863
|
-
const encodedParams = encodeQueryParams(this.
|
|
1864
|
-
return `${this.serverUrl}/${this.
|
|
2015
|
+
const encodedParams = encodeQueryParams(this.configuration.parameters);
|
|
2016
|
+
return `${this.serverUrl}/${this.configuration.name}${encodedParams.length === 0 ? '' : `?${encodedParams}`}`;
|
|
1865
2017
|
}
|
|
1866
2018
|
get synced() {
|
|
1867
2019
|
return this.isSynced;
|
|
@@ -1874,12 +2026,8 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
1874
2026
|
this.emit('synced', { state });
|
|
1875
2027
|
this.emit('sync', { state });
|
|
1876
2028
|
}
|
|
1877
|
-
|
|
1878
|
-
this.
|
|
1879
|
-
if (this.status !== exports.WebSocketStatus.Connected) {
|
|
1880
|
-
this.createWebSocketConnection();
|
|
1881
|
-
this.subscribeToBroadcastChannel();
|
|
1882
|
-
}
|
|
2029
|
+
get isAuthenticationRequired() {
|
|
2030
|
+
return !!this.configuration.token && !this.isAuthenticated;
|
|
1883
2031
|
}
|
|
1884
2032
|
disconnect() {
|
|
1885
2033
|
this.shouldConnect = false;
|
|
@@ -1894,27 +2042,24 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
1894
2042
|
//
|
|
1895
2043
|
}
|
|
1896
2044
|
}
|
|
1897
|
-
|
|
1898
|
-
|
|
2045
|
+
async onOpen(event) {
|
|
2046
|
+
this.emit('open', { event });
|
|
2047
|
+
if (this.isAuthenticationRequired) {
|
|
2048
|
+
this.send(AuthenticationMessage, {
|
|
2049
|
+
token: await this.getToken(),
|
|
2050
|
+
});
|
|
1899
2051
|
return;
|
|
1900
2052
|
}
|
|
1901
|
-
this.
|
|
1902
|
-
this.webSocket.binaryType = 'arraybuffer';
|
|
1903
|
-
this.status = exports.WebSocketStatus.Connecting;
|
|
1904
|
-
this.synced = false;
|
|
1905
|
-
this.webSocket.onmessage = this.onMessage.bind(this);
|
|
1906
|
-
this.webSocket.onclose = this.onClose.bind(this);
|
|
1907
|
-
this.webSocket.onopen = this.onOpen.bind(this);
|
|
1908
|
-
this.emit('status', { status: 'connecting' });
|
|
2053
|
+
this.startSync();
|
|
1909
2054
|
}
|
|
1910
|
-
|
|
1911
|
-
this.
|
|
2055
|
+
async getToken() {
|
|
2056
|
+
if (typeof this.configuration.token === 'function') {
|
|
2057
|
+
const token = await this.configuration.token();
|
|
2058
|
+
return token;
|
|
2059
|
+
}
|
|
2060
|
+
return this.configuration.token;
|
|
1912
2061
|
}
|
|
1913
|
-
|
|
1914
|
-
this.failedConnectionAttempts = 0;
|
|
1915
|
-
this.status = exports.WebSocketStatus.Connected;
|
|
1916
|
-
this.emit('status', { status: 'connected' });
|
|
1917
|
-
this.emit('connect');
|
|
2062
|
+
startSync() {
|
|
1918
2063
|
this.send(SyncStepOneMessage, { document: this.document });
|
|
1919
2064
|
if (this.awareness.getLocalState() !== null) {
|
|
1920
2065
|
this.send(AwarenessMessage, {
|
|
@@ -1924,56 +2069,66 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
1924
2069
|
}
|
|
1925
2070
|
}
|
|
1926
2071
|
send(Message, args, broadcast = false) {
|
|
1927
|
-
|
|
2072
|
+
var _a;
|
|
1928
2073
|
if (broadcast) {
|
|
1929
|
-
this.mux(() => {
|
|
1930
|
-
this.broadcast(Message, args);
|
|
1931
|
-
});
|
|
2074
|
+
this.mux(() => { this.broadcast(Message, args); });
|
|
1932
2075
|
}
|
|
1933
|
-
if (this.
|
|
2076
|
+
if (((_a = this.webSocket) === null || _a === void 0 ? void 0 : _a.readyState) === common.WsReadyStates.Open) {
|
|
1934
2077
|
const messageSender = new MessageSender(Message, args);
|
|
1935
2078
|
this.emit('outgoingMessage', { message: messageSender.message });
|
|
1936
2079
|
messageSender.send(this.webSocket);
|
|
1937
2080
|
}
|
|
1938
2081
|
}
|
|
1939
2082
|
onMessage(event) {
|
|
1940
|
-
|
|
1941
|
-
this.webSocketConnectionEstablished();
|
|
1942
|
-
}
|
|
2083
|
+
this.resolveConnectionAttempt();
|
|
1943
2084
|
this.lastMessageReceived = getUnixTime();
|
|
1944
2085
|
const message = new IncomingMessage(event.data);
|
|
1945
2086
|
this.emit('message', { event, message });
|
|
1946
|
-
new MessageReceiver(message
|
|
1947
|
-
// TODO: What’s that doing?
|
|
1948
|
-
// if (encoding.length(encoder) > 1) {
|
|
1949
|
-
// this.send(encoding.toUint8Array(encoder))
|
|
1950
|
-
// }
|
|
2087
|
+
new MessageReceiver(message).apply(this);
|
|
1951
2088
|
}
|
|
1952
2089
|
onClose(event) {
|
|
1953
2090
|
this.emit('close', { event });
|
|
1954
2091
|
this.webSocket = null;
|
|
2092
|
+
this.isAuthenticated = false;
|
|
2093
|
+
this.synced = false;
|
|
1955
2094
|
if (this.status === exports.WebSocketStatus.Connected) {
|
|
1956
|
-
this.synced = false;
|
|
1957
2095
|
// update awareness (all users except local left)
|
|
1958
2096
|
removeAwarenessStates(this.awareness, Array.from(this.awareness.getStates().keys()).filter(client => client !== this.document.clientID), this);
|
|
1959
2097
|
this.status = exports.WebSocketStatus.Disconnected;
|
|
1960
|
-
this.emit('status', { status:
|
|
2098
|
+
this.emit('status', { status: exports.WebSocketStatus.Disconnected });
|
|
1961
2099
|
this.emit('disconnect', { event });
|
|
1962
2100
|
}
|
|
1963
|
-
|
|
1964
|
-
this.
|
|
2101
|
+
if (event.code === common.Unauthorized.code) {
|
|
2102
|
+
if (!this.configuration.quiet) {
|
|
2103
|
+
console.warn('[HocuspocusProvider] An authentication token is required, but you didn’t send one. Try adding a `token` to your HocuspocusProvider configuration. Won’t try again.');
|
|
2104
|
+
}
|
|
2105
|
+
this.shouldConnect = false;
|
|
1965
2106
|
}
|
|
2107
|
+
if (event.code === common.Forbidden.code) {
|
|
2108
|
+
if (!this.configuration.quiet) {
|
|
2109
|
+
console.warn('[HocuspocusProvider] The provided authentication token isn’t allowed to connect to this server. Will try again.');
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
if (this.connectionAttempt) {
|
|
2113
|
+
// That connection attempt failed.
|
|
2114
|
+
this.rejectConnectionAttempt();
|
|
2115
|
+
}
|
|
2116
|
+
else if (this.shouldConnect) {
|
|
2117
|
+
// The connection was closed by the server. Let’s just try again.
|
|
2118
|
+
this.connect();
|
|
2119
|
+
}
|
|
2120
|
+
// If we’ll reconnect, we’re done for now.
|
|
1966
2121
|
if (this.shouldConnect) {
|
|
1967
|
-
const wait = round(min(log10(this.failedConnectionAttempts + 1) * this.options.reconnectTimeoutBase, this.options.maxReconnectTimeout));
|
|
1968
|
-
this.log(`[close] Reconnecting in ${wait}ms …`);
|
|
1969
|
-
setTimeout(this.createWebSocketConnection.bind(this), wait);
|
|
1970
2122
|
return;
|
|
1971
2123
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
this.emit('disconnect', { event });
|
|
2124
|
+
// The status is set correctly already.
|
|
2125
|
+
if (this.status === exports.WebSocketStatus.Disconnected) {
|
|
2126
|
+
return;
|
|
1976
2127
|
}
|
|
2128
|
+
// Let’s update the connection status.
|
|
2129
|
+
this.status = exports.WebSocketStatus.Disconnected;
|
|
2130
|
+
this.emit('status', { status: exports.WebSocketStatus.Disconnected });
|
|
2131
|
+
this.emit('disconnect', { event });
|
|
1977
2132
|
}
|
|
1978
2133
|
destroy() {
|
|
1979
2134
|
this.emit('destroy');
|
|
@@ -1981,27 +2136,35 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
1981
2136
|
clearInterval(this.intervals.forceSync);
|
|
1982
2137
|
}
|
|
1983
2138
|
clearInterval(this.intervals.connectionChecker);
|
|
2139
|
+
removeAwarenessStates(this.awareness, [this.document.clientID], 'provider destroy');
|
|
2140
|
+
// If there is still a connection attempt outstanding then we should stop
|
|
2141
|
+
// it before calling disconnect, otherwise it will be rejected in the onClose
|
|
2142
|
+
// handler and trigger a retry
|
|
2143
|
+
this.stopConnectionAttempt();
|
|
1984
2144
|
this.disconnect();
|
|
1985
2145
|
this.awareness.off('update', this.awarenessUpdateHandler);
|
|
1986
2146
|
this.document.off('update', this.documentUpdateHandler);
|
|
1987
2147
|
this.removeAllListeners();
|
|
2148
|
+
if (typeof window === 'undefined') {
|
|
2149
|
+
return;
|
|
2150
|
+
}
|
|
2151
|
+
window.removeEventListener('online', this.boundConnect);
|
|
2152
|
+
window.removeEventListener('beforeunload', this.boundBeforeUnload);
|
|
1988
2153
|
}
|
|
1989
2154
|
get broadcastChannel() {
|
|
1990
|
-
return `${this.serverUrl}/${this.
|
|
2155
|
+
return `${this.serverUrl}/${this.configuration.name}`;
|
|
1991
2156
|
}
|
|
1992
2157
|
broadcastChannelSubscriber(data) {
|
|
1993
2158
|
this.mux(() => {
|
|
1994
2159
|
const message = new IncomingMessage(data);
|
|
1995
|
-
new MessageReceiver(message
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
// this.broadcast(encoding.toUint8Array(encoder))
|
|
1999
|
-
// }
|
|
2160
|
+
new MessageReceiver(message)
|
|
2161
|
+
.setBroadcasted(true)
|
|
2162
|
+
.apply(this, false);
|
|
2000
2163
|
});
|
|
2001
2164
|
}
|
|
2002
2165
|
subscribeToBroadcastChannel() {
|
|
2003
2166
|
if (!this.subscribedToBroadcastChannel) {
|
|
2004
|
-
subscribe(this.broadcastChannel, this.
|
|
2167
|
+
subscribe(this.broadcastChannel, this.boundBroadcastChannelSubscriber);
|
|
2005
2168
|
this.subscribedToBroadcastChannel = true;
|
|
2006
2169
|
}
|
|
2007
2170
|
this.mux(() => {
|
|
@@ -2019,26 +2182,39 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2019
2182
|
states: new Map(),
|
|
2020
2183
|
}, true);
|
|
2021
2184
|
if (this.subscribedToBroadcastChannel) {
|
|
2022
|
-
unsubscribe(this.broadcastChannel, this.
|
|
2185
|
+
unsubscribe(this.broadcastChannel, this.boundBroadcastChannelSubscriber);
|
|
2023
2186
|
this.subscribedToBroadcastChannel = false;
|
|
2024
2187
|
}
|
|
2025
2188
|
}
|
|
2026
2189
|
broadcast(Message, args) {
|
|
2027
|
-
if (this.
|
|
2028
|
-
|
|
2190
|
+
if (!this.configuration.broadcast) {
|
|
2191
|
+
return;
|
|
2029
2192
|
}
|
|
2030
|
-
|
|
2031
|
-
log(message) {
|
|
2032
|
-
if (!this.options.debug) {
|
|
2193
|
+
if (!this.subscribedToBroadcastChannel) {
|
|
2033
2194
|
return;
|
|
2034
2195
|
}
|
|
2035
|
-
|
|
2196
|
+
new MessageSender(Message, args).broadcast(this.broadcastChannel);
|
|
2036
2197
|
}
|
|
2037
2198
|
setAwarenessField(key, value) {
|
|
2038
2199
|
this.awareness.setLocalStateField(key, value);
|
|
2039
2200
|
}
|
|
2040
2201
|
}
|
|
2041
2202
|
|
|
2203
|
+
class HocuspocusCloudProvider extends HocuspocusProvider {
|
|
2204
|
+
constructor(configuration) {
|
|
2205
|
+
if (!configuration.url) {
|
|
2206
|
+
configuration.url = 'wss://connect.hocuspocus.cloud';
|
|
2207
|
+
}
|
|
2208
|
+
if (configuration.key) {
|
|
2209
|
+
if (!configuration.parameters) {
|
|
2210
|
+
configuration.parameters = {};
|
|
2211
|
+
}
|
|
2212
|
+
configuration.parameters.key = configuration.key;
|
|
2213
|
+
}
|
|
2214
|
+
super(configuration);
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
exports.HocuspocusCloudProvider = HocuspocusCloudProvider;
|
|
2042
2219
|
exports.HocuspocusProvider = HocuspocusProvider;
|
|
2043
|
-
|
|
2044
|
-
//# sourceMappingURL=hocuspocus-provider.js.map
|
|
2220
|
+
//# sourceMappingURL=hocuspocus-provider.cjs.map
|