@fluidframework/sequence 2.31.1 → 2.32.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 +4 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/intervalCollection.d.ts +5 -9
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +38 -104
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervalCollectionMap.d.ts.map +1 -1
- package/dist/intervalCollectionMap.js +5 -4
- package/dist/intervalCollectionMap.js.map +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.js +2 -2
- package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
- package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
- package/dist/intervalIndex/endpointIndex.js +2 -3
- package/dist/intervalIndex/endpointIndex.js.map +1 -1
- package/dist/intervalIndex/idIntervalIndex.d.ts.map +1 -1
- package/dist/intervalIndex/idIntervalIndex.js +0 -7
- package/dist/intervalIndex/idIntervalIndex.js.map +1 -1
- package/dist/intervalIndex/index.d.ts +0 -1
- package/dist/intervalIndex/index.d.ts.map +1 -1
- package/dist/intervalIndex/index.js +1 -3
- package/dist/intervalIndex/index.js.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.js +2 -2
- package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
- package/dist/intervalIndex/startpointInRangeIndex.js +2 -2
- package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
- package/dist/intervals/index.d.ts +2 -2
- package/dist/intervals/index.d.ts.map +1 -1
- package/dist/intervals/index.js +3 -1
- package/dist/intervals/index.js.map +1 -1
- package/dist/intervals/intervalUtils.d.ts +1 -5
- package/dist/intervals/intervalUtils.d.ts.map +1 -1
- package/dist/intervals/intervalUtils.js.map +1 -1
- package/dist/intervals/sequenceInterval.d.ts +20 -9
- package/dist/intervals/sequenceInterval.d.ts.map +1 -1
- package/dist/intervals/sequenceInterval.js +82 -27
- package/dist/intervals/sequenceInterval.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.map +1 -1
- package/dist/revertibles.js +8 -7
- package/dist/revertibles.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/intervalCollection.d.ts +5 -9
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +39 -105
- package/lib/intervalCollection.js.map +1 -1
- package/lib/intervalCollectionMap.d.ts.map +1 -1
- package/lib/intervalCollectionMap.js +6 -5
- package/lib/intervalCollectionMap.js.map +1 -1
- package/lib/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
- package/lib/intervalIndex/endpointInRangeIndex.js +3 -3
- package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -1
- package/lib/intervalIndex/endpointIndex.d.ts.map +1 -1
- package/lib/intervalIndex/endpointIndex.js +3 -4
- package/lib/intervalIndex/endpointIndex.js.map +1 -1
- package/lib/intervalIndex/idIntervalIndex.d.ts.map +1 -1
- package/lib/intervalIndex/idIntervalIndex.js +0 -7
- package/lib/intervalIndex/idIntervalIndex.js.map +1 -1
- package/lib/intervalIndex/index.d.ts +0 -1
- package/lib/intervalIndex/index.d.ts.map +1 -1
- package/lib/intervalIndex/index.js +0 -1
- package/lib/intervalIndex/index.js.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.js +3 -3
- package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
- package/lib/intervalIndex/startpointInRangeIndex.js +3 -3
- package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -1
- package/lib/intervals/index.d.ts +2 -2
- 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/intervalUtils.d.ts +1 -5
- package/lib/intervals/intervalUtils.d.ts.map +1 -1
- package/lib/intervals/intervalUtils.js.map +1 -1
- package/lib/intervals/sequenceInterval.d.ts +20 -9
- package/lib/intervals/sequenceInterval.d.ts.map +1 -1
- package/lib/intervals/sequenceInterval.js +81 -28
- package/lib/intervals/sequenceInterval.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.map +1 -1
- package/lib/revertibles.js +8 -7
- package/lib/revertibles.js.map +1 -1
- package/package.json +19 -18
- package/src/index.ts +0 -1
- package/src/intervalCollection.ts +59 -144
- package/src/intervalCollectionMap.ts +5 -5
- package/src/intervalIndex/endpointInRangeIndex.ts +3 -15
- package/src/intervalIndex/endpointIndex.ts +3 -17
- package/src/intervalIndex/idIntervalIndex.ts +0 -7
- package/src/intervalIndex/index.ts +0 -1
- package/src/intervalIndex/overlappingIntervalsIndex.ts +3 -12
- package/src/intervalIndex/startpointInRangeIndex.ts +3 -15
- package/src/intervals/index.ts +2 -1
- package/src/intervals/intervalUtils.ts +0 -7
- package/src/intervals/sequenceInterval.ts +124 -33
- package/src/packageVersion.ts +1 -1
- package/src/revertibles.ts +8 -7
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +0 -11
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +0 -1
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js +0 -38
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js.map +0 -1
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +0 -11
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +0 -1
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js +0 -34
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js.map +0 -1
- package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +0 -80
|
@@ -5,12 +5,11 @@
|
|
|
5
5
|
/* eslint-disable no-bitwise */
|
|
6
6
|
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
7
7
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
8
|
-
import { DetachedReferencePosition, ReferenceType, SlidingPreference,
|
|
8
|
+
import { DetachedReferencePosition, ReferenceType, SlidingPreference, getSlideToSegoff, refTypeIncludesFlag, reservedRangeLabelsKey, Side, endpointPosAndSide, createLocalReconnectingPerspective, } from "@fluidframework/merge-tree/internal";
|
|
9
9
|
import { LoggingError, UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
10
10
|
import { v4 as uuid } from "uuid";
|
|
11
11
|
import { createIdIntervalIndex, EndpointIndex, OverlappingIntervalsIndex, } from "./intervalIndex/index.js";
|
|
12
|
-
import { IntervalDeltaOpType, IntervalStickiness, IntervalType, createPositionReferenceFromSegoff, createSequenceInterval, endReferenceSlidingPreference, startReferenceSlidingPreference, } from "./intervals/index.js";
|
|
13
|
-
export const reservedIntervalIdKey = "intervalId";
|
|
12
|
+
import { IntervalDeltaOpType, IntervalStickiness, IntervalType, createPositionReferenceFromSegoff, createSequenceInterval, endReferenceSlidingPreference, getSerializedProperties, startReferenceSlidingPreference, } from "./intervals/index.js";
|
|
14
13
|
export function sidesFromStickiness(stickiness) {
|
|
15
14
|
const startSide = (stickiness & IntervalStickiness.START) !== 0 ? Side.After : Side.Before;
|
|
16
15
|
const endSide = (stickiness & IntervalStickiness.END) !== 0 ? Side.Before : Side.After;
|
|
@@ -88,11 +87,6 @@ export class LocalIntervalCollection {
|
|
|
88
87
|
this.endIntervalIndex,
|
|
89
88
|
]);
|
|
90
89
|
}
|
|
91
|
-
createLegacyId(start, end) {
|
|
92
|
-
// Create a non-unique ID based on start and end to be used on intervals that come from legacy clients
|
|
93
|
-
// without ID's.
|
|
94
|
-
return `${LocalIntervalCollection.legacyIdPrefix}${start}-${end}`;
|
|
95
|
-
}
|
|
96
90
|
/**
|
|
97
91
|
* Validates that a serialized interval has the ID property. Creates an ID
|
|
98
92
|
* if one does not already exist
|
|
@@ -100,26 +94,6 @@ export class LocalIntervalCollection {
|
|
|
100
94
|
* @param serializedInterval - The interval to be checked
|
|
101
95
|
* @returns The interval's existing or newly created id
|
|
102
96
|
*/
|
|
103
|
-
ensureSerializedId(serializedInterval) {
|
|
104
|
-
let id = serializedInterval.properties?.[reservedIntervalIdKey];
|
|
105
|
-
if (id === undefined) {
|
|
106
|
-
// Back-compat: 0.39 and earlier did not have IDs on intervals. If an interval from such a client
|
|
107
|
-
// comes over the wire, create a non-unique one based on start/end.
|
|
108
|
-
// This will allow all clients to refer to this interval consistently.
|
|
109
|
-
id = this.createLegacyId(serializedInterval.start, serializedInterval.end);
|
|
110
|
-
const newProps = {
|
|
111
|
-
[reservedIntervalIdKey]: id,
|
|
112
|
-
};
|
|
113
|
-
serializedInterval.properties = addProperties(serializedInterval.properties, newProps);
|
|
114
|
-
}
|
|
115
|
-
// Make the ID immutable for safety's sake.
|
|
116
|
-
Object.defineProperty(serializedInterval.properties, reservedIntervalIdKey, {
|
|
117
|
-
configurable: false,
|
|
118
|
-
enumerable: true,
|
|
119
|
-
writable: false,
|
|
120
|
-
});
|
|
121
|
-
return id;
|
|
122
|
-
}
|
|
123
97
|
removeIntervalFromIndexes(interval) {
|
|
124
98
|
for (const index of this.indexes) {
|
|
125
99
|
index.remove(interval);
|
|
@@ -135,28 +109,16 @@ export class LocalIntervalCollection {
|
|
|
135
109
|
this.removeIntervalFromIndexes(interval);
|
|
136
110
|
this.removeIntervalListeners(interval);
|
|
137
111
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
interval.properties = createMap();
|
|
146
|
-
}
|
|
147
|
-
if (props) {
|
|
148
|
-
// This check is intended to prevent scenarios where a random interval is created and then
|
|
149
|
-
// inserted into a collection. The aim is to ensure that the collection is created first
|
|
150
|
-
// then the user can create/add intervals based on the collection
|
|
151
|
-
if (props[reservedRangeLabelsKey] !== undefined &&
|
|
152
|
-
props[reservedRangeLabelsKey][0] !== this.label) {
|
|
153
|
-
throw new LoggingError("Adding an interval that belongs to another interval collection is not permitted");
|
|
154
|
-
}
|
|
155
|
-
interval.properties = addProperties(interval.properties, props);
|
|
156
|
-
}
|
|
157
|
-
interval.properties[reservedIntervalIdKey] ??= uuid();
|
|
158
|
-
this.add(interval);
|
|
112
|
+
addInterval(id, start, end, props, op) {
|
|
113
|
+
// This check is intended to prevent scenarios where a random interval is created and then
|
|
114
|
+
// inserted into a collection. The aim is to ensure that the collection is created first
|
|
115
|
+
// then the user can create/add intervals based on the collection
|
|
116
|
+
if (props?.[reservedRangeLabelsKey] !== undefined &&
|
|
117
|
+
props[reservedRangeLabelsKey][0] !== this.label) {
|
|
118
|
+
throw new LoggingError("Adding an interval that belongs to another interval collection is not permitted");
|
|
159
119
|
}
|
|
120
|
+
const interval = createSequenceInterval(this.label, id, start, end, this.client, IntervalType.SlideOnRemove, op, undefined, this.options.mergeTreeReferencesCanSlideToEndpoint, props);
|
|
121
|
+
this.add(interval);
|
|
160
122
|
return interval;
|
|
161
123
|
}
|
|
162
124
|
linkEndpointsToInterval(interval) {
|
|
@@ -227,7 +189,6 @@ export class LocalIntervalCollection {
|
|
|
227
189
|
interval.removePositionChangeListeners();
|
|
228
190
|
}
|
|
229
191
|
}
|
|
230
|
-
LocalIntervalCollection.legacyIdPrefix = "legacy";
|
|
231
192
|
const rebase = (collection, op, localOpMetadata) => {
|
|
232
193
|
const { localSeq } = localOpMetadata;
|
|
233
194
|
const rebasedValue = collection.rebaseLocalInterval(op.opName, op.value, localSeq);
|
|
@@ -353,7 +314,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
353
314
|
}, localSeq);
|
|
354
315
|
// if segment is undefined, it slid off the string
|
|
355
316
|
assert(segment !== undefined, 0x54e /* No segment found */);
|
|
356
|
-
const segoff = getSlideToSegoff({ segment, offset }, undefined, this.options.mergeTreeReferencesCanSlideToEndpoint) ?? segment;
|
|
317
|
+
const segoff = getSlideToSegoff({ segment, offset }, undefined, createLocalReconnectingPerspective(this.client.getCurrentSeq(), clientId, localSeq), this.options.mergeTreeReferencesCanSlideToEndpoint) ?? segment;
|
|
357
318
|
// case happens when rebasing op, but concurrently entire string has been deleted
|
|
358
319
|
if (segoff.segment === undefined || segoff.offset === undefined) {
|
|
359
320
|
return DetachedReferencePosition;
|
|
@@ -394,18 +355,15 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
394
355
|
this.localCollection = new LocalIntervalCollection(client, label, this.options, (interval, previousInterval) => this.emitChange(interval, previousInterval, true, true));
|
|
395
356
|
if (this.savedSerializedIntervals) {
|
|
396
357
|
for (const serializedInterval of this.savedSerializedIntervals) {
|
|
397
|
-
|
|
398
|
-
const { start: startPos, end: endPos, intervalType,
|
|
358
|
+
const { id, properties } = getSerializedProperties(serializedInterval);
|
|
359
|
+
const { start: startPos, end: endPos, intervalType, startSide, endSide, } = serializedInterval;
|
|
399
360
|
const start = typeof startPos === "number" && startSide !== undefined
|
|
400
361
|
? { pos: startPos, side: startSide }
|
|
401
362
|
: startPos;
|
|
402
363
|
const end = typeof endPos === "number" && endSide !== undefined
|
|
403
364
|
? { pos: endPos, side: endSide }
|
|
404
365
|
: endPos;
|
|
405
|
-
const interval = createSequenceInterval(label, start, end, client, intervalType, undefined, true, this.options.mergeTreeReferencesCanSlideToEndpoint);
|
|
406
|
-
if (properties) {
|
|
407
|
-
interval.properties = addProperties(interval.properties, properties);
|
|
408
|
-
}
|
|
366
|
+
const interval = createSequenceInterval(label, id, start, end, client, intervalType, undefined, true, this.options.mergeTreeReferencesCanSlideToEndpoint, properties);
|
|
409
367
|
this.localCollection.add(interval);
|
|
410
368
|
}
|
|
411
369
|
}
|
|
@@ -451,7 +409,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
451
409
|
/**
|
|
452
410
|
* {@inheritdoc IIntervalCollection.add}
|
|
453
411
|
*/
|
|
454
|
-
add({ start, end, props, }) {
|
|
412
|
+
add({ id, start, end, props, }) {
|
|
455
413
|
if (!this.localCollection) {
|
|
456
414
|
throw new LoggingError("attach must be called prior to adding intervals");
|
|
457
415
|
}
|
|
@@ -460,24 +418,14 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
460
418
|
endPos !== undefined &&
|
|
461
419
|
startSide !== undefined &&
|
|
462
420
|
endSide !== undefined, 0x793 /* start and end cannot be undefined because they were not passed in as undefined */);
|
|
463
|
-
const stickiness = computeStickinessFromSide(startPos, startSide, endPos, endSide);
|
|
464
421
|
this.assertStickinessEnabled(start, end);
|
|
465
|
-
const interval = this.localCollection.addInterval(toSequencePlace(startPos, startSide), toSequencePlace(endPos, endSide),
|
|
422
|
+
const interval = this.localCollection.addInterval(id ?? uuid(), toSequencePlace(startPos, startSide), toSequencePlace(endPos, endSide), props);
|
|
466
423
|
if (interval) {
|
|
467
424
|
if (!this.isCollaborating) {
|
|
468
425
|
setSlideOnRemove(interval.start);
|
|
469
426
|
setSlideOnRemove(interval.end);
|
|
470
427
|
}
|
|
471
|
-
const serializedInterval =
|
|
472
|
-
start: startPos,
|
|
473
|
-
end: endPos,
|
|
474
|
-
intervalType: IntervalType.SlideOnRemove,
|
|
475
|
-
properties: { ...interval.properties },
|
|
476
|
-
sequenceNumber: this.client?.getCurrentSeq() ?? 0,
|
|
477
|
-
stickiness,
|
|
478
|
-
startSide,
|
|
479
|
-
endSide,
|
|
480
|
-
};
|
|
428
|
+
const serializedInterval = interval.serialize();
|
|
481
429
|
const localSeq = this.getNextLocalSeq();
|
|
482
430
|
if (this.isCollaborating) {
|
|
483
431
|
this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
|
|
@@ -554,29 +502,21 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
554
502
|
let deltaProps;
|
|
555
503
|
let newInterval;
|
|
556
504
|
if (props !== undefined) {
|
|
557
|
-
interval.
|
|
558
|
-
deltaProps = interval.propertyManager.handleProperties({ props }, interval, this.isCollaborating ? UnassignedSequenceNumber : UniversalSequenceNumber, UniversalSequenceNumber, true);
|
|
505
|
+
deltaProps = interval.changeProperties(props);
|
|
559
506
|
}
|
|
560
|
-
|
|
507
|
+
const changeEndpoints = start !== undefined && end !== undefined;
|
|
508
|
+
if (changeEndpoints) {
|
|
561
509
|
newInterval = this.localCollection.changeInterval(interval, start, end);
|
|
562
510
|
if (!this.isCollaborating && newInterval !== undefined) {
|
|
563
511
|
setSlideOnRemove(newInterval.start);
|
|
564
512
|
setSlideOnRemove(newInterval.end);
|
|
565
513
|
}
|
|
566
514
|
}
|
|
567
|
-
const serializedInterval = interval.serialize();
|
|
568
|
-
const { startPos, startSide, endPos, endSide } = endpointPosAndSide(start, end);
|
|
569
|
-
const stickiness = computeStickinessFromSide(startPos, startSide, endPos, endSide);
|
|
570
|
-
serializedInterval.start = startPos;
|
|
571
|
-
serializedInterval.end = endPos;
|
|
572
|
-
serializedInterval.startSide = startSide;
|
|
573
|
-
serializedInterval.endSide = endSide;
|
|
574
|
-
serializedInterval.stickiness = stickiness;
|
|
575
515
|
// Emit a property bag containing the ID and the other (if any) properties changed
|
|
576
|
-
serializedInterval
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
};
|
|
516
|
+
const serializedInterval = (newInterval ?? interval).serializeDelta({
|
|
517
|
+
props,
|
|
518
|
+
includeEndpoints: changeEndpoints,
|
|
519
|
+
});
|
|
580
520
|
const localSeq = this.getNextLocalSeq();
|
|
581
521
|
if (this.isCollaborating) {
|
|
582
522
|
this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
|
|
@@ -626,7 +566,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
626
566
|
}
|
|
627
567
|
removePendingChange(serializedInterval) {
|
|
628
568
|
// Change ops always have an ID.
|
|
629
|
-
const id = serializedInterval
|
|
569
|
+
const { id } = getSerializedProperties(serializedInterval);
|
|
630
570
|
if (serializedInterval.start !== undefined) {
|
|
631
571
|
this.removePendingChangeHelper(id, this.pendingChangesStart, serializedInterval);
|
|
632
572
|
}
|
|
@@ -668,7 +608,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
668
608
|
// Note that the ID is in the property bag only to allow us to find the interval.
|
|
669
609
|
// This API cannot change the ID, and writing to the ID property will result in an exception. So we
|
|
670
610
|
// strip it out of the properties here.
|
|
671
|
-
const {
|
|
611
|
+
const { id, properties } = getSerializedProperties(serializedInterval);
|
|
672
612
|
assert(id !== undefined, 0x3fe /* id must exist on the interval */);
|
|
673
613
|
const interval = this.getIntervalById(id);
|
|
674
614
|
if (!interval) {
|
|
@@ -676,11 +616,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
676
616
|
return;
|
|
677
617
|
}
|
|
678
618
|
if (local) {
|
|
679
|
-
interval.
|
|
680
|
-
// Let the propertyManager prune its pending change-properties set.
|
|
681
|
-
interval.propertyManager.ack(op.sequenceNumber, op.minimumSequenceNumber, {
|
|
682
|
-
props: newProps,
|
|
683
|
-
});
|
|
619
|
+
interval.ackPropertiesChange(properties, op);
|
|
684
620
|
this.ackInterval(interval, op);
|
|
685
621
|
}
|
|
686
622
|
else {
|
|
@@ -702,15 +638,14 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
702
638
|
newInterval =
|
|
703
639
|
this.localCollection.changeInterval(interval, toOptionalSequencePlace(start, serializedInterval.startSide ?? Side.Before), toOptionalSequencePlace(end, serializedInterval.endSide ?? Side.Before), op) ?? interval;
|
|
704
640
|
}
|
|
705
|
-
|
|
706
|
-
const deltaProps = newInterval.propertyManager.handleProperties({ props: newProps }, newInterval, op.sequenceNumber, op.minimumSequenceNumber, true);
|
|
641
|
+
const deltaProps = newInterval.changeProperties(properties, op);
|
|
707
642
|
if (this.onDeserialize) {
|
|
708
643
|
this.onDeserialize(newInterval);
|
|
709
644
|
}
|
|
710
645
|
if (newInterval !== interval) {
|
|
711
646
|
this.emitChange(newInterval, interval, local, false, op);
|
|
712
647
|
}
|
|
713
|
-
const changedProperties = Object.keys(
|
|
648
|
+
const changedProperties = Object.keys(properties).length > 0;
|
|
714
649
|
if (changedProperties) {
|
|
715
650
|
this.emit("propertyChanged", interval, deltaProps, local, op);
|
|
716
651
|
this.emit("changed", interval, deltaProps, undefined, local, false);
|
|
@@ -747,9 +682,9 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
747
682
|
throw new LoggingError("attachSequence must be called");
|
|
748
683
|
}
|
|
749
684
|
const { intervalType, properties, stickiness, startSide, endSide } = serializedInterval;
|
|
685
|
+
const { id } = getSerializedProperties(serializedInterval);
|
|
750
686
|
const { start: startRebased, end: endRebased } = this.localSeqToRebasedInterval.get(localSeq) ?? this.computeRebasedPositions(localSeq);
|
|
751
|
-
const
|
|
752
|
-
const localInterval = this.localCollection?.idIntervalIndex.getIntervalById(intervalId);
|
|
687
|
+
const localInterval = this.localCollection?.idIntervalIndex.getIntervalById(id);
|
|
753
688
|
const rebased = {
|
|
754
689
|
start: startRebased,
|
|
755
690
|
end: endRebased,
|
|
@@ -762,9 +697,9 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
762
697
|
};
|
|
763
698
|
if (opName === "change" &&
|
|
764
699
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- ?? is not logically equivalent when .hasPendingChangeStart returns false.
|
|
765
|
-
(this.hasPendingChangeStart(
|
|
700
|
+
(this.hasPendingChangeStart(id) || this.hasPendingChangeEnd(id))) {
|
|
766
701
|
this.removePendingChange(serializedInterval);
|
|
767
|
-
this.addPendingChange(
|
|
702
|
+
this.addPendingChange(id, rebased);
|
|
768
703
|
}
|
|
769
704
|
// if the interval slid off the string, rebase the op to be a noop and delete the interval.
|
|
770
705
|
if (!this.options.mergeTreeReferencesCanSlideToEndpoint &&
|
|
@@ -792,7 +727,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
792
727
|
if (segoff.segment?.localRefs?.has(lref) !== true) {
|
|
793
728
|
return undefined;
|
|
794
729
|
}
|
|
795
|
-
const newSegoff = getSlideToSegoff(segoff, slidingPreference, this.options.mergeTreeReferencesCanSlideToEndpoint);
|
|
730
|
+
const newSegoff = getSlideToSegoff(segoff, slidingPreference, undefined, this.options.mergeTreeReferencesCanSlideToEndpoint);
|
|
796
731
|
const value = segoff.segment === newSegoff.segment && segoff.offset === newSegoff.offset
|
|
797
732
|
? undefined
|
|
798
733
|
: newSegoff;
|
|
@@ -805,7 +740,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
805
740
|
}
|
|
806
741
|
const newStart = this.getSlideToSegment(interval.start, startReferenceSlidingPreference(interval.stickiness));
|
|
807
742
|
const newEnd = this.getSlideToSegment(interval.end, endReferenceSlidingPreference(interval.stickiness));
|
|
808
|
-
const id = interval.
|
|
743
|
+
const id = interval.getIntervalId();
|
|
809
744
|
const hasPendingStartChange = this.hasPendingChangeStart(id);
|
|
810
745
|
const hasPendingEndChange = this.hasPendingChangeEnd(id);
|
|
811
746
|
if (!hasPendingStartChange) {
|
|
@@ -858,10 +793,10 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
858
793
|
}
|
|
859
794
|
}
|
|
860
795
|
ackAdd(serializedInterval, local, op, localOpMetadata) {
|
|
796
|
+
const { id, properties } = getSerializedProperties(serializedInterval);
|
|
861
797
|
if (local) {
|
|
862
798
|
assert(localOpMetadata !== undefined, 0x553 /* op metadata should be defined for local op */);
|
|
863
799
|
this.localSeqToSerializedInterval.delete(localOpMetadata.localSeq);
|
|
864
|
-
const id = serializedInterval.properties?.[reservedIntervalIdKey];
|
|
865
800
|
const localInterval = this.getIntervalById(id);
|
|
866
801
|
if (localInterval) {
|
|
867
802
|
this.ackInterval(localInterval, op);
|
|
@@ -871,8 +806,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
871
806
|
if (!this.localCollection) {
|
|
872
807
|
throw new LoggingError("attachSequence must be called");
|
|
873
808
|
}
|
|
874
|
-
this.localCollection.
|
|
875
|
-
const interval = this.localCollection.addInterval(toSequencePlace(serializedInterval.start, serializedInterval.startSide ?? Side.Before), toSequencePlace(serializedInterval.end, serializedInterval.endSide ?? Side.Before), serializedInterval.intervalType, serializedInterval.properties, op);
|
|
809
|
+
const interval = this.localCollection.addInterval(id, toSequencePlace(serializedInterval.start, serializedInterval.startSide ?? Side.Before), toSequencePlace(serializedInterval.end, serializedInterval.endSide ?? Side.Before), properties, op);
|
|
876
810
|
if (interval) {
|
|
877
811
|
if (this.onDeserialize) {
|
|
878
812
|
this.onDeserialize(interval);
|
|
@@ -891,7 +825,7 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
891
825
|
if (!this.localCollection) {
|
|
892
826
|
throw new LoggingError("attach must be called prior to deleting intervals");
|
|
893
827
|
}
|
|
894
|
-
const id =
|
|
828
|
+
const { id } = getSerializedProperties(serializedInterval);
|
|
895
829
|
const interval = this.localCollection.idIntervalIndex.getIntervalById(id);
|
|
896
830
|
if (interval) {
|
|
897
831
|
this.deleteExistingInterval(interval, local, op);
|