@hocuspocus/provider 2.3.1 → 2.4.0-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 +45 -20
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +45 -21
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +10 -2
- package/dist/packages/server/src/Document.d.ts +1 -1
- package/dist/packages/server/src/IncomingMessage.d.ts +5 -2
- package/package.json +2 -2
- package/src/HocuspocusProvider.ts +45 -23
- package/src/HocuspocusProviderWebsocket.ts +3 -4
- package/src/MessageReceiver.ts +4 -0
|
@@ -21,8 +21,13 @@ export interface CompleteHocuspocusProviderConfiguration {
|
|
|
21
21
|
broadcast: boolean;
|
|
22
22
|
/**
|
|
23
23
|
* An Awareness instance to keep the presence state of all clients.
|
|
24
|
+
*
|
|
25
|
+
* You can disable sharing awareness information by passing `null`.
|
|
26
|
+
* Note that having no awareness information shared across all connections will break our ping checks
|
|
27
|
+
* and thus trigger reconnects. You should always have at least one Provider with enabled awareness per
|
|
28
|
+
* socket connection, or ensure that the Provider receives messages before running into `HocuspocusProviderWebsocket.messageReconnectTimeout`.
|
|
24
29
|
*/
|
|
25
|
-
awareness: Awareness;
|
|
30
|
+
awareness: Awareness | null;
|
|
26
31
|
/**
|
|
27
32
|
* A token that’s sent to the backend for authentication purposes.
|
|
28
33
|
*/
|
|
@@ -68,6 +73,9 @@ export interface CompleteHocuspocusProviderConfiguration {
|
|
|
68
73
|
*/
|
|
69
74
|
preserveConnection: boolean;
|
|
70
75
|
}
|
|
76
|
+
export declare class AwarenessError extends Error {
|
|
77
|
+
code: number;
|
|
78
|
+
}
|
|
71
79
|
export declare class HocuspocusProvider extends EventEmitter {
|
|
72
80
|
configuration: CompleteHocuspocusProviderConfiguration;
|
|
73
81
|
subscribedToBroadcastChannel: boolean;
|
|
@@ -94,7 +102,7 @@ export declare class HocuspocusProvider extends EventEmitter {
|
|
|
94
102
|
onStatus({ status }: onStatusParameters): void;
|
|
95
103
|
setConfiguration(configuration?: Partial<HocuspocusProviderConfiguration>): void;
|
|
96
104
|
get document(): Y.Doc;
|
|
97
|
-
get awareness(): Awareness;
|
|
105
|
+
get awareness(): Awareness | null;
|
|
98
106
|
get hasUnsyncedChanges(): boolean;
|
|
99
107
|
incrementUnsyncedChanges(): void;
|
|
100
108
|
decrementUnsyncedChanges(): void;
|
|
@@ -24,7 +24,7 @@ export declare class Document extends Doc {
|
|
|
24
24
|
*/
|
|
25
25
|
constructor(name: string, logger: Debugger, yDocOptions: {});
|
|
26
26
|
/**
|
|
27
|
-
* Check if the Document is empty
|
|
27
|
+
* Check if the Document (XMLFragment or Map) is empty
|
|
28
28
|
*/
|
|
29
29
|
isEmpty(fieldName: string): boolean;
|
|
30
30
|
/**
|
|
@@ -7,10 +7,13 @@ export declare class IncomingMessage {
|
|
|
7
7
|
*/
|
|
8
8
|
decoder: Decoder;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Private encoder; can be undefined.
|
|
11
|
+
*
|
|
12
|
+
* Lazy creation of the encoder speeds up IncomingMessages that need only a decoder.
|
|
11
13
|
*/
|
|
12
|
-
|
|
14
|
+
private encoderInternal?;
|
|
13
15
|
constructor(input: any);
|
|
16
|
+
get encoder(): Encoder;
|
|
14
17
|
readVarUint8Array(): Uint8Array;
|
|
15
18
|
readVarUint(): number;
|
|
16
19
|
readVarString(): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hocuspocus/provider",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0-rc.0",
|
|
4
4
|
"description": "hocuspocus provider",
|
|
5
5
|
"homepage": "https://hocuspocus.dev",
|
|
6
6
|
"keywords": [
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dist"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@hocuspocus/common": "^2.
|
|
32
|
+
"@hocuspocus/common": "^2.4.0-rc.0",
|
|
33
33
|
"@lifeomic/attempt": "^3.0.2",
|
|
34
34
|
"lib0": "^0.2.47",
|
|
35
35
|
"ws": "^7.5.9"
|
|
@@ -58,8 +58,13 @@ export interface CompleteHocuspocusProviderConfiguration {
|
|
|
58
58
|
broadcast: boolean,
|
|
59
59
|
/**
|
|
60
60
|
* An Awareness instance to keep the presence state of all clients.
|
|
61
|
+
*
|
|
62
|
+
* You can disable sharing awareness information by passing `null`.
|
|
63
|
+
* Note that having no awareness information shared across all connections will break our ping checks
|
|
64
|
+
* and thus trigger reconnects. You should always have at least one Provider with enabled awareness per
|
|
65
|
+
* socket connection, or ensure that the Provider receives messages before running into `HocuspocusProviderWebsocket.messageReconnectTimeout`.
|
|
61
66
|
*/
|
|
62
|
-
awareness: Awareness,
|
|
67
|
+
awareness: Awareness | null,
|
|
63
68
|
/**
|
|
64
69
|
* A token that’s sent to the backend for authentication purposes.
|
|
65
70
|
*/
|
|
@@ -108,6 +113,10 @@ export interface CompleteHocuspocusProviderConfiguration {
|
|
|
108
113
|
preserveConnection: boolean,
|
|
109
114
|
}
|
|
110
115
|
|
|
116
|
+
export class AwarenessError extends Error {
|
|
117
|
+
code = 1001
|
|
118
|
+
}
|
|
119
|
+
|
|
111
120
|
export class HocuspocusProvider extends EventEmitter {
|
|
112
121
|
public configuration: CompleteHocuspocusProviderConfiguration = {
|
|
113
122
|
name: '',
|
|
@@ -163,7 +172,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
163
172
|
this.setConfiguration(configuration)
|
|
164
173
|
|
|
165
174
|
this.configuration.document = configuration.document ? configuration.document : new Y.Doc()
|
|
166
|
-
this.configuration.awareness = configuration.awareness ? configuration.awareness : new Awareness(this.document)
|
|
175
|
+
this.configuration.awareness = configuration.awareness !== undefined ? configuration.awareness : new Awareness(this.document)
|
|
167
176
|
|
|
168
177
|
this.on('open', this.configuration.onOpen)
|
|
169
178
|
this.on('message', this.configuration.onMessage)
|
|
@@ -197,16 +206,16 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
197
206
|
this.configuration.websocketProvider.on('destroy', this.configuration.onDestroy)
|
|
198
207
|
this.configuration.websocketProvider.on('destroy', this.forwardDestroy)
|
|
199
208
|
|
|
200
|
-
this.awareness
|
|
201
|
-
this.emit('awarenessUpdate', { states: awarenessStatesToArray(this.awareness
|
|
209
|
+
this.awareness?.on('update', () => {
|
|
210
|
+
this.emit('awarenessUpdate', { states: awarenessStatesToArray(this.awareness!.getStates()) })
|
|
202
211
|
})
|
|
203
212
|
|
|
204
|
-
this.awareness
|
|
205
|
-
this.emit('awarenessChange', { states: awarenessStatesToArray(this.awareness
|
|
213
|
+
this.awareness?.on('change', () => {
|
|
214
|
+
this.emit('awarenessChange', { states: awarenessStatesToArray(this.awareness!.getStates()) })
|
|
206
215
|
})
|
|
207
216
|
|
|
208
217
|
this.document.on('update', this.documentUpdateHandler.bind(this))
|
|
209
|
-
this.awareness
|
|
218
|
+
this.awareness?.on('update', this.awarenessUpdateHandler.bind(this))
|
|
210
219
|
this.registerEventListeners()
|
|
211
220
|
|
|
212
221
|
if (this.configuration.forceSyncInterval) {
|
|
@@ -292,7 +301,9 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
292
301
|
}
|
|
293
302
|
|
|
294
303
|
pageUnload() {
|
|
295
|
-
|
|
304
|
+
if (this.awareness) {
|
|
305
|
+
removeAwarenessStates(this.awareness, [this.document.clientID], 'window unload')
|
|
306
|
+
}
|
|
296
307
|
}
|
|
297
308
|
|
|
298
309
|
registerEventListeners() {
|
|
@@ -395,7 +406,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
395
406
|
this.incrementUnsyncedChanges()
|
|
396
407
|
this.send(SyncStepOneMessage, { document: this.document, documentName: this.configuration.name })
|
|
397
408
|
|
|
398
|
-
if (this.awareness.getLocalState() !== null) {
|
|
409
|
+
if (this.awareness && this.awareness.getLocalState() !== null) {
|
|
399
410
|
this.send(AwarenessMessage, {
|
|
400
411
|
awareness: this.awareness,
|
|
401
412
|
clients: [this.document.clientID],
|
|
@@ -440,11 +451,13 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
440
451
|
this.synced = false
|
|
441
452
|
|
|
442
453
|
// update awareness (all users except local left)
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
454
|
+
if (this.awareness) {
|
|
455
|
+
removeAwarenessStates(
|
|
456
|
+
this.awareness,
|
|
457
|
+
Array.from(this.awareness.getStates().keys()).filter(client => client !== this.document.clientID),
|
|
458
|
+
this,
|
|
459
|
+
)
|
|
460
|
+
}
|
|
448
461
|
}
|
|
449
462
|
|
|
450
463
|
destroy() {
|
|
@@ -454,11 +467,13 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
454
467
|
clearInterval(this.intervals.forceSync)
|
|
455
468
|
}
|
|
456
469
|
|
|
457
|
-
|
|
470
|
+
if (this.awareness) {
|
|
471
|
+
removeAwarenessStates(this.awareness, [this.document.clientID], 'provider destroy')
|
|
472
|
+
}
|
|
458
473
|
|
|
459
474
|
this.disconnect()
|
|
460
475
|
|
|
461
|
-
this.awareness
|
|
476
|
+
this.awareness?.off('update', this.awarenessUpdateHandler)
|
|
462
477
|
this.document.off('update', this.documentUpdateHandler)
|
|
463
478
|
|
|
464
479
|
this.removeAllListeners()
|
|
@@ -530,18 +545,22 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
530
545
|
this.broadcast(SyncStepOneMessage, { document: this.document })
|
|
531
546
|
this.broadcast(SyncStepTwoMessage, { document: this.document })
|
|
532
547
|
this.broadcast(QueryAwarenessMessage, { document: this.document })
|
|
533
|
-
|
|
548
|
+
if (this.awareness) {
|
|
549
|
+
this.broadcast(AwarenessMessage, { awareness: this.awareness, clients: [this.document.clientID], document: this.document })
|
|
550
|
+
}
|
|
534
551
|
})
|
|
535
552
|
}
|
|
536
553
|
|
|
537
554
|
disconnectBroadcastChannel() {
|
|
538
555
|
// broadcast message with local awareness state set to null (indicating disconnect)
|
|
539
|
-
this.
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
556
|
+
if (this.awareness) {
|
|
557
|
+
this.send(AwarenessMessage, {
|
|
558
|
+
awareness: this.awareness,
|
|
559
|
+
clients: [this.document.clientID],
|
|
560
|
+
states: new Map(),
|
|
561
|
+
documentName: this.configuration.name,
|
|
562
|
+
}, true)
|
|
563
|
+
}
|
|
545
564
|
|
|
546
565
|
if (this.subscribedToBroadcastChannel) {
|
|
547
566
|
bc.unsubscribe(this.broadcastChannel, this.boundBroadcastChannelSubscriber)
|
|
@@ -562,6 +581,9 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
562
581
|
}
|
|
563
582
|
|
|
564
583
|
setAwarenessField(key: string, value: any) {
|
|
584
|
+
if (!this.awareness) {
|
|
585
|
+
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.`)
|
|
586
|
+
}
|
|
565
587
|
this.awareness.setLocalStateField(key, value)
|
|
566
588
|
}
|
|
567
589
|
}
|
|
@@ -98,8 +98,6 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
98
98
|
url: '',
|
|
99
99
|
// @ts-ignore
|
|
100
100
|
document: undefined,
|
|
101
|
-
// @ts-ignore
|
|
102
|
-
awareness: undefined,
|
|
103
101
|
WebSocketPolyfill: undefined,
|
|
104
102
|
parameters: {},
|
|
105
103
|
connect: true,
|
|
@@ -358,7 +356,7 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
358
356
|
return
|
|
359
357
|
}
|
|
360
358
|
|
|
361
|
-
// Don’t close
|
|
359
|
+
// Don’t close the connection while waiting for the first message
|
|
362
360
|
if (!this.lastMessageReceived) {
|
|
363
361
|
return
|
|
364
362
|
}
|
|
@@ -369,7 +367,8 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
369
367
|
}
|
|
370
368
|
|
|
371
369
|
// No message received in a long time, not even your own
|
|
372
|
-
// Awareness updates, which are updated every 15 seconds
|
|
370
|
+
// Awareness updates, which are updated every 15 seconds
|
|
371
|
+
// if awareness is enabled.
|
|
373
372
|
this.closeTries += 1
|
|
374
373
|
// https://bugs.webkit.org/show_bug.cgi?id=247943
|
|
375
374
|
if (this.closeTries > 2) {
|
package/src/MessageReceiver.ts
CHANGED
|
@@ -97,6 +97,8 @@ export class MessageReceiver {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
private applyAwarenessMessage(provider: HocuspocusProvider) {
|
|
100
|
+
if (!provider.awareness) return
|
|
101
|
+
|
|
100
102
|
const { message } = this
|
|
101
103
|
|
|
102
104
|
awarenessProtocol.applyAwarenessUpdate(
|
|
@@ -117,6 +119,8 @@ export class MessageReceiver {
|
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
private applyQueryAwarenessMessage(provider: HocuspocusProvider) {
|
|
122
|
+
if (!provider.awareness) return
|
|
123
|
+
|
|
120
124
|
const { message } = this
|
|
121
125
|
|
|
122
126
|
message.writeVarUint(MessageType.Awareness)
|