@fluidframework/merge-tree 2.41.0 → 2.42.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/client.d.ts +6 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +71 -25
- package/dist/client.js.map +1 -1
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +6 -1
- package/dist/constants.js.map +1 -1
- package/dist/mergeTree.js +1 -1
- package/dist/mergeTree.js.map +1 -1
- package/dist/perspective.d.ts +15 -0
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +25 -1
- package/dist/perspective.js.map +1 -1
- package/dist/stamps.d.ts +1 -0
- package/dist/stamps.d.ts.map +1 -1
- package/dist/stamps.js +5 -1
- package/dist/stamps.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +4 -4
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.d.ts.map +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js +3 -3
- package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/dist/test/client.reconnectFarm.spec.js +1 -1
- package/dist/test/client.reconnectFarm.spec.js.map +1 -1
- package/dist/test/client.searchForMarker.spec.js +2 -2
- package/dist/test/client.searchForMarker.spec.js.map +1 -1
- package/dist/test/clientTestHelper.js +1 -1
- package/dist/test/clientTestHelper.js.map +1 -1
- package/dist/test/resetPendingSegmentsToOp.spec.js +10 -10
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/lib/client.d.ts +6 -3
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +73 -27
- package/lib/client.js.map +1 -1
- package/lib/constants.d.ts +5 -0
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +5 -0
- package/lib/constants.js.map +1 -1
- package/lib/mergeTree.js +1 -1
- package/lib/mergeTree.js.map +1 -1
- package/lib/perspective.d.ts +15 -0
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +23 -0
- package/lib/perspective.js.map +1 -1
- package/lib/stamps.d.ts +1 -0
- package/lib/stamps.d.ts.map +1 -1
- package/lib/stamps.js +4 -1
- package/lib/stamps.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +4 -4
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.d.ts.map +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js +3 -3
- package/lib/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/lib/test/client.reconnectFarm.spec.js +1 -1
- package/lib/test/client.reconnectFarm.spec.js.map +1 -1
- package/lib/test/client.searchForMarker.spec.js +2 -2
- package/lib/test/client.searchForMarker.spec.js.map +1 -1
- package/lib/test/clientTestHelper.js +1 -1
- package/lib/test/clientTestHelper.js.map +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js +10 -10
- package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/package.json +16 -16
- package/src/client.ts +95 -30
- package/src/constants.ts +6 -0
- package/src/mergeTree.ts +1 -1
- package/src/perspective.ts +26 -0
- package/src/stamps.ts +9 -1
package/lib/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,KAAK,qBAAqB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE3F,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAEN,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAErF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EACN,mBAAmB,EAGnB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAG1F,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAKN,KAAK,yBAAyB,EAC9B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACX,2BAA2B,EAC3B,qBAAqB,EACrB,iCAAiC,EACjC,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACN,mBAAmB,EACnB,QAAQ,EACR,cAAc,EAEd,MAAM,EAMN,MAAM,qBAAqB,CAAC;AAW7B,OAAO,EACN,YAAY,EACZ,qBAAqB,EAGrB,kBAAkB,EAClB,mBAAmB,EAEnB,uBAAuB,EACvB,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EAEjB,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/lib/client.js
CHANGED
|
@@ -10,14 +10,14 @@ import { toDeltaManagerInternal } from "@fluidframework/runtime-utils/internal";
|
|
|
10
10
|
import { LoggingError, UsageError, } from "@fluidframework/telemetry-utils/internal";
|
|
11
11
|
import { MergeTreeTextHelper } from "./MergeTreeTextHelper.js";
|
|
12
12
|
import { RedBlackTree } from "./collections/index.js";
|
|
13
|
-
import { NonCollabClient, UniversalSequenceNumber } from "./constants.js";
|
|
13
|
+
import { NonCollabClient, SquashClient, UniversalSequenceNumber } from "./constants.js";
|
|
14
14
|
import { SlidingPreference } from "./localReference.js";
|
|
15
15
|
import { MergeTree, errorIfOptionNotTrue, getSlideToSegoff, isRemovedAndAcked, } from "./mergeTree.js";
|
|
16
16
|
import { walkAllChildSegments } from "./mergeTreeNodeWalk.js";
|
|
17
17
|
import { compareStrings, isSegmentLeaf, } from "./mergeTreeNodes.js";
|
|
18
18
|
import { createAdjustRangeOp, createAnnotateMarkerOp, createAnnotateRangeOp, createGroupOp, createInsertSegmentOp, createObliterateRangeOp, createObliterateRangeOpSided, createRemoveRangeOp, } from "./opBuilder.js";
|
|
19
19
|
import { MergeTreeDeltaType, ReferenceType, } from "./ops.js";
|
|
20
|
-
import { LocalReconnectingPerspective, PriorPerspective, } from "./perspective.js";
|
|
20
|
+
import { LocalReconnectingPerspective, LocalSquashPerspective, PriorPerspective, } from "./perspective.js";
|
|
21
21
|
import { DetachedReferencePosition } from "./referencePositions.js";
|
|
22
22
|
import { isInserted, isRemoved, overwriteInfo, toRemovalInfo, } from "./segmentInfos.js";
|
|
23
23
|
import { Side } from "./sequencePlace.js";
|
|
@@ -186,8 +186,10 @@ export class Client extends TypedEventEmitter {
|
|
|
186
186
|
}
|
|
187
187
|
return this.insertSegmentLocal(pos, segment);
|
|
188
188
|
}
|
|
189
|
-
walkSegments(handler, start, end, accum, splitRange = false) {
|
|
190
|
-
this._mergeTree.mapRange(handler,
|
|
189
|
+
walkSegments(handler, start, end, accum, splitRange = false, perspective) {
|
|
190
|
+
this._mergeTree.mapRange(handler, perspective === undefined
|
|
191
|
+
? this.getCollabWindow().localPerspective
|
|
192
|
+
: this.getOperationPerspective(perspective), accum, start, end, splitRange);
|
|
191
193
|
}
|
|
192
194
|
walkAllSegments(action, accum) {
|
|
193
195
|
return walkAllChildSegments(this._mergeTree.root, accum === undefined ? action : (seg) => action(seg, accum));
|
|
@@ -566,9 +568,9 @@ export class Client extends TypedEventEmitter {
|
|
|
566
568
|
: Side.After;
|
|
567
569
|
return { segment: newSegment, offset: newOffset, side: newSide };
|
|
568
570
|
}
|
|
569
|
-
computeNewObliterateEndpoints(obliterateInfo) {
|
|
571
|
+
computeNewObliterateEndpoints(obliterateInfo, squash) {
|
|
570
572
|
const { currentSeq, clientId } = this.getCollabWindow();
|
|
571
|
-
const reconnectingPerspective = new LocalReconnectingPerspective(currentSeq, clientId, obliterateInfo.stamp.localSeq - 1);
|
|
573
|
+
const reconnectingPerspective = new (squash ? LocalSquashPerspective : LocalReconnectingPerspective)(currentSeq, clientId, obliterateInfo.stamp.localSeq - 1);
|
|
572
574
|
const newStart = this.rebaseSidedLocalReference(obliterateInfo.start, obliterateInfo.startSide, reconnectingPerspective, SlidingPreference.FORWARD);
|
|
573
575
|
const newEnd = this.rebaseSidedLocalReference(obliterateInfo.end, obliterateInfo.endSide, reconnectingPerspective, SlidingPreference.BACKWARD);
|
|
574
576
|
return {
|
|
@@ -576,7 +578,7 @@ export class Client extends TypedEventEmitter {
|
|
|
576
578
|
end: newEnd,
|
|
577
579
|
};
|
|
578
580
|
}
|
|
579
|
-
resetPendingDeltaToOps(resetOp, segmentGroup) {
|
|
581
|
+
resetPendingDeltaToOps(resetOp, segmentGroup, squash) {
|
|
580
582
|
assert(!!segmentGroup, 0x033 /* "Segment group undefined" */);
|
|
581
583
|
const NACKedSegmentGroup = this.pendingRebase?.shift()?.data;
|
|
582
584
|
assert(segmentGroup === NACKedSegmentGroup, 0x034 /* "Segment group not at head of pending rebase queue" */);
|
|
@@ -603,11 +605,17 @@ export class Client extends TypedEventEmitter {
|
|
|
603
605
|
for (const segment of segmentGroup.segments) {
|
|
604
606
|
assert(isRemovedAndAcked(segment), 0xb66 /* On reconnect, obliterate applied to new segments even though original ones were not removed. */);
|
|
605
607
|
const lastRemove = segment.removes[segment.removes.length - 1];
|
|
606
|
-
assert(lastRemove.type === "sliceRemove" &&
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
//
|
|
610
|
-
segment
|
|
608
|
+
assert((lastRemove.type === "sliceRemove" &&
|
|
609
|
+
lastRemove.localSeq === segmentGroup.localSeq) ||
|
|
610
|
+
opstampUtils.isSquashedOp(lastRemove), 0xbad /* Last remove should be the obliterate that is being resubmitted. */);
|
|
611
|
+
// The original obliterate affected this segment, but it has since been removed.
|
|
612
|
+
// This can happen when a concurrent obliterate also removed the segment, as well as when the segment was
|
|
613
|
+
// only locally inserted and its insertion was squashed upon reconnecting.
|
|
614
|
+
// In the concurrent removal case (where we didn't avoid sending the segment's insertion in the first place due
|
|
615
|
+
// to squashing), we adjust the metadata on that segment to reflect the fact that this obliterate no longer removes it.
|
|
616
|
+
if (!opstampUtils.isSquashedOp(lastRemove)) {
|
|
617
|
+
segment.removes.pop();
|
|
618
|
+
}
|
|
611
619
|
}
|
|
612
620
|
this._mergeTree.rebaseObliterateTo(obliterateInfo, undefined);
|
|
613
621
|
return [];
|
|
@@ -636,19 +644,24 @@ export class Client extends TypedEventEmitter {
|
|
|
636
644
|
};
|
|
637
645
|
for (const segment of segmentGroup.segments) {
|
|
638
646
|
assert(segment.segmentGroups?.remove(segmentGroup) === true, 0x035 /* "Segment group not in segment pending queue" */);
|
|
639
|
-
if ((segment
|
|
640
|
-
segment.ordinal
|
|
641
|
-
|
|
642
|
-
|
|
647
|
+
if (!isRemovedAndAcked(segment) &&
|
|
648
|
+
((segment.ordinal > newStartSegment.ordinal &&
|
|
649
|
+
segment.ordinal < newEndSegment.ordinal) ||
|
|
650
|
+
(segment === newStartSegment && newStartSide === Side.Before) ||
|
|
651
|
+
(segment === newEndSegment && newEndSide === Side.After))) {
|
|
643
652
|
segment.segmentGroups.enqueue(newObliterate.segmentGroup);
|
|
644
653
|
}
|
|
645
654
|
else {
|
|
646
655
|
assert(isRemovedAndAcked(segment), 0xb69 /* On reconnect, obliterate applied to new segments even though original ones were not removed. */);
|
|
647
656
|
const lastRemove = segment.removes[segment.removes.length - 1];
|
|
648
|
-
assert(lastRemove.type === "sliceRemove" &&
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
657
|
+
assert((lastRemove.type === "sliceRemove" &&
|
|
658
|
+
lastRemove.localSeq === segmentGroup.localSeq) ||
|
|
659
|
+
opstampUtils.isSquashedOp(lastRemove), 0xbae /* Last remove should be the obliterate that is being resubmitted. */);
|
|
660
|
+
if (!opstampUtils.isSquashedOp(lastRemove)) {
|
|
661
|
+
// The original obliterate affected this segment, but it has since been removed and it's impossible to apply the
|
|
662
|
+
// local obliterate so that is so. We adjust the metadata on that segment now.
|
|
663
|
+
segment.removes.pop();
|
|
664
|
+
}
|
|
652
665
|
}
|
|
653
666
|
}
|
|
654
667
|
this._mergeTree.rebaseObliterateTo(obliterateInfo, newObliterate);
|
|
@@ -701,9 +714,19 @@ export class Client extends TypedEventEmitter {
|
|
|
701
714
|
break;
|
|
702
715
|
}
|
|
703
716
|
case MergeTreeDeltaType.INSERT: {
|
|
717
|
+
if (isInserted(segment) && opstampUtils.isSquashedOp(segment.insert)) {
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
704
720
|
assert(isInserted(segment) && opstampUtils.isLocal(segment.insert), 0x037 /* "Segment already has assigned sequence number" */);
|
|
705
721
|
const removeInfo = toRemovalInfo(segment);
|
|
706
|
-
|
|
722
|
+
const unusedStamp = { seq: 0, clientId: 0 };
|
|
723
|
+
if (removeInfo !== undefined && squash) {
|
|
724
|
+
assert(removeInfo.removes.length === 1 ||
|
|
725
|
+
opstampUtils.isAcked(removeInfo.removes[removeInfo.removes.length - 2]), 0xbaf /* Expected only one local remove */);
|
|
726
|
+
this.squashInsertion(segment);
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
729
|
+
else if (removeInfo !== undefined && opstampUtils.isAcked(removeInfo.removes[0])) {
|
|
707
730
|
assert(removeInfo.removes[0].type === "sliceRemove", 0xb5c /* Remove on insertion must be caused by obliterate. */);
|
|
708
731
|
errorIfOptionNotTrue(this._mergeTree.options, "mergeTreeEnableObliterateReconnect");
|
|
709
732
|
// the segment was remotely obliterated, so is considered removed
|
|
@@ -718,6 +741,7 @@ export class Client extends TypedEventEmitter {
|
|
|
718
741
|
clientId: NonCollabClient,
|
|
719
742
|
},
|
|
720
743
|
});
|
|
744
|
+
this._mergeTree.blockUpdatePathLengths(segment.parent, unusedStamp, true);
|
|
721
745
|
break;
|
|
722
746
|
}
|
|
723
747
|
const segInsertOp = segment.clone();
|
|
@@ -857,13 +881,34 @@ export class Client extends TypedEventEmitter {
|
|
|
857
881
|
const shortRemoteClientId = this.getOrAddShortClientId(remoteClientId);
|
|
858
882
|
return this._mergeTree.resolveRemoteClientPosition(remoteClientPosition, remoteClientRefSeq, shortRemoteClientId);
|
|
859
883
|
}
|
|
884
|
+
squashInsertion(segment) {
|
|
885
|
+
overwriteInfo(segment, {
|
|
886
|
+
insert: {
|
|
887
|
+
type: "insert",
|
|
888
|
+
seq: UniversalSequenceNumber,
|
|
889
|
+
localSeq: undefined,
|
|
890
|
+
clientId: SquashClient,
|
|
891
|
+
},
|
|
892
|
+
removes: [
|
|
893
|
+
{
|
|
894
|
+
type: "setRemove",
|
|
895
|
+
seq: UniversalSequenceNumber,
|
|
896
|
+
localSeq: undefined,
|
|
897
|
+
clientId: SquashClient,
|
|
898
|
+
},
|
|
899
|
+
],
|
|
900
|
+
});
|
|
901
|
+
this._mergeTree.blockUpdatePathLengths(segment.parent, { seq: 0, clientId: 0 }, true);
|
|
902
|
+
}
|
|
860
903
|
/**
|
|
861
904
|
* Given a pending operation and segment group, regenerate the op, so it
|
|
862
905
|
* can be resubmitted
|
|
863
906
|
* @param resetOp - The op to reset
|
|
864
907
|
* @param segmentGroup - The segment group associated with the op
|
|
908
|
+
* @param squash - whether intermediate states should be squashed. See `IDeltaHandler.reSubmit`'s squash parameter
|
|
909
|
+
* documentation for more details.
|
|
865
910
|
*/
|
|
866
|
-
regeneratePendingOp(resetOp, localOpMetadata) {
|
|
911
|
+
regeneratePendingOp(resetOp, localOpMetadata, squash) {
|
|
867
912
|
const segmentGroup = localOpMetadata;
|
|
868
913
|
if (this.pendingRebase === undefined || this.pendingRebase.empty) {
|
|
869
914
|
let firstGroup;
|
|
@@ -885,13 +930,14 @@ export class Client extends TypedEventEmitter {
|
|
|
885
930
|
if (this.lastNormalization === undefined ||
|
|
886
931
|
collabWindow.currentSeq !== this.lastNormalization.refSeq ||
|
|
887
932
|
collabWindow.localSeq !== this.lastNormalization.localRefSeq) {
|
|
933
|
+
const allPendingSegments = [...this._mergeTree.pendingSegments, ...this.pendingRebase];
|
|
888
934
|
// Compute obliterate endpoint destinations before segments are normalized.
|
|
889
935
|
// Segment normalization can affect what should be the semantically correct segments for the endpoints to be placed on.
|
|
890
936
|
this.cachedObliterateRebases.clear();
|
|
891
|
-
for (const group of
|
|
937
|
+
for (const group of allPendingSegments) {
|
|
892
938
|
const { obliterateInfo } = group.data;
|
|
893
939
|
if (obliterateInfo !== undefined) {
|
|
894
|
-
const { start, end } = this.computeNewObliterateEndpoints(obliterateInfo);
|
|
940
|
+
const { start, end } = this.computeNewObliterateEndpoints(obliterateInfo, squash);
|
|
895
941
|
const { localSeq } = obliterateInfo.stamp;
|
|
896
942
|
assert(localSeq !== undefined, 0xb6d /* Local seq must be defined */);
|
|
897
943
|
this.cachedObliterateRebases.set(localSeq, { start, end });
|
|
@@ -909,20 +955,20 @@ export class Client extends TypedEventEmitter {
|
|
|
909
955
|
if (Array.isArray(segmentGroup)) {
|
|
910
956
|
assert(resetOp.ops.length === segmentGroup.length, 0x03a /* "Number of ops in 'resetOp' must match the number of segment groups provided." */);
|
|
911
957
|
for (let i = 0; i < resetOp.ops.length; i++) {
|
|
912
|
-
opList.push(...this.resetPendingDeltaToOps(resetOp.ops[i], segmentGroup[i]));
|
|
958
|
+
opList.push(...this.resetPendingDeltaToOps(resetOp.ops[i], segmentGroup[i], squash));
|
|
913
959
|
}
|
|
914
960
|
}
|
|
915
961
|
else {
|
|
916
962
|
// A group op containing a single op will pass a direct reference to 'segmentGroup'
|
|
917
963
|
// rather than an array of segment groups. (See 'peekPendingSegmentGroups()')
|
|
918
964
|
assert(resetOp.ops.length === 1, 0x03b /* "Number of ops in 'resetOp' must match the number of segment groups provided." */);
|
|
919
|
-
opList.push(...this.resetPendingDeltaToOps(resetOp.ops[0], segmentGroup));
|
|
965
|
+
opList.push(...this.resetPendingDeltaToOps(resetOp.ops[0], segmentGroup, squash));
|
|
920
966
|
}
|
|
921
967
|
}
|
|
922
968
|
else {
|
|
923
969
|
assert(resetOp.type !== MergeTreeDeltaType.GROUP, 0x03c /* "Reset op has 'group' delta type!" */);
|
|
924
970
|
assert(!Array.isArray(segmentGroup), 0x03d /* "segmentGroup is array rather than singleton!" */);
|
|
925
|
-
opList.push(...this.resetPendingDeltaToOps(resetOp, segmentGroup));
|
|
971
|
+
opList.push(...this.resetPendingDeltaToOps(resetOp, segmentGroup, squash));
|
|
926
972
|
}
|
|
927
973
|
return opList.length === 1 ? opList[0] : createGroupOp(...opList);
|
|
928
974
|
}
|