@fluidframework/sequence 2.0.0-internal.6.3.3 → 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 (191) hide show
  1. package/CHANGELOG.md +64 -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 +2 -2
  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 +140 -22
  15. package/dist/intervalCollection.d.ts.map +1 -1
  16. package/dist/intervalCollection.js +146 -49
  17. package/dist/intervalCollection.js.map +1 -1
  18. package/dist/intervalIndex/endpointInRangeIndex.d.ts +13 -3
  19. package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
  20. package/dist/intervalIndex/endpointInRangeIndex.js +9 -6
  21. package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
  22. package/dist/intervalIndex/endpointIndex.d.ts +13 -2
  23. package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
  24. package/dist/intervalIndex/endpointIndex.js +7 -5
  25. package/dist/intervalIndex/endpointIndex.js.map +1 -1
  26. package/dist/intervalIndex/idIntervalIndex.js.map +1 -1
  27. package/dist/intervalIndex/index.d.ts +4 -4
  28. package/dist/intervalIndex/index.d.ts.map +1 -1
  29. package/dist/intervalIndex/index.js +5 -1
  30. package/dist/intervalIndex/index.js.map +1 -1
  31. package/dist/intervalIndex/intervalIndex.d.ts +2 -2
  32. package/dist/intervalIndex/intervalIndex.js.map +1 -1
  33. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +8 -6
  34. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  35. package/dist/intervalIndex/overlappingIntervalsIndex.js +11 -4
  36. package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  37. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +2 -2
  38. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -1
  39. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js +3 -1
  40. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -1
  41. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +1 -1
  42. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -1
  43. package/dist/intervalIndex/sequenceIntervalIndexes.js.map +1 -1
  44. package/dist/intervalIndex/startpointInRangeIndex.d.ts +13 -3
  45. package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
  46. package/dist/intervalIndex/startpointInRangeIndex.js +9 -8
  47. package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
  48. package/dist/intervalTree.d.ts +1 -1
  49. package/dist/intervalTree.d.ts.map +1 -1
  50. package/dist/intervals/interval.d.ts +4 -3
  51. package/dist/intervals/interval.d.ts.map +1 -1
  52. package/dist/intervals/interval.js +14 -6
  53. package/dist/intervals/interval.js.map +1 -1
  54. package/dist/intervals/intervalUtils.d.ts +42 -20
  55. package/dist/intervals/intervalUtils.d.ts.map +1 -1
  56. package/dist/intervals/intervalUtils.js +12 -10
  57. package/dist/intervals/intervalUtils.js.map +1 -1
  58. package/dist/intervals/sequenceInterval.d.ts +30 -17
  59. package/dist/intervals/sequenceInterval.d.ts.map +1 -1
  60. package/dist/intervals/sequenceInterval.js +124 -45
  61. package/dist/intervals/sequenceInterval.js.map +1 -1
  62. package/dist/packageVersion.d.ts +1 -1
  63. package/dist/packageVersion.js +1 -1
  64. package/dist/packageVersion.js.map +1 -1
  65. package/dist/revertibles.d.ts +3 -15
  66. package/dist/revertibles.d.ts.map +1 -1
  67. package/dist/revertibles.js +6 -17
  68. package/dist/revertibles.js.map +1 -1
  69. package/dist/sequence.d.ts +3 -2
  70. package/dist/sequence.d.ts.map +1 -1
  71. package/dist/sequence.js +46 -45
  72. package/dist/sequence.js.map +1 -1
  73. package/dist/sequenceDeltaEvent.d.ts +8 -3
  74. package/dist/sequenceDeltaEvent.d.ts.map +1 -1
  75. package/dist/sequenceDeltaEvent.js.map +1 -1
  76. package/dist/sequenceFactory.js +1 -1
  77. package/dist/sequenceFactory.js.map +1 -1
  78. package/dist/sharedIntervalCollection.js +9 -9
  79. package/dist/sharedIntervalCollection.js.map +1 -1
  80. package/dist/sharedSequence.js +6 -6
  81. package/dist/sharedSequence.js.map +1 -1
  82. package/dist/sharedString.d.ts +1 -1
  83. package/dist/sharedString.d.ts.map +1 -1
  84. package/dist/sharedString.js +7 -6
  85. package/dist/sharedString.js.map +1 -1
  86. package/dist/tsdoc-metadata.json +1 -1
  87. package/lib/defaultMap.d.ts +1 -1
  88. package/lib/defaultMap.d.ts.map +1 -1
  89. package/lib/defaultMap.js +6 -6
  90. package/lib/defaultMap.js.map +1 -1
  91. package/lib/defaultMapInterfaces.d.ts +21 -2
  92. package/lib/defaultMapInterfaces.d.ts.map +1 -1
  93. package/lib/defaultMapInterfaces.js.map +1 -1
  94. package/lib/index.d.ts +2 -2
  95. package/lib/index.d.ts.map +1 -1
  96. package/lib/index.js +1 -1
  97. package/lib/index.js.map +1 -1
  98. package/lib/intervalCollection.d.ts +140 -22
  99. package/lib/intervalCollection.d.ts.map +1 -1
  100. package/lib/intervalCollection.js +144 -50
  101. package/lib/intervalCollection.js.map +1 -1
  102. package/lib/intervalIndex/endpointInRangeIndex.d.ts +13 -3
  103. package/lib/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
  104. package/lib/intervalIndex/endpointInRangeIndex.js +9 -7
  105. package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -1
  106. package/lib/intervalIndex/endpointIndex.d.ts +13 -2
  107. package/lib/intervalIndex/endpointIndex.d.ts.map +1 -1
  108. package/lib/intervalIndex/endpointIndex.js +7 -6
  109. package/lib/intervalIndex/endpointIndex.js.map +1 -1
  110. package/lib/intervalIndex/idIntervalIndex.js.map +1 -1
  111. package/lib/intervalIndex/index.d.ts +4 -4
  112. package/lib/intervalIndex/index.d.ts.map +1 -1
  113. package/lib/intervalIndex/index.js +4 -4
  114. package/lib/intervalIndex/index.js.map +1 -1
  115. package/lib/intervalIndex/intervalIndex.d.ts +2 -2
  116. package/lib/intervalIndex/intervalIndex.js.map +1 -1
  117. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +8 -6
  118. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  119. package/lib/intervalIndex/overlappingIntervalsIndex.js +12 -5
  120. package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  121. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +2 -2
  122. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -1
  123. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js +3 -1
  124. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -1
  125. package/lib/intervalIndex/sequenceIntervalIndexes.d.ts +1 -1
  126. package/lib/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -1
  127. package/lib/intervalIndex/sequenceIntervalIndexes.js.map +1 -1
  128. package/lib/intervalIndex/startpointInRangeIndex.d.ts +13 -3
  129. package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
  130. package/lib/intervalIndex/startpointInRangeIndex.js +9 -9
  131. package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -1
  132. package/lib/intervalTree.d.ts +1 -1
  133. package/lib/intervalTree.d.ts.map +1 -1
  134. package/lib/intervals/interval.d.ts +4 -3
  135. package/lib/intervals/interval.d.ts.map +1 -1
  136. package/lib/intervals/interval.js +14 -6
  137. package/lib/intervals/interval.js.map +1 -1
  138. package/lib/intervals/intervalUtils.d.ts +42 -20
  139. package/lib/intervals/intervalUtils.d.ts.map +1 -1
  140. package/lib/intervals/intervalUtils.js +8 -6
  141. package/lib/intervals/intervalUtils.js.map +1 -1
  142. package/lib/intervals/sequenceInterval.d.ts +30 -17
  143. package/lib/intervals/sequenceInterval.d.ts.map +1 -1
  144. package/lib/intervals/sequenceInterval.js +125 -44
  145. package/lib/intervals/sequenceInterval.js.map +1 -1
  146. package/lib/packageVersion.d.ts +1 -1
  147. package/lib/packageVersion.js +1 -1
  148. package/lib/packageVersion.js.map +1 -1
  149. package/lib/revertibles.d.ts +3 -15
  150. package/lib/revertibles.d.ts.map +1 -1
  151. package/lib/revertibles.js +6 -17
  152. package/lib/revertibles.js.map +1 -1
  153. package/lib/sequence.d.ts +3 -2
  154. package/lib/sequence.d.ts.map +1 -1
  155. package/lib/sequence.js +46 -45
  156. package/lib/sequence.js.map +1 -1
  157. package/lib/sequenceDeltaEvent.d.ts +8 -3
  158. package/lib/sequenceDeltaEvent.d.ts.map +1 -1
  159. package/lib/sequenceDeltaEvent.js.map +1 -1
  160. package/lib/sequenceFactory.js +1 -1
  161. package/lib/sequenceFactory.js.map +1 -1
  162. package/lib/sharedIntervalCollection.js +9 -9
  163. package/lib/sharedIntervalCollection.js.map +1 -1
  164. package/lib/sharedSequence.js +6 -6
  165. package/lib/sharedSequence.js.map +1 -1
  166. package/lib/sharedString.d.ts +1 -1
  167. package/lib/sharedString.d.ts.map +1 -1
  168. package/lib/sharedString.js +7 -6
  169. package/lib/sharedString.js.map +1 -1
  170. package/package.json +49 -23
  171. package/src/defaultMapInterfaces.ts +21 -2
  172. package/src/index.ts +4 -1
  173. package/src/intervalCollection.ts +347 -84
  174. package/src/intervalIndex/endpointInRangeIndex.ts +19 -11
  175. package/src/intervalIndex/endpointIndex.ts +16 -9
  176. package/src/intervalIndex/idIntervalIndex.ts +1 -1
  177. package/src/intervalIndex/index.ts +12 -3
  178. package/src/intervalIndex/intervalIndex.ts +2 -2
  179. package/src/intervalIndex/overlappingIntervalsIndex.ts +31 -15
  180. package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +4 -1
  181. package/src/intervalIndex/sequenceIntervalIndexes.ts +1 -1
  182. package/src/intervalIndex/startpointInRangeIndex.ts +19 -17
  183. package/src/intervals/interval.ts +30 -8
  184. package/src/intervals/intervalUtils.ts +51 -28
  185. package/src/intervals/sequenceInterval.ts +197 -49
  186. package/src/packageVersion.ts +1 -1
  187. package/src/revertibles.ts +8 -33
  188. package/src/sequence.ts +5 -2
  189. package/src/sequenceDeltaEvent.ts +11 -3
  190. package/src/sequenceFactory.ts +1 -1
  191. package/src/sharedString.ts +2 -1
@@ -2,9 +2,17 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ /* eslint-disable import/no-deprecated */
5
6
 
6
7
  import { Client, PropertyAction, RedBlackTree } from "@fluidframework/merge-tree";
7
- import { IIntervalHelpers, ISerializableInterval, IntervalType } from "../intervals";
8
+ import {
9
+ IIntervalHelpers,
10
+ ISerializableInterval,
11
+ IntervalType,
12
+ SequenceInterval,
13
+ sequenceIntervalHelpers,
14
+ } from "../intervals";
15
+ import { SharedString } from "../sharedString";
8
16
  import { IntervalIndex } from "./intervalIndex";
9
17
  import { HasComparisonOverride, compareOverrideables, forceCompare } from "./intervalIndexUtils";
10
18
 
@@ -18,20 +26,20 @@ export interface IEndpointInRangeIndex<TInterval extends ISerializableInterval>
18
26
  /**
19
27
  * @returns an array of all intervals contained in this collection whose endpoints locate in the range [start, end] (includes both ends)
20
28
  */
21
- findIntervalsWithEndpointInRange(start: number, end: number);
29
+ findIntervalsWithEndpointInRange(start: number, end: number): TInterval[];
22
30
  }
23
31
 
24
- class EndpointInRangeIndex<TInterval extends ISerializableInterval>
32
+ export class EndpointInRangeIndex<TInterval extends ISerializableInterval>
25
33
  implements IEndpointInRangeIndex<TInterval>
26
34
  {
27
35
  private readonly intervalTree;
28
36
 
29
37
  constructor(
30
- private readonly helpers: IIntervalHelpers<TInterval>,
31
38
  private readonly client: Client,
39
+ private readonly helpers: IIntervalHelpers<TInterval>,
32
40
  ) {
33
41
  this.intervalTree = new RedBlackTree<TInterval, TInterval>((a: TInterval, b: TInterval) => {
34
- const compareEndsResult = helpers.compareEnds(a, b);
42
+ const compareEndsResult = a.compareEnd(b);
35
43
  if (compareEndsResult !== 0) {
36
44
  return compareEndsResult;
37
45
  }
@@ -61,7 +69,7 @@ class EndpointInRangeIndex<TInterval extends ISerializableInterval>
61
69
  this.intervalTree.remove(interval);
62
70
  }
63
71
 
64
- public findIntervalsWithEndpointInRange(start: number, end: number) {
72
+ public findIntervalsWithEndpointInRange(start: number, end: number): TInterval[] {
65
73
  if (start <= 0 || start > end || this.intervalTree.isEmpty()) {
66
74
  return [];
67
75
  }
@@ -96,9 +104,9 @@ class EndpointInRangeIndex<TInterval extends ISerializableInterval>
96
104
  }
97
105
  }
98
106
 
99
- export function createEndpointInRangeIndex<TInterval extends ISerializableInterval>(
100
- helpers: IIntervalHelpers<TInterval>,
101
- client: Client,
102
- ): IEndpointInRangeIndex<TInterval> {
103
- return new EndpointInRangeIndex<TInterval>(helpers, client);
107
+ export function createEndpointInRangeIndex(
108
+ sharedString: SharedString,
109
+ ): IEndpointInRangeIndex<SequenceInterval> {
110
+ const client = (sharedString as unknown as { client: Client }).client;
111
+ return new EndpointInRangeIndex<SequenceInterval>(client, sequenceIntervalHelpers);
104
112
  }
@@ -2,9 +2,17 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ /* eslint-disable import/no-deprecated */
5
6
 
6
7
  import { Client, RedBlackTree } from "@fluidframework/merge-tree";
7
- import { IIntervalHelpers, ISerializableInterval, IntervalType } from "../intervals";
8
+ import {
9
+ IIntervalHelpers,
10
+ ISerializableInterval,
11
+ IntervalType,
12
+ SequenceInterval,
13
+ sequenceIntervalHelpers,
14
+ } from "../intervals";
15
+ import { SharedString } from "../sharedString";
8
16
  import { IntervalIndex } from "./intervalIndex";
9
17
 
10
18
  export interface IEndpointIndex<TInterval extends ISerializableInterval>
@@ -22,15 +30,16 @@ export interface IEndpointIndex<TInterval extends ISerializableInterval>
22
30
  nextInterval(pos: number): TInterval | undefined;
23
31
  }
24
32
 
25
- class EndpointIndex<TInterval extends ISerializableInterval> implements IEndpointIndex<TInterval> {
33
+ export class EndpointIndex<TInterval extends ISerializableInterval>
34
+ implements IEndpointIndex<TInterval>
35
+ {
26
36
  private readonly endIntervalTree: RedBlackTree<TInterval, TInterval>;
27
37
 
28
38
  constructor(
29
39
  private readonly client: Client,
30
40
  private readonly helpers: IIntervalHelpers<TInterval>,
31
41
  ) {
32
- // eslint-disable-next-line @typescript-eslint/unbound-method
33
- this.endIntervalTree = new RedBlackTree<TInterval, TInterval>(helpers.compareEnds);
42
+ this.endIntervalTree = new RedBlackTree<TInterval, TInterval>((a, b) => a.compareEnd(b));
34
43
  }
35
44
 
36
45
  public previousInterval(pos: number): TInterval | undefined {
@@ -70,9 +79,7 @@ class EndpointIndex<TInterval extends ISerializableInterval> implements IEndpoin
70
79
  }
71
80
  }
72
81
 
73
- export function createEndpointIndex<TInterval extends ISerializableInterval>(
74
- client: Client,
75
- helpers: IIntervalHelpers<TInterval>,
76
- ): IEndpointIndex<TInterval> {
77
- return new EndpointIndex<TInterval>(client, helpers);
82
+ export function createEndpointIndex(sharedString: SharedString): IEndpointIndex<SequenceInterval> {
83
+ const client = (sharedString as unknown as { client: Client }).client;
84
+ return new EndpointIndex<SequenceInterval>(client, sequenceIntervalHelpers);
78
85
  }
@@ -19,7 +19,7 @@ export interface IIdIntervalIndex<TInterval extends ISerializableInterval>
19
19
  class IdIntervalIndex<TInterval extends ISerializableInterval>
20
20
  implements IIdIntervalIndex<TInterval>, Iterable<TInterval>
21
21
  {
22
- private readonly intervalIdMap: Map<string, TInterval> = new Map();
22
+ private readonly intervalIdMap = new Map<string, TInterval>();
23
23
 
24
24
  public add(interval: TInterval) {
25
25
  const id = interval.getIntervalId();
@@ -5,12 +5,21 @@
5
5
 
6
6
  export { IntervalIndex } from "./intervalIndex";
7
7
  export { IIdIntervalIndex, createIdIntervalIndex } from "./idIntervalIndex";
8
- export { IEndpointIndex, createEndpointIndex } from "./endpointIndex";
9
- export { IEndpointInRangeIndex, createEndpointInRangeIndex } from "./endpointInRangeIndex";
10
- export { IStartpointInRangeIndex, createStartpointInRangeIndex } from "./startpointInRangeIndex";
8
+ export { IEndpointIndex, createEndpointIndex, EndpointIndex } from "./endpointIndex";
9
+ export {
10
+ IEndpointInRangeIndex,
11
+ createEndpointInRangeIndex,
12
+ EndpointInRangeIndex,
13
+ } from "./endpointInRangeIndex";
14
+ export {
15
+ IStartpointInRangeIndex,
16
+ createStartpointInRangeIndex,
17
+ StartpointInRangeIndex,
18
+ } from "./startpointInRangeIndex";
11
19
  export { SequenceIntervalIndexes } from "./sequenceIntervalIndexes";
12
20
  export {
13
21
  IOverlappingIntervalsIndex,
14
22
  createOverlappingIntervalsIndex,
23
+ OverlappingIntervalsIndex,
15
24
  } from "./overlappingIntervalsIndex";
16
25
  export { createOverlappingSequenceIntervalsIndex } from "./overlappingSequenceIntervalsIndex";
@@ -17,14 +17,14 @@ import { ISerializableInterval } from "../intervals";
17
17
  export interface IntervalIndex<TInterval extends ISerializableInterval> {
18
18
  /**
19
19
  * Adds an interval to the index.
20
- * @remarks - Application code should never need to invoke this method on their index for production scenarios:
20
+ * @remarks Application code should never need to invoke this method on their index for production scenarios:
21
21
  * Fluid handles adding and removing intervals from an index in response to sequence or interval changes.
22
22
  */
23
23
  add(interval: TInterval): void;
24
24
 
25
25
  /**
26
26
  * Removes an interval from the index.
27
- * @remarks - Application code should never need to invoke this method on their index for production scenarios:
27
+ * @remarks Application code should never need to invoke this method on their index for production scenarios:
28
28
  * Fluid handles adding and removing intervals from an index in response to sequence or interval changes.
29
29
  */
30
30
  remove(interval: TInterval): void;
@@ -2,10 +2,19 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ /* eslint-disable import/no-deprecated */
5
6
 
6
7
  import { Client } from "@fluidframework/merge-tree";
7
- import { IntervalType, IIntervalHelpers, ISerializableInterval } from "../intervals";
8
+ import {
9
+ IntervalType,
10
+ IIntervalHelpers,
11
+ ISerializableInterval,
12
+ sequenceIntervalHelpers,
13
+ SequenceInterval,
14
+ } from "../intervals";
8
15
  import { IntervalNode, IntervalTree } from "../intervalTree";
16
+ import { SharedString } from "../sharedString";
17
+ import { SequencePlace, endpointPosAndSide } from "../intervalCollection";
9
18
  import { IntervalIndex } from "./intervalIndex";
10
19
 
11
20
  export interface IOverlappingIntervalsIndex<TInterval extends ISerializableInterval>
@@ -14,7 +23,7 @@ export interface IOverlappingIntervalsIndex<TInterval extends ISerializableInter
14
23
  * @returns an array of all intervals contained in this collection that overlap the range
15
24
  * `[start end]`.
16
25
  */
17
- findOverlappingIntervals(start: number, end: number): TInterval[];
26
+ findOverlappingIntervals(start: SequencePlace, end: SequencePlace): TInterval[];
18
27
 
19
28
  /**
20
29
  * Gathers the interval results based on specified parameters.
@@ -22,8 +31,8 @@ export interface IOverlappingIntervalsIndex<TInterval extends ISerializableInter
22
31
  gatherIterationResults(
23
32
  results: TInterval[],
24
33
  iteratesForward: boolean,
25
- start?: number,
26
- end?: number,
34
+ start?: SequencePlace,
35
+ end?: SequencePlace,
27
36
  ): void;
28
37
  }
29
38
 
@@ -50,8 +59,8 @@ export class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>
50
59
  public gatherIterationResults(
51
60
  results: TInterval[],
52
61
  iteratesForward: boolean,
53
- start?: number,
54
- end?: number,
62
+ start?: SequencePlace,
63
+ end?: SequencePlace,
55
64
  ): void {
56
65
  if (this.intervalTree.intervals.isEmpty()) {
57
66
  return;
@@ -71,8 +80,8 @@ export class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>
71
80
  } else {
72
81
  const transientInterval: TInterval = this.helpers.create(
73
82
  "transient",
74
- start,
75
- end,
83
+ start ?? "start",
84
+ end ?? "end",
76
85
  this.client,
77
86
  IntervalType.Transient,
78
87
  );
@@ -129,8 +138,15 @@ export class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>
129
138
  }
130
139
  }
131
140
 
132
- public findOverlappingIntervals(start: number, end: number): TInterval[] {
133
- 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
+ ) {
134
150
  return [];
135
151
  }
136
152
  const transientInterval = this.helpers.create(
@@ -154,9 +170,9 @@ export class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>
154
170
  }
155
171
  }
156
172
 
157
- export function createOverlappingIntervalsIndex<TInterval extends ISerializableInterval>(
158
- client: Client,
159
- helpers: IIntervalHelpers<TInterval>,
160
- ): IOverlappingIntervalsIndex<TInterval> {
161
- return new OverlappingIntervalsIndex<TInterval>(client, helpers);
173
+ export function createOverlappingIntervalsIndex(
174
+ sharedString: SharedString,
175
+ ): IOverlappingIntervalsIndex<SequenceInterval> {
176
+ const client = (sharedString as unknown as { client: Client }).client;
177
+ return new OverlappingIntervalsIndex<SequenceInterval>(client, sequenceIntervalHelpers);
162
178
  }
@@ -2,6 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ /* eslint-disable import/no-deprecated */
5
6
 
6
7
  import {
7
8
  Client,
@@ -16,6 +17,7 @@ import {
16
17
  SequenceInterval,
17
18
  createPositionReferenceFromSegoff,
18
19
  } from "../intervals";
20
+ import { SharedString } from "../sharedString";
19
21
  import { SequenceIntervalIndexes } from "./sequenceIntervalIndexes";
20
22
  import { OverlappingIntervalsIndex } from "./overlappingIntervalsIndex";
21
23
 
@@ -65,7 +67,8 @@ class OverlappingSequenceIntervalsIndex
65
67
  }
66
68
 
67
69
  export function createOverlappingSequenceIntervalsIndex(
68
- client: Client,
70
+ sharedString: SharedString,
69
71
  ): SequenceIntervalIndexes.Overlapping {
72
+ const client = (sharedString as unknown as { client: Client }).client;
70
73
  return new OverlappingSequenceIntervalsIndex(client);
71
74
  }
@@ -27,6 +27,6 @@ export namespace SequenceIntervalIndexes {
27
27
  findOverlappingIntervalsBySegoff(
28
28
  startSegoff: { segment: ISegment | undefined; offset: number | undefined },
29
29
  endSegoff: { segment: ISegment | undefined; offset: number | undefined },
30
- );
30
+ ): Iterable<SequenceInterval>;
31
31
  }
32
32
  }
@@ -2,10 +2,17 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ /* eslint-disable import/no-deprecated */
5
6
 
6
7
  import { Client, PropertyAction, RedBlackTree } from "@fluidframework/merge-tree";
7
- import { assert } from "@fluidframework/core-utils";
8
- import { IIntervalHelpers, ISerializableInterval, IntervalType } from "../intervals";
8
+ import {
9
+ IIntervalHelpers,
10
+ ISerializableInterval,
11
+ IntervalType,
12
+ SequenceInterval,
13
+ sequenceIntervalHelpers,
14
+ } from "../intervals";
15
+ import { SharedString } from "../sharedString";
9
16
  import { IntervalIndex } from "./intervalIndex";
10
17
  import { HasComparisonOverride, compareOverrideables, forceCompare } from "./intervalIndexUtils";
11
18
 
@@ -19,25 +26,20 @@ export interface IStartpointInRangeIndex<TInterval extends ISerializableInterval
19
26
  /**
20
27
  * @returns an array of all intervals contained in this collection whose startpoints locate in the range [start, end] (includes both ends)
21
28
  */
22
- findIntervalsWithStartpointInRange(start: number, end: number);
29
+ findIntervalsWithStartpointInRange(start: number, end: number): TInterval[];
23
30
  }
24
31
 
25
- class StartpointInRangeIndex<TInterval extends ISerializableInterval>
32
+ export class StartpointInRangeIndex<TInterval extends ISerializableInterval>
26
33
  implements IStartpointInRangeIndex<TInterval>
27
34
  {
28
35
  private readonly intervalTree;
29
36
 
30
37
  constructor(
31
- private readonly helpers: IIntervalHelpers<TInterval>,
32
38
  private readonly client: Client,
39
+ private readonly helpers: IIntervalHelpers<TInterval>,
33
40
  ) {
34
41
  this.intervalTree = new RedBlackTree<TInterval, TInterval>((a: TInterval, b: TInterval) => {
35
- assert(
36
- typeof helpers.compareStarts === "function",
37
- 0x6d1 /* compareStarts does not exist in the helpers */,
38
- );
39
-
40
- const compareStartsResult = helpers.compareStarts(a, b);
42
+ const compareStartsResult = a.compareStart(b);
41
43
  if (compareStartsResult !== 0) {
42
44
  return compareStartsResult;
43
45
  }
@@ -66,7 +68,7 @@ class StartpointInRangeIndex<TInterval extends ISerializableInterval>
66
68
  this.intervalTree.remove(interval);
67
69
  }
68
70
 
69
- public findIntervalsWithStartpointInRange(start: number, end: number) {
71
+ public findIntervalsWithStartpointInRange(start: number, end: number): TInterval[] {
70
72
  if (start <= 0 || start > end || this.intervalTree.isEmpty()) {
71
73
  return [];
72
74
  }
@@ -101,9 +103,9 @@ class StartpointInRangeIndex<TInterval extends ISerializableInterval>
101
103
  }
102
104
  }
103
105
 
104
- export function createStartpointInRangeIndex<TInterval extends ISerializableInterval>(
105
- helpers: IIntervalHelpers<TInterval>,
106
- client: Client,
107
- ): IStartpointInRangeIndex<TInterval> {
108
- return new StartpointInRangeIndex<TInterval>(helpers, client);
106
+ export function createStartpointInRangeIndex(
107
+ sharedString: SharedString,
108
+ ): IStartpointInRangeIndex<SequenceInterval> {
109
+ const client = (sharedString as unknown as { client: Client }).client;
110
+ return new StartpointInRangeIndex<SequenceInterval>(client, sequenceIntervalHelpers);
109
111
  }
@@ -2,6 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ /* eslint-disable import/no-deprecated */
5
6
 
6
7
  import {
7
8
  ICombiningOp,
@@ -12,6 +13,8 @@ import {
12
13
  } from "@fluidframework/merge-tree";
13
14
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
14
15
  import { assert } from "@fluidframework/core-utils";
16
+ import { UsageError } from "@fluidframework/telemetry-utils";
17
+ import { SequencePlace } from "../intervalCollection";
15
18
  import { IIntervalHelpers, ISerializableInterval, ISerializedInterval } from "./intervalUtils";
16
19
 
17
20
  const reservedIntervalIdKey = "intervalId";
@@ -60,7 +63,7 @@ export class Interval implements ISerializableInterval {
60
63
  * Adds an auxiliary set of properties to this interval.
61
64
  * These properties can be recovered using `getAdditionalPropertySets`
62
65
  * @param props - set of properties to add
63
- * @remarks - This gets called as part of the default conflict resolver for `IIntervalCollection<Interval>`
66
+ * @remarks This gets called as part of the default conflict resolver for `IIntervalCollection<Interval>`
64
67
  * (i.e. non-sequence-based interval collections). However, the additional properties don't get serialized.
65
68
  * This functionality seems half-baked.
66
69
  */
@@ -184,9 +187,21 @@ export class Interval implements ISerializableInterval {
184
187
  * {@inheritDoc IInterval.modify}
185
188
  * @internal
186
189
  */
187
- public modify(label: string, start: number, end: number, op?: ISequencedDocumentMessage) {
188
- const startPos = start ?? this.start;
189
- 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
+
190
205
  if (this.start === startPos && this.end === endPos) {
191
206
  // Return undefined to indicate that no change is necessary.
192
207
  return;
@@ -213,18 +228,25 @@ export class Interval implements ISerializableInterval {
213
228
  }
214
229
  }
215
230
 
216
- 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
+
217
238
  const rangeProp: PropertySet = {};
218
239
 
219
240
  if (label && label.length > 0) {
220
241
  rangeProp[reservedRangeLabelsKey] = [label];
221
242
  }
222
243
 
223
- 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);
224
248
  }
225
249
 
226
250
  export const intervalHelpers: IIntervalHelpers<Interval> = {
227
- compareEnds: (a: Interval, b: Interval) => a.end - b.end,
228
- compareStarts: (a: Interval, b: Interval) => a.start - b.start,
229
251
  create: createInterval,
230
252
  };
@@ -12,6 +12,8 @@ import {
12
12
  SlidingPreference,
13
13
  } from "@fluidframework/merge-tree";
14
14
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
15
+ import { SequencePlace, Side } from "../intervalCollection";
16
+
15
17
  /**
16
18
  * Basic interval abstraction
17
19
  */
@@ -46,10 +48,11 @@ export interface IInterval {
46
48
  */
47
49
  modify(
48
50
  label: string,
49
- start: number | undefined,
50
- end: number | undefined,
51
+ start: SequencePlace | undefined,
52
+ end: SequencePlace | undefined,
51
53
  op?: ISequencedDocumentMessage,
52
54
  localSeq?: number,
55
+ useNewSlidingBehavior?: boolean,
53
56
  ): IInterval | undefined;
54
57
  /**
55
58
  * @returns whether this interval overlaps with `b`.
@@ -105,18 +108,23 @@ export interface ISerializedInterval {
105
108
  /**
106
109
  * Sequence number at which `start` and `end` should be interpreted
107
110
  *
108
- * @remarks - It's unclear that this is necessary to store here.
111
+ * @remarks It's unclear that this is necessary to store here.
109
112
  * This should just be the refSeq on the op that modified the interval, which should be available via other means.
110
113
  * At the time of writing, it's not plumbed through to the reconnect/rebase code, however, which does need it.
111
114
  */
112
115
  sequenceNumber: number;
113
116
  /** Start position of the interval */
114
- start: number;
117
+ start: number | "start" | "end";
115
118
  /** End position of the interval */
116
- end: number;
119
+ end: number | "start" | "end";
117
120
  /** Interval type to create */
118
121
  intervalType: IntervalType;
122
+ /**
123
+ * The stickiness of this interval
124
+ */
119
125
  stickiness?: IntervalStickiness;
126
+ startSide?: Side;
127
+ endSide?: Side;
120
128
  /** Any properties the interval has */
121
129
  properties?: PropertySet;
122
130
  }
@@ -138,7 +146,7 @@ export interface ISerializableInterval extends IInterval {
138
146
  * Gets the id associated with this interval.
139
147
  * When the interval is used as part of an interval collection, this id can be used to modify or remove the
140
148
  * interval.
141
- * @remarks - This signature includes `undefined` strictly for backwards-compatibility reasons, as older versions
149
+ * @remarks This signature includes `undefined` strictly for backwards-compatibility reasons, as older versions
142
150
  * of Fluid didn't always write interval ids.
143
151
  */
144
152
  getIntervalId(): string | undefined;
@@ -158,25 +166,33 @@ export type SerializedIntervalDelta = Omit<ISerializedInterval, "start" | "end"
158
166
  *
159
167
  * Intervals are of the format:
160
168
  *
161
- * [start, end, sequenceNumber, intervalType, properties, stickiness?]
169
+ * [
170
+ * start,
171
+ * end,
172
+ * sequenceNumber,
173
+ * intervalType,
174
+ * properties,
175
+ * stickiness?,
176
+ * startSide?,
177
+ * endSide?,
178
+ * ]
162
179
  */
163
180
  export type CompressedSerializedInterval =
164
- | [number, number, number, IntervalType, PropertySet, IntervalStickiness]
165
- | [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];
166
190
 
167
191
  /**
168
192
  * @sealed
193
+ * @deprecated The methods within have substitutions
169
194
  */
170
195
  export interface IIntervalHelpers<TInterval extends ISerializableInterval> {
171
- /**
172
- * @deprecated Use the method `IInterval.compareEnd` instead
173
- */
174
- compareEnds(a: TInterval, b: TInterval): number;
175
-
176
- /**
177
- * @deprecated Use the method `IInterval.compareStart` instead
178
- */
179
- compareStarts?(a: TInterval, b: TInterval): number;
180
196
  /**
181
197
  *
182
198
  * @param label - label of the interval collection this interval is being added to. This parameter is
@@ -187,17 +203,20 @@ export interface IIntervalHelpers<TInterval extends ISerializableInterval> {
187
203
  * @param intervalType - Type of interval to create. Default is SlideOnRemove
188
204
  * @param op - If this create came from a remote client, op that created it. Default is undefined (i.e. local)
189
205
  * @param fromSnapshot - If this create came from loading a snapshot. Default is false.
190
- * @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
191
210
  */
192
211
  create(
193
212
  label: string,
194
- start: number | undefined,
195
- end: number | undefined,
213
+ start: SequencePlace | undefined,
214
+ end: SequencePlace | undefined,
196
215
  client: Client | undefined,
197
216
  intervalType: IntervalType,
198
217
  op?: ISequencedDocumentMessage,
199
218
  fromSnapshot?: boolean,
200
- stickiness?: IntervalStickiness,
219
+ useNewSlidingBehavior?: boolean,
201
220
  ): TInterval;
202
221
  }
203
222
 
@@ -207,6 +226,8 @@ export interface IIntervalHelpers<TInterval extends ISerializableInterval> {
207
226
  *
208
227
  * Note that interval stickiness is currently an experimental feature and must
209
228
  * be explicitly enabled with the `intervalStickinessEnabled` flag
229
+ *
230
+ * @internal
210
231
  */
211
232
  export const IntervalStickiness = {
212
233
  /**
@@ -238,19 +259,21 @@ export const IntervalStickiness = {
238
259
  *
239
260
  * Note that interval stickiness is currently an experimental feature and must
240
261
  * be explicitly enabled with the `intervalStickinessEnabled` flag
262
+ *
263
+ * @internal
241
264
  */
242
265
  export type IntervalStickiness = typeof IntervalStickiness[keyof typeof IntervalStickiness];
243
266
 
244
- export function endReferenceSlidingPreference(stickiness: IntervalStickiness): SlidingPreference {
245
- // if any end stickiness, prefer sliding forwards
246
- 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
247
270
  ? SlidingPreference.FORWARD
248
271
  : SlidingPreference.BACKWARD;
249
272
  }
250
273
 
251
- export function startReferenceSlidingPreference(stickiness: IntervalStickiness): SlidingPreference {
252
- // if any start stickiness, prefer sliding backwards
253
- 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
254
277
  ? SlidingPreference.BACKWARD
255
278
  : SlidingPreference.FORWARD;
256
279
  }