@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.
- package/dist/hocuspocus-provider.cjs +68 -31
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +68 -31
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/packages/extension-redis/src/Redis.d.ts +6 -1
- package/dist/packages/provider/src/HocuspocusProviderWebsocket.d.ts +10 -2
- package/dist/packages/provider/src/TiptapCollabProvider.d.ts +19 -8
- package/dist/packages/provider/src/types.d.ts +45 -0
- package/dist/packages/server/src/Hocuspocus.d.ts +1 -9
- package/dist/packages/server/src/MessageReceiver.d.ts +2 -1
- package/dist/packages/server/src/index.d.ts +1 -0
- package/dist/packages/server/src/types.d.ts +4 -12
- package/dist/packages/server/src/util/debounce.d.ts +1 -0
- package/package.json +2 -2
- package/src/HocuspocusProvider.ts +4 -0
- package/src/HocuspocusProviderWebsocket.ts +78 -37
- package/src/TiptapCollabProvider.ts +26 -21
- package/src/types.ts +63 -0
- package/dist/tests/extension-redis/closeConnections.d.ts +0 -1
- package/dist/tests/extension-redis/getConnectionCount.d.ts +0 -1
- package/dist/tests/extension-redis/getDocumentsCount.d.ts +0 -1
|
@@ -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
|
|
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.
|
|
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.
|
|
1777
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|