@fluidframework/sequence 2.0.0-internal.6.4.0 → 2.0.0-internal.7.0.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.
- package/CHANGELOG.md +60 -0
- package/README.md +130 -0
- package/dist/defaultMap.d.ts +1 -1
- package/dist/defaultMap.d.ts.map +1 -1
- package/dist/defaultMap.js +6 -6
- package/dist/defaultMap.js.map +1 -1
- package/dist/defaultMapInterfaces.d.ts +21 -2
- package/dist/defaultMapInterfaces.d.ts.map +1 -1
- package/dist/defaultMapInterfaces.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/intervalCollection.d.ts +136 -18
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +120 -37
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.js +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
- package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
- package/dist/intervalIndex/endpointIndex.js +1 -2
- package/dist/intervalIndex/endpointIndex.js.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +5 -4
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.js +7 -2
- package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
- package/dist/intervalIndex/startpointInRangeIndex.js +1 -3
- package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
- package/dist/intervalTree.d.ts +1 -1
- package/dist/intervalTree.d.ts.map +1 -1
- package/dist/intervals/interval.d.ts +3 -2
- package/dist/intervals/interval.d.ts.map +1 -1
- package/dist/intervals/interval.js +12 -5
- package/dist/intervals/interval.js.map +1 -1
- package/dist/intervals/intervalUtils.d.ts +39 -18
- package/dist/intervals/intervalUtils.d.ts.map +1 -1
- package/dist/intervals/intervalUtils.js +12 -10
- package/dist/intervals/intervalUtils.js.map +1 -1
- package/dist/intervals/sequenceInterval.d.ts +23 -13
- package/dist/intervals/sequenceInterval.d.ts.map +1 -1
- package/dist/intervals/sequenceInterval.js +117 -42
- package/dist/intervals/sequenceInterval.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/revertibles.d.ts +3 -15
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +6 -17
- package/dist/revertibles.js.map +1 -1
- package/dist/sequence.d.ts +1 -1
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +43 -43
- package/dist/sequence.js.map +1 -1
- package/dist/sharedIntervalCollection.js +9 -9
- package/dist/sharedIntervalCollection.js.map +1 -1
- package/dist/sharedSequence.js +6 -6
- package/dist/sharedSequence.js.map +1 -1
- package/dist/sharedString.d.ts +1 -1
- package/dist/sharedString.d.ts.map +1 -1
- package/dist/sharedString.js +5 -5
- package/dist/sharedString.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/defaultMap.d.ts +1 -1
- package/lib/defaultMap.d.ts.map +1 -1
- package/lib/defaultMap.js +6 -6
- package/lib/defaultMap.js.map +1 -1
- package/lib/defaultMapInterfaces.d.ts +21 -2
- package/lib/defaultMapInterfaces.d.ts.map +1 -1
- package/lib/defaultMapInterfaces.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/intervalCollection.d.ts +136 -18
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +117 -37
- package/lib/intervalCollection.js.map +1 -1
- package/lib/intervalIndex/endpointInRangeIndex.js +1 -1
- package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -1
- package/lib/intervalIndex/endpointIndex.d.ts.map +1 -1
- package/lib/intervalIndex/endpointIndex.js +1 -2
- package/lib/intervalIndex/endpointIndex.js.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +5 -4
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.js +7 -2
- package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
- package/lib/intervalIndex/startpointInRangeIndex.js +1 -3
- package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -1
- package/lib/intervalTree.d.ts +1 -1
- package/lib/intervalTree.d.ts.map +1 -1
- package/lib/intervals/interval.d.ts +3 -2
- package/lib/intervals/interval.d.ts.map +1 -1
- package/lib/intervals/interval.js +12 -5
- package/lib/intervals/interval.js.map +1 -1
- package/lib/intervals/intervalUtils.d.ts +39 -18
- package/lib/intervals/intervalUtils.d.ts.map +1 -1
- package/lib/intervals/intervalUtils.js +8 -6
- package/lib/intervals/intervalUtils.js.map +1 -1
- package/lib/intervals/sequenceInterval.d.ts +23 -13
- package/lib/intervals/sequenceInterval.d.ts.map +1 -1
- package/lib/intervals/sequenceInterval.js +118 -41
- package/lib/intervals/sequenceInterval.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/revertibles.d.ts +3 -15
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +6 -17
- package/lib/revertibles.js.map +1 -1
- package/lib/sequence.d.ts +1 -1
- package/lib/sequence.d.ts.map +1 -1
- package/lib/sequence.js +43 -43
- package/lib/sequence.js.map +1 -1
- package/lib/sharedIntervalCollection.js +9 -9
- package/lib/sharedIntervalCollection.js.map +1 -1
- package/lib/sharedSequence.js +6 -6
- package/lib/sharedSequence.js.map +1 -1
- package/lib/sharedString.d.ts +1 -1
- package/lib/sharedString.d.ts.map +1 -1
- package/lib/sharedString.js +5 -5
- package/lib/sharedString.js.map +1 -1
- package/package.json +48 -20
- package/src/defaultMapInterfaces.ts +21 -2
- package/src/index.ts +3 -0
- package/src/intervalCollection.ts +309 -66
- package/src/intervalIndex/endpointInRangeIndex.ts +1 -1
- package/src/intervalIndex/endpointIndex.ts +1 -2
- package/src/intervalIndex/overlappingIntervalsIndex.ts +17 -9
- package/src/intervalIndex/startpointInRangeIndex.ts +1 -7
- package/src/intervals/interval.ts +28 -7
- package/src/intervals/intervalUtils.ts +47 -26
- package/src/intervals/sequenceInterval.ts +190 -46
- package/src/packageVersion.ts +1 -1
- package/src/revertibles.ts +8 -33
- package/src/sequence.ts +2 -0
|
@@ -27,6 +27,13 @@ import {
|
|
|
27
27
|
import { assert } from "@fluidframework/core-utils";
|
|
28
28
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
29
29
|
import { UsageError } from "@fluidframework/telemetry-utils";
|
|
30
|
+
import {
|
|
31
|
+
SequencePlace,
|
|
32
|
+
Side,
|
|
33
|
+
computeStickinessFromSide,
|
|
34
|
+
endpointPosAndSide,
|
|
35
|
+
sidesFromStickiness,
|
|
36
|
+
} from "../intervalCollection";
|
|
30
37
|
import {
|
|
31
38
|
IIntervalHelpers,
|
|
32
39
|
ISerializableInterval,
|
|
@@ -39,14 +46,42 @@ import {
|
|
|
39
46
|
|
|
40
47
|
const reservedIntervalIdKey = "intervalId";
|
|
41
48
|
|
|
49
|
+
function compareSides(sideA: Side, sideB: Side): number {
|
|
50
|
+
if (sideA === sideB) {
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (sideA === Side.Before) {
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return -1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function minSide(sideA: Side, sideB: Side): Side {
|
|
62
|
+
if (sideA === Side.After && sideB === Side.After) {
|
|
63
|
+
return Side.After;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return Side.Before;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function maxSide(sideA: Side, sideB: Side): Side {
|
|
70
|
+
if (sideA === Side.Before && sideB === Side.Before) {
|
|
71
|
+
return Side.Before;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return Side.After;
|
|
75
|
+
}
|
|
76
|
+
|
|
42
77
|
/**
|
|
43
78
|
* Interval implementation whose ends are associated with positions in a mutatable sequence.
|
|
44
79
|
* As such, when content is inserted into the middle of the interval, the interval expands to
|
|
45
80
|
* include that content.
|
|
46
81
|
*
|
|
47
|
-
* @remarks The
|
|
48
|
-
* an interval referring to "hello" in "hello world"
|
|
49
|
-
* position of 5.
|
|
82
|
+
* @remarks The endpoints' positions should be treated exclusively to get
|
|
83
|
+
* reasonable behavior. E.g., an interval referring to "hello" in "hello world"
|
|
84
|
+
* should have a start position of 0 and an end position of 5.
|
|
50
85
|
*
|
|
51
86
|
* To see why, consider what happens if "llo wor" is removed from the string to make "held".
|
|
52
87
|
* The interval's startpoint remains on the "h" (it isn't altered), but the interval's endpoint
|
|
@@ -56,9 +91,15 @@ const reservedIntervalIdKey = "intervalId";
|
|
|
56
91
|
* If the interval endpoint was treated inclusively, the interval would now refer to "hel", which
|
|
57
92
|
* is undesirable.
|
|
58
93
|
*
|
|
59
|
-
* Since the
|
|
60
|
-
* length of the associated sequence,
|
|
61
|
-
*
|
|
94
|
+
* Since the endpoints of an interval are treated exclusively but cannot be greater
|
|
95
|
+
* than or equal to the length of the associated sequence, there exist special
|
|
96
|
+
* endpoint segments, "start" and "end", which represent the position immediately
|
|
97
|
+
* before or immediately after the string respectively.
|
|
98
|
+
*
|
|
99
|
+
* If a `SequenceInterval` is created on a sequence with the
|
|
100
|
+
* `mergeTreeReferencesCanSlideToEndpoint` feature flag set to true, the endpoints
|
|
101
|
+
* of the interval that are exclusive will have the ability to slide to these
|
|
102
|
+
* special endpoint segments.
|
|
62
103
|
*/
|
|
63
104
|
export class SequenceInterval implements ISerializableInterval {
|
|
64
105
|
/**
|
|
@@ -71,6 +112,20 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
71
112
|
*/
|
|
72
113
|
public propertyManager: PropertiesManager;
|
|
73
114
|
|
|
115
|
+
/**
|
|
116
|
+
* @internal
|
|
117
|
+
*/
|
|
118
|
+
public get stickiness(): IntervalStickiness {
|
|
119
|
+
const startSegment = this.start.getSegment();
|
|
120
|
+
const endSegment = this.end.getSegment();
|
|
121
|
+
return computeStickinessFromSide(
|
|
122
|
+
startSegment?.endpointType,
|
|
123
|
+
this.startSide,
|
|
124
|
+
endSegment?.endpointType,
|
|
125
|
+
this.endSide,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
74
129
|
constructor(
|
|
75
130
|
private readonly client: Client,
|
|
76
131
|
/**
|
|
@@ -85,7 +140,8 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
85
140
|
public end: LocalReferencePosition,
|
|
86
141
|
public intervalType: IntervalType,
|
|
87
142
|
props?: PropertySet,
|
|
88
|
-
public readonly
|
|
143
|
+
public readonly startSide: Side = Side.Before,
|
|
144
|
+
public readonly endSide: Side = Side.Before,
|
|
89
145
|
) {
|
|
90
146
|
this.propertyManager = new PropertiesManager();
|
|
91
147
|
this.properties = {};
|
|
@@ -137,19 +193,20 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
137
193
|
public serialize(): ISerializedInterval {
|
|
138
194
|
const startPosition = this.client.localReferencePositionToPosition(this.start);
|
|
139
195
|
const endPosition = this.client.localReferencePositionToPosition(this.end);
|
|
196
|
+
const { startSide, endSide } = sidesFromStickiness(this.stickiness);
|
|
140
197
|
const serializedInterval: ISerializedInterval = {
|
|
141
198
|
end: endPosition,
|
|
142
199
|
intervalType: this.intervalType,
|
|
143
200
|
sequenceNumber: this.client.getCurrentSeq(),
|
|
144
201
|
start: startPosition,
|
|
202
|
+
stickiness: this.stickiness,
|
|
203
|
+
startSide,
|
|
204
|
+
endSide,
|
|
145
205
|
};
|
|
146
206
|
|
|
147
207
|
if (this.properties) {
|
|
148
208
|
serializedInterval.properties = this.properties;
|
|
149
209
|
}
|
|
150
|
-
if (this.stickiness !== IntervalStickiness.END) {
|
|
151
|
-
serializedInterval.stickiness = this.stickiness;
|
|
152
|
-
}
|
|
153
210
|
|
|
154
211
|
return serializedInterval;
|
|
155
212
|
}
|
|
@@ -164,7 +221,8 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
164
221
|
this.end,
|
|
165
222
|
this.intervalType,
|
|
166
223
|
this.properties,
|
|
167
|
-
this.
|
|
224
|
+
this.startSide,
|
|
225
|
+
this.endSide,
|
|
168
226
|
);
|
|
169
227
|
}
|
|
170
228
|
|
|
@@ -197,14 +255,26 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
197
255
|
* {@inheritDoc IInterval.compareStart}
|
|
198
256
|
*/
|
|
199
257
|
public compareStart(b: SequenceInterval) {
|
|
200
|
-
|
|
258
|
+
const dist = compareReferencePositions(this.start, b.start);
|
|
259
|
+
|
|
260
|
+
if (dist === 0) {
|
|
261
|
+
return compareSides(this.startSide, b.startSide);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return dist;
|
|
201
265
|
}
|
|
202
266
|
|
|
203
267
|
/**
|
|
204
268
|
* {@inheritDoc IInterval.compareEnd}
|
|
205
269
|
*/
|
|
206
|
-
public compareEnd(b: SequenceInterval) {
|
|
207
|
-
|
|
270
|
+
public compareEnd(b: SequenceInterval): number {
|
|
271
|
+
const dist = compareReferencePositions(this.end, b.end);
|
|
272
|
+
|
|
273
|
+
if (dist === 0) {
|
|
274
|
+
return compareSides(b.endSide, this.endSide);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return dist;
|
|
208
278
|
}
|
|
209
279
|
|
|
210
280
|
/**
|
|
@@ -231,11 +301,33 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
231
301
|
* @internal
|
|
232
302
|
*/
|
|
233
303
|
public union(b: SequenceInterval) {
|
|
304
|
+
const newStart = minReferencePosition(this.start, b.start);
|
|
305
|
+
const newEnd = maxReferencePosition(this.end, b.end);
|
|
306
|
+
|
|
307
|
+
let startSide: Side;
|
|
308
|
+
|
|
309
|
+
if (this.start === b.start) {
|
|
310
|
+
startSide = minSide(this.startSide, b.startSide);
|
|
311
|
+
} else {
|
|
312
|
+
startSide = this.start === newStart ? this.startSide : b.startSide;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
let endSide: Side;
|
|
316
|
+
|
|
317
|
+
if (this.end === b.end) {
|
|
318
|
+
endSide = maxSide(this.endSide, b.endSide);
|
|
319
|
+
} else {
|
|
320
|
+
endSide = this.end === newEnd ? this.endSide : b.endSide;
|
|
321
|
+
}
|
|
322
|
+
|
|
234
323
|
return new SequenceInterval(
|
|
235
324
|
this.client,
|
|
236
|
-
|
|
237
|
-
|
|
325
|
+
newStart,
|
|
326
|
+
newEnd,
|
|
238
327
|
this.intervalType,
|
|
328
|
+
undefined,
|
|
329
|
+
startSide,
|
|
330
|
+
endSide,
|
|
239
331
|
);
|
|
240
332
|
}
|
|
241
333
|
|
|
@@ -268,12 +360,19 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
268
360
|
*/
|
|
269
361
|
public modify(
|
|
270
362
|
label: string,
|
|
271
|
-
start:
|
|
272
|
-
end:
|
|
363
|
+
start: SequencePlace | undefined,
|
|
364
|
+
end: SequencePlace | undefined,
|
|
273
365
|
op?: ISequencedDocumentMessage,
|
|
274
366
|
localSeq?: number,
|
|
275
|
-
|
|
367
|
+
useNewSlidingBehavior: boolean = false,
|
|
276
368
|
) {
|
|
369
|
+
const { startSide, endSide, startPos, endPos } = endpointPosAndSide(start, end);
|
|
370
|
+
const stickiness = computeStickinessFromSide(
|
|
371
|
+
startPos ?? this.start.getSegment()?.endpointType,
|
|
372
|
+
startSide ?? this.startSide,
|
|
373
|
+
endPos ?? this.end.getSegment()?.endpointType,
|
|
374
|
+
endSide ?? this.endSide,
|
|
375
|
+
);
|
|
277
376
|
const getRefType = (baseType: ReferenceType): ReferenceType => {
|
|
278
377
|
let refType = baseType;
|
|
279
378
|
if (op === undefined) {
|
|
@@ -284,15 +383,17 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
284
383
|
};
|
|
285
384
|
|
|
286
385
|
let startRef = this.start;
|
|
287
|
-
if (
|
|
386
|
+
if (startPos !== undefined) {
|
|
288
387
|
startRef = createPositionReference(
|
|
289
388
|
this.client,
|
|
290
|
-
|
|
389
|
+
startPos,
|
|
291
390
|
getRefType(this.start.refType),
|
|
292
391
|
op,
|
|
293
392
|
undefined,
|
|
294
393
|
localSeq,
|
|
295
394
|
startReferenceSlidingPreference(stickiness),
|
|
395
|
+
startReferenceSlidingPreference(stickiness) === SlidingPreference.BACKWARD,
|
|
396
|
+
useNewSlidingBehavior,
|
|
296
397
|
);
|
|
297
398
|
if (this.start.properties) {
|
|
298
399
|
startRef.addProperties(this.start.properties);
|
|
@@ -300,22 +401,32 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
300
401
|
}
|
|
301
402
|
|
|
302
403
|
let endRef = this.end;
|
|
303
|
-
if (
|
|
404
|
+
if (endPos !== undefined) {
|
|
304
405
|
endRef = createPositionReference(
|
|
305
406
|
this.client,
|
|
306
|
-
|
|
407
|
+
endPos,
|
|
307
408
|
getRefType(this.end.refType),
|
|
308
409
|
op,
|
|
309
410
|
undefined,
|
|
310
411
|
localSeq,
|
|
311
412
|
endReferenceSlidingPreference(stickiness),
|
|
413
|
+
endReferenceSlidingPreference(stickiness) === SlidingPreference.FORWARD,
|
|
414
|
+
useNewSlidingBehavior,
|
|
312
415
|
);
|
|
313
416
|
if (this.end.properties) {
|
|
314
417
|
endRef.addProperties(this.end.properties);
|
|
315
418
|
}
|
|
316
419
|
}
|
|
317
420
|
|
|
318
|
-
const newInterval = new SequenceInterval(
|
|
421
|
+
const newInterval = new SequenceInterval(
|
|
422
|
+
this.client,
|
|
423
|
+
startRef,
|
|
424
|
+
endRef,
|
|
425
|
+
this.intervalType,
|
|
426
|
+
undefined,
|
|
427
|
+
startSide ?? this.startSide,
|
|
428
|
+
endSide ?? this.endSide,
|
|
429
|
+
);
|
|
319
430
|
if (this.properties) {
|
|
320
431
|
newInterval.initializeProperties();
|
|
321
432
|
this.propertyManager.copyTo(
|
|
@@ -339,13 +450,25 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
339
450
|
|
|
340
451
|
export function createPositionReferenceFromSegoff(
|
|
341
452
|
client: Client,
|
|
342
|
-
segoff: { segment: ISegment | undefined; offset: number | undefined },
|
|
453
|
+
segoff: { segment: ISegment | undefined; offset: number | undefined } | "start" | "end",
|
|
343
454
|
refType: ReferenceType,
|
|
344
455
|
op?: ISequencedDocumentMessage,
|
|
345
456
|
localSeq?: number,
|
|
346
457
|
fromSnapshot?: boolean,
|
|
347
458
|
slidingPreference?: SlidingPreference,
|
|
459
|
+
canSlideToEndpoint?: boolean,
|
|
348
460
|
): LocalReferencePosition {
|
|
461
|
+
if (segoff === "start" || segoff === "end") {
|
|
462
|
+
return client.createLocalReferencePosition(
|
|
463
|
+
segoff,
|
|
464
|
+
undefined,
|
|
465
|
+
refType,
|
|
466
|
+
undefined,
|
|
467
|
+
slidingPreference,
|
|
468
|
+
canSlideToEndpoint,
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
349
472
|
if (segoff.segment) {
|
|
350
473
|
const ref = client.createLocalReferencePosition(
|
|
351
474
|
segoff.segment,
|
|
@@ -353,6 +476,7 @@ export function createPositionReferenceFromSegoff(
|
|
|
353
476
|
refType,
|
|
354
477
|
undefined,
|
|
355
478
|
slidingPreference,
|
|
479
|
+
canSlideToEndpoint,
|
|
356
480
|
);
|
|
357
481
|
return ref;
|
|
358
482
|
}
|
|
@@ -376,30 +500,40 @@ export function createPositionReferenceFromSegoff(
|
|
|
376
500
|
|
|
377
501
|
function createPositionReference(
|
|
378
502
|
client: Client,
|
|
379
|
-
pos: number,
|
|
503
|
+
pos: number | "start" | "end",
|
|
380
504
|
refType: ReferenceType,
|
|
381
505
|
op?: ISequencedDocumentMessage,
|
|
382
506
|
fromSnapshot?: boolean,
|
|
383
507
|
localSeq?: number,
|
|
384
508
|
slidingPreference?: SlidingPreference,
|
|
509
|
+
exclusive: boolean = false,
|
|
510
|
+
useNewSlidingBehavior: boolean = false,
|
|
385
511
|
): LocalReferencePosition {
|
|
386
512
|
let segoff;
|
|
513
|
+
|
|
387
514
|
if (op) {
|
|
388
515
|
assert(
|
|
389
516
|
(refType & ReferenceType.SlideOnRemove) !== 0,
|
|
390
517
|
0x2f5 /* op create references must be SlideOnRemove */,
|
|
391
518
|
);
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
519
|
+
if (pos === "start" || pos === "end") {
|
|
520
|
+
segoff = pos;
|
|
521
|
+
} else {
|
|
522
|
+
segoff = client.getContainingSegment(pos, {
|
|
523
|
+
referenceSequenceNumber: op.referenceSequenceNumber,
|
|
524
|
+
clientId: op.clientId,
|
|
525
|
+
});
|
|
526
|
+
segoff = getSlideToSegoff(segoff, undefined, useNewSlidingBehavior);
|
|
527
|
+
}
|
|
397
528
|
} else {
|
|
398
529
|
assert(
|
|
399
530
|
(refType & ReferenceType.SlideOnRemove) === 0 || !!fromSnapshot,
|
|
400
531
|
0x2f6 /* SlideOnRemove references must be op created */,
|
|
401
532
|
);
|
|
402
|
-
segoff =
|
|
533
|
+
segoff =
|
|
534
|
+
pos === "start" || pos === "end"
|
|
535
|
+
? pos
|
|
536
|
+
: client.getContainingSegment(pos, undefined, localSeq);
|
|
403
537
|
}
|
|
404
538
|
|
|
405
539
|
return createPositionReferenceFromSegoff(
|
|
@@ -410,19 +544,32 @@ function createPositionReference(
|
|
|
410
544
|
localSeq,
|
|
411
545
|
fromSnapshot,
|
|
412
546
|
slidingPreference,
|
|
547
|
+
exclusive,
|
|
413
548
|
);
|
|
414
549
|
}
|
|
415
550
|
|
|
416
551
|
export function createSequenceInterval(
|
|
417
552
|
label: string,
|
|
418
|
-
start:
|
|
419
|
-
end:
|
|
553
|
+
start: SequencePlace | undefined,
|
|
554
|
+
end: SequencePlace | undefined,
|
|
420
555
|
client: Client,
|
|
421
556
|
intervalType: IntervalType,
|
|
422
557
|
op?: ISequencedDocumentMessage,
|
|
423
558
|
fromSnapshot?: boolean,
|
|
424
|
-
|
|
559
|
+
useNewSlidingBehavior: boolean = false,
|
|
425
560
|
): SequenceInterval {
|
|
561
|
+
const { startPos, startSide, endPos, endSide } = endpointPosAndSide(
|
|
562
|
+
start ?? "start",
|
|
563
|
+
end ?? "end",
|
|
564
|
+
);
|
|
565
|
+
assert(
|
|
566
|
+
startPos !== undefined &&
|
|
567
|
+
endPos !== undefined &&
|
|
568
|
+
startSide !== undefined &&
|
|
569
|
+
endSide !== undefined,
|
|
570
|
+
0x794 /* start and end cannot be undefined because they were not passed in as undefined */,
|
|
571
|
+
);
|
|
572
|
+
const stickiness = computeStickinessFromSide(startPos, startSide, endPos, endSide);
|
|
426
573
|
let beginRefType = ReferenceType.RangeBegin;
|
|
427
574
|
let endRefType = ReferenceType.RangeEnd;
|
|
428
575
|
if (intervalType === IntervalType.Transient) {
|
|
@@ -447,22 +594,26 @@ export function createSequenceInterval(
|
|
|
447
594
|
|
|
448
595
|
const startLref = createPositionReference(
|
|
449
596
|
client,
|
|
450
|
-
|
|
597
|
+
startPos,
|
|
451
598
|
beginRefType,
|
|
452
599
|
op,
|
|
453
600
|
fromSnapshot,
|
|
454
601
|
undefined,
|
|
455
602
|
startReferenceSlidingPreference(stickiness),
|
|
603
|
+
startReferenceSlidingPreference(stickiness) === SlidingPreference.BACKWARD,
|
|
604
|
+
useNewSlidingBehavior,
|
|
456
605
|
);
|
|
457
606
|
|
|
458
607
|
const endLref = createPositionReference(
|
|
459
608
|
client,
|
|
460
|
-
|
|
609
|
+
endPos,
|
|
461
610
|
endRefType,
|
|
462
611
|
op,
|
|
463
612
|
fromSnapshot,
|
|
464
613
|
undefined,
|
|
465
614
|
endReferenceSlidingPreference(stickiness),
|
|
615
|
+
endReferenceSlidingPreference(stickiness) === SlidingPreference.FORWARD,
|
|
616
|
+
useNewSlidingBehavior,
|
|
466
617
|
);
|
|
467
618
|
|
|
468
619
|
const rangeProp = {
|
|
@@ -477,22 +628,15 @@ export function createSequenceInterval(
|
|
|
477
628
|
endLref,
|
|
478
629
|
intervalType,
|
|
479
630
|
rangeProp,
|
|
480
|
-
|
|
631
|
+
startSide,
|
|
632
|
+
endSide,
|
|
481
633
|
);
|
|
482
634
|
return ival;
|
|
483
635
|
}
|
|
484
636
|
|
|
485
|
-
export const compareSequenceIntervalEnds = (a: SequenceInterval, b: SequenceInterval): number =>
|
|
486
|
-
compareReferencePositions(a.end, b.end);
|
|
487
|
-
|
|
488
|
-
export const compareSequenceIntervalStarts = (a: SequenceInterval, b: SequenceInterval): number =>
|
|
489
|
-
compareReferencePositions(a.start, b.start);
|
|
490
|
-
|
|
491
637
|
/**
|
|
492
638
|
* @deprecated The methods within have substitutions
|
|
493
639
|
*/
|
|
494
640
|
export const sequenceIntervalHelpers: IIntervalHelpers<SequenceInterval> = {
|
|
495
|
-
compareEnds: compareSequenceIntervalEnds,
|
|
496
|
-
compareStarts: compareSequenceIntervalStarts,
|
|
497
641
|
create: createSequenceInterval,
|
|
498
642
|
};
|
package/src/packageVersion.ts
CHANGED
package/src/revertibles.ts
CHANGED
|
@@ -27,9 +27,6 @@ import { ISequenceDeltaRange, SequenceDeltaEvent } from "./sequenceDeltaEvent";
|
|
|
27
27
|
/**
|
|
28
28
|
* Data for undoing edits on SharedStrings and Intervals.
|
|
29
29
|
*
|
|
30
|
-
* Revertibles are new and require the option mergeTreeUseNewLengthCalculations to
|
|
31
|
-
* be set as true on the underlying merge tree in order to function correctly.
|
|
32
|
-
*
|
|
33
30
|
* @alpha
|
|
34
31
|
*/
|
|
35
32
|
export type SharedStringRevertible = MergeTreeDeltaRevertible | IntervalRevertible;
|
|
@@ -41,9 +38,6 @@ type IntervalOpType = typeof IntervalOpType[keyof typeof IntervalOpType];
|
|
|
41
38
|
/**
|
|
42
39
|
* Data for undoing edits affecting Intervals.
|
|
43
40
|
*
|
|
44
|
-
* Revertibles are new and require the option mergeTreeUseNewLengthCalculations to
|
|
45
|
-
* be set as true on the underlying merge tree in order to function correctly.
|
|
46
|
-
*
|
|
47
41
|
* @alpha
|
|
48
42
|
*/
|
|
49
43
|
export type IntervalRevertible =
|
|
@@ -271,9 +265,6 @@ function addIfRevertibleRef(
|
|
|
271
265
|
* Create revertibles for SharedStringDeltas, handling indirectly modified intervals
|
|
272
266
|
* (e.g. reverting remove of a range that contains an interval will move the interval back)
|
|
273
267
|
*
|
|
274
|
-
* Revertibles are new and require the option mergeTreeUseNewLengthCalculations to
|
|
275
|
-
* be set as true on the underlying merge tree in order to function correctly.
|
|
276
|
-
*
|
|
277
268
|
* @alpha
|
|
278
269
|
*/
|
|
279
270
|
export function appendSharedStringDeltaToRevertibles(
|
|
@@ -537,27 +528,14 @@ function revertLocalSequenceRemove(
|
|
|
537
528
|
const intervalId = getUpdatedId(intervalInfo.intervalId);
|
|
538
529
|
const interval = intervalCollection.getIntervalById(intervalId);
|
|
539
530
|
if (interval !== undefined) {
|
|
540
|
-
const
|
|
541
|
-
intervalInfo.startOffset,
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
sharedString,
|
|
549
|
-
);
|
|
550
|
-
// only move interval if start <= end
|
|
551
|
-
if (
|
|
552
|
-
(newStart === undefined &&
|
|
553
|
-
newEnd !== undefined &&
|
|
554
|
-
sharedString.localReferencePositionToPosition(interval.start) <= newEnd) ||
|
|
555
|
-
(newEnd === undefined &&
|
|
556
|
-
newStart !== undefined &&
|
|
557
|
-
sharedString.localReferencePositionToPosition(interval.end) >= newStart) ||
|
|
558
|
-
(newStart !== undefined && newEnd !== undefined && newStart <= newEnd)
|
|
559
|
-
) {
|
|
560
|
-
intervalCollection.change(intervalId, newStart, newEnd);
|
|
531
|
+
const start =
|
|
532
|
+
newEndpointPosition(intervalInfo.startOffset, restoredRanges, sharedString) ??
|
|
533
|
+
sharedString.localReferencePositionToPosition(interval.start);
|
|
534
|
+
const end =
|
|
535
|
+
newEndpointPosition(intervalInfo.endOffset, restoredRanges, sharedString) ??
|
|
536
|
+
sharedString.localReferencePositionToPosition(interval.end);
|
|
537
|
+
if (start <= end) {
|
|
538
|
+
intervalCollection.change(intervalId, start, end);
|
|
561
539
|
}
|
|
562
540
|
}
|
|
563
541
|
});
|
|
@@ -597,9 +575,6 @@ function revertLocalSequenceRemove(
|
|
|
597
575
|
/**
|
|
598
576
|
* Invoke revertibles to reverse prior edits
|
|
599
577
|
*
|
|
600
|
-
* Revertibles are new and require the option mergeTreeUseNewLengthCalculations to
|
|
601
|
-
* be set as true on the underlying merge tree in order to function correctly.
|
|
602
|
-
*
|
|
603
578
|
* @alpha
|
|
604
579
|
*/
|
|
605
580
|
export function revertSharedStringRevertibles(
|
package/src/sequence.ts
CHANGED
|
@@ -340,6 +340,7 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
340
340
|
refType: ReferenceType,
|
|
341
341
|
properties: PropertySet | undefined,
|
|
342
342
|
slidingPreference?: SlidingPreference,
|
|
343
|
+
canSlideToEndpoint?: boolean,
|
|
343
344
|
): LocalReferencePosition {
|
|
344
345
|
return this.client.createLocalReferencePosition(
|
|
345
346
|
segment,
|
|
@@ -347,6 +348,7 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
347
348
|
refType,
|
|
348
349
|
properties,
|
|
349
350
|
slidingPreference,
|
|
351
|
+
canSlideToEndpoint,
|
|
350
352
|
);
|
|
351
353
|
}
|
|
352
354
|
|