@hocuspocus/provider 4.0.0-rc.0 → 4.0.0-rc.2
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 +30 -4
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +30 -4
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/package.json +3 -3
- package/src/HocuspocusProvider.ts +1 -1
- package/src/HocuspocusProviderWebsocket.ts +44 -4
package/dist/index.d.ts
CHANGED
|
@@ -396,6 +396,7 @@ interface CompleteHocuspocusProviderWebsocketConfiguration {
|
|
|
396
396
|
providerMap: Map<string, HocuspocusProvider>;
|
|
397
397
|
}
|
|
398
398
|
declare class HocuspocusProviderWebsocket extends EventEmitter {
|
|
399
|
+
private static readonly DEDUPLICATABLE_TYPES;
|
|
399
400
|
private messageQueue;
|
|
400
401
|
configuration: CompleteHocuspocusProviderWebsocketConfiguration;
|
|
401
402
|
webSocket: HocusPocusWebSocket | null;
|
|
@@ -435,6 +436,8 @@ declare class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
435
436
|
get serverUrl(): string;
|
|
436
437
|
get url(): string;
|
|
437
438
|
disconnect(): void;
|
|
439
|
+
private parseQueuedMessage;
|
|
440
|
+
private addToQueue;
|
|
438
441
|
send(message: any): void;
|
|
439
442
|
onClose({
|
|
440
443
|
event
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hocuspocus/provider",
|
|
3
|
-
"version": "4.0.0-rc.
|
|
3
|
+
"version": "4.0.0-rc.2",
|
|
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": "^4.0.0-rc.
|
|
32
|
+
"@hocuspocus/common": "^4.0.0-rc.2",
|
|
33
33
|
"@lifeomic/attempt": "^3.0.2",
|
|
34
34
|
"lib0": "^0.2.87",
|
|
35
35
|
"ws": "^8.17.1"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"y-protocols": "^1.0.6",
|
|
39
39
|
"yjs": "^13.6.8"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "f1037a372b664d3582cf12ad7ff3dd245664629c",
|
|
42
42
|
"repository": {
|
|
43
43
|
"url": "https://github.com/ueberdosis/hocuspocus"
|
|
44
44
|
},
|
|
@@ -123,7 +123,7 @@ export class HocuspocusProvider extends EventEmitter {
|
|
|
123
123
|
// @ts-ignore
|
|
124
124
|
awareness: undefined,
|
|
125
125
|
token: null,
|
|
126
|
-
sessionAwareness:
|
|
126
|
+
sessionAwareness: false,
|
|
127
127
|
forceSyncInterval: false,
|
|
128
128
|
onAuthenticated: () => null,
|
|
129
129
|
onAuthenticationFailed: () => null,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { WsReadyStates } from "@hocuspocus/common";
|
|
2
2
|
import { retry } from "@lifeomic/attempt";
|
|
3
|
+
import { createDecoder, readVarString, readVarUint } from "lib0/decoding";
|
|
3
4
|
import * as encoding from "lib0/encoding";
|
|
4
5
|
import * as time from "lib0/time";
|
|
5
6
|
import EventEmitter from "./EventEmitter.ts";
|
|
@@ -8,7 +9,6 @@ import { IncomingMessage } from "./IncomingMessage.ts";
|
|
|
8
9
|
import { CloseMessage } from "./OutgoingMessages/CloseMessage.ts";
|
|
9
10
|
import {
|
|
10
11
|
MessageType,
|
|
11
|
-
WebSocketStatus,
|
|
12
12
|
type onAwarenessChangeParameters,
|
|
13
13
|
type onAwarenessUpdateParameters,
|
|
14
14
|
type onCloseParameters,
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type onOpenParameters,
|
|
18
18
|
type onOutgoingMessageParameters,
|
|
19
19
|
type onStatusParameters,
|
|
20
|
+
WebSocketStatus,
|
|
20
21
|
} from "./types.ts";
|
|
21
22
|
|
|
22
23
|
export type HocuspocusWebSocket = WebSocket & { identifier: string };
|
|
@@ -104,13 +105,18 @@ export interface CompleteHocuspocusProviderWebsocketConfiguration {
|
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
108
|
+
private static readonly DEDUPLICATABLE_TYPES = new Set([
|
|
109
|
+
MessageType.Awareness,
|
|
110
|
+
MessageType.QueryAwareness,
|
|
111
|
+
]);
|
|
112
|
+
|
|
107
113
|
private messageQueue: any[] = [];
|
|
108
114
|
|
|
109
115
|
public configuration: CompleteHocuspocusProviderWebsocketConfiguration = {
|
|
110
116
|
url: "",
|
|
111
117
|
autoConnect: true,
|
|
112
118
|
preserveTrailingSlash: false,
|
|
113
|
-
// @ts-
|
|
119
|
+
// @ts-expect-error
|
|
114
120
|
document: undefined,
|
|
115
121
|
WebSocketPolyfill: undefined,
|
|
116
122
|
// TODO: this should depend on awareness.outdatedTime
|
|
@@ -218,7 +224,7 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
218
224
|
if (existing.isAuthenticated) {
|
|
219
225
|
throw new Error(
|
|
220
226
|
`Cannot attach two providers with the same effective name "${key}". ` +
|
|
221
|
-
|
|
227
|
+
"Use sessionAwareness: true to multiplex providers with the same document name.",
|
|
222
228
|
);
|
|
223
229
|
}
|
|
224
230
|
}
|
|
@@ -510,11 +516,45 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
|
|
|
510
516
|
}
|
|
511
517
|
}
|
|
512
518
|
|
|
519
|
+
private parseQueuedMessage(
|
|
520
|
+
message: Uint8Array,
|
|
521
|
+
): { documentName: string; messageType: number } | null {
|
|
522
|
+
try {
|
|
523
|
+
const decoder = createDecoder(message);
|
|
524
|
+
const documentName = readVarString(decoder);
|
|
525
|
+
const messageType = readVarUint(decoder);
|
|
526
|
+
return { documentName, messageType };
|
|
527
|
+
} catch {
|
|
528
|
+
return null;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
private addToQueue(message: any) {
|
|
533
|
+
if (message instanceof Uint8Array) {
|
|
534
|
+
const parsed = this.parseQueuedMessage(message);
|
|
535
|
+
if (
|
|
536
|
+
parsed &&
|
|
537
|
+
HocuspocusProviderWebsocket.DEDUPLICATABLE_TYPES.has(parsed.messageType)
|
|
538
|
+
) {
|
|
539
|
+
this.messageQueue = this.messageQueue.filter((queued) => {
|
|
540
|
+
if (!(queued instanceof Uint8Array)) return true;
|
|
541
|
+
const queuedParsed = this.parseQueuedMessage(queued);
|
|
542
|
+
if (!queuedParsed) return true;
|
|
543
|
+
return !(
|
|
544
|
+
queuedParsed.documentName === parsed.documentName &&
|
|
545
|
+
queuedParsed.messageType === parsed.messageType
|
|
546
|
+
);
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
this.messageQueue.push(message);
|
|
551
|
+
}
|
|
552
|
+
|
|
513
553
|
send(message: any) {
|
|
514
554
|
if (this.webSocket?.readyState === WsReadyStates.Open) {
|
|
515
555
|
this.webSocket.send(message);
|
|
516
556
|
} else {
|
|
517
|
-
this.
|
|
557
|
+
this.addToQueue(message);
|
|
518
558
|
}
|
|
519
559
|
}
|
|
520
560
|
|