diff --git a/packages/dds/sequence/src/intervalCollection.ts b/packages/dds/sequence/src/intervalCollection.ts index 73fce3f7f2f5..b2eb58d8cfa6 100644 --- a/packages/dds/sequence/src/intervalCollection.ts +++ b/packages/dds/sequence/src/intervalCollection.ts @@ -1630,6 +1630,7 @@ export class IntervalCollection private getSlideToSegment( lref: LocalReferencePosition, + slidingPreference: SlidingPreference, ): { segment: ISegment | undefined; offset: number | undefined } | undefined { if (!this.client) { throw new LoggingError("client does not exist"); @@ -1640,7 +1641,7 @@ export class IntervalCollection } const newSegoff = getSlideToSegoff( segoff, - undefined, + slidingPreference, this.options.mergeTreeReferencesCanSlideToEndpoint, ); const value: { segment: ISegment | undefined; offset: number | undefined } | undefined = @@ -1663,8 +1664,14 @@ export class IntervalCollection return; } - const newStart = this.getSlideToSegment(interval.start); - const newEnd = this.getSlideToSegment(interval.end); + const newStart = this.getSlideToSegment( + interval.start, + startReferenceSlidingPreference(interval.stickiness), + ); + const newEnd = this.getSlideToSegment( + interval.end, + endReferenceSlidingPreference(interval.stickiness), + ); const id = interval.properties[reservedIntervalIdKey]; const hasPendingStartChange = this.hasPendingChangeStart(id); diff --git a/packages/dds/sequence/src/intervals/sequenceInterval.ts b/packages/dds/sequence/src/intervals/sequenceInterval.ts index 2aff4997e4c6..928b50af66a9 100644 --- a/packages/dds/sequence/src/intervals/sequenceInterval.ts +++ b/packages/dds/sequence/src/intervals/sequenceInterval.ts @@ -509,7 +509,7 @@ function createPositionReference( referenceSequenceNumber: op.referenceSequenceNumber, clientId: op.clientId, }); - segoff = getSlideToSegoff(segoff, undefined, useNewSlidingBehavior); + segoff = getSlideToSegoff(segoff, slidingPreference, useNewSlidingBehavior); } } else { assert( diff --git a/packages/dds/sequence/src/test/intervalCollection.spec.ts b/packages/dds/sequence/src/test/intervalCollection.spec.ts index 5d160673a05a..91e0fe3ee311 100644 --- a/packages/dds/sequence/src/test/intervalCollection.spec.ts +++ b/packages/dds/sequence/src/test/intervalCollection.spec.ts @@ -560,7 +560,38 @@ describe("SharedString interval collections", () => { assertSequenceIntervals(sharedString, collection1, [{ start: 1, end: 2 }]); }); - it("can slide intervals on create ack", () => { + describe("respects interval slide preference on create", () => { + for (const { testName, side, expectedPos } of [ + { testName: "Side.Before -> prefer forward", side: Side.Before, expectedPos: 1 }, + { testName: "Side.After -> prefer backward", side: Side.After, expectedPos: 0 }, + ]) { + it(testName, () => { + const collection1 = sharedString.getIntervalCollection("test"); + sharedString.insertText(0, "ABCD"); + containerRuntimeFactory.processAllMessages(); + const collection2 = sharedString2.getIntervalCollection("test"); + sharedString.removeRange(1, 3); + + collection2.add({ + start: { pos: 1, side }, + end: { pos: 2, side }, + }); + + containerRuntimeFactory.processAllMessages(); + assert.strictEqual(sharedString.getText(), "AD"); + assert.strictEqual(sharedString2.getText(), "AD"); + + assertSequenceIntervals(sharedString, collection1, [ + { start: expectedPos, end: expectedPos }, + ]); + assertSequenceIntervals(sharedString2, collection2, [ + { start: expectedPos, end: expectedPos }, + ]); + }); + } + }); + + it("can slide intervals backward on create ack", () => { // Create and connect a third SharedString. const dataStoreRuntime3 = new MockFluidDataStoreRuntime({ clientId: "3" }); const containerRuntime3 =