@liveblocks/client 0.16.17 → 0.17.0-beta1

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.
Files changed (10) hide show
  1. package/index.d.ts +28 -8
  2. package/index.js +1290 -830
  3. package/index.mjs +1091 -782
  4. package/internal.d.ts +416 -276
  5. package/internal.js +313 -205
  6. package/internal.mjs +265 -171
  7. package/package.json +15 -10
  8. package/shared.d.ts +719 -650
  9. package/shared.js +2569 -1326
  10. package/shared.mjs +1990 -1204
package/shared.mjs CHANGED
@@ -1,1277 +1,2063 @@
1
- var ServerMsgCode, ClientMsgCode, CrdtType, OpCode, WebsocketCloseCodes;
2
-
1
+ const _emittedDeprecationWarnings = new Set();
2
+ function deprecate(message, key = message) {
3
+ "production" !== process.env.NODE_ENV &&
4
+ (_emittedDeprecationWarnings.has(key) ||
5
+ (_emittedDeprecationWarnings.add(key),
6
+ console.error(`DEPRECATION WARNING: ${message}`)));
7
+ }
8
+ function deprecateIf(condition, message, key = message) {
9
+ "production" !== process.env.NODE_ENV && condition && deprecate(message, key);
10
+ }
11
+ function throwUsageError(message) {
12
+ if ("production" !== process.env.NODE_ENV) {
13
+ const usageError = new Error(message);
14
+ throw ((usageError.name = "Usage error"), usageError);
15
+ }
16
+ }
17
+ function errorIf(condition, message) {
18
+ "production" !== process.env.NODE_ENV &&
19
+ condition &&
20
+ throwUsageError(message);
21
+ }
22
+ function __rest(s, e) {
23
+ var t = {};
24
+ for (var p in s)
25
+ Object.prototype.hasOwnProperty.call(s, p) &&
26
+ e.indexOf(p) < 0 &&
27
+ (t[p] = s[p]);
28
+ if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
29
+ var i = 0;
30
+ for (p = Object.getOwnPropertySymbols(s); i < p.length; i++)
31
+ e.indexOf(p[i]) < 0 &&
32
+ Object.prototype.propertyIsEnumerable.call(s, p[i]) &&
33
+ (t[p[i]] = s[p[i]]);
34
+ }
35
+ return t;
36
+ }
37
+ function assertNever(_value, errmsg) {
38
+ throw new Error(errmsg);
39
+ }
40
+ function nn(value, errmsg = "Expected value to be non-nullable") {
41
+ return (
42
+ (function (condition, errmsg) {
43
+ if ("production" !== process.env.NODE_ENV && !condition) {
44
+ const err = new Error(errmsg);
45
+ throw ((err.name = "Assertion failure"), err);
46
+ }
47
+ })(null != value, errmsg),
48
+ value
49
+ );
50
+ }
51
+ var ClientMsgCode,
52
+ OpCode,
53
+ CrdtType,
54
+ ServerMsgCode,
55
+ WebsocketCloseCodes,
56
+ OpSource;
3
57
  function isRootCrdt(crdt) {
4
- return crdt.type === CrdtType.OBJECT && !isChildCrdt(crdt);
58
+ return crdt.type === CrdtType.OBJECT && !isChildCrdt(crdt);
5
59
  }
6
-
7
60
  function isChildCrdt(crdt) {
8
- return void 0 !== crdt.parentId && void 0 !== crdt.parentKey;
61
+ return void 0 !== crdt.parentId && void 0 !== crdt.parentKey;
9
62
  }
10
-
11
- !function(ServerMsgCode) {
12
- ServerMsgCode[ServerMsgCode.UPDATE_PRESENCE = 100] = "UPDATE_PRESENCE", ServerMsgCode[ServerMsgCode.USER_JOINED = 101] = "USER_JOINED",
13
- ServerMsgCode[ServerMsgCode.USER_LEFT = 102] = "USER_LEFT", ServerMsgCode[ServerMsgCode.BROADCASTED_EVENT = 103] = "BROADCASTED_EVENT",
14
- ServerMsgCode[ServerMsgCode.ROOM_STATE = 104] = "ROOM_STATE", ServerMsgCode[ServerMsgCode.INITIAL_STORAGE_STATE = 200] = "INITIAL_STORAGE_STATE",
15
- ServerMsgCode[ServerMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE";
16
- }(ServerMsgCode || (ServerMsgCode = {})), function(ClientMsgCode) {
17
- ClientMsgCode[ClientMsgCode.UPDATE_PRESENCE = 100] = "UPDATE_PRESENCE", ClientMsgCode[ClientMsgCode.BROADCAST_EVENT = 103] = "BROADCAST_EVENT",
18
- ClientMsgCode[ClientMsgCode.FETCH_STORAGE = 200] = "FETCH_STORAGE", ClientMsgCode[ClientMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE";
19
- }(ClientMsgCode || (ClientMsgCode = {})), function(CrdtType) {
20
- CrdtType[CrdtType.OBJECT = 0] = "OBJECT", CrdtType[CrdtType.LIST = 1] = "LIST",
21
- CrdtType[CrdtType.MAP = 2] = "MAP", CrdtType[CrdtType.REGISTER = 3] = "REGISTER";
22
- }(CrdtType || (CrdtType = {})), function(OpCode) {
23
- OpCode[OpCode.INIT = 0] = "INIT", OpCode[OpCode.SET_PARENT_KEY = 1] = "SET_PARENT_KEY",
24
- OpCode[OpCode.CREATE_LIST = 2] = "CREATE_LIST", OpCode[OpCode.UPDATE_OBJECT = 3] = "UPDATE_OBJECT",
25
- OpCode[OpCode.CREATE_OBJECT = 4] = "CREATE_OBJECT", OpCode[OpCode.DELETE_CRDT = 5] = "DELETE_CRDT",
26
- OpCode[OpCode.DELETE_OBJECT_KEY = 6] = "DELETE_OBJECT_KEY", OpCode[OpCode.CREATE_MAP = 7] = "CREATE_MAP",
27
- OpCode[OpCode.CREATE_REGISTER = 8] = "CREATE_REGISTER";
28
- }(OpCode || (OpCode = {})), function(WebsocketCloseCodes) {
29
- WebsocketCloseCodes[WebsocketCloseCodes.CLOSE_ABNORMAL = 1006] = "CLOSE_ABNORMAL",
30
- WebsocketCloseCodes[WebsocketCloseCodes.INVALID_MESSAGE_FORMAT = 4e3] = "INVALID_MESSAGE_FORMAT",
31
- WebsocketCloseCodes[WebsocketCloseCodes.NOT_ALLOWED = 4001] = "NOT_ALLOWED", WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002] = "MAX_NUMBER_OF_MESSAGES_PER_SECONDS",
32
- WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS",
33
- WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP",
34
- WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM",
35
- WebsocketCloseCodes[WebsocketCloseCodes.CLOSE_WITHOUT_RETRY = 4999] = "CLOSE_WITHOUT_RETRY";
36
- }(WebsocketCloseCodes || (WebsocketCloseCodes = {}));
37
-
38
- class AbstractCrdt {
39
- get _doc() {
40
- return this.__doc;
41
- }
42
- get roomId() {
43
- return this.__doc ? this.__doc.roomId : null;
44
- }
45
- get _id() {
46
- return this.__id;
47
- }
48
- get _parent() {
49
- return this.__parent;
50
- }
51
- get _parentKey() {
52
- return this.__parentKey;
53
- }
54
- _apply(op, _isLocal) {
55
- return op.type === OpCode.DELETE_CRDT && null != this._parent && null != this._parentKey ? this._parent._detachChild(this) : {
56
- modified: !1
57
- };
58
- }
59
- _setParentLink(parent, key) {
60
- if (null != this.__parent && this.__parent !== parent) throw new Error("Cannot attach parent if it already exist");
61
- this.__parentKey = key, this.__parent = parent;
62
- }
63
- _attach(id, doc) {
64
- if (this.__id || this.__doc) throw new Error("Cannot attach if CRDT is already attached");
65
- doc.addItem(id, this), this.__id = id, this.__doc = doc;
66
- }
67
- _detach() {
68
- this.__doc && this.__id && this.__doc.deleteItem(this.__id), this.__parent = void 0,
69
- this.__doc = void 0;
70
- }
63
+ function isRoomEventName(value) {
64
+ return (
65
+ "my-presence" === value ||
66
+ "others" === value ||
67
+ "event" === value ||
68
+ "error" === value ||
69
+ "connection" === value
70
+ );
71
71
  }
72
-
73
- function isJsonScalar(data) {
74
- return null === data || "string" == typeof data || "number" == typeof data || "boolean" == typeof data;
72
+ function HasParent(node, key) {
73
+ return Object.freeze({ type: "HasParent", node: node, key: key });
75
74
  }
76
-
77
- function isJsonArray(data) {
78
- return Array.isArray(data);
75
+ !(function (ClientMsgCode) {
76
+ (ClientMsgCode[(ClientMsgCode.UPDATE_PRESENCE = 100)] = "UPDATE_PRESENCE"),
77
+ (ClientMsgCode[(ClientMsgCode.BROADCAST_EVENT = 103)] = "BROADCAST_EVENT"),
78
+ (ClientMsgCode[(ClientMsgCode.FETCH_STORAGE = 200)] = "FETCH_STORAGE"),
79
+ (ClientMsgCode[(ClientMsgCode.UPDATE_STORAGE = 201)] = "UPDATE_STORAGE");
80
+ })(ClientMsgCode || (ClientMsgCode = {})),
81
+ (function (OpCode) {
82
+ (OpCode[(OpCode.INIT = 0)] = "INIT"),
83
+ (OpCode[(OpCode.SET_PARENT_KEY = 1)] = "SET_PARENT_KEY"),
84
+ (OpCode[(OpCode.CREATE_LIST = 2)] = "CREATE_LIST"),
85
+ (OpCode[(OpCode.UPDATE_OBJECT = 3)] = "UPDATE_OBJECT"),
86
+ (OpCode[(OpCode.CREATE_OBJECT = 4)] = "CREATE_OBJECT"),
87
+ (OpCode[(OpCode.DELETE_CRDT = 5)] = "DELETE_CRDT"),
88
+ (OpCode[(OpCode.DELETE_OBJECT_KEY = 6)] = "DELETE_OBJECT_KEY"),
89
+ (OpCode[(OpCode.CREATE_MAP = 7)] = "CREATE_MAP"),
90
+ (OpCode[(OpCode.CREATE_REGISTER = 8)] = "CREATE_REGISTER");
91
+ })(OpCode || (OpCode = {})),
92
+ (function (CrdtType) {
93
+ (CrdtType[(CrdtType.OBJECT = 0)] = "OBJECT"),
94
+ (CrdtType[(CrdtType.LIST = 1)] = "LIST"),
95
+ (CrdtType[(CrdtType.MAP = 2)] = "MAP"),
96
+ (CrdtType[(CrdtType.REGISTER = 3)] = "REGISTER");
97
+ })(CrdtType || (CrdtType = {})),
98
+ (function (ServerMsgCode) {
99
+ (ServerMsgCode[(ServerMsgCode.UPDATE_PRESENCE = 100)] = "UPDATE_PRESENCE"),
100
+ (ServerMsgCode[(ServerMsgCode.USER_JOINED = 101)] = "USER_JOINED"),
101
+ (ServerMsgCode[(ServerMsgCode.USER_LEFT = 102)] = "USER_LEFT"),
102
+ (ServerMsgCode[(ServerMsgCode.BROADCASTED_EVENT = 103)] =
103
+ "BROADCASTED_EVENT"),
104
+ (ServerMsgCode[(ServerMsgCode.ROOM_STATE = 104)] = "ROOM_STATE"),
105
+ (ServerMsgCode[(ServerMsgCode.INITIAL_STORAGE_STATE = 200)] =
106
+ "INITIAL_STORAGE_STATE"),
107
+ (ServerMsgCode[(ServerMsgCode.UPDATE_STORAGE = 201)] = "UPDATE_STORAGE");
108
+ })(ServerMsgCode || (ServerMsgCode = {})),
109
+ (function (WebsocketCloseCodes) {
110
+ (WebsocketCloseCodes[(WebsocketCloseCodes.CLOSE_ABNORMAL = 1006)] =
111
+ "CLOSE_ABNORMAL"),
112
+ (WebsocketCloseCodes[(WebsocketCloseCodes.INVALID_MESSAGE_FORMAT = 4e3)] =
113
+ "INVALID_MESSAGE_FORMAT"),
114
+ (WebsocketCloseCodes[(WebsocketCloseCodes.NOT_ALLOWED = 4001)] =
115
+ "NOT_ALLOWED"),
116
+ (WebsocketCloseCodes[
117
+ (WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002)
118
+ ] = "MAX_NUMBER_OF_MESSAGES_PER_SECONDS"),
119
+ (WebsocketCloseCodes[
120
+ (WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003)
121
+ ] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS"),
122
+ (WebsocketCloseCodes[
123
+ (WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004)
124
+ ] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP"),
125
+ (WebsocketCloseCodes[
126
+ (WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005)
127
+ ] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM"),
128
+ (WebsocketCloseCodes[(WebsocketCloseCodes.CLOSE_WITHOUT_RETRY = 4999)] =
129
+ "CLOSE_WITHOUT_RETRY");
130
+ })(WebsocketCloseCodes || (WebsocketCloseCodes = {})),
131
+ (function (OpSource) {
132
+ (OpSource[(OpSource.UNDOREDO_RECONNECT = 0)] = "UNDOREDO_RECONNECT"),
133
+ (OpSource[(OpSource.REMOTE = 1)] = "REMOTE"),
134
+ (OpSource[(OpSource.ACK = 2)] = "ACK");
135
+ })(OpSource || (OpSource = {}));
136
+ const NoParent = Object.freeze({ type: "NoParent" });
137
+ function Orphaned(oldKey) {
138
+ return Object.freeze({ type: "Orphaned", oldKey: oldKey });
79
139
  }
80
-
81
- function isJsonObject(data) {
82
- return !isJsonScalar(data) && !isJsonArray(data);
140
+ class AbstractCrdt {
141
+ constructor() {
142
+ this._parent = NoParent;
143
+ }
144
+ _getParentKeyOrThrow() {
145
+ switch (this.parent.type) {
146
+ case "HasParent":
147
+ return this.parent.key;
148
+ case "NoParent":
149
+ throw new Error("Parent key is missing");
150
+ case "Orphaned":
151
+ return this.parent.oldKey;
152
+ default:
153
+ return assertNever(this.parent, "Unknown state");
154
+ }
155
+ }
156
+ get _doc() {
157
+ return this.__doc;
158
+ }
159
+ get roomId() {
160
+ return this.__doc ? this.__doc.roomId : null;
161
+ }
162
+ get _id() {
163
+ return this.__id;
164
+ }
165
+ get parent() {
166
+ return this._parent;
167
+ }
168
+ get _parentNode() {
169
+ switch (this.parent.type) {
170
+ case "HasParent":
171
+ return this.parent.node;
172
+ case "NoParent":
173
+ case "Orphaned":
174
+ return null;
175
+ default:
176
+ return assertNever(this.parent, "Unknown state");
177
+ }
178
+ }
179
+ get _parentKey() {
180
+ switch (this.parent.type) {
181
+ case "HasParent":
182
+ return this.parent.key;
183
+ case "NoParent":
184
+ return null;
185
+ case "Orphaned":
186
+ return this.parent.oldKey;
187
+ default:
188
+ return assertNever(this.parent, "Unknown state");
189
+ }
190
+ }
191
+ _apply(op, _isLocal) {
192
+ return op.type === OpCode.DELETE_CRDT && "HasParent" === this.parent.type
193
+ ? this.parent.node._detachChild(this)
194
+ : { modified: !1 };
195
+ }
196
+ _setParentLink(newParentNode, newParentKey) {
197
+ switch (this.parent.type) {
198
+ case "HasParent":
199
+ if (this.parent.node !== newParentNode)
200
+ throw new Error("Cannot attach parent if it already exist");
201
+ return void (this._parent = HasParent(newParentNode, newParentKey));
202
+ case "Orphaned":
203
+ case "NoParent":
204
+ return void (this._parent = HasParent(newParentNode, newParentKey));
205
+ default:
206
+ return assertNever(this.parent, "Unknown state");
207
+ }
208
+ }
209
+ _attach(id, doc) {
210
+ if (this.__id || this.__doc)
211
+ throw new Error("Cannot attach if CRDT is already attached");
212
+ doc.addItem(id, this), (this.__id = id), (this.__doc = doc);
213
+ }
214
+ _detach() {
215
+ switch (
216
+ (this.__doc && this.__id && this.__doc.deleteItem(this.__id),
217
+ this.parent.type)
218
+ ) {
219
+ case "HasParent":
220
+ this._parent = Orphaned(this.parent.key);
221
+ break;
222
+ case "NoParent":
223
+ this._parent = NoParent;
224
+ break;
225
+ case "Orphaned":
226
+ this._parent = Orphaned(this.parent.oldKey);
227
+ break;
228
+ default:
229
+ assertNever(this.parent, "Unknown state");
230
+ }
231
+ this.__doc = void 0;
232
+ }
83
233
  }
84
-
85
234
  class LiveRegister extends AbstractCrdt {
86
- constructor(data) {
87
- super(), this._data = data;
88
- }
89
- get data() {
90
- return this._data;
91
- }
92
- static _deserialize([id, item], _parentToChildren, doc) {
93
- const register = new LiveRegister(item.data);
94
- return register._attach(id, doc), register;
95
- }
96
- _serialize(parentId, parentKey, doc, intent) {
97
- if (null == this._id || null == parentId || null == parentKey) throw new Error("Cannot serialize register if parentId or parentKey is undefined");
98
- return [ {
99
- type: OpCode.CREATE_REGISTER,
100
- opId: null == doc ? void 0 : doc.generateOpId(),
101
- id: this._id,
102
- intent: intent,
103
- parentId: parentId,
104
- parentKey: parentKey,
105
- data: this.data
106
- } ];
107
- }
108
- _toSerializedCrdt() {
109
- var _a;
110
- return {
111
- type: CrdtType.REGISTER,
112
- parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
113
- parentKey: this._parentKey,
114
- data: this.data
115
- };
116
- }
117
- _attachChild(_op, _isLocal) {
118
- throw new Error("Method not implemented.");
119
- }
120
- _detachChild(_crdt) {
121
- throw new Error("Method not implemented.");
122
- }
123
- _apply(op, isLocal) {
124
- return super._apply(op, isLocal);
125
- }
235
+ constructor(data) {
236
+ super(), (this._data = data);
237
+ }
238
+ get data() {
239
+ return this._data;
240
+ }
241
+ static _deserialize([id, item], _parentToChildren, doc) {
242
+ const register = new LiveRegister(item.data);
243
+ return register._attach(id, doc), register;
244
+ }
245
+ _serialize(parentId, parentKey, doc) {
246
+ if (null == this._id || null == parentId || null == parentKey)
247
+ throw new Error(
248
+ "Cannot serialize register if parentId or parentKey is undefined"
249
+ );
250
+ return [
251
+ {
252
+ type: OpCode.CREATE_REGISTER,
253
+ opId: null == doc ? void 0 : doc.generateOpId(),
254
+ id: this._id,
255
+ parentId: parentId,
256
+ parentKey: parentKey,
257
+ data: this.data,
258
+ },
259
+ ];
260
+ }
261
+ _toSerializedCrdt() {
262
+ if ("HasParent" !== this.parent.type)
263
+ throw new Error("Cannot serialize LiveRegister if parent is missing");
264
+ return {
265
+ type: CrdtType.REGISTER,
266
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
267
+ parentKey: this.parent.key,
268
+ data: this.data,
269
+ };
270
+ }
271
+ _attachChild(_op) {
272
+ throw new Error("Method not implemented.");
273
+ }
274
+ _detachChild(_crdt) {
275
+ throw new Error("Method not implemented.");
276
+ }
277
+ _apply(op, isLocal) {
278
+ return super._apply(op, isLocal);
279
+ }
126
280
  }
127
-
128
281
  function makePosition(before, after) {
129
- return null == before && null == after ? pos([ 33 ]) : null != before && null == after ? function(before) {
130
- const result = [], beforeCodes = posCodes(before);
131
- for (let i = 0; i < beforeCodes.length; i++) {
132
- const code = beforeCodes[i];
133
- if (126 !== code) {
134
- result.push(code + 1);
135
- break;
136
- }
137
- if (result.push(code), beforeCodes.length - 1 === i) {
138
- result.push(33);
139
- break;
140
- }
141
- }
142
- return pos(result);
143
- }(before) : null == before && null != after ? function(after) {
144
- const result = [], afterCodes = posCodes(after);
145
- for (let i = 0; i < afterCodes.length; i++) {
146
- const code = afterCodes[i];
147
- if (!(code <= 33)) {
148
- result.push(code - 1);
149
- break;
150
- }
151
- if (result.push(32), afterCodes.length - 1 === i) {
152
- result.push(126);
153
- break;
154
- }
155
- }
156
- return pos(result);
157
- }(after) : pos(makePositionFromCodes(posCodes(before), posCodes(after)));
282
+ return null != before && null != after
283
+ ? pos(makePositionFromCodes(posCodes(before), posCodes(after)))
284
+ : null != before
285
+ ? (function (before) {
286
+ const result = [],
287
+ beforeCodes = posCodes(before);
288
+ for (let i = 0; i < beforeCodes.length; i++) {
289
+ const code = beforeCodes[i];
290
+ if (126 !== code) {
291
+ result.push(code + 1);
292
+ break;
293
+ }
294
+ if ((result.push(code), beforeCodes.length - 1 === i)) {
295
+ result.push(33);
296
+ break;
297
+ }
298
+ }
299
+ return pos(result);
300
+ })(before)
301
+ : null != after
302
+ ? (function (after) {
303
+ const result = [],
304
+ afterCodes = posCodes(after);
305
+ for (let i = 0; i < afterCodes.length; i++) {
306
+ const code = afterCodes[i];
307
+ if (!(code <= 33)) {
308
+ result.push(code - 1);
309
+ break;
310
+ }
311
+ if ((result.push(32), afterCodes.length - 1 === i)) {
312
+ result.push(126);
313
+ break;
314
+ }
315
+ }
316
+ return pos(result);
317
+ })(after)
318
+ : pos([33]);
158
319
  }
159
-
160
320
  function makePositionFromCodes(before, after) {
161
- let index = 0;
162
- const result = [];
163
- for (;;) {
164
- const beforeDigit = before[index] || 32, afterDigit = after[index] || 126;
165
- if (beforeDigit > afterDigit) throw new Error(`Impossible to generate position between ${before} and ${after}`);
166
- if (beforeDigit === afterDigit) {
167
- result.push(beforeDigit), index++;
168
- continue;
169
- }
170
- if (afterDigit - beforeDigit == 1) {
171
- result.push(beforeDigit), result.push(...makePositionFromCodes(before.slice(index + 1), []));
172
- break;
173
- }
174
- const mid = afterDigit + beforeDigit >> 1;
175
- result.push(mid);
176
- break;
177
- }
178
- return result;
321
+ let index = 0;
322
+ const result = [];
323
+ for (;;) {
324
+ const beforeDigit = before[index] || 32,
325
+ afterDigit = after[index] || 126;
326
+ if (beforeDigit > afterDigit)
327
+ throw new Error(
328
+ `Impossible to generate position between ${before} and ${after}`
329
+ );
330
+ if (beforeDigit === afterDigit) {
331
+ result.push(beforeDigit), index++;
332
+ continue;
333
+ }
334
+ if (afterDigit - beforeDigit == 1) {
335
+ result.push(beforeDigit),
336
+ result.push(...makePositionFromCodes(before.slice(index + 1), []));
337
+ break;
338
+ }
339
+ const mid = (afterDigit + beforeDigit) >> 1;
340
+ result.push(mid);
341
+ break;
342
+ }
343
+ return result;
179
344
  }
180
-
181
345
  function posCodes(str) {
182
- const codes = [];
183
- for (let i = 0; i < str.length; i++) codes.push(str.charCodeAt(i));
184
- return codes;
346
+ const codes = [];
347
+ for (let i = 0; i < str.length; i++) codes.push(str.charCodeAt(i));
348
+ return codes;
185
349
  }
186
-
187
350
  function pos(codes) {
188
- return String.fromCharCode(...codes);
351
+ return String.fromCharCode(...codes);
189
352
  }
190
-
191
353
  function comparePosition(posA, posB) {
192
- const aCodes = posCodes(posA), bCodes = posCodes(posB), maxLength = Math.max(aCodes.length, bCodes.length);
193
- for (let i = 0; i < maxLength; i++) {
194
- const a = null == aCodes[i] ? 32 : aCodes[i], b = null == bCodes[i] ? 32 : bCodes[i];
195
- if (a !== b) return a - b;
196
- }
197
- throw new Error(`Impossible to compare similar position "${posA}" and "${posB}"`);
354
+ const aCodes = posCodes(posA),
355
+ bCodes = posCodes(posB),
356
+ maxLength = Math.max(aCodes.length, bCodes.length);
357
+ for (let i = 0; i < maxLength; i++) {
358
+ const a = null == aCodes[i] ? 32 : aCodes[i],
359
+ b = null == bCodes[i] ? 32 : bCodes[i];
360
+ if (a !== b) return a - b;
361
+ }
362
+ throw new Error(
363
+ `Impossible to compare similar position "${posA}" and "${posB}"`
364
+ );
198
365
  }
199
-
200
366
  class LiveList extends AbstractCrdt {
201
- constructor(items = []) {
202
- let position;
203
- super(), this._items = [];
204
- for (let i = 0; i < items.length; i++) {
205
- const newPosition = makePosition(position), item = selfOrRegister(items[i]);
206
- this._items.push([ item, newPosition ]), position = newPosition;
207
- }
208
- }
209
- static _deserialize([id], parentToChildren, doc) {
210
- const list = new LiveList([]);
211
- list._attach(id, doc);
212
- const children = parentToChildren.get(id);
213
- if (null == children) return list;
214
- for (const entry of children) {
215
- const child = deserialize(entry, parentToChildren, doc);
216
- child._setParentLink(list, entry[1].parentKey), list._items.push([ child, entry[1].parentKey ]),
217
- list._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
218
- }
219
- return list;
220
- }
221
- _serialize(parentId, parentKey, doc, intent) {
222
- if (null == this._id) throw new Error("Cannot serialize item is not attached");
223
- if (null == parentId || null == parentKey) throw new Error("Cannot serialize list if parentId or parentKey is undefined");
224
- const ops = [], op = {
225
- id: this._id,
226
- opId: null == doc ? void 0 : doc.generateOpId(),
227
- intent: intent,
228
- type: OpCode.CREATE_LIST,
229
- parentId: parentId,
230
- parentKey: parentKey
231
- };
232
- ops.push(op);
233
- for (const [value, key] of this._items) ops.push(...value._serialize(this._id, key, doc));
234
- return ops;
235
- }
236
- _indexOfPosition(position) {
237
- return this._items.findIndex((item => item[1] === position));
238
- }
239
- _attach(id, doc) {
240
- super._attach(id, doc);
241
- for (const [item] of this._items) item._attach(doc.generateId(), doc);
242
- }
243
- _detach() {
244
- super._detach();
245
- for (const [value] of this._items) value._detach();
246
- }
247
- _attachChild(op, isLocal) {
248
- var _a;
249
- if (null == this._doc) throw new Error("Can't attach child if doc is not present");
250
- const {id: id, parentKey: parentKey, intent: intent} = op, key = parentKey, child = creationOpToLiveStructure(op);
251
- if (void 0 !== this._doc.getItem(id)) return {
252
- modified: !1
253
- };
254
- child._attach(id, this._doc), child._setParentLink(this, key);
255
- const index = this._items.findIndex((entry => entry[1] === key));
256
- let newKey = key;
257
- if (-1 !== index) {
258
- if ("set" === intent) {
259
- const existingItem = this._items[index][0];
260
- existingItem._detach();
261
- const storageUpdate = {
262
- node: this,
263
- type: "LiveList",
264
- updates: [ {
265
- index: index,
266
- type: "set",
267
- item: child instanceof LiveRegister ? child.data : child
268
- } ]
367
+ constructor(items = []) {
368
+ let position;
369
+ super(),
370
+ (this._items = []),
371
+ (this._implicitlyDeletedItems = new Set()),
372
+ (this._unacknowledgedSets = new Map());
373
+ for (let i = 0; i < items.length; i++) {
374
+ const newPosition = makePosition(position),
375
+ item = lsonToLiveNode(items[i]);
376
+ item._setParentLink(this, newPosition),
377
+ this._items.push(item),
378
+ (position = newPosition);
379
+ }
380
+ }
381
+ static _deserialize([id], parentToChildren, doc) {
382
+ const list = new LiveList();
383
+ list._attach(id, doc);
384
+ const children = parentToChildren.get(id);
385
+ if (null == children) return list;
386
+ for (const [id, crdt] of children) {
387
+ const child = deserialize([id, crdt], parentToChildren, doc);
388
+ child._setParentLink(list, crdt.parentKey),
389
+ list._items.push(child),
390
+ sortListItem(list._items);
391
+ }
392
+ return list;
393
+ }
394
+ _serialize(parentId, parentKey, doc) {
395
+ if (null == this._id)
396
+ throw new Error("Cannot serialize item is not attached");
397
+ const ops = [],
398
+ op = {
399
+ id: this._id,
400
+ opId: null == doc ? void 0 : doc.generateOpId(),
401
+ type: OpCode.CREATE_LIST,
402
+ parentId: parentId,
403
+ parentKey: parentKey,
404
+ };
405
+ ops.push(op);
406
+ for (const item of this._items)
407
+ ops.push(...item._serialize(this._id, item._getParentKeyOrThrow(), doc));
408
+ return ops;
409
+ }
410
+ _indexOfPosition(position) {
411
+ return this._items.findIndex(
412
+ (item) => item._getParentKeyOrThrow() === position
413
+ );
414
+ }
415
+ _attach(id, doc) {
416
+ super._attach(id, doc);
417
+ for (const item of this._items) item._attach(doc.generateId(), doc);
418
+ }
419
+ _detach() {
420
+ super._detach();
421
+ for (const item of this._items) item._detach();
422
+ }
423
+ _applySetRemote(op) {
424
+ if (null == this._doc)
425
+ throw new Error("Can't attach child if doc is not present");
426
+ const { id: id, parentKey: key } = op,
427
+ child = creationOpToLiveNode(op);
428
+ child._attach(id, this._doc), child._setParentLink(this, key);
429
+ const deletedId = op.deletedId,
430
+ indexOfItemWithSamePosition = this._indexOfPosition(key);
431
+ if (-1 !== indexOfItemWithSamePosition) {
432
+ const itemWithSamePosition = this._items[indexOfItemWithSamePosition];
433
+ if (itemWithSamePosition._id === deletedId)
434
+ return (
435
+ itemWithSamePosition._detach(),
436
+ (this._items[indexOfItemWithSamePosition] = child),
437
+ {
438
+ modified: makeUpdate(this, [
439
+ setDelta(indexOfItemWithSamePosition, child),
440
+ ]),
441
+ reverse: [],
442
+ }
443
+ );
444
+ {
445
+ this._implicitlyDeletedItems.add(itemWithSamePosition),
446
+ (this._items[indexOfItemWithSamePosition] = child);
447
+ const delta = [setDelta(indexOfItemWithSamePosition, child)],
448
+ deleteDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
449
+ return (
450
+ deleteDelta && delta.push(deleteDelta),
451
+ { modified: makeUpdate(this, delta), reverse: [] }
452
+ );
453
+ }
454
+ }
455
+ {
456
+ const updates = [],
457
+ deleteDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
458
+ return (
459
+ deleteDelta && updates.push(deleteDelta),
460
+ this._items.push(child),
461
+ sortListItem(this._items),
462
+ updates.push(insertDelta(this._indexOfPosition(key), child)),
463
+ { reverse: [], modified: makeUpdate(this, updates) }
464
+ );
465
+ }
466
+ }
467
+ _applySetAck(op) {
468
+ if (null == this._doc)
469
+ throw new Error("Can't attach child if doc is not present");
470
+ const delta = [],
471
+ deletedDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
472
+ deletedDelta && delta.push(deletedDelta);
473
+ const unacknowledgedOpId = this._unacknowledgedSets.get(op.parentKey);
474
+ if (null != unacknowledgedOpId) {
475
+ if (unacknowledgedOpId !== op.opId)
476
+ return 0 === delta.length
477
+ ? { modified: !1 }
478
+ : { modified: makeUpdate(this, delta), reverse: [] };
479
+ this._unacknowledgedSets.delete(op.parentKey);
480
+ }
481
+ const indexOfItemWithSamePosition = this._indexOfPosition(op.parentKey),
482
+ existingItem = this._items.find((item) => item._id === op.id);
483
+ if (null != existingItem) {
484
+ if (existingItem._parentKey === op.parentKey)
485
+ return {
486
+ modified: delta.length > 0 && makeUpdate(this, delta),
487
+ reverse: [],
488
+ };
489
+ -1 !== indexOfItemWithSamePosition &&
490
+ (this._implicitlyDeletedItems.add(
491
+ this._items[indexOfItemWithSamePosition]
492
+ ),
493
+ this._items.splice(indexOfItemWithSamePosition, 1),
494
+ delta.push(deleteDelta(indexOfItemWithSamePosition)));
495
+ const previousIndex = this._items.indexOf(existingItem);
496
+ existingItem._setParentLink(this, op.parentKey),
497
+ sortListItem(this._items);
498
+ const newIndex = this._items.indexOf(existingItem);
499
+ return (
500
+ newIndex !== previousIndex &&
501
+ delta.push(moveDelta(previousIndex, newIndex, existingItem)),
502
+ { modified: delta.length > 0 && makeUpdate(this, delta), reverse: [] }
503
+ );
504
+ }
505
+ {
506
+ const orphan = this._doc.getItem(op.id);
507
+ if (orphan && this._implicitlyDeletedItems.has(orphan)) {
508
+ orphan._setParentLink(this, op.parentKey),
509
+ this._implicitlyDeletedItems.delete(orphan),
510
+ this._items.push(orphan),
511
+ sortListItem(this._items);
512
+ const recreatedItemIndex = this._items.indexOf(orphan);
513
+ return {
514
+ modified: makeUpdate(this, [
515
+ -1 === indexOfItemWithSamePosition
516
+ ? insertDelta(recreatedItemIndex, orphan)
517
+ : setDelta(recreatedItemIndex, orphan),
518
+ ...delta,
519
+ ]),
520
+ reverse: [],
521
+ };
522
+ }
523
+ {
524
+ -1 !== indexOfItemWithSamePosition &&
525
+ this._items.splice(indexOfItemWithSamePosition, 1);
526
+ const { newItem: newItem, newIndex: newIndex } =
527
+ this._createAttachItemAndSort(op, op.parentKey);
528
+ return {
529
+ modified: makeUpdate(this, [
530
+ -1 === indexOfItemWithSamePosition
531
+ ? insertDelta(newIndex, newItem)
532
+ : setDelta(newIndex, newItem),
533
+ ...delta,
534
+ ]),
535
+ reverse: [],
536
+ };
537
+ }
538
+ }
539
+ }
540
+ _detachItemAssociatedToSetOperation(deletedId) {
541
+ if (null == deletedId || null == this._doc) return null;
542
+ const deletedItem = this._doc.getItem(deletedId);
543
+ if (null == deletedItem) return null;
544
+ const result = this._detachChild(deletedItem);
545
+ return !1 === result.modified ? null : result.modified.updates[0];
546
+ }
547
+ _applyRemoteInsert(op) {
548
+ if (null == this._doc)
549
+ throw new Error("Can't attach child if doc is not present");
550
+ const key = op.parentKey,
551
+ existingItemIndex = this._indexOfPosition(key);
552
+ -1 !== existingItemIndex && this._shiftItemPosition(existingItemIndex, key);
553
+ const { newItem: newItem, newIndex: newIndex } =
554
+ this._createAttachItemAndSort(op, key);
555
+ return {
556
+ modified: makeUpdate(this, [insertDelta(newIndex, newItem)]),
557
+ reverse: [],
269
558
  };
270
- return this._items[index][0] = child, {
271
- modified: storageUpdate,
272
- reverse: existingItem._serialize(this._id, key, this._doc, "set")
559
+ }
560
+ _applyInsertAck(op) {
561
+ const existingItem = this._items.find((item) => item._id === op.id),
562
+ key = op.parentKey,
563
+ itemIndexAtPosition = this._indexOfPosition(key);
564
+ if (existingItem) {
565
+ if (existingItem._parentKey === key) return { modified: !1 };
566
+ {
567
+ const oldPositionIndex = this._items.indexOf(existingItem);
568
+ -1 !== itemIndexAtPosition &&
569
+ this._shiftItemPosition(itemIndexAtPosition, key),
570
+ existingItem._setParentLink(this, key),
571
+ sortListItem(this._items);
572
+ const newIndex = this._indexOfPosition(key);
573
+ return newIndex === oldPositionIndex
574
+ ? { modified: !1 }
575
+ : {
576
+ modified: makeUpdate(this, [
577
+ moveDelta(oldPositionIndex, newIndex, existingItem),
578
+ ]),
579
+ reverse: [],
580
+ };
581
+ }
582
+ }
583
+ {
584
+ const orphan = nn(this._doc).getItem(op.id);
585
+ if (orphan && this._implicitlyDeletedItems.has(orphan)) {
586
+ orphan._setParentLink(this, key),
587
+ this._implicitlyDeletedItems.delete(orphan),
588
+ this._items.push(orphan),
589
+ sortListItem(this._items);
590
+ return {
591
+ modified: makeUpdate(this, [
592
+ insertDelta(this._indexOfPosition(key), orphan),
593
+ ]),
594
+ reverse: [],
595
+ };
596
+ }
597
+ {
598
+ -1 !== itemIndexAtPosition &&
599
+ this._shiftItemPosition(itemIndexAtPosition, key);
600
+ const { newItem: newItem, newIndex: newIndex } =
601
+ this._createAttachItemAndSort(op, key);
602
+ return {
603
+ modified: makeUpdate(this, [insertDelta(newIndex, newItem)]),
604
+ reverse: [],
605
+ };
606
+ }
607
+ }
608
+ }
609
+ _applyInsertUndoRedo(op) {
610
+ var _a;
611
+ const { id: id, parentKey: key } = op,
612
+ child = creationOpToLiveNode(op);
613
+ if (
614
+ void 0 !==
615
+ (null === (_a = this._doc) || void 0 === _a ? void 0 : _a.getItem(id))
616
+ )
617
+ return { modified: !1 };
618
+ child._attach(id, nn(this._doc)), child._setParentLink(this, key);
619
+ const existingItemIndex = this._indexOfPosition(key);
620
+ let newKey = key;
621
+ if (-1 !== existingItemIndex) {
622
+ (newKey = makePosition(
623
+ this._items[existingItemIndex]
624
+ ? this._items[existingItemIndex]._getParentKeyOrThrow()
625
+ : void 0,
626
+ this._items[existingItemIndex + 1]
627
+ ? this._items[existingItemIndex + 1]._getParentKeyOrThrow()
628
+ : void 0
629
+ )),
630
+ child._setParentLink(this, newKey);
631
+ }
632
+ this._items.push(child), sortListItem(this._items);
633
+ return {
634
+ modified: makeUpdate(this, [
635
+ insertDelta(this._indexOfPosition(newKey), child),
636
+ ]),
637
+ reverse: [{ type: OpCode.DELETE_CRDT, id: id }],
273
638
  };
274
- }
275
- if (isLocal) {
276
- const before = this._items[index] ? this._items[index][1] : void 0, after = this._items[index + 1] ? this._items[index + 1][1] : void 0;
277
- newKey = makePosition(before, after), child._setParentLink(this, newKey);
278
- } else this._items[index][1] = makePosition(key, null === (_a = this._items[index + 1]) || void 0 === _a ? void 0 : _a[1]);
279
- }
280
- this._items.push([ child, newKey ]), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
281
- const newIndex = this._items.findIndex((entry => entry[1] === newKey));
282
- return {
283
- reverse: [ {
284
- type: OpCode.DELETE_CRDT,
285
- id: id
286
- } ],
287
- modified: {
288
- node: this,
289
- type: "LiveList",
290
- updates: [ {
291
- index: newIndex,
292
- type: "insert",
293
- item: child instanceof LiveRegister ? child.data : child
294
- } ]
295
- }
296
- };
297
- }
298
- _detachChild(child) {
299
- if (child) {
300
- const reverse = child._serialize(this._id, child._parentKey, this._doc), indexToDelete = this._items.findIndex((item => item[0] === child));
301
- this._items.splice(indexToDelete, 1), child._detach();
302
- return {
303
- modified: {
304
- node: this,
305
- type: "LiveList",
306
- updates: [ {
307
- index: indexToDelete,
308
- type: "delete"
309
- } ]
310
- },
311
- reverse: reverse
312
- };
313
639
  }
640
+ _applySetUndoRedo(op) {
641
+ var _a;
642
+ const { id: id, parentKey: key } = op,
643
+ child = creationOpToLiveNode(op);
644
+ if (
645
+ void 0 !==
646
+ (null === (_a = this._doc) || void 0 === _a ? void 0 : _a.getItem(id))
647
+ )
648
+ return { modified: !1 };
649
+ this._unacknowledgedSets.set(key, nn(op.opId));
650
+ const indexOfItemWithSameKey = this._indexOfPosition(key);
651
+ child._attach(id, nn(this._doc)), child._setParentLink(this, key);
652
+ const newKey = key;
653
+ if (-1 !== indexOfItemWithSameKey) {
654
+ const existingItem = this._items[indexOfItemWithSameKey];
655
+ existingItem._detach(), (this._items[indexOfItemWithSameKey] = child);
656
+ const reverse = existingItem._serialize(nn(this._id), key, this._doc);
657
+ addIntentAndDeletedIdToOperation(reverse, op.id);
658
+ const delta = [setDelta(indexOfItemWithSameKey, child)],
659
+ deletedDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
660
+ return (
661
+ deletedDelta && delta.push(deletedDelta),
662
+ { modified: makeUpdate(this, delta), reverse: reverse }
663
+ );
664
+ }
665
+ {
666
+ this._items.push(child),
667
+ sortListItem(this._items),
668
+ this._detachItemAssociatedToSetOperation(op.deletedId);
669
+ const newIndex = this._indexOfPosition(newKey);
670
+ return {
671
+ reverse: [{ type: OpCode.DELETE_CRDT, id: id }],
672
+ modified: makeUpdate(this, [insertDelta(newIndex, child)]),
673
+ };
674
+ }
675
+ }
676
+ _attachChild(op, source) {
677
+ if (null == this._doc)
678
+ throw new Error("Can't attach child if doc is not present");
679
+ if ("set" === op.intent) {
680
+ if (source === OpSource.REMOTE) return this._applySetRemote(op);
681
+ if (source === OpSource.UNDOREDO_RECONNECT)
682
+ return this._applySetUndoRedo(op);
683
+ if (source === OpSource.ACK) return this._applySetAck(op);
684
+ }
685
+ return source === OpSource.REMOTE
686
+ ? this._applyRemoteInsert(op)
687
+ : source === OpSource.ACK
688
+ ? this._applyInsertAck(op)
689
+ : this._applyInsertUndoRedo(op);
690
+ }
691
+ _detachChild(child) {
692
+ if (child) {
693
+ const parentKey = nn(child._parentKey),
694
+ reverse = child._serialize(nn(this._id), parentKey, this._doc),
695
+ indexToDelete = this._items.indexOf(child);
696
+ return (
697
+ this._items.splice(indexToDelete, 1),
698
+ child._detach(),
699
+ {
700
+ modified: makeUpdate(this, [deleteDelta(indexToDelete)]),
701
+ reverse: reverse,
702
+ }
703
+ );
704
+ }
705
+ return { modified: !1 };
706
+ }
707
+ _applySetChildKeyRemote(newKey, child) {
708
+ var _a;
709
+ if (this._implicitlyDeletedItems.has(child)) {
710
+ this._implicitlyDeletedItems.delete(child),
711
+ child._setParentLink(this, newKey),
712
+ this._items.push(child),
713
+ sortListItem(this._items);
714
+ return {
715
+ modified: makeUpdate(this, [
716
+ insertDelta(this._items.indexOf(child), child),
717
+ ]),
718
+ reverse: [],
719
+ };
720
+ }
721
+ if (newKey === child._parentKey) return { modified: !1 };
722
+ const existingItemIndex = this._indexOfPosition(newKey);
723
+ if (-1 === existingItemIndex) {
724
+ const previousIndex = this._items.indexOf(child);
725
+ child._setParentLink(this, newKey), sortListItem(this._items);
726
+ const newIndex = this._items.indexOf(child);
727
+ return newIndex === previousIndex
728
+ ? { modified: !1 }
729
+ : {
730
+ modified: makeUpdate(this, [
731
+ moveDelta(previousIndex, newIndex, child),
732
+ ]),
733
+ reverse: [],
734
+ };
735
+ }
736
+ {
737
+ this._items[existingItemIndex]._setParentLink(
738
+ this,
739
+ makePosition(
740
+ newKey,
741
+ null === (_a = this._items[existingItemIndex + 1]) || void 0 === _a
742
+ ? void 0
743
+ : _a._getParentKeyOrThrow()
744
+ )
745
+ );
746
+ const previousIndex = this._items.indexOf(child);
747
+ child._setParentLink(this, newKey), sortListItem(this._items);
748
+ const newIndex = this._items.indexOf(child);
749
+ return newIndex === previousIndex
750
+ ? { modified: !1 }
751
+ : {
752
+ modified: makeUpdate(this, [
753
+ moveDelta(previousIndex, newIndex, child),
754
+ ]),
755
+ reverse: [],
756
+ };
757
+ }
758
+ }
759
+ _applySetChildKeyAck(newKey, child) {
760
+ var _a, _b;
761
+ const previousKey = nn(child._parentKey);
762
+ if (this._implicitlyDeletedItems.has(child)) {
763
+ const existingItemIndex = this._indexOfPosition(newKey);
764
+ return (
765
+ this._implicitlyDeletedItems.delete(child),
766
+ -1 !== existingItemIndex &&
767
+ this._items[existingItemIndex]._setParentLink(
768
+ this,
769
+ makePosition(
770
+ newKey,
771
+ null === (_a = this._items[existingItemIndex + 1]) ||
772
+ void 0 === _a
773
+ ? void 0
774
+ : _a._getParentKeyOrThrow()
775
+ )
776
+ ),
777
+ child._setParentLink(this, newKey),
778
+ this._items.push(child),
779
+ sortListItem(this._items),
780
+ { modified: !1 }
781
+ );
782
+ }
783
+ {
784
+ if (newKey === previousKey) return { modified: !1 };
785
+ const previousIndex = this._items.indexOf(child),
786
+ existingItemIndex = this._indexOfPosition(newKey);
787
+ -1 !== existingItemIndex &&
788
+ this._items[existingItemIndex]._setParentLink(
789
+ this,
790
+ makePosition(
791
+ newKey,
792
+ null === (_b = this._items[existingItemIndex + 1]) || void 0 === _b
793
+ ? void 0
794
+ : _b._getParentKeyOrThrow()
795
+ )
796
+ ),
797
+ child._setParentLink(this, newKey),
798
+ sortListItem(this._items);
799
+ const newIndex = this._items.indexOf(child);
800
+ return previousIndex === newIndex
801
+ ? { modified: !1 }
802
+ : {
803
+ modified: makeUpdate(this, [
804
+ moveDelta(previousIndex, newIndex, child),
805
+ ]),
806
+ reverse: [],
807
+ };
808
+ }
809
+ }
810
+ _applySetChildKeyUndoRedo(newKey, child) {
811
+ var _a;
812
+ const previousKey = nn(child._parentKey),
813
+ previousIndex = this._items.indexOf(child),
814
+ existingItemIndex = this._indexOfPosition(newKey);
815
+ -1 !== existingItemIndex &&
816
+ this._items[existingItemIndex]._setParentLink(
817
+ this,
818
+ makePosition(
819
+ newKey,
820
+ null === (_a = this._items[existingItemIndex + 1]) || void 0 === _a
821
+ ? void 0
822
+ : _a._getParentKeyOrThrow()
823
+ )
824
+ ),
825
+ child._setParentLink(this, newKey),
826
+ sortListItem(this._items);
827
+ const newIndex = this._items.indexOf(child);
828
+ return previousIndex === newIndex
829
+ ? { modified: !1 }
830
+ : {
831
+ modified: makeUpdate(this, [
832
+ moveDelta(previousIndex, newIndex, child),
833
+ ]),
834
+ reverse: [
835
+ {
836
+ type: OpCode.SET_PARENT_KEY,
837
+ id: nn(child._id),
838
+ parentKey: previousKey,
839
+ },
840
+ ],
841
+ };
842
+ }
843
+ _setChildKey(newKey, child, source) {
844
+ return source === OpSource.REMOTE
845
+ ? this._applySetChildKeyRemote(newKey, child)
846
+ : source === OpSource.ACK
847
+ ? this._applySetChildKeyAck(newKey, child)
848
+ : this._applySetChildKeyUndoRedo(newKey, child);
849
+ }
850
+ _apply(op, isLocal) {
851
+ return super._apply(op, isLocal);
852
+ }
853
+ _toSerializedCrdt() {
854
+ if ("HasParent" !== this.parent.type)
855
+ throw new Error("Cannot serialize LiveList if parent is missing");
856
+ return {
857
+ type: CrdtType.LIST,
858
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
859
+ parentKey: this.parent.key,
860
+ };
861
+ }
862
+ get length() {
863
+ return this._items.length;
864
+ }
865
+ push(element) {
866
+ return this.insert(element, this.length);
867
+ }
868
+ insert(element, index) {
869
+ if (index < 0 || index > this._items.length)
870
+ throw new Error(
871
+ `Cannot insert list item at index "${index}". index should be between 0 and ${this._items.length}`
872
+ );
873
+ const position = makePosition(
874
+ this._items[index - 1]
875
+ ? this._items[index - 1]._getParentKeyOrThrow()
876
+ : void 0,
877
+ this._items[index] ? this._items[index]._getParentKeyOrThrow() : void 0
878
+ ),
879
+ value = lsonToLiveNode(element);
880
+ if (
881
+ (value._setParentLink(this, position),
882
+ this._items.push(value),
883
+ sortListItem(this._items),
884
+ this._doc && this._id)
885
+ ) {
886
+ const id = this._doc.generateId();
887
+ value._attach(id, this._doc),
888
+ this._doc.dispatch(
889
+ value._serialize(this._id, position, this._doc),
890
+ [{ type: OpCode.DELETE_CRDT, id: id }],
891
+ new Map([[this._id, makeUpdate(this, [insertDelta(index, value)])]])
892
+ );
893
+ }
894
+ }
895
+ move(index, targetIndex) {
896
+ if (targetIndex < 0) throw new Error("targetIndex cannot be less than 0");
897
+ if (targetIndex >= this._items.length)
898
+ throw new Error(
899
+ "targetIndex cannot be greater or equal than the list length"
900
+ );
901
+ if (index < 0) throw new Error("index cannot be less than 0");
902
+ if (index >= this._items.length)
903
+ throw new Error("index cannot be greater or equal than the list length");
904
+ let beforePosition = null,
905
+ afterPosition = null;
906
+ index < targetIndex
907
+ ? ((afterPosition =
908
+ targetIndex === this._items.length - 1
909
+ ? void 0
910
+ : this._items[targetIndex + 1]._getParentKeyOrThrow()),
911
+ (beforePosition = this._items[targetIndex]._getParentKeyOrThrow()))
912
+ : ((afterPosition = this._items[targetIndex]._getParentKeyOrThrow()),
913
+ (beforePosition =
914
+ 0 === targetIndex
915
+ ? void 0
916
+ : this._items[targetIndex - 1]._getParentKeyOrThrow()));
917
+ const position = makePosition(beforePosition, afterPosition),
918
+ item = this._items[index],
919
+ previousPosition = item._getParentKeyOrThrow();
920
+ if (
921
+ (item._setParentLink(this, position),
922
+ sortListItem(this._items),
923
+ this._doc && this._id)
924
+ ) {
925
+ const storageUpdates = new Map([
926
+ [this._id, makeUpdate(this, [moveDelta(index, targetIndex, item)])],
927
+ ]);
928
+ this._doc.dispatch(
929
+ [
930
+ {
931
+ type: OpCode.SET_PARENT_KEY,
932
+ id: nn(item._id),
933
+ opId: this._doc.generateOpId(),
934
+ parentKey: position,
935
+ },
936
+ ],
937
+ [
938
+ {
939
+ type: OpCode.SET_PARENT_KEY,
940
+ id: nn(item._id),
941
+ parentKey: previousPosition,
942
+ },
943
+ ],
944
+ storageUpdates
945
+ );
946
+ }
947
+ }
948
+ delete(index) {
949
+ if (index < 0 || index >= this._items.length)
950
+ throw new Error(
951
+ `Cannot delete list item at index "${index}". index should be between 0 and ${
952
+ this._items.length - 1
953
+ }`
954
+ );
955
+ const item = this._items[index];
956
+ if ((item._detach(), this._items.splice(index, 1), this._doc)) {
957
+ const childRecordId = item._id;
958
+ if (childRecordId) {
959
+ const storageUpdates = new Map();
960
+ storageUpdates.set(
961
+ nn(this._id),
962
+ makeUpdate(this, [deleteDelta(index)])
963
+ ),
964
+ this._doc.dispatch(
965
+ [
966
+ {
967
+ id: childRecordId,
968
+ opId: this._doc.generateOpId(),
969
+ type: OpCode.DELETE_CRDT,
970
+ },
971
+ ],
972
+ item._serialize(nn(this._id), item._getParentKeyOrThrow()),
973
+ storageUpdates
974
+ );
975
+ }
976
+ }
977
+ }
978
+ clear() {
979
+ if (this._doc) {
980
+ const ops = [],
981
+ reverseOps = [],
982
+ updateDelta = [];
983
+ for (const item of this._items) {
984
+ item._detach();
985
+ const childId = item._id;
986
+ childId &&
987
+ (ops.push({
988
+ type: OpCode.DELETE_CRDT,
989
+ id: childId,
990
+ opId: this._doc.generateOpId(),
991
+ }),
992
+ reverseOps.push(
993
+ ...item._serialize(nn(this._id), item._getParentKeyOrThrow())
994
+ ),
995
+ updateDelta.push(deleteDelta(0)));
996
+ }
997
+ this._items = [];
998
+ const storageUpdates = new Map();
999
+ storageUpdates.set(nn(this._id), makeUpdate(this, updateDelta)),
1000
+ this._doc.dispatch(ops, reverseOps, storageUpdates);
1001
+ } else {
1002
+ for (const item of this._items) item._detach();
1003
+ this._items = [];
1004
+ }
1005
+ }
1006
+ set(index, item) {
1007
+ if (index < 0 || index >= this._items.length)
1008
+ throw new Error(
1009
+ `Cannot set list item at index "${index}". index should be between 0 and ${
1010
+ this._items.length - 1
1011
+ }`
1012
+ );
1013
+ const existingItem = this._items[index],
1014
+ position = existingItem._getParentKeyOrThrow(),
1015
+ existingId = existingItem._id;
1016
+ existingItem._detach();
1017
+ const value = lsonToLiveNode(item);
1018
+ if (
1019
+ (value._setParentLink(this, position),
1020
+ (this._items[index] = value),
1021
+ this._doc && this._id)
1022
+ ) {
1023
+ const id = this._doc.generateId();
1024
+ value._attach(id, this._doc);
1025
+ const storageUpdates = new Map();
1026
+ storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
1027
+ const ops = value._serialize(this._id, position, this._doc);
1028
+ addIntentAndDeletedIdToOperation(ops, existingId),
1029
+ this._unacknowledgedSets.set(position, nn(ops[0].opId));
1030
+ const reverseOps = existingItem._serialize(this._id, position, void 0);
1031
+ addIntentAndDeletedIdToOperation(reverseOps, id),
1032
+ this._doc.dispatch(ops, reverseOps, storageUpdates);
1033
+ }
1034
+ }
1035
+ toArray() {
1036
+ return this._items.map((entry) => liveNodeToLson(entry));
1037
+ }
1038
+ every(predicate) {
1039
+ return this.toArray().every(predicate);
1040
+ }
1041
+ filter(predicate) {
1042
+ return this.toArray().filter(predicate);
1043
+ }
1044
+ find(predicate) {
1045
+ return this.toArray().find(predicate);
1046
+ }
1047
+ findIndex(predicate) {
1048
+ return this.toArray().findIndex(predicate);
1049
+ }
1050
+ forEach(callbackfn) {
1051
+ return this.toArray().forEach(callbackfn);
1052
+ }
1053
+ get(index) {
1054
+ if (!(index < 0 || index >= this._items.length))
1055
+ return liveNodeToLson(this._items[index]);
1056
+ }
1057
+ indexOf(searchElement, fromIndex) {
1058
+ return this.toArray().indexOf(searchElement, fromIndex);
1059
+ }
1060
+ lastIndexOf(searchElement, fromIndex) {
1061
+ return this.toArray().lastIndexOf(searchElement, fromIndex);
1062
+ }
1063
+ map(callback) {
1064
+ return this._items.map((entry, i) => callback(liveNodeToLson(entry), i));
1065
+ }
1066
+ some(predicate) {
1067
+ return this.toArray().some(predicate);
1068
+ }
1069
+ [Symbol.iterator]() {
1070
+ return new LiveListIterator(this._items);
1071
+ }
1072
+ _createAttachItemAndSort(op, key) {
1073
+ const newItem = creationOpToLiveNode(op);
1074
+ newItem._attach(op.id, nn(this._doc)),
1075
+ newItem._setParentLink(this, key),
1076
+ this._items.push(newItem),
1077
+ sortListItem(this._items);
1078
+ return { newItem: newItem, newIndex: this._indexOfPosition(key) };
1079
+ }
1080
+ _shiftItemPosition(index, key) {
1081
+ var _a;
1082
+ const shiftedPosition = makePosition(
1083
+ key,
1084
+ this._items.length > index + 1
1085
+ ? null === (_a = this._items[index + 1]) || void 0 === _a
1086
+ ? void 0
1087
+ : _a._getParentKeyOrThrow()
1088
+ : void 0
1089
+ );
1090
+ this._items[index]._setParentLink(this, shiftedPosition);
1091
+ }
1092
+ }
1093
+ class LiveListIterator {
1094
+ constructor(items) {
1095
+ this._innerIterator = items[Symbol.iterator]();
1096
+ }
1097
+ [Symbol.iterator]() {
1098
+ return this;
1099
+ }
1100
+ next() {
1101
+ const result = this._innerIterator.next();
1102
+ if (result.done) return { done: !0, value: void 0 };
1103
+ return { value: liveNodeToLson(result.value) };
1104
+ }
1105
+ }
1106
+ function makeUpdate(liveList, deltaUpdates) {
1107
+ return { node: liveList, type: "LiveList", updates: deltaUpdates };
1108
+ }
1109
+ function setDelta(index, item) {
314
1110
  return {
315
- modified: !1
316
- };
317
- }
318
- _setChildKey(key, child, previousKey) {
319
- var _a;
320
- child._setParentLink(this, key);
321
- const previousIndex = this._items.findIndex((entry => entry[0]._id === child._id)), index = this._items.findIndex((entry => entry[1] === key));
322
- -1 !== index && (this._items[index][1] = makePosition(key, null === (_a = this._items[index + 1]) || void 0 === _a ? void 0 : _a[1]));
323
- const item = this._items.find((item => item[0] === child));
324
- item && (item[1] = key), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
325
- const newIndex = this._items.findIndex((entry => entry[0]._id === child._id));
326
- return {
327
- modified: {
328
- node: this,
329
- type: "LiveList",
330
- updates: newIndex === previousIndex ? [] : [ {
331
- index: newIndex,
332
- item: child instanceof LiveRegister ? child.data : child,
333
- previousIndex: previousIndex,
334
- type: "move"
335
- } ]
336
- },
337
- reverse: [ {
338
- type: OpCode.SET_PARENT_KEY,
339
- id: null == item ? void 0 : item[0]._id,
340
- parentKey: previousKey
341
- } ]
1111
+ index: index,
1112
+ type: "set",
1113
+ item: item instanceof LiveRegister ? item.data : item,
342
1114
  };
343
- }
344
- _apply(op, isLocal) {
345
- return super._apply(op, isLocal);
346
- }
347
- _toSerializedCrdt() {
348
- var _a;
1115
+ }
1116
+ function deleteDelta(index) {
1117
+ return { index: index, type: "delete" };
1118
+ }
1119
+ function insertDelta(index, item) {
349
1120
  return {
350
- type: CrdtType.LIST,
351
- parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
352
- parentKey: this._parentKey
1121
+ index: index,
1122
+ type: "insert",
1123
+ item: item instanceof LiveRegister ? item.data : item,
353
1124
  };
354
- }
355
- get length() {
356
- return this._items.length;
357
- }
358
- push(element) {
359
- return this.insert(element, this.length);
360
- }
361
- insert(element, index) {
362
- if (index < 0 || index > this._items.length) throw new Error(`Cannot insert list item at index "${index}". index should be between 0 and ${this._items.length}`);
363
- const position = makePosition(this._items[index - 1] ? this._items[index - 1][1] : void 0, this._items[index] ? this._items[index][1] : void 0), value = selfOrRegister(element);
364
- value._setParentLink(this, position), this._items.push([ value, position ]), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
365
- const newIndex = this._items.findIndex((entry => entry[1] === position));
366
- if (this._doc && this._id) {
367
- const id = this._doc.generateId();
368
- value._attach(id, this._doc);
369
- const storageUpdates = new Map;
370
- storageUpdates.set(this._id, {
371
- node: this,
372
- type: "LiveList",
373
- updates: [ {
374
- index: newIndex,
375
- item: value instanceof LiveRegister ? value.data : value,
376
- type: "insert"
377
- } ]
378
- }), this._doc.dispatch(value._serialize(this._id, position, this._doc), [ {
379
- type: OpCode.DELETE_CRDT,
380
- id: id
381
- } ], storageUpdates);
382
- }
383
- }
384
- move(index, targetIndex) {
385
- if (targetIndex < 0) throw new Error("targetIndex cannot be less than 0");
386
- if (targetIndex >= this._items.length) throw new Error("targetIndex cannot be greater or equal than the list length");
387
- if (index < 0) throw new Error("index cannot be less than 0");
388
- if (index >= this._items.length) throw new Error("index cannot be greater or equal than the list length");
389
- let beforePosition = null, afterPosition = null;
390
- index < targetIndex ? (afterPosition = targetIndex === this._items.length - 1 ? void 0 : this._items[targetIndex + 1][1],
391
- beforePosition = this._items[targetIndex][1]) : (afterPosition = this._items[targetIndex][1],
392
- beforePosition = 0 === targetIndex ? void 0 : this._items[targetIndex - 1][1]);
393
- const position = makePosition(beforePosition, afterPosition), item = this._items[index], previousPosition = item[1];
394
- item[1] = position, item[0]._setParentLink(this, position), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
395
- const newIndex = this._items.findIndex((entry => entry[1] === position));
396
- if (this._doc && this._id) {
397
- const storageUpdates = new Map;
398
- storageUpdates.set(this._id, {
399
- node: this,
400
- type: "LiveList",
401
- updates: [ {
402
- index: newIndex,
403
- previousIndex: index,
404
- item: item[0],
405
- type: "move"
406
- } ]
407
- }), this._doc.dispatch([ {
408
- type: OpCode.SET_PARENT_KEY,
409
- id: item[0]._id,
410
- opId: this._doc.generateOpId(),
411
- parentKey: position
412
- } ], [ {
413
- type: OpCode.SET_PARENT_KEY,
414
- id: item[0]._id,
415
- parentKey: previousPosition
416
- } ], storageUpdates);
417
- }
418
- }
419
- delete(index) {
420
- if (index < 0 || index >= this._items.length) throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length - 1}`);
421
- const item = this._items[index];
422
- if (item[0]._detach(), this._items.splice(index, 1), this._doc) {
423
- const childRecordId = item[0]._id;
424
- if (childRecordId) {
425
- const storageUpdates = new Map;
426
- storageUpdates.set(this._id, {
427
- node: this,
428
- type: "LiveList",
429
- updates: [ {
430
- index: index,
431
- type: "delete"
432
- } ]
433
- }), this._doc.dispatch([ {
434
- id: childRecordId,
435
- opId: this._doc.generateOpId(),
436
- type: OpCode.DELETE_CRDT
437
- } ], item[0]._serialize(this._id, item[1]), storageUpdates);
438
- }
439
- }
440
- }
441
- clear() {
442
- if (this._doc) {
443
- const ops = [], reverseOps = [], updateDelta = [];
444
- let i = 0;
445
- for (const item of this._items) {
446
- item[0]._detach();
447
- const childId = item[0]._id;
448
- childId && (ops.push({
449
- id: childId,
450
- type: OpCode.DELETE_CRDT
451
- }), reverseOps.push(...item[0]._serialize(this._id, item[1])), updateDelta.push({
452
- index: i,
453
- type: "delete"
454
- })), i++;
455
- }
456
- this._items = [];
457
- const storageUpdates = new Map;
458
- storageUpdates.set(this._id, {
459
- node: this,
460
- type: "LiveList",
461
- updates: updateDelta
462
- }), this._doc.dispatch(ops, reverseOps, storageUpdates);
463
- } else {
464
- for (const item of this._items) item[0]._detach();
465
- this._items = [];
466
- }
467
- }
468
- set(index, item) {
469
- if (index < 0 || index >= this._items.length) throw new Error(`Cannot set list item at index "${index}". index should be between 0 and ${this._items.length - 1}`);
470
- const [existingItem, position] = this._items[index];
471
- existingItem._detach();
472
- const value = selfOrRegister(item);
473
- if (value._setParentLink(this, position), this._items[index][0] = value, this._doc && this._id) {
474
- const id = this._doc.generateId();
475
- value._attach(id, this._doc);
476
- const storageUpdates = new Map;
477
- storageUpdates.set(this._id, {
478
- node: this,
479
- type: "LiveList",
480
- updates: [ {
481
- index: index,
482
- item: value instanceof LiveRegister ? value.data : value,
483
- type: "set"
484
- } ]
485
- }), this._doc.dispatch(value._serialize(this._id, position, this._doc, "set"), existingItem._serialize(this._id, position, void 0, "set"), storageUpdates);
486
- }
487
- }
488
- toArray() {
489
- return this._items.map((entry => selfOrRegisterValue(entry[0])));
490
- }
491
- every(predicate) {
492
- return this.toArray().every(predicate);
493
- }
494
- filter(predicate) {
495
- return this.toArray().filter(predicate);
496
- }
497
- find(predicate) {
498
- return this.toArray().find(predicate);
499
- }
500
- findIndex(predicate) {
501
- return this.toArray().findIndex(predicate);
502
- }
503
- forEach(callbackfn) {
504
- return this.toArray().forEach(callbackfn);
505
- }
506
- get(index) {
507
- if (!(index < 0 || index >= this._items.length)) return selfOrRegisterValue(this._items[index][0]);
508
- }
509
- indexOf(searchElement, fromIndex) {
510
- return this.toArray().indexOf(searchElement, fromIndex);
511
- }
512
- lastIndexOf(searchElement, fromIndex) {
513
- return this.toArray().lastIndexOf(searchElement, fromIndex);
514
- }
515
- map(callback) {
516
- return this._items.map(((entry, i) => callback(selfOrRegisterValue(entry[0]), i)));
517
- }
518
- some(predicate) {
519
- return this.toArray().some(predicate);
520
- }
521
- [Symbol.iterator]() {
522
- return new LiveListIterator(this._items);
523
- }
524
1125
  }
525
-
526
- class LiveListIterator {
527
- constructor(items) {
528
- this._innerIterator = items[Symbol.iterator]();
529
- }
530
- [Symbol.iterator]() {
531
- return this;
532
- }
533
- next() {
534
- const result = this._innerIterator.next();
535
- return result.done ? {
536
- done: !0,
537
- value: void 0
538
- } : {
539
- value: selfOrRegisterValue(result.value[0])
1126
+ function moveDelta(previousIndex, index, item) {
1127
+ return {
1128
+ index: index,
1129
+ type: "move",
1130
+ previousIndex: previousIndex,
1131
+ item: item instanceof LiveRegister ? item.data : item,
540
1132
  };
541
- }
542
- }
543
-
544
- const _emittedDeprecationWarnings = new Set;
545
-
546
- function deprecate(message, key = message) {
547
- "production" !== process.env.NODE_ENV && (_emittedDeprecationWarnings.has(key) || (_emittedDeprecationWarnings.add(key),
548
- console.error(`DEPRECATION WARNING: ${message}`)));
549
1133
  }
550
-
551
- function deprecateIf(condition, message, key = message) {
552
- "production" !== process.env.NODE_ENV && condition && deprecate(message, key);
1134
+ function sortListItem(items) {
1135
+ items.sort((itemA, itemB) =>
1136
+ comparePosition(itemA._getParentKeyOrThrow(), itemB._getParentKeyOrThrow())
1137
+ );
553
1138
  }
554
-
555
- function throwUsageError(message) {
556
- if ("production" !== process.env.NODE_ENV) {
557
- const usageError = new Error(message);
558
- throw usageError.name = "Usage error", usageError;
559
- }
1139
+ function addIntentAndDeletedIdToOperation(ops, deletedId) {
1140
+ if (0 === ops.length)
1141
+ throw new Error(
1142
+ "Internal error. Serialized LiveStructure should have at least 1 operation"
1143
+ );
1144
+ const firstOp = ops[0];
1145
+ (firstOp.intent = "set"), (firstOp.deletedId = deletedId);
560
1146
  }
561
-
562
- function errorIf(condition, message) {
563
- "production" !== process.env.NODE_ENV && condition && throwUsageError(message);
564
- }
565
-
566
1147
  class LiveMap extends AbstractCrdt {
567
- constructor(entries) {
568
- if (super(), deprecateIf(null === entries, "Support for calling `new LiveMap(null)` will be removed in @liveblocks/client 0.18. Please call as `new LiveMap()`, or `new LiveMap([])`."),
569
- entries) {
570
- const mappedEntries = [];
571
- for (const entry of entries) {
572
- const value = selfOrRegister(entry[1]);
573
- value._setParentLink(this, entry[0]), mappedEntries.push([ entry[0], value ]);
574
- }
575
- this._map = new Map(mappedEntries);
576
- } else this._map = new Map;
577
- }
578
- _serialize(parentId, parentKey, doc, intent) {
579
- if (null == this._id) throw new Error("Cannot serialize item is not attached");
580
- if (null == parentId || null == parentKey) throw new Error("Cannot serialize map if parentId or parentKey is undefined");
581
- const ops = [], op = {
582
- id: this._id,
583
- opId: null == doc ? void 0 : doc.generateOpId(),
584
- type: OpCode.CREATE_MAP,
585
- intent: intent,
586
- parentId: parentId,
587
- parentKey: parentKey
588
- };
589
- ops.push(op);
590
- for (const [key, value] of this._map) ops.push(...value._serialize(this._id, key, doc));
591
- return ops;
592
- }
593
- static _deserialize([id, _item], parentToChildren, doc) {
594
- const map = new LiveMap;
595
- map._attach(id, doc);
596
- const children = parentToChildren.get(id);
597
- if (null == children) return map;
598
- for (const entry of children) {
599
- const crdt = entry[1];
600
- if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
601
- const child = deserialize(entry, parentToChildren, doc);
602
- child._setParentLink(map, crdt.parentKey), map._map.set(crdt.parentKey, child);
603
- }
604
- return map;
605
- }
606
- _attach(id, doc) {
607
- super._attach(id, doc);
608
- for (const [_key, value] of this._map) isCrdt(value) && value._attach(doc.generateId(), doc);
609
- }
610
- _attachChild(op, _isLocal) {
611
- if (null == this._doc) throw new Error("Can't attach child if doc is not present");
612
- const {id: id, parentKey: parentKey} = op, key = parentKey, child = creationOpToLiveStructure(op);
613
- if (void 0 !== this._doc.getItem(id)) return {
614
- modified: !1
615
- };
616
- const previousValue = this._map.get(key);
617
- let reverse;
618
- return previousValue ? (reverse = previousValue._serialize(this._id, key), previousValue._detach()) : reverse = [ {
619
- type: OpCode.DELETE_CRDT,
620
- id: id
621
- } ], child._setParentLink(this, key), child._attach(id, this._doc), this._map.set(key, child),
622
- {
623
- modified: {
624
- node: this,
625
- type: "LiveMap",
626
- updates: {
627
- [key]: {
628
- type: "update"
629
- }
630
- }
631
- },
632
- reverse: reverse
633
- };
634
- }
635
- _detach() {
636
- super._detach();
637
- for (const item of this._map.values()) item._detach();
638
- }
639
- _detachChild(child) {
640
- const reverse = child._serialize(this._id, child._parentKey, this._doc);
641
- for (const [key, value] of this._map) value === child && this._map.delete(key);
642
- child._detach();
643
- return {
644
- modified: {
645
- node: this,
646
- type: "LiveMap",
647
- updates: {
648
- [child._parentKey]: {
649
- type: "delete"
650
- }
1148
+ constructor(entries) {
1149
+ if (
1150
+ (super(),
1151
+ errorIf(
1152
+ null === entries,
1153
+ "Support for calling `new LiveMap(null)` will be removed in @liveblocks/client 0.18. Please call as `new LiveMap()`, or `new LiveMap([])`."
1154
+ ),
1155
+ entries)
1156
+ ) {
1157
+ const mappedEntries = [];
1158
+ for (const entry of entries) {
1159
+ const value = lsonToLiveNode(entry[1]);
1160
+ value._setParentLink(this, entry[0]),
1161
+ mappedEntries.push([entry[0], value]);
1162
+ }
1163
+ this._map = new Map(mappedEntries);
1164
+ } else this._map = new Map();
1165
+ }
1166
+ _serialize(parentId, parentKey, doc) {
1167
+ if (null == this._id)
1168
+ throw new Error("Cannot serialize item is not attached");
1169
+ const ops = [],
1170
+ op = {
1171
+ id: this._id,
1172
+ opId: null == doc ? void 0 : doc.generateOpId(),
1173
+ type: OpCode.CREATE_MAP,
1174
+ parentId: parentId,
1175
+ parentKey: parentKey,
1176
+ };
1177
+ ops.push(op);
1178
+ for (const [key, value] of this._map)
1179
+ ops.push(...value._serialize(this._id, key, doc));
1180
+ return ops;
1181
+ }
1182
+ static _deserialize([id, _item], parentToChildren, doc) {
1183
+ const map = new LiveMap();
1184
+ map._attach(id, doc);
1185
+ const children = parentToChildren.get(id);
1186
+ if (null == children) return map;
1187
+ for (const [id, crdt] of children) {
1188
+ const child = deserialize([id, crdt], parentToChildren, doc);
1189
+ child._setParentLink(map, crdt.parentKey),
1190
+ map._map.set(crdt.parentKey, child);
651
1191
  }
652
- },
653
- reverse: reverse
654
- };
655
- }
656
- _toSerializedCrdt() {
657
- var _a;
658
- return {
659
- type: CrdtType.MAP,
660
- parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
661
- parentKey: this._parentKey
662
- };
663
- }
664
- get(key) {
665
- const value = this._map.get(key);
666
- if (null != value) return selfOrRegisterValue(value);
667
- }
668
- set(key, value) {
669
- const oldValue = this._map.get(key);
670
- oldValue && oldValue._detach();
671
- const item = selfOrRegister(value);
672
- if (item._setParentLink(this, key), this._map.set(key, item), this._doc && this._id) {
673
- const id = this._doc.generateId();
674
- item._attach(id, this._doc);
675
- const storageUpdates = new Map;
676
- storageUpdates.set(this._id, {
677
- node: this,
678
- type: "LiveMap",
679
- updates: {
680
- [key]: {
681
- type: "update"
682
- }
1192
+ return map;
1193
+ }
1194
+ _attach(id, doc) {
1195
+ super._attach(id, doc);
1196
+ for (const [_key, value] of this._map)
1197
+ isLiveNode(value) && value._attach(doc.generateId(), doc);
1198
+ }
1199
+ _attachChild(op) {
1200
+ if (null == this._doc)
1201
+ throw new Error("Can't attach child if doc is not present");
1202
+ const { id: id, parentKey: key } = op,
1203
+ child = creationOpToLiveNode(op);
1204
+ if (void 0 !== this._doc.getItem(id)) return { modified: !1 };
1205
+ const previousValue = this._map.get(key);
1206
+ let reverse;
1207
+ if (previousValue) {
1208
+ const thisId = nn(this._id);
1209
+ (reverse = previousValue._serialize(thisId, key)),
1210
+ previousValue._detach();
1211
+ } else reverse = [{ type: OpCode.DELETE_CRDT, id: id }];
1212
+ return (
1213
+ child._setParentLink(this, key),
1214
+ child._attach(id, this._doc),
1215
+ this._map.set(key, child),
1216
+ {
1217
+ modified: {
1218
+ node: this,
1219
+ type: "LiveMap",
1220
+ updates: { [key]: { type: "update" } },
1221
+ },
1222
+ reverse: reverse,
1223
+ }
1224
+ );
1225
+ }
1226
+ _detach() {
1227
+ super._detach();
1228
+ for (const item of this._map.values()) item._detach();
1229
+ }
1230
+ _detachChild(child) {
1231
+ const id = nn(this._id),
1232
+ parentKey = nn(child._parentKey),
1233
+ reverse = child._serialize(id, parentKey, this._doc);
1234
+ for (const [key, value] of this._map)
1235
+ value === child && this._map.delete(key);
1236
+ child._detach();
1237
+ return {
1238
+ modified: {
1239
+ node: this,
1240
+ type: "LiveMap",
1241
+ updates: { [parentKey]: { type: "delete" } },
1242
+ },
1243
+ reverse: reverse,
1244
+ };
1245
+ }
1246
+ _toSerializedCrdt() {
1247
+ if ("HasParent" !== this.parent.type)
1248
+ throw new Error("Cannot serialize LiveMap if parent is missing");
1249
+ return {
1250
+ type: CrdtType.MAP,
1251
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
1252
+ parentKey: this.parent.key,
1253
+ };
1254
+ }
1255
+ get(key) {
1256
+ const value = this._map.get(key);
1257
+ if (null != value) return liveNodeToLson(value);
1258
+ }
1259
+ set(key, value) {
1260
+ const oldValue = this._map.get(key);
1261
+ oldValue && oldValue._detach();
1262
+ const item = lsonToLiveNode(value);
1263
+ if (
1264
+ (item._setParentLink(this, key),
1265
+ this._map.set(key, item),
1266
+ this._doc && this._id)
1267
+ ) {
1268
+ const id = this._doc.generateId();
1269
+ item._attach(id, this._doc);
1270
+ const storageUpdates = new Map();
1271
+ storageUpdates.set(this._id, {
1272
+ node: this,
1273
+ type: "LiveMap",
1274
+ updates: { [key]: { type: "update" } },
1275
+ }),
1276
+ this._doc.dispatch(
1277
+ item._serialize(this._id, key, this._doc),
1278
+ oldValue
1279
+ ? oldValue._serialize(this._id, key)
1280
+ : [{ type: OpCode.DELETE_CRDT, id: id }],
1281
+ storageUpdates
1282
+ );
683
1283
  }
684
- }), this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue ? oldValue._serialize(this._id, key) : [ {
685
- type: OpCode.DELETE_CRDT,
686
- id: id
687
- } ], storageUpdates);
688
- }
689
- }
690
- get size() {
691
- return this._map.size;
692
- }
693
- has(key) {
694
- return this._map.has(key);
695
- }
696
- delete(key) {
697
- const item = this._map.get(key);
698
- if (null == item) return !1;
699
- if (item._detach(), this._map.delete(key), this._doc && item._id) {
700
- const storageUpdates = new Map;
701
- storageUpdates.set(this._id, {
702
- node: this,
703
- type: "LiveMap",
704
- updates: {
705
- [key]: {
706
- type: "delete"
707
- }
1284
+ }
1285
+ get size() {
1286
+ return this._map.size;
1287
+ }
1288
+ has(key) {
1289
+ return this._map.has(key);
1290
+ }
1291
+ delete(key) {
1292
+ const item = this._map.get(key);
1293
+ if (null == item) return !1;
1294
+ if ((item._detach(), this._map.delete(key), this._doc && item._id)) {
1295
+ const thisId = nn(this._id),
1296
+ storageUpdates = new Map();
1297
+ storageUpdates.set(thisId, {
1298
+ node: this,
1299
+ type: "LiveMap",
1300
+ updates: { [key]: { type: "delete" } },
1301
+ }),
1302
+ this._doc.dispatch(
1303
+ [
1304
+ {
1305
+ type: OpCode.DELETE_CRDT,
1306
+ id: item._id,
1307
+ opId: this._doc.generateOpId(),
1308
+ },
1309
+ ],
1310
+ item._serialize(thisId, key),
1311
+ storageUpdates
1312
+ );
708
1313
  }
709
- }), this._doc.dispatch([ {
710
- type: OpCode.DELETE_CRDT,
711
- id: item._id,
712
- opId: this._doc.generateOpId()
713
- } ], item._serialize(this._id, key), storageUpdates);
714
- }
715
- return !0;
716
- }
717
- entries() {
718
- const innerIterator = this._map.entries();
719
- return {
720
- [Symbol.iterator]: function() {
721
- return this;
722
- },
723
- next() {
724
- const iteratorValue = innerIterator.next();
725
- if (iteratorValue.done) return {
726
- done: !0,
727
- value: void 0
728
- };
1314
+ return !0;
1315
+ }
1316
+ entries() {
1317
+ const innerIterator = this._map.entries();
729
1318
  return {
730
- value: [ iteratorValue.value[0], selfOrRegisterValue(iteratorValue.value[1]) ]
1319
+ [Symbol.iterator]() {
1320
+ return this;
1321
+ },
1322
+ next() {
1323
+ const iteratorValue = innerIterator.next();
1324
+ if (iteratorValue.done) return { done: !0, value: void 0 };
1325
+ return {
1326
+ value: [
1327
+ iteratorValue.value[0],
1328
+ liveNodeToLson(iteratorValue.value[1]),
1329
+ ],
1330
+ };
1331
+ },
731
1332
  };
732
- }
733
- };
734
- }
735
- [Symbol.iterator]() {
736
- return this.entries();
737
- }
738
- keys() {
739
- return this._map.keys();
740
- }
741
- values() {
742
- const innerIterator = this._map.values();
743
- return {
744
- [Symbol.iterator]: function() {
745
- return this;
746
- },
747
- next() {
748
- const iteratorValue = innerIterator.next();
749
- return iteratorValue.done ? {
750
- done: !0,
751
- value: void 0
752
- } : {
753
- value: selfOrRegisterValue(iteratorValue.value)
1333
+ }
1334
+ [Symbol.iterator]() {
1335
+ return this.entries();
1336
+ }
1337
+ keys() {
1338
+ return this._map.keys();
1339
+ }
1340
+ values() {
1341
+ const innerIterator = this._map.values();
1342
+ return {
1343
+ [Symbol.iterator]() {
1344
+ return this;
1345
+ },
1346
+ next() {
1347
+ const iteratorValue = innerIterator.next();
1348
+ if (iteratorValue.done) return { done: !0, value: void 0 };
1349
+ return { value: liveNodeToLson(iteratorValue.value) };
1350
+ },
754
1351
  };
755
- }
756
- };
757
- }
758
- forEach(callback) {
759
- for (const entry of this) callback(entry[1], entry[0], this);
760
- }
1352
+ }
1353
+ forEach(callback) {
1354
+ for (const entry of this) callback(entry[1], entry[0], this);
1355
+ }
761
1356
  }
762
-
763
- function assertNever(_value, errmsg) {
764
- throw new Error(errmsg);
1357
+ class LiveObject extends AbstractCrdt {
1358
+ constructor(obj = {}) {
1359
+ super(), (this._propToLastUpdate = new Map());
1360
+ for (const key in obj) {
1361
+ const value = obj[key];
1362
+ void 0 !== value && isLiveNode(value) && value._setParentLink(this, key);
1363
+ }
1364
+ this._map = new Map(Object.entries(obj));
1365
+ }
1366
+ _serialize(parentId, parentKey, doc) {
1367
+ if (null == this._id)
1368
+ throw new Error("Cannot serialize item is not attached");
1369
+ const opId = null == doc ? void 0 : doc.generateOpId(),
1370
+ ops = [],
1371
+ op =
1372
+ void 0 !== parentId && void 0 !== parentKey
1373
+ ? {
1374
+ type: OpCode.CREATE_OBJECT,
1375
+ id: this._id,
1376
+ opId: opId,
1377
+ parentId: parentId,
1378
+ parentKey: parentKey,
1379
+ data: {},
1380
+ }
1381
+ : { type: OpCode.CREATE_OBJECT, id: this._id, opId: opId, data: {} };
1382
+ ops.push(op);
1383
+ for (const [key, value] of this._map)
1384
+ isLiveNode(value)
1385
+ ? ops.push(...value._serialize(this._id, key, doc))
1386
+ : (op.data[key] = value);
1387
+ return ops;
1388
+ }
1389
+ static _deserialize([id, item], parentToChildren, doc) {
1390
+ const liveObj = new LiveObject(item.data);
1391
+ return (
1392
+ liveObj._attach(id, doc),
1393
+ this._deserializeChildren(liveObj, parentToChildren, doc)
1394
+ );
1395
+ }
1396
+ static _deserializeChildren(liveObj, parentToChildren, doc) {
1397
+ const children = parentToChildren.get(nn(liveObj._id));
1398
+ if (null == children) return liveObj;
1399
+ for (const [id, crdt] of children) {
1400
+ const child = deserializeToLson([id, crdt], parentToChildren, doc);
1401
+ isLiveStructure(child) && child._setParentLink(liveObj, crdt.parentKey),
1402
+ liveObj._map.set(crdt.parentKey, child);
1403
+ }
1404
+ return liveObj;
1405
+ }
1406
+ _attach(id, doc) {
1407
+ super._attach(id, doc);
1408
+ for (const [_key, value] of this._map)
1409
+ isLiveNode(value) && value._attach(doc.generateId(), doc);
1410
+ }
1411
+ _attachChild(op, source) {
1412
+ if (null == this._doc)
1413
+ throw new Error("Can't attach child if doc is not present");
1414
+ const { id: id, opId: opId, parentKey: key } = op,
1415
+ child = creationOpToLson(op);
1416
+ if (void 0 !== this._doc.getItem(id))
1417
+ return (
1418
+ this._propToLastUpdate.get(key) === opId &&
1419
+ this._propToLastUpdate.delete(key),
1420
+ { modified: !1 }
1421
+ );
1422
+ if (source === OpSource.UNDOREDO_RECONNECT)
1423
+ this._propToLastUpdate.set(key, nn(opId));
1424
+ else if (void 0 !== this._propToLastUpdate.get(key))
1425
+ return this._propToLastUpdate.get(key) === opId
1426
+ ? (this._propToLastUpdate.delete(key), { modified: !1 })
1427
+ : { modified: !1 };
1428
+ const thisId = nn(this._id),
1429
+ previousValue = this._map.get(key);
1430
+ let reverse;
1431
+ return (
1432
+ isLiveNode(previousValue)
1433
+ ? ((reverse = previousValue._serialize(thisId, key)),
1434
+ previousValue._detach())
1435
+ : (reverse =
1436
+ void 0 === previousValue
1437
+ ? [{ type: OpCode.DELETE_OBJECT_KEY, id: thisId, key: key }]
1438
+ : [
1439
+ {
1440
+ type: OpCode.UPDATE_OBJECT,
1441
+ id: thisId,
1442
+ data: { [key]: previousValue },
1443
+ },
1444
+ ]),
1445
+ this._map.set(key, child),
1446
+ isLiveStructure(child) &&
1447
+ (child._setParentLink(this, key), child._attach(id, this._doc)),
1448
+ {
1449
+ reverse: reverse,
1450
+ modified: {
1451
+ node: this,
1452
+ type: "LiveObject",
1453
+ updates: { [key]: { type: "update" } },
1454
+ },
1455
+ }
1456
+ );
1457
+ }
1458
+ _detachChild(child) {
1459
+ if (child) {
1460
+ const id = nn(this._id),
1461
+ parentKey = nn(child._parentKey),
1462
+ reverse = child._serialize(id, parentKey, this._doc);
1463
+ for (const [key, value] of this._map)
1464
+ value === child && this._map.delete(key);
1465
+ child._detach();
1466
+ return {
1467
+ modified: {
1468
+ node: this,
1469
+ type: "LiveObject",
1470
+ updates: { [parentKey]: { type: "delete" } },
1471
+ },
1472
+ reverse: reverse,
1473
+ };
1474
+ }
1475
+ return { modified: !1 };
1476
+ }
1477
+ _detach() {
1478
+ super._detach();
1479
+ for (const value of this._map.values())
1480
+ isLiveNode(value) && value._detach();
1481
+ }
1482
+ _apply(op, isLocal) {
1483
+ return op.type === OpCode.UPDATE_OBJECT
1484
+ ? this._applyUpdate(op, isLocal)
1485
+ : op.type === OpCode.DELETE_OBJECT_KEY
1486
+ ? this._applyDeleteObjectKey(op)
1487
+ : super._apply(op, isLocal);
1488
+ }
1489
+ _toSerializedCrdt() {
1490
+ const data = {};
1491
+ for (const [key, value] of this._map)
1492
+ isLiveNode(value) || (data[key] = value);
1493
+ return "HasParent" === this.parent.type && this.parent.node._id
1494
+ ? {
1495
+ type: CrdtType.OBJECT,
1496
+ parentId: this.parent.node._id,
1497
+ parentKey: this.parent.key,
1498
+ data: data,
1499
+ }
1500
+ : { type: CrdtType.OBJECT, data: data };
1501
+ }
1502
+ _applyUpdate(op, isLocal) {
1503
+ let isModified = !1;
1504
+ const id = nn(this._id),
1505
+ reverse = [],
1506
+ reverseUpdate = { type: OpCode.UPDATE_OBJECT, id: id, data: {} };
1507
+ reverse.push(reverseUpdate);
1508
+ for (const key in op.data) {
1509
+ const oldValue = this._map.get(key);
1510
+ isLiveNode(oldValue)
1511
+ ? (reverse.push(...oldValue._serialize(id, key)), oldValue._detach())
1512
+ : void 0 !== oldValue
1513
+ ? (reverseUpdate.data[key] = oldValue)
1514
+ : void 0 === oldValue &&
1515
+ reverse.push({ type: OpCode.DELETE_OBJECT_KEY, id: id, key: key });
1516
+ }
1517
+ const updateDelta = {};
1518
+ for (const key in op.data) {
1519
+ const value = op.data[key];
1520
+ if (void 0 === value) continue;
1521
+ if (isLocal) this._propToLastUpdate.set(key, nn(op.opId));
1522
+ else {
1523
+ if (null != this._propToLastUpdate.get(key)) {
1524
+ if (this._propToLastUpdate.get(key) === op.opId) {
1525
+ this._propToLastUpdate.delete(key);
1526
+ continue;
1527
+ }
1528
+ continue;
1529
+ }
1530
+ isModified = !0;
1531
+ }
1532
+ const oldValue = this._map.get(key);
1533
+ isLiveNode(oldValue) && oldValue._detach(),
1534
+ (isModified = !0),
1535
+ (updateDelta[key] = { type: "update" }),
1536
+ this._map.set(key, value);
1537
+ }
1538
+ return (
1539
+ 0 !== Object.keys(reverseUpdate.data).length &&
1540
+ reverse.unshift(reverseUpdate),
1541
+ isModified
1542
+ ? {
1543
+ modified: { node: this, type: "LiveObject", updates: updateDelta },
1544
+ reverse: reverse,
1545
+ }
1546
+ : { modified: !1 }
1547
+ );
1548
+ }
1549
+ _applyDeleteObjectKey(op) {
1550
+ const key = op.key;
1551
+ if (!1 === this._map.has(key)) return { modified: !1 };
1552
+ if (void 0 !== this._propToLastUpdate.get(key)) return { modified: !1 };
1553
+ const oldValue = this._map.get(key),
1554
+ id = nn(this._id);
1555
+ let reverse = [];
1556
+ return (
1557
+ isLiveNode(oldValue)
1558
+ ? ((reverse = oldValue._serialize(id, op.key)), oldValue._detach())
1559
+ : void 0 !== oldValue &&
1560
+ (reverse = [
1561
+ { type: OpCode.UPDATE_OBJECT, id: id, data: { [key]: oldValue } },
1562
+ ]),
1563
+ this._map.delete(key),
1564
+ {
1565
+ modified: {
1566
+ node: this,
1567
+ type: "LiveObject",
1568
+ updates: { [op.key]: { type: "delete" } },
1569
+ },
1570
+ reverse: reverse,
1571
+ }
1572
+ );
1573
+ }
1574
+ toObject() {
1575
+ return (function (iterable) {
1576
+ const obj = {};
1577
+ for (const [key, val] of iterable) obj[key] = val;
1578
+ return obj;
1579
+ })(this._map);
1580
+ }
1581
+ set(key, value) {
1582
+ this.update({ [key]: value });
1583
+ }
1584
+ get(key) {
1585
+ return this._map.get(key);
1586
+ }
1587
+ delete(key) {
1588
+ const keyAsString = key,
1589
+ oldValue = this._map.get(keyAsString);
1590
+ if (void 0 === oldValue) return;
1591
+ if (null == this._doc || null == this._id)
1592
+ return (
1593
+ isLiveNode(oldValue) && oldValue._detach(),
1594
+ void this._map.delete(keyAsString)
1595
+ );
1596
+ let reverse;
1597
+ isLiveNode(oldValue)
1598
+ ? (oldValue._detach(),
1599
+ (reverse = oldValue._serialize(this._id, keyAsString)))
1600
+ : (reverse = [
1601
+ {
1602
+ type: OpCode.UPDATE_OBJECT,
1603
+ data: { [keyAsString]: oldValue },
1604
+ id: this._id,
1605
+ },
1606
+ ]),
1607
+ this._map.delete(keyAsString);
1608
+ const storageUpdates = new Map();
1609
+ storageUpdates.set(this._id, {
1610
+ node: this,
1611
+ type: "LiveObject",
1612
+ updates: { [key]: { type: "delete" } },
1613
+ }),
1614
+ this._doc.dispatch(
1615
+ [
1616
+ {
1617
+ type: OpCode.DELETE_OBJECT_KEY,
1618
+ key: keyAsString,
1619
+ id: this._id,
1620
+ opId: this._doc.generateOpId(),
1621
+ },
1622
+ ],
1623
+ reverse,
1624
+ storageUpdates
1625
+ );
1626
+ }
1627
+ update(overrides) {
1628
+ if (null == this._doc || null == this._id) {
1629
+ for (const key in overrides) {
1630
+ const newValue = overrides[key];
1631
+ if (void 0 === newValue) continue;
1632
+ const oldValue = this._map.get(key);
1633
+ isLiveNode(oldValue) && oldValue._detach(),
1634
+ isLiveNode(newValue) && newValue._setParentLink(this, key),
1635
+ this._map.set(key, newValue);
1636
+ }
1637
+ return;
1638
+ }
1639
+ const ops = [],
1640
+ reverseOps = [],
1641
+ opId = this._doc.generateOpId(),
1642
+ updatedProps = {},
1643
+ reverseUpdateOp = { id: this._id, type: OpCode.UPDATE_OBJECT, data: {} },
1644
+ updateDelta = {};
1645
+ for (const key in overrides) {
1646
+ const newValue = overrides[key];
1647
+ if (void 0 === newValue) continue;
1648
+ const oldValue = this._map.get(key);
1649
+ if (
1650
+ (isLiveNode(oldValue)
1651
+ ? (reverseOps.push(...oldValue._serialize(this._id, key)),
1652
+ oldValue._detach())
1653
+ : void 0 === oldValue
1654
+ ? reverseOps.push({
1655
+ type: OpCode.DELETE_OBJECT_KEY,
1656
+ id: this._id,
1657
+ key: key,
1658
+ })
1659
+ : (reverseUpdateOp.data[key] = oldValue),
1660
+ isLiveNode(newValue))
1661
+ ) {
1662
+ newValue._setParentLink(this, key),
1663
+ newValue._attach(this._doc.generateId(), this._doc);
1664
+ const newAttachChildOps = newValue._serialize(this._id, key, this._doc),
1665
+ createCrdtOp = newAttachChildOps.find(
1666
+ (op) => op.parentId === this._id
1667
+ );
1668
+ createCrdtOp && this._propToLastUpdate.set(key, nn(createCrdtOp.opId)),
1669
+ ops.push(...newAttachChildOps);
1670
+ } else
1671
+ (updatedProps[key] = newValue), this._propToLastUpdate.set(key, opId);
1672
+ this._map.set(key, newValue), (updateDelta[key] = { type: "update" });
1673
+ }
1674
+ 0 !== Object.keys(reverseUpdateOp.data).length &&
1675
+ reverseOps.unshift(reverseUpdateOp),
1676
+ 0 !== Object.keys(updatedProps).length &&
1677
+ ops.unshift({
1678
+ opId: opId,
1679
+ id: this._id,
1680
+ type: OpCode.UPDATE_OBJECT,
1681
+ data: updatedProps,
1682
+ });
1683
+ const storageUpdates = new Map();
1684
+ storageUpdates.set(this._id, {
1685
+ node: this,
1686
+ type: "LiveObject",
1687
+ updates: updateDelta,
1688
+ }),
1689
+ this._doc.dispatch(ops, reverseOps, storageUpdates);
1690
+ }
765
1691
  }
766
-
767
1692
  function remove(array, item) {
768
- for (let i = 0; i < array.length; i++) if (array[i] === item) {
769
- array.splice(i, 1);
770
- break;
771
- }
1693
+ for (let i = 0; i < array.length; i++)
1694
+ if (array[i] === item) {
1695
+ array.splice(i, 1);
1696
+ break;
1697
+ }
772
1698
  }
773
-
774
1699
  function compact(items) {
775
- return items.filter((item => null != item));
1700
+ return items.filter((item) => null != item);
776
1701
  }
777
-
778
- function creationOpToLiveStructure(op) {
779
- switch (op.type) {
780
- case OpCode.CREATE_REGISTER:
781
- return new LiveRegister(op.data);
782
-
783
- case OpCode.CREATE_OBJECT:
784
- return new LiveObject(op.data);
785
-
786
- case OpCode.CREATE_MAP:
787
- return new LiveMap;
788
-
789
- case OpCode.CREATE_LIST:
790
- return new LiveList;
791
- }
1702
+ function creationOpToLiveNode(op) {
1703
+ return lsonToLiveNode(creationOpToLson(op));
1704
+ }
1705
+ function creationOpToLson(op) {
1706
+ switch (op.type) {
1707
+ case OpCode.CREATE_REGISTER:
1708
+ return op.data;
1709
+ case OpCode.CREATE_OBJECT:
1710
+ return new LiveObject(op.data);
1711
+ case OpCode.CREATE_MAP:
1712
+ return new LiveMap();
1713
+ case OpCode.CREATE_LIST:
1714
+ return new LiveList();
1715
+ default:
1716
+ return assertNever(0, "Unknown creation Op");
1717
+ }
792
1718
  }
793
-
794
1719
  function isSameNodeOrChildOf(node, parent) {
795
- return node === parent || !!node._parent && isSameNodeOrChildOf(node._parent, parent);
1720
+ return (
1721
+ node === parent ||
1722
+ ("HasParent" === node.parent.type &&
1723
+ isSameNodeOrChildOf(node.parent.node, parent))
1724
+ );
796
1725
  }
797
-
798
1726
  function deserialize([id, crdt], parentToChildren, doc) {
799
- switch (crdt.type) {
800
- case CrdtType.OBJECT:
801
- return LiveObject._deserialize([ id, crdt ], parentToChildren, doc);
802
-
803
- case CrdtType.LIST:
804
- return LiveList._deserialize([ id, crdt ], parentToChildren, doc);
805
-
806
- case CrdtType.MAP:
807
- return LiveMap._deserialize([ id, crdt ], parentToChildren, doc);
808
-
809
- case CrdtType.REGISTER:
810
- return LiveRegister._deserialize([ id, crdt ], parentToChildren, doc);
811
-
812
- default:
813
- throw new Error("Unexpected CRDT type");
814
- }
1727
+ switch (crdt.type) {
1728
+ case CrdtType.OBJECT:
1729
+ return LiveObject._deserialize([id, crdt], parentToChildren, doc);
1730
+ case CrdtType.LIST:
1731
+ return LiveList._deserialize([id, crdt], parentToChildren, doc);
1732
+ case CrdtType.MAP:
1733
+ return LiveMap._deserialize([id, crdt], parentToChildren, doc);
1734
+ case CrdtType.REGISTER:
1735
+ return LiveRegister._deserialize([id, crdt], parentToChildren, doc);
1736
+ default:
1737
+ throw new Error("Unexpected CRDT type");
1738
+ }
1739
+ }
1740
+ function deserializeToLson([id, crdt], parentToChildren, doc) {
1741
+ switch (crdt.type) {
1742
+ case CrdtType.OBJECT:
1743
+ return LiveObject._deserialize([id, crdt], parentToChildren, doc);
1744
+ case CrdtType.LIST:
1745
+ return LiveList._deserialize([id, crdt], parentToChildren, doc);
1746
+ case CrdtType.MAP:
1747
+ return LiveMap._deserialize([id, crdt], parentToChildren, doc);
1748
+ case CrdtType.REGISTER:
1749
+ return crdt.data;
1750
+ default:
1751
+ throw new Error("Unexpected CRDT type");
1752
+ }
1753
+ }
1754
+ function isLiveStructure(value) {
1755
+ return (
1756
+ isLiveList(value) ||
1757
+ (function (value) {
1758
+ return value instanceof LiveMap;
1759
+ })(value) ||
1760
+ isLiveObject(value)
1761
+ );
1762
+ }
1763
+ function isLiveNode(value) {
1764
+ return (
1765
+ isLiveStructure(value) ||
1766
+ (function (value) {
1767
+ return value instanceof LiveRegister;
1768
+ })(value)
1769
+ );
815
1770
  }
816
-
817
- function isCrdt(obj) {
818
- return obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList || obj instanceof LiveRegister;
1771
+ function isLiveList(value) {
1772
+ return value instanceof LiveList;
819
1773
  }
820
-
821
- function selfOrRegisterValue(obj) {
822
- return obj instanceof LiveRegister ? obj.data : obj;
1774
+ function isLiveObject(value) {
1775
+ return value instanceof LiveObject;
823
1776
  }
824
-
825
- function selfOrRegister(obj) {
826
- if (obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList) return obj;
827
- if (obj instanceof LiveRegister) throw new Error("Internal error. LiveRegister should not be created from selfOrRegister");
828
- return new LiveRegister(obj);
1777
+ function liveNodeToLson(obj) {
1778
+ return obj instanceof LiveRegister
1779
+ ? obj.data
1780
+ : obj instanceof LiveList ||
1781
+ obj instanceof LiveMap ||
1782
+ obj instanceof LiveObject
1783
+ ? obj
1784
+ : assertNever(0, "Unknown AbstractCrdt");
1785
+ }
1786
+ function lsonToLiveNode(value) {
1787
+ return value instanceof LiveObject ||
1788
+ value instanceof LiveMap ||
1789
+ value instanceof LiveList
1790
+ ? value
1791
+ : new LiveRegister(value);
829
1792
  }
830
-
831
1793
  function getTreesDiffOperations(currentItems, newItems) {
832
- const ops = [];
833
- return currentItems.forEach(((_, id) => {
834
- newItems.get(id) || ops.push({
835
- type: OpCode.DELETE_CRDT,
836
- id: id
837
- });
838
- })), newItems.forEach(((crdt, id) => {
839
- const currentCrdt = currentItems.get(id);
840
- if (currentCrdt) crdt.type === CrdtType.OBJECT && (currentCrdt.type === CrdtType.OBJECT && JSON.stringify(crdt.data) === JSON.stringify(currentCrdt.data) || ops.push({
841
- type: OpCode.UPDATE_OBJECT,
842
- id: id,
843
- data: crdt.data
844
- })), crdt.parentKey !== currentCrdt.parentKey && ops.push({
845
- type: OpCode.SET_PARENT_KEY,
846
- id: id,
847
- parentKey: crdt.parentKey
848
- }); else switch (crdt.type) {
849
- case CrdtType.REGISTER:
850
- ops.push({
851
- type: OpCode.CREATE_REGISTER,
852
- id: id,
853
- parentId: crdt.parentId,
854
- parentKey: crdt.parentKey,
855
- data: crdt.data
856
- });
857
- break;
858
-
859
- case CrdtType.LIST:
860
- ops.push({
861
- type: OpCode.CREATE_LIST,
862
- id: id,
863
- parentId: crdt.parentId,
864
- parentKey: crdt.parentKey
865
- });
866
- break;
867
-
868
- case CrdtType.OBJECT:
869
- ops.push(crdt.parentId ? {
870
- type: OpCode.CREATE_OBJECT,
871
- id: id,
872
- parentId: crdt.parentId,
873
- parentKey: crdt.parentKey,
874
- data: crdt.data
875
- } : {
876
- type: OpCode.CREATE_OBJECT,
877
- id: id,
878
- data: crdt.data
879
- });
880
- break;
881
-
882
- case CrdtType.MAP:
883
- ops.push({
884
- type: OpCode.CREATE_MAP,
885
- id: id,
886
- parentId: crdt.parentId,
887
- parentKey: crdt.parentKey
888
- });
889
- }
890
- })), ops;
1794
+ const ops = [];
1795
+ return (
1796
+ currentItems.forEach((_, id) => {
1797
+ newItems.get(id) || ops.push({ type: OpCode.DELETE_CRDT, id: id });
1798
+ }),
1799
+ newItems.forEach((crdt, id) => {
1800
+ const currentCrdt = currentItems.get(id);
1801
+ if (currentCrdt)
1802
+ crdt.type === CrdtType.OBJECT &&
1803
+ ((currentCrdt.type === CrdtType.OBJECT &&
1804
+ JSON.stringify(crdt.data) === JSON.stringify(currentCrdt.data)) ||
1805
+ ops.push({ type: OpCode.UPDATE_OBJECT, id: id, data: crdt.data })),
1806
+ crdt.parentKey !== currentCrdt.parentKey &&
1807
+ ops.push({
1808
+ type: OpCode.SET_PARENT_KEY,
1809
+ id: id,
1810
+ parentKey: nn(crdt.parentKey, "Parent key must not be missing"),
1811
+ });
1812
+ else
1813
+ switch (crdt.type) {
1814
+ case CrdtType.REGISTER:
1815
+ ops.push({
1816
+ type: OpCode.CREATE_REGISTER,
1817
+ id: id,
1818
+ parentId: crdt.parentId,
1819
+ parentKey: crdt.parentKey,
1820
+ data: crdt.data,
1821
+ });
1822
+ break;
1823
+ case CrdtType.LIST:
1824
+ ops.push({
1825
+ type: OpCode.CREATE_LIST,
1826
+ id: id,
1827
+ parentId: crdt.parentId,
1828
+ parentKey: crdt.parentKey,
1829
+ });
1830
+ break;
1831
+ case CrdtType.OBJECT:
1832
+ ops.push(
1833
+ crdt.parentId
1834
+ ? {
1835
+ type: OpCode.CREATE_OBJECT,
1836
+ id: id,
1837
+ parentId: crdt.parentId,
1838
+ parentKey: crdt.parentKey,
1839
+ data: crdt.data,
1840
+ }
1841
+ : { type: OpCode.CREATE_OBJECT, id: id, data: crdt.data }
1842
+ );
1843
+ break;
1844
+ case CrdtType.MAP:
1845
+ ops.push({
1846
+ type: OpCode.CREATE_MAP,
1847
+ id: id,
1848
+ parentId: crdt.parentId,
1849
+ parentKey: crdt.parentKey,
1850
+ });
1851
+ }
1852
+ }),
1853
+ ops
1854
+ );
891
1855
  }
892
-
893
1856
  function mergeStorageUpdates(first, second) {
894
- return first ? "LiveObject" === first.type && "LiveObject" === second.type ? function(first, second) {
895
- const updates = first.updates;
896
- for (const [key, value] of entries(second.updates)) updates[key] = value;
897
- return Object.assign(Object.assign({}, second), {
898
- updates: updates
899
- });
900
- }(first, second) : "LiveMap" === first.type && "LiveMap" === second.type ? function(first, second) {
901
- const updates = first.updates;
902
- for (const [key, value] of entries(second.updates)) updates[key] = value;
903
- return Object.assign(Object.assign({}, second), {
904
- updates: updates
905
- });
906
- }(first, second) : "LiveList" === first.type && "LiveList" === second.type ? function(first, second) {
907
- const updates = first.updates;
908
- return Object.assign(Object.assign({}, second), {
909
- updates: updates.concat(second.updates)
910
- });
911
- }(first, second) : second : second;
1857
+ return first
1858
+ ? "LiveObject" === first.type && "LiveObject" === second.type
1859
+ ? (function (first, second) {
1860
+ const updates = first.updates;
1861
+ for (const [key, value] of entries(second.updates))
1862
+ updates[key] = value;
1863
+ return Object.assign(Object.assign({}, second), { updates: updates });
1864
+ })(first, second)
1865
+ : "LiveMap" === first.type && "LiveMap" === second.type
1866
+ ? (function (first, second) {
1867
+ const updates = first.updates;
1868
+ for (const [key, value] of entries(second.updates))
1869
+ updates[key] = value;
1870
+ return Object.assign(Object.assign({}, second), { updates: updates });
1871
+ })(first, second)
1872
+ : "LiveList" === first.type && "LiveList" === second.type
1873
+ ? (function (first, second) {
1874
+ const updates = first.updates;
1875
+ return Object.assign(Object.assign({}, second), {
1876
+ updates: updates.concat(second.updates),
1877
+ });
1878
+ })(first, second)
1879
+ : second
1880
+ : second;
912
1881
  }
913
-
914
1882
  function isPlain(value) {
915
- const type = typeof value;
916
- return "undefined" === type || null === value || "string" === type || "boolean" === type || "number" === type || Array.isArray(value) || isPlainObject(value);
1883
+ const type = typeof value;
1884
+ return (
1885
+ null == value ||
1886
+ "string" === type ||
1887
+ "boolean" === type ||
1888
+ "number" === type ||
1889
+ Array.isArray(value) ||
1890
+ isPlainObject(value)
1891
+ );
917
1892
  }
918
-
919
1893
  function isPlainObject(blob) {
920
- return null !== blob && "object" == typeof blob && "[object Object]" === Object.prototype.toString.call(blob);
1894
+ return (
1895
+ null !== blob &&
1896
+ "object" == typeof blob &&
1897
+ "[object Object]" === Object.prototype.toString.call(blob)
1898
+ );
921
1899
  }
922
-
923
1900
  function findNonSerializableValue(value, path = "") {
924
- if (!isPlain) return {
925
- path: path || "root",
926
- value: value
927
- };
928
- if ("object" != typeof value || null === value) return !1;
929
- for (const [key, nestedValue] of Object.entries(value)) {
930
- const nestedPath = path ? path + "." + key : key;
931
- if (!isPlain(nestedValue)) return {
932
- path: nestedPath,
933
- value: nestedValue
934
- };
935
- if ("object" == typeof nestedValue) {
936
- const nonSerializableNestedValue = findNonSerializableValue(nestedValue, nestedPath);
937
- if (nonSerializableNestedValue) return nonSerializableNestedValue;
1901
+ if (!isPlain) return { path: path || "root", value: value };
1902
+ if ("object" != typeof value || null === value) return !1;
1903
+ for (const [key, nestedValue] of Object.entries(value)) {
1904
+ const nestedPath = path ? path + "." + key : key;
1905
+ if (!isPlain(nestedValue)) return { path: nestedPath, value: nestedValue };
1906
+ if ("object" == typeof nestedValue) {
1907
+ const nonSerializableNestedValue = findNonSerializableValue(
1908
+ nestedValue,
1909
+ nestedPath
1910
+ );
1911
+ if (nonSerializableNestedValue) return nonSerializableNestedValue;
1912
+ }
938
1913
  }
939
- }
940
- return !1;
941
- }
942
-
943
- function isTokenValid(token) {
944
- const tokenParts = token.split(".");
945
- if (3 !== tokenParts.length) return !1;
946
- const data = tryParseJson(atob(tokenParts[1]));
947
- if (void 0 === data || !isJsonObject(data) || "number" != typeof data.exp) return !1;
948
- return !(Date.now() / 1e3 > data.exp - 300);
1914
+ return !1;
949
1915
  }
950
-
951
1916
  function entries(obj) {
952
- return Object.entries(obj);
1917
+ return Object.entries(obj);
953
1918
  }
954
-
955
1919
  function tryParseJson(rawMessage) {
956
- try {
957
- return JSON.parse(rawMessage);
958
- } catch (e) {
959
- return;
960
- }
1920
+ try {
1921
+ return JSON.parse(rawMessage);
1922
+ } catch (e) {
1923
+ return;
1924
+ }
961
1925
  }
962
-
963
1926
  function b64decode(b64value) {
964
- try {
965
- const formattedValue = b64value.replace(/-/g, "+").replace(/_/g, "/");
966
- return decodeURIComponent(atob(formattedValue).split("").map((function(c) {
967
- return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
968
- })).join(""));
969
- } catch (err) {
970
- return atob(b64value);
971
- }
1927
+ try {
1928
+ const formattedValue = b64value.replace(/-/g, "+").replace(/_/g, "/");
1929
+ return decodeURIComponent(
1930
+ atob(formattedValue)
1931
+ .split("")
1932
+ .map(function (c) {
1933
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
1934
+ })
1935
+ .join("")
1936
+ );
1937
+ } catch (err) {
1938
+ return atob(b64value);
1939
+ }
972
1940
  }
973
-
974
- class LiveObject extends AbstractCrdt {
975
- constructor(obj = {}) {
976
- super(), this._propToLastUpdate = new Map;
977
- for (const key in obj) {
978
- const value = obj[key];
979
- value instanceof AbstractCrdt && value._setParentLink(this, key);
980
- }
981
- this._map = new Map(Object.entries(obj));
982
- }
983
- _serialize(parentId, parentKey, doc, intent) {
984
- if (null == this._id) throw new Error("Cannot serialize item is not attached");
985
- const opId = null == doc ? void 0 : doc.generateOpId(), ops = [], op = void 0 !== parentId && void 0 !== parentKey ? {
986
- type: OpCode.CREATE_OBJECT,
987
- id: this._id,
988
- opId: opId,
989
- intent: intent,
990
- parentId: parentId,
991
- parentKey: parentKey,
992
- data: {}
993
- } : {
994
- type: OpCode.CREATE_OBJECT,
995
- id: this._id,
996
- opId: opId,
997
- intent: intent,
998
- data: {}
999
- };
1000
- ops.push(op);
1001
- for (const [key, value] of this._map) value instanceof AbstractCrdt ? ops.push(...value._serialize(this._id, key, doc)) : op.data[key] = value;
1002
- return ops;
1003
- }
1004
- static _deserialize([id, item], parentToChildren, doc) {
1005
- const liveObj = new LiveObject(item.data);
1006
- return liveObj._attach(id, doc), this._deserializeChildren(liveObj, parentToChildren, doc);
1007
- }
1008
- static _deserializeChildren(liveObj, parentToChildren, doc) {
1009
- const children = parentToChildren.get(liveObj._id);
1010
- if (null == children) return liveObj;
1011
- for (const entry of children) {
1012
- const crdt = entry[1];
1013
- if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
1014
- const child = deserialize(entry, parentToChildren, doc);
1015
- child._setParentLink(liveObj, crdt.parentKey), liveObj._map.set(crdt.parentKey, child);
1016
- }
1017
- return liveObj;
1018
- }
1019
- _attach(id, doc) {
1020
- super._attach(id, doc);
1021
- for (const [_key, value] of this._map) value instanceof AbstractCrdt && value._attach(doc.generateId(), doc);
1022
- }
1023
- _attachChild(op, isLocal) {
1024
- if (null == this._doc) throw new Error("Can't attach child if doc is not present");
1025
- const {id: id, parentKey: parentKey, opId: opId} = op, key = parentKey, child = creationOpToLiveStructure(op);
1026
- if (void 0 !== this._doc.getItem(id)) return this._propToLastUpdate.get(key) === opId && this._propToLastUpdate.delete(key),
1027
- {
1028
- modified: !1
1029
- };
1030
- if (isLocal) this._propToLastUpdate.set(key, opId); else if (void 0 !== this._propToLastUpdate.get(key)) return this._propToLastUpdate.get(key) === opId ? (this._propToLastUpdate.delete(key),
1031
- {
1032
- modified: !1
1033
- }) : {
1034
- modified: !1
1035
- };
1036
- const previousValue = this._map.get(key);
1037
- let reverse;
1038
- return isCrdt(previousValue) ? (reverse = previousValue._serialize(this._id, key),
1039
- previousValue._detach()) : reverse = void 0 === previousValue ? [ {
1040
- type: OpCode.DELETE_OBJECT_KEY,
1041
- id: this._id,
1042
- key: key
1043
- } ] : [ {
1044
- type: OpCode.UPDATE_OBJECT,
1045
- id: this._id,
1046
- data: {
1047
- [key]: previousValue
1048
- }
1049
- } ], this._map.set(key, child), child._setParentLink(this, key), child._attach(id, this._doc),
1050
- {
1051
- reverse: reverse,
1052
- modified: {
1053
- node: this,
1054
- type: "LiveObject",
1055
- updates: {
1056
- [key]: {
1057
- type: "update"
1058
- }
1059
- }
1060
- }
1061
- };
1062
- }
1063
- _detachChild(child) {
1064
- if (child) {
1065
- const reverse = child._serialize(this._id, child._parentKey, this._doc);
1066
- for (const [key, value] of this._map) value === child && this._map.delete(key);
1067
- child._detach();
1068
- return {
1069
- modified: {
1070
- node: this,
1071
- type: "LiveObject",
1072
- updates: {
1073
- [child._parentKey]: {
1074
- type: "delete"
1075
- }
1076
- }
1077
- },
1078
- reverse: reverse
1079
- };
1941
+ const SCOPES = [
1942
+ "websocket:presence",
1943
+ "websocket:storage",
1944
+ "room:read",
1945
+ "room:write",
1946
+ "rooms:read",
1947
+ "rooms:write",
1948
+ ];
1949
+ function isTokenExpired(token) {
1950
+ const now = Date.now() / 1e3;
1951
+ return now > token.exp - 300 || now < token.iat + 300;
1952
+ }
1953
+ function isScope(value) {
1954
+ return SCOPES.includes(value);
1955
+ }
1956
+ function isStringList(value) {
1957
+ return Array.isArray(value) && value.every((i) => "string" == typeof i);
1958
+ }
1959
+ function isAppOnlyAuthToken(data) {
1960
+ return (
1961
+ "string" == typeof data.appId &&
1962
+ void 0 === data.roomId &&
1963
+ isStringList(data.scopes)
1964
+ );
1965
+ }
1966
+ function isRoomAuthToken(data) {
1967
+ return (
1968
+ "string" == typeof data.appId &&
1969
+ "string" == typeof data.roomId &&
1970
+ "number" == typeof data.actor &&
1971
+ (void 0 === data.id || "string" == typeof data.id) &&
1972
+ isStringList(data.scopes) &&
1973
+ (void 0 === data.maxConnectionsPerRoom ||
1974
+ "number" == typeof data.maxConnectionsPerRoom)
1975
+ );
1976
+ }
1977
+ function isAuthToken(data) {
1978
+ return isAppOnlyAuthToken(data) || isRoomAuthToken(data);
1979
+ }
1980
+ function parseJwtToken(token) {
1981
+ const tokenParts = token.split(".");
1982
+ if (3 !== tokenParts.length)
1983
+ throw new Error("Authentication error: invalid JWT token");
1984
+ const data = tryParseJson(b64decode(tokenParts[1]));
1985
+ if (
1986
+ data &&
1987
+ (function (data) {
1988
+ if (!isPlainObject(data)) return !1;
1989
+ const { iat: iat, exp: exp } = data;
1990
+ return "number" == typeof iat && "number" == typeof exp;
1991
+ })(data)
1992
+ )
1993
+ return data;
1994
+ throw new Error("Authentication error: missing JWT metadata");
1995
+ }
1996
+ function parseRoomAuthToken(tokenString) {
1997
+ const data = parseJwtToken(tokenString);
1998
+ if (data && isRoomAuthToken(data)) {
1999
+ return __rest(data, ["maxConnections"]);
1080
2000
  }
1081
- return {
1082
- modified: !1
1083
- };
1084
- }
1085
- _detachChildren() {
1086
- for (const [key, value] of this._map) this._map.delete(key), value._detach();
1087
- }
1088
- _detach() {
1089
- super._detach();
1090
- for (const value of this._map.values()) isCrdt(value) && value._detach();
1091
- }
1092
- _apply(op, isLocal) {
1093
- return op.type === OpCode.UPDATE_OBJECT ? this._applyUpdate(op, isLocal) : op.type === OpCode.DELETE_OBJECT_KEY ? this._applyDeleteObjectKey(op) : super._apply(op, isLocal);
1094
- }
1095
- _toSerializedCrdt() {
1096
- var _a;
1097
- const data = {};
1098
- for (const [key, value] of this._map) value instanceof AbstractCrdt == !1 && (data[key] = value);
1099
- return void 0 !== (null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id) && void 0 !== this._parentKey ? {
1100
- type: CrdtType.OBJECT,
1101
- parentId: this._parent._id,
1102
- parentKey: this._parentKey,
1103
- data: data
1104
- } : {
1105
- type: CrdtType.OBJECT,
1106
- data: data
1107
- };
1108
- }
1109
- _applyUpdate(op, isLocal) {
1110
- let isModified = !1;
1111
- const reverse = [], reverseUpdate = {
1112
- type: OpCode.UPDATE_OBJECT,
1113
- id: this._id,
1114
- data: {}
1115
- };
1116
- reverse.push(reverseUpdate);
1117
- for (const key in op.data) {
1118
- const oldValue = this._map.get(key);
1119
- oldValue instanceof AbstractCrdt ? (reverse.push(...oldValue._serialize(this._id, key)),
1120
- oldValue._detach()) : void 0 !== oldValue ? reverseUpdate.data[key] = oldValue : void 0 === oldValue && reverse.push({
1121
- type: OpCode.DELETE_OBJECT_KEY,
1122
- id: this._id,
1123
- key: key
1124
- });
1125
- }
1126
- const updateDelta = {};
1127
- for (const key in op.data) {
1128
- if (isLocal) this._propToLastUpdate.set(key, op.opId); else {
1129
- if (null != this._propToLastUpdate.get(key)) {
1130
- if (this._propToLastUpdate.get(key) === op.opId) {
1131
- this._propToLastUpdate.delete(key);
1132
- continue;
1133
- }
1134
- continue;
1135
- }
1136
- isModified = !0;
1137
- }
1138
- const oldValue = this._map.get(key);
1139
- isCrdt(oldValue) && oldValue._detach(), isModified = !0, updateDelta[key] = {
1140
- type: "update"
1141
- }, this._map.set(key, op.data[key]);
1142
- }
1143
- return 0 !== Object.keys(reverseUpdate.data).length && reverse.unshift(reverseUpdate),
1144
- isModified ? {
1145
- modified: {
1146
- node: this,
1147
- type: "LiveObject",
1148
- updates: updateDelta
1149
- },
1150
- reverse: reverse
1151
- } : {
1152
- modified: !1
1153
- };
1154
- }
1155
- _applyDeleteObjectKey(op) {
1156
- const key = op.key;
1157
- if (!1 === this._map.has(key)) return {
1158
- modified: !1
1159
- };
1160
- if (void 0 !== this._propToLastUpdate.get(key)) return {
1161
- modified: !1
1162
- };
1163
- const oldValue = this._map.get(key);
1164
- let reverse = [];
1165
- return isCrdt(oldValue) ? (reverse = oldValue._serialize(this._id, op.key), oldValue._detach()) : void 0 !== oldValue && (reverse = [ {
1166
- type: OpCode.UPDATE_OBJECT,
1167
- id: this._id,
1168
- data: {
1169
- [key]: oldValue
1170
- }
1171
- } ]), this._map.delete(key), {
1172
- modified: {
1173
- node: this,
1174
- type: "LiveObject",
1175
- updates: {
1176
- [op.key]: {
1177
- type: "delete"
1178
- }
1179
- }
1180
- },
1181
- reverse: reverse
1182
- };
1183
- }
1184
- toObject() {
1185
- return function(iterable) {
1186
- const obj = {};
1187
- for (const [key, val] of iterable) obj[key] = val;
1188
- return obj;
1189
- }(this._map);
1190
- }
1191
- set(key, value) {
1192
- this.update({
1193
- [key]: value
1194
- });
1195
- }
1196
- get(key) {
1197
- return this._map.get(key);
1198
- }
1199
- delete(key) {
1200
- const keyAsString = key, oldValue = this._map.get(keyAsString);
1201
- if (void 0 === oldValue) return;
1202
- if (null == this._doc || null == this._id) return oldValue instanceof AbstractCrdt && oldValue._detach(),
1203
- void this._map.delete(keyAsString);
1204
- let reverse;
1205
- oldValue instanceof AbstractCrdt ? (oldValue._detach(), reverse = oldValue._serialize(this._id, keyAsString)) : reverse = [ {
1206
- type: OpCode.UPDATE_OBJECT,
1207
- data: {
1208
- [keyAsString]: oldValue
1209
- },
1210
- id: this._id
1211
- } ], this._map.delete(keyAsString);
1212
- const storageUpdates = new Map;
1213
- storageUpdates.set(this._id, {
1214
- node: this,
1215
- type: "LiveObject",
1216
- updates: {
1217
- [key]: {
1218
- type: "delete"
1219
- }
1220
- }
1221
- }), this._doc.dispatch([ {
1222
- type: OpCode.DELETE_OBJECT_KEY,
1223
- key: keyAsString,
1224
- id: this._id,
1225
- opId: this._doc.generateOpId()
1226
- } ], reverse, storageUpdates);
1227
- }
1228
- update(overrides) {
1229
- if (null == this._doc || null == this._id) {
1230
- for (const key in overrides) {
1231
- const oldValue = this._map.get(key);
1232
- oldValue instanceof AbstractCrdt && oldValue._detach();
1233
- const newValue = overrides[key];
1234
- newValue instanceof AbstractCrdt && newValue._setParentLink(this, key), this._map.set(key, newValue);
1235
- }
1236
- return;
1237
- }
1238
- const ops = [], reverseOps = [], opId = this._doc.generateOpId(), updatedProps = {}, reverseUpdateOp = {
1239
- id: this._id,
1240
- type: OpCode.UPDATE_OBJECT,
1241
- data: {}
1242
- }, updateDelta = {};
1243
- for (const key in overrides) {
1244
- const oldValue = this._map.get(key);
1245
- oldValue instanceof AbstractCrdt ? (reverseOps.push(...oldValue._serialize(this._id, key)),
1246
- oldValue._detach()) : void 0 === oldValue ? reverseOps.push({
1247
- type: OpCode.DELETE_OBJECT_KEY,
1248
- id: this._id,
1249
- key: key
1250
- }) : reverseUpdateOp.data[key] = oldValue;
1251
- const newValue = overrides[key];
1252
- if (newValue instanceof AbstractCrdt) {
1253
- newValue._setParentLink(this, key), newValue._attach(this._doc.generateId(), this._doc);
1254
- const newAttachChildOps = newValue._serialize(this._id, key, this._doc), createCrdtOp = newAttachChildOps.find((op => op.parentId === this._id));
1255
- createCrdtOp && this._propToLastUpdate.set(key, createCrdtOp.opId), ops.push(...newAttachChildOps);
1256
- } else updatedProps[key] = newValue, this._propToLastUpdate.set(key, opId);
1257
- this._map.set(key, newValue), updateDelta[key] = {
1258
- type: "update"
1259
- };
1260
- }
1261
- 0 !== Object.keys(reverseUpdateOp.data).length && reverseOps.unshift(reverseUpdateOp),
1262
- 0 !== Object.keys(updatedProps).length && ops.unshift({
1263
- opId: opId,
1264
- id: this._id,
1265
- type: OpCode.UPDATE_OBJECT,
1266
- data: updatedProps
1267
- });
1268
- const storageUpdates = new Map;
1269
- storageUpdates.set(this._id, {
1270
- node: this,
1271
- type: "LiveObject",
1272
- updates: updateDelta
1273
- }), this._doc.dispatch(ops, reverseOps, storageUpdates);
1274
- }
2001
+ throw new Error(
2002
+ "Authentication error: we expected a room token but did not get one. Hint: if you are using a callback, ensure the room is passed when creating the token. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClientCallback"
2003
+ );
2004
+ }
2005
+ function isJsonScalar(data) {
2006
+ return (
2007
+ null === data ||
2008
+ "string" == typeof data ||
2009
+ "number" == typeof data ||
2010
+ "boolean" == typeof data
2011
+ );
2012
+ }
2013
+ function isJsonArray(data) {
2014
+ return Array.isArray(data);
2015
+ }
2016
+ function isJsonObject(data) {
2017
+ return !isJsonScalar(data) && !isJsonArray(data);
1275
2018
  }
1276
-
1277
- export { AbstractCrdt as A, ClientMsgCode as C, LiveObject as L, OpCode as O, ServerMsgCode as S, WebsocketCloseCodes as W, isSameNodeOrChildOf as a, LiveList as b, isJsonArray as c, compact as d, b64decode as e, isJsonObject as f, getTreesDiffOperations as g, isRootCrdt as h, isTokenValid as i, deprecateIf as j, LiveMap as k, isPlainObject as l, mergeStorageUpdates as m, LiveRegister as n, findNonSerializableValue as o, deprecate as p, errorIf as q, remove as r, throwUsageError as s, tryParseJson as t, CrdtType as u, comparePosition as v, makePosition as w, isChildCrdt as x, assertNever as y, isJsonScalar as z };
2019
+ export {
2020
+ isRoomAuthToken as A,
2021
+ isScope as B,
2022
+ ClientMsgCode as C,
2023
+ deprecate as D,
2024
+ deprecateIf as E,
2025
+ throwUsageError as F,
2026
+ comparePosition as G,
2027
+ makePosition as H,
2028
+ CrdtType as I,
2029
+ isJsonScalar as J,
2030
+ isChildCrdt as K,
2031
+ LiveObject as L,
2032
+ b64decode as M,
2033
+ OpSource as O,
2034
+ ServerMsgCode as S,
2035
+ WebsocketCloseCodes as W,
2036
+ __rest as _,
2037
+ isRoomEventName as a,
2038
+ isPlainObject as b,
2039
+ isTokenExpired as c,
2040
+ isSameNodeOrChildOf as d,
2041
+ OpCode as e,
2042
+ isLiveList as f,
2043
+ getTreesDiffOperations as g,
2044
+ isJsonArray as h,
2045
+ isLiveNode as i,
2046
+ compact as j,
2047
+ isRootCrdt as k,
2048
+ isJsonObject as l,
2049
+ mergeStorageUpdates as m,
2050
+ nn as n,
2051
+ errorIf as o,
2052
+ parseRoomAuthToken as p,
2053
+ LiveList as q,
2054
+ remove as r,
2055
+ LiveMap as s,
2056
+ tryParseJson as t,
2057
+ LiveRegister as u,
2058
+ findNonSerializableValue as v,
2059
+ isLiveObject as w,
2060
+ assertNever as x,
2061
+ isAppOnlyAuthToken as y,
2062
+ isAuthToken as z,
2063
+ };