@hocuspocus/provider 2.5.0-rc.0 → 2.6.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.
@@ -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,22 +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
  }
1808
+ this.lastMessageReceived = 0;
1809
+ this.identifier += 1;
1773
1810
  // Init the WebSocket connection
1774
1811
  const ws = new this.configuration.WebSocketPolyfill(this.url);
1775
1812
  ws.binaryType = 'arraybuffer';
1776
- ws.onmessage = (payload) => this.emit('message', payload);
1777
- ws.onclose = (payload) => this.emit('close', { event: payload });
1778
- ws.onopen = (payload) => this.emit('open', payload);
1779
- ws.onerror = (err) => {
1780
- reject(err);
1781
- };
1813
+ ws.identifier = this.identifier;
1814
+ this.attachWebSocketListeners(ws, reject);
1782
1815
  this.webSocket = ws;
1783
1816
  // Reset the status
1784
1817
  this.status = WebSocketStatus.Connecting;
@@ -1824,7 +1857,8 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1824
1857
  return;
1825
1858
  }
1826
1859
  // Don’t close the connection when a message was received recently
1827
- if (this.configuration.messageReconnectTimeout >= getUnixTime() - this.lastMessageReceived) {
1860
+ if (this.configuration.messageReconnectTimeout
1861
+ >= getUnixTime() - this.lastMessageReceived) {
1828
1862
  return;
1829
1863
  }
1830
1864
  // No message received in a long time, not even your own
@@ -1846,12 +1880,6 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1846
1880
  this.messageQueue = [];
1847
1881
  }
1848
1882
  }
1849
- registerEventListeners() {
1850
- if (typeof window === 'undefined') {
1851
- return;
1852
- }
1853
- window.addEventListener('online', this.boundConnect);
1854
- }
1855
1883
  // Ensure that the URL always ends with /
1856
1884
  get serverUrl() {
1857
1885
  while (this.configuration.url[this.configuration.url.length - 1] === '/') {
@@ -1887,7 +1915,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1887
1915
  }
1888
1916
  onClose({ event }) {
1889
1917
  this.closeTries = 0;
1890
- this.webSocket = null;
1918
+ this.cleanupWebSocket();
1891
1919
  if (this.status === WebSocketStatus.Connected) {
1892
1920
  this.status = WebSocketStatus.Disconnected;
1893
1921
  this.emit('status', { status: WebSocketStatus.Disconnected });
@@ -1945,10 +1973,7 @@ class HocuspocusProviderWebsocket extends EventEmitter {
1945
1973
  this.stopConnectionAttempt();
1946
1974
  this.disconnect();
1947
1975
  this.removeAllListeners();
1948
- if (typeof window === 'undefined') {
1949
- return;
1950
- }
1951
- window.removeEventListener('online', this.boundConnect);
1976
+ this.cleanupWebSocket();
1952
1977
  }
1953
1978
  }
1954
1979
 
@@ -2547,6 +2572,9 @@ class HocuspocusProvider extends EventEmitter {
2547
2572
  }
2548
2573
  // not needed, but provides backward compatibility with e.g. lexicla/yjs
2549
2574
  async connect() {
2575
+ if (this.configuration.broadcast) {
2576
+ this.subscribeToBroadcastChannel();
2577
+ }
2550
2578
  return this.configuration.websocketProvider.connect();
2551
2579
  }
2552
2580
  disconnect() {
@@ -2735,36 +2763,45 @@ class TiptapCollabProvider extends HocuspocusProvider {
2735
2763
  super(configuration);
2736
2764
  this.tiptapCollabConfigurationPrefix = '__tiptapcollab__';
2737
2765
  }
2766
+ /**
2767
+ * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
2768
+ */
2738
2769
  createVersion(name) {
2739
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2740
2770
  return this.sendStateless(JSON.stringify({ action: 'version.create', name }));
2741
2771
  }
2772
+ /**
2773
+ * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
2774
+ */
2742
2775
  revertToVersion(targetVersion) {
2743
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2744
- return this.sendStateless(JSON.stringify({ action: 'version.revert', version: targetVersion }));
2776
+ return this.sendStateless(JSON.stringify({ action: 'document.revert', version: targetVersion }));
2745
2777
  }
2778
+ /**
2779
+ * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
2780
+ *
2781
+ * The server will reply with a stateless message (THistoryVersionPreviewEvent)
2782
+ */
2783
+ previewVersion(targetVersion) {
2784
+ return this.sendStateless(JSON.stringify({ action: 'version.preview', version: targetVersion }));
2785
+ }
2786
+ /**
2787
+ * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
2788
+ */
2746
2789
  getVersions() {
2747
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2748
2790
  return this.configuration.document.getArray(`${this.tiptapCollabConfigurationPrefix}versions`).toArray();
2749
2791
  }
2750
2792
  watchVersions(callback) {
2751
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2752
2793
  return this.configuration.document.getArray('__tiptapcollab__versions').observe(callback);
2753
2794
  }
2754
2795
  unwatchVersions(callback) {
2755
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2756
2796
  return this.configuration.document.getArray('__tiptapcollab__versions').unobserve(callback);
2757
2797
  }
2758
2798
  isAutoVersioning() {
2759
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2760
2799
  return !!this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).get('autoVersioning');
2761
2800
  }
2762
2801
  enableAutoVersioning() {
2763
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2764
2802
  return this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 1);
2765
2803
  }
2766
2804
  disableAutoVersioning() {
2767
- console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev');
2768
2805
  return this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 0);
2769
2806
  }
2770
2807
  }