@hocuspocus/provider 2.0.2 → 2.0.4
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 +23 -4
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +24 -6
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/packages/common/src/CloseEvents.d.ts +6 -0
- package/dist/packages/extension-redis/src/Redis.d.ts +6 -1
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +1 -0
- package/dist/packages/provider/src/TiptapCollabProviderWebsocket.d.ts +11 -0
- package/dist/packages/provider/src/index.d.ts +1 -0
- package/package.json +2 -2
- package/src/HocuspocusProvider.ts +13 -2
- package/src/HocuspocusProviderWebsocket.ts +6 -1
- package/src/MessageReceiver.ts +1 -1
- package/src/TiptapCollabProvider.ts +4 -5
- package/src/TiptapCollabProviderWebsocket.ts +21 -0
- package/src/index.ts +1 -0
- package/dist/packages/provider/src/HocuspocusCloudProvider.d.ts +0 -12
- package/src/HocuspocusCloudProvider.ts +0 -41
|
@@ -2,6 +2,12 @@ export interface CloseEvent {
|
|
|
2
2
|
code: number;
|
|
3
3
|
reason: string;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* The server is terminating the connection because a data frame was received
|
|
7
|
+
* that is too large.
|
|
8
|
+
* See: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
|
|
9
|
+
*/
|
|
10
|
+
export declare const MessageTooBig: CloseEvent;
|
|
5
11
|
/**
|
|
6
12
|
* The server successfully processed the request, asks that the requester reset
|
|
7
13
|
* its document view, and is not returning any content.
|
|
@@ -42,6 +42,11 @@ export interface Configuration {
|
|
|
42
42
|
* The maximum time for the Redis lock in ms (in case it can’t be released).
|
|
43
43
|
*/
|
|
44
44
|
lockTimeout: number;
|
|
45
|
+
/**
|
|
46
|
+
* A delay before onDisconnect is executed. This allows last minute updates'
|
|
47
|
+
* sync messages to be received by the subscription before it's closed.
|
|
48
|
+
*/
|
|
49
|
+
disconnectDelay: number;
|
|
45
50
|
}
|
|
46
51
|
export declare class Redis implements Extension {
|
|
47
52
|
/**
|
|
@@ -103,7 +108,7 @@ export declare class Redis implements Extension {
|
|
|
103
108
|
* Make sure to *not* listen for further changes, when there’s
|
|
104
109
|
* noone connected anymore.
|
|
105
110
|
*/
|
|
106
|
-
onDisconnect: ({
|
|
111
|
+
onDisconnect: ({ document, documentName }: onDisconnectPayload) => Promise<void>;
|
|
107
112
|
beforeBroadcastStateless(data: beforeBroadcastStatelessPayload): Promise<number>;
|
|
108
113
|
/**
|
|
109
114
|
* Kill the Redlock connection immediately.
|
|
@@ -77,6 +77,7 @@ export declare class HocuspocusProvider extends EventEmitter {
|
|
|
77
77
|
get document(): Y.Doc;
|
|
78
78
|
get awareness(): Awareness;
|
|
79
79
|
get hasUnsyncedChanges(): boolean;
|
|
80
|
+
updateUnsyncedChanges(unsyncedChanges?: number): void;
|
|
80
81
|
forceSync(): void;
|
|
81
82
|
boundBeforeUnload: () => void;
|
|
82
83
|
beforeUnload(): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CompleteHocuspocusProviderWebsocketConfiguration, HocuspocusProviderWebsocket } from './HocuspocusProviderWebsocket';
|
|
2
|
+
export type TiptapCollabProviderWebsocketConfiguration = Partial<CompleteHocuspocusProviderWebsocketConfiguration> & AdditionalTiptapCollabProviderWebsocketConfiguration;
|
|
3
|
+
export interface AdditionalTiptapCollabProviderWebsocketConfiguration {
|
|
4
|
+
/**
|
|
5
|
+
* A Hocuspocus Cloud App ID, get one here: https://collab.tiptap.dev
|
|
6
|
+
*/
|
|
7
|
+
appId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class TiptapCollabProviderWebsocket extends HocuspocusProviderWebsocket {
|
|
10
|
+
constructor(configuration: TiptapCollabProviderWebsocketConfiguration);
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hocuspocus/provider",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "hocuspocus provider",
|
|
5
5
|
"homepage": "https://hocuspocus.dev",
|
|
6
6
|
"keywords": [
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@hocuspocus/common": "^2.0.
|
|
31
|
+
"@hocuspocus/common": "^2.0.4",
|
|
32
32
|
"@lifeomic/attempt": "^3.0.2",
|
|
33
33
|
"lib0": "^0.2.47",
|
|
34
34
|
"ws": "^7.5.9"
|
|
@@ -232,10 +232,15 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
232
232
|
return this.configuration.awareness
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
get hasUnsyncedChanges() {
|
|
235
|
+
get hasUnsyncedChanges(): boolean {
|
|
236
236
|
return this.unsyncedChanges > 0
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
updateUnsyncedChanges(unsyncedChanges = 0) {
|
|
240
|
+
this.unsyncedChanges += unsyncedChanges
|
|
241
|
+
this.emit('unsyncedChanges', this.unsyncedChanges)
|
|
242
|
+
}
|
|
243
|
+
|
|
239
244
|
forceSync() {
|
|
240
245
|
this.send(SyncStepOneMessage, { document: this.document, documentName: this.configuration.name })
|
|
241
246
|
}
|
|
@@ -263,7 +268,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
263
268
|
return
|
|
264
269
|
}
|
|
265
270
|
|
|
266
|
-
this.
|
|
271
|
+
this.updateUnsyncedChanges(1)
|
|
267
272
|
this.send(UpdateMessage, { update, documentName: this.configuration.name }, true)
|
|
268
273
|
}
|
|
269
274
|
|
|
@@ -286,6 +291,10 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
286
291
|
return
|
|
287
292
|
}
|
|
288
293
|
|
|
294
|
+
if (state && this.unsyncedChanges > 0) {
|
|
295
|
+
this.updateUnsyncedChanges(-1 * this.unsyncedChanges)
|
|
296
|
+
}
|
|
297
|
+
|
|
289
298
|
this.isSynced = state
|
|
290
299
|
this.emit('synced', { state })
|
|
291
300
|
this.emit('sync', { state })
|
|
@@ -310,6 +319,8 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
310
319
|
}
|
|
311
320
|
|
|
312
321
|
async onOpen(event: Event) {
|
|
322
|
+
this.isAuthenticated = false
|
|
323
|
+
|
|
313
324
|
this.emit('open', { event })
|
|
314
325
|
|
|
315
326
|
if (this.isAuthenticationRequired) {
|
|
@@ -4,7 +4,7 @@ import * as url from 'lib0/url'
|
|
|
4
4
|
import type { MessageEvent } from 'ws'
|
|
5
5
|
import { retry } from '@lifeomic/attempt'
|
|
6
6
|
import {
|
|
7
|
-
Forbidden, Unauthorized, WsReadyStates,
|
|
7
|
+
Forbidden, MessageTooBig, Unauthorized, WsReadyStates,
|
|
8
8
|
} from '@hocuspocus/common'
|
|
9
9
|
import { Event } from 'ws'
|
|
10
10
|
import EventEmitter from './EventEmitter'
|
|
@@ -425,6 +425,11 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
+
if (event.code === MessageTooBig.code) {
|
|
429
|
+
console.warn(`[HocuspocusProvider] Connection closed with status MessageTooBig: ${event.reason}`)
|
|
430
|
+
this.shouldConnect = false
|
|
431
|
+
}
|
|
432
|
+
|
|
428
433
|
if (this.connectionAttempt) {
|
|
429
434
|
// That connection attempt failed.
|
|
430
435
|
this.rejectConnectionAttempt()
|
package/src/MessageReceiver.ts
CHANGED
|
@@ -2,9 +2,8 @@ import {
|
|
|
2
2
|
HocuspocusProvider,
|
|
3
3
|
HocuspocusProviderConfiguration,
|
|
4
4
|
} from './HocuspocusProvider'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from './HocuspocusProviderWebsocket'
|
|
5
|
+
|
|
6
|
+
import { TiptapCollabProviderWebsocket } from './TiptapCollabProviderWebsocket'
|
|
8
7
|
|
|
9
8
|
export type TiptapCollabProviderConfiguration =
|
|
10
9
|
Required<Pick<HocuspocusProviderConfiguration, 'name'>> &
|
|
@@ -21,11 +20,11 @@ export interface AdditionalTiptapCollabProviderConfiguration {
|
|
|
21
20
|
export class TiptapCollabProvider extends HocuspocusProvider {
|
|
22
21
|
constructor(configuration: TiptapCollabProviderConfiguration) {
|
|
23
22
|
if (!configuration.websocketProvider) {
|
|
24
|
-
configuration.websocketProvider = new
|
|
23
|
+
configuration.websocketProvider = new TiptapCollabProviderWebsocket({ appId: configuration.appId })
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
if (!configuration.token) {
|
|
28
|
-
configuration.token = 'notoken'
|
|
27
|
+
configuration.token = 'notoken' // need to send a token anyway (which will be ignored)
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
super(configuration as HocuspocusProviderConfiguration)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CompleteHocuspocusProviderWebsocketConfiguration,
|
|
3
|
+
HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration,
|
|
4
|
+
} from './HocuspocusProviderWebsocket'
|
|
5
|
+
|
|
6
|
+
export type TiptapCollabProviderWebsocketConfiguration =
|
|
7
|
+
Partial<CompleteHocuspocusProviderWebsocketConfiguration> &
|
|
8
|
+
AdditionalTiptapCollabProviderWebsocketConfiguration
|
|
9
|
+
|
|
10
|
+
export interface AdditionalTiptapCollabProviderWebsocketConfiguration {
|
|
11
|
+
/**
|
|
12
|
+
* A Hocuspocus Cloud App ID, get one here: https://collab.tiptap.dev
|
|
13
|
+
*/
|
|
14
|
+
appId: string,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class TiptapCollabProviderWebsocket extends HocuspocusProviderWebsocket {
|
|
18
|
+
constructor(configuration: TiptapCollabProviderWebsocketConfiguration) {
|
|
19
|
+
super({ ...configuration as HocuspocusProviderWebsocketConfiguration, url: `wss://${configuration.appId}.collab.tiptap.cloud` })
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { HocuspocusProvider, HocuspocusProviderConfiguration } from './HocuspocusProvider';
|
|
2
|
-
import { HocuspocusProviderWebsocketConfiguration } from './HocuspocusProviderWebsocket';
|
|
3
|
-
export type HocuspocusCloudProviderConfiguration = Required<Pick<HocuspocusProviderConfiguration, 'name'>> & Partial<HocuspocusProviderConfiguration> & Partial<Pick<HocuspocusProviderWebsocketConfiguration, 'url'>> & AdditionalHocuspocusCloudProviderConfiguration;
|
|
4
|
-
export interface AdditionalHocuspocusCloudProviderConfiguration {
|
|
5
|
-
/**
|
|
6
|
-
* A Hocuspocus Cloud key, get one here: https://hocuspocus.cloud/
|
|
7
|
-
*/
|
|
8
|
-
key: string;
|
|
9
|
-
}
|
|
10
|
-
export declare class HocuspocusCloudProvider extends HocuspocusProvider {
|
|
11
|
-
constructor(configuration: HocuspocusCloudProviderConfiguration);
|
|
12
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HocuspocusProvider,
|
|
3
|
-
HocuspocusProviderConfiguration,
|
|
4
|
-
} from './HocuspocusProvider'
|
|
5
|
-
import {
|
|
6
|
-
HocuspocusProviderWebsocket,
|
|
7
|
-
HocuspocusProviderWebsocketConfiguration,
|
|
8
|
-
} from './HocuspocusProviderWebsocket'
|
|
9
|
-
|
|
10
|
-
export type HocuspocusCloudProviderConfiguration =
|
|
11
|
-
Required<Pick<HocuspocusProviderConfiguration, 'name'>> &
|
|
12
|
-
Partial<HocuspocusProviderConfiguration> &
|
|
13
|
-
Partial<Pick<HocuspocusProviderWebsocketConfiguration, 'url'>> &
|
|
14
|
-
AdditionalHocuspocusCloudProviderConfiguration
|
|
15
|
-
|
|
16
|
-
export interface AdditionalHocuspocusCloudProviderConfiguration {
|
|
17
|
-
/**
|
|
18
|
-
* A Hocuspocus Cloud key, get one here: https://hocuspocus.cloud/
|
|
19
|
-
*/
|
|
20
|
-
key: string,
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export class HocuspocusCloudProvider extends HocuspocusProvider {
|
|
24
|
-
constructor(configuration: HocuspocusCloudProviderConfiguration) {
|
|
25
|
-
if (!configuration.url) {
|
|
26
|
-
configuration.url = 'wss://connect.hocuspocus.cloud'
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (configuration.key) {
|
|
30
|
-
if (!configuration.parameters) {
|
|
31
|
-
configuration.parameters = {}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
configuration.parameters.key = configuration.key
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
configuration.websocketProvider = new HocuspocusProviderWebsocket({ url: configuration.url })
|
|
38
|
-
|
|
39
|
-
super(configuration as HocuspocusProviderConfiguration)
|
|
40
|
-
}
|
|
41
|
-
}
|