@liveblocks/core 0.19.0-beta0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +682 -676
  2. package/dist/index.js +881 -877
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -50,7 +50,161 @@ var __async = (__this, __arguments, generator) => {
50
50
  });
51
51
  };
52
52
 
53
- // src/assert.ts
53
+ // src/lib/utils.ts
54
+ function isPlainObject(blob) {
55
+ return blob !== null && typeof blob === "object" && Object.prototype.toString.call(blob) === "[object Object]";
56
+ }
57
+ function fromEntries(iterable) {
58
+ const obj = {};
59
+ for (const [key, val] of iterable) {
60
+ obj[key] = val;
61
+ }
62
+ return obj;
63
+ }
64
+ function entries(obj) {
65
+ return Object.entries(obj);
66
+ }
67
+ function tryParseJson(rawMessage) {
68
+ try {
69
+ return JSON.parse(rawMessage);
70
+ } catch (e) {
71
+ return void 0;
72
+ }
73
+ }
74
+ function b64decode(b64value) {
75
+ try {
76
+ const formattedValue = b64value.replace(/-/g, "+").replace(/_/g, "/");
77
+ const decodedValue = decodeURIComponent(
78
+ atob(formattedValue).split("").map(function(c) {
79
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
80
+ }).join("")
81
+ );
82
+ return decodedValue;
83
+ } catch (err) {
84
+ return atob(b64value);
85
+ }
86
+ }
87
+ function compact(items) {
88
+ return items.filter(
89
+ (item) => item !== null && item !== void 0
90
+ );
91
+ }
92
+ function compactObject(obj) {
93
+ const newObj = __spreadValues({}, obj);
94
+ Object.keys(obj).forEach((k) => {
95
+ const key = k;
96
+ if (newObj[key] === void 0) {
97
+ delete newObj[key];
98
+ }
99
+ });
100
+ return newObj;
101
+ }
102
+
103
+ // src/AuthToken.ts
104
+ function hasJwtMeta(data) {
105
+ if (!isPlainObject(data)) {
106
+ return false;
107
+ }
108
+ const { iat, exp } = data;
109
+ return typeof iat === "number" && typeof exp === "number";
110
+ }
111
+ function isTokenExpired(token) {
112
+ const now = Date.now() / 1e3;
113
+ return now > token.exp - 300 || now < token.iat + 300;
114
+ }
115
+ function isStringList(value) {
116
+ return Array.isArray(value) && value.every((i) => typeof i === "string");
117
+ }
118
+ function isAppOnlyAuthToken(data) {
119
+ return typeof data.appId === "string" && data.roomId === void 0 && isStringList(data.scopes);
120
+ }
121
+ function isRoomAuthToken(data) {
122
+ return typeof data.appId === "string" && typeof data.roomId === "string" && typeof data.actor === "number" && (data.id === void 0 || typeof data.id === "string") && isStringList(data.scopes) && (data.maxConnectionsPerRoom === void 0 || typeof data.maxConnectionsPerRoom === "number");
123
+ }
124
+ function isAuthToken(data) {
125
+ return isAppOnlyAuthToken(data) || isRoomAuthToken(data);
126
+ }
127
+ function parseJwtToken(token) {
128
+ const tokenParts = token.split(".");
129
+ if (tokenParts.length !== 3) {
130
+ throw new Error("Authentication error: invalid JWT token");
131
+ }
132
+ const data = tryParseJson(b64decode(tokenParts[1]));
133
+ if (data && hasJwtMeta(data)) {
134
+ return data;
135
+ } else {
136
+ throw new Error("Authentication error: missing JWT metadata");
137
+ }
138
+ }
139
+ function parseRoomAuthToken(tokenString) {
140
+ const data = parseJwtToken(tokenString);
141
+ if (data && isRoomAuthToken(data)) {
142
+ const _a = data, {
143
+ maxConnections: _legacyField
144
+ } = _a, token = __objRest(_a, [
145
+ "maxConnections"
146
+ ]);
147
+ return token;
148
+ } else {
149
+ throw new Error(
150
+ "Authentication error: we expected a room token but did not get one. Hint: if you are using a callback, ensure the room is passed when creating the token. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClientCallback"
151
+ );
152
+ }
153
+ }
154
+
155
+ // src/lib/fancy-console.ts
156
+ var badge = "background:radial-gradient(106.94% 108.33% at -10% -5%,#ff1aa3 0,#ff881a 100%);border-radius:3px;color:#fff;padding:2px 5px;font-family:sans-serif;font-weight:600";
157
+ var bold = "font-weight:600";
158
+ function wrap(method) {
159
+ return typeof window === "undefined" || process.env.NODE_ENV === "test" ? console[method] : (message, ...args) => console[method]("%cLiveblocks", badge, message, ...args);
160
+ }
161
+ var warn = wrap("warn");
162
+ var error = wrap("error");
163
+ function wrapWithTitle(method) {
164
+ return typeof window === "undefined" || process.env.NODE_ENV === "test" ? console[method] : (title, message, ...args) => console[method](
165
+ `%cLiveblocks%c ${title}`,
166
+ badge,
167
+ bold,
168
+ message,
169
+ ...args
170
+ );
171
+ }
172
+ var errorWithTitle = wrapWithTitle("error");
173
+
174
+ // src/lib/deprecation.ts
175
+ var _emittedDeprecationWarnings = /* @__PURE__ */ new Set();
176
+ function deprecate(message, key = message) {
177
+ if (process.env.NODE_ENV !== "production") {
178
+ if (!_emittedDeprecationWarnings.has(key)) {
179
+ _emittedDeprecationWarnings.add(key);
180
+ errorWithTitle("Deprecation warning", message);
181
+ }
182
+ }
183
+ }
184
+ function deprecateIf(condition, message, key = message) {
185
+ if (process.env.NODE_ENV !== "production") {
186
+ if (condition) {
187
+ deprecate(message, key);
188
+ }
189
+ }
190
+ }
191
+ function throwUsageError(message) {
192
+ if (process.env.NODE_ENV !== "production") {
193
+ const usageError = new Error(message);
194
+ usageError.name = "Usage error";
195
+ errorWithTitle("Usage error", message);
196
+ throw usageError;
197
+ }
198
+ }
199
+ function errorIf(condition, message) {
200
+ if (process.env.NODE_ENV !== "production") {
201
+ if (condition) {
202
+ throwUsageError(message);
203
+ }
204
+ }
205
+ }
206
+
207
+ // src/lib/assert.ts
54
208
  function assertNever(_value, errmsg) {
55
209
  throw new Error(errmsg);
56
210
  }
@@ -66,16 +220,7 @@ function nn(value, errmsg = "Expected value to be non-nullable") {
66
220
  return value;
67
221
  }
68
222
 
69
- // src/types/ClientMsg.ts
70
- var ClientMsgCode = /* @__PURE__ */ ((ClientMsgCode2) => {
71
- ClientMsgCode2[ClientMsgCode2["UPDATE_PRESENCE"] = 100] = "UPDATE_PRESENCE";
72
- ClientMsgCode2[ClientMsgCode2["BROADCAST_EVENT"] = 103] = "BROADCAST_EVENT";
73
- ClientMsgCode2[ClientMsgCode2["FETCH_STORAGE"] = 200] = "FETCH_STORAGE";
74
- ClientMsgCode2[ClientMsgCode2["UPDATE_STORAGE"] = 201] = "UPDATE_STORAGE";
75
- return ClientMsgCode2;
76
- })(ClientMsgCode || {});
77
-
78
- // src/types/Op.ts
223
+ // src/protocol/Op.ts
79
224
  var OpCode = /* @__PURE__ */ ((OpCode2) => {
80
225
  OpCode2[OpCode2["INIT"] = 0] = "INIT";
81
226
  OpCode2[OpCode2["SET_PARENT_KEY"] = 1] = "SET_PARENT_KEY";
@@ -89,50 +234,7 @@ var OpCode = /* @__PURE__ */ ((OpCode2) => {
89
234
  return OpCode2;
90
235
  })(OpCode || {});
91
236
 
92
- // src/types/SerializedCrdt.ts
93
- var CrdtType = /* @__PURE__ */ ((CrdtType2) => {
94
- CrdtType2[CrdtType2["OBJECT"] = 0] = "OBJECT";
95
- CrdtType2[CrdtType2["LIST"] = 1] = "LIST";
96
- CrdtType2[CrdtType2["MAP"] = 2] = "MAP";
97
- CrdtType2[CrdtType2["REGISTER"] = 3] = "REGISTER";
98
- return CrdtType2;
99
- })(CrdtType || {});
100
- function isRootCrdt(crdt) {
101
- return crdt.type === 0 /* OBJECT */ && !isChildCrdt(crdt);
102
- }
103
- function isChildCrdt(crdt) {
104
- return crdt.parentId !== void 0 && crdt.parentKey !== void 0;
105
- }
106
-
107
- // src/types/ServerMsg.ts
108
- var ServerMsgCode = /* @__PURE__ */ ((ServerMsgCode2) => {
109
- ServerMsgCode2[ServerMsgCode2["UPDATE_PRESENCE"] = 100] = "UPDATE_PRESENCE";
110
- ServerMsgCode2[ServerMsgCode2["USER_JOINED"] = 101] = "USER_JOINED";
111
- ServerMsgCode2[ServerMsgCode2["USER_LEFT"] = 102] = "USER_LEFT";
112
- ServerMsgCode2[ServerMsgCode2["BROADCASTED_EVENT"] = 103] = "BROADCASTED_EVENT";
113
- ServerMsgCode2[ServerMsgCode2["ROOM_STATE"] = 104] = "ROOM_STATE";
114
- ServerMsgCode2[ServerMsgCode2["INITIAL_STORAGE_STATE"] = 200] = "INITIAL_STORAGE_STATE";
115
- ServerMsgCode2[ServerMsgCode2["UPDATE_STORAGE"] = 201] = "UPDATE_STORAGE";
116
- return ServerMsgCode2;
117
- })(ServerMsgCode || {});
118
-
119
- // src/types/index.ts
120
- function isRoomEventName(value) {
121
- return value === "my-presence" || value === "others" || value === "event" || value === "error" || value === "connection" || value === "history";
122
- }
123
- var WebsocketCloseCodes = /* @__PURE__ */ ((WebsocketCloseCodes2) => {
124
- WebsocketCloseCodes2[WebsocketCloseCodes2["CLOSE_ABNORMAL"] = 1006] = "CLOSE_ABNORMAL";
125
- WebsocketCloseCodes2[WebsocketCloseCodes2["INVALID_MESSAGE_FORMAT"] = 4e3] = "INVALID_MESSAGE_FORMAT";
126
- WebsocketCloseCodes2[WebsocketCloseCodes2["NOT_ALLOWED"] = 4001] = "NOT_ALLOWED";
127
- WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_MESSAGES_PER_SECONDS"] = 4002] = "MAX_NUMBER_OF_MESSAGES_PER_SECONDS";
128
- WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_CONCURRENT_CONNECTIONS"] = 4003] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS";
129
- WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP"] = 4004] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP";
130
- WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM"] = 4005] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM";
131
- WebsocketCloseCodes2[WebsocketCloseCodes2["CLOSE_WITHOUT_RETRY"] = 4999] = "CLOSE_WITHOUT_RETRY";
132
- return WebsocketCloseCodes2;
133
- })(WebsocketCloseCodes || {});
134
-
135
- // src/AbstractCrdt.ts
237
+ // src/crdts/AbstractCrdt.ts
136
238
  function crdtAsLiveNode(value) {
137
239
  return value;
138
240
  }
@@ -270,63 +372,7 @@ var AbstractCrdt = class {
270
372
  }
271
373
  };
272
374
 
273
- // src/LiveRegister.ts
274
- var LiveRegister = class extends AbstractCrdt {
275
- constructor(data) {
276
- super();
277
- this._data = data;
278
- }
279
- get data() {
280
- return this._data;
281
- }
282
- static _deserialize([id, item], _parentToChildren, pool) {
283
- const register = new LiveRegister(item.data);
284
- register._attach(id, pool);
285
- return register;
286
- }
287
- _toOps(parentId, parentKey, pool) {
288
- if (this._id === void 0) {
289
- throw new Error(
290
- "Cannot serialize register if parentId or parentKey is undefined"
291
- );
292
- }
293
- return [
294
- {
295
- type: 8 /* CREATE_REGISTER */,
296
- opId: pool == null ? void 0 : pool.generateOpId(),
297
- id: this._id,
298
- parentId,
299
- parentKey,
300
- data: this.data
301
- }
302
- ];
303
- }
304
- _serialize() {
305
- if (this.parent.type !== "HasParent") {
306
- throw new Error("Cannot serialize LiveRegister if parent is missing");
307
- }
308
- return {
309
- type: 3 /* REGISTER */,
310
- parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
311
- parentKey: this.parent.key,
312
- data: this.data
313
- };
314
- }
315
- _attachChild(_op) {
316
- throw new Error("Method not implemented.");
317
- }
318
- _detachChild(_crdt) {
319
- throw new Error("Method not implemented.");
320
- }
321
- _apply(op, isLocal) {
322
- return super._apply(op, isLocal);
323
- }
324
- _toImmutable() {
325
- return this._data;
326
- }
327
- };
328
-
329
- // src/position.ts
375
+ // src/lib/position.ts
330
376
  var min = 32;
331
377
  var max = 126;
332
378
  function makePosition(before, after) {
@@ -430,9 +476,80 @@ function comparePosition(posA, posB) {
430
476
  );
431
477
  }
432
478
 
433
- // src/LiveList.ts
434
- function compareNodePosition(itemA, itemB) {
435
- return comparePosition(
479
+ // src/protocol/SerializedCrdt.ts
480
+ var CrdtType = /* @__PURE__ */ ((CrdtType2) => {
481
+ CrdtType2[CrdtType2["OBJECT"] = 0] = "OBJECT";
482
+ CrdtType2[CrdtType2["LIST"] = 1] = "LIST";
483
+ CrdtType2[CrdtType2["MAP"] = 2] = "MAP";
484
+ CrdtType2[CrdtType2["REGISTER"] = 3] = "REGISTER";
485
+ return CrdtType2;
486
+ })(CrdtType || {});
487
+ function isRootCrdt(crdt) {
488
+ return crdt.type === 0 /* OBJECT */ && !isChildCrdt(crdt);
489
+ }
490
+ function isChildCrdt(crdt) {
491
+ return crdt.parentId !== void 0 && crdt.parentKey !== void 0;
492
+ }
493
+
494
+ // src/crdts/LiveRegister.ts
495
+ var LiveRegister = class extends AbstractCrdt {
496
+ constructor(data) {
497
+ super();
498
+ this._data = data;
499
+ }
500
+ get data() {
501
+ return this._data;
502
+ }
503
+ static _deserialize([id, item], _parentToChildren, pool) {
504
+ const register = new LiveRegister(item.data);
505
+ register._attach(id, pool);
506
+ return register;
507
+ }
508
+ _toOps(parentId, parentKey, pool) {
509
+ if (this._id === void 0) {
510
+ throw new Error(
511
+ "Cannot serialize register if parentId or parentKey is undefined"
512
+ );
513
+ }
514
+ return [
515
+ {
516
+ type: 8 /* CREATE_REGISTER */,
517
+ opId: pool == null ? void 0 : pool.generateOpId(),
518
+ id: this._id,
519
+ parentId,
520
+ parentKey,
521
+ data: this.data
522
+ }
523
+ ];
524
+ }
525
+ _serialize() {
526
+ if (this.parent.type !== "HasParent") {
527
+ throw new Error("Cannot serialize LiveRegister if parent is missing");
528
+ }
529
+ return {
530
+ type: 3 /* REGISTER */,
531
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
532
+ parentKey: this.parent.key,
533
+ data: this.data
534
+ };
535
+ }
536
+ _attachChild(_op) {
537
+ throw new Error("Method not implemented.");
538
+ }
539
+ _detachChild(_crdt) {
540
+ throw new Error("Method not implemented.");
541
+ }
542
+ _apply(op, isLocal) {
543
+ return super._apply(op, isLocal);
544
+ }
545
+ _toImmutable() {
546
+ return this._data;
547
+ }
548
+ };
549
+
550
+ // src/crdts/LiveList.ts
551
+ function compareNodePosition(itemA, itemB) {
552
+ return comparePosition(
436
553
  itemA._getParentKeyOrThrow(),
437
554
  itemB._getParentKeyOrThrow()
438
555
  );
@@ -1315,7 +1432,10 @@ function addIntentAndDeletedIdToOperation(ops, deletedId) {
1315
1432
  firstOp.deletedId = deletedId;
1316
1433
  }
1317
1434
 
1318
- // src/LiveMap.ts
1435
+ // src/lib/freeze.ts
1436
+ var freeze = process.env.NODE_ENV === "production" ? (x) => x : Object.freeze;
1437
+
1438
+ // src/crdts/LiveMap.ts
1319
1439
  var LiveMap = class extends AbstractCrdt {
1320
1440
  constructor(entries2) {
1321
1441
  super();
@@ -1589,239 +1709,483 @@ var LiveMap = class extends AbstractCrdt {
1589
1709
  }
1590
1710
  };
1591
1711
 
1592
- // src/LiveObject.ts
1593
- var LiveObject = class extends AbstractCrdt {
1594
- constructor(obj = {}) {
1595
- super();
1596
- this._propToLastUpdate = /* @__PURE__ */ new Map();
1597
- for (const key in obj) {
1598
- const value = obj[key];
1599
- if (value === void 0) {
1600
- continue;
1601
- } else if (isLiveNode(value)) {
1602
- value._setParentLink(this, key);
1603
- }
1604
- }
1605
- this._map = new Map(Object.entries(obj));
1712
+ // src/liveblocks-helpers.ts
1713
+ function creationOpToLiveNode(op) {
1714
+ return lsonToLiveNode(creationOpToLson(op));
1715
+ }
1716
+ function creationOpToLson(op) {
1717
+ switch (op.type) {
1718
+ case 8 /* CREATE_REGISTER */:
1719
+ return op.data;
1720
+ case 4 /* CREATE_OBJECT */:
1721
+ return new LiveObject(op.data);
1722
+ case 7 /* CREATE_MAP */:
1723
+ return new LiveMap();
1724
+ case 2 /* CREATE_LIST */:
1725
+ return new LiveList();
1726
+ default:
1727
+ return assertNever(op, "Unknown creation Op");
1606
1728
  }
1607
- _toOps(parentId, parentKey, pool) {
1608
- if (this._id === void 0) {
1609
- throw new Error("Cannot serialize item is not attached");
1610
- }
1611
- const opId = pool == null ? void 0 : pool.generateOpId();
1612
- const ops = [];
1613
- const op = parentId !== void 0 && parentKey !== void 0 ? {
1614
- type: 4 /* CREATE_OBJECT */,
1615
- id: this._id,
1616
- opId,
1617
- parentId,
1618
- parentKey,
1619
- data: {}
1620
- } : { type: 4 /* CREATE_OBJECT */, id: this._id, opId, data: {} };
1621
- ops.push(op);
1622
- for (const [key, value] of this._map) {
1623
- if (isLiveNode(value)) {
1624
- ops.push(...value._toOps(this._id, key, pool));
1625
- } else {
1626
- op.data[key] = value;
1627
- }
1628
- }
1629
- return ops;
1729
+ }
1730
+ function isSameNodeOrChildOf(node, parent) {
1731
+ if (node === parent) {
1732
+ return true;
1630
1733
  }
1631
- static _deserialize([id, item], parentToChildren, pool) {
1632
- const liveObj = new LiveObject(item.data);
1633
- liveObj._attach(id, pool);
1634
- return this._deserializeChildren(liveObj, parentToChildren, pool);
1734
+ if (node.parent.type === "HasParent") {
1735
+ return isSameNodeOrChildOf(node.parent.node, parent);
1635
1736
  }
1636
- static _deserializeChildren(liveObj, parentToChildren, pool) {
1637
- const children = parentToChildren.get(nn(liveObj._id));
1638
- if (children === void 0) {
1639
- return liveObj;
1737
+ return false;
1738
+ }
1739
+ function deserialize([id, crdt], parentToChildren, pool) {
1740
+ switch (crdt.type) {
1741
+ case 0 /* OBJECT */: {
1742
+ return LiveObject._deserialize([id, crdt], parentToChildren, pool);
1640
1743
  }
1641
- for (const [id, crdt] of children) {
1642
- const child = deserializeToLson([id, crdt], parentToChildren, pool);
1643
- if (isLiveStructure(child)) {
1644
- child._setParentLink(liveObj, crdt.parentKey);
1645
- }
1646
- liveObj._map.set(crdt.parentKey, child);
1647
- liveObj.invalidate();
1744
+ case 1 /* LIST */: {
1745
+ return LiveList._deserialize([id, crdt], parentToChildren, pool);
1648
1746
  }
1649
- return liveObj;
1650
- }
1651
- _attach(id, pool) {
1652
- super._attach(id, pool);
1653
- for (const [_key, value] of this._map) {
1654
- if (isLiveNode(value)) {
1655
- value._attach(pool.generateId(), pool);
1656
- }
1747
+ case 2 /* MAP */: {
1748
+ return LiveMap._deserialize([id, crdt], parentToChildren, pool);
1657
1749
  }
1658
- }
1659
- _attachChild(op, source) {
1660
- if (this._pool === void 0) {
1661
- throw new Error("Can't attach child if managed pool is not present");
1750
+ case 3 /* REGISTER */: {
1751
+ return LiveRegister._deserialize([id, crdt], parentToChildren, pool);
1662
1752
  }
1663
- const { id, opId, parentKey: key } = op;
1664
- const child = creationOpToLson(op);
1665
- if (this._pool.getNode(id) !== void 0) {
1666
- if (this._propToLastUpdate.get(key) === opId) {
1667
- this._propToLastUpdate.delete(key);
1668
- }
1669
- return { modified: false };
1753
+ default: {
1754
+ throw new Error("Unexpected CRDT type");
1670
1755
  }
1671
- if (source === 0 /* UNDOREDO_RECONNECT */) {
1672
- this._propToLastUpdate.set(key, nn(opId));
1673
- } else if (this._propToLastUpdate.get(key) === void 0) {
1674
- } else if (this._propToLastUpdate.get(key) === opId) {
1675
- this._propToLastUpdate.delete(key);
1676
- return { modified: false };
1677
- } else {
1678
- return { modified: false };
1756
+ }
1757
+ }
1758
+ function deserializeToLson([id, crdt], parentToChildren, pool) {
1759
+ switch (crdt.type) {
1760
+ case 0 /* OBJECT */: {
1761
+ return LiveObject._deserialize([id, crdt], parentToChildren, pool);
1679
1762
  }
1680
- const thisId = nn(this._id);
1681
- const previousValue = this._map.get(key);
1682
- let reverse;
1683
- if (isLiveNode(previousValue)) {
1684
- reverse = previousValue._toOps(thisId, key);
1685
- previousValue._detach();
1686
- } else if (previousValue === void 0) {
1687
- reverse = [{ type: 6 /* DELETE_OBJECT_KEY */, id: thisId, key }];
1688
- } else {
1689
- reverse = [
1690
- {
1691
- type: 3 /* UPDATE_OBJECT */,
1692
- id: thisId,
1693
- data: { [key]: previousValue }
1694
- }
1695
- ];
1763
+ case 1 /* LIST */: {
1764
+ return LiveList._deserialize([id, crdt], parentToChildren, pool);
1696
1765
  }
1697
- this._map.set(key, child);
1698
- this.invalidate();
1699
- if (isLiveStructure(child)) {
1700
- child._setParentLink(this, key);
1701
- child._attach(id, this._pool);
1766
+ case 2 /* MAP */: {
1767
+ return LiveMap._deserialize([id, crdt], parentToChildren, pool);
1702
1768
  }
1703
- return {
1704
- reverse,
1705
- modified: {
1706
- node: this,
1707
- type: "LiveObject",
1708
- updates: { [key]: { type: "update" } }
1709
- }
1710
- };
1711
- }
1712
- _detachChild(child) {
1713
- if (child) {
1714
- const id = nn(this._id);
1715
- const parentKey = nn(child._parentKey);
1716
- const reverse = child._toOps(id, parentKey, this._pool);
1717
- for (const [key, value] of this._map) {
1718
- if (value === child) {
1719
- this._map.delete(key);
1720
- this.invalidate();
1721
- }
1722
- }
1723
- child._detach();
1724
- const storageUpdate = {
1725
- node: this,
1726
- type: "LiveObject",
1727
- updates: {
1728
- [parentKey]: { type: "delete" }
1729
- }
1730
- };
1731
- return { modified: storageUpdate, reverse };
1769
+ case 3 /* REGISTER */: {
1770
+ return crdt.data;
1771
+ }
1772
+ default: {
1773
+ throw new Error("Unexpected CRDT type");
1732
1774
  }
1733
- return { modified: false };
1734
1775
  }
1735
- _detach() {
1736
- super._detach();
1737
- for (const value of this._map.values()) {
1738
- if (isLiveNode(value)) {
1739
- value._detach();
1740
- }
1741
- }
1776
+ }
1777
+ function isLiveStructure(value) {
1778
+ return isLiveList(value) || isLiveMap(value) || isLiveObject(value);
1779
+ }
1780
+ function isLiveNode(value) {
1781
+ return isLiveStructure(value) || isLiveRegister(value);
1782
+ }
1783
+ function isLiveList(value) {
1784
+ return value instanceof LiveList;
1785
+ }
1786
+ function isLiveMap(value) {
1787
+ return value instanceof LiveMap;
1788
+ }
1789
+ function isLiveObject(value) {
1790
+ return value instanceof LiveObject;
1791
+ }
1792
+ function isLiveRegister(value) {
1793
+ return value instanceof LiveRegister;
1794
+ }
1795
+ function liveNodeToLson(obj) {
1796
+ if (obj instanceof LiveRegister) {
1797
+ return obj.data;
1798
+ } else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject) {
1799
+ return obj;
1800
+ } else {
1801
+ return assertNever(obj, "Unknown AbstractCrdt");
1742
1802
  }
1743
- _apply(op, isLocal) {
1744
- if (op.type === 3 /* UPDATE_OBJECT */) {
1745
- return this._applyUpdate(op, isLocal);
1746
- } else if (op.type === 6 /* DELETE_OBJECT_KEY */) {
1747
- return this._applyDeleteObjectKey(op);
1748
- }
1749
- return super._apply(op, isLocal);
1803
+ }
1804
+ function lsonToLiveNode(value) {
1805
+ if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList) {
1806
+ return value;
1807
+ } else {
1808
+ return new LiveRegister(value);
1750
1809
  }
1751
- _serialize() {
1752
- const data = {};
1753
- for (const [key, value] of this._map) {
1754
- if (!isLiveNode(value)) {
1755
- data[key] = value;
1756
- }
1810
+ }
1811
+ function getTreesDiffOperations(currentItems, newItems) {
1812
+ const ops = [];
1813
+ currentItems.forEach((_, id) => {
1814
+ if (!newItems.get(id)) {
1815
+ ops.push({
1816
+ type: 5 /* DELETE_CRDT */,
1817
+ id
1818
+ });
1757
1819
  }
1758
- if (this.parent.type === "HasParent" && this.parent.node._id) {
1759
- return {
1760
- type: 0 /* OBJECT */,
1761
- parentId: this.parent.node._id,
1762
- parentKey: this.parent.key,
1763
- data
1764
- };
1820
+ });
1821
+ newItems.forEach((crdt, id) => {
1822
+ const currentCrdt = currentItems.get(id);
1823
+ if (currentCrdt) {
1824
+ if (crdt.type === 0 /* OBJECT */) {
1825
+ if (currentCrdt.type !== 0 /* OBJECT */ || JSON.stringify(crdt.data) !== JSON.stringify(currentCrdt.data)) {
1826
+ ops.push({
1827
+ type: 3 /* UPDATE_OBJECT */,
1828
+ id,
1829
+ data: crdt.data
1830
+ });
1831
+ }
1832
+ }
1833
+ if (crdt.parentKey !== currentCrdt.parentKey) {
1834
+ ops.push({
1835
+ type: 1 /* SET_PARENT_KEY */,
1836
+ id,
1837
+ parentKey: nn(crdt.parentKey, "Parent key must not be missing")
1838
+ });
1839
+ }
1765
1840
  } else {
1766
- return {
1767
- type: 0 /* OBJECT */,
1768
- data
1769
- };
1841
+ switch (crdt.type) {
1842
+ case 3 /* REGISTER */:
1843
+ ops.push({
1844
+ type: 8 /* CREATE_REGISTER */,
1845
+ id,
1846
+ parentId: crdt.parentId,
1847
+ parentKey: crdt.parentKey,
1848
+ data: crdt.data
1849
+ });
1850
+ break;
1851
+ case 1 /* LIST */:
1852
+ ops.push({
1853
+ type: 2 /* CREATE_LIST */,
1854
+ id,
1855
+ parentId: crdt.parentId,
1856
+ parentKey: crdt.parentKey
1857
+ });
1858
+ break;
1859
+ case 0 /* OBJECT */:
1860
+ ops.push(
1861
+ crdt.parentId ? {
1862
+ type: 4 /* CREATE_OBJECT */,
1863
+ id,
1864
+ parentId: crdt.parentId,
1865
+ parentKey: crdt.parentKey,
1866
+ data: crdt.data
1867
+ } : { type: 4 /* CREATE_OBJECT */, id, data: crdt.data }
1868
+ );
1869
+ break;
1870
+ case 2 /* MAP */:
1871
+ ops.push({
1872
+ type: 7 /* CREATE_MAP */,
1873
+ id,
1874
+ parentId: crdt.parentId,
1875
+ parentKey: crdt.parentKey
1876
+ });
1877
+ break;
1878
+ }
1770
1879
  }
1880
+ });
1881
+ return ops;
1882
+ }
1883
+ function mergeObjectStorageUpdates(first, second) {
1884
+ const updates = first.updates;
1885
+ for (const [key, value] of entries(second.updates)) {
1886
+ updates[key] = value;
1771
1887
  }
1772
- _applyUpdate(op, isLocal) {
1773
- let isModified = false;
1774
- const id = nn(this._id);
1775
- const reverse = [];
1776
- const reverseUpdate = {
1777
- type: 3 /* UPDATE_OBJECT */,
1778
- id,
1779
- data: {}
1888
+ return __spreadProps(__spreadValues({}, second), {
1889
+ updates
1890
+ });
1891
+ }
1892
+ function mergeMapStorageUpdates(first, second) {
1893
+ const updates = first.updates;
1894
+ for (const [key, value] of entries(second.updates)) {
1895
+ updates[key] = value;
1896
+ }
1897
+ return __spreadProps(__spreadValues({}, second), {
1898
+ updates
1899
+ });
1900
+ }
1901
+ function mergeListStorageUpdates(first, second) {
1902
+ const updates = first.updates;
1903
+ return __spreadProps(__spreadValues({}, second), {
1904
+ updates: updates.concat(second.updates)
1905
+ });
1906
+ }
1907
+ function mergeStorageUpdates(first, second) {
1908
+ if (!first) {
1909
+ return second;
1910
+ }
1911
+ if (first.type === "LiveObject" && second.type === "LiveObject") {
1912
+ return mergeObjectStorageUpdates(first, second);
1913
+ } else if (first.type === "LiveMap" && second.type === "LiveMap") {
1914
+ return mergeMapStorageUpdates(first, second);
1915
+ } else if (first.type === "LiveList" && second.type === "LiveList") {
1916
+ return mergeListStorageUpdates(first, second);
1917
+ } else {
1918
+ }
1919
+ return second;
1920
+ }
1921
+ function isPlain(value) {
1922
+ const type = typeof value;
1923
+ return value === void 0 || value === null || type === "string" || type === "boolean" || type === "number" || Array.isArray(value) || isPlainObject(value);
1924
+ }
1925
+ function findNonSerializableValue(value, path = "") {
1926
+ if (!isPlain) {
1927
+ return {
1928
+ path: path || "root",
1929
+ value
1780
1930
  };
1781
- reverse.push(reverseUpdate);
1782
- for (const key in op.data) {
1783
- const oldValue = this._map.get(key);
1784
- if (isLiveNode(oldValue)) {
1785
- reverse.push(...oldValue._toOps(id, key));
1786
- oldValue._detach();
1787
- } else if (oldValue !== void 0) {
1788
- reverseUpdate.data[key] = oldValue;
1789
- } else if (oldValue === void 0) {
1790
- reverse.push({ type: 6 /* DELETE_OBJECT_KEY */, id, key });
1931
+ }
1932
+ if (typeof value !== "object" || value === null) {
1933
+ return false;
1934
+ }
1935
+ for (const [key, nestedValue] of Object.entries(value)) {
1936
+ const nestedPath = path ? path + "." + key : key;
1937
+ if (!isPlain(nestedValue)) {
1938
+ return {
1939
+ path: nestedPath,
1940
+ value: nestedValue
1941
+ };
1942
+ }
1943
+ if (typeof nestedValue === "object") {
1944
+ const nonSerializableNestedValue = findNonSerializableValue(
1945
+ nestedValue,
1946
+ nestedPath
1947
+ );
1948
+ if (nonSerializableNestedValue) {
1949
+ return nonSerializableNestedValue;
1791
1950
  }
1792
1951
  }
1793
- const updateDelta = {};
1794
- for (const key in op.data) {
1795
- const value = op.data[key];
1952
+ }
1953
+ return false;
1954
+ }
1955
+
1956
+ // src/crdts/LiveObject.ts
1957
+ var LiveObject = class extends AbstractCrdt {
1958
+ constructor(obj = {}) {
1959
+ super();
1960
+ this._propToLastUpdate = /* @__PURE__ */ new Map();
1961
+ for (const key in obj) {
1962
+ const value = obj[key];
1796
1963
  if (value === void 0) {
1797
1964
  continue;
1965
+ } else if (isLiveNode(value)) {
1966
+ value._setParentLink(this, key);
1798
1967
  }
1799
- if (isLocal) {
1800
- this._propToLastUpdate.set(key, nn(op.opId));
1801
- } else if (this._propToLastUpdate.get(key) === void 0) {
1802
- isModified = true;
1803
- } else if (this._propToLastUpdate.get(key) === op.opId) {
1804
- this._propToLastUpdate.delete(key);
1805
- continue;
1806
- } else {
1807
- continue;
1808
- }
1809
- const oldValue = this._map.get(key);
1810
- if (isLiveNode(oldValue)) {
1811
- oldValue._detach();
1812
- }
1813
- isModified = true;
1814
- updateDelta[key] = { type: "update" };
1815
- this._map.set(key, value);
1816
- this.invalidate();
1817
1968
  }
1818
- if (Object.keys(reverseUpdate.data).length !== 0) {
1819
- reverse.unshift(reverseUpdate);
1969
+ this._map = new Map(Object.entries(obj));
1970
+ }
1971
+ _toOps(parentId, parentKey, pool) {
1972
+ if (this._id === void 0) {
1973
+ throw new Error("Cannot serialize item is not attached");
1820
1974
  }
1821
- return isModified ? {
1822
- modified: {
1823
- node: this,
1824
- type: "LiveObject",
1975
+ const opId = pool == null ? void 0 : pool.generateOpId();
1976
+ const ops = [];
1977
+ const op = parentId !== void 0 && parentKey !== void 0 ? {
1978
+ type: 4 /* CREATE_OBJECT */,
1979
+ id: this._id,
1980
+ opId,
1981
+ parentId,
1982
+ parentKey,
1983
+ data: {}
1984
+ } : { type: 4 /* CREATE_OBJECT */, id: this._id, opId, data: {} };
1985
+ ops.push(op);
1986
+ for (const [key, value] of this._map) {
1987
+ if (isLiveNode(value)) {
1988
+ ops.push(...value._toOps(this._id, key, pool));
1989
+ } else {
1990
+ op.data[key] = value;
1991
+ }
1992
+ }
1993
+ return ops;
1994
+ }
1995
+ static _deserialize([id, item], parentToChildren, pool) {
1996
+ const liveObj = new LiveObject(item.data);
1997
+ liveObj._attach(id, pool);
1998
+ return this._deserializeChildren(liveObj, parentToChildren, pool);
1999
+ }
2000
+ static _deserializeChildren(liveObj, parentToChildren, pool) {
2001
+ const children = parentToChildren.get(nn(liveObj._id));
2002
+ if (children === void 0) {
2003
+ return liveObj;
2004
+ }
2005
+ for (const [id, crdt] of children) {
2006
+ const child = deserializeToLson([id, crdt], parentToChildren, pool);
2007
+ if (isLiveStructure(child)) {
2008
+ child._setParentLink(liveObj, crdt.parentKey);
2009
+ }
2010
+ liveObj._map.set(crdt.parentKey, child);
2011
+ liveObj.invalidate();
2012
+ }
2013
+ return liveObj;
2014
+ }
2015
+ _attach(id, pool) {
2016
+ super._attach(id, pool);
2017
+ for (const [_key, value] of this._map) {
2018
+ if (isLiveNode(value)) {
2019
+ value._attach(pool.generateId(), pool);
2020
+ }
2021
+ }
2022
+ }
2023
+ _attachChild(op, source) {
2024
+ if (this._pool === void 0) {
2025
+ throw new Error("Can't attach child if managed pool is not present");
2026
+ }
2027
+ const { id, opId, parentKey: key } = op;
2028
+ const child = creationOpToLson(op);
2029
+ if (this._pool.getNode(id) !== void 0) {
2030
+ if (this._propToLastUpdate.get(key) === opId) {
2031
+ this._propToLastUpdate.delete(key);
2032
+ }
2033
+ return { modified: false };
2034
+ }
2035
+ if (source === 0 /* UNDOREDO_RECONNECT */) {
2036
+ this._propToLastUpdate.set(key, nn(opId));
2037
+ } else if (this._propToLastUpdate.get(key) === void 0) {
2038
+ } else if (this._propToLastUpdate.get(key) === opId) {
2039
+ this._propToLastUpdate.delete(key);
2040
+ return { modified: false };
2041
+ } else {
2042
+ return { modified: false };
2043
+ }
2044
+ const thisId = nn(this._id);
2045
+ const previousValue = this._map.get(key);
2046
+ let reverse;
2047
+ if (isLiveNode(previousValue)) {
2048
+ reverse = previousValue._toOps(thisId, key);
2049
+ previousValue._detach();
2050
+ } else if (previousValue === void 0) {
2051
+ reverse = [{ type: 6 /* DELETE_OBJECT_KEY */, id: thisId, key }];
2052
+ } else {
2053
+ reverse = [
2054
+ {
2055
+ type: 3 /* UPDATE_OBJECT */,
2056
+ id: thisId,
2057
+ data: { [key]: previousValue }
2058
+ }
2059
+ ];
2060
+ }
2061
+ this._map.set(key, child);
2062
+ this.invalidate();
2063
+ if (isLiveStructure(child)) {
2064
+ child._setParentLink(this, key);
2065
+ child._attach(id, this._pool);
2066
+ }
2067
+ return {
2068
+ reverse,
2069
+ modified: {
2070
+ node: this,
2071
+ type: "LiveObject",
2072
+ updates: { [key]: { type: "update" } }
2073
+ }
2074
+ };
2075
+ }
2076
+ _detachChild(child) {
2077
+ if (child) {
2078
+ const id = nn(this._id);
2079
+ const parentKey = nn(child._parentKey);
2080
+ const reverse = child._toOps(id, parentKey, this._pool);
2081
+ for (const [key, value] of this._map) {
2082
+ if (value === child) {
2083
+ this._map.delete(key);
2084
+ this.invalidate();
2085
+ }
2086
+ }
2087
+ child._detach();
2088
+ const storageUpdate = {
2089
+ node: this,
2090
+ type: "LiveObject",
2091
+ updates: {
2092
+ [parentKey]: { type: "delete" }
2093
+ }
2094
+ };
2095
+ return { modified: storageUpdate, reverse };
2096
+ }
2097
+ return { modified: false };
2098
+ }
2099
+ _detach() {
2100
+ super._detach();
2101
+ for (const value of this._map.values()) {
2102
+ if (isLiveNode(value)) {
2103
+ value._detach();
2104
+ }
2105
+ }
2106
+ }
2107
+ _apply(op, isLocal) {
2108
+ if (op.type === 3 /* UPDATE_OBJECT */) {
2109
+ return this._applyUpdate(op, isLocal);
2110
+ } else if (op.type === 6 /* DELETE_OBJECT_KEY */) {
2111
+ return this._applyDeleteObjectKey(op);
2112
+ }
2113
+ return super._apply(op, isLocal);
2114
+ }
2115
+ _serialize() {
2116
+ const data = {};
2117
+ for (const [key, value] of this._map) {
2118
+ if (!isLiveNode(value)) {
2119
+ data[key] = value;
2120
+ }
2121
+ }
2122
+ if (this.parent.type === "HasParent" && this.parent.node._id) {
2123
+ return {
2124
+ type: 0 /* OBJECT */,
2125
+ parentId: this.parent.node._id,
2126
+ parentKey: this.parent.key,
2127
+ data
2128
+ };
2129
+ } else {
2130
+ return {
2131
+ type: 0 /* OBJECT */,
2132
+ data
2133
+ };
2134
+ }
2135
+ }
2136
+ _applyUpdate(op, isLocal) {
2137
+ let isModified = false;
2138
+ const id = nn(this._id);
2139
+ const reverse = [];
2140
+ const reverseUpdate = {
2141
+ type: 3 /* UPDATE_OBJECT */,
2142
+ id,
2143
+ data: {}
2144
+ };
2145
+ reverse.push(reverseUpdate);
2146
+ for (const key in op.data) {
2147
+ const oldValue = this._map.get(key);
2148
+ if (isLiveNode(oldValue)) {
2149
+ reverse.push(...oldValue._toOps(id, key));
2150
+ oldValue._detach();
2151
+ } else if (oldValue !== void 0) {
2152
+ reverseUpdate.data[key] = oldValue;
2153
+ } else if (oldValue === void 0) {
2154
+ reverse.push({ type: 6 /* DELETE_OBJECT_KEY */, id, key });
2155
+ }
2156
+ }
2157
+ const updateDelta = {};
2158
+ for (const key in op.data) {
2159
+ const value = op.data[key];
2160
+ if (value === void 0) {
2161
+ continue;
2162
+ }
2163
+ if (isLocal) {
2164
+ this._propToLastUpdate.set(key, nn(op.opId));
2165
+ } else if (this._propToLastUpdate.get(key) === void 0) {
2166
+ isModified = true;
2167
+ } else if (this._propToLastUpdate.get(key) === op.opId) {
2168
+ this._propToLastUpdate.delete(key);
2169
+ continue;
2170
+ } else {
2171
+ continue;
2172
+ }
2173
+ const oldValue = this._map.get(key);
2174
+ if (isLiveNode(oldValue)) {
2175
+ oldValue._detach();
2176
+ }
2177
+ isModified = true;
2178
+ updateDelta[key] = { type: "update" };
2179
+ this._map.set(key, value);
2180
+ this.invalidate();
2181
+ }
2182
+ if (Object.keys(reverseUpdate.data).length !== 0) {
2183
+ reverse.unshift(reverseUpdate);
2184
+ }
2185
+ return isModified ? {
2186
+ modified: {
2187
+ node: this,
2188
+ type: "LiveObject",
1825
2189
  updates: updateDelta
1826
2190
  },
1827
2191
  reverse
@@ -1867,554 +2231,157 @@ var LiveObject = class extends AbstractCrdt {
1867
2231
  set(key, value) {
1868
2232
  var _a;
1869
2233
  (_a = this._pool) == null ? void 0 : _a.assertStorageIsWritable();
1870
- this.update({ [key]: value });
1871
- }
1872
- get(key) {
1873
- return this._map.get(key);
1874
- }
1875
- delete(key) {
1876
- var _a;
1877
- (_a = this._pool) == null ? void 0 : _a.assertStorageIsWritable();
1878
- const keyAsString = key;
1879
- const oldValue = this._map.get(keyAsString);
1880
- if (oldValue === void 0) {
1881
- return;
1882
- }
1883
- if (this._pool === void 0 || this._id === void 0) {
1884
- if (isLiveNode(oldValue)) {
1885
- oldValue._detach();
1886
- }
1887
- this._map.delete(keyAsString);
1888
- this.invalidate();
1889
- return;
1890
- }
1891
- let reverse;
1892
- if (isLiveNode(oldValue)) {
1893
- oldValue._detach();
1894
- reverse = oldValue._toOps(this._id, keyAsString);
1895
- } else {
1896
- reverse = [
1897
- {
1898
- type: 3 /* UPDATE_OBJECT */,
1899
- data: { [keyAsString]: oldValue },
1900
- id: this._id
1901
- }
1902
- ];
1903
- }
1904
- this._map.delete(keyAsString);
1905
- this.invalidate();
1906
- const storageUpdates = /* @__PURE__ */ new Map();
1907
- storageUpdates.set(this._id, {
1908
- node: this,
1909
- type: "LiveObject",
1910
- updates: { [key]: { type: "delete" } }
1911
- });
1912
- this._pool.dispatch(
1913
- [
1914
- {
1915
- type: 6 /* DELETE_OBJECT_KEY */,
1916
- key: keyAsString,
1917
- id: this._id,
1918
- opId: this._pool.generateOpId()
1919
- }
1920
- ],
1921
- reverse,
1922
- storageUpdates
1923
- );
1924
- }
1925
- update(patch) {
1926
- var _a;
1927
- (_a = this._pool) == null ? void 0 : _a.assertStorageIsWritable();
1928
- if (this._pool === void 0 || this._id === void 0) {
1929
- for (const key in patch) {
1930
- const newValue = patch[key];
1931
- if (newValue === void 0) {
1932
- continue;
1933
- }
1934
- const oldValue = this._map.get(key);
1935
- if (isLiveNode(oldValue)) {
1936
- oldValue._detach();
1937
- }
1938
- if (isLiveNode(newValue)) {
1939
- newValue._setParentLink(this, key);
1940
- }
1941
- this._map.set(key, newValue);
1942
- this.invalidate();
1943
- }
1944
- return;
1945
- }
1946
- const ops = [];
1947
- const reverseOps = [];
1948
- const opId = this._pool.generateOpId();
1949
- const updatedProps = {};
1950
- const reverseUpdateOp = {
1951
- id: this._id,
1952
- type: 3 /* UPDATE_OBJECT */,
1953
- data: {}
1954
- };
1955
- const updateDelta = {};
1956
- for (const key in patch) {
1957
- const newValue = patch[key];
1958
- if (newValue === void 0) {
1959
- continue;
1960
- }
1961
- const oldValue = this._map.get(key);
1962
- if (isLiveNode(oldValue)) {
1963
- reverseOps.push(...oldValue._toOps(this._id, key));
1964
- oldValue._detach();
1965
- } else if (oldValue === void 0) {
1966
- reverseOps.push({ type: 6 /* DELETE_OBJECT_KEY */, id: this._id, key });
1967
- } else {
1968
- reverseUpdateOp.data[key] = oldValue;
1969
- }
1970
- if (isLiveNode(newValue)) {
1971
- newValue._setParentLink(this, key);
1972
- newValue._attach(this._pool.generateId(), this._pool);
1973
- const newAttachChildOps = newValue._toOps(this._id, key, this._pool);
1974
- const createCrdtOp = newAttachChildOps.find(
1975
- (op) => op.parentId === this._id
1976
- );
1977
- if (createCrdtOp) {
1978
- this._propToLastUpdate.set(key, nn(createCrdtOp.opId));
1979
- }
1980
- ops.push(...newAttachChildOps);
1981
- } else {
1982
- updatedProps[key] = newValue;
1983
- this._propToLastUpdate.set(key, opId);
1984
- }
1985
- this._map.set(key, newValue);
1986
- this.invalidate();
1987
- updateDelta[key] = { type: "update" };
1988
- }
1989
- if (Object.keys(reverseUpdateOp.data).length !== 0) {
1990
- reverseOps.unshift(reverseUpdateOp);
1991
- }
1992
- if (Object.keys(updatedProps).length !== 0) {
1993
- ops.unshift({
1994
- opId,
1995
- id: this._id,
1996
- type: 3 /* UPDATE_OBJECT */,
1997
- data: updatedProps
1998
- });
1999
- }
2000
- const storageUpdates = /* @__PURE__ */ new Map();
2001
- storageUpdates.set(this._id, {
2002
- node: this,
2003
- type: "LiveObject",
2004
- updates: updateDelta
2005
- });
2006
- this._pool.dispatch(ops, reverseOps, storageUpdates);
2007
- }
2008
- toImmutable() {
2009
- return super.toImmutable();
2010
- }
2011
- _toImmutable() {
2012
- const result = {};
2013
- for (const [key, val] of this._map) {
2014
- result[key] = isLiveStructure(val) ? val.toImmutable() : val;
2015
- }
2016
- return process.env.NODE_ENV === "production" ? result : Object.freeze(result);
2017
- }
2018
- };
2019
-
2020
- // src/utils.ts
2021
- var freeze = process.env.NODE_ENV === "production" ? (x) => x : Object.freeze;
2022
- function compact(items) {
2023
- return items.filter(
2024
- (item) => item !== null && item !== void 0
2025
- );
2026
- }
2027
- function compactObject(obj) {
2028
- const newObj = __spreadValues({}, obj);
2029
- Object.keys(obj).forEach((k) => {
2030
- const key = k;
2031
- if (newObj[key] === void 0) {
2032
- delete newObj[key];
2033
- }
2034
- });
2035
- return newObj;
2036
- }
2037
- function creationOpToLiveNode(op) {
2038
- return lsonToLiveNode(creationOpToLson(op));
2039
- }
2040
- function creationOpToLson(op) {
2041
- switch (op.type) {
2042
- case 8 /* CREATE_REGISTER */:
2043
- return op.data;
2044
- case 4 /* CREATE_OBJECT */:
2045
- return new LiveObject(op.data);
2046
- case 7 /* CREATE_MAP */:
2047
- return new LiveMap();
2048
- case 2 /* CREATE_LIST */:
2049
- return new LiveList();
2050
- default:
2051
- return assertNever(op, "Unknown creation Op");
2052
- }
2053
- }
2054
- function isSameNodeOrChildOf(node, parent) {
2055
- if (node === parent) {
2056
- return true;
2057
- }
2058
- if (node.parent.type === "HasParent") {
2059
- return isSameNodeOrChildOf(node.parent.node, parent);
2060
- }
2061
- return false;
2062
- }
2063
- function deserialize([id, crdt], parentToChildren, pool) {
2064
- switch (crdt.type) {
2065
- case 0 /* OBJECT */: {
2066
- return LiveObject._deserialize([id, crdt], parentToChildren, pool);
2067
- }
2068
- case 1 /* LIST */: {
2069
- return LiveList._deserialize([id, crdt], parentToChildren, pool);
2070
- }
2071
- case 2 /* MAP */: {
2072
- return LiveMap._deserialize([id, crdt], parentToChildren, pool);
2073
- }
2074
- case 3 /* REGISTER */: {
2075
- return LiveRegister._deserialize([id, crdt], parentToChildren, pool);
2076
- }
2077
- default: {
2078
- throw new Error("Unexpected CRDT type");
2079
- }
2080
- }
2081
- }
2082
- function deserializeToLson([id, crdt], parentToChildren, pool) {
2083
- switch (crdt.type) {
2084
- case 0 /* OBJECT */: {
2085
- return LiveObject._deserialize([id, crdt], parentToChildren, pool);
2086
- }
2087
- case 1 /* LIST */: {
2088
- return LiveList._deserialize([id, crdt], parentToChildren, pool);
2089
- }
2090
- case 2 /* MAP */: {
2091
- return LiveMap._deserialize([id, crdt], parentToChildren, pool);
2092
- }
2093
- case 3 /* REGISTER */: {
2094
- return crdt.data;
2095
- }
2096
- default: {
2097
- throw new Error("Unexpected CRDT type");
2098
- }
2099
- }
2100
- }
2101
- function isLiveStructure(value) {
2102
- return isLiveList(value) || isLiveMap(value) || isLiveObject(value);
2103
- }
2104
- function isLiveNode(value) {
2105
- return isLiveStructure(value) || isLiveRegister(value);
2106
- }
2107
- function isLiveList(value) {
2108
- return value instanceof LiveList;
2109
- }
2110
- function isLiveMap(value) {
2111
- return value instanceof LiveMap;
2112
- }
2113
- function isLiveObject(value) {
2114
- return value instanceof LiveObject;
2115
- }
2116
- function isLiveRegister(value) {
2117
- return value instanceof LiveRegister;
2118
- }
2119
- function liveNodeToLson(obj) {
2120
- if (obj instanceof LiveRegister) {
2121
- return obj.data;
2122
- } else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject) {
2123
- return obj;
2124
- } else {
2125
- return assertNever(obj, "Unknown AbstractCrdt");
2126
- }
2127
- }
2128
- function lsonToLiveNode(value) {
2129
- if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList) {
2130
- return value;
2131
- } else {
2132
- return new LiveRegister(value);
2133
- }
2134
- }
2135
- function getTreesDiffOperations(currentItems, newItems) {
2136
- const ops = [];
2137
- currentItems.forEach((_, id) => {
2138
- if (!newItems.get(id)) {
2139
- ops.push({
2140
- type: 5 /* DELETE_CRDT */,
2141
- id
2142
- });
2143
- }
2144
- });
2145
- newItems.forEach((crdt, id) => {
2146
- const currentCrdt = currentItems.get(id);
2147
- if (currentCrdt) {
2148
- if (crdt.type === 0 /* OBJECT */) {
2149
- if (currentCrdt.type !== 0 /* OBJECT */ || JSON.stringify(crdt.data) !== JSON.stringify(currentCrdt.data)) {
2150
- ops.push({
2151
- type: 3 /* UPDATE_OBJECT */,
2152
- id,
2153
- data: crdt.data
2154
- });
2155
- }
2156
- }
2157
- if (crdt.parentKey !== currentCrdt.parentKey) {
2158
- ops.push({
2159
- type: 1 /* SET_PARENT_KEY */,
2160
- id,
2161
- parentKey: nn(crdt.parentKey, "Parent key must not be missing")
2162
- });
2163
- }
2164
- } else {
2165
- switch (crdt.type) {
2166
- case 3 /* REGISTER */:
2167
- ops.push({
2168
- type: 8 /* CREATE_REGISTER */,
2169
- id,
2170
- parentId: crdt.parentId,
2171
- parentKey: crdt.parentKey,
2172
- data: crdt.data
2173
- });
2174
- break;
2175
- case 1 /* LIST */:
2176
- ops.push({
2177
- type: 2 /* CREATE_LIST */,
2178
- id,
2179
- parentId: crdt.parentId,
2180
- parentKey: crdt.parentKey
2181
- });
2182
- break;
2183
- case 0 /* OBJECT */:
2184
- ops.push(
2185
- crdt.parentId ? {
2186
- type: 4 /* CREATE_OBJECT */,
2187
- id,
2188
- parentId: crdt.parentId,
2189
- parentKey: crdt.parentKey,
2190
- data: crdt.data
2191
- } : { type: 4 /* CREATE_OBJECT */, id, data: crdt.data }
2192
- );
2193
- break;
2194
- case 2 /* MAP */:
2195
- ops.push({
2196
- type: 7 /* CREATE_MAP */,
2197
- id,
2198
- parentId: crdt.parentId,
2199
- parentKey: crdt.parentKey
2200
- });
2201
- break;
2202
- }
2203
- }
2204
- });
2205
- return ops;
2206
- }
2207
- function mergeObjectStorageUpdates(first, second) {
2208
- const updates = first.updates;
2209
- for (const [key, value] of entries(second.updates)) {
2210
- updates[key] = value;
2211
- }
2212
- return __spreadProps(__spreadValues({}, second), {
2213
- updates
2214
- });
2215
- }
2216
- function mergeMapStorageUpdates(first, second) {
2217
- const updates = first.updates;
2218
- for (const [key, value] of entries(second.updates)) {
2219
- updates[key] = value;
2220
- }
2221
- return __spreadProps(__spreadValues({}, second), {
2222
- updates
2223
- });
2224
- }
2225
- function mergeListStorageUpdates(first, second) {
2226
- const updates = first.updates;
2227
- return __spreadProps(__spreadValues({}, second), {
2228
- updates: updates.concat(second.updates)
2229
- });
2230
- }
2231
- function mergeStorageUpdates(first, second) {
2232
- if (!first) {
2233
- return second;
2234
- }
2235
- if (first.type === "LiveObject" && second.type === "LiveObject") {
2236
- return mergeObjectStorageUpdates(first, second);
2237
- } else if (first.type === "LiveMap" && second.type === "LiveMap") {
2238
- return mergeMapStorageUpdates(first, second);
2239
- } else if (first.type === "LiveList" && second.type === "LiveList") {
2240
- return mergeListStorageUpdates(first, second);
2241
- } else {
2242
- }
2243
- return second;
2244
- }
2245
- function isPlain(value) {
2246
- const type = typeof value;
2247
- return value === void 0 || value === null || type === "string" || type === "boolean" || type === "number" || Array.isArray(value) || isPlainObject(value);
2248
- }
2249
- function isPlainObject(blob) {
2250
- return blob !== null && typeof blob === "object" && Object.prototype.toString.call(blob) === "[object Object]";
2251
- }
2252
- function findNonSerializableValue(value, path = "") {
2253
- if (!isPlain) {
2254
- return {
2255
- path: path || "root",
2256
- value
2257
- };
2258
- }
2259
- if (typeof value !== "object" || value === null) {
2260
- return false;
2261
- }
2262
- for (const [key, nestedValue] of Object.entries(value)) {
2263
- const nestedPath = path ? path + "." + key : key;
2264
- if (!isPlain(nestedValue)) {
2265
- return {
2266
- path: nestedPath,
2267
- value: nestedValue
2268
- };
2269
- }
2270
- if (typeof nestedValue === "object") {
2271
- const nonSerializableNestedValue = findNonSerializableValue(
2272
- nestedValue,
2273
- nestedPath
2274
- );
2275
- if (nonSerializableNestedValue) {
2276
- return nonSerializableNestedValue;
2277
- }
2278
- }
2279
- }
2280
- return false;
2281
- }
2282
- function fromEntries(iterable) {
2283
- const obj = {};
2284
- for (const [key, val] of iterable) {
2285
- obj[key] = val;
2286
- }
2287
- return obj;
2288
- }
2289
- function entries(obj) {
2290
- return Object.entries(obj);
2291
- }
2292
- function tryParseJson(rawMessage) {
2293
- try {
2294
- return JSON.parse(rawMessage);
2295
- } catch (e) {
2296
- return void 0;
2297
- }
2298
- }
2299
- function b64decode(b64value) {
2300
- try {
2301
- const formattedValue = b64value.replace(/-/g, "+").replace(/_/g, "/");
2302
- const decodedValue = decodeURIComponent(
2303
- atob(formattedValue).split("").map(function(c) {
2304
- return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
2305
- }).join("")
2306
- );
2307
- return decodedValue;
2308
- } catch (err) {
2309
- return atob(b64value);
2310
- }
2311
- }
2312
-
2313
- // src/AuthToken.ts
2314
- function hasJwtMeta(data) {
2315
- if (!isPlainObject(data)) {
2316
- return false;
2317
- }
2318
- const { iat, exp } = data;
2319
- return typeof iat === "number" && typeof exp === "number";
2320
- }
2321
- function isTokenExpired(token) {
2322
- const now = Date.now() / 1e3;
2323
- return now > token.exp - 300 || now < token.iat + 300;
2324
- }
2325
- function isStringList(value) {
2326
- return Array.isArray(value) && value.every((i) => typeof i === "string");
2327
- }
2328
- function isAppOnlyAuthToken(data) {
2329
- return typeof data.appId === "string" && data.roomId === void 0 && isStringList(data.scopes);
2330
- }
2331
- function isRoomAuthToken(data) {
2332
- return typeof data.appId === "string" && typeof data.roomId === "string" && typeof data.actor === "number" && (data.id === void 0 || typeof data.id === "string") && isStringList(data.scopes) && (data.maxConnectionsPerRoom === void 0 || typeof data.maxConnectionsPerRoom === "number");
2333
- }
2334
- function isAuthToken(data) {
2335
- return isAppOnlyAuthToken(data) || isRoomAuthToken(data);
2336
- }
2337
- function parseJwtToken(token) {
2338
- const tokenParts = token.split(".");
2339
- if (tokenParts.length !== 3) {
2340
- throw new Error("Authentication error: invalid JWT token");
2234
+ this.update({ [key]: value });
2341
2235
  }
2342
- const data = tryParseJson(b64decode(tokenParts[1]));
2343
- if (data && hasJwtMeta(data)) {
2344
- return data;
2345
- } else {
2346
- throw new Error("Authentication error: missing JWT metadata");
2236
+ get(key) {
2237
+ return this._map.get(key);
2347
2238
  }
2348
- }
2349
- function parseRoomAuthToken(tokenString) {
2350
- const data = parseJwtToken(tokenString);
2351
- if (data && isRoomAuthToken(data)) {
2352
- const _a = data, {
2353
- maxConnections: _legacyField
2354
- } = _a, token = __objRest(_a, [
2355
- "maxConnections"
2356
- ]);
2357
- return token;
2358
- } else {
2359
- throw new Error(
2360
- "Authentication error: we expected a room token but did not get one. Hint: if you are using a callback, ensure the room is passed when creating the token. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClientCallback"
2239
+ delete(key) {
2240
+ var _a;
2241
+ (_a = this._pool) == null ? void 0 : _a.assertStorageIsWritable();
2242
+ const keyAsString = key;
2243
+ const oldValue = this._map.get(keyAsString);
2244
+ if (oldValue === void 0) {
2245
+ return;
2246
+ }
2247
+ if (this._pool === void 0 || this._id === void 0) {
2248
+ if (isLiveNode(oldValue)) {
2249
+ oldValue._detach();
2250
+ }
2251
+ this._map.delete(keyAsString);
2252
+ this.invalidate();
2253
+ return;
2254
+ }
2255
+ let reverse;
2256
+ if (isLiveNode(oldValue)) {
2257
+ oldValue._detach();
2258
+ reverse = oldValue._toOps(this._id, keyAsString);
2259
+ } else {
2260
+ reverse = [
2261
+ {
2262
+ type: 3 /* UPDATE_OBJECT */,
2263
+ data: { [keyAsString]: oldValue },
2264
+ id: this._id
2265
+ }
2266
+ ];
2267
+ }
2268
+ this._map.delete(keyAsString);
2269
+ this.invalidate();
2270
+ const storageUpdates = /* @__PURE__ */ new Map();
2271
+ storageUpdates.set(this._id, {
2272
+ node: this,
2273
+ type: "LiveObject",
2274
+ updates: { [key]: { type: "delete" } }
2275
+ });
2276
+ this._pool.dispatch(
2277
+ [
2278
+ {
2279
+ type: 6 /* DELETE_OBJECT_KEY */,
2280
+ key: keyAsString,
2281
+ id: this._id,
2282
+ opId: this._pool.generateOpId()
2283
+ }
2284
+ ],
2285
+ reverse,
2286
+ storageUpdates
2361
2287
  );
2362
2288
  }
2363
- }
2364
-
2365
- // src/fancy-console.ts
2366
- var badge = "background:radial-gradient(106.94% 108.33% at -10% -5%,#ff1aa3 0,#ff881a 100%);border-radius:3px;color:#fff;padding:2px 5px;font-family:sans-serif;font-weight:600";
2367
- var bold = "font-weight:600";
2368
- function wrap(method) {
2369
- return typeof window === "undefined" || process.env.NODE_ENV === "test" ? console[method] : (message, ...args) => console[method]("%cLiveblocks", badge, message, ...args);
2370
- }
2371
- var warn = wrap("warn");
2372
- var error = wrap("error");
2373
- function wrapWithTitle(method) {
2374
- return typeof window === "undefined" || process.env.NODE_ENV === "test" ? console[method] : (title, message, ...args) => console[method](
2375
- `%cLiveblocks%c ${title}`,
2376
- badge,
2377
- bold,
2378
- message,
2379
- ...args
2380
- );
2381
- }
2382
- var errorWithTitle = wrapWithTitle("error");
2383
-
2384
- // src/deprecation.ts
2385
- var _emittedDeprecationWarnings = /* @__PURE__ */ new Set();
2386
- function deprecate(message, key = message) {
2387
- if (process.env.NODE_ENV !== "production") {
2388
- if (!_emittedDeprecationWarnings.has(key)) {
2389
- _emittedDeprecationWarnings.add(key);
2390
- errorWithTitle("Deprecation warning", message);
2289
+ update(patch) {
2290
+ var _a;
2291
+ (_a = this._pool) == null ? void 0 : _a.assertStorageIsWritable();
2292
+ if (this._pool === void 0 || this._id === void 0) {
2293
+ for (const key in patch) {
2294
+ const newValue = patch[key];
2295
+ if (newValue === void 0) {
2296
+ continue;
2297
+ }
2298
+ const oldValue = this._map.get(key);
2299
+ if (isLiveNode(oldValue)) {
2300
+ oldValue._detach();
2301
+ }
2302
+ if (isLiveNode(newValue)) {
2303
+ newValue._setParentLink(this, key);
2304
+ }
2305
+ this._map.set(key, newValue);
2306
+ this.invalidate();
2307
+ }
2308
+ return;
2391
2309
  }
2392
- }
2393
- }
2394
- function deprecateIf(condition, message, key = message) {
2395
- if (process.env.NODE_ENV !== "production") {
2396
- if (condition) {
2397
- deprecate(message, key);
2310
+ const ops = [];
2311
+ const reverseOps = [];
2312
+ const opId = this._pool.generateOpId();
2313
+ const updatedProps = {};
2314
+ const reverseUpdateOp = {
2315
+ id: this._id,
2316
+ type: 3 /* UPDATE_OBJECT */,
2317
+ data: {}
2318
+ };
2319
+ const updateDelta = {};
2320
+ for (const key in patch) {
2321
+ const newValue = patch[key];
2322
+ if (newValue === void 0) {
2323
+ continue;
2324
+ }
2325
+ const oldValue = this._map.get(key);
2326
+ if (isLiveNode(oldValue)) {
2327
+ reverseOps.push(...oldValue._toOps(this._id, key));
2328
+ oldValue._detach();
2329
+ } else if (oldValue === void 0) {
2330
+ reverseOps.push({ type: 6 /* DELETE_OBJECT_KEY */, id: this._id, key });
2331
+ } else {
2332
+ reverseUpdateOp.data[key] = oldValue;
2333
+ }
2334
+ if (isLiveNode(newValue)) {
2335
+ newValue._setParentLink(this, key);
2336
+ newValue._attach(this._pool.generateId(), this._pool);
2337
+ const newAttachChildOps = newValue._toOps(this._id, key, this._pool);
2338
+ const createCrdtOp = newAttachChildOps.find(
2339
+ (op) => op.parentId === this._id
2340
+ );
2341
+ if (createCrdtOp) {
2342
+ this._propToLastUpdate.set(key, nn(createCrdtOp.opId));
2343
+ }
2344
+ ops.push(...newAttachChildOps);
2345
+ } else {
2346
+ updatedProps[key] = newValue;
2347
+ this._propToLastUpdate.set(key, opId);
2348
+ }
2349
+ this._map.set(key, newValue);
2350
+ this.invalidate();
2351
+ updateDelta[key] = { type: "update" };
2352
+ }
2353
+ if (Object.keys(reverseUpdateOp.data).length !== 0) {
2354
+ reverseOps.unshift(reverseUpdateOp);
2355
+ }
2356
+ if (Object.keys(updatedProps).length !== 0) {
2357
+ ops.unshift({
2358
+ opId,
2359
+ id: this._id,
2360
+ type: 3 /* UPDATE_OBJECT */,
2361
+ data: updatedProps
2362
+ });
2398
2363
  }
2364
+ const storageUpdates = /* @__PURE__ */ new Map();
2365
+ storageUpdates.set(this._id, {
2366
+ node: this,
2367
+ type: "LiveObject",
2368
+ updates: updateDelta
2369
+ });
2370
+ this._pool.dispatch(ops, reverseOps, storageUpdates);
2399
2371
  }
2400
- }
2401
- function throwUsageError(message) {
2402
- if (process.env.NODE_ENV !== "production") {
2403
- const usageError = new Error(message);
2404
- usageError.name = "Usage error";
2405
- errorWithTitle("Usage error", message);
2406
- throw usageError;
2372
+ toImmutable() {
2373
+ return super.toImmutable();
2407
2374
  }
2408
- }
2409
- function errorIf(condition, message) {
2410
- if (process.env.NODE_ENV !== "production") {
2411
- if (condition) {
2412
- throwUsageError(message);
2375
+ _toImmutable() {
2376
+ const result = {};
2377
+ for (const [key, val] of this._map) {
2378
+ result[key] = isLiveStructure(val) ? val.toImmutable() : val;
2413
2379
  }
2380
+ return process.env.NODE_ENV === "production" ? result : Object.freeze(result);
2414
2381
  }
2415
- }
2382
+ };
2416
2383
 
2417
- // src/EventSource.ts
2384
+ // src/lib/EventSource.ts
2418
2385
  function makeEventSource() {
2419
2386
  const _onetimeObservers = /* @__PURE__ */ new Set();
2420
2387
  const _observers = /* @__PURE__ */ new Set();
@@ -2447,7 +2414,39 @@ function makeEventSource() {
2447
2414
  };
2448
2415
  }
2449
2416
 
2450
- // src/ImmutableRef.ts
2417
+ // src/lib/Json.ts
2418
+ function isJsonScalar(data) {
2419
+ return data === null || typeof data === "string" || typeof data === "number" || typeof data === "boolean";
2420
+ }
2421
+ function isJsonArray(data) {
2422
+ return Array.isArray(data);
2423
+ }
2424
+ function isJsonObject(data) {
2425
+ return !isJsonScalar(data) && !isJsonArray(data);
2426
+ }
2427
+
2428
+ // src/protocol/ClientMsg.ts
2429
+ var ClientMsgCode = /* @__PURE__ */ ((ClientMsgCode2) => {
2430
+ ClientMsgCode2[ClientMsgCode2["UPDATE_PRESENCE"] = 100] = "UPDATE_PRESENCE";
2431
+ ClientMsgCode2[ClientMsgCode2["BROADCAST_EVENT"] = 103] = "BROADCAST_EVENT";
2432
+ ClientMsgCode2[ClientMsgCode2["FETCH_STORAGE"] = 200] = "FETCH_STORAGE";
2433
+ ClientMsgCode2[ClientMsgCode2["UPDATE_STORAGE"] = 201] = "UPDATE_STORAGE";
2434
+ return ClientMsgCode2;
2435
+ })(ClientMsgCode || {});
2436
+
2437
+ // src/protocol/ServerMsg.ts
2438
+ var ServerMsgCode = /* @__PURE__ */ ((ServerMsgCode2) => {
2439
+ ServerMsgCode2[ServerMsgCode2["UPDATE_PRESENCE"] = 100] = "UPDATE_PRESENCE";
2440
+ ServerMsgCode2[ServerMsgCode2["USER_JOINED"] = 101] = "USER_JOINED";
2441
+ ServerMsgCode2[ServerMsgCode2["USER_LEFT"] = 102] = "USER_LEFT";
2442
+ ServerMsgCode2[ServerMsgCode2["BROADCASTED_EVENT"] = 103] = "BROADCASTED_EVENT";
2443
+ ServerMsgCode2[ServerMsgCode2["ROOM_STATE"] = 104] = "ROOM_STATE";
2444
+ ServerMsgCode2[ServerMsgCode2["INITIAL_STORAGE_STATE"] = 200] = "INITIAL_STORAGE_STATE";
2445
+ ServerMsgCode2[ServerMsgCode2["UPDATE_STORAGE"] = 201] = "UPDATE_STORAGE";
2446
+ return ServerMsgCode2;
2447
+ })(ServerMsgCode || {});
2448
+
2449
+ // src/refs/ImmutableRef.ts
2451
2450
  function merge(target, patch) {
2452
2451
  let updated = false;
2453
2452
  const newValue = __spreadValues({}, target);
@@ -2484,7 +2483,7 @@ var ImmutableRef = class {
2484
2483
  }
2485
2484
  };
2486
2485
 
2487
- // src/MeRef.ts
2486
+ // src/refs/MeRef.ts
2488
2487
  var MeRef = class extends ImmutableRef {
2489
2488
  constructor(initialPresence) {
2490
2489
  super();
@@ -2503,7 +2502,7 @@ var MeRef = class extends ImmutableRef {
2503
2502
  }
2504
2503
  };
2505
2504
 
2506
- // src/LegacyArray.ts
2505
+ // src/lib/LegacyArray.ts
2507
2506
  function asArrayWithLegacyMethods(arr) {
2508
2507
  Object.defineProperty(arr, "count", {
2509
2508
  value: arr.length,
@@ -2516,7 +2515,7 @@ function asArrayWithLegacyMethods(arr) {
2516
2515
  return freeze(arr);
2517
2516
  }
2518
2517
 
2519
- // src/OthersRef.ts
2518
+ // src/refs/OthersRef.ts
2520
2519
  function makeUser(conn, presence) {
2521
2520
  return freeze(compactObject(__spreadProps(__spreadValues({}, conn), { presence })));
2522
2521
  }
@@ -2602,18 +2601,7 @@ var OthersRef = class extends ImmutableRef {
2602
2601
  }
2603
2602
  };
2604
2603
 
2605
- // src/types/Json.ts
2606
- function isJsonScalar(data) {
2607
- return data === null || typeof data === "string" || typeof data === "number" || typeof data === "boolean";
2608
- }
2609
- function isJsonArray(data) {
2610
- return Array.isArray(data);
2611
- }
2612
- function isJsonObject(data) {
2613
- return !isJsonScalar(data) && !isJsonArray(data);
2614
- }
2615
-
2616
- // src/ValueRef.ts
2604
+ // src/refs/ValueRef.ts
2617
2605
  var ValueRef = class extends ImmutableRef {
2618
2606
  constructor(initialValue) {
2619
2607
  super();
@@ -2641,7 +2629,23 @@ var DerivedRef = class extends ImmutableRef {
2641
2629
  }
2642
2630
  };
2643
2631
 
2632
+ // src/types/WebsocketCloseCodes.ts
2633
+ var WebsocketCloseCodes = /* @__PURE__ */ ((WebsocketCloseCodes2) => {
2634
+ WebsocketCloseCodes2[WebsocketCloseCodes2["CLOSE_ABNORMAL"] = 1006] = "CLOSE_ABNORMAL";
2635
+ WebsocketCloseCodes2[WebsocketCloseCodes2["INVALID_MESSAGE_FORMAT"] = 4e3] = "INVALID_MESSAGE_FORMAT";
2636
+ WebsocketCloseCodes2[WebsocketCloseCodes2["NOT_ALLOWED"] = 4001] = "NOT_ALLOWED";
2637
+ WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_MESSAGES_PER_SECONDS"] = 4002] = "MAX_NUMBER_OF_MESSAGES_PER_SECONDS";
2638
+ WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_CONCURRENT_CONNECTIONS"] = 4003] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS";
2639
+ WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP"] = 4004] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP";
2640
+ WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM"] = 4005] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM";
2641
+ WebsocketCloseCodes2[WebsocketCloseCodes2["CLOSE_WITHOUT_RETRY"] = 4999] = "CLOSE_WITHOUT_RETRY";
2642
+ return WebsocketCloseCodes2;
2643
+ })(WebsocketCloseCodes || {});
2644
+
2644
2645
  // src/room.ts
2646
+ function isRoomEventName(value) {
2647
+ return value === "my-presence" || value === "others" || value === "event" || value === "error" || value === "connection" || value === "history";
2648
+ }
2645
2649
  var BACKOFF_RETRY_DELAYS = [250, 500, 1e3, 2e3, 4e3, 8e3, 1e4];
2646
2650
  var BACKOFF_RETRY_DELAYS_SLOW = [2e3, 3e4, 6e4, 3e5];
2647
2651
  var HEARTBEAT_INTERVAL = 3e4;
@@ -3793,7 +3797,7 @@ function prepareCreateWebSocket(liveblocksServer, WebSocketPolyfill) {
3793
3797
  const ws = WebSocketPolyfill || WebSocket;
3794
3798
  return (token) => {
3795
3799
  return new ws(
3796
- `${liveblocksServer}/?token=${token}&version=${true ? "0.19.0-beta0" : "dev"}`
3800
+ `${liveblocksServer}/?token=${token}&version=${true ? "0.19.0" : "dev"}`
3797
3801
  );
3798
3802
  };
3799
3803
  }
@@ -4311,7 +4315,7 @@ function legacy_patchImmutableNode(state, path, update) {
4311
4315
  }
4312
4316
  }
4313
4317
 
4314
- // src/shallow.ts
4318
+ // src/lib/shallow.ts
4315
4319
  function shallowArray(xs, ys) {
4316
4320
  if (xs.length !== ys.length) {
4317
4321
  return false;