@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.
Files changed (137) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +130 -0
  3. package/dist/defaultMap.d.ts +1 -1
  4. package/dist/defaultMap.d.ts.map +1 -1
  5. package/dist/defaultMap.js +6 -6
  6. package/dist/defaultMap.js.map +1 -1
  7. package/dist/defaultMapInterfaces.d.ts +21 -2
  8. package/dist/defaultMapInterfaces.d.ts.map +1 -1
  9. package/dist/defaultMapInterfaces.js.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/intervalCollection.d.ts +136 -18
  15. package/dist/intervalCollection.d.ts.map +1 -1
  16. package/dist/intervalCollection.js +120 -37
  17. package/dist/intervalCollection.js.map +1 -1
  18. package/dist/intervalIndex/endpointInRangeIndex.js +1 -1
  19. package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
  20. package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
  21. package/dist/intervalIndex/endpointIndex.js +1 -2
  22. package/dist/intervalIndex/endpointIndex.js.map +1 -1
  23. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +5 -4
  24. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  25. package/dist/intervalIndex/overlappingIntervalsIndex.js +7 -2
  26. package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  27. package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
  28. package/dist/intervalIndex/startpointInRangeIndex.js +1 -3
  29. package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
  30. package/dist/intervalTree.d.ts +1 -1
  31. package/dist/intervalTree.d.ts.map +1 -1
  32. package/dist/intervals/interval.d.ts +3 -2
  33. package/dist/intervals/interval.d.ts.map +1 -1
  34. package/dist/intervals/interval.js +12 -5
  35. package/dist/intervals/interval.js.map +1 -1
  36. package/dist/intervals/intervalUtils.d.ts +39 -18
  37. package/dist/intervals/intervalUtils.d.ts.map +1 -1
  38. package/dist/intervals/intervalUtils.js +12 -10
  39. package/dist/intervals/intervalUtils.js.map +1 -1
  40. package/dist/intervals/sequenceInterval.d.ts +23 -13
  41. package/dist/intervals/sequenceInterval.d.ts.map +1 -1
  42. package/dist/intervals/sequenceInterval.js +117 -42
  43. package/dist/intervals/sequenceInterval.js.map +1 -1
  44. package/dist/packageVersion.d.ts +1 -1
  45. package/dist/packageVersion.js +1 -1
  46. package/dist/packageVersion.js.map +1 -1
  47. package/dist/revertibles.d.ts +3 -15
  48. package/dist/revertibles.d.ts.map +1 -1
  49. package/dist/revertibles.js +6 -17
  50. package/dist/revertibles.js.map +1 -1
  51. package/dist/sequence.d.ts +1 -1
  52. package/dist/sequence.d.ts.map +1 -1
  53. package/dist/sequence.js +43 -43
  54. package/dist/sequence.js.map +1 -1
  55. package/dist/sharedIntervalCollection.js +9 -9
  56. package/dist/sharedIntervalCollection.js.map +1 -1
  57. package/dist/sharedSequence.js +6 -6
  58. package/dist/sharedSequence.js.map +1 -1
  59. package/dist/sharedString.d.ts +1 -1
  60. package/dist/sharedString.d.ts.map +1 -1
  61. package/dist/sharedString.js +5 -5
  62. package/dist/sharedString.js.map +1 -1
  63. package/dist/tsdoc-metadata.json +1 -1
  64. package/lib/defaultMap.d.ts +1 -1
  65. package/lib/defaultMap.d.ts.map +1 -1
  66. package/lib/defaultMap.js +6 -6
  67. package/lib/defaultMap.js.map +1 -1
  68. package/lib/defaultMapInterfaces.d.ts +21 -2
  69. package/lib/defaultMapInterfaces.d.ts.map +1 -1
  70. package/lib/defaultMapInterfaces.js.map +1 -1
  71. package/lib/index.d.ts +1 -1
  72. package/lib/index.d.ts.map +1 -1
  73. package/lib/index.js +1 -1
  74. package/lib/index.js.map +1 -1
  75. package/lib/intervalCollection.d.ts +136 -18
  76. package/lib/intervalCollection.d.ts.map +1 -1
  77. package/lib/intervalCollection.js +117 -37
  78. package/lib/intervalCollection.js.map +1 -1
  79. package/lib/intervalIndex/endpointInRangeIndex.js +1 -1
  80. package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -1
  81. package/lib/intervalIndex/endpointIndex.d.ts.map +1 -1
  82. package/lib/intervalIndex/endpointIndex.js +1 -2
  83. package/lib/intervalIndex/endpointIndex.js.map +1 -1
  84. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +5 -4
  85. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  86. package/lib/intervalIndex/overlappingIntervalsIndex.js +7 -2
  87. package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  88. package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
  89. package/lib/intervalIndex/startpointInRangeIndex.js +1 -3
  90. package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -1
  91. package/lib/intervalTree.d.ts +1 -1
  92. package/lib/intervalTree.d.ts.map +1 -1
  93. package/lib/intervals/interval.d.ts +3 -2
  94. package/lib/intervals/interval.d.ts.map +1 -1
  95. package/lib/intervals/interval.js +12 -5
  96. package/lib/intervals/interval.js.map +1 -1
  97. package/lib/intervals/intervalUtils.d.ts +39 -18
  98. package/lib/intervals/intervalUtils.d.ts.map +1 -1
  99. package/lib/intervals/intervalUtils.js +8 -6
  100. package/lib/intervals/intervalUtils.js.map +1 -1
  101. package/lib/intervals/sequenceInterval.d.ts +23 -13
  102. package/lib/intervals/sequenceInterval.d.ts.map +1 -1
  103. package/lib/intervals/sequenceInterval.js +118 -41
  104. package/lib/intervals/sequenceInterval.js.map +1 -1
  105. package/lib/packageVersion.d.ts +1 -1
  106. package/lib/packageVersion.js +1 -1
  107. package/lib/packageVersion.js.map +1 -1
  108. package/lib/revertibles.d.ts +3 -15
  109. package/lib/revertibles.d.ts.map +1 -1
  110. package/lib/revertibles.js +6 -17
  111. package/lib/revertibles.js.map +1 -1
  112. package/lib/sequence.d.ts +1 -1
  113. package/lib/sequence.d.ts.map +1 -1
  114. package/lib/sequence.js +43 -43
  115. package/lib/sequence.js.map +1 -1
  116. package/lib/sharedIntervalCollection.js +9 -9
  117. package/lib/sharedIntervalCollection.js.map +1 -1
  118. package/lib/sharedSequence.js +6 -6
  119. package/lib/sharedSequence.js.map +1 -1
  120. package/lib/sharedString.d.ts +1 -1
  121. package/lib/sharedString.d.ts.map +1 -1
  122. package/lib/sharedString.js +5 -5
  123. package/lib/sharedString.js.map +1 -1
  124. package/package.json +48 -20
  125. package/src/defaultMapInterfaces.ts +21 -2
  126. package/src/index.ts +3 -0
  127. package/src/intervalCollection.ts +309 -66
  128. package/src/intervalIndex/endpointInRangeIndex.ts +1 -1
  129. package/src/intervalIndex/endpointIndex.ts +1 -2
  130. package/src/intervalIndex/overlappingIntervalsIndex.ts +17 -9
  131. package/src/intervalIndex/startpointInRangeIndex.ts +1 -7
  132. package/src/intervals/interval.ts +28 -7
  133. package/src/intervals/intervalUtils.ts +47 -26
  134. package/src/intervals/sequenceInterval.ts +190 -46
  135. package/src/packageVersion.ts +1 -1
  136. package/src/revertibles.ts +8 -33
  137. 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 endpoint's position should be treated exclusively to get reasonable behavior--i.e.
48
- * an interval referring to "hello" in "hello world" should have a start position of 0 and an end
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 end of an interval is treated exclusively but cannot be greater than or equal to the
60
- * length of the associated sequence, application models which leverage interval collections should
61
- * consider inserting a marker at the end of the sequence to represent the end of the content.
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 stickiness: IntervalStickiness = IntervalStickiness.END,
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.stickiness,
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
- return compareReferencePositions(this.start, b.start);
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
- return compareReferencePositions(this.end, b.end);
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
- minReferencePosition(this.start, b.start),
237
- maxReferencePosition(this.end, b.end),
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: number,
272
- end: number,
363
+ start: SequencePlace | undefined,
364
+ end: SequencePlace | undefined,
273
365
  op?: ISequencedDocumentMessage,
274
366
  localSeq?: number,
275
- stickiness: IntervalStickiness = IntervalStickiness.END,
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 (start !== undefined) {
386
+ if (startPos !== undefined) {
288
387
  startRef = createPositionReference(
289
388
  this.client,
290
- start,
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 (end !== undefined) {
404
+ if (endPos !== undefined) {
304
405
  endRef = createPositionReference(
305
406
  this.client,
306
- end,
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(this.client, startRef, endRef, this.intervalType);
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
- segoff = client.getContainingSegment(pos, {
393
- referenceSequenceNumber: op.referenceSequenceNumber,
394
- clientId: op.clientId,
395
- });
396
- segoff = getSlideToSegoff(segoff);
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 = client.getContainingSegment(pos, undefined, localSeq);
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: number,
419
- end: number,
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
- stickiness: IntervalStickiness = IntervalStickiness.END,
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
- start,
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
- end,
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
- stickiness,
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
  };
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/sequence";
9
- export const pkgVersion = "2.0.0-internal.6.4.0";
9
+ export const pkgVersion = "2.0.0-internal.7.0.0";
@@ -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 newStart = newEndpointPosition(
541
- intervalInfo.startOffset,
542
- restoredRanges,
543
- sharedString,
544
- );
545
- const newEnd = newEndpointPosition(
546
- intervalInfo.endOffset,
547
- restoredRanges,
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