@fluidframework/sequence 2.0.0-internal.4.3.0 → 2.0.0-internal.5.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 (70) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/defaultMap.d.ts +3 -2
  3. package/dist/defaultMap.d.ts.map +1 -1
  4. package/dist/defaultMap.js +4 -3
  5. package/dist/defaultMap.js.map +1 -1
  6. package/dist/defaultMapInterfaces.d.ts +12 -1
  7. package/dist/defaultMapInterfaces.d.ts.map +1 -1
  8. package/dist/defaultMapInterfaces.js.map +1 -1
  9. package/dist/index.d.ts +3 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +11 -3
  12. package/dist/index.js.map +1 -1
  13. package/dist/intervalCollection.d.ts +197 -56
  14. package/dist/intervalCollection.d.ts.map +1 -1
  15. package/dist/intervalCollection.js +161 -80
  16. package/dist/intervalCollection.js.map +1 -1
  17. package/dist/packageVersion.d.ts +1 -1
  18. package/dist/packageVersion.js +1 -1
  19. package/dist/packageVersion.js.map +1 -1
  20. package/dist/revertibles.d.ts +104 -0
  21. package/dist/revertibles.d.ts.map +1 -0
  22. package/dist/revertibles.js +374 -0
  23. package/dist/revertibles.js.map +1 -0
  24. package/dist/sequence.d.ts +4 -4
  25. package/dist/sequence.d.ts.map +1 -1
  26. package/dist/sequence.js +3 -3
  27. package/dist/sequence.js.map +1 -1
  28. package/dist/sharedIntervalCollection.d.ts +3 -3
  29. package/dist/sharedIntervalCollection.d.ts.map +1 -1
  30. package/dist/sharedIntervalCollection.js +1 -1
  31. package/dist/sharedIntervalCollection.js.map +1 -1
  32. package/lib/defaultMap.d.ts +3 -2
  33. package/lib/defaultMap.d.ts.map +1 -1
  34. package/lib/defaultMap.js +4 -3
  35. package/lib/defaultMap.js.map +1 -1
  36. package/lib/defaultMapInterfaces.d.ts +12 -1
  37. package/lib/defaultMapInterfaces.d.ts.map +1 -1
  38. package/lib/defaultMapInterfaces.js.map +1 -1
  39. package/lib/index.d.ts +3 -2
  40. package/lib/index.d.ts.map +1 -1
  41. package/lib/index.js +2 -1
  42. package/lib/index.js.map +1 -1
  43. package/lib/intervalCollection.d.ts +197 -56
  44. package/lib/intervalCollection.d.ts.map +1 -1
  45. package/lib/intervalCollection.js +162 -80
  46. package/lib/intervalCollection.js.map +1 -1
  47. package/lib/packageVersion.d.ts +1 -1
  48. package/lib/packageVersion.js +1 -1
  49. package/lib/packageVersion.js.map +1 -1
  50. package/lib/revertibles.d.ts +104 -0
  51. package/lib/revertibles.d.ts.map +1 -0
  52. package/lib/revertibles.js +364 -0
  53. package/lib/revertibles.js.map +1 -0
  54. package/lib/sequence.d.ts +4 -4
  55. package/lib/sequence.d.ts.map +1 -1
  56. package/lib/sequence.js +3 -3
  57. package/lib/sequence.js.map +1 -1
  58. package/lib/sharedIntervalCollection.d.ts +3 -3
  59. package/lib/sharedIntervalCollection.d.ts.map +1 -1
  60. package/lib/sharedIntervalCollection.js +1 -1
  61. package/lib/sharedIntervalCollection.js.map +1 -1
  62. package/package.json +46 -14
  63. package/src/defaultMap.ts +4 -1
  64. package/src/defaultMapInterfaces.ts +13 -1
  65. package/src/index.ts +16 -5
  66. package/src/intervalCollection.ts +373 -66
  67. package/src/packageVersion.ts +1 -1
  68. package/src/revertibles.ts +572 -0
  69. package/src/sequence.ts +12 -2
  70. package/src/sharedIntervalCollection.ts +4 -2
@@ -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.intervalLocatorFromEndpoint = exports.IntervalCollection = exports.IntervalCollectionIterator = exports.makeOpsMap = exports.IntervalCollectionValueType = exports.SequenceIntervalCollectionValueType = exports.compareSequenceIntervalEnds = exports.LocalIntervalCollection = exports.createIntervalIndex = exports.createSequenceInterval = exports.SequenceInterval = exports.Interval = exports.IntervalType = void 0;
18
+ exports.intervalLocatorFromEndpoint = exports.IntervalCollection = exports.makeOpsMap = exports.IntervalCollectionValueType = exports.SequenceIntervalCollectionValueType = exports.compareSequenceIntervalEnds = exports.LocalIntervalCollection = exports.createIntervalIndex = exports.createSequenceInterval = exports.SequenceInterval = exports.Interval = exports.IntervalStickiness = exports.IntervalType = exports.IntervalOpType = 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");
@@ -24,6 +24,17 @@ const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
24
24
  const uuid_1 = require("uuid");
25
25
  const intervalTree_1 = require("./intervalTree");
26
26
  const reservedIntervalIdKey = "intervalId";
27
+ /**
28
+ * Values are used in persisted formats (ops) and revertibles.
29
+ * @alpha
30
+ */
31
+ exports.IntervalOpType = {
32
+ ADD: "add",
33
+ DELETE: "delete",
34
+ CHANGE: "change",
35
+ PROPERTY_CHANGED: "propertyChanged",
36
+ POSITION_REMOVE: "positionRemove",
37
+ };
27
38
  var IntervalType;
28
39
  (function (IntervalType) {
29
40
  IntervalType[IntervalType["Simple"] = 0] = "Simple";
@@ -52,6 +63,7 @@ function decompressInterval(interval, label) {
52
63
  sequenceNumber: interval[2],
53
64
  intervalType: interval[3],
54
65
  properties: Object.assign(Object.assign({}, interval[4]), { [merge_tree_1.reservedRangeLabelsKey]: [label] }),
66
+ stickiness: interval[5],
55
67
  };
56
68
  }
57
69
  /**
@@ -60,14 +72,57 @@ function decompressInterval(interval, label) {
60
72
  */
61
73
  function compressInterval(interval) {
62
74
  const { start, end, sequenceNumber, intervalType, properties } = interval;
63
- return [
75
+ const base = [
64
76
  start,
65
77
  end,
66
78
  sequenceNumber,
67
79
  intervalType,
68
80
  Object.assign(Object.assign({}, properties), { [merge_tree_1.reservedRangeLabelsKey]: undefined }),
69
81
  ];
82
+ if (interval.stickiness !== undefined && interval.stickiness !== exports.IntervalStickiness.END) {
83
+ base.push(interval.stickiness);
84
+ }
85
+ return base;
86
+ }
87
+ function startReferenceSlidingPreference(stickiness) {
88
+ // if any start stickiness, prefer sliding backwards
89
+ return (stickiness & exports.IntervalStickiness.START) !== 0
90
+ ? merge_tree_1.SlidingPreference.BACKWARD
91
+ : merge_tree_1.SlidingPreference.FORWARD;
92
+ }
93
+ function endReferenceSlidingPreference(stickiness) {
94
+ // if any end stickiness, prefer sliding forwards
95
+ return (stickiness & exports.IntervalStickiness.END) !== 0
96
+ ? merge_tree_1.SlidingPreference.FORWARD
97
+ : merge_tree_1.SlidingPreference.BACKWARD;
70
98
  }
99
+ /**
100
+ * Determines how an interval should expand when segments are inserted adjacent
101
+ * to the range it spans
102
+ *
103
+ * Note that interval stickiness is currently an experimental feature and must
104
+ * be explicitly enabled with the `intervalStickinessEnabled` flag
105
+ */
106
+ exports.IntervalStickiness = {
107
+ /**
108
+ * Interval does not expand to include adjacent segments
109
+ */
110
+ NONE: 0b00,
111
+ /**
112
+ * Interval expands to include segments inserted adjacent to the start
113
+ */
114
+ START: 0b01,
115
+ /**
116
+ * Interval expands to include segments inserted adjacent to the end
117
+ *
118
+ * This is the default stickiness
119
+ */
120
+ END: 0b10,
121
+ /**
122
+ * Interval expands to include all segments inserted adjacent to it
123
+ */
124
+ FULL: 0b11,
125
+ };
71
126
  /**
72
127
  * Serializable interval whose endpoints are plain-old numbers.
73
128
  */
@@ -101,7 +156,7 @@ class Interval {
101
156
  * Adds an auxiliary set of properties to this interval.
102
157
  * These properties can be recovered using `getAdditionalPropertySets`
103
158
  * @param props - set of properties to add
104
- * @remarks - This gets called as part of the default conflict resolver for `IntervalCollection<Interval>`
159
+ * @remarks - This gets called as part of the default conflict resolver for `IIntervalCollection<Interval>`
105
160
  * (i.e. non-sequence-based interval collections). However, the additional properties don't get serialized.
106
161
  * This functionality seems half-baked.
107
162
  */
@@ -258,11 +313,12 @@ class SequenceInterval {
258
313
  * End endpoint of this interval.
259
314
  * @remarks - This endpoint can be resolved into a character position using the SharedString it's a part of.
260
315
  */
261
- end, intervalType, props) {
316
+ end, intervalType, props, stickiness = exports.IntervalStickiness.END) {
262
317
  this.client = client;
263
318
  this.start = start;
264
319
  this.end = end;
265
320
  this.intervalType = intervalType;
321
+ this.stickiness = stickiness;
266
322
  this.propertyManager = new merge_tree_1.PropertiesManager();
267
323
  this.properties = {};
268
324
  if (props) {
@@ -314,13 +370,16 @@ class SequenceInterval {
314
370
  if (this.properties) {
315
371
  serializedInterval.properties = this.properties;
316
372
  }
373
+ if (this.stickiness !== exports.IntervalStickiness.END) {
374
+ serializedInterval.stickiness = this.stickiness;
375
+ }
317
376
  return serializedInterval;
318
377
  }
319
378
  /**
320
379
  * {@inheritDoc IInterval.clone}
321
380
  */
322
381
  clone() {
323
- return new SequenceInterval(this.client, this.start, this.end, this.intervalType, this.properties);
382
+ return new SequenceInterval(this.client, this.start, this.end, this.intervalType, this.properties, this.stickiness);
324
383
  }
325
384
  /**
326
385
  * {@inheritDoc IInterval.compare}
@@ -404,7 +463,7 @@ class SequenceInterval {
404
463
  * {@inheritDoc IInterval.modify}
405
464
  * @deprecated - This API was never intended to be public and will be marked internal in a future release.
406
465
  */
407
- modify(label, start, end, op, localSeq) {
466
+ modify(label, start, end, op, localSeq, stickiness = exports.IntervalStickiness.END) {
408
467
  const getRefType = (baseType) => {
409
468
  let refType = baseType;
410
469
  if (op === undefined) {
@@ -415,14 +474,14 @@ class SequenceInterval {
415
474
  };
416
475
  let startRef = this.start;
417
476
  if (start !== undefined) {
418
- startRef = createPositionReference(this.client, start, getRefType(this.start.refType), op, undefined, localSeq);
477
+ startRef = createPositionReference(this.client, start, getRefType(this.start.refType), op, undefined, localSeq, startReferenceSlidingPreference(stickiness));
419
478
  if (this.start.properties) {
420
479
  startRef.addProperties(this.start.properties);
421
480
  }
422
481
  }
423
482
  let endRef = this.end;
424
483
  if (end !== undefined) {
425
- endRef = createPositionReference(this.client, end, getRefType(this.end.refType), op, undefined, localSeq);
484
+ endRef = createPositionReference(this.client, end, getRefType(this.end.refType), op, undefined, localSeq, endReferenceSlidingPreference(stickiness));
426
485
  if (this.end.properties) {
427
486
  endRef.addProperties(this.end.properties);
428
487
  }
@@ -444,9 +503,9 @@ class SequenceInterval {
444
503
  }
445
504
  }
446
505
  exports.SequenceInterval = SequenceInterval;
447
- function createPositionReferenceFromSegoff(client, segoff, refType, op, localSeq, fromSnapshot) {
506
+ function createPositionReferenceFromSegoff(client, segoff, refType, op, localSeq, fromSnapshot, slidingPreference) {
448
507
  if (segoff.segment) {
449
- const ref = client.createLocalReferencePosition(segoff.segment, segoff.offset, refType, undefined);
508
+ const ref = client.createLocalReferencePosition(segoff.segment, segoff.offset, refType, undefined, slidingPreference);
450
509
  return ref;
451
510
  }
452
511
  // Creating references on detached segments is allowed for:
@@ -462,7 +521,7 @@ function createPositionReferenceFromSegoff(client, segoff, refType, op, localSeq
462
521
  }
463
522
  return (0, merge_tree_1.createDetachedLocalReferencePosition)(refType);
464
523
  }
465
- function createPositionReference(client, pos, refType, op, fromSnapshot, localSeq) {
524
+ function createPositionReference(client, pos, refType, op, fromSnapshot, localSeq, slidingPreference) {
466
525
  let segoff;
467
526
  if (op) {
468
527
  (0, common_utils_1.assert)((refType & merge_tree_1.ReferenceType.SlideOnRemove) !== 0, 0x2f5 /* op create references must be SlideOnRemove */);
@@ -476,9 +535,9 @@ function createPositionReference(client, pos, refType, op, fromSnapshot, localSe
476
535
  (0, common_utils_1.assert)((refType & merge_tree_1.ReferenceType.SlideOnRemove) === 0 || !!fromSnapshot, 0x2f6 /* SlideOnRemove references must be op created */);
477
536
  segoff = client.getContainingSegment(pos, undefined, localSeq);
478
537
  }
479
- return createPositionReferenceFromSegoff(client, segoff, refType, op, localSeq, fromSnapshot);
538
+ return createPositionReferenceFromSegoff(client, segoff, refType, op, localSeq, fromSnapshot, slidingPreference);
480
539
  }
481
- function createSequenceInterval(label, start, end, client, intervalType, op, fromSnapshot) {
540
+ function createSequenceInterval(label, start, end, client, intervalType, op, fromSnapshot, stickiness = exports.IntervalStickiness.END) {
482
541
  let beginRefType = merge_tree_1.ReferenceType.RangeBegin;
483
542
  let endRefType = merge_tree_1.ReferenceType.RangeEnd;
484
543
  if (intervalType === IntervalType.Transient) {
@@ -502,14 +561,14 @@ function createSequenceInterval(label, start, end, client, intervalType, op, fro
502
561
  endRefType |= merge_tree_1.ReferenceType.StayOnRemove;
503
562
  }
504
563
  }
505
- const startLref = createPositionReference(client, start, beginRefType, op, fromSnapshot);
506
- const endLref = createPositionReference(client, end, endRefType, op, fromSnapshot);
564
+ const startLref = createPositionReference(client, start, beginRefType, op, fromSnapshot, undefined, startReferenceSlidingPreference(stickiness));
565
+ const endLref = createPositionReference(client, end, endRefType, op, fromSnapshot, undefined, endReferenceSlidingPreference(stickiness));
507
566
  const rangeProp = {
508
567
  [merge_tree_1.reservedRangeLabelsKey]: [label],
509
568
  };
510
569
  startLref.addProperties(rangeProp);
511
570
  endLref.addProperties(rangeProp);
512
- const ival = new SequenceInterval(client, startLref, endLref, intervalType, rangeProp);
571
+ const ival = new SequenceInterval(client, startLref, endLref, intervalType, rangeProp, stickiness);
513
572
  return ival;
514
573
  }
515
574
  exports.createSequenceInterval = createSequenceInterval;
@@ -680,11 +739,11 @@ class LocalIntervalCollection {
680
739
  this.overlappingIntervalsIndex = new OverlappingIntervalsIndex(client, helpers);
681
740
  this.idIntervalIndex = new IdIntervalIndex();
682
741
  this.endIntervalIndex = new EndpointIndex(client, helpers);
683
- this.indexes = [
742
+ this.indexes = new Set([
684
743
  this.overlappingIntervalsIndex,
685
744
  this.idIntervalIndex,
686
745
  this.endIntervalIndex,
687
- ];
746
+ ]);
688
747
  }
689
748
  createLegacyId(start, end) {
690
749
  // Create a non-unique ID based on start and end to be used on intervals that come from legacy clients
@@ -724,17 +783,23 @@ class LocalIntervalCollection {
724
783
  index.remove(interval);
725
784
  }
726
785
  }
786
+ appendIndex(index) {
787
+ this.indexes.add(index);
788
+ }
789
+ removeIndex(index) {
790
+ return this.indexes.delete(index);
791
+ }
727
792
  removeExistingInterval(interval) {
728
793
  this.removeIntervalFromIndexes(interval);
729
794
  this.removeIntervalListeners(interval);
730
795
  }
731
- createInterval(start, end, intervalType, op) {
732
- return this.helpers.create(this.label, start, end, this.client, intervalType, op);
796
+ createInterval(start, end, intervalType, op, stickiness = exports.IntervalStickiness.END) {
797
+ return this.helpers.create(this.label, start, end, this.client, intervalType, op, undefined, stickiness);
733
798
  }
734
- addInterval(start, end, intervalType, props, op) {
799
+ addInterval(start, end, intervalType, props, op, stickiness = exports.IntervalStickiness.END) {
735
800
  var _a;
736
801
  var _b;
737
- const interval = this.createInterval(start, end, intervalType, op);
802
+ const interval = this.createInterval(start, end, intervalType, op, stickiness);
738
803
  if (interval) {
739
804
  if (!interval.properties) {
740
805
  interval.properties = (0, merge_tree_1.createMap)();
@@ -787,7 +852,7 @@ class LocalIntervalCollection {
787
852
  // either, so this must be special-cased.
788
853
  return ref;
789
854
  }
790
- return this.client.createLocalReferencePosition(segment, ref.getOffset(), merge_tree_1.ReferenceType.Transient, ref.properties);
855
+ return this.client.createLocalReferencePosition(segment, ref.getOffset(), merge_tree_1.ReferenceType.Transient, ref.properties, ref.slidingPreference);
791
856
  };
792
857
  if (interval instanceof SequenceInterval) {
793
858
  let previousInterval;
@@ -824,12 +889,12 @@ LocalIntervalCollection.legacyIdPrefix = "legacy";
824
889
  const compareSequenceIntervalEnds = (a, b) => (0, merge_tree_1.compareReferencePositions)(a.end, b.end);
825
890
  exports.compareSequenceIntervalEnds = compareSequenceIntervalEnds;
826
891
  class SequenceIntervalCollectionFactory {
827
- load(emitter, raw = []) {
892
+ load(emitter, raw = [], options) {
828
893
  const helpers = {
829
894
  compareEnds: exports.compareSequenceIntervalEnds,
830
895
  create: createSequenceInterval,
831
896
  };
832
- return new IntervalCollection(helpers, true, emitter, raw);
897
+ return new IntervalCollection(helpers, true, emitter, raw, options);
833
898
  }
834
899
  store(value) {
835
900
  return value.serializeInternal();
@@ -851,7 +916,7 @@ SequenceIntervalCollectionValueType.Name = "sharedStringIntervalCollection";
851
916
  SequenceIntervalCollectionValueType._factory = new SequenceIntervalCollectionFactory();
852
917
  SequenceIntervalCollectionValueType._ops = makeOpsMap();
853
918
  const compareIntervalEnds = (a, b) => a.end - b.end;
854
- function createInterval(label, start, end, client) {
919
+ function createInterval(label, start, end, client, intervalType, op, fromSnapshot) {
855
920
  const rangeProp = {};
856
921
  if (label && label.length > 0) {
857
922
  rangeProp[merge_tree_1.reservedRangeLabelsKey] = [label];
@@ -859,12 +924,12 @@ function createInterval(label, start, end, client) {
859
924
  return new Interval(start, end, rangeProp);
860
925
  }
861
926
  class IntervalCollectionFactory {
862
- load(emitter, raw = []) {
927
+ load(emitter, raw = [], options) {
863
928
  const helpers = {
864
929
  compareEnds: compareIntervalEnds,
865
930
  create: createInterval,
866
931
  };
867
- const collection = new IntervalCollection(helpers, false, emitter, raw);
932
+ const collection = new IntervalCollection(helpers, false, emitter, raw, options);
868
933
  collection.attachGraph(undefined, "");
869
934
  return collection;
870
935
  }
@@ -896,7 +961,7 @@ function makeOpsMap() {
896
961
  };
897
962
  return new Map([
898
963
  [
899
- "add",
964
+ exports.IntervalOpType.ADD,
900
965
  {
901
966
  process: (collection, params, local, op, localOpMetadata) => {
902
967
  // if params is undefined, the interval was deleted during
@@ -911,7 +976,7 @@ function makeOpsMap() {
911
976
  },
912
977
  ],
913
978
  [
914
- "delete",
979
+ exports.IntervalOpType.DELETE,
915
980
  {
916
981
  process: (collection, params, local, op) => {
917
982
  (0, common_utils_1.assert)(op !== undefined, 0x3fc /* op should exist here */);
@@ -924,7 +989,7 @@ function makeOpsMap() {
924
989
  },
925
990
  ],
926
991
  [
927
- "change",
992
+ exports.IntervalOpType.CHANGE,
928
993
  {
929
994
  process: (collection, params, local, op, localOpMetadata) => {
930
995
  // if params is undefined, the interval was deleted during
@@ -960,21 +1025,17 @@ class IntervalCollectionIterator {
960
1025
  };
961
1026
  }
962
1027
  }
963
- exports.IntervalCollectionIterator = IntervalCollectionIterator;
964
1028
  /**
965
- * Collection of intervals that supports addition, modification, removal, and efficient spatial querying.
966
- * This class is not a DDS in its own right, but emits events on mutating operations such that it's possible to
967
- * integrate into a DDS.
968
- * This aligns with its usage in `SharedSegmentSequence`, which allows associating intervals to positions in the
969
- * sequence DDS which are broadcast to all other clients in an eventually consistent fashion.
1029
+ * {@inheritdoc IIntervalCollection}
970
1030
  */
971
1031
  class IntervalCollection extends common_utils_1.TypedEventEmitter {
972
1032
  /** @internal */
973
- constructor(helpers, requiresClient, emitter, serializedIntervals) {
1033
+ constructor(helpers, requiresClient, emitter, serializedIntervals, options = {}) {
974
1034
  super();
975
1035
  this.helpers = helpers;
976
1036
  this.requiresClient = requiresClient;
977
1037
  this.emitter = emitter;
1038
+ this.options = options;
978
1039
  this.localSeqToSerializedInterval = new Map();
979
1040
  this.localSeqToRebasedInterval = new Map();
980
1041
  this.pendingChangesStart = new Map();
@@ -986,6 +1047,36 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
986
1047
  get attached() {
987
1048
  return !!this.localCollection;
988
1049
  }
1050
+ /**
1051
+ * {@inheritdoc IIntervalCollection.attachIndex}
1052
+ */
1053
+ attachIndex(index) {
1054
+ var _a;
1055
+ if (!this.attached) {
1056
+ throw new telemetry_utils_1.LoggingError("The local interval collection must exist");
1057
+ }
1058
+ for (const interval of this) {
1059
+ index.add(interval);
1060
+ }
1061
+ (_a = this.localCollection) === null || _a === void 0 ? void 0 : _a.appendIndex(index);
1062
+ }
1063
+ /**
1064
+ * {@inheritdoc IIntervalCollection.detachIndex}
1065
+ */
1066
+ detachIndex(index) {
1067
+ var _a;
1068
+ if (!this.attached) {
1069
+ throw new telemetry_utils_1.LoggingError("The local interval collection must exist");
1070
+ }
1071
+ // Avoid removing intervals if the index does not exist
1072
+ if (!((_a = this.localCollection) === null || _a === void 0 ? void 0 : _a.removeIndex(index))) {
1073
+ return false;
1074
+ }
1075
+ for (const interval of this) {
1076
+ index.remove(interval);
1077
+ }
1078
+ return true;
1079
+ }
989
1080
  rebasePositionWithSegmentSlide(pos, seqNumberFrom, localSeq) {
990
1081
  var _a;
991
1082
  if (!this.client) {
@@ -1041,8 +1132,8 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1041
1132
  if (this.savedSerializedIntervals) {
1042
1133
  for (const serializedInterval of this.savedSerializedIntervals) {
1043
1134
  this.localCollection.ensureSerializedId(serializedInterval);
1044
- const { start, end, intervalType, properties } = serializedInterval;
1045
- const interval = this.helpers.create(label, start, end, client, intervalType, undefined, true);
1135
+ const { start, end, intervalType, properties, stickiness } = serializedInterval;
1136
+ const interval = this.helpers.create(label, start, end, client, intervalType, undefined, true, stickiness);
1046
1137
  if (properties) {
1047
1138
  interval.addProperties(properties);
1048
1139
  }
@@ -1080,8 +1171,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1080
1171
  }
1081
1172
  }
1082
1173
  /**
1083
- * @returns the interval in this collection that has the provided `id`.
1084
- * If no interval in the collection has this `id`, returns `undefined`.
1174
+ * {@inheritdoc IIntervalCollection.getIntervalById}
1085
1175
  */
1086
1176
  getIntervalById(id) {
1087
1177
  if (!this.localCollection) {
@@ -1090,16 +1180,9 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1090
1180
  return this.localCollection.idIntervalIndex.getIntervalById(id);
1091
1181
  }
1092
1182
  /**
1093
- * Creates a new interval and add it to the collection.
1094
- * @param start - interval start position (inclusive)
1095
- * @param end - interval end position (exclusive)
1096
- * @param intervalType - type of the interval. All intervals are SlideOnRemove. Intervals may not be Transient.
1097
- * @param props - properties of the interval
1098
- * @returns - the created interval
1099
- * @remarks - See documentation on {@link SequenceInterval} for comments on interval endpoint semantics: there are subtleties
1100
- * with how the current half-open behavior is represented.
1183
+ * {@inheritdoc IIntervalCollection.add}
1101
1184
  */
1102
- add(start, end, intervalType, props) {
1185
+ add(start, end, intervalType, props, stickiness = exports.IntervalStickiness.END) {
1103
1186
  var _a, _b;
1104
1187
  if (!this.localCollection) {
1105
1188
  throw new telemetry_utils_1.LoggingError("attach must be called prior to adding intervals");
@@ -1107,7 +1190,10 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1107
1190
  if (intervalType & IntervalType.Transient) {
1108
1191
  throw new telemetry_utils_1.LoggingError("Can not add transient intervals");
1109
1192
  }
1110
- const interval = this.localCollection.addInterval(start, end, intervalType, props);
1193
+ if (stickiness !== exports.IntervalStickiness.END && !this.options.intervalStickinessEnabled) {
1194
+ throw new container_utils_1.UsageError("attempted to set interval stickiness without enabling `intervalStickinessEnabled` feature flag");
1195
+ }
1196
+ const interval = this.localCollection.addInterval(start, end, intervalType, props, undefined, stickiness);
1111
1197
  if (interval) {
1112
1198
  const serializedInterval = {
1113
1199
  end,
@@ -1115,6 +1201,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1115
1201
  properties: interval.properties,
1116
1202
  sequenceNumber: (_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.getCurrentSeq()) !== null && _b !== void 0 ? _b : 0,
1117
1203
  start,
1204
+ stickiness,
1118
1205
  };
1119
1206
  const localSeq = this.getNextLocalSeq();
1120
1207
  this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
@@ -1146,9 +1233,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1146
1233
  this.emit("deleteInterval", interval, local, op);
1147
1234
  }
1148
1235
  /**
1149
- * Removes an interval from the collection.
1150
- * @param id - Id of the interval to remove
1151
- * @returns the removed interval
1236
+ * {@inheritdoc IIntervalCollection.removeIntervalById}
1152
1237
  */
1153
1238
  removeIntervalById(id) {
1154
1239
  if (!this.localCollection) {
@@ -1161,10 +1246,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1161
1246
  return interval;
1162
1247
  }
1163
1248
  /**
1164
- * Changes the properties on an existing interval.
1165
- * @param id - Id of the interval whose properties should be changed
1166
- * @param props - Property set to apply to the interval. Shallow merging is used between any existing properties
1167
- * and `prop`, i.e. the interval will end up with a property object equivalent to `{ ...oldProps, ...props }`.
1249
+ * {@inheritdoc IIntervalCollection.changeProperties}
1168
1250
  */
1169
1251
  changeProperties(id, props) {
1170
1252
  if (!this.attached) {
@@ -1194,11 +1276,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1194
1276
  }
1195
1277
  }
1196
1278
  /**
1197
- * Changes the endpoints of an existing interval.
1198
- * @param id - Id of the interval to change
1199
- * @param start - New start value, if defined. `undefined` signifies this endpoint should be left unchanged.
1200
- * @param end - New end value, if defined. `undefined` signifies this endpoint should be left unchanged.
1201
- * @returns the interval that was changed, if it existed in the collection.
1279
+ * {@inheritdoc IIntervalCollection.change}
1202
1280
  */
1203
1281
  change(id, start, end) {
1204
1282
  if (!this.localCollection) {
@@ -1353,6 +1431,9 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1353
1431
  throw new telemetry_utils_1.LoggingError("attachSequence must be called");
1354
1432
  }
1355
1433
  }
1434
+ /**
1435
+ * {@inheritdoc IIntervalCollection.attachDeserializer}
1436
+ */
1356
1437
  attachDeserializer(onDeserialize) {
1357
1438
  // If no deserializer is specified can skip all processing work
1358
1439
  if (!onDeserialize) {
@@ -1473,7 +1554,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1473
1554
  }
1474
1555
  if (needsStartUpdate) {
1475
1556
  const props = interval.start.properties;
1476
- interval.start = createPositionReferenceFromSegoff(this.client, newStart, interval.start.refType, op);
1557
+ interval.start = createPositionReferenceFromSegoff(this.client, newStart, interval.start.refType, op, startReferenceSlidingPreference(interval.stickiness));
1477
1558
  if (props) {
1478
1559
  interval.start.addProperties(props);
1479
1560
  }
@@ -1485,7 +1566,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1485
1566
  }
1486
1567
  if (needsEndUpdate) {
1487
1568
  const props = interval.end.properties;
1488
- interval.end = createPositionReferenceFromSegoff(this.client, newEnd, interval.end.refType, op);
1569
+ interval.end = createPositionReferenceFromSegoff(this.client, newEnd, interval.end.refType, op, endReferenceSlidingPreference(interval.stickiness));
1489
1570
  if (props) {
1490
1571
  interval.end.addProperties(props);
1491
1572
  }
@@ -1516,7 +1597,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1516
1597
  throw new telemetry_utils_1.LoggingError("attachSequence must be called");
1517
1598
  }
1518
1599
  this.localCollection.ensureSerializedId(serializedInterval);
1519
- const interval = this.localCollection.addInterval(serializedInterval.start, serializedInterval.end, serializedInterval.intervalType, serializedInterval.properties, op);
1600
+ const interval = this.localCollection.addInterval(serializedInterval.start, serializedInterval.end, serializedInterval.intervalType, serializedInterval.properties, op, serializedInterval.stickiness);
1520
1601
  if (interval) {
1521
1602
  if (this.onDeserialize) {
1522
1603
  this.onDeserialize(interval);
@@ -1559,40 +1640,35 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1559
1640
  return iterator;
1560
1641
  }
1561
1642
  /**
1562
- * @returns a forward iterator over all intervals in this collection with start point equal to `startPosition`.
1643
+ * {@inheritdoc IIntervalCollection.CreateForwardIteratorWithStartPosition}
1563
1644
  */
1564
1645
  CreateForwardIteratorWithStartPosition(startPosition) {
1565
1646
  const iterator = new IntervalCollectionIterator(this, true, startPosition);
1566
1647
  return iterator;
1567
1648
  }
1568
1649
  /**
1569
- * @returns a backward iterator over all intervals in this collection with start point equal to `startPosition`.
1650
+ * {@inheritdoc IIntervalCollection.CreateBackwardIteratorWithStartPosition}
1570
1651
  */
1571
1652
  CreateBackwardIteratorWithStartPosition(startPosition) {
1572
1653
  const iterator = new IntervalCollectionIterator(this, false, startPosition);
1573
1654
  return iterator;
1574
1655
  }
1575
1656
  /**
1576
- * @returns a forward iterator over all intervals in this collection with end point equal to `endPosition`.
1657
+ * {@inheritdoc IIntervalCollection.CreateForwardIteratorWithEndPosition}
1577
1658
  */
1578
1659
  CreateForwardIteratorWithEndPosition(endPosition) {
1579
1660
  const iterator = new IntervalCollectionIterator(this, true, undefined, endPosition);
1580
1661
  return iterator;
1581
1662
  }
1582
1663
  /**
1583
- * @returns a backward iterator over all intervals in this collection with end point equal to `endPosition`.
1664
+ * {@inheritdoc IIntervalCollection.CreateBackwardIteratorWithEndPosition}
1584
1665
  */
1585
1666
  CreateBackwardIteratorWithEndPosition(endPosition) {
1586
1667
  const iterator = new IntervalCollectionIterator(this, false, undefined, endPosition);
1587
1668
  return iterator;
1588
1669
  }
1589
1670
  /**
1590
- * Gathers iteration results that optionally match a start/end criteria into the provided array.
1591
- * @param results - Array to gather the results into. In lieu of a return value, this array will be populated with
1592
- * intervals matching the query upon edit.
1593
- * @param iteratesForward - whether or not iteration should be in the forward direction
1594
- * @param start - If provided, only match intervals whose start point is equal to `start`.
1595
- * @param end - If provided, only match intervals whose end point is equal to `end`.
1671
+ * {@inheritdoc IIntervalCollection.gatherIterationResults}
1596
1672
  */
1597
1673
  gatherIterationResults(results, iteratesForward, start, end) {
1598
1674
  if (!this.localCollection) {
@@ -1601,8 +1677,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1601
1677
  this.localCollection.overlappingIntervalsIndex.gatherIterationResults(results, iteratesForward, start, end);
1602
1678
  }
1603
1679
  /**
1604
- * @returns an array of all intervals in this collection that overlap with the interval
1605
- * `[startPosition, endPosition]`.
1680
+ * {@inheritdoc IIntervalCollection.findOverlappingIntervals}
1606
1681
  */
1607
1682
  findOverlappingIntervals(startPosition, endPosition) {
1608
1683
  if (!this.localCollection) {
@@ -1611,7 +1686,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1611
1686
  return this.localCollection.overlappingIntervalsIndex.findOverlappingIntervals(startPosition, endPosition);
1612
1687
  }
1613
1688
  /**
1614
- * Applies a function to each interval in this collection.
1689
+ * {@inheritdoc IIntervalCollection.map}
1615
1690
  */
1616
1691
  map(fn) {
1617
1692
  if (!this.localCollection) {
@@ -1621,12 +1696,18 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
1621
1696
  fn(interval);
1622
1697
  }
1623
1698
  }
1699
+ /**
1700
+ * {@inheritdoc IIntervalCollection.previousInterval}
1701
+ */
1624
1702
  previousInterval(pos) {
1625
1703
  if (!this.localCollection) {
1626
1704
  throw new telemetry_utils_1.LoggingError("attachSequence must be called");
1627
1705
  }
1628
1706
  return this.localCollection.endIntervalIndex.previousInterval(pos);
1629
1707
  }
1708
+ /**
1709
+ * {@inheritdoc IIntervalCollection.nextInterval}
1710
+ */
1630
1711
  nextInterval(pos) {
1631
1712
  if (!this.localCollection) {
1632
1713
  throw new telemetry_utils_1.LoggingError("attachSequence must be called");