@fluidframework/sequence 2.90.0-378676 → 2.91.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.
- package/CHANGELOG.md +8 -0
- package/api-report/sequence.legacy.beta.api.md +1 -1
- package/dist/intervalCollection.d.ts +3 -2
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +5 -5
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.d.ts +3 -3
- package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.js +5 -6
- package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
- package/dist/intervalIndex/endpointIndex.d.ts +3 -3
- package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
- package/dist/intervalIndex/endpointIndex.js +5 -6
- package/dist/intervalIndex/endpointIndex.js.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +8 -7
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.js +5 -6
- package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/dist/intervalIndex/startpointInRangeIndex.d.ts +3 -3
- package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
- package/dist/intervalIndex/startpointInRangeIndex.js +5 -6
- package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
- package/dist/intervals/index.d.ts +1 -1
- package/dist/intervals/index.d.ts.map +1 -1
- package/dist/intervals/index.js +4 -2
- package/dist/intervals/index.js.map +1 -1
- package/dist/intervals/sequenceInterval.d.ts +60 -35
- package/dist/intervals/sequenceInterval.d.ts.map +1 -1
- package/dist/intervals/sequenceInterval.js +166 -102
- package/dist/intervals/sequenceInterval.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/sequence.d.ts +3 -6
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +2 -5
- package/dist/sequence.js.map +1 -1
- package/lib/intervalCollection.d.ts +3 -2
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +5 -5
- package/lib/intervalCollection.js.map +1 -1
- package/lib/intervalIndex/endpointInRangeIndex.d.ts +3 -3
- package/lib/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
- package/lib/intervalIndex/endpointInRangeIndex.js +6 -7
- package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -1
- package/lib/intervalIndex/endpointIndex.d.ts +3 -3
- package/lib/intervalIndex/endpointIndex.d.ts.map +1 -1
- package/lib/intervalIndex/endpointIndex.js +6 -7
- package/lib/intervalIndex/endpointIndex.js.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +8 -7
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.js +7 -8
- package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/lib/intervalIndex/startpointInRangeIndex.d.ts +3 -3
- package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
- package/lib/intervalIndex/startpointInRangeIndex.js +6 -7
- package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -1
- package/lib/intervals/index.d.ts +1 -1
- package/lib/intervals/index.d.ts.map +1 -1
- package/lib/intervals/index.js +1 -1
- package/lib/intervals/index.js.map +1 -1
- package/lib/intervals/sequenceInterval.d.ts +60 -35
- package/lib/intervals/sequenceInterval.d.ts.map +1 -1
- package/lib/intervals/sequenceInterval.js +162 -100
- package/lib/intervals/sequenceInterval.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/sequence.d.ts +3 -6
- package/lib/sequence.d.ts.map +1 -1
- package/lib/sequence.js +2 -5
- package/lib/sequence.js.map +1 -1
- package/package.json +21 -21
- package/src/intervalCollection.ts +6 -3
- package/src/intervalIndex/endpointInRangeIndex.ts +11 -7
- package/src/intervalIndex/endpointIndex.ts +7 -7
- package/src/intervalIndex/overlappingIntervalsIndex.ts +18 -25
- package/src/intervalIndex/startpointInRangeIndex.ts +11 -7
- package/src/intervals/index.ts +3 -1
- package/src/intervals/sequenceInterval.ts +249 -124
- package/src/packageVersion.ts +1 -1
- package/src/sequence.ts +8 -11
|
@@ -3,18 +3,15 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
Client,
|
|
8
|
-
SequencePlace,
|
|
9
|
-
endpointPosAndSide,
|
|
10
|
-
} from "@fluidframework/merge-tree/internal";
|
|
6
|
+
import { SequencePlace, endpointPosAndSide } from "@fluidframework/merge-tree/internal";
|
|
11
7
|
|
|
12
8
|
import { IntervalNode, IntervalTree } from "../intervalTree.js";
|
|
13
9
|
import {
|
|
14
10
|
SequenceInterval,
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
BaseSequenceInterval,
|
|
12
|
+
createTransientIntervalFromSequence,
|
|
17
13
|
} from "../intervals/index.js";
|
|
14
|
+
import type { ISharedSegmentSequence } from "../sequence.js";
|
|
18
15
|
import { ISharedString } from "../sharedString.js";
|
|
19
16
|
|
|
20
17
|
import type { SequenceIntervalIndex } from "./intervalIndex.js";
|
|
@@ -41,12 +38,9 @@ export interface ISequenceOverlappingIntervalsIndex extends SequenceIntervalInde
|
|
|
41
38
|
}
|
|
42
39
|
|
|
43
40
|
export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsIndex {
|
|
44
|
-
protected readonly intervalTree = new IntervalTree<
|
|
45
|
-
protected readonly client: Client;
|
|
41
|
+
protected readonly intervalTree = new IntervalTree<BaseSequenceInterval>();
|
|
46
42
|
|
|
47
|
-
constructor(
|
|
48
|
-
this.client = client;
|
|
49
|
-
}
|
|
43
|
+
constructor(protected readonly sequence: ISharedSegmentSequence<any>) {}
|
|
50
44
|
|
|
51
45
|
public map(fn: (interval: SequenceInterval) => void) {
|
|
52
46
|
this.intervalTree.map(fn);
|
|
@@ -69,7 +63,7 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
|
|
|
69
63
|
if (start === undefined && end === undefined) {
|
|
70
64
|
// No start/end provided. Gather the whole tree in the specified order.
|
|
71
65
|
if (iteratesForward) {
|
|
72
|
-
this.intervalTree.map((interval:
|
|
66
|
+
this.intervalTree.map((interval: SequenceInterval) => {
|
|
73
67
|
results.push(interval);
|
|
74
68
|
});
|
|
75
69
|
} else {
|
|
@@ -78,23 +72,23 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
|
|
|
78
72
|
});
|
|
79
73
|
}
|
|
80
74
|
} else {
|
|
81
|
-
const transientInterval:
|
|
75
|
+
const transientInterval: BaseSequenceInterval = createTransientIntervalFromSequence(
|
|
82
76
|
start ?? "start",
|
|
83
77
|
end ?? "end",
|
|
84
|
-
this.
|
|
78
|
+
this.sequence,
|
|
85
79
|
);
|
|
86
80
|
|
|
87
81
|
if (start === undefined) {
|
|
88
82
|
// Only end position provided. Since the tree is not sorted by end position,
|
|
89
83
|
// walk the whole tree in the specified order, gathering intervals that match the end.
|
|
90
84
|
if (iteratesForward) {
|
|
91
|
-
this.intervalTree.map((interval:
|
|
85
|
+
this.intervalTree.map((interval: SequenceInterval) => {
|
|
92
86
|
if (transientInterval.compareEnd(interval) === 0) {
|
|
93
87
|
results.push(interval);
|
|
94
88
|
}
|
|
95
89
|
});
|
|
96
90
|
} else {
|
|
97
|
-
this.intervalTree.mapBackward((interval:
|
|
91
|
+
this.intervalTree.mapBackward((interval: SequenceInterval) => {
|
|
98
92
|
if (transientInterval.compareEnd(interval) === 0) {
|
|
99
93
|
results.push(interval);
|
|
100
94
|
}
|
|
@@ -105,15 +99,15 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
|
|
|
105
99
|
// this start position.
|
|
106
100
|
const compareFn =
|
|
107
101
|
end === undefined
|
|
108
|
-
? (node: IntervalNode<
|
|
102
|
+
? (node: IntervalNode<BaseSequenceInterval>) => {
|
|
109
103
|
return transientInterval.compareStart(node.key);
|
|
110
104
|
}
|
|
111
|
-
: (node: IntervalNode<
|
|
105
|
+
: (node: IntervalNode<BaseSequenceInterval>) => {
|
|
112
106
|
return transientInterval.compare(node.key);
|
|
113
107
|
};
|
|
114
108
|
const continueLeftFn = (cmpResult: number) => cmpResult <= 0;
|
|
115
109
|
const continueRightFn = (cmpResult: number) => cmpResult >= 0;
|
|
116
|
-
const actionFn = (node: IntervalNode<
|
|
110
|
+
const actionFn = (node: IntervalNode<BaseSequenceInterval>) => {
|
|
117
111
|
results.push(node.key);
|
|
118
112
|
};
|
|
119
113
|
|
|
@@ -152,17 +146,17 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
|
|
|
152
146
|
) {
|
|
153
147
|
return [];
|
|
154
148
|
}
|
|
155
|
-
const transientInterval =
|
|
149
|
+
const transientInterval = createTransientIntervalFromSequence(start, end, this.sequence);
|
|
156
150
|
|
|
157
151
|
const overlappingIntervalNodes = this.intervalTree.match(transientInterval);
|
|
158
152
|
return overlappingIntervalNodes.map((node) => node.key);
|
|
159
153
|
}
|
|
160
154
|
|
|
161
|
-
public remove(interval:
|
|
155
|
+
public remove(interval: BaseSequenceInterval) {
|
|
162
156
|
this.intervalTree.removeExisting(interval);
|
|
163
157
|
}
|
|
164
158
|
|
|
165
|
-
public add(interval:
|
|
159
|
+
public add(interval: BaseSequenceInterval) {
|
|
166
160
|
this.intervalTree.put(interval);
|
|
167
161
|
}
|
|
168
162
|
}
|
|
@@ -175,6 +169,5 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
|
|
|
175
169
|
export function createOverlappingIntervalsIndex(
|
|
176
170
|
sharedString: ISharedString,
|
|
177
171
|
): ISequenceOverlappingIntervalsIndex {
|
|
178
|
-
|
|
179
|
-
return new OverlappingIntervalsIndex(client);
|
|
172
|
+
return new OverlappingIntervalsIndex(sharedString);
|
|
180
173
|
}
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { PropertyAction, RedBlackTree } from "@fluidframework/merge-tree/internal";
|
|
7
7
|
|
|
8
|
-
import { SequenceInterval,
|
|
8
|
+
import { SequenceInterval, createTransientIntervalFromSequence } from "../intervals/index.js";
|
|
9
|
+
import type { ISharedSegmentSequence } from "../sequence.js";
|
|
9
10
|
import { ISharedString } from "../sharedString.js";
|
|
10
11
|
|
|
11
12
|
import type { SequenceIntervalIndex } from "./intervalIndex.js";
|
|
@@ -31,7 +32,7 @@ export interface IStartpointInRangeIndex extends SequenceIntervalIndex {
|
|
|
31
32
|
export class StartpointInRangeIndex implements IStartpointInRangeIndex {
|
|
32
33
|
private readonly intervalTree;
|
|
33
34
|
|
|
34
|
-
constructor(private readonly
|
|
35
|
+
constructor(private readonly sequence: ISharedSegmentSequence<any>) {
|
|
35
36
|
this.intervalTree = new RedBlackTree<SequenceInterval, SequenceInterval>(
|
|
36
37
|
(a: SequenceInterval, b: SequenceInterval) => {
|
|
37
38
|
const compareStartsResult = a.compareStart(b);
|
|
@@ -74,9 +75,13 @@ export class StartpointInRangeIndex implements IStartpointInRangeIndex {
|
|
|
74
75
|
return true;
|
|
75
76
|
};
|
|
76
77
|
|
|
77
|
-
const transientStartInterval =
|
|
78
|
+
const transientStartInterval = createTransientIntervalFromSequence(
|
|
79
|
+
start,
|
|
80
|
+
start,
|
|
81
|
+
this.sequence,
|
|
82
|
+
);
|
|
78
83
|
|
|
79
|
-
const transientEndInterval =
|
|
84
|
+
const transientEndInterval = createTransientIntervalFromSequence(end, end, this.sequence);
|
|
80
85
|
|
|
81
86
|
// Add comparison overrides to the transient intervals
|
|
82
87
|
(transientStartInterval as Partial<HasComparisonOverride>)[forceCompare] = -1;
|
|
@@ -94,6 +99,5 @@ export class StartpointInRangeIndex implements IStartpointInRangeIndex {
|
|
|
94
99
|
export function createStartpointInRangeIndex(
|
|
95
100
|
sharedString: ISharedString,
|
|
96
101
|
): IStartpointInRangeIndex {
|
|
97
|
-
|
|
98
|
-
return new StartpointInRangeIndex(client);
|
|
102
|
+
return new StartpointInRangeIndex(sharedString);
|
|
99
103
|
}
|
package/src/intervals/index.ts
CHANGED
|
@@ -19,8 +19,10 @@ export {
|
|
|
19
19
|
export {
|
|
20
20
|
SequenceInterval,
|
|
21
21
|
SequenceIntervalClass,
|
|
22
|
+
BaseSequenceInterval,
|
|
22
23
|
createSequenceInterval,
|
|
23
24
|
createPositionReferenceFromSegoff,
|
|
24
|
-
|
|
25
|
+
createTransientIntervalFromSequence,
|
|
26
|
+
resolvePositionRef,
|
|
25
27
|
getSerializedProperties,
|
|
26
28
|
} from "./sequenceInterval.js";
|
|
@@ -35,6 +35,8 @@ import {
|
|
|
35
35
|
import { LoggingError, UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
36
36
|
import { v4 as uuid } from "uuid";
|
|
37
37
|
|
|
38
|
+
import type { ISharedSegmentSequence } from "../sequence.js";
|
|
39
|
+
|
|
38
40
|
import {
|
|
39
41
|
ISerializableInterval,
|
|
40
42
|
ISerializedInterval,
|
|
@@ -182,8 +184,148 @@ export interface SequenceInterval extends IInterval {
|
|
|
182
184
|
getIntervalId(): string;
|
|
183
185
|
}
|
|
184
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Lightweight interval for index queries (overlap, comparison).
|
|
189
|
+
* Has no Client dependency; cannot serialize or be disposed.
|
|
190
|
+
*/
|
|
191
|
+
export class BaseSequenceInterval implements SequenceInterval, ISerializableInterval {
|
|
192
|
+
readonly #id: string;
|
|
193
|
+
readonly #properties: PropertySet = createMap<any>();
|
|
194
|
+
|
|
195
|
+
constructor(
|
|
196
|
+
id: string,
|
|
197
|
+
/**
|
|
198
|
+
* Start endpoint of this interval.
|
|
199
|
+
* @remarks This endpoint can be resolved into a character position using the SharedString it's a part of.
|
|
200
|
+
*/
|
|
201
|
+
public start: LocalReferencePosition,
|
|
202
|
+
/**
|
|
203
|
+
* End endpoint of this interval.
|
|
204
|
+
* @remarks This endpoint can be resolved into a character position using the SharedString it's a part of.
|
|
205
|
+
*/
|
|
206
|
+
public end: LocalReferencePosition,
|
|
207
|
+
public intervalType: IntervalType,
|
|
208
|
+
public readonly startSide: Side = Side.Before,
|
|
209
|
+
public readonly endSide: Side = Side.Before,
|
|
210
|
+
) {
|
|
211
|
+
this.#id = id;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public get properties(): Readonly<PropertySet> {
|
|
215
|
+
return this.#properties;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/***/
|
|
219
|
+
public get stickiness(): IntervalStickiness {
|
|
220
|
+
this.verifyNotDispose();
|
|
221
|
+
|
|
222
|
+
const startSegment: ISegmentInternal | undefined = this.start.getSegment();
|
|
223
|
+
const endSegment: ISegmentInternal | undefined = this.end.getSegment();
|
|
224
|
+
return computeStickinessFromSide(
|
|
225
|
+
startSegment?.endpointType,
|
|
226
|
+
this.startSide,
|
|
227
|
+
endSegment?.endpointType,
|
|
228
|
+
this.endSide,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* {@inheritDoc ISerializableInterval.getIntervalId}
|
|
234
|
+
*/
|
|
235
|
+
public getIntervalId(): string {
|
|
236
|
+
return this.#id;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* {@inheritDoc IInterval.compare}
|
|
241
|
+
*/
|
|
242
|
+
public compare(b: SequenceInterval) {
|
|
243
|
+
const startResult = this.compareStart(b);
|
|
244
|
+
if (startResult === 0) {
|
|
245
|
+
const endResult = this.compareEnd(b);
|
|
246
|
+
if (endResult === 0) {
|
|
247
|
+
const thisId = this.getIntervalId();
|
|
248
|
+
if (thisId) {
|
|
249
|
+
const bId = b.getIntervalId();
|
|
250
|
+
if (bId) {
|
|
251
|
+
return thisId > bId ? 1 : thisId < bId ? -1 : 0;
|
|
252
|
+
}
|
|
253
|
+
return 0;
|
|
254
|
+
}
|
|
255
|
+
return 0;
|
|
256
|
+
} else {
|
|
257
|
+
return endResult;
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
return startResult;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* {@inheritDoc IInterval.compareStart}
|
|
266
|
+
*/
|
|
267
|
+
public compareStart(b: SequenceInterval) {
|
|
268
|
+
this.verifyNotDispose();
|
|
269
|
+
|
|
270
|
+
const dist = compareReferencePositions(this.start, b.start);
|
|
271
|
+
|
|
272
|
+
if (dist === 0) {
|
|
273
|
+
return compareSides(this.startSide, b.startSide);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return dist;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* {@inheritDoc IInterval.compareEnd}
|
|
281
|
+
*/
|
|
282
|
+
public compareEnd(b: SequenceInterval): number {
|
|
283
|
+
this.verifyNotDispose();
|
|
284
|
+
|
|
285
|
+
const dist = compareReferencePositions(this.end, b.end);
|
|
286
|
+
|
|
287
|
+
if (dist === 0) {
|
|
288
|
+
return compareSides(b.endSide, this.endSide);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return dist;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* {@inheritDoc IInterval.overlaps}
|
|
296
|
+
*/
|
|
297
|
+
public overlaps(b: SequenceInterval) {
|
|
298
|
+
this.verifyNotDispose();
|
|
299
|
+
|
|
300
|
+
const result =
|
|
301
|
+
compareReferencePositions(this.start, b.end) <= 0 &&
|
|
302
|
+
compareReferencePositions(this.end, b.start) >= 0;
|
|
303
|
+
return result;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Whether this interval overlaps the provided numerical positions.
|
|
308
|
+
*/
|
|
309
|
+
public overlapsPos(_bstart: number, _bend: number): boolean {
|
|
310
|
+
assert(false, 0xcd7 /* overlapsPos not supported on BaseSequenceInterval */);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
public clone(): BaseSequenceInterval {
|
|
314
|
+
assert(false, 0xcd8 /* clone not supported on BaseSequenceInterval */);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
public union(_b: BaseSequenceInterval): BaseSequenceInterval {
|
|
318
|
+
assert(false, 0xcd9 /* union not supported on BaseSequenceInterval */);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
protected verifyNotDispose(): void {
|
|
322
|
+
// No-op: transient intervals are not disposable.
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
185
326
|
export class SequenceIntervalClass
|
|
186
|
-
|
|
327
|
+
extends BaseSequenceInterval
|
|
328
|
+
implements ISerializableInterval, IDisposable
|
|
187
329
|
{
|
|
188
330
|
readonly #props: {
|
|
189
331
|
propertyManager?: PropertiesManager;
|
|
@@ -193,7 +335,7 @@ export class SequenceIntervalClass
|
|
|
193
335
|
/**
|
|
194
336
|
* {@inheritDoc ISerializableInterval.properties}
|
|
195
337
|
*/
|
|
196
|
-
public get properties(): Readonly<PropertySet> {
|
|
338
|
+
public override get properties(): Readonly<PropertySet> {
|
|
197
339
|
this.verifyNotDispose();
|
|
198
340
|
return this.#props.properties;
|
|
199
341
|
}
|
|
@@ -220,39 +362,18 @@ export class SequenceIntervalClass
|
|
|
220
362
|
}
|
|
221
363
|
}
|
|
222
364
|
|
|
223
|
-
/***/
|
|
224
|
-
public get stickiness(): IntervalStickiness {
|
|
225
|
-
this.verifyNotDispose();
|
|
226
|
-
|
|
227
|
-
const startSegment: ISegmentInternal | undefined = this.start.getSegment();
|
|
228
|
-
const endSegment: ISegmentInternal | undefined = this.end.getSegment();
|
|
229
|
-
return computeStickinessFromSide(
|
|
230
|
-
startSegment?.endpointType,
|
|
231
|
-
this.startSide,
|
|
232
|
-
endSegment?.endpointType,
|
|
233
|
-
this.endSide,
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
365
|
constructor(
|
|
238
366
|
private readonly client: Client,
|
|
239
|
-
|
|
367
|
+
id: string,
|
|
240
368
|
private readonly label: string,
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
*/
|
|
245
|
-
public start: LocalReferencePosition,
|
|
246
|
-
/**
|
|
247
|
-
* End endpoint of this interval.
|
|
248
|
-
* @remarks This endpoint can be resolved into a character position using the SharedString it's a part of.
|
|
249
|
-
*/
|
|
250
|
-
public end: LocalReferencePosition,
|
|
251
|
-
public intervalType: IntervalType,
|
|
369
|
+
start: LocalReferencePosition,
|
|
370
|
+
end: LocalReferencePosition,
|
|
371
|
+
intervalType: IntervalType,
|
|
252
372
|
props?: PropertySet,
|
|
253
|
-
|
|
254
|
-
|
|
373
|
+
startSide: Side = Side.Before,
|
|
374
|
+
endSide: Side = Side.Before,
|
|
255
375
|
) {
|
|
376
|
+
super(id, start, end, intervalType, startSide, endSide);
|
|
256
377
|
if (props) {
|
|
257
378
|
this.#props.properties = addProperties(this.#props.properties, props);
|
|
258
379
|
}
|
|
@@ -270,7 +391,7 @@ export class SequenceIntervalClass
|
|
|
270
391
|
this.#props.propertyManager = undefined;
|
|
271
392
|
}
|
|
272
393
|
|
|
273
|
-
|
|
394
|
+
protected override verifyNotDispose() {
|
|
274
395
|
if (this.#disposed) {
|
|
275
396
|
throw new LoggingError("Invalid interval access after dispose");
|
|
276
397
|
}
|
|
@@ -350,7 +471,7 @@ export class SequenceIntervalClass
|
|
|
350
471
|
endSide: includeEndpoints ? this.endSide : undefined,
|
|
351
472
|
properties: {
|
|
352
473
|
...props,
|
|
353
|
-
[reservedIntervalIdKey]: this.
|
|
474
|
+
[reservedIntervalIdKey]: this.getIntervalId(),
|
|
354
475
|
[reservedRangeLabelsKey]: [this.label],
|
|
355
476
|
},
|
|
356
477
|
} satisfies SerializedIntervalDelta;
|
|
@@ -364,7 +485,7 @@ export class SequenceIntervalClass
|
|
|
364
485
|
|
|
365
486
|
return new SequenceIntervalClass(
|
|
366
487
|
this.client,
|
|
367
|
-
this.
|
|
488
|
+
this.getIntervalId(),
|
|
368
489
|
this.label,
|
|
369
490
|
this.start,
|
|
370
491
|
this.end,
|
|
@@ -375,80 +496,6 @@ export class SequenceIntervalClass
|
|
|
375
496
|
);
|
|
376
497
|
}
|
|
377
498
|
|
|
378
|
-
/**
|
|
379
|
-
* {@inheritDoc IInterval.compare}
|
|
380
|
-
*/
|
|
381
|
-
public compare(b: SequenceInterval) {
|
|
382
|
-
const startResult = this.compareStart(b);
|
|
383
|
-
if (startResult === 0) {
|
|
384
|
-
const endResult = this.compareEnd(b);
|
|
385
|
-
if (endResult === 0) {
|
|
386
|
-
const thisId = this.getIntervalId();
|
|
387
|
-
if (thisId) {
|
|
388
|
-
const bId = b.getIntervalId();
|
|
389
|
-
if (bId) {
|
|
390
|
-
return thisId > bId ? 1 : thisId < bId ? -1 : 0;
|
|
391
|
-
}
|
|
392
|
-
return 0;
|
|
393
|
-
}
|
|
394
|
-
return 0;
|
|
395
|
-
} else {
|
|
396
|
-
return endResult;
|
|
397
|
-
}
|
|
398
|
-
} else {
|
|
399
|
-
return startResult;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* {@inheritDoc IInterval.compareStart}
|
|
405
|
-
*/
|
|
406
|
-
public compareStart(b: SequenceInterval) {
|
|
407
|
-
this.verifyNotDispose();
|
|
408
|
-
|
|
409
|
-
const dist = compareReferencePositions(this.start, b.start);
|
|
410
|
-
|
|
411
|
-
if (dist === 0) {
|
|
412
|
-
return compareSides(this.startSide, b.startSide);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
return dist;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* {@inheritDoc IInterval.compareEnd}
|
|
420
|
-
*/
|
|
421
|
-
public compareEnd(b: SequenceInterval): number {
|
|
422
|
-
this.verifyNotDispose();
|
|
423
|
-
|
|
424
|
-
const dist = compareReferencePositions(this.end, b.end);
|
|
425
|
-
|
|
426
|
-
if (dist === 0) {
|
|
427
|
-
return compareSides(b.endSide, this.endSide);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return dist;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* {@inheritDoc IInterval.overlaps}
|
|
435
|
-
*/
|
|
436
|
-
public overlaps(b: SequenceInterval) {
|
|
437
|
-
this.verifyNotDispose();
|
|
438
|
-
|
|
439
|
-
const result =
|
|
440
|
-
compareReferencePositions(this.start, b.end) <= 0 &&
|
|
441
|
-
compareReferencePositions(this.end, b.start) >= 0;
|
|
442
|
-
return result;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* {@inheritDoc ISerializableInterval.getIntervalId}
|
|
447
|
-
*/
|
|
448
|
-
public getIntervalId(): string {
|
|
449
|
-
return this.id;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
499
|
/**
|
|
453
500
|
* {@inheritDoc IInterval.union}
|
|
454
501
|
*/
|
|
@@ -490,7 +537,7 @@ export class SequenceIntervalClass
|
|
|
490
537
|
/**
|
|
491
538
|
* Whether this interval overlaps the provided numerical positions.
|
|
492
539
|
*/
|
|
493
|
-
public overlapsPos(bstart: number, bend: number) {
|
|
540
|
+
public override overlapsPos(bstart: number, bend: number) {
|
|
494
541
|
this.verifyNotDispose();
|
|
495
542
|
|
|
496
543
|
const startPos = this.client.localReferencePositionToPosition(this.start);
|
|
@@ -602,7 +649,7 @@ export class SequenceIntervalClass
|
|
|
602
649
|
|
|
603
650
|
const newInterval = new SequenceIntervalClass(
|
|
604
651
|
this.client,
|
|
605
|
-
this.
|
|
652
|
+
this.getIntervalId(),
|
|
606
653
|
this.label,
|
|
607
654
|
startRef,
|
|
608
655
|
endRef,
|
|
@@ -697,6 +744,41 @@ export function createPositionReferenceFromSegoff({
|
|
|
697
744
|
return createDetachedLocalReferencePosition(slidingPreference, refType);
|
|
698
745
|
}
|
|
699
746
|
|
|
747
|
+
/**
|
|
748
|
+
* Resolves a position to a {@link LocalReferencePosition} using an
|
|
749
|
+
* {@link ISharedSegmentSequence} (no Client or op context needed).
|
|
750
|
+
*/
|
|
751
|
+
export function resolvePositionRef(
|
|
752
|
+
sequence: ISharedSegmentSequence<any>,
|
|
753
|
+
pos: number | "start" | "end",
|
|
754
|
+
refType: ReferenceType,
|
|
755
|
+
slidingPreference: SlidingPreference,
|
|
756
|
+
canSlideToEndpoint?: boolean,
|
|
757
|
+
): LocalReferencePosition {
|
|
758
|
+
if (pos === "start" || pos === "end") {
|
|
759
|
+
return sequence.createLocalReferencePosition(
|
|
760
|
+
pos,
|
|
761
|
+
undefined,
|
|
762
|
+
refType,
|
|
763
|
+
undefined,
|
|
764
|
+
slidingPreference,
|
|
765
|
+
canSlideToEndpoint,
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
const segoff = sequence.getContainingSegment(pos);
|
|
769
|
+
if (segoff?.segment !== undefined && segoff?.offset !== undefined) {
|
|
770
|
+
return sequence.createLocalReferencePosition(
|
|
771
|
+
segoff.segment,
|
|
772
|
+
segoff.offset,
|
|
773
|
+
refType,
|
|
774
|
+
undefined,
|
|
775
|
+
slidingPreference,
|
|
776
|
+
canSlideToEndpoint,
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
return createDetachedLocalReferencePosition(slidingPreference, refType);
|
|
780
|
+
}
|
|
781
|
+
|
|
700
782
|
function createPositionReference({
|
|
701
783
|
client,
|
|
702
784
|
pos,
|
|
@@ -758,18 +840,61 @@ function createPositionReference({
|
|
|
758
840
|
});
|
|
759
841
|
}
|
|
760
842
|
|
|
761
|
-
|
|
843
|
+
/**
|
|
844
|
+
* Creates a transient interval using an `ISharedSegmentSequence` instead of a `Client`.
|
|
845
|
+
* This avoids coupling index classes to merge-tree internals.
|
|
846
|
+
*/
|
|
847
|
+
export function createTransientIntervalFromSequence(
|
|
762
848
|
start: SequencePlace | undefined,
|
|
763
849
|
end: SequencePlace | undefined,
|
|
764
|
-
|
|
765
|
-
) {
|
|
766
|
-
|
|
767
|
-
"
|
|
850
|
+
sequence: ISharedSegmentSequence<any>,
|
|
851
|
+
): BaseSequenceInterval {
|
|
852
|
+
const { startPos, startSide, endPos, endSide } = endpointPosAndSide(
|
|
853
|
+
start ?? "start",
|
|
854
|
+
end ?? "end",
|
|
855
|
+
);
|
|
856
|
+
assert(
|
|
857
|
+
startPos !== undefined &&
|
|
858
|
+
endPos !== undefined &&
|
|
859
|
+
startSide !== undefined &&
|
|
860
|
+
endSide !== undefined,
|
|
861
|
+
0xcda /* start and end cannot be undefined because they were not passed in as undefined */,
|
|
862
|
+
);
|
|
863
|
+
|
|
864
|
+
const startSlidingPref = startReferenceSlidingPreference(
|
|
865
|
+
startPos,
|
|
866
|
+
startSide,
|
|
867
|
+
endPos,
|
|
868
|
+
endSide,
|
|
869
|
+
);
|
|
870
|
+
const endSlidingPref = endReferenceSlidingPreference(startPos, startSide, endPos, endSide);
|
|
871
|
+
|
|
872
|
+
const startLref = resolvePositionRef(
|
|
873
|
+
sequence,
|
|
874
|
+
startPos,
|
|
875
|
+
ReferenceType.Transient,
|
|
876
|
+
startSlidingPref,
|
|
877
|
+
);
|
|
878
|
+
const endLref = resolvePositionRef(
|
|
879
|
+
sequence,
|
|
880
|
+
endPos,
|
|
881
|
+
ReferenceType.Transient,
|
|
882
|
+
endSlidingPref,
|
|
883
|
+
);
|
|
884
|
+
|
|
885
|
+
const rangeProp = {
|
|
886
|
+
[reservedRangeLabelsKey]: ["transient"],
|
|
887
|
+
};
|
|
888
|
+
startLref.addProperties(rangeProp);
|
|
889
|
+
endLref.addProperties(rangeProp);
|
|
890
|
+
|
|
891
|
+
return new BaseSequenceInterval(
|
|
768
892
|
uuid(),
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
client,
|
|
893
|
+
startLref,
|
|
894
|
+
endLref,
|
|
772
895
|
IntervalType.Transient,
|
|
896
|
+
startSide,
|
|
897
|
+
endSide,
|
|
773
898
|
);
|
|
774
899
|
}
|
|
775
900
|
|
|
@@ -824,6 +949,13 @@ export function createSequenceInterval(
|
|
|
824
949
|
endSide,
|
|
825
950
|
);
|
|
826
951
|
|
|
952
|
+
const endSlidingPreference = endReferenceSlidingPreference(
|
|
953
|
+
startPos,
|
|
954
|
+
startSide,
|
|
955
|
+
endPos,
|
|
956
|
+
endSide,
|
|
957
|
+
);
|
|
958
|
+
|
|
827
959
|
const startLref = createPositionReference({
|
|
828
960
|
client,
|
|
829
961
|
pos: startPos,
|
|
@@ -835,13 +967,6 @@ export function createSequenceInterval(
|
|
|
835
967
|
rollback,
|
|
836
968
|
});
|
|
837
969
|
|
|
838
|
-
const endSlidingPreference = endReferenceSlidingPreference(
|
|
839
|
-
startPos,
|
|
840
|
-
startSide,
|
|
841
|
-
endPos,
|
|
842
|
-
endSide,
|
|
843
|
-
);
|
|
844
|
-
|
|
845
970
|
const endLref = createPositionReference({
|
|
846
971
|
client,
|
|
847
972
|
pos: endPos,
|
package/src/packageVersion.ts
CHANGED