@liveblocks/client 0.16.15 → 0.17.0-test1

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