@liveblocks/client 0.14.0 → 0.15.0-alpha.1

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.
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.patchImmutableObject = exports.patchLiveObject = exports.patchLiveObjectKey = exports.patchLiveList = exports.liveNodeToJson = exports.liveObjectToJson = void 0;
4
+ const LiveList_1 = require("./LiveList");
5
+ const LiveMap_1 = require("./LiveMap");
6
+ const LiveObject_1 = require("./LiveObject");
7
+ const LiveRegister_1 = require("./LiveRegister");
8
+ function liveObjectToJson(liveObject) {
9
+ const result = {};
10
+ const obj = liveObject.toObject();
11
+ for (const key in obj) {
12
+ result[key] = liveNodeToJson(obj[key]);
13
+ }
14
+ return result;
15
+ }
16
+ exports.liveObjectToJson = liveObjectToJson;
17
+ function liveMapToJson(map) {
18
+ const result = {};
19
+ const obj = Object.fromEntries(map);
20
+ for (const key in obj) {
21
+ result[key] = liveNodeToJson(obj[key]);
22
+ }
23
+ return result;
24
+ }
25
+ function liveListToJson(value) {
26
+ return value.toArray().map(liveNodeToJson);
27
+ }
28
+ function liveNodeToJson(value) {
29
+ if (value instanceof LiveObject_1.LiveObject) {
30
+ return liveObjectToJson(value);
31
+ }
32
+ else if (value instanceof LiveList_1.LiveList) {
33
+ return liveListToJson(value);
34
+ }
35
+ else if (value instanceof LiveMap_1.LiveMap) {
36
+ return liveMapToJson(value);
37
+ }
38
+ else if (value instanceof LiveRegister_1.LiveRegister) {
39
+ return value.data;
40
+ }
41
+ return value;
42
+ }
43
+ exports.liveNodeToJson = liveNodeToJson;
44
+ function isPlainObject(obj) {
45
+ return Object.prototype.toString.call(obj) === "[object Object]";
46
+ }
47
+ function anyToCrdt(obj) {
48
+ if (obj == null) {
49
+ return obj;
50
+ }
51
+ if (Array.isArray(obj)) {
52
+ return new LiveList_1.LiveList(obj.map(anyToCrdt));
53
+ }
54
+ if (isPlainObject(obj)) {
55
+ const init = {};
56
+ for (const key in obj) {
57
+ init[key] = anyToCrdt(obj[key]);
58
+ }
59
+ return new LiveObject_1.LiveObject(init);
60
+ }
61
+ return obj;
62
+ }
63
+ function patchLiveList(liveList, prev, next) {
64
+ let i = 0;
65
+ let prevEnd = prev.length - 1;
66
+ let nextEnd = next.length - 1;
67
+ let prevNode = prev[0];
68
+ let nextNode = next[0];
69
+ /**
70
+ * For A,B,C => A,B,C,D
71
+ * i = 3, prevEnd = 2, nextEnd = 3
72
+ *
73
+ * For A,B,C => B,C
74
+ * i = 2, prevEnd = 2, nextEnd = 1
75
+ *
76
+ * For B,C => A,B,C
77
+ * i = 0, pre
78
+ */
79
+ outer: {
80
+ while (prevNode === nextNode) {
81
+ ++i;
82
+ if (i > prevEnd || i > nextEnd) {
83
+ break outer;
84
+ }
85
+ prevNode = prev[i];
86
+ nextNode = next[i];
87
+ }
88
+ prevNode = prev[prevEnd];
89
+ nextNode = next[nextEnd];
90
+ while (prevNode === nextNode) {
91
+ prevEnd--;
92
+ nextEnd--;
93
+ if (i > prevEnd || i > nextEnd) {
94
+ break outer;
95
+ }
96
+ prevNode = prev[prevEnd];
97
+ nextNode = next[nextEnd];
98
+ }
99
+ }
100
+ if (i > prevEnd) {
101
+ if (i <= nextEnd) {
102
+ while (i <= nextEnd) {
103
+ liveList.insert(anyToCrdt(next[i]), i);
104
+ i++;
105
+ }
106
+ }
107
+ }
108
+ else if (i > nextEnd) {
109
+ while (i <= prevEnd) {
110
+ liveList.delete(i++);
111
+ }
112
+ }
113
+ else {
114
+ while (i <= prevEnd && i <= nextEnd) {
115
+ prevNode = prev[i];
116
+ nextNode = next[i];
117
+ const liveListNode = liveList.get(i);
118
+ if (liveListNode instanceof LiveObject_1.LiveObject &&
119
+ isPlainObject(prevNode) &&
120
+ isPlainObject(nextNode)) {
121
+ patchLiveObject(liveListNode, prevNode, nextNode);
122
+ }
123
+ else {
124
+ liveList.delete(i);
125
+ liveList.insert(anyToCrdt(nextNode), i);
126
+ }
127
+ i++;
128
+ }
129
+ while (i <= nextEnd) {
130
+ liveList.insert(anyToCrdt(next[i]), i);
131
+ i++;
132
+ }
133
+ while (i <= prevEnd) {
134
+ liveList.delete(i);
135
+ i++;
136
+ }
137
+ }
138
+ }
139
+ exports.patchLiveList = patchLiveList;
140
+ function patchLiveObjectKey(liveObject, key, prev, next) {
141
+ const value = liveObject.get(key);
142
+ if (next === undefined) {
143
+ liveObject.delete(key);
144
+ }
145
+ else if (value === undefined) {
146
+ liveObject.set(key, anyToCrdt(next));
147
+ }
148
+ else if (prev === next) {
149
+ return;
150
+ }
151
+ else if (value instanceof LiveList_1.LiveList &&
152
+ Array.isArray(prev) &&
153
+ Array.isArray(next)) {
154
+ patchLiveList(value, prev, next);
155
+ }
156
+ else if (value instanceof LiveObject_1.LiveObject &&
157
+ isPlainObject(prev) &&
158
+ isPlainObject(next)) {
159
+ patchLiveObject(value, prev, next);
160
+ }
161
+ else {
162
+ liveObject.set(key, anyToCrdt(next));
163
+ }
164
+ }
165
+ exports.patchLiveObjectKey = patchLiveObjectKey;
166
+ function patchLiveObject(root, prev, next) {
167
+ const updates = {};
168
+ for (const key in next) {
169
+ patchLiveObjectKey(root, key, prev[key], next[key]);
170
+ }
171
+ for (const key in prev) {
172
+ if (next[key] === undefined) {
173
+ root.delete(key);
174
+ }
175
+ }
176
+ if (Object.keys(updates).length > 0) {
177
+ root.update(updates);
178
+ }
179
+ }
180
+ exports.patchLiveObject = patchLiveObject;
181
+ function getParentsPath(node) {
182
+ const path = [];
183
+ while (node._parentKey != null && node._parent != null) {
184
+ if (node._parent instanceof LiveList_1.LiveList) {
185
+ path.push(node._parent._indexOfPosition(node._parentKey));
186
+ }
187
+ else {
188
+ path.push(node._parentKey);
189
+ }
190
+ node = node._parent;
191
+ }
192
+ return path;
193
+ }
194
+ function patchImmutableObject(state, updates) {
195
+ return updates.reduce((state, update) => patchImmutableObjectWithUpdate(state, update), state);
196
+ }
197
+ exports.patchImmutableObject = patchImmutableObject;
198
+ function patchImmutableObjectWithUpdate(state, update) {
199
+ const path = getParentsPath(update.node);
200
+ return patchImmutableNode(state, path, update);
201
+ }
202
+ function patchImmutableNode(state, path, update) {
203
+ var _a, _b, _c, _d;
204
+ const pathItem = path.pop();
205
+ if (pathItem === undefined) {
206
+ switch (update.type) {
207
+ case "LiveObject": {
208
+ if (typeof state !== "object") {
209
+ throw new Error("Internal: received update on LiveObject but state was not an object");
210
+ }
211
+ let newState = Object.assign({}, state);
212
+ for (const key in update.updates) {
213
+ if (((_a = update.updates[key]) === null || _a === void 0 ? void 0 : _a.type) === "update") {
214
+ newState[key] = liveNodeToJson(update.node.get(key));
215
+ }
216
+ else if (((_b = update.updates[key]) === null || _b === void 0 ? void 0 : _b.type) === "delete") {
217
+ delete newState[key];
218
+ }
219
+ }
220
+ return newState;
221
+ }
222
+ case "LiveList": {
223
+ if (Array.isArray(state) === false) {
224
+ throw new Error("Internal: received update on LiveList but state was not an array");
225
+ }
226
+ let newState = state.map((x) => x);
227
+ const newArray = update.node.toArray();
228
+ for (const listUpdate of update.updates) {
229
+ if (listUpdate.type === "insert") {
230
+ if (listUpdate.index === newState.length) {
231
+ newState.push(liveNodeToJson(newArray[listUpdate.index]));
232
+ }
233
+ else {
234
+ newState = [
235
+ ...newState.slice(0, listUpdate.index),
236
+ liveNodeToJson(newArray[listUpdate.index]),
237
+ ...newState.slice(listUpdate.index),
238
+ ];
239
+ }
240
+ }
241
+ else if (listUpdate.type === "delete") {
242
+ newState.splice(listUpdate.index, 1);
243
+ }
244
+ }
245
+ return newState;
246
+ }
247
+ case "LiveMap": {
248
+ if (typeof state !== "object") {
249
+ throw new Error("Internal: received update on LiveMap but state was not an object");
250
+ }
251
+ let newState = Object.assign({}, state);
252
+ for (const key in update.updates) {
253
+ if (((_c = update.updates[key]) === null || _c === void 0 ? void 0 : _c.type) === "update") {
254
+ newState[key] = liveNodeToJson(update.node.get(key));
255
+ }
256
+ else if (((_d = update.updates[key]) === null || _d === void 0 ? void 0 : _d.type) === "delete") {
257
+ delete newState[key];
258
+ }
259
+ }
260
+ return newState;
261
+ }
262
+ }
263
+ }
264
+ if (Array.isArray(state)) {
265
+ const newArray = [...state];
266
+ newArray[pathItem] = patchImmutableNode(state[pathItem], path, update);
267
+ return newArray;
268
+ }
269
+ else {
270
+ return Object.assign(Object.assign({}, state), { [pathItem]: patchImmutableNode(state[pathItem], path, update) });
271
+ }
272
+ }
@@ -3,3 +3,4 @@ export { LiveMap } from "./LiveMap";
3
3
  export { LiveList } from "./LiveList";
4
4
  export type { Others, Presence, Room, Client, User, BroadcastOptions, } from "./types";
5
5
  export { createClient } from "./client";
6
+ export { liveObjectToJson, liveNodeToJson, patchLiveList, patchImmutableObject, patchLiveObject, patchLiveObjectKey, } from "./immutable";
package/lib/cjs/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createClient = exports.LiveList = exports.LiveMap = exports.LiveObject = void 0;
3
+ exports.patchLiveObjectKey = exports.patchLiveObject = exports.patchImmutableObject = exports.patchLiveList = exports.liveNodeToJson = exports.liveObjectToJson = exports.createClient = exports.LiveList = exports.LiveMap = exports.LiveObject = void 0;
4
4
  var LiveObject_1 = require("./LiveObject");
5
5
  Object.defineProperty(exports, "LiveObject", { enumerable: true, get: function () { return LiveObject_1.LiveObject; } });
6
6
  var LiveMap_1 = require("./LiveMap");
@@ -9,3 +9,10 @@ var LiveList_1 = require("./LiveList");
9
9
  Object.defineProperty(exports, "LiveList", { enumerable: true, get: function () { return LiveList_1.LiveList; } });
10
10
  var client_1 = require("./client");
11
11
  Object.defineProperty(exports, "createClient", { enumerable: true, get: function () { return client_1.createClient; } });
12
+ var immutable_1 = require("./immutable");
13
+ Object.defineProperty(exports, "liveObjectToJson", { enumerable: true, get: function () { return immutable_1.liveObjectToJson; } });
14
+ Object.defineProperty(exports, "liveNodeToJson", { enumerable: true, get: function () { return immutable_1.liveNodeToJson; } });
15
+ Object.defineProperty(exports, "patchLiveList", { enumerable: true, get: function () { return immutable_1.patchLiveList; } });
16
+ Object.defineProperty(exports, "patchImmutableObject", { enumerable: true, get: function () { return immutable_1.patchImmutableObject; } });
17
+ Object.defineProperty(exports, "patchLiveObject", { enumerable: true, get: function () { return immutable_1.patchLiveObject; } });
18
+ Object.defineProperty(exports, "patchLiveObjectKey", { enumerable: true, get: function () { return immutable_1.patchLiveObjectKey; } });
package/lib/cjs/room.d.ts CHANGED
@@ -60,7 +60,7 @@ export declare type State = {
60
60
  updates: {
61
61
  others: [];
62
62
  presence: boolean;
63
- nodes: Set<AbstractCrdt>;
63
+ storageUpdates: Map<string, StorageUpdate>;
64
64
  };
65
65
  };
66
66
  offlineOperations: Map<string, Op>;
package/lib/cjs/room.js CHANGED
@@ -215,22 +215,22 @@ function makeStateMachine(state, context, mockedEffects) {
215
215
  state.undoStack.push(historyItem);
216
216
  }
217
217
  }
218
- function storageDispatch(ops, reverse, modified) {
218
+ function storageDispatch(ops, reverse, storageUpdates) {
219
219
  if (state.isBatching) {
220
220
  state.batch.ops.push(...ops);
221
- for (const item of modified) {
222
- state.batch.updates.nodes.add(item);
223
- }
221
+ storageUpdates.forEach((value, key) => {
222
+ state.batch.updates.storageUpdates.set(key, (0, utils_1.mergeStorageUpdates)(state.batch.updates.storageUpdates.get(key), value));
223
+ });
224
224
  state.batch.reverseOps.push(...reverse);
225
225
  }
226
226
  else {
227
227
  addToUndoStack(reverse);
228
228
  state.redoStack = [];
229
229
  dispatch(ops);
230
- notify({ nodes: new Set(modified) });
230
+ notify({ storageUpdates: storageUpdates });
231
231
  }
232
232
  }
233
- function notify({ nodes = new Set(), presence = false, others = [], }) {
233
+ function notify({ storageUpdates = new Map(), presence = false, others = [], }) {
234
234
  if (others.length > 0) {
235
235
  state.others = makeOthers(state.users);
236
236
  for (const event of others) {
@@ -244,28 +244,9 @@ function makeStateMachine(state, context, mockedEffects) {
244
244
  listener(state.me);
245
245
  }
246
246
  }
247
- if (nodes.size > 0) {
247
+ if (storageUpdates.size > 0) {
248
248
  for (const subscriber of state.listeners.storage) {
249
- subscriber(Array.from(nodes).map((m) => {
250
- if (m instanceof LiveObject_1.LiveObject) {
251
- return {
252
- type: "LiveObject",
253
- node: m,
254
- };
255
- }
256
- else if (m instanceof LiveList_1.LiveList) {
257
- return {
258
- type: "LiveList",
259
- node: m,
260
- };
261
- }
262
- else {
263
- return {
264
- type: "LiveMap",
265
- node: m,
266
- };
267
- }
268
- }));
249
+ subscriber(Array.from(storageUpdates.values()));
269
250
  }
270
251
  }
271
252
  }
@@ -288,7 +269,10 @@ function makeStateMachine(state, context, mockedEffects) {
288
269
  function apply(item, isLocal) {
289
270
  const result = {
290
271
  reverse: [],
291
- updates: { nodes: new Set(), presence: false },
272
+ updates: {
273
+ storageUpdates: new Map(),
274
+ presence: false,
275
+ },
292
276
  };
293
277
  for (const op of item) {
294
278
  if (op.type === "presence") {
@@ -318,7 +302,7 @@ function makeStateMachine(state, context, mockedEffects) {
318
302
  }
319
303
  const applyOpResult = applyOp(op, isLocal);
320
304
  if (applyOpResult.modified) {
321
- result.updates.nodes.add(applyOpResult.modified);
305
+ result.updates.storageUpdates.set(applyOpResult.modified.node._id, (0, utils_1.mergeStorageUpdates)(result.updates.storageUpdates.get(applyOpResult.modified.node._id), applyOpResult.modified));
322
306
  result.reverse.unshift(...applyOpResult.reverse);
323
307
  }
324
308
  }
@@ -346,17 +330,12 @@ function makeStateMachine(state, context, mockedEffects) {
346
330
  }
347
331
  if (item._parent instanceof LiveList_1.LiveList) {
348
332
  const previousKey = item._parentKey;
349
- item._parent._setChildKey(op.parentKey, item);
350
- return {
351
- reverse: [
352
- {
353
- type: live_1.OpType.SetParentKey,
354
- id: item._id,
355
- parentKey: previousKey,
356
- },
357
- ],
358
- modified: item._parent,
359
- };
333
+ if (previousKey === op.parentKey) {
334
+ return { modified: false };
335
+ }
336
+ else {
337
+ return item._parent._setChildKey(op.parentKey, item, previousKey);
338
+ }
360
339
  }
361
340
  return { modified: false };
362
341
  }
@@ -579,7 +558,7 @@ See v0.13 release notes for more information.
579
558
  subMessages.push(message);
580
559
  }
581
560
  const updates = {
582
- nodes: new Set(),
561
+ storageUpdates: new Map(),
583
562
  others: [],
584
563
  };
585
564
  for (const subMessage of subMessages) {
@@ -615,9 +594,9 @@ See v0.13 release notes for more information.
615
594
  }
616
595
  case live_1.ServerMessageType.UpdateStorage: {
617
596
  const applyResult = apply(subMessage.ops, false);
618
- for (const node of applyResult.updates.nodes) {
619
- updates.nodes.add(node);
620
- }
597
+ applyResult.updates.storageUpdates.forEach((value, key) => {
598
+ updates.storageUpdates.set(key, (0, utils_1.mergeStorageUpdates)(updates.storageUpdates.get(key), value));
599
+ });
621
600
  break;
622
601
  }
623
602
  }
@@ -911,8 +890,11 @@ See v0.13 release notes for more information.
911
890
  if (state.batch.reverseOps.length > 0) {
912
891
  addToUndoStack(state.batch.reverseOps);
913
892
  }
914
- // Clear the redo stack because batch is always called from a local operation
915
- state.redoStack = [];
893
+ if (state.batch.ops.length > 0) {
894
+ // Only clear the redo stack if something has changed during a batch
895
+ // Clear the redo stack because batch is always called from a local operation
896
+ state.redoStack = [];
897
+ }
916
898
  if (state.batch.ops.length > 0) {
917
899
  dispatch(state.batch.ops);
918
900
  }
@@ -922,7 +904,7 @@ See v0.13 release notes for more information.
922
904
  reverseOps: [],
923
905
  updates: {
924
906
  others: [],
925
- nodes: new Set(),
907
+ storageUpdates: new Map(),
926
908
  presence: false,
927
909
  },
928
910
  };
@@ -1035,7 +1017,11 @@ function defaultState(me, defaultStorageRoot) {
1035
1017
  isBatching: false,
1036
1018
  batch: {
1037
1019
  ops: [],
1038
- updates: { nodes: new Set(), presence: false, others: [] },
1020
+ updates: {
1021
+ storageUpdates: new Map(),
1022
+ presence: false,
1023
+ others: [],
1024
+ },
1039
1025
  reverseOps: [],
1040
1026
  },
1041
1027
  offlineOperations: new Map(),
@@ -16,17 +16,37 @@ export declare type RoomEventCallbackMap = {
16
16
  error: ErrorCallback;
17
17
  connection: ConnectionCallback;
18
18
  };
19
+ export declare type UpdateDelta = {
20
+ type: "update";
21
+ } | {
22
+ type: "delete";
23
+ };
19
24
  export declare type LiveMapUpdates<TKey extends string = string, TValue = any> = {
20
25
  type: "LiveMap";
21
26
  node: LiveMap<TKey, TValue>;
27
+ updates: Record<TKey, UpdateDelta>;
22
28
  };
29
+ export declare type LiveObjectUpdateDelta<T> = Partial<{
30
+ [Property in keyof T]: UpdateDelta;
31
+ }>;
23
32
  export declare type LiveObjectUpdates<TData = any> = {
24
33
  type: "LiveObject";
25
34
  node: LiveObject<TData>;
35
+ updates: LiveObjectUpdateDelta<TData>;
36
+ };
37
+ export declare type ListUpdateDelta = {
38
+ type: "insert";
39
+ } | {
40
+ type: "delete";
41
+ };
42
+ export declare type LiveListUpdateDelta = {
43
+ index: number;
44
+ type: "insert" | "delete";
26
45
  };
27
46
  export declare type LiveListUpdates<TItem = any> = {
28
47
  type: "LiveList";
29
48
  node: LiveList<TItem>;
49
+ updates: LiveListUpdateDelta[];
30
50
  };
31
51
  export declare type BroadcastOptions = {
32
52
  /**
@@ -1,5 +1,6 @@
1
1
  import { AbstractCrdt, Doc } from "./AbstractCrdt";
2
2
  import { SerializedCrdtWithId, Op, SerializedCrdt } from "./live";
3
+ import { StorageUpdate } from "./types";
3
4
  export declare function remove<T>(array: T[], item: T): void;
4
5
  export declare function isSameNodeOrChildOf(node: AbstractCrdt, parent: AbstractCrdt): boolean;
5
6
  export declare function deserialize(entry: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): AbstractCrdt;
@@ -7,3 +8,4 @@ export declare function isCrdt(obj: any): obj is AbstractCrdt;
7
8
  export declare function selfOrRegisterValue(obj: AbstractCrdt): any;
8
9
  export declare function selfOrRegister(obj: any): AbstractCrdt;
9
10
  export declare function getTreesDiffOperations(currentItems: Map<string, SerializedCrdt>, newItems: Map<string, SerializedCrdt>): Op[];
11
+ export declare function mergeStorageUpdates(first: StorageUpdate | undefined, second: StorageUpdate): StorageUpdate;
package/lib/cjs/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTreesDiffOperations = exports.selfOrRegister = exports.selfOrRegisterValue = exports.isCrdt = exports.deserialize = exports.isSameNodeOrChildOf = exports.remove = void 0;
3
+ exports.mergeStorageUpdates = exports.getTreesDiffOperations = exports.selfOrRegister = exports.selfOrRegisterValue = exports.isCrdt = exports.deserialize = exports.isSameNodeOrChildOf = exports.remove = void 0;
4
4
  const live_1 = require("./live");
5
5
  const LiveList_1 = require("./LiveList");
6
6
  const LiveMap_1 = require("./LiveMap");
@@ -148,3 +148,28 @@ function getTreesDiffOperations(currentItems, newItems) {
148
148
  return ops;
149
149
  }
150
150
  exports.getTreesDiffOperations = getTreesDiffOperations;
151
+ function mergeStorageUpdates(first, second) {
152
+ if (!first) {
153
+ return second;
154
+ }
155
+ if (second.type === "LiveObject") {
156
+ const updates = first.updates;
157
+ for (const [key, value] of Object.entries(second.updates)) {
158
+ updates[key] = value;
159
+ }
160
+ return Object.assign(Object.assign({}, second), { updates: updates });
161
+ }
162
+ else if (second.type === "LiveMap") {
163
+ const updates = first.updates;
164
+ for (const [key, value] of Object.entries(second.updates)) {
165
+ updates[key] = value;
166
+ }
167
+ return Object.assign(Object.assign({}, second), { updates: updates });
168
+ }
169
+ else if (second.type === "LiveList") {
170
+ const updates = first.updates;
171
+ return Object.assign(Object.assign({}, second), { updates: updates.concat(second.updates) });
172
+ }
173
+ return second;
174
+ }
175
+ exports.mergeStorageUpdates = mergeStorageUpdates;
@@ -1,7 +1,8 @@
1
1
  import { Op, SerializedCrdt } from "./live";
2
+ import { StorageUpdate } from "./types";
2
3
  export declare type ApplyResult = {
3
4
  reverse: Op[];
4
- modified: AbstractCrdt;
5
+ modified: StorageUpdate;
5
6
  } | {
6
7
  modified: false;
7
8
  };
@@ -10,7 +11,7 @@ export interface Doc {
10
11
  generateOpId: () => string;
11
12
  addItem: (id: string, item: AbstractCrdt) => void;
12
13
  deleteItem: (id: string) => void;
13
- dispatch: (ops: Op[], reverseOps: Op[], modified: AbstractCrdt[]) => void;
14
+ dispatch: (ops: Op[], reverseOps: Op[], storageUpdates: Map<string, StorageUpdate>) => void;
14
15
  }
15
16
  export declare abstract class AbstractCrdt {
16
17
  #private;
@@ -53,7 +54,7 @@ export declare abstract class AbstractCrdt {
53
54
  /**
54
55
  * INTERNAL
55
56
  */
56
- abstract _detachChild(crdt: AbstractCrdt): void;
57
+ abstract _detachChild(crdt: AbstractCrdt): ApplyResult;
57
58
  /**
58
59
  * INTERNAL
59
60
  */
@@ -62,4 +63,5 @@ export declare abstract class AbstractCrdt {
62
63
  * INTERNAL
63
64
  */
64
65
  abstract _toSerializedCrdt(): SerializedCrdt;
66
+ abstract _getType(): string;
65
67
  }
@@ -49,10 +49,7 @@ export class AbstractCrdt {
49
49
  switch (op.type) {
50
50
  case OpType.DeleteCrdt: {
51
51
  if (this._parent != null && this._parentKey != null) {
52
- const parent = this._parent;
53
- const reverse = this._serialize(this._parent._id, this._parentKey, __classPrivateFieldGet(this, _AbstractCrdt_doc, "f"));
54
- this._parent._detachChild(this);
55
- return { modified: parent, reverse };
52
+ return this._parent._detachChild(this);
56
53
  }
57
54
  return { modified: false };
58
55
  }
@@ -14,6 +14,7 @@ export declare class LiveList<T> extends AbstractCrdt {
14
14
  * INTERNAL
15
15
  */
16
16
  _serialize(parentId?: string, parentKey?: string, doc?: Doc): Op[];
17
+ _indexOfPosition(position: string): number;
17
18
  /**
18
19
  * INTERNAL
19
20
  */
@@ -29,15 +30,19 @@ export declare class LiveList<T> extends AbstractCrdt {
29
30
  /**
30
31
  * INTERNAL
31
32
  */
32
- _detachChild(child: AbstractCrdt): void;
33
+ _detachChild(child: AbstractCrdt): ApplyResult;
33
34
  /**
34
35
  * INTERNAL
35
36
  */
36
- _setChildKey(key: string, child: AbstractCrdt): void;
37
+ _setChildKey(key: string, child: AbstractCrdt, previousKey: string): ApplyResult;
37
38
  /**
38
39
  * INTERNAL
39
40
  */
40
41
  _apply(op: Op, isLocal: boolean): ApplyResult;
42
+ /**
43
+ * INTERNAL
44
+ */
45
+ _getType(): string;
41
46
  /**
42
47
  * INTERNAL
43
48
  */
@@ -73,6 +78,7 @@ export declare class LiveList<T> extends AbstractCrdt {
73
78
  * Returns an Array of all the elements in the LiveList.
74
79
  */
75
80
  toArray(): T[];
81
+ toCrdtArray(): AbstractCrdt[];
76
82
  /**
77
83
  * Tests whether all elements pass the test implemented by the provided function.
78
84
  * @param predicate Function to test for each element, taking two arguments (the element and its index).