@fluidframework/sequence 2.0.0-internal.8.0.1 → 2.0.0-rc.1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/README.md +0 -6
- package/api-extractor-esm.json +4 -0
- package/api-extractor-lint.json +1 -10
- package/api-extractor.json +1 -9
- package/api-report/sequence.api.md +3 -15
- package/dist/defaultMap.d.ts +2 -2
- package/dist/defaultMap.d.ts.map +1 -1
- package/dist/defaultMap.js +10 -5
- package/dist/defaultMap.js.map +1 -1
- package/dist/defaultMapInterfaces.d.ts +3 -2
- package/dist/defaultMapInterfaces.d.ts.map +1 -1
- package/dist/defaultMapInterfaces.js.map +1 -1
- package/dist/intervalCollection.d.ts +3 -43
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +62 -50
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervals/index.d.ts +1 -1
- package/dist/intervals/index.d.ts.map +1 -1
- package/dist/intervals/index.js +2 -1
- package/dist/intervals/index.js.map +1 -1
- package/dist/intervals/intervalUtils.d.ts +12 -2
- package/dist/intervals/intervalUtils.d.ts.map +1 -1
- package/dist/intervals/intervalUtils.js +10 -3
- package/dist/intervals/intervalUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +9 -3
- package/dist/revertibles.js.map +1 -1
- package/dist/sequence-alpha.d.ts +2 -47
- package/dist/sequence-beta.d.ts +0 -29
- package/dist/sequence-public.d.ts +0 -29
- package/dist/sequence-untrimmed.d.ts +5 -48
- package/dist/sequence.d.ts +2 -2
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +5 -1
- package/dist/sequence.js.map +1 -1
- package/dist/sharedString.d.ts +1 -14
- package/dist/sharedString.d.ts.map +1 -1
- package/dist/sharedString.js +0 -12
- package/dist/sharedString.js.map +1 -1
- package/lib/{defaultMap.d.ts → defaultMap.d.mts} +3 -3
- package/lib/defaultMap.d.mts.map +1 -0
- package/lib/{defaultMap.js → defaultMap.mjs} +28 -27
- package/lib/defaultMap.mjs.map +1 -0
- package/lib/{defaultMapInterfaces.d.ts → defaultMapInterfaces.d.mts} +4 -3
- package/lib/defaultMapInterfaces.d.mts.map +1 -0
- package/lib/{intervalIndex/intervalIndex.js → defaultMapInterfaces.mjs} +2 -3
- package/lib/defaultMapInterfaces.mjs.map +1 -0
- package/lib/{index.d.ts → index.d.mts} +12 -24
- 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.ts → intervalCollection.d.mts} +6 -46
- package/lib/intervalCollection.d.mts.map +1 -0
- package/lib/{intervalCollection.js → intervalCollection.mjs} +176 -179
- package/lib/intervalCollection.mjs.map +1 -0
- package/lib/intervalIndex/{endpointInRangeIndex.d.ts → endpointInRangeIndex.d.mts} +4 -4
- package/lib/intervalIndex/endpointInRangeIndex.d.mts.map +1 -0
- package/lib/intervalIndex/{endpointInRangeIndex.js → endpointInRangeIndex.mjs} +13 -18
- package/lib/intervalIndex/endpointInRangeIndex.mjs.map +1 -0
- package/lib/intervalIndex/{endpointIndex.d.ts → endpointIndex.d.mts} +4 -4
- package/lib/intervalIndex/endpointIndex.d.mts.map +1 -0
- package/lib/intervalIndex/{endpointIndex.js → endpointIndex.mjs} +9 -14
- package/lib/intervalIndex/endpointIndex.mjs.map +1 -0
- package/lib/intervalIndex/{idIntervalIndex.d.ts → idIntervalIndex.d.mts} +3 -3
- package/lib/intervalIndex/idIntervalIndex.d.mts.map +1 -0
- package/lib/intervalIndex/{idIntervalIndex.js → idIntervalIndex.mjs} +5 -9
- package/lib/intervalIndex/idIntervalIndex.mjs.map +1 -0
- package/lib/intervalIndex/{index.d.ts → index.d.mts} +9 -9
- package/lib/intervalIndex/index.d.mts.map +1 -0
- package/lib/intervalIndex/index.mjs +11 -0
- package/lib/intervalIndex/{index.js.map → index.mjs.map} +1 -1
- package/lib/intervalIndex/{intervalIndex.d.ts → intervalIndex.d.mts} +2 -2
- package/lib/intervalIndex/intervalIndex.d.mts.map +1 -0
- package/lib/intervalIndex/intervalIndex.mjs +6 -0
- package/lib/intervalIndex/{intervalIndex.js.map → intervalIndex.mjs.map} +1 -1
- package/lib/intervalIndex/{intervalIndexUtils.d.ts → intervalIndexUtils.d.mts} +1 -1
- package/lib/intervalIndex/intervalIndexUtils.d.mts.map +1 -0
- package/lib/intervalIndex/{intervalIndexUtils.js → intervalIndexUtils.mjs} +5 -9
- package/lib/intervalIndex/intervalIndexUtils.mjs.map +1 -0
- package/lib/intervalIndex/{overlappingIntervalsIndex.d.ts → overlappingIntervalsIndex.d.mts} +6 -6
- package/lib/intervalIndex/overlappingIntervalsIndex.d.mts.map +1 -0
- package/lib/intervalIndex/{overlappingIntervalsIndex.js → overlappingIntervalsIndex.mjs} +11 -16
- package/lib/intervalIndex/overlappingIntervalsIndex.mjs.map +1 -0
- package/lib/intervalIndex/{overlappingSequenceIntervalsIndex.d.ts → overlappingSequenceIntervalsIndex.d.mts} +3 -3
- 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.ts → sequenceIntervalIndexes.d.mts} +3 -3
- package/lib/intervalIndex/sequenceIntervalIndexes.d.mts.map +1 -0
- package/lib/intervalIndex/sequenceIntervalIndexes.mjs +6 -0
- package/lib/intervalIndex/{sequenceIntervalIndexes.js.map → sequenceIntervalIndexes.mjs.map} +1 -1
- package/lib/intervalIndex/{startpointInRangeIndex.d.ts → startpointInRangeIndex.d.mts} +4 -4
- package/lib/intervalIndex/startpointInRangeIndex.d.mts.map +1 -0
- package/lib/intervalIndex/{startpointInRangeIndex.js → startpointInRangeIndex.mjs} +13 -18
- package/lib/intervalIndex/startpointInRangeIndex.mjs.map +1 -0
- package/lib/{intervalTree.d.ts → intervalTree.d.mts} +2 -2
- package/lib/intervalTree.d.mts.map +1 -0
- package/lib/{intervalTree.js → intervalTree.mjs} +4 -8
- package/lib/intervalTree.mjs.map +1 -0
- package/lib/intervals/{index.d.ts → index.d.mts} +4 -4
- 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.ts → interval.d.mts} +3 -3
- package/lib/intervals/interval.d.mts.map +1 -0
- package/lib/intervals/{interval.js → interval.mjs} +13 -18
- package/lib/intervals/interval.mjs.map +1 -0
- package/lib/intervals/{intervalUtils.d.ts → intervalUtils.d.mts} +14 -4
- package/lib/intervals/intervalUtils.d.mts.map +1 -0
- package/lib/intervals/{intervalUtils.js → intervalUtils.mjs} +22 -21
- package/lib/intervals/intervalUtils.mjs.map +1 -0
- package/lib/intervals/{sequenceInterval.d.ts → sequenceInterval.d.mts} +3 -3
- package/lib/intervals/sequenceInterval.d.mts.map +1 -0
- package/lib/intervals/{sequenceInterval.js → sequenceInterval.mjs} +56 -64
- package/lib/intervals/sequenceInterval.mjs.map +1 -0
- package/lib/{localValues.d.ts → localValues.d.mts} +3 -3
- package/lib/localValues.d.mts.map +1 -0
- package/lib/{localValues.js → localValues.mjs} +5 -10
- package/lib/localValues.mjs.map +1 -0
- package/lib/{packageVersion.d.ts → packageVersion.d.mts} +2 -2
- package/lib/packageVersion.d.mts.map +1 -0
- package/lib/packageVersion.mjs +9 -0
- package/lib/packageVersion.mjs.map +1 -0
- package/lib/{revertibles.d.ts → revertibles.d.mts} +4 -4
- package/lib/revertibles.d.mts.map +1 -0
- package/lib/{revertibles.js → revertibles.mjs} +71 -74
- package/lib/revertibles.mjs.map +1 -0
- package/lib/{sequence-alpha.d.ts → sequence-alpha.d.mts} +2 -60
- package/lib/{sequence-public.d.ts → sequence-beta.d.mts} +0 -42
- package/lib/{sequence-beta.d.ts → sequence-public.d.mts} +0 -42
- package/lib/{sequence-untrimmed.d.ts → sequence-untrimmed.d.mts} +5 -61
- package/lib/{sequence.d.ts → sequence.d.mts} +7 -7
- package/lib/sequence.d.mts.map +1 -0
- package/lib/{sequence.js → sequence.mjs} +51 -48
- package/lib/sequence.mjs.map +1 -0
- package/lib/{sequenceDeltaEvent.d.ts → sequenceDeltaEvent.d.mts} +1 -1
- package/lib/sequenceDeltaEvent.d.mts.map +1 -0
- package/lib/{sequenceDeltaEvent.js → sequenceDeltaEvent.mjs} +10 -14
- package/lib/sequenceDeltaEvent.mjs.map +1 -0
- package/lib/{sequenceFactory.d.ts → sequenceFactory.d.mts} +2 -2
- package/lib/sequenceFactory.d.mts.map +1 -0
- package/lib/{sequenceFactory.js → sequenceFactory.mjs} +10 -14
- package/lib/sequenceFactory.mjs.map +1 -0
- package/lib/{sharedIntervalCollection.d.ts → sharedIntervalCollection.d.mts} +3 -3
- package/lib/sharedIntervalCollection.d.mts.map +1 -0
- package/lib/{sharedIntervalCollection.js → sharedIntervalCollection.mjs} +14 -19
- package/lib/sharedIntervalCollection.mjs.map +1 -0
- package/lib/{sharedSequence.d.ts → sharedSequence.d.mts} +2 -2
- package/lib/sharedSequence.d.mts.map +1 -0
- package/lib/{sharedSequence.js → sharedSequence.mjs} +7 -12
- package/lib/sharedSequence.mjs.map +1 -0
- package/lib/{sharedString.d.ts → sharedString.d.mts} +4 -17
- package/lib/sharedString.d.mts.map +1 -0
- package/lib/{sharedString.js → sharedString.mjs} +17 -34
- package/lib/sharedString.mjs.map +1 -0
- package/package.json +97 -46
- package/src/defaultMap.ts +17 -12
- package/src/defaultMapInterfaces.ts +9 -2
- package/src/intervalCollection.ts +67 -123
- package/src/intervals/index.ts +1 -0
- package/src/intervals/intervalUtils.ts +14 -4
- package/src/packageVersion.ts +1 -1
- package/src/revertibles.ts +9 -11
- package/src/sequence.ts +7 -3
- package/src/sharedString.ts +0 -23
- 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 +0 -7
- package/lib/defaultMapInterfaces.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -60
- package/lib/index.js.map +0 -1
- package/lib/intervalCollection.d.ts.map +0 -1
- package/lib/intervalCollection.js.map +0 -1
- package/lib/intervalIndex/endpointInRangeIndex.d.ts.map +0 -1
- package/lib/intervalIndex/endpointInRangeIndex.js.map +0 -1
- package/lib/intervalIndex/endpointIndex.d.ts.map +0 -1
- package/lib/intervalIndex/endpointIndex.js.map +0 -1
- package/lib/intervalIndex/idIntervalIndex.d.ts.map +0 -1
- package/lib/intervalIndex/idIntervalIndex.js.map +0 -1
- package/lib/intervalIndex/index.d.ts.map +0 -1
- package/lib/intervalIndex/index.js +0 -24
- package/lib/intervalIndex/intervalIndex.d.ts.map +0 -1
- package/lib/intervalIndex/intervalIndexUtils.d.ts.map +0 -1
- package/lib/intervalIndex/intervalIndexUtils.js.map +0 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +0 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.js.map +0 -1
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +0 -1
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js +0 -41
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js.map +0 -1
- package/lib/intervalIndex/sequenceIntervalIndexes.d.ts.map +0 -1
- package/lib/intervalIndex/sequenceIntervalIndexes.js +0 -7
- package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +0 -1
- package/lib/intervalIndex/startpointInRangeIndex.js.map +0 -1
- package/lib/intervalTree.d.ts.map +0 -1
- package/lib/intervalTree.js.map +0 -1
- package/lib/intervals/index.d.ts.map +0 -1
- package/lib/intervals/index.js +0 -23
- package/lib/intervals/index.js.map +0 -1
- package/lib/intervals/interval.d.ts.map +0 -1
- package/lib/intervals/interval.js.map +0 -1
- package/lib/intervals/intervalUtils.d.ts.map +0 -1
- package/lib/intervals/intervalUtils.js.map +0 -1
- package/lib/intervals/sequenceInterval.d.ts.map +0 -1
- package/lib/intervals/sequenceInterval.js.map +0 -1
- package/lib/localValues.d.ts.map +0 -1
- package/lib/localValues.js.map +0 -1
- package/lib/packageVersion.d.ts.map +0 -1
- package/lib/packageVersion.js +0 -12
- package/lib/packageVersion.js.map +0 -1
- package/lib/revertibles.d.ts.map +0 -1
- package/lib/revertibles.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.map +0 -1
- package/lib/sequenceFactory.js.map +0 -1
- package/lib/sharedIntervalCollection.d.ts.map +0 -1
- package/lib/sharedIntervalCollection.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.map +0 -1
- package/sequence.test-files.tar +0 -0
- package/tsconfig.esnext.json +0 -6
|
@@ -1,50 +1,44 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*!
|
|
3
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
3
|
* Licensed under the MIT License.
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
14
|
-
const uuid_1 = require("uuid");
|
|
15
|
-
const intervals_1 = require("./intervals");
|
|
16
|
-
const intervalIndex_1 = require("./intervalIndex");
|
|
5
|
+
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
6
|
+
import { assert, unreachableCase } from "@fluidframework/core-utils";
|
|
7
|
+
import { addProperties, createMap, getSlideToSegoff, MergeTreeDeltaType, ReferenceType, refTypeIncludesFlag, reservedRangeLabelsKey, UnassignedSequenceNumber, DetachedReferencePosition, UniversalSequenceNumber, SlidingPreference, } from "@fluidframework/merge-tree";
|
|
8
|
+
import { LoggingError, UsageError } from "@fluidframework/telemetry-utils";
|
|
9
|
+
import { v4 as uuid } from "uuid";
|
|
10
|
+
import { IntervalOpType, IntervalStickiness, IntervalType, SequenceInterval, createPositionReferenceFromSegoff, endReferenceSlidingPreference, startReferenceSlidingPreference, sequenceIntervalHelpers, createInterval, IntervalDeltaOpType, } from "./intervals/index.mjs";
|
|
11
|
+
import { EndpointIndex, OverlappingIntervalsIndex, createIdIntervalIndex, } from "./intervalIndex/index.mjs";
|
|
17
12
|
/**
|
|
18
13
|
* Defines a side relative to a character in a sequence.
|
|
19
14
|
*
|
|
20
15
|
* @remarks See {@link SequencePlace} for additional context on usage.
|
|
21
16
|
* @alpha
|
|
22
17
|
*/
|
|
23
|
-
var Side;
|
|
18
|
+
export var Side;
|
|
24
19
|
(function (Side) {
|
|
25
20
|
Side[Side["Before"] = 0] = "Before";
|
|
26
21
|
Side[Side["After"] = 1] = "After";
|
|
27
|
-
})(Side || (
|
|
22
|
+
})(Side || (Side = {}));
|
|
28
23
|
const reservedIntervalIdKey = "intervalId";
|
|
29
|
-
function sidesFromStickiness(stickiness) {
|
|
30
|
-
const startSide = (stickiness &
|
|
31
|
-
const endSide = (stickiness &
|
|
24
|
+
export function sidesFromStickiness(stickiness) {
|
|
25
|
+
const startSide = (stickiness & IntervalStickiness.START) !== 0 ? Side.After : Side.Before;
|
|
26
|
+
const endSide = (stickiness & IntervalStickiness.END) !== 0 ? Side.Before : Side.After;
|
|
32
27
|
return { startSide, endSide };
|
|
33
28
|
}
|
|
34
|
-
exports.sidesFromStickiness = sidesFromStickiness;
|
|
35
29
|
/**
|
|
36
30
|
* Decompress an interval after loading a summary from JSON. The exact format
|
|
37
31
|
* of this compression is unspecified and subject to change
|
|
38
32
|
*/
|
|
39
33
|
function decompressInterval(interval, label) {
|
|
40
|
-
const stickiness = interval[5] ??
|
|
34
|
+
const stickiness = interval[5] ?? IntervalStickiness.END;
|
|
41
35
|
const { startSide, endSide } = sidesFromStickiness(stickiness);
|
|
42
36
|
return {
|
|
43
37
|
start: interval[0],
|
|
44
38
|
end: interval[1],
|
|
45
39
|
sequenceNumber: interval[2],
|
|
46
40
|
intervalType: interval[3],
|
|
47
|
-
properties: { ...interval[4], [
|
|
41
|
+
properties: { ...interval[4], [reservedRangeLabelsKey]: [label] },
|
|
48
42
|
stickiness,
|
|
49
43
|
startSide,
|
|
50
44
|
endSide,
|
|
@@ -63,15 +57,15 @@ function compressInterval(interval) {
|
|
|
63
57
|
intervalType,
|
|
64
58
|
// remove the `referenceRangeLabels` property as it is already stored
|
|
65
59
|
// in the `label` field of the summary
|
|
66
|
-
{ ...properties, [
|
|
60
|
+
{ ...properties, [reservedRangeLabelsKey]: undefined },
|
|
67
61
|
];
|
|
68
|
-
if (interval.stickiness !== undefined && interval.stickiness !==
|
|
62
|
+
if (interval.stickiness !== undefined && interval.stickiness !== IntervalStickiness.END) {
|
|
69
63
|
// reassignment to make it easier for typescript to reason about types
|
|
70
64
|
base = [...base, interval.stickiness];
|
|
71
65
|
}
|
|
72
66
|
return base;
|
|
73
67
|
}
|
|
74
|
-
function endpointPosAndSide(start, end) {
|
|
68
|
+
export function endpointPosAndSide(start, end) {
|
|
75
69
|
const startIsPlainEndpoint = typeof start === "number" || start === "start" || start === "end";
|
|
76
70
|
const endIsPlainEndpoint = typeof end === "number" || end === "start" || end === "end";
|
|
77
71
|
const startSide = startIsPlainEndpoint ? Side.Before : start?.side;
|
|
@@ -85,33 +79,30 @@ function endpointPosAndSide(start, end) {
|
|
|
85
79
|
endPos,
|
|
86
80
|
};
|
|
87
81
|
}
|
|
88
|
-
exports.endpointPosAndSide = endpointPosAndSide;
|
|
89
82
|
function toSequencePlace(pos, side) {
|
|
90
83
|
return typeof pos === "number" ? { pos, side } : pos;
|
|
91
84
|
}
|
|
92
85
|
function toOptionalSequencePlace(pos, side = Side.Before) {
|
|
93
86
|
return typeof pos === "number" ? { pos, side } : pos;
|
|
94
87
|
}
|
|
95
|
-
function computeStickinessFromSide(startPos = -1, startSide = Side.Before, endPos = -1, endSide = Side.Before) {
|
|
96
|
-
let stickiness =
|
|
88
|
+
export function computeStickinessFromSide(startPos = -1, startSide = Side.Before, endPos = -1, endSide = Side.Before) {
|
|
89
|
+
let stickiness = IntervalStickiness.NONE;
|
|
97
90
|
if (startSide === Side.After || startPos === "start") {
|
|
98
|
-
stickiness |=
|
|
91
|
+
stickiness |= IntervalStickiness.START;
|
|
99
92
|
}
|
|
100
93
|
if (endSide === Side.Before || endPos === "end") {
|
|
101
|
-
stickiness |=
|
|
94
|
+
stickiness |= IntervalStickiness.END;
|
|
102
95
|
}
|
|
103
96
|
return stickiness;
|
|
104
97
|
}
|
|
105
|
-
|
|
106
|
-
function createIntervalIndex() {
|
|
98
|
+
export function createIntervalIndex() {
|
|
107
99
|
const helpers = {
|
|
108
|
-
create:
|
|
100
|
+
create: createInterval,
|
|
109
101
|
};
|
|
110
102
|
const lc = new LocalIntervalCollection(undefined, "", helpers, {});
|
|
111
103
|
return lc;
|
|
112
104
|
}
|
|
113
|
-
|
|
114
|
-
class LocalIntervalCollection {
|
|
105
|
+
export class LocalIntervalCollection {
|
|
115
106
|
constructor(client, label, helpers, options,
|
|
116
107
|
/** Callback invoked each time one of the endpoints of an interval slides. */
|
|
117
108
|
onPositionChange) {
|
|
@@ -120,9 +111,9 @@ class LocalIntervalCollection {
|
|
|
120
111
|
this.helpers = helpers;
|
|
121
112
|
this.options = options;
|
|
122
113
|
this.onPositionChange = onPositionChange;
|
|
123
|
-
this.overlappingIntervalsIndex = new
|
|
124
|
-
this.idIntervalIndex =
|
|
125
|
-
this.endIntervalIndex = new
|
|
114
|
+
this.overlappingIntervalsIndex = new OverlappingIntervalsIndex(client, helpers);
|
|
115
|
+
this.idIntervalIndex = createIdIntervalIndex();
|
|
116
|
+
this.endIntervalIndex = new EndpointIndex(client, helpers);
|
|
126
117
|
this.indexes = new Set([
|
|
127
118
|
this.overlappingIntervalsIndex,
|
|
128
119
|
this.idIntervalIndex,
|
|
@@ -151,7 +142,7 @@ class LocalIntervalCollection {
|
|
|
151
142
|
const newProps = {
|
|
152
143
|
[reservedIntervalIdKey]: id,
|
|
153
144
|
};
|
|
154
|
-
serializedInterval.properties =
|
|
145
|
+
serializedInterval.properties = addProperties(serializedInterval.properties, newProps);
|
|
155
146
|
}
|
|
156
147
|
// Make the ID immutable for safety's sake.
|
|
157
148
|
Object.defineProperty(serializedInterval.properties, reservedIntervalIdKey, {
|
|
@@ -184,25 +175,25 @@ class LocalIntervalCollection {
|
|
|
184
175
|
const interval = this.createInterval(start, end, intervalType, op);
|
|
185
176
|
if (interval) {
|
|
186
177
|
if (!interval.properties) {
|
|
187
|
-
interval.properties =
|
|
178
|
+
interval.properties = createMap();
|
|
188
179
|
}
|
|
189
180
|
if (props) {
|
|
190
181
|
// This check is intended to prevent scenarios where a random interval is created and then
|
|
191
182
|
// inserted into a collection. The aim is to ensure that the collection is created first
|
|
192
183
|
// then the user can create/add intervals based on the collection
|
|
193
|
-
if (props[
|
|
194
|
-
props[
|
|
195
|
-
throw new
|
|
184
|
+
if (props[reservedRangeLabelsKey] !== undefined &&
|
|
185
|
+
props[reservedRangeLabelsKey][0] !== this.label) {
|
|
186
|
+
throw new LoggingError("Adding an interval that belongs to another interval collection is not permitted");
|
|
196
187
|
}
|
|
197
188
|
interval.addProperties(props);
|
|
198
189
|
}
|
|
199
|
-
(_a = interval.properties)[reservedIntervalIdKey] ?? (_a[reservedIntervalIdKey] = (
|
|
190
|
+
(_a = interval.properties)[reservedIntervalIdKey] ?? (_a[reservedIntervalIdKey] = uuid());
|
|
200
191
|
this.add(interval);
|
|
201
192
|
}
|
|
202
193
|
return interval;
|
|
203
194
|
}
|
|
204
195
|
linkEndpointsToInterval(interval) {
|
|
205
|
-
if (interval instanceof
|
|
196
|
+
if (interval instanceof SequenceInterval) {
|
|
206
197
|
interval.start.addProperties({ interval });
|
|
207
198
|
interval.end.addProperties({ interval });
|
|
208
199
|
}
|
|
@@ -241,9 +232,9 @@ class LocalIntervalCollection {
|
|
|
241
232
|
// either, so this must be special-cased.
|
|
242
233
|
return ref;
|
|
243
234
|
}
|
|
244
|
-
return this.client.createLocalReferencePosition(segment, ref.getOffset(),
|
|
235
|
+
return this.client.createLocalReferencePosition(segment, ref.getOffset(), ReferenceType.Transient, ref.properties, ref.slidingPreference, ref.canSlideToEndpoint);
|
|
245
236
|
};
|
|
246
|
-
if (interval instanceof
|
|
237
|
+
if (interval instanceof SequenceInterval) {
|
|
247
238
|
let previousInterval;
|
|
248
239
|
let pendingChanges = 0;
|
|
249
240
|
interval.addPositionChangeListeners(() => {
|
|
@@ -256,7 +247,7 @@ class LocalIntervalCollection {
|
|
|
256
247
|
this.removeIntervalFromIndexes(interval);
|
|
257
248
|
}
|
|
258
249
|
}, () => {
|
|
259
|
-
|
|
250
|
+
assert(previousInterval !== undefined, 0x3fa /* Invalid interleaving of before/after slide */);
|
|
260
251
|
pendingChanges--;
|
|
261
252
|
if (pendingChanges === 0) {
|
|
262
253
|
this.addIntervalToIndexes(interval);
|
|
@@ -267,22 +258,21 @@ class LocalIntervalCollection {
|
|
|
267
258
|
}
|
|
268
259
|
}
|
|
269
260
|
removeIntervalListeners(interval) {
|
|
270
|
-
if (interval instanceof
|
|
261
|
+
if (interval instanceof SequenceInterval) {
|
|
271
262
|
interval.removePositionChangeListeners();
|
|
272
263
|
}
|
|
273
264
|
}
|
|
274
265
|
}
|
|
275
|
-
exports.LocalIntervalCollection = LocalIntervalCollection;
|
|
276
266
|
LocalIntervalCollection.legacyIdPrefix = "legacy";
|
|
277
267
|
class SequenceIntervalCollectionFactory {
|
|
278
268
|
load(emitter, raw = [], options) {
|
|
279
|
-
return new IntervalCollection(
|
|
269
|
+
return new IntervalCollection(sequenceIntervalHelpers, true, emitter, raw, options);
|
|
280
270
|
}
|
|
281
271
|
store(value) {
|
|
282
272
|
return value.serializeInternal();
|
|
283
273
|
}
|
|
284
274
|
}
|
|
285
|
-
class SequenceIntervalCollectionValueType {
|
|
275
|
+
export class SequenceIntervalCollectionValueType {
|
|
286
276
|
get name() {
|
|
287
277
|
return SequenceIntervalCollectionValueType.Name;
|
|
288
278
|
}
|
|
@@ -293,14 +283,13 @@ class SequenceIntervalCollectionValueType {
|
|
|
293
283
|
return SequenceIntervalCollectionValueType._ops;
|
|
294
284
|
}
|
|
295
285
|
}
|
|
296
|
-
exports.SequenceIntervalCollectionValueType = SequenceIntervalCollectionValueType;
|
|
297
286
|
SequenceIntervalCollectionValueType.Name = "sharedStringIntervalCollection";
|
|
298
287
|
SequenceIntervalCollectionValueType._factory = new SequenceIntervalCollectionFactory();
|
|
299
288
|
SequenceIntervalCollectionValueType._ops = makeOpsMap();
|
|
300
289
|
class IntervalCollectionFactory {
|
|
301
290
|
load(emitter, raw = [], options) {
|
|
302
291
|
const helpers = {
|
|
303
|
-
create:
|
|
292
|
+
create: createInterval,
|
|
304
293
|
};
|
|
305
294
|
const collection = new IntervalCollection(helpers, false, emitter, raw, options);
|
|
306
295
|
collection.attachGraph(undefined, "");
|
|
@@ -310,7 +299,7 @@ class IntervalCollectionFactory {
|
|
|
310
299
|
return value.serializeInternal();
|
|
311
300
|
}
|
|
312
301
|
}
|
|
313
|
-
class IntervalCollectionValueType {
|
|
302
|
+
export class IntervalCollectionValueType {
|
|
314
303
|
get name() {
|
|
315
304
|
return IntervalCollectionValueType.Name;
|
|
316
305
|
}
|
|
@@ -321,11 +310,10 @@ class IntervalCollectionValueType {
|
|
|
321
310
|
return IntervalCollectionValueType._ops;
|
|
322
311
|
}
|
|
323
312
|
}
|
|
324
|
-
exports.IntervalCollectionValueType = IntervalCollectionValueType;
|
|
325
313
|
IntervalCollectionValueType.Name = "sharedIntervalCollection";
|
|
326
314
|
IntervalCollectionValueType._factory = new IntervalCollectionFactory();
|
|
327
315
|
IntervalCollectionValueType._ops = makeOpsMap();
|
|
328
|
-
function makeOpsMap() {
|
|
316
|
+
export function makeOpsMap() {
|
|
329
317
|
const rebase = (collection, op, localOpMetadata) => {
|
|
330
318
|
const { localSeq } = localOpMetadata;
|
|
331
319
|
const rebasedValue = collection.rebaseLocalInterval(op.opName, op.value, localSeq);
|
|
@@ -335,9 +323,12 @@ function makeOpsMap() {
|
|
|
335
323
|
const rebasedOp = { ...op, value: rebasedValue };
|
|
336
324
|
return { rebasedOp, rebasedLocalOpMetadata: localOpMetadata };
|
|
337
325
|
};
|
|
326
|
+
const applyStashedOp = (collection, op) => {
|
|
327
|
+
return collection.applyStashedOp(op);
|
|
328
|
+
};
|
|
338
329
|
return new Map([
|
|
339
330
|
[
|
|
340
|
-
|
|
331
|
+
IntervalOpType.ADD,
|
|
341
332
|
{
|
|
342
333
|
process: (collection, params, local, op, localOpMetadata) => {
|
|
343
334
|
// if params is undefined, the interval was deleted during
|
|
@@ -345,27 +336,29 @@ function makeOpsMap() {
|
|
|
345
336
|
if (!params) {
|
|
346
337
|
return;
|
|
347
338
|
}
|
|
348
|
-
|
|
339
|
+
assert(op !== undefined, 0x3fb /* op should exist here */);
|
|
349
340
|
collection.ackAdd(params, local, op, localOpMetadata);
|
|
350
341
|
},
|
|
351
342
|
rebase,
|
|
343
|
+
applyStashedOp,
|
|
352
344
|
},
|
|
353
345
|
],
|
|
354
346
|
[
|
|
355
|
-
|
|
347
|
+
IntervalOpType.DELETE,
|
|
356
348
|
{
|
|
357
349
|
process: (collection, params, local, op) => {
|
|
358
|
-
|
|
350
|
+
assert(op !== undefined, 0x3fc /* op should exist here */);
|
|
359
351
|
collection.ackDelete(params, local, op);
|
|
360
352
|
},
|
|
361
353
|
rebase: (collection, op, localOpMetadata) => {
|
|
362
354
|
// Deletion of intervals is based on id, so requires no rebasing.
|
|
363
355
|
return { rebasedOp: op, rebasedLocalOpMetadata: localOpMetadata };
|
|
364
356
|
},
|
|
357
|
+
applyStashedOp,
|
|
365
358
|
},
|
|
366
359
|
],
|
|
367
360
|
[
|
|
368
|
-
|
|
361
|
+
IntervalOpType.CHANGE,
|
|
369
362
|
{
|
|
370
363
|
process: (collection, params, local, op, localOpMetadata) => {
|
|
371
364
|
// if params is undefined, the interval was deleted during
|
|
@@ -373,15 +366,15 @@ function makeOpsMap() {
|
|
|
373
366
|
if (!params) {
|
|
374
367
|
return;
|
|
375
368
|
}
|
|
376
|
-
|
|
369
|
+
assert(op !== undefined, 0x3fd /* op should exist here */);
|
|
377
370
|
collection.ackChange(params, local, op, localOpMetadata);
|
|
378
371
|
},
|
|
379
372
|
rebase,
|
|
373
|
+
applyStashedOp,
|
|
380
374
|
},
|
|
381
375
|
],
|
|
382
376
|
]);
|
|
383
377
|
}
|
|
384
|
-
exports.makeOpsMap = makeOpsMap;
|
|
385
378
|
class IntervalCollectionIterator {
|
|
386
379
|
constructor(collection, iteratesForward = true, start, end) {
|
|
387
380
|
this.results = [];
|
|
@@ -401,15 +394,10 @@ class IntervalCollectionIterator {
|
|
|
401
394
|
};
|
|
402
395
|
}
|
|
403
396
|
}
|
|
404
|
-
// solely for type checking in the implementation of add - will be removed once
|
|
405
|
-
// deprecated signatures are removed
|
|
406
|
-
const isSequencePlace = (place) => {
|
|
407
|
-
return typeof place === "number" || typeof place === "string" || place.pos !== undefined;
|
|
408
|
-
};
|
|
409
397
|
/**
|
|
410
398
|
* {@inheritdoc IIntervalCollection}
|
|
411
399
|
*/
|
|
412
|
-
class IntervalCollection extends
|
|
400
|
+
export class IntervalCollection extends TypedEventEmitter {
|
|
413
401
|
get attached() {
|
|
414
402
|
return !!this.localCollection;
|
|
415
403
|
}
|
|
@@ -433,7 +421,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
433
421
|
*/
|
|
434
422
|
attachIndex(index) {
|
|
435
423
|
if (!this.attached) {
|
|
436
|
-
throw new
|
|
424
|
+
throw new LoggingError("The local interval collection must exist");
|
|
437
425
|
}
|
|
438
426
|
for (const interval of this) {
|
|
439
427
|
index.add(interval);
|
|
@@ -445,7 +433,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
445
433
|
*/
|
|
446
434
|
detachIndex(index) {
|
|
447
435
|
if (!this.attached) {
|
|
448
|
-
throw new
|
|
436
|
+
throw new LoggingError("The local interval collection must exist");
|
|
449
437
|
}
|
|
450
438
|
// Avoid removing intervals if the index does not exist
|
|
451
439
|
if (!this.localCollection?.removeIndex(index)) {
|
|
@@ -458,7 +446,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
458
446
|
}
|
|
459
447
|
rebasePositionWithSegmentSlide(pos, seqNumberFrom, localSeq) {
|
|
460
448
|
if (!this.client) {
|
|
461
|
-
throw new
|
|
449
|
+
throw new LoggingError("mergeTree client must exist");
|
|
462
450
|
}
|
|
463
451
|
if (pos === "start" || pos === "end") {
|
|
464
452
|
return pos;
|
|
@@ -469,19 +457,19 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
469
457
|
clientId: this.client.getLongClientId(clientId),
|
|
470
458
|
}, localSeq);
|
|
471
459
|
// if segment is undefined, it slid off the string
|
|
472
|
-
|
|
473
|
-
const segoff =
|
|
460
|
+
assert(segment !== undefined, 0x54e /* No segment found */);
|
|
461
|
+
const segoff = getSlideToSegoff({ segment, offset }, undefined, this.options.mergeTreeReferencesCanSlideToEndpoint) ?? segment;
|
|
474
462
|
// case happens when rebasing op, but concurrently entire string has been deleted
|
|
475
463
|
if (segoff.segment === undefined || segoff.offset === undefined) {
|
|
476
|
-
return
|
|
464
|
+
return DetachedReferencePosition;
|
|
477
465
|
}
|
|
478
|
-
|
|
466
|
+
assert(offset !== undefined && 0 <= offset && offset < segment.cachedLength, 0x54f /* Invalid offset */);
|
|
479
467
|
return this.client.findReconnectionPosition(segoff.segment, localSeq) + segoff.offset;
|
|
480
468
|
}
|
|
481
469
|
computeRebasedPositions(localSeq) {
|
|
482
|
-
|
|
470
|
+
assert(this.client !== undefined, 0x550 /* Client should be defined when computing rebased position */);
|
|
483
471
|
const original = this.localSeqToSerializedInterval.get(localSeq);
|
|
484
|
-
|
|
472
|
+
assert(original !== undefined, 0x551 /* Failed to store pending serialized interval info for this localSeq. */);
|
|
485
473
|
const rebased = { ...original };
|
|
486
474
|
const { start, end, sequenceNumber } = original;
|
|
487
475
|
if (start !== undefined) {
|
|
@@ -495,10 +483,10 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
495
483
|
/** @internal */
|
|
496
484
|
attachGraph(client, label) {
|
|
497
485
|
if (this.attached) {
|
|
498
|
-
throw new
|
|
486
|
+
throw new LoggingError("Only supports one Sequence attach");
|
|
499
487
|
}
|
|
500
488
|
if (client === undefined && this.requiresClient) {
|
|
501
|
-
throw new
|
|
489
|
+
throw new LoggingError("Client required for this collection");
|
|
502
490
|
}
|
|
503
491
|
// Instantiate the local interval collection based on the saved intervals
|
|
504
492
|
this.client = client;
|
|
@@ -544,11 +532,11 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
544
532
|
// is restored as single-endpoint changes re-use previous references.
|
|
545
533
|
let startRefType;
|
|
546
534
|
let endRefType;
|
|
547
|
-
if (previousInterval instanceof
|
|
535
|
+
if (previousInterval instanceof SequenceInterval) {
|
|
548
536
|
startRefType = previousInterval.start.refType;
|
|
549
537
|
endRefType = previousInterval.end.refType;
|
|
550
|
-
previousInterval.start.refType =
|
|
551
|
-
previousInterval.end.refType =
|
|
538
|
+
previousInterval.start.refType = ReferenceType.Transient;
|
|
539
|
+
previousInterval.end.refType = ReferenceType.Transient;
|
|
552
540
|
this.emit("changeInterval", interval, previousInterval, local, op, slide);
|
|
553
541
|
previousInterval.start.refType = startRefType;
|
|
554
542
|
previousInterval.end.refType = endRefType;
|
|
@@ -562,58 +550,40 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
562
550
|
*/
|
|
563
551
|
getIntervalById(id) {
|
|
564
552
|
if (!this.localCollection) {
|
|
565
|
-
throw new
|
|
553
|
+
throw new LoggingError("attach must be called before accessing intervals");
|
|
566
554
|
}
|
|
567
555
|
return this.localCollection.idIntervalIndex.getIntervalById(id);
|
|
568
556
|
}
|
|
569
557
|
assertStickinessEnabled(start, end) {
|
|
570
558
|
if (!(typeof start === "number" && typeof end === "number") &&
|
|
571
559
|
!this.options.intervalStickinessEnabled) {
|
|
572
|
-
throw new
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
add(start, end, intervalType, props) {
|
|
576
|
-
let intStart;
|
|
577
|
-
let intEnd;
|
|
578
|
-
let type;
|
|
579
|
-
let properties;
|
|
580
|
-
if (isSequencePlace(start)) {
|
|
581
|
-
intStart = start;
|
|
582
|
-
(0, core_utils_1.assert)(end !== undefined, 0x7c0 /* end must be defined */);
|
|
583
|
-
intEnd = end;
|
|
584
|
-
(0, core_utils_1.assert)(intervalType !== undefined, 0x7c1 /* intervalType must be defined */);
|
|
585
|
-
type = intervalType;
|
|
586
|
-
properties = props;
|
|
587
|
-
}
|
|
588
|
-
else {
|
|
589
|
-
intStart = start.start;
|
|
590
|
-
intEnd = start.end;
|
|
591
|
-
type = intervals_1.IntervalType.SlideOnRemove;
|
|
592
|
-
properties = start.props;
|
|
560
|
+
throw new UsageError("attempted to set interval stickiness without enabling `intervalStickinessEnabled` feature flag");
|
|
593
561
|
}
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* {@inheritdoc IIntervalCollection.add}
|
|
565
|
+
*/
|
|
566
|
+
add({ start, end, props, }) {
|
|
594
567
|
if (!this.localCollection) {
|
|
595
|
-
throw new
|
|
568
|
+
throw new LoggingError("attach must be called prior to adding intervals");
|
|
596
569
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
}
|
|
600
|
-
const { startSide, endSide, startPos, endPos } = endpointPosAndSide(intStart, intEnd);
|
|
601
|
-
(0, core_utils_1.assert)(startPos !== undefined &&
|
|
570
|
+
const { startSide, endSide, startPos, endPos } = endpointPosAndSide(start, end);
|
|
571
|
+
assert(startPos !== undefined &&
|
|
602
572
|
endPos !== undefined &&
|
|
603
573
|
startSide !== undefined &&
|
|
604
574
|
endSide !== undefined, 0x793 /* start and end cannot be undefined because they were not passed in as undefined */);
|
|
605
575
|
const stickiness = computeStickinessFromSide(startPos, startSide, endPos, endSide);
|
|
606
|
-
this.assertStickinessEnabled(
|
|
607
|
-
const interval = this.localCollection.addInterval(toSequencePlace(startPos, startSide), toSequencePlace(endPos, endSide),
|
|
576
|
+
this.assertStickinessEnabled(start, end);
|
|
577
|
+
const interval = this.localCollection.addInterval(toSequencePlace(startPos, startSide), toSequencePlace(endPos, endSide), IntervalType.SlideOnRemove, props);
|
|
608
578
|
if (interval) {
|
|
609
|
-
if (!this.isCollaborating && interval instanceof
|
|
579
|
+
if (!this.isCollaborating && interval instanceof SequenceInterval) {
|
|
610
580
|
setSlideOnRemove(interval.start);
|
|
611
581
|
setSlideOnRemove(interval.end);
|
|
612
582
|
}
|
|
613
583
|
const serializedInterval = {
|
|
614
584
|
start: startPos,
|
|
615
585
|
end: endPos,
|
|
616
|
-
intervalType:
|
|
586
|
+
intervalType: IntervalType.SlideOnRemove,
|
|
617
587
|
properties: interval.properties,
|
|
618
588
|
sequenceNumber: this.client?.getCurrentSeq() ?? 0,
|
|
619
589
|
stickiness,
|
|
@@ -630,7 +600,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
630
600
|
}
|
|
631
601
|
deleteExistingInterval(interval, local, op) {
|
|
632
602
|
if (!this.localCollection) {
|
|
633
|
-
throw new
|
|
603
|
+
throw new LoggingError("Attach must be called before accessing intervals");
|
|
634
604
|
}
|
|
635
605
|
// The given interval is known to exist in the collection.
|
|
636
606
|
this.localCollection.removeExistingInterval(interval);
|
|
@@ -654,7 +624,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
654
624
|
*/
|
|
655
625
|
removeIntervalById(id) {
|
|
656
626
|
if (!this.localCollection) {
|
|
657
|
-
throw new
|
|
627
|
+
throw new LoggingError("Attach must be called before accessing intervals");
|
|
658
628
|
}
|
|
659
629
|
const interval = this.localCollection.idIntervalIndex.getIntervalById(id);
|
|
660
630
|
if (interval) {
|
|
@@ -663,52 +633,35 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
663
633
|
return interval;
|
|
664
634
|
}
|
|
665
635
|
/**
|
|
666
|
-
* {@inheritdoc IIntervalCollection.
|
|
667
|
-
* @deprecated - call change with the id and an object containing the new props values
|
|
636
|
+
* {@inheritdoc IIntervalCollection.change}
|
|
668
637
|
*/
|
|
669
|
-
|
|
670
|
-
this.change(id, { props });
|
|
671
|
-
}
|
|
672
|
-
change(arg1, arg2, arg3) {
|
|
673
|
-
const id = arg1;
|
|
674
|
-
let start;
|
|
675
|
-
let end;
|
|
676
|
-
let props;
|
|
677
|
-
if (isSequencePlace(arg2)) {
|
|
678
|
-
start = arg2;
|
|
679
|
-
end = arg3;
|
|
680
|
-
}
|
|
681
|
-
else {
|
|
682
|
-
start = arg2.start;
|
|
683
|
-
end = arg2.end;
|
|
684
|
-
props = arg2.props;
|
|
685
|
-
}
|
|
638
|
+
change(id, { start, end, props }) {
|
|
686
639
|
if (!this.localCollection) {
|
|
687
|
-
throw new
|
|
640
|
+
throw new LoggingError("Attach must be called before accessing intervals");
|
|
688
641
|
}
|
|
689
642
|
// Force id to be a string.
|
|
690
643
|
if (typeof id !== "string") {
|
|
691
|
-
throw new
|
|
644
|
+
throw new UsageError("Change API requires an ID that is a string");
|
|
692
645
|
}
|
|
693
646
|
// Ensure that both start and end are defined or both are undefined.
|
|
694
647
|
if ((start === undefined) !== (end === undefined)) {
|
|
695
|
-
throw new
|
|
648
|
+
throw new UsageError("Change API requires both start and end to be defined or undefined");
|
|
696
649
|
}
|
|
697
650
|
// prevent the overwriting of an interval label, it should remain unchanged
|
|
698
651
|
// once it has been inserted into the collection.
|
|
699
|
-
if (props?.[
|
|
700
|
-
throw new
|
|
652
|
+
if (props?.[reservedRangeLabelsKey] !== undefined) {
|
|
653
|
+
throw new UsageError("The label property should not be modified once inserted to the collection");
|
|
701
654
|
}
|
|
702
655
|
const interval = this.getIntervalById(id);
|
|
703
656
|
if (interval) {
|
|
704
657
|
let deltaProps;
|
|
705
658
|
let newInterval;
|
|
706
659
|
if (props !== undefined) {
|
|
707
|
-
deltaProps = interval.addProperties(props, true, this.isCollaborating ?
|
|
660
|
+
deltaProps = interval.addProperties(props, true, this.isCollaborating ? UnassignedSequenceNumber : UniversalSequenceNumber);
|
|
708
661
|
}
|
|
709
662
|
if (start !== undefined && end !== undefined) {
|
|
710
663
|
newInterval = this.localCollection.changeInterval(interval, start, end);
|
|
711
|
-
if (!this.isCollaborating && newInterval instanceof
|
|
664
|
+
if (!this.isCollaborating && newInterval instanceof SequenceInterval) {
|
|
712
665
|
setSlideOnRemove(newInterval.start);
|
|
713
666
|
setSlideOnRemove(newInterval.end);
|
|
714
667
|
}
|
|
@@ -782,7 +735,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
782
735
|
}
|
|
783
736
|
if (pendingChange?.start !== serializedInterval.start ||
|
|
784
737
|
pendingChange?.end !== serializedInterval.end) {
|
|
785
|
-
throw new
|
|
738
|
+
throw new LoggingError("Mismatch in pending changes");
|
|
786
739
|
}
|
|
787
740
|
}
|
|
788
741
|
}
|
|
@@ -797,10 +750,10 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
797
750
|
/** @internal */
|
|
798
751
|
ackChange(serializedInterval, local, op, localOpMetadata) {
|
|
799
752
|
if (!this.localCollection) {
|
|
800
|
-
throw new
|
|
753
|
+
throw new LoggingError("Attach must be called before accessing intervals");
|
|
801
754
|
}
|
|
802
755
|
if (local) {
|
|
803
|
-
|
|
756
|
+
assert(localOpMetadata !== undefined, 0x552 /* op metadata should be defined for local op */);
|
|
804
757
|
this.localSeqToSerializedInterval.delete(localOpMetadata?.localSeq);
|
|
805
758
|
// This is an ack from the server. Remove the pending change.
|
|
806
759
|
this.removePendingChange(serializedInterval);
|
|
@@ -809,7 +762,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
809
762
|
// This API cannot change the ID, and writing to the ID property will result in an exception. So we
|
|
810
763
|
// strip it out of the properties here.
|
|
811
764
|
const { [reservedIntervalIdKey]: id, ...newProps } = serializedInterval.properties ?? {};
|
|
812
|
-
|
|
765
|
+
assert(id !== undefined, 0x3fe /* id must exist on the interval */);
|
|
813
766
|
const interval = this.getIntervalById(id);
|
|
814
767
|
if (!interval) {
|
|
815
768
|
// The interval has been removed locally; no-op.
|
|
@@ -818,7 +771,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
818
771
|
if (local) {
|
|
819
772
|
// Let the propertyManager prune its pending change-properties set.
|
|
820
773
|
interval.propertyManager?.ackPendingProperties({
|
|
821
|
-
type:
|
|
774
|
+
type: MergeTreeDeltaType.ANNOTATE,
|
|
822
775
|
props: serializedInterval.properties ?? {},
|
|
823
776
|
});
|
|
824
777
|
this.ackInterval(interval, op);
|
|
@@ -883,7 +836,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
883
836
|
return serializedInterval;
|
|
884
837
|
}
|
|
885
838
|
if (!this.attached) {
|
|
886
|
-
throw new
|
|
839
|
+
throw new LoggingError("attachSequence must be called");
|
|
887
840
|
}
|
|
888
841
|
const { intervalType, properties, stickiness, startSide, endSide } = serializedInterval;
|
|
889
842
|
const { start: startRebased, end: endRebased } = this.localSeqToRebasedInterval.get(localSeq) ?? this.computeRebasedPositions(localSeq);
|
|
@@ -906,8 +859,8 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
906
859
|
this.addPendingChange(intervalId, rebased);
|
|
907
860
|
}
|
|
908
861
|
// if the interval slid off the string, rebase the op to be a noop and delete the interval.
|
|
909
|
-
if (startRebased ===
|
|
910
|
-
endRebased ===
|
|
862
|
+
if (startRebased === DetachedReferencePosition ||
|
|
863
|
+
endRebased === DetachedReferencePosition) {
|
|
911
864
|
if (localInterval) {
|
|
912
865
|
this.localCollection?.removeExistingInterval(localInterval);
|
|
913
866
|
}
|
|
@@ -915,22 +868,68 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
915
868
|
}
|
|
916
869
|
if (localInterval !== undefined) {
|
|
917
870
|
// we know we must be using `SequenceInterval` because `this.client` exists
|
|
918
|
-
|
|
871
|
+
assert(localInterval instanceof SequenceInterval, 0x3a0 /* localInterval must be `SequenceInterval` when used with client */);
|
|
919
872
|
// The rebased op may place this interval's endpoints on different segments. Calling `changeInterval` here
|
|
920
873
|
// updates the local client's state to be consistent with the emitted op.
|
|
921
874
|
this.localCollection?.changeInterval(localInterval, toOptionalSequencePlace(startRebased, startSide), toOptionalSequencePlace(endRebased, endSide), undefined, localSeq);
|
|
922
875
|
}
|
|
923
876
|
return rebased;
|
|
924
877
|
}
|
|
878
|
+
applyStashedOp(op) {
|
|
879
|
+
let interval;
|
|
880
|
+
let props;
|
|
881
|
+
let intervalId;
|
|
882
|
+
switch (op.opName) {
|
|
883
|
+
case IntervalDeltaOpType.ADD: {
|
|
884
|
+
assert(op.value.start !== undefined, 0x87a /* start is undefined */);
|
|
885
|
+
assert(op.value.end !== undefined, 0x87b /* end is undefined */);
|
|
886
|
+
interval = this.add({
|
|
887
|
+
start: op.value.start,
|
|
888
|
+
end: op.value.end,
|
|
889
|
+
props: op.value.properties,
|
|
890
|
+
});
|
|
891
|
+
const metadata = {
|
|
892
|
+
localSeq: this.getNextLocalSeq(),
|
|
893
|
+
};
|
|
894
|
+
if (interval !== undefined) {
|
|
895
|
+
this.localSeqToSerializedInterval.set(metadata.localSeq, interval.serialize());
|
|
896
|
+
}
|
|
897
|
+
return metadata;
|
|
898
|
+
}
|
|
899
|
+
case IntervalDeltaOpType.DELETE:
|
|
900
|
+
this.removeIntervalById(op.value.properties?.intervalId);
|
|
901
|
+
return {
|
|
902
|
+
localSeq: this.getNextLocalSeq(),
|
|
903
|
+
};
|
|
904
|
+
case IntervalDeltaOpType.CHANGE: {
|
|
905
|
+
assert(op.value.properties !== undefined, 0x87c /* properties is undefined */);
|
|
906
|
+
({ intervalId, ...props } = op.value.properties);
|
|
907
|
+
interval = this.change(intervalId, {
|
|
908
|
+
start: op.value.start,
|
|
909
|
+
end: op.value.end,
|
|
910
|
+
props,
|
|
911
|
+
});
|
|
912
|
+
const metadata = {
|
|
913
|
+
localSeq: this.getNextLocalSeq(),
|
|
914
|
+
};
|
|
915
|
+
if (interval !== undefined) {
|
|
916
|
+
this.localSeqToSerializedInterval.set(metadata.localSeq, interval.serialize());
|
|
917
|
+
}
|
|
918
|
+
return metadata;
|
|
919
|
+
}
|
|
920
|
+
default:
|
|
921
|
+
unreachableCase(op.opName, `Unknown interval op type: ${op.opName}`);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
925
924
|
getSlideToSegment(lref) {
|
|
926
925
|
if (!this.client) {
|
|
927
|
-
throw new
|
|
926
|
+
throw new LoggingError("client does not exist");
|
|
928
927
|
}
|
|
929
928
|
const segoff = { segment: lref.getSegment(), offset: lref.getOffset() };
|
|
930
929
|
if (segoff.segment?.localRefs?.has(lref) !== true) {
|
|
931
930
|
return undefined;
|
|
932
931
|
}
|
|
933
|
-
const newSegoff =
|
|
932
|
+
const newSegoff = getSlideToSegoff(segoff, undefined, this.options.mergeTreeReferencesCanSlideToEndpoint);
|
|
934
933
|
const value = segoff.segment === newSegoff.segment && segoff.offset === newSegoff.offset
|
|
935
934
|
? undefined
|
|
936
935
|
: newSegoff;
|
|
@@ -938,11 +937,11 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
938
937
|
}
|
|
939
938
|
ackInterval(interval, op) {
|
|
940
939
|
// Only SequenceIntervals need potential sliding
|
|
941
|
-
if (!(interval instanceof
|
|
940
|
+
if (!(interval instanceof SequenceInterval)) {
|
|
942
941
|
return;
|
|
943
942
|
}
|
|
944
|
-
if (!
|
|
945
|
-
!
|
|
943
|
+
if (!refTypeIncludesFlag(interval.start, ReferenceType.StayOnRemove) &&
|
|
944
|
+
!refTypeIncludesFlag(interval.end, ReferenceType.StayOnRemove)) {
|
|
946
945
|
return;
|
|
947
946
|
}
|
|
948
947
|
const newStart = this.getSlideToSegment(interval.start);
|
|
@@ -960,7 +959,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
960
959
|
const needsEndUpdate = newEnd !== undefined && !hasPendingEndChange;
|
|
961
960
|
if (needsStartUpdate || needsEndUpdate) {
|
|
962
961
|
if (!this.localCollection) {
|
|
963
|
-
throw new
|
|
962
|
+
throw new LoggingError("Attach must be called before accessing intervals");
|
|
964
963
|
}
|
|
965
964
|
// `interval`'s endpoints will get modified in-place, so clone it prior to doing so for event emission.
|
|
966
965
|
const oldInterval = interval.clone();
|
|
@@ -969,32 +968,32 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
969
968
|
// This ensures that the correct listeners are added to the LocalReferencePosition.
|
|
970
969
|
this.localCollection.removeExistingInterval(interval);
|
|
971
970
|
if (!this.client) {
|
|
972
|
-
throw new
|
|
971
|
+
throw new LoggingError("client does not exist");
|
|
973
972
|
}
|
|
974
973
|
if (needsStartUpdate) {
|
|
975
974
|
const props = interval.start.properties;
|
|
976
|
-
interval.start =
|
|
977
|
-
|
|
975
|
+
interval.start = createPositionReferenceFromSegoff(this.client, newStart, interval.start.refType, op, undefined, undefined, startReferenceSlidingPreference(interval.stickiness), startReferenceSlidingPreference(interval.stickiness) ===
|
|
976
|
+
SlidingPreference.BACKWARD);
|
|
978
977
|
if (props) {
|
|
979
978
|
interval.start.addProperties(props);
|
|
980
979
|
}
|
|
981
980
|
const oldSeg = oldInterval.start.getSegment();
|
|
982
981
|
// remove and rebuild start interval as transient for event
|
|
983
982
|
this.client.removeLocalReferencePosition(oldInterval.start);
|
|
984
|
-
oldInterval.start.refType =
|
|
983
|
+
oldInterval.start.refType = ReferenceType.Transient;
|
|
985
984
|
oldSeg?.localRefs?.addLocalRef(oldInterval.start, oldInterval.start.getOffset());
|
|
986
985
|
}
|
|
987
986
|
if (needsEndUpdate) {
|
|
988
987
|
const props = interval.end.properties;
|
|
989
|
-
interval.end =
|
|
990
|
-
|
|
988
|
+
interval.end = createPositionReferenceFromSegoff(this.client, newEnd, interval.end.refType, op, undefined, undefined, endReferenceSlidingPreference(interval.stickiness), endReferenceSlidingPreference(interval.stickiness) ===
|
|
989
|
+
SlidingPreference.FORWARD);
|
|
991
990
|
if (props) {
|
|
992
991
|
interval.end.addProperties(props);
|
|
993
992
|
}
|
|
994
993
|
// remove and rebuild end interval as transient for event
|
|
995
994
|
const oldSeg = oldInterval.end.getSegment();
|
|
996
995
|
this.client.removeLocalReferencePosition(oldInterval.end);
|
|
997
|
-
oldInterval.end.refType =
|
|
996
|
+
oldInterval.end.refType = ReferenceType.Transient;
|
|
998
997
|
oldSeg?.localRefs?.addLocalRef(oldInterval.end, oldInterval.end.getOffset());
|
|
999
998
|
}
|
|
1000
999
|
this.localCollection.add(interval);
|
|
@@ -1004,7 +1003,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
1004
1003
|
/** @internal */
|
|
1005
1004
|
ackAdd(serializedInterval, local, op, localOpMetadata) {
|
|
1006
1005
|
if (local) {
|
|
1007
|
-
|
|
1006
|
+
assert(localOpMetadata !== undefined, 0x553 /* op metadata should be defined for local op */);
|
|
1008
1007
|
this.localSeqToSerializedInterval.delete(localOpMetadata.localSeq);
|
|
1009
1008
|
const id = serializedInterval.properties?.[reservedIntervalIdKey];
|
|
1010
1009
|
const localInterval = this.getIntervalById(id);
|
|
@@ -1014,7 +1013,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
1014
1013
|
return;
|
|
1015
1014
|
}
|
|
1016
1015
|
if (!this.localCollection) {
|
|
1017
|
-
throw new
|
|
1016
|
+
throw new LoggingError("attachSequence must be called");
|
|
1018
1017
|
}
|
|
1019
1018
|
this.localCollection.ensureSerializedId(serializedInterval);
|
|
1020
1019
|
const interval = this.localCollection.addInterval(toSequencePlace(serializedInterval.start, serializedInterval.startSide ?? Side.Before), toSequencePlace(serializedInterval.end, serializedInterval.endSide ?? Side.Before), serializedInterval.intervalType, serializedInterval.properties, op);
|
|
@@ -1035,7 +1034,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
1035
1034
|
return;
|
|
1036
1035
|
}
|
|
1037
1036
|
if (!this.localCollection) {
|
|
1038
|
-
throw new
|
|
1037
|
+
throw new LoggingError("attach must be called prior to deleting intervals");
|
|
1039
1038
|
}
|
|
1040
1039
|
const id = this.localCollection.ensureSerializedId(serializedInterval);
|
|
1041
1040
|
const interval = this.localCollection.idIntervalIndex.getIntervalById(id);
|
|
@@ -1048,7 +1047,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
1048
1047
|
*/
|
|
1049
1048
|
serializeInternal() {
|
|
1050
1049
|
if (!this.localCollection) {
|
|
1051
|
-
throw new
|
|
1050
|
+
throw new LoggingError("attachSequence must be called");
|
|
1052
1051
|
}
|
|
1053
1052
|
return this.localCollection.serialize();
|
|
1054
1053
|
}
|
|
@@ -1101,7 +1100,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
1101
1100
|
*/
|
|
1102
1101
|
findOverlappingIntervals(startPosition, endPosition) {
|
|
1103
1102
|
if (!this.localCollection) {
|
|
1104
|
-
throw new
|
|
1103
|
+
throw new LoggingError("attachSequence must be called");
|
|
1105
1104
|
}
|
|
1106
1105
|
return this.localCollection.overlappingIntervalsIndex.findOverlappingIntervals(startPosition, endPosition);
|
|
1107
1106
|
}
|
|
@@ -1110,7 +1109,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
1110
1109
|
*/
|
|
1111
1110
|
map(fn) {
|
|
1112
1111
|
if (!this.localCollection) {
|
|
1113
|
-
throw new
|
|
1112
|
+
throw new LoggingError("attachSequence must be called");
|
|
1114
1113
|
}
|
|
1115
1114
|
for (const interval of this.localCollection.idIntervalIndex) {
|
|
1116
1115
|
fn(interval);
|
|
@@ -1121,7 +1120,7 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
1121
1120
|
*/
|
|
1122
1121
|
previousInterval(pos) {
|
|
1123
1122
|
if (!this.localCollection) {
|
|
1124
|
-
throw new
|
|
1123
|
+
throw new LoggingError("attachSequence must be called");
|
|
1125
1124
|
}
|
|
1126
1125
|
return this.localCollection.endIntervalIndex.previousInterval(pos);
|
|
1127
1126
|
}
|
|
@@ -1130,16 +1129,15 @@ class IntervalCollection extends client_utils_1.TypedEventEmitter {
|
|
|
1130
1129
|
*/
|
|
1131
1130
|
nextInterval(pos) {
|
|
1132
1131
|
if (!this.localCollection) {
|
|
1133
|
-
throw new
|
|
1132
|
+
throw new LoggingError("attachSequence must be called");
|
|
1134
1133
|
}
|
|
1135
1134
|
return this.localCollection.endIntervalIndex.nextInterval(pos);
|
|
1136
1135
|
}
|
|
1137
1136
|
}
|
|
1138
|
-
exports.IntervalCollection = IntervalCollection;
|
|
1139
1137
|
function setSlideOnRemove(lref) {
|
|
1140
1138
|
let refType = lref.refType;
|
|
1141
|
-
refType = refType & ~
|
|
1142
|
-
refType = refType |
|
|
1139
|
+
refType = refType & ~ReferenceType.StayOnRemove;
|
|
1140
|
+
refType = refType | ReferenceType.SlideOnRemove;
|
|
1143
1141
|
lref.refType = refType;
|
|
1144
1142
|
}
|
|
1145
1143
|
/**
|
|
@@ -1149,11 +1147,10 @@ function setSlideOnRemove(lref) {
|
|
|
1149
1147
|
* endpoint is a part of.
|
|
1150
1148
|
* @internal
|
|
1151
1149
|
*/
|
|
1152
|
-
function intervalLocatorFromEndpoint(potentialEndpoint) {
|
|
1153
|
-
const { interval, [
|
|
1150
|
+
export function intervalLocatorFromEndpoint(potentialEndpoint) {
|
|
1151
|
+
const { interval, [reservedRangeLabelsKey]: collectionNameArray } = potentialEndpoint.properties ?? {};
|
|
1154
1152
|
return interval && collectionNameArray?.length === 1
|
|
1155
1153
|
? { label: collectionNameArray[0], interval }
|
|
1156
1154
|
: undefined;
|
|
1157
1155
|
}
|
|
1158
|
-
|
|
1159
|
-
//# sourceMappingURL=intervalCollection.js.map
|
|
1156
|
+
//# sourceMappingURL=intervalCollection.mjs.map
|