@fluidframework/sequence 1.2.7 → 2.0.0-dev.1.3.0.96595

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 (73) hide show
  1. package/.mocharc.js +12 -0
  2. package/README.md +19 -18
  3. package/dist/index.d.ts +2 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +3 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/intervalCollection.d.ts +39 -17
  8. package/dist/intervalCollection.d.ts.map +1 -1
  9. package/dist/intervalCollection.js +108 -67
  10. package/dist/intervalCollection.js.map +1 -1
  11. package/dist/packageVersion.d.ts +1 -1
  12. package/dist/packageVersion.d.ts.map +1 -1
  13. package/dist/packageVersion.js +1 -1
  14. package/dist/packageVersion.js.map +1 -1
  15. package/dist/sequence.d.ts +13 -22
  16. package/dist/sequence.d.ts.map +1 -1
  17. package/dist/sequence.js +11 -32
  18. package/dist/sequence.js.map +1 -1
  19. package/dist/sequenceDeltaEvent.d.ts +0 -6
  20. package/dist/sequenceDeltaEvent.d.ts.map +1 -1
  21. package/dist/sequenceDeltaEvent.js +0 -1
  22. package/dist/sequenceDeltaEvent.js.map +1 -1
  23. package/dist/sharedIntervalCollection.d.ts +5 -5
  24. package/dist/sharedIntervalCollection.js +5 -5
  25. package/dist/sharedIntervalCollection.js.map +1 -1
  26. package/dist/sharedString.d.ts +30 -1
  27. package/dist/sharedString.d.ts.map +1 -1
  28. package/dist/sharedString.js +40 -5
  29. package/dist/sharedString.js.map +1 -1
  30. package/dist/sparsematrix.d.ts +28 -15
  31. package/dist/sparsematrix.d.ts.map +1 -1
  32. package/dist/sparsematrix.js +24 -13
  33. package/dist/sparsematrix.js.map +1 -1
  34. package/lib/index.d.ts +2 -2
  35. package/lib/index.d.ts.map +1 -1
  36. package/lib/index.js +2 -2
  37. package/lib/index.js.map +1 -1
  38. package/lib/intervalCollection.d.ts +39 -17
  39. package/lib/intervalCollection.d.ts.map +1 -1
  40. package/lib/intervalCollection.js +107 -67
  41. package/lib/intervalCollection.js.map +1 -1
  42. package/lib/packageVersion.d.ts +1 -1
  43. package/lib/packageVersion.d.ts.map +1 -1
  44. package/lib/packageVersion.js +1 -1
  45. package/lib/packageVersion.js.map +1 -1
  46. package/lib/sequence.d.ts +13 -22
  47. package/lib/sequence.d.ts.map +1 -1
  48. package/lib/sequence.js +12 -33
  49. package/lib/sequence.js.map +1 -1
  50. package/lib/sequenceDeltaEvent.d.ts +0 -6
  51. package/lib/sequenceDeltaEvent.d.ts.map +1 -1
  52. package/lib/sequenceDeltaEvent.js +0 -1
  53. package/lib/sequenceDeltaEvent.js.map +1 -1
  54. package/lib/sharedIntervalCollection.d.ts +5 -5
  55. package/lib/sharedIntervalCollection.js +5 -5
  56. package/lib/sharedIntervalCollection.js.map +1 -1
  57. package/lib/sharedString.d.ts +30 -1
  58. package/lib/sharedString.d.ts.map +1 -1
  59. package/lib/sharedString.js +38 -4
  60. package/lib/sharedString.js.map +1 -1
  61. package/lib/sparsematrix.d.ts +28 -15
  62. package/lib/sparsematrix.d.ts.map +1 -1
  63. package/lib/sparsematrix.js +24 -13
  64. package/lib/sparsematrix.js.map +1 -1
  65. package/package.json +70 -25
  66. package/src/index.ts +3 -1
  67. package/src/intervalCollection.ts +169 -85
  68. package/src/packageVersion.ts +1 -1
  69. package/src/sequence.ts +12 -41
  70. package/src/sequenceDeltaEvent.ts +0 -7
  71. package/src/sharedIntervalCollection.ts +5 -5
  72. package/src/sharedString.ts +44 -6
  73. package/src/sparsematrix.ts +48 -35
@@ -15,7 +15,7 @@ var __rest = (this && this.__rest) || function (s, e) {
15
15
  return t;
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.IntervalCollection = exports.IntervalCollectionIterator = exports.IntervalCollectionValueType = exports.SequenceIntervalCollectionValueType = exports.LocalIntervalCollection = exports.createIntervalIndex = exports.defaultIntervalConflictResolver = exports.SequenceInterval = exports.Interval = exports.IntervalType = void 0;
18
+ exports.intervalLocatorFromEndpoint = exports.IntervalCollection = exports.IntervalCollectionIterator = exports.IntervalCollectionValueType = exports.SequenceIntervalCollectionValueType = exports.LocalIntervalCollection = exports.createIntervalIndex = exports.defaultIntervalConflictResolver = exports.SequenceInterval = exports.Interval = exports.IntervalType = void 0;
19
19
  /* eslint-disable no-bitwise */
20
20
  const common_utils_1 = require("@fluidframework/common-utils");
21
21
  const container_utils_1 = require("@fluidframework/container-utils");
@@ -35,8 +35,8 @@ var IntervalType;
35
35
  */
36
36
  IntervalType[IntervalType["SlideOnRemove"] = 2] = "SlideOnRemove";
37
37
  /**
38
- * @internal
39
38
  * A temporary interval, used internally
39
+ * @internal
40
40
  */
41
41
  IntervalType[IntervalType["Transient"] = 4] = "Transient";
42
42
  })(IntervalType = exports.IntervalType || (exports.IntervalType = {}));
@@ -50,7 +50,7 @@ function decompressInterval(interval, label) {
50
50
  end: interval[1],
51
51
  sequenceNumber: interval[2],
52
52
  intervalType: interval[3],
53
- properties: Object.assign(Object.assign({}, interval[4]), { [merge_tree_1.reservedRangeLabelsKey]: label }),
53
+ properties: Object.assign(Object.assign({}, interval[4]), { [merge_tree_1.reservedRangeLabelsKey]: [label] }),
54
54
  };
55
55
  }
56
56
  /**
@@ -95,10 +95,8 @@ class Interval {
95
95
  this.auxProps.push(props);
96
96
  }
97
97
  serialize(client) {
98
- let seq = 0;
99
- if (client) {
100
- seq = client.getCurrentSeq();
101
- }
98
+ var _a;
99
+ const seq = (_a = client === null || client === void 0 ? void 0 : client.getCurrentSeq()) !== null && _a !== void 0 ? _a : 0;
102
100
  const serializedInterval = {
103
101
  end: this.end,
104
102
  intervalType: 0,
@@ -184,7 +182,8 @@ class Interval {
184
182
  }
185
183
  exports.Interval = Interval;
186
184
  class SequenceInterval {
187
- constructor(start, end, intervalType, props) {
185
+ constructor(client, start, end, intervalType, props) {
186
+ this.client = client;
188
187
  this.start = start;
189
188
  this.end = end;
190
189
  this.intervalType = intervalType;
@@ -195,8 +194,8 @@ class SequenceInterval {
195
194
  }
196
195
  }
197
196
  /**
198
- * @internal
199
197
  * Subscribes to position change events on this interval if there are no current listeners.
198
+ * @internal
200
199
  */
201
200
  addPositionChangeListeners(beforePositionChange, afterPositionChange) {
202
201
  var _a, _b;
@@ -213,8 +212,8 @@ class SequenceInterval {
213
212
  }
214
213
  }
215
214
  /**
216
- * @internal
217
215
  * Removes the currently subscribed position change listeners.
216
+ * @internal
218
217
  */
219
218
  removePositionChangeListeners() {
220
219
  if (this.callbacks) {
@@ -224,8 +223,8 @@ class SequenceInterval {
224
223
  }
225
224
  }
226
225
  serialize(client) {
227
- const startPosition = this.start.toPosition();
228
- const endPosition = this.end.toPosition();
226
+ const startPosition = client.localReferencePositionToPosition(this.start);
227
+ const endPosition = client.localReferencePositionToPosition(this.end);
229
228
  const serializedInterval = {
230
229
  end: endPosition,
231
230
  intervalType: this.intervalType,
@@ -238,7 +237,7 @@ class SequenceInterval {
238
237
  return serializedInterval;
239
238
  }
240
239
  clone() {
241
- return new SequenceInterval(this.start, this.end, this.intervalType, this.properties);
240
+ return new SequenceInterval(this.client, this.start, this.end, this.intervalType, this.properties);
242
241
  }
243
242
  compare(b) {
244
243
  const startResult = this.compareStart(b);
@@ -264,14 +263,14 @@ class SequenceInterval {
264
263
  }
265
264
  }
266
265
  compareStart(b) {
267
- return this.start.compare(b.start);
266
+ return (0, merge_tree_1.compareReferencePositions)(this.start, b.start);
268
267
  }
269
268
  compareEnd(b) {
270
- return this.end.compare(b.end);
269
+ return (0, merge_tree_1.compareReferencePositions)(this.end, b.end);
271
270
  }
272
271
  overlaps(b) {
273
- const result = (this.start.compare(b.end) <= 0) &&
274
- (this.end.compare(b.start) >= 0);
272
+ const result = ((0, merge_tree_1.compareReferencePositions)(this.start, b.end) <= 0) &&
273
+ ((0, merge_tree_1.compareReferencePositions)(this.end, b.start) >= 0);
275
274
  return result;
276
275
  }
277
276
  getIntervalId() {
@@ -283,18 +282,18 @@ class SequenceInterval {
283
282
  return `${id}`;
284
283
  }
285
284
  union(b) {
286
- return new SequenceInterval(this.start.min(b.start), this.end.max(b.end), this.intervalType);
285
+ return new SequenceInterval(this.client, (0, merge_tree_1.minReferencePosition)(this.start, b.start), (0, merge_tree_1.maxReferencePosition)(this.end, b.end), this.intervalType);
287
286
  }
288
287
  addProperties(newProps, collab = false, seq, op) {
289
288
  this.initializeProperties();
290
289
  return this.propertyManager.addProperties(this.properties, newProps, op, seq, collab);
291
290
  }
292
291
  overlapsPos(bstart, bend) {
293
- const startPos = this.start.toPosition();
294
- const endPos = this.start.toPosition();
292
+ const startPos = this.client.localReferencePositionToPosition(this.start);
293
+ const endPos = this.client.localReferencePositionToPosition(this.end);
295
294
  return (endPos > bstart) && (startPos < bend);
296
295
  }
297
- modify(label, start, end, op) {
296
+ modify(label, start, end, op, localSeq) {
298
297
  const getRefType = (baseType) => {
299
298
  let refType = baseType;
300
299
  if (op === undefined) {
@@ -305,17 +304,15 @@ class SequenceInterval {
305
304
  };
306
305
  let startRef = this.start;
307
306
  if (start !== undefined) {
308
- startRef = createPositionReference(this.start.getClient(), start, getRefType(this.start.refType), op);
307
+ startRef = createPositionReference(this.client, start, getRefType(this.start.refType), op, undefined, localSeq);
309
308
  startRef.addProperties(this.start.properties);
310
309
  }
311
310
  let endRef = this.end;
312
311
  if (end !== undefined) {
313
- endRef = createPositionReference(this.end.getClient(), end, getRefType(this.end.refType), op);
312
+ endRef = createPositionReference(this.client, end, getRefType(this.end.refType), op, undefined, localSeq);
314
313
  endRef.addProperties(this.end.properties);
315
314
  }
316
- startRef.pairedRef = endRef;
317
- endRef.pairedRef = startRef;
318
- const newInterval = new SequenceInterval(startRef, endRef, this.intervalType);
315
+ const newInterval = new SequenceInterval(this.client, startRef, endRef, this.intervalType);
319
316
  if (this.properties) {
320
317
  newInterval.initializeProperties();
321
318
  this.propertyManager.copyTo(this.properties, newInterval.properties, newInterval.propertyManager);
@@ -337,14 +334,13 @@ function createPositionReferenceFromSegoff(client, segoff, refType, op) {
337
334
  const ref = client.createLocalReferencePosition(segoff.segment, segoff.offset, refType, undefined);
338
335
  return ref;
339
336
  }
340
- else {
341
- if (!op && !(0, merge_tree_1.refTypeIncludesFlag)(refType, merge_tree_1.ReferenceType.Transient)) {
342
- throw new container_utils_1.UsageError("Non-transient references need segment");
343
- }
344
- return new merge_tree_1.LocalReference(client, undefined, 0, refType);
337
+ if (!op && !(0, merge_tree_1.refTypeIncludesFlag)(refType, merge_tree_1.ReferenceType.Transient)) {
338
+ // reference to segment that dne locally
339
+ throw new container_utils_1.UsageError("Non-transient references need segment");
345
340
  }
341
+ return (0, merge_tree_1.createDetachedLocalReferencePosition)(refType);
346
342
  }
347
- function createPositionReference(client, pos, refType, op, fromSnapshot) {
343
+ function createPositionReference(client, pos, refType, op, fromSnapshot, localSeq) {
348
344
  let segoff;
349
345
  if (op) {
350
346
  (0, common_utils_1.assert)((refType & merge_tree_1.ReferenceType.SlideOnRemove) !== 0, 0x2f5 /* op create references must be SlideOnRemove */);
@@ -353,7 +349,7 @@ function createPositionReference(client, pos, refType, op, fromSnapshot) {
353
349
  }
354
350
  else {
355
351
  (0, common_utils_1.assert)((refType & merge_tree_1.ReferenceType.SlideOnRemove) === 0 || fromSnapshot, 0x2f6 /* SlideOnRemove references must be op created */);
356
- segoff = client.getContainingSegment(pos);
352
+ segoff = client.getContainingSegment(pos, undefined, localSeq);
357
353
  }
358
354
  return createPositionReferenceFromSegoff(client, segoff, refType, op);
359
355
  }
@@ -383,14 +379,12 @@ function createSequenceInterval(label, start, end, client, intervalType, op, fro
383
379
  }
384
380
  const startLref = createPositionReference(client, start, beginRefType, op, fromSnapshot);
385
381
  const endLref = createPositionReference(client, end, endRefType, op, fromSnapshot);
386
- startLref.pairedRef = endLref;
387
- endLref.pairedRef = startLref;
388
382
  const rangeProp = {
389
383
  [merge_tree_1.reservedRangeLabelsKey]: [label],
390
384
  };
391
385
  startLref.addProperties(rangeProp);
392
386
  endLref.addProperties(rangeProp);
393
- const ival = new SequenceInterval(startLref, endLref, intervalType, rangeProp);
387
+ const ival = new SequenceInterval(client, startLref, endLref, intervalType, rangeProp);
394
388
  return ival;
395
389
  }
396
390
  function defaultIntervalConflictResolver(a, b) {
@@ -579,6 +573,8 @@ class LocalIntervalCollection {
579
573
  return this.helpers.create(this.label, start, end, this.client, intervalType, op);
580
574
  }
581
575
  addInterval(start, end, intervalType, props, op) {
576
+ var _a;
577
+ var _b;
582
578
  const interval = this.createInterval(start, end, intervalType, op);
583
579
  if (interval) {
584
580
  if (!interval.properties) {
@@ -587,14 +583,17 @@ class LocalIntervalCollection {
587
583
  if (props) {
588
584
  interval.addProperties(props);
589
585
  }
590
- if (interval.properties[reservedIntervalIdKey] === undefined) {
591
- // Create a new ID.
592
- interval.properties[reservedIntervalIdKey] = (0, uuid_1.v4)();
593
- }
586
+ (_a = (_b = interval.properties)[reservedIntervalIdKey]) !== null && _a !== void 0 ? _a : (_b[reservedIntervalIdKey] = (0, uuid_1.v4)());
594
587
  this.add(interval);
595
588
  }
596
589
  return interval;
597
590
  }
591
+ linkEndpointsToInterval(interval) {
592
+ if (interval instanceof SequenceInterval) {
593
+ interval.start.addProperties({ interval });
594
+ interval.end.addProperties({ interval });
595
+ }
596
+ }
598
597
  addIntervalToIndex(interval) {
599
598
  const id = interval.getIntervalId();
600
599
  (0, common_utils_1.assert)(id !== undefined, 0x2c0 /* "ID must be created before adding interval to collection" */);
@@ -609,14 +608,15 @@ class LocalIntervalCollection {
609
608
  this.intervalIdMap.set(id, interval);
610
609
  }
611
610
  add(interval) {
611
+ this.linkEndpointsToInterval(interval);
612
612
  this.addIntervalToIndex(interval);
613
613
  this.addIntervalListeners(interval);
614
614
  }
615
615
  getIntervalById(id) {
616
616
  return this.intervalIdMap.get(id);
617
617
  }
618
- changeInterval(interval, start, end, op) {
619
- const newInterval = interval.modify(this.label, start, end, op);
618
+ changeInterval(interval, start, end, op, localSeq) {
619
+ const newInterval = interval.modify(this.label, start, end, op, localSeq);
620
620
  if (newInterval) {
621
621
  this.removeExistingInterval(interval);
622
622
  this.add(newInterval);
@@ -649,7 +649,7 @@ class LocalIntervalCollection {
649
649
  }
650
650
  exports.LocalIntervalCollection = LocalIntervalCollection;
651
651
  LocalIntervalCollection.legacyIdPrefix = "legacy";
652
- const compareSequenceIntervalEnds = (a, b) => a.end.compare(b.end);
652
+ const compareSequenceIntervalEnds = (a, b) => (0, merge_tree_1.compareReferencePositions)(a.end, b.end);
653
653
  class SequenceIntervalCollectionFactory {
654
654
  load(emitter, raw = []) {
655
655
  const helpers = {
@@ -725,6 +725,11 @@ function makeOpsMap() {
725
725
  "add",
726
726
  {
727
727
  process: (collection, params, local, op) => {
728
+ // if params is undefined, the interval was deleted during
729
+ // rebasing
730
+ if (!params) {
731
+ return;
732
+ }
728
733
  collection.ackAdd(params, local, op);
729
734
  },
730
735
  rebase,
@@ -746,6 +751,11 @@ function makeOpsMap() {
746
751
  "change",
747
752
  {
748
753
  process: (collection, params, local, op) => {
754
+ // if params is undefined, the interval was deleted during
755
+ // rebasing
756
+ if (!params) {
757
+ return;
758
+ }
749
759
  collection.ackChange(params, local, op);
750
760
  },
751
761
  rebase,
@@ -781,13 +791,9 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
781
791
  this.emitter = emitter;
782
792
  this.pendingChangesStart = new Map();
783
793
  this.pendingChangesEnd = new Map();
784
- if (Array.isArray(serializedIntervals)) {
785
- this.savedSerializedIntervals = serializedIntervals;
786
- }
787
- else {
788
- this.savedSerializedIntervals =
789
- serializedIntervals.intervals.map((i) => decompressInterval(i, serializedIntervals.label));
790
- }
794
+ this.savedSerializedIntervals = Array.isArray(serializedIntervals)
795
+ ? serializedIntervals
796
+ : serializedIntervals.intervals.map((i) => decompressInterval(i, serializedIntervals.label));
791
797
  }
792
798
  get attached() {
793
799
  return !!this.localCollection;
@@ -817,7 +823,10 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
817
823
  * Gets the next local sequence number, modifying this client's collab window in doing so.
818
824
  */
819
825
  getNextLocalSeq() {
820
- return ++this.client.getCollabWindow().localSeq;
826
+ if (this.client) {
827
+ return ++this.client.getCollabWindow().localSeq;
828
+ }
829
+ return 0;
821
830
  }
822
831
  getIntervalById(id) {
823
832
  if (!this.attached) {
@@ -980,10 +989,6 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
980
989
  const entries = this.pendingChangesEnd.get(id);
981
990
  return entries && entries.length !== 0;
982
991
  }
983
- /** @deprecated - use ackChange */
984
- changeInterval(serializedInterval, local, op) {
985
- return this.ackChange(serializedInterval, local, op);
986
- }
987
992
  /** @internal */
988
993
  ackChange(serializedInterval, local, op) {
989
994
  var _a, _b, _c, _d;
@@ -1057,9 +1062,19 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1057
1062
  onDeserialize(interval);
1058
1063
  });
1059
1064
  }
1060
- /** @internal */
1065
+ /**
1066
+ * Returns new interval after rebasing. If undefined, the interval was
1067
+ * deleted as a result of rebasing. This can occur if the interval applies
1068
+ * to a range that no longer exists, and the interval was unable to slide.
1069
+ *
1070
+ * @internal
1071
+ */
1061
1072
  rebaseLocalInterval(opName, serializedInterval, localSeq) {
1062
1073
  var _a, _b;
1074
+ if (!this.client) {
1075
+ // If there's no associated mergeTree client, the originally submitted op is still correct.
1076
+ return serializedInterval;
1077
+ }
1063
1078
  if (!this.attached) {
1064
1079
  throw new telemetry_utils_1.LoggingError("attachSequence must be called");
1065
1080
  }
@@ -1069,6 +1084,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1069
1084
  const endRebased = end === undefined ? undefined :
1070
1085
  this.client.rebasePosition(end, sequenceNumber, localSeq);
1071
1086
  const intervalId = properties === null || properties === void 0 ? void 0 : properties[reservedIntervalIdKey];
1087
+ const localInterval = this.localCollection.getIntervalById(intervalId);
1072
1088
  const rebased = {
1073
1089
  start: startRebased,
1074
1090
  end: endRebased,
@@ -1080,10 +1096,31 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1080
1096
  this.removePendingChange(serializedInterval);
1081
1097
  this.addPendingChange(intervalId, rebased);
1082
1098
  }
1099
+ // if the interval slid off the string, rebase the op to be a noop and
1100
+ // delete the interval
1101
+ if (startRebased === merge_tree_1.DetachedReferencePosition || endRebased === merge_tree_1.DetachedReferencePosition) {
1102
+ if (localInterval) {
1103
+ this.localCollection.removeExistingInterval(localInterval);
1104
+ }
1105
+ return undefined;
1106
+ }
1107
+ if (!localInterval) {
1108
+ return rebased;
1109
+ }
1110
+ // we know we must be using `SequenceInterval` because `this.client` exists
1111
+ (0, common_utils_1.assert)(localInterval instanceof SequenceInterval, 0x3a0 /* localInterval must be `SequenceInterval` when used with client */);
1112
+ const startSegment = this.getSlideToSegment(localInterval.start);
1113
+ const endSegment = this.getSlideToSegment(localInterval.end);
1114
+ // we need to slide because the reference has been removed
1115
+ if (startSegment || endSegment) {
1116
+ const newStart = startSegment && this.client.getPosition(startSegment.segment, localSeq) + startSegment.offset;
1117
+ const newEnd = endSegment && this.client.getPosition(endSegment.segment, localSeq) + endSegment.offset;
1118
+ this.localCollection.changeInterval(localInterval, newStart, newEnd, undefined, localSeq);
1119
+ }
1083
1120
  return rebased;
1084
1121
  }
1085
1122
  getSlideToSegment(lref) {
1086
- const segoff = { segment: lref.segment, offset: lref.offset };
1123
+ const segoff = { segment: lref.getSegment(), offset: lref.getOffset() };
1087
1124
  const newSegoff = this.client.getSlideToSegment(segoff);
1088
1125
  const value = (segoff.segment === newSegoff.segment && segoff.offset === newSegoff.offset) ? undefined : newSegoff;
1089
1126
  return value;
@@ -1095,7 +1132,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1095
1132
  lref.refType = refType;
1096
1133
  }
1097
1134
  ackInterval(interval, op) {
1098
- // in current usage, interval is always a SequenceInterval
1135
+ // Only SequenceIntervals need potential sliding
1099
1136
  if (!(interval instanceof SequenceInterval)) {
1100
1137
  return;
1101
1138
  }
@@ -1119,7 +1156,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1119
1156
  if (needsStartUpdate || needsEndUpdate) {
1120
1157
  // In this case, where we change the start or end of an interval,
1121
1158
  // it is necessary to remove and re-add the interval listeners.
1122
- // This ensures that the correct listeners are added to the ReferencePosition.
1159
+ // This ensures that the correct listeners are added to the LocalReferencePosition.
1123
1160
  this.localCollection.removeExistingInterval(interval);
1124
1161
  if (needsStartUpdate) {
1125
1162
  const props = interval.start.properties;
@@ -1140,10 +1177,6 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1140
1177
  this.localCollection.add(interval);
1141
1178
  }
1142
1179
  }
1143
- /** @deprecated - use ackAdd */
1144
- addInternal(serializedInterval, local, op) {
1145
- return this.ackAdd(serializedInterval, local, op);
1146
- }
1147
1180
  /** @internal */
1148
1181
  ackAdd(serializedInterval, local, op) {
1149
1182
  var _a;
@@ -1168,10 +1201,6 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1168
1201
  this.emit("addInterval", interval, local, op);
1169
1202
  return interval;
1170
1203
  }
1171
- /** @deprecated - use ackDelete */
1172
- deleteInterval(serializedInterval, local, op) {
1173
- return this.ackDelete(serializedInterval, local, op);
1174
- }
1175
1204
  /** @internal */
1176
1205
  ackDelete(serializedInterval, local, op) {
1177
1206
  if (local) {
@@ -1250,4 +1279,16 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1250
1279
  }
1251
1280
  }
1252
1281
  exports.IntervalCollection = IntervalCollection;
1282
+ /**
1283
+ * Returns an object that can be used to find the interval a given LocalReferencePosition belongs to.
1284
+ * @returns undefined if the reference position is not the endpoint of any interval (e.g. it was created
1285
+ * on the merge tree directly by app code), otherwise an {@link IntervalLocator} for the interval this
1286
+ * endpoint is a part of.
1287
+ */
1288
+ function intervalLocatorFromEndpoint(potentialEndpoint) {
1289
+ var _a;
1290
+ const { interval, [merge_tree_1.reservedRangeLabelsKey]: collectionNameArray, } = (_a = potentialEndpoint.properties) !== null && _a !== void 0 ? _a : {};
1291
+ return (interval && (collectionNameArray === null || collectionNameArray === void 0 ? void 0 : collectionNameArray.length) === 1) ? { label: collectionNameArray[0], interval } : undefined;
1292
+ }
1293
+ exports.intervalLocatorFromEndpoint = intervalLocatorFromEndpoint;
1253
1294
  //# sourceMappingURL=intervalCollection.js.map