@fluidframework/merge-tree 2.42.0 → 2.43.0-343119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +3 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8 -11
- package/dist/client.js.map +1 -1
- package/dist/collections/list.d.ts +95 -5
- package/dist/collections/list.d.ts.map +1 -1
- package/dist/collections/list.js +67 -5
- package/dist/collections/list.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/mergeTree.d.ts +9 -9
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +14 -6
- package/dist/mergeTree.js.map +1 -1
- package/dist/revertibles.js +1 -1
- package/dist/revertibles.js.map +1 -1
- package/dist/test/beastTest.spec.js +1 -1
- package/dist/test/beastTest.spec.js.map +1 -1
- package/dist/test/client.annotateMarker.spec.js +1 -1
- package/dist/test/client.annotateMarker.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +21 -21
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.attributionFarm.spec.js +1 -1
- package/dist/test/client.attributionFarm.spec.js.map +1 -1
- package/dist/test/client.getPosition.spec.js +1 -0
- package/dist/test/client.getPosition.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +62 -48
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.localReferenceFarm.spec.js +1 -0
- package/dist/test/client.localReferenceFarm.spec.js.map +1 -1
- package/dist/test/client.rollback.spec.js +8 -6
- package/dist/test/client.rollback.spec.js.map +1 -1
- package/dist/test/mergeTree.annotate.spec.js +25 -25
- package/dist/test/mergeTree.annotate.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +4 -4
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/resetPendingSegmentsToOp.spec.js +4 -4
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/dist/test/snapshot.utils.js +1 -1
- package/dist/test/snapshot.utils.js.map +1 -1
- package/dist/test/sortedSegmentSet.spec.js +3 -3
- package/dist/test/sortedSegmentSet.spec.js.map +1 -1
- package/dist/test/testClient.js +3 -3
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/tracking.spec.js +7 -7
- package/dist/test/tracking.spec.js.map +1 -1
- package/dist/test/wordUnitTests.spec.js.map +1 -1
- package/lib/client.d.ts +3 -3
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +8 -11
- package/lib/client.js.map +1 -1
- package/lib/collections/list.d.ts +95 -5
- package/lib/collections/list.d.ts.map +1 -1
- package/lib/collections/list.js +67 -5
- package/lib/collections/list.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/mergeTree.d.ts +9 -9
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +14 -6
- package/lib/mergeTree.js.map +1 -1
- package/lib/revertibles.js +1 -1
- package/lib/revertibles.js.map +1 -1
- package/lib/test/beastTest.spec.js +1 -1
- package/lib/test/beastTest.spec.js.map +1 -1
- package/lib/test/client.annotateMarker.spec.js +1 -1
- package/lib/test/client.annotateMarker.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +21 -21
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.attributionFarm.spec.js +1 -1
- package/lib/test/client.attributionFarm.spec.js.map +1 -1
- package/lib/test/client.getPosition.spec.js +1 -0
- package/lib/test/client.getPosition.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +62 -48
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.localReferenceFarm.spec.js +1 -0
- package/lib/test/client.localReferenceFarm.spec.js.map +1 -1
- package/lib/test/client.rollback.spec.js +8 -6
- package/lib/test/client.rollback.spec.js.map +1 -1
- package/lib/test/mergeTree.annotate.spec.js +25 -25
- package/lib/test/mergeTree.annotate.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +4 -4
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js +4 -4
- package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/lib/test/snapshot.utils.js +1 -1
- package/lib/test/snapshot.utils.js.map +1 -1
- package/lib/test/sortedSegmentSet.spec.js +3 -3
- package/lib/test/sortedSegmentSet.spec.js.map +1 -1
- package/lib/test/testClient.js +3 -3
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/tracking.spec.js +7 -7
- package/lib/test/tracking.spec.js.map +1 -1
- package/lib/test/wordUnitTests.spec.js.map +1 -1
- package/package.json +16 -16
- package/src/client.ts +22 -20
- package/src/collections/list.ts +101 -5
- package/src/index.ts +3 -0
- package/src/mergeTree.ts +29 -23
- package/src/revertibles.ts +1 -1
package/src/client.ts
CHANGED
|
@@ -878,17 +878,20 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
878
878
|
const useNewSlidingBehavior = true;
|
|
879
879
|
// Destructuring segment + offset is convenient and segment is reassigned
|
|
880
880
|
// eslint-disable-next-line prefer-const
|
|
881
|
-
|
|
881
|
+
const segOff = getSlideToSegoff(
|
|
882
882
|
{ segment: oldSegment, offset: oldOffset },
|
|
883
883
|
slidePreference,
|
|
884
884
|
reconnectingPerspective,
|
|
885
885
|
useNewSlidingBehavior,
|
|
886
886
|
);
|
|
887
887
|
|
|
888
|
-
newSegment
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
888
|
+
const { segment: newSegment, offset: newOffset } = segOff ?? {
|
|
889
|
+
segment:
|
|
890
|
+
slidePreference === SlidingPreference.FORWARD
|
|
891
|
+
? this._mergeTree.endOfTree
|
|
892
|
+
: this._mergeTree.startOfTree,
|
|
893
|
+
offset: 0,
|
|
894
|
+
};
|
|
892
895
|
|
|
893
896
|
assert(
|
|
894
897
|
isSegmentLeaf(newSegment) && newOffset !== undefined,
|
|
@@ -1612,10 +1615,12 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
1612
1615
|
pos: number,
|
|
1613
1616
|
sequenceArgs?: Pick<ISequencedDocumentMessage, "referenceSequenceNumber" | "clientId">,
|
|
1614
1617
|
localSeq?: number,
|
|
1615
|
-
):
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1618
|
+
):
|
|
1619
|
+
| {
|
|
1620
|
+
segment: T;
|
|
1621
|
+
offset: number;
|
|
1622
|
+
}
|
|
1623
|
+
| undefined {
|
|
1619
1624
|
let perspective: Perspective;
|
|
1620
1625
|
const clientId =
|
|
1621
1626
|
sequenceArgs === undefined
|
|
@@ -1630,20 +1635,17 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
1630
1635
|
perspective = new PriorPerspective(refSeq, clientId);
|
|
1631
1636
|
}
|
|
1632
1637
|
|
|
1633
|
-
return this._mergeTree.getContainingSegment(pos, perspective) as
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1638
|
+
return this._mergeTree.getContainingSegment(pos, perspective) as
|
|
1639
|
+
| {
|
|
1640
|
+
segment: T;
|
|
1641
|
+
offset: number;
|
|
1642
|
+
}
|
|
1643
|
+
| undefined;
|
|
1637
1644
|
}
|
|
1638
1645
|
|
|
1639
1646
|
getPropertiesAtPosition(pos: number): PropertySet | undefined {
|
|
1640
|
-
let propertiesAtPosition: PropertySet | undefined;
|
|
1641
1647
|
const segoff = this.getContainingSegment(pos);
|
|
1642
|
-
|
|
1643
|
-
if (seg) {
|
|
1644
|
-
propertiesAtPosition = seg.properties;
|
|
1645
|
-
}
|
|
1646
|
-
return propertiesAtPosition;
|
|
1648
|
+
return segoff?.segment?.properties;
|
|
1647
1649
|
}
|
|
1648
1650
|
|
|
1649
1651
|
getRangeExtentsOfPosition(pos: number): {
|
|
@@ -1654,7 +1656,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
1654
1656
|
let posAfterEnd: number | undefined;
|
|
1655
1657
|
|
|
1656
1658
|
const segoff = this.getContainingSegment(pos);
|
|
1657
|
-
const seg = segoff
|
|
1659
|
+
const seg = segoff?.segment;
|
|
1658
1660
|
if (seg) {
|
|
1659
1661
|
posStart = this.getPosition(seg);
|
|
1660
1662
|
posAfterEnd = posStart + seg.cachedLength;
|
package/src/collections/list.ts
CHANGED
|
@@ -5,15 +5,46 @@
|
|
|
5
5
|
|
|
6
6
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Represents a node in a doubly linked list.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
8
12
|
export interface ListNode<T> {
|
|
13
|
+
/**
|
|
14
|
+
* The list this node belongs to, or undefined if not attached.
|
|
15
|
+
*/
|
|
9
16
|
readonly list: DoublyLinkedList<T> | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* The data value stored in this node.
|
|
19
|
+
*/
|
|
10
20
|
readonly data: T;
|
|
21
|
+
/**
|
|
22
|
+
* The next node in the list, or undefined if this is the last node.
|
|
23
|
+
*/
|
|
11
24
|
readonly next: ListNode<T> | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* The previous node in the list, or undefined if this is the first node.
|
|
27
|
+
*/
|
|
12
28
|
readonly prev: ListNode<T> | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Removes this node from its list.
|
|
31
|
+
* @returns The removed node, or undefined if not in a list.
|
|
32
|
+
*/
|
|
33
|
+
remove(): ListNode<T> | undefined;
|
|
13
34
|
}
|
|
14
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Represents a range of nodes in a doubly linked list.
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
15
40
|
export interface ListNodeRange<T> {
|
|
41
|
+
/**
|
|
42
|
+
* The first node in the range.
|
|
43
|
+
*/
|
|
16
44
|
first: ListNode<T>;
|
|
45
|
+
/**
|
|
46
|
+
* The last node in the range.
|
|
47
|
+
*/
|
|
17
48
|
last: ListNode<T>;
|
|
18
49
|
}
|
|
19
50
|
|
|
@@ -50,6 +81,9 @@ class DataNode<T> extends HeadNode<T> implements ListNode<T> {
|
|
|
50
81
|
super(undefined);
|
|
51
82
|
this.headNode = headNode;
|
|
52
83
|
}
|
|
84
|
+
remove(): ListNode<T> | undefined {
|
|
85
|
+
return this.list?.remove(this);
|
|
86
|
+
}
|
|
53
87
|
}
|
|
54
88
|
|
|
55
89
|
function insertAfter<T>(node: DataNode<T> | HeadNode<T>, items: T[]): ListNodeRange<T> {
|
|
@@ -80,6 +114,11 @@ function insertAfter<T>(node: DataNode<T> | HeadNode<T>, items: T[]): ListNodeRa
|
|
|
80
114
|
return newRange;
|
|
81
115
|
}
|
|
82
116
|
|
|
117
|
+
/**
|
|
118
|
+
* A doubly linked list implementation with array-like methods and node access.
|
|
119
|
+
* @typeParam T - The type of data stored in the list nodes.
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
83
122
|
export class DoublyLinkedList<T>
|
|
84
123
|
implements
|
|
85
124
|
Iterable<ListNode<T>>,
|
|
@@ -87,12 +126,21 @@ export class DoublyLinkedList<T>
|
|
|
87
126
|
// try to match array signature and semantics where possible
|
|
88
127
|
Pick<ListNode<T>[], "pop" | "shift" | "length" | "includes">
|
|
89
128
|
{
|
|
129
|
+
/**
|
|
130
|
+
* Creates a new doubly linked list optionally initialized with values.
|
|
131
|
+
* @param values - Optional iterable of values to populate the list.
|
|
132
|
+
*/
|
|
90
133
|
constructor(values?: Iterable<T>) {
|
|
91
134
|
if (values !== undefined) {
|
|
92
135
|
this.push(...values);
|
|
93
136
|
}
|
|
94
137
|
}
|
|
95
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Finds the first node matching the predicate.
|
|
141
|
+
* @param predicate - Function to test each node.
|
|
142
|
+
* @returns The first matching node, or undefined if none found.
|
|
143
|
+
*/
|
|
96
144
|
find(
|
|
97
145
|
predicate: (value: ListNode<T>, obj: DoublyLinkedList<T>) => unknown,
|
|
98
146
|
): ListNode<T> | undefined {
|
|
@@ -106,6 +154,10 @@ export class DoublyLinkedList<T>
|
|
|
106
154
|
return found;
|
|
107
155
|
}
|
|
108
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Returns an iterable that maps each node to a new value.
|
|
159
|
+
* @param callbackfn - Function to produce a new value for each node.
|
|
160
|
+
*/
|
|
109
161
|
map<U>(callbackfn: (value: ListNode<T>) => U): Iterable<U> {
|
|
110
162
|
let node = this.first;
|
|
111
163
|
const iterator: IterableIterator<U> = {
|
|
@@ -124,6 +176,12 @@ export class DoublyLinkedList<T>
|
|
|
124
176
|
return iterator;
|
|
125
177
|
}
|
|
126
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Inserts items after the specified node.
|
|
181
|
+
* @param preceding - The node to insert after.
|
|
182
|
+
* @param items - Items to insert.
|
|
183
|
+
* @returns The range of newly inserted nodes.
|
|
184
|
+
*/
|
|
127
185
|
insertAfter(preceding: ListNode<T>, ...items: T[]): ListNodeRange<T> {
|
|
128
186
|
if (!this._includes(preceding)) {
|
|
129
187
|
throw new Error("preceding not in list");
|
|
@@ -132,10 +190,19 @@ export class DoublyLinkedList<T>
|
|
|
132
190
|
return insertAfter(preceding, items);
|
|
133
191
|
}
|
|
134
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Removes and returns the last node in the list.
|
|
195
|
+
* @returns The removed node, or undefined if the list is empty.
|
|
196
|
+
*/
|
|
135
197
|
pop(): ListNode<T> | undefined {
|
|
136
198
|
return this.remove(this.last);
|
|
137
199
|
}
|
|
138
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Appends items to the end of the list.
|
|
203
|
+
* @param items - Items to append.
|
|
204
|
+
* @returns The range of newly inserted nodes.
|
|
205
|
+
*/
|
|
139
206
|
push(...items: T[]): ListNodeRange<T> {
|
|
140
207
|
this._len += items.length;
|
|
141
208
|
const start = this.headNode._prev;
|
|
@@ -143,14 +210,17 @@ export class DoublyLinkedList<T>
|
|
|
143
210
|
}
|
|
144
211
|
|
|
145
212
|
/**
|
|
146
|
-
*
|
|
213
|
+
* Removes and returns the first node in the list.
|
|
214
|
+
* @returns The removed node, or undefined if the list is empty.
|
|
147
215
|
*/
|
|
148
216
|
shift(): ListNode<T> | undefined {
|
|
149
217
|
return this.remove(this.first);
|
|
150
218
|
}
|
|
151
219
|
|
|
152
220
|
/**
|
|
153
|
-
*
|
|
221
|
+
* Inserts items at the start of the list.
|
|
222
|
+
* @param items - Items to insert.
|
|
223
|
+
* @returns The range of newly inserted nodes.
|
|
154
224
|
*/
|
|
155
225
|
unshift(...items: T[]): ListNodeRange<T> {
|
|
156
226
|
this._len += items.length;
|
|
@@ -158,9 +228,10 @@ export class DoublyLinkedList<T>
|
|
|
158
228
|
}
|
|
159
229
|
|
|
160
230
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
231
|
+
* Removes nodes starting at `start` until `end` or `count` is reached.
|
|
232
|
+
* @param start - The node to start removing from.
|
|
233
|
+
* @param countOrEnd - The number of nodes to remove or the end node.
|
|
234
|
+
* @returns A new list containing the removed nodes.
|
|
164
235
|
*/
|
|
165
236
|
splice(start: ListNode<T>, countOrEnd?: ListNode<T> | number): DoublyLinkedList<T> {
|
|
166
237
|
const newList = new DoublyLinkedList<T>();
|
|
@@ -187,6 +258,11 @@ export class DoublyLinkedList<T>
|
|
|
187
258
|
return newList;
|
|
188
259
|
}
|
|
189
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Checks if the node is in this list.
|
|
263
|
+
* @param node - The node to check.
|
|
264
|
+
* @returns True if the node is in the list.
|
|
265
|
+
*/
|
|
190
266
|
public includes(node: ListNode<T> | undefined): node is ListNode<T> {
|
|
191
267
|
return this._includes(node);
|
|
192
268
|
}
|
|
@@ -207,6 +283,11 @@ export class DoublyLinkedList<T>
|
|
|
207
283
|
return undefined;
|
|
208
284
|
}
|
|
209
285
|
|
|
286
|
+
/**
|
|
287
|
+
* Removes the specified node from the list.
|
|
288
|
+
* @param node - The node to remove.
|
|
289
|
+
* @returns The removed node, or undefined if not in the list.
|
|
290
|
+
*/
|
|
210
291
|
public remove(node: ListNode<T> | undefined): ListNode<T> | undefined {
|
|
211
292
|
return this._remove(node);
|
|
212
293
|
}
|
|
@@ -231,16 +312,31 @@ export class DoublyLinkedList<T>
|
|
|
231
312
|
|
|
232
313
|
private _len: number = 0;
|
|
233
314
|
private readonly headNode: HeadNode<T> | DataNode<T> = new HeadNode(this);
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* The number of nodes in the list.
|
|
318
|
+
*/
|
|
234
319
|
public get length(): number {
|
|
235
320
|
return this._len;
|
|
236
321
|
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Whether the list is empty.
|
|
325
|
+
*/
|
|
237
326
|
public get empty(): boolean {
|
|
238
327
|
return this._len === 0;
|
|
239
328
|
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* The first node in the list, or undefined if empty.
|
|
332
|
+
*/
|
|
240
333
|
public get first(): ListNode<T> | undefined {
|
|
241
334
|
return this.headNode.next;
|
|
242
335
|
}
|
|
243
336
|
|
|
337
|
+
/**
|
|
338
|
+
* The last node in the list, or undefined if empty.
|
|
339
|
+
*/
|
|
244
340
|
public get last(): ListNode<T> | undefined {
|
|
245
341
|
return this.headNode.prev;
|
|
246
342
|
}
|
package/src/index.ts
CHANGED
package/src/mergeTree.ts
CHANGED
|
@@ -469,15 +469,17 @@ function getSlideToSegment(
|
|
|
469
469
|
* @internal
|
|
470
470
|
*/
|
|
471
471
|
export function getSlideToSegoff(
|
|
472
|
-
segoff: { segment: ISegmentInternal
|
|
472
|
+
segoff: { segment: ISegmentInternal; offset: number } | undefined,
|
|
473
473
|
slidingPreference: SlidingPreference = SlidingPreference.FORWARD,
|
|
474
474
|
perspective: Perspective = allAckedChangesPerspective,
|
|
475
475
|
useNewSlidingBehavior: boolean = false,
|
|
476
|
-
):
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
476
|
+
):
|
|
477
|
+
| {
|
|
478
|
+
segment: ISegmentInternal;
|
|
479
|
+
offset: number;
|
|
480
|
+
}
|
|
481
|
+
| undefined {
|
|
482
|
+
if (!isSegmentLeaf(segoff?.segment)) {
|
|
481
483
|
return segoff;
|
|
482
484
|
}
|
|
483
485
|
const [segment, _] = getSlideToSegment(
|
|
@@ -490,8 +492,11 @@ export function getSlideToSegoff(
|
|
|
490
492
|
if (segment === segoff.segment) {
|
|
491
493
|
return segoff;
|
|
492
494
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
+
if (segment === undefined) {
|
|
496
|
+
return undefined;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const offset = segment.ordinal < segoff.segment.ordinal ? segment.cachedLength - 1 : 0;
|
|
495
500
|
return {
|
|
496
501
|
segment,
|
|
497
502
|
offset,
|
|
@@ -849,10 +854,12 @@ export class MergeTree {
|
|
|
849
854
|
public getContainingSegment(
|
|
850
855
|
pos: number,
|
|
851
856
|
perspective: Perspective,
|
|
852
|
-
):
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
857
|
+
):
|
|
858
|
+
| {
|
|
859
|
+
segment: ISegmentLeaf;
|
|
860
|
+
offset: number;
|
|
861
|
+
}
|
|
862
|
+
| undefined {
|
|
856
863
|
assert(
|
|
857
864
|
perspective.localSeq === undefined ||
|
|
858
865
|
perspective.clientId === this.collabWindow.clientId,
|
|
@@ -868,6 +875,9 @@ export class MergeTree {
|
|
|
868
875
|
return false;
|
|
869
876
|
};
|
|
870
877
|
this.nodeMap(perspective, leaf, undefined, pos, pos + 1);
|
|
878
|
+
if (segment === undefined || offset === undefined) {
|
|
879
|
+
return undefined;
|
|
880
|
+
}
|
|
871
881
|
return { segment, offset };
|
|
872
882
|
}
|
|
873
883
|
|
|
@@ -1260,10 +1270,11 @@ export class MergeTree {
|
|
|
1260
1270
|
): Marker | undefined {
|
|
1261
1271
|
let foundMarker: Marker | undefined;
|
|
1262
1272
|
|
|
1263
|
-
const
|
|
1264
|
-
if (!isSegmentLeaf(segment)) {
|
|
1273
|
+
const segoff = this.getContainingSegment(startPos, this.localPerspective);
|
|
1274
|
+
if (!isSegmentLeaf(segoff?.segment)) {
|
|
1265
1275
|
return undefined;
|
|
1266
1276
|
}
|
|
1277
|
+
const { segment } = segoff;
|
|
1267
1278
|
|
|
1268
1279
|
depthFirstNodeWalk(
|
|
1269
1280
|
segment.parent,
|
|
@@ -1529,7 +1540,7 @@ export class MergeTree {
|
|
|
1529
1540
|
|
|
1530
1541
|
if (isSegmentLeaf(segmentInfo?.segment)) {
|
|
1531
1542
|
const segmentPosition = this.getPosition(segmentInfo.segment, this.localPerspective);
|
|
1532
|
-
return segmentPosition + segmentInfo.offset
|
|
1543
|
+
return segmentPosition + segmentInfo.offset;
|
|
1533
1544
|
} else {
|
|
1534
1545
|
if (remoteClientPosition === this.getLength(remotePerspective)) {
|
|
1535
1546
|
return this.getLength(this.localPerspective);
|
|
@@ -2085,14 +2096,9 @@ export class MergeTree {
|
|
|
2085
2096
|
const createRefFromSequencePlace = (
|
|
2086
2097
|
place: InteriorSequencePlace,
|
|
2087
2098
|
): LocalReferencePosition => {
|
|
2088
|
-
const
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
);
|
|
2092
|
-
assert(
|
|
2093
|
-
isSegmentLeaf(placeSeg) && placeOffset !== undefined,
|
|
2094
|
-
0xa3f /* segments cannot be undefined */,
|
|
2095
|
-
);
|
|
2099
|
+
const segOff = this.getContainingSegment(place.pos, perspective);
|
|
2100
|
+
assert(isSegmentLeaf(segOff?.segment), 0xa3f /* segments cannot be undefined */);
|
|
2101
|
+
const { segment: placeSeg, offset: placeOffset } = segOff;
|
|
2096
2102
|
return this.createLocalReferencePosition(
|
|
2097
2103
|
placeSeg,
|
|
2098
2104
|
placeOffset,
|
package/src/revertibles.ts
CHANGED
|
@@ -309,7 +309,7 @@ function revertLocalRemove(
|
|
|
309
309
|
const insertSegment = mergeTreeWithRevert.getContainingSegment(
|
|
310
310
|
realPos,
|
|
311
311
|
mergeTreeWithRevert.localPerspective,
|
|
312
|
-
)
|
|
312
|
+
)?.segment;
|
|
313
313
|
assertSegmentLeaf(insertSegment);
|
|
314
314
|
|
|
315
315
|
const localSlideFilter = (lref: LocalReferencePosition): boolean =>
|