@fluidframework/sequence 2.0.0-dev.4.4.0.162574 → 2.0.0-dev.5.2.0.169897
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 +20 -0
- package/dist/defaultMap.d.ts +3 -2
- package/dist/defaultMap.d.ts.map +1 -1
- package/dist/defaultMap.js +4 -3
- package/dist/defaultMap.js.map +1 -1
- package/dist/defaultMapInterfaces.d.ts +12 -1
- package/dist/defaultMapInterfaces.d.ts.map +1 -1
- package/dist/defaultMapInterfaces.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/intervalCollection.d.ts +231 -59
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +288 -86
- package/dist/intervalCollection.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/revertibles.d.ts +104 -0
- package/dist/revertibles.d.ts.map +1 -0
- package/dist/revertibles.js +374 -0
- package/dist/revertibles.js.map +1 -0
- package/dist/sequence.d.ts +4 -4
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +3 -3
- package/dist/sequence.js.map +1 -1
- package/dist/sharedIntervalCollection.d.ts +3 -3
- package/dist/sharedIntervalCollection.d.ts.map +1 -1
- package/dist/sharedIntervalCollection.js +1 -1
- package/dist/sharedIntervalCollection.js.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/lib/defaultMap.d.ts +3 -2
- package/lib/defaultMap.d.ts.map +1 -1
- package/lib/defaultMap.js +4 -3
- package/lib/defaultMap.js.map +1 -1
- package/lib/defaultMapInterfaces.d.ts +12 -1
- package/lib/defaultMapInterfaces.d.ts.map +1 -1
- package/lib/defaultMapInterfaces.js.map +1 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/intervalCollection.d.ts +231 -59
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +286 -86
- package/lib/intervalCollection.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/revertibles.d.ts +104 -0
- package/lib/revertibles.d.ts.map +1 -0
- package/lib/revertibles.js +364 -0
- package/lib/revertibles.js.map +1 -0
- package/lib/sequence.d.ts +4 -4
- package/lib/sequence.d.ts.map +1 -1
- package/lib/sequence.js +3 -3
- package/lib/sequence.js.map +1 -1
- package/lib/sharedIntervalCollection.d.ts +3 -3
- package/lib/sharedIntervalCollection.d.ts.map +1 -1
- package/lib/sharedIntervalCollection.js +1 -1
- package/lib/sharedIntervalCollection.js.map +1 -1
- package/package.json +20 -22
- package/src/defaultMap.ts +4 -1
- package/src/defaultMapInterfaces.ts +13 -1
- package/src/index.ts +21 -5
- package/src/intervalCollection.ts +619 -73
- package/src/packageVersion.ts +1 -1
- package/src/revertibles.ts +572 -0
- package/src/sequence.ts +12 -2
- 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.
|
|
18
|
+
exports.intervalLocatorFromEndpoint = exports.IntervalCollection = exports.makeOpsMap = exports.IntervalCollectionValueType = exports.SequenceIntervalCollectionValueType = exports.intervalHelpers = exports.sequenceIntervalHelpers = exports.compareSequenceIntervalStarts = exports.compareSequenceIntervalEnds = exports.LocalIntervalCollection = exports.createStartpointInRangeIndex = exports.createEndpointInRangeIndex = 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";
|
|
@@ -31,7 +42,7 @@ var IntervalType;
|
|
|
31
42
|
/**
|
|
32
43
|
* SlideOnRemove indicates that the ends of the interval will slide if the segment
|
|
33
44
|
* they reference is removed and acked.
|
|
34
|
-
* See `packages\dds\merge-tree\REFERENCEPOSITIONS.md` for details
|
|
45
|
+
* See `packages\dds\merge-tree\docs\REFERENCEPOSITIONS.md` for details
|
|
35
46
|
* SlideOnRemove is the default interval behavior and does not need to be specified.
|
|
36
47
|
*/
|
|
37
48
|
IntervalType[IntervalType["SlideOnRemove"] = 2] = "SlideOnRemove";
|
|
@@ -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
|
-
|
|
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 `
|
|
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
|
*/
|
|
@@ -227,7 +282,7 @@ class Interval {
|
|
|
227
282
|
}
|
|
228
283
|
exports.Interval = Interval;
|
|
229
284
|
/**
|
|
230
|
-
* Interval
|
|
285
|
+
* Interval implementation whose ends are associated with positions in a mutatable sequence.
|
|
231
286
|
* As such, when content is inserted into the middle of the interval, the interval expands to
|
|
232
287
|
* include that content.
|
|
233
288
|
*
|
|
@@ -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;
|
|
@@ -669,6 +728,119 @@ class EndpointIndex {
|
|
|
669
728
|
this.endIntervalTree.remove(interval);
|
|
670
729
|
}
|
|
671
730
|
}
|
|
731
|
+
/**
|
|
732
|
+
* Interface for intervals that have comparison override properties.
|
|
733
|
+
*/
|
|
734
|
+
const forceCompare = Symbol();
|
|
735
|
+
/**
|
|
736
|
+
* Compares two objects based on their comparison override properties.
|
|
737
|
+
* @returns A number indicating the order of the intervals (negative for a is lower than b, 0 for tie, positive for a is greater than b).
|
|
738
|
+
*/
|
|
739
|
+
function compareOverrideables(a, b) {
|
|
740
|
+
var _a, _b;
|
|
741
|
+
const forceCompareA = (_a = a[forceCompare]) !== null && _a !== void 0 ? _a : 0;
|
|
742
|
+
const forceCompareB = (_b = b[forceCompare]) !== null && _b !== void 0 ? _b : 0;
|
|
743
|
+
return forceCompareA - forceCompareB;
|
|
744
|
+
}
|
|
745
|
+
class EndpointInRangeIndex {
|
|
746
|
+
constructor(helpers, client) {
|
|
747
|
+
this.helpers = helpers;
|
|
748
|
+
this.client = client;
|
|
749
|
+
this.intervalTree = new merge_tree_1.RedBlackTree((a, b) => {
|
|
750
|
+
const compareEndsResult = helpers.compareEnds(a, b);
|
|
751
|
+
if (compareEndsResult !== 0) {
|
|
752
|
+
return compareEndsResult;
|
|
753
|
+
}
|
|
754
|
+
const overrideablesComparison = compareOverrideables(a, b);
|
|
755
|
+
if (overrideablesComparison !== 0) {
|
|
756
|
+
return overrideablesComparison;
|
|
757
|
+
}
|
|
758
|
+
const aId = a.getIntervalId();
|
|
759
|
+
const bId = b.getIntervalId();
|
|
760
|
+
if (aId !== undefined && bId !== undefined) {
|
|
761
|
+
return aId.localeCompare(bId);
|
|
762
|
+
}
|
|
763
|
+
return 0;
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
add(interval) {
|
|
767
|
+
this.intervalTree.put(interval, interval);
|
|
768
|
+
}
|
|
769
|
+
remove(interval) {
|
|
770
|
+
this.intervalTree.remove(interval);
|
|
771
|
+
}
|
|
772
|
+
findIntervalsWithEndpointInRange(start, end) {
|
|
773
|
+
if (start <= 0 || start > end || this.intervalTree.isEmpty()) {
|
|
774
|
+
return [];
|
|
775
|
+
}
|
|
776
|
+
const results = [];
|
|
777
|
+
const action = (node) => {
|
|
778
|
+
results.push(node.data);
|
|
779
|
+
return true;
|
|
780
|
+
};
|
|
781
|
+
const transientStartInterval = this.helpers.create("transient", start, start, this.client, IntervalType.Transient);
|
|
782
|
+
const transientEndInterval = this.helpers.create("transient", end, end, this.client, IntervalType.Transient);
|
|
783
|
+
// Add comparison overrides to the transient intervals
|
|
784
|
+
transientStartInterval[forceCompare] = -1;
|
|
785
|
+
transientEndInterval[forceCompare] = 1;
|
|
786
|
+
this.intervalTree.mapRange(action, results, transientStartInterval, transientEndInterval);
|
|
787
|
+
return results;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
class StartpointInRangeIndex {
|
|
791
|
+
constructor(helpers, client) {
|
|
792
|
+
this.helpers = helpers;
|
|
793
|
+
this.client = client;
|
|
794
|
+
this.intervalTree = new merge_tree_1.RedBlackTree((a, b) => {
|
|
795
|
+
(0, common_utils_1.assert)(typeof helpers.compareStarts === "function", 0x6d1 /* compareStarts does not exist in the helpers */);
|
|
796
|
+
const compareStartsResult = helpers.compareStarts(a, b);
|
|
797
|
+
if (compareStartsResult !== 0) {
|
|
798
|
+
return compareStartsResult;
|
|
799
|
+
}
|
|
800
|
+
const overrideablesComparison = compareOverrideables(a, b);
|
|
801
|
+
if (overrideablesComparison !== 0) {
|
|
802
|
+
return overrideablesComparison;
|
|
803
|
+
}
|
|
804
|
+
const aId = a.getIntervalId();
|
|
805
|
+
const bId = b.getIntervalId();
|
|
806
|
+
if (aId !== undefined && bId !== undefined) {
|
|
807
|
+
return aId.localeCompare(bId);
|
|
808
|
+
}
|
|
809
|
+
return 0;
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
add(interval) {
|
|
813
|
+
this.intervalTree.put(interval, interval);
|
|
814
|
+
}
|
|
815
|
+
remove(interval) {
|
|
816
|
+
this.intervalTree.remove(interval);
|
|
817
|
+
}
|
|
818
|
+
findIntervalsWithStartpointInRange(start, end) {
|
|
819
|
+
if (start <= 0 || start > end || this.intervalTree.isEmpty()) {
|
|
820
|
+
return [];
|
|
821
|
+
}
|
|
822
|
+
const results = [];
|
|
823
|
+
const action = (node) => {
|
|
824
|
+
results.push(node.data);
|
|
825
|
+
return true;
|
|
826
|
+
};
|
|
827
|
+
const transientStartInterval = this.helpers.create("transient", start, start, this.client, IntervalType.Transient);
|
|
828
|
+
const transientEndInterval = this.helpers.create("transient", end, end, this.client, IntervalType.Transient);
|
|
829
|
+
// Add comparison overrides to the transient intervals
|
|
830
|
+
transientStartInterval[forceCompare] = -1;
|
|
831
|
+
transientEndInterval[forceCompare] = 1;
|
|
832
|
+
this.intervalTree.mapRange(action, results, transientStartInterval, transientEndInterval);
|
|
833
|
+
return results;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
function createEndpointInRangeIndex(helpers, client) {
|
|
837
|
+
return new EndpointInRangeIndex(helpers, client);
|
|
838
|
+
}
|
|
839
|
+
exports.createEndpointInRangeIndex = createEndpointInRangeIndex;
|
|
840
|
+
function createStartpointInRangeIndex(helpers, client) {
|
|
841
|
+
return new StartpointInRangeIndex(helpers, client);
|
|
842
|
+
}
|
|
843
|
+
exports.createStartpointInRangeIndex = createStartpointInRangeIndex;
|
|
672
844
|
class LocalIntervalCollection {
|
|
673
845
|
constructor(client, label, helpers,
|
|
674
846
|
/** Callback invoked each time one of the endpoints of an interval slides. */
|
|
@@ -680,11 +852,11 @@ class LocalIntervalCollection {
|
|
|
680
852
|
this.overlappingIntervalsIndex = new OverlappingIntervalsIndex(client, helpers);
|
|
681
853
|
this.idIntervalIndex = new IdIntervalIndex();
|
|
682
854
|
this.endIntervalIndex = new EndpointIndex(client, helpers);
|
|
683
|
-
this.indexes = [
|
|
855
|
+
this.indexes = new Set([
|
|
684
856
|
this.overlappingIntervalsIndex,
|
|
685
857
|
this.idIntervalIndex,
|
|
686
858
|
this.endIntervalIndex,
|
|
687
|
-
];
|
|
859
|
+
]);
|
|
688
860
|
}
|
|
689
861
|
createLegacyId(start, end) {
|
|
690
862
|
// Create a non-unique ID based on start and end to be used on intervals that come from legacy clients
|
|
@@ -724,17 +896,23 @@ class LocalIntervalCollection {
|
|
|
724
896
|
index.remove(interval);
|
|
725
897
|
}
|
|
726
898
|
}
|
|
899
|
+
appendIndex(index) {
|
|
900
|
+
this.indexes.add(index);
|
|
901
|
+
}
|
|
902
|
+
removeIndex(index) {
|
|
903
|
+
return this.indexes.delete(index);
|
|
904
|
+
}
|
|
727
905
|
removeExistingInterval(interval) {
|
|
728
906
|
this.removeIntervalFromIndexes(interval);
|
|
729
907
|
this.removeIntervalListeners(interval);
|
|
730
908
|
}
|
|
731
|
-
createInterval(start, end, intervalType, op) {
|
|
732
|
-
return this.helpers.create(this.label, start, end, this.client, intervalType, op);
|
|
909
|
+
createInterval(start, end, intervalType, op, stickiness = exports.IntervalStickiness.END) {
|
|
910
|
+
return this.helpers.create(this.label, start, end, this.client, intervalType, op, undefined, stickiness);
|
|
733
911
|
}
|
|
734
|
-
addInterval(start, end, intervalType, props, op) {
|
|
912
|
+
addInterval(start, end, intervalType, props, op, stickiness = exports.IntervalStickiness.END) {
|
|
735
913
|
var _a;
|
|
736
914
|
var _b;
|
|
737
|
-
const interval = this.createInterval(start, end, intervalType, op);
|
|
915
|
+
const interval = this.createInterval(start, end, intervalType, op, stickiness);
|
|
738
916
|
if (interval) {
|
|
739
917
|
if (!interval.properties) {
|
|
740
918
|
interval.properties = (0, merge_tree_1.createMap)();
|
|
@@ -787,7 +965,7 @@ class LocalIntervalCollection {
|
|
|
787
965
|
// either, so this must be special-cased.
|
|
788
966
|
return ref;
|
|
789
967
|
}
|
|
790
|
-
return this.client.createLocalReferencePosition(segment, ref.getOffset(), merge_tree_1.ReferenceType.Transient, ref.properties);
|
|
968
|
+
return this.client.createLocalReferencePosition(segment, ref.getOffset(), merge_tree_1.ReferenceType.Transient, ref.properties, ref.slidingPreference);
|
|
791
969
|
};
|
|
792
970
|
if (interval instanceof SequenceInterval) {
|
|
793
971
|
let previousInterval;
|
|
@@ -823,13 +1001,21 @@ exports.LocalIntervalCollection = LocalIntervalCollection;
|
|
|
823
1001
|
LocalIntervalCollection.legacyIdPrefix = "legacy";
|
|
824
1002
|
const compareSequenceIntervalEnds = (a, b) => (0, merge_tree_1.compareReferencePositions)(a.end, b.end);
|
|
825
1003
|
exports.compareSequenceIntervalEnds = compareSequenceIntervalEnds;
|
|
1004
|
+
const compareSequenceIntervalStarts = (a, b) => (0, merge_tree_1.compareReferencePositions)(a.start, b.start);
|
|
1005
|
+
exports.compareSequenceIntervalStarts = compareSequenceIntervalStarts;
|
|
1006
|
+
exports.sequenceIntervalHelpers = {
|
|
1007
|
+
compareEnds: exports.compareSequenceIntervalEnds,
|
|
1008
|
+
compareStarts: exports.compareSequenceIntervalStarts,
|
|
1009
|
+
create: createSequenceInterval,
|
|
1010
|
+
};
|
|
1011
|
+
exports.intervalHelpers = {
|
|
1012
|
+
compareEnds: (a, b) => a.end - b.end,
|
|
1013
|
+
compareStarts: (a, b) => a.start - b.start,
|
|
1014
|
+
create: createInterval,
|
|
1015
|
+
};
|
|
826
1016
|
class SequenceIntervalCollectionFactory {
|
|
827
|
-
load(emitter, raw = []) {
|
|
828
|
-
|
|
829
|
-
compareEnds: exports.compareSequenceIntervalEnds,
|
|
830
|
-
create: createSequenceInterval,
|
|
831
|
-
};
|
|
832
|
-
return new IntervalCollection(helpers, true, emitter, raw);
|
|
1017
|
+
load(emitter, raw = [], options) {
|
|
1018
|
+
return new IntervalCollection(exports.sequenceIntervalHelpers, true, emitter, raw, options);
|
|
833
1019
|
}
|
|
834
1020
|
store(value) {
|
|
835
1021
|
return value.serializeInternal();
|
|
@@ -851,7 +1037,7 @@ SequenceIntervalCollectionValueType.Name = "sharedStringIntervalCollection";
|
|
|
851
1037
|
SequenceIntervalCollectionValueType._factory = new SequenceIntervalCollectionFactory();
|
|
852
1038
|
SequenceIntervalCollectionValueType._ops = makeOpsMap();
|
|
853
1039
|
const compareIntervalEnds = (a, b) => a.end - b.end;
|
|
854
|
-
function createInterval(label, start, end, client) {
|
|
1040
|
+
function createInterval(label, start, end, client, intervalType, op, fromSnapshot) {
|
|
855
1041
|
const rangeProp = {};
|
|
856
1042
|
if (label && label.length > 0) {
|
|
857
1043
|
rangeProp[merge_tree_1.reservedRangeLabelsKey] = [label];
|
|
@@ -859,12 +1045,12 @@ function createInterval(label, start, end, client) {
|
|
|
859
1045
|
return new Interval(start, end, rangeProp);
|
|
860
1046
|
}
|
|
861
1047
|
class IntervalCollectionFactory {
|
|
862
|
-
load(emitter, raw = []) {
|
|
1048
|
+
load(emitter, raw = [], options) {
|
|
863
1049
|
const helpers = {
|
|
864
1050
|
compareEnds: compareIntervalEnds,
|
|
865
1051
|
create: createInterval,
|
|
866
1052
|
};
|
|
867
|
-
const collection = new IntervalCollection(helpers, false, emitter, raw);
|
|
1053
|
+
const collection = new IntervalCollection(helpers, false, emitter, raw, options);
|
|
868
1054
|
collection.attachGraph(undefined, "");
|
|
869
1055
|
return collection;
|
|
870
1056
|
}
|
|
@@ -896,7 +1082,7 @@ function makeOpsMap() {
|
|
|
896
1082
|
};
|
|
897
1083
|
return new Map([
|
|
898
1084
|
[
|
|
899
|
-
|
|
1085
|
+
exports.IntervalOpType.ADD,
|
|
900
1086
|
{
|
|
901
1087
|
process: (collection, params, local, op, localOpMetadata) => {
|
|
902
1088
|
// if params is undefined, the interval was deleted during
|
|
@@ -911,7 +1097,7 @@ function makeOpsMap() {
|
|
|
911
1097
|
},
|
|
912
1098
|
],
|
|
913
1099
|
[
|
|
914
|
-
|
|
1100
|
+
exports.IntervalOpType.DELETE,
|
|
915
1101
|
{
|
|
916
1102
|
process: (collection, params, local, op) => {
|
|
917
1103
|
(0, common_utils_1.assert)(op !== undefined, 0x3fc /* op should exist here */);
|
|
@@ -924,7 +1110,7 @@ function makeOpsMap() {
|
|
|
924
1110
|
},
|
|
925
1111
|
],
|
|
926
1112
|
[
|
|
927
|
-
|
|
1113
|
+
exports.IntervalOpType.CHANGE,
|
|
928
1114
|
{
|
|
929
1115
|
process: (collection, params, local, op, localOpMetadata) => {
|
|
930
1116
|
// if params is undefined, the interval was deleted during
|
|
@@ -960,21 +1146,17 @@ class IntervalCollectionIterator {
|
|
|
960
1146
|
};
|
|
961
1147
|
}
|
|
962
1148
|
}
|
|
963
|
-
exports.IntervalCollectionIterator = IntervalCollectionIterator;
|
|
964
1149
|
/**
|
|
965
|
-
*
|
|
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.
|
|
1150
|
+
* {@inheritdoc IIntervalCollection}
|
|
970
1151
|
*/
|
|
971
1152
|
class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
972
1153
|
/** @internal */
|
|
973
|
-
constructor(helpers, requiresClient, emitter, serializedIntervals) {
|
|
1154
|
+
constructor(helpers, requiresClient, emitter, serializedIntervals, options = {}) {
|
|
974
1155
|
super();
|
|
975
1156
|
this.helpers = helpers;
|
|
976
1157
|
this.requiresClient = requiresClient;
|
|
977
1158
|
this.emitter = emitter;
|
|
1159
|
+
this.options = options;
|
|
978
1160
|
this.localSeqToSerializedInterval = new Map();
|
|
979
1161
|
this.localSeqToRebasedInterval = new Map();
|
|
980
1162
|
this.pendingChangesStart = new Map();
|
|
@@ -986,6 +1168,36 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
986
1168
|
get attached() {
|
|
987
1169
|
return !!this.localCollection;
|
|
988
1170
|
}
|
|
1171
|
+
/**
|
|
1172
|
+
* {@inheritdoc IIntervalCollection.attachIndex}
|
|
1173
|
+
*/
|
|
1174
|
+
attachIndex(index) {
|
|
1175
|
+
var _a;
|
|
1176
|
+
if (!this.attached) {
|
|
1177
|
+
throw new telemetry_utils_1.LoggingError("The local interval collection must exist");
|
|
1178
|
+
}
|
|
1179
|
+
for (const interval of this) {
|
|
1180
|
+
index.add(interval);
|
|
1181
|
+
}
|
|
1182
|
+
(_a = this.localCollection) === null || _a === void 0 ? void 0 : _a.appendIndex(index);
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* {@inheritdoc IIntervalCollection.detachIndex}
|
|
1186
|
+
*/
|
|
1187
|
+
detachIndex(index) {
|
|
1188
|
+
var _a;
|
|
1189
|
+
if (!this.attached) {
|
|
1190
|
+
throw new telemetry_utils_1.LoggingError("The local interval collection must exist");
|
|
1191
|
+
}
|
|
1192
|
+
// Avoid removing intervals if the index does not exist
|
|
1193
|
+
if (!((_a = this.localCollection) === null || _a === void 0 ? void 0 : _a.removeIndex(index))) {
|
|
1194
|
+
return false;
|
|
1195
|
+
}
|
|
1196
|
+
for (const interval of this) {
|
|
1197
|
+
index.remove(interval);
|
|
1198
|
+
}
|
|
1199
|
+
return true;
|
|
1200
|
+
}
|
|
989
1201
|
rebasePositionWithSegmentSlide(pos, seqNumberFrom, localSeq) {
|
|
990
1202
|
var _a;
|
|
991
1203
|
if (!this.client) {
|
|
@@ -1041,8 +1253,8 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1041
1253
|
if (this.savedSerializedIntervals) {
|
|
1042
1254
|
for (const serializedInterval of this.savedSerializedIntervals) {
|
|
1043
1255
|
this.localCollection.ensureSerializedId(serializedInterval);
|
|
1044
|
-
const { start, end, intervalType, properties } = serializedInterval;
|
|
1045
|
-
const interval = this.helpers.create(label, start, end, client, intervalType, undefined, true);
|
|
1256
|
+
const { start, end, intervalType, properties, stickiness } = serializedInterval;
|
|
1257
|
+
const interval = this.helpers.create(label, start, end, client, intervalType, undefined, true, stickiness);
|
|
1046
1258
|
if (properties) {
|
|
1047
1259
|
interval.addProperties(properties);
|
|
1048
1260
|
}
|
|
@@ -1080,8 +1292,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1080
1292
|
}
|
|
1081
1293
|
}
|
|
1082
1294
|
/**
|
|
1083
|
-
* @
|
|
1084
|
-
* If no interval in the collection has this `id`, returns `undefined`.
|
|
1295
|
+
* {@inheritdoc IIntervalCollection.getIntervalById}
|
|
1085
1296
|
*/
|
|
1086
1297
|
getIntervalById(id) {
|
|
1087
1298
|
if (!this.localCollection) {
|
|
@@ -1090,16 +1301,9 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1090
1301
|
return this.localCollection.idIntervalIndex.getIntervalById(id);
|
|
1091
1302
|
}
|
|
1092
1303
|
/**
|
|
1093
|
-
*
|
|
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.
|
|
1304
|
+
* {@inheritdoc IIntervalCollection.add}
|
|
1101
1305
|
*/
|
|
1102
|
-
add(start, end, intervalType, props) {
|
|
1306
|
+
add(start, end, intervalType, props, stickiness = exports.IntervalStickiness.END) {
|
|
1103
1307
|
var _a, _b;
|
|
1104
1308
|
if (!this.localCollection) {
|
|
1105
1309
|
throw new telemetry_utils_1.LoggingError("attach must be called prior to adding intervals");
|
|
@@ -1107,7 +1311,10 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1107
1311
|
if (intervalType & IntervalType.Transient) {
|
|
1108
1312
|
throw new telemetry_utils_1.LoggingError("Can not add transient intervals");
|
|
1109
1313
|
}
|
|
1110
|
-
|
|
1314
|
+
if (stickiness !== exports.IntervalStickiness.END && !this.options.intervalStickinessEnabled) {
|
|
1315
|
+
throw new container_utils_1.UsageError("attempted to set interval stickiness without enabling `intervalStickinessEnabled` feature flag");
|
|
1316
|
+
}
|
|
1317
|
+
const interval = this.localCollection.addInterval(start, end, intervalType, props, undefined, stickiness);
|
|
1111
1318
|
if (interval) {
|
|
1112
1319
|
const serializedInterval = {
|
|
1113
1320
|
end,
|
|
@@ -1115,6 +1322,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1115
1322
|
properties: interval.properties,
|
|
1116
1323
|
sequenceNumber: (_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.getCurrentSeq()) !== null && _b !== void 0 ? _b : 0,
|
|
1117
1324
|
start,
|
|
1325
|
+
stickiness,
|
|
1118
1326
|
};
|
|
1119
1327
|
const localSeq = this.getNextLocalSeq();
|
|
1120
1328
|
this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
|
|
@@ -1146,9 +1354,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1146
1354
|
this.emit("deleteInterval", interval, local, op);
|
|
1147
1355
|
}
|
|
1148
1356
|
/**
|
|
1149
|
-
*
|
|
1150
|
-
* @param id - Id of the interval to remove
|
|
1151
|
-
* @returns the removed interval
|
|
1357
|
+
* {@inheritdoc IIntervalCollection.removeIntervalById}
|
|
1152
1358
|
*/
|
|
1153
1359
|
removeIntervalById(id) {
|
|
1154
1360
|
if (!this.localCollection) {
|
|
@@ -1161,10 +1367,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1161
1367
|
return interval;
|
|
1162
1368
|
}
|
|
1163
1369
|
/**
|
|
1164
|
-
*
|
|
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 }`.
|
|
1370
|
+
* {@inheritdoc IIntervalCollection.changeProperties}
|
|
1168
1371
|
*/
|
|
1169
1372
|
changeProperties(id, props) {
|
|
1170
1373
|
if (!this.attached) {
|
|
@@ -1194,11 +1397,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1194
1397
|
}
|
|
1195
1398
|
}
|
|
1196
1399
|
/**
|
|
1197
|
-
*
|
|
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.
|
|
1400
|
+
* {@inheritdoc IIntervalCollection.change}
|
|
1202
1401
|
*/
|
|
1203
1402
|
change(id, start, end) {
|
|
1204
1403
|
if (!this.localCollection) {
|
|
@@ -1353,6 +1552,9 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1353
1552
|
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1354
1553
|
}
|
|
1355
1554
|
}
|
|
1555
|
+
/**
|
|
1556
|
+
* {@inheritdoc IIntervalCollection.attachDeserializer}
|
|
1557
|
+
*/
|
|
1356
1558
|
attachDeserializer(onDeserialize) {
|
|
1357
1559
|
// If no deserializer is specified can skip all processing work
|
|
1358
1560
|
if (!onDeserialize) {
|
|
@@ -1473,7 +1675,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1473
1675
|
}
|
|
1474
1676
|
if (needsStartUpdate) {
|
|
1475
1677
|
const props = interval.start.properties;
|
|
1476
|
-
interval.start = createPositionReferenceFromSegoff(this.client, newStart, interval.start.refType, op);
|
|
1678
|
+
interval.start = createPositionReferenceFromSegoff(this.client, newStart, interval.start.refType, op, startReferenceSlidingPreference(interval.stickiness));
|
|
1477
1679
|
if (props) {
|
|
1478
1680
|
interval.start.addProperties(props);
|
|
1479
1681
|
}
|
|
@@ -1485,7 +1687,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1485
1687
|
}
|
|
1486
1688
|
if (needsEndUpdate) {
|
|
1487
1689
|
const props = interval.end.properties;
|
|
1488
|
-
interval.end = createPositionReferenceFromSegoff(this.client, newEnd, interval.end.refType, op);
|
|
1690
|
+
interval.end = createPositionReferenceFromSegoff(this.client, newEnd, interval.end.refType, op, endReferenceSlidingPreference(interval.stickiness));
|
|
1489
1691
|
if (props) {
|
|
1490
1692
|
interval.end.addProperties(props);
|
|
1491
1693
|
}
|
|
@@ -1516,7 +1718,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1516
1718
|
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1517
1719
|
}
|
|
1518
1720
|
this.localCollection.ensureSerializedId(serializedInterval);
|
|
1519
|
-
const interval = this.localCollection.addInterval(serializedInterval.start, serializedInterval.end, serializedInterval.intervalType, serializedInterval.properties, op);
|
|
1721
|
+
const interval = this.localCollection.addInterval(serializedInterval.start, serializedInterval.end, serializedInterval.intervalType, serializedInterval.properties, op, serializedInterval.stickiness);
|
|
1520
1722
|
if (interval) {
|
|
1521
1723
|
if (this.onDeserialize) {
|
|
1522
1724
|
this.onDeserialize(interval);
|
|
@@ -1559,40 +1761,35 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1559
1761
|
return iterator;
|
|
1560
1762
|
}
|
|
1561
1763
|
/**
|
|
1562
|
-
* @
|
|
1764
|
+
* {@inheritdoc IIntervalCollection.CreateForwardIteratorWithStartPosition}
|
|
1563
1765
|
*/
|
|
1564
1766
|
CreateForwardIteratorWithStartPosition(startPosition) {
|
|
1565
1767
|
const iterator = new IntervalCollectionIterator(this, true, startPosition);
|
|
1566
1768
|
return iterator;
|
|
1567
1769
|
}
|
|
1568
1770
|
/**
|
|
1569
|
-
* @
|
|
1771
|
+
* {@inheritdoc IIntervalCollection.CreateBackwardIteratorWithStartPosition}
|
|
1570
1772
|
*/
|
|
1571
1773
|
CreateBackwardIteratorWithStartPosition(startPosition) {
|
|
1572
1774
|
const iterator = new IntervalCollectionIterator(this, false, startPosition);
|
|
1573
1775
|
return iterator;
|
|
1574
1776
|
}
|
|
1575
1777
|
/**
|
|
1576
|
-
* @
|
|
1778
|
+
* {@inheritdoc IIntervalCollection.CreateForwardIteratorWithEndPosition}
|
|
1577
1779
|
*/
|
|
1578
1780
|
CreateForwardIteratorWithEndPosition(endPosition) {
|
|
1579
1781
|
const iterator = new IntervalCollectionIterator(this, true, undefined, endPosition);
|
|
1580
1782
|
return iterator;
|
|
1581
1783
|
}
|
|
1582
1784
|
/**
|
|
1583
|
-
* @
|
|
1785
|
+
* {@inheritdoc IIntervalCollection.CreateBackwardIteratorWithEndPosition}
|
|
1584
1786
|
*/
|
|
1585
1787
|
CreateBackwardIteratorWithEndPosition(endPosition) {
|
|
1586
1788
|
const iterator = new IntervalCollectionIterator(this, false, undefined, endPosition);
|
|
1587
1789
|
return iterator;
|
|
1588
1790
|
}
|
|
1589
1791
|
/**
|
|
1590
|
-
*
|
|
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`.
|
|
1792
|
+
* {@inheritdoc IIntervalCollection.gatherIterationResults}
|
|
1596
1793
|
*/
|
|
1597
1794
|
gatherIterationResults(results, iteratesForward, start, end) {
|
|
1598
1795
|
if (!this.localCollection) {
|
|
@@ -1601,8 +1798,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1601
1798
|
this.localCollection.overlappingIntervalsIndex.gatherIterationResults(results, iteratesForward, start, end);
|
|
1602
1799
|
}
|
|
1603
1800
|
/**
|
|
1604
|
-
* @
|
|
1605
|
-
* `[startPosition, endPosition]`.
|
|
1801
|
+
* {@inheritdoc IIntervalCollection.findOverlappingIntervals}
|
|
1606
1802
|
*/
|
|
1607
1803
|
findOverlappingIntervals(startPosition, endPosition) {
|
|
1608
1804
|
if (!this.localCollection) {
|
|
@@ -1611,7 +1807,7 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1611
1807
|
return this.localCollection.overlappingIntervalsIndex.findOverlappingIntervals(startPosition, endPosition);
|
|
1612
1808
|
}
|
|
1613
1809
|
/**
|
|
1614
|
-
*
|
|
1810
|
+
* {@inheritdoc IIntervalCollection.map}
|
|
1615
1811
|
*/
|
|
1616
1812
|
map(fn) {
|
|
1617
1813
|
if (!this.localCollection) {
|
|
@@ -1621,12 +1817,18 @@ class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
|
1621
1817
|
fn(interval);
|
|
1622
1818
|
}
|
|
1623
1819
|
}
|
|
1820
|
+
/**
|
|
1821
|
+
* {@inheritdoc IIntervalCollection.previousInterval}
|
|
1822
|
+
*/
|
|
1624
1823
|
previousInterval(pos) {
|
|
1625
1824
|
if (!this.localCollection) {
|
|
1626
1825
|
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1627
1826
|
}
|
|
1628
1827
|
return this.localCollection.endIntervalIndex.previousInterval(pos);
|
|
1629
1828
|
}
|
|
1829
|
+
/**
|
|
1830
|
+
* {@inheritdoc IIntervalCollection.nextInterval}
|
|
1831
|
+
*/
|
|
1630
1832
|
nextInterval(pos) {
|
|
1631
1833
|
if (!this.localCollection) {
|
|
1632
1834
|
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|