@hocuspocus/provider 3.4.4 → 3.4.5-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 +1836 -2085
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +1803 -2062
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/index.d.ts +558 -0
- package/dist/index.js +1940 -0
- package/package.json +4 -4
- package/dist/node_modules/@tiptap/pm/model/index.d.ts +0 -1
- package/dist/node_modules/@tiptap/pm/state/index.d.ts +0 -1
- package/dist/node_modules/@tiptap/pm/transform/index.d.ts +0 -1
- package/dist/node_modules/@tiptap/pm/view/index.d.ts +0 -1
- package/dist/packages/common/src/CloseEvents.d.ts +0 -29
- package/dist/packages/common/src/auth.d.ts +0 -13
- package/dist/packages/common/src/awarenessStatesToArray.d.ts +0 -3
- package/dist/packages/common/src/index.d.ts +0 -4
- package/dist/packages/common/src/types.d.ts +0 -10
- package/dist/packages/extension-database/src/Database.d.ts +0 -30
- package/dist/packages/extension-database/src/index.d.ts +0 -1
- package/dist/packages/extension-logger/src/Logger.d.ts +0 -67
- package/dist/packages/extension-logger/src/index.d.ts +0 -1
- package/dist/packages/extension-redis/src/Redis.d.ts +0 -124
- package/dist/packages/extension-redis/src/index.d.ts +0 -1
- package/dist/packages/extension-s3/src/S3.d.ts +0 -44
- package/dist/packages/extension-s3/src/index.d.ts +0 -1
- package/dist/packages/extension-sqlite/src/SQLite.d.ts +0 -27
- package/dist/packages/extension-sqlite/src/index.d.ts +0 -1
- package/dist/packages/extension-throttle/src/index.d.ts +0 -30
- package/dist/packages/extension-webhook/src/index.d.ts +0 -56
- package/dist/packages/provider/src/EventEmitter.d.ts +0 -9
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +0 -116
- package/dist/packages/provider/src/HocuspocusProviderWebsocket.d.ts +0 -119
- package/dist/packages/provider/src/IncomingMessage.d.ts +0 -17
- package/dist/packages/provider/src/MessageReceiver.d.ts +0 -12
- package/dist/packages/provider/src/MessageSender.d.ts +0 -9
- package/dist/packages/provider/src/OutgoingMessage.d.ts +0 -9
- package/dist/packages/provider/src/OutgoingMessages/AuthenticationMessage.d.ts +0 -8
- package/dist/packages/provider/src/OutgoingMessages/AwarenessMessage.d.ts +0 -9
- package/dist/packages/provider/src/OutgoingMessages/CloseMessage.d.ts +0 -9
- package/dist/packages/provider/src/OutgoingMessages/QueryAwarenessMessage.d.ts +0 -9
- package/dist/packages/provider/src/OutgoingMessages/StatelessMessage.d.ts +0 -8
- package/dist/packages/provider/src/OutgoingMessages/SyncStepOneMessage.d.ts +0 -9
- package/dist/packages/provider/src/OutgoingMessages/SyncStepTwoMessage.d.ts +0 -9
- package/dist/packages/provider/src/OutgoingMessages/UpdateMessage.d.ts +0 -8
- package/dist/packages/provider/src/index.d.ts +0 -3
- package/dist/packages/provider/src/types.d.ts +0 -93
- package/dist/packages/server/src/ClientConnection.d.ts +0 -63
- package/dist/packages/server/src/Connection.d.ts +0 -75
- package/dist/packages/server/src/DirectConnection.d.ts +0 -14
- package/dist/packages/server/src/Document.d.ts +0 -92
- package/dist/packages/server/src/Hocuspocus.d.ts +0 -80
- package/dist/packages/server/src/IncomingMessage.d.ts +0 -25
- package/dist/packages/server/src/MessageReceiver.d.ts +0 -11
- package/dist/packages/server/src/OutgoingMessage.d.ts +0 -23
- package/dist/packages/server/src/Server.d.ts +0 -32
- package/dist/packages/server/src/index.d.ts +0 -9
- package/dist/packages/server/src/types.d.ts +0 -342
- package/dist/packages/server/src/util/debounce.d.ts +0 -6
- package/dist/packages/server/src/util/getParameters.d.ts +0 -6
- package/dist/packages/transformer/src/Prosemirror.d.ts +0 -11
- package/dist/packages/transformer/src/Tiptap.d.ts +0 -10
- package/dist/packages/transformer/src/index.d.ts +0 -3
- package/dist/packages/transformer/src/types.d.ts +0 -5
- package/dist/playground/backend/src/default.d.ts +0 -1
- package/dist/playground/backend/src/deno.d.ts +0 -1
- package/dist/playground/backend/src/express.d.ts +0 -1
- package/dist/playground/backend/src/hono.d.ts +0 -1
- package/dist/playground/backend/src/koa.d.ts +0 -1
- package/dist/playground/backend/src/load-document.d.ts +0 -1
- package/dist/playground/backend/src/redis.d.ts +0 -1
- package/dist/playground/backend/src/s3-redis.d.ts +0 -1
- package/dist/playground/backend/src/s3.d.ts +0 -1
- package/dist/playground/backend/src/slow.d.ts +0 -1
- package/dist/playground/backend/src/tiptapcollab.d.ts +0 -1
- package/dist/playground/backend/src/webhook.d.ts +0 -1
- package/dist/playground/frontend/app/SocketContext1.d.ts +0 -2
- package/dist/playground/frontend/app/SocketContext2.d.ts +0 -2
- package/dist/playground/frontend/next.config.d.ts +0 -3
- package/dist/tests/extension-database/fetch.d.ts +0 -1
- package/dist/tests/extension-logger/onListen.d.ts +0 -1
- package/dist/tests/extension-redis/onAwarenessChange.d.ts +0 -1
- package/dist/tests/extension-redis/onChange.d.ts +0 -1
- package/dist/tests/extension-redis/onStateless.d.ts +0 -1
- package/dist/tests/extension-redis/onStoreDocument.d.ts +0 -1
- package/dist/tests/extension-s3/fetch.d.ts +0 -1
- package/dist/tests/extension-throttle/banning.d.ts +0 -1
- package/dist/tests/extension-throttle/configuration.d.ts +0 -1
- package/dist/tests/provider/hasUnsyncedChanges.d.ts +0 -1
- package/dist/tests/provider/observe.d.ts +0 -1
- package/dist/tests/provider/observeDeep.d.ts +0 -1
- package/dist/tests/provider/onAuthenticated.d.ts +0 -1
- package/dist/tests/provider/onAuthenticationFailed.d.ts +0 -1
- package/dist/tests/provider/onAwarenessChange.d.ts +0 -1
- package/dist/tests/provider/onAwarenessUpdate.d.ts +0 -1
- package/dist/tests/provider/onClose.d.ts +0 -1
- package/dist/tests/provider/onConnect.d.ts +0 -1
- package/dist/tests/provider/onDisconnect.d.ts +0 -1
- package/dist/tests/provider/onMessage.d.ts +0 -1
- package/dist/tests/provider/onOpen.d.ts +0 -1
- package/dist/tests/provider/onStateless.d.ts +0 -1
- package/dist/tests/provider/onSynced.d.ts +0 -1
- package/dist/tests/providerwebsocket/configuration.d.ts +0 -1
- package/dist/tests/server/address.d.ts +0 -1
- package/dist/tests/server/afterLoadDocument.d.ts +0 -1
- package/dist/tests/server/afterStoreDocument.d.ts +0 -1
- package/dist/tests/server/afterUnloadDocument.d.ts +0 -1
- package/dist/tests/server/beforeBroadcastStateless.d.ts +0 -1
- package/dist/tests/server/beforeHandleMessage.d.ts +0 -1
- package/dist/tests/server/beforeSync.d.ts +0 -1
- package/dist/tests/server/beforeUnloadDocument.d.ts +0 -1
- package/dist/tests/server/closeConnections.d.ts +0 -1
- package/dist/tests/server/getConnectionsCount.d.ts +0 -1
- package/dist/tests/server/getDocumentsCount.d.ts +0 -1
- package/dist/tests/server/listen.d.ts +0 -1
- package/dist/tests/server/onAuthenticate.d.ts +0 -1
- package/dist/tests/server/onAwarenessUpdate.d.ts +0 -1
- package/dist/tests/server/onChange.d.ts +0 -1
- package/dist/tests/server/onClose.d.ts +0 -1
- package/dist/tests/server/onConfigure.d.ts +0 -1
- package/dist/tests/server/onConnect.d.ts +0 -1
- package/dist/tests/server/onDestroy.d.ts +0 -1
- package/dist/tests/server/onDisconnect.d.ts +0 -1
- package/dist/tests/server/onListen.d.ts +0 -1
- package/dist/tests/server/onLoadDocument.d.ts +0 -1
- package/dist/tests/server/onRequest.d.ts +0 -1
- package/dist/tests/server/onStateless.d.ts +0 -1
- package/dist/tests/server/onStoreDocument.d.ts +0 -1
- package/dist/tests/server/onTokenSync.d.ts +0 -1
- package/dist/tests/server/onUpgrade.d.ts +0 -1
- package/dist/tests/server/openDirectConnection.d.ts +0 -1
- package/dist/tests/server/websocketError.d.ts +0 -1
- package/dist/tests/transformer/TiptapTransformer.d.ts +0 -1
- package/dist/tests/utils/createDirectory.d.ts +0 -1
- package/dist/tests/utils/flushRedis.d.ts +0 -1
- package/dist/tests/utils/index.d.ts +0 -9
- package/dist/tests/utils/newHocuspocus.d.ts +0 -2
- package/dist/tests/utils/newHocuspocusProvider.d.ts +0 -3
- package/dist/tests/utils/newHocuspocusProviderWebsocket.d.ts +0 -4
- package/dist/tests/utils/randomInteger.d.ts +0 -1
- package/dist/tests/utils/redisConnectionSettings.d.ts +0 -4
- package/dist/tests/utils/removeDirectory.d.ts +0 -1
- package/dist/tests/utils/retryableAssertion.d.ts +0 -2
- package/dist/tests/utils/sleep.d.ts +0 -1
|
@@ -1,2223 +1,1974 @@
|
|
|
1
|
-
'
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: ((k) => from[k]).bind(null, key),
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
24
|
+
value: mod,
|
|
25
|
+
enumerable: true
|
|
26
|
+
}) : target, mod));
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
let _hocuspocus_common = require("@hocuspocus/common");
|
|
30
|
+
let yjs = require("yjs");
|
|
31
|
+
yjs = __toESM(yjs);
|
|
32
|
+
let _lifeomic_attempt = require("@lifeomic/attempt");
|
|
33
|
+
|
|
34
|
+
//#region node_modules/lib0/math.js
|
|
35
|
+
/**
|
|
36
|
+
* Common Math expressions.
|
|
37
|
+
*
|
|
38
|
+
* @module math
|
|
39
|
+
*/
|
|
32
40
|
const floor = Math.floor;
|
|
33
|
-
|
|
34
41
|
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
* @function
|
|
43
|
+
* @param {number} a
|
|
44
|
+
* @param {number} b
|
|
45
|
+
* @return {number} The smaller element of a and b
|
|
46
|
+
*/
|
|
40
47
|
const min = (a, b) => a < b ? a : b;
|
|
41
|
-
|
|
42
48
|
/**
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
* @function
|
|
50
|
+
* @param {number} a
|
|
51
|
+
* @param {number} b
|
|
52
|
+
* @return {number} The bigger element of a and b
|
|
53
|
+
*/
|
|
48
54
|
const max = (a, b) => a > b ? a : b;
|
|
55
|
+
const isNaN$1 = Number.isNaN;
|
|
49
56
|
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region node_modules/lib0/binary.js
|
|
52
59
|
const BIT7 = 64;
|
|
53
60
|
const BIT8 = 128;
|
|
61
|
+
const BIT18 = 1 << 17;
|
|
62
|
+
const BIT19 = 1 << 18;
|
|
63
|
+
const BIT20 = 1 << 19;
|
|
64
|
+
const BIT21 = 1 << 20;
|
|
65
|
+
const BIT22 = 1 << 21;
|
|
66
|
+
const BIT23 = 1 << 22;
|
|
67
|
+
const BIT24 = 1 << 23;
|
|
68
|
+
const BIT25 = 1 << 24;
|
|
69
|
+
const BIT26 = 1 << 25;
|
|
70
|
+
const BIT27 = 1 << 26;
|
|
71
|
+
const BIT28 = 1 << 27;
|
|
72
|
+
const BIT29 = 1 << 28;
|
|
73
|
+
const BIT30 = 1 << 29;
|
|
74
|
+
const BIT31 = 1 << 30;
|
|
75
|
+
const BIT32 = 1 << 31;
|
|
54
76
|
const BITS6 = 63;
|
|
55
77
|
const BITS7 = 127;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
const BITS17 = BIT18 - 1;
|
|
79
|
+
const BITS18 = BIT19 - 1;
|
|
80
|
+
const BITS19 = BIT20 - 1;
|
|
81
|
+
const BITS20 = BIT21 - 1;
|
|
82
|
+
const BITS21 = BIT22 - 1;
|
|
83
|
+
const BITS22 = BIT23 - 1;
|
|
84
|
+
const BITS23 = BIT24 - 1;
|
|
85
|
+
const BITS24 = BIT25 - 1;
|
|
86
|
+
const BITS25 = BIT26 - 1;
|
|
87
|
+
const BITS26 = BIT27 - 1;
|
|
88
|
+
const BITS27 = BIT28 - 1;
|
|
89
|
+
const BITS28 = BIT29 - 1;
|
|
90
|
+
const BITS29 = BIT30 - 1;
|
|
91
|
+
const BITS30 = BIT31 - 1;
|
|
92
|
+
/**
|
|
93
|
+
* @type {number}
|
|
94
|
+
*/
|
|
95
|
+
const BITS31 = 2147483647;
|
|
96
|
+
/**
|
|
97
|
+
* @type {number}
|
|
98
|
+
*/
|
|
99
|
+
const BITS32 = 4294967295;
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region node_modules/lib0/number.js
|
|
103
|
+
/**
|
|
104
|
+
* Utility helpers for working with numbers.
|
|
105
|
+
*
|
|
106
|
+
* @module number
|
|
107
|
+
*/
|
|
64
108
|
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
109
|
+
const MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER;
|
|
110
|
+
const LOWEST_INT32 = 1 << 31;
|
|
111
|
+
const HIGHEST_INT32 = BITS31;
|
|
112
|
+
const HIGHEST_UINT32 = BITS32;
|
|
113
|
+
/* c8 ignore next */
|
|
114
|
+
const isInteger = Number.isInteger || ((num) => typeof num === "number" && isFinite(num) && floor(num) === num);
|
|
115
|
+
const isNaN = Number.isNaN;
|
|
116
|
+
const parseInt = Number.parseInt;
|
|
117
|
+
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region node_modules/lib0/set.js
|
|
120
|
+
/**
|
|
121
|
+
* Utility module to work with sets.
|
|
122
|
+
*
|
|
123
|
+
* @module set
|
|
124
|
+
*/
|
|
125
|
+
const create$2 = () => /* @__PURE__ */ new Set();
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region node_modules/lib0/array.js
|
|
129
|
+
/**
|
|
130
|
+
* Transforms something array-like to an actual Array.
|
|
131
|
+
*
|
|
132
|
+
* @function
|
|
133
|
+
* @template T
|
|
134
|
+
* @param {ArrayLike<T>|Iterable<T>} arraylike
|
|
135
|
+
* @return {T}
|
|
136
|
+
*/
|
|
89
137
|
const from = Array.from;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
138
|
+
const isArray$1 = Array.isArray;
|
|
139
|
+
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region node_modules/lib0/string.js
|
|
142
|
+
/**
|
|
143
|
+
* Utility module to work with strings.
|
|
144
|
+
*
|
|
145
|
+
* @module string
|
|
146
|
+
*/
|
|
147
|
+
const fromCharCode = String.fromCharCode;
|
|
148
|
+
const fromCodePoint = String.fromCodePoint;
|
|
149
|
+
/**
|
|
150
|
+
* The largest utf16 character.
|
|
151
|
+
* Corresponds to Uint8Array([255, 255]) or charcodeof(2x2^8)
|
|
152
|
+
*/
|
|
153
|
+
const MAX_UTF16_CHARACTER = fromCharCode(65535);
|
|
154
|
+
/**
|
|
155
|
+
* @param {string} str
|
|
156
|
+
* @return {Uint8Array}
|
|
157
|
+
*/
|
|
158
|
+
const _encodeUtf8Polyfill = (str) => {
|
|
159
|
+
const encodedString = unescape(encodeURIComponent(str));
|
|
160
|
+
const len = encodedString.length;
|
|
161
|
+
const buf = new Uint8Array(len);
|
|
162
|
+
for (let i = 0; i < len; i++) buf[i] = encodedString.codePointAt(i);
|
|
163
|
+
return buf;
|
|
103
164
|
};
|
|
104
|
-
|
|
105
165
|
/* c8 ignore next */
|
|
106
|
-
const utf8TextEncoder =
|
|
107
|
-
|
|
166
|
+
const utf8TextEncoder = typeof TextEncoder !== "undefined" ? new TextEncoder() : null;
|
|
108
167
|
/**
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const _encodeUtf8Native = str => utf8TextEncoder.encode(str);
|
|
113
|
-
|
|
168
|
+
* @param {string} str
|
|
169
|
+
* @return {Uint8Array}
|
|
170
|
+
*/
|
|
171
|
+
const _encodeUtf8Native = (str) => utf8TextEncoder.encode(str);
|
|
114
172
|
/**
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
173
|
+
* @param {string} str
|
|
174
|
+
* @return {Uint8Array}
|
|
175
|
+
*/
|
|
118
176
|
/* c8 ignore next */
|
|
119
177
|
const encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill;
|
|
120
|
-
|
|
121
178
|
/* c8 ignore next */
|
|
122
|
-
let utf8TextDecoder = typeof TextDecoder ===
|
|
123
|
-
|
|
179
|
+
let utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8", {
|
|
180
|
+
fatal: true,
|
|
181
|
+
ignoreBOM: true
|
|
182
|
+
});
|
|
124
183
|
/* c8 ignore start */
|
|
125
|
-
if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* @type {Array<Uint8Array>}
|
|
173
|
-
*/
|
|
174
|
-
this.bufs = [];
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
184
|
+
if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1)
|
|
185
|
+
/* c8 ignore next */
|
|
186
|
+
utf8TextDecoder = null;
|
|
187
|
+
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region node_modules/lib0/encoding.js
|
|
190
|
+
/**
|
|
191
|
+
* Efficient schema-less binary encoding with support for variable length encoding.
|
|
192
|
+
*
|
|
193
|
+
* Use [lib0/encoding] with [lib0/decoding]. Every encoding function has a corresponding decoding function.
|
|
194
|
+
*
|
|
195
|
+
* Encodes numbers in little-endian order (least to most significant byte order)
|
|
196
|
+
* and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
|
|
197
|
+
* which is also used in Protocol Buffers.
|
|
198
|
+
*
|
|
199
|
+
* ```js
|
|
200
|
+
* // encoding step
|
|
201
|
+
* const encoder = encoding.createEncoder()
|
|
202
|
+
* encoding.writeVarUint(encoder, 256)
|
|
203
|
+
* encoding.writeVarString(encoder, 'Hello world!')
|
|
204
|
+
* const buf = encoding.toUint8Array(encoder)
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* ```js
|
|
208
|
+
* // decoding step
|
|
209
|
+
* const decoder = decoding.createDecoder(buf)
|
|
210
|
+
* decoding.readVarUint(decoder) // => 256
|
|
211
|
+
* decoding.readVarString(decoder) // => 'Hello world!'
|
|
212
|
+
* decoding.hasContent(decoder) // => false - all data is read
|
|
213
|
+
* ```
|
|
214
|
+
*
|
|
215
|
+
* @module encoding
|
|
216
|
+
*/
|
|
217
|
+
/**
|
|
218
|
+
* A BinaryEncoder handles the encoding to an Uint8Array.
|
|
219
|
+
*/
|
|
220
|
+
var Encoder = class {
|
|
221
|
+
constructor() {
|
|
222
|
+
this.cpos = 0;
|
|
223
|
+
this.cbuf = new Uint8Array(100);
|
|
224
|
+
/**
|
|
225
|
+
* @type {Array<Uint8Array>}
|
|
226
|
+
*/
|
|
227
|
+
this.bufs = [];
|
|
228
|
+
}
|
|
229
|
+
};
|
|
178
230
|
/**
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
231
|
+
* @function
|
|
232
|
+
* @return {Encoder}
|
|
233
|
+
*/
|
|
182
234
|
const createEncoder = () => new Encoder();
|
|
183
|
-
|
|
184
235
|
/**
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const length$1 = encoder => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
return len
|
|
236
|
+
* The current length of the encoded data.
|
|
237
|
+
*
|
|
238
|
+
* @function
|
|
239
|
+
* @param {Encoder} encoder
|
|
240
|
+
* @return {number}
|
|
241
|
+
*/
|
|
242
|
+
const length$1 = (encoder) => {
|
|
243
|
+
let len = encoder.cpos;
|
|
244
|
+
for (let i = 0; i < encoder.bufs.length; i++) len += encoder.bufs[i].length;
|
|
245
|
+
return len;
|
|
197
246
|
};
|
|
198
|
-
|
|
199
247
|
/**
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const toUint8Array = encoder => {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
248
|
+
* Transform to Uint8Array.
|
|
249
|
+
*
|
|
250
|
+
* @function
|
|
251
|
+
* @param {Encoder} encoder
|
|
252
|
+
* @return {Uint8Array} The created ArrayBuffer.
|
|
253
|
+
*/
|
|
254
|
+
const toUint8Array = (encoder) => {
|
|
255
|
+
const uint8arr = new Uint8Array(length$1(encoder));
|
|
256
|
+
let curPos = 0;
|
|
257
|
+
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
258
|
+
const d = encoder.bufs[i];
|
|
259
|
+
uint8arr.set(d, curPos);
|
|
260
|
+
curPos += d.length;
|
|
261
|
+
}
|
|
262
|
+
uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos);
|
|
263
|
+
return uint8arr;
|
|
216
264
|
};
|
|
217
|
-
|
|
218
265
|
/**
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
266
|
+
* Write one byte to the encoder.
|
|
267
|
+
*
|
|
268
|
+
* @function
|
|
269
|
+
* @param {Encoder} encoder
|
|
270
|
+
* @param {number} num The byte that is to be encoded.
|
|
271
|
+
*/
|
|
225
272
|
const write = (encoder, num) => {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
273
|
+
const bufferLen = encoder.cbuf.length;
|
|
274
|
+
if (encoder.cpos === bufferLen) {
|
|
275
|
+
encoder.bufs.push(encoder.cbuf);
|
|
276
|
+
encoder.cbuf = new Uint8Array(bufferLen * 2);
|
|
277
|
+
encoder.cpos = 0;
|
|
278
|
+
}
|
|
279
|
+
encoder.cbuf[encoder.cpos++] = num;
|
|
233
280
|
};
|
|
234
|
-
|
|
235
281
|
/**
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
282
|
+
* Write a variable length unsigned integer. Max encodable integer is 2^53.
|
|
283
|
+
*
|
|
284
|
+
* @function
|
|
285
|
+
* @param {Encoder} encoder
|
|
286
|
+
* @param {number} num The number that is to be encoded.
|
|
287
|
+
*/
|
|
242
288
|
const writeVarUint = (encoder, num) => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
289
|
+
while (num > BITS7) {
|
|
290
|
+
write(encoder, BIT8 | BITS7 & num);
|
|
291
|
+
num = floor(num / 128);
|
|
292
|
+
}
|
|
293
|
+
write(encoder, BITS7 & num);
|
|
248
294
|
};
|
|
249
|
-
|
|
250
295
|
/**
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const _strBuffer = new Uint8Array(
|
|
296
|
+
* A cache to store strings temporarily
|
|
297
|
+
*/
|
|
298
|
+
const _strBuffer = new Uint8Array(3e4);
|
|
254
299
|
const _maxStrBSize = _strBuffer.length / 3;
|
|
255
|
-
|
|
256
300
|
/**
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
301
|
+
* Write a variable length string.
|
|
302
|
+
*
|
|
303
|
+
* @function
|
|
304
|
+
* @param {Encoder} encoder
|
|
305
|
+
* @param {String} str The string that is to be encoded.
|
|
306
|
+
*/
|
|
263
307
|
const _writeVarStringNative = (encoder, str) => {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
write(encoder, _strBuffer[i]);
|
|
271
|
-
}
|
|
272
|
-
} else {
|
|
273
|
-
writeVarUint8Array(encoder, encodeUtf8(str));
|
|
274
|
-
}
|
|
308
|
+
if (str.length < _maxStrBSize) {
|
|
309
|
+
/* c8 ignore next */
|
|
310
|
+
const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0;
|
|
311
|
+
writeVarUint(encoder, written);
|
|
312
|
+
for (let i = 0; i < written; i++) write(encoder, _strBuffer[i]);
|
|
313
|
+
} else writeVarUint8Array(encoder, encodeUtf8(str));
|
|
275
314
|
};
|
|
276
|
-
|
|
277
315
|
/**
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
316
|
+
* Write a variable length string.
|
|
317
|
+
*
|
|
318
|
+
* @function
|
|
319
|
+
* @param {Encoder} encoder
|
|
320
|
+
* @param {String} str The string that is to be encoded.
|
|
321
|
+
*/
|
|
284
322
|
const _writeVarStringPolyfill = (encoder, str) => {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
write(encoder, /** @type {number} */ (encodedString.codePointAt(i)));
|
|
290
|
-
}
|
|
323
|
+
const encodedString = unescape(encodeURIComponent(str));
|
|
324
|
+
const len = encodedString.length;
|
|
325
|
+
writeVarUint(encoder, len);
|
|
326
|
+
for (let i = 0; i < len; i++) write(encoder, encodedString.codePointAt(i));
|
|
291
327
|
};
|
|
292
|
-
|
|
293
328
|
/**
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
329
|
+
* Write a variable length string.
|
|
330
|
+
*
|
|
331
|
+
* @function
|
|
332
|
+
* @param {Encoder} encoder
|
|
333
|
+
* @param {String} str The string that is to be encoded.
|
|
334
|
+
*/
|
|
300
335
|
/* c8 ignore next */
|
|
301
|
-
const writeVarString =
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
*/
|
|
336
|
+
const writeVarString = utf8TextEncoder && utf8TextEncoder.encodeInto ? _writeVarStringNative : _writeVarStringPolyfill;
|
|
337
|
+
/**
|
|
338
|
+
* Append fixed-length Uint8Array to the encoder.
|
|
339
|
+
*
|
|
340
|
+
* @function
|
|
341
|
+
* @param {Encoder} encoder
|
|
342
|
+
* @param {Uint8Array} uint8Array
|
|
343
|
+
*/
|
|
310
344
|
const writeUint8Array = (encoder, uint8Array) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// copy array
|
|
324
|
-
encoder.cbuf.set(uint8Array.subarray(leftCopyLen));
|
|
325
|
-
encoder.cpos = rightCopyLen;
|
|
326
|
-
}
|
|
345
|
+
const bufferLen = encoder.cbuf.length;
|
|
346
|
+
const cpos = encoder.cpos;
|
|
347
|
+
const leftCopyLen = min(bufferLen - cpos, uint8Array.length);
|
|
348
|
+
const rightCopyLen = uint8Array.length - leftCopyLen;
|
|
349
|
+
encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos);
|
|
350
|
+
encoder.cpos += leftCopyLen;
|
|
351
|
+
if (rightCopyLen > 0) {
|
|
352
|
+
encoder.bufs.push(encoder.cbuf);
|
|
353
|
+
encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen));
|
|
354
|
+
encoder.cbuf.set(uint8Array.subarray(leftCopyLen));
|
|
355
|
+
encoder.cpos = rightCopyLen;
|
|
356
|
+
}
|
|
327
357
|
};
|
|
328
|
-
|
|
329
358
|
/**
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
359
|
+
* Append an Uint8Array to Encoder.
|
|
360
|
+
*
|
|
361
|
+
* @function
|
|
362
|
+
* @param {Encoder} encoder
|
|
363
|
+
* @param {Uint8Array} uint8Array
|
|
364
|
+
*/
|
|
336
365
|
const writeVarUint8Array = (encoder, uint8Array) => {
|
|
337
|
-
|
|
338
|
-
|
|
366
|
+
writeVarUint(encoder, uint8Array.byteLength);
|
|
367
|
+
writeUint8Array(encoder, uint8Array);
|
|
339
368
|
};
|
|
340
369
|
|
|
370
|
+
//#endregion
|
|
371
|
+
//#region node_modules/lib0/error.js
|
|
341
372
|
/**
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
373
|
+
* Error helpers.
|
|
374
|
+
*
|
|
375
|
+
* @module error
|
|
376
|
+
*/
|
|
347
377
|
/**
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
378
|
+
* @param {string} s
|
|
379
|
+
* @return {Error}
|
|
380
|
+
*/
|
|
351
381
|
/* c8 ignore next */
|
|
352
|
-
const create$1 = s => new Error(s);
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const errorUnexpectedEndOfArray = create$1(
|
|
384
|
-
const errorIntegerOutOfRange = create$1(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* @function
|
|
411
|
-
* @param {Uint8Array} uint8Array
|
|
412
|
-
* @return {Decoder}
|
|
413
|
-
*/
|
|
414
|
-
const createDecoder = uint8Array => new Decoder(uint8Array);
|
|
415
|
-
|
|
382
|
+
const create$1 = (s) => new Error(s);
|
|
383
|
+
|
|
384
|
+
//#endregion
|
|
385
|
+
//#region node_modules/lib0/decoding.js
|
|
386
|
+
/**
|
|
387
|
+
* Efficient schema-less binary decoding with support for variable length encoding.
|
|
388
|
+
*
|
|
389
|
+
* Use [lib0/decoding] with [lib0/encoding]. Every encoding function has a corresponding decoding function.
|
|
390
|
+
*
|
|
391
|
+
* Encodes numbers in little-endian order (least to most significant byte order)
|
|
392
|
+
* and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
|
|
393
|
+
* which is also used in Protocol Buffers.
|
|
394
|
+
*
|
|
395
|
+
* ```js
|
|
396
|
+
* // encoding step
|
|
397
|
+
* const encoder = encoding.createEncoder()
|
|
398
|
+
* encoding.writeVarUint(encoder, 256)
|
|
399
|
+
* encoding.writeVarString(encoder, 'Hello world!')
|
|
400
|
+
* const buf = encoding.toUint8Array(encoder)
|
|
401
|
+
* ```
|
|
402
|
+
*
|
|
403
|
+
* ```js
|
|
404
|
+
* // decoding step
|
|
405
|
+
* const decoder = decoding.createDecoder(buf)
|
|
406
|
+
* decoding.readVarUint(decoder) // => 256
|
|
407
|
+
* decoding.readVarString(decoder) // => 'Hello world!'
|
|
408
|
+
* decoding.hasContent(decoder) // => false - all data is read
|
|
409
|
+
* ```
|
|
410
|
+
*
|
|
411
|
+
* @module decoding
|
|
412
|
+
*/
|
|
413
|
+
const errorUnexpectedEndOfArray = create$1("Unexpected end of array");
|
|
414
|
+
const errorIntegerOutOfRange = create$1("Integer out of Range");
|
|
415
|
+
/**
|
|
416
|
+
* A Decoder handles the decoding of an Uint8Array.
|
|
417
|
+
*/
|
|
418
|
+
var Decoder = class {
|
|
419
|
+
/**
|
|
420
|
+
* @param {Uint8Array} uint8Array Binary data to decode
|
|
421
|
+
*/
|
|
422
|
+
constructor(uint8Array) {
|
|
423
|
+
/**
|
|
424
|
+
* Decoding target.
|
|
425
|
+
*
|
|
426
|
+
* @type {Uint8Array}
|
|
427
|
+
*/
|
|
428
|
+
this.arr = uint8Array;
|
|
429
|
+
/**
|
|
430
|
+
* Current decoding position.
|
|
431
|
+
*
|
|
432
|
+
* @type {number}
|
|
433
|
+
*/
|
|
434
|
+
this.pos = 0;
|
|
435
|
+
}
|
|
436
|
+
};
|
|
416
437
|
/**
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
438
|
+
* @function
|
|
439
|
+
* @param {Uint8Array} uint8Array
|
|
440
|
+
* @return {Decoder}
|
|
441
|
+
*/
|
|
442
|
+
const createDecoder = (uint8Array) => new Decoder(uint8Array);
|
|
443
|
+
/**
|
|
444
|
+
* Create an Uint8Array view of the next `len` bytes and advance the position by `len`.
|
|
445
|
+
*
|
|
446
|
+
* Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.
|
|
447
|
+
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
448
|
+
*
|
|
449
|
+
* @function
|
|
450
|
+
* @param {Decoder} decoder The decoder instance
|
|
451
|
+
* @param {number} len The length of bytes to read
|
|
452
|
+
* @return {Uint8Array}
|
|
453
|
+
*/
|
|
427
454
|
const readUint8Array = (decoder, len) => {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
455
|
+
const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len);
|
|
456
|
+
decoder.pos += len;
|
|
457
|
+
return view;
|
|
431
458
|
};
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Read variable length Uint8Array.
|
|
435
|
-
*
|
|
436
|
-
* Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.
|
|
437
|
-
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
438
|
-
*
|
|
439
|
-
* @function
|
|
440
|
-
* @param {Decoder} decoder
|
|
441
|
-
* @return {Uint8Array}
|
|
442
|
-
*/
|
|
443
|
-
const readVarUint8Array = decoder => readUint8Array(decoder, readVarUint(decoder));
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Read one byte as unsigned integer.
|
|
447
|
-
* @function
|
|
448
|
-
* @param {Decoder} decoder The decoder instance
|
|
449
|
-
* @return {number} Unsigned 8-bit integer
|
|
450
|
-
*/
|
|
451
|
-
const readUint8 = decoder => decoder.arr[decoder.pos++];
|
|
452
|
-
|
|
453
459
|
/**
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
460
|
+
* Read variable length Uint8Array.
|
|
461
|
+
*
|
|
462
|
+
* Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.
|
|
463
|
+
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
464
|
+
*
|
|
465
|
+
* @function
|
|
466
|
+
* @param {Decoder} decoder
|
|
467
|
+
* @return {Uint8Array}
|
|
468
|
+
*/
|
|
469
|
+
const readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder));
|
|
470
|
+
/**
|
|
471
|
+
* Read one byte as unsigned integer.
|
|
472
|
+
* @function
|
|
473
|
+
* @param {Decoder} decoder The decoder instance
|
|
474
|
+
* @return {number} Unsigned 8-bit integer
|
|
475
|
+
*/
|
|
476
|
+
const readUint8 = (decoder) => decoder.arr[decoder.pos++];
|
|
477
|
+
/**
|
|
478
|
+
* Read unsigned integer (32bit) with variable length.
|
|
479
|
+
* 1/8th of the storage is used as encoding overhead.
|
|
480
|
+
* * numbers < 2^7 is stored in one bytlength
|
|
481
|
+
* * numbers < 2^14 is stored in two bylength
|
|
482
|
+
*
|
|
483
|
+
* @function
|
|
484
|
+
* @param {Decoder} decoder
|
|
485
|
+
* @return {number} An unsigned integer.length
|
|
486
|
+
*/
|
|
487
|
+
const readVarUint = (decoder) => {
|
|
488
|
+
let num = 0;
|
|
489
|
+
let mult = 1;
|
|
490
|
+
const len = decoder.arr.length;
|
|
491
|
+
while (decoder.pos < len) {
|
|
492
|
+
const r = decoder.arr[decoder.pos++];
|
|
493
|
+
num = num + (r & BITS7) * mult;
|
|
494
|
+
mult *= 128;
|
|
495
|
+
if (r < BIT8) return num;
|
|
496
|
+
/* c8 ignore start */
|
|
497
|
+
if (num > MAX_SAFE_INTEGER) throw errorIntegerOutOfRange;
|
|
498
|
+
}
|
|
499
|
+
throw errorUnexpectedEndOfArray;
|
|
482
500
|
};
|
|
483
|
-
|
|
484
501
|
/**
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
const readVarInt = decoder => {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
return sign * num
|
|
512
|
-
}
|
|
513
|
-
/* c8 ignore start */
|
|
514
|
-
if (num > MAX_SAFE_INTEGER) {
|
|
515
|
-
throw errorIntegerOutOfRange
|
|
516
|
-
}
|
|
517
|
-
/* c8 ignore stop */
|
|
518
|
-
}
|
|
519
|
-
throw errorUnexpectedEndOfArray
|
|
502
|
+
* Read signed integer (32bit) with variable length.
|
|
503
|
+
* 1/8th of the storage is used as encoding overhead.
|
|
504
|
+
* * numbers < 2^7 is stored in one bytlength
|
|
505
|
+
* * numbers < 2^14 is stored in two bylength
|
|
506
|
+
* @todo This should probably create the inverse ~num if number is negative - but this would be a breaking change.
|
|
507
|
+
*
|
|
508
|
+
* @function
|
|
509
|
+
* @param {Decoder} decoder
|
|
510
|
+
* @return {number} An unsigned integer.length
|
|
511
|
+
*/
|
|
512
|
+
const readVarInt = (decoder) => {
|
|
513
|
+
let r = decoder.arr[decoder.pos++];
|
|
514
|
+
let num = r & BITS6;
|
|
515
|
+
let mult = 64;
|
|
516
|
+
const sign = (r & BIT7) > 0 ? -1 : 1;
|
|
517
|
+
if ((r & BIT8) === 0) return sign * num;
|
|
518
|
+
const len = decoder.arr.length;
|
|
519
|
+
while (decoder.pos < len) {
|
|
520
|
+
r = decoder.arr[decoder.pos++];
|
|
521
|
+
num = num + (r & BITS7) * mult;
|
|
522
|
+
mult *= 128;
|
|
523
|
+
if (r < BIT8) return sign * num;
|
|
524
|
+
/* c8 ignore start */
|
|
525
|
+
if (num > MAX_SAFE_INTEGER) throw errorIntegerOutOfRange;
|
|
526
|
+
}
|
|
527
|
+
throw errorUnexpectedEndOfArray;
|
|
520
528
|
};
|
|
521
|
-
|
|
522
529
|
/**
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
530
|
+
* We don't test this function anymore as we use native decoding/encoding by default now.
|
|
531
|
+
* Better not modify this anymore..
|
|
532
|
+
*
|
|
533
|
+
* Transforming utf8 to a string is pretty expensive. The code performs 10x better
|
|
534
|
+
* when String.fromCodePoint is fed with all characters as arguments.
|
|
535
|
+
* But most environments have a maximum number of arguments per functions.
|
|
536
|
+
* For effiency reasons we apply a maximum of 10000 characters at once.
|
|
537
|
+
*
|
|
538
|
+
* @function
|
|
539
|
+
* @param {Decoder} decoder
|
|
540
|
+
* @return {String} The read String.
|
|
541
|
+
*/
|
|
535
542
|
/* c8 ignore start */
|
|
536
|
-
const _readVarStringPolyfill = decoder => {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
decoder.pos += nextLen;
|
|
552
|
-
// Starting with ES5.1 we can supply a generic array-like object as arguments
|
|
553
|
-
encodedString += String.fromCodePoint.apply(null, /** @type {any} */ (bytes));
|
|
554
|
-
remainingLen -= nextLen;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
return decodeURIComponent(escape(encodedString))
|
|
558
|
-
}
|
|
543
|
+
const _readVarStringPolyfill = (decoder) => {
|
|
544
|
+
let remainingLen = readVarUint(decoder);
|
|
545
|
+
if (remainingLen === 0) return "";
|
|
546
|
+
else {
|
|
547
|
+
let encodedString = String.fromCodePoint(readUint8(decoder));
|
|
548
|
+
if (--remainingLen < 100) while (remainingLen--) encodedString += String.fromCodePoint(readUint8(decoder));
|
|
549
|
+
else while (remainingLen > 0) {
|
|
550
|
+
const nextLen = remainingLen < 1e4 ? remainingLen : 1e4;
|
|
551
|
+
const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen);
|
|
552
|
+
decoder.pos += nextLen;
|
|
553
|
+
encodedString += String.fromCodePoint.apply(null, bytes);
|
|
554
|
+
remainingLen -= nextLen;
|
|
555
|
+
}
|
|
556
|
+
return decodeURIComponent(escape(encodedString));
|
|
557
|
+
}
|
|
559
558
|
};
|
|
560
559
|
/* c8 ignore stop */
|
|
561
|
-
|
|
562
560
|
/**
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
const _readVarStringNative = decoder =>
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
*
|
|
578
|
-
*/
|
|
561
|
+
* @function
|
|
562
|
+
* @param {Decoder} decoder
|
|
563
|
+
* @return {String} The read String
|
|
564
|
+
*/
|
|
565
|
+
const _readVarStringNative = (decoder) => utf8TextDecoder.decode(readVarUint8Array(decoder));
|
|
566
|
+
/**
|
|
567
|
+
* Read string of variable length
|
|
568
|
+
* * varUint is used to store the length of the string
|
|
569
|
+
*
|
|
570
|
+
* @function
|
|
571
|
+
* @param {Decoder} decoder
|
|
572
|
+
* @return {String} The read String
|
|
573
|
+
*
|
|
574
|
+
*/
|
|
579
575
|
/* c8 ignore next */
|
|
580
576
|
const readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill;
|
|
581
|
-
|
|
582
577
|
/**
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const peekVarString = decoder => {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
578
|
+
* Look ahead and read varString without incrementing position
|
|
579
|
+
*
|
|
580
|
+
* @function
|
|
581
|
+
* @param {Decoder} decoder
|
|
582
|
+
* @return {string}
|
|
583
|
+
*/
|
|
584
|
+
const peekVarString = (decoder) => {
|
|
585
|
+
const pos = decoder.pos;
|
|
586
|
+
const s = readVarString(decoder);
|
|
587
|
+
decoder.pos = pos;
|
|
588
|
+
return s;
|
|
594
589
|
};
|
|
595
590
|
|
|
591
|
+
//#endregion
|
|
592
|
+
//#region node_modules/lib0/time.js
|
|
596
593
|
/**
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
/**
|
|
604
|
-
* Return current unix time.
|
|
605
|
-
*
|
|
606
|
-
* @return {number}
|
|
607
|
-
*/
|
|
594
|
+
* Return current unix time.
|
|
595
|
+
*
|
|
596
|
+
* @return {number}
|
|
597
|
+
*/
|
|
608
598
|
const getUnixTime = Date.now;
|
|
609
599
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
/**
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
600
|
+
//#endregion
|
|
601
|
+
//#region node_modules/lib0/map.js
|
|
602
|
+
/**
|
|
603
|
+
* Utility module to work with key-value stores.
|
|
604
|
+
*
|
|
605
|
+
* @module map
|
|
606
|
+
*/
|
|
607
|
+
/**
|
|
608
|
+
* Creates a new Map instance.
|
|
609
|
+
*
|
|
610
|
+
* @function
|
|
611
|
+
* @return {Map<any, any>}
|
|
612
|
+
*
|
|
613
|
+
* @function
|
|
614
|
+
*/
|
|
615
|
+
const create = () => /* @__PURE__ */ new Map();
|
|
616
|
+
/**
|
|
617
|
+
* Get map property. Create T if property is undefined and set T on map.
|
|
618
|
+
*
|
|
619
|
+
* ```js
|
|
620
|
+
* const listeners = map.setIfUndefined(events, 'eventName', set.create)
|
|
621
|
+
* listeners.add(listener)
|
|
622
|
+
* ```
|
|
623
|
+
*
|
|
624
|
+
* @function
|
|
625
|
+
* @template {Map<any, any>} MAP
|
|
626
|
+
* @template {MAP extends Map<any,infer V> ? function():V : unknown} CF
|
|
627
|
+
* @param {MAP} map
|
|
628
|
+
* @param {MAP extends Map<infer K,any> ? K : unknown} key
|
|
629
|
+
* @param {CF} createT
|
|
630
|
+
* @return {ReturnType<CF>}
|
|
631
|
+
*/
|
|
642
632
|
const setIfUndefined = (map, key, createT) => {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
}
|
|
647
|
-
return set
|
|
633
|
+
let set = map.get(key);
|
|
634
|
+
if (set === void 0) map.set(key, set = createT());
|
|
635
|
+
return set;
|
|
648
636
|
};
|
|
649
637
|
|
|
638
|
+
//#endregion
|
|
639
|
+
//#region node_modules/lib0/observable.js
|
|
650
640
|
/**
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
641
|
+
* Observable class prototype.
|
|
642
|
+
*
|
|
643
|
+
* @module observable
|
|
644
|
+
*/
|
|
657
645
|
/* c8 ignore start */
|
|
658
646
|
/**
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
// copy all listeners to an array first to make sure that no event is emitted to listeners that are subscribed while the event handler is called.
|
|
721
|
-
return from((this._observers.get(name) || create()).values()).forEach(f => f(...args))
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
destroy () {
|
|
725
|
-
this._observers = create();
|
|
726
|
-
}
|
|
727
|
-
}
|
|
647
|
+
* Handles named events.
|
|
648
|
+
*
|
|
649
|
+
* @deprecated
|
|
650
|
+
* @template N
|
|
651
|
+
*/
|
|
652
|
+
var Observable = class {
|
|
653
|
+
constructor() {
|
|
654
|
+
/**
|
|
655
|
+
* Some desc.
|
|
656
|
+
* @type {Map<N, any>}
|
|
657
|
+
*/
|
|
658
|
+
this._observers = create();
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* @param {N} name
|
|
662
|
+
* @param {function} f
|
|
663
|
+
*/
|
|
664
|
+
on(name, f) {
|
|
665
|
+
setIfUndefined(this._observers, name, create$2).add(f);
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* @param {N} name
|
|
669
|
+
* @param {function} f
|
|
670
|
+
*/
|
|
671
|
+
once(name, f) {
|
|
672
|
+
/**
|
|
673
|
+
* @param {...any} args
|
|
674
|
+
*/
|
|
675
|
+
const _f = (...args) => {
|
|
676
|
+
this.off(name, _f);
|
|
677
|
+
f(...args);
|
|
678
|
+
};
|
|
679
|
+
this.on(name, _f);
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* @param {N} name
|
|
683
|
+
* @param {function} f
|
|
684
|
+
*/
|
|
685
|
+
off(name, f) {
|
|
686
|
+
const observers = this._observers.get(name);
|
|
687
|
+
if (observers !== void 0) {
|
|
688
|
+
observers.delete(f);
|
|
689
|
+
if (observers.size === 0) this._observers.delete(name);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Emit a named event. All registered event listeners that listen to the
|
|
694
|
+
* specified name will receive the event.
|
|
695
|
+
*
|
|
696
|
+
* @todo This should catch exceptions
|
|
697
|
+
*
|
|
698
|
+
* @param {N} name The event name.
|
|
699
|
+
* @param {Array<any>} args The arguments that are applied to the event listener.
|
|
700
|
+
*/
|
|
701
|
+
emit(name, args) {
|
|
702
|
+
return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args));
|
|
703
|
+
}
|
|
704
|
+
destroy() {
|
|
705
|
+
this._observers = create();
|
|
706
|
+
}
|
|
707
|
+
};
|
|
728
708
|
/* c8 ignore end */
|
|
729
709
|
|
|
710
|
+
//#endregion
|
|
711
|
+
//#region node_modules/lib0/object.js
|
|
730
712
|
/**
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
* @module object
|
|
734
|
-
*/
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
/**
|
|
738
|
-
* @param {Object<string,any>} obj
|
|
739
|
-
*/
|
|
713
|
+
* @param {Object<string,any>} obj
|
|
714
|
+
*/
|
|
740
715
|
const keys = Object.keys;
|
|
741
|
-
|
|
742
716
|
/**
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
const length = obj => keys(obj).length;
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
*/
|
|
717
|
+
* @deprecated use object.size instead
|
|
718
|
+
* @param {Object<string,any>} obj
|
|
719
|
+
* @return {number}
|
|
720
|
+
*/
|
|
721
|
+
const length = (obj) => keys(obj).length;
|
|
722
|
+
/**
|
|
723
|
+
* Calls `Object.prototype.hasOwnProperty`.
|
|
724
|
+
*
|
|
725
|
+
* @param {any} obj
|
|
726
|
+
* @param {string|symbol} key
|
|
727
|
+
* @return {boolean}
|
|
728
|
+
*/
|
|
756
729
|
const hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
|
|
757
730
|
|
|
731
|
+
//#endregion
|
|
732
|
+
//#region node_modules/lib0/function.js
|
|
758
733
|
/**
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
734
|
+
* Common functions and function call helpers.
|
|
735
|
+
*
|
|
736
|
+
* @module function
|
|
737
|
+
*/
|
|
765
738
|
/**
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
739
|
+
* @template T
|
|
740
|
+
*
|
|
741
|
+
* @param {T} a
|
|
742
|
+
* @param {T} b
|
|
743
|
+
* @return {boolean}
|
|
744
|
+
*/
|
|
772
745
|
const equalityStrict = (a, b) => a === b;
|
|
773
|
-
|
|
774
746
|
/* c8 ignore start */
|
|
775
|
-
|
|
776
747
|
/**
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
748
|
+
* @param {any} a
|
|
749
|
+
* @param {any} b
|
|
750
|
+
* @return {boolean}
|
|
751
|
+
*/
|
|
781
752
|
const equalityDeep = (a, b) => {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
753
|
+
if (a == null || b == null) return equalityStrict(a, b);
|
|
754
|
+
if (a.constructor !== b.constructor) return false;
|
|
755
|
+
if (a === b) return true;
|
|
756
|
+
switch (a.constructor) {
|
|
757
|
+
case ArrayBuffer:
|
|
758
|
+
a = new Uint8Array(a);
|
|
759
|
+
b = new Uint8Array(b);
|
|
760
|
+
case Uint8Array:
|
|
761
|
+
if (a.byteLength !== b.byteLength) return false;
|
|
762
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
763
|
+
break;
|
|
764
|
+
case Set:
|
|
765
|
+
if (a.size !== b.size) return false;
|
|
766
|
+
for (const value of a) if (!b.has(value)) return false;
|
|
767
|
+
break;
|
|
768
|
+
case Map:
|
|
769
|
+
if (a.size !== b.size) return false;
|
|
770
|
+
for (const key of a.keys()) if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) return false;
|
|
771
|
+
break;
|
|
772
|
+
case Object:
|
|
773
|
+
if (length(a) !== length(b)) return false;
|
|
774
|
+
for (const key in a) if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) return false;
|
|
775
|
+
break;
|
|
776
|
+
case Array:
|
|
777
|
+
if (a.length !== b.length) return false;
|
|
778
|
+
for (let i = 0; i < a.length; i++) if (!equalityDeep(a[i], b[i])) return false;
|
|
779
|
+
break;
|
|
780
|
+
default: return false;
|
|
781
|
+
}
|
|
782
|
+
return true;
|
|
783
|
+
};
|
|
784
|
+
/* c8 ignore stop */
|
|
785
|
+
const isArray = isArray$1;
|
|
786
|
+
|
|
787
|
+
//#endregion
|
|
788
|
+
//#region node_modules/y-protocols/awareness.js
|
|
789
|
+
/**
|
|
790
|
+
* @module awareness-protocol
|
|
791
|
+
*/
|
|
792
|
+
const outdatedTimeout = 3e4;
|
|
793
|
+
/**
|
|
794
|
+
* @typedef {Object} MetaClientState
|
|
795
|
+
* @property {number} MetaClientState.clock
|
|
796
|
+
* @property {number} MetaClientState.lastUpdated unix timestamp
|
|
797
|
+
*/
|
|
798
|
+
/**
|
|
799
|
+
* The Awareness class implements a simple shared state protocol that can be used for non-persistent data like awareness information
|
|
800
|
+
* (cursor, username, status, ..). Each client can update its own local state and listen to state changes of
|
|
801
|
+
* remote clients. Every client may set a state of a remote peer to `null` to mark the client as offline.
|
|
802
|
+
*
|
|
803
|
+
* Each client is identified by a unique client id (something we borrow from `doc.clientID`). A client can override
|
|
804
|
+
* its own state by propagating a message with an increasing timestamp (`clock`). If such a message is received, it is
|
|
805
|
+
* applied if the known state of that client is older than the new state (`clock < newClock`). If a client thinks that
|
|
806
|
+
* a remote client is offline, it may propagate a message with
|
|
807
|
+
* `{ clock: currentClientClock, state: null, client: remoteClient }`. If such a
|
|
808
|
+
* message is received, and the known clock of that client equals the received clock, it will override the state with `null`.
|
|
809
|
+
*
|
|
810
|
+
* Before a client disconnects, it should propagate a `null` state with an updated clock.
|
|
811
|
+
*
|
|
812
|
+
* Awareness states must be updated every 30 seconds. Otherwise the Awareness instance will delete the client state.
|
|
813
|
+
*
|
|
814
|
+
* @extends {Observable<string>}
|
|
815
|
+
*/
|
|
816
|
+
var Awareness = class extends Observable {
|
|
817
|
+
/**
|
|
818
|
+
* @param {Y.Doc} doc
|
|
819
|
+
*/
|
|
820
|
+
constructor(doc) {
|
|
821
|
+
super();
|
|
822
|
+
this.doc = doc;
|
|
823
|
+
/**
|
|
824
|
+
* @type {number}
|
|
825
|
+
*/
|
|
826
|
+
this.clientID = doc.clientID;
|
|
827
|
+
/**
|
|
828
|
+
* Maps from client id to client state
|
|
829
|
+
* @type {Map<number, Object<string, any>>}
|
|
830
|
+
*/
|
|
831
|
+
this.states = /* @__PURE__ */ new Map();
|
|
832
|
+
/**
|
|
833
|
+
* @type {Map<number, MetaClientState>}
|
|
834
|
+
*/
|
|
835
|
+
this.meta = /* @__PURE__ */ new Map();
|
|
836
|
+
this._checkInterval = setInterval(() => {
|
|
837
|
+
const now = getUnixTime();
|
|
838
|
+
if (this.getLocalState() !== null && outdatedTimeout / 2 <= now - this.meta.get(this.clientID).lastUpdated) this.setLocalState(this.getLocalState());
|
|
839
|
+
/**
|
|
840
|
+
* @type {Array<number>}
|
|
841
|
+
*/
|
|
842
|
+
const remove = [];
|
|
843
|
+
this.meta.forEach((meta, clientid) => {
|
|
844
|
+
if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) remove.push(clientid);
|
|
845
|
+
});
|
|
846
|
+
if (remove.length > 0) removeAwarenessStates(this, remove, "timeout");
|
|
847
|
+
}, floor(outdatedTimeout / 10));
|
|
848
|
+
doc.on("destroy", () => {
|
|
849
|
+
this.destroy();
|
|
850
|
+
});
|
|
851
|
+
this.setLocalState({});
|
|
852
|
+
}
|
|
853
|
+
destroy() {
|
|
854
|
+
this.emit("destroy", [this]);
|
|
855
|
+
this.setLocalState(null);
|
|
856
|
+
super.destroy();
|
|
857
|
+
clearInterval(this._checkInterval);
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* @return {Object<string,any>|null}
|
|
861
|
+
*/
|
|
862
|
+
getLocalState() {
|
|
863
|
+
return this.states.get(this.clientID) || null;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* @param {Object<string,any>|null} state
|
|
867
|
+
*/
|
|
868
|
+
setLocalState(state) {
|
|
869
|
+
const clientID = this.clientID;
|
|
870
|
+
const currLocalMeta = this.meta.get(clientID);
|
|
871
|
+
const clock = currLocalMeta === void 0 ? 0 : currLocalMeta.clock + 1;
|
|
872
|
+
const prevState = this.states.get(clientID);
|
|
873
|
+
if (state === null) this.states.delete(clientID);
|
|
874
|
+
else this.states.set(clientID, state);
|
|
875
|
+
this.meta.set(clientID, {
|
|
876
|
+
clock,
|
|
877
|
+
lastUpdated: getUnixTime()
|
|
878
|
+
});
|
|
879
|
+
const added = [];
|
|
880
|
+
const updated = [];
|
|
881
|
+
const filteredUpdated = [];
|
|
882
|
+
const removed = [];
|
|
883
|
+
if (state === null) removed.push(clientID);
|
|
884
|
+
else if (prevState == null) {
|
|
885
|
+
if (state != null) added.push(clientID);
|
|
886
|
+
} else {
|
|
887
|
+
updated.push(clientID);
|
|
888
|
+
if (!equalityDeep(prevState, state)) filteredUpdated.push(clientID);
|
|
889
|
+
}
|
|
890
|
+
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) this.emit("change", [{
|
|
891
|
+
added,
|
|
892
|
+
updated: filteredUpdated,
|
|
893
|
+
removed
|
|
894
|
+
}, "local"]);
|
|
895
|
+
this.emit("update", [{
|
|
896
|
+
added,
|
|
897
|
+
updated,
|
|
898
|
+
removed
|
|
899
|
+
}, "local"]);
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* @param {string} field
|
|
903
|
+
* @param {any} value
|
|
904
|
+
*/
|
|
905
|
+
setLocalStateField(field, value) {
|
|
906
|
+
const state = this.getLocalState();
|
|
907
|
+
if (state !== null) this.setLocalState({
|
|
908
|
+
...state,
|
|
909
|
+
[field]: value
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* @return {Map<number,Object<string,any>>}
|
|
914
|
+
*/
|
|
915
|
+
getStates() {
|
|
916
|
+
return this.states;
|
|
917
|
+
}
|
|
853
918
|
};
|
|
854
|
-
|
|
855
|
-
/**
|
|
856
|
-
* @module awareness-protocol
|
|
857
|
-
*/
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
const outdatedTimeout = 30000;
|
|
861
|
-
|
|
862
|
-
/**
|
|
863
|
-
* @typedef {Object} MetaClientState
|
|
864
|
-
* @property {number} MetaClientState.clock
|
|
865
|
-
* @property {number} MetaClientState.lastUpdated unix timestamp
|
|
866
|
-
*/
|
|
867
|
-
|
|
868
|
-
/**
|
|
869
|
-
* The Awareness class implements a simple shared state protocol that can be used for non-persistent data like awareness information
|
|
870
|
-
* (cursor, username, status, ..). Each client can update its own local state and listen to state changes of
|
|
871
|
-
* remote clients. Every client may set a state of a remote peer to `null` to mark the client as offline.
|
|
872
|
-
*
|
|
873
|
-
* Each client is identified by a unique client id (something we borrow from `doc.clientID`). A client can override
|
|
874
|
-
* its own state by propagating a message with an increasing timestamp (`clock`). If such a message is received, it is
|
|
875
|
-
* applied if the known state of that client is older than the new state (`clock < newClock`). If a client thinks that
|
|
876
|
-
* a remote client is offline, it may propagate a message with
|
|
877
|
-
* `{ clock: currentClientClock, state: null, client: remoteClient }`. If such a
|
|
878
|
-
* message is received, and the known clock of that client equals the received clock, it will override the state with `null`.
|
|
879
|
-
*
|
|
880
|
-
* Before a client disconnects, it should propagate a `null` state with an updated clock.
|
|
881
|
-
*
|
|
882
|
-
* Awareness states must be updated every 30 seconds. Otherwise the Awareness instance will delete the client state.
|
|
883
|
-
*
|
|
884
|
-
* @extends {Observable<string>}
|
|
885
|
-
*/
|
|
886
|
-
class Awareness extends Observable {
|
|
887
|
-
/**
|
|
888
|
-
* @param {Y.Doc} doc
|
|
889
|
-
*/
|
|
890
|
-
constructor (doc) {
|
|
891
|
-
super();
|
|
892
|
-
this.doc = doc;
|
|
893
|
-
/**
|
|
894
|
-
* @type {number}
|
|
895
|
-
*/
|
|
896
|
-
this.clientID = doc.clientID;
|
|
897
|
-
/**
|
|
898
|
-
* Maps from client id to client state
|
|
899
|
-
* @type {Map<number, Object<string, any>>}
|
|
900
|
-
*/
|
|
901
|
-
this.states = new Map();
|
|
902
|
-
/**
|
|
903
|
-
* @type {Map<number, MetaClientState>}
|
|
904
|
-
*/
|
|
905
|
-
this.meta = new Map();
|
|
906
|
-
this._checkInterval = /** @type {any} */ (setInterval(() => {
|
|
907
|
-
const now = getUnixTime();
|
|
908
|
-
if (this.getLocalState() !== null && (outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ (this.meta.get(this.clientID)).lastUpdated)) {
|
|
909
|
-
// renew local clock
|
|
910
|
-
this.setLocalState(this.getLocalState());
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
* @type {Array<number>}
|
|
914
|
-
*/
|
|
915
|
-
const remove = [];
|
|
916
|
-
this.meta.forEach((meta, clientid) => {
|
|
917
|
-
if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) {
|
|
918
|
-
remove.push(clientid);
|
|
919
|
-
}
|
|
920
|
-
});
|
|
921
|
-
if (remove.length > 0) {
|
|
922
|
-
removeAwarenessStates(this, remove, 'timeout');
|
|
923
|
-
}
|
|
924
|
-
}, floor(outdatedTimeout / 10)));
|
|
925
|
-
doc.on('destroy', () => {
|
|
926
|
-
this.destroy();
|
|
927
|
-
});
|
|
928
|
-
this.setLocalState({});
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
destroy () {
|
|
932
|
-
this.emit('destroy', [this]);
|
|
933
|
-
this.setLocalState(null);
|
|
934
|
-
super.destroy();
|
|
935
|
-
clearInterval(this._checkInterval);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
/**
|
|
939
|
-
* @return {Object<string,any>|null}
|
|
940
|
-
*/
|
|
941
|
-
getLocalState () {
|
|
942
|
-
return this.states.get(this.clientID) || null
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
/**
|
|
946
|
-
* @param {Object<string,any>|null} state
|
|
947
|
-
*/
|
|
948
|
-
setLocalState (state) {
|
|
949
|
-
const clientID = this.clientID;
|
|
950
|
-
const currLocalMeta = this.meta.get(clientID);
|
|
951
|
-
const clock = currLocalMeta === undefined ? 0 : currLocalMeta.clock + 1;
|
|
952
|
-
const prevState = this.states.get(clientID);
|
|
953
|
-
if (state === null) {
|
|
954
|
-
this.states.delete(clientID);
|
|
955
|
-
} else {
|
|
956
|
-
this.states.set(clientID, state);
|
|
957
|
-
}
|
|
958
|
-
this.meta.set(clientID, {
|
|
959
|
-
clock,
|
|
960
|
-
lastUpdated: getUnixTime()
|
|
961
|
-
});
|
|
962
|
-
const added = [];
|
|
963
|
-
const updated = [];
|
|
964
|
-
const filteredUpdated = [];
|
|
965
|
-
const removed = [];
|
|
966
|
-
if (state === null) {
|
|
967
|
-
removed.push(clientID);
|
|
968
|
-
} else if (prevState == null) {
|
|
969
|
-
if (state != null) {
|
|
970
|
-
added.push(clientID);
|
|
971
|
-
}
|
|
972
|
-
} else {
|
|
973
|
-
updated.push(clientID);
|
|
974
|
-
if (!equalityDeep(prevState, state)) {
|
|
975
|
-
filteredUpdated.push(clientID);
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) {
|
|
979
|
-
this.emit('change', [{ added, updated: filteredUpdated, removed }, 'local']);
|
|
980
|
-
}
|
|
981
|
-
this.emit('update', [{ added, updated, removed }, 'local']);
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
/**
|
|
985
|
-
* @param {string} field
|
|
986
|
-
* @param {any} value
|
|
987
|
-
*/
|
|
988
|
-
setLocalStateField (field, value) {
|
|
989
|
-
const state = this.getLocalState();
|
|
990
|
-
if (state !== null) {
|
|
991
|
-
this.setLocalState({
|
|
992
|
-
...state,
|
|
993
|
-
[field]: value
|
|
994
|
-
});
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
/**
|
|
999
|
-
* @return {Map<number,Object<string,any>>}
|
|
1000
|
-
*/
|
|
1001
|
-
getStates () {
|
|
1002
|
-
return this.states
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
919
|
/**
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
920
|
+
* Mark (remote) clients as inactive and remove them from the list of active peers.
|
|
921
|
+
* This change will be propagated to remote clients.
|
|
922
|
+
*
|
|
923
|
+
* @param {Awareness} awareness
|
|
924
|
+
* @param {Array<number>} clients
|
|
925
|
+
* @param {any} origin
|
|
926
|
+
*/
|
|
1014
927
|
const removeAwarenessStates = (awareness, clients, origin) => {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
928
|
+
const removed = [];
|
|
929
|
+
for (let i = 0; i < clients.length; i++) {
|
|
930
|
+
const clientID = clients[i];
|
|
931
|
+
if (awareness.states.has(clientID)) {
|
|
932
|
+
awareness.states.delete(clientID);
|
|
933
|
+
if (clientID === awareness.clientID) {
|
|
934
|
+
const curMeta = awareness.meta.get(clientID);
|
|
935
|
+
awareness.meta.set(clientID, {
|
|
936
|
+
clock: curMeta.clock + 1,
|
|
937
|
+
lastUpdated: getUnixTime()
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
removed.push(clientID);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (removed.length > 0) {
|
|
944
|
+
awareness.emit("change", [{
|
|
945
|
+
added: [],
|
|
946
|
+
updated: [],
|
|
947
|
+
removed
|
|
948
|
+
}, origin]);
|
|
949
|
+
awareness.emit("update", [{
|
|
950
|
+
added: [],
|
|
951
|
+
updated: [],
|
|
952
|
+
removed
|
|
953
|
+
}, origin]);
|
|
954
|
+
}
|
|
1034
955
|
};
|
|
1035
|
-
|
|
1036
956
|
/**
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
957
|
+
* @param {Awareness} awareness
|
|
958
|
+
* @param {Array<number>} clients
|
|
959
|
+
* @return {Uint8Array}
|
|
960
|
+
*/
|
|
1041
961
|
const encodeAwarenessUpdate = (awareness, clients, states = awareness.states) => {
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
962
|
+
const len = clients.length;
|
|
963
|
+
const encoder = createEncoder();
|
|
964
|
+
writeVarUint(encoder, len);
|
|
965
|
+
for (let i = 0; i < len; i++) {
|
|
966
|
+
const clientID = clients[i];
|
|
967
|
+
const state = states.get(clientID) || null;
|
|
968
|
+
const clock = awareness.meta.get(clientID).clock;
|
|
969
|
+
writeVarUint(encoder, clientID);
|
|
970
|
+
writeVarUint(encoder, clock);
|
|
971
|
+
writeVarString(encoder, JSON.stringify(state));
|
|
972
|
+
}
|
|
973
|
+
return toUint8Array(encoder);
|
|
1054
974
|
};
|
|
1055
|
-
|
|
1056
975
|
/**
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
976
|
+
* @param {Awareness} awareness
|
|
977
|
+
* @param {Uint8Array} update
|
|
978
|
+
* @param {any} origin This will be added to the emitted change event
|
|
979
|
+
*/
|
|
1061
980
|
const applyAwarenessUpdate = (awareness, update, origin) => {
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) {
|
|
1106
|
-
awareness.emit('change', [{
|
|
1107
|
-
added, updated: filteredUpdated, removed
|
|
1108
|
-
}, origin]);
|
|
1109
|
-
}
|
|
1110
|
-
if (added.length > 0 || updated.length > 0 || removed.length > 0) {
|
|
1111
|
-
awareness.emit('update', [{
|
|
1112
|
-
added, updated, removed
|
|
1113
|
-
}, origin]);
|
|
1114
|
-
}
|
|
981
|
+
const decoder = createDecoder(update);
|
|
982
|
+
const timestamp = getUnixTime();
|
|
983
|
+
const added = [];
|
|
984
|
+
const updated = [];
|
|
985
|
+
const filteredUpdated = [];
|
|
986
|
+
const removed = [];
|
|
987
|
+
const len = readVarUint(decoder);
|
|
988
|
+
for (let i = 0; i < len; i++) {
|
|
989
|
+
const clientID = readVarUint(decoder);
|
|
990
|
+
let clock = readVarUint(decoder);
|
|
991
|
+
const state = JSON.parse(readVarString(decoder));
|
|
992
|
+
const clientMeta = awareness.meta.get(clientID);
|
|
993
|
+
const prevState = awareness.states.get(clientID);
|
|
994
|
+
const currClock = clientMeta === void 0 ? 0 : clientMeta.clock;
|
|
995
|
+
if (currClock < clock || currClock === clock && state === null && awareness.states.has(clientID)) {
|
|
996
|
+
if (state === null) if (clientID === awareness.clientID && awareness.getLocalState() != null) clock++;
|
|
997
|
+
else awareness.states.delete(clientID);
|
|
998
|
+
else awareness.states.set(clientID, state);
|
|
999
|
+
awareness.meta.set(clientID, {
|
|
1000
|
+
clock,
|
|
1001
|
+
lastUpdated: timestamp
|
|
1002
|
+
});
|
|
1003
|
+
if (clientMeta === void 0 && state !== null) added.push(clientID);
|
|
1004
|
+
else if (clientMeta !== void 0 && state === null) removed.push(clientID);
|
|
1005
|
+
else if (state !== null) {
|
|
1006
|
+
if (!equalityDeep(state, prevState)) filteredUpdated.push(clientID);
|
|
1007
|
+
updated.push(clientID);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) awareness.emit("change", [{
|
|
1012
|
+
added,
|
|
1013
|
+
updated: filteredUpdated,
|
|
1014
|
+
removed
|
|
1015
|
+
}, origin]);
|
|
1016
|
+
if (added.length > 0 || updated.length > 0 || removed.length > 0) awareness.emit("update", [{
|
|
1017
|
+
added,
|
|
1018
|
+
updated,
|
|
1019
|
+
removed
|
|
1020
|
+
}, origin]);
|
|
1115
1021
|
};
|
|
1116
1022
|
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
}
|
|
1144
|
-
else {
|
|
1145
|
-
delete this.callbacks[event];
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
return this;
|
|
1149
|
-
}
|
|
1150
|
-
removeAllListeners() {
|
|
1151
|
-
this.callbacks = {};
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
class IncomingMessage {
|
|
1156
|
-
constructor(data) {
|
|
1157
|
-
this.data = data;
|
|
1158
|
-
this.encoder = createEncoder();
|
|
1159
|
-
this.decoder = createDecoder(new Uint8Array(this.data));
|
|
1160
|
-
}
|
|
1161
|
-
peekVarString() {
|
|
1162
|
-
return peekVarString(this.decoder);
|
|
1163
|
-
}
|
|
1164
|
-
readVarUint() {
|
|
1165
|
-
return readVarUint(this.decoder);
|
|
1166
|
-
}
|
|
1167
|
-
readVarString() {
|
|
1168
|
-
return readVarString(this.decoder);
|
|
1169
|
-
}
|
|
1170
|
-
readVarUint8Array() {
|
|
1171
|
-
return readVarUint8Array(this.decoder);
|
|
1172
|
-
}
|
|
1173
|
-
writeVarUint(type) {
|
|
1174
|
-
return writeVarUint(this.encoder, type);
|
|
1175
|
-
}
|
|
1176
|
-
writeVarString(string) {
|
|
1177
|
-
return writeVarString(this.encoder, string);
|
|
1178
|
-
}
|
|
1179
|
-
writeVarUint8Array(data) {
|
|
1180
|
-
return writeVarUint8Array(this.encoder, data);
|
|
1181
|
-
}
|
|
1182
|
-
length() {
|
|
1183
|
-
return length$1(this.encoder);
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
exports.MessageType = void 0;
|
|
1188
|
-
(function (MessageType) {
|
|
1189
|
-
MessageType[MessageType["Sync"] = 0] = "Sync";
|
|
1190
|
-
MessageType[MessageType["Awareness"] = 1] = "Awareness";
|
|
1191
|
-
MessageType[MessageType["Auth"] = 2] = "Auth";
|
|
1192
|
-
MessageType[MessageType["QueryAwareness"] = 3] = "QueryAwareness";
|
|
1193
|
-
MessageType[MessageType["Stateless"] = 5] = "Stateless";
|
|
1194
|
-
MessageType[MessageType["CLOSE"] = 7] = "CLOSE";
|
|
1195
|
-
MessageType[MessageType["SyncStatus"] = 8] = "SyncStatus";
|
|
1196
|
-
})(exports.MessageType || (exports.MessageType = {}));
|
|
1197
|
-
exports.WebSocketStatus = void 0;
|
|
1198
|
-
(function (WebSocketStatus) {
|
|
1199
|
-
WebSocketStatus["Connecting"] = "connecting";
|
|
1200
|
-
WebSocketStatus["Connected"] = "connected";
|
|
1201
|
-
WebSocketStatus["Disconnected"] = "disconnected";
|
|
1202
|
-
})(exports.WebSocketStatus || (exports.WebSocketStatus = {}));
|
|
1203
|
-
|
|
1204
|
-
class OutgoingMessage {
|
|
1205
|
-
constructor() {
|
|
1206
|
-
this.encoder = createEncoder();
|
|
1207
|
-
}
|
|
1208
|
-
get(args) {
|
|
1209
|
-
return args.encoder;
|
|
1210
|
-
}
|
|
1211
|
-
toUint8Array() {
|
|
1212
|
-
return toUint8Array(this.encoder);
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
class CloseMessage extends OutgoingMessage {
|
|
1217
|
-
constructor() {
|
|
1218
|
-
super(...arguments);
|
|
1219
|
-
this.type = exports.MessageType.CLOSE;
|
|
1220
|
-
this.description = "Ask the server to close the connection";
|
|
1221
|
-
}
|
|
1222
|
-
get(args) {
|
|
1223
|
-
writeVarString(this.encoder, args.documentName);
|
|
1224
|
-
writeVarUint(this.encoder, this.type);
|
|
1225
|
-
return this.encoder;
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
class HocuspocusProviderWebsocket extends EventEmitter {
|
|
1230
|
-
constructor(configuration) {
|
|
1231
|
-
super();
|
|
1232
|
-
this.messageQueue = [];
|
|
1233
|
-
this.configuration = {
|
|
1234
|
-
url: "",
|
|
1235
|
-
autoConnect: true,
|
|
1236
|
-
preserveTrailingSlash: false,
|
|
1237
|
-
// @ts-ignore
|
|
1238
|
-
document: undefined,
|
|
1239
|
-
WebSocketPolyfill: undefined,
|
|
1240
|
-
// TODO: this should depend on awareness.outdatedTime
|
|
1241
|
-
messageReconnectTimeout: 30000,
|
|
1242
|
-
// 1 second
|
|
1243
|
-
delay: 1000,
|
|
1244
|
-
// instant
|
|
1245
|
-
initialDelay: 0,
|
|
1246
|
-
// double the delay each time
|
|
1247
|
-
factor: 2,
|
|
1248
|
-
// unlimited retries
|
|
1249
|
-
maxAttempts: 0,
|
|
1250
|
-
// wait at least 1 second
|
|
1251
|
-
minDelay: 1000,
|
|
1252
|
-
// at least every 30 seconds
|
|
1253
|
-
maxDelay: 30000,
|
|
1254
|
-
// randomize
|
|
1255
|
-
jitter: true,
|
|
1256
|
-
// retry forever
|
|
1257
|
-
timeout: 0,
|
|
1258
|
-
onOpen: () => null,
|
|
1259
|
-
onConnect: () => null,
|
|
1260
|
-
onMessage: () => null,
|
|
1261
|
-
onOutgoingMessage: () => null,
|
|
1262
|
-
onStatus: () => null,
|
|
1263
|
-
onDisconnect: () => null,
|
|
1264
|
-
onClose: () => null,
|
|
1265
|
-
onDestroy: () => null,
|
|
1266
|
-
onAwarenessUpdate: () => null,
|
|
1267
|
-
onAwarenessChange: () => null,
|
|
1268
|
-
handleTimeout: null,
|
|
1269
|
-
providerMap: new Map(),
|
|
1270
|
-
};
|
|
1271
|
-
this.webSocket = null;
|
|
1272
|
-
this.webSocketHandlers = {};
|
|
1273
|
-
this.shouldConnect = true;
|
|
1274
|
-
this.status = exports.WebSocketStatus.Disconnected;
|
|
1275
|
-
this.lastMessageReceived = 0;
|
|
1276
|
-
this.identifier = 0;
|
|
1277
|
-
this.intervals = {
|
|
1278
|
-
connectionChecker: null,
|
|
1279
|
-
};
|
|
1280
|
-
this.connectionAttempt = null;
|
|
1281
|
-
this.receivedOnOpenPayload = undefined;
|
|
1282
|
-
this.closeTries = 0;
|
|
1283
|
-
this.setConfiguration(configuration);
|
|
1284
|
-
this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill
|
|
1285
|
-
? configuration.WebSocketPolyfill
|
|
1286
|
-
: WebSocket;
|
|
1287
|
-
this.on("open", this.configuration.onOpen);
|
|
1288
|
-
this.on("open", this.onOpen.bind(this));
|
|
1289
|
-
this.on("connect", this.configuration.onConnect);
|
|
1290
|
-
this.on("message", this.configuration.onMessage);
|
|
1291
|
-
this.on("outgoingMessage", this.configuration.onOutgoingMessage);
|
|
1292
|
-
this.on("status", this.configuration.onStatus);
|
|
1293
|
-
this.on("disconnect", this.configuration.onDisconnect);
|
|
1294
|
-
this.on("close", this.configuration.onClose);
|
|
1295
|
-
this.on("destroy", this.configuration.onDestroy);
|
|
1296
|
-
this.on("awarenessUpdate", this.configuration.onAwarenessUpdate);
|
|
1297
|
-
this.on("awarenessChange", this.configuration.onAwarenessChange);
|
|
1298
|
-
this.on("close", this.onClose.bind(this));
|
|
1299
|
-
this.on("message", this.onMessage.bind(this));
|
|
1300
|
-
this.intervals.connectionChecker = setInterval(this.checkConnection.bind(this), this.configuration.messageReconnectTimeout / 10);
|
|
1301
|
-
if (this.shouldConnect) {
|
|
1302
|
-
this.connect();
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
async onOpen(event) {
|
|
1306
|
-
this.status = exports.WebSocketStatus.Connected;
|
|
1307
|
-
this.emit("status", { status: exports.WebSocketStatus.Connected });
|
|
1308
|
-
this.cancelWebsocketRetry = undefined;
|
|
1309
|
-
this.receivedOnOpenPayload = event;
|
|
1310
|
-
}
|
|
1311
|
-
attach(provider) {
|
|
1312
|
-
this.configuration.providerMap.set(provider.configuration.name, provider);
|
|
1313
|
-
if (this.status === exports.WebSocketStatus.Disconnected && this.shouldConnect) {
|
|
1314
|
-
this.connect();
|
|
1315
|
-
}
|
|
1316
|
-
if (this.receivedOnOpenPayload &&
|
|
1317
|
-
this.status === exports.WebSocketStatus.Connected) {
|
|
1318
|
-
provider.onOpen(this.receivedOnOpenPayload);
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
detach(provider) {
|
|
1322
|
-
if (this.configuration.providerMap.has(provider.configuration.name)) {
|
|
1323
|
-
provider.send(CloseMessage, {
|
|
1324
|
-
documentName: provider.configuration.name,
|
|
1325
|
-
});
|
|
1326
|
-
this.configuration.providerMap.delete(provider.configuration.name);
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
setConfiguration(configuration = {}) {
|
|
1330
|
-
this.configuration = { ...this.configuration, ...configuration };
|
|
1331
|
-
if (!this.configuration.autoConnect) {
|
|
1332
|
-
this.shouldConnect = false;
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1335
|
-
async connect() {
|
|
1336
|
-
if (this.status === exports.WebSocketStatus.Connected) {
|
|
1337
|
-
return;
|
|
1338
|
-
}
|
|
1339
|
-
// Always cancel any previously initiated connection retryer instances
|
|
1340
|
-
if (this.cancelWebsocketRetry) {
|
|
1341
|
-
this.cancelWebsocketRetry();
|
|
1342
|
-
this.cancelWebsocketRetry = undefined;
|
|
1343
|
-
}
|
|
1344
|
-
this.receivedOnOpenPayload = undefined;
|
|
1345
|
-
this.shouldConnect = true;
|
|
1346
|
-
const abortableRetry = () => {
|
|
1347
|
-
let cancelAttempt = false;
|
|
1348
|
-
const retryPromise = attempt.retry(this.createWebSocketConnection.bind(this), {
|
|
1349
|
-
delay: this.configuration.delay,
|
|
1350
|
-
initialDelay: this.configuration.initialDelay,
|
|
1351
|
-
factor: this.configuration.factor,
|
|
1352
|
-
maxAttempts: this.configuration.maxAttempts,
|
|
1353
|
-
minDelay: this.configuration.minDelay,
|
|
1354
|
-
maxDelay: this.configuration.maxDelay,
|
|
1355
|
-
jitter: this.configuration.jitter,
|
|
1356
|
-
timeout: this.configuration.timeout,
|
|
1357
|
-
handleTimeout: this.configuration.handleTimeout,
|
|
1358
|
-
beforeAttempt: (context) => {
|
|
1359
|
-
if (!this.shouldConnect || cancelAttempt) {
|
|
1360
|
-
context.abort();
|
|
1361
|
-
}
|
|
1362
|
-
},
|
|
1363
|
-
}).catch((error) => {
|
|
1364
|
-
// If we aborted the connection attempt then don’t throw an error
|
|
1365
|
-
// ref: https://github.com/lifeomic/attempt/blob/master/src/index.ts#L136
|
|
1366
|
-
if (error && error.code !== "ATTEMPT_ABORTED") {
|
|
1367
|
-
throw error;
|
|
1368
|
-
}
|
|
1369
|
-
});
|
|
1370
|
-
return {
|
|
1371
|
-
retryPromise,
|
|
1372
|
-
cancelFunc: () => {
|
|
1373
|
-
cancelAttempt = true;
|
|
1374
|
-
},
|
|
1375
|
-
};
|
|
1376
|
-
};
|
|
1377
|
-
const { retryPromise, cancelFunc } = abortableRetry();
|
|
1378
|
-
this.cancelWebsocketRetry = cancelFunc;
|
|
1379
|
-
return retryPromise;
|
|
1380
|
-
}
|
|
1381
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
1382
|
-
attachWebSocketListeners(ws, reject) {
|
|
1383
|
-
const { identifier } = ws;
|
|
1384
|
-
const onMessageHandler = (payload) => this.emit("message", payload);
|
|
1385
|
-
const onCloseHandler = (payload) => this.emit("close", { event: payload });
|
|
1386
|
-
const onOpenHandler = (payload) => this.emit("open", payload);
|
|
1387
|
-
const onErrorHandler = (err) => {
|
|
1388
|
-
reject(err);
|
|
1389
|
-
};
|
|
1390
|
-
this.webSocketHandlers[identifier] = {
|
|
1391
|
-
message: onMessageHandler,
|
|
1392
|
-
close: onCloseHandler,
|
|
1393
|
-
open: onOpenHandler,
|
|
1394
|
-
error: onErrorHandler,
|
|
1395
|
-
};
|
|
1396
|
-
const handlers = this.webSocketHandlers[ws.identifier];
|
|
1397
|
-
Object.keys(handlers).forEach((name) => {
|
|
1398
|
-
ws.addEventListener(name, handlers[name]);
|
|
1399
|
-
});
|
|
1400
|
-
}
|
|
1401
|
-
cleanupWebSocket() {
|
|
1402
|
-
if (!this.webSocket) {
|
|
1403
|
-
return;
|
|
1404
|
-
}
|
|
1405
|
-
const { identifier } = this.webSocket;
|
|
1406
|
-
const handlers = this.webSocketHandlers[identifier];
|
|
1407
|
-
Object.keys(handlers).forEach((name) => {
|
|
1408
|
-
var _a;
|
|
1409
|
-
(_a = this.webSocket) === null || _a === void 0 ? void 0 : _a.removeEventListener(name, handlers[name]);
|
|
1410
|
-
delete this.webSocketHandlers[identifier];
|
|
1411
|
-
});
|
|
1412
|
-
this.webSocket.close();
|
|
1413
|
-
this.webSocket = null;
|
|
1414
|
-
}
|
|
1415
|
-
createWebSocketConnection() {
|
|
1416
|
-
return new Promise((resolve, reject) => {
|
|
1417
|
-
if (this.webSocket) {
|
|
1418
|
-
this.messageQueue = [];
|
|
1419
|
-
this.cleanupWebSocket();
|
|
1420
|
-
}
|
|
1421
|
-
this.lastMessageReceived = 0;
|
|
1422
|
-
this.identifier += 1;
|
|
1423
|
-
// Init the WebSocket connection
|
|
1424
|
-
const ws = new this.configuration.WebSocketPolyfill(this.url);
|
|
1425
|
-
ws.binaryType = "arraybuffer";
|
|
1426
|
-
ws.identifier = this.identifier;
|
|
1427
|
-
this.attachWebSocketListeners(ws, reject);
|
|
1428
|
-
this.webSocket = ws;
|
|
1429
|
-
// Reset the status
|
|
1430
|
-
this.status = exports.WebSocketStatus.Connecting;
|
|
1431
|
-
this.emit("status", { status: exports.WebSocketStatus.Connecting });
|
|
1432
|
-
// Store resolve/reject for later use
|
|
1433
|
-
this.connectionAttempt = {
|
|
1434
|
-
resolve,
|
|
1435
|
-
reject,
|
|
1436
|
-
};
|
|
1437
|
-
});
|
|
1438
|
-
}
|
|
1439
|
-
onMessage(event) {
|
|
1440
|
-
var _a;
|
|
1441
|
-
this.resolveConnectionAttempt();
|
|
1442
|
-
this.lastMessageReceived = getUnixTime();
|
|
1443
|
-
const message = new IncomingMessage(event.data);
|
|
1444
|
-
const documentName = message.peekVarString();
|
|
1445
|
-
(_a = this.configuration.providerMap.get(documentName)) === null || _a === void 0 ? void 0 : _a.onMessage(event);
|
|
1446
|
-
}
|
|
1447
|
-
resolveConnectionAttempt() {
|
|
1448
|
-
if (this.connectionAttempt) {
|
|
1449
|
-
this.connectionAttempt.resolve();
|
|
1450
|
-
this.connectionAttempt = null;
|
|
1451
|
-
this.status = exports.WebSocketStatus.Connected;
|
|
1452
|
-
this.emit("status", { status: exports.WebSocketStatus.Connected });
|
|
1453
|
-
this.emit("connect");
|
|
1454
|
-
this.messageQueue.forEach((message) => this.send(message));
|
|
1455
|
-
this.messageQueue = [];
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
stopConnectionAttempt() {
|
|
1459
|
-
this.connectionAttempt = null;
|
|
1460
|
-
}
|
|
1461
|
-
rejectConnectionAttempt() {
|
|
1462
|
-
var _a;
|
|
1463
|
-
(_a = this.connectionAttempt) === null || _a === void 0 ? void 0 : _a.reject();
|
|
1464
|
-
this.connectionAttempt = null;
|
|
1465
|
-
}
|
|
1466
|
-
checkConnection() {
|
|
1467
|
-
var _a;
|
|
1468
|
-
// Don’t check the connection when it’s not even established
|
|
1469
|
-
if (this.status !== exports.WebSocketStatus.Connected) {
|
|
1470
|
-
return;
|
|
1471
|
-
}
|
|
1472
|
-
// Don’t close the connection while waiting for the first message
|
|
1473
|
-
if (!this.lastMessageReceived) {
|
|
1474
|
-
return;
|
|
1475
|
-
}
|
|
1476
|
-
// Don’t close the connection when a message was received recently
|
|
1477
|
-
if (this.configuration.messageReconnectTimeout >=
|
|
1478
|
-
getUnixTime() - this.lastMessageReceived) {
|
|
1479
|
-
return;
|
|
1480
|
-
}
|
|
1481
|
-
// No message received in a long time, not even your own
|
|
1482
|
-
// Awareness updates, which are updated every 15 seconds
|
|
1483
|
-
// if awareness is enabled.
|
|
1484
|
-
this.closeTries += 1;
|
|
1485
|
-
// https://bugs.webkit.org/show_bug.cgi?id=247943
|
|
1486
|
-
if (this.closeTries > 2) {
|
|
1487
|
-
this.onClose({
|
|
1488
|
-
event: {
|
|
1489
|
-
code: 4408,
|
|
1490
|
-
reason: "forced",
|
|
1491
|
-
},
|
|
1492
|
-
});
|
|
1493
|
-
this.closeTries = 0;
|
|
1494
|
-
}
|
|
1495
|
-
else {
|
|
1496
|
-
(_a = this.webSocket) === null || _a === void 0 ? void 0 : _a.close();
|
|
1497
|
-
this.messageQueue = [];
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
get serverUrl() {
|
|
1501
|
-
if (this.configuration.preserveTrailingSlash) {
|
|
1502
|
-
return this.configuration.url;
|
|
1503
|
-
}
|
|
1504
|
-
// By default, ensure that the URL never ends with /
|
|
1505
|
-
let url = this.configuration.url;
|
|
1506
|
-
while (url[url.length - 1] === "/") {
|
|
1507
|
-
url = url.slice(0, url.length - 1);
|
|
1508
|
-
}
|
|
1509
|
-
return url;
|
|
1510
|
-
}
|
|
1511
|
-
get url() {
|
|
1512
|
-
return this.serverUrl;
|
|
1513
|
-
}
|
|
1514
|
-
disconnect() {
|
|
1515
|
-
this.shouldConnect = false;
|
|
1516
|
-
if (this.webSocket === null) {
|
|
1517
|
-
return;
|
|
1518
|
-
}
|
|
1519
|
-
try {
|
|
1520
|
-
this.webSocket.close();
|
|
1521
|
-
this.messageQueue = [];
|
|
1522
|
-
}
|
|
1523
|
-
catch (e) {
|
|
1524
|
-
console.error(e);
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
send(message) {
|
|
1528
|
-
var _a;
|
|
1529
|
-
if (((_a = this.webSocket) === null || _a === void 0 ? void 0 : _a.readyState) === common.WsReadyStates.Open) {
|
|
1530
|
-
this.webSocket.send(message);
|
|
1531
|
-
}
|
|
1532
|
-
else {
|
|
1533
|
-
this.messageQueue.push(message);
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
onClose({ event }) {
|
|
1537
|
-
this.closeTries = 0;
|
|
1538
|
-
this.cleanupWebSocket();
|
|
1539
|
-
if (this.connectionAttempt) {
|
|
1540
|
-
// That connection attempt failed.
|
|
1541
|
-
this.rejectConnectionAttempt();
|
|
1542
|
-
}
|
|
1543
|
-
// Let’s update the connection status.
|
|
1544
|
-
this.status = exports.WebSocketStatus.Disconnected;
|
|
1545
|
-
this.emit("status", { status: exports.WebSocketStatus.Disconnected });
|
|
1546
|
-
this.emit("disconnect", { event });
|
|
1547
|
-
// trigger connect if no retry is running and we want to have a connection
|
|
1548
|
-
if (!this.cancelWebsocketRetry && this.shouldConnect) {
|
|
1549
|
-
setTimeout(() => {
|
|
1550
|
-
this.connect();
|
|
1551
|
-
}, this.configuration.delay);
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
destroy() {
|
|
1555
|
-
this.emit("destroy");
|
|
1556
|
-
clearInterval(this.intervals.connectionChecker);
|
|
1557
|
-
// If there is still a connection attempt outstanding then we should stop
|
|
1558
|
-
// it before calling disconnect, otherwise it will be rejected in the onClose
|
|
1559
|
-
// handler and trigger a retry
|
|
1560
|
-
this.stopConnectionAttempt();
|
|
1561
|
-
this.disconnect();
|
|
1562
|
-
this.removeAllListeners();
|
|
1563
|
-
this.cleanupWebSocket();
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1023
|
+
//#endregion
|
|
1024
|
+
//#region packages/provider/src/EventEmitter.ts
|
|
1025
|
+
var EventEmitter = class {
|
|
1026
|
+
constructor() {
|
|
1027
|
+
this.callbacks = {};
|
|
1028
|
+
}
|
|
1029
|
+
on(event, fn) {
|
|
1030
|
+
if (!this.callbacks[event]) this.callbacks[event] = [];
|
|
1031
|
+
this.callbacks[event].push(fn);
|
|
1032
|
+
return this;
|
|
1033
|
+
}
|
|
1034
|
+
emit(event, ...args) {
|
|
1035
|
+
const callbacks = this.callbacks[event];
|
|
1036
|
+
if (callbacks) callbacks.forEach((callback) => callback.apply(this, args));
|
|
1037
|
+
return this;
|
|
1038
|
+
}
|
|
1039
|
+
off(event, fn) {
|
|
1040
|
+
const callbacks = this.callbacks[event];
|
|
1041
|
+
if (callbacks) if (fn) this.callbacks[event] = callbacks.filter((callback) => callback !== fn);
|
|
1042
|
+
else delete this.callbacks[event];
|
|
1043
|
+
return this;
|
|
1044
|
+
}
|
|
1045
|
+
removeAllListeners() {
|
|
1046
|
+
this.callbacks = {};
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1566
1049
|
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1050
|
+
//#endregion
|
|
1051
|
+
//#region packages/provider/src/IncomingMessage.ts
|
|
1052
|
+
var IncomingMessage = class {
|
|
1053
|
+
constructor(data) {
|
|
1054
|
+
this.data = data;
|
|
1055
|
+
this.encoder = createEncoder();
|
|
1056
|
+
this.decoder = createDecoder(new Uint8Array(this.data));
|
|
1057
|
+
}
|
|
1058
|
+
peekVarString() {
|
|
1059
|
+
return peekVarString(this.decoder);
|
|
1060
|
+
}
|
|
1061
|
+
readVarUint() {
|
|
1062
|
+
return readVarUint(this.decoder);
|
|
1063
|
+
}
|
|
1064
|
+
readVarString() {
|
|
1065
|
+
return readVarString(this.decoder);
|
|
1066
|
+
}
|
|
1067
|
+
readVarUint8Array() {
|
|
1068
|
+
return readVarUint8Array(this.decoder);
|
|
1069
|
+
}
|
|
1070
|
+
writeVarUint(type) {
|
|
1071
|
+
return writeVarUint(this.encoder, type);
|
|
1072
|
+
}
|
|
1073
|
+
writeVarString(string) {
|
|
1074
|
+
return writeVarString(this.encoder, string);
|
|
1075
|
+
}
|
|
1076
|
+
writeVarUint8Array(data) {
|
|
1077
|
+
return writeVarUint8Array(this.encoder, data);
|
|
1078
|
+
}
|
|
1079
|
+
length() {
|
|
1080
|
+
return length$1(this.encoder);
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1570
1083
|
|
|
1084
|
+
//#endregion
|
|
1085
|
+
//#region packages/provider/src/types.ts
|
|
1086
|
+
let MessageType = /* @__PURE__ */ function(MessageType) {
|
|
1087
|
+
MessageType[MessageType["Sync"] = 0] = "Sync";
|
|
1088
|
+
MessageType[MessageType["Awareness"] = 1] = "Awareness";
|
|
1089
|
+
MessageType[MessageType["Auth"] = 2] = "Auth";
|
|
1090
|
+
MessageType[MessageType["QueryAwareness"] = 3] = "QueryAwareness";
|
|
1091
|
+
MessageType[MessageType["Stateless"] = 5] = "Stateless";
|
|
1092
|
+
MessageType[MessageType["CLOSE"] = 7] = "CLOSE";
|
|
1093
|
+
MessageType[MessageType["SyncStatus"] = 8] = "SyncStatus";
|
|
1094
|
+
return MessageType;
|
|
1095
|
+
}({});
|
|
1096
|
+
let WebSocketStatus = /* @__PURE__ */ function(WebSocketStatus) {
|
|
1097
|
+
WebSocketStatus["Connecting"] = "connecting";
|
|
1098
|
+
WebSocketStatus["Connected"] = "connected";
|
|
1099
|
+
WebSocketStatus["Disconnected"] = "disconnected";
|
|
1100
|
+
return WebSocketStatus;
|
|
1101
|
+
}({});
|
|
1102
|
+
|
|
1103
|
+
//#endregion
|
|
1104
|
+
//#region packages/provider/src/OutgoingMessage.ts
|
|
1105
|
+
var OutgoingMessage = class {
|
|
1106
|
+
constructor() {
|
|
1107
|
+
this.encoder = createEncoder();
|
|
1108
|
+
}
|
|
1109
|
+
get(args) {
|
|
1110
|
+
return args.encoder;
|
|
1111
|
+
}
|
|
1112
|
+
toUint8Array() {
|
|
1113
|
+
return toUint8Array(this.encoder);
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1571
1116
|
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1117
|
+
//#endregion
|
|
1118
|
+
//#region packages/provider/src/OutgoingMessages/CloseMessage.ts
|
|
1119
|
+
var CloseMessage = class extends OutgoingMessage {
|
|
1120
|
+
constructor(..._args) {
|
|
1121
|
+
super(..._args);
|
|
1122
|
+
this.type = MessageType.CLOSE;
|
|
1123
|
+
this.description = "Ask the server to close the connection";
|
|
1124
|
+
}
|
|
1125
|
+
get(args) {
|
|
1126
|
+
writeVarString(this.encoder, args.documentName);
|
|
1127
|
+
writeVarUint(this.encoder, this.type);
|
|
1128
|
+
return this.encoder;
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1575
1131
|
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1132
|
+
//#endregion
|
|
1133
|
+
//#region packages/provider/src/HocuspocusProviderWebsocket.ts
|
|
1134
|
+
var HocuspocusProviderWebsocket = class extends EventEmitter {
|
|
1135
|
+
constructor(configuration) {
|
|
1136
|
+
super();
|
|
1137
|
+
this.messageQueue = [];
|
|
1138
|
+
this.configuration = {
|
|
1139
|
+
url: "",
|
|
1140
|
+
autoConnect: true,
|
|
1141
|
+
preserveTrailingSlash: false,
|
|
1142
|
+
document: void 0,
|
|
1143
|
+
WebSocketPolyfill: void 0,
|
|
1144
|
+
messageReconnectTimeout: 3e4,
|
|
1145
|
+
delay: 1e3,
|
|
1146
|
+
initialDelay: 0,
|
|
1147
|
+
factor: 2,
|
|
1148
|
+
maxAttempts: 0,
|
|
1149
|
+
minDelay: 1e3,
|
|
1150
|
+
maxDelay: 3e4,
|
|
1151
|
+
jitter: true,
|
|
1152
|
+
timeout: 0,
|
|
1153
|
+
onOpen: () => null,
|
|
1154
|
+
onConnect: () => null,
|
|
1155
|
+
onMessage: () => null,
|
|
1156
|
+
onOutgoingMessage: () => null,
|
|
1157
|
+
onStatus: () => null,
|
|
1158
|
+
onDisconnect: () => null,
|
|
1159
|
+
onClose: () => null,
|
|
1160
|
+
onDestroy: () => null,
|
|
1161
|
+
onAwarenessUpdate: () => null,
|
|
1162
|
+
onAwarenessChange: () => null,
|
|
1163
|
+
handleTimeout: null,
|
|
1164
|
+
providerMap: /* @__PURE__ */ new Map()
|
|
1165
|
+
};
|
|
1166
|
+
this.webSocket = null;
|
|
1167
|
+
this.webSocketHandlers = {};
|
|
1168
|
+
this.shouldConnect = true;
|
|
1169
|
+
this.status = WebSocketStatus.Disconnected;
|
|
1170
|
+
this.lastMessageReceived = 0;
|
|
1171
|
+
this.identifier = 0;
|
|
1172
|
+
this.intervals = { connectionChecker: null };
|
|
1173
|
+
this.connectionAttempt = null;
|
|
1174
|
+
this.receivedOnOpenPayload = void 0;
|
|
1175
|
+
this.closeTries = 0;
|
|
1176
|
+
this.setConfiguration(configuration);
|
|
1177
|
+
this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill ? configuration.WebSocketPolyfill : WebSocket;
|
|
1178
|
+
this.on("open", this.configuration.onOpen);
|
|
1179
|
+
this.on("open", this.onOpen.bind(this));
|
|
1180
|
+
this.on("connect", this.configuration.onConnect);
|
|
1181
|
+
this.on("message", this.configuration.onMessage);
|
|
1182
|
+
this.on("outgoingMessage", this.configuration.onOutgoingMessage);
|
|
1183
|
+
this.on("status", this.configuration.onStatus);
|
|
1184
|
+
this.on("disconnect", this.configuration.onDisconnect);
|
|
1185
|
+
this.on("close", this.configuration.onClose);
|
|
1186
|
+
this.on("destroy", this.configuration.onDestroy);
|
|
1187
|
+
this.on("awarenessUpdate", this.configuration.onAwarenessUpdate);
|
|
1188
|
+
this.on("awarenessChange", this.configuration.onAwarenessChange);
|
|
1189
|
+
this.on("close", this.onClose.bind(this));
|
|
1190
|
+
this.on("message", this.onMessage.bind(this));
|
|
1191
|
+
this.intervals.connectionChecker = setInterval(this.checkConnection.bind(this), this.configuration.messageReconnectTimeout / 10);
|
|
1192
|
+
if (this.shouldConnect) this.connect();
|
|
1193
|
+
}
|
|
1194
|
+
async onOpen(event) {
|
|
1195
|
+
this.status = WebSocketStatus.Connected;
|
|
1196
|
+
this.emit("status", { status: WebSocketStatus.Connected });
|
|
1197
|
+
this.cancelWebsocketRetry = void 0;
|
|
1198
|
+
this.receivedOnOpenPayload = event;
|
|
1199
|
+
}
|
|
1200
|
+
attach(provider) {
|
|
1201
|
+
this.configuration.providerMap.set(provider.configuration.name, provider);
|
|
1202
|
+
if (this.status === WebSocketStatus.Disconnected && this.shouldConnect) this.connect();
|
|
1203
|
+
if (this.receivedOnOpenPayload && this.status === WebSocketStatus.Connected) provider.onOpen(this.receivedOnOpenPayload);
|
|
1204
|
+
}
|
|
1205
|
+
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);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
setConfiguration(configuration = {}) {
|
|
1212
|
+
this.configuration = {
|
|
1213
|
+
...this.configuration,
|
|
1214
|
+
...configuration
|
|
1215
|
+
};
|
|
1216
|
+
if (!this.configuration.autoConnect) this.shouldConnect = false;
|
|
1217
|
+
}
|
|
1218
|
+
async connect() {
|
|
1219
|
+
if (this.status === WebSocketStatus.Connected) return;
|
|
1220
|
+
if (this.cancelWebsocketRetry) {
|
|
1221
|
+
this.cancelWebsocketRetry();
|
|
1222
|
+
this.cancelWebsocketRetry = void 0;
|
|
1223
|
+
}
|
|
1224
|
+
this.receivedOnOpenPayload = void 0;
|
|
1225
|
+
this.shouldConnect = true;
|
|
1226
|
+
const abortableRetry = () => {
|
|
1227
|
+
let cancelAttempt = false;
|
|
1228
|
+
return {
|
|
1229
|
+
retryPromise: (0, _lifeomic_attempt.retry)(this.createWebSocketConnection.bind(this), {
|
|
1230
|
+
delay: this.configuration.delay,
|
|
1231
|
+
initialDelay: this.configuration.initialDelay,
|
|
1232
|
+
factor: this.configuration.factor,
|
|
1233
|
+
maxAttempts: this.configuration.maxAttempts,
|
|
1234
|
+
minDelay: this.configuration.minDelay,
|
|
1235
|
+
maxDelay: this.configuration.maxDelay,
|
|
1236
|
+
jitter: this.configuration.jitter,
|
|
1237
|
+
timeout: this.configuration.timeout,
|
|
1238
|
+
handleTimeout: this.configuration.handleTimeout,
|
|
1239
|
+
beforeAttempt: (context) => {
|
|
1240
|
+
if (!this.shouldConnect || cancelAttempt) context.abort();
|
|
1241
|
+
}
|
|
1242
|
+
}).catch((error) => {
|
|
1243
|
+
if (error && error.code !== "ATTEMPT_ABORTED") throw error;
|
|
1244
|
+
}),
|
|
1245
|
+
cancelFunc: () => {
|
|
1246
|
+
cancelAttempt = true;
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
};
|
|
1250
|
+
const { retryPromise, cancelFunc } = abortableRetry();
|
|
1251
|
+
this.cancelWebsocketRetry = cancelFunc;
|
|
1252
|
+
return retryPromise;
|
|
1253
|
+
}
|
|
1254
|
+
attachWebSocketListeners(ws, reject) {
|
|
1255
|
+
const { identifier } = ws;
|
|
1256
|
+
const onMessageHandler = (payload) => this.emit("message", payload);
|
|
1257
|
+
const onCloseHandler = (payload) => this.emit("close", { event: payload });
|
|
1258
|
+
const onOpenHandler = (payload) => this.emit("open", payload);
|
|
1259
|
+
const onErrorHandler = (err) => {
|
|
1260
|
+
reject(err);
|
|
1261
|
+
};
|
|
1262
|
+
this.webSocketHandlers[identifier] = {
|
|
1263
|
+
message: onMessageHandler,
|
|
1264
|
+
close: onCloseHandler,
|
|
1265
|
+
open: onOpenHandler,
|
|
1266
|
+
error: onErrorHandler
|
|
1267
|
+
};
|
|
1268
|
+
const handlers = this.webSocketHandlers[ws.identifier];
|
|
1269
|
+
Object.keys(handlers).forEach((name) => {
|
|
1270
|
+
ws.addEventListener(name, handlers[name]);
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
cleanupWebSocket() {
|
|
1274
|
+
if (!this.webSocket) return;
|
|
1275
|
+
const { identifier } = this.webSocket;
|
|
1276
|
+
const handlers = this.webSocketHandlers[identifier];
|
|
1277
|
+
Object.keys(handlers).forEach((name) => {
|
|
1278
|
+
this.webSocket?.removeEventListener(name, handlers[name]);
|
|
1279
|
+
delete this.webSocketHandlers[identifier];
|
|
1280
|
+
});
|
|
1281
|
+
this.webSocket.close();
|
|
1282
|
+
this.webSocket = null;
|
|
1283
|
+
}
|
|
1284
|
+
createWebSocketConnection() {
|
|
1285
|
+
return new Promise((resolve, reject) => {
|
|
1286
|
+
if (this.webSocket) {
|
|
1287
|
+
this.messageQueue = [];
|
|
1288
|
+
this.cleanupWebSocket();
|
|
1289
|
+
}
|
|
1290
|
+
this.lastMessageReceived = 0;
|
|
1291
|
+
this.identifier += 1;
|
|
1292
|
+
const ws = new this.configuration.WebSocketPolyfill(this.url);
|
|
1293
|
+
ws.binaryType = "arraybuffer";
|
|
1294
|
+
ws.identifier = this.identifier;
|
|
1295
|
+
this.attachWebSocketListeners(ws, reject);
|
|
1296
|
+
this.webSocket = ws;
|
|
1297
|
+
this.status = WebSocketStatus.Connecting;
|
|
1298
|
+
this.emit("status", { status: WebSocketStatus.Connecting });
|
|
1299
|
+
this.connectionAttempt = {
|
|
1300
|
+
resolve,
|
|
1301
|
+
reject
|
|
1302
|
+
};
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
onMessage(event) {
|
|
1306
|
+
this.resolveConnectionAttempt();
|
|
1307
|
+
this.lastMessageReceived = getUnixTime();
|
|
1308
|
+
const documentName = new IncomingMessage(event.data).peekVarString();
|
|
1309
|
+
this.configuration.providerMap.get(documentName)?.onMessage(event);
|
|
1310
|
+
}
|
|
1311
|
+
resolveConnectionAttempt() {
|
|
1312
|
+
if (this.connectionAttempt) {
|
|
1313
|
+
this.connectionAttempt.resolve();
|
|
1314
|
+
this.connectionAttempt = null;
|
|
1315
|
+
this.status = WebSocketStatus.Connected;
|
|
1316
|
+
this.emit("status", { status: WebSocketStatus.Connected });
|
|
1317
|
+
this.emit("connect");
|
|
1318
|
+
this.messageQueue.forEach((message) => this.send(message));
|
|
1319
|
+
this.messageQueue = [];
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
stopConnectionAttempt() {
|
|
1323
|
+
this.connectionAttempt = null;
|
|
1324
|
+
}
|
|
1325
|
+
rejectConnectionAttempt() {
|
|
1326
|
+
this.connectionAttempt?.reject();
|
|
1327
|
+
this.connectionAttempt = null;
|
|
1328
|
+
}
|
|
1329
|
+
checkConnection() {
|
|
1330
|
+
if (this.status !== WebSocketStatus.Connected) return;
|
|
1331
|
+
if (!this.lastMessageReceived) return;
|
|
1332
|
+
if (this.configuration.messageReconnectTimeout >= getUnixTime() - this.lastMessageReceived) return;
|
|
1333
|
+
this.closeTries += 1;
|
|
1334
|
+
if (this.closeTries > 2) {
|
|
1335
|
+
this.onClose({ event: {
|
|
1336
|
+
code: 4408,
|
|
1337
|
+
reason: "forced"
|
|
1338
|
+
} });
|
|
1339
|
+
this.closeTries = 0;
|
|
1340
|
+
} else {
|
|
1341
|
+
this.webSocket?.close();
|
|
1342
|
+
this.messageQueue = [];
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
get serverUrl() {
|
|
1346
|
+
if (this.configuration.preserveTrailingSlash) return this.configuration.url;
|
|
1347
|
+
let url = this.configuration.url;
|
|
1348
|
+
while (url[url.length - 1] === "/") url = url.slice(0, url.length - 1);
|
|
1349
|
+
return url;
|
|
1350
|
+
}
|
|
1351
|
+
get url() {
|
|
1352
|
+
return this.serverUrl;
|
|
1353
|
+
}
|
|
1354
|
+
disconnect() {
|
|
1355
|
+
this.shouldConnect = false;
|
|
1356
|
+
if (this.webSocket === null) return;
|
|
1357
|
+
try {
|
|
1358
|
+
this.webSocket.close();
|
|
1359
|
+
this.messageQueue = [];
|
|
1360
|
+
} catch (e) {
|
|
1361
|
+
console.error(e);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
send(message) {
|
|
1365
|
+
if (this.webSocket?.readyState === _hocuspocus_common.WsReadyStates.Open) this.webSocket.send(message);
|
|
1366
|
+
else this.messageQueue.push(message);
|
|
1367
|
+
}
|
|
1368
|
+
onClose({ event }) {
|
|
1369
|
+
this.closeTries = 0;
|
|
1370
|
+
this.cleanupWebSocket();
|
|
1371
|
+
if (this.connectionAttempt) this.rejectConnectionAttempt();
|
|
1372
|
+
this.status = WebSocketStatus.Disconnected;
|
|
1373
|
+
this.emit("status", { status: WebSocketStatus.Disconnected });
|
|
1374
|
+
this.emit("disconnect", { event });
|
|
1375
|
+
if (!this.cancelWebsocketRetry && this.shouldConnect) setTimeout(() => {
|
|
1376
|
+
this.connect();
|
|
1377
|
+
}, this.configuration.delay);
|
|
1378
|
+
}
|
|
1379
|
+
destroy() {
|
|
1380
|
+
this.emit("destroy");
|
|
1381
|
+
clearInterval(this.intervals.connectionChecker);
|
|
1382
|
+
this.stopConnectionAttempt();
|
|
1383
|
+
this.disconnect();
|
|
1384
|
+
this.removeAllListeners();
|
|
1385
|
+
this.cleanupWebSocket();
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1600
1388
|
|
|
1389
|
+
//#endregion
|
|
1390
|
+
//#region node_modules/y-protocols/sync.js
|
|
1391
|
+
/**
|
|
1392
|
+
* @module sync-protocol
|
|
1393
|
+
*/
|
|
1394
|
+
/**
|
|
1395
|
+
* @typedef {Map<number, number>} StateMap
|
|
1396
|
+
*/
|
|
1397
|
+
/**
|
|
1398
|
+
* Core Yjs defines two message types:
|
|
1399
|
+
* • YjsSyncStep1: Includes the State Set of the sending client. When received, the client should reply with YjsSyncStep2.
|
|
1400
|
+
* • YjsSyncStep2: Includes all missing structs and the complete delete set. When received, the client is assured that it
|
|
1401
|
+
* received all information from the remote client.
|
|
1402
|
+
*
|
|
1403
|
+
* In a peer-to-peer network, you may want to introduce a SyncDone message type. Both parties should initiate the connection
|
|
1404
|
+
* with SyncStep1. When a client received SyncStep2, it should reply with SyncDone. When the local client received both
|
|
1405
|
+
* SyncStep2 and SyncDone, it is assured that it is synced to the remote client.
|
|
1406
|
+
*
|
|
1407
|
+
* In a client-server model, you want to handle this differently: The client should initiate the connection with SyncStep1.
|
|
1408
|
+
* When the server receives SyncStep1, it should reply with SyncStep2 immediately followed by SyncStep1. The client replies
|
|
1409
|
+
* with SyncStep2 when it receives SyncStep1. Optionally the server may send a SyncDone after it received SyncStep2, so the
|
|
1410
|
+
* client knows that the sync is finished. There are two reasons for this more elaborated sync model: 1. This protocol can
|
|
1411
|
+
* easily be implemented on top of http and websockets. 2. The server should only reply to requests, and not initiate them.
|
|
1412
|
+
* Therefore it is necessary that the client initiates the sync.
|
|
1413
|
+
*
|
|
1414
|
+
* Construction of a message:
|
|
1415
|
+
* [messageType : varUint, message definition..]
|
|
1416
|
+
*
|
|
1417
|
+
* Note: A message does not include information about the room name. This must to be handled by the upper layer protocol!
|
|
1418
|
+
*
|
|
1419
|
+
* stringify[messageType] stringifies a message definition (messageType is already read from the bufffer)
|
|
1420
|
+
*/
|
|
1601
1421
|
const messageYjsSyncStep1 = 0;
|
|
1602
1422
|
const messageYjsSyncStep2 = 1;
|
|
1603
1423
|
const messageYjsUpdate = 2;
|
|
1604
|
-
|
|
1605
1424
|
/**
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1425
|
+
* Create a sync step 1 message based on the state of the current shared document.
|
|
1426
|
+
*
|
|
1427
|
+
* @param {encoding.Encoder} encoder
|
|
1428
|
+
* @param {Y.Doc} doc
|
|
1429
|
+
*/
|
|
1611
1430
|
const writeSyncStep1 = (encoder, doc) => {
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1431
|
+
writeVarUint(encoder, messageYjsSyncStep1);
|
|
1432
|
+
const sv = yjs.encodeStateVector(doc);
|
|
1433
|
+
writeVarUint8Array(encoder, sv);
|
|
1615
1434
|
};
|
|
1616
|
-
|
|
1617
1435
|
/**
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1436
|
+
* @param {encoding.Encoder} encoder
|
|
1437
|
+
* @param {Y.Doc} doc
|
|
1438
|
+
* @param {Uint8Array} [encodedStateVector]
|
|
1439
|
+
*/
|
|
1622
1440
|
const writeSyncStep2 = (encoder, doc, encodedStateVector) => {
|
|
1623
|
-
|
|
1624
|
-
|
|
1441
|
+
writeVarUint(encoder, messageYjsSyncStep2);
|
|
1442
|
+
writeVarUint8Array(encoder, yjs.encodeStateAsUpdate(doc, encodedStateVector));
|
|
1625
1443
|
};
|
|
1626
|
-
|
|
1627
1444
|
/**
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
const readSyncStep1 = (decoder, encoder, doc) =>
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
* @param {any} transactionOrigin
|
|
1643
|
-
*/
|
|
1445
|
+
* Read SyncStep1 message and reply with SyncStep2.
|
|
1446
|
+
*
|
|
1447
|
+
* @param {decoding.Decoder} decoder The reply to the received message
|
|
1448
|
+
* @param {encoding.Encoder} encoder The received message
|
|
1449
|
+
* @param {Y.Doc} doc
|
|
1450
|
+
*/
|
|
1451
|
+
const readSyncStep1 = (decoder, encoder, doc) => writeSyncStep2(encoder, doc, readVarUint8Array(decoder));
|
|
1452
|
+
/**
|
|
1453
|
+
* Read and apply Structs and then DeleteStore to a y instance.
|
|
1454
|
+
*
|
|
1455
|
+
* @param {decoding.Decoder} decoder
|
|
1456
|
+
* @param {Y.Doc} doc
|
|
1457
|
+
* @param {any} transactionOrigin
|
|
1458
|
+
*/
|
|
1644
1459
|
const readSyncStep2 = (decoder, doc, transactionOrigin) => {
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
}
|
|
1460
|
+
try {
|
|
1461
|
+
yjs.applyUpdate(doc, readVarUint8Array(decoder), transactionOrigin);
|
|
1462
|
+
} catch (error) {
|
|
1463
|
+
console.error("Caught error while handling a Yjs update", error);
|
|
1464
|
+
}
|
|
1651
1465
|
};
|
|
1652
|
-
|
|
1653
1466
|
/**
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1467
|
+
* @param {encoding.Encoder} encoder
|
|
1468
|
+
* @param {Uint8Array} update
|
|
1469
|
+
*/
|
|
1657
1470
|
const writeUpdate = (encoder, update) => {
|
|
1658
|
-
|
|
1659
|
-
|
|
1471
|
+
writeVarUint(encoder, messageYjsUpdate);
|
|
1472
|
+
writeVarUint8Array(encoder, update);
|
|
1660
1473
|
};
|
|
1661
|
-
|
|
1662
1474
|
/**
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1475
|
+
* Read and apply Structs and then DeleteStore to a y instance.
|
|
1476
|
+
*
|
|
1477
|
+
* @param {decoding.Decoder} decoder
|
|
1478
|
+
* @param {Y.Doc} doc
|
|
1479
|
+
* @param {any} transactionOrigin
|
|
1480
|
+
*/
|
|
1669
1481
|
const readUpdate = readSyncStep2;
|
|
1670
|
-
|
|
1671
1482
|
/**
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1483
|
+
* @param {decoding.Decoder} decoder A message received from another client
|
|
1484
|
+
* @param {encoding.Encoder} encoder The reply message. Does not need to be sent if empty.
|
|
1485
|
+
* @param {Y.Doc} doc
|
|
1486
|
+
* @param {any} transactionOrigin
|
|
1487
|
+
*/
|
|
1677
1488
|
const readSyncMessage = (decoder, encoder, doc, transactionOrigin) => {
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
return messageType
|
|
1489
|
+
const messageType = readVarUint(decoder);
|
|
1490
|
+
switch (messageType) {
|
|
1491
|
+
case messageYjsSyncStep1:
|
|
1492
|
+
readSyncStep1(decoder, encoder, doc);
|
|
1493
|
+
break;
|
|
1494
|
+
case messageYjsSyncStep2:
|
|
1495
|
+
readSyncStep2(decoder, doc, transactionOrigin);
|
|
1496
|
+
break;
|
|
1497
|
+
case messageYjsUpdate:
|
|
1498
|
+
readUpdate(decoder, doc, transactionOrigin);
|
|
1499
|
+
break;
|
|
1500
|
+
default: throw new Error("Unknown message type");
|
|
1501
|
+
}
|
|
1502
|
+
return messageType;
|
|
1693
1503
|
};
|
|
1694
1504
|
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
applyAwarenessUpdate(provider.awareness, message.readVarUint8Array(), provider);
|
|
1765
|
-
}
|
|
1766
|
-
applyAuthMessage(provider) {
|
|
1767
|
-
const { message } = this;
|
|
1768
|
-
common.readAuthMessage(message.decoder, provider.sendToken.bind(provider), provider.permissionDeniedHandler.bind(provider), provider.authenticatedHandler.bind(provider));
|
|
1769
|
-
}
|
|
1770
|
-
applyQueryAwarenessMessage(provider) {
|
|
1771
|
-
if (!provider.awareness)
|
|
1772
|
-
return;
|
|
1773
|
-
const { message } = this;
|
|
1774
|
-
message.writeVarUint(exports.MessageType.Awareness);
|
|
1775
|
-
message.writeVarUint8Array(encodeAwarenessUpdate(provider.awareness, Array.from(provider.awareness.getStates().keys())));
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1505
|
+
//#endregion
|
|
1506
|
+
//#region packages/provider/src/MessageReceiver.ts
|
|
1507
|
+
var MessageReceiver = class {
|
|
1508
|
+
constructor(message) {
|
|
1509
|
+
this.message = message;
|
|
1510
|
+
}
|
|
1511
|
+
apply(provider, emitSynced) {
|
|
1512
|
+
const { message } = this;
|
|
1513
|
+
const type = message.readVarUint();
|
|
1514
|
+
const emptyMessageLength = message.length();
|
|
1515
|
+
switch (type) {
|
|
1516
|
+
case MessageType.Sync:
|
|
1517
|
+
this.applySyncMessage(provider, emitSynced);
|
|
1518
|
+
break;
|
|
1519
|
+
case MessageType.Awareness:
|
|
1520
|
+
this.applyAwarenessMessage(provider);
|
|
1521
|
+
break;
|
|
1522
|
+
case MessageType.Auth:
|
|
1523
|
+
this.applyAuthMessage(provider);
|
|
1524
|
+
break;
|
|
1525
|
+
case MessageType.QueryAwareness:
|
|
1526
|
+
this.applyQueryAwarenessMessage(provider);
|
|
1527
|
+
break;
|
|
1528
|
+
case MessageType.Stateless:
|
|
1529
|
+
provider.receiveStateless(readVarString(message.decoder));
|
|
1530
|
+
break;
|
|
1531
|
+
case MessageType.SyncStatus:
|
|
1532
|
+
this.applySyncStatusMessage(provider, readVarInt(message.decoder) === 1);
|
|
1533
|
+
break;
|
|
1534
|
+
case MessageType.CLOSE:
|
|
1535
|
+
const event = {
|
|
1536
|
+
code: 1e3,
|
|
1537
|
+
reason: readVarString(message.decoder),
|
|
1538
|
+
target: provider.configuration.websocketProvider.webSocket,
|
|
1539
|
+
type: "close"
|
|
1540
|
+
};
|
|
1541
|
+
provider.onClose();
|
|
1542
|
+
provider.configuration.onClose({ event });
|
|
1543
|
+
provider.forwardClose({ event });
|
|
1544
|
+
break;
|
|
1545
|
+
default: throw new Error(`Can’t apply message of unknown type: ${type}`);
|
|
1546
|
+
}
|
|
1547
|
+
if (message.length() > emptyMessageLength + 1) provider.send(OutgoingMessage, { encoder: message.encoder });
|
|
1548
|
+
}
|
|
1549
|
+
applySyncMessage(provider, emitSynced) {
|
|
1550
|
+
const { message } = this;
|
|
1551
|
+
message.writeVarUint(MessageType.Sync);
|
|
1552
|
+
const syncMessageType = readSyncMessage(message.decoder, message.encoder, provider.document, provider);
|
|
1553
|
+
if (emitSynced && syncMessageType === messageYjsSyncStep2) provider.synced = true;
|
|
1554
|
+
}
|
|
1555
|
+
applySyncStatusMessage(provider, applied) {
|
|
1556
|
+
if (applied) provider.decrementUnsyncedChanges();
|
|
1557
|
+
}
|
|
1558
|
+
applyAwarenessMessage(provider) {
|
|
1559
|
+
if (!provider.awareness) return;
|
|
1560
|
+
const { message } = this;
|
|
1561
|
+
applyAwarenessUpdate(provider.awareness, message.readVarUint8Array(), provider);
|
|
1562
|
+
}
|
|
1563
|
+
applyAuthMessage(provider) {
|
|
1564
|
+
const { message } = this;
|
|
1565
|
+
(0, _hocuspocus_common.readAuthMessage)(message.decoder, provider.sendToken.bind(provider), provider.permissionDeniedHandler.bind(provider), provider.authenticatedHandler.bind(provider));
|
|
1566
|
+
}
|
|
1567
|
+
applyQueryAwarenessMessage(provider) {
|
|
1568
|
+
if (!provider.awareness) return;
|
|
1569
|
+
const { message } = this;
|
|
1570
|
+
message.writeVarUint(MessageType.Awareness);
|
|
1571
|
+
message.writeVarUint8Array(encodeAwarenessUpdate(provider.awareness, Array.from(provider.awareness.getStates().keys())));
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1778
1574
|
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1575
|
+
//#endregion
|
|
1576
|
+
//#region packages/provider/src/MessageSender.ts
|
|
1577
|
+
var MessageSender = class {
|
|
1578
|
+
constructor(Message, args = {}) {
|
|
1579
|
+
this.message = new Message();
|
|
1580
|
+
this.encoder = this.message.get(args);
|
|
1581
|
+
}
|
|
1582
|
+
create() {
|
|
1583
|
+
return toUint8Array(this.encoder);
|
|
1584
|
+
}
|
|
1585
|
+
send(webSocket) {
|
|
1586
|
+
webSocket?.send(this.create());
|
|
1587
|
+
}
|
|
1588
|
+
};
|
|
1791
1589
|
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
}
|
|
1590
|
+
//#endregion
|
|
1591
|
+
//#region packages/provider/src/OutgoingMessages/AuthenticationMessage.ts
|
|
1592
|
+
var AuthenticationMessage = class extends OutgoingMessage {
|
|
1593
|
+
constructor(..._args) {
|
|
1594
|
+
super(..._args);
|
|
1595
|
+
this.type = MessageType.Auth;
|
|
1596
|
+
this.description = "Authentication";
|
|
1597
|
+
}
|
|
1598
|
+
get(args) {
|
|
1599
|
+
if (typeof args.token === "undefined") throw new Error("The authentication message requires `token` as an argument.");
|
|
1600
|
+
writeVarString(this.encoder, args.documentName);
|
|
1601
|
+
writeVarUint(this.encoder, this.type);
|
|
1602
|
+
(0, _hocuspocus_common.writeAuthentication)(this.encoder, args.token);
|
|
1603
|
+
return this.encoder;
|
|
1604
|
+
}
|
|
1605
|
+
};
|
|
1808
1606
|
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
awarenessUpdate = encodeAwarenessUpdate(args.awareness, args.clients, args.states);
|
|
1830
|
-
}
|
|
1831
|
-
writeVarUint8Array(this.encoder, awarenessUpdate);
|
|
1832
|
-
return this.encoder;
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1607
|
+
//#endregion
|
|
1608
|
+
//#region packages/provider/src/OutgoingMessages/AwarenessMessage.ts
|
|
1609
|
+
var AwarenessMessage = class extends OutgoingMessage {
|
|
1610
|
+
constructor(..._args) {
|
|
1611
|
+
super(..._args);
|
|
1612
|
+
this.type = MessageType.Awareness;
|
|
1613
|
+
this.description = "Awareness states update";
|
|
1614
|
+
}
|
|
1615
|
+
get(args) {
|
|
1616
|
+
if (typeof args.awareness === "undefined") throw new Error("The awareness message requires awareness as an argument");
|
|
1617
|
+
if (typeof args.clients === "undefined") throw new Error("The awareness message requires clients as an argument");
|
|
1618
|
+
writeVarString(this.encoder, args.documentName);
|
|
1619
|
+
writeVarUint(this.encoder, this.type);
|
|
1620
|
+
let awarenessUpdate;
|
|
1621
|
+
if (args.states === void 0) awarenessUpdate = encodeAwarenessUpdate(args.awareness, args.clients);
|
|
1622
|
+
else awarenessUpdate = encodeAwarenessUpdate(args.awareness, args.clients, args.states);
|
|
1623
|
+
writeVarUint8Array(this.encoder, awarenessUpdate);
|
|
1624
|
+
return this.encoder;
|
|
1625
|
+
}
|
|
1626
|
+
};
|
|
1835
1627
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
}
|
|
1628
|
+
//#endregion
|
|
1629
|
+
//#region packages/provider/src/OutgoingMessages/StatelessMessage.ts
|
|
1630
|
+
var StatelessMessage = class extends OutgoingMessage {
|
|
1631
|
+
constructor(..._args) {
|
|
1632
|
+
super(..._args);
|
|
1633
|
+
this.type = MessageType.Stateless;
|
|
1634
|
+
this.description = "A stateless message";
|
|
1635
|
+
}
|
|
1636
|
+
get(args) {
|
|
1637
|
+
writeVarString(this.encoder, args.documentName);
|
|
1638
|
+
writeVarUint(this.encoder, this.type);
|
|
1639
|
+
writeVarString(this.encoder, args.payload ?? "");
|
|
1640
|
+
return this.encoder;
|
|
1641
|
+
}
|
|
1642
|
+
};
|
|
1850
1643
|
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
}
|
|
1644
|
+
//#endregion
|
|
1645
|
+
//#region packages/provider/src/OutgoingMessages/SyncStepOneMessage.ts
|
|
1646
|
+
var SyncStepOneMessage = class extends OutgoingMessage {
|
|
1647
|
+
constructor(..._args) {
|
|
1648
|
+
super(..._args);
|
|
1649
|
+
this.type = MessageType.Sync;
|
|
1650
|
+
this.description = "First sync step";
|
|
1651
|
+
}
|
|
1652
|
+
get(args) {
|
|
1653
|
+
if (typeof args.document === "undefined") throw new Error("The sync step one message requires document as an argument");
|
|
1654
|
+
writeVarString(this.encoder, args.documentName);
|
|
1655
|
+
writeVarUint(this.encoder, this.type);
|
|
1656
|
+
writeSyncStep1(this.encoder, args.document);
|
|
1657
|
+
return this.encoder;
|
|
1658
|
+
}
|
|
1659
|
+
};
|
|
1867
1660
|
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1661
|
+
//#endregion
|
|
1662
|
+
//#region packages/provider/src/OutgoingMessages/UpdateMessage.ts
|
|
1663
|
+
var UpdateMessage = class extends OutgoingMessage {
|
|
1664
|
+
constructor(..._args) {
|
|
1665
|
+
super(..._args);
|
|
1666
|
+
this.type = MessageType.Sync;
|
|
1667
|
+
this.description = "A document update";
|
|
1668
|
+
}
|
|
1669
|
+
get(args) {
|
|
1670
|
+
writeVarString(this.encoder, args.documentName);
|
|
1671
|
+
writeVarUint(this.encoder, this.type);
|
|
1672
|
+
writeUpdate(this.encoder, args.update);
|
|
1673
|
+
return this.encoder;
|
|
1674
|
+
}
|
|
1675
|
+
};
|
|
1881
1676
|
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
this.configuration.websocketProvider.off("status", this.forwardStatus);
|
|
2173
|
-
this.configuration.websocketProvider.off("status", this.configuration.onStatus);
|
|
2174
|
-
this.configuration.websocketProvider.off("open", this.boundOnOpen);
|
|
2175
|
-
this.configuration.websocketProvider.off("close", this.boundOnClose);
|
|
2176
|
-
this.configuration.websocketProvider.off("close", this.configuration.onClose);
|
|
2177
|
-
this.configuration.websocketProvider.off("close", this.forwardClose);
|
|
2178
|
-
this.configuration.websocketProvider.off("disconnect", this.configuration.onDisconnect);
|
|
2179
|
-
this.configuration.websocketProvider.off("disconnect", this.forwardDisconnect);
|
|
2180
|
-
this.configuration.websocketProvider.off("destroy", this.configuration.onDestroy);
|
|
2181
|
-
this.configuration.websocketProvider.off("destroy", this.forwardDestroy);
|
|
2182
|
-
this.configuration.websocketProvider.detach(this);
|
|
2183
|
-
this._isAttached = false;
|
|
2184
|
-
}
|
|
2185
|
-
attach() {
|
|
2186
|
-
if (this._isAttached)
|
|
2187
|
-
return;
|
|
2188
|
-
this.configuration.websocketProvider.on("connect", this.configuration.onConnect);
|
|
2189
|
-
this.configuration.websocketProvider.on("connect", this.forwardConnect);
|
|
2190
|
-
this.configuration.websocketProvider.on("status", this.configuration.onStatus);
|
|
2191
|
-
this.configuration.websocketProvider.on("status", this.forwardStatus);
|
|
2192
|
-
this.configuration.websocketProvider.on("open", this.boundOnOpen);
|
|
2193
|
-
this.configuration.websocketProvider.on("close", this.boundOnClose);
|
|
2194
|
-
this.configuration.websocketProvider.on("close", this.configuration.onClose);
|
|
2195
|
-
this.configuration.websocketProvider.on("close", this.forwardClose);
|
|
2196
|
-
this.configuration.websocketProvider.on("disconnect", this.configuration.onDisconnect);
|
|
2197
|
-
this.configuration.websocketProvider.on("disconnect", this.forwardDisconnect);
|
|
2198
|
-
this.configuration.websocketProvider.on("destroy", this.configuration.onDestroy);
|
|
2199
|
-
this.configuration.websocketProvider.on("destroy", this.forwardDestroy);
|
|
2200
|
-
this.configuration.websocketProvider.attach(this);
|
|
2201
|
-
this._isAttached = true;
|
|
2202
|
-
}
|
|
2203
|
-
permissionDeniedHandler(reason) {
|
|
2204
|
-
this.emit("authenticationFailed", { reason });
|
|
2205
|
-
this.isAuthenticated = false;
|
|
2206
|
-
}
|
|
2207
|
-
authenticatedHandler(scope) {
|
|
2208
|
-
this.isAuthenticated = true;
|
|
2209
|
-
this.authorizedScope = scope;
|
|
2210
|
-
this.emit("authenticated", { scope });
|
|
2211
|
-
}
|
|
2212
|
-
setAwarenessField(key, value) {
|
|
2213
|
-
if (!this.awareness) {
|
|
2214
|
-
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.`);
|
|
2215
|
-
}
|
|
2216
|
-
this.awareness.setLocalStateField(key, value);
|
|
2217
|
-
}
|
|
2218
|
-
}
|
|
1677
|
+
//#endregion
|
|
1678
|
+
//#region packages/provider/src/HocuspocusProvider.ts
|
|
1679
|
+
var AwarenessError = class extends Error {
|
|
1680
|
+
constructor(..._args) {
|
|
1681
|
+
super(..._args);
|
|
1682
|
+
this.code = 1001;
|
|
1683
|
+
}
|
|
1684
|
+
};
|
|
1685
|
+
var HocuspocusProvider = class extends EventEmitter {
|
|
1686
|
+
constructor(configuration) {
|
|
1687
|
+
super();
|
|
1688
|
+
this.configuration = {
|
|
1689
|
+
name: "",
|
|
1690
|
+
document: void 0,
|
|
1691
|
+
awareness: void 0,
|
|
1692
|
+
token: null,
|
|
1693
|
+
forceSyncInterval: false,
|
|
1694
|
+
onAuthenticated: () => null,
|
|
1695
|
+
onAuthenticationFailed: () => null,
|
|
1696
|
+
onOpen: () => null,
|
|
1697
|
+
onConnect: () => null,
|
|
1698
|
+
onMessage: () => null,
|
|
1699
|
+
onOutgoingMessage: () => null,
|
|
1700
|
+
onSynced: () => null,
|
|
1701
|
+
onStatus: () => null,
|
|
1702
|
+
onDisconnect: () => null,
|
|
1703
|
+
onClose: () => null,
|
|
1704
|
+
onDestroy: () => null,
|
|
1705
|
+
onAwarenessUpdate: () => null,
|
|
1706
|
+
onAwarenessChange: () => null,
|
|
1707
|
+
onStateless: () => null,
|
|
1708
|
+
onUnsyncedChanges: () => null
|
|
1709
|
+
};
|
|
1710
|
+
this.isSynced = false;
|
|
1711
|
+
this.unsyncedChanges = 0;
|
|
1712
|
+
this.isAuthenticated = false;
|
|
1713
|
+
this.authorizedScope = void 0;
|
|
1714
|
+
this.manageSocket = false;
|
|
1715
|
+
this._isAttached = false;
|
|
1716
|
+
this.intervals = { forceSync: null };
|
|
1717
|
+
this.boundDocumentUpdateHandler = this.documentUpdateHandler.bind(this);
|
|
1718
|
+
this.boundAwarenessUpdateHandler = this.awarenessUpdateHandler.bind(this);
|
|
1719
|
+
this.boundPageHide = this.pageHide.bind(this);
|
|
1720
|
+
this.boundOnOpen = this.onOpen.bind(this);
|
|
1721
|
+
this.boundOnClose = this.onClose.bind(this);
|
|
1722
|
+
this.forwardConnect = () => this.emit("connect");
|
|
1723
|
+
this.forwardStatus = (e) => this.emit("status", e);
|
|
1724
|
+
this.forwardClose = (e) => this.emit("close", e);
|
|
1725
|
+
this.forwardDisconnect = (e) => this.emit("disconnect", e);
|
|
1726
|
+
this.forwardDestroy = () => this.emit("destroy");
|
|
1727
|
+
this.setConfiguration(configuration);
|
|
1728
|
+
this.configuration.document = configuration.document ? configuration.document : new yjs.Doc();
|
|
1729
|
+
this.configuration.awareness = configuration.awareness !== void 0 ? configuration.awareness : new Awareness(this.document);
|
|
1730
|
+
this.on("open", this.configuration.onOpen);
|
|
1731
|
+
this.on("message", this.configuration.onMessage);
|
|
1732
|
+
this.on("outgoingMessage", this.configuration.onOutgoingMessage);
|
|
1733
|
+
this.on("synced", this.configuration.onSynced);
|
|
1734
|
+
this.on("destroy", this.configuration.onDestroy);
|
|
1735
|
+
this.on("awarenessUpdate", this.configuration.onAwarenessUpdate);
|
|
1736
|
+
this.on("awarenessChange", this.configuration.onAwarenessChange);
|
|
1737
|
+
this.on("stateless", this.configuration.onStateless);
|
|
1738
|
+
this.on("unsyncedChanges", this.configuration.onUnsyncedChanges);
|
|
1739
|
+
this.on("authenticated", this.configuration.onAuthenticated);
|
|
1740
|
+
this.on("authenticationFailed", this.configuration.onAuthenticationFailed);
|
|
1741
|
+
this.awareness?.on("update", () => {
|
|
1742
|
+
this.emit("awarenessUpdate", { states: (0, _hocuspocus_common.awarenessStatesToArray)(this.awareness.getStates()) });
|
|
1743
|
+
});
|
|
1744
|
+
this.awareness?.on("change", () => {
|
|
1745
|
+
this.emit("awarenessChange", { states: (0, _hocuspocus_common.awarenessStatesToArray)(this.awareness.getStates()) });
|
|
1746
|
+
});
|
|
1747
|
+
this.document.on("update", this.boundDocumentUpdateHandler);
|
|
1748
|
+
this.awareness?.on("update", this.boundAwarenessUpdateHandler);
|
|
1749
|
+
this.registerEventListeners();
|
|
1750
|
+
if (this.configuration.forceSyncInterval && typeof this.configuration.forceSyncInterval === "number") this.intervals.forceSync = setInterval(this.forceSync.bind(this), this.configuration.forceSyncInterval);
|
|
1751
|
+
if (this.manageSocket) this.attach();
|
|
1752
|
+
}
|
|
1753
|
+
setConfiguration(configuration = {}) {
|
|
1754
|
+
if (!configuration.websocketProvider) {
|
|
1755
|
+
this.manageSocket = true;
|
|
1756
|
+
this.configuration.websocketProvider = new HocuspocusProviderWebsocket(configuration);
|
|
1757
|
+
}
|
|
1758
|
+
this.configuration = {
|
|
1759
|
+
...this.configuration,
|
|
1760
|
+
...configuration
|
|
1761
|
+
};
|
|
1762
|
+
}
|
|
1763
|
+
get document() {
|
|
1764
|
+
return this.configuration.document;
|
|
1765
|
+
}
|
|
1766
|
+
get isAttached() {
|
|
1767
|
+
return this._isAttached;
|
|
1768
|
+
}
|
|
1769
|
+
get awareness() {
|
|
1770
|
+
return this.configuration.awareness;
|
|
1771
|
+
}
|
|
1772
|
+
get hasUnsyncedChanges() {
|
|
1773
|
+
return this.unsyncedChanges > 0;
|
|
1774
|
+
}
|
|
1775
|
+
resetUnsyncedChanges() {
|
|
1776
|
+
this.unsyncedChanges = 1;
|
|
1777
|
+
this.emit("unsyncedChanges", { number: this.unsyncedChanges });
|
|
1778
|
+
}
|
|
1779
|
+
incrementUnsyncedChanges() {
|
|
1780
|
+
this.unsyncedChanges += 1;
|
|
1781
|
+
this.emit("unsyncedChanges", { number: this.unsyncedChanges });
|
|
1782
|
+
}
|
|
1783
|
+
decrementUnsyncedChanges() {
|
|
1784
|
+
if (this.unsyncedChanges > 0) this.unsyncedChanges -= 1;
|
|
1785
|
+
if (this.unsyncedChanges === 0) this.synced = true;
|
|
1786
|
+
this.emit("unsyncedChanges", { number: this.unsyncedChanges });
|
|
1787
|
+
}
|
|
1788
|
+
forceSync() {
|
|
1789
|
+
this.resetUnsyncedChanges();
|
|
1790
|
+
this.send(SyncStepOneMessage, {
|
|
1791
|
+
document: this.document,
|
|
1792
|
+
documentName: this.configuration.name
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1795
|
+
pageHide() {
|
|
1796
|
+
if (this.awareness) removeAwarenessStates(this.awareness, [this.document.clientID], "page hide");
|
|
1797
|
+
}
|
|
1798
|
+
registerEventListeners() {
|
|
1799
|
+
if (typeof window === "undefined" || !("addEventListener" in window)) return;
|
|
1800
|
+
window.addEventListener("pagehide", this.boundPageHide);
|
|
1801
|
+
}
|
|
1802
|
+
sendStateless(payload) {
|
|
1803
|
+
this.send(StatelessMessage, {
|
|
1804
|
+
documentName: this.configuration.name,
|
|
1805
|
+
payload
|
|
1806
|
+
});
|
|
1807
|
+
}
|
|
1808
|
+
async sendToken() {
|
|
1809
|
+
let token;
|
|
1810
|
+
try {
|
|
1811
|
+
token = await this.getToken();
|
|
1812
|
+
} catch (error) {
|
|
1813
|
+
this.permissionDeniedHandler(`Failed to get token during sendToken(): ${error}`);
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
this.send(AuthenticationMessage, {
|
|
1817
|
+
token: token ?? "",
|
|
1818
|
+
documentName: this.configuration.name
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
documentUpdateHandler(update, origin) {
|
|
1822
|
+
if (origin === this) return;
|
|
1823
|
+
this.incrementUnsyncedChanges();
|
|
1824
|
+
this.send(UpdateMessage, {
|
|
1825
|
+
update,
|
|
1826
|
+
documentName: this.configuration.name
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
awarenessUpdateHandler({ added, updated, removed }, origin) {
|
|
1830
|
+
const changedClients = added.concat(updated).concat(removed);
|
|
1831
|
+
this.send(AwarenessMessage, {
|
|
1832
|
+
awareness: this.awareness,
|
|
1833
|
+
clients: changedClients,
|
|
1834
|
+
documentName: this.configuration.name
|
|
1835
|
+
});
|
|
1836
|
+
}
|
|
1837
|
+
/**
|
|
1838
|
+
* Indicates whether a first handshake with the server has been established
|
|
1839
|
+
*
|
|
1840
|
+
* Note: this does not mean all updates from the client have been persisted to the backend. For this,
|
|
1841
|
+
* use `hasUnsyncedChanges`.
|
|
1842
|
+
*/
|
|
1843
|
+
get synced() {
|
|
1844
|
+
return this.isSynced;
|
|
1845
|
+
}
|
|
1846
|
+
set synced(state) {
|
|
1847
|
+
if (this.isSynced === state) return;
|
|
1848
|
+
this.isSynced = state;
|
|
1849
|
+
if (state) this.emit("synced", { state });
|
|
1850
|
+
}
|
|
1851
|
+
receiveStateless(payload) {
|
|
1852
|
+
this.emit("stateless", { payload });
|
|
1853
|
+
}
|
|
1854
|
+
async connect() {
|
|
1855
|
+
if (this.manageSocket) return this.configuration.websocketProvider.connect();
|
|
1856
|
+
console.warn("HocuspocusProvider::connect() is deprecated and does not do anything. Please connect/disconnect on the websocketProvider, or attach/deattach providers.");
|
|
1857
|
+
}
|
|
1858
|
+
disconnect() {
|
|
1859
|
+
if (this.manageSocket) return this.configuration.websocketProvider.disconnect();
|
|
1860
|
+
console.warn("HocuspocusProvider::disconnect() is deprecated and does not do anything. Please connect/disconnect on the websocketProvider, or attach/deattach providers.");
|
|
1861
|
+
}
|
|
1862
|
+
async onOpen(event) {
|
|
1863
|
+
this.isAuthenticated = false;
|
|
1864
|
+
this.emit("open", { event });
|
|
1865
|
+
await this.sendToken();
|
|
1866
|
+
this.startSync();
|
|
1867
|
+
}
|
|
1868
|
+
async getToken() {
|
|
1869
|
+
if (typeof this.configuration.token === "function") return await this.configuration.token();
|
|
1870
|
+
return this.configuration.token;
|
|
1871
|
+
}
|
|
1872
|
+
startSync() {
|
|
1873
|
+
this.resetUnsyncedChanges();
|
|
1874
|
+
this.send(SyncStepOneMessage, {
|
|
1875
|
+
document: this.document,
|
|
1876
|
+
documentName: this.configuration.name
|
|
1877
|
+
});
|
|
1878
|
+
if (this.awareness && this.awareness.getLocalState() !== null) this.send(AwarenessMessage, {
|
|
1879
|
+
awareness: this.awareness,
|
|
1880
|
+
clients: [this.document.clientID],
|
|
1881
|
+
documentName: this.configuration.name
|
|
1882
|
+
});
|
|
1883
|
+
}
|
|
1884
|
+
send(message, args) {
|
|
1885
|
+
if (!this._isAttached) return;
|
|
1886
|
+
const messageSender = new MessageSender(message, args);
|
|
1887
|
+
this.emit("outgoingMessage", { message: messageSender.message });
|
|
1888
|
+
messageSender.send(this.configuration.websocketProvider);
|
|
1889
|
+
}
|
|
1890
|
+
onMessage(event) {
|
|
1891
|
+
const message = new IncomingMessage(event.data);
|
|
1892
|
+
const documentName = message.readVarString();
|
|
1893
|
+
message.writeVarString(documentName);
|
|
1894
|
+
this.emit("message", {
|
|
1895
|
+
event,
|
|
1896
|
+
message: new IncomingMessage(event.data)
|
|
1897
|
+
});
|
|
1898
|
+
new MessageReceiver(message).apply(this, true);
|
|
1899
|
+
}
|
|
1900
|
+
onClose() {
|
|
1901
|
+
this.isAuthenticated = false;
|
|
1902
|
+
this.synced = false;
|
|
1903
|
+
if (this.awareness) removeAwarenessStates(this.awareness, Array.from(this.awareness.getStates().keys()).filter((client) => client !== this.document.clientID), this);
|
|
1904
|
+
}
|
|
1905
|
+
destroy() {
|
|
1906
|
+
this.emit("destroy");
|
|
1907
|
+
if (this.intervals.forceSync) clearInterval(this.intervals.forceSync);
|
|
1908
|
+
if (this.awareness) {
|
|
1909
|
+
removeAwarenessStates(this.awareness, [this.document.clientID], "provider destroy");
|
|
1910
|
+
this.awareness.off("update", this.boundAwarenessUpdateHandler);
|
|
1911
|
+
this.awareness.destroy();
|
|
1912
|
+
}
|
|
1913
|
+
this.document.off("update", this.boundDocumentUpdateHandler);
|
|
1914
|
+
this.removeAllListeners();
|
|
1915
|
+
this.detach();
|
|
1916
|
+
if (this.manageSocket) this.configuration.websocketProvider.destroy();
|
|
1917
|
+
if (typeof window === "undefined" || !("removeEventListener" in window)) return;
|
|
1918
|
+
window.removeEventListener("pagehide", this.boundPageHide);
|
|
1919
|
+
}
|
|
1920
|
+
detach() {
|
|
1921
|
+
this.configuration.websocketProvider.off("connect", this.configuration.onConnect);
|
|
1922
|
+
this.configuration.websocketProvider.off("connect", this.forwardConnect);
|
|
1923
|
+
this.configuration.websocketProvider.off("status", this.forwardStatus);
|
|
1924
|
+
this.configuration.websocketProvider.off("status", this.configuration.onStatus);
|
|
1925
|
+
this.configuration.websocketProvider.off("open", this.boundOnOpen);
|
|
1926
|
+
this.configuration.websocketProvider.off("close", this.boundOnClose);
|
|
1927
|
+
this.configuration.websocketProvider.off("close", this.configuration.onClose);
|
|
1928
|
+
this.configuration.websocketProvider.off("close", this.forwardClose);
|
|
1929
|
+
this.configuration.websocketProvider.off("disconnect", this.configuration.onDisconnect);
|
|
1930
|
+
this.configuration.websocketProvider.off("disconnect", this.forwardDisconnect);
|
|
1931
|
+
this.configuration.websocketProvider.off("destroy", this.configuration.onDestroy);
|
|
1932
|
+
this.configuration.websocketProvider.off("destroy", this.forwardDestroy);
|
|
1933
|
+
this.configuration.websocketProvider.detach(this);
|
|
1934
|
+
this._isAttached = false;
|
|
1935
|
+
}
|
|
1936
|
+
attach() {
|
|
1937
|
+
if (this._isAttached) return;
|
|
1938
|
+
this.configuration.websocketProvider.on("connect", this.configuration.onConnect);
|
|
1939
|
+
this.configuration.websocketProvider.on("connect", this.forwardConnect);
|
|
1940
|
+
this.configuration.websocketProvider.on("status", this.configuration.onStatus);
|
|
1941
|
+
this.configuration.websocketProvider.on("status", this.forwardStatus);
|
|
1942
|
+
this.configuration.websocketProvider.on("open", this.boundOnOpen);
|
|
1943
|
+
this.configuration.websocketProvider.on("close", this.boundOnClose);
|
|
1944
|
+
this.configuration.websocketProvider.on("close", this.configuration.onClose);
|
|
1945
|
+
this.configuration.websocketProvider.on("close", this.forwardClose);
|
|
1946
|
+
this.configuration.websocketProvider.on("disconnect", this.configuration.onDisconnect);
|
|
1947
|
+
this.configuration.websocketProvider.on("disconnect", this.forwardDisconnect);
|
|
1948
|
+
this.configuration.websocketProvider.on("destroy", this.configuration.onDestroy);
|
|
1949
|
+
this.configuration.websocketProvider.on("destroy", this.forwardDestroy);
|
|
1950
|
+
this.configuration.websocketProvider.attach(this);
|
|
1951
|
+
this._isAttached = true;
|
|
1952
|
+
}
|
|
1953
|
+
permissionDeniedHandler(reason) {
|
|
1954
|
+
this.emit("authenticationFailed", { reason });
|
|
1955
|
+
this.isAuthenticated = false;
|
|
1956
|
+
}
|
|
1957
|
+
authenticatedHandler(scope) {
|
|
1958
|
+
this.isAuthenticated = true;
|
|
1959
|
+
this.authorizedScope = scope;
|
|
1960
|
+
this.emit("authenticated", { scope });
|
|
1961
|
+
}
|
|
1962
|
+
setAwarenessField(key, value) {
|
|
1963
|
+
if (!this.awareness) 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.`);
|
|
1964
|
+
this.awareness.setLocalStateField(key, value);
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
2219
1967
|
|
|
1968
|
+
//#endregion
|
|
2220
1969
|
exports.AwarenessError = AwarenessError;
|
|
2221
1970
|
exports.HocuspocusProvider = HocuspocusProvider;
|
|
2222
1971
|
exports.HocuspocusProviderWebsocket = HocuspocusProviderWebsocket;
|
|
2223
|
-
|
|
1972
|
+
exports.MessageType = MessageType;
|
|
1973
|
+
exports.WebSocketStatus = WebSocketStatus;
|
|
1974
|
+
//# sourceMappingURL=hocuspocus-provider.cjs.map
|