@hocuspocus/provider 1.0.0-alpha.28 → 1.0.0-alpha.29
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 +117 -337
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +115 -335
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/packages/common/src/CloseEvents.d.ts +23 -0
- package/dist/packages/common/src/index.d.ts +1 -0
- package/dist/packages/provider/src/HocuspocusCloudProvider.d.ts +4 -3
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +9 -4
- package/dist/packages/server/src/Connection.d.ts +1 -1
- package/dist/packages/server/src/Hocuspocus.d.ts +9 -2
- package/dist/packages/server/src/types.d.ts +5 -8
- package/package.json +3 -2
- package/src/HocuspocusCloudProvider.ts +18 -10
- package/src/HocuspocusProvider.ts +86 -62
- package/dist/packages/server/src/CloseEvents.d.ts +0 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Y from 'yjs';
|
|
2
2
|
import { retry } from '@lifeomic/attempt';
|
|
3
|
+
import { readAuthMessage, writeAuthentication, Unauthorized, Forbidden } from '@hocuspocus/common';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Utility module to work with key-value stores.
|
|
@@ -277,8 +278,8 @@ const min = (a, b) => a < b ? a : b;
|
|
|
277
278
|
const max = (a, b) => a > b ? a : b;
|
|
278
279
|
|
|
279
280
|
/* eslint-env browser */
|
|
280
|
-
const BIT8
|
|
281
|
-
const BITS7
|
|
281
|
+
const BIT8 = 128;
|
|
282
|
+
const BITS7 = 127;
|
|
282
283
|
|
|
283
284
|
/**
|
|
284
285
|
* Efficient schema-less binary encoding with support for variable length encoding.
|
|
@@ -369,7 +370,7 @@ const toUint8Array = encoder => {
|
|
|
369
370
|
* @param {Encoder} encoder
|
|
370
371
|
* @param {number} num The byte that is to be encoded.
|
|
371
372
|
*/
|
|
372
|
-
const write
|
|
373
|
+
const write = (encoder, num) => {
|
|
373
374
|
const bufferLen = encoder.cbuf.length;
|
|
374
375
|
if (encoder.cpos === bufferLen) {
|
|
375
376
|
encoder.bufs.push(encoder.cbuf);
|
|
@@ -388,12 +389,12 @@ const write$1 = (encoder, num) => {
|
|
|
388
389
|
* @param {Encoder} encoder
|
|
389
390
|
* @param {number} num The number that is to be encoded.
|
|
390
391
|
*/
|
|
391
|
-
const writeVarUint
|
|
392
|
-
while (num > BITS7
|
|
393
|
-
write
|
|
392
|
+
const writeVarUint = (encoder, num) => {
|
|
393
|
+
while (num > BITS7) {
|
|
394
|
+
write(encoder, BIT8 | (BITS7 & num));
|
|
394
395
|
num >>>= 7;
|
|
395
396
|
}
|
|
396
|
-
write
|
|
397
|
+
write(encoder, BITS7 & num);
|
|
397
398
|
};
|
|
398
399
|
|
|
399
400
|
/**
|
|
@@ -403,12 +404,12 @@ const writeVarUint$1 = (encoder, num) => {
|
|
|
403
404
|
* @param {Encoder} encoder
|
|
404
405
|
* @param {String} str The string that is to be encoded.
|
|
405
406
|
*/
|
|
406
|
-
const writeVarString
|
|
407
|
+
const writeVarString = (encoder, str) => {
|
|
407
408
|
const encodedString = unescape(encodeURIComponent(str));
|
|
408
409
|
const len = encodedString.length;
|
|
409
|
-
writeVarUint
|
|
410
|
+
writeVarUint(encoder, len);
|
|
410
411
|
for (let i = 0; i < len; i++) {
|
|
411
|
-
write
|
|
412
|
+
write(encoder, /** @type {number} */ (encodedString.codePointAt(i)));
|
|
412
413
|
}
|
|
413
414
|
};
|
|
414
415
|
|
|
@@ -446,7 +447,7 @@ const writeUint8Array = (encoder, uint8Array) => {
|
|
|
446
447
|
* @param {Uint8Array} uint8Array
|
|
447
448
|
*/
|
|
448
449
|
const writeVarUint8Array = (encoder, uint8Array) => {
|
|
449
|
-
writeVarUint
|
|
450
|
+
writeVarUint(encoder, uint8Array.byteLength);
|
|
450
451
|
writeUint8Array(encoder, uint8Array);
|
|
451
452
|
};
|
|
452
453
|
|
|
@@ -535,7 +536,7 @@ const readUint8Array = (decoder, len) => {
|
|
|
535
536
|
* @param {Decoder} decoder
|
|
536
537
|
* @return {Uint8Array}
|
|
537
538
|
*/
|
|
538
|
-
const readVarUint8Array = decoder => readUint8Array(decoder, readVarUint
|
|
539
|
+
const readVarUint8Array = decoder => readUint8Array(decoder, readVarUint(decoder));
|
|
539
540
|
|
|
540
541
|
/**
|
|
541
542
|
* Read one byte as unsigned integer.
|
|
@@ -543,7 +544,7 @@ const readVarUint8Array = decoder => readUint8Array(decoder, readVarUint$1(decod
|
|
|
543
544
|
* @param {Decoder} decoder The decoder instance
|
|
544
545
|
* @return {number} Unsigned 8-bit integer
|
|
545
546
|
*/
|
|
546
|
-
const readUint8
|
|
547
|
+
const readUint8 = decoder => decoder.arr[decoder.pos++];
|
|
547
548
|
|
|
548
549
|
/**
|
|
549
550
|
* Read unsigned integer (32bit) with variable length.
|
|
@@ -555,14 +556,14 @@ const readUint8$1 = decoder => decoder.arr[decoder.pos++];
|
|
|
555
556
|
* @param {Decoder} decoder
|
|
556
557
|
* @return {number} An unsigned integer.length
|
|
557
558
|
*/
|
|
558
|
-
const readVarUint
|
|
559
|
+
const readVarUint = decoder => {
|
|
559
560
|
let num = 0;
|
|
560
561
|
let len = 0;
|
|
561
562
|
while (true) {
|
|
562
563
|
const r = decoder.arr[decoder.pos++];
|
|
563
|
-
num = num | ((r & BITS7
|
|
564
|
+
num = num | ((r & BITS7) << len);
|
|
564
565
|
len += 7;
|
|
565
|
-
if (r < BIT8
|
|
566
|
+
if (r < BIT8) {
|
|
566
567
|
return num >>> 0 // return unsigned number!
|
|
567
568
|
}
|
|
568
569
|
/* istanbul ignore if */
|
|
@@ -585,15 +586,15 @@ const readVarUint$1 = decoder => {
|
|
|
585
586
|
* @param {Decoder} decoder
|
|
586
587
|
* @return {String} The read String.
|
|
587
588
|
*/
|
|
588
|
-
const readVarString
|
|
589
|
-
let remainingLen = readVarUint
|
|
589
|
+
const readVarString = decoder => {
|
|
590
|
+
let remainingLen = readVarUint(decoder);
|
|
590
591
|
if (remainingLen === 0) {
|
|
591
592
|
return ''
|
|
592
593
|
} else {
|
|
593
|
-
let encodedString = String.fromCodePoint(readUint8
|
|
594
|
+
let encodedString = String.fromCodePoint(readUint8(decoder)); // remember to decrease remainingLen
|
|
594
595
|
if (--remainingLen < 100) { // do not create a Uint8Array for small strings
|
|
595
596
|
while (remainingLen--) {
|
|
596
|
-
encodedString += String.fromCodePoint(readUint8
|
|
597
|
+
encodedString += String.fromCodePoint(readUint8(decoder));
|
|
597
598
|
}
|
|
598
599
|
} else {
|
|
599
600
|
while (remainingLen > 0) {
|
|
@@ -1206,14 +1207,14 @@ const removeAwarenessStates = (awareness, clients, origin) => {
|
|
|
1206
1207
|
const encodeAwarenessUpdate = (awareness, clients, states = awareness.states) => {
|
|
1207
1208
|
const len = clients.length;
|
|
1208
1209
|
const encoder = createEncoder();
|
|
1209
|
-
writeVarUint
|
|
1210
|
+
writeVarUint(encoder, len);
|
|
1210
1211
|
for (let i = 0; i < len; i++) {
|
|
1211
1212
|
const clientID = clients[i];
|
|
1212
1213
|
const state = states.get(clientID) || null;
|
|
1213
1214
|
const clock = /** @type {MetaClientState} */ (awareness.meta.get(clientID)).clock;
|
|
1214
|
-
writeVarUint
|
|
1215
|
-
writeVarUint
|
|
1216
|
-
writeVarString
|
|
1215
|
+
writeVarUint(encoder, clientID);
|
|
1216
|
+
writeVarUint(encoder, clock);
|
|
1217
|
+
writeVarString(encoder, JSON.stringify(state));
|
|
1217
1218
|
}
|
|
1218
1219
|
return toUint8Array(encoder)
|
|
1219
1220
|
};
|
|
@@ -1230,11 +1231,11 @@ const applyAwarenessUpdate = (awareness, update, origin) => {
|
|
|
1230
1231
|
const updated = [];
|
|
1231
1232
|
const filteredUpdated = [];
|
|
1232
1233
|
const removed = [];
|
|
1233
|
-
const len = readVarUint
|
|
1234
|
+
const len = readVarUint(decoder);
|
|
1234
1235
|
for (let i = 0; i < len; i++) {
|
|
1235
|
-
const clientID = readVarUint
|
|
1236
|
-
let clock = readVarUint
|
|
1237
|
-
const state = JSON.parse(readVarString
|
|
1236
|
+
const clientID = readVarUint(decoder);
|
|
1237
|
+
let clock = readVarUint(decoder);
|
|
1238
|
+
const state = JSON.parse(readVarString(decoder));
|
|
1238
1239
|
const clientMeta = awareness.meta.get(clientID);
|
|
1239
1240
|
const prevState = awareness.states.get(clientID);
|
|
1240
1241
|
const currClock = clientMeta === undefined ? 0 : clientMeta.clock;
|
|
@@ -1378,13 +1379,13 @@ class IncomingMessage {
|
|
|
1378
1379
|
this.decoder = createDecoder(new Uint8Array(this.data));
|
|
1379
1380
|
}
|
|
1380
1381
|
readVarUint() {
|
|
1381
|
-
return readVarUint
|
|
1382
|
+
return readVarUint(this.decoder);
|
|
1382
1383
|
}
|
|
1383
1384
|
readVarUint8Array() {
|
|
1384
1385
|
return readVarUint8Array(this.decoder);
|
|
1385
1386
|
}
|
|
1386
1387
|
writeVarUint(type) {
|
|
1387
|
-
return writeVarUint
|
|
1388
|
+
return writeVarUint(this.encoder, type);
|
|
1388
1389
|
}
|
|
1389
1390
|
writeVarUint8Array(data) {
|
|
1390
1391
|
return writeVarUint8Array(this.encoder, data);
|
|
@@ -1438,7 +1439,7 @@ const messageYjsUpdate = 2;
|
|
|
1438
1439
|
* @param {Y.Doc} doc
|
|
1439
1440
|
*/
|
|
1440
1441
|
const writeSyncStep1 = (encoder, doc) => {
|
|
1441
|
-
writeVarUint
|
|
1442
|
+
writeVarUint(encoder, messageYjsSyncStep1);
|
|
1442
1443
|
const sv = Y.encodeStateVector(doc);
|
|
1443
1444
|
writeVarUint8Array(encoder, sv);
|
|
1444
1445
|
};
|
|
@@ -1449,7 +1450,7 @@ const writeSyncStep1 = (encoder, doc) => {
|
|
|
1449
1450
|
* @param {Uint8Array} [encodedStateVector]
|
|
1450
1451
|
*/
|
|
1451
1452
|
const writeSyncStep2 = (encoder, doc, encodedStateVector) => {
|
|
1452
|
-
writeVarUint
|
|
1453
|
+
writeVarUint(encoder, messageYjsSyncStep2);
|
|
1453
1454
|
writeVarUint8Array(encoder, Y.encodeStateAsUpdate(doc, encodedStateVector));
|
|
1454
1455
|
};
|
|
1455
1456
|
|
|
@@ -1484,7 +1485,7 @@ const readSyncStep2 = (decoder, doc, transactionOrigin) => {
|
|
|
1484
1485
|
* @param {Uint8Array} update
|
|
1485
1486
|
*/
|
|
1486
1487
|
const writeUpdate = (encoder, update) => {
|
|
1487
|
-
writeVarUint
|
|
1488
|
+
writeVarUint(encoder, messageYjsUpdate);
|
|
1488
1489
|
writeVarUint8Array(encoder, update);
|
|
1489
1490
|
};
|
|
1490
1491
|
|
|
@@ -1504,7 +1505,7 @@ const readUpdate = readSyncStep2;
|
|
|
1504
1505
|
* @param {any} transactionOrigin
|
|
1505
1506
|
*/
|
|
1506
1507
|
const readSyncMessage = (decoder, encoder, doc, transactionOrigin) => {
|
|
1507
|
-
const messageType = readVarUint
|
|
1508
|
+
const messageType = readVarUint(decoder);
|
|
1508
1509
|
switch (messageType) {
|
|
1509
1510
|
case messageYjsSyncStep1:
|
|
1510
1511
|
readSyncStep1(decoder, encoder, doc);
|
|
@@ -1521,239 +1522,6 @@ const readSyncMessage = (decoder, encoder, doc, transactionOrigin) => {
|
|
|
1521
1522
|
return messageType
|
|
1522
1523
|
};
|
|
1523
1524
|
|
|
1524
|
-
/* eslint-env browser */
|
|
1525
|
-
const BIT8 = 128;
|
|
1526
|
-
const BITS7 = 127;
|
|
1527
|
-
/**
|
|
1528
|
-
* Efficient schema-less binary decoding with support for variable length encoding.
|
|
1529
|
-
*
|
|
1530
|
-
* Use [lib0/decoding] with [lib0/encoding]. Every encoding function has a corresponding decoding function.
|
|
1531
|
-
*
|
|
1532
|
-
* Encodes numbers in little-endian order (least to most significant byte order)
|
|
1533
|
-
* and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
|
|
1534
|
-
* which is also used in Protocol Buffers.
|
|
1535
|
-
*
|
|
1536
|
-
* ```js
|
|
1537
|
-
* // encoding step
|
|
1538
|
-
* const encoder = new encoding.createEncoder()
|
|
1539
|
-
* encoding.writeVarUint(encoder, 256)
|
|
1540
|
-
* encoding.writeVarString(encoder, 'Hello world!')
|
|
1541
|
-
* const buf = encoding.toUint8Array(encoder)
|
|
1542
|
-
* ```
|
|
1543
|
-
*
|
|
1544
|
-
* ```js
|
|
1545
|
-
* // decoding step
|
|
1546
|
-
* const decoder = new decoding.createDecoder(buf)
|
|
1547
|
-
* decoding.readVarUint(decoder) // => 256
|
|
1548
|
-
* decoding.readVarString(decoder) // => 'Hello world!'
|
|
1549
|
-
* decoding.hasContent(decoder) // => false - all data is read
|
|
1550
|
-
* ```
|
|
1551
|
-
*
|
|
1552
|
-
* @module decoding
|
|
1553
|
-
*/
|
|
1554
|
-
|
|
1555
|
-
/**
|
|
1556
|
-
* Read one byte as unsigned integer.
|
|
1557
|
-
* @function
|
|
1558
|
-
* @param {Decoder} decoder The decoder instance
|
|
1559
|
-
* @return {number} Unsigned 8-bit integer
|
|
1560
|
-
*/
|
|
1561
|
-
|
|
1562
|
-
const readUint8 = decoder => decoder.arr[decoder.pos++];
|
|
1563
|
-
/**
|
|
1564
|
-
* Read unsigned integer (32bit) with variable length.
|
|
1565
|
-
* 1/8th of the storage is used as encoding overhead.
|
|
1566
|
-
* * numbers < 2^7 is stored in one bytlength
|
|
1567
|
-
* * numbers < 2^14 is stored in two bylength
|
|
1568
|
-
*
|
|
1569
|
-
* @function
|
|
1570
|
-
* @param {Decoder} decoder
|
|
1571
|
-
* @return {number} An unsigned integer.length
|
|
1572
|
-
*/
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
const readVarUint = decoder => {
|
|
1576
|
-
let num = 0;
|
|
1577
|
-
let len = 0;
|
|
1578
|
-
|
|
1579
|
-
while (true) {
|
|
1580
|
-
const r = decoder.arr[decoder.pos++];
|
|
1581
|
-
num = num | (r & BITS7) << len;
|
|
1582
|
-
len += 7;
|
|
1583
|
-
|
|
1584
|
-
if (r < BIT8) {
|
|
1585
|
-
return num >>> 0; // return unsigned number!
|
|
1586
|
-
}
|
|
1587
|
-
/* istanbul ignore if */
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
if (len > 35) {
|
|
1591
|
-
throw new Error('Integer out of range!');
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
1594
|
-
};
|
|
1595
|
-
/**
|
|
1596
|
-
* Read string of variable length
|
|
1597
|
-
* * varUint is used to store the length of the string
|
|
1598
|
-
*
|
|
1599
|
-
* Transforming utf8 to a string is pretty expensive. The code performs 10x better
|
|
1600
|
-
* when String.fromCodePoint is fed with all characters as arguments.
|
|
1601
|
-
* But most environments have a maximum number of arguments per functions.
|
|
1602
|
-
* For effiency reasons we apply a maximum of 10000 characters at once.
|
|
1603
|
-
*
|
|
1604
|
-
* @function
|
|
1605
|
-
* @param {Decoder} decoder
|
|
1606
|
-
* @return {String} The read String.
|
|
1607
|
-
*/
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
const readVarString = decoder => {
|
|
1611
|
-
let remainingLen = readVarUint(decoder);
|
|
1612
|
-
|
|
1613
|
-
if (remainingLen === 0) {
|
|
1614
|
-
return '';
|
|
1615
|
-
} else {
|
|
1616
|
-
let encodedString = String.fromCodePoint(readUint8(decoder)); // remember to decrease remainingLen
|
|
1617
|
-
|
|
1618
|
-
if (--remainingLen < 100) {
|
|
1619
|
-
// do not create a Uint8Array for small strings
|
|
1620
|
-
while (remainingLen--) {
|
|
1621
|
-
encodedString += String.fromCodePoint(readUint8(decoder));
|
|
1622
|
-
}
|
|
1623
|
-
} else {
|
|
1624
|
-
while (remainingLen > 0) {
|
|
1625
|
-
const nextLen = remainingLen < 10000 ? remainingLen : 10000; // this is dangerous, we create a fresh array view from the existing buffer
|
|
1626
|
-
|
|
1627
|
-
const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen);
|
|
1628
|
-
decoder.pos += nextLen; // Starting with ES5.1 we can supply a generic array-like object as arguments
|
|
1629
|
-
|
|
1630
|
-
encodedString += String.fromCodePoint.apply(null,
|
|
1631
|
-
/** @type {any} */
|
|
1632
|
-
bytes);
|
|
1633
|
-
remainingLen -= nextLen;
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
|
|
1637
|
-
return decodeURIComponent(escape(encodedString));
|
|
1638
|
-
}
|
|
1639
|
-
};
|
|
1640
|
-
/**
|
|
1641
|
-
* Efficient schema-less binary encoding with support for variable length encoding.
|
|
1642
|
-
*
|
|
1643
|
-
* Use [lib0/encoding] with [lib0/decoding]. Every encoding function has a corresponding decoding function.
|
|
1644
|
-
*
|
|
1645
|
-
* Encodes numbers in little-endian order (least to most significant byte order)
|
|
1646
|
-
* and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
|
|
1647
|
-
* which is also used in Protocol Buffers.
|
|
1648
|
-
*
|
|
1649
|
-
* ```js
|
|
1650
|
-
* // encoding step
|
|
1651
|
-
* const encoder = new encoding.createEncoder()
|
|
1652
|
-
* encoding.writeVarUint(encoder, 256)
|
|
1653
|
-
* encoding.writeVarString(encoder, 'Hello world!')
|
|
1654
|
-
* const buf = encoding.toUint8Array(encoder)
|
|
1655
|
-
* ```
|
|
1656
|
-
*
|
|
1657
|
-
* ```js
|
|
1658
|
-
* // decoding step
|
|
1659
|
-
* const decoder = new decoding.createDecoder(buf)
|
|
1660
|
-
* decoding.readVarUint(decoder) // => 256
|
|
1661
|
-
* decoding.readVarString(decoder) // => 'Hello world!'
|
|
1662
|
-
* decoding.hasContent(decoder) // => false - all data is read
|
|
1663
|
-
* ```
|
|
1664
|
-
*
|
|
1665
|
-
* @module encoding
|
|
1666
|
-
*/
|
|
1667
|
-
|
|
1668
|
-
/**
|
|
1669
|
-
* Write one byte to the encoder.
|
|
1670
|
-
*
|
|
1671
|
-
* @function
|
|
1672
|
-
* @param {Encoder} encoder
|
|
1673
|
-
* @param {number} num The byte that is to be encoded.
|
|
1674
|
-
*/
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
const write = (encoder, num) => {
|
|
1678
|
-
const bufferLen = encoder.cbuf.length;
|
|
1679
|
-
|
|
1680
|
-
if (encoder.cpos === bufferLen) {
|
|
1681
|
-
encoder.bufs.push(encoder.cbuf);
|
|
1682
|
-
encoder.cbuf = new Uint8Array(bufferLen * 2);
|
|
1683
|
-
encoder.cpos = 0;
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
encoder.cbuf[encoder.cpos++] = num;
|
|
1687
|
-
};
|
|
1688
|
-
/**
|
|
1689
|
-
* Write a variable length unsigned integer.
|
|
1690
|
-
*
|
|
1691
|
-
* Encodes integers in the range from [0, 4294967295] / [0, 0xffffffff]. (max 32 bit unsigned integer)
|
|
1692
|
-
*
|
|
1693
|
-
* @function
|
|
1694
|
-
* @param {Encoder} encoder
|
|
1695
|
-
* @param {number} num The number that is to be encoded.
|
|
1696
|
-
*/
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
const writeVarUint = (encoder, num) => {
|
|
1700
|
-
while (num > BITS7) {
|
|
1701
|
-
write(encoder, BIT8 | BITS7 & num);
|
|
1702
|
-
num >>>= 7;
|
|
1703
|
-
}
|
|
1704
|
-
|
|
1705
|
-
write(encoder, BITS7 & num);
|
|
1706
|
-
};
|
|
1707
|
-
/**
|
|
1708
|
-
* Write a variable length string.
|
|
1709
|
-
*
|
|
1710
|
-
* @function
|
|
1711
|
-
* @param {Encoder} encoder
|
|
1712
|
-
* @param {String} str The string that is to be encoded.
|
|
1713
|
-
*/
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
const writeVarString = (encoder, str) => {
|
|
1717
|
-
const encodedString = unescape(encodeURIComponent(str));
|
|
1718
|
-
const len = encodedString.length;
|
|
1719
|
-
writeVarUint(encoder, len);
|
|
1720
|
-
|
|
1721
|
-
for (let i = 0; i < len; i++) {
|
|
1722
|
-
write(encoder,
|
|
1723
|
-
/** @type {number} */
|
|
1724
|
-
encodedString.codePointAt(i));
|
|
1725
|
-
}
|
|
1726
|
-
};
|
|
1727
|
-
|
|
1728
|
-
var AuthMessageType;
|
|
1729
|
-
|
|
1730
|
-
(function (AuthMessageType) {
|
|
1731
|
-
AuthMessageType[AuthMessageType["Token"] = 0] = "Token";
|
|
1732
|
-
AuthMessageType[AuthMessageType["PermissionDenied"] = 1] = "PermissionDenied";
|
|
1733
|
-
AuthMessageType[AuthMessageType["Authenticated"] = 2] = "Authenticated";
|
|
1734
|
-
})(AuthMessageType || (AuthMessageType = {}));
|
|
1735
|
-
|
|
1736
|
-
const writeAuthentication = (encoder, auth) => {
|
|
1737
|
-
writeVarUint(encoder, AuthMessageType.Token);
|
|
1738
|
-
writeVarString(encoder, auth);
|
|
1739
|
-
};
|
|
1740
|
-
|
|
1741
|
-
const readAuthMessage = (decoder, permissionDeniedHandler, authenticatedHandler) => {
|
|
1742
|
-
switch (readVarUint(decoder)) {
|
|
1743
|
-
case AuthMessageType.PermissionDenied:
|
|
1744
|
-
{
|
|
1745
|
-
permissionDeniedHandler(readVarString(decoder));
|
|
1746
|
-
break;
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
|
-
case AuthMessageType.Authenticated:
|
|
1750
|
-
{
|
|
1751
|
-
authenticatedHandler();
|
|
1752
|
-
break;
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
};
|
|
1756
|
-
|
|
1757
1525
|
var MessageType;
|
|
1758
1526
|
(function (MessageType) {
|
|
1759
1527
|
MessageType[MessageType["Sync"] = 0] = "Sync";
|
|
@@ -1867,7 +1635,7 @@ class SyncStepOneMessage extends OutgoingMessage {
|
|
|
1867
1635
|
if (typeof args.document === 'undefined') {
|
|
1868
1636
|
throw new Error('The sync step one message requires document as an argument');
|
|
1869
1637
|
}
|
|
1870
|
-
writeVarUint
|
|
1638
|
+
writeVarUint(this.encoder, this.type);
|
|
1871
1639
|
writeSyncStep1(this.encoder, args.document);
|
|
1872
1640
|
return this.encoder;
|
|
1873
1641
|
}
|
|
@@ -1883,7 +1651,7 @@ class SyncStepTwoMessage extends OutgoingMessage {
|
|
|
1883
1651
|
if (typeof args.document === 'undefined') {
|
|
1884
1652
|
throw new Error('The sync step two message requires document as an argument');
|
|
1885
1653
|
}
|
|
1886
|
-
writeVarUint
|
|
1654
|
+
writeVarUint(this.encoder, this.type);
|
|
1887
1655
|
writeSyncStep2(this.encoder, args.document);
|
|
1888
1656
|
return this.encoder;
|
|
1889
1657
|
}
|
|
@@ -1896,7 +1664,7 @@ class QueryAwarenessMessage extends OutgoingMessage {
|
|
|
1896
1664
|
this.description = 'Queries awareness states';
|
|
1897
1665
|
}
|
|
1898
1666
|
get(args) {
|
|
1899
|
-
writeVarUint
|
|
1667
|
+
writeVarUint(this.encoder, this.type);
|
|
1900
1668
|
return this.encoder;
|
|
1901
1669
|
}
|
|
1902
1670
|
}
|
|
@@ -1911,7 +1679,7 @@ class AuthenticationMessage extends OutgoingMessage {
|
|
|
1911
1679
|
if (typeof args.token === 'undefined') {
|
|
1912
1680
|
throw new Error('The authentication message requires `token` as an argument.');
|
|
1913
1681
|
}
|
|
1914
|
-
writeVarUint
|
|
1682
|
+
writeVarUint(this.encoder, this.type);
|
|
1915
1683
|
writeAuthentication(this.encoder, args.token);
|
|
1916
1684
|
return this.encoder;
|
|
1917
1685
|
}
|
|
@@ -1930,7 +1698,7 @@ class AwarenessMessage extends OutgoingMessage {
|
|
|
1930
1698
|
if (typeof args.clients === 'undefined') {
|
|
1931
1699
|
throw new Error('The awareness message requires clients as an argument');
|
|
1932
1700
|
}
|
|
1933
|
-
writeVarUint
|
|
1701
|
+
writeVarUint(this.encoder, this.type);
|
|
1934
1702
|
let awarenessUpdate;
|
|
1935
1703
|
if (args.states === undefined) {
|
|
1936
1704
|
awarenessUpdate = encodeAwarenessUpdate(args.awareness, args.clients);
|
|
@@ -1950,7 +1718,7 @@ class UpdateMessage extends OutgoingMessage {
|
|
|
1950
1718
|
this.description = 'A document update';
|
|
1951
1719
|
}
|
|
1952
1720
|
get(args) {
|
|
1953
|
-
writeVarUint
|
|
1721
|
+
writeVarUint(this.encoder, this.type);
|
|
1954
1722
|
writeUpdate(this.encoder, args.update);
|
|
1955
1723
|
return this.encoder;
|
|
1956
1724
|
}
|
|
@@ -1972,16 +1740,16 @@ var WebSocketStatus;
|
|
|
1972
1740
|
WebSocketStatus["Disconnected"] = "disconnected";
|
|
1973
1741
|
})(WebSocketStatus || (WebSocketStatus = {}));
|
|
1974
1742
|
class HocuspocusProvider extends EventEmitter {
|
|
1975
|
-
constructor(
|
|
1743
|
+
constructor(configuration) {
|
|
1976
1744
|
super();
|
|
1977
|
-
this.
|
|
1745
|
+
this.configuration = {
|
|
1746
|
+
name: '',
|
|
1747
|
+
url: '',
|
|
1978
1748
|
// @ts-ignore
|
|
1979
1749
|
document: undefined,
|
|
1980
1750
|
// @ts-ignore
|
|
1981
1751
|
awareness: undefined,
|
|
1982
1752
|
WebSocketPolyfill: undefined,
|
|
1983
|
-
url: '',
|
|
1984
|
-
name: '',
|
|
1985
1753
|
token: null,
|
|
1986
1754
|
parameters: {},
|
|
1987
1755
|
connect: true,
|
|
@@ -2018,6 +1786,7 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2018
1786
|
onDestroy: () => null,
|
|
2019
1787
|
onAwarenessUpdate: () => null,
|
|
2020
1788
|
onAwarenessChange: () => null,
|
|
1789
|
+
quiet: false,
|
|
2021
1790
|
};
|
|
2022
1791
|
this.subscribedToBroadcastChannel = false;
|
|
2023
1792
|
this.webSocket = null;
|
|
@@ -2032,23 +1801,23 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2032
1801
|
connectionChecker: null,
|
|
2033
1802
|
};
|
|
2034
1803
|
this.connectionAttempt = null;
|
|
2035
|
-
this.
|
|
2036
|
-
this.
|
|
2037
|
-
this.
|
|
2038
|
-
this.
|
|
2039
|
-
this.on('open', this.
|
|
2040
|
-
this.on('authenticated', this.
|
|
2041
|
-
this.on('authenticationFailed', this.
|
|
2042
|
-
this.on('connect', this.
|
|
2043
|
-
this.on('message', this.
|
|
2044
|
-
this.on('outgoingMessage', this.
|
|
2045
|
-
this.on('synced', this.
|
|
2046
|
-
this.on('status', this.
|
|
2047
|
-
this.on('disconnect', this.
|
|
2048
|
-
this.on('close', this.
|
|
2049
|
-
this.on('destroy', this.
|
|
2050
|
-
this.on('awarenessUpdate', this.
|
|
2051
|
-
this.on('awarenessChange', this.
|
|
1804
|
+
this.setConfiguration(configuration);
|
|
1805
|
+
this.configuration.document = configuration.document ? configuration.document : new Y.Doc();
|
|
1806
|
+
this.configuration.awareness = configuration.awareness ? configuration.awareness : new Awareness(this.document);
|
|
1807
|
+
this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill ? configuration.WebSocketPolyfill : WebSocket;
|
|
1808
|
+
this.on('open', this.configuration.onOpen);
|
|
1809
|
+
this.on('authenticated', this.configuration.onAuthenticated);
|
|
1810
|
+
this.on('authenticationFailed', this.configuration.onAuthenticationFailed);
|
|
1811
|
+
this.on('connect', this.configuration.onConnect);
|
|
1812
|
+
this.on('message', this.configuration.onMessage);
|
|
1813
|
+
this.on('outgoingMessage', this.configuration.onOutgoingMessage);
|
|
1814
|
+
this.on('synced', this.configuration.onSynced);
|
|
1815
|
+
this.on('status', this.configuration.onStatus);
|
|
1816
|
+
this.on('disconnect', this.configuration.onDisconnect);
|
|
1817
|
+
this.on('close', this.configuration.onClose);
|
|
1818
|
+
this.on('destroy', this.configuration.onDestroy);
|
|
1819
|
+
this.on('awarenessUpdate', this.configuration.onAwarenessUpdate);
|
|
1820
|
+
this.on('awarenessChange', this.configuration.onAwarenessChange);
|
|
2052
1821
|
this.awareness.on('update', () => {
|
|
2053
1822
|
this.emit('awarenessUpdate', { states: awarenessStatesToArray(this.awareness.getStates()) });
|
|
2054
1823
|
});
|
|
@@ -2058,20 +1827,20 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2058
1827
|
this.document.on('update', this.documentUpdateHandler.bind(this));
|
|
2059
1828
|
this.awareness.on('update', this.awarenessUpdateHandler.bind(this));
|
|
2060
1829
|
this.registerEventListeners();
|
|
2061
|
-
this.intervals.connectionChecker = setInterval(this.checkConnection.bind(this), this.
|
|
2062
|
-
if (this.
|
|
2063
|
-
this.intervals.forceSync = setInterval(this.forceSync.bind(this), this.
|
|
1830
|
+
this.intervals.connectionChecker = setInterval(this.checkConnection.bind(this), this.configuration.messageReconnectTimeout / 10);
|
|
1831
|
+
if (this.configuration.forceSyncInterval) {
|
|
1832
|
+
this.intervals.forceSync = setInterval(this.forceSync.bind(this), this.configuration.forceSyncInterval);
|
|
2064
1833
|
}
|
|
2065
|
-
if (typeof
|
|
2066
|
-
this.shouldConnect =
|
|
1834
|
+
if (typeof configuration.connect !== 'undefined') {
|
|
1835
|
+
this.shouldConnect = configuration.connect;
|
|
2067
1836
|
}
|
|
2068
1837
|
if (!this.shouldConnect) {
|
|
2069
1838
|
return;
|
|
2070
1839
|
}
|
|
2071
1840
|
this.connect();
|
|
2072
1841
|
}
|
|
2073
|
-
|
|
2074
|
-
this.
|
|
1842
|
+
setConfiguration(configuration = {}) {
|
|
1843
|
+
this.configuration = { ...this.configuration, ...configuration };
|
|
2075
1844
|
}
|
|
2076
1845
|
async connect() {
|
|
2077
1846
|
if (this.status === WebSocketStatus.Connected) {
|
|
@@ -2081,14 +1850,14 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2081
1850
|
this.subscribeToBroadcastChannel();
|
|
2082
1851
|
try {
|
|
2083
1852
|
await retry(this.createWebSocketConnection.bind(this), {
|
|
2084
|
-
delay: this.
|
|
2085
|
-
initialDelay: this.
|
|
2086
|
-
factor: this.
|
|
2087
|
-
maxAttempts: this.
|
|
2088
|
-
minDelay: this.
|
|
2089
|
-
maxDelay: this.
|
|
2090
|
-
jitter: this.
|
|
2091
|
-
timeout: this.
|
|
1853
|
+
delay: this.configuration.delay,
|
|
1854
|
+
initialDelay: this.configuration.initialDelay,
|
|
1855
|
+
factor: this.configuration.factor,
|
|
1856
|
+
maxAttempts: this.configuration.maxAttempts,
|
|
1857
|
+
minDelay: this.configuration.minDelay,
|
|
1858
|
+
maxDelay: this.configuration.maxDelay,
|
|
1859
|
+
jitter: this.configuration.jitter,
|
|
1860
|
+
timeout: this.configuration.timeout,
|
|
2092
1861
|
beforeAttempt: context => {
|
|
2093
1862
|
if (!this.shouldConnect) {
|
|
2094
1863
|
context.abort();
|
|
@@ -2107,7 +1876,7 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2107
1876
|
createWebSocketConnection() {
|
|
2108
1877
|
return new Promise((resolve, reject) => {
|
|
2109
1878
|
// Init the WebSocket connection
|
|
2110
|
-
const ws = new this.
|
|
1879
|
+
const ws = new this.configuration.WebSocketPolyfill(this.url);
|
|
2111
1880
|
ws.binaryType = 'arraybuffer';
|
|
2112
1881
|
ws.onmessage = this.onMessage.bind(this);
|
|
2113
1882
|
ws.onclose = this.onClose.bind(this);
|
|
@@ -2138,10 +1907,10 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2138
1907
|
this.connectionAttempt = null;
|
|
2139
1908
|
}
|
|
2140
1909
|
get document() {
|
|
2141
|
-
return this.
|
|
1910
|
+
return this.configuration.document;
|
|
2142
1911
|
}
|
|
2143
1912
|
get awareness() {
|
|
2144
|
-
return this.
|
|
1913
|
+
return this.configuration.awareness;
|
|
2145
1914
|
}
|
|
2146
1915
|
checkConnection() {
|
|
2147
1916
|
var _a;
|
|
@@ -2154,7 +1923,7 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2154
1923
|
return;
|
|
2155
1924
|
}
|
|
2156
1925
|
// Don’t close the connection when a message was received recently
|
|
2157
|
-
if (this.
|
|
1926
|
+
if (this.configuration.messageReconnectTimeout >= getUnixTime() - this.lastMessageReceived) {
|
|
2158
1927
|
return;
|
|
2159
1928
|
}
|
|
2160
1929
|
// No message received in a long time, not even your own
|
|
@@ -2201,14 +1970,14 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2201
1970
|
}
|
|
2202
1971
|
// Ensure that the URL always ends with /
|
|
2203
1972
|
get serverUrl() {
|
|
2204
|
-
while (this.
|
|
2205
|
-
return this.
|
|
1973
|
+
while (this.configuration.url[this.configuration.url.length - 1] === '/') {
|
|
1974
|
+
return this.configuration.url.slice(0, this.configuration.url.length - 1);
|
|
2206
1975
|
}
|
|
2207
|
-
return this.
|
|
1976
|
+
return this.configuration.url;
|
|
2208
1977
|
}
|
|
2209
1978
|
get url() {
|
|
2210
|
-
const encodedParams = encodeQueryParams(this.
|
|
2211
|
-
return `${this.serverUrl}/${this.
|
|
1979
|
+
const encodedParams = encodeQueryParams(this.configuration.parameters);
|
|
1980
|
+
return `${this.serverUrl}/${this.configuration.name}${encodedParams.length === 0 ? '' : `?${encodedParams}`}`;
|
|
2212
1981
|
}
|
|
2213
1982
|
get synced() {
|
|
2214
1983
|
return this.isSynced;
|
|
@@ -2222,7 +1991,7 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2222
1991
|
this.emit('sync', { state });
|
|
2223
1992
|
}
|
|
2224
1993
|
get isAuthenticationRequired() {
|
|
2225
|
-
return !!this.
|
|
1994
|
+
return !!this.configuration.token && !this.isAuthenticated;
|
|
2226
1995
|
}
|
|
2227
1996
|
disconnect() {
|
|
2228
1997
|
this.shouldConnect = false;
|
|
@@ -2244,11 +2013,11 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2244
2013
|
}
|
|
2245
2014
|
}
|
|
2246
2015
|
async getToken() {
|
|
2247
|
-
if (typeof this.
|
|
2248
|
-
const token = await this.
|
|
2016
|
+
if (typeof this.configuration.token === 'function') {
|
|
2017
|
+
const token = await this.configuration.token();
|
|
2249
2018
|
return token;
|
|
2250
2019
|
}
|
|
2251
|
-
return this.
|
|
2020
|
+
return this.configuration.token;
|
|
2252
2021
|
}
|
|
2253
2022
|
async webSocketConnectionEstablished() {
|
|
2254
2023
|
this.status = WebSocketStatus.Connected;
|
|
@@ -2300,15 +2069,26 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2300
2069
|
this.emit('status', { status: 'disconnected' });
|
|
2301
2070
|
this.emit('disconnect', { event });
|
|
2302
2071
|
}
|
|
2072
|
+
if (event.code === Unauthorized.code) {
|
|
2073
|
+
if (!this.configuration.quiet) {
|
|
2074
|
+
console.warn('[HocuspocusProvider] An authentication token is required, but you didn’t send one. Try adding a `token` to your HocuspocusProvider configuration. Won’t try again.');
|
|
2075
|
+
}
|
|
2076
|
+
this.shouldConnect = false;
|
|
2077
|
+
}
|
|
2078
|
+
if (event.code === Forbidden.code) {
|
|
2079
|
+
if (!this.configuration.quiet) {
|
|
2080
|
+
console.warn('[HocuspocusProvider] The provided authentication token isn’t allowed to connect to this server. Will try again.');
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2303
2083
|
if (this.connectionAttempt) {
|
|
2304
|
-
//
|
|
2084
|
+
// That connection attempt failed.
|
|
2305
2085
|
this.rejectConnectionAttempt();
|
|
2306
2086
|
}
|
|
2307
2087
|
else if (this.shouldConnect) {
|
|
2308
|
-
// The connection was closed by the server
|
|
2088
|
+
// The connection was closed by the server. Let’s just try again.
|
|
2309
2089
|
this.connect();
|
|
2310
2090
|
}
|
|
2311
|
-
// If we’ll reconnect
|
|
2091
|
+
// If we’ll reconnect, we’re done for now.
|
|
2312
2092
|
if (this.shouldConnect) {
|
|
2313
2093
|
return;
|
|
2314
2094
|
}
|
|
@@ -2342,7 +2122,7 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2342
2122
|
window.removeEventListener('online', this.connect.bind(this));
|
|
2343
2123
|
}
|
|
2344
2124
|
get broadcastChannel() {
|
|
2345
|
-
return `${this.serverUrl}/${this.
|
|
2125
|
+
return `${this.serverUrl}/${this.configuration.name}`;
|
|
2346
2126
|
}
|
|
2347
2127
|
broadcastChannelSubscriber(data) {
|
|
2348
2128
|
this.mux(() => {
|
|
@@ -2377,7 +2157,7 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2377
2157
|
}
|
|
2378
2158
|
}
|
|
2379
2159
|
broadcast(Message, args) {
|
|
2380
|
-
if (!this.
|
|
2160
|
+
if (!this.configuration.broadcast) {
|
|
2381
2161
|
return;
|
|
2382
2162
|
}
|
|
2383
2163
|
if (!this.subscribedToBroadcastChannel) {
|
|
@@ -2391,17 +2171,17 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2391
2171
|
}
|
|
2392
2172
|
|
|
2393
2173
|
class HocuspocusCloudProvider extends HocuspocusProvider {
|
|
2394
|
-
constructor(
|
|
2395
|
-
if (!
|
|
2396
|
-
|
|
2174
|
+
constructor(configuration) {
|
|
2175
|
+
if (!configuration.url) {
|
|
2176
|
+
configuration.url = 'wss://connect.hocuspocus.cloud';
|
|
2397
2177
|
}
|
|
2398
|
-
if (
|
|
2399
|
-
if (!
|
|
2400
|
-
|
|
2178
|
+
if (configuration.key) {
|
|
2179
|
+
if (!configuration.parameters) {
|
|
2180
|
+
configuration.parameters = {};
|
|
2401
2181
|
}
|
|
2402
|
-
|
|
2182
|
+
configuration.parameters.key = configuration.key;
|
|
2403
2183
|
}
|
|
2404
|
-
super(
|
|
2184
|
+
super(configuration);
|
|
2405
2185
|
}
|
|
2406
2186
|
}
|
|
2407
2187
|
|