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