@hocuspocus/provider 2.15.2 → 3.0.4-rc.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 +931 -1532
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +931 -1527
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/packages/extension-database/src/Database.d.ts +1 -1
- package/dist/packages/extension-logger/src/Logger.d.ts +1 -1
- package/dist/packages/extension-redis/src/Redis.d.ts +4 -3
- package/dist/packages/extension-sqlite/src/SQLite.d.ts +2 -1
- package/dist/packages/extension-throttle/src/index.d.ts +2 -2
- package/dist/packages/extension-webhook/src/index.d.ts +3 -3
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +12 -45
- package/dist/packages/provider/src/HocuspocusProviderWebsocket.d.ts +5 -9
- package/dist/packages/provider/src/IncomingMessage.d.ts +3 -3
- package/dist/packages/provider/src/MessageReceiver.d.ts +2 -4
- package/dist/packages/provider/src/MessageSender.d.ts +2 -2
- package/dist/packages/provider/src/OutgoingMessage.d.ts +2 -2
- package/dist/packages/provider/src/OutgoingMessages/AuthenticationMessage.d.ts +2 -1
- package/dist/packages/provider/src/OutgoingMessages/AwarenessMessage.d.ts +2 -1
- package/dist/packages/provider/src/OutgoingMessages/CloseMessage.d.ts +2 -1
- package/dist/packages/provider/src/OutgoingMessages/QueryAwarenessMessage.d.ts +2 -1
- package/dist/packages/provider/src/OutgoingMessages/StatelessMessage.d.ts +2 -1
- package/dist/packages/provider/src/OutgoingMessages/SyncStepOneMessage.d.ts +2 -1
- package/dist/packages/provider/src/OutgoingMessages/SyncStepTwoMessage.d.ts +2 -1
- package/dist/packages/provider/src/OutgoingMessages/UpdateMessage.d.ts +2 -1
- package/dist/packages/provider/src/index.d.ts +0 -2
- package/dist/packages/provider/src/types.d.ts +12 -12
- package/dist/packages/server/src/ClientConnection.d.ts +19 -10
- package/dist/packages/server/src/Connection.d.ts +7 -23
- package/dist/packages/server/src/DirectConnection.d.ts +2 -2
- package/dist/packages/server/src/Document.d.ts +3 -7
- package/dist/packages/server/src/Hocuspocus.d.ts +7 -36
- package/dist/packages/server/src/IncomingMessage.d.ts +3 -3
- package/dist/packages/server/src/MessageReceiver.d.ts +4 -6
- package/dist/packages/server/src/OutgoingMessage.d.ts +4 -3
- package/dist/packages/server/src/Server.d.ts +23 -3
- package/dist/packages/server/src/index.d.ts +1 -1
- package/dist/packages/server/src/types.d.ts +15 -29
- package/dist/packages/server/src/util/getParameters.d.ts +1 -1
- package/dist/packages/transformer/src/Prosemirror.d.ts +1 -1
- package/dist/packages/transformer/src/Tiptap.d.ts +3 -3
- package/dist/packages/transformer/src/types.d.ts +1 -1
- package/dist/tests/utils/newHocuspocus.d.ts +2 -2
- package/dist/tests/utils/newHocuspocusProvider.d.ts +2 -2
- package/dist/tests/utils/newHocuspocusProviderWebsocket.d.ts +4 -3
- package/dist/tests/utils/retryableAssertion.d.ts +1 -1
- package/package.json +2 -2
- package/src/EventEmitter.ts +3 -1
- package/src/HocuspocusProvider.ts +74 -200
- package/src/HocuspocusProviderWebsocket.ts +24 -75
- package/src/IncomingMessage.ts +5 -3
- package/src/MessageReceiver.ts +20 -19
- package/src/MessageSender.ts +3 -2
- package/src/OutgoingMessage.ts +3 -2
- package/src/OutgoingMessages/AuthenticationMessage.ts +2 -1
- package/src/OutgoingMessages/AwarenessMessage.ts +2 -1
- package/src/OutgoingMessages/CloseMessage.ts +2 -1
- package/src/OutgoingMessages/QueryAwarenessMessage.ts +2 -1
- package/src/OutgoingMessages/StatelessMessage.ts +2 -1
- package/src/OutgoingMessages/SyncStepOneMessage.ts +2 -1
- package/src/OutgoingMessages/SyncStepTwoMessage.ts +2 -1
- package/src/OutgoingMessages/UpdateMessage.ts +2 -1
- package/src/index.ts +0 -2
- package/src/types.ts +12 -12
- package/dist/packages/provider/src/TiptapCollabProvider.d.ts +0 -161
- package/dist/packages/provider/src/TiptapCollabProviderWebsocket.d.ts +0 -19
- package/dist/packages/server/src/Debugger.d.ts +0 -14
- package/dist/tests/server/getMessageLogs.d.ts +0 -1
- package/dist/tests/server/requiresAuthentication.d.ts +0 -1
- package/src/TiptapCollabProvider.ts +0 -505
- package/src/TiptapCollabProviderWebsocket.ts +0 -38
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { awarenessStatesToArray } from '@hocuspocus/common'
|
|
2
|
-
import
|
|
3
|
-
import * as mutex from 'lib0/mutex'
|
|
4
|
-
import type { CloseEvent, Event, MessageEvent } from 'ws'
|
|
2
|
+
import type { Event, MessageEvent } from 'ws'
|
|
5
3
|
import { Awareness, removeAwarenessStates } from 'y-protocols/awareness'
|
|
6
4
|
import * as Y from 'yjs'
|
|
7
5
|
import EventEmitter from './EventEmitter.js'
|
|
6
|
+
import type {
|
|
7
|
+
CompleteHocuspocusProviderWebsocketConfiguration} from './HocuspocusProviderWebsocket.js'
|
|
8
8
|
import {
|
|
9
|
-
CompleteHocuspocusProviderWebsocketConfiguration,
|
|
10
9
|
HocuspocusProviderWebsocket,
|
|
11
10
|
} from './HocuspocusProviderWebsocket.js'
|
|
12
11
|
import { IncomingMessage } from './IncomingMessage.js'
|
|
@@ -14,15 +13,11 @@ import { MessageReceiver } from './MessageReceiver.js'
|
|
|
14
13
|
import { MessageSender } from './MessageSender.js'
|
|
15
14
|
import { AuthenticationMessage } from './OutgoingMessages/AuthenticationMessage.js'
|
|
16
15
|
import { AwarenessMessage } from './OutgoingMessages/AwarenessMessage.js'
|
|
17
|
-
import { CloseMessage } from './OutgoingMessages/CloseMessage.js'
|
|
18
|
-
import { QueryAwarenessMessage } from './OutgoingMessages/QueryAwarenessMessage.js'
|
|
19
16
|
import { StatelessMessage } from './OutgoingMessages/StatelessMessage.js'
|
|
20
17
|
import { SyncStepOneMessage } from './OutgoingMessages/SyncStepOneMessage.js'
|
|
21
|
-
import { SyncStepTwoMessage } from './OutgoingMessages/SyncStepTwoMessage.js'
|
|
22
18
|
import { UpdateMessage } from './OutgoingMessages/UpdateMessage.js'
|
|
23
|
-
import {
|
|
19
|
+
import type {
|
|
24
20
|
ConstructableOutgoingMessage,
|
|
25
|
-
WebSocketStatus,
|
|
26
21
|
onAuthenticationFailedParameters,
|
|
27
22
|
onAwarenessChangeParameters,
|
|
28
23
|
onAwarenessUpdateParameters,
|
|
@@ -31,7 +26,6 @@ import {
|
|
|
31
26
|
onMessageParameters,
|
|
32
27
|
onOpenParameters,
|
|
33
28
|
onOutgoingMessageParameters, onStatelessParameters,
|
|
34
|
-
onStatusParameters,
|
|
35
29
|
onSyncedParameters,
|
|
36
30
|
} from './types.js'
|
|
37
31
|
|
|
@@ -52,10 +46,6 @@ export interface CompleteHocuspocusProviderConfiguration {
|
|
|
52
46
|
*/
|
|
53
47
|
document: Y.Doc,
|
|
54
48
|
|
|
55
|
-
/**
|
|
56
|
-
* Pass false to disable broadcasting between browser tabs.
|
|
57
|
-
*/
|
|
58
|
-
broadcast: boolean,
|
|
59
49
|
/**
|
|
60
50
|
* An Awareness instance to keep the presence state of all clients.
|
|
61
51
|
*
|
|
@@ -65,18 +55,17 @@ export interface CompleteHocuspocusProviderConfiguration {
|
|
|
65
55
|
* socket connection, or ensure that the Provider receives messages before running into `HocuspocusProviderWebsocket.messageReconnectTimeout`.
|
|
66
56
|
*/
|
|
67
57
|
awareness: Awareness | null,
|
|
58
|
+
|
|
68
59
|
/**
|
|
69
60
|
* A token that’s sent to the backend for authentication purposes.
|
|
70
61
|
*/
|
|
71
62
|
token: string | (() => string) | (() => Promise<string>) | null,
|
|
72
|
-
|
|
73
|
-
* URL parameters that should be added.
|
|
74
|
-
*/
|
|
75
|
-
parameters: { [key: string]: any },
|
|
63
|
+
|
|
76
64
|
/**
|
|
77
65
|
* Hocuspocus websocket provider
|
|
78
66
|
*/
|
|
79
67
|
websocketProvider: HocuspocusProviderWebsocket,
|
|
68
|
+
|
|
80
69
|
/**
|
|
81
70
|
* Force syncing the document in the defined interval.
|
|
82
71
|
*/
|
|
@@ -88,7 +77,6 @@ export interface CompleteHocuspocusProviderConfiguration {
|
|
|
88
77
|
onConnect: () => void,
|
|
89
78
|
onMessage: (data: onMessageParameters) => void,
|
|
90
79
|
onOutgoingMessage: (data: onOutgoingMessageParameters) => void,
|
|
91
|
-
onStatus: (data: onStatusParameters) => void,
|
|
92
80
|
onSynced: (data: onSyncedParameters) => void,
|
|
93
81
|
onDisconnect: (data: onDisconnectParameters) => void,
|
|
94
82
|
onClose: (data: onCloseParameters) => void,
|
|
@@ -96,21 +84,6 @@ export interface CompleteHocuspocusProviderConfiguration {
|
|
|
96
84
|
onAwarenessUpdate: (data: onAwarenessUpdateParameters) => void,
|
|
97
85
|
onAwarenessChange: (data: onAwarenessChangeParameters) => void,
|
|
98
86
|
onStateless: (data: onStatelessParameters) => void
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Don’t output any warnings.
|
|
102
|
-
*/
|
|
103
|
-
quiet: boolean,
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Pass `false` to start the connection manually.
|
|
107
|
-
*/
|
|
108
|
-
connect: boolean,
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Pass `false` to close the connection manually.
|
|
112
|
-
*/
|
|
113
|
-
preserveConnection: boolean,
|
|
114
87
|
}
|
|
115
88
|
|
|
116
89
|
export class AwarenessError extends Error {
|
|
@@ -125,8 +98,6 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
125
98
|
// @ts-ignore
|
|
126
99
|
awareness: undefined,
|
|
127
100
|
token: null,
|
|
128
|
-
parameters: {},
|
|
129
|
-
broadcast: true,
|
|
130
101
|
forceSyncInterval: false,
|
|
131
102
|
onAuthenticated: () => null,
|
|
132
103
|
onAuthenticationFailed: () => null,
|
|
@@ -134,7 +105,6 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
134
105
|
onConnect: () => null,
|
|
135
106
|
onMessage: () => null,
|
|
136
107
|
onOutgoingMessage: () => null,
|
|
137
|
-
onStatus: () => null,
|
|
138
108
|
onSynced: () => null,
|
|
139
109
|
onDisconnect: () => null,
|
|
140
110
|
onClose: () => null,
|
|
@@ -142,31 +112,25 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
142
112
|
onAwarenessUpdate: () => null,
|
|
143
113
|
onAwarenessChange: () => null,
|
|
144
114
|
onStateless: () => null,
|
|
145
|
-
quiet: false,
|
|
146
|
-
connect: true,
|
|
147
|
-
preserveConnection: true,
|
|
148
115
|
}
|
|
149
116
|
|
|
150
|
-
subscribedToBroadcastChannel = false
|
|
151
|
-
|
|
152
117
|
isSynced = false
|
|
153
118
|
|
|
154
119
|
unsyncedChanges = 0
|
|
155
120
|
|
|
156
|
-
status = WebSocketStatus.Disconnected
|
|
157
|
-
|
|
158
121
|
isAuthenticated = false
|
|
159
122
|
|
|
160
123
|
authorizedScope: string | undefined = undefined
|
|
161
124
|
|
|
162
|
-
|
|
125
|
+
// @internal
|
|
126
|
+
manageSocket = false
|
|
127
|
+
|
|
128
|
+
private isAttached = false
|
|
163
129
|
|
|
164
130
|
intervals: any = {
|
|
165
131
|
forceSync: null,
|
|
166
132
|
}
|
|
167
133
|
|
|
168
|
-
isConnected = true
|
|
169
|
-
|
|
170
134
|
constructor(configuration: HocuspocusProviderConfiguration) {
|
|
171
135
|
super()
|
|
172
136
|
this.setConfiguration(configuration)
|
|
@@ -186,24 +150,6 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
186
150
|
this.on('authenticated', this.configuration.onAuthenticated)
|
|
187
151
|
this.on('authenticationFailed', this.configuration.onAuthenticationFailed)
|
|
188
152
|
|
|
189
|
-
this.configuration.websocketProvider.on('connect', this.configuration.onConnect)
|
|
190
|
-
this.configuration.websocketProvider.on('connect', this.forwardConnect)
|
|
191
|
-
|
|
192
|
-
this.configuration.websocketProvider.on('open', this.boundOnOpen)
|
|
193
|
-
this.configuration.websocketProvider.on('open', this.forwardOpen)
|
|
194
|
-
|
|
195
|
-
this.configuration.websocketProvider.on('close', this.boundOnClose)
|
|
196
|
-
this.configuration.websocketProvider.on('close', this.configuration.onClose)
|
|
197
|
-
this.configuration.websocketProvider.on('close', this.forwardClose)
|
|
198
|
-
|
|
199
|
-
this.configuration.websocketProvider.on('status', this.boundOnStatus)
|
|
200
|
-
|
|
201
|
-
this.configuration.websocketProvider.on('disconnect', this.configuration.onDisconnect)
|
|
202
|
-
this.configuration.websocketProvider.on('disconnect', this.forwardDisconnect)
|
|
203
|
-
|
|
204
|
-
this.configuration.websocketProvider.on('destroy', this.configuration.onDestroy)
|
|
205
|
-
this.configuration.websocketProvider.on('destroy', this.forwardDestroy)
|
|
206
|
-
|
|
207
153
|
this.awareness?.on('update', () => {
|
|
208
154
|
this.emit('awarenessUpdate', { states: awarenessStatesToArray(this.awareness!.getStates()) })
|
|
209
155
|
})
|
|
@@ -214,6 +160,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
214
160
|
|
|
215
161
|
this.document.on('update', this.boundDocumentUpdateHandler)
|
|
216
162
|
this.awareness?.on('update', this.boundAwarenessUpdateHandler)
|
|
163
|
+
|
|
217
164
|
this.registerEventListeners()
|
|
218
165
|
|
|
219
166
|
if (
|
|
@@ -226,26 +173,24 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
226
173
|
)
|
|
227
174
|
}
|
|
228
175
|
|
|
229
|
-
this.
|
|
176
|
+
if( this.manageSocket ) {
|
|
177
|
+
this.attach()
|
|
178
|
+
}
|
|
230
179
|
}
|
|
231
180
|
|
|
232
181
|
boundDocumentUpdateHandler = this.documentUpdateHandler.bind(this)
|
|
233
182
|
|
|
234
183
|
boundAwarenessUpdateHandler = this.awarenessUpdateHandler.bind(this)
|
|
235
184
|
|
|
236
|
-
boundBroadcastChannelSubscriber = this.broadcastChannelSubscriber.bind(this)
|
|
237
|
-
|
|
238
185
|
boundPageHide = this.pageHide.bind(this)
|
|
239
186
|
|
|
240
187
|
boundOnOpen = this.onOpen.bind(this)
|
|
241
188
|
|
|
242
189
|
boundOnClose = this.onClose.bind(this)
|
|
243
190
|
|
|
244
|
-
boundOnStatus = this.onStatus.bind(this)
|
|
245
|
-
|
|
246
191
|
forwardConnect = (e: any) => this.emit('connect', e)
|
|
247
192
|
|
|
248
|
-
forwardOpen = (e: any) => this.emit('open', e)
|
|
193
|
+
// forwardOpen = (e: any) => this.emit('open', e)
|
|
249
194
|
|
|
250
195
|
forwardClose = (e: any) => this.emit('close', e)
|
|
251
196
|
|
|
@@ -253,21 +198,12 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
253
198
|
|
|
254
199
|
forwardDestroy = (e: any) => this.emit('destroy', e)
|
|
255
200
|
|
|
256
|
-
public onStatus({ status } : onStatusParameters) {
|
|
257
|
-
this.status = status
|
|
258
|
-
|
|
259
|
-
this.configuration.onStatus({ status })
|
|
260
|
-
this.emit('status', { status })
|
|
261
|
-
}
|
|
262
|
-
|
|
263
201
|
public setConfiguration(configuration: Partial<HocuspocusProviderConfiguration> = {}): void {
|
|
264
|
-
if (!configuration.websocketProvider
|
|
202
|
+
if (!configuration.websocketProvider) {
|
|
265
203
|
const websocketProviderConfig = configuration as CompleteHocuspocusProviderWebsocketConfiguration
|
|
266
|
-
|
|
204
|
+
this.manageSocket = true
|
|
267
205
|
this.configuration.websocketProvider = new HocuspocusProviderWebsocket({
|
|
268
206
|
url: websocketProviderConfig.url,
|
|
269
|
-
connect: websocketProviderConfig.connect,
|
|
270
|
-
parameters: websocketProviderConfig.parameters,
|
|
271
207
|
})
|
|
272
208
|
}
|
|
273
209
|
|
|
@@ -297,10 +233,14 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
297
233
|
}
|
|
298
234
|
|
|
299
235
|
decrementUnsyncedChanges() {
|
|
300
|
-
this.unsyncedChanges
|
|
236
|
+
if( this.unsyncedChanges > 0 ) {
|
|
237
|
+
this.unsyncedChanges -= 1
|
|
238
|
+
}
|
|
239
|
+
|
|
301
240
|
if (this.unsyncedChanges === 0) {
|
|
302
241
|
this.synced = true
|
|
303
242
|
}
|
|
243
|
+
|
|
304
244
|
this.emit('unsyncedChanges', this.unsyncedChanges)
|
|
305
245
|
}
|
|
306
246
|
|
|
@@ -334,7 +274,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
334
274
|
}
|
|
335
275
|
|
|
336
276
|
this.incrementUnsyncedChanges()
|
|
337
|
-
this.send(UpdateMessage, { update, documentName: this.configuration.name }
|
|
277
|
+
this.send(UpdateMessage, { update, documentName: this.configuration.name })
|
|
338
278
|
}
|
|
339
279
|
|
|
340
280
|
awarenessUpdateHandler({ added, updated, removed }: any, origin: any) {
|
|
@@ -344,7 +284,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
344
284
|
awareness: this.awareness,
|
|
345
285
|
clients: changedClients,
|
|
346
286
|
documentName: this.configuration.name,
|
|
347
|
-
}
|
|
287
|
+
})
|
|
348
288
|
}
|
|
349
289
|
|
|
350
290
|
/**
|
|
@@ -363,43 +303,27 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
363
303
|
}
|
|
364
304
|
|
|
365
305
|
this.isSynced = state
|
|
366
|
-
|
|
367
|
-
|
|
306
|
+
|
|
307
|
+
if( state ) {
|
|
308
|
+
this.emit('synced', { state })
|
|
309
|
+
}
|
|
368
310
|
}
|
|
369
311
|
|
|
370
312
|
receiveStateless(payload: string) {
|
|
371
313
|
this.emit('stateless', { payload })
|
|
372
314
|
}
|
|
373
315
|
|
|
374
|
-
get isAuthenticationRequired(): boolean {
|
|
375
|
-
return !!this.configuration.token && !this.isAuthenticated
|
|
376
|
-
}
|
|
377
|
-
|
|
378
316
|
// not needed, but provides backward compatibility with e.g. lexical/yjs
|
|
379
317
|
async connect() {
|
|
380
|
-
|
|
381
|
-
this.subscribeToBroadcastChannel()
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
this.configuration.websocketProvider.shouldConnect = true
|
|
385
|
-
|
|
386
|
-
return this.configuration.websocketProvider.attach(this)
|
|
318
|
+
console.warn('HocuspocusProvider::connect() is deprecated and does not do anything. Please connect/disconnect on the websocketProvider, or attach/deattach providers.')
|
|
387
319
|
}
|
|
388
320
|
|
|
389
321
|
disconnect() {
|
|
390
|
-
|
|
391
|
-
this.configuration.websocketProvider.detach(this)
|
|
392
|
-
this.isConnected = false
|
|
393
|
-
|
|
394
|
-
if (!this.configuration.preserveConnection) {
|
|
395
|
-
this.configuration.websocketProvider.disconnect()
|
|
396
|
-
}
|
|
397
|
-
|
|
322
|
+
console.warn('HocuspocusProvider::disconnect() is deprecated and does not do anything. Please connect/disconnect on the websocketProvider, or attach/deattach providers.')
|
|
398
323
|
}
|
|
399
324
|
|
|
400
325
|
async onOpen(event: Event) {
|
|
401
326
|
this.isAuthenticated = false
|
|
402
|
-
this.isConnected = true
|
|
403
327
|
|
|
404
328
|
this.emit('open', { event })
|
|
405
329
|
|
|
@@ -411,12 +335,10 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
411
335
|
return
|
|
412
336
|
}
|
|
413
337
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
})
|
|
419
|
-
}
|
|
338
|
+
this.send(AuthenticationMessage, {
|
|
339
|
+
token: token ?? '',
|
|
340
|
+
documentName: this.configuration.name,
|
|
341
|
+
})
|
|
420
342
|
|
|
421
343
|
this.startSync()
|
|
422
344
|
}
|
|
@@ -444,15 +366,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
444
366
|
}
|
|
445
367
|
}
|
|
446
368
|
|
|
447
|
-
send(message: ConstructableOutgoingMessage, args: any
|
|
448
|
-
if (!this.isConnected) {
|
|
449
|
-
return
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
if (broadcast) {
|
|
453
|
-
this.mux(() => { this.broadcast(message, args) })
|
|
454
|
-
}
|
|
455
|
-
|
|
369
|
+
send(message: ConstructableOutgoingMessage, args: any) {
|
|
456
370
|
const messageSender = new MessageSender(message, args)
|
|
457
371
|
|
|
458
372
|
this.emit('outgoingMessage', { message: messageSender.message })
|
|
@@ -471,7 +385,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
471
385
|
new MessageReceiver(message).apply(this, true)
|
|
472
386
|
}
|
|
473
387
|
|
|
474
|
-
onClose(
|
|
388
|
+
onClose() {
|
|
475
389
|
this.isAuthenticated = false
|
|
476
390
|
this.synced = false
|
|
477
391
|
|
|
@@ -502,109 +416,69 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
502
416
|
|
|
503
417
|
this.removeAllListeners()
|
|
504
418
|
|
|
419
|
+
this.detach()
|
|
420
|
+
|
|
421
|
+
if( this.manageSocket ) {
|
|
422
|
+
this.configuration.websocketProvider.destroy()
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (typeof window === 'undefined' || !('removeEventListener' in window)) {
|
|
426
|
+
return
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
window.removeEventListener('pagehide', this.boundPageHide)
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
detach() {
|
|
505
433
|
this.configuration.websocketProvider.off('connect', this.configuration.onConnect)
|
|
506
434
|
this.configuration.websocketProvider.off('connect', this.forwardConnect)
|
|
507
435
|
this.configuration.websocketProvider.off('open', this.boundOnOpen)
|
|
508
|
-
this.configuration.websocketProvider.off('open', this.forwardOpen)
|
|
509
436
|
this.configuration.websocketProvider.off('close', this.boundOnClose)
|
|
510
437
|
this.configuration.websocketProvider.off('close', this.configuration.onClose)
|
|
511
438
|
this.configuration.websocketProvider.off('close', this.forwardClose)
|
|
512
|
-
this.configuration.websocketProvider.off('status', this.boundOnStatus)
|
|
513
439
|
this.configuration.websocketProvider.off('disconnect', this.configuration.onDisconnect)
|
|
514
440
|
this.configuration.websocketProvider.off('disconnect', this.forwardDisconnect)
|
|
515
441
|
this.configuration.websocketProvider.off('destroy', this.configuration.onDestroy)
|
|
516
442
|
this.configuration.websocketProvider.off('destroy', this.forwardDestroy)
|
|
517
443
|
|
|
518
|
-
this.
|
|
519
|
-
this.disconnect()
|
|
520
|
-
|
|
521
|
-
if (typeof window === 'undefined' || !('removeEventListener' in window)) {
|
|
522
|
-
return
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
window.removeEventListener('pagehide', this.boundPageHide)
|
|
526
|
-
}
|
|
444
|
+
this.configuration.websocketProvider.detach(this)
|
|
527
445
|
|
|
528
|
-
|
|
529
|
-
this.emit('authenticationFailed', { reason })
|
|
530
|
-
this.isAuthenticated = false
|
|
531
|
-
this.disconnect()
|
|
532
|
-
this.status = WebSocketStatus.Disconnected
|
|
446
|
+
this.isAttached = false
|
|
533
447
|
}
|
|
534
448
|
|
|
535
|
-
|
|
536
|
-
this.
|
|
537
|
-
this.authorizedScope = scope
|
|
538
|
-
|
|
539
|
-
this.emit('authenticated')
|
|
540
|
-
}
|
|
449
|
+
attach() {
|
|
450
|
+
if( this.isAttached ) return
|
|
541
451
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
}
|
|
452
|
+
this.configuration.websocketProvider.on('connect', this.configuration.onConnect)
|
|
453
|
+
this.configuration.websocketProvider.on('connect', this.forwardConnect)
|
|
545
454
|
|
|
546
|
-
|
|
547
|
-
this.mux(() => {
|
|
548
|
-
const message = new IncomingMessage(data)
|
|
455
|
+
this.configuration.websocketProvider.on('open', this.boundOnOpen)
|
|
549
456
|
|
|
550
|
-
|
|
457
|
+
this.configuration.websocketProvider.on('close', this.boundOnClose)
|
|
458
|
+
this.configuration.websocketProvider.on('close', this.configuration.onClose)
|
|
459
|
+
this.configuration.websocketProvider.on('close', this.forwardClose)
|
|
551
460
|
|
|
552
|
-
|
|
461
|
+
this.configuration.websocketProvider.on('disconnect', this.configuration.onDisconnect)
|
|
462
|
+
this.configuration.websocketProvider.on('disconnect', this.forwardDisconnect)
|
|
553
463
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
.apply(this, false)
|
|
557
|
-
})
|
|
558
|
-
}
|
|
464
|
+
this.configuration.websocketProvider.on('destroy', this.configuration.onDestroy)
|
|
465
|
+
this.configuration.websocketProvider.on('destroy', this.forwardDestroy)
|
|
559
466
|
|
|
560
|
-
|
|
561
|
-
if (!this.subscribedToBroadcastChannel) {
|
|
562
|
-
bc.subscribe(this.broadcastChannel, this.boundBroadcastChannelSubscriber)
|
|
563
|
-
this.subscribedToBroadcastChannel = true
|
|
564
|
-
}
|
|
467
|
+
this.configuration.websocketProvider.attach(this)
|
|
565
468
|
|
|
566
|
-
this.
|
|
567
|
-
this.broadcast(SyncStepOneMessage, { document: this.document, documentName: this.configuration.name })
|
|
568
|
-
this.broadcast(SyncStepTwoMessage, { document: this.document, documentName: this.configuration.name })
|
|
569
|
-
this.broadcast(QueryAwarenessMessage, { document: this.document, documentName: this.configuration.name })
|
|
570
|
-
if (this.awareness) {
|
|
571
|
-
this.broadcast(AwarenessMessage, {
|
|
572
|
-
awareness: this.awareness,
|
|
573
|
-
clients: [this.document.clientID],
|
|
574
|
-
document: this.document,
|
|
575
|
-
documentName: this.configuration.name,
|
|
576
|
-
})
|
|
577
|
-
}
|
|
578
|
-
})
|
|
469
|
+
this.isAttached = true
|
|
579
470
|
}
|
|
580
471
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
this.send(AwarenessMessage, {
|
|
585
|
-
awareness: this.awareness,
|
|
586
|
-
clients: [this.document.clientID],
|
|
587
|
-
states: new Map(),
|
|
588
|
-
documentName: this.configuration.name,
|
|
589
|
-
}, true)
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
if (this.subscribedToBroadcastChannel) {
|
|
593
|
-
bc.unsubscribe(this.broadcastChannel, this.boundBroadcastChannelSubscriber)
|
|
594
|
-
this.subscribedToBroadcastChannel = false
|
|
595
|
-
}
|
|
472
|
+
permissionDeniedHandler(reason: string) {
|
|
473
|
+
this.emit('authenticationFailed', { reason })
|
|
474
|
+
this.isAuthenticated = false
|
|
596
475
|
}
|
|
597
476
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
if (!this.subscribedToBroadcastChannel) {
|
|
604
|
-
return
|
|
605
|
-
}
|
|
477
|
+
authenticatedHandler(scope: string) {
|
|
478
|
+
this.isAuthenticated = true
|
|
479
|
+
this.authorizedScope = scope
|
|
606
480
|
|
|
607
|
-
|
|
481
|
+
this.emit('authenticated')
|
|
608
482
|
}
|
|
609
483
|
|
|
610
484
|
setAwarenessField(key: string, value: any) {
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
WsReadyStates,
|
|
3
3
|
} from '@hocuspocus/common'
|
|
4
4
|
import { retry } from '@lifeomic/attempt'
|
|
5
5
|
import * as time from 'lib0/time'
|
|
6
6
|
import * as url from 'lib0/url'
|
|
7
|
-
import type { MessageEvent } from 'ws'
|
|
8
|
-
import { Event } from 'ws'
|
|
7
|
+
import type { MessageEvent , Event } from 'ws'
|
|
9
8
|
import EventEmitter from './EventEmitter.js'
|
|
10
|
-
import { HocuspocusProvider } from './HocuspocusProvider.js'
|
|
9
|
+
import type { HocuspocusProvider } from './HocuspocusProvider.js'
|
|
10
|
+
import type {
|
|
11
|
+
onAwarenessChangeParameters, onAwarenessUpdateParameters,
|
|
12
|
+
onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatusParameters} from './types.js'
|
|
11
13
|
import {
|
|
12
14
|
WebSocketStatus,
|
|
13
|
-
onAwarenessChangeParameters, onAwarenessUpdateParameters,
|
|
14
|
-
onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatusParameters,
|
|
15
15
|
} from './types.js'
|
|
16
16
|
import { IncomingMessage } from './IncomingMessage.js'
|
|
17
|
+
import {CloseMessage} from "./OutgoingMessages/CloseMessage.js"
|
|
17
18
|
|
|
18
19
|
export type HocusPocusWebSocket = WebSocket & { identifier: string };
|
|
19
20
|
|
|
@@ -87,10 +88,6 @@ export interface CompleteHocuspocusProviderWebsocketConfiguration {
|
|
|
87
88
|
onDestroy: () => void,
|
|
88
89
|
onAwarenessUpdate: (data: onAwarenessUpdateParameters) => void,
|
|
89
90
|
onAwarenessChange: (data: onAwarenessChangeParameters) => void,
|
|
90
|
-
/**
|
|
91
|
-
* Don’t output any warnings.
|
|
92
|
-
*/
|
|
93
|
-
quiet: boolean,
|
|
94
91
|
|
|
95
92
|
/**
|
|
96
93
|
* Map of attached providers keyed by documentName.
|
|
@@ -138,7 +135,6 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
138
135
|
onDestroy: () => null,
|
|
139
136
|
onAwarenessUpdate: () => null,
|
|
140
137
|
onAwarenessChange: () => null,
|
|
141
|
-
quiet: false,
|
|
142
138
|
providerMap: new Map(),
|
|
143
139
|
}
|
|
144
140
|
|
|
@@ -155,7 +151,6 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
155
151
|
identifier = 0
|
|
156
152
|
|
|
157
153
|
intervals: any = {
|
|
158
|
-
forceSync: null,
|
|
159
154
|
connectionChecker: null,
|
|
160
155
|
}
|
|
161
156
|
|
|
@@ -209,6 +204,7 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
209
204
|
receivedOnStatusPayload?: onStatusParameters | undefined = undefined
|
|
210
205
|
|
|
211
206
|
async onOpen(event: Event) {
|
|
207
|
+
this.cancelWebsocketRetry = undefined
|
|
212
208
|
this.receivedOnOpenPayload = event
|
|
213
209
|
}
|
|
214
210
|
|
|
@@ -227,16 +223,13 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
227
223
|
if (this.receivedOnOpenPayload) {
|
|
228
224
|
provider.onOpen(this.receivedOnOpenPayload)
|
|
229
225
|
}
|
|
230
|
-
|
|
231
|
-
if (this.receivedOnStatusPayload) {
|
|
232
|
-
provider.onStatus(this.receivedOnStatusPayload)
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return connectPromise
|
|
236
226
|
}
|
|
237
227
|
|
|
238
228
|
detach(provider: HocuspocusProvider) {
|
|
239
|
-
this.configuration.providerMap.
|
|
229
|
+
if( this.configuration.providerMap.has(provider.configuration.name )) {
|
|
230
|
+
provider.send(CloseMessage, { documentName: provider.configuration.name })
|
|
231
|
+
this.configuration.providerMap.delete(provider.configuration.name)
|
|
232
|
+
}
|
|
240
233
|
}
|
|
241
234
|
|
|
242
235
|
public setConfiguration(
|
|
@@ -301,6 +294,7 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
301
294
|
return retryPromise
|
|
302
295
|
}
|
|
303
296
|
|
|
297
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
304
298
|
attachWebSocketListeners(ws: HocusPocusWebSocket, reject: Function) {
|
|
305
299
|
const { identifier } = ws
|
|
306
300
|
const onMessageHandler = (payload: any) => this.emit('message', payload)
|
|
@@ -442,7 +436,7 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
442
436
|
}
|
|
443
437
|
}
|
|
444
438
|
|
|
445
|
-
// Ensure that the URL
|
|
439
|
+
// Ensure that the URL never ends with /
|
|
446
440
|
get serverUrl() {
|
|
447
441
|
while (this.configuration.url[this.configuration.url.length - 1] === '/') {
|
|
448
442
|
return this.configuration.url.slice(0, this.configuration.url.length - 1)
|
|
@@ -467,8 +461,8 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
467
461
|
try {
|
|
468
462
|
this.webSocket.close()
|
|
469
463
|
this.messageQueue = []
|
|
470
|
-
} catch {
|
|
471
|
-
|
|
464
|
+
} catch(e) {
|
|
465
|
+
console.error(e)
|
|
472
466
|
}
|
|
473
467
|
}
|
|
474
468
|
|
|
@@ -484,73 +478,28 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
484
478
|
this.closeTries = 0
|
|
485
479
|
this.cleanupWebSocket()
|
|
486
480
|
|
|
487
|
-
if (this.status === WebSocketStatus.Connected) {
|
|
488
|
-
this.status = WebSocketStatus.Disconnected
|
|
489
|
-
this.emit('status', { status: WebSocketStatus.Disconnected })
|
|
490
|
-
this.emit('disconnect', { event })
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
if (event.code === Unauthorized.code) {
|
|
494
|
-
if (event.reason === Unauthorized.reason) {
|
|
495
|
-
console.warn(
|
|
496
|
-
'[HocuspocusProvider] An authentication token is required, but you didn’t send one. Try adding a `token` to your HocuspocusProvider configuration. Won’t try again.',
|
|
497
|
-
)
|
|
498
|
-
} else {
|
|
499
|
-
console.warn(
|
|
500
|
-
`[HocuspocusProvider] Connection closed with status Unauthorized: ${event.reason}`,
|
|
501
|
-
)
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
this.shouldConnect = false
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
if (event.code === Forbidden.code) {
|
|
508
|
-
if (!this.configuration.quiet) {
|
|
509
|
-
console.warn(
|
|
510
|
-
'[HocuspocusProvider] The provided authentication token isn’t allowed to connect to this server. Will try again.',
|
|
511
|
-
)
|
|
512
|
-
return // TODO REMOVE ME
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
if (event.code === MessageTooBig.code) {
|
|
517
|
-
console.warn(
|
|
518
|
-
`[HocuspocusProvider] Connection closed with status MessageTooBig: ${event.reason}`,
|
|
519
|
-
)
|
|
520
|
-
this.shouldConnect = false
|
|
521
|
-
}
|
|
522
|
-
|
|
523
481
|
if (this.connectionAttempt) {
|
|
524
482
|
// That connection attempt failed.
|
|
525
483
|
this.rejectConnectionAttempt()
|
|
526
|
-
} else if (this.shouldConnect) {
|
|
527
|
-
// The connection was closed by the server. Let’s just try again.
|
|
528
|
-
this.connect()
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
// If we’ll reconnect, we’re done for now.
|
|
532
|
-
if (this.shouldConnect) {
|
|
533
|
-
return
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
// The status is set correctly already.
|
|
537
|
-
if (this.status === WebSocketStatus.Disconnected) {
|
|
538
|
-
return
|
|
539
484
|
}
|
|
540
485
|
|
|
541
486
|
// Let’s update the connection status.
|
|
542
487
|
this.status = WebSocketStatus.Disconnected
|
|
543
488
|
this.emit('status', { status: WebSocketStatus.Disconnected })
|
|
544
489
|
this.emit('disconnect', { event })
|
|
490
|
+
|
|
491
|
+
// trigger connect if no retry is running and we want to have a connection
|
|
492
|
+
if( !this.cancelWebsocketRetry && this.shouldConnect ) {
|
|
493
|
+
|
|
494
|
+
setTimeout(() => {
|
|
495
|
+
this.connect()
|
|
496
|
+
}, this.configuration.delay)
|
|
497
|
+
}
|
|
545
498
|
}
|
|
546
499
|
|
|
547
500
|
destroy() {
|
|
548
501
|
this.emit('destroy')
|
|
549
502
|
|
|
550
|
-
if (this.intervals.forceSync) {
|
|
551
|
-
clearInterval(this.intervals.forceSync)
|
|
552
|
-
}
|
|
553
|
-
|
|
554
503
|
clearInterval(this.intervals.connectionChecker)
|
|
555
504
|
|
|
556
505
|
// If there is still a connection attempt outstanding then we should stop
|