@fluidframework/sequence 1.4.0-121020 → 2.0.0-dev-rc.1.0.0.224419
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/.eslintrc.js +9 -11
- package/.mocharc.js +12 -0
- package/CHANGELOG.md +449 -0
- package/README.md +364 -183
- package/api-extractor-lint.json +4 -0
- package/api-extractor.json +2 -2
- package/api-report/sequence.api.md +741 -0
- package/dist/{defaultMap.js → defaultMap.cjs} +29 -22
- package/dist/defaultMap.cjs.map +1 -0
- package/dist/defaultMap.d.ts +7 -6
- package/dist/defaultMap.d.ts.map +1 -1
- package/dist/defaultMapInterfaces.cjs +7 -0
- package/dist/defaultMapInterfaces.cjs.map +1 -0
- package/dist/defaultMapInterfaces.d.ts +44 -12
- package/dist/defaultMapInterfaces.d.ts.map +1 -1
- package/dist/index.cjs +60 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +14 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/intervalCollection.cjs +1159 -0
- package/dist/intervalCollection.cjs.map +1 -0
- package/dist/intervalCollection.d.ts +461 -162
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.cjs +66 -0
- package/dist/intervalIndex/endpointInRangeIndex.cjs.map +1 -0
- package/dist/intervalIndex/endpointInRangeIndex.d.ts +34 -0
- package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -0
- package/dist/intervalIndex/endpointIndex.cjs +47 -0
- package/dist/intervalIndex/endpointIndex.cjs.map +1 -0
- package/dist/intervalIndex/endpointIndex.d.ts +38 -0
- package/dist/intervalIndex/endpointIndex.d.ts.map +1 -0
- package/dist/intervalIndex/idIntervalIndex.cjs +44 -0
- package/dist/intervalIndex/idIntervalIndex.cjs.map +1 -0
- package/dist/intervalIndex/idIntervalIndex.d.ts +18 -0
- package/dist/intervalIndex/idIntervalIndex.d.ts.map +1 -0
- package/dist/intervalIndex/index.cjs +24 -0
- package/dist/intervalIndex/index.cjs.map +1 -0
- package/dist/intervalIndex/index.d.ts +13 -0
- package/dist/intervalIndex/index.d.ts.map +1 -0
- package/dist/{defaultMapInterfaces.js → intervalIndex/intervalIndex.cjs} +1 -1
- package/dist/intervalIndex/intervalIndex.cjs.map +1 -0
- package/dist/intervalIndex/intervalIndex.d.ts +30 -0
- package/dist/intervalIndex/intervalIndex.d.ts.map +1 -0
- package/dist/intervalIndex/intervalIndexUtils.cjs +22 -0
- package/dist/intervalIndex/intervalIndexUtils.cjs.map +1 -0
- package/dist/intervalIndex/intervalIndexUtils.d.ts +17 -0
- package/dist/intervalIndex/intervalIndexUtils.d.ts.map +1 -0
- package/dist/intervalIndex/overlappingIntervalsIndex.cjs +116 -0
- package/dist/intervalIndex/overlappingIntervalsIndex.cjs.map +1 -0
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +44 -0
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -0
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.cjs +41 -0
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.cjs.map +1 -0
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +11 -0
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -0
- package/dist/intervalIndex/sequenceIntervalIndexes.cjs +7 -0
- package/dist/intervalIndex/sequenceIntervalIndexes.cjs.map +1 -0
- package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +35 -0
- package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -0
- package/dist/intervalIndex/startpointInRangeIndex.cjs +66 -0
- package/dist/intervalIndex/startpointInRangeIndex.cjs.map +1 -0
- package/dist/intervalIndex/startpointInRangeIndex.d.ts +34 -0
- package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -0
- package/dist/intervalTree.cjs +80 -0
- package/dist/intervalTree.cjs.map +1 -0
- package/dist/intervalTree.d.ts +24 -0
- package/dist/intervalTree.d.ts.map +1 -0
- package/dist/intervals/index.cjs +23 -0
- package/dist/intervals/index.cjs.map +1 -0
- package/dist/intervals/index.d.ts +8 -0
- package/dist/intervals/index.d.ts.map +1 -0
- package/dist/intervals/interval.cjs +181 -0
- package/dist/intervals/interval.cjs.map +1 -0
- package/dist/intervals/interval.d.ts +84 -0
- package/dist/intervals/interval.d.ts.map +1 -0
- package/dist/intervals/intervalUtils.cjs +83 -0
- package/dist/intervals/intervalUtils.cjs.map +1 -0
- package/dist/intervals/intervalUtils.d.ts +230 -0
- package/dist/intervals/intervalUtils.d.ts.map +1 -0
- package/dist/intervals/sequenceInterval.cjs +378 -0
- package/dist/intervals/sequenceInterval.cjs.map +1 -0
- package/dist/intervals/sequenceInterval.d.ts +137 -0
- package/dist/intervals/sequenceInterval.d.ts.map +1 -0
- package/dist/{localValues.js → localValues.cjs} +1 -1
- package/dist/localValues.cjs.map +1 -0
- package/dist/localValues.d.ts +2 -1
- package/dist/localValues.d.ts.map +1 -1
- package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
- package/dist/packageVersion.cjs.map +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/revertibles.cjs +425 -0
- package/dist/revertibles.cjs.map +1 -0
- package/dist/revertibles.d.ts +86 -0
- package/dist/revertibles.d.ts.map +1 -0
- package/dist/sequence-alpha.d.ts +1315 -0
- package/dist/sequence-beta.d.ts +244 -0
- package/dist/sequence-public.d.ts +244 -0
- package/dist/sequence-untrimmed.d.ts +1803 -0
- package/dist/{sequence.js → sequence.cjs} +226 -156
- package/dist/sequence.cjs.map +1 -0
- package/dist/sequence.d.ts +125 -48
- package/dist/sequence.d.ts.map +1 -1
- package/dist/{sequenceDeltaEvent.js → sequenceDeltaEvent.cjs} +18 -8
- package/dist/sequenceDeltaEvent.cjs.map +1 -0
- package/dist/sequenceDeltaEvent.d.ts +24 -7
- package/dist/sequenceDeltaEvent.d.ts.map +1 -1
- package/dist/sequenceFactory.cjs +55 -0
- package/dist/sequenceFactory.cjs.map +1 -0
- package/dist/sequenceFactory.d.ts +3 -89
- package/dist/sequenceFactory.d.ts.map +1 -1
- package/dist/{sharedIntervalCollection.js → sharedIntervalCollection.cjs} +17 -22
- package/dist/sharedIntervalCollection.cjs.map +1 -0
- package/dist/sharedIntervalCollection.d.ts +12 -12
- package/dist/sharedIntervalCollection.d.ts.map +1 -1
- package/dist/{sharedSequence.js → sharedSequence.cjs} +29 -22
- package/dist/sharedSequence.cjs.map +1 -0
- package/dist/sharedSequence.d.ts +14 -2
- package/dist/sharedSequence.d.ts.map +1 -1
- package/dist/sharedString.cjs +286 -0
- package/dist/sharedString.cjs.map +1 -0
- package/dist/sharedString.d.ts +58 -22
- package/dist/sharedString.d.ts.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/lib/{defaultMap.d.ts → defaultMap.d.mts} +7 -6
- package/lib/defaultMap.d.mts.map +1 -0
- package/lib/{defaultMap.js → defaultMap.mjs} +28 -21
- package/lib/defaultMap.mjs.map +1 -0
- package/lib/{defaultMapInterfaces.d.ts → defaultMapInterfaces.d.mts} +44 -12
- package/lib/defaultMapInterfaces.d.mts.map +1 -0
- package/lib/defaultMapInterfaces.mjs +6 -0
- package/lib/defaultMapInterfaces.mjs.map +1 -0
- package/lib/index.d.mts +17 -0
- package/lib/index.d.mts.map +1 -0
- package/lib/index.mjs +16 -0
- package/lib/index.mjs.map +1 -0
- package/lib/intervalCollection.d.mts +569 -0
- package/lib/intervalCollection.d.mts.map +1 -0
- package/lib/intervalCollection.mjs +1144 -0
- package/lib/intervalCollection.mjs.map +1 -0
- package/lib/intervalIndex/endpointInRangeIndex.d.mts +34 -0
- package/lib/intervalIndex/endpointInRangeIndex.d.mts.map +1 -0
- package/lib/intervalIndex/endpointInRangeIndex.mjs +61 -0
- package/lib/intervalIndex/endpointInRangeIndex.mjs.map +1 -0
- package/lib/intervalIndex/endpointIndex.d.mts +38 -0
- package/lib/intervalIndex/endpointIndex.d.mts.map +1 -0
- package/lib/intervalIndex/endpointIndex.mjs +42 -0
- package/lib/intervalIndex/endpointIndex.mjs.map +1 -0
- package/lib/intervalIndex/idIntervalIndex.d.mts +18 -0
- package/lib/intervalIndex/idIntervalIndex.d.mts.map +1 -0
- package/lib/intervalIndex/idIntervalIndex.mjs +40 -0
- package/lib/intervalIndex/idIntervalIndex.mjs.map +1 -0
- package/lib/intervalIndex/index.d.mts +13 -0
- package/lib/intervalIndex/index.d.mts.map +1 -0
- package/lib/intervalIndex/index.mjs +11 -0
- package/lib/intervalIndex/index.mjs.map +1 -0
- package/lib/intervalIndex/intervalIndex.d.mts +30 -0
- package/lib/intervalIndex/intervalIndex.d.mts.map +1 -0
- package/lib/{defaultMapInterfaces.js → intervalIndex/intervalIndex.mjs} +1 -1
- package/lib/intervalIndex/intervalIndex.mjs.map +1 -0
- package/lib/intervalIndex/intervalIndexUtils.d.mts +17 -0
- package/lib/intervalIndex/intervalIndexUtils.d.mts.map +1 -0
- package/lib/intervalIndex/intervalIndexUtils.mjs +18 -0
- package/lib/intervalIndex/intervalIndexUtils.mjs.map +1 -0
- package/lib/intervalIndex/overlappingIntervalsIndex.d.mts +44 -0
- package/lib/intervalIndex/overlappingIntervalsIndex.d.mts.map +1 -0
- package/lib/intervalIndex/overlappingIntervalsIndex.mjs +111 -0
- package/lib/intervalIndex/overlappingIntervalsIndex.mjs.map +1 -0
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.mts +11 -0
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.mts.map +1 -0
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.mjs +37 -0
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.mjs.map +1 -0
- package/lib/intervalIndex/sequenceIntervalIndexes.d.mts +35 -0
- package/lib/intervalIndex/sequenceIntervalIndexes.d.mts.map +1 -0
- package/lib/intervalIndex/sequenceIntervalIndexes.mjs +6 -0
- package/lib/intervalIndex/sequenceIntervalIndexes.mjs.map +1 -0
- package/lib/intervalIndex/startpointInRangeIndex.d.mts +34 -0
- package/lib/intervalIndex/startpointInRangeIndex.d.mts.map +1 -0
- package/lib/intervalIndex/startpointInRangeIndex.mjs +61 -0
- package/lib/intervalIndex/startpointInRangeIndex.mjs.map +1 -0
- package/lib/intervalTree.d.mts +24 -0
- package/lib/intervalTree.d.mts.map +1 -0
- package/lib/intervalTree.mjs +76 -0
- package/lib/intervalTree.mjs.map +1 -0
- package/lib/intervals/index.d.mts +8 -0
- package/lib/intervals/index.d.mts.map +1 -0
- package/lib/intervals/index.mjs +8 -0
- package/lib/intervals/index.mjs.map +1 -0
- package/lib/intervals/interval.d.mts +84 -0
- package/lib/intervals/interval.d.mts.map +1 -0
- package/lib/intervals/interval.mjs +176 -0
- package/lib/intervals/interval.mjs.map +1 -0
- package/lib/intervals/intervalUtils.d.mts +230 -0
- package/lib/intervals/intervalUtils.d.mts.map +1 -0
- package/lib/intervals/intervalUtils.mjs +77 -0
- package/lib/intervals/intervalUtils.mjs.map +1 -0
- package/lib/intervals/sequenceInterval.d.mts +137 -0
- package/lib/intervals/sequenceInterval.d.mts.map +1 -0
- package/lib/intervals/sequenceInterval.mjs +370 -0
- package/lib/intervals/sequenceInterval.mjs.map +1 -0
- package/lib/{localValues.d.ts → localValues.d.mts} +3 -2
- package/lib/localValues.d.mts.map +1 -0
- package/lib/{localValues.js → localValues.mjs} +2 -2
- package/lib/localValues.mjs.map +1 -0
- package/lib/{packageVersion.d.ts → packageVersion.d.mts} +1 -1
- package/lib/{packageVersion.d.ts.map → packageVersion.d.mts.map} +1 -1
- package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
- package/lib/packageVersion.mjs.map +1 -0
- package/lib/revertibles.d.mts +86 -0
- package/lib/revertibles.d.mts.map +1 -0
- package/lib/revertibles.mjs +416 -0
- package/lib/revertibles.mjs.map +1 -0
- package/lib/sequence-alpha.d.mts +1315 -0
- package/lib/sequence-beta.d.mts +244 -0
- package/lib/sequence-public.d.mts +244 -0
- package/lib/sequence-untrimmed.d.mts +1803 -0
- package/lib/{sequence.d.ts → sequence.d.mts} +127 -50
- package/lib/sequence.d.mts.map +1 -0
- package/lib/{sequence.js → sequence.mjs} +225 -152
- package/lib/sequence.mjs.map +1 -0
- package/lib/{sequenceDeltaEvent.d.ts → sequenceDeltaEvent.d.mts} +24 -7
- package/lib/sequenceDeltaEvent.d.mts.map +1 -0
- package/lib/{sequenceDeltaEvent.js → sequenceDeltaEvent.mjs} +20 -8
- package/lib/sequenceDeltaEvent.mjs.map +1 -0
- package/lib/sequenceFactory.d.mts +22 -0
- package/lib/sequenceFactory.d.mts.map +1 -0
- package/lib/sequenceFactory.mjs +51 -0
- package/lib/sequenceFactory.mjs.map +1 -0
- package/lib/{sharedIntervalCollection.d.ts → sharedIntervalCollection.d.mts} +12 -12
- package/lib/sharedIntervalCollection.d.mts.map +1 -0
- package/lib/{sharedIntervalCollection.js → sharedIntervalCollection.mjs} +16 -21
- package/lib/sharedIntervalCollection.mjs.map +1 -0
- package/lib/{sharedSequence.d.ts → sharedSequence.d.mts} +15 -3
- package/lib/sharedSequence.d.mts.map +1 -0
- package/lib/{sharedSequence.js → sharedSequence.mjs} +30 -23
- package/lib/sharedSequence.mjs.map +1 -0
- package/lib/{sharedString.d.ts → sharedString.d.mts} +60 -24
- package/lib/sharedString.d.mts.map +1 -0
- package/lib/sharedString.mjs +281 -0
- package/lib/sharedString.mjs.map +1 -0
- package/package.json +146 -75
- package/prettier.config.cjs +8 -0
- package/sequence.test-files.tar +0 -0
- package/src/defaultMap.ts +417 -403
- package/src/defaultMapInterfaces.ts +157 -117
- package/src/index.ts +86 -26
- package/src/intervalCollection.ts +2043 -1563
- package/src/intervalIndex/endpointInRangeIndex.ts +116 -0
- package/src/intervalIndex/endpointIndex.ts +91 -0
- package/src/intervalIndex/idIntervalIndex.ts +64 -0
- package/src/intervalIndex/index.ts +25 -0
- package/src/intervalIndex/intervalIndex.ts +32 -0
- package/src/intervalIndex/intervalIndexUtils.ts +27 -0
- package/src/intervalIndex/overlappingIntervalsIndex.ts +187 -0
- package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +80 -0
- package/src/intervalIndex/sequenceIntervalIndexes.ts +34 -0
- package/src/intervalIndex/startpointInRangeIndex.ts +114 -0
- package/src/intervalTree.ts +98 -0
- package/src/intervals/index.ts +25 -0
- package/src/intervals/interval.ts +238 -0
- package/src/intervals/intervalUtils.ts +288 -0
- package/src/intervals/sequenceInterval.ts +616 -0
- package/src/localValues.ts +68 -73
- package/src/packageVersion.ts +1 -1
- package/src/revertibles.ts +693 -0
- package/src/sequence.ts +845 -690
- package/src/sequenceDeltaEvent.ts +164 -131
- package/src/sequenceFactory.ts +58 -214
- package/src/sharedIntervalCollection.ts +161 -152
- package/src/sharedSequence.ts +181 -167
- package/src/sharedString.ts +390 -234
- package/tsc-multi.test.json +10 -0
- package/tsconfig.json +11 -13
- package/.editorconfig +0 -7
- package/.vscode/launch.json +0 -15
- package/dist/defaultMap.js.map +0 -1
- package/dist/defaultMapInterfaces.js.map +0 -1
- package/dist/index.js +0 -44
- package/dist/index.js.map +0 -1
- package/dist/intervalCollection.js +0 -1250
- package/dist/intervalCollection.js.map +0 -1
- package/dist/localValues.js.map +0 -1
- package/dist/packageVersion.js.map +0 -1
- package/dist/sequence.js.map +0 -1
- package/dist/sequenceDeltaEvent.js.map +0 -1
- package/dist/sequenceFactory.js +0 -192
- package/dist/sequenceFactory.js.map +0 -1
- package/dist/sharedIntervalCollection.js.map +0 -1
- package/dist/sharedNumberSequence.d.ts +0 -50
- package/dist/sharedNumberSequence.d.ts.map +0 -1
- package/dist/sharedNumberSequence.js +0 -61
- package/dist/sharedNumberSequence.js.map +0 -1
- package/dist/sharedObjectSequence.d.ts +0 -50
- package/dist/sharedObjectSequence.d.ts.map +0 -1
- package/dist/sharedObjectSequence.js +0 -61
- package/dist/sharedObjectSequence.js.map +0 -1
- package/dist/sharedSequence.js.map +0 -1
- package/dist/sharedString.js +0 -187
- package/dist/sharedString.js.map +0 -1
- package/dist/sparsematrix.d.ts +0 -139
- package/dist/sparsematrix.d.ts.map +0 -1
- package/dist/sparsematrix.js +0 -332
- package/dist/sparsematrix.js.map +0 -1
- package/lib/defaultMap.d.ts.map +0 -1
- package/lib/defaultMap.js.map +0 -1
- package/lib/defaultMapInterfaces.d.ts.map +0 -1
- package/lib/defaultMapInterfaces.js.map +0 -1
- package/lib/index.d.ts +0 -27
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -26
- package/lib/index.js.map +0 -1
- package/lib/intervalCollection.d.ts +0 -270
- package/lib/intervalCollection.d.ts.map +0 -1
- package/lib/intervalCollection.js +0 -1238
- package/lib/intervalCollection.js.map +0 -1
- package/lib/localValues.d.ts.map +0 -1
- package/lib/localValues.js.map +0 -1
- package/lib/packageVersion.js.map +0 -1
- package/lib/sequence.d.ts.map +0 -1
- package/lib/sequence.js.map +0 -1
- package/lib/sequenceDeltaEvent.d.ts.map +0 -1
- package/lib/sequenceDeltaEvent.js.map +0 -1
- package/lib/sequenceFactory.d.ts +0 -108
- package/lib/sequenceFactory.d.ts.map +0 -1
- package/lib/sequenceFactory.js +0 -186
- package/lib/sequenceFactory.js.map +0 -1
- package/lib/sharedIntervalCollection.d.ts.map +0 -1
- package/lib/sharedIntervalCollection.js.map +0 -1
- package/lib/sharedNumberSequence.d.ts +0 -50
- package/lib/sharedNumberSequence.d.ts.map +0 -1
- package/lib/sharedNumberSequence.js +0 -57
- package/lib/sharedNumberSequence.js.map +0 -1
- package/lib/sharedObjectSequence.d.ts +0 -50
- package/lib/sharedObjectSequence.d.ts.map +0 -1
- package/lib/sharedObjectSequence.js +0 -57
- package/lib/sharedObjectSequence.js.map +0 -1
- package/lib/sharedSequence.d.ts.map +0 -1
- package/lib/sharedSequence.js.map +0 -1
- package/lib/sharedString.d.ts.map +0 -1
- package/lib/sharedString.js +0 -183
- package/lib/sharedString.js.map +0 -1
- package/lib/sparsematrix.d.ts +0 -139
- package/lib/sparsematrix.d.ts.map +0 -1
- package/lib/sparsematrix.js +0 -323
- package/lib/sparsematrix.js.map +0 -1
- package/src/sharedNumberSequence.ts +0 -62
- package/src/sharedObjectSequence.ts +0 -62
- package/src/sparsematrix.ts +0 -421
- package/tsconfig.esnext.json +0 -7
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable no-bitwise */
|
|
7
|
+
|
|
8
|
+
import { assert, unreachableCase } from "@fluidframework/core-utils";
|
|
9
|
+
import {
|
|
10
|
+
appendToMergeTreeDeltaRevertibles,
|
|
11
|
+
discardMergeTreeDeltaRevertible,
|
|
12
|
+
isMergeTreeDeltaRevertible,
|
|
13
|
+
LocalReferencePosition,
|
|
14
|
+
MergeTreeDeltaOperationType,
|
|
15
|
+
MergeTreeDeltaRevertible,
|
|
16
|
+
MergeTreeDeltaType,
|
|
17
|
+
PropertySet,
|
|
18
|
+
ReferenceType,
|
|
19
|
+
refTypeIncludesFlag,
|
|
20
|
+
revertMergeTreeDeltaRevertibles,
|
|
21
|
+
// eslint-disable-next-line import/no-deprecated
|
|
22
|
+
SortedSet,
|
|
23
|
+
getSlideToSegoff,
|
|
24
|
+
SlidingPreference,
|
|
25
|
+
} from "@fluidframework/merge-tree";
|
|
26
|
+
import { InteriorSequencePlace, Side } from "./intervalCollection";
|
|
27
|
+
import { IntervalOpType, SequenceInterval } from "./intervals";
|
|
28
|
+
import { SharedString, SharedStringSegment } from "./sharedString";
|
|
29
|
+
import { ISequenceDeltaRange, SequenceDeltaEvent } from "./sequenceDeltaEvent";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Data for undoing edits on SharedStrings and Intervals.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export type SharedStringRevertible = MergeTreeDeltaRevertible | IntervalRevertible;
|
|
36
|
+
|
|
37
|
+
const idMap = new Map<string, string>();
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Data for undoing edits affecting Intervals.
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export type IntervalRevertible =
|
|
44
|
+
| {
|
|
45
|
+
event: typeof IntervalOpType.CHANGE;
|
|
46
|
+
interval: SequenceInterval;
|
|
47
|
+
start: LocalReferencePosition;
|
|
48
|
+
end: LocalReferencePosition;
|
|
49
|
+
}
|
|
50
|
+
| {
|
|
51
|
+
event: typeof IntervalOpType.ADD;
|
|
52
|
+
interval: SequenceInterval;
|
|
53
|
+
}
|
|
54
|
+
| {
|
|
55
|
+
event: typeof IntervalOpType.DELETE;
|
|
56
|
+
interval: SequenceInterval;
|
|
57
|
+
start: LocalReferencePosition;
|
|
58
|
+
end: LocalReferencePosition;
|
|
59
|
+
}
|
|
60
|
+
| {
|
|
61
|
+
event: typeof IntervalOpType.PROPERTY_CHANGED;
|
|
62
|
+
interval: SequenceInterval;
|
|
63
|
+
propertyDeltas: PropertySet;
|
|
64
|
+
}
|
|
65
|
+
| {
|
|
66
|
+
event: typeof IntervalOpType.POSITION_REMOVE;
|
|
67
|
+
intervals: {
|
|
68
|
+
intervalId: string;
|
|
69
|
+
label: string;
|
|
70
|
+
startOffset?: number; // interval start index within a removed range
|
|
71
|
+
endOffset?: number; // interval end index within a removed range
|
|
72
|
+
}[];
|
|
73
|
+
// local refs used by IntervalOpType.CHANGE and DELETE revertibles
|
|
74
|
+
revertibleRefs: {
|
|
75
|
+
revertible: IntervalRevertible;
|
|
76
|
+
offset: number;
|
|
77
|
+
isStart: boolean;
|
|
78
|
+
}[];
|
|
79
|
+
mergeTreeRevertible: MergeTreeDeltaRevertible;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
type TypedRevertible<T extends IntervalRevertible["event"]> = IntervalRevertible & { event: T };
|
|
83
|
+
|
|
84
|
+
function getUpdatedIdFromInterval(interval: SequenceInterval): string {
|
|
85
|
+
const maybeId = interval.getIntervalId();
|
|
86
|
+
return getUpdatedId(maybeId);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getUpdatedId(intervalId: string): string {
|
|
90
|
+
return idMap.get(intervalId) ?? intervalId;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Create revertibles for adding an interval
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
97
|
+
export function appendAddIntervalToRevertibles(
|
|
98
|
+
interval: SequenceInterval,
|
|
99
|
+
revertibles: SharedStringRevertible[],
|
|
100
|
+
) {
|
|
101
|
+
revertibles.push({
|
|
102
|
+
event: IntervalOpType.ADD,
|
|
103
|
+
interval,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return revertibles;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Create revertibles for deleting an interval
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
113
|
+
export function appendDeleteIntervalToRevertibles(
|
|
114
|
+
string: SharedString,
|
|
115
|
+
interval: SequenceInterval,
|
|
116
|
+
revertibles: SharedStringRevertible[],
|
|
117
|
+
): SharedStringRevertible[] {
|
|
118
|
+
const startSeg = interval.start.getSegment() as SharedStringSegment | undefined;
|
|
119
|
+
if (!startSeg) {
|
|
120
|
+
return revertibles;
|
|
121
|
+
}
|
|
122
|
+
const startType =
|
|
123
|
+
startSeg.removedSeq !== undefined
|
|
124
|
+
? ReferenceType.SlideOnRemove | ReferenceType.RangeBegin
|
|
125
|
+
: ReferenceType.StayOnRemove | ReferenceType.RangeBegin;
|
|
126
|
+
const endSeg = interval.end.getSegment() as SharedStringSegment | undefined;
|
|
127
|
+
if (!endSeg) {
|
|
128
|
+
return revertibles;
|
|
129
|
+
}
|
|
130
|
+
const endType =
|
|
131
|
+
endSeg.removedSeq !== undefined
|
|
132
|
+
? ReferenceType.SlideOnRemove | ReferenceType.RangeEnd
|
|
133
|
+
: ReferenceType.StayOnRemove | ReferenceType.RangeEnd;
|
|
134
|
+
const startRef = string.createLocalReferencePosition(
|
|
135
|
+
startSeg,
|
|
136
|
+
interval.start.getOffset(),
|
|
137
|
+
startType,
|
|
138
|
+
undefined,
|
|
139
|
+
interval.start.slidingPreference,
|
|
140
|
+
);
|
|
141
|
+
const endRef = string.createLocalReferencePosition(
|
|
142
|
+
endSeg,
|
|
143
|
+
interval.end.getOffset(),
|
|
144
|
+
endType,
|
|
145
|
+
undefined,
|
|
146
|
+
interval.end.slidingPreference,
|
|
147
|
+
);
|
|
148
|
+
const revertible = {
|
|
149
|
+
event: IntervalOpType.DELETE,
|
|
150
|
+
interval,
|
|
151
|
+
start: startRef,
|
|
152
|
+
end: endRef,
|
|
153
|
+
};
|
|
154
|
+
revertible.start.addProperties({ revertible });
|
|
155
|
+
revertible.end.addProperties({ revertible });
|
|
156
|
+
revertibles.push(revertible);
|
|
157
|
+
|
|
158
|
+
return revertibles;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Create revertibles for moving endpoints of an interval
|
|
163
|
+
* @internal
|
|
164
|
+
*/
|
|
165
|
+
export function appendChangeIntervalToRevertibles(
|
|
166
|
+
string: SharedString,
|
|
167
|
+
newInterval: SequenceInterval,
|
|
168
|
+
previousInterval: SequenceInterval,
|
|
169
|
+
revertibles: SharedStringRevertible[],
|
|
170
|
+
) {
|
|
171
|
+
const startSeg = previousInterval.start.getSegment() as SharedStringSegment;
|
|
172
|
+
// This logic is needed because the ReferenceType StayOnRemove cannot be used
|
|
173
|
+
// on removed segments. This works for revertibles because the old position of the
|
|
174
|
+
// interval within the removed segment is handled by the remove range revertible.
|
|
175
|
+
const startType =
|
|
176
|
+
startSeg.removedSeq !== undefined
|
|
177
|
+
? ReferenceType.SlideOnRemove | ReferenceType.RangeBegin
|
|
178
|
+
: ReferenceType.StayOnRemove | ReferenceType.RangeBegin;
|
|
179
|
+
const endSeg = previousInterval.end.getSegment() as SharedStringSegment;
|
|
180
|
+
const endType =
|
|
181
|
+
endSeg.removedSeq !== undefined
|
|
182
|
+
? ReferenceType.SlideOnRemove | ReferenceType.RangeEnd
|
|
183
|
+
: ReferenceType.StayOnRemove | ReferenceType.RangeEnd;
|
|
184
|
+
const prevStartRef = string.createLocalReferencePosition(
|
|
185
|
+
startSeg,
|
|
186
|
+
previousInterval.start.getOffset(),
|
|
187
|
+
startType,
|
|
188
|
+
undefined,
|
|
189
|
+
previousInterval.start.slidingPreference,
|
|
190
|
+
);
|
|
191
|
+
const prevEndRef = string.createLocalReferencePosition(
|
|
192
|
+
endSeg,
|
|
193
|
+
previousInterval.end.getOffset(),
|
|
194
|
+
endType,
|
|
195
|
+
undefined,
|
|
196
|
+
previousInterval.end.slidingPreference,
|
|
197
|
+
);
|
|
198
|
+
const revertible = {
|
|
199
|
+
event: IntervalOpType.CHANGE,
|
|
200
|
+
interval: newInterval,
|
|
201
|
+
start: prevStartRef,
|
|
202
|
+
end: prevEndRef,
|
|
203
|
+
};
|
|
204
|
+
revertible.start.addProperties({ revertible });
|
|
205
|
+
revertible.end.addProperties({ revertible });
|
|
206
|
+
revertibles.push(revertible);
|
|
207
|
+
|
|
208
|
+
return revertibles;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Create revertibles for changing properties of an interval
|
|
213
|
+
* @internal
|
|
214
|
+
*/
|
|
215
|
+
export function appendIntervalPropertyChangedToRevertibles(
|
|
216
|
+
interval: SequenceInterval,
|
|
217
|
+
deltas: PropertySet,
|
|
218
|
+
revertibles: SharedStringRevertible[],
|
|
219
|
+
) {
|
|
220
|
+
revertibles.push({
|
|
221
|
+
event: IntervalOpType.PROPERTY_CHANGED,
|
|
222
|
+
interval,
|
|
223
|
+
propertyDeltas: deltas,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
return revertibles;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function addIfIntervalEndpoint(
|
|
230
|
+
ref: LocalReferencePosition,
|
|
231
|
+
segmentLengths: number,
|
|
232
|
+
startIntervals: { offset: number; interval: SequenceInterval }[],
|
|
233
|
+
endIntervals: { offset: number; interval: SequenceInterval }[],
|
|
234
|
+
) {
|
|
235
|
+
if (refTypeIncludesFlag(ref.refType, ReferenceType.RangeBegin)) {
|
|
236
|
+
const interval = ref.properties?.interval;
|
|
237
|
+
if (interval && interval instanceof SequenceInterval) {
|
|
238
|
+
startIntervals.push({ offset: segmentLengths + interval.start.getOffset(), interval });
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
} else if (refTypeIncludesFlag(ref.refType, ReferenceType.RangeEnd)) {
|
|
242
|
+
const interval = ref.properties?.interval;
|
|
243
|
+
if (interval && interval instanceof SequenceInterval) {
|
|
244
|
+
endIntervals.push({ offset: segmentLengths + interval.end.getOffset(), interval });
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function addIfRevertibleRef(
|
|
252
|
+
ref: LocalReferencePosition,
|
|
253
|
+
segmentLengths: number,
|
|
254
|
+
revertibleRefs: {
|
|
255
|
+
revertible: IntervalRevertible;
|
|
256
|
+
offset: number;
|
|
257
|
+
isStart: boolean;
|
|
258
|
+
}[],
|
|
259
|
+
) {
|
|
260
|
+
const revertible = ref.properties?.revertible;
|
|
261
|
+
if (revertible) {
|
|
262
|
+
revertibleRefs.push({
|
|
263
|
+
revertible,
|
|
264
|
+
offset: segmentLengths + ref.getOffset(),
|
|
265
|
+
isStart: refTypeIncludesFlag(ref.refType, ReferenceType.RangeBegin),
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Create revertibles for SharedStringDeltas, handling indirectly modified intervals
|
|
272
|
+
* (e.g. reverting remove of a range that contains an interval will move the interval back)
|
|
273
|
+
* @internal
|
|
274
|
+
*/
|
|
275
|
+
export function appendSharedStringDeltaToRevertibles(
|
|
276
|
+
string: SharedString,
|
|
277
|
+
delta: SequenceDeltaEvent,
|
|
278
|
+
revertibles: SharedStringRevertible[],
|
|
279
|
+
) {
|
|
280
|
+
if (delta.ranges.length === 0) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (delta.deltaOperation === MergeTreeDeltaType.REMOVE) {
|
|
284
|
+
const startIntervals: { offset: number; interval: SequenceInterval }[] = [];
|
|
285
|
+
const endIntervals: { offset: number; interval: SequenceInterval }[] = [];
|
|
286
|
+
const revertibleRefs: {
|
|
287
|
+
revertible: IntervalRevertible;
|
|
288
|
+
offset: number;
|
|
289
|
+
isStart: boolean;
|
|
290
|
+
}[] = [];
|
|
291
|
+
let segmentLengths = 0;
|
|
292
|
+
|
|
293
|
+
// find interval endpoints in each segment
|
|
294
|
+
for (const deltaRange of delta.ranges) {
|
|
295
|
+
const refs = deltaRange.segment.localRefs;
|
|
296
|
+
if (refs !== undefined && deltaRange.position !== -1) {
|
|
297
|
+
for (const ref of refs) {
|
|
298
|
+
addIfIntervalEndpoint(ref, segmentLengths, startIntervals, endIntervals);
|
|
299
|
+
addIfRevertibleRef(ref, segmentLengths, revertibleRefs);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
segmentLengths += deltaRange.segment.cachedLength;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (startIntervals.length > 0 || endIntervals.length > 0 || revertibleRefs.length > 0) {
|
|
306
|
+
const removeRevertibles: MergeTreeDeltaRevertible[] = [];
|
|
307
|
+
appendToMergeTreeDeltaRevertibles(delta.deltaArgs, removeRevertibles);
|
|
308
|
+
assert(
|
|
309
|
+
removeRevertibles.length === 1,
|
|
310
|
+
0x6c4 /* Remove revertible should be a single delta */,
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
const revertible: TypedRevertible<typeof IntervalOpType.POSITION_REMOVE> = {
|
|
314
|
+
event: IntervalOpType.POSITION_REMOVE,
|
|
315
|
+
intervals: [],
|
|
316
|
+
revertibleRefs,
|
|
317
|
+
mergeTreeRevertible: removeRevertibles[0],
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// add an interval for each startInterval, accounting for any corresponding endIntervals
|
|
321
|
+
startIntervals.forEach(({ interval, offset }) => {
|
|
322
|
+
// find any corresponding end for this interval
|
|
323
|
+
const endIntervalIndex = endIntervals.findIndex((end) => {
|
|
324
|
+
return end.interval === interval;
|
|
325
|
+
});
|
|
326
|
+
let endOffset: number | undefined;
|
|
327
|
+
if (endIntervalIndex !== -1) {
|
|
328
|
+
endOffset = endIntervals[endIntervalIndex].offset;
|
|
329
|
+
endIntervals.splice(endIntervalIndex, 1);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
revertible.intervals.push({
|
|
333
|
+
intervalId: interval.getIntervalId(),
|
|
334
|
+
label: interval.properties.referenceRangeLabels[0],
|
|
335
|
+
startOffset: offset,
|
|
336
|
+
endOffset,
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
// add any remaining endIntervals that aren't matched with a startInterval
|
|
341
|
+
endIntervals.forEach(({ interval, offset }) => {
|
|
342
|
+
revertible.intervals.push({
|
|
343
|
+
intervalId: interval.getIntervalId(),
|
|
344
|
+
label: interval.properties.referenceRangeLabels[0],
|
|
345
|
+
endOffset: offset,
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
revertibles.push(revertible);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Handle any merge tree delta that is not REMOVE or is REMOVE with no interval endpoints
|
|
355
|
+
const mergeTreeRevertibles: MergeTreeDeltaRevertible[] = [];
|
|
356
|
+
// Allow merging MergeTreeDeltaRevertible with previous
|
|
357
|
+
if (revertibles.length > 0 && isMergeTreeDeltaRevertible(revertibles[revertibles.length - 1])) {
|
|
358
|
+
mergeTreeRevertibles.push(revertibles.pop() as MergeTreeDeltaRevertible);
|
|
359
|
+
}
|
|
360
|
+
appendToMergeTreeDeltaRevertibles(delta.deltaArgs, mergeTreeRevertibles);
|
|
361
|
+
revertibles.push(...mergeTreeRevertibles);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Clean up resources held by revertibles that are no longer needed.
|
|
366
|
+
* @internal
|
|
367
|
+
*/
|
|
368
|
+
export function discardSharedStringRevertibles(
|
|
369
|
+
sharedString: SharedString,
|
|
370
|
+
revertibles: SharedStringRevertible[],
|
|
371
|
+
) {
|
|
372
|
+
revertibles.forEach((r) => {
|
|
373
|
+
if (isMergeTreeDeltaRevertible(r)) {
|
|
374
|
+
discardMergeTreeDeltaRevertible([r]);
|
|
375
|
+
} else if (r.event === IntervalOpType.CHANGE || r.event === IntervalOpType.DELETE) {
|
|
376
|
+
sharedString.removeLocalReferencePosition(r.start);
|
|
377
|
+
sharedString.removeLocalReferencePosition(r.end);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function getSlidePosition(string: SharedString, lref: LocalReferencePosition, pos: number): number {
|
|
383
|
+
const slide = getSlideToSegoff(
|
|
384
|
+
{ segment: lref.getSegment(), offset: undefined },
|
|
385
|
+
lref.slidingPreference,
|
|
386
|
+
);
|
|
387
|
+
return slide?.segment !== undefined &&
|
|
388
|
+
slide.offset !== undefined &&
|
|
389
|
+
string.getPosition(slide.segment) !== -1 &&
|
|
390
|
+
(pos < 0 || pos >= string.getLength())
|
|
391
|
+
? string.getPosition(slide.segment) + slide.offset
|
|
392
|
+
: pos;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function isValidRange(
|
|
396
|
+
start: number,
|
|
397
|
+
startSlide: SlidingPreference | undefined,
|
|
398
|
+
end: number,
|
|
399
|
+
endSlide: SlidingPreference | undefined,
|
|
400
|
+
string: SharedString,
|
|
401
|
+
) {
|
|
402
|
+
return (
|
|
403
|
+
start >= 0 &&
|
|
404
|
+
start < string.getLength() &&
|
|
405
|
+
end >= 0 &&
|
|
406
|
+
end < string.getLength() &&
|
|
407
|
+
(start < end ||
|
|
408
|
+
(start === end &&
|
|
409
|
+
(startSlide === SlidingPreference.FORWARD ||
|
|
410
|
+
endSlide !== SlidingPreference.FORWARD)))
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function revertLocalAdd(
|
|
415
|
+
string: SharedString,
|
|
416
|
+
revertible: TypedRevertible<typeof IntervalOpType.ADD>,
|
|
417
|
+
) {
|
|
418
|
+
const id = getUpdatedIdFromInterval(revertible.interval);
|
|
419
|
+
const label = revertible.interval.properties.referenceRangeLabels[0];
|
|
420
|
+
string.getIntervalCollection(label).removeIntervalById(id);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function createSequencePlace(
|
|
424
|
+
pos: number,
|
|
425
|
+
newSlidingPreference: SlidingPreference | undefined,
|
|
426
|
+
oldSlidingPreference: SlidingPreference | undefined = undefined,
|
|
427
|
+
): number | InteriorSequencePlace {
|
|
428
|
+
return newSlidingPreference === SlidingPreference.BACKWARD ||
|
|
429
|
+
(newSlidingPreference === undefined && oldSlidingPreference === SlidingPreference.BACKWARD)
|
|
430
|
+
? {
|
|
431
|
+
pos,
|
|
432
|
+
side: Side.After,
|
|
433
|
+
}
|
|
434
|
+
: newSlidingPreference === SlidingPreference.FORWARD &&
|
|
435
|
+
oldSlidingPreference === SlidingPreference.BACKWARD
|
|
436
|
+
? {
|
|
437
|
+
pos,
|
|
438
|
+
side: Side.Before,
|
|
439
|
+
}
|
|
440
|
+
: pos; // Avoid setting side if possible since stickiness may not be enabled
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function revertLocalDelete(
|
|
444
|
+
string: SharedString,
|
|
445
|
+
revertible: TypedRevertible<typeof IntervalOpType.DELETE>,
|
|
446
|
+
) {
|
|
447
|
+
const label = revertible.interval.properties.referenceRangeLabels[0];
|
|
448
|
+
const collection = string.getIntervalCollection(label);
|
|
449
|
+
const start = string.localReferencePositionToPosition(revertible.start);
|
|
450
|
+
const startSlidePos = getSlidePosition(string, revertible.start, start);
|
|
451
|
+
const end = string.localReferencePositionToPosition(revertible.end);
|
|
452
|
+
const endSlidePos = getSlidePosition(string, revertible.end, end);
|
|
453
|
+
// reusing the id causes eventual consistency bugs, so it is removed here and recreated in add
|
|
454
|
+
const { intervalId, ...props } = revertible.interval.properties;
|
|
455
|
+
if (
|
|
456
|
+
isValidRange(
|
|
457
|
+
startSlidePos,
|
|
458
|
+
revertible.start.slidingPreference,
|
|
459
|
+
endSlidePos,
|
|
460
|
+
revertible.end.slidingPreference,
|
|
461
|
+
string,
|
|
462
|
+
)
|
|
463
|
+
) {
|
|
464
|
+
const int = collection.add({
|
|
465
|
+
start: createSequencePlace(startSlidePos, revertible.start.slidingPreference),
|
|
466
|
+
end: createSequencePlace(endSlidePos, revertible.end.slidingPreference),
|
|
467
|
+
props,
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
idMap.forEach((newId, oldId) => {
|
|
471
|
+
if (intervalId === newId) {
|
|
472
|
+
idMap.set(oldId, getUpdatedIdFromInterval(int));
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
idMap.set(intervalId, int.getIntervalId());
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
string.removeLocalReferencePosition(revertible.start);
|
|
479
|
+
string.removeLocalReferencePosition(revertible.end);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function revertLocalChange(
|
|
483
|
+
string: SharedString,
|
|
484
|
+
revertible: TypedRevertible<typeof IntervalOpType.CHANGE>,
|
|
485
|
+
) {
|
|
486
|
+
const label = revertible.interval.properties.referenceRangeLabels[0];
|
|
487
|
+
const collection = string.getIntervalCollection(label);
|
|
488
|
+
const id = getUpdatedIdFromInterval(revertible.interval);
|
|
489
|
+
const start = string.localReferencePositionToPosition(revertible.start);
|
|
490
|
+
const startSlidePos = getSlidePosition(string, revertible.start, start);
|
|
491
|
+
const end = string.localReferencePositionToPosition(revertible.end);
|
|
492
|
+
const endSlidePos = getSlidePosition(string, revertible.end, end);
|
|
493
|
+
const interval = collection.getIntervalById(id);
|
|
494
|
+
if (
|
|
495
|
+
interval !== undefined &&
|
|
496
|
+
isValidRange(
|
|
497
|
+
startSlidePos,
|
|
498
|
+
revertible.start.slidingPreference ?? interval.start.slidingPreference,
|
|
499
|
+
endSlidePos,
|
|
500
|
+
revertible.end.slidingPreference ?? interval.end.slidingPreference,
|
|
501
|
+
string,
|
|
502
|
+
)
|
|
503
|
+
) {
|
|
504
|
+
collection.change(
|
|
505
|
+
id,
|
|
506
|
+
createSequencePlace(
|
|
507
|
+
startSlidePos,
|
|
508
|
+
revertible.start.slidingPreference,
|
|
509
|
+
interval.start.slidingPreference,
|
|
510
|
+
),
|
|
511
|
+
createSequencePlace(
|
|
512
|
+
endSlidePos,
|
|
513
|
+
revertible.end.slidingPreference,
|
|
514
|
+
interval.end.slidingPreference,
|
|
515
|
+
),
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
string.removeLocalReferencePosition(revertible.start);
|
|
520
|
+
string.removeLocalReferencePosition(revertible.end);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
function revertLocalPropertyChanged(
|
|
524
|
+
string: SharedString,
|
|
525
|
+
revertible: TypedRevertible<typeof IntervalOpType.PROPERTY_CHANGED>,
|
|
526
|
+
) {
|
|
527
|
+
const label = revertible.interval.properties.referenceRangeLabels[0];
|
|
528
|
+
const id = getUpdatedIdFromInterval(revertible.interval);
|
|
529
|
+
const newProps = revertible.propertyDeltas;
|
|
530
|
+
string.getIntervalCollection(label).changeProperties(id, newProps);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
function newPosition(offset: number | undefined, restoredRanges: SortedRangeSet) {
|
|
534
|
+
if (offset === undefined) {
|
|
535
|
+
return undefined;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
let offsetFromSegment = offset;
|
|
539
|
+
for (const rangeInfo of restoredRanges.items) {
|
|
540
|
+
if (offsetFromSegment < rangeInfo.length) {
|
|
541
|
+
// find the segment inside the range
|
|
542
|
+
for (const range of rangeInfo.ranges) {
|
|
543
|
+
if (range.segment.cachedLength > offsetFromSegment) {
|
|
544
|
+
return { segment: range.segment, offset: offsetFromSegment };
|
|
545
|
+
}
|
|
546
|
+
offsetFromSegment -= range.segment.cachedLength;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
offsetFromSegment -= rangeInfo.length;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
return undefined;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
function newEndpointPosition(
|
|
556
|
+
offset: number | undefined,
|
|
557
|
+
restoredRanges: SortedRangeSet,
|
|
558
|
+
sharedString: SharedString,
|
|
559
|
+
) {
|
|
560
|
+
const pos = newPosition(offset, restoredRanges);
|
|
561
|
+
return pos === undefined ? undefined : sharedString.getPosition(pos.segment) + pos.offset;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
interface RangeInfo {
|
|
565
|
+
ranges: readonly Readonly<ISequenceDeltaRange<MergeTreeDeltaOperationType>>[];
|
|
566
|
+
length: number;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// eslint-disable-next-line import/no-deprecated
|
|
570
|
+
class SortedRangeSet extends SortedSet<RangeInfo, string> {
|
|
571
|
+
protected getKey(item: RangeInfo): string {
|
|
572
|
+
return item.ranges[0].segment.ordinal;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function revertLocalSequenceRemove(
|
|
577
|
+
sharedString: SharedString,
|
|
578
|
+
revertible: TypedRevertible<typeof IntervalOpType.POSITION_REMOVE>,
|
|
579
|
+
) {
|
|
580
|
+
const restoredRanges = new SortedRangeSet();
|
|
581
|
+
const saveSegments = (event: SequenceDeltaEvent) => {
|
|
582
|
+
if (event.ranges.length > 0) {
|
|
583
|
+
let length = 0;
|
|
584
|
+
event.ranges.forEach((range) => {
|
|
585
|
+
length += range.segment.cachedLength;
|
|
586
|
+
});
|
|
587
|
+
restoredRanges.addOrUpdate({ ranges: event.ranges, length });
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
sharedString.on("sequenceDelta", saveSegments);
|
|
591
|
+
revertMergeTreeDeltaRevertibles(sharedString, [revertible.mergeTreeRevertible]);
|
|
592
|
+
sharedString.off("sequenceDelta", saveSegments);
|
|
593
|
+
|
|
594
|
+
revertible.intervals.forEach((intervalInfo) => {
|
|
595
|
+
const intervalCollection = sharedString.getIntervalCollection(intervalInfo.label);
|
|
596
|
+
const intervalId = getUpdatedId(intervalInfo.intervalId);
|
|
597
|
+
const interval = intervalCollection.getIntervalById(intervalId);
|
|
598
|
+
if (interval !== undefined) {
|
|
599
|
+
const start =
|
|
600
|
+
newEndpointPosition(intervalInfo.startOffset, restoredRanges, sharedString) ??
|
|
601
|
+
sharedString.localReferencePositionToPosition(interval.start);
|
|
602
|
+
const end =
|
|
603
|
+
newEndpointPosition(intervalInfo.endOffset, restoredRanges, sharedString) ??
|
|
604
|
+
sharedString.localReferencePositionToPosition(interval.end);
|
|
605
|
+
if (
|
|
606
|
+
isValidRange(
|
|
607
|
+
start,
|
|
608
|
+
interval.start.slidingPreference,
|
|
609
|
+
end,
|
|
610
|
+
interval.end.slidingPreference,
|
|
611
|
+
sharedString,
|
|
612
|
+
)
|
|
613
|
+
) {
|
|
614
|
+
intervalCollection.change(
|
|
615
|
+
intervalId,
|
|
616
|
+
createSequencePlace(start, interval.start.slidingPreference),
|
|
617
|
+
createSequencePlace(end, interval.end.slidingPreference),
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
// fix up the local references used by delete and change revertibles
|
|
624
|
+
revertible.revertibleRefs.forEach((revertibleRef) => {
|
|
625
|
+
assert(
|
|
626
|
+
revertibleRef.revertible.event === IntervalOpType.CHANGE ||
|
|
627
|
+
revertibleRef.revertible.event === IntervalOpType.DELETE,
|
|
628
|
+
0x6c5 /* revertible is not delete or change */,
|
|
629
|
+
);
|
|
630
|
+
const pos = newPosition(revertibleRef.offset, restoredRanges);
|
|
631
|
+
if (pos !== undefined) {
|
|
632
|
+
if (revertibleRef.isStart) {
|
|
633
|
+
sharedString.removeLocalReferencePosition(revertibleRef.revertible.start);
|
|
634
|
+
const newRef = sharedString.createLocalReferencePosition(
|
|
635
|
+
pos.segment as SharedStringSegment,
|
|
636
|
+
pos.offset,
|
|
637
|
+
ReferenceType.StayOnRemove | ReferenceType.RangeBegin,
|
|
638
|
+
{ revertible: revertibleRef.revertible },
|
|
639
|
+
revertibleRef.revertible.start.slidingPreference,
|
|
640
|
+
);
|
|
641
|
+
revertibleRef.revertible.start = newRef;
|
|
642
|
+
} else {
|
|
643
|
+
sharedString.removeLocalReferencePosition(revertibleRef.revertible.end);
|
|
644
|
+
const newRef = sharedString.createLocalReferencePosition(
|
|
645
|
+
pos.segment as SharedStringSegment,
|
|
646
|
+
pos.offset,
|
|
647
|
+
ReferenceType.StayOnRemove | ReferenceType.RangeEnd,
|
|
648
|
+
{ revertible: revertibleRef.revertible },
|
|
649
|
+
revertibleRef.revertible.end.slidingPreference,
|
|
650
|
+
);
|
|
651
|
+
revertibleRef.revertible.end = newRef;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Invoke revertibles to reverse prior edits
|
|
659
|
+
* @internal
|
|
660
|
+
*/
|
|
661
|
+
export function revertSharedStringRevertibles(
|
|
662
|
+
sharedString: SharedString,
|
|
663
|
+
revertibles: SharedStringRevertible[],
|
|
664
|
+
) {
|
|
665
|
+
while (revertibles.length > 0) {
|
|
666
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
667
|
+
const r = revertibles.pop()!;
|
|
668
|
+
if ("event" in r) {
|
|
669
|
+
const event = r.event;
|
|
670
|
+
switch (event) {
|
|
671
|
+
case IntervalOpType.ADD:
|
|
672
|
+
revertLocalAdd(sharedString, r);
|
|
673
|
+
break;
|
|
674
|
+
case IntervalOpType.DELETE:
|
|
675
|
+
revertLocalDelete(sharedString, r);
|
|
676
|
+
break;
|
|
677
|
+
case IntervalOpType.CHANGE:
|
|
678
|
+
revertLocalChange(sharedString, r);
|
|
679
|
+
break;
|
|
680
|
+
case IntervalOpType.PROPERTY_CHANGED:
|
|
681
|
+
revertLocalPropertyChanged(sharedString, r);
|
|
682
|
+
break;
|
|
683
|
+
case IntervalOpType.POSITION_REMOVE:
|
|
684
|
+
revertLocalSequenceRemove(sharedString, r);
|
|
685
|
+
break;
|
|
686
|
+
default:
|
|
687
|
+
unreachableCase(event);
|
|
688
|
+
}
|
|
689
|
+
} else {
|
|
690
|
+
revertMergeTreeDeltaRevertibles(sharedString, [r]);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|