@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
@@ -14,6 +14,7 @@ import {
14
14
  } from "../intervals";
15
15
  import { IntervalNode, IntervalTree } from "../intervalTree";
16
16
  import { SharedString } from "../sharedString";
17
+ import { SequencePlace, endpointPosAndSide } from "../intervalCollection";
17
18
  import { IntervalIndex } from "./intervalIndex";
18
19
 
19
20
  export interface IOverlappingIntervalsIndex<TInterval extends ISerializableInterval>
@@ -22,7 +23,7 @@ export interface IOverlappingIntervalsIndex<TInterval extends ISerializableInter
22
23
  * @returns an array of all intervals contained in this collection that overlap the range
23
24
  * `[start end]`.
24
25
  */
25
- findOverlappingIntervals(start: number, end: number): TInterval[];
26
+ findOverlappingIntervals(start: SequencePlace, end: SequencePlace): TInterval[];
26
27
 
27
28
  /**
28
29
  * Gathers the interval results based on specified parameters.
@@ -30,8 +31,8 @@ export interface IOverlappingIntervalsIndex<TInterval extends ISerializableInter
30
31
  gatherIterationResults(
31
32
  results: TInterval[],
32
33
  iteratesForward: boolean,
33
- start?: number,
34
- end?: number,
34
+ start?: SequencePlace,
35
+ end?: SequencePlace,
35
36
  ): void;
36
37
  }
37
38
 
@@ -58,8 +59,8 @@ export class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>
58
59
  public gatherIterationResults(
59
60
  results: TInterval[],
60
61
  iteratesForward: boolean,
61
- start?: number,
62
- end?: number,
62
+ start?: SequencePlace,
63
+ end?: SequencePlace,
63
64
  ): void {
64
65
  if (this.intervalTree.intervals.isEmpty()) {
65
66
  return;
@@ -79,8 +80,8 @@ export class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>
79
80
  } else {
80
81
  const transientInterval: TInterval = this.helpers.create(
81
82
  "transient",
82
- start,
83
- end,
83
+ start ?? "start",
84
+ end ?? "end",
84
85
  this.client,
85
86
  IntervalType.Transient,
86
87
  );
@@ -137,8 +138,15 @@ export class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>
137
138
  }
138
139
  }
139
140
 
140
- public findOverlappingIntervals(start: number, end: number): TInterval[] {
141
- if (end < start || this.intervalTree.intervals.isEmpty()) {
141
+ public findOverlappingIntervals(start: SequencePlace, end: SequencePlace): TInterval[] {
142
+ const { startPos, endPos } = endpointPosAndSide(start, end);
143
+
144
+ if (
145
+ startPos === undefined ||
146
+ endPos === undefined ||
147
+ endPos < startPos ||
148
+ this.intervalTree.intervals.isEmpty()
149
+ ) {
142
150
  return [];
143
151
  }
144
152
  const transientInterval = this.helpers.create(
@@ -5,7 +5,6 @@
5
5
  /* eslint-disable import/no-deprecated */
6
6
 
7
7
  import { Client, PropertyAction, RedBlackTree } from "@fluidframework/merge-tree";
8
- import { assert } from "@fluidframework/core-utils";
9
8
  import {
10
9
  IIntervalHelpers,
11
10
  ISerializableInterval,
@@ -40,12 +39,7 @@ export class StartpointInRangeIndex<TInterval extends ISerializableInterval>
40
39
  private readonly helpers: IIntervalHelpers<TInterval>,
41
40
  ) {
42
41
  this.intervalTree = new RedBlackTree<TInterval, TInterval>((a: TInterval, b: TInterval) => {
43
- assert(
44
- typeof helpers.compareStarts === "function",
45
- 0x6d1 /* compareStarts does not exist in the helpers */,
46
- );
47
-
48
- const compareStartsResult = helpers.compareStarts(a, b);
42
+ const compareStartsResult = a.compareStart(b);
49
43
  if (compareStartsResult !== 0) {
50
44
  return compareStartsResult;
51
45
  }
@@ -13,6 +13,8 @@ import {
13
13
  } from "@fluidframework/merge-tree";
14
14
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
15
15
  import { assert } from "@fluidframework/core-utils";
16
+ import { UsageError } from "@fluidframework/telemetry-utils";
17
+ import { SequencePlace } from "../intervalCollection";
16
18
  import { IIntervalHelpers, ISerializableInterval, ISerializedInterval } from "./intervalUtils";
17
19
 
18
20
  const reservedIntervalIdKey = "intervalId";
@@ -185,9 +187,21 @@ export class Interval implements ISerializableInterval {
185
187
  * {@inheritDoc IInterval.modify}
186
188
  * @internal
187
189
  */
188
- public modify(label: string, start: number, end: number, op?: ISequencedDocumentMessage) {
189
- const startPos = start ?? this.start;
190
- const endPos = end ?? this.end;
190
+ public modify(
191
+ label: string,
192
+ start?: SequencePlace,
193
+ end?: SequencePlace,
194
+ op?: ISequencedDocumentMessage,
195
+ ) {
196
+ if (typeof start === "string" || typeof end === "string") {
197
+ throw new UsageError(
198
+ "The start and end positions of a plain interval may not be on the special endpoint segments.",
199
+ );
200
+ }
201
+
202
+ const startPos = typeof start === "number" ? start : start?.pos ?? this.start;
203
+ const endPos = typeof end === "number" ? end : end?.pos ?? this.end;
204
+
191
205
  if (this.start === startPos && this.end === endPos) {
192
206
  // Return undefined to indicate that no change is necessary.
193
207
  return;
@@ -214,18 +228,25 @@ export class Interval implements ISerializableInterval {
214
228
  }
215
229
  }
216
230
 
217
- export function createInterval(label: string, start: number, end: number): Interval {
231
+ export function createInterval(label: string, start: SequencePlace, end: SequencePlace): Interval {
232
+ if (typeof start === "string" || typeof end === "string") {
233
+ throw new UsageError(
234
+ "The start and end positions of a plain interval may not be on the special endpoint segments.",
235
+ );
236
+ }
237
+
218
238
  const rangeProp: PropertySet = {};
219
239
 
220
240
  if (label && label.length > 0) {
221
241
  rangeProp[reservedRangeLabelsKey] = [label];
222
242
  }
223
243
 
224
- return new Interval(start, end, rangeProp);
244
+ const startPos = typeof start === "number" ? start : start.pos;
245
+ const endPos = typeof end === "number" ? end : end.pos;
246
+
247
+ return new Interval(startPos, endPos, rangeProp);
225
248
  }
226
249
 
227
250
  export const intervalHelpers: IIntervalHelpers<Interval> = {
228
- compareEnds: (a: Interval, b: Interval) => a.end - b.end,
229
- compareStarts: (a: Interval, b: Interval) => a.start - b.start,
230
251
  create: createInterval,
231
252
  };
@@ -12,6 +12,7 @@ import {
12
12
  SlidingPreference,
13
13
  } from "@fluidframework/merge-tree";
14
14
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
15
+ import { SequencePlace, Side } from "../intervalCollection";
15
16
 
16
17
  /**
17
18
  * Basic interval abstraction
@@ -47,10 +48,11 @@ export interface IInterval {
47
48
  */
48
49
  modify(
49
50
  label: string,
50
- start: number | undefined,
51
- end: number | undefined,
51
+ start: SequencePlace | undefined,
52
+ end: SequencePlace | undefined,
52
53
  op?: ISequencedDocumentMessage,
53
54
  localSeq?: number,
55
+ useNewSlidingBehavior?: boolean,
54
56
  ): IInterval | undefined;
55
57
  /**
56
58
  * @returns whether this interval overlaps with `b`.
@@ -112,12 +114,17 @@ export interface ISerializedInterval {
112
114
  */
113
115
  sequenceNumber: number;
114
116
  /** Start position of the interval */
115
- start: number;
117
+ start: number | "start" | "end";
116
118
  /** End position of the interval */
117
- end: number;
119
+ end: number | "start" | "end";
118
120
  /** Interval type to create */
119
121
  intervalType: IntervalType;
122
+ /**
123
+ * The stickiness of this interval
124
+ */
120
125
  stickiness?: IntervalStickiness;
126
+ startSide?: Side;
127
+ endSide?: Side;
121
128
  /** Any properties the interval has */
122
129
  properties?: PropertySet;
123
130
  }
@@ -159,26 +166,33 @@ export type SerializedIntervalDelta = Omit<ISerializedInterval, "start" | "end"
159
166
  *
160
167
  * Intervals are of the format:
161
168
  *
162
- * [start, end, sequenceNumber, intervalType, properties, stickiness?]
169
+ * [
170
+ * start,
171
+ * end,
172
+ * sequenceNumber,
173
+ * intervalType,
174
+ * properties,
175
+ * stickiness?,
176
+ * startSide?,
177
+ * endSide?,
178
+ * ]
163
179
  */
164
180
  export type CompressedSerializedInterval =
165
- | [number, number, number, IntervalType, PropertySet, IntervalStickiness]
166
- | [number, number, number, IntervalType, PropertySet];
181
+ | [
182
+ number | "start" | "end",
183
+ number | "start" | "end",
184
+ number,
185
+ IntervalType,
186
+ PropertySet,
187
+ IntervalStickiness,
188
+ ]
189
+ | [number | "start" | "end", number | "start" | "end", number, IntervalType, PropertySet];
167
190
 
168
191
  /**
169
192
  * @sealed
170
193
  * @deprecated The methods within have substitutions
171
194
  */
172
195
  export interface IIntervalHelpers<TInterval extends ISerializableInterval> {
173
- /**
174
- * @deprecated Use the method `IInterval.compareEnd` instead
175
- */
176
- compareEnds(a: TInterval, b: TInterval): number;
177
-
178
- /**
179
- * @deprecated Use the method `IInterval.compareStart` instead
180
- */
181
- compareStarts?(a: TInterval, b: TInterval): number;
182
196
  /**
183
197
  *
184
198
  * @param label - label of the interval collection this interval is being added to. This parameter is
@@ -189,17 +203,20 @@ export interface IIntervalHelpers<TInterval extends ISerializableInterval> {
189
203
  * @param intervalType - Type of interval to create. Default is SlideOnRemove
190
204
  * @param op - If this create came from a remote client, op that created it. Default is undefined (i.e. local)
191
205
  * @param fromSnapshot - If this create came from loading a snapshot. Default is false.
192
- * @param stickiness - {@link (IntervalStickiness:type)} to apply to the added interval.
206
+ * @param startSide - The side on which the start position lays. See
207
+ * {@link SequencePlace} for additional context
208
+ * @param endSide - The side on which the end position lays. See
209
+ * {@link SequencePlace} for additional context
193
210
  */
194
211
  create(
195
212
  label: string,
196
- start: number | undefined,
197
- end: number | undefined,
213
+ start: SequencePlace | undefined,
214
+ end: SequencePlace | undefined,
198
215
  client: Client | undefined,
199
216
  intervalType: IntervalType,
200
217
  op?: ISequencedDocumentMessage,
201
218
  fromSnapshot?: boolean,
202
- stickiness?: IntervalStickiness,
219
+ useNewSlidingBehavior?: boolean,
203
220
  ): TInterval;
204
221
  }
205
222
 
@@ -209,6 +226,8 @@ export interface IIntervalHelpers<TInterval extends ISerializableInterval> {
209
226
  *
210
227
  * Note that interval stickiness is currently an experimental feature and must
211
228
  * be explicitly enabled with the `intervalStickinessEnabled` flag
229
+ *
230
+ * @internal
212
231
  */
213
232
  export const IntervalStickiness = {
214
233
  /**
@@ -240,19 +259,21 @@ export const IntervalStickiness = {
240
259
  *
241
260
  * Note that interval stickiness is currently an experimental feature and must
242
261
  * be explicitly enabled with the `intervalStickinessEnabled` flag
262
+ *
263
+ * @internal
243
264
  */
244
265
  export type IntervalStickiness = typeof IntervalStickiness[keyof typeof IntervalStickiness];
245
266
 
246
- export function endReferenceSlidingPreference(stickiness: IntervalStickiness): SlidingPreference {
247
- // if any end stickiness, prefer sliding forwards
248
- return (stickiness & IntervalStickiness.END) !== 0
267
+ export function startReferenceSlidingPreference(stickiness: IntervalStickiness): SlidingPreference {
268
+ // if any start stickiness, prefer sliding backwards
269
+ return (stickiness & IntervalStickiness.START) === 0
249
270
  ? SlidingPreference.FORWARD
250
271
  : SlidingPreference.BACKWARD;
251
272
  }
252
273
 
253
- export function startReferenceSlidingPreference(stickiness: IntervalStickiness): SlidingPreference {
254
- // if any start stickiness, prefer sliding backwards
255
- return (stickiness & IntervalStickiness.START) !== 0
274
+ export function endReferenceSlidingPreference(stickiness: IntervalStickiness): SlidingPreference {
275
+ // if any end stickiness, prefer sliding forwards
276
+ return (stickiness & IntervalStickiness.END) === 0
256
277
  ? SlidingPreference.BACKWARD
257
278
  : SlidingPreference.FORWARD;
258
279
  }