@hocuspocus/provider 3.4.6-rc.2 → 4.0.0-rc.1

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023, Tiptap GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -31,7 +31,7 @@ let yjs = require("yjs");
31
31
  yjs = __toESM(yjs);
32
32
  let _lifeomic_attempt = require("@lifeomic/attempt");
33
33
 
34
- //#region node_modules/lib0/math.js
34
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/math.js
35
35
  /**
36
36
  * Common Math expressions.
37
37
  *
@@ -55,7 +55,7 @@ const max = (a, b) => a > b ? a : b;
55
55
  const isNaN$1 = Number.isNaN;
56
56
 
57
57
  //#endregion
58
- //#region node_modules/lib0/binary.js
58
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/binary.js
59
59
  const BIT7 = 64;
60
60
  const BIT8 = 128;
61
61
  const BIT18 = 1 << 17;
@@ -99,7 +99,7 @@ const BITS31 = 2147483647;
99
99
  const BITS32 = 4294967295;
100
100
 
101
101
  //#endregion
102
- //#region node_modules/lib0/number.js
102
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/number.js
103
103
  /**
104
104
  * Utility helpers for working with numbers.
105
105
  *
@@ -116,7 +116,7 @@ const isNaN = Number.isNaN;
116
116
  const parseInt = Number.parseInt;
117
117
 
118
118
  //#endregion
119
- //#region node_modules/lib0/set.js
119
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/set.js
120
120
  /**
121
121
  * Utility module to work with sets.
122
122
  *
@@ -125,7 +125,7 @@ const parseInt = Number.parseInt;
125
125
  const create$2 = () => /* @__PURE__ */ new Set();
126
126
 
127
127
  //#endregion
128
- //#region node_modules/lib0/array.js
128
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/array.js
129
129
  /**
130
130
  * Transforms something array-like to an actual Array.
131
131
  *
@@ -138,7 +138,7 @@ const from = Array.from;
138
138
  const isArray$1 = Array.isArray;
139
139
 
140
140
  //#endregion
141
- //#region node_modules/lib0/string.js
141
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/string.js
142
142
  /**
143
143
  * Utility module to work with strings.
144
144
  *
@@ -153,7 +153,7 @@ const fromCodePoint = String.fromCodePoint;
153
153
  const MAX_UTF16_CHARACTER = fromCharCode(65535);
154
154
  /**
155
155
  * @param {string} str
156
- * @return {Uint8Array}
156
+ * @return {Uint8Array<ArrayBuffer>}
157
157
  */
158
158
  const _encodeUtf8Polyfill = (str) => {
159
159
  const encodedString = unescape(encodeURIComponent(str));
@@ -166,7 +166,7 @@ const _encodeUtf8Polyfill = (str) => {
166
166
  const utf8TextEncoder = typeof TextEncoder !== "undefined" ? new TextEncoder() : null;
167
167
  /**
168
168
  * @param {string} str
169
- * @return {Uint8Array}
169
+ * @return {Uint8Array<ArrayBuffer>}
170
170
  */
171
171
  const _encodeUtf8Native = (str) => utf8TextEncoder.encode(str);
172
172
  /**
@@ -186,7 +186,7 @@ if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1)
186
186
  utf8TextDecoder = null;
187
187
 
188
188
  //#endregion
189
- //#region node_modules/lib0/encoding.js
189
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/encoding.js
190
190
  /**
191
191
  * Efficient schema-less binary encoding with support for variable length encoding.
192
192
  *
@@ -239,7 +239,7 @@ const createEncoder = () => new Encoder();
239
239
  * @param {Encoder} encoder
240
240
  * @return {number}
241
241
  */
242
- const length$1 = (encoder) => {
242
+ const length = (encoder) => {
243
243
  let len = encoder.cpos;
244
244
  for (let i = 0; i < encoder.bufs.length; i++) len += encoder.bufs[i].length;
245
245
  return len;
@@ -249,10 +249,10 @@ const length$1 = (encoder) => {
249
249
  *
250
250
  * @function
251
251
  * @param {Encoder} encoder
252
- * @return {Uint8Array} The created ArrayBuffer.
252
+ * @return {Uint8Array<ArrayBuffer>} The created ArrayBuffer.
253
253
  */
254
254
  const toUint8Array = (encoder) => {
255
- const uint8arr = new Uint8Array(length$1(encoder));
255
+ const uint8arr = new Uint8Array(length(encoder));
256
256
  let curPos = 0;
257
257
  for (let i = 0; i < encoder.bufs.length; i++) {
258
258
  const d = encoder.bufs[i];
@@ -368,7 +368,7 @@ const writeVarUint8Array = (encoder, uint8Array) => {
368
368
  };
369
369
 
370
370
  //#endregion
371
- //#region node_modules/lib0/error.js
371
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/error.js
372
372
  /**
373
373
  * Error helpers.
374
374
  *
@@ -382,7 +382,7 @@ const writeVarUint8Array = (encoder, uint8Array) => {
382
382
  const create$1 = (s) => new Error(s);
383
383
 
384
384
  //#endregion
385
- //#region node_modules/lib0/decoding.js
385
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/decoding.js
386
386
  /**
387
387
  * Efficient schema-less binary decoding with support for variable length encoding.
388
388
  *
@@ -414,16 +414,17 @@ const errorUnexpectedEndOfArray = create$1("Unexpected end of array");
414
414
  const errorIntegerOutOfRange = create$1("Integer out of Range");
415
415
  /**
416
416
  * A Decoder handles the decoding of an Uint8Array.
417
+ * @template {ArrayBufferLike} [Buf=ArrayBufferLike]
417
418
  */
418
419
  var Decoder = class {
419
420
  /**
420
- * @param {Uint8Array} uint8Array Binary data to decode
421
+ * @param {Uint8Array<Buf>} uint8Array Binary data to decode
421
422
  */
422
423
  constructor(uint8Array) {
423
424
  /**
424
425
  * Decoding target.
425
426
  *
426
- * @type {Uint8Array}
427
+ * @type {Uint8Array<Buf>}
427
428
  */
428
429
  this.arr = uint8Array;
429
430
  /**
@@ -436,8 +437,9 @@ var Decoder = class {
436
437
  };
437
438
  /**
438
439
  * @function
439
- * @param {Uint8Array} uint8Array
440
- * @return {Decoder}
440
+ * @template {ArrayBufferLike} Buf
441
+ * @param {Uint8Array<Buf>} uint8Array
442
+ * @return {Decoder<Buf>}
441
443
  */
442
444
  const createDecoder = (uint8Array) => new Decoder(uint8Array);
443
445
  /**
@@ -447,9 +449,10 @@ const createDecoder = (uint8Array) => new Decoder(uint8Array);
447
449
  * Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
448
450
  *
449
451
  * @function
450
- * @param {Decoder} decoder The decoder instance
452
+ * @template {ArrayBufferLike} Buf
453
+ * @param {Decoder<Buf>} decoder The decoder instance
451
454
  * @param {number} len The length of bytes to read
452
- * @return {Uint8Array}
455
+ * @return {Uint8Array<Buf>}
453
456
  */
454
457
  const readUint8Array = (decoder, len) => {
455
458
  const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len);
@@ -463,8 +466,9 @@ const readUint8Array = (decoder, len) => {
463
466
  * Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
464
467
  *
465
468
  * @function
466
- * @param {Decoder} decoder
467
- * @return {Uint8Array}
469
+ * @template {ArrayBufferLike} Buf
470
+ * @param {Decoder<Buf>} decoder
471
+ * @return {Uint8Array<Buf>}
468
472
  */
469
473
  const readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder));
470
474
  /**
@@ -589,7 +593,7 @@ const peekVarString = (decoder) => {
589
593
  };
590
594
 
591
595
  //#endregion
592
- //#region node_modules/lib0/time.js
596
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/time.js
593
597
  /**
594
598
  * Return current unix time.
595
599
  *
@@ -598,13 +602,18 @@ const peekVarString = (decoder) => {
598
602
  const getUnixTime = Date.now;
599
603
 
600
604
  //#endregion
601
- //#region node_modules/lib0/map.js
605
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/map.js
602
606
  /**
603
607
  * Utility module to work with key-value stores.
604
608
  *
605
609
  * @module map
606
610
  */
607
611
  /**
612
+ * @template K
613
+ * @template V
614
+ * @typedef {Map<K,V>} GlobalMap
615
+ */
616
+ /**
608
617
  * Creates a new Map instance.
609
618
  *
610
619
  * @function
@@ -636,7 +645,7 @@ const setIfUndefined = (map, key, createT) => {
636
645
  };
637
646
 
638
647
  //#endregion
639
- //#region node_modules/lib0/observable.js
648
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/observable.js
640
649
  /**
641
650
  * Observable class prototype.
642
651
  *
@@ -708,41 +717,36 @@ var Observable = class {
708
717
  /* c8 ignore end */
709
718
 
710
719
  //#endregion
711
- //#region node_modules/lib0/object.js
720
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/trait/equality.js
721
+ const EqualityTraitSymbol = Symbol("Equality");
722
+
723
+ //#endregion
724
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/object.js
712
725
  /**
713
726
  * @param {Object<string,any>} obj
714
727
  */
715
728
  const keys = Object.keys;
716
729
  /**
717
- * @deprecated use object.size instead
718
730
  * @param {Object<string,any>} obj
719
731
  * @return {number}
720
732
  */
721
- const length = (obj) => keys(obj).length;
733
+ const size = (obj) => keys(obj).length;
722
734
  /**
723
735
  * Calls `Object.prototype.hasOwnProperty`.
724
736
  *
725
737
  * @param {any} obj
726
- * @param {string|symbol} key
738
+ * @param {string|number|symbol} key
727
739
  * @return {boolean}
728
740
  */
729
741
  const hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
730
742
 
731
743
  //#endregion
732
- //#region node_modules/lib0/function.js
744
+ //#region node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/function.js
733
745
  /**
734
746
  * Common functions and function call helpers.
735
747
  *
736
748
  * @module function
737
749
  */
738
- /**
739
- * @template T
740
- *
741
- * @param {T} a
742
- * @param {T} b
743
- * @return {boolean}
744
- */
745
- const equalityStrict = (a, b) => a === b;
746
750
  /* c8 ignore start */
747
751
  /**
748
752
  * @param {any} a
@@ -750,9 +754,9 @@ const equalityStrict = (a, b) => a === b;
750
754
  * @return {boolean}
751
755
  */
752
756
  const equalityDeep = (a, b) => {
753
- if (a == null || b == null) return equalityStrict(a, b);
754
- if (a.constructor !== b.constructor) return false;
755
757
  if (a === b) return true;
758
+ if (a == null || b == null || a.constructor !== b.constructor && (a.constructor || Object) !== (b.constructor || Object)) return false;
759
+ if (a[EqualityTraitSymbol] != null) return a[EqualityTraitSymbol](b);
756
760
  switch (a.constructor) {
757
761
  case ArrayBuffer:
758
762
  a = new Uint8Array(a);
@@ -769,8 +773,9 @@ const equalityDeep = (a, b) => {
769
773
  if (a.size !== b.size) return false;
770
774
  for (const key of a.keys()) if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) return false;
771
775
  break;
776
+ case void 0:
772
777
  case Object:
773
- if (length(a) !== length(b)) return false;
778
+ if (size(a) !== size(b)) return false;
774
779
  for (const key in a) if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) return false;
775
780
  break;
776
781
  case Array:
@@ -785,7 +790,7 @@ const equalityDeep = (a, b) => {
785
790
  const isArray = isArray$1;
786
791
 
787
792
  //#endregion
788
- //#region node_modules/y-protocols/awareness.js
793
+ //#region node_modules/.pnpm/y-protocols@1.0.7_yjs@13.6.29/node_modules/y-protocols/awareness.js
789
794
  /**
790
795
  * @module awareness-protocol
791
796
  */
@@ -1077,7 +1082,7 @@ var IncomingMessage = class {
1077
1082
  return writeVarUint8Array(this.encoder, data);
1078
1083
  }
1079
1084
  length() {
1080
- return length$1(this.encoder);
1085
+ return length(this.encoder);
1081
1086
  }
1082
1087
  };
1083
1088
 
@@ -1091,6 +1096,8 @@ let MessageType = /* @__PURE__ */ function(MessageType) {
1091
1096
  MessageType[MessageType["Stateless"] = 5] = "Stateless";
1092
1097
  MessageType[MessageType["CLOSE"] = 7] = "CLOSE";
1093
1098
  MessageType[MessageType["SyncStatus"] = 8] = "SyncStatus";
1099
+ MessageType[MessageType["Ping"] = 9] = "Ping";
1100
+ MessageType[MessageType["Pong"] = 10] = "Pong";
1094
1101
  return MessageType;
1095
1102
  }({});
1096
1103
  let WebSocketStatus = /* @__PURE__ */ function(WebSocketStatus) {
@@ -1131,7 +1138,10 @@ var CloseMessage = class extends OutgoingMessage {
1131
1138
 
1132
1139
  //#endregion
1133
1140
  //#region packages/provider/src/HocuspocusProviderWebsocket.ts
1134
- var HocuspocusProviderWebsocket = class extends EventEmitter {
1141
+ var HocuspocusProviderWebsocket = class HocuspocusProviderWebsocket extends EventEmitter {
1142
+ static {
1143
+ this.DEDUPLICATABLE_TYPES = new Set([MessageType.Awareness, MessageType.QueryAwareness]);
1144
+ }
1135
1145
  constructor(configuration) {
1136
1146
  super();
1137
1147
  this.messageQueue = [];
@@ -1198,14 +1208,20 @@ var HocuspocusProviderWebsocket = class extends EventEmitter {
1198
1208
  this.receivedOnOpenPayload = event;
1199
1209
  }
1200
1210
  attach(provider) {
1201
- this.configuration.providerMap.set(provider.configuration.name, provider);
1211
+ const key = provider.effectiveName;
1212
+ const existing = this.configuration.providerMap.get(key);
1213
+ if (existing && existing !== provider) {
1214
+ if (existing.isAuthenticated) throw new Error(`Cannot attach two providers with the same effective name "${key}". Use sessionAwareness: true to multiplex providers with the same document name.`);
1215
+ }
1216
+ this.configuration.providerMap.set(key, provider);
1202
1217
  if (this.status === WebSocketStatus.Disconnected && this.shouldConnect) this.connect();
1203
1218
  if (this.receivedOnOpenPayload && this.status === WebSocketStatus.Connected) provider.onOpen(this.receivedOnOpenPayload);
1204
1219
  }
1205
1220
  detach(provider) {
1206
- if (this.configuration.providerMap.has(provider.configuration.name)) {
1207
- provider.send(CloseMessage, { documentName: provider.configuration.name });
1208
- this.configuration.providerMap.delete(provider.configuration.name);
1221
+ const key = provider.effectiveName;
1222
+ if (this.configuration.providerMap.has(key)) {
1223
+ provider.send(CloseMessage, { documentName: key });
1224
+ this.configuration.providerMap.delete(key);
1209
1225
  }
1210
1226
  }
1211
1227
  setConfiguration(configuration = {}) {
@@ -1305,8 +1321,21 @@ var HocuspocusProviderWebsocket = class extends EventEmitter {
1305
1321
  onMessage(event) {
1306
1322
  this.resolveConnectionAttempt();
1307
1323
  this.lastMessageReceived = getUnixTime();
1308
- const documentName = new IncomingMessage(event.data).peekVarString();
1309
- this.configuration.providerMap.get(documentName)?.onMessage(event);
1324
+ const data = new Uint8Array(event.data);
1325
+ if (data.length === 1 && data[0] === MessageType.Ping) {
1326
+ this.sendPong();
1327
+ return;
1328
+ }
1329
+ const rawKey = new IncomingMessage(data).peekVarString();
1330
+ this.configuration.providerMap.get(rawKey)?.onMessage(event);
1331
+ }
1332
+ /**
1333
+ * Send application-level Pong response to server Ping
1334
+ */
1335
+ sendPong() {
1336
+ const encoder = createEncoder();
1337
+ writeVarUint(encoder, MessageType.Pong);
1338
+ this.send(toUint8Array(encoder));
1310
1339
  }
1311
1340
  resolveConnectionAttempt() {
1312
1341
  if (this.connectionAttempt) {
@@ -1361,9 +1390,32 @@ var HocuspocusProviderWebsocket = class extends EventEmitter {
1361
1390
  console.error(e);
1362
1391
  }
1363
1392
  }
1393
+ parseQueuedMessage(message) {
1394
+ try {
1395
+ const decoder = createDecoder(message);
1396
+ return {
1397
+ documentName: readVarString(decoder),
1398
+ messageType: readVarUint(decoder)
1399
+ };
1400
+ } catch {
1401
+ return null;
1402
+ }
1403
+ }
1404
+ addToQueue(message) {
1405
+ if (message instanceof Uint8Array) {
1406
+ const parsed = this.parseQueuedMessage(message);
1407
+ if (parsed && HocuspocusProviderWebsocket.DEDUPLICATABLE_TYPES.has(parsed.messageType)) this.messageQueue = this.messageQueue.filter((queued) => {
1408
+ if (!(queued instanceof Uint8Array)) return true;
1409
+ const queuedParsed = this.parseQueuedMessage(queued);
1410
+ if (!queuedParsed) return true;
1411
+ return !(queuedParsed.documentName === parsed.documentName && queuedParsed.messageType === parsed.messageType);
1412
+ });
1413
+ }
1414
+ this.messageQueue.push(message);
1415
+ }
1364
1416
  send(message) {
1365
1417
  if (this.webSocket?.readyState === _hocuspocus_common.WsReadyStates.Open) this.webSocket.send(message);
1366
- else this.messageQueue.push(message);
1418
+ else this.addToQueue(message);
1367
1419
  }
1368
1420
  onClose({ event }) {
1369
1421
  this.closeTries = 0;
@@ -1387,7 +1439,7 @@ var HocuspocusProviderWebsocket = class extends EventEmitter {
1387
1439
  };
1388
1440
 
1389
1441
  //#endregion
1390
- //#region node_modules/y-protocols/sync.js
1442
+ //#region node_modules/.pnpm/y-protocols@1.0.7_yjs@13.6.29/node_modules/y-protocols/sync.js
1391
1443
  /**
1392
1444
  * @module sync-protocol
1393
1445
  */
@@ -1455,11 +1507,13 @@ const readSyncStep1 = (decoder, encoder, doc) => writeSyncStep2(encoder, doc, re
1455
1507
  * @param {decoding.Decoder} decoder
1456
1508
  * @param {Y.Doc} doc
1457
1509
  * @param {any} transactionOrigin
1510
+ * @param {(error:Error)=>any} [errorHandler]
1458
1511
  */
1459
- const readSyncStep2 = (decoder, doc, transactionOrigin) => {
1512
+ const readSyncStep2 = (decoder, doc, transactionOrigin, errorHandler) => {
1460
1513
  try {
1461
1514
  yjs.applyUpdate(doc, readVarUint8Array(decoder), transactionOrigin);
1462
1515
  } catch (error) {
1516
+ if (errorHandler != null) errorHandler(error);
1463
1517
  console.error("Caught error while handling a Yjs update", error);
1464
1518
  }
1465
1519
  };
@@ -1477,6 +1531,7 @@ const writeUpdate = (encoder, update) => {
1477
1531
  * @param {decoding.Decoder} decoder
1478
1532
  * @param {Y.Doc} doc
1479
1533
  * @param {any} transactionOrigin
1534
+ * @param {(error:Error)=>any} [errorHandler]
1480
1535
  */
1481
1536
  const readUpdate = readSyncStep2;
1482
1537
  /**
@@ -1484,18 +1539,19 @@ const readUpdate = readSyncStep2;
1484
1539
  * @param {encoding.Encoder} encoder The reply message. Does not need to be sent if empty.
1485
1540
  * @param {Y.Doc} doc
1486
1541
  * @param {any} transactionOrigin
1542
+ * @param {(error:Error)=>any} [errorHandler] Optional error handler that catches errors when reading Yjs messages.
1487
1543
  */
1488
- const readSyncMessage = (decoder, encoder, doc, transactionOrigin) => {
1544
+ const readSyncMessage = (decoder, encoder, doc, transactionOrigin, errorHandler) => {
1489
1545
  const messageType = readVarUint(decoder);
1490
1546
  switch (messageType) {
1491
1547
  case messageYjsSyncStep1:
1492
1548
  readSyncStep1(decoder, encoder, doc);
1493
1549
  break;
1494
1550
  case messageYjsSyncStep2:
1495
- readSyncStep2(decoder, doc, transactionOrigin);
1551
+ readSyncStep2(decoder, doc, transactionOrigin, errorHandler);
1496
1552
  break;
1497
1553
  case messageYjsUpdate:
1498
- readUpdate(decoder, doc, transactionOrigin);
1554
+ readUpdate(decoder, doc, transactionOrigin, errorHandler);
1499
1555
  break;
1500
1556
  default: throw new Error("Unknown message type");
1501
1557
  }
@@ -1534,15 +1590,13 @@ var MessageReceiver = class {
1534
1590
  case MessageType.CLOSE:
1535
1591
  const event = {
1536
1592
  code: 1e3,
1537
- reason: readVarString(message.decoder),
1538
- target: provider.configuration.websocketProvider.webSocket,
1539
- type: "close"
1593
+ reason: readVarString(message.decoder)
1540
1594
  };
1541
1595
  provider.onClose();
1542
1596
  provider.configuration.onClose({ event });
1543
1597
  provider.forwardClose({ event });
1544
1598
  break;
1545
- default: throw new Error(`Can’t apply message of unknown type: ${type}`);
1599
+ default: console.error(`Can’t apply message of unknown type: ${type}`);
1546
1600
  }
1547
1601
  if (message.length() > emptyMessageLength + 1) provider.send(OutgoingMessage, { encoder: message.encoder });
1548
1602
  }
@@ -1587,6 +1641,10 @@ var MessageSender = class {
1587
1641
  }
1588
1642
  };
1589
1643
 
1644
+ //#endregion
1645
+ //#region packages/provider/src/version.ts
1646
+ const version = "4.0.0-rc.1";
1647
+
1590
1648
  //#endregion
1591
1649
  //#region packages/provider/src/OutgoingMessages/AuthenticationMessage.ts
1592
1650
  var AuthenticationMessage = class extends OutgoingMessage {
@@ -1600,6 +1658,7 @@ var AuthenticationMessage = class extends OutgoingMessage {
1600
1658
  writeVarString(this.encoder, args.documentName);
1601
1659
  writeVarUint(this.encoder, this.type);
1602
1660
  (0, _hocuspocus_common.writeAuthentication)(this.encoder, args.token);
1661
+ writeVarString(this.encoder, version);
1603
1662
  return this.encoder;
1604
1663
  }
1605
1664
  };
@@ -1683,6 +1742,14 @@ var AwarenessError = class extends Error {
1683
1742
  }
1684
1743
  };
1685
1744
  var HocuspocusProvider = class extends EventEmitter {
1745
+ /**
1746
+ * The effective name used as the first VarString in messages.
1747
+ * When `sessionAwareness` is enabled, returns a composite key (documentName\0sessionId).
1748
+ * Otherwise, returns the plain document name.
1749
+ */
1750
+ get effectiveName() {
1751
+ return this.configuration.sessionAwareness ? (0, _hocuspocus_common.makeRoutingKey)(this.configuration.name, this.sessionId) : this.configuration.name;
1752
+ }
1686
1753
  constructor(configuration) {
1687
1754
  super();
1688
1755
  this.configuration = {
@@ -1690,6 +1757,7 @@ var HocuspocusProvider = class extends EventEmitter {
1690
1757
  document: void 0,
1691
1758
  awareness: void 0,
1692
1759
  token: null,
1760
+ sessionAwareness: true,
1693
1761
  forceSyncInterval: false,
1694
1762
  onAuthenticated: () => null,
1695
1763
  onAuthenticationFailed: () => null,
@@ -1713,6 +1781,7 @@ var HocuspocusProvider = class extends EventEmitter {
1713
1781
  this.authorizedScope = void 0;
1714
1782
  this.manageSocket = false;
1715
1783
  this._isAttached = false;
1784
+ this.sessionId = Math.random().toString(36).slice(2);
1716
1785
  this.intervals = { forceSync: null };
1717
1786
  this.boundDocumentUpdateHandler = this.documentUpdateHandler.bind(this);
1718
1787
  this.boundAwarenessUpdateHandler = this.awarenessUpdateHandler.bind(this);
@@ -1789,7 +1858,7 @@ var HocuspocusProvider = class extends EventEmitter {
1789
1858
  this.resetUnsyncedChanges();
1790
1859
  this.send(SyncStepOneMessage, {
1791
1860
  document: this.document,
1792
- documentName: this.configuration.name
1861
+ documentName: this.effectiveName
1793
1862
  });
1794
1863
  }
1795
1864
  pageHide() {
@@ -1801,7 +1870,7 @@ var HocuspocusProvider = class extends EventEmitter {
1801
1870
  }
1802
1871
  sendStateless(payload) {
1803
1872
  this.send(StatelessMessage, {
1804
- documentName: this.configuration.name,
1873
+ documentName: this.effectiveName,
1805
1874
  payload
1806
1875
  });
1807
1876
  }
@@ -1815,7 +1884,7 @@ var HocuspocusProvider = class extends EventEmitter {
1815
1884
  }
1816
1885
  this.send(AuthenticationMessage, {
1817
1886
  token: token ?? "",
1818
- documentName: this.configuration.name
1887
+ documentName: this.effectiveName
1819
1888
  });
1820
1889
  }
1821
1890
  documentUpdateHandler(update, origin) {
@@ -1823,7 +1892,7 @@ var HocuspocusProvider = class extends EventEmitter {
1823
1892
  this.incrementUnsyncedChanges();
1824
1893
  this.send(UpdateMessage, {
1825
1894
  update,
1826
- documentName: this.configuration.name
1895
+ documentName: this.effectiveName
1827
1896
  });
1828
1897
  }
1829
1898
  awarenessUpdateHandler({ added, updated, removed }, origin) {
@@ -1831,7 +1900,7 @@ var HocuspocusProvider = class extends EventEmitter {
1831
1900
  this.send(AwarenessMessage, {
1832
1901
  awareness: this.awareness,
1833
1902
  clients: changedClients,
1834
- documentName: this.configuration.name
1903
+ documentName: this.effectiveName
1835
1904
  });
1836
1905
  }
1837
1906
  /**
@@ -1873,12 +1942,12 @@ var HocuspocusProvider = class extends EventEmitter {
1873
1942
  this.resetUnsyncedChanges();
1874
1943
  this.send(SyncStepOneMessage, {
1875
1944
  document: this.document,
1876
- documentName: this.configuration.name
1945
+ documentName: this.effectiveName
1877
1946
  });
1878
1947
  if (this.awareness && this.awareness.getLocalState() !== null) this.send(AwarenessMessage, {
1879
1948
  awareness: this.awareness,
1880
1949
  clients: [this.document.clientID],
1881
- documentName: this.configuration.name
1950
+ documentName: this.effectiveName
1882
1951
  });
1883
1952
  }
1884
1953
  send(message, args) {
@@ -1889,8 +1958,8 @@ var HocuspocusProvider = class extends EventEmitter {
1889
1958
  }
1890
1959
  onMessage(event) {
1891
1960
  const message = new IncomingMessage(event.data);
1892
- const documentName = message.readVarString();
1893
- message.writeVarString(documentName);
1961
+ const { documentName } = (0, _hocuspocus_common.parseRoutingKey)(message.readVarString());
1962
+ message.writeVarString(this.effectiveName);
1894
1963
  this.emit("message", {
1895
1964
  event,
1896
1965
  message: new IncomingMessage(event.data)