@hocuspocus/provider 2.5.0 → 2.6.1

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.
@@ -1655,9 +1655,11 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1655
1655
  };
1656
1656
  this.subscribedToBroadcastChannel = false;
1657
1657
  this.webSocket = null;
1658
+ this.webSocketHandlers = {};
1658
1659
  this.shouldConnect = true;
1659
1660
  this.status = WebSocketStatus.Disconnected;
1660
1661
  this.lastMessageReceived = 0;
1662
+ this.identifier = 0;
1661
1663
  this.mux = createMutex();
1662
1664
  this.intervals = {
1663
1665
  forceSync: null,
@@ -1669,7 +1671,9 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1669
1671
  this.boundConnect = this.connect.bind(this);
1670
1672
  this.closeTries = 0;
1671
1673
  this.setConfiguration(configuration);
1672
- this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill ? configuration.WebSocketPolyfill : WebSocket;
1674
+ this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill
1675
+ ? configuration.WebSocketPolyfill
1676
+ : WebSocket;
1673
1677
  this.on('open', this.configuration.onOpen);
1674
1678
  this.on('open', this.onOpen.bind(this));
1675
1679
  this.on('connect', this.configuration.onConnect);
@@ -1684,7 +1688,6 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1684
1688
  this.on('awarenessChange', this.configuration.onAwarenessChange);
1685
1689
  this.on('close', this.onClose.bind(this));
1686
1690
  this.on('message', this.onMessage.bind(this));
1687
- this.registerEventListeners();
1688
1691
  this.intervals.connectionChecker = setInterval(this.checkConnection.bind(this), this.configuration.messageReconnectTimeout / 10);
1689
1692
  if (typeof configuration.connect !== 'undefined') {
1690
1693
  this.shouldConnect = configuration.connect;
@@ -1763,23 +1766,52 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1763
1766
  this.cancelWebsocketRetry = cancelFunc;
1764
1767
  return retryPromise;
1765
1768
  }
1769
+ attachWebSocketListeners(ws, reject) {
1770
+ const { identifier } = ws;
1771
+ const onMessageHandler = (payload) => this.emit('message', payload);
1772
+ const onCloseHandler = (payload) => this.emit('close', { event: payload });
1773
+ const onOpenHandler = (payload) => this.emit('open', payload);
1774
+ const onErrorHandler = (err) => {
1775
+ reject(err);
1776
+ };
1777
+ this.webSocketHandlers[identifier] = {
1778
+ message: onMessageHandler,
1779
+ close: onCloseHandler,
1780
+ open: onOpenHandler,
1781
+ error: onErrorHandler,
1782
+ };
1783
+ const handlers = this.webSocketHandlers[ws.identifier];
1784
+ Object.keys(handlers).forEach(name => {
1785
+ ws.addEventListener(name, handlers[name]);
1786
+ });
1787
+ }
1788
+ cleanupWebSocket() {
1789
+ if (!this.webSocket) {
1790
+ return;
1791
+ }
1792
+ const { identifier } = this.webSocket;
1793
+ const handlers = this.webSocketHandlers[identifier];
1794
+ Object.keys(handlers).forEach(name => {
1795
+ var _a;
1796
+ (_a = this.webSocket) === null || _a === void 0 ? void 0 : _a.removeEventListener(name, handlers[name]);
1797
+ delete this.webSocketHandlers[identifier];
1798
+ });
1799
+ this.webSocket.close();
1800
+ this.webSocket = null;
1801
+ }
1766
1802
  createWebSocketConnection() {
1767
1803
  return new Promise((resolve, reject) => {
1768
1804
  if (this.webSocket) {
1769
1805
  this.messageQueue = [];
1770
- this.webSocket.close();
1771
- this.webSocket = null;
1806
+ this.cleanupWebSocket();
1772
1807
  }
1773
1808
  this.lastMessageReceived = 0;
1809
+ this.identifier += 1;
1774
1810
  // Init the WebSocket connection
1775
1811
  const ws = new this.configuration.WebSocketPolyfill(this.url);
1776
1812
  ws.binaryType = 'arraybuffer';
1777
- ws.onmessage = (payload) => this.emit('message', payload);
1778
- ws.onclose = (payload) => this.emit('close', { event: payload });
1779
- ws.onopen = (payload) => this.emit('open', payload);
1780
- ws.onerror = (err) => {
1781
- reject(err);
1782
- };
1813
+ ws.identifier = this.identifier;
1814
+ this.attachWebSocketListeners(ws, reject);
1783
1815
  this.webSocket = ws;
1784
1816
  // Reset the status
1785
1817
  this.status = WebSocketStatus.Connecting;
@@ -1825,7 +1857,8 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1825
1857
  return;
1826
1858
  }
1827
1859
  // Don’t close the connection when a message was received recently
1828
- if (this.configuration.messageReconnectTimeout >= getUnixTime() - this.lastMessageReceived) {
1860
+ if (this.configuration.messageReconnectTimeout
1861
+ >= getUnixTime() - this.lastMessageReceived) {
1829
1862
  return;
1830
1863
  }
1831
1864
  // No message received in a long time, not even your own
@@ -1847,12 +1880,6 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1847
1880
  this.messageQueue = [];
1848
1881
  }
1849
1882
  }
1850
- registerEventListeners() {
1851
- if (typeof window === 'undefined') {
1852
- return;
1853
- }
1854
- window.addEventListener('online', this.boundConnect);
1855
- }
1856
1883
  // Ensure that the URL always ends with /
1857
1884
  get serverUrl() {
1858
1885
  while (this.configuration.url[this.configuration.url.length - 1] === '/') {
@@ -1888,7 +1915,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1888
1915
  }
1889
1916
  onClose({ event }) {
1890
1917
  this.closeTries = 0;
1891
- this.webSocket = null;
1918
+ this.cleanupWebSocket();
1892
1919
  if (this.status === WebSocketStatus.Connected) {
1893
1920
  this.status = WebSocketStatus.Disconnected;
1894
1921
  this.emit('status', { status: WebSocketStatus.Disconnected });
@@ -1946,10 +1973,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1946
1973
  this.stopConnectionAttempt();
1947
1974
  this.disconnect();
1948
1975
  this.removeAllListeners();
1949
- if (typeof window === 'undefined') {
1950
- return;
1951
- }
1952
- window.removeEventListener('online', this.boundConnect);
1976
+ this.cleanupWebSocket();
1953
1977
  }
1954
1978
  }
1955
1979
 
@@ -2548,6 +2572,9 @@ class HocuspocusProvider extends EventEmitter {
2548
2572
  }
2549
2573
  // not needed, but provides backward compatibility with e.g. lexicla/yjs
2550
2574
  async connect() {
2575
+ if (this.configuration.broadcast) {
2576
+ this.subscribeToBroadcastChannel();
2577
+ }
2551
2578
  return this.configuration.websocketProvider.connect();
2552
2579
  }
2553
2580
  disconnect() {
@@ -2679,11 +2706,16 @@ class HocuspocusProvider extends EventEmitter {
2679
2706
  this.subscribedToBroadcastChannel = true;
2680
2707
  }
2681
2708
  this.mux(() => {
2682
- this.broadcast(SyncStepOneMessage, { document: this.document });
2683
- this.broadcast(SyncStepTwoMessage, { document: this.document });
2684
- this.broadcast(QueryAwarenessMessage, { document: this.document });
2709
+ this.broadcast(SyncStepOneMessage, { document: this.document, documentName: this.configuration.name });
2710
+ this.broadcast(SyncStepTwoMessage, { document: this.document, documentName: this.configuration.name });
2711
+ this.broadcast(QueryAwarenessMessage, { document: this.document, documentName: this.configuration.name });
2685
2712
  if (this.awareness) {
2686
- this.broadcast(AwarenessMessage, { awareness: this.awareness, clients: [this.document.clientID], document: this.document });
2713
+ this.broadcast(AwarenessMessage, {
2714
+ awareness: this.awareness,
2715
+ clients: [this.document.clientID],
2716
+ document: this.document,
2717
+ documentName: this.configuration.name,
2718
+ });
2687
2719
  }
2688
2720
  });
2689
2721
  }
@@ -2736,36 +2768,45 @@ class TiptapCollabProvider extends HocuspocusProvider {
2736
2768
  super(configuration);
2737
2769
  this.tiptapCollabConfigurationPrefix = '__tiptapcollab__';
2738
2770
  }
2771
+ /**
2772
+ * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
2773
+ */
2739
2774
  createVersion(name) {
2740
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2741
2775
  return this.sendStateless(JSON.stringify({ action: 'version.create', name }));
2742
2776
  }
2777
+ /**
2778
+ * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
2779
+ */
2743
2780
  revertToVersion(targetVersion) {
2744
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2745
- return this.sendStateless(JSON.stringify({ action: 'version.revert', version: targetVersion }));
2781
+ return this.sendStateless(JSON.stringify({ action: 'document.revert', version: targetVersion }));
2746
2782
  }
2783
+ /**
2784
+ * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
2785
+ *
2786
+ * The server will reply with a stateless message (THistoryVersionPreviewEvent)
2787
+ */
2788
+ previewVersion(targetVersion) {
2789
+ return this.sendStateless(JSON.stringify({ action: 'version.preview', version: targetVersion }));
2790
+ }
2791
+ /**
2792
+ * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
2793
+ */
2747
2794
  getVersions() {
2748
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2749
2795
  return this.configuration.document.getArray(`${this.tiptapCollabConfigurationPrefix}versions`).toArray();
2750
2796
  }
2751
2797
  watchVersions(callback) {
2752
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2753
2798
  return this.configuration.document.getArray('__tiptapcollab__versions').observe(callback);
2754
2799
  }
2755
2800
  unwatchVersions(callback) {
2756
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2757
2801
  return this.configuration.document.getArray('__tiptapcollab__versions').unobserve(callback);
2758
2802
  }
2759
2803
  isAutoVersioning() {
2760
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2761
2804
  return !!this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).get('autoVersioning');
2762
2805
  }
2763
2806
  enableAutoVersioning() {
2764
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2765
2807
  return this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 1);
2766
2808
  }
2767
2809
  disableAutoVersioning() {
2768
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2769
2810
  return this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 0);
2770
2811
  }
2771
2812
  }