@fluidframework/merge-tree 1.2.2 → 2.0.0-internal.1.0.0.82159
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/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 +69 -21
- 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 +38 -0
- package/dist/collections/list.d.ts.map +1 -0
- package/dist/collections/list.js +151 -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 +140 -171
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts +35 -298
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +197 -594
- 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 +268 -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/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 +1 -1
- package/dist/segmentGroupCollection.d.ts.map +1 -1
- package/dist/segmentGroupCollection.js.map +1 -1
- package/dist/segmentPropertiesManager.js +1 -1
- 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 +3 -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 +68 -20
- 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 +38 -0
- package/lib/collections/list.d.ts.map +1 -0
- package/lib/collections/list.js +145 -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 +140 -172
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts +35 -298
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +172 -558
- 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 +268 -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/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 +1 -1
- package/lib/segmentGroupCollection.d.ts.map +1 -1
- package/lib/segmentGroupCollection.js.map +1 -1
- package/lib/segmentPropertiesManager.js +1 -1
- 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 +3 -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 +92 -16
- package/src/MergeTreeTextHelper.ts +172 -0
- package/src/base.ts +2 -35
- package/src/client.ts +89 -25
- 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 +160 -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 +158 -205
- package/src/mergeTree.ts +241 -863
- package/src/mergeTreeDeltaCallback.ts +1 -1
- package/src/mergeTreeNodes.ts +672 -0
- package/src/mergeTreeTracking.ts +1 -1
- package/src/opBuilder.ts +1 -1
- package/src/partialLengths.ts +295 -150
- package/src/referencePositions.ts +7 -27
- package/src/segmentGroupCollection.ts +1 -1
- package/src/segmentPropertiesManager.ts +1 -1
- 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 +6 -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.
|
|
@@ -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":"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","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,15 @@ 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");
|
|
17
16
|
const snapshotlegacy_1 = require("./snapshotlegacy");
|
|
18
17
|
const snapshotLoader_1 = require("./snapshotLoader");
|
|
19
|
-
const textSegment_1 = require("./textSegment");
|
|
20
18
|
const snapshotV1_1 = require("./snapshotV1");
|
|
19
|
+
const referencePositions_1 = require("./referencePositions");
|
|
20
|
+
const mergeTree_1 = require("./mergeTree");
|
|
21
|
+
const MergeTreeTextHelper_1 = require("./MergeTreeTextHelper");
|
|
21
22
|
function elapsedMicroseconds(trace) {
|
|
22
23
|
return trace.trace().duration * 1000;
|
|
23
24
|
}
|
|
@@ -35,7 +36,7 @@ class Client {
|
|
|
35
36
|
this.accumWindow = 0;
|
|
36
37
|
this.accumOps = 0;
|
|
37
38
|
this.maxWindowTime = 0;
|
|
38
|
-
this.clientNameToIds = new collections_1.RedBlackTree(
|
|
39
|
+
this.clientNameToIds = new collections_1.RedBlackTree(mergeTreeNodes_1.compareStrings);
|
|
39
40
|
this.shortClientIdMap = [];
|
|
40
41
|
this.pendingConsensus = new Map();
|
|
41
42
|
this.mergeTree = new mergeTree_1.MergeTree(options);
|
|
@@ -159,7 +160,7 @@ class Client {
|
|
|
159
160
|
*/
|
|
160
161
|
insertAtReferencePositionLocal(refPos, segment) {
|
|
161
162
|
const pos = this.mergeTree.referencePositionToLocalPosition(refPos, this.getCurrentSeq(), this.getClientId());
|
|
162
|
-
if (pos ===
|
|
163
|
+
if (pos === referencePositions_1.DetachedReferencePosition) {
|
|
163
164
|
return undefined;
|
|
164
165
|
}
|
|
165
166
|
const op = (0, opBuilder_1.createInsertSegmentOp)(pos, segment);
|
|
@@ -205,20 +206,8 @@ class Client {
|
|
|
205
206
|
}
|
|
206
207
|
return this.mergeTree.getPosition(segment, this.getCurrentSeq(), this.getClientId());
|
|
207
208
|
}
|
|
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
209
|
createLocalReferencePosition(segment, offset, refType, properties) {
|
|
221
|
-
return this.mergeTree.createLocalReferencePosition(segment, offset, refType, properties
|
|
210
|
+
return this.mergeTree.createLocalReferencePosition(segment, offset !== null && offset !== void 0 ? offset : 0, refType, properties);
|
|
222
211
|
}
|
|
223
212
|
removeLocalReferencePosition(lref) {
|
|
224
213
|
return this.mergeTree.removeLocalReferencePosition(lref);
|
|
@@ -237,6 +226,50 @@ class Client {
|
|
|
237
226
|
getMarkerFromId(id) {
|
|
238
227
|
return this.mergeTree.getMarkerFromId(id);
|
|
239
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Revert an op
|
|
231
|
+
*/
|
|
232
|
+
rollback(op, localOpMetadata) {
|
|
233
|
+
var _a;
|
|
234
|
+
if (op.type !== ops_1.MergeTreeDeltaType.INSERT) {
|
|
235
|
+
throw new Error("Unsupported op type for rollback");
|
|
236
|
+
}
|
|
237
|
+
const lastList = (_a = this.mergeTree.pendingSegments) === null || _a === void 0 ? void 0 : _a.prev;
|
|
238
|
+
if (!lastList) {
|
|
239
|
+
throw new Error("No pending segments");
|
|
240
|
+
}
|
|
241
|
+
(0, collections_1.ListRemoveEntry)(lastList);
|
|
242
|
+
const pendingSegmentGroup = lastList.data;
|
|
243
|
+
if (pendingSegmentGroup === undefined || pendingSegmentGroup !== localOpMetadata) {
|
|
244
|
+
throw new Error("Rollback op doesn't match last edit");
|
|
245
|
+
}
|
|
246
|
+
for (const segment of pendingSegmentGroup.segments) {
|
|
247
|
+
const segmentSegmentGroup = segment.segmentGroups.dequeue();
|
|
248
|
+
(0, common_utils_1.assert)(segmentSegmentGroup === pendingSegmentGroup, "Unexpected segmentGroup in segment");
|
|
249
|
+
const start = this.findRollbackPosition(segment);
|
|
250
|
+
const segWindow = this.getCollabWindow();
|
|
251
|
+
const removeOp = (0, opBuilder_1.createRemoveRangeOp)(start, start + segment.cachedLength);
|
|
252
|
+
this.mergeTree.markRangeRemoved(start, start + segment.cachedLength, constants_1.UniversalSequenceNumber, segWindow.clientId, constants_1.UniversalSequenceNumber, false, { op: removeOp });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Walk the segments up to the current segment and calculate its position
|
|
257
|
+
*/
|
|
258
|
+
findRollbackPosition(segment) {
|
|
259
|
+
let segmentPosition = 0;
|
|
260
|
+
this.mergeTree.walkAllSegments(this.mergeTree.root, (seg) => {
|
|
261
|
+
// If we've found the desired segment, terminate the walk and return 'segmentPosition'.
|
|
262
|
+
if (seg === segment) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
// If not removed, increase position
|
|
266
|
+
if (seg.removedSeq === undefined) {
|
|
267
|
+
segmentPosition += seg.cachedLength;
|
|
268
|
+
}
|
|
269
|
+
return true;
|
|
270
|
+
});
|
|
271
|
+
return segmentPosition;
|
|
272
|
+
}
|
|
240
273
|
/**
|
|
241
274
|
* Performs the remove based on the provided op
|
|
242
275
|
* @param opArgs - The ops args for the op
|
|
@@ -487,7 +520,7 @@ class Client {
|
|
|
487
520
|
(0, common_utils_1.assert)(localSeq <= this.mergeTree.collabWindow.localSeq, 0x032 /* "localSeq greater than collab window" */);
|
|
488
521
|
let segmentPosition = 0;
|
|
489
522
|
/*
|
|
490
|
-
Walk the segments up to the current segment, and calculate
|
|
523
|
+
Walk the segments up to the current segment, and calculate its
|
|
491
524
|
position taking into account local segments that were modified,
|
|
492
525
|
after the current segment.
|
|
493
526
|
|
|
@@ -726,7 +759,7 @@ class Client {
|
|
|
726
759
|
return opList.length === 1 ? opList[0] : (0, opBuilder_1.createGroupOp)(...opList);
|
|
727
760
|
}
|
|
728
761
|
createTextHelper() {
|
|
729
|
-
return new
|
|
762
|
+
return new MergeTreeTextHelper_1.MergeTreeTextHelper(this.mergeTree);
|
|
730
763
|
}
|
|
731
764
|
summarize(runtime, handle, serializer, catchUpMsgs) {
|
|
732
765
|
var _a;
|
|
@@ -757,6 +790,10 @@ class Client {
|
|
|
757
790
|
const loader = new snapshotLoader_1.SnapshotLoader(runtime, this, this.mergeTree, this.logger, serializer);
|
|
758
791
|
return loader.initialize(storage);
|
|
759
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* @deprecated for internal use only. public export will be removed.
|
|
795
|
+
* @internal
|
|
796
|
+
*/
|
|
760
797
|
getStackContext(startPos, rangeLabels) {
|
|
761
798
|
return this.mergeTree.getStackContext(startPos, this.getCollabWindow().clientId, rangeLabels);
|
|
762
799
|
}
|
|
@@ -822,7 +859,18 @@ class Client {
|
|
|
822
859
|
* @returns - segment and offset to slide the reference to
|
|
823
860
|
*/
|
|
824
861
|
getSlideToSegment(segoff) {
|
|
825
|
-
|
|
862
|
+
if (segoff.segment === undefined) {
|
|
863
|
+
return segoff;
|
|
864
|
+
}
|
|
865
|
+
const segment = this.mergeTree._getSlideToSegment(segoff.segment);
|
|
866
|
+
if (segment === segoff.segment) {
|
|
867
|
+
return segoff;
|
|
868
|
+
}
|
|
869
|
+
const offset = segment && segment.ordinal < segoff.segment.ordinal ? segment.cachedLength - 1 : 0;
|
|
870
|
+
return {
|
|
871
|
+
segment,
|
|
872
|
+
offset,
|
|
873
|
+
};
|
|
826
874
|
}
|
|
827
875
|
getPropertiesAtPosition(pos) {
|
|
828
876
|
let propertiesAtPosition;
|