@fluidframework/sequence 2.0.0-internal.4.2.1 → 2.0.0-internal.4.4.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 +12 -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 +11 -1
- package/dist/index.js.map +1 -1
- package/dist/intervalCollection.d.ts +199 -46
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +164 -78
- 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 +2 -2
- 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.map +1 -1
- package/dist/sharedIntervalCollection.js +1 -1
- package/dist/sharedIntervalCollection.js.map +1 -1
- 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 +199 -46
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +164 -78
- 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 +2 -2
- 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.map +1 -1
- package/lib/sharedIntervalCollection.js +1 -1
- package/lib/sharedIntervalCollection.js.map +1 -1
- package/package.json +38 -14
- package/src/defaultMap.ts +4 -1
- package/src/defaultMapInterfaces.ts +13 -1
- package/src/index.ts +16 -1
- package/src/intervalCollection.ts +370 -57
- package/src/packageVersion.ts +1 -1
- package/src/revertibles.ts +572 -0
- package/src/sequence.ts +12 -3
- package/src/sharedIntervalCollection.ts +3 -2
- package/.vscode/launch.json +0 -16
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
maxReferencePosition,
|
|
29
29
|
createDetachedLocalReferencePosition,
|
|
30
30
|
DetachedReferencePosition,
|
|
31
|
+
SlidingPreference,
|
|
31
32
|
} from "@fluidframework/merge-tree";
|
|
32
33
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
33
34
|
import { LoggingError } from "@fluidframework/telemetry-utils";
|
|
@@ -39,11 +40,24 @@ import {
|
|
|
39
40
|
IValueOperation,
|
|
40
41
|
IValueType,
|
|
41
42
|
IValueTypeOperationValue,
|
|
43
|
+
SequenceOptions,
|
|
42
44
|
} from "./defaultMapInterfaces";
|
|
43
45
|
import { IInterval, IntervalConflictResolver, IntervalTree, IntervalNode } from "./intervalTree";
|
|
44
46
|
|
|
45
47
|
const reservedIntervalIdKey = "intervalId";
|
|
46
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Values are used in persisted formats (ops) and revertibles.
|
|
51
|
+
* @alpha
|
|
52
|
+
*/
|
|
53
|
+
export const IntervalOpType = {
|
|
54
|
+
ADD: "add",
|
|
55
|
+
DELETE: "delete",
|
|
56
|
+
CHANGE: "change",
|
|
57
|
+
PROPERTY_CHANGED: "propertyChanged",
|
|
58
|
+
POSITION_REMOVE: "positionRemove",
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
47
61
|
export enum IntervalType {
|
|
48
62
|
Simple = 0x0,
|
|
49
63
|
Nest = 0x1,
|
|
@@ -83,6 +97,7 @@ export interface ISerializedInterval {
|
|
|
83
97
|
end: number;
|
|
84
98
|
/** Interval type to create */
|
|
85
99
|
intervalType: IntervalType;
|
|
100
|
+
stickiness?: IntervalStickiness;
|
|
86
101
|
/** Any properties the interval has */
|
|
87
102
|
properties?: PropertySet;
|
|
88
103
|
}
|
|
@@ -101,12 +116,17 @@ export type SerializedIntervalDelta = Omit<ISerializedInterval, "start" | "end"
|
|
|
101
116
|
*
|
|
102
117
|
* Intervals are of the format:
|
|
103
118
|
*
|
|
104
|
-
* [start, end, sequenceNumber, intervalType, properties]
|
|
119
|
+
* [start, end, sequenceNumber, intervalType, properties, stickiness?]
|
|
120
|
+
*
|
|
121
|
+
* @deprecated - Public export was never intended and will be removed.
|
|
105
122
|
*/
|
|
106
|
-
export type CompressedSerializedInterval =
|
|
123
|
+
export type CompressedSerializedInterval =
|
|
124
|
+
| [number, number, number, IntervalType, PropertySet, IntervalStickiness]
|
|
125
|
+
| [number, number, number, IntervalType, PropertySet];
|
|
107
126
|
|
|
108
127
|
/**
|
|
109
128
|
* @internal
|
|
129
|
+
* @deprecated - Public export will be removed.
|
|
110
130
|
*/
|
|
111
131
|
export interface ISerializedIntervalCollectionV2 {
|
|
112
132
|
label: string;
|
|
@@ -128,6 +148,7 @@ function decompressInterval(
|
|
|
128
148
|
sequenceNumber: interval[2],
|
|
129
149
|
intervalType: interval[3],
|
|
130
150
|
properties: { ...interval[4], [reservedRangeLabelsKey]: [label] },
|
|
151
|
+
stickiness: interval[5],
|
|
131
152
|
};
|
|
132
153
|
}
|
|
133
154
|
|
|
@@ -138,7 +159,7 @@ function decompressInterval(
|
|
|
138
159
|
function compressInterval(interval: ISerializedInterval): CompressedSerializedInterval {
|
|
139
160
|
const { start, end, sequenceNumber, intervalType, properties } = interval;
|
|
140
161
|
|
|
141
|
-
|
|
162
|
+
const base: CompressedSerializedInterval = [
|
|
142
163
|
start,
|
|
143
164
|
end,
|
|
144
165
|
sequenceNumber,
|
|
@@ -147,6 +168,26 @@ function compressInterval(interval: ISerializedInterval): CompressedSerializedIn
|
|
|
147
168
|
// in the `label` field of the summary
|
|
148
169
|
{ ...properties, [reservedRangeLabelsKey]: undefined },
|
|
149
170
|
];
|
|
171
|
+
|
|
172
|
+
if (interval.stickiness !== undefined && interval.stickiness !== IntervalStickiness.END) {
|
|
173
|
+
base.push(interval.stickiness);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return base;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function startReferenceSlidingPreference(stickiness: IntervalStickiness): SlidingPreference {
|
|
180
|
+
// if any start stickiness, prefer sliding backwards
|
|
181
|
+
return (stickiness & IntervalStickiness.START) !== 0
|
|
182
|
+
? SlidingPreference.BACKWARD
|
|
183
|
+
: SlidingPreference.FORWARD;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function endReferenceSlidingPreference(stickiness: IntervalStickiness): SlidingPreference {
|
|
187
|
+
// if any end stickiness, prefer sliding forwards
|
|
188
|
+
return (stickiness & IntervalStickiness.END) !== 0
|
|
189
|
+
? SlidingPreference.FORWARD
|
|
190
|
+
: SlidingPreference.BACKWARD;
|
|
150
191
|
}
|
|
151
192
|
|
|
152
193
|
export interface ISerializableInterval extends IInterval {
|
|
@@ -193,9 +234,50 @@ export interface IIntervalHelpers<TInterval extends ISerializableInterval> {
|
|
|
193
234
|
intervalType: IntervalType,
|
|
194
235
|
op?: ISequencedDocumentMessage,
|
|
195
236
|
fromSnapshot?: boolean,
|
|
237
|
+
stickiness?: IntervalStickiness,
|
|
196
238
|
): TInterval;
|
|
197
239
|
}
|
|
198
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Determines how an interval should expand when segments are inserted adjacent
|
|
243
|
+
* to the range it spans
|
|
244
|
+
*
|
|
245
|
+
* Note that interval stickiness is currently an experimental feature and must
|
|
246
|
+
* be explicitly enabled with the `intervalStickinessEnabled` flag
|
|
247
|
+
*/
|
|
248
|
+
export const IntervalStickiness = {
|
|
249
|
+
/**
|
|
250
|
+
* Interval does not expand to include adjacent segments
|
|
251
|
+
*/
|
|
252
|
+
NONE: 0b00,
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Interval expands to include segments inserted adjacent to the start
|
|
256
|
+
*/
|
|
257
|
+
START: 0b01,
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Interval expands to include segments inserted adjacent to the end
|
|
261
|
+
*
|
|
262
|
+
* This is the default stickiness
|
|
263
|
+
*/
|
|
264
|
+
END: 0b10,
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Interval expands to include all segments inserted adjacent to it
|
|
268
|
+
*/
|
|
269
|
+
FULL: 0b11,
|
|
270
|
+
} as const;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Determines how an interval should expand when segments are inserted adjacent
|
|
274
|
+
* to the range it spans
|
|
275
|
+
*
|
|
276
|
+
* Note that interval stickiness is currently an experimental feature and must
|
|
277
|
+
* be explicitly enabled with the `intervalStickinessEnabled` flag
|
|
278
|
+
*/
|
|
279
|
+
export type IntervalStickiness = typeof IntervalStickiness[keyof typeof IntervalStickiness];
|
|
280
|
+
|
|
199
281
|
/**
|
|
200
282
|
* Serializable interval whose endpoints are plain-old numbers.
|
|
201
283
|
*/
|
|
@@ -439,6 +521,7 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
439
521
|
public end: LocalReferencePosition,
|
|
440
522
|
public intervalType: IntervalType,
|
|
441
523
|
props?: PropertySet,
|
|
524
|
+
public readonly stickiness: IntervalStickiness = IntervalStickiness.END,
|
|
442
525
|
) {
|
|
443
526
|
this.propertyManager = new PropertiesManager();
|
|
444
527
|
this.properties = {};
|
|
@@ -500,6 +583,9 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
500
583
|
if (this.properties) {
|
|
501
584
|
serializedInterval.properties = this.properties;
|
|
502
585
|
}
|
|
586
|
+
if (this.stickiness !== IntervalStickiness.END) {
|
|
587
|
+
serializedInterval.stickiness = this.stickiness;
|
|
588
|
+
}
|
|
503
589
|
|
|
504
590
|
return serializedInterval;
|
|
505
591
|
}
|
|
@@ -514,6 +600,7 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
514
600
|
this.end,
|
|
515
601
|
this.intervalType,
|
|
516
602
|
this.properties,
|
|
603
|
+
this.stickiness,
|
|
517
604
|
);
|
|
518
605
|
}
|
|
519
606
|
|
|
@@ -621,6 +708,7 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
621
708
|
end: number,
|
|
622
709
|
op?: ISequencedDocumentMessage,
|
|
623
710
|
localSeq?: number,
|
|
711
|
+
stickiness: IntervalStickiness = IntervalStickiness.END,
|
|
624
712
|
) {
|
|
625
713
|
const getRefType = (baseType: ReferenceType): ReferenceType => {
|
|
626
714
|
let refType = baseType;
|
|
@@ -640,6 +728,7 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
640
728
|
op,
|
|
641
729
|
undefined,
|
|
642
730
|
localSeq,
|
|
731
|
+
startReferenceSlidingPreference(stickiness),
|
|
643
732
|
);
|
|
644
733
|
if (this.start.properties) {
|
|
645
734
|
startRef.addProperties(this.start.properties);
|
|
@@ -655,6 +744,7 @@ export class SequenceInterval implements ISerializableInterval {
|
|
|
655
744
|
op,
|
|
656
745
|
undefined,
|
|
657
746
|
localSeq,
|
|
747
|
+
endReferenceSlidingPreference(stickiness),
|
|
658
748
|
);
|
|
659
749
|
if (this.end.properties) {
|
|
660
750
|
endRef.addProperties(this.end.properties);
|
|
@@ -690,6 +780,7 @@ function createPositionReferenceFromSegoff(
|
|
|
690
780
|
op?: ISequencedDocumentMessage,
|
|
691
781
|
localSeq?: number,
|
|
692
782
|
fromSnapshot?: boolean,
|
|
783
|
+
slidingPreference?: SlidingPreference,
|
|
693
784
|
): LocalReferencePosition {
|
|
694
785
|
if (segoff.segment) {
|
|
695
786
|
const ref = client.createLocalReferencePosition(
|
|
@@ -697,6 +788,7 @@ function createPositionReferenceFromSegoff(
|
|
|
697
788
|
segoff.offset,
|
|
698
789
|
refType,
|
|
699
790
|
undefined,
|
|
791
|
+
slidingPreference,
|
|
700
792
|
);
|
|
701
793
|
return ref;
|
|
702
794
|
}
|
|
@@ -725,6 +817,7 @@ function createPositionReference(
|
|
|
725
817
|
op?: ISequencedDocumentMessage,
|
|
726
818
|
fromSnapshot?: boolean,
|
|
727
819
|
localSeq?: number,
|
|
820
|
+
slidingPreference?: SlidingPreference,
|
|
728
821
|
): LocalReferencePosition {
|
|
729
822
|
let segoff;
|
|
730
823
|
if (op) {
|
|
@@ -744,7 +837,16 @@ function createPositionReference(
|
|
|
744
837
|
);
|
|
745
838
|
segoff = client.getContainingSegment(pos, undefined, localSeq);
|
|
746
839
|
}
|
|
747
|
-
|
|
840
|
+
|
|
841
|
+
return createPositionReferenceFromSegoff(
|
|
842
|
+
client,
|
|
843
|
+
segoff,
|
|
844
|
+
refType,
|
|
845
|
+
op,
|
|
846
|
+
localSeq,
|
|
847
|
+
fromSnapshot,
|
|
848
|
+
slidingPreference,
|
|
849
|
+
);
|
|
748
850
|
}
|
|
749
851
|
|
|
750
852
|
export function createSequenceInterval(
|
|
@@ -755,6 +857,7 @@ export function createSequenceInterval(
|
|
|
755
857
|
intervalType: IntervalType,
|
|
756
858
|
op?: ISequencedDocumentMessage,
|
|
757
859
|
fromSnapshot?: boolean,
|
|
860
|
+
stickiness: IntervalStickiness = IntervalStickiness.END,
|
|
758
861
|
): SequenceInterval {
|
|
759
862
|
let beginRefType = ReferenceType.RangeBegin;
|
|
760
863
|
let endRefType = ReferenceType.RangeEnd;
|
|
@@ -778,15 +881,38 @@ export function createSequenceInterval(
|
|
|
778
881
|
}
|
|
779
882
|
}
|
|
780
883
|
|
|
781
|
-
const startLref = createPositionReference(
|
|
782
|
-
|
|
884
|
+
const startLref = createPositionReference(
|
|
885
|
+
client,
|
|
886
|
+
start,
|
|
887
|
+
beginRefType,
|
|
888
|
+
op,
|
|
889
|
+
fromSnapshot,
|
|
890
|
+
undefined,
|
|
891
|
+
startReferenceSlidingPreference(stickiness),
|
|
892
|
+
);
|
|
893
|
+
const endLref = createPositionReference(
|
|
894
|
+
client,
|
|
895
|
+
end,
|
|
896
|
+
endRefType,
|
|
897
|
+
op,
|
|
898
|
+
fromSnapshot,
|
|
899
|
+
undefined,
|
|
900
|
+
endReferenceSlidingPreference(stickiness),
|
|
901
|
+
);
|
|
783
902
|
const rangeProp = {
|
|
784
903
|
[reservedRangeLabelsKey]: [label],
|
|
785
904
|
};
|
|
786
905
|
startLref.addProperties(rangeProp);
|
|
787
906
|
endLref.addProperties(rangeProp);
|
|
788
907
|
|
|
789
|
-
const ival = new SequenceInterval(
|
|
908
|
+
const ival = new SequenceInterval(
|
|
909
|
+
client,
|
|
910
|
+
startLref,
|
|
911
|
+
endLref,
|
|
912
|
+
intervalType,
|
|
913
|
+
rangeProp,
|
|
914
|
+
stickiness,
|
|
915
|
+
);
|
|
790
916
|
return ival;
|
|
791
917
|
}
|
|
792
918
|
|
|
@@ -1041,7 +1167,7 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
|
|
|
1041
1167
|
public readonly overlappingIntervalsIndex: OverlappingIntervalsIndex<TInterval>;
|
|
1042
1168
|
public readonly idIntervalIndex: IdIntervalIndex<TInterval>;
|
|
1043
1169
|
public readonly endIntervalIndex: EndpointIndex<TInterval>;
|
|
1044
|
-
private readonly indexes: IntervalIndex<TInterval
|
|
1170
|
+
private readonly indexes: Set<IntervalIndex<TInterval>>;
|
|
1045
1171
|
|
|
1046
1172
|
constructor(
|
|
1047
1173
|
private readonly client: Client,
|
|
@@ -1056,11 +1182,11 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
|
|
|
1056
1182
|
this.overlappingIntervalsIndex = new OverlappingIntervalsIndex(client, helpers);
|
|
1057
1183
|
this.idIntervalIndex = new IdIntervalIndex();
|
|
1058
1184
|
this.endIntervalIndex = new EndpointIndex(client, helpers);
|
|
1059
|
-
this.indexes = [
|
|
1185
|
+
this.indexes = new Set([
|
|
1060
1186
|
this.overlappingIntervalsIndex,
|
|
1061
1187
|
this.idIntervalIndex,
|
|
1062
1188
|
this.endIntervalIndex,
|
|
1063
|
-
];
|
|
1189
|
+
]);
|
|
1064
1190
|
}
|
|
1065
1191
|
|
|
1066
1192
|
public createLegacyId(start: number, end: number): string {
|
|
@@ -1104,6 +1230,14 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
|
|
|
1104
1230
|
}
|
|
1105
1231
|
}
|
|
1106
1232
|
|
|
1233
|
+
public appendIndex(index: IntervalIndex<TInterval>) {
|
|
1234
|
+
this.indexes.add(index);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
public removeIndex(index: IntervalIndex<TInterval>): boolean {
|
|
1238
|
+
return this.indexes.delete(index);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1107
1241
|
public removeExistingInterval(interval: TInterval) {
|
|
1108
1242
|
this.removeIntervalFromIndexes(interval);
|
|
1109
1243
|
this.removeIntervalListeners(interval);
|
|
@@ -1114,8 +1248,18 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
|
|
|
1114
1248
|
end: number,
|
|
1115
1249
|
intervalType: IntervalType,
|
|
1116
1250
|
op?: ISequencedDocumentMessage,
|
|
1251
|
+
stickiness: IntervalStickiness = IntervalStickiness.END,
|
|
1117
1252
|
): TInterval {
|
|
1118
|
-
return this.helpers.create(
|
|
1253
|
+
return this.helpers.create(
|
|
1254
|
+
this.label,
|
|
1255
|
+
start,
|
|
1256
|
+
end,
|
|
1257
|
+
this.client,
|
|
1258
|
+
intervalType,
|
|
1259
|
+
op,
|
|
1260
|
+
undefined,
|
|
1261
|
+
stickiness,
|
|
1262
|
+
);
|
|
1119
1263
|
}
|
|
1120
1264
|
|
|
1121
1265
|
public addInterval(
|
|
@@ -1124,8 +1268,9 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
|
|
|
1124
1268
|
intervalType: IntervalType,
|
|
1125
1269
|
props?: PropertySet,
|
|
1126
1270
|
op?: ISequencedDocumentMessage,
|
|
1271
|
+
stickiness: IntervalStickiness = IntervalStickiness.END,
|
|
1127
1272
|
) {
|
|
1128
|
-
const interval: TInterval = this.createInterval(start, end, intervalType, op);
|
|
1273
|
+
const interval: TInterval = this.createInterval(start, end, intervalType, op, stickiness);
|
|
1129
1274
|
if (interval) {
|
|
1130
1275
|
if (!interval.properties) {
|
|
1131
1276
|
interval.properties = createMap<any>();
|
|
@@ -1201,6 +1346,7 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
|
|
|
1201
1346
|
ref.getOffset(),
|
|
1202
1347
|
ReferenceType.Transient,
|
|
1203
1348
|
ref.properties,
|
|
1349
|
+
ref.slidingPreference,
|
|
1204
1350
|
);
|
|
1205
1351
|
};
|
|
1206
1352
|
if (interval instanceof SequenceInterval) {
|
|
@@ -1249,12 +1395,13 @@ class SequenceIntervalCollectionFactory
|
|
|
1249
1395
|
public load(
|
|
1250
1396
|
emitter: IValueOpEmitter,
|
|
1251
1397
|
raw: ISerializedInterval[] | ISerializedIntervalCollectionV2 = [],
|
|
1398
|
+
options?: Partial<SequenceOptions>,
|
|
1252
1399
|
): IntervalCollection<SequenceInterval> {
|
|
1253
1400
|
const helpers: IIntervalHelpers<SequenceInterval> = {
|
|
1254
1401
|
compareEnds: compareSequenceIntervalEnds,
|
|
1255
1402
|
create: createSequenceInterval,
|
|
1256
1403
|
};
|
|
1257
|
-
return new IntervalCollection<SequenceInterval>(helpers, true, emitter, raw);
|
|
1404
|
+
return new IntervalCollection<SequenceInterval>(helpers, true, emitter, raw, options);
|
|
1258
1405
|
}
|
|
1259
1406
|
|
|
1260
1407
|
public store(
|
|
@@ -1289,7 +1436,15 @@ export class SequenceIntervalCollectionValueType
|
|
|
1289
1436
|
|
|
1290
1437
|
const compareIntervalEnds = (a: Interval, b: Interval) => a.end - b.end;
|
|
1291
1438
|
|
|
1292
|
-
function createInterval(
|
|
1439
|
+
function createInterval(
|
|
1440
|
+
label: string,
|
|
1441
|
+
start: number,
|
|
1442
|
+
end: number,
|
|
1443
|
+
client: Client,
|
|
1444
|
+
intervalType?: IntervalType,
|
|
1445
|
+
op?: ISequencedDocumentMessage,
|
|
1446
|
+
fromSnapshot?: boolean,
|
|
1447
|
+
): Interval {
|
|
1293
1448
|
const rangeProp: PropertySet = {};
|
|
1294
1449
|
|
|
1295
1450
|
if (label && label.length > 0) {
|
|
@@ -1303,12 +1458,13 @@ class IntervalCollectionFactory implements IValueFactory<IntervalCollection<Inte
|
|
|
1303
1458
|
public load(
|
|
1304
1459
|
emitter: IValueOpEmitter,
|
|
1305
1460
|
raw: ISerializedInterval[] | ISerializedIntervalCollectionV2 = [],
|
|
1461
|
+
options?: Partial<SequenceOptions>,
|
|
1306
1462
|
): IntervalCollection<Interval> {
|
|
1307
1463
|
const helpers: IIntervalHelpers<Interval> = {
|
|
1308
1464
|
compareEnds: compareIntervalEnds,
|
|
1309
1465
|
create: createInterval,
|
|
1310
1466
|
};
|
|
1311
|
-
const collection = new IntervalCollection<Interval>(helpers, false, emitter, raw);
|
|
1467
|
+
const collection = new IntervalCollection<Interval>(helpers, false, emitter, raw, options);
|
|
1312
1468
|
collection.attachGraph(undefined as any as Client, "");
|
|
1313
1469
|
return collection;
|
|
1314
1470
|
}
|
|
@@ -1355,7 +1511,7 @@ export function makeOpsMap<T extends ISerializableInterval>(): Map<
|
|
|
1355
1511
|
|
|
1356
1512
|
return new Map<string, IValueOperation<IntervalCollection<T>>>([
|
|
1357
1513
|
[
|
|
1358
|
-
|
|
1514
|
+
IntervalOpType.ADD,
|
|
1359
1515
|
{
|
|
1360
1516
|
process: (collection, params, local, op, localOpMetadata) => {
|
|
1361
1517
|
// if params is undefined, the interval was deleted during
|
|
@@ -1370,7 +1526,7 @@ export function makeOpsMap<T extends ISerializableInterval>(): Map<
|
|
|
1370
1526
|
},
|
|
1371
1527
|
],
|
|
1372
1528
|
[
|
|
1373
|
-
|
|
1529
|
+
IntervalOpType.DELETE,
|
|
1374
1530
|
{
|
|
1375
1531
|
process: (collection, params, local, op) => {
|
|
1376
1532
|
assert(op !== undefined, 0x3fc /* op should exist here */);
|
|
@@ -1383,7 +1539,7 @@ export function makeOpsMap<T extends ISerializableInterval>(): Map<
|
|
|
1383
1539
|
},
|
|
1384
1540
|
],
|
|
1385
1541
|
[
|
|
1386
|
-
|
|
1542
|
+
IntervalOpType.CHANGE,
|
|
1387
1543
|
{
|
|
1388
1544
|
process: (collection, params, local, op, localOpMetadata) => {
|
|
1389
1545
|
// if params is undefined, the interval was deleted during
|
|
@@ -1402,6 +1558,10 @@ export function makeOpsMap<T extends ISerializableInterval>(): Map<
|
|
|
1402
1558
|
|
|
1403
1559
|
export type DeserializeCallback = (properties: PropertySet) => void;
|
|
1404
1560
|
|
|
1561
|
+
/**
|
|
1562
|
+
* @deprecated - Public export will be removed. Use an appropriate iterator creation method on
|
|
1563
|
+
* {@link IIntervalCollection} to iterate intervals instead.
|
|
1564
|
+
*/
|
|
1405
1565
|
export class IntervalCollectionIterator<TInterval extends ISerializableInterval>
|
|
1406
1566
|
implements Iterator<TInterval>
|
|
1407
1567
|
{
|
|
@@ -1500,9 +1660,128 @@ export interface IIntervalCollectionEvent<TInterval extends ISerializableInterva
|
|
|
1500
1660
|
* This aligns with its usage in `SharedSegmentSequence`, which allows associating intervals to positions in the
|
|
1501
1661
|
* sequence DDS which are broadcast to all other clients in an eventually consistent fashion.
|
|
1502
1662
|
*/
|
|
1503
|
-
export
|
|
1504
|
-
IIntervalCollectionEvent<TInterval
|
|
1505
|
-
|
|
1663
|
+
export interface IIntervalCollection<TInterval extends ISerializableInterval>
|
|
1664
|
+
extends TypedEventEmitter<IIntervalCollectionEvent<TInterval>> {
|
|
1665
|
+
readonly attached: boolean;
|
|
1666
|
+
/**
|
|
1667
|
+
* Attaches an index to this collection.
|
|
1668
|
+
* All intervals which are part of this collection will be added to the index, and the index will automatically
|
|
1669
|
+
* be updated when this collection updates due to local or remote changes.
|
|
1670
|
+
*
|
|
1671
|
+
* @remarks - After attaching an index to an interval collection, applications should typically store this
|
|
1672
|
+
* index somewhere in their in-memory data model for future reference and querying.
|
|
1673
|
+
*/
|
|
1674
|
+
attachIndex(index: IntervalIndex<TInterval>): void;
|
|
1675
|
+
/**
|
|
1676
|
+
* Detaches an index from this collection.
|
|
1677
|
+
* All intervals which are part of this collection will be removed from the index, and updates to this collection
|
|
1678
|
+
* due to local or remote changes will no longer incur updates to the index.
|
|
1679
|
+
*
|
|
1680
|
+
* @returns - Return false if the target index cannot be found in the indexes, otherwise remove all intervals in the index and return true
|
|
1681
|
+
*/
|
|
1682
|
+
detachIndex(index: IntervalIndex<TInterval>): boolean;
|
|
1683
|
+
/**
|
|
1684
|
+
* @returns the interval in this collection that has the provided `id`.
|
|
1685
|
+
* If no interval in the collection has this `id`, returns `undefined`.
|
|
1686
|
+
*/
|
|
1687
|
+
getIntervalById(id: string): TInterval | undefined;
|
|
1688
|
+
/**
|
|
1689
|
+
* Creates a new interval and add it to the collection.
|
|
1690
|
+
* @param start - interval start position (inclusive)
|
|
1691
|
+
* @param end - interval end position (exclusive)
|
|
1692
|
+
* @param intervalType - type of the interval. All intervals are SlideOnRemove. Intervals may not be Transient.
|
|
1693
|
+
* @param props - properties of the interval
|
|
1694
|
+
* @returns - the created interval
|
|
1695
|
+
* @remarks - See documentation on {@link SequenceInterval} for comments on interval endpoint semantics: there are subtleties
|
|
1696
|
+
* with how the current half-open behavior is represented.
|
|
1697
|
+
*/
|
|
1698
|
+
add(start: number, end: number, intervalType: IntervalType, props?: PropertySet): TInterval;
|
|
1699
|
+
/**
|
|
1700
|
+
* Removes an interval from the collection.
|
|
1701
|
+
* @param id - Id of the interval to remove
|
|
1702
|
+
* @returns the removed interval
|
|
1703
|
+
*/
|
|
1704
|
+
removeIntervalById(id: string): TInterval | undefined;
|
|
1705
|
+
/**
|
|
1706
|
+
* Changes the properties on an existing interval.
|
|
1707
|
+
* @param id - Id of the interval whose properties should be changed
|
|
1708
|
+
* @param props - Property set to apply to the interval. Shallow merging is used between any existing properties
|
|
1709
|
+
* and `prop`, i.e. the interval will end up with a property object equivalent to `{ ...oldProps, ...props }`.
|
|
1710
|
+
*/
|
|
1711
|
+
changeProperties(id: string, props: PropertySet);
|
|
1712
|
+
/**
|
|
1713
|
+
* Changes the endpoints of an existing interval.
|
|
1714
|
+
* @param id - Id of the interval to change
|
|
1715
|
+
* @param start - New start value, if defined. `undefined` signifies this endpoint should be left unchanged.
|
|
1716
|
+
* @param end - New end value, if defined. `undefined` signifies this endpoint should be left unchanged.
|
|
1717
|
+
* @returns the interval that was changed, if it existed in the collection.
|
|
1718
|
+
*/
|
|
1719
|
+
change(id: string, start?: number, end?: number): TInterval | undefined;
|
|
1720
|
+
|
|
1721
|
+
attachDeserializer(onDeserialize: DeserializeCallback): void;
|
|
1722
|
+
/**
|
|
1723
|
+
* @returns an iterator over all intervals in this collection.
|
|
1724
|
+
*/
|
|
1725
|
+
[Symbol.iterator](): Iterator<TInterval>;
|
|
1726
|
+
|
|
1727
|
+
/**
|
|
1728
|
+
* @returns a forward iterator over all intervals in this collection with start point equal to `startPosition`.
|
|
1729
|
+
*/
|
|
1730
|
+
CreateForwardIteratorWithStartPosition(startPosition: number): Iterator<TInterval>;
|
|
1731
|
+
|
|
1732
|
+
/**
|
|
1733
|
+
* @returns a backward iterator over all intervals in this collection with start point equal to `startPosition`.
|
|
1734
|
+
*/
|
|
1735
|
+
CreateBackwardIteratorWithStartPosition(startPosition: number): Iterator<TInterval>;
|
|
1736
|
+
|
|
1737
|
+
/**
|
|
1738
|
+
* @returns a forward iterator over all intervals in this collection with end point equal to `endPosition`.
|
|
1739
|
+
*/
|
|
1740
|
+
CreateForwardIteratorWithEndPosition(endPosition: number): Iterator<TInterval>;
|
|
1741
|
+
|
|
1742
|
+
/**
|
|
1743
|
+
* @returns a backward iterator over all intervals in this collection with end point equal to `endPosition`.
|
|
1744
|
+
*/
|
|
1745
|
+
CreateBackwardIteratorWithEndPosition(endPosition: number): Iterator<TInterval>;
|
|
1746
|
+
|
|
1747
|
+
/**
|
|
1748
|
+
* Gathers iteration results that optionally match a start/end criteria into the provided array.
|
|
1749
|
+
* @param results - Array to gather the results into. In lieu of a return value, this array will be populated with
|
|
1750
|
+
* intervals matching the query upon edit.
|
|
1751
|
+
* @param iteratesForward - whether or not iteration should be in the forward direction
|
|
1752
|
+
* @param start - If provided, only match intervals whose start point is equal to `start`.
|
|
1753
|
+
* @param end - If provided, only match intervals whose end point is equal to `end`.
|
|
1754
|
+
*/
|
|
1755
|
+
gatherIterationResults(
|
|
1756
|
+
results: TInterval[],
|
|
1757
|
+
iteratesForward: boolean,
|
|
1758
|
+
start?: number,
|
|
1759
|
+
end?: number,
|
|
1760
|
+
): void;
|
|
1761
|
+
|
|
1762
|
+
/**
|
|
1763
|
+
* @returns an array of all intervals in this collection that overlap with the interval
|
|
1764
|
+
* `[startPosition, endPosition]`.
|
|
1765
|
+
*/
|
|
1766
|
+
findOverlappingIntervals(startPosition: number, endPosition: number): TInterval[];
|
|
1767
|
+
|
|
1768
|
+
/**
|
|
1769
|
+
* Applies a function to each interval in this collection.
|
|
1770
|
+
*/
|
|
1771
|
+
map(fn: (interval: TInterval) => void): void;
|
|
1772
|
+
|
|
1773
|
+
previousInterval(pos: number): TInterval | undefined;
|
|
1774
|
+
|
|
1775
|
+
nextInterval(pos: number): TInterval | undefined;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
/**
|
|
1779
|
+
* @deprecated - Use {@link IIntervalCollection} instead.
|
|
1780
|
+
*/
|
|
1781
|
+
export class IntervalCollection<TInterval extends ISerializableInterval>
|
|
1782
|
+
extends TypedEventEmitter<IIntervalCollectionEvent<TInterval>>
|
|
1783
|
+
implements IIntervalCollection<TInterval>
|
|
1784
|
+
{
|
|
1506
1785
|
private savedSerializedIntervals?: ISerializedInterval[];
|
|
1507
1786
|
private localCollection: LocalIntervalCollection<TInterval> | undefined;
|
|
1508
1787
|
private onDeserialize: DeserializeCallback | undefined;
|
|
@@ -1534,6 +1813,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1534
1813
|
private readonly requiresClient: boolean,
|
|
1535
1814
|
private readonly emitter: IValueOpEmitter,
|
|
1536
1815
|
serializedIntervals: ISerializedInterval[] | ISerializedIntervalCollectionV2,
|
|
1816
|
+
private readonly options: Partial<SequenceOptions> = {},
|
|
1537
1817
|
) {
|
|
1538
1818
|
super();
|
|
1539
1819
|
|
|
@@ -1544,6 +1824,40 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1544
1824
|
);
|
|
1545
1825
|
}
|
|
1546
1826
|
|
|
1827
|
+
/**
|
|
1828
|
+
* {@inheritdoc IIntervalCollection.attachIndex}
|
|
1829
|
+
*/
|
|
1830
|
+
public attachIndex(index: IntervalIndex<TInterval>): void {
|
|
1831
|
+
if (!this.attached) {
|
|
1832
|
+
throw new LoggingError("The local interval collection must exist");
|
|
1833
|
+
}
|
|
1834
|
+
for (const interval of this) {
|
|
1835
|
+
index.add(interval);
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
this.localCollection?.appendIndex(index);
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
/**
|
|
1842
|
+
* {@inheritdoc IIntervalCollection.detachIndex}
|
|
1843
|
+
*/
|
|
1844
|
+
public detachIndex(index: IntervalIndex<TInterval>): boolean {
|
|
1845
|
+
if (!this.attached) {
|
|
1846
|
+
throw new LoggingError("The local interval collection must exist");
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
// Avoid removing intervals if the index does not exist
|
|
1850
|
+
if (!this.localCollection?.removeIndex(index)) {
|
|
1851
|
+
return false;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
for (const interval of this) {
|
|
1855
|
+
index.remove(interval);
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
return true;
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1547
1861
|
private rebasePositionWithSegmentSlide(
|
|
1548
1862
|
pos: number,
|
|
1549
1863
|
seqNumberFrom: number,
|
|
@@ -1634,7 +1948,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1634
1948
|
if (this.savedSerializedIntervals) {
|
|
1635
1949
|
for (const serializedInterval of this.savedSerializedIntervals) {
|
|
1636
1950
|
this.localCollection.ensureSerializedId(serializedInterval);
|
|
1637
|
-
const { start, end, intervalType, properties } = serializedInterval;
|
|
1951
|
+
const { start, end, intervalType, properties, stickiness } = serializedInterval;
|
|
1638
1952
|
const interval = this.helpers.create(
|
|
1639
1953
|
label,
|
|
1640
1954
|
start,
|
|
@@ -1643,6 +1957,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1643
1957
|
intervalType,
|
|
1644
1958
|
undefined,
|
|
1645
1959
|
true,
|
|
1960
|
+
stickiness,
|
|
1646
1961
|
);
|
|
1647
1962
|
if (properties) {
|
|
1648
1963
|
interval.addProperties(properties);
|
|
@@ -1689,8 +2004,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1689
2004
|
}
|
|
1690
2005
|
|
|
1691
2006
|
/**
|
|
1692
|
-
* @
|
|
1693
|
-
* If no interval in the collection has this `id`, returns `undefined`.
|
|
2007
|
+
* {@inheritdoc IIntervalCollection.getIntervalById}
|
|
1694
2008
|
*/
|
|
1695
2009
|
public getIntervalById(id: string) {
|
|
1696
2010
|
if (!this.localCollection) {
|
|
@@ -1700,20 +2014,14 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1700
2014
|
}
|
|
1701
2015
|
|
|
1702
2016
|
/**
|
|
1703
|
-
*
|
|
1704
|
-
* @param start - interval start position (inclusive)
|
|
1705
|
-
* @param end - interval end position (exclusive)
|
|
1706
|
-
* @param intervalType - type of the interval. All intervals are SlideOnRemove. Intervals may not be Transient.
|
|
1707
|
-
* @param props - properties of the interval
|
|
1708
|
-
* @returns - the created interval
|
|
1709
|
-
* @remarks - See documentation on {@link SequenceInterval} for comments on interval endpoint semantics: there are subtleties
|
|
1710
|
-
* with how the current half-open behavior is represented.
|
|
2017
|
+
* {@inheritdoc IIntervalCollection.add}
|
|
1711
2018
|
*/
|
|
1712
2019
|
public add(
|
|
1713
2020
|
start: number,
|
|
1714
2021
|
end: number,
|
|
1715
2022
|
intervalType: IntervalType,
|
|
1716
2023
|
props?: PropertySet,
|
|
2024
|
+
stickiness: IntervalStickiness = IntervalStickiness.END,
|
|
1717
2025
|
): TInterval {
|
|
1718
2026
|
if (!this.localCollection) {
|
|
1719
2027
|
throw new LoggingError("attach must be called prior to adding intervals");
|
|
@@ -1721,12 +2029,19 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1721
2029
|
if (intervalType & IntervalType.Transient) {
|
|
1722
2030
|
throw new LoggingError("Can not add transient intervals");
|
|
1723
2031
|
}
|
|
2032
|
+
if (stickiness !== IntervalStickiness.END && !this.options.intervalStickinessEnabled) {
|
|
2033
|
+
throw new UsageError(
|
|
2034
|
+
"attempted to set interval stickiness without enabling `intervalStickinessEnabled` feature flag",
|
|
2035
|
+
);
|
|
2036
|
+
}
|
|
1724
2037
|
|
|
1725
2038
|
const interval: TInterval = this.localCollection.addInterval(
|
|
1726
2039
|
start,
|
|
1727
2040
|
end,
|
|
1728
2041
|
intervalType,
|
|
1729
2042
|
props,
|
|
2043
|
+
undefined,
|
|
2044
|
+
stickiness,
|
|
1730
2045
|
);
|
|
1731
2046
|
|
|
1732
2047
|
if (interval) {
|
|
@@ -1736,6 +2051,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1736
2051
|
properties: interval.properties,
|
|
1737
2052
|
sequenceNumber: this.client?.getCurrentSeq() ?? 0,
|
|
1738
2053
|
start,
|
|
2054
|
+
stickiness,
|
|
1739
2055
|
};
|
|
1740
2056
|
const localSeq = this.getNextLocalSeq();
|
|
1741
2057
|
this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
|
|
@@ -1776,9 +2092,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1776
2092
|
}
|
|
1777
2093
|
|
|
1778
2094
|
/**
|
|
1779
|
-
*
|
|
1780
|
-
* @param id - Id of the interval to remove
|
|
1781
|
-
* @returns the removed interval
|
|
2095
|
+
* {@inheritdoc IIntervalCollection.removeIntervalById}
|
|
1782
2096
|
*/
|
|
1783
2097
|
public removeIntervalById(id: string) {
|
|
1784
2098
|
if (!this.localCollection) {
|
|
@@ -1792,10 +2106,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1792
2106
|
}
|
|
1793
2107
|
|
|
1794
2108
|
/**
|
|
1795
|
-
*
|
|
1796
|
-
* @param id - Id of the interval whose properties should be changed
|
|
1797
|
-
* @param props - Property set to apply to the interval. Shallow merging is used between any existing properties
|
|
1798
|
-
* and `prop`, i.e. the interval will end up with a property object equivalent to `{ ...oldProps, ...props }`.
|
|
2109
|
+
* {@inheritdoc IIntervalCollection.changeProperties}
|
|
1799
2110
|
*/
|
|
1800
2111
|
public changeProperties(id: string, props: PropertySet) {
|
|
1801
2112
|
if (!this.attached) {
|
|
@@ -1829,11 +2140,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
1829
2140
|
}
|
|
1830
2141
|
|
|
1831
2142
|
/**
|
|
1832
|
-
*
|
|
1833
|
-
* @param id - Id of the interval to change
|
|
1834
|
-
* @param start - New start value, if defined. `undefined` signifies this endpoint should be left unchanged.
|
|
1835
|
-
* @param end - New end value, if defined. `undefined` signifies this endpoint should be left unchanged.
|
|
1836
|
-
* @returns the interval that was changed, if it existed in the collection.
|
|
2143
|
+
* {@inheritdoc IIntervalCollection.change}
|
|
1837
2144
|
*/
|
|
1838
2145
|
public change(id: string, start?: number, end?: number): TInterval | undefined {
|
|
1839
2146
|
if (!this.localCollection) {
|
|
@@ -2021,6 +2328,9 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2021
2328
|
}
|
|
2022
2329
|
}
|
|
2023
2330
|
|
|
2331
|
+
/**
|
|
2332
|
+
* {@inheritdoc IIntervalCollection.attachDeserializer}
|
|
2333
|
+
*/
|
|
2024
2334
|
public attachDeserializer(onDeserialize: DeserializeCallback): void {
|
|
2025
2335
|
// If no deserializer is specified can skip all processing work
|
|
2026
2336
|
if (!onDeserialize) {
|
|
@@ -2188,6 +2498,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2188
2498
|
newStart,
|
|
2189
2499
|
interval.start.refType,
|
|
2190
2500
|
op,
|
|
2501
|
+
startReferenceSlidingPreference(interval.stickiness),
|
|
2191
2502
|
);
|
|
2192
2503
|
if (props) {
|
|
2193
2504
|
interval.start.addProperties(props);
|
|
@@ -2205,6 +2516,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2205
2516
|
newEnd,
|
|
2206
2517
|
interval.end.refType,
|
|
2207
2518
|
op,
|
|
2519
|
+
endReferenceSlidingPreference(interval.stickiness),
|
|
2208
2520
|
);
|
|
2209
2521
|
if (props) {
|
|
2210
2522
|
interval.end.addProperties(props);
|
|
@@ -2253,6 +2565,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2253
2565
|
serializedInterval.intervalType,
|
|
2254
2566
|
serializedInterval.properties,
|
|
2255
2567
|
op,
|
|
2568
|
+
serializedInterval.stickiness,
|
|
2256
2569
|
);
|
|
2257
2570
|
|
|
2258
2571
|
if (interval) {
|
|
@@ -2310,7 +2623,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2310
2623
|
}
|
|
2311
2624
|
|
|
2312
2625
|
/**
|
|
2313
|
-
* @
|
|
2626
|
+
* {@inheritdoc IIntervalCollection.CreateForwardIteratorWithStartPosition}
|
|
2314
2627
|
*/
|
|
2315
2628
|
public CreateForwardIteratorWithStartPosition(
|
|
2316
2629
|
startPosition: number,
|
|
@@ -2320,7 +2633,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2320
2633
|
}
|
|
2321
2634
|
|
|
2322
2635
|
/**
|
|
2323
|
-
* @
|
|
2636
|
+
* {@inheritdoc IIntervalCollection.CreateBackwardIteratorWithStartPosition}
|
|
2324
2637
|
*/
|
|
2325
2638
|
public CreateBackwardIteratorWithStartPosition(
|
|
2326
2639
|
startPosition: number,
|
|
@@ -2330,7 +2643,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2330
2643
|
}
|
|
2331
2644
|
|
|
2332
2645
|
/**
|
|
2333
|
-
* @
|
|
2646
|
+
* {@inheritdoc IIntervalCollection.CreateForwardIteratorWithEndPosition}
|
|
2334
2647
|
*/
|
|
2335
2648
|
public CreateForwardIteratorWithEndPosition(
|
|
2336
2649
|
endPosition: number,
|
|
@@ -2345,7 +2658,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2345
2658
|
}
|
|
2346
2659
|
|
|
2347
2660
|
/**
|
|
2348
|
-
* @
|
|
2661
|
+
* {@inheritdoc IIntervalCollection.CreateBackwardIteratorWithEndPosition}
|
|
2349
2662
|
*/
|
|
2350
2663
|
public CreateBackwardIteratorWithEndPosition(
|
|
2351
2664
|
endPosition: number,
|
|
@@ -2360,12 +2673,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2360
2673
|
}
|
|
2361
2674
|
|
|
2362
2675
|
/**
|
|
2363
|
-
*
|
|
2364
|
-
* @param results - Array to gather the results into. In lieu of a return value, this array will be populated with
|
|
2365
|
-
* intervals matching the query upon edit.
|
|
2366
|
-
* @param iteratesForward - whether or not iteration should be in the forward direction
|
|
2367
|
-
* @param start - If provided, only match intervals whose start point is equal to `start`.
|
|
2368
|
-
* @param end - If provided, only match intervals whose end point is equal to `end`.
|
|
2676
|
+
* {@inheritdoc IIntervalCollection.gatherIterationResults}
|
|
2369
2677
|
*/
|
|
2370
2678
|
public gatherIterationResults(
|
|
2371
2679
|
results: TInterval[],
|
|
@@ -2386,8 +2694,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2386
2694
|
}
|
|
2387
2695
|
|
|
2388
2696
|
/**
|
|
2389
|
-
* @
|
|
2390
|
-
* `[startPosition, endPosition]`.
|
|
2697
|
+
* {@inheritdoc IIntervalCollection.findOverlappingIntervals}
|
|
2391
2698
|
*/
|
|
2392
2699
|
public findOverlappingIntervals(startPosition: number, endPosition: number): TInterval[] {
|
|
2393
2700
|
if (!this.localCollection) {
|
|
@@ -2401,7 +2708,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2401
2708
|
}
|
|
2402
2709
|
|
|
2403
2710
|
/**
|
|
2404
|
-
*
|
|
2711
|
+
* {@inheritdoc IIntervalCollection.map}
|
|
2405
2712
|
*/
|
|
2406
2713
|
public map(fn: (interval: TInterval) => void) {
|
|
2407
2714
|
if (!this.localCollection) {
|
|
@@ -2413,6 +2720,9 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2413
2720
|
}
|
|
2414
2721
|
}
|
|
2415
2722
|
|
|
2723
|
+
/**
|
|
2724
|
+
* {@inheritdoc IIntervalCollection.previousInterval}
|
|
2725
|
+
*/
|
|
2416
2726
|
public previousInterval(pos: number): TInterval | undefined {
|
|
2417
2727
|
if (!this.localCollection) {
|
|
2418
2728
|
throw new LoggingError("attachSequence must be called");
|
|
@@ -2421,6 +2731,9 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
|
|
|
2421
2731
|
return this.localCollection.endIntervalIndex.previousInterval(pos);
|
|
2422
2732
|
}
|
|
2423
2733
|
|
|
2734
|
+
/**
|
|
2735
|
+
* {@inheritdoc IIntervalCollection.nextInterval}
|
|
2736
|
+
*/
|
|
2424
2737
|
public nextInterval(pos: number): TInterval | undefined {
|
|
2425
2738
|
if (!this.localCollection) {
|
|
2426
2739
|
throw new LoggingError("attachSequence must be called");
|