@fluidframework/merge-tree 2.12.0 → 2.20.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 +46 -0
- package/api-report/merge-tree.legacy.alpha.api.md +0 -108
- package/dist/MergeTreeTextHelper.d.ts.map +1 -1
- package/dist/MergeTreeTextHelper.js +0 -2
- package/dist/MergeTreeTextHelper.js.map +1 -1
- package/dist/attributionPolicy.d.ts.map +1 -1
- package/dist/attributionPolicy.js +6 -16
- package/dist/attributionPolicy.js.map +1 -1
- package/dist/client.d.ts +3 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +39 -28
- package/dist/client.js.map +1 -1
- package/dist/endOfTreeSegment.d.ts +2 -1
- package/dist/endOfTreeSegment.d.ts.map +1 -1
- package/dist/endOfTreeSegment.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +0 -4
- package/dist/localReference.d.ts +5 -7
- package/dist/localReference.d.ts.map +1 -1
- package/dist/localReference.js +1 -3
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts +8 -7
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +187 -228
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodeWalk.d.ts.map +1 -1
- package/dist/mergeTreeNodeWalk.js +3 -2
- package/dist/mergeTreeNodeWalk.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +65 -325
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +96 -130
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/mergeTreeTracking.d.ts.map +1 -1
- package/dist/mergeTreeTracking.js +0 -2
- package/dist/mergeTreeTracking.js.map +1 -1
- package/dist/opBuilder.d.ts +0 -5
- package/dist/opBuilder.d.ts.map +1 -1
- package/dist/opBuilder.js +0 -5
- package/dist/opBuilder.js.map +1 -1
- package/dist/package.json +2 -1
- package/dist/partialLengths.d.ts +2 -2
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +29 -31
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +3 -2
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +5 -2
- package/dist/perspective.js.map +1 -1
- package/dist/referencePositions.d.ts.map +1 -1
- package/dist/referencePositions.js +4 -1
- package/dist/referencePositions.js.map +1 -1
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +10 -14
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentGroupCollection.d.ts +4 -4
- package/dist/segmentGroupCollection.d.ts.map +1 -1
- package/dist/segmentGroupCollection.js +0 -6
- package/dist/segmentGroupCollection.js.map +1 -1
- package/dist/segmentInfos.d.ts +251 -0
- package/dist/segmentInfos.d.ts.map +1 -0
- package/dist/segmentInfos.js +166 -0
- package/dist/segmentInfos.js.map +1 -0
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js +36 -44
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js +9 -12
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts +2 -2
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +5 -3
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +5 -8
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/test/beastTest.spec.d.ts +0 -2
- package/dist/test/beastTest.spec.d.ts.map +1 -1
- package/dist/test/beastTest.spec.js +1 -5
- package/dist/test/beastTest.spec.js.map +1 -1
- package/dist/test/client.annotateMarker.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +15 -12
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.attributionFarm.spec.js.map +1 -1
- package/dist/test/client.getPosition.spec.js +3 -2
- package/dist/test/client.getPosition.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +6 -6
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.localReferenceFarm.spec.js.map +1 -1
- package/dist/test/client.rollback.spec.js.map +1 -1
- package/dist/test/dirname.cjs +0 -1
- package/dist/test/dirname.cjs.map +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +2 -4
- package/dist/test/index.js.map +1 -1
- package/dist/test/mergeTree.annotate.spec.js +3 -0
- package/dist/test/mergeTree.annotate.spec.js.map +1 -1
- package/dist/test/mergeTree.insertingWalk.spec.js +1 -1
- package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js +2 -0
- package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/dist/test/mergeTree.walk.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +2 -3
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/propertyManager.spec.js.map +1 -1
- package/dist/test/reconnectHelper.d.ts +2 -1
- package/dist/test/reconnectHelper.d.ts.map +1 -1
- package/dist/test/reconnectHelper.js.map +1 -1
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/dist/test/revertibleFarm.spec.js.map +1 -1
- package/dist/test/segmentGroupCollection.spec.js +15 -3
- package/dist/test/segmentGroupCollection.spec.js.map +1 -1
- package/dist/test/snapshot.utils.d.ts +2 -2
- package/dist/test/snapshot.utils.d.ts.map +1 -1
- package/dist/test/snapshot.utils.js.map +1 -1
- package/dist/test/sortedSegmentSet.spec.js +4 -3
- package/dist/test/sortedSegmentSet.spec.js.map +1 -1
- package/dist/test/testClient.d.ts +8 -6
- package/dist/test/testClient.d.ts.map +1 -1
- package/dist/test/testClient.js +28 -27
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testClientLogger.d.ts.map +1 -1
- package/dist/test/testClientLogger.js +6 -4
- package/dist/test/testClientLogger.js.map +1 -1
- package/dist/test/testUtils.d.ts +2 -2
- package/dist/test/testUtils.d.ts.map +1 -1
- package/dist/test/testUtils.js +32 -8
- package/dist/test/testUtils.js.map +1 -1
- package/dist/test/text.d.ts +2 -2
- package/dist/test/text.d.ts.map +1 -1
- package/dist/test/text.js +12 -6
- package/dist/test/text.js.map +1 -1
- package/dist/test/tracking.spec.js.map +1 -1
- package/dist/test/wordUnitTests.spec.js +1 -1
- package/dist/test/wordUnitTests.spec.js.map +1 -1
- package/dist/zamboni.d.ts.map +1 -1
- package/dist/zamboni.js +8 -7
- package/dist/zamboni.js.map +1 -1
- package/lib/MergeTreeTextHelper.d.ts.map +1 -1
- package/lib/MergeTreeTextHelper.js +0 -2
- package/lib/MergeTreeTextHelper.js.map +1 -1
- package/lib/attributionPolicy.d.ts.map +1 -1
- package/lib/attributionPolicy.js +6 -16
- package/lib/attributionPolicy.js.map +1 -1
- package/lib/client.d.ts +3 -4
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +40 -29
- package/lib/client.js.map +1 -1
- package/lib/endOfTreeSegment.d.ts +2 -1
- package/lib/endOfTreeSegment.d.ts.map +1 -1
- package/lib/endOfTreeSegment.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/legacy.d.ts +0 -4
- package/lib/localReference.d.ts +5 -7
- package/lib/localReference.d.ts.map +1 -1
- package/lib/localReference.js +1 -3
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts +8 -7
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +175 -220
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodeWalk.d.ts.map +1 -1
- package/lib/mergeTreeNodeWalk.js +3 -2
- package/lib/mergeTreeNodeWalk.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +65 -325
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +92 -127
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/mergeTreeTracking.d.ts.map +1 -1
- package/lib/mergeTreeTracking.js +0 -2
- package/lib/mergeTreeTracking.js.map +1 -1
- package/lib/opBuilder.d.ts +0 -5
- package/lib/opBuilder.d.ts.map +1 -1
- package/lib/opBuilder.js +0 -5
- package/lib/opBuilder.js.map +1 -1
- package/lib/partialLengths.d.ts +2 -2
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +26 -28
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +3 -2
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +5 -2
- package/lib/perspective.js.map +1 -1
- package/lib/referencePositions.d.ts.map +1 -1
- package/lib/referencePositions.js +4 -1
- package/lib/referencePositions.js.map +1 -1
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +8 -12
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentGroupCollection.d.ts +4 -4
- package/lib/segmentGroupCollection.d.ts.map +1 -1
- package/lib/segmentGroupCollection.js +0 -6
- package/lib/segmentGroupCollection.js.map +1 -1
- package/lib/segmentInfos.d.ts +251 -0
- package/lib/segmentInfos.d.ts.map +1 -0
- package/lib/segmentInfos.js +145 -0
- package/lib/segmentInfos.js.map +1 -0
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js +36 -44
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js +9 -12
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts +2 -2
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +5 -3
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +5 -8
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/test/beastTest.spec.d.ts +0 -2
- package/lib/test/beastTest.spec.d.ts.map +1 -1
- package/lib/test/beastTest.spec.js +0 -3
- package/lib/test/beastTest.spec.js.map +1 -1
- package/lib/test/client.annotateMarker.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +15 -12
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.attributionFarm.spec.js.map +1 -1
- package/lib/test/client.getPosition.spec.js +3 -2
- package/lib/test/client.getPosition.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +1 -1
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.localReferenceFarm.spec.js.map +1 -1
- package/lib/test/client.rollback.spec.js +1 -1
- package/lib/test/client.rollback.spec.js.map +1 -1
- package/lib/test/dirname.cjs +0 -1
- package/lib/test/dirname.cjs.map +1 -1
- package/lib/test/index.d.ts +1 -1
- package/lib/test/index.d.ts.map +1 -1
- package/lib/test/index.js +1 -1
- package/lib/test/index.js.map +1 -1
- package/lib/test/mergeTree.annotate.spec.js +3 -0
- package/lib/test/mergeTree.annotate.spec.js.map +1 -1
- package/lib/test/mergeTree.insertingWalk.spec.js +2 -2
- package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js +2 -0
- package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/lib/test/mergeTree.walk.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +1 -2
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/propertyManager.spec.js.map +1 -1
- package/lib/test/reconnectHelper.d.ts +2 -1
- package/lib/test/reconnectHelper.d.ts.map +1 -1
- package/lib/test/reconnectHelper.js.map +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/lib/test/revertibleFarm.spec.js.map +1 -1
- package/lib/test/segmentGroupCollection.spec.js +15 -3
- package/lib/test/segmentGroupCollection.spec.js.map +1 -1
- package/lib/test/snapshot.utils.d.ts +2 -2
- package/lib/test/snapshot.utils.d.ts.map +1 -1
- package/lib/test/snapshot.utils.js.map +1 -1
- package/lib/test/sortedSegmentSet.spec.js +4 -3
- package/lib/test/sortedSegmentSet.spec.js.map +1 -1
- package/lib/test/testClient.d.ts +8 -6
- package/lib/test/testClient.d.ts.map +1 -1
- package/lib/test/testClient.js +29 -28
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testClientLogger.d.ts.map +1 -1
- package/lib/test/testClientLogger.js +5 -3
- package/lib/test/testClientLogger.js.map +1 -1
- package/lib/test/testUtils.d.ts +2 -2
- package/lib/test/testUtils.d.ts.map +1 -1
- package/lib/test/testUtils.js +9 -8
- package/lib/test/testUtils.js.map +1 -1
- package/lib/test/text.d.ts +2 -2
- package/lib/test/text.d.ts.map +1 -1
- package/lib/test/text.js +12 -6
- package/lib/test/text.js.map +1 -1
- package/lib/test/tracking.spec.js.map +1 -1
- package/lib/test/wordUnitTests.spec.js +1 -1
- package/lib/test/wordUnitTests.spec.js.map +1 -1
- package/lib/zamboni.d.ts.map +1 -1
- package/lib/zamboni.js +7 -6
- package/lib/zamboni.js.map +1 -1
- package/package.json +77 -19
- package/src/MergeTreeTextHelper.ts +2 -4
- package/src/attributionPolicy.ts +5 -13
- package/src/client.ts +55 -44
- package/src/endOfTreeSegment.ts +3 -5
- package/src/index.ts +0 -7
- package/src/localReference.ts +6 -8
- package/src/mergeTree.ts +233 -290
- package/src/mergeTreeNodeWalk.ts +3 -2
- package/src/mergeTreeNodes.ts +160 -490
- package/src/mergeTreeTracking.ts +0 -3
- package/src/opBuilder.ts +0 -5
- package/src/partialLengths.ts +40 -29
- package/src/perspective.ts +23 -4
- package/src/referencePositions.ts +4 -1
- package/src/revertibles.ts +19 -16
- package/src/segmentGroupCollection.ts +7 -18
- package/src/segmentInfos.ts +371 -0
- package/src/snapshotLoader.ts +56 -57
- package/src/snapshotV1.ts +14 -16
- package/src/snapshotlegacy.ts +12 -17
- package/src/sortedSegmentSet.ts +6 -8
- package/src/zamboni.ts +10 -12
package/src/mergeTreeNodes.ts
CHANGED
|
@@ -3,84 +3,74 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
7
|
-
|
|
8
6
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
9
7
|
import { AttributionKey } from "@fluidframework/runtime-definitions/internal";
|
|
10
8
|
|
|
11
9
|
import { IAttributionCollection } from "./attributionCollection.js";
|
|
12
|
-
import {
|
|
13
|
-
LocalClientId,
|
|
14
|
-
UnassignedSequenceNumber,
|
|
15
|
-
UniversalSequenceNumber,
|
|
16
|
-
} from "./constants.js";
|
|
17
|
-
// eslint-disable-next-line import/no-deprecated
|
|
10
|
+
import { LocalClientId, UnassignedSequenceNumber } from "./constants.js";
|
|
18
11
|
import { LocalReferenceCollection, type LocalReferencePosition } from "./localReference.js";
|
|
19
12
|
import { TrackingGroupCollection } from "./mergeTreeTracking.js";
|
|
20
13
|
import { IJSONSegment, IMarkerDef, ReferenceType } from "./ops.js";
|
|
21
14
|
import { computeHierarchicalOrdinal } from "./ordinal.js";
|
|
22
15
|
import type { PartialSequenceLengths } from "./partialLengths.js";
|
|
23
16
|
import { PropertySet, clone, createMap, type MapLike } from "./properties.js";
|
|
24
|
-
import {
|
|
25
|
-
ReferencePosition,
|
|
26
|
-
refGetTileLabels,
|
|
27
|
-
refTypeIncludesFlag,
|
|
28
|
-
} from "./referencePositions.js";
|
|
29
|
-
// eslint-disable-next-line import/no-deprecated
|
|
17
|
+
import { ReferencePosition } from "./referencePositions.js";
|
|
30
18
|
import { SegmentGroupCollection } from "./segmentGroupCollection.js";
|
|
31
|
-
|
|
19
|
+
import {
|
|
20
|
+
hasProp,
|
|
21
|
+
isInserted,
|
|
22
|
+
isMergeNodeInfo as isMergeNode,
|
|
23
|
+
isMoved,
|
|
24
|
+
isRemoved,
|
|
25
|
+
overwriteInfo,
|
|
26
|
+
type IInsertionInfo,
|
|
27
|
+
type IMergeNodeInfo,
|
|
28
|
+
type IMoveInfo,
|
|
29
|
+
type IRemovalInfo,
|
|
30
|
+
type SegmentWithInfo,
|
|
31
|
+
} from "./segmentInfos.js";
|
|
32
32
|
import { PropertiesManager } from "./segmentPropertiesManager.js";
|
|
33
33
|
|
|
34
|
-
/**
|
|
35
|
-
* Common properties for a node in a merge tree.
|
|
36
|
-
* @legacy
|
|
37
|
-
* @alpha
|
|
38
|
-
* @deprecated - This interface will be removed in 2.20 with no replacement.
|
|
39
|
-
*/
|
|
40
|
-
export interface IMergeNodeCommon {
|
|
41
|
-
/**
|
|
42
|
-
* The index of this node in its parent's list of children.
|
|
43
|
-
*/
|
|
44
|
-
index: number;
|
|
45
|
-
/**
|
|
46
|
-
* A string that can be used for comparing the location of this node to other `MergeNode`s in the same tree.
|
|
47
|
-
* `a.ordinal < b.ordinal` if and only if `a` comes before `b` in a pre-order traversal of the tree.
|
|
48
|
-
*/
|
|
49
|
-
ordinal: string;
|
|
50
|
-
isLeaf(): this is ISegment;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
34
|
/**
|
|
54
35
|
* This interface exposes internal things to dds that leverage merge tree,
|
|
55
36
|
* like sequence and matrix.
|
|
56
37
|
*
|
|
57
38
|
* We use tiered interface to control visibility of segment properties.
|
|
58
|
-
* This sits between ISegment and
|
|
39
|
+
* This sits between ISegment and ISegmentPrivate. It should only expose
|
|
59
40
|
* things tagged internal.
|
|
60
41
|
*
|
|
42
|
+
* Everything added here beyond ISegment should be optional to keep the ability
|
|
43
|
+
* to implicitly convert between the tiered interfaces.
|
|
44
|
+
*
|
|
61
45
|
* @internal
|
|
62
46
|
*/
|
|
63
|
-
export
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
47
|
+
export interface ISegmentInternal extends ISegment {
|
|
48
|
+
localRefs?: LocalReferenceCollection;
|
|
49
|
+
/**
|
|
50
|
+
* Whether or not this segment is a special segment denoting the start or
|
|
51
|
+
* end of the tree
|
|
52
|
+
*
|
|
53
|
+
* Endpoint segments are imaginary segments positioned immediately before or
|
|
54
|
+
* after the tree. These segments cannot be referenced by regular operations
|
|
55
|
+
* and exist primarily as a bucket for local references to slide onto during
|
|
56
|
+
* deletion of regular segments.
|
|
57
|
+
*/
|
|
58
|
+
readonly endpointType?: "start" | "end";
|
|
59
|
+
}
|
|
70
60
|
|
|
71
61
|
/**
|
|
72
62
|
* We use tiered interface to control visibility of segment properties.
|
|
73
63
|
* This is the lowest interface and is not exported, it site below ISegment and ISegmentInternal.
|
|
74
64
|
* It should only expose unexported things.
|
|
75
65
|
*
|
|
66
|
+
* Everything added here beyond ISegmentInternal should be optional to keep the ability
|
|
67
|
+
* to implicitly convert between the tiered interfaces.
|
|
68
|
+
*
|
|
76
69
|
* someday we may split tree leaves from segments, but for now they are the same
|
|
77
70
|
* this is just a convenience type that makes it clear that we need something that is both a segment and a leaf node
|
|
78
71
|
*/
|
|
79
|
-
export
|
|
80
|
-
parent?: MergeBlock;
|
|
81
|
-
// eslint-disable-next-line import/no-deprecated
|
|
72
|
+
export interface ISegmentPrivate extends ISegmentInternal {
|
|
82
73
|
segmentGroups?: SegmentGroupCollection;
|
|
83
|
-
// eslint-disable-next-line import/no-deprecated
|
|
84
74
|
propertyManager?: PropertiesManager;
|
|
85
75
|
/**
|
|
86
76
|
* If a segment is inserted into an obliterated range,
|
|
@@ -88,130 +78,54 @@ export type ISegmentLeaf = ISegmentInternal & {
|
|
|
88
78
|
* then the segment is not obliterated because it is aware of the latest obliteration.
|
|
89
79
|
*/
|
|
90
80
|
prevObliterateByInserter?: ObliterateInfo;
|
|
91
|
-
}
|
|
92
|
-
export type IMergeNode = MergeBlock | ISegmentLeaf;
|
|
93
|
-
|
|
81
|
+
}
|
|
94
82
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
83
|
+
* Segment leafs are segments that have both IMergeNodeInfo and IInsertionInfo. This means they
|
|
84
|
+
* are inserted at a position, and bound via their parent MergeBlock to the merge tree. MergeBlocks'
|
|
85
|
+
* children are either a segment leaf, or another merge block for interior nodes of the tree. When working
|
|
86
|
+
* within the tree it is generally unnecessary to use type coercions methods common to the infos, and segment
|
|
87
|
+
* leafs, as the children of MergeBlocks are already well typed. However, when segments come from outside the
|
|
88
|
+
* merge tree, like via client's public methods, it becomes necessary to use the type coercions methods
|
|
89
|
+
* to ensure the passed in segment objects are correctly bound to the merge tree.
|
|
99
90
|
*/
|
|
100
|
-
export
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* List of client IDs that have removed this segment.
|
|
111
|
-
* The client that actually removed the segment (i.e. whose removal op was sequenced first) is stored as the first
|
|
112
|
-
* client in this list. Other clients in the list have all issued concurrent ops to remove the segment.
|
|
113
|
-
* @remarks When this list has length \> 1, this is referred to as the "overlapping remove" case.
|
|
114
|
-
*/
|
|
115
|
-
removedClientIds: number[];
|
|
116
|
-
}
|
|
91
|
+
export type ISegmentLeaf = SegmentWithInfo<IMergeNodeInfo & IInsertionInfo>;
|
|
92
|
+
/**
|
|
93
|
+
* A type-guard which determines if the segment has segment leaf, and
|
|
94
|
+
* returns true if it does, along with applying strong typing.
|
|
95
|
+
* @param nodeLike - The segment-like object to check.
|
|
96
|
+
* @returns True if the segment is a segment leaf, otherwise false.
|
|
97
|
+
*/
|
|
98
|
+
export const isSegmentLeaf = (segmentLike: unknown): segmentLike is ISegmentLeaf =>
|
|
99
|
+
isInserted(segmentLike) && isMergeNode(segmentLike);
|
|
117
100
|
|
|
118
101
|
/**
|
|
119
|
-
*
|
|
102
|
+
* Converts a segment-like object to a segment leaf object if possible.
|
|
120
103
|
*
|
|
121
|
-
* @
|
|
104
|
+
* @param segmentLike - The segment-like object to convert.
|
|
105
|
+
* @returns The segment leaf if the conversion is possible, otherwise undefined.
|
|
122
106
|
*/
|
|
123
|
-
export
|
|
124
|
-
|
|
125
|
-
): IRemovalInfo | undefined {
|
|
126
|
-
if (maybe?.removedClientIds !== undefined && maybe?.removedSeq !== undefined) {
|
|
127
|
-
return maybe as IRemovalInfo;
|
|
128
|
-
}
|
|
129
|
-
assert(
|
|
130
|
-
maybe?.removedClientIds === undefined && maybe?.removedSeq === undefined,
|
|
131
|
-
0x2bf /* "both removedClientIds and removedSeq should be set or not set" */,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
107
|
+
export const toSegmentLeaf = (segmentLike: unknown): ISegmentLeaf | undefined =>
|
|
108
|
+
isSegmentLeaf(segmentLike) ? segmentLike : undefined;
|
|
135
109
|
/**
|
|
136
|
-
*
|
|
110
|
+
* Asserts that the segment is a segment leaf. Usage of this function should not produce a user facing error.
|
|
137
111
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* in the future, when moves _are_ supported.
|
|
141
|
-
* @legacy
|
|
142
|
-
* @alpha
|
|
143
|
-
* @deprecated - This interface will be removed in 2.20 with no replacement.
|
|
112
|
+
* @param segmentLike - The segment-like object to check.
|
|
113
|
+
* @throws Will throw an error if the segment is not a segment leaf.
|
|
144
114
|
*/
|
|
145
|
-
export
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
* The first seq at which this segment was moved.
|
|
154
|
-
*/
|
|
155
|
-
movedSeq: number;
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* All seqs at which this segment was moved. In the case of overlapping,
|
|
159
|
-
* concurrent moves this array will contain multiple seqs.
|
|
160
|
-
*
|
|
161
|
-
* The seq at `movedSeqs[i]` corresponds to the client id at `movedClientIds[i]`.
|
|
162
|
-
*
|
|
163
|
-
* The first element corresponds to the seq of the first move
|
|
164
|
-
*/
|
|
165
|
-
movedSeqs: number[];
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* A reference to the inserted destination segment corresponding to this
|
|
169
|
-
* segment's move.
|
|
170
|
-
*
|
|
171
|
-
* If undefined, the move was an obliterate.
|
|
172
|
-
*
|
|
173
|
-
* Currently this field is unused, as we only support obliterate operations
|
|
174
|
-
*/
|
|
175
|
-
moveDst?: ReferencePosition;
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* List of client IDs that have moved this segment.
|
|
179
|
-
*
|
|
180
|
-
* The client that actually moved the segment (i.e. whose move op was sequenced
|
|
181
|
-
* first) is stored as the first client in this list. Other clients in the
|
|
182
|
-
* list have all issued concurrent ops to move the segment.
|
|
183
|
-
*/
|
|
184
|
-
movedClientIds: number[];
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* If this segment was inserted into a concurrently moved range and
|
|
188
|
-
* the move op was sequenced before the insertion op. In this case,
|
|
189
|
-
* the segment is visible only to the inserting client
|
|
190
|
-
*
|
|
191
|
-
* `wasMovedOnInsert` only applies for acked obliterates. That is, if
|
|
192
|
-
* a segment inserted by a remote client is moved on insertion by a local
|
|
193
|
-
* and unacked obliterate, we do not consider it as having been moved
|
|
194
|
-
* on insert
|
|
195
|
-
*
|
|
196
|
-
* If a segment is moved on insertion, its length is only ever visible to
|
|
197
|
-
* the client that inserted the segment. This is relevant in partial length
|
|
198
|
-
* calculations
|
|
199
|
-
*/
|
|
200
|
-
wasMovedOnInsert: boolean;
|
|
201
|
-
}
|
|
115
|
+
export const assertSegmentLeaf: (segmentLike: unknown) => asserts segmentLike is ISegmentLeaf =
|
|
116
|
+
(segmentLike) => assert(isSegmentLeaf(segmentLike), 0xaab /* must be segment leaf */);
|
|
117
|
+
/**
|
|
118
|
+
* This type is used for building MergeBlocks from segments and other MergeBlocks. We need this
|
|
119
|
+
* type as segments may not yet be bound to the tree, so lack merge node info which is required for
|
|
120
|
+
* segment leafs.
|
|
121
|
+
*/
|
|
122
|
+
export type IMergeNodeBuilder = MergeBlock | SegmentWithInfo<IInsertionInfo>;
|
|
202
123
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
maybe?.movedClientIds === undefined &&
|
|
209
|
-
maybe?.movedSeq === undefined &&
|
|
210
|
-
maybe?.movedSeqs === undefined &&
|
|
211
|
-
maybe?.wasMovedOnInsert === undefined,
|
|
212
|
-
0x86d /* movedClientIds, movedSeq, wasMovedOnInsert, and movedSeqs should all be either set or not set */,
|
|
213
|
-
);
|
|
214
|
-
}
|
|
124
|
+
/**
|
|
125
|
+
* This type is used by MergeBlocks to define their children, which are either segments or other
|
|
126
|
+
* MergeBlocks.
|
|
127
|
+
*/
|
|
128
|
+
export type IMergeNode = MergeBlock | ISegmentLeaf;
|
|
215
129
|
|
|
216
130
|
/**
|
|
217
131
|
* A segment representing a portion of the merge tree.
|
|
@@ -223,17 +137,6 @@ export interface ISegment {
|
|
|
223
137
|
readonly type: string;
|
|
224
138
|
|
|
225
139
|
readonly trackingCollection: TrackingGroupCollection;
|
|
226
|
-
/**
|
|
227
|
-
* Whether or not this segment is a special segment denoting the start or
|
|
228
|
-
* end of the tree
|
|
229
|
-
*
|
|
230
|
-
* Endpoint segments are imaginary segments positioned immediately before or
|
|
231
|
-
* after the tree. These segments cannot be referenced by regular operations
|
|
232
|
-
* and exist primarily as a bucket for local references to slide onto during
|
|
233
|
-
* deletion of regular segments.
|
|
234
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
235
|
-
*/
|
|
236
|
-
readonly endpointType?: "start" | "end";
|
|
237
140
|
|
|
238
141
|
/**
|
|
239
142
|
* The length of the contents of the node.
|
|
@@ -256,45 +159,6 @@ export interface ISegment {
|
|
|
256
159
|
*/
|
|
257
160
|
attribution?: IAttributionCollection<AttributionKey>;
|
|
258
161
|
|
|
259
|
-
/**
|
|
260
|
-
* Local seq at which this segment was inserted.
|
|
261
|
-
* This is defined if and only if the insertion of the segment is pending ack, i.e. `seq` is UnassignedSequenceNumber.
|
|
262
|
-
* Once the segment is acked, this field is cleared.
|
|
263
|
-
*
|
|
264
|
-
* @privateRemarks
|
|
265
|
-
* See {@link CollaborationWindow.localSeq} for more information on the semantics of localSeq.
|
|
266
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
267
|
-
*/
|
|
268
|
-
localSeq?: number;
|
|
269
|
-
/**
|
|
270
|
-
* Local seq at which this segment was removed. If this is defined, `removedSeq` will initially be set to
|
|
271
|
-
* UnassignedSequenceNumber. However, if another client concurrently removes the same segment, `removedSeq`
|
|
272
|
-
* will be updated to the seq at which that client removed this segment.
|
|
273
|
-
*
|
|
274
|
-
* Like {@link ISegment.localSeq}, this field is cleared once the local removal of the segment is acked.
|
|
275
|
-
*
|
|
276
|
-
* @privateRemarks
|
|
277
|
-
* See {@link CollaborationWindow.localSeq} for more information on the semantics of localSeq.
|
|
278
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
279
|
-
*/
|
|
280
|
-
localRemovedSeq?: number;
|
|
281
|
-
/**
|
|
282
|
-
* Seq at which this segment was inserted.
|
|
283
|
-
* If undefined, it is assumed the segment was inserted prior to the collab window's minimum sequence number.
|
|
284
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
285
|
-
*/
|
|
286
|
-
seq?: number;
|
|
287
|
-
/**
|
|
288
|
-
* Short clientId for the client that inserted this segment.
|
|
289
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
290
|
-
*/
|
|
291
|
-
clientId: number;
|
|
292
|
-
/**
|
|
293
|
-
* Local references added to this segment.
|
|
294
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
295
|
-
*/
|
|
296
|
-
// eslint-disable-next-line import/no-deprecated
|
|
297
|
-
localRefs?: LocalReferenceCollection;
|
|
298
162
|
/**
|
|
299
163
|
* Properties that have been added to this segment via annotation.
|
|
300
164
|
*/
|
|
@@ -308,59 +172,6 @@ export interface ISegment {
|
|
|
308
172
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
309
173
|
toJSONObject(): any;
|
|
310
174
|
isLeaf(): this is ISegment;
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* {@inheritDoc @fluidframework/merge-tree#IMergeNodeCommon.index}
|
|
314
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
315
|
-
*/
|
|
316
|
-
index: number;
|
|
317
|
-
/**
|
|
318
|
-
* {@inheritDoc @fluidframework/merge-tree#IMergeNodeCommon.ordinal}
|
|
319
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
320
|
-
*/
|
|
321
|
-
ordinal: string;
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* {@inheritDoc @fluidframework/merge-tree#IRemovalInfo.removedSeq}
|
|
325
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
326
|
-
*/
|
|
327
|
-
removedSeq?: number;
|
|
328
|
-
/**
|
|
329
|
-
* {@inheritDoc @fluidframework/merge-tree#IRemovalInfo.removedClientIds}
|
|
330
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
331
|
-
*/
|
|
332
|
-
removedClientIds?: number[];
|
|
333
|
-
/**
|
|
334
|
-
* {@inheritDoc @fluidframework/merge-tree#IMoveInfo.localMovedSeq}
|
|
335
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
336
|
-
*/
|
|
337
|
-
localMovedSeq?: number;
|
|
338
|
-
/**
|
|
339
|
-
* {@inheritDoc @fluidframework/merge-tree#IMoveInfo.movedSeq}
|
|
340
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
341
|
-
*/
|
|
342
|
-
movedSeq?: number;
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* {@inheritDoc @fluidframework/merge-tree#IMoveInfo.movedSeqs}
|
|
346
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
347
|
-
*/
|
|
348
|
-
movedSeqs?: number[];
|
|
349
|
-
/**
|
|
350
|
-
* {@inheritDoc @fluidframework/merge-tree#IMoveInfo.moveDst}
|
|
351
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
352
|
-
*/
|
|
353
|
-
moveDst?: ReferencePosition;
|
|
354
|
-
/**
|
|
355
|
-
* {@inheritDoc @fluidframework/merge-tree#IMoveInfo.movedClientIds}
|
|
356
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
357
|
-
*/
|
|
358
|
-
movedClientIds?: number[];
|
|
359
|
-
/**
|
|
360
|
-
* {@inheritDoc @fluidframework/merge-tree#IMoveInfo.wasMovedOnInsert}
|
|
361
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
362
|
-
*/
|
|
363
|
-
wasMovedOnInsert?: boolean;
|
|
364
175
|
}
|
|
365
176
|
|
|
366
177
|
/**
|
|
@@ -369,16 +180,7 @@ export interface ISegment {
|
|
|
369
180
|
* @alpha
|
|
370
181
|
*/
|
|
371
182
|
export function segmentIsRemoved(segment: ISegment): boolean {
|
|
372
|
-
|
|
373
|
-
return leaf.removedSeq !== undefined;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* @internal
|
|
378
|
-
*/
|
|
379
|
-
export interface IMarkerModifiedAction {
|
|
380
|
-
// eslint-disable-next-line @typescript-eslint/prefer-function-type
|
|
381
|
-
(marker: Marker): void;
|
|
183
|
+
return isRemoved(segment);
|
|
382
184
|
}
|
|
383
185
|
|
|
384
186
|
/**
|
|
@@ -397,72 +199,17 @@ export interface ISegmentAction<TClientData> {
|
|
|
397
199
|
accum: TClientData,
|
|
398
200
|
): boolean;
|
|
399
201
|
}
|
|
400
|
-
/**
|
|
401
|
-
* @internal
|
|
402
|
-
*/
|
|
403
202
|
export interface ISegmentChanges {
|
|
404
|
-
next?:
|
|
405
|
-
replaceCurrent?:
|
|
406
|
-
}
|
|
407
|
-
/**
|
|
408
|
-
* @internal
|
|
409
|
-
*/
|
|
410
|
-
export interface BlockAction<TClientData> {
|
|
411
|
-
// eslint-disable-next-line @typescript-eslint/prefer-function-type
|
|
412
|
-
(
|
|
413
|
-
block: MergeBlock,
|
|
414
|
-
pos: number,
|
|
415
|
-
refSeq: number,
|
|
416
|
-
clientId: number,
|
|
417
|
-
start: number | undefined,
|
|
418
|
-
end: number | undefined,
|
|
419
|
-
accum: TClientData,
|
|
420
|
-
): boolean;
|
|
203
|
+
next?: SegmentWithInfo<IInsertionInfo>;
|
|
204
|
+
replaceCurrent?: SegmentWithInfo<IInsertionInfo>;
|
|
421
205
|
}
|
|
422
206
|
|
|
423
|
-
/**
|
|
424
|
-
* @internal
|
|
425
|
-
*/
|
|
426
|
-
export interface NodeAction<TClientData> {
|
|
427
|
-
// eslint-disable-next-line @typescript-eslint/prefer-function-type
|
|
428
|
-
(
|
|
429
|
-
node: IMergeNode,
|
|
430
|
-
pos: number,
|
|
431
|
-
refSeq: number,
|
|
432
|
-
clientId: number,
|
|
433
|
-
start: number | undefined,
|
|
434
|
-
end: number | undefined,
|
|
435
|
-
clientData: TClientData,
|
|
436
|
-
): boolean;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* @internal
|
|
441
|
-
*/
|
|
442
207
|
export interface InsertContext {
|
|
443
|
-
candidateSegment?:
|
|
444
|
-
leaf: (
|
|
445
|
-
segment: ISegmentInternal | undefined,
|
|
446
|
-
pos: number,
|
|
447
|
-
ic: InsertContext,
|
|
448
|
-
) => ISegmentChanges;
|
|
208
|
+
candidateSegment?: SegmentWithInfo<IInsertionInfo>;
|
|
209
|
+
leaf: (segment: ISegmentLeaf | undefined, pos: number, ic: InsertContext) => ISegmentChanges;
|
|
449
210
|
continuePredicate?: (continueFromBlock: MergeBlock) => boolean;
|
|
450
211
|
}
|
|
451
212
|
|
|
452
|
-
/**
|
|
453
|
-
* @internal
|
|
454
|
-
*/
|
|
455
|
-
export interface SegmentActions<TClientData> {
|
|
456
|
-
leaf?: ISegmentAction<TClientData>;
|
|
457
|
-
shift?: NodeAction<TClientData>;
|
|
458
|
-
contains?: NodeAction<TClientData>;
|
|
459
|
-
pre?: BlockAction<TClientData>;
|
|
460
|
-
post?: BlockAction<TClientData>;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* @internal
|
|
465
|
-
*/
|
|
466
213
|
export interface ObliterateInfo {
|
|
467
214
|
start: LocalReferencePosition;
|
|
468
215
|
end: LocalReferencePosition;
|
|
@@ -473,11 +220,8 @@ export interface ObliterateInfo {
|
|
|
473
220
|
segmentGroup: SegmentGroup | undefined;
|
|
474
221
|
}
|
|
475
222
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
*/
|
|
479
|
-
export interface SegmentGroup<S extends ISegmentInternal = ISegmentInternal> {
|
|
480
|
-
segments: S[];
|
|
223
|
+
export interface SegmentGroup {
|
|
224
|
+
segments: ISegmentLeaf[];
|
|
481
225
|
previousProps?: PropertySet[];
|
|
482
226
|
localSeq?: number;
|
|
483
227
|
refSeq: number;
|
|
@@ -489,13 +233,9 @@ export interface SegmentGroup<S extends ISegmentInternal = ISegmentInternal> {
|
|
|
489
233
|
* the MergeTree always inserts first, then checks for overflow and splits if the child count equals
|
|
490
234
|
* `MaxNodesInBlock`. (i.e., `MaxNodesInBlock` contains 1 extra slot for temporary storage to
|
|
491
235
|
* facilitate splits.)
|
|
492
|
-
* @internal
|
|
493
236
|
*/
|
|
494
237
|
export const MaxNodesInBlock = 8;
|
|
495
|
-
|
|
496
|
-
* @internal
|
|
497
|
-
*/
|
|
498
|
-
export class MergeBlock implements IMergeNodeCommon {
|
|
238
|
+
export class MergeBlock implements Partial<IMergeNodeInfo> {
|
|
499
239
|
public children: IMergeNode[];
|
|
500
240
|
public needsScour?: boolean;
|
|
501
241
|
public parent?: MergeBlock;
|
|
@@ -553,15 +293,22 @@ export class MergeBlock implements IMergeNodeCommon {
|
|
|
553
293
|
index === 0 ? undefined : this.children[index - 1]?.ordinal,
|
|
554
294
|
);
|
|
555
295
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
296
|
+
}
|
|
297
|
+
export function assignChild<C extends IMergeNodeBuilder>(
|
|
298
|
+
parent: MergeBlock,
|
|
299
|
+
child: C,
|
|
300
|
+
index: number,
|
|
301
|
+
updateOrdinal = true,
|
|
302
|
+
): asserts child is C & IMergeNodeInfo {
|
|
303
|
+
const node = Object.assign<C, IMergeNodeInfo>(child, {
|
|
304
|
+
parent,
|
|
305
|
+
index,
|
|
306
|
+
ordinal: hasProp(child, "ordinal", "string") ? child.ordinal : "",
|
|
307
|
+
});
|
|
308
|
+
if (updateOrdinal) {
|
|
309
|
+
parent.setOrdinal(node, index);
|
|
310
|
+
}
|
|
311
|
+
parent.children[index] = node;
|
|
565
312
|
}
|
|
566
313
|
|
|
567
314
|
export function seqLTE(seq: number, minOrRefSeq: number): boolean {
|
|
@@ -573,46 +320,6 @@ export function seqLTE(seq: number, minOrRefSeq: number): boolean {
|
|
|
573
320
|
* @alpha
|
|
574
321
|
*/
|
|
575
322
|
export abstract class BaseSegment implements ISegment {
|
|
576
|
-
/**
|
|
577
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
578
|
-
*/
|
|
579
|
-
public clientId: number = LocalClientId;
|
|
580
|
-
/**
|
|
581
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
582
|
-
*/
|
|
583
|
-
public seq: number = UniversalSequenceNumber;
|
|
584
|
-
/**
|
|
585
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
586
|
-
*/
|
|
587
|
-
public removedSeq?: number;
|
|
588
|
-
/**
|
|
589
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
590
|
-
*/
|
|
591
|
-
public removedClientIds?: number[];
|
|
592
|
-
/**
|
|
593
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
594
|
-
*/
|
|
595
|
-
public movedSeq?: number;
|
|
596
|
-
/**
|
|
597
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
598
|
-
*/
|
|
599
|
-
public movedSeqs?: number[];
|
|
600
|
-
/**
|
|
601
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
602
|
-
*/
|
|
603
|
-
public movedClientIds?: number[];
|
|
604
|
-
/**
|
|
605
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
606
|
-
*/
|
|
607
|
-
public wasMovedOnInsert?: boolean | undefined;
|
|
608
|
-
/**
|
|
609
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
610
|
-
*/
|
|
611
|
-
public index: number = 0;
|
|
612
|
-
/**
|
|
613
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
614
|
-
*/
|
|
615
|
-
public ordinal: string = "";
|
|
616
323
|
public cachedLength: number = 0;
|
|
617
324
|
|
|
618
325
|
public readonly trackingCollection: TrackingGroupCollection = new TrackingGroupCollection(
|
|
@@ -622,25 +329,7 @@ export abstract class BaseSegment implements ISegment {
|
|
|
622
329
|
public attribution?: IAttributionCollection<AttributionKey>;
|
|
623
330
|
|
|
624
331
|
public properties?: PropertySet;
|
|
625
|
-
/**
|
|
626
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
627
|
-
*/
|
|
628
|
-
// eslint-disable-next-line import/no-deprecated
|
|
629
|
-
public localRefs?: LocalReferenceCollection;
|
|
630
332
|
public abstract readonly type: string;
|
|
631
|
-
/**
|
|
632
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
633
|
-
*/
|
|
634
|
-
public localSeq?: number;
|
|
635
|
-
/**
|
|
636
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
637
|
-
*/
|
|
638
|
-
public localRemovedSeq?: number;
|
|
639
|
-
/**
|
|
640
|
-
* @deprecated - This property will be removed in 2.20 with no replacement.
|
|
641
|
-
*/
|
|
642
|
-
public localMovedSeq?: number;
|
|
643
|
-
|
|
644
333
|
public constructor(properties?: PropertySet) {
|
|
645
334
|
if (properties !== undefined) {
|
|
646
335
|
this.properties = clone(properties);
|
|
@@ -656,18 +345,30 @@ export abstract class BaseSegment implements ISegment {
|
|
|
656
345
|
}
|
|
657
346
|
|
|
658
347
|
protected cloneInto(b: ISegment): void {
|
|
659
|
-
|
|
348
|
+
const seg: ISegmentPrivate = b;
|
|
349
|
+
if (isInserted(this)) {
|
|
350
|
+
overwriteInfo<IInsertionInfo>(seg, {
|
|
351
|
+
clientId: this.clientId,
|
|
352
|
+
seq: this.seq,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
660
355
|
// TODO: deep clone properties
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
356
|
+
seg.properties = clone(this.properties);
|
|
357
|
+
if (isRemoved(this)) {
|
|
358
|
+
overwriteInfo<IRemovalInfo>(seg, {
|
|
359
|
+
removedSeq: this.removedSeq,
|
|
360
|
+
removedClientIds: [...this.removedClientIds],
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
if (isMoved(this)) {
|
|
364
|
+
overwriteInfo<IMoveInfo>(seg, {
|
|
365
|
+
movedSeq: this.movedSeq,
|
|
366
|
+
movedSeqs: [...this.movedSeqs],
|
|
367
|
+
wasMovedOnInsert: this.wasMovedOnInsert,
|
|
368
|
+
movedClientIds: [...this.movedClientIds],
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
seg.attribution = this.attribution?.clone();
|
|
671
372
|
}
|
|
672
373
|
|
|
673
374
|
public canAppend(segment: ISegment): boolean {
|
|
@@ -689,35 +390,49 @@ export abstract class BaseSegment implements ISegment {
|
|
|
689
390
|
return undefined;
|
|
690
391
|
}
|
|
691
392
|
|
|
692
|
-
const leafSegment:
|
|
393
|
+
const leafSegment: ISegmentPrivate | undefined = this.createSplitSegmentAt(pos);
|
|
693
394
|
|
|
694
395
|
if (!leafSegment) {
|
|
695
396
|
return undefined;
|
|
696
397
|
}
|
|
697
398
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
399
|
+
if (isMergeNode(this)) {
|
|
400
|
+
overwriteInfo<IMergeNodeInfo>(leafSegment, {
|
|
401
|
+
index: this.index + 1,
|
|
402
|
+
// Give the leaf a temporary yet valid ordinal.
|
|
403
|
+
// when this segment is put in the tree, it will get its real ordinal,
|
|
404
|
+
// but this ordinal meets all the necessary invariants for now.
|
|
405
|
+
// Ordinals exist purely for lexicographical sort order and use a small set of valid bytes for each string character.
|
|
406
|
+
// The extra handling fromCodePoint has for things like surrogate pairs is therefore unnecessary.
|
|
407
|
+
// eslint-disable-next-line unicorn/prefer-code-point
|
|
408
|
+
ordinal: this.ordinal + String.fromCharCode(0),
|
|
409
|
+
parent: this.parent,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (isInserted(this)) {
|
|
414
|
+
overwriteInfo<IInsertionInfo>(leafSegment, {
|
|
415
|
+
seq: this.seq,
|
|
416
|
+
localSeq: this.localSeq,
|
|
417
|
+
clientId: this.clientId,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (isRemoved(this)) {
|
|
421
|
+
overwriteInfo<IRemovalInfo>(leafSegment, {
|
|
422
|
+
removedClientIds: [...this.removedClientIds],
|
|
423
|
+
removedSeq: this.removedSeq,
|
|
424
|
+
localRemovedSeq: this.localRemovedSeq,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
if (isMoved(this)) {
|
|
428
|
+
overwriteInfo<IMoveInfo>(leafSegment, {
|
|
429
|
+
movedClientIds: [...this.movedClientIds],
|
|
430
|
+
movedSeq: this.movedSeq,
|
|
431
|
+
movedSeqs: [...this.movedSeqs],
|
|
432
|
+
localMovedSeq: this.localMovedSeq,
|
|
433
|
+
wasMovedOnInsert: this.wasMovedOnInsert,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
721
436
|
|
|
722
437
|
this.trackingCollection.copyTo(leafSegment);
|
|
723
438
|
if (this.attribution) {
|
|
@@ -732,7 +447,6 @@ export abstract class BaseSegment implements ISegment {
|
|
|
732
447
|
public append(other: ISegment): void {
|
|
733
448
|
// Note: Must call 'appendLocalRefs' before modifying this segment's length as
|
|
734
449
|
// 'this.cachedLength' is used to adjust the offsets of the local refs.
|
|
735
|
-
// eslint-disable-next-line import/no-deprecated
|
|
736
450
|
LocalReferenceCollection.append(this, other);
|
|
737
451
|
if (this.attribution) {
|
|
738
452
|
assert(
|
|
@@ -901,7 +615,7 @@ export class CollaborationWindow {
|
|
|
901
615
|
* { localSeq: 1, seq: UnassignedSequenceNumber, text: "C" },
|
|
902
616
|
* ]
|
|
903
617
|
* ```
|
|
904
|
-
* (note that
|
|
618
|
+
* (note that localSeq tracks the localSeq at which a segment was inserted)
|
|
905
619
|
*
|
|
906
620
|
* Suppose the client then disconnects and reconnects before any of its insertions are acked. The reconnect flow will necessitate
|
|
907
621
|
* that the client regenerates and resubmits ops based on its current segment state as well as the original op that was sent.
|
|
@@ -961,47 +675,3 @@ export const compareNumbers = (a: number, b: number): number => a - b;
|
|
|
961
675
|
* Compares two strings.
|
|
962
676
|
*/
|
|
963
677
|
export const compareStrings = (a: string, b: string): number => a.localeCompare(b);
|
|
964
|
-
|
|
965
|
-
/**
|
|
966
|
-
* Get a human-readable string for a given {@link Marker}.
|
|
967
|
-
*
|
|
968
|
-
* @remarks This function is intended for debugging only. The exact format of
|
|
969
|
-
* this string should not be relied upon between versions.
|
|
970
|
-
* @internal
|
|
971
|
-
*/
|
|
972
|
-
export function debugMarkerToString(marker: Marker): string {
|
|
973
|
-
let bbuf = "";
|
|
974
|
-
if (refTypeIncludesFlag(marker, ReferenceType.Tile)) {
|
|
975
|
-
bbuf += "Tile";
|
|
976
|
-
}
|
|
977
|
-
let lbuf = "";
|
|
978
|
-
const id = marker.getId();
|
|
979
|
-
if (id) {
|
|
980
|
-
bbuf += ` (${id}) `;
|
|
981
|
-
}
|
|
982
|
-
const tileLabels = refGetTileLabels(marker);
|
|
983
|
-
if (tileLabels) {
|
|
984
|
-
lbuf += "tile -- ";
|
|
985
|
-
for (let i = 0, len = tileLabels.length; i < len; i++) {
|
|
986
|
-
const tileLabel = tileLabels[i];
|
|
987
|
-
if (i > 0) {
|
|
988
|
-
lbuf += "; ";
|
|
989
|
-
}
|
|
990
|
-
lbuf += tileLabel;
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
let pbuf = "";
|
|
995
|
-
if (marker.properties) {
|
|
996
|
-
pbuf += JSON.stringify(marker.properties, (key, value) => {
|
|
997
|
-
// Avoid circular reference when stringifying makers containing handles.
|
|
998
|
-
// (Substitute a debug string instead.)
|
|
999
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
1000
|
-
const handle = !!value && value.IFluidHandle;
|
|
1001
|
-
|
|
1002
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
|
|
1003
|
-
return handle ? `#Handle(${handle.routeContext.path}/${handle.path})` : value;
|
|
1004
|
-
});
|
|
1005
|
-
}
|
|
1006
|
-
return `M ${bbuf}: ${lbuf} ${pbuf}`;
|
|
1007
|
-
}
|