@hocuspocus/provider 2.5.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 +67 -31
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +67 -31
- package/dist/hocuspocus-provider.esm.js.map +1 -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/types.d.ts +4 -3
- package/package.json +2 -2
- package/src/HocuspocusProvider.ts +4 -0
- package/src/HocuspocusProviderWebsocket.ts +77 -37
- package/src/TiptapCollabProvider.ts +26 -21
- package/src/types.ts +63 -0
|
@@ -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,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.
|
|
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.
|
|
1778
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
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() {
|
|
@@ -2736,36 +2763,45 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2736
2763
|
super(configuration);
|
|
2737
2764
|
this.tiptapCollabConfigurationPrefix = '__tiptapcollab__';
|
|
2738
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
|
+
*/
|
|
2739
2769
|
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
2770
|
return this.sendStateless(JSON.stringify({ action: 'version.create', name }));
|
|
2742
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
|
+
*/
|
|
2743
2775
|
revertToVersion(targetVersion) {
|
|
2744
|
-
|
|
2745
|
-
return this.sendStateless(JSON.stringify({ action: 'version.revert', version: targetVersion }));
|
|
2776
|
+
return this.sendStateless(JSON.stringify({ action: 'document.revert', version: targetVersion }));
|
|
2746
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
|
+
*/
|
|
2747
2789
|
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
2790
|
return this.configuration.document.getArray(`${this.tiptapCollabConfigurationPrefix}versions`).toArray();
|
|
2750
2791
|
}
|
|
2751
2792
|
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
2793
|
return this.configuration.document.getArray('__tiptapcollab__versions').observe(callback);
|
|
2754
2794
|
}
|
|
2755
2795
|
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
2796
|
return this.configuration.document.getArray('__tiptapcollab__versions').unobserve(callback);
|
|
2758
2797
|
}
|
|
2759
2798
|
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
2799
|
return !!this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).get('autoVersioning');
|
|
2762
2800
|
}
|
|
2763
2801
|
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
2802
|
return this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 1);
|
|
2766
2803
|
}
|
|
2767
2804
|
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
2805
|
return this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 0);
|
|
2770
2806
|
}
|
|
2771
2807
|
}
|