@fluidframework/merge-tree 2.30.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +403 -399
- package/api-report/merge-tree.legacy.alpha.api.md +1 -0
- package/dist/MergeTreeTextHelper.d.ts +9 -3
- package/dist/MergeTreeTextHelper.d.ts.map +1 -1
- package/dist/MergeTreeTextHelper.js +5 -5
- package/dist/MergeTreeTextHelper.js.map +1 -1
- package/dist/client.d.ts +7 -13
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +136 -110
- package/dist/client.js.map +1 -1
- package/dist/endOfTreeSegment.d.ts +12 -8
- package/dist/endOfTreeSegment.d.ts.map +1 -1
- package/dist/endOfTreeSegment.js +2 -4
- package/dist/endOfTreeSegment.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/mergeTree.d.ts +37 -23
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +400 -483
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeDeltaCallback.d.ts +4 -8
- package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/dist/mergeTreeDeltaCallback.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +32 -10
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +43 -28
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/partialLengths.d.ts +2 -2
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +181 -109
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +8 -27
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +7 -67
- package/dist/perspective.js.map +1 -1
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +2 -2
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentInfos.d.ts +20 -106
- package/dist/segmentInfos.d.ts.map +1 -1
- package/dist/segmentInfos.js +28 -42
- package/dist/segmentInfos.js.map +1 -1
- package/dist/segmentPropertiesManager.d.ts +1 -14
- package/dist/segmentPropertiesManager.d.ts.map +1 -1
- package/dist/segmentPropertiesManager.js +3 -17
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js +62 -19
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js +55 -24
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +6 -9
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/stamps.d.ts +1 -1
- package/dist/stamps.js +1 -1
- package/dist/stamps.js.map +1 -1
- package/dist/test/Insertion.perf.spec.js +6 -51
- package/dist/test/Insertion.perf.spec.js.map +1 -1
- package/dist/test/PartialLengths.perf.spec.js +18 -25
- package/dist/test/PartialLengths.perf.spec.js.map +1 -1
- package/dist/test/Removal.perf.spec.js +13 -41
- package/dist/test/Removal.perf.spec.js.map +1 -1
- package/dist/test/beastTest.spec.d.ts.map +1 -1
- package/dist/test/beastTest.spec.js +41 -66
- package/dist/test/beastTest.spec.js.map +1 -1
- package/dist/test/client.annotateMarker.spec.js +1 -11
- package/dist/test/client.annotateMarker.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +14 -14
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.getPosition.spec.js +1 -1
- package/dist/test/client.getPosition.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +1 -1
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.rollback.spec.js +49 -58
- package/dist/test/client.rollback.spec.js.map +1 -1
- package/dist/test/client.rollbackFarm.spec.js +1 -1
- package/dist/test/client.rollbackFarm.spec.js.map +1 -1
- package/dist/test/client.searchForMarker.spec.js +4 -21
- package/dist/test/client.searchForMarker.spec.js.map +1 -1
- package/dist/test/index.d.ts +2 -2
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +2 -6
- package/dist/test/index.js.map +1 -1
- package/dist/test/mergeTree.annotate.deltaCallback.spec.js +14 -59
- package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.annotate.spec.js +47 -63
- package/dist/test/mergeTree.annotate.spec.js.map +1 -1
- package/dist/test/mergeTree.insert.deltaCallback.spec.js +9 -62
- package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.insertingWalk.spec.js +59 -125
- package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +12 -93
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js +10 -7
- package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/dist/test/mergeTree.walk.spec.js +2 -14
- package/dist/test/mergeTree.walk.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +2 -2
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +18 -23
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/dist/test/obliterate.partialLength.spec.js +166 -136
- package/dist/test/obliterate.partialLength.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +16 -126
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/partialLength.spec.js +28 -196
- package/dist/test/partialLength.spec.js.map +1 -1
- package/dist/test/perspective.spec.js +34 -0
- package/dist/test/perspective.spec.js.map +1 -1
- package/dist/test/propertyManager.spec.js +1 -1
- package/dist/test/propertyManager.spec.js.map +1 -1
- package/dist/test/resetPendingSegmentsToOp.spec.js +0 -2
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/dist/test/segmentGroupCollection.spec.js +10 -4
- package/dist/test/segmentGroupCollection.spec.js.map +1 -1
- package/dist/test/testClient.d.ts +1 -0
- package/dist/test/testClient.d.ts.map +1 -1
- package/dist/test/testClient.js +16 -26
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testClientLogger.d.ts.map +1 -1
- package/dist/test/testClientLogger.js +3 -10
- package/dist/test/testClientLogger.js.map +1 -1
- package/dist/test/testServer.d.ts +2 -1
- package/dist/test/testServer.d.ts.map +1 -1
- package/dist/test/testServer.js +7 -5
- package/dist/test/testServer.js.map +1 -1
- package/dist/test/testUtils.d.ts +36 -56
- package/dist/test/testUtils.d.ts.map +1 -1
- package/dist/test/testUtils.js +68 -77
- package/dist/test/testUtils.js.map +1 -1
- package/dist/test/text.d.ts +2 -2
- package/dist/test/text.d.ts.map +1 -1
- package/dist/test/text.js +5 -2
- package/dist/test/text.js.map +1 -1
- package/dist/textSegment.d.ts +0 -6
- package/dist/textSegment.d.ts.map +1 -1
- package/dist/textSegment.js.map +1 -1
- package/dist/zamboni.d.ts.map +1 -1
- package/dist/zamboni.js +53 -26
- package/dist/zamboni.js.map +1 -1
- package/lib/MergeTreeTextHelper.d.ts +9 -3
- package/lib/MergeTreeTextHelper.d.ts.map +1 -1
- package/lib/MergeTreeTextHelper.js +5 -5
- package/lib/MergeTreeTextHelper.js.map +1 -1
- package/lib/client.d.ts +7 -13
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +117 -116
- package/lib/client.js.map +1 -1
- package/lib/endOfTreeSegment.d.ts +12 -8
- package/lib/endOfTreeSegment.d.ts.map +1 -1
- package/lib/endOfTreeSegment.js +2 -4
- package/lib/endOfTreeSegment.js.map +1 -1
- package/lib/index.d.ts +6 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/mergeTree.d.ts +37 -23
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +381 -488
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeDeltaCallback.d.ts +4 -8
- package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/lib/mergeTreeDeltaCallback.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +32 -10
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +42 -29
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/partialLengths.d.ts +2 -2
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +160 -111
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +8 -27
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +8 -68
- package/lib/perspective.js.map +1 -1
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +2 -2
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentInfos.d.ts +20 -106
- package/lib/segmentInfos.d.ts.map +1 -1
- package/lib/segmentInfos.js +26 -37
- package/lib/segmentInfos.js.map +1 -1
- package/lib/segmentPropertiesManager.d.ts +1 -14
- package/lib/segmentPropertiesManager.d.ts.map +1 -1
- package/lib/segmentPropertiesManager.js +2 -16
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js +39 -19
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js +34 -26
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +7 -10
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/stamps.d.ts +1 -1
- package/lib/stamps.js +1 -1
- package/lib/stamps.js.map +1 -1
- package/lib/test/Insertion.perf.spec.js +6 -51
- package/lib/test/Insertion.perf.spec.js.map +1 -1
- package/lib/test/PartialLengths.perf.spec.js +18 -25
- package/lib/test/PartialLengths.perf.spec.js.map +1 -1
- package/lib/test/Removal.perf.spec.js +13 -41
- package/lib/test/Removal.perf.spec.js.map +1 -1
- package/lib/test/beastTest.spec.d.ts.map +1 -1
- package/lib/test/beastTest.spec.js +42 -67
- package/lib/test/beastTest.spec.js.map +1 -1
- package/lib/test/client.annotateMarker.spec.js +1 -11
- package/lib/test/client.annotateMarker.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +14 -14
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.getPosition.spec.js +1 -1
- package/lib/test/client.getPosition.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +1 -1
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.rollback.spec.js +50 -59
- package/lib/test/client.rollback.spec.js.map +1 -1
- package/lib/test/client.rollbackFarm.spec.js +1 -1
- package/lib/test/client.rollbackFarm.spec.js.map +1 -1
- package/lib/test/client.searchForMarker.spec.js +4 -21
- package/lib/test/client.searchForMarker.spec.js.map +1 -1
- package/lib/test/index.d.ts +2 -2
- package/lib/test/index.d.ts.map +1 -1
- package/lib/test/index.js +1 -1
- package/lib/test/index.js.map +1 -1
- package/lib/test/mergeTree.annotate.deltaCallback.spec.js +15 -60
- package/lib/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.annotate.spec.js +48 -64
- package/lib/test/mergeTree.annotate.spec.js.map +1 -1
- package/lib/test/mergeTree.insert.deltaCallback.spec.js +10 -63
- package/lib/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.insertingWalk.spec.js +61 -127
- package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +13 -94
- package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js +10 -7
- package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/lib/test/mergeTree.walk.spec.js +2 -14
- package/lib/test/mergeTree.walk.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +3 -3
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +18 -23
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/test/obliterate.partialLength.spec.js +167 -137
- package/lib/test/obliterate.partialLength.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +17 -127
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/partialLength.spec.js +29 -197
- package/lib/test/partialLength.spec.js.map +1 -1
- package/lib/test/perspective.spec.js +34 -0
- package/lib/test/perspective.spec.js.map +1 -1
- package/lib/test/propertyManager.spec.js +2 -2
- package/lib/test/propertyManager.spec.js.map +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js +0 -2
- package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/lib/test/segmentGroupCollection.spec.js +10 -4
- package/lib/test/segmentGroupCollection.spec.js.map +1 -1
- package/lib/test/testClient.d.ts +1 -0
- package/lib/test/testClient.d.ts.map +1 -1
- package/lib/test/testClient.js +18 -28
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testClientLogger.d.ts.map +1 -1
- package/lib/test/testClientLogger.js +3 -10
- package/lib/test/testClientLogger.js.map +1 -1
- package/lib/test/testServer.d.ts +2 -1
- package/lib/test/testServer.d.ts.map +1 -1
- package/lib/test/testServer.js +7 -5
- package/lib/test/testServer.js.map +1 -1
- package/lib/test/testUtils.d.ts +36 -56
- package/lib/test/testUtils.d.ts.map +1 -1
- package/lib/test/testUtils.js +66 -48
- package/lib/test/testUtils.js.map +1 -1
- package/lib/test/text.d.ts +2 -2
- package/lib/test/text.d.ts.map +1 -1
- package/lib/test/text.js +6 -3
- package/lib/test/text.js.map +1 -1
- package/lib/textSegment.d.ts +0 -6
- package/lib/textSegment.d.ts.map +1 -1
- package/lib/textSegment.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/zamboni.d.ts.map +1 -1
- package/lib/zamboni.js +32 -28
- package/lib/zamboni.js.map +1 -1
- package/package.json +17 -20
- package/src/MergeTreeTextHelper.ts +17 -12
- package/src/client.ts +141 -197
- package/src/endOfTreeSegment.ts +11 -8
- package/src/index.ts +4 -3
- package/src/mergeTree.ts +482 -633
- package/src/mergeTreeDeltaCallback.ts +4 -8
- package/src/mergeTreeNodes.ts +66 -45
- package/src/partialLengths.ts +181 -137
- package/src/perspective.ts +17 -95
- package/src/revertibles.ts +2 -7
- package/src/segmentInfos.ts +48 -141
- package/src/segmentPropertiesManager.ts +2 -16
- package/src/snapshotLoader.ts +62 -30
- package/src/snapshotV1.ts +36 -28
- package/src/snapshotlegacy.ts +7 -16
- package/src/stamps.ts +1 -1
- package/src/textSegment.ts +0 -13
- package/src/zamboni.ts +38 -32
- package/tsconfig.json +1 -0
- package/prettier.config.cjs +0 -8
|
@@ -7,15 +7,15 @@ export class MergeTreeTextHelper {
|
|
|
7
7
|
constructor(mergeTree) {
|
|
8
8
|
this.mergeTree = mergeTree;
|
|
9
9
|
}
|
|
10
|
-
getText(
|
|
11
|
-
const range = this.getValidRange(start, end,
|
|
10
|
+
getText(perspective, placeholder = "", start, end) {
|
|
11
|
+
const range = this.getValidRange(start, end, perspective);
|
|
12
12
|
const accum = { textSegment: new TextSegment(""), placeholder };
|
|
13
|
-
this.mergeTree.mapRange(gatherText,
|
|
13
|
+
this.mergeTree.mapRange(gatherText, perspective, accum, range.start, range.end);
|
|
14
14
|
return accum.textSegment.text;
|
|
15
15
|
}
|
|
16
|
-
getValidRange(start, end,
|
|
16
|
+
getValidRange(start, end, perspective) {
|
|
17
17
|
const range = {
|
|
18
|
-
end: end ?? this.mergeTree.getLength(
|
|
18
|
+
end: end ?? this.mergeTree.getLength(perspective),
|
|
19
19
|
start: start ?? 0,
|
|
20
20
|
};
|
|
21
21
|
return range;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MergeTreeTextHelper.js","sourceRoot":"","sources":["../src/MergeTreeTextHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"MergeTreeTextHelper.js","sourceRoot":"","sources":["../src/MergeTreeTextHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAe/C,MAAM,OAAO,mBAAmB;IAC/B,YAA6B,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAE9C,OAAO,CACb,WAAwB,EACxB,WAAW,GAAG,EAAE,EAChB,KAAc,EACd,GAAY;QAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QAE1D,MAAM,KAAK,GAAqB,EAAE,WAAW,EAAE,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;QAElF,IAAI,CAAC,SAAS,CAAC,QAAQ,CACtB,UAAU,EACV,WAAW,EACX,KAAK,EACL,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,GAAG,CACT,CAAC;QACF,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAEO,aAAa,CACpB,KAAyB,EACzB,GAAuB,EACvB,WAAwB;QAExB,MAAM,KAAK,GAAkB;YAC5B,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC;YACjD,KAAK,EAAE,KAAK,IAAI,CAAC;SACjB,CAAC;QACF,OAAO,KAAK,CAAC;IACd,CAAC;CACD;AAED,SAAS,UAAU,CAClB,OAAwB,EACxB,GAAW,EACX,MAAc,EACd,QAAgB,EAChB,KAAa,EACb,GAAW,EACX,EAAE,WAAW,EAAE,WAAW,EAAoB;IAE9C,IAAI,WAAW,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9C,WAAW,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;QAClC,CAAC;aAAM,CAAC;YACP,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YACnC,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACrC,MAAM,IAAI,GAAG,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;YAC7C,WAAW,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACtD,CAAC;IACF,CAAC;SAAM,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,eAAe;QACpB,gEAAgE;QAChE,WAAW,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACjF,WAAW,CAAC,IAAI,IAAI,eAAe,CAAC;IACrC,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IIntegerRange } from \"./client.js\";\nimport type { MergeTree } from \"./mergeTree.js\";\nimport type { ISegmentPrivate } from \"./mergeTreeNodes.js\";\nimport type { Perspective } from \"./perspective.js\";\nimport { TextSegment } from \"./textSegment.js\";\n\ninterface ITextAccumulator {\n\ttextSegment: TextSegment;\n\tplaceholder?: string;\n\tparallelArrays?: boolean;\n}\n\n/**\n * @internal\n */\nexport interface IMergeTreeTextHelper {\n\tgetText(perspective: Perspective, placeholder: string, start?: number, end?: number): string;\n}\n\nexport class MergeTreeTextHelper implements IMergeTreeTextHelper {\n\tconstructor(private readonly mergeTree: MergeTree) {}\n\n\tpublic getText(\n\t\tperspective: Perspective,\n\t\tplaceholder = \"\",\n\t\tstart?: number,\n\t\tend?: number,\n\t): string {\n\t\tconst range = this.getValidRange(start, end, perspective);\n\n\t\tconst accum: ITextAccumulator = { textSegment: new TextSegment(\"\"), placeholder };\n\n\t\tthis.mergeTree.mapRange<ITextAccumulator>(\n\t\t\tgatherText,\n\t\t\tperspective,\n\t\t\taccum,\n\t\t\trange.start,\n\t\t\trange.end,\n\t\t);\n\t\treturn accum.textSegment.text;\n\t}\n\n\tprivate getValidRange(\n\t\tstart: number | undefined,\n\t\tend: number | undefined,\n\t\tperspective: Perspective,\n\t): IIntegerRange {\n\t\tconst range: IIntegerRange = {\n\t\t\tend: end ?? this.mergeTree.getLength(perspective),\n\t\t\tstart: start ?? 0,\n\t\t};\n\t\treturn range;\n\t}\n}\n\nfunction gatherText(\n\tsegment: ISegmentPrivate,\n\tpos: number,\n\trefSeq: number,\n\tclientId: number,\n\tstart: number,\n\tend: number,\n\t{ textSegment, placeholder }: ITextAccumulator,\n): boolean {\n\tif (TextSegment.is(segment)) {\n\t\tif (start <= 0 && end >= segment.text.length) {\n\t\t\ttextSegment.text += segment.text;\n\t\t} else {\n\t\t\tconst seglen = segment.text.length;\n\t\t\tconst _start = start < 0 ? 0 : start;\n\t\t\tconst _end = end >= seglen ? undefined : end;\n\t\t\ttextSegment.text += segment.text.slice(_start, _end);\n\t\t}\n\t} else if (placeholder && placeholder.length > 0) {\n\t\tconst placeholderText =\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\t\tplaceholder === \"*\" ? `\\n${segment}` : placeholder.repeat(segment.cachedLength);\n\t\ttextSegment.text += placeholderText;\n\t}\n\n\treturn true;\n}\n"]}
|
package/lib/client.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/in
|
|
|
9
9
|
import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions/internal";
|
|
10
10
|
import { IFluidSerializer } from "@fluidframework/shared-object-base/internal";
|
|
11
11
|
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
|
|
12
|
+
import { type IMergeTreeTextHelper } from "./MergeTreeTextHelper.js";
|
|
12
13
|
import { LocalReferencePosition, SlidingPreference } from "./localReference.js";
|
|
13
14
|
import { type IMergeTreeOptionsInternal } from "./mergeTree.js";
|
|
14
15
|
import type { IMergeTreeDeltaCallbackArgs, IMergeTreeDeltaOpArgs, IMergeTreeMaintenanceCallbackArgs } from "./mergeTreeDeltaCallback.js";
|
|
@@ -17,7 +18,6 @@ import { IJSONSegment, IMergeTreeAnnotateMsg, IMergeTreeGroupMsg, IMergeTreeInse
|
|
|
17
18
|
import { PropertySet, type MapLike } from "./properties.js";
|
|
18
19
|
import { ReferencePosition } from "./referencePositions.js";
|
|
19
20
|
import { type InteriorSequencePlace } from "./sequencePlace.js";
|
|
20
|
-
import { IMergeTreeTextHelper } from "./textSegment.js";
|
|
21
21
|
/**
|
|
22
22
|
* A range [start, end)
|
|
23
23
|
* @internal
|
|
@@ -175,8 +175,13 @@ export declare class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
175
175
|
/**
|
|
176
176
|
* Revert an op
|
|
177
177
|
*/
|
|
178
|
-
rollback
|
|
178
|
+
rollback(op: unknown, localOpMetadata: unknown): void;
|
|
179
179
|
private applyObliterateRangeOp;
|
|
180
|
+
private getOperationPerspective;
|
|
181
|
+
/**
|
|
182
|
+
* Returns the operation stamp to apply for a change, minting a new one local one if necessary.
|
|
183
|
+
*/
|
|
184
|
+
private getOperationStamp;
|
|
180
185
|
/**
|
|
181
186
|
* Performs the remove based on the provided op
|
|
182
187
|
* @param opArgs - The ops args for the op
|
|
@@ -206,16 +211,6 @@ export declare class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
206
211
|
* @param clientArgs - The client args for the op
|
|
207
212
|
*/
|
|
208
213
|
private getValidOpRange;
|
|
209
|
-
/**
|
|
210
|
-
* Gets the client args from the op if remote, otherwise uses the local clients info
|
|
211
|
-
* @param sequencedMessage - The sequencedMessage to get the client sequence args for
|
|
212
|
-
*/
|
|
213
|
-
private getClientSequenceArgsForMessage;
|
|
214
|
-
/**
|
|
215
|
-
* Gets the client args from the op if remote, otherwise uses the local clients info
|
|
216
|
-
* @param opArgs - The op arg to get the client sequence args for
|
|
217
|
-
*/
|
|
218
|
-
private getClientSequenceArgs;
|
|
219
214
|
private ackPendingSegment;
|
|
220
215
|
getOrAddShortClientId(longClientId: string): number;
|
|
221
216
|
protected getShortClientId(longClientId: string): number;
|
|
@@ -260,7 +255,6 @@ export declare class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
260
255
|
load(runtime: IFluidDataStoreRuntime, storage: IChannelStorageService, serializer: IFluidSerializer): Promise<{
|
|
261
256
|
catchupOpsP: Promise<ISequencedDocumentMessage[]>;
|
|
262
257
|
}>;
|
|
263
|
-
private getLocalSequenceNumber;
|
|
264
258
|
localTransaction(groupOp: IMergeTreeGroupMsg): void;
|
|
265
259
|
updateMinSeq(minSeq: number): void;
|
|
266
260
|
getContainingSegment<T extends ISegment>(pos: number, sequenceArgs?: Pick<ISequencedDocumentMessage, "referenceSequenceNumber" | "clientId">, localSeq?: number): {
|
package/lib/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,KAAK,qBAAqB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE3F,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAEN,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAErF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EACN,mBAAmB,EAGnB,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/lib/client.js
CHANGED
|
@@ -10,20 +10,20 @@ import { toDeltaManagerInternal } from "@fluidframework/runtime-utils/internal";
|
|
|
10
10
|
import { LoggingError, UsageError, } from "@fluidframework/telemetry-utils/internal";
|
|
11
11
|
import { MergeTreeTextHelper } from "./MergeTreeTextHelper.js";
|
|
12
12
|
import { RedBlackTree } from "./collections/index.js";
|
|
13
|
-
import { NonCollabClient,
|
|
14
|
-
import { MergeTree, errorIfOptionNotTrue, } from "./mergeTree.js";
|
|
13
|
+
import { NonCollabClient, UniversalSequenceNumber } from "./constants.js";
|
|
14
|
+
import { MergeTree, errorIfOptionNotTrue, isRemovedAndAcked, } from "./mergeTree.js";
|
|
15
15
|
import { walkAllChildSegments } from "./mergeTreeNodeWalk.js";
|
|
16
16
|
import { compareStrings, isSegmentLeaf, } from "./mergeTreeNodes.js";
|
|
17
|
-
import { createAdjustRangeOp, createAnnotateMarkerOp, createAnnotateRangeOp,
|
|
18
|
-
// eslint-disable-next-line import/no-deprecated
|
|
19
|
-
createGroupOp, createInsertSegmentOp, createObliterateRangeOp, createObliterateRangeOpSided, createRemoveRangeOp, } from "./opBuilder.js";
|
|
17
|
+
import { createAdjustRangeOp, createAnnotateMarkerOp, createAnnotateRangeOp, createGroupOp, createInsertSegmentOp, createObliterateRangeOp, createObliterateRangeOpSided, createRemoveRangeOp, } from "./opBuilder.js";
|
|
20
18
|
import { MergeTreeDeltaType, } from "./ops.js";
|
|
19
|
+
import { LocalReconnectingPerspective, PriorPerspective, } from "./perspective.js";
|
|
21
20
|
import { DetachedReferencePosition } from "./referencePositions.js";
|
|
22
|
-
import { isInserted,
|
|
21
|
+
import { isInserted, isRemoved, overwriteInfo, toRemovalInfo, } from "./segmentInfos.js";
|
|
23
22
|
import { Side } from "./sequencePlace.js";
|
|
24
23
|
import { SnapshotLoader } from "./snapshotLoader.js";
|
|
25
24
|
import { SnapshotV1 } from "./snapshotV1.js";
|
|
26
25
|
import { SnapshotLegacy } from "./snapshotlegacy.js";
|
|
26
|
+
import * as opstampUtils from "./stamps.js";
|
|
27
27
|
const UNBOUND_SEGMENT_ERROR = "The provided segment is not bound to this DDS.";
|
|
28
28
|
/**
|
|
29
29
|
* This class encapsulates a merge-tree, and provides a local client specific view over it and
|
|
@@ -186,7 +186,7 @@ export class Client extends TypedEventEmitter {
|
|
|
186
186
|
return this.insertSegmentLocal(pos, segment);
|
|
187
187
|
}
|
|
188
188
|
walkSegments(handler, start, end, accum, splitRange = false) {
|
|
189
|
-
this._mergeTree.mapRange(handler, this.
|
|
189
|
+
this._mergeTree.mapRange(handler, this._mergeTree.localPerspective, accum, start, end, splitRange);
|
|
190
190
|
}
|
|
191
191
|
walkAllSegments(action, accum) {
|
|
192
192
|
return walkAllChildSegments(this._mergeTree.root, accum === undefined ? action : (seg) => action(seg, accum));
|
|
@@ -199,12 +199,18 @@ export class Client extends TypedEventEmitter {
|
|
|
199
199
|
serializeGCData(handle, handleCollectingSerializer) {
|
|
200
200
|
let localInserts = 0;
|
|
201
201
|
let localRemoves = 0;
|
|
202
|
+
let localObliterates = 0;
|
|
202
203
|
walkAllChildSegments(this._mergeTree.root, (seg) => {
|
|
203
|
-
if (isInserted(seg) && seg.
|
|
204
|
+
if (isInserted(seg) && opstampUtils.isLocal(seg.insert)) {
|
|
204
205
|
localInserts++;
|
|
205
206
|
}
|
|
206
|
-
if (isRemoved(seg) && seg.
|
|
207
|
-
|
|
207
|
+
if (isRemoved(seg) && opstampUtils.isLocal(seg.removes[seg.removes.length - 1])) {
|
|
208
|
+
if (seg.removes[seg.removes.length - 1].type === "setRemove") {
|
|
209
|
+
localRemoves++;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
localObliterates++;
|
|
213
|
+
}
|
|
208
214
|
}
|
|
209
215
|
// Only serialize segments that have not been removed.
|
|
210
216
|
if (!isRemoved(seg)) {
|
|
@@ -217,6 +223,7 @@ export class Client extends TypedEventEmitter {
|
|
|
217
223
|
eventName: "LocalEditsInProcessGCData",
|
|
218
224
|
localInserts,
|
|
219
225
|
localRemoves,
|
|
226
|
+
localObliterates,
|
|
220
227
|
});
|
|
221
228
|
}
|
|
222
229
|
}
|
|
@@ -232,7 +239,10 @@ export class Client extends TypedEventEmitter {
|
|
|
232
239
|
if (!isSegmentLeaf(segment)) {
|
|
233
240
|
return -1;
|
|
234
241
|
}
|
|
235
|
-
|
|
242
|
+
const perspective = localSeq === undefined
|
|
243
|
+
? this._mergeTree.localPerspective
|
|
244
|
+
: new LocalReconnectingPerspective(this.getCurrentSeq(), this.getClientId(), localSeq);
|
|
245
|
+
return this._mergeTree.getPosition(segment, perspective);
|
|
236
246
|
}
|
|
237
247
|
/**
|
|
238
248
|
* Creates a `LocalReferencePosition` on this client. If the refType does not include ReferenceType.Transient,
|
|
@@ -274,7 +284,7 @@ export class Client extends TypedEventEmitter {
|
|
|
274
284
|
* @param relativePos - Id of marker (may be indirect) and whether position is before or after marker.
|
|
275
285
|
*/
|
|
276
286
|
posFromRelativePos(relativePos) {
|
|
277
|
-
return this._mergeTree.posFromRelativePos(relativePos);
|
|
287
|
+
return this._mergeTree.posFromRelativePos(relativePos, this._mergeTree.localPerspective);
|
|
278
288
|
}
|
|
279
289
|
getMarkerFromId(id) {
|
|
280
290
|
return this._mergeTree.getMarkerFromId(id);
|
|
@@ -286,41 +296,66 @@ export class Client extends TypedEventEmitter {
|
|
|
286
296
|
this._mergeTree.rollback(op, localOpMetadata);
|
|
287
297
|
}
|
|
288
298
|
applyObliterateRangeOp(opArgs) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const
|
|
299
|
+
const { op, sequencedMessage } = opArgs;
|
|
300
|
+
assert(op.type === MergeTreeDeltaType.OBLITERATE ||
|
|
301
|
+
op.type === MergeTreeDeltaType.OBLITERATE_SIDED, 0x866 /* Unexpected op type on range obliterate! */);
|
|
302
|
+
const perspective = this.getOperationPerspective(sequencedMessage);
|
|
303
|
+
const stamp = this.getOperationStamp(sequencedMessage);
|
|
293
304
|
if (this._mergeTree.options?.mergeTreeEnableSidedObliterate) {
|
|
294
|
-
const { start, end } = this.getValidSidedRange(op,
|
|
295
|
-
this._mergeTree.obliterateRange(start, end,
|
|
305
|
+
const { start, end } = this.getValidSidedRange(op, perspective);
|
|
306
|
+
this._mergeTree.obliterateRange(start, end, perspective, stamp, opArgs);
|
|
296
307
|
}
|
|
297
308
|
else {
|
|
298
309
|
assert(op.type === MergeTreeDeltaType.OBLITERATE, 0xa43 /* Unexpected sided obliterate while mergeTreeEnableSidedObliterate is disabled */);
|
|
299
|
-
const
|
|
300
|
-
this._mergeTree.obliterateRange(
|
|
310
|
+
const { start, end } = this.getValidOpRange(op, perspective);
|
|
311
|
+
this._mergeTree.obliterateRange(start, end, perspective, stamp, opArgs);
|
|
301
312
|
}
|
|
302
313
|
}
|
|
314
|
+
getOperationPerspective(sequencedMessage) {
|
|
315
|
+
if (!sequencedMessage) {
|
|
316
|
+
return this._mergeTree.localPerspective;
|
|
317
|
+
}
|
|
318
|
+
const clientId = this.getOrAddShortClientIdFromMessage(sequencedMessage);
|
|
319
|
+
const { referenceSequenceNumber: refSeq } = sequencedMessage;
|
|
320
|
+
return new PriorPerspective(refSeq, clientId);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Returns the operation stamp to apply for a change, minting a new one local one if necessary.
|
|
324
|
+
*/
|
|
325
|
+
getOperationStamp(sequencedMessage) {
|
|
326
|
+
if (!sequencedMessage) {
|
|
327
|
+
return this.getCollabWindow().mintNextLocalOperationStamp();
|
|
328
|
+
}
|
|
329
|
+
const { sequenceNumber: seq } = sequencedMessage;
|
|
330
|
+
const clientId = this.getOrAddShortClientIdFromMessage(sequencedMessage);
|
|
331
|
+
return {
|
|
332
|
+
seq,
|
|
333
|
+
clientId,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
303
336
|
/**
|
|
304
337
|
* Performs the remove based on the provided op
|
|
305
338
|
* @param opArgs - The ops args for the op
|
|
306
339
|
*/
|
|
307
340
|
applyRemoveRangeOp(opArgs) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const
|
|
311
|
-
const
|
|
312
|
-
|
|
341
|
+
const { op, sequencedMessage } = opArgs;
|
|
342
|
+
assert(op.type === MergeTreeDeltaType.REMOVE, 0x02d /* "Unexpected op type on range remove!" */);
|
|
343
|
+
const perspective = this.getOperationPerspective(sequencedMessage);
|
|
344
|
+
const stamp = this.getOperationStamp(sequencedMessage);
|
|
345
|
+
const range = this.getValidOpRange(op, perspective);
|
|
346
|
+
this._mergeTree.markRangeRemoved(range.start, range.end, perspective, stamp, opArgs);
|
|
313
347
|
}
|
|
314
348
|
/**
|
|
315
349
|
* Performs the annotate based on the provided op
|
|
316
350
|
* @param opArgs - The ops args for the op
|
|
317
351
|
*/
|
|
318
352
|
applyAnnotateRangeOp(opArgs) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const
|
|
322
|
-
const
|
|
323
|
-
|
|
353
|
+
const { op, sequencedMessage } = opArgs;
|
|
354
|
+
assert(op.type === MergeTreeDeltaType.ANNOTATE, 0x02e /* "Unexpected op type on range annotate!" */);
|
|
355
|
+
const perspective = this.getOperationPerspective(sequencedMessage);
|
|
356
|
+
const stamp = this.getOperationStamp(sequencedMessage);
|
|
357
|
+
const range = this.getValidOpRange(op, perspective);
|
|
358
|
+
this._mergeTree.annotateRange(range.start, range.end, op, perspective, stamp, opArgs);
|
|
324
359
|
}
|
|
325
360
|
/**
|
|
326
361
|
* Performs the insert based on the provided op
|
|
@@ -328,13 +363,14 @@ export class Client extends TypedEventEmitter {
|
|
|
328
363
|
* @returns True if the insert was applied. False if it could not be.
|
|
329
364
|
*/
|
|
330
365
|
applyInsertOp(opArgs) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
const
|
|
366
|
+
const { op, sequencedMessage } = opArgs;
|
|
367
|
+
assert(op.type === MergeTreeDeltaType.INSERT, 0x02f /* "Unexpected op type on range insert!" */);
|
|
368
|
+
const perspective = this.getOperationPerspective(sequencedMessage);
|
|
369
|
+
const stamp = this.getOperationStamp(sequencedMessage);
|
|
370
|
+
const range = this.getValidOpRange(op, perspective);
|
|
335
371
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
336
372
|
const segments = [this.specToSegment(op.seg)];
|
|
337
|
-
this._mergeTree.insertSegments(range.start, segments,
|
|
373
|
+
this._mergeTree.insertSegments(range.start, segments, perspective, stamp, opArgs);
|
|
338
374
|
}
|
|
339
375
|
/**
|
|
340
376
|
* Returns a valid range for the op, or throws if the range is invalid
|
|
@@ -344,7 +380,7 @@ export class Client extends TypedEventEmitter {
|
|
|
344
380
|
*/
|
|
345
381
|
getValidSidedRange(
|
|
346
382
|
// eslint-disable-next-line import/no-deprecated
|
|
347
|
-
op,
|
|
383
|
+
op, perspective) {
|
|
348
384
|
const invalidPositions = [];
|
|
349
385
|
let start;
|
|
350
386
|
let end;
|
|
@@ -367,8 +403,8 @@ export class Client extends TypedEventEmitter {
|
|
|
367
403
|
: { pos: op.pos2 - 1, side: Side.After };
|
|
368
404
|
}
|
|
369
405
|
// Validate if local op
|
|
370
|
-
if (
|
|
371
|
-
const length = this._mergeTree.getLength(this.
|
|
406
|
+
if (perspective.clientId === this.getClientId()) {
|
|
407
|
+
const length = this._mergeTree.getLength(this._mergeTree.localPerspective);
|
|
372
408
|
if (start !== undefined && (start.pos >= length || start.pos < 0)) {
|
|
373
409
|
// start out of bounds
|
|
374
410
|
invalidPositions.push("start");
|
|
@@ -406,17 +442,17 @@ export class Client extends TypedEventEmitter {
|
|
|
406
442
|
* @param op - The op to generate the range for
|
|
407
443
|
* @param clientArgs - The client args for the op
|
|
408
444
|
*/
|
|
409
|
-
getValidOpRange(op,
|
|
445
|
+
getValidOpRange(op, perspective) {
|
|
410
446
|
let start = op.pos1;
|
|
411
447
|
if (start === undefined && op.relativePos1) {
|
|
412
|
-
start = this._mergeTree.posFromRelativePos(op.relativePos1,
|
|
448
|
+
start = this._mergeTree.posFromRelativePos(op.relativePos1, perspective);
|
|
413
449
|
}
|
|
414
450
|
let end = op.pos2;
|
|
415
451
|
if (end === undefined && op.relativePos2) {
|
|
416
|
-
end = this._mergeTree.posFromRelativePos(op.relativePos2,
|
|
452
|
+
end = this._mergeTree.posFromRelativePos(op.relativePos2, perspective);
|
|
417
453
|
}
|
|
418
454
|
// Validate if local op
|
|
419
|
-
if (
|
|
455
|
+
if (perspective.clientId === this.getClientId()) {
|
|
420
456
|
const length = this.getLength();
|
|
421
457
|
const invalidPositions = [];
|
|
422
458
|
// Validate start position
|
|
@@ -453,39 +489,6 @@ export class Client extends TypedEventEmitter {
|
|
|
453
489
|
// start and end are guaranteed to be non-null here, otherwise we throw above.
|
|
454
490
|
return { start: start, end: end };
|
|
455
491
|
}
|
|
456
|
-
/**
|
|
457
|
-
* Gets the client args from the op if remote, otherwise uses the local clients info
|
|
458
|
-
* @param sequencedMessage - The sequencedMessage to get the client sequence args for
|
|
459
|
-
*/
|
|
460
|
-
getClientSequenceArgsForMessage(sequencedMessage) {
|
|
461
|
-
// If there this no sequenced message, then the op is local
|
|
462
|
-
// and unacked, so use this clients sequenced args
|
|
463
|
-
//
|
|
464
|
-
if (sequencedMessage) {
|
|
465
|
-
return {
|
|
466
|
-
clientId: this.getOrAddShortClientIdFromMessage(sequencedMessage),
|
|
467
|
-
referenceSequenceNumber: sequencedMessage.referenceSequenceNumber,
|
|
468
|
-
// Note: return value satisfies overload signatures despite the cast, as if input argument doesn't contain sequenceNumber,
|
|
469
|
-
// return value isn't expected to have it either.
|
|
470
|
-
sequenceNumber: sequencedMessage.sequenceNumber,
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
else {
|
|
474
|
-
const segWindow = this.getCollabWindow();
|
|
475
|
-
return {
|
|
476
|
-
clientId: segWindow.clientId,
|
|
477
|
-
referenceSequenceNumber: segWindow.currentSeq,
|
|
478
|
-
sequenceNumber: this.getLocalSequenceNumber(),
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Gets the client args from the op if remote, otherwise uses the local clients info
|
|
484
|
-
* @param opArgs - The op arg to get the client sequence args for
|
|
485
|
-
*/
|
|
486
|
-
getClientSequenceArgs(opArgs) {
|
|
487
|
-
return this.getClientSequenceArgsForMessage(opArgs.sequencedMessage);
|
|
488
|
-
}
|
|
489
492
|
ackPendingSegment(opArgs) {
|
|
490
493
|
if (opArgs.op.type === MergeTreeDeltaType.GROUP) {
|
|
491
494
|
for (const memberOp of opArgs.op.ops) {
|
|
@@ -534,7 +537,8 @@ export class Client extends TypedEventEmitter {
|
|
|
534
537
|
if (!isSegmentLeaf(segment)) {
|
|
535
538
|
throw new UsageError(UNBOUND_SEGMENT_ERROR);
|
|
536
539
|
}
|
|
537
|
-
|
|
540
|
+
const perspective = new LocalReconnectingPerspective(currentSeq, clientId, localSeq);
|
|
541
|
+
return this._mergeTree.getPosition(segment, perspective);
|
|
538
542
|
}
|
|
539
543
|
resetPendingDeltaToOps(resetOp, segmentGroup) {
|
|
540
544
|
assert(!!segmentGroup, 0x033 /* "Segment group undefined" */);
|
|
@@ -570,12 +574,7 @@ export class Client extends TypedEventEmitter {
|
|
|
570
574
|
// if the segment has been removed or obliterated, there's no need to send the annotate op
|
|
571
575
|
// unless the remove was local, in which case the annotate must have come
|
|
572
576
|
// before the remove
|
|
573
|
-
if (
|
|
574
|
-
(segment.localRemovedSeq !== undefined &&
|
|
575
|
-
segment.removedSeq === UnassignedSequenceNumber)) &&
|
|
576
|
-
(!isMoved(segment) ||
|
|
577
|
-
(segment.localMovedSeq !== undefined &&
|
|
578
|
-
segment.movedSeq === UnassignedSequenceNumber))) {
|
|
577
|
+
if (!isRemovedAndAcked(segment)) {
|
|
579
578
|
newOp =
|
|
580
579
|
resetOp.props === undefined
|
|
581
580
|
? createAdjustRangeOp(segmentPosition, segmentPosition + segment.cachedLength, resetOp.adjust)
|
|
@@ -584,22 +583,24 @@ export class Client extends TypedEventEmitter {
|
|
|
584
583
|
break;
|
|
585
584
|
}
|
|
586
585
|
case MergeTreeDeltaType.INSERT: {
|
|
587
|
-
assert(isInserted(segment) && segment.
|
|
588
|
-
const
|
|
589
|
-
if (
|
|
586
|
+
assert(isInserted(segment) && opstampUtils.isLocal(segment.insert), 0x037 /* "Segment already has assigned sequence number" */);
|
|
587
|
+
const removeInfo = toRemovalInfo(segment);
|
|
588
|
+
if (removeInfo !== undefined && opstampUtils.isAcked(removeInfo.removes[0])) {
|
|
589
|
+
assert(removeInfo.removes[0].type === "sliceRemove", 0xb5c /* Remove on insertion must be caused by obliterate. */);
|
|
590
590
|
errorIfOptionNotTrue(this._mergeTree.options, "mergeTreeEnableObliterateReconnect");
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
591
|
+
// the segment was remotely obliterated, so is considered removed
|
|
592
|
+
// we set the seq to the universal seq and remove the local seq,
|
|
593
|
+
// so its length is not considered for subsequent local changes
|
|
594
|
+
// this allows us to not send the op as even the local client will ignore the segment
|
|
595
|
+
overwriteInfo(segment, {
|
|
596
|
+
insert: {
|
|
597
|
+
type: "insert",
|
|
597
598
|
seq: UniversalSequenceNumber,
|
|
598
599
|
localSeq: undefined,
|
|
599
600
|
clientId: NonCollabClient,
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
break;
|
|
603
604
|
}
|
|
604
605
|
const segInsertOp = segment.clone();
|
|
605
606
|
const opProps = isObject(resetOp.seg) && "props" in resetOp.seg && isObject(resetOp.seg.props)
|
|
@@ -610,24 +611,18 @@ export class Client extends TypedEventEmitter {
|
|
|
610
611
|
break;
|
|
611
612
|
}
|
|
612
613
|
case MergeTreeDeltaType.REMOVE: {
|
|
613
|
-
if
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
(!isMoved(segment) ||
|
|
617
|
-
(segment.localMovedSeq !== undefined &&
|
|
618
|
-
segment.movedSeq === UnassignedSequenceNumber))) {
|
|
614
|
+
// Only bother resubmitting if nobody else has removed it in the meantime.
|
|
615
|
+
// When that happens, the first removal will have been acked.
|
|
616
|
+
if (isRemoved(segment) && opstampUtils.isLocal(segment.removes[0])) {
|
|
619
617
|
newOp = createRemoveRangeOp(segmentPosition, segmentPosition + segment.cachedLength);
|
|
620
618
|
}
|
|
621
619
|
break;
|
|
622
620
|
}
|
|
623
621
|
case MergeTreeDeltaType.OBLITERATE: {
|
|
624
622
|
errorIfOptionNotTrue(this._mergeTree.options, "mergeTreeEnableObliterateReconnect");
|
|
625
|
-
if
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
(!isRemoved(segment) ||
|
|
629
|
-
(segment.localRemovedSeq !== undefined &&
|
|
630
|
-
segment.removedSeq === UnassignedSequenceNumber))) {
|
|
623
|
+
// Only bother resubmitting if nobody else has removed it in the meantime.
|
|
624
|
+
// When that happens, the first removal will have been acked.
|
|
625
|
+
if (isRemoved(segment) && opstampUtils.isLocal(segment.removes[0])) {
|
|
631
626
|
newOp = createObliterateRangeOp(segmentPosition, segmentPosition + segment.cachedLength);
|
|
632
627
|
}
|
|
633
628
|
break;
|
|
@@ -783,7 +778,6 @@ export class Client extends TypedEventEmitter {
|
|
|
783
778
|
if (Array.isArray(segmentGroup)) {
|
|
784
779
|
if (segmentGroup.length === 0) {
|
|
785
780
|
// sometimes we rebase to an empty op
|
|
786
|
-
// eslint-disable-next-line import/no-deprecated
|
|
787
781
|
return createGroupOp();
|
|
788
782
|
}
|
|
789
783
|
firstGroup = segmentGroup[0];
|
|
@@ -821,7 +815,6 @@ export class Client extends TypedEventEmitter {
|
|
|
821
815
|
assert(!Array.isArray(segmentGroup), 0x03d /* "segmentGroup is array rather than singleton!" */);
|
|
822
816
|
opList.push(...this.resetPendingDeltaToOps(resetOp, segmentGroup));
|
|
823
817
|
}
|
|
824
|
-
// eslint-disable-next-line import/no-deprecated
|
|
825
818
|
return opList.length === 1 ? opList[0] : createGroupOp(...opList);
|
|
826
819
|
}
|
|
827
820
|
createTextHelper() {
|
|
@@ -855,10 +848,6 @@ export class Client extends TypedEventEmitter {
|
|
|
855
848
|
const loader = new SnapshotLoader(runtime, this, this._mergeTree, this.logger, serializer);
|
|
856
849
|
return loader.initialize(storage);
|
|
857
850
|
}
|
|
858
|
-
getLocalSequenceNumber() {
|
|
859
|
-
const segWindow = this.getCollabWindow();
|
|
860
|
-
return segWindow.collaborating ? UnassignedSequenceNumber : UniversalSequenceNumber;
|
|
861
|
-
}
|
|
862
851
|
// eslint-disable-next-line import/no-deprecated
|
|
863
852
|
localTransaction(groupOp) {
|
|
864
853
|
for (const op of groupOp.ops) {
|
|
@@ -894,8 +883,21 @@ export class Client extends TypedEventEmitter {
|
|
|
894
883
|
this._mergeTree.setMinSeq(minSeq);
|
|
895
884
|
}
|
|
896
885
|
getContainingSegment(pos, sequenceArgs, localSeq) {
|
|
897
|
-
|
|
898
|
-
|
|
886
|
+
let perspective;
|
|
887
|
+
const clientId = sequenceArgs === undefined
|
|
888
|
+
? this.getClientId()
|
|
889
|
+
: this.getOrAddShortClientIdFromMessage(sequenceArgs);
|
|
890
|
+
const refSeq = sequenceArgs?.referenceSequenceNumber ?? this.getCollabWindow().currentSeq;
|
|
891
|
+
if (localSeq !== undefined) {
|
|
892
|
+
perspective = new LocalReconnectingPerspective(refSeq, clientId, localSeq);
|
|
893
|
+
}
|
|
894
|
+
else if (sequenceArgs === undefined) {
|
|
895
|
+
perspective = this._mergeTree.localPerspective;
|
|
896
|
+
}
|
|
897
|
+
else {
|
|
898
|
+
perspective = new PriorPerspective(refSeq, clientId);
|
|
899
|
+
}
|
|
900
|
+
return this._mergeTree.getContainingSegment(pos, perspective);
|
|
899
901
|
}
|
|
900
902
|
getPropertiesAtPosition(pos) {
|
|
901
903
|
let propertiesAtPosition;
|
|
@@ -957,8 +959,7 @@ export class Client extends TypedEventEmitter {
|
|
|
957
959
|
* @param forwards - Whether the desired marker comes before (false) or after (true) `startPos`
|
|
958
960
|
*/
|
|
959
961
|
searchForMarker(startPos, markerLabel, forwards = true) {
|
|
960
|
-
|
|
961
|
-
return this._mergeTree.searchForMarker(startPos, clientId, markerLabel, forwards);
|
|
962
|
+
return this._mergeTree.searchForMarker(startPos, markerLabel, forwards);
|
|
962
963
|
}
|
|
963
964
|
}
|
|
964
965
|
//# sourceMappingURL=client.js.map
|