@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
|
@@ -1,1250 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*!
|
|
3
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
-
* Licensed under the MIT License.
|
|
5
|
-
*/
|
|
6
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
7
|
-
var t = {};
|
|
8
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
9
|
-
t[p] = s[p];
|
|
10
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
11
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
12
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
13
|
-
t[p[i]] = s[p[i]];
|
|
14
|
-
}
|
|
15
|
-
return t;
|
|
16
|
-
};
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.IntervalCollection = exports.IntervalCollectionIterator = exports.IntervalCollectionValueType = exports.SequenceIntervalCollectionValueType = exports.LocalIntervalCollection = exports.createIntervalIndex = exports.defaultIntervalConflictResolver = exports.SequenceInterval = exports.Interval = exports.IntervalType = void 0;
|
|
19
|
-
/* eslint-disable no-bitwise */
|
|
20
|
-
const common_utils_1 = require("@fluidframework/common-utils");
|
|
21
|
-
const container_utils_1 = require("@fluidframework/container-utils");
|
|
22
|
-
const merge_tree_1 = require("@fluidframework/merge-tree");
|
|
23
|
-
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
24
|
-
const uuid_1 = require("uuid");
|
|
25
|
-
const reservedIntervalIdKey = "intervalId";
|
|
26
|
-
var IntervalType;
|
|
27
|
-
(function (IntervalType) {
|
|
28
|
-
IntervalType[IntervalType["Simple"] = 0] = "Simple";
|
|
29
|
-
IntervalType[IntervalType["Nest"] = 1] = "Nest";
|
|
30
|
-
/**
|
|
31
|
-
* SlideOnRemove indicates that the ends of the interval will slide if the segment
|
|
32
|
-
* they reference is removed and acked.
|
|
33
|
-
* See `packages\dds\merge-tree\REFERENCEPOSITIONS.md` for details
|
|
34
|
-
* SlideOnRemove is the default interval behavior and does not need to be specified.
|
|
35
|
-
*/
|
|
36
|
-
IntervalType[IntervalType["SlideOnRemove"] = 2] = "SlideOnRemove";
|
|
37
|
-
/**
|
|
38
|
-
* @internal
|
|
39
|
-
* A temporary interval, used internally
|
|
40
|
-
*/
|
|
41
|
-
IntervalType[IntervalType["Transient"] = 4] = "Transient";
|
|
42
|
-
})(IntervalType = exports.IntervalType || (exports.IntervalType = {}));
|
|
43
|
-
/**
|
|
44
|
-
* Decompress an interval after loading a summary from JSON. The exact format
|
|
45
|
-
* of this compression is unspecified and subject to change
|
|
46
|
-
*/
|
|
47
|
-
function decompressInterval(interval, label) {
|
|
48
|
-
return {
|
|
49
|
-
start: interval[0],
|
|
50
|
-
end: interval[1],
|
|
51
|
-
sequenceNumber: interval[2],
|
|
52
|
-
intervalType: interval[3],
|
|
53
|
-
properties: Object.assign(Object.assign({}, interval[4]), { [merge_tree_1.reservedRangeLabelsKey]: label }),
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Compress an interval prior to serialization as JSON. The exact format of this
|
|
58
|
-
* compression is unspecified and subject to change
|
|
59
|
-
*/
|
|
60
|
-
function compressInterval(interval) {
|
|
61
|
-
const { start, end, sequenceNumber, intervalType, properties } = interval;
|
|
62
|
-
return [
|
|
63
|
-
start,
|
|
64
|
-
end,
|
|
65
|
-
sequenceNumber,
|
|
66
|
-
intervalType,
|
|
67
|
-
Object.assign(Object.assign({}, properties), { [merge_tree_1.reservedRangeLabelsKey]: undefined }),
|
|
68
|
-
];
|
|
69
|
-
}
|
|
70
|
-
class Interval {
|
|
71
|
-
constructor(start, end, props) {
|
|
72
|
-
this.start = start;
|
|
73
|
-
this.end = end;
|
|
74
|
-
this.propertyManager = new merge_tree_1.PropertiesManager();
|
|
75
|
-
this.properties = {};
|
|
76
|
-
if (props) {
|
|
77
|
-
this.addProperties(props);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
getIntervalId() {
|
|
81
|
-
var _a;
|
|
82
|
-
const id = (_a = this.properties) === null || _a === void 0 ? void 0 : _a[reservedIntervalIdKey];
|
|
83
|
-
if (id === undefined) {
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
return `${id}`;
|
|
87
|
-
}
|
|
88
|
-
getAdditionalPropertySets() {
|
|
89
|
-
return this.auxProps;
|
|
90
|
-
}
|
|
91
|
-
addPropertySet(props) {
|
|
92
|
-
if (this.auxProps === undefined) {
|
|
93
|
-
this.auxProps = [];
|
|
94
|
-
}
|
|
95
|
-
this.auxProps.push(props);
|
|
96
|
-
}
|
|
97
|
-
serialize(client) {
|
|
98
|
-
let seq = 0;
|
|
99
|
-
if (client) {
|
|
100
|
-
seq = client.getCurrentSeq();
|
|
101
|
-
}
|
|
102
|
-
const serializedInterval = {
|
|
103
|
-
end: this.end,
|
|
104
|
-
intervalType: 0,
|
|
105
|
-
sequenceNumber: seq,
|
|
106
|
-
start: this.start,
|
|
107
|
-
};
|
|
108
|
-
if (this.properties) {
|
|
109
|
-
serializedInterval.properties = this.properties;
|
|
110
|
-
}
|
|
111
|
-
return serializedInterval;
|
|
112
|
-
}
|
|
113
|
-
clone() {
|
|
114
|
-
return new Interval(this.start, this.end, this.properties);
|
|
115
|
-
}
|
|
116
|
-
compare(b) {
|
|
117
|
-
const startResult = this.compareStart(b);
|
|
118
|
-
if (startResult === 0) {
|
|
119
|
-
const endResult = this.compareEnd(b);
|
|
120
|
-
if (endResult === 0) {
|
|
121
|
-
const thisId = this.getIntervalId();
|
|
122
|
-
if (thisId) {
|
|
123
|
-
const bId = b.getIntervalId();
|
|
124
|
-
if (bId) {
|
|
125
|
-
return thisId > bId ? 1 : thisId < bId ? -1 : 0;
|
|
126
|
-
}
|
|
127
|
-
return 0;
|
|
128
|
-
}
|
|
129
|
-
return 0;
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
return endResult;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
return startResult;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
compareStart(b) {
|
|
140
|
-
return this.start - b.start;
|
|
141
|
-
}
|
|
142
|
-
compareEnd(b) {
|
|
143
|
-
return this.end - b.end;
|
|
144
|
-
}
|
|
145
|
-
overlaps(b) {
|
|
146
|
-
const result = (this.start <= b.end) &&
|
|
147
|
-
(this.end >= b.start);
|
|
148
|
-
return result;
|
|
149
|
-
}
|
|
150
|
-
union(b) {
|
|
151
|
-
return new Interval(Math.min(this.start, b.start), Math.max(this.end, b.end), this.properties);
|
|
152
|
-
}
|
|
153
|
-
getProperties() {
|
|
154
|
-
return this.properties;
|
|
155
|
-
}
|
|
156
|
-
addProperties(newProps, collaborating = false, seq, op) {
|
|
157
|
-
if (newProps) {
|
|
158
|
-
this.initializeProperties();
|
|
159
|
-
return this.propertyManager.addProperties(this.properties, newProps, op, seq, collaborating);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
modify(label, start, end, op) {
|
|
163
|
-
const startPos = start !== null && start !== void 0 ? start : this.start;
|
|
164
|
-
const endPos = end !== null && end !== void 0 ? end : this.end;
|
|
165
|
-
if (this.start === startPos && this.end === endPos) {
|
|
166
|
-
// Return undefined to indicate that no change is necessary.
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
const newInterval = new Interval(startPos, endPos);
|
|
170
|
-
if (this.properties) {
|
|
171
|
-
newInterval.initializeProperties();
|
|
172
|
-
this.propertyManager.copyTo(this.properties, newInterval.properties, newInterval.propertyManager);
|
|
173
|
-
}
|
|
174
|
-
return newInterval;
|
|
175
|
-
}
|
|
176
|
-
initializeProperties() {
|
|
177
|
-
if (!this.propertyManager) {
|
|
178
|
-
this.propertyManager = new merge_tree_1.PropertiesManager();
|
|
179
|
-
}
|
|
180
|
-
if (!this.properties) {
|
|
181
|
-
this.properties = (0, merge_tree_1.createMap)();
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
exports.Interval = Interval;
|
|
186
|
-
class SequenceInterval {
|
|
187
|
-
constructor(start, end, intervalType, props) {
|
|
188
|
-
this.start = start;
|
|
189
|
-
this.end = end;
|
|
190
|
-
this.intervalType = intervalType;
|
|
191
|
-
this.propertyManager = new merge_tree_1.PropertiesManager();
|
|
192
|
-
this.properties = {};
|
|
193
|
-
if (props) {
|
|
194
|
-
this.addProperties(props);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* @internal
|
|
199
|
-
* Subscribes to position change events on this interval if there are no current listeners.
|
|
200
|
-
*/
|
|
201
|
-
addPositionChangeListeners(beforePositionChange, afterPositionChange) {
|
|
202
|
-
var _a, _b;
|
|
203
|
-
var _c, _d;
|
|
204
|
-
if (this.callbacks === undefined) {
|
|
205
|
-
this.callbacks = {
|
|
206
|
-
beforePositionChange,
|
|
207
|
-
afterPositionChange,
|
|
208
|
-
};
|
|
209
|
-
const startCbs = (_a = (_c = this.start).callbacks) !== null && _a !== void 0 ? _a : (_c.callbacks = {});
|
|
210
|
-
const endCbs = (_b = (_d = this.end).callbacks) !== null && _b !== void 0 ? _b : (_d.callbacks = {});
|
|
211
|
-
startCbs.beforeSlide = endCbs.beforeSlide = beforePositionChange;
|
|
212
|
-
startCbs.afterSlide = endCbs.afterSlide = afterPositionChange;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* @internal
|
|
217
|
-
* Removes the currently subscribed position change listeners.
|
|
218
|
-
*/
|
|
219
|
-
removePositionChangeListeners() {
|
|
220
|
-
if (this.callbacks) {
|
|
221
|
-
this.callbacks = undefined;
|
|
222
|
-
this.start.callbacks = undefined;
|
|
223
|
-
this.end.callbacks = undefined;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
serialize(client) {
|
|
227
|
-
const startPosition = this.start.toPosition();
|
|
228
|
-
const endPosition = this.end.toPosition();
|
|
229
|
-
const serializedInterval = {
|
|
230
|
-
end: endPosition,
|
|
231
|
-
intervalType: this.intervalType,
|
|
232
|
-
sequenceNumber: client.getCurrentSeq(),
|
|
233
|
-
start: startPosition,
|
|
234
|
-
};
|
|
235
|
-
if (this.properties) {
|
|
236
|
-
serializedInterval.properties = this.properties;
|
|
237
|
-
}
|
|
238
|
-
return serializedInterval;
|
|
239
|
-
}
|
|
240
|
-
clone() {
|
|
241
|
-
return new SequenceInterval(this.start, this.end, this.intervalType, this.properties);
|
|
242
|
-
}
|
|
243
|
-
compare(b) {
|
|
244
|
-
const startResult = this.compareStart(b);
|
|
245
|
-
if (startResult === 0) {
|
|
246
|
-
const endResult = this.compareEnd(b);
|
|
247
|
-
if (endResult === 0) {
|
|
248
|
-
const thisId = this.getIntervalId();
|
|
249
|
-
if (thisId) {
|
|
250
|
-
const bId = b.getIntervalId();
|
|
251
|
-
if (bId) {
|
|
252
|
-
return thisId > bId ? 1 : thisId < bId ? -1 : 0;
|
|
253
|
-
}
|
|
254
|
-
return 0;
|
|
255
|
-
}
|
|
256
|
-
return 0;
|
|
257
|
-
}
|
|
258
|
-
else {
|
|
259
|
-
return endResult;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
return startResult;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
compareStart(b) {
|
|
267
|
-
return this.start.compare(b.start);
|
|
268
|
-
}
|
|
269
|
-
compareEnd(b) {
|
|
270
|
-
return this.end.compare(b.end);
|
|
271
|
-
}
|
|
272
|
-
overlaps(b) {
|
|
273
|
-
const result = (this.start.compare(b.end) <= 0) &&
|
|
274
|
-
(this.end.compare(b.start) >= 0);
|
|
275
|
-
return result;
|
|
276
|
-
}
|
|
277
|
-
getIntervalId() {
|
|
278
|
-
var _a;
|
|
279
|
-
const id = (_a = this.properties) === null || _a === void 0 ? void 0 : _a[reservedIntervalIdKey];
|
|
280
|
-
if (id === undefined) {
|
|
281
|
-
return undefined;
|
|
282
|
-
}
|
|
283
|
-
return `${id}`;
|
|
284
|
-
}
|
|
285
|
-
union(b) {
|
|
286
|
-
return new SequenceInterval(this.start.min(b.start), this.end.max(b.end), this.intervalType);
|
|
287
|
-
}
|
|
288
|
-
addProperties(newProps, collab = false, seq, op) {
|
|
289
|
-
this.initializeProperties();
|
|
290
|
-
return this.propertyManager.addProperties(this.properties, newProps, op, seq, collab);
|
|
291
|
-
}
|
|
292
|
-
overlapsPos(bstart, bend) {
|
|
293
|
-
const startPos = this.start.toPosition();
|
|
294
|
-
const endPos = this.start.toPosition();
|
|
295
|
-
return (endPos > bstart) && (startPos < bend);
|
|
296
|
-
}
|
|
297
|
-
modify(label, start, end, op) {
|
|
298
|
-
const getRefType = (baseType) => {
|
|
299
|
-
let refType = baseType;
|
|
300
|
-
if (op === undefined) {
|
|
301
|
-
refType &= ~merge_tree_1.ReferenceType.SlideOnRemove;
|
|
302
|
-
refType |= merge_tree_1.ReferenceType.StayOnRemove;
|
|
303
|
-
}
|
|
304
|
-
return refType;
|
|
305
|
-
};
|
|
306
|
-
let startRef = this.start;
|
|
307
|
-
if (start !== undefined) {
|
|
308
|
-
startRef = createPositionReference(this.start.getClient(), start, getRefType(this.start.refType), op);
|
|
309
|
-
startRef.addProperties(this.start.properties);
|
|
310
|
-
}
|
|
311
|
-
let endRef = this.end;
|
|
312
|
-
if (end !== undefined) {
|
|
313
|
-
endRef = createPositionReference(this.end.getClient(), end, getRefType(this.end.refType), op);
|
|
314
|
-
endRef.addProperties(this.end.properties);
|
|
315
|
-
}
|
|
316
|
-
startRef.pairedRef = endRef;
|
|
317
|
-
endRef.pairedRef = startRef;
|
|
318
|
-
const newInterval = new SequenceInterval(startRef, endRef, this.intervalType);
|
|
319
|
-
if (this.properties) {
|
|
320
|
-
newInterval.initializeProperties();
|
|
321
|
-
this.propertyManager.copyTo(this.properties, newInterval.properties, newInterval.propertyManager);
|
|
322
|
-
}
|
|
323
|
-
return newInterval;
|
|
324
|
-
}
|
|
325
|
-
initializeProperties() {
|
|
326
|
-
if (!this.propertyManager) {
|
|
327
|
-
this.propertyManager = new merge_tree_1.PropertiesManager();
|
|
328
|
-
}
|
|
329
|
-
if (!this.properties) {
|
|
330
|
-
this.properties = (0, merge_tree_1.createMap)();
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
exports.SequenceInterval = SequenceInterval;
|
|
335
|
-
function createPositionReferenceFromSegoff(client, segoff, refType, op) {
|
|
336
|
-
if (segoff.segment) {
|
|
337
|
-
const ref = client.createLocalReferencePosition(segoff.segment, segoff.offset, refType, undefined);
|
|
338
|
-
return ref;
|
|
339
|
-
}
|
|
340
|
-
else {
|
|
341
|
-
if (!op && !(0, merge_tree_1.refTypeIncludesFlag)(refType, merge_tree_1.ReferenceType.Transient)) {
|
|
342
|
-
throw new container_utils_1.UsageError("Non-transient references need segment");
|
|
343
|
-
}
|
|
344
|
-
return new merge_tree_1.LocalReference(client, undefined, 0, refType);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
function createPositionReference(client, pos, refType, op) {
|
|
348
|
-
let segoff;
|
|
349
|
-
if (op) {
|
|
350
|
-
(0, common_utils_1.assert)((refType & merge_tree_1.ReferenceType.SlideOnRemove) !== 0, 0x2f5 /* op create references must be SlideOnRemove */);
|
|
351
|
-
segoff = client.getContainingSegment(pos, op);
|
|
352
|
-
segoff = client.getSlideToSegment(segoff);
|
|
353
|
-
}
|
|
354
|
-
else {
|
|
355
|
-
(0, common_utils_1.assert)((refType & merge_tree_1.ReferenceType.SlideOnRemove) === 0, 0x2f6 /* SlideOnRemove references must be op created */);
|
|
356
|
-
segoff = client.getContainingSegment(pos);
|
|
357
|
-
}
|
|
358
|
-
return createPositionReferenceFromSegoff(client, segoff, refType, op);
|
|
359
|
-
}
|
|
360
|
-
function createSequenceInterval(label, start, end, client, intervalType, op) {
|
|
361
|
-
let beginRefType = merge_tree_1.ReferenceType.RangeBegin;
|
|
362
|
-
let endRefType = merge_tree_1.ReferenceType.RangeEnd;
|
|
363
|
-
if (intervalType === IntervalType.Transient) {
|
|
364
|
-
beginRefType = merge_tree_1.ReferenceType.Transient;
|
|
365
|
-
endRefType = merge_tree_1.ReferenceType.Transient;
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
if (intervalType === IntervalType.Nest) {
|
|
369
|
-
beginRefType = merge_tree_1.ReferenceType.NestBegin;
|
|
370
|
-
endRefType = merge_tree_1.ReferenceType.NestEnd;
|
|
371
|
-
}
|
|
372
|
-
// All non-transient interval references must eventually be SlideOnRemove
|
|
373
|
-
// To ensure eventual consistency, they must start as StayOnRemove when
|
|
374
|
-
// pending (created locally and creation op is not acked)
|
|
375
|
-
if (op) {
|
|
376
|
-
beginRefType |= merge_tree_1.ReferenceType.SlideOnRemove;
|
|
377
|
-
endRefType |= merge_tree_1.ReferenceType.SlideOnRemove;
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
beginRefType |= merge_tree_1.ReferenceType.StayOnRemove;
|
|
381
|
-
endRefType |= merge_tree_1.ReferenceType.StayOnRemove;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
const startLref = createPositionReference(client, start, beginRefType, op);
|
|
385
|
-
const endLref = createPositionReference(client, end, endRefType, op);
|
|
386
|
-
startLref.pairedRef = endLref;
|
|
387
|
-
endLref.pairedRef = startLref;
|
|
388
|
-
const rangeProp = {
|
|
389
|
-
[merge_tree_1.reservedRangeLabelsKey]: [label],
|
|
390
|
-
};
|
|
391
|
-
startLref.addProperties(rangeProp);
|
|
392
|
-
endLref.addProperties(rangeProp);
|
|
393
|
-
const ival = new SequenceInterval(startLref, endLref, intervalType, rangeProp);
|
|
394
|
-
return ival;
|
|
395
|
-
}
|
|
396
|
-
function defaultIntervalConflictResolver(a, b) {
|
|
397
|
-
a.addPropertySet(b.properties);
|
|
398
|
-
return a;
|
|
399
|
-
}
|
|
400
|
-
exports.defaultIntervalConflictResolver = defaultIntervalConflictResolver;
|
|
401
|
-
function createIntervalIndex(conflict) {
|
|
402
|
-
const helpers = {
|
|
403
|
-
compareEnds: compareIntervalEnds,
|
|
404
|
-
create: createInterval,
|
|
405
|
-
};
|
|
406
|
-
const lc = new LocalIntervalCollection(undefined, "", helpers);
|
|
407
|
-
if (conflict) {
|
|
408
|
-
lc.addConflictResolver(conflict);
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
lc.addConflictResolver(defaultIntervalConflictResolver);
|
|
412
|
-
}
|
|
413
|
-
return lc;
|
|
414
|
-
}
|
|
415
|
-
exports.createIntervalIndex = createIntervalIndex;
|
|
416
|
-
class LocalIntervalCollection {
|
|
417
|
-
constructor(client, label, helpers,
|
|
418
|
-
/** Callback invoked each time one of the endpoints of an interval slides. */
|
|
419
|
-
onPositionChange) {
|
|
420
|
-
this.client = client;
|
|
421
|
-
this.label = label;
|
|
422
|
-
this.helpers = helpers;
|
|
423
|
-
this.onPositionChange = onPositionChange;
|
|
424
|
-
this.intervalTree = new merge_tree_1.IntervalTree();
|
|
425
|
-
this.intervalIdMap = new Map();
|
|
426
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
427
|
-
this.endIntervalTree = new merge_tree_1.RedBlackTree(helpers.compareEnds);
|
|
428
|
-
}
|
|
429
|
-
addConflictResolver(conflictResolver) {
|
|
430
|
-
this.conflictResolver = conflictResolver;
|
|
431
|
-
this.endConflictResolver =
|
|
432
|
-
(key, currentKey) => {
|
|
433
|
-
const ival = conflictResolver(key, currentKey);
|
|
434
|
-
return {
|
|
435
|
-
data: ival,
|
|
436
|
-
key: ival,
|
|
437
|
-
};
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
map(fn) {
|
|
441
|
-
this.intervalTree.map(fn);
|
|
442
|
-
}
|
|
443
|
-
createLegacyId(start, end) {
|
|
444
|
-
// Create a non-unique ID based on start and end to be used on intervals that come from legacy clients
|
|
445
|
-
// without ID's.
|
|
446
|
-
return `${LocalIntervalCollection.legacyIdPrefix}${start}-${end}`;
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Validates that a serialized interval has the ID property. Creates an ID
|
|
450
|
-
* if one does not already exist
|
|
451
|
-
*
|
|
452
|
-
* @param serializedInterval - The interval to be checked
|
|
453
|
-
* @returns The interval's existing or newly created id
|
|
454
|
-
*/
|
|
455
|
-
ensureSerializedId(serializedInterval) {
|
|
456
|
-
var _a;
|
|
457
|
-
let id = (_a = serializedInterval.properties) === null || _a === void 0 ? void 0 : _a[reservedIntervalIdKey];
|
|
458
|
-
if (id === undefined) {
|
|
459
|
-
// An interval came over the wire without an ID, so create a non-unique one based on start/end.
|
|
460
|
-
// This will allow all clients to refer to this interval consistently.
|
|
461
|
-
id = this.createLegacyId(serializedInterval.start, serializedInterval.end);
|
|
462
|
-
const newProps = {
|
|
463
|
-
[reservedIntervalIdKey]: id,
|
|
464
|
-
};
|
|
465
|
-
serializedInterval.properties = (0, merge_tree_1.addProperties)(serializedInterval.properties, newProps);
|
|
466
|
-
}
|
|
467
|
-
// Make the ID immutable for safety's sake.
|
|
468
|
-
Object.defineProperty(serializedInterval.properties, reservedIntervalIdKey, {
|
|
469
|
-
configurable: false,
|
|
470
|
-
enumerable: true,
|
|
471
|
-
writable: false,
|
|
472
|
-
});
|
|
473
|
-
return id;
|
|
474
|
-
}
|
|
475
|
-
mapUntil(fn) {
|
|
476
|
-
this.intervalTree.mapUntil(fn);
|
|
477
|
-
}
|
|
478
|
-
gatherIterationResults(results, iteratesForward, start, end) {
|
|
479
|
-
if (this.intervalTree.intervals.isEmpty()) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
if (start === undefined && end === undefined) {
|
|
483
|
-
// No start/end provided. Gather the whole tree in the specified order.
|
|
484
|
-
if (iteratesForward) {
|
|
485
|
-
this.intervalTree.map((interval) => {
|
|
486
|
-
results.push(interval);
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
else {
|
|
490
|
-
this.intervalTree.mapBackward((interval) => {
|
|
491
|
-
results.push(interval);
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
else {
|
|
496
|
-
const transientInterval = this.helpers.create("transient", start, end, this.client, IntervalType.Transient);
|
|
497
|
-
if (start === undefined) {
|
|
498
|
-
// Only end position provided. Since the tree is not sorted by end position,
|
|
499
|
-
// walk the whole tree in the specified order, gathering intervals that match the end.
|
|
500
|
-
if (iteratesForward) {
|
|
501
|
-
this.intervalTree.map((interval) => {
|
|
502
|
-
if (transientInterval.compareEnd(interval) === 0) {
|
|
503
|
-
results.push(interval);
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
else {
|
|
508
|
-
this.intervalTree.mapBackward((interval) => {
|
|
509
|
-
if (transientInterval.compareEnd(interval) === 0) {
|
|
510
|
-
results.push(interval);
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
// Start and (possibly) end provided. Walk the subtrees that may contain
|
|
517
|
-
// this start position.
|
|
518
|
-
const compareFn = end === undefined ?
|
|
519
|
-
(node) => {
|
|
520
|
-
return transientInterval.compareStart(node.key);
|
|
521
|
-
} :
|
|
522
|
-
(node) => {
|
|
523
|
-
return transientInterval.compare(node.key);
|
|
524
|
-
};
|
|
525
|
-
const continueLeftFn = (cmpResult) => cmpResult <= 0;
|
|
526
|
-
const continueRightFn = (cmpResult) => cmpResult >= 0;
|
|
527
|
-
const actionFn = (node) => {
|
|
528
|
-
results.push(node.key);
|
|
529
|
-
};
|
|
530
|
-
if (iteratesForward) {
|
|
531
|
-
this.intervalTree.intervals.walkExactMatchesForward(compareFn, actionFn, continueLeftFn, continueRightFn);
|
|
532
|
-
}
|
|
533
|
-
else {
|
|
534
|
-
this.intervalTree.intervals.walkExactMatchesBackward(compareFn, actionFn, continueLeftFn, continueRightFn);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
findOverlappingIntervals(startPosition, endPosition) {
|
|
540
|
-
if (endPosition < startPosition || this.intervalTree.intervals.isEmpty()) {
|
|
541
|
-
return [];
|
|
542
|
-
}
|
|
543
|
-
const transientInterval = this.helpers.create("transient", startPosition, endPosition, this.client, IntervalType.Transient);
|
|
544
|
-
const overlappingIntervalNodes = this.intervalTree.match(transientInterval);
|
|
545
|
-
return overlappingIntervalNodes.map((node) => node.key);
|
|
546
|
-
}
|
|
547
|
-
previousInterval(pos) {
|
|
548
|
-
const transientInterval = this.helpers.create("transient", pos, pos, this.client, IntervalType.Transient);
|
|
549
|
-
const rbNode = this.endIntervalTree.floor(transientInterval);
|
|
550
|
-
if (rbNode) {
|
|
551
|
-
return rbNode.data;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
nextInterval(pos) {
|
|
555
|
-
const transientInterval = this.helpers.create("transient", pos, pos, this.client, IntervalType.Transient);
|
|
556
|
-
const rbNode = this.endIntervalTree.ceil(transientInterval);
|
|
557
|
-
if (rbNode) {
|
|
558
|
-
return rbNode.data;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
removeInterval(startPosition, endPosition) {
|
|
562
|
-
const transientInterval = this.helpers.create("transient", startPosition, endPosition, this.client, IntervalType.Transient);
|
|
563
|
-
this.intervalTree.remove(transientInterval);
|
|
564
|
-
this.endIntervalTree.remove(transientInterval);
|
|
565
|
-
return transientInterval;
|
|
566
|
-
}
|
|
567
|
-
removeIntervalFromIndex(interval) {
|
|
568
|
-
this.intervalTree.removeExisting(interval);
|
|
569
|
-
this.endIntervalTree.remove(interval);
|
|
570
|
-
const id = interval.getIntervalId();
|
|
571
|
-
(0, common_utils_1.assert)(id !== undefined, 0x311 /* expected id to exist on interval */);
|
|
572
|
-
this.intervalIdMap.delete(id);
|
|
573
|
-
}
|
|
574
|
-
removeExistingInterval(interval) {
|
|
575
|
-
this.removeIntervalFromIndex(interval);
|
|
576
|
-
this.removeIntervalListeners(interval);
|
|
577
|
-
}
|
|
578
|
-
createInterval(start, end, intervalType, op) {
|
|
579
|
-
return this.helpers.create(this.label, start, end, this.client, intervalType, op);
|
|
580
|
-
}
|
|
581
|
-
addInterval(start, end, intervalType, props, op) {
|
|
582
|
-
const interval = this.createInterval(start, end, intervalType, op);
|
|
583
|
-
if (interval) {
|
|
584
|
-
if (!interval.properties) {
|
|
585
|
-
interval.properties = (0, merge_tree_1.createMap)();
|
|
586
|
-
}
|
|
587
|
-
if (props) {
|
|
588
|
-
interval.addProperties(props);
|
|
589
|
-
}
|
|
590
|
-
if (interval.properties[reservedIntervalIdKey] === undefined) {
|
|
591
|
-
// Create a new ID.
|
|
592
|
-
interval.properties[reservedIntervalIdKey] = (0, uuid_1.v4)();
|
|
593
|
-
}
|
|
594
|
-
this.add(interval);
|
|
595
|
-
}
|
|
596
|
-
return interval;
|
|
597
|
-
}
|
|
598
|
-
addIntervalToIndex(interval) {
|
|
599
|
-
const id = interval.getIntervalId();
|
|
600
|
-
(0, common_utils_1.assert)(id !== undefined, 0x2c0 /* "ID must be created before adding interval to collection" */);
|
|
601
|
-
// Make the ID immutable.
|
|
602
|
-
Object.defineProperty(interval.properties, reservedIntervalIdKey, {
|
|
603
|
-
configurable: false,
|
|
604
|
-
enumerable: true,
|
|
605
|
-
writable: false,
|
|
606
|
-
});
|
|
607
|
-
this.intervalTree.put(interval, this.conflictResolver);
|
|
608
|
-
this.endIntervalTree.put(interval, interval, this.endConflictResolver);
|
|
609
|
-
this.intervalIdMap.set(id, interval);
|
|
610
|
-
}
|
|
611
|
-
add(interval) {
|
|
612
|
-
this.addIntervalToIndex(interval);
|
|
613
|
-
this.addIntervalListeners(interval);
|
|
614
|
-
}
|
|
615
|
-
getIntervalById(id) {
|
|
616
|
-
return this.intervalIdMap.get(id);
|
|
617
|
-
}
|
|
618
|
-
changeInterval(interval, start, end, op) {
|
|
619
|
-
const newInterval = interval.modify(this.label, start, end, op);
|
|
620
|
-
if (newInterval) {
|
|
621
|
-
this.removeExistingInterval(interval);
|
|
622
|
-
this.add(newInterval);
|
|
623
|
-
}
|
|
624
|
-
return newInterval;
|
|
625
|
-
}
|
|
626
|
-
serialize() {
|
|
627
|
-
const client = this.client;
|
|
628
|
-
const intervals = this.intervalTree.intervals.keys();
|
|
629
|
-
return {
|
|
630
|
-
label: this.label,
|
|
631
|
-
intervals: intervals.map((interval) => compressInterval(interval.serialize(client))),
|
|
632
|
-
version: 2,
|
|
633
|
-
};
|
|
634
|
-
}
|
|
635
|
-
addIntervalListeners(interval) {
|
|
636
|
-
if (interval instanceof SequenceInterval) {
|
|
637
|
-
interval.addPositionChangeListeners(() => this.removeIntervalFromIndex(interval), () => {
|
|
638
|
-
var _a;
|
|
639
|
-
this.addIntervalToIndex(interval);
|
|
640
|
-
(_a = this.onPositionChange) === null || _a === void 0 ? void 0 : _a.call(this, interval);
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
removeIntervalListeners(interval) {
|
|
645
|
-
if (interval instanceof SequenceInterval) {
|
|
646
|
-
interval.removePositionChangeListeners();
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
exports.LocalIntervalCollection = LocalIntervalCollection;
|
|
651
|
-
LocalIntervalCollection.legacyIdPrefix = "legacy";
|
|
652
|
-
const compareSequenceIntervalEnds = (a, b) => a.end.compare(b.end);
|
|
653
|
-
class SequenceIntervalCollectionFactory {
|
|
654
|
-
load(emitter, raw = []) {
|
|
655
|
-
const helpers = {
|
|
656
|
-
compareEnds: compareSequenceIntervalEnds,
|
|
657
|
-
create: createSequenceInterval,
|
|
658
|
-
};
|
|
659
|
-
return new IntervalCollection(helpers, true, emitter, raw);
|
|
660
|
-
}
|
|
661
|
-
store(value) {
|
|
662
|
-
return value.serializeInternal();
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
class SequenceIntervalCollectionValueType {
|
|
666
|
-
get name() {
|
|
667
|
-
return SequenceIntervalCollectionValueType.Name;
|
|
668
|
-
}
|
|
669
|
-
get factory() {
|
|
670
|
-
return SequenceIntervalCollectionValueType._factory;
|
|
671
|
-
}
|
|
672
|
-
get ops() {
|
|
673
|
-
return SequenceIntervalCollectionValueType._ops;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
exports.SequenceIntervalCollectionValueType = SequenceIntervalCollectionValueType;
|
|
677
|
-
SequenceIntervalCollectionValueType.Name = "sharedStringIntervalCollection";
|
|
678
|
-
SequenceIntervalCollectionValueType._factory = new SequenceIntervalCollectionFactory();
|
|
679
|
-
SequenceIntervalCollectionValueType._ops = makeOpsMap();
|
|
680
|
-
const compareIntervalEnds = (a, b) => a.end - b.end;
|
|
681
|
-
function createInterval(label, start, end, client) {
|
|
682
|
-
const rangeProp = {};
|
|
683
|
-
if (label && label.length > 0) {
|
|
684
|
-
rangeProp[merge_tree_1.reservedRangeLabelsKey] = [label];
|
|
685
|
-
}
|
|
686
|
-
return new Interval(start, end, rangeProp);
|
|
687
|
-
}
|
|
688
|
-
class IntervalCollectionFactory {
|
|
689
|
-
load(emitter, raw = []) {
|
|
690
|
-
const helpers = {
|
|
691
|
-
compareEnds: compareIntervalEnds,
|
|
692
|
-
create: createInterval,
|
|
693
|
-
};
|
|
694
|
-
const collection = new IntervalCollection(helpers, false, emitter, raw);
|
|
695
|
-
collection.attachGraph(undefined, "");
|
|
696
|
-
return collection;
|
|
697
|
-
}
|
|
698
|
-
store(value) {
|
|
699
|
-
return value.serializeInternal();
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
class IntervalCollectionValueType {
|
|
703
|
-
get name() {
|
|
704
|
-
return IntervalCollectionValueType.Name;
|
|
705
|
-
}
|
|
706
|
-
get factory() {
|
|
707
|
-
return IntervalCollectionValueType._factory;
|
|
708
|
-
}
|
|
709
|
-
get ops() {
|
|
710
|
-
return IntervalCollectionValueType._ops;
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
exports.IntervalCollectionValueType = IntervalCollectionValueType;
|
|
714
|
-
IntervalCollectionValueType.Name = "sharedIntervalCollection";
|
|
715
|
-
IntervalCollectionValueType._factory = new IntervalCollectionFactory();
|
|
716
|
-
IntervalCollectionValueType._ops = makeOpsMap();
|
|
717
|
-
function makeOpsMap() {
|
|
718
|
-
const rebase = (collection, op, localOpMetadata) => {
|
|
719
|
-
const { localSeq } = localOpMetadata;
|
|
720
|
-
const rebasedValue = collection.rebaseLocalInterval(op.opName, op.value, localSeq);
|
|
721
|
-
const rebasedOp = Object.assign(Object.assign({}, op), { value: rebasedValue });
|
|
722
|
-
return { rebasedOp, rebasedLocalOpMetadata: localOpMetadata };
|
|
723
|
-
};
|
|
724
|
-
return new Map([[
|
|
725
|
-
"add",
|
|
726
|
-
{
|
|
727
|
-
process: (collection, params, local, op) => {
|
|
728
|
-
collection.ackAdd(params, local, op);
|
|
729
|
-
},
|
|
730
|
-
rebase,
|
|
731
|
-
},
|
|
732
|
-
],
|
|
733
|
-
[
|
|
734
|
-
"delete",
|
|
735
|
-
{
|
|
736
|
-
process: (collection, params, local, op) => {
|
|
737
|
-
collection.ackDelete(params, local, op);
|
|
738
|
-
},
|
|
739
|
-
rebase: (collection, op, localOpMetadata) => {
|
|
740
|
-
// Deletion of intervals is based on id, so requires no rebasing.
|
|
741
|
-
return { rebasedOp: op, rebasedLocalOpMetadata: localOpMetadata };
|
|
742
|
-
},
|
|
743
|
-
},
|
|
744
|
-
],
|
|
745
|
-
[
|
|
746
|
-
"change",
|
|
747
|
-
{
|
|
748
|
-
process: (collection, params, local, op) => {
|
|
749
|
-
collection.ackChange(params, local, op);
|
|
750
|
-
},
|
|
751
|
-
rebase,
|
|
752
|
-
},
|
|
753
|
-
]]);
|
|
754
|
-
}
|
|
755
|
-
class IntervalCollectionIterator {
|
|
756
|
-
constructor(collection, iteratesForward = true, start, end) {
|
|
757
|
-
this.results = [];
|
|
758
|
-
this.index = 0;
|
|
759
|
-
collection.gatherIterationResults(this.results, iteratesForward, start, end);
|
|
760
|
-
}
|
|
761
|
-
next() {
|
|
762
|
-
let _value;
|
|
763
|
-
let _done = true;
|
|
764
|
-
if (this.index < this.results.length) {
|
|
765
|
-
_value = this.results[this.index++];
|
|
766
|
-
_done = false;
|
|
767
|
-
}
|
|
768
|
-
return {
|
|
769
|
-
value: _value,
|
|
770
|
-
done: _done,
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
exports.IntervalCollectionIterator = IntervalCollectionIterator;
|
|
775
|
-
class IntervalCollection extends common_utils_1.TypedEventEmitter {
|
|
776
|
-
/** @internal */
|
|
777
|
-
constructor(helpers, requiresClient, emitter, serializedIntervals) {
|
|
778
|
-
super();
|
|
779
|
-
this.helpers = helpers;
|
|
780
|
-
this.requiresClient = requiresClient;
|
|
781
|
-
this.emitter = emitter;
|
|
782
|
-
this.pendingChangesStart = new Map();
|
|
783
|
-
this.pendingChangesEnd = new Map();
|
|
784
|
-
if (Array.isArray(serializedIntervals)) {
|
|
785
|
-
this.savedSerializedIntervals = serializedIntervals;
|
|
786
|
-
}
|
|
787
|
-
else {
|
|
788
|
-
this.savedSerializedIntervals =
|
|
789
|
-
serializedIntervals.intervals.map((i) => decompressInterval(i, serializedIntervals.label));
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
get attached() {
|
|
793
|
-
return !!this.localCollection;
|
|
794
|
-
}
|
|
795
|
-
attachGraph(client, label) {
|
|
796
|
-
if (this.attached) {
|
|
797
|
-
throw new telemetry_utils_1.LoggingError("Only supports one Sequence attach");
|
|
798
|
-
}
|
|
799
|
-
if ((client === undefined) && (this.requiresClient)) {
|
|
800
|
-
throw new telemetry_utils_1.LoggingError("Client required for this collection");
|
|
801
|
-
}
|
|
802
|
-
// Instantiate the local interval collection based on the saved intervals
|
|
803
|
-
this.client = client;
|
|
804
|
-
this.localCollection = new LocalIntervalCollection(client, label, this.helpers, (interval) => this.emit("changeInterval", interval, true, undefined));
|
|
805
|
-
if (this.savedSerializedIntervals) {
|
|
806
|
-
for (const serializedInterval of this.savedSerializedIntervals) {
|
|
807
|
-
this.localCollection.ensureSerializedId(serializedInterval);
|
|
808
|
-
this.localCollection.addInterval(serializedInterval.start, serializedInterval.end, serializedInterval.intervalType, serializedInterval.properties);
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
this.savedSerializedIntervals = undefined;
|
|
812
|
-
}
|
|
813
|
-
/**
|
|
814
|
-
* Gets the next local sequence number, modifying this client's collab window in doing so.
|
|
815
|
-
*/
|
|
816
|
-
getNextLocalSeq() {
|
|
817
|
-
return ++this.client.getCollabWindow().localSeq;
|
|
818
|
-
}
|
|
819
|
-
getIntervalById(id) {
|
|
820
|
-
if (!this.attached) {
|
|
821
|
-
throw new telemetry_utils_1.LoggingError("attach must be called before accessing intervals");
|
|
822
|
-
}
|
|
823
|
-
return this.localCollection.getIntervalById(id);
|
|
824
|
-
}
|
|
825
|
-
/**
|
|
826
|
-
* Create a new interval and add it to the collection
|
|
827
|
-
* @param start - interval start position
|
|
828
|
-
* @param end - interval end position
|
|
829
|
-
* @param intervalType - type of the interval. All intervals are SlideOnRemove. Intervals may not be Transient.
|
|
830
|
-
* @param props - properties of the interval
|
|
831
|
-
* @returns - the created interval
|
|
832
|
-
*/
|
|
833
|
-
add(start, end, intervalType, props) {
|
|
834
|
-
var _a, _b;
|
|
835
|
-
if (!this.attached) {
|
|
836
|
-
throw new telemetry_utils_1.LoggingError("attach must be called prior to adding intervals");
|
|
837
|
-
}
|
|
838
|
-
if (intervalType & IntervalType.Transient) {
|
|
839
|
-
throw new telemetry_utils_1.LoggingError("Can not add transient intervals");
|
|
840
|
-
}
|
|
841
|
-
const interval = this.localCollection.addInterval(start, end, intervalType, props);
|
|
842
|
-
if (interval) {
|
|
843
|
-
const serializedInterval = {
|
|
844
|
-
end,
|
|
845
|
-
intervalType,
|
|
846
|
-
properties: interval.properties,
|
|
847
|
-
sequenceNumber: (_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.getCurrentSeq()) !== null && _b !== void 0 ? _b : 0,
|
|
848
|
-
start,
|
|
849
|
-
};
|
|
850
|
-
// Local ops get submitted to the server. Remote ops have the deserializer run.
|
|
851
|
-
this.emitter.emit("add", undefined, serializedInterval, { localSeq: this.getNextLocalSeq() });
|
|
852
|
-
}
|
|
853
|
-
this.emit("addInterval", interval, true, undefined);
|
|
854
|
-
return interval;
|
|
855
|
-
}
|
|
856
|
-
deleteExistingInterval(interval, local, op) {
|
|
857
|
-
// The given interval is known to exist in the collection.
|
|
858
|
-
this.localCollection.removeExistingInterval(interval);
|
|
859
|
-
if (interval) {
|
|
860
|
-
// Local ops get submitted to the server. Remote ops have the deserializer run.
|
|
861
|
-
if (local) {
|
|
862
|
-
this.emitter.emit("delete", undefined, interval.serialize(this.client), { localSeq: this.getNextLocalSeq() });
|
|
863
|
-
}
|
|
864
|
-
else {
|
|
865
|
-
if (this.onDeserialize) {
|
|
866
|
-
this.onDeserialize(interval);
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
this.emit("deleteInterval", interval, local, op);
|
|
871
|
-
}
|
|
872
|
-
removeIntervalById(id) {
|
|
873
|
-
const interval = this.localCollection.getIntervalById(id);
|
|
874
|
-
if (interval) {
|
|
875
|
-
this.deleteExistingInterval(interval, true, undefined);
|
|
876
|
-
}
|
|
877
|
-
return interval;
|
|
878
|
-
}
|
|
879
|
-
changeProperties(id, props) {
|
|
880
|
-
if (!this.attached) {
|
|
881
|
-
throw new telemetry_utils_1.LoggingError("Attach must be called before accessing intervals");
|
|
882
|
-
}
|
|
883
|
-
if (typeof (id) !== "string") {
|
|
884
|
-
throw new telemetry_utils_1.LoggingError("Change API requires an ID that is a string");
|
|
885
|
-
}
|
|
886
|
-
if (!props) {
|
|
887
|
-
throw new telemetry_utils_1.LoggingError("changeProperties should be called with a property set");
|
|
888
|
-
}
|
|
889
|
-
const interval = this.getIntervalById(id);
|
|
890
|
-
if (interval) {
|
|
891
|
-
// Pass Unassigned as the sequence number to indicate that this is a local op that is waiting for an ack.
|
|
892
|
-
const deltaProps = interval.addProperties(props, true, merge_tree_1.UnassignedSequenceNumber);
|
|
893
|
-
const serializedInterval = interval.serialize(this.client);
|
|
894
|
-
// Emit a change op that will only change properties. Add the ID to
|
|
895
|
-
// the property bag provided by the caller.
|
|
896
|
-
serializedInterval.start = undefined;
|
|
897
|
-
serializedInterval.end = undefined;
|
|
898
|
-
serializedInterval.properties = props;
|
|
899
|
-
serializedInterval.properties[reservedIntervalIdKey] = interval.getIntervalId();
|
|
900
|
-
this.emitter.emit("change", undefined, serializedInterval, { localSeq: this.getNextLocalSeq() });
|
|
901
|
-
this.emit("propertyChanged", interval, deltaProps);
|
|
902
|
-
}
|
|
903
|
-
this.emit("changeInterval", interval, true, undefined);
|
|
904
|
-
}
|
|
905
|
-
change(id, start, end) {
|
|
906
|
-
if (!this.attached) {
|
|
907
|
-
throw new telemetry_utils_1.LoggingError("Attach must be called before accessing intervals");
|
|
908
|
-
}
|
|
909
|
-
// Force id to be a string.
|
|
910
|
-
if (typeof (id) !== "string") {
|
|
911
|
-
throw new telemetry_utils_1.LoggingError("Change API requires an ID that is a string");
|
|
912
|
-
}
|
|
913
|
-
const interval = this.getIntervalById(id);
|
|
914
|
-
if (interval) {
|
|
915
|
-
const newInterval = this.localCollection.changeInterval(interval, start, end);
|
|
916
|
-
const serializedInterval = interval.serialize(this.client);
|
|
917
|
-
serializedInterval.start = start;
|
|
918
|
-
serializedInterval.end = end;
|
|
919
|
-
// Emit a property bag containing only the ID, as we don't intend for this op to change any properties.
|
|
920
|
-
serializedInterval.properties =
|
|
921
|
-
{
|
|
922
|
-
[reservedIntervalIdKey]: interval.getIntervalId(),
|
|
923
|
-
};
|
|
924
|
-
this.emitter.emit("change", undefined, serializedInterval, { localSeq: this.getNextLocalSeq() });
|
|
925
|
-
this.addPendingChange(id, serializedInterval);
|
|
926
|
-
this.emit("changeInterval", newInterval, true, undefined);
|
|
927
|
-
return newInterval;
|
|
928
|
-
}
|
|
929
|
-
// No interval to change
|
|
930
|
-
return undefined;
|
|
931
|
-
}
|
|
932
|
-
addPendingChange(id, serializedInterval) {
|
|
933
|
-
if (serializedInterval.start !== undefined) {
|
|
934
|
-
this.addPendingChangeHelper(id, this.pendingChangesStart, serializedInterval);
|
|
935
|
-
}
|
|
936
|
-
if (serializedInterval.end !== undefined) {
|
|
937
|
-
this.addPendingChangeHelper(id, this.pendingChangesEnd, serializedInterval);
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
addPendingChangeHelper(id, pendingChanges, serializedInterval) {
|
|
941
|
-
let entries = pendingChanges.get(id);
|
|
942
|
-
if (!entries) {
|
|
943
|
-
entries = [];
|
|
944
|
-
pendingChanges.set(id, entries);
|
|
945
|
-
}
|
|
946
|
-
entries.push(serializedInterval);
|
|
947
|
-
}
|
|
948
|
-
removePendingChange(serializedInterval) {
|
|
949
|
-
var _a;
|
|
950
|
-
// Change ops always have an ID.
|
|
951
|
-
const id = (_a = serializedInterval.properties) === null || _a === void 0 ? void 0 : _a[reservedIntervalIdKey];
|
|
952
|
-
if (serializedInterval.start !== undefined) {
|
|
953
|
-
this.removePendingChangeHelper(id, this.pendingChangesStart, serializedInterval);
|
|
954
|
-
}
|
|
955
|
-
if (serializedInterval.end !== undefined) {
|
|
956
|
-
this.removePendingChangeHelper(id, this.pendingChangesEnd, serializedInterval);
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
removePendingChangeHelper(id, pendingChanges, serializedInterval) {
|
|
960
|
-
const entries = pendingChanges.get(id);
|
|
961
|
-
if (entries) {
|
|
962
|
-
const pendingChange = entries.shift();
|
|
963
|
-
if (entries.length === 0) {
|
|
964
|
-
pendingChanges.delete(id);
|
|
965
|
-
}
|
|
966
|
-
if ((pendingChange === null || pendingChange === void 0 ? void 0 : pendingChange.start) !== serializedInterval.start ||
|
|
967
|
-
(pendingChange === null || pendingChange === void 0 ? void 0 : pendingChange.end) !== serializedInterval.end) {
|
|
968
|
-
throw new telemetry_utils_1.LoggingError("Mismatch in pending changes");
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
hasPendingChangeStart(id) {
|
|
973
|
-
const entries = this.pendingChangesStart.get(id);
|
|
974
|
-
return entries && entries.length !== 0;
|
|
975
|
-
}
|
|
976
|
-
hasPendingChangeEnd(id) {
|
|
977
|
-
const entries = this.pendingChangesEnd.get(id);
|
|
978
|
-
return entries && entries.length !== 0;
|
|
979
|
-
}
|
|
980
|
-
/** @deprecated - use ackChange */
|
|
981
|
-
changeInterval(serializedInterval, local, op) {
|
|
982
|
-
return this.ackChange(serializedInterval, local, op);
|
|
983
|
-
}
|
|
984
|
-
/** @internal */
|
|
985
|
-
ackChange(serializedInterval, local, op) {
|
|
986
|
-
var _a, _b, _c, _d;
|
|
987
|
-
if (!this.attached) {
|
|
988
|
-
throw new telemetry_utils_1.LoggingError("Attach must be called before accessing intervals");
|
|
989
|
-
}
|
|
990
|
-
let interval;
|
|
991
|
-
if (local) {
|
|
992
|
-
// This is an ack from the server. Remove the pending change.
|
|
993
|
-
this.removePendingChange(serializedInterval);
|
|
994
|
-
const id = (_a = serializedInterval.properties) === null || _a === void 0 ? void 0 : _a[reservedIntervalIdKey];
|
|
995
|
-
interval = this.getIntervalById(id);
|
|
996
|
-
if (interval) {
|
|
997
|
-
// Let the propertyManager prune its pending change-properties set.
|
|
998
|
-
(_b = interval.propertyManager) === null || _b === void 0 ? void 0 : _b.ackPendingProperties({
|
|
999
|
-
type: merge_tree_1.MergeTreeDeltaType.ANNOTATE,
|
|
1000
|
-
props: (_c = serializedInterval.properties) !== null && _c !== void 0 ? _c : {},
|
|
1001
|
-
});
|
|
1002
|
-
this.ackInterval(interval, op);
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
else {
|
|
1006
|
-
// If there are pending changes with this ID, don't apply the remote start/end change, as the local ack
|
|
1007
|
-
// should be the winning change.
|
|
1008
|
-
// Note that the ID is in the property bag only to allow us to find the interval.
|
|
1009
|
-
// This API cannot change the ID, and writing to the ID property will result in an exception. So we
|
|
1010
|
-
// strip it out of the properties here.
|
|
1011
|
-
const _e = serializedInterval.properties, _f = reservedIntervalIdKey, id = _e[_f], newProps = __rest(_e, [typeof _f === "symbol" ? _f : _f + ""]);
|
|
1012
|
-
interval = this.getIntervalById(id);
|
|
1013
|
-
if (interval) {
|
|
1014
|
-
let start;
|
|
1015
|
-
let end;
|
|
1016
|
-
// Track pending start/end independently of one another.
|
|
1017
|
-
if (!this.hasPendingChangeStart(id)) {
|
|
1018
|
-
start = serializedInterval.start;
|
|
1019
|
-
}
|
|
1020
|
-
if (!this.hasPendingChangeEnd(id)) {
|
|
1021
|
-
end = serializedInterval.end;
|
|
1022
|
-
}
|
|
1023
|
-
if (start !== undefined || end !== undefined) {
|
|
1024
|
-
// If changeInterval gives us a new interval, work with that one. Otherwise keep working with
|
|
1025
|
-
// the one we originally found in the tree.
|
|
1026
|
-
interval = (_d = this.localCollection.changeInterval(interval, start, end, op)) !== null && _d !== void 0 ? _d : interval;
|
|
1027
|
-
}
|
|
1028
|
-
const deltaProps = interval.addProperties(newProps, true, op.sequenceNumber);
|
|
1029
|
-
if (this.onDeserialize) {
|
|
1030
|
-
this.onDeserialize(interval);
|
|
1031
|
-
}
|
|
1032
|
-
this.emit("propertyChanged", interval, deltaProps);
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
if (interval) {
|
|
1036
|
-
this.emit("changeInterval", interval, local, op);
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
addConflictResolver(conflictResolver) {
|
|
1040
|
-
if (!this.attached) {
|
|
1041
|
-
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1042
|
-
}
|
|
1043
|
-
this.localCollection.addConflictResolver(conflictResolver);
|
|
1044
|
-
}
|
|
1045
|
-
attachDeserializer(onDeserialize) {
|
|
1046
|
-
// If no deserializer is specified can skip all processing work
|
|
1047
|
-
if (!onDeserialize) {
|
|
1048
|
-
return;
|
|
1049
|
-
}
|
|
1050
|
-
// Start by storing the callbacks so that any subsequent modifications make use of them
|
|
1051
|
-
this.onDeserialize = onDeserialize;
|
|
1052
|
-
// Trigger the async prepare work across all values in the collection
|
|
1053
|
-
this.localCollection.map((interval) => {
|
|
1054
|
-
onDeserialize(interval);
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
/** @internal */
|
|
1058
|
-
rebaseLocalInterval(opName, serializedInterval, localSeq) {
|
|
1059
|
-
var _a, _b;
|
|
1060
|
-
if (!this.attached) {
|
|
1061
|
-
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1062
|
-
}
|
|
1063
|
-
const { start, end, intervalType, properties, sequenceNumber } = serializedInterval;
|
|
1064
|
-
const startRebased = start === undefined ? undefined :
|
|
1065
|
-
this.client.rebasePosition(start, sequenceNumber, localSeq);
|
|
1066
|
-
const endRebased = end === undefined ? undefined :
|
|
1067
|
-
this.client.rebasePosition(end, sequenceNumber, localSeq);
|
|
1068
|
-
const intervalId = properties === null || properties === void 0 ? void 0 : properties[reservedIntervalIdKey];
|
|
1069
|
-
const rebased = {
|
|
1070
|
-
start: startRebased,
|
|
1071
|
-
end: endRebased,
|
|
1072
|
-
intervalType,
|
|
1073
|
-
sequenceNumber: (_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.getCurrentSeq()) !== null && _b !== void 0 ? _b : 0,
|
|
1074
|
-
properties,
|
|
1075
|
-
};
|
|
1076
|
-
if (opName === "change" && (this.hasPendingChangeStart(intervalId) || this.hasPendingChangeEnd(intervalId))) {
|
|
1077
|
-
this.removePendingChange(serializedInterval);
|
|
1078
|
-
this.addPendingChange(intervalId, rebased);
|
|
1079
|
-
}
|
|
1080
|
-
return rebased;
|
|
1081
|
-
}
|
|
1082
|
-
getSlideToSegment(lref) {
|
|
1083
|
-
const segoff = { segment: lref.segment, offset: lref.offset };
|
|
1084
|
-
const newSegoff = this.client.getSlideToSegment(segoff);
|
|
1085
|
-
const value = (segoff.segment === newSegoff.segment && segoff.offset === newSegoff.offset) ? undefined : newSegoff;
|
|
1086
|
-
return value;
|
|
1087
|
-
}
|
|
1088
|
-
setSlideOnRemove(lref) {
|
|
1089
|
-
let refType = lref.refType;
|
|
1090
|
-
refType = refType & ~merge_tree_1.ReferenceType.StayOnRemove;
|
|
1091
|
-
refType = refType | merge_tree_1.ReferenceType.SlideOnRemove;
|
|
1092
|
-
lref.refType = refType;
|
|
1093
|
-
}
|
|
1094
|
-
ackInterval(interval, op) {
|
|
1095
|
-
// in current usage, interval is always a SequenceInterval
|
|
1096
|
-
if (!(interval instanceof SequenceInterval)) {
|
|
1097
|
-
return;
|
|
1098
|
-
}
|
|
1099
|
-
if (!(0, merge_tree_1.refTypeIncludesFlag)(interval.start, merge_tree_1.ReferenceType.StayOnRemove) &&
|
|
1100
|
-
!(0, merge_tree_1.refTypeIncludesFlag)(interval.end, merge_tree_1.ReferenceType.StayOnRemove)) {
|
|
1101
|
-
return;
|
|
1102
|
-
}
|
|
1103
|
-
const newStart = this.getSlideToSegment(interval.start);
|
|
1104
|
-
const newEnd = this.getSlideToSegment(interval.end);
|
|
1105
|
-
const id = interval.properties[reservedIntervalIdKey];
|
|
1106
|
-
const hasPendingStartChange = this.hasPendingChangeStart(id);
|
|
1107
|
-
const hasPendingEndChange = this.hasPendingChangeEnd(id);
|
|
1108
|
-
if (!hasPendingStartChange) {
|
|
1109
|
-
this.setSlideOnRemove(interval.start);
|
|
1110
|
-
}
|
|
1111
|
-
if (!hasPendingEndChange) {
|
|
1112
|
-
this.setSlideOnRemove(interval.end);
|
|
1113
|
-
}
|
|
1114
|
-
const needsStartUpdate = newStart !== undefined && !hasPendingStartChange;
|
|
1115
|
-
const needsEndUpdate = newEnd !== undefined && !hasPendingEndChange;
|
|
1116
|
-
if (needsStartUpdate || needsEndUpdate) {
|
|
1117
|
-
// In this case, where we change the start or end of an interval,
|
|
1118
|
-
// it is necessary to remove and re-add the interval listeners.
|
|
1119
|
-
// This ensures that the correct listeners are added to the ReferencePosition.
|
|
1120
|
-
this.localCollection.removeExistingInterval(interval);
|
|
1121
|
-
if (needsStartUpdate) {
|
|
1122
|
-
const props = interval.start.properties;
|
|
1123
|
-
this.client.removeLocalReferencePosition(interval.start);
|
|
1124
|
-
interval.start = createPositionReferenceFromSegoff(this.client, newStart, interval.start.refType, op);
|
|
1125
|
-
if (props) {
|
|
1126
|
-
interval.start.addProperties(props);
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
if (needsEndUpdate) {
|
|
1130
|
-
const props = interval.end.properties;
|
|
1131
|
-
this.client.removeLocalReferencePosition(interval.end);
|
|
1132
|
-
interval.end = createPositionReferenceFromSegoff(this.client, newEnd, interval.end.refType, op);
|
|
1133
|
-
if (props) {
|
|
1134
|
-
interval.end.addProperties(props);
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
this.localCollection.add(interval);
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
/** @deprecated - use ackAdd */
|
|
1141
|
-
addInternal(serializedInterval, local, op) {
|
|
1142
|
-
return this.ackAdd(serializedInterval, local, op);
|
|
1143
|
-
}
|
|
1144
|
-
/** @internal */
|
|
1145
|
-
ackAdd(serializedInterval, local, op) {
|
|
1146
|
-
var _a;
|
|
1147
|
-
if (local) {
|
|
1148
|
-
const id = (_a = serializedInterval.properties) === null || _a === void 0 ? void 0 : _a[reservedIntervalIdKey];
|
|
1149
|
-
const localInterval = this.getIntervalById(id);
|
|
1150
|
-
if (localInterval) {
|
|
1151
|
-
this.ackInterval(localInterval, op);
|
|
1152
|
-
}
|
|
1153
|
-
return;
|
|
1154
|
-
}
|
|
1155
|
-
if (!this.attached) {
|
|
1156
|
-
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1157
|
-
}
|
|
1158
|
-
this.localCollection.ensureSerializedId(serializedInterval);
|
|
1159
|
-
const interval = this.localCollection.addInterval(serializedInterval.start, serializedInterval.end, serializedInterval.intervalType, serializedInterval.properties, op);
|
|
1160
|
-
if (interval) {
|
|
1161
|
-
if (this.onDeserialize) {
|
|
1162
|
-
this.onDeserialize(interval);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
this.emit("addInterval", interval, local, op);
|
|
1166
|
-
return interval;
|
|
1167
|
-
}
|
|
1168
|
-
/** @deprecated - use ackDelete */
|
|
1169
|
-
deleteInterval(serializedInterval, local, op) {
|
|
1170
|
-
return this.ackDelete(serializedInterval, local, op);
|
|
1171
|
-
}
|
|
1172
|
-
/** @internal */
|
|
1173
|
-
ackDelete(serializedInterval, local, op) {
|
|
1174
|
-
if (local) {
|
|
1175
|
-
// Local ops were applied when the message was created and there's no "pending delete"
|
|
1176
|
-
// state to bookkeep: remote operation application takes into account possibility of
|
|
1177
|
-
// locally deleted interval whenever a lookup happens.
|
|
1178
|
-
return;
|
|
1179
|
-
}
|
|
1180
|
-
if (!this.attached) {
|
|
1181
|
-
throw new telemetry_utils_1.LoggingError("attach must be called prior to deleting intervals");
|
|
1182
|
-
}
|
|
1183
|
-
const id = this.localCollection.ensureSerializedId(serializedInterval);
|
|
1184
|
-
const interval = this.localCollection.getIntervalById(id);
|
|
1185
|
-
if (interval) {
|
|
1186
|
-
this.deleteExistingInterval(interval, local, op);
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
/**
|
|
1190
|
-
* @internal
|
|
1191
|
-
*/
|
|
1192
|
-
serializeInternal() {
|
|
1193
|
-
if (!this.attached) {
|
|
1194
|
-
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1195
|
-
}
|
|
1196
|
-
return this.localCollection.serialize();
|
|
1197
|
-
}
|
|
1198
|
-
[Symbol.iterator]() {
|
|
1199
|
-
const iterator = new IntervalCollectionIterator(this);
|
|
1200
|
-
return iterator;
|
|
1201
|
-
}
|
|
1202
|
-
CreateForwardIteratorWithStartPosition(startPosition) {
|
|
1203
|
-
const iterator = new IntervalCollectionIterator(this, true, startPosition);
|
|
1204
|
-
return iterator;
|
|
1205
|
-
}
|
|
1206
|
-
CreateBackwardIteratorWithStartPosition(startPosition) {
|
|
1207
|
-
const iterator = new IntervalCollectionIterator(this, false, startPosition);
|
|
1208
|
-
return iterator;
|
|
1209
|
-
}
|
|
1210
|
-
CreateForwardIteratorWithEndPosition(endPosition) {
|
|
1211
|
-
const iterator = new IntervalCollectionIterator(this, true, undefined, endPosition);
|
|
1212
|
-
return iterator;
|
|
1213
|
-
}
|
|
1214
|
-
CreateBackwardIteratorWithEndPosition(endPosition) {
|
|
1215
|
-
const iterator = new IntervalCollectionIterator(this, false, undefined, endPosition);
|
|
1216
|
-
return iterator;
|
|
1217
|
-
}
|
|
1218
|
-
gatherIterationResults(results, iteratesForward, start, end) {
|
|
1219
|
-
if (!this.attached) {
|
|
1220
|
-
return;
|
|
1221
|
-
}
|
|
1222
|
-
this.localCollection.gatherIterationResults(results, iteratesForward, start, end);
|
|
1223
|
-
}
|
|
1224
|
-
findOverlappingIntervals(startPosition, endPosition) {
|
|
1225
|
-
if (!this.attached) {
|
|
1226
|
-
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1227
|
-
}
|
|
1228
|
-
return this.localCollection.findOverlappingIntervals(startPosition, endPosition);
|
|
1229
|
-
}
|
|
1230
|
-
map(fn) {
|
|
1231
|
-
if (!this.attached) {
|
|
1232
|
-
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1233
|
-
}
|
|
1234
|
-
this.localCollection.map(fn);
|
|
1235
|
-
}
|
|
1236
|
-
previousInterval(pos) {
|
|
1237
|
-
if (!this.attached) {
|
|
1238
|
-
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1239
|
-
}
|
|
1240
|
-
return this.localCollection.previousInterval(pos);
|
|
1241
|
-
}
|
|
1242
|
-
nextInterval(pos) {
|
|
1243
|
-
if (!this.attached) {
|
|
1244
|
-
throw new telemetry_utils_1.LoggingError("attachSequence must be called");
|
|
1245
|
-
}
|
|
1246
|
-
return this.localCollection.nextInterval(pos);
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
exports.IntervalCollection = IntervalCollection;
|
|
1250
|
-
//# sourceMappingURL=intervalCollection.js.map
|