@fluidframework/merge-tree 1.2.1 → 2.0.0-internal.1.0.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/DEV.md +2 -2
- package/README.md +1 -1
- package/REFERENCEPOSITIONS.md +2 -2
- package/dist/MergeTreeTextHelper.d.ts +23 -0
- package/dist/MergeTreeTextHelper.d.ts.map +1 -0
- package/dist/MergeTreeTextHelper.js +136 -0
- package/dist/MergeTreeTextHelper.js.map +1 -0
- package/dist/base.d.ts +2 -26
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js.map +1 -1
- package/dist/client.d.ts +21 -12
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +87 -27
- package/dist/client.js.map +1 -1
- package/dist/collections/heap.d.ts +28 -0
- package/dist/collections/heap.d.ts.map +1 -0
- package/dist/collections/heap.js +65 -0
- package/dist/collections/heap.js.map +1 -0
- package/dist/collections/index.d.ts +11 -0
- package/dist/collections/index.d.ts.map +1 -0
- package/dist/collections/index.js +23 -0
- package/dist/collections/index.js.map +1 -0
- package/dist/collections/intervalTree.d.ts +60 -0
- package/dist/collections/intervalTree.d.ts.map +1 -0
- package/dist/collections/intervalTree.js +99 -0
- package/dist/collections/intervalTree.js.map +1 -0
- package/dist/collections/list.d.ts +39 -0
- package/dist/collections/list.d.ts.map +1 -0
- package/dist/collections/list.js +155 -0
- package/dist/collections/list.js.map +1 -0
- package/dist/collections/rbTree.d.ts +154 -0
- package/dist/collections/rbTree.d.ts.map +1 -0
- package/dist/{collections.js → collections/rbTree.js} +10 -448
- package/dist/collections/rbTree.js.map +1 -0
- package/dist/collections/stack.d.ts +16 -0
- package/dist/collections/stack.d.ts.map +1 -0
- package/dist/collections/stack.js +30 -0
- package/dist/collections/stack.js.map +1 -0
- package/dist/collections/tst.d.ts +55 -0
- package/dist/collections/tst.d.ts.map +1 -0
- package/dist/collections/tst.js +171 -0
- package/dist/collections/tst.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/localReference.d.ts +48 -99
- package/dist/localReference.d.ts.map +1 -1
- package/dist/localReference.js +132 -169
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts +38 -299
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +214 -598
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeDeltaCallback.d.ts +1 -1
- package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/dist/mergeTreeDeltaCallback.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +269 -0
- package/dist/mergeTreeNodes.d.ts.map +1 -0
- package/dist/mergeTreeNodes.js +383 -0
- package/dist/mergeTreeNodes.js.map +1 -0
- package/dist/mergeTreeTracking.d.ts +1 -1
- package/dist/mergeTreeTracking.d.ts.map +1 -1
- package/dist/mergeTreeTracking.js.map +1 -1
- package/dist/opBuilder.d.ts +1 -1
- package/dist/opBuilder.d.ts.map +1 -1
- package/dist/opBuilder.js.map +1 -1
- package/dist/partialLengths.d.ts +130 -15
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +230 -138
- package/dist/partialLengths.js.map +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js.map +1 -1
- package/dist/referencePositions.d.ts +6 -26
- package/dist/referencePositions.d.ts.map +1 -1
- package/dist/referencePositions.js.map +1 -1
- package/dist/segmentGroupCollection.d.ts +2 -1
- package/dist/segmentGroupCollection.d.ts.map +1 -1
- package/dist/segmentGroupCollection.js +3 -0
- package/dist/segmentGroupCollection.js.map +1 -1
- package/dist/segmentPropertiesManager.d.ts +10 -1
- package/dist/segmentPropertiesManager.d.ts.map +1 -1
- package/dist/segmentPropertiesManager.js +41 -6
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts +5 -1
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +4 -0
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +1 -1
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/textSegment.d.ts +7 -7
- package/dist/textSegment.d.ts.map +1 -1
- package/dist/textSegment.js +3 -125
- package/dist/textSegment.js.map +1 -1
- package/lib/MergeTreeTextHelper.d.ts +23 -0
- package/lib/MergeTreeTextHelper.d.ts.map +1 -0
- package/lib/MergeTreeTextHelper.js +132 -0
- package/lib/MergeTreeTextHelper.js.map +1 -0
- package/lib/base.d.ts +2 -26
- package/lib/base.d.ts.map +1 -1
- package/lib/base.js.map +1 -1
- package/lib/client.d.ts +21 -12
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +85 -25
- package/lib/client.js.map +1 -1
- package/lib/collections/heap.d.ts +28 -0
- package/lib/collections/heap.d.ts.map +1 -0
- package/lib/collections/heap.js +61 -0
- package/lib/collections/heap.js.map +1 -0
- package/lib/collections/index.d.ts +11 -0
- package/lib/collections/index.d.ts.map +1 -0
- package/lib/collections/index.js +11 -0
- package/lib/collections/index.js.map +1 -0
- package/lib/collections/intervalTree.d.ts +60 -0
- package/lib/collections/intervalTree.d.ts.map +1 -0
- package/lib/collections/intervalTree.js +94 -0
- package/lib/collections/intervalTree.js.map +1 -0
- package/lib/collections/list.d.ts +39 -0
- package/lib/collections/list.d.ts.map +1 -0
- package/lib/collections/list.js +149 -0
- package/lib/collections/list.js.map +1 -0
- package/lib/collections/rbTree.d.ts +154 -0
- package/lib/collections/rbTree.d.ts.map +1 -0
- package/lib/{collections.js → collections/rbTree.js} +9 -439
- package/lib/collections/rbTree.js.map +1 -0
- package/lib/collections/stack.d.ts +16 -0
- package/lib/collections/stack.d.ts.map +1 -0
- package/lib/collections/stack.js +26 -0
- package/lib/collections/stack.js.map +1 -0
- package/lib/collections/tst.d.ts +55 -0
- package/lib/collections/tst.d.ts.map +1 -0
- package/lib/collections/tst.js +167 -0
- package/lib/collections/tst.js.map +1 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/localReference.d.ts +48 -99
- package/lib/localReference.d.ts.map +1 -1
- package/lib/localReference.js +132 -170
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts +38 -299
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +190 -563
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeDeltaCallback.d.ts +1 -1
- package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/lib/mergeTreeDeltaCallback.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +269 -0
- package/lib/mergeTreeNodes.d.ts.map +1 -0
- package/lib/mergeTreeNodes.js +369 -0
- package/lib/mergeTreeNodes.js.map +1 -0
- package/lib/mergeTreeTracking.d.ts +1 -1
- package/lib/mergeTreeTracking.d.ts.map +1 -1
- package/lib/mergeTreeTracking.js.map +1 -1
- package/lib/opBuilder.d.ts +1 -1
- package/lib/opBuilder.d.ts.map +1 -1
- package/lib/opBuilder.js.map +1 -1
- package/lib/partialLengths.d.ts +130 -15
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +227 -135
- package/lib/partialLengths.js.map +1 -1
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js.map +1 -1
- package/lib/referencePositions.d.ts +6 -26
- package/lib/referencePositions.d.ts.map +1 -1
- package/lib/referencePositions.js.map +1 -1
- package/lib/segmentGroupCollection.d.ts +2 -1
- package/lib/segmentGroupCollection.d.ts.map +1 -1
- package/lib/segmentGroupCollection.js +3 -0
- package/lib/segmentGroupCollection.js.map +1 -1
- package/lib/segmentPropertiesManager.d.ts +10 -1
- package/lib/segmentPropertiesManager.d.ts.map +1 -1
- package/lib/segmentPropertiesManager.js +41 -6
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts +5 -1
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +4 -0
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +1 -1
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/textSegment.d.ts +7 -7
- package/lib/textSegment.d.ts.map +1 -1
- package/lib/textSegment.js +1 -122
- package/lib/textSegment.js.map +1 -1
- package/package.json +93 -17
- package/src/MergeTreeTextHelper.ts +172 -0
- package/src/base.ts +2 -35
- package/src/client.ts +114 -30
- package/src/collections/heap.ts +75 -0
- package/src/collections/index.ts +11 -0
- package/src/collections/intervalTree.ts +140 -0
- package/src/collections/list.ts +165 -0
- package/src/{collections.ts → collections/rbTree.ts} +79 -538
- package/src/collections/stack.ts +27 -0
- package/src/collections/tst.ts +212 -0
- package/src/index.ts +8 -2
- package/src/localReference.ts +152 -203
- package/src/mergeTree.ts +265 -868
- package/src/mergeTreeDeltaCallback.ts +1 -1
- package/src/mergeTreeNodes.ts +676 -0
- package/src/mergeTreeTracking.ts +1 -1
- package/src/opBuilder.ts +1 -1
- package/src/partialLengths.ts +295 -150
- package/src/properties.ts +1 -0
- package/src/referencePositions.ts +7 -27
- package/src/segmentGroupCollection.ts +5 -1
- package/src/segmentPropertiesManager.ts +45 -6
- package/src/snapshotLoader.ts +2 -1
- package/src/snapshotV1.ts +2 -2
- package/src/snapshotlegacy.ts +6 -2
- package/src/sortedSegmentSet.ts +1 -1
- package/src/textSegment.ts +10 -157
- package/dist/collections.d.ts +0 -197
- package/dist/collections.d.ts.map +0 -1
- package/dist/collections.js.map +0 -1
- package/lib/collections.d.ts +0 -197
- package/lib/collections.d.ts.map +0 -1
- package/lib/collections.js.map +0 -1
package/DEV.md
CHANGED
|
@@ -10,10 +10,10 @@ These have implications for eventually consistent conflict resolution. Generally
|
|
|
10
10
|
of conflicting insert as handled in the `breakTie` function
|
|
11
11
|
|
|
12
12
|
### Zamboni
|
|
13
|
-
Zamboni is the garbage collection process in the merge tree. As segment change due to inserts and deletes, we add them to a heap which keeps the segment with the lowest sequence number at the head. These segments drive the zamboni process which is also run on every change. The zamboni process peeks at the heap to determine if the head is below the min sequence, then the segment is eligible. The minimum sequence number is important here, as the
|
|
13
|
+
Zamboni is the garbage collection process in the merge tree. As segment change due to inserts and deletes, we add them to a heap which keeps the segment with the lowest sequence number at the head. These segments drive the zamboni process which is also run on every change. The zamboni process peeks at the heap to determine if the head is below the min sequence, then the segment is eligible. The minimum sequence number is important here, as the minimum sequence number is a sequence seen by all clients, and all clients will specify their reference sequence number as above the minimum sequence number. This mean that no new operations can come in that reference anything at or below the minimum sequence number, so we are safe to clean up anything we would need to applying incoming. Eligible segments are collected, and then a few different operations are done, superficially, merge, remove, and tree rebalance. Zamboni is incremental, and only collects a constant number of segments at each change so as not to introduce performance issues.
|
|
14
14
|
|
|
15
15
|
Merge is done if two adjacent segments are of the same type like text, that type is mergable (markers are not), neither are deleted, and all the properties match. The merge process reduces the number of segments, which are leaf nodes of the merge tree. For instance a user may type `c`, `a`, and `t` with each character being it's own operation therefore segment. The user could then highlight that range, and set a property on on all the characters indicating that they are bold, `{bold: true}`. At some later point, these segments would move to the top of th heap, and their sequence numbers would move below the minium sequence number. At that point zamboni could take those individual segments, and merge the into a single segment, `cat` with the property `{bold: true}`
|
|
16
16
|
|
|
17
17
|
Remove is a bit simpler. On removal of a segment, we track it's removed sequence number. When the segment's removed sequence number drops below the minimum sequence number it can be safely removed from the tree.
|
|
18
18
|
|
|
19
|
-
Rebalance is a bit different from merge and remove, as it has to do with maintaining the tree itself. After merge or removal there are fewer segments aka leaf nodes in the tree. This allows us to more efficiently pack the non-leaf node of the tree, and potentially remove layers from the tree. This keeps the tree compact, which has both memory
|
|
19
|
+
Rebalance is a bit different from merge and remove, as it has to do with maintaining the tree itself. After merge or removal there are fewer segments aka leaf nodes in the tree. This allows us to more efficiently pack the non-leaf node of the tree, and potentially remove layers from the tree. This keeps the tree compact, which has both memory and cpu performance implications.
|
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ changes over time.)
|
|
|
35
35
|
|
|
36
36
|
To process operations like insertion and removal, the MergeTree maps positions in the sequence to the containing segment
|
|
37
37
|
and offset of the position within the segment. While the MergeTree implementation uses a B+Tree to accelerate this
|
|
38
|
-
mapping, to understand the semantics of the MergeTree it is easier to consider a
|
|
38
|
+
mapping, to understand the semantics of the MergeTree it is easier to consider a naïve implementation that searches
|
|
39
39
|
for the containing (segment, offset) by walking all segments in order. This naïve search subtracts the length of each
|
|
40
40
|
segment from the desired position until it reaches the segment that contains the remaining offset.
|
|
41
41
|
|
package/REFERENCEPOSITIONS.md
CHANGED
|
@@ -53,7 +53,7 @@ It's position is defined to be `LocalReference.DetachedPosition` (-1).
|
|
|
53
53
|
|
|
54
54
|
LocalReferences may reference removed segments:
|
|
55
55
|
|
|
56
|
-
* SlideOnRemove references may reference a removed segment which is pending (not
|
|
56
|
+
* SlideOnRemove references may reference a removed segment which is pending (not acknowledged)
|
|
57
57
|
* StayOnRemove references may reference removed segments
|
|
58
58
|
* Transient references may reference removed segments
|
|
59
59
|
|
|
@@ -70,7 +70,7 @@ For example, SharedIntervals are built using LocalReferences.
|
|
|
70
70
|
|
|
71
71
|
### Implementing Eventually Consistent LocalReferences
|
|
72
72
|
|
|
73
|
-
To implement an operation which creates LocalReferences which will
|
|
73
|
+
To implement an operation which creates LocalReferences which will have an eventually consistent position:
|
|
74
74
|
|
|
75
75
|
1. Locally create the reference as StayOnRemove
|
|
76
76
|
2. Send the reference numerical position in an op
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { Marker } from "./mergeTreeNodes";
|
|
6
|
+
import { MergeTree } from "./mergeTree";
|
|
7
|
+
import { IMergeTreeTextHelper } from "./textSegment";
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated for internal use only. public export will be removed.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare class MergeTreeTextHelper implements IMergeTreeTextHelper {
|
|
13
|
+
private readonly mergeTree;
|
|
14
|
+
constructor(mergeTree: MergeTree);
|
|
15
|
+
getTextAndMarkers(refSeq: number, clientId: number, label: string, start?: number, end?: number): {
|
|
16
|
+
parallelText: string[];
|
|
17
|
+
parallelMarkers: Marker[];
|
|
18
|
+
};
|
|
19
|
+
getText(refSeq: number, clientId: number, placeholder?: string, start?: number, end?: number): string;
|
|
20
|
+
private getValidRange;
|
|
21
|
+
private readonly gatherText;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=MergeTreeTextHelper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MergeTreeTextHelper.d.ts","sourceRoot":"","sources":["../src/MergeTreeTextHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAY,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAe,MAAM,eAAe,CAAC;AAsBlE;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,oBAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAE1C,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;;;;IAsB/F,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,SAAK,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAe/F,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAkFzB;CACL"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.MergeTreeTextHelper = void 0;
|
|
8
|
+
const referencePositions_1 = require("./referencePositions");
|
|
9
|
+
const textSegment_1 = require("./textSegment");
|
|
10
|
+
function isTextAndMarkerAccumulator(accum) {
|
|
11
|
+
return accum.parallelArrays === true;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated for internal use only. public export will be removed.
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
class MergeTreeTextHelper {
|
|
18
|
+
constructor(mergeTree) {
|
|
19
|
+
this.mergeTree = mergeTree;
|
|
20
|
+
this.gatherText = (segment, pos, refSeq, clientId, start, end, accumText) => {
|
|
21
|
+
var _a, _b;
|
|
22
|
+
let _start = start;
|
|
23
|
+
if (textSegment_1.TextSegment.is(segment)) {
|
|
24
|
+
let beginTags = "";
|
|
25
|
+
let endTags = "";
|
|
26
|
+
if (isTextAndMarkerAccumulator(accumText)) {
|
|
27
|
+
// TODO: let clients pass in function to get tag
|
|
28
|
+
const tags = [];
|
|
29
|
+
const initTags = [];
|
|
30
|
+
if ((_a = segment.properties) === null || _a === void 0 ? void 0 : _a["font-weight"]) {
|
|
31
|
+
tags.push("b");
|
|
32
|
+
}
|
|
33
|
+
if ((_b = segment.properties) === null || _b === void 0 ? void 0 : _b["text-decoration"]) {
|
|
34
|
+
tags.push("u");
|
|
35
|
+
}
|
|
36
|
+
const remTags = [];
|
|
37
|
+
if (tags.length > 0) {
|
|
38
|
+
for (const tag of tags) {
|
|
39
|
+
if (!accumText.tagsInProgress.includes(tag)) {
|
|
40
|
+
beginTags += `<${tag}>`;
|
|
41
|
+
initTags.push(tag);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const accumTag of accumText.tagsInProgress) {
|
|
45
|
+
if (!tags.includes(accumTag)) {
|
|
46
|
+
endTags += `</${accumTag}>`;
|
|
47
|
+
remTags.push(accumTag);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const initTag of initTags.reverse()) {
|
|
51
|
+
accumText.tagsInProgress.push(initTag);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
for (const accumTag of accumText.tagsInProgress) {
|
|
56
|
+
endTags += `</${accumTag}>`;
|
|
57
|
+
remTags.push(accumTag);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const remTag of remTags) {
|
|
61
|
+
const remdex = accumText.tagsInProgress.indexOf(remTag);
|
|
62
|
+
if (remdex >= 0) {
|
|
63
|
+
accumText.tagsInProgress.splice(remdex, 1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
accumText.textSegment.text += endTags;
|
|
68
|
+
accumText.textSegment.text += beginTags;
|
|
69
|
+
if ((_start <= 0) && (end >= segment.text.length)) {
|
|
70
|
+
accumText.textSegment.text += segment.text;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
if (_start < 0) {
|
|
74
|
+
_start = 0;
|
|
75
|
+
}
|
|
76
|
+
if (end >= segment.text.length) {
|
|
77
|
+
accumText.textSegment.text += segment.text.substring(_start);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
accumText.textSegment.text += segment.text.substring(_start, end);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
if (accumText.placeholder && (accumText.placeholder.length > 0)) {
|
|
86
|
+
if (accumText.placeholder === "*") {
|
|
87
|
+
const marker = segment;
|
|
88
|
+
accumText.textSegment.text += `\n${marker.toString()}`;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
for (let i = 0; i < segment.cachedLength; i++) {
|
|
92
|
+
accumText.textSegment.text += accumText.placeholder;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (isTextAndMarkerAccumulator(accumText)) {
|
|
97
|
+
const marker = segment;
|
|
98
|
+
if ((0, referencePositions_1.refHasTileLabel)(marker, accumText.parallelMarkerLabel)) {
|
|
99
|
+
accumText.parallelMarkers.push(marker);
|
|
100
|
+
accumText.parallelText.push(accumText.textSegment.text);
|
|
101
|
+
accumText.textSegment.text = "";
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
getTextAndMarkers(refSeq, clientId, label, start, end) {
|
|
109
|
+
const range = this.getValidRange(start, end, refSeq, clientId);
|
|
110
|
+
const accum = {
|
|
111
|
+
parallelArrays: true,
|
|
112
|
+
parallelMarkerLabel: label,
|
|
113
|
+
parallelMarkers: [],
|
|
114
|
+
parallelText: [],
|
|
115
|
+
tagsInProgress: [],
|
|
116
|
+
textSegment: new textSegment_1.TextSegment(""),
|
|
117
|
+
};
|
|
118
|
+
this.mergeTree.mapRange({ leaf: this.gatherText }, refSeq, clientId, accum, range.start, range.end);
|
|
119
|
+
return { parallelText: accum.parallelText, parallelMarkers: accum.parallelMarkers };
|
|
120
|
+
}
|
|
121
|
+
getText(refSeq, clientId, placeholder = "", start, end) {
|
|
122
|
+
const range = this.getValidRange(start, end, refSeq, clientId);
|
|
123
|
+
const accum = { textSegment: new textSegment_1.TextSegment(""), placeholder };
|
|
124
|
+
this.mergeTree.mapRange({ leaf: this.gatherText }, refSeq, clientId, accum, range.start, range.end);
|
|
125
|
+
return accum.textSegment.text;
|
|
126
|
+
}
|
|
127
|
+
getValidRange(start, end, refSeq, clientId) {
|
|
128
|
+
const range = {
|
|
129
|
+
end: end !== null && end !== void 0 ? end : this.mergeTree.getLength(refSeq, clientId),
|
|
130
|
+
start: start !== null && start !== void 0 ? start : 0,
|
|
131
|
+
};
|
|
132
|
+
return range;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.MergeTreeTextHelper = MergeTreeTextHelper;
|
|
136
|
+
//# sourceMappingURL=MergeTreeTextHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MergeTreeTextHelper.js","sourceRoot":"","sources":["../src/MergeTreeTextHelper.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,6DAAuD;AAEvD,+CAAkE;AAgBlE,SAAS,0BAA0B,CAAC,KAAuB;IACvD,OAAO,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC;AACzC,CAAC;AAID;;;GAGG;AACH,MAAa,mBAAmB;IAC5B,YAA6B,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;QAoDhC,eAAU,GAAG,CAAC,OAAiB,EAAE,GAAW,EAAE,MAAc,EAAE,QAAgB,EAAE,KAAa,EAC1G,GAAW,EAAE,SAA+B,EAAE,EAAE;;YAChD,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAI,yBAAW,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE;gBACzB,IAAI,SAAS,GAAG,EAAE,CAAC;gBACnB,IAAI,OAAO,GAAG,EAAE,CAAC;gBACjB,IAAI,0BAA0B,CAAC,SAAS,CAAC,EAAE;oBACvC,gDAAgD;oBAChD,MAAM,IAAI,GAAG,EAAc,CAAC;oBAC5B,MAAM,QAAQ,GAAG,EAAc,CAAC;oBAEhC,IAAI,MAAA,OAAO,CAAC,UAAU,0CAAG,aAAa,CAAC,EAAE;wBACrC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;qBAClB;oBACD,IAAI,MAAA,OAAO,CAAC,UAAU,0CAAG,iBAAiB,CAAC,EAAE;wBACzC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;qBAClB;oBACD,MAAM,OAAO,GAAG,EAAc,CAAC;oBAC/B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;wBACjB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;4BACpB,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gCACzC,SAAS,IAAI,IAAI,GAAG,GAAG,CAAC;gCACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;6BACtB;yBACJ;wBACD,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,cAAc,EAAE;4BAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;gCAC1B,OAAO,IAAI,KAAK,QAAQ,GAAG,CAAC;gCAC5B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;6BAC1B;yBACJ;wBACD,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE;4BACtC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;yBAC1C;qBACJ;yBAAM;wBACH,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,cAAc,EAAE;4BAC7C,OAAO,IAAI,KAAK,QAAQ,GAAG,CAAC;4BAC5B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;yBAC1B;qBACJ;oBACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;wBAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;wBACxD,IAAI,MAAM,IAAI,CAAC,EAAE;4BACb,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;yBAC9C;qBACJ;iBACJ;gBACD,SAAS,CAAC,WAAW,CAAC,IAAI,IAAI,OAAO,CAAC;gBACtC,SAAS,CAAC,WAAW,CAAC,IAAI,IAAI,SAAS,CAAC;gBACxC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;oBAC/C,SAAS,CAAC,WAAW,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;iBAC9C;qBAAM;oBACH,IAAI,MAAM,GAAG,CAAC,EAAE;wBACZ,MAAM,GAAG,CAAC,CAAC;qBACd;oBACD,IAAI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE;wBAC5B,SAAS,CAAC,WAAW,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;qBAChE;yBAAM;wBACH,SAAS,CAAC,WAAW,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;qBACrE;iBACJ;aACJ;iBAAM;gBACH,IAAI,SAAS,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;oBAC7D,IAAI,SAAS,CAAC,WAAW,KAAK,GAAG,EAAE;wBAC/B,MAAM,MAAM,GAAG,OAAiB,CAAC;wBACjC,SAAS,CAAC,WAAW,CAAC,IAAI,IAAI,KAAK,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;qBAC1D;yBAAM;wBACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE;4BAC3C,SAAS,CAAC,WAAW,CAAC,IAAI,IAAI,SAAS,CAAC,WAAW,CAAC;yBACvD;qBACJ;iBACJ;qBAAM,IAAI,0BAA0B,CAAC,SAAS,CAAC,EAAE;oBAC9C,MAAM,MAAM,GAAG,OAAiB,CAAC;oBACjC,IAAI,IAAA,oCAAe,EAAC,MAAM,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE;wBACxD,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;wBACvC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;wBACxD,SAAS,CAAC,WAAW,CAAC,IAAI,GAAG,EAAE,CAAC;qBACnC;iBACJ;aACJ;YAED,OAAO,IAAI,CAAC;QAChB,CAAC,CAAC;IAtImD,CAAC;IAE/C,iBAAiB,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAa,EAAE,KAAc,EAAE,GAAY;QAClG,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/D,MAAM,KAAK,GAA8B;YACrC,cAAc,EAAE,IAAI;YACpB,mBAAmB,EAAE,KAAK;YAC1B,eAAe,EAAE,EAAE;YACnB,YAAY,EAAE,EAAE;YAChB,cAAc,EAAE,EAAE;YAClB,WAAW,EAAE,IAAI,yBAAW,CAAC,EAAE,CAAC;SACnC,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,QAAQ,CACnB,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,EACzB,MAAM,EACN,QAAQ,EACR,KAAK,EACL,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,GAAG,CAAC,CAAC;QAEf,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,CAAC;IACxF,CAAC;IAEM,OAAO,CAAC,MAAc,EAAE,QAAgB,EAAE,WAAW,GAAG,EAAE,EAAE,KAAc,EAAE,GAAY;QAC3F,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAE/D,MAAM,KAAK,GAAqB,EAAE,WAAW,EAAE,IAAI,yBAAW,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;QAElF,IAAI,CAAC,SAAS,CAAC,QAAQ,CACnB,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,EACzB,MAAM,EACN,QAAQ,EACR,KAAK,EACL,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,GAAG,CAAC,CAAC;QACf,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC;IAClC,CAAC;IAEO,aAAa,CACjB,KAAyB,EACzB,GAAuB,EACvB,MAAc,EACd,QAAgB;QAEhB,MAAM,KAAK,GAAkB;YACzB,GAAG,EAAE,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC;YACtD,KAAK,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,CAAC;SACpB,CAAC;QACF,OAAO,KAAK,CAAC;IACjB,CAAC;CAqFJ;AAxID,kDAwIC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IIntegerRange } from \"./base\";\nimport { ISegment, Marker } from \"./mergeTreeNodes\";\nimport { refHasTileLabel } from \"./referencePositions\";\nimport { MergeTree } from \"./mergeTree\";\nimport { IMergeTreeTextHelper, TextSegment } from \"./textSegment\";\n\ninterface ITextAccumulator {\n textSegment: TextSegment;\n placeholder?: string;\n parallelArrays?: boolean;\n}\n\ninterface ITextAndMarkerAccumulator extends ITextAccumulator {\n parallelArrays: true;\n parallelText: string[];\n parallelMarkers: Marker[];\n parallelMarkerLabel: string;\n tagsInProgress: string[];\n}\n\nfunction isTextAndMarkerAccumulator(accum: ITextAccumulator): accum is ITextAndMarkerAccumulator {\n return accum.parallelArrays === true;\n}\n\ntype ITextAccumulatorType = ITextAccumulator | ITextAndMarkerAccumulator;\n\n/**\n * @deprecated for internal use only. public export will be removed.\n * @internal\n */\nexport class MergeTreeTextHelper implements IMergeTreeTextHelper {\n constructor(private readonly mergeTree: MergeTree) { }\n\n public getTextAndMarkers(refSeq: number, clientId: number, label: string, start?: number, end?: number) {\n const range = this.getValidRange(start, end, refSeq, clientId);\n const accum: ITextAndMarkerAccumulator = {\n parallelArrays: true,\n parallelMarkerLabel: label,\n parallelMarkers: [],\n parallelText: [],\n tagsInProgress: [],\n textSegment: new TextSegment(\"\"),\n };\n\n this.mergeTree.mapRange<ITextAndMarkerAccumulator>(\n { leaf: this.gatherText },\n refSeq,\n clientId,\n accum,\n range.start,\n range.end);\n\n return { parallelText: accum.parallelText, parallelMarkers: accum.parallelMarkers };\n }\n\n public getText(refSeq: number, clientId: number, placeholder = \"\", start?: number, end?: number) {\n const range = this.getValidRange(start, end, refSeq, clientId);\n\n const accum: ITextAccumulator = { textSegment: new TextSegment(\"\"), placeholder };\n\n this.mergeTree.mapRange<ITextAccumulator>(\n { leaf: this.gatherText },\n refSeq,\n clientId,\n accum,\n range.start,\n range.end);\n return accum.textSegment.text;\n }\n\n private getValidRange(\n start: number | undefined,\n end: number | undefined,\n refSeq: number,\n clientId: number,\n ): IIntegerRange {\n const range: IIntegerRange = {\n end: end ?? this.mergeTree.getLength(refSeq, clientId),\n start: start ?? 0,\n };\n return range;\n }\n\n private readonly gatherText = (segment: ISegment, pos: number, refSeq: number, clientId: number, start: number,\n end: number, accumText: ITextAccumulatorType) => {\n let _start = start;\n if (TextSegment.is(segment)) {\n let beginTags = \"\";\n let endTags = \"\";\n if (isTextAndMarkerAccumulator(accumText)) {\n // TODO: let clients pass in function to get tag\n const tags = [] as string[];\n const initTags = [] as string[];\n\n if (segment.properties?.[\"font-weight\"]) {\n tags.push(\"b\");\n }\n if (segment.properties?.[\"text-decoration\"]) {\n tags.push(\"u\");\n }\n const remTags = [] as string[];\n if (tags.length > 0) {\n for (const tag of tags) {\n if (!accumText.tagsInProgress.includes(tag)) {\n beginTags += `<${tag}>`;\n initTags.push(tag);\n }\n }\n for (const accumTag of accumText.tagsInProgress) {\n if (!tags.includes(accumTag)) {\n endTags += `</${accumTag}>`;\n remTags.push(accumTag);\n }\n }\n for (const initTag of initTags.reverse()) {\n accumText.tagsInProgress.push(initTag);\n }\n } else {\n for (const accumTag of accumText.tagsInProgress) {\n endTags += `</${accumTag}>`;\n remTags.push(accumTag);\n }\n }\n for (const remTag of remTags) {\n const remdex = accumText.tagsInProgress.indexOf(remTag);\n if (remdex >= 0) {\n accumText.tagsInProgress.splice(remdex, 1);\n }\n }\n }\n accumText.textSegment.text += endTags;\n accumText.textSegment.text += beginTags;\n if ((_start <= 0) && (end >= segment.text.length)) {\n accumText.textSegment.text += segment.text;\n } else {\n if (_start < 0) {\n _start = 0;\n }\n if (end >= segment.text.length) {\n accumText.textSegment.text += segment.text.substring(_start);\n } else {\n accumText.textSegment.text += segment.text.substring(_start, end);\n }\n }\n } else {\n if (accumText.placeholder && (accumText.placeholder.length > 0)) {\n if (accumText.placeholder === \"*\") {\n const marker = segment as Marker;\n accumText.textSegment.text += `\\n${marker.toString()}`;\n } else {\n for (let i = 0; i < segment.cachedLength; i++) {\n accumText.textSegment.text += accumText.placeholder;\n }\n }\n } else if (isTextAndMarkerAccumulator(accumText)) {\n const marker = segment as Marker;\n if (refHasTileLabel(marker, accumText.parallelMarkerLabel)) {\n accumText.parallelMarkers.push(marker);\n accumText.parallelText.push(accumText.textSegment.text);\n accumText.textSegment.text = \"\";\n }\n }\n }\n\n return true;\n };\n}\n"]}
|
package/dist/base.d.ts
CHANGED
|
@@ -2,33 +2,9 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
export interface Property<TKey, TData> {
|
|
6
|
-
key: TKey;
|
|
7
|
-
data: TData;
|
|
8
|
-
}
|
|
9
|
-
export interface QProperty<TKey, TData> {
|
|
10
|
-
key?: TKey;
|
|
11
|
-
data?: TData;
|
|
12
|
-
}
|
|
13
|
-
export interface PropertyAction<TKey, TData> {
|
|
14
|
-
<TAccum>(p: Property<TKey, TData>, accum?: TAccum): boolean;
|
|
15
|
-
}
|
|
16
|
-
export declare type ConflictAction<TKey, TData> = (key: TKey, currentKey: TKey, data: TData, currentData: TData) => QProperty<TKey, TData>;
|
|
17
|
-
export interface Dictionary<TKey, TData> {
|
|
18
|
-
get(key: TKey): Property<TKey, TData> | undefined;
|
|
19
|
-
put(key: TKey, data: TData, conflict?: ConflictAction<TKey, TData>): void;
|
|
20
|
-
remove(key: TKey): void;
|
|
21
|
-
map<TAccum>(action: PropertyAction<TKey, TData>, accum?: TAccum): void;
|
|
22
|
-
}
|
|
23
|
-
export interface SortedDictionary<TKey, TData> extends Dictionary<TKey, TData> {
|
|
24
|
-
max(): Property<TKey, TData> | undefined;
|
|
25
|
-
min(): Property<TKey, TData> | undefined;
|
|
26
|
-
mapRange<TAccum>(action: PropertyAction<TKey, TData>, accum?: TAccum, start?: TKey, end?: TKey): void;
|
|
27
|
-
}
|
|
28
|
-
export interface KeyComparer<TKey> {
|
|
29
|
-
(a: TKey, b: TKey): number;
|
|
30
|
-
}
|
|
31
5
|
/**
|
|
6
|
+
* @deprecated for internal use only. public export will be removed.
|
|
7
|
+
* @internal
|
|
32
8
|
* A range [start, end)
|
|
33
9
|
*/
|
|
34
10
|
export interface IIntegerRange {
|
package/dist/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACf"}
|
package/dist/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * @deprecated for internal use only. public export will be removed.\n * @internal\n * A range [start, end)\n */\nexport interface IIntegerRange {\n start: number;\n end: number;\n}\n"]}
|
package/dist/client.d.ts
CHANGED
|
@@ -8,13 +8,14 @@ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions"
|
|
|
8
8
|
import { IFluidDataStoreRuntime, IChannelStorageService } from "@fluidframework/datastore-definitions";
|
|
9
9
|
import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
|
|
10
10
|
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
11
|
-
import {
|
|
12
|
-
import { CollaborationWindow, ISegment, ISegmentAction, Marker,
|
|
11
|
+
import { LocalReferencePosition } from "./localReference";
|
|
12
|
+
import { CollaborationWindow, ISegment, ISegmentAction, Marker, SegmentGroup } from "./mergeTreeNodes";
|
|
13
13
|
import { MergeTreeDeltaCallback } from "./mergeTreeDeltaCallback";
|
|
14
14
|
import { ICombiningOp, IJSONSegment, IMergeTreeAnnotateMsg, IMergeTreeDeltaOp, IMergeTreeGroupMsg, IMergeTreeInsertMsg, IMergeTreeRemoveMsg, IMergeTreeOp, IRelativePosition, ReferenceType } from "./ops";
|
|
15
15
|
import { PropertySet } from "./properties";
|
|
16
|
-
import {
|
|
16
|
+
import { IMergeTreeTextHelper } from "./textSegment";
|
|
17
17
|
import { ReferencePosition, RangeStackMap } from "./referencePositions";
|
|
18
|
+
import { MergeTree } from "./mergeTree";
|
|
18
19
|
import { MergeTreeMaintenanceCallback } from "./index";
|
|
19
20
|
export declare class Client {
|
|
20
21
|
readonly specToSegment: (spec: IJSONSegment) => ISegment;
|
|
@@ -32,6 +33,10 @@ export declare class Client {
|
|
|
32
33
|
set mergeTreeDeltaCallback(callback: MergeTreeDeltaCallback | undefined);
|
|
33
34
|
get mergeTreeMaintenanceCallback(): MergeTreeMaintenanceCallback | undefined;
|
|
34
35
|
set mergeTreeMaintenanceCallback(callback: MergeTreeMaintenanceCallback | undefined);
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated for internal use only. public export will be removed.
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
35
40
|
protected readonly mergeTree: MergeTree;
|
|
36
41
|
private readonly clientNameToIds;
|
|
37
42
|
private readonly shortClientIdMap;
|
|
@@ -102,14 +107,6 @@ export declare class Client {
|
|
|
102
107
|
* @param segment - The segment to get the position of
|
|
103
108
|
*/
|
|
104
109
|
getPosition(segment: ISegment): number;
|
|
105
|
-
/**
|
|
106
|
-
* @deprecated - use createReferencePosition instead
|
|
107
|
-
*/
|
|
108
|
-
addLocalReference(lref: LocalReference): void;
|
|
109
|
-
/**
|
|
110
|
-
* @deprecated - use removeReferencePosition instead
|
|
111
|
-
*/
|
|
112
|
-
removeLocalReference(lref: LocalReference): LocalReferencePosition | undefined;
|
|
113
110
|
createLocalReferencePosition(segment: ISegment, offset: number | undefined, refType: ReferenceType, properties: PropertySet | undefined): LocalReferencePosition;
|
|
114
111
|
removeLocalReferencePosition(lref: LocalReferencePosition): LocalReferencePosition | undefined;
|
|
115
112
|
localReferencePositionToPosition(lref: ReferencePosition): number;
|
|
@@ -120,6 +117,14 @@ export declare class Client {
|
|
|
120
117
|
*/
|
|
121
118
|
posFromRelativePos(relativePos: IRelativePosition): number;
|
|
122
119
|
getMarkerFromId(id: string): ISegment | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* Revert an op
|
|
122
|
+
*/
|
|
123
|
+
rollback?(op: any, localOpMetadata: unknown): void;
|
|
124
|
+
/**
|
|
125
|
+
* Walk the segments up to the current segment and calculate its position
|
|
126
|
+
*/
|
|
127
|
+
private findRollbackPosition;
|
|
123
128
|
/**
|
|
124
129
|
* Performs the remove based on the provided op
|
|
125
130
|
* @param opArgs - The ops args for the op
|
|
@@ -210,11 +215,15 @@ export declare class Client {
|
|
|
210
215
|
* @param segmentGroup - The segment group associated with the op
|
|
211
216
|
*/
|
|
212
217
|
regeneratePendingOp(resetOp: IMergeTreeOp, segmentGroup: SegmentGroup | SegmentGroup[]): IMergeTreeOp;
|
|
213
|
-
createTextHelper():
|
|
218
|
+
createTextHelper(): IMergeTreeTextHelper;
|
|
214
219
|
summarize(runtime: IFluidDataStoreRuntime, handle: IFluidHandle, serializer: IFluidSerializer, catchUpMsgs: ISequencedDocumentMessage[]): ISummaryTreeWithStats;
|
|
215
220
|
load(runtime: IFluidDataStoreRuntime, storage: IChannelStorageService, serializer: IFluidSerializer): Promise<{
|
|
216
221
|
catchupOpsP: Promise<ISequencedDocumentMessage[]>;
|
|
217
222
|
}>;
|
|
223
|
+
/**
|
|
224
|
+
* @deprecated for internal use only. public export will be removed.
|
|
225
|
+
* @internal
|
|
226
|
+
*/
|
|
218
227
|
getStackContext(startPos: number, rangeLabels: string[]): RangeStackMap;
|
|
219
228
|
private getLocalSequenceNumber;
|
|
220
229
|
localTransaction(groupOp: IMergeTreeGroupMsg): void;
|
package/dist/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,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AACvG,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAMtE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -10,14 +10,16 @@ const common_utils_1 = require("@fluidframework/common-utils");
|
|
|
10
10
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
11
11
|
const collections_1 = require("./collections");
|
|
12
12
|
const constants_1 = require("./constants");
|
|
13
|
-
const
|
|
14
|
-
const mergeTree_1 = require("./mergeTree");
|
|
13
|
+
const mergeTreeNodes_1 = require("./mergeTreeNodes");
|
|
15
14
|
const opBuilder_1 = require("./opBuilder");
|
|
16
15
|
const ops_1 = require("./ops");
|
|
16
|
+
const segmentPropertiesManager_1 = require("./segmentPropertiesManager");
|
|
17
17
|
const snapshotlegacy_1 = require("./snapshotlegacy");
|
|
18
18
|
const snapshotLoader_1 = require("./snapshotLoader");
|
|
19
|
-
const textSegment_1 = require("./textSegment");
|
|
20
19
|
const snapshotV1_1 = require("./snapshotV1");
|
|
20
|
+
const referencePositions_1 = require("./referencePositions");
|
|
21
|
+
const mergeTree_1 = require("./mergeTree");
|
|
22
|
+
const MergeTreeTextHelper_1 = require("./MergeTreeTextHelper");
|
|
21
23
|
function elapsedMicroseconds(trace) {
|
|
22
24
|
return trace.trace().duration * 1000;
|
|
23
25
|
}
|
|
@@ -35,7 +37,7 @@ class Client {
|
|
|
35
37
|
this.accumWindow = 0;
|
|
36
38
|
this.accumOps = 0;
|
|
37
39
|
this.maxWindowTime = 0;
|
|
38
|
-
this.clientNameToIds = new collections_1.RedBlackTree(
|
|
40
|
+
this.clientNameToIds = new collections_1.RedBlackTree(mergeTreeNodes_1.compareStrings);
|
|
39
41
|
this.shortClientIdMap = [];
|
|
40
42
|
this.pendingConsensus = new Map();
|
|
41
43
|
this.mergeTree = new mergeTree_1.MergeTree(options);
|
|
@@ -159,7 +161,7 @@ class Client {
|
|
|
159
161
|
*/
|
|
160
162
|
insertAtReferencePositionLocal(refPos, segment) {
|
|
161
163
|
const pos = this.mergeTree.referencePositionToLocalPosition(refPos, this.getCurrentSeq(), this.getClientId());
|
|
162
|
-
if (pos ===
|
|
164
|
+
if (pos === referencePositions_1.DetachedReferencePosition) {
|
|
163
165
|
return undefined;
|
|
164
166
|
}
|
|
165
167
|
const op = (0, opBuilder_1.createInsertSegmentOp)(pos, segment);
|
|
@@ -205,20 +207,8 @@ class Client {
|
|
|
205
207
|
}
|
|
206
208
|
return this.mergeTree.getPosition(segment, this.getCurrentSeq(), this.getClientId());
|
|
207
209
|
}
|
|
208
|
-
/**
|
|
209
|
-
* @deprecated - use createReferencePosition instead
|
|
210
|
-
*/
|
|
211
|
-
addLocalReference(lref) {
|
|
212
|
-
return this.mergeTree.addLocalReference(lref);
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* @deprecated - use removeReferencePosition instead
|
|
216
|
-
*/
|
|
217
|
-
removeLocalReference(lref) {
|
|
218
|
-
return this.removeLocalReferencePosition(lref);
|
|
219
|
-
}
|
|
220
210
|
createLocalReferencePosition(segment, offset, refType, properties) {
|
|
221
|
-
return this.mergeTree.createLocalReferencePosition(segment, offset, refType, properties
|
|
211
|
+
return this.mergeTree.createLocalReferencePosition(segment, offset !== null && offset !== void 0 ? offset : 0, refType, properties);
|
|
222
212
|
}
|
|
223
213
|
removeLocalReferencePosition(lref) {
|
|
224
214
|
return this.mergeTree.removeLocalReferencePosition(lref);
|
|
@@ -237,6 +227,59 @@ class Client {
|
|
|
237
227
|
getMarkerFromId(id) {
|
|
238
228
|
return this.mergeTree.getMarkerFromId(id);
|
|
239
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Revert an op
|
|
232
|
+
*/
|
|
233
|
+
rollback(op, localOpMetadata) {
|
|
234
|
+
var _a, _b;
|
|
235
|
+
if (op.type === ops_1.MergeTreeDeltaType.INSERT || op.type === ops_1.MergeTreeDeltaType.ANNOTATE) {
|
|
236
|
+
const pendingSegmentGroup = (_b = (_a = this.mergeTree.pendingSegments) === null || _a === void 0 ? void 0 : _a.pop) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
237
|
+
if (pendingSegmentGroup === undefined || pendingSegmentGroup !== localOpMetadata
|
|
238
|
+
|| (op.type === ops_1.MergeTreeDeltaType.ANNOTATE && !pendingSegmentGroup.previousProps)) {
|
|
239
|
+
throw new Error("Rollback op doesn't match last edit");
|
|
240
|
+
}
|
|
241
|
+
let i = 0;
|
|
242
|
+
for (const segment of pendingSegmentGroup.segments) {
|
|
243
|
+
const segmentSegmentGroup = segment.segmentGroups.pop ? segment.segmentGroups.pop() : undefined;
|
|
244
|
+
(0, common_utils_1.assert)(segmentSegmentGroup === pendingSegmentGroup, 0x347 /* Unexpected segmentGroup in segment */);
|
|
245
|
+
const start = this.findRollbackPosition(segment);
|
|
246
|
+
const segWindow = this.getCollabWindow();
|
|
247
|
+
if (op.type === ops_1.MergeTreeDeltaType.INSERT) {
|
|
248
|
+
const removeOp = (0, opBuilder_1.createRemoveRangeOp)(start, start + segment.cachedLength);
|
|
249
|
+
this.mergeTree.markRangeRemoved(start, start + segment.cachedLength, constants_1.UniversalSequenceNumber, segWindow.clientId, constants_1.UniversalSequenceNumber, false, { op: removeOp });
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
const props = pendingSegmentGroup.previousProps[i];
|
|
253
|
+
const rollbackType = (op.combiningOp && op.combiningOp.name === "rewrite") ?
|
|
254
|
+
segmentPropertiesManager_1.PropertiesRollback.Rewrite : segmentPropertiesManager_1.PropertiesRollback.Rollback;
|
|
255
|
+
const annotateOp = (0, opBuilder_1.createAnnotateRangeOp)(start, start + segment.cachedLength, props, undefined);
|
|
256
|
+
this.mergeTree.annotateRange(start, start + segment.cachedLength, props, undefined, constants_1.UniversalSequenceNumber, segWindow.clientId, constants_1.UniversalSequenceNumber, { op: annotateOp }, rollbackType);
|
|
257
|
+
i++;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
throw new Error("Unsupported op type for rollback");
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Walk the segments up to the current segment and calculate its position
|
|
267
|
+
*/
|
|
268
|
+
findRollbackPosition(segment) {
|
|
269
|
+
let segmentPosition = 0;
|
|
270
|
+
this.mergeTree.walkAllSegments(this.mergeTree.root, (seg) => {
|
|
271
|
+
// If we've found the desired segment, terminate the walk and return 'segmentPosition'.
|
|
272
|
+
if (seg === segment) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
// If not removed, increase position
|
|
276
|
+
if (seg.removedSeq === undefined) {
|
|
277
|
+
segmentPosition += seg.cachedLength;
|
|
278
|
+
}
|
|
279
|
+
return true;
|
|
280
|
+
});
|
|
281
|
+
return segmentPosition;
|
|
282
|
+
}
|
|
240
283
|
/**
|
|
241
284
|
* Performs the remove based on the provided op
|
|
242
285
|
* @param opArgs - The ops args for the op
|
|
@@ -486,8 +529,11 @@ class Client {
|
|
|
486
529
|
findReconnectionPosition(segment, localSeq) {
|
|
487
530
|
(0, common_utils_1.assert)(localSeq <= this.mergeTree.collabWindow.localSeq, 0x032 /* "localSeq greater than collab window" */);
|
|
488
531
|
let segmentPosition = 0;
|
|
532
|
+
const isInsertedInView = (seg) => seg.localSeq === undefined || seg.localSeq <= localSeq;
|
|
533
|
+
const isRemovedFromView = (seg) => seg.removedSeq !== undefined &&
|
|
534
|
+
(seg.removedSeq !== constants_1.UnassignedSequenceNumber || seg.localRemovedSeq <= localSeq);
|
|
489
535
|
/*
|
|
490
|
-
Walk the segments up to the current segment, and calculate
|
|
536
|
+
Walk the segments up to the current segment, and calculate its
|
|
491
537
|
position taking into account local segments that were modified,
|
|
492
538
|
after the current segment.
|
|
493
539
|
|
|
@@ -504,9 +550,7 @@ class Client {
|
|
|
504
550
|
//
|
|
505
551
|
// Note that all ACKed / remote ops are applied and we only need concern ourself with
|
|
506
552
|
// determining if locally pending ops fall before/after the given 'localSeq'.
|
|
507
|
-
if ((seg
|
|
508
|
-
&& (seg.removedSeq === undefined || seg.localRemovedSeq > localSeq) // Not removed
|
|
509
|
-
) {
|
|
553
|
+
if (isInsertedInView(seg) && !isRemovedFromView(seg)) {
|
|
510
554
|
segmentPosition += seg.cachedLength;
|
|
511
555
|
}
|
|
512
556
|
return true;
|
|
@@ -563,7 +607,7 @@ class Client {
|
|
|
563
607
|
// We need to sort the segments by ordinal, as the segments are not sorted in the segment group.
|
|
564
608
|
// The reason they need them sorted, as they have the same local sequence number and which means
|
|
565
609
|
// farther segments will take into account nearer segments when calculating their position.
|
|
566
|
-
// By sorting we ensure the nearer segment will be applied and sequenced before the
|
|
610
|
+
// By sorting we ensure the nearer segment will be applied and sequenced before the farther segments
|
|
567
611
|
// so their recalculated positions will be correct.
|
|
568
612
|
for (const segment of segmentGroup.segments.sort((a, b) => a.ordinal < b.ordinal ? -1 : 1)) {
|
|
569
613
|
const segmentSegGroup = segment.segmentGroups.dequeue();
|
|
@@ -576,7 +620,8 @@ class Client {
|
|
|
576
620
|
// if the segment has been removed, there's no need to send the annotate op
|
|
577
621
|
// unless the remove was local, in which case the annotate must have come
|
|
578
622
|
// before the remove
|
|
579
|
-
if (segment.removedSeq === undefined ||
|
|
623
|
+
if (segment.removedSeq === undefined ||
|
|
624
|
+
(segment.localRemovedSeq !== undefined && segment.removedSeq === constants_1.UnassignedSequenceNumber)) {
|
|
580
625
|
newOp = (0, opBuilder_1.createAnnotateRangeOp)(segmentPosition, segmentPosition + segment.cachedLength, resetOp.props, resetOp.combiningOp);
|
|
581
626
|
}
|
|
582
627
|
break;
|
|
@@ -590,7 +635,7 @@ class Client {
|
|
|
590
635
|
newOp = (0, opBuilder_1.createInsertSegmentOp)(segmentPosition, segInsertOp);
|
|
591
636
|
break;
|
|
592
637
|
case ops_1.MergeTreeDeltaType.REMOVE:
|
|
593
|
-
if (segment.localRemovedSeq !== undefined) {
|
|
638
|
+
if (segment.localRemovedSeq !== undefined && segment.removedSeq === constants_1.UnassignedSequenceNumber) {
|
|
594
639
|
newOp = (0, opBuilder_1.createRemoveRangeOp)(segmentPosition, segmentPosition + segment.cachedLength);
|
|
595
640
|
}
|
|
596
641
|
break;
|
|
@@ -726,7 +771,7 @@ class Client {
|
|
|
726
771
|
return opList.length === 1 ? opList[0] : (0, opBuilder_1.createGroupOp)(...opList);
|
|
727
772
|
}
|
|
728
773
|
createTextHelper() {
|
|
729
|
-
return new
|
|
774
|
+
return new MergeTreeTextHelper_1.MergeTreeTextHelper(this.mergeTree);
|
|
730
775
|
}
|
|
731
776
|
summarize(runtime, handle, serializer, catchUpMsgs) {
|
|
732
777
|
var _a;
|
|
@@ -757,6 +802,10 @@ class Client {
|
|
|
757
802
|
const loader = new snapshotLoader_1.SnapshotLoader(runtime, this, this.mergeTree, this.logger, serializer);
|
|
758
803
|
return loader.initialize(storage);
|
|
759
804
|
}
|
|
805
|
+
/**
|
|
806
|
+
* @deprecated for internal use only. public export will be removed.
|
|
807
|
+
* @internal
|
|
808
|
+
*/
|
|
760
809
|
getStackContext(startPos, rangeLabels) {
|
|
761
810
|
return this.mergeTree.getStackContext(startPos, this.getCollabWindow().clientId, rangeLabels);
|
|
762
811
|
}
|
|
@@ -822,7 +871,18 @@ class Client {
|
|
|
822
871
|
* @returns - segment and offset to slide the reference to
|
|
823
872
|
*/
|
|
824
873
|
getSlideToSegment(segoff) {
|
|
825
|
-
|
|
874
|
+
if (segoff.segment === undefined) {
|
|
875
|
+
return segoff;
|
|
876
|
+
}
|
|
877
|
+
const segment = this.mergeTree._getSlideToSegment(segoff.segment);
|
|
878
|
+
if (segment === segoff.segment) {
|
|
879
|
+
return segoff;
|
|
880
|
+
}
|
|
881
|
+
const offset = segment && segment.ordinal < segoff.segment.ordinal ? segment.cachedLength - 1 : 0;
|
|
882
|
+
return {
|
|
883
|
+
segment,
|
|
884
|
+
offset,
|
|
885
|
+
};
|
|
826
886
|
}
|
|
827
887
|
getPropertiesAtPosition(pos) {
|
|
828
888
|
let propertiesAtPosition;
|