@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,81 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SharedSegmentSequence = void 0;
|
|
4
2
|
/*!
|
|
5
3
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
6
4
|
* Licensed under the MIT License.
|
|
7
5
|
*/
|
|
8
|
-
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.resetReentrancyLogCounter = exports.SharedSegmentSequence = void 0;
|
|
8
|
+
const core_utils_1 = require("@fluidframework/core-utils");
|
|
9
|
+
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
10
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
10
11
|
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
11
12
|
const merge_tree_1 = require("@fluidframework/merge-tree");
|
|
12
13
|
const runtime_utils_1 = require("@fluidframework/runtime-utils");
|
|
13
14
|
const shared_object_base_1 = require("@fluidframework/shared-object-base");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const sequenceDeltaEvent_1 = require("./sequenceDeltaEvent");
|
|
15
|
+
const defaultMap_1 = require("./defaultMap.cjs");
|
|
16
|
+
const intervalCollection_1 = require("./intervalCollection.cjs");
|
|
17
|
+
const sequenceDeltaEvent_1 = require("./sequenceDeltaEvent.cjs");
|
|
17
18
|
const snapshotFileName = "header";
|
|
18
19
|
const contentPath = "content";
|
|
20
|
+
/**
|
|
21
|
+
* @alpha
|
|
22
|
+
*/
|
|
19
23
|
class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
20
|
-
constructor(dataStoreRuntime, id, attributes, segmentFromSpec) {
|
|
21
|
-
super(id, dataStoreRuntime, attributes, "fluid_sequence_");
|
|
22
|
-
this.dataStoreRuntime = dataStoreRuntime;
|
|
23
|
-
this.id = id;
|
|
24
|
-
this.segmentFromSpec = segmentFromSpec;
|
|
25
|
-
// Deferred that triggers once the object is loaded
|
|
26
|
-
this.loadedDeferred = new common_utils_1.Deferred();
|
|
27
|
-
// cache out going ops created when partial loading
|
|
28
|
-
this.loadedDeferredOutgoingOps = [];
|
|
29
|
-
// cache incoming ops that arrive when partial loading
|
|
30
|
-
this.deferIncomingOps = true;
|
|
31
|
-
this.loadedDeferredIncomingOps = [];
|
|
32
|
-
this.messagesSinceMSNChange = [];
|
|
33
|
-
this.loadedDeferred.promise.catch((error) => {
|
|
34
|
-
this.logger.sendErrorEvent({ eventName: "SequenceLoadFailed" }, error);
|
|
35
|
-
});
|
|
36
|
-
this.client = new merge_tree_1.Client(segmentFromSpec, telemetry_utils_1.ChildLogger.create(this.logger, "SharedSegmentSequence.MergeTreeClient"), dataStoreRuntime.options);
|
|
37
|
-
super.on("newListener", (event) => {
|
|
38
|
-
switch (event) {
|
|
39
|
-
case "sequenceDelta":
|
|
40
|
-
if (!this.client.mergeTreeDeltaCallback) {
|
|
41
|
-
this.client.mergeTreeDeltaCallback = (opArgs, deltaArgs) => {
|
|
42
|
-
this.emit("sequenceDelta", new sequenceDeltaEvent_1.SequenceDeltaEvent(opArgs, deltaArgs, this.client), this);
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
break;
|
|
46
|
-
case "maintenance":
|
|
47
|
-
if (!this.client.mergeTreeMaintenanceCallback) {
|
|
48
|
-
this.client.mergeTreeMaintenanceCallback = (args, opArgs) => {
|
|
49
|
-
this.emit("maintenance", new sequenceDeltaEvent_1.SequenceMaintenanceEvent(opArgs, args, this.client), this);
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
break;
|
|
53
|
-
default:
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
super.on("removeListener", (event) => {
|
|
57
|
-
switch (event) {
|
|
58
|
-
case "sequenceDelta":
|
|
59
|
-
if (super.listenerCount(event) === 0) {
|
|
60
|
-
this.client.mergeTreeDeltaCallback = undefined;
|
|
61
|
-
}
|
|
62
|
-
break;
|
|
63
|
-
case "maintenance":
|
|
64
|
-
if (super.listenerCount(event) === 0) {
|
|
65
|
-
this.client.mergeTreeMaintenanceCallback = undefined;
|
|
66
|
-
}
|
|
67
|
-
break;
|
|
68
|
-
default:
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
this.intervalCollections = new defaultMap_1.DefaultMap(this.serializer, this.handle, (op, localOpMetadata) => this.submitLocalMessage(op, localOpMetadata), new intervalCollection_1.SequenceIntervalCollectionValueType());
|
|
73
|
-
}
|
|
74
24
|
get loaded() {
|
|
75
25
|
return this.loadedDeferred.promise;
|
|
76
26
|
}
|
|
77
27
|
static createOpsFromDelta(event) {
|
|
78
|
-
var _a, _b;
|
|
79
28
|
const ops = [];
|
|
80
29
|
for (const r of event.ranges) {
|
|
81
30
|
switch (event.deltaOperation) {
|
|
@@ -83,14 +32,15 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
83
32
|
const lastAnnotate = ops[ops.length - 1];
|
|
84
33
|
const props = {};
|
|
85
34
|
for (const key of Object.keys(r.propertyDeltas)) {
|
|
86
|
-
props[key] =
|
|
35
|
+
props[key] = r.segment.properties?.[key] ?? null;
|
|
87
36
|
}
|
|
88
|
-
if (lastAnnotate &&
|
|
37
|
+
if (lastAnnotate &&
|
|
38
|
+
lastAnnotate.pos2 === r.position &&
|
|
89
39
|
(0, merge_tree_1.matchProperties)(lastAnnotate.props, props)) {
|
|
90
40
|
lastAnnotate.pos2 += r.segment.cachedLength;
|
|
91
41
|
}
|
|
92
42
|
else {
|
|
93
|
-
ops.push((0, merge_tree_1.createAnnotateRangeOp)(r.position, r.position + r.segment.cachedLength, props
|
|
43
|
+
ops.push((0, merge_tree_1.createAnnotateRangeOp)(r.position, r.position + r.segment.cachedLength, props));
|
|
94
44
|
}
|
|
95
45
|
break;
|
|
96
46
|
}
|
|
@@ -99,7 +49,8 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
99
49
|
break;
|
|
100
50
|
case merge_tree_1.MergeTreeDeltaType.REMOVE: {
|
|
101
51
|
const lastRem = ops[ops.length - 1];
|
|
102
|
-
if (
|
|
52
|
+
if (lastRem?.pos1 === r.position) {
|
|
53
|
+
(0, core_utils_1.assert)(lastRem.pos2 !== undefined, 0x3ff /* pos2 should not be undefined here */);
|
|
103
54
|
lastRem.pos2 += r.segment.cachedLength;
|
|
104
55
|
}
|
|
105
56
|
else {
|
|
@@ -107,26 +58,94 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
107
58
|
}
|
|
108
59
|
break;
|
|
109
60
|
}
|
|
61
|
+
case merge_tree_1.MergeTreeDeltaType.OBLITERATE: {
|
|
62
|
+
const lastRem = ops[ops.length - 1];
|
|
63
|
+
if (lastRem?.pos1 === r.position) {
|
|
64
|
+
(0, core_utils_1.assert)(lastRem.pos2 !== undefined, 0x874 /* pos2 should not be undefined here */);
|
|
65
|
+
lastRem.pos2 += r.segment.cachedLength;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
ops.push((0, merge_tree_1.createObliterateRangeOp)(r.position, r.position + r.segment.cachedLength));
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
110
72
|
default:
|
|
111
73
|
}
|
|
112
74
|
}
|
|
113
75
|
return ops;
|
|
114
76
|
}
|
|
77
|
+
constructor(dataStoreRuntime, id, attributes, segmentFromSpec) {
|
|
78
|
+
super(id, dataStoreRuntime, attributes, "fluid_sequence_");
|
|
79
|
+
this.dataStoreRuntime = dataStoreRuntime;
|
|
80
|
+
this.id = id;
|
|
81
|
+
this.segmentFromSpec = segmentFromSpec;
|
|
82
|
+
/** `Deferred` that triggers once the object is loaded */
|
|
83
|
+
this.loadedDeferred = new core_utils_1.Deferred();
|
|
84
|
+
// cache out going ops created when partial loading
|
|
85
|
+
this.loadedDeferredOutgoingOps = [];
|
|
86
|
+
// cache incoming ops that arrive when partial loading
|
|
87
|
+
this.deferIncomingOps = true;
|
|
88
|
+
this.loadedDeferredIncomingOps = [];
|
|
89
|
+
this.messagesSinceMSNChange = [];
|
|
90
|
+
this.guardReentrancy =
|
|
91
|
+
dataStoreRuntime.options.sharedStringPreventReentrancy ?? true
|
|
92
|
+
? ensureNoReentrancy
|
|
93
|
+
: createReentrancyDetector((depth) => {
|
|
94
|
+
if (totalReentrancyLogs > 0) {
|
|
95
|
+
totalReentrancyLogs--;
|
|
96
|
+
this.logger.sendTelemetryEvent({ eventName: "LocalOpReentry", depth }, new telemetry_utils_1.LoggingError(reentrancyErrorMessage));
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
this.loadedDeferred.promise.catch((error) => {
|
|
100
|
+
this.logger.sendErrorEvent({ eventName: "SequenceLoadFailed" }, error);
|
|
101
|
+
});
|
|
102
|
+
// eslint-disable-next-line import/no-deprecated
|
|
103
|
+
this.client = new merge_tree_1.Client(segmentFromSpec, (0, telemetry_utils_1.createChildLogger)({
|
|
104
|
+
logger: this.logger,
|
|
105
|
+
namespace: "SharedSegmentSequence.MergeTreeClient",
|
|
106
|
+
}), dataStoreRuntime.options);
|
|
107
|
+
this.client.prependListener("delta", (opArgs, deltaArgs) => {
|
|
108
|
+
const event = new sequenceDeltaEvent_1.SequenceDeltaEvent(opArgs, deltaArgs, this.client);
|
|
109
|
+
if (opArgs.stashed !== true && event.isLocal) {
|
|
110
|
+
this.submitSequenceMessage(opArgs.op);
|
|
111
|
+
}
|
|
112
|
+
this.emit("sequenceDelta", event, this);
|
|
113
|
+
});
|
|
114
|
+
this.client.on("maintenance", (args, opArgs) => {
|
|
115
|
+
this.emit("maintenance", new sequenceDeltaEvent_1.SequenceMaintenanceEvent(opArgs, args, this.client), this);
|
|
116
|
+
});
|
|
117
|
+
this.intervalCollections = new defaultMap_1.DefaultMap(this.serializer, this.handle, (op, localOpMetadata) => this.submitLocalMessage(op, localOpMetadata), new intervalCollection_1.SequenceIntervalCollectionValueType(), dataStoreRuntime.options);
|
|
118
|
+
}
|
|
115
119
|
/**
|
|
116
120
|
* @param start - The inclusive start of the range to remove
|
|
117
121
|
* @param end - The exclusive end of the range to remove
|
|
118
122
|
*/
|
|
119
123
|
removeRange(start, end) {
|
|
120
|
-
|
|
121
|
-
if (removeOp) {
|
|
122
|
-
this.submitSequenceMessage(removeOp);
|
|
123
|
-
}
|
|
124
|
-
return removeOp;
|
|
124
|
+
this.guardReentrancy(() => this.client.removeRangeLocal(start, end));
|
|
125
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Obliterate is similar to remove, but differs in that segments concurrently
|
|
128
|
+
* inserted into an obliterated range will also be removed
|
|
129
|
+
*
|
|
130
|
+
* @param start - The inclusive start of the range to obliterate
|
|
131
|
+
* @param end - The exclusive end of the range to obliterate
|
|
132
|
+
*/
|
|
133
|
+
obliterateRange(start, end) {
|
|
134
|
+
this.guardReentrancy(() => this.client.obliterateRangeLocal(start, end));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* @deprecated The ability to create group ops will be removed in an upcoming
|
|
138
|
+
* release, as group ops are redundant with the native batching capabilities
|
|
139
|
+
* of the runtime
|
|
140
|
+
*/
|
|
126
141
|
groupOperation(groupOp) {
|
|
127
|
-
this.client.localTransaction(groupOp);
|
|
128
|
-
this.submitSequenceMessage(groupOp);
|
|
142
|
+
this.guardReentrancy(() => this.client.localTransaction(groupOp));
|
|
129
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Finds the segment information (i.e. segment + offset) corresponding to a character position in the SharedString.
|
|
146
|
+
* If the position is past the end of the string, `segment` and `offset` on the returned object may be undefined.
|
|
147
|
+
* @param pos - Character position (index) into the current local view of the SharedString.
|
|
148
|
+
*/
|
|
130
149
|
getContainingSegment(pos) {
|
|
131
150
|
return this.client.getContainingSegment(pos);
|
|
132
151
|
}
|
|
@@ -150,14 +169,10 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
150
169
|
* @param start - The inclusive start position of the range to annotate
|
|
151
170
|
* @param end - The exclusive end position of the range to annotate
|
|
152
171
|
* @param props - The properties to annotate the range with
|
|
153
|
-
* @param combiningOp - Optional. Specifies how to combine values for the property, such as "incr" for increment.
|
|
154
172
|
*
|
|
155
173
|
*/
|
|
156
|
-
annotateRange(start, end, props
|
|
157
|
-
|
|
158
|
-
if (annotateOp) {
|
|
159
|
-
this.submitSequenceMessage(annotateOp);
|
|
160
|
-
}
|
|
174
|
+
annotateRange(start, end, props) {
|
|
175
|
+
this.guardReentrancy(() => this.client.annotateRangeLocal(start, end, props));
|
|
161
176
|
}
|
|
162
177
|
getPropertiesAtPosition(pos) {
|
|
163
178
|
return this.client.getPropertiesAtPosition(pos);
|
|
@@ -166,27 +181,28 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
166
181
|
return this.client.getRangeExtentsOfPosition(pos);
|
|
167
182
|
}
|
|
168
183
|
/**
|
|
169
|
-
*
|
|
184
|
+
* Creates a `LocalReferencePosition` on this SharedString. If the refType does not include
|
|
185
|
+
* ReferenceType.Transient, the returned reference will be added to the localRefs on the provided segment.
|
|
186
|
+
* @param segment - Segment to add the local reference on
|
|
187
|
+
* @param offset - Offset on the segment at which to place the local reference
|
|
188
|
+
* @param refType - ReferenceType for the created local reference
|
|
189
|
+
* @param properties - PropertySet to place on the created local reference
|
|
170
190
|
*/
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (refType !== merge_tree_1.ReferenceType.Transient) {
|
|
174
|
-
this.addLocalReference(lref);
|
|
175
|
-
}
|
|
176
|
-
return lref;
|
|
177
|
-
}
|
|
178
|
-
createLocalReferencePosition(segment, offset, refType, properties) {
|
|
179
|
-
return this.client.createLocalReferencePosition(segment, offset, refType, properties);
|
|
191
|
+
createLocalReferencePosition(segment, offset, refType, properties, slidingPreference, canSlideToEndpoint) {
|
|
192
|
+
return this.client.createLocalReferencePosition(segment, offset, refType, properties, slidingPreference, canSlideToEndpoint);
|
|
180
193
|
}
|
|
181
194
|
/**
|
|
182
|
-
*
|
|
195
|
+
* Resolves a `ReferencePosition` into a character position using this client's perspective.
|
|
183
196
|
*/
|
|
184
|
-
localRefToPos(localRef) {
|
|
185
|
-
return this.client.localReferencePositionToPosition(localRef);
|
|
186
|
-
}
|
|
187
197
|
localReferencePositionToPosition(lref) {
|
|
188
198
|
return this.client.localReferencePositionToPosition(lref);
|
|
189
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Removes a `LocalReferencePosition` from this SharedString.
|
|
202
|
+
*/
|
|
203
|
+
removeLocalReferencePosition(lref) {
|
|
204
|
+
return this.client.removeLocalReferencePosition(lref);
|
|
205
|
+
}
|
|
190
206
|
/**
|
|
191
207
|
* Resolves a remote client's position against the local sequence
|
|
192
208
|
* and returns the remote client's position relative to the local
|
|
@@ -212,29 +228,14 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
212
228
|
const metadata = this.client.peekPendingSegmentGroups(message.type === merge_tree_1.MergeTreeDeltaType.GROUP ? message.ops.length : 1);
|
|
213
229
|
// if loading isn't complete, we need to cache
|
|
214
230
|
// local ops until loading is complete, and then
|
|
215
|
-
// they will be
|
|
231
|
+
// they will be present
|
|
216
232
|
if (!this.loadedDeferred.isCompleted) {
|
|
217
|
-
this.loadedDeferredOutgoingOps.push([translated, metadata]);
|
|
233
|
+
this.loadedDeferredOutgoingOps.push(metadata ? [translated, metadata] : translated);
|
|
218
234
|
}
|
|
219
235
|
else {
|
|
220
236
|
this.submitLocalMessage(translated, metadata);
|
|
221
237
|
}
|
|
222
238
|
}
|
|
223
|
-
/**
|
|
224
|
-
* @deprecated - use createLocalReferencePosition
|
|
225
|
-
*/
|
|
226
|
-
addLocalReference(lref) {
|
|
227
|
-
return this.client.addLocalReference(lref);
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* @deprecated - use removeLocalReferencePosition
|
|
231
|
-
*/
|
|
232
|
-
removeLocalReference(lref) {
|
|
233
|
-
return this.client.removeLocalReferencePosition(lref);
|
|
234
|
-
}
|
|
235
|
-
removeLocalReferencePosition(lref) {
|
|
236
|
-
return this.client.removeLocalReferencePosition(lref);
|
|
237
|
-
}
|
|
238
239
|
/**
|
|
239
240
|
* Given a position specified relative to a marker id, lookup the marker
|
|
240
241
|
* and convert the position to a character position.
|
|
@@ -245,53 +246,70 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
245
246
|
}
|
|
246
247
|
/**
|
|
247
248
|
* Walk the underlying segments of the sequence.
|
|
248
|
-
* The walked segments may extend beyond the range
|
|
249
|
-
*
|
|
250
|
-
* Set split range to true to ensure only segments within the
|
|
251
|
-
* range are walked.
|
|
249
|
+
* The walked segments may extend beyond the range if the segments cross the
|
|
250
|
+
* ranges start or end boundaries.
|
|
252
251
|
*
|
|
253
|
-
*
|
|
252
|
+
* Set split range to true to ensure only segments within the range are walked.
|
|
253
|
+
*
|
|
254
|
+
* @param handler - The function to handle each segment. Traversal ends if
|
|
255
|
+
* this function returns true.
|
|
254
256
|
* @param start - Optional. The start of range walk.
|
|
255
257
|
* @param end - Optional. The end of range walk
|
|
256
258
|
* @param accum - Optional. An object that will be passed to the handler for accumulation
|
|
257
259
|
* @param splitRange - Optional. Splits boundary segments on the range boundaries
|
|
258
260
|
*/
|
|
259
261
|
walkSegments(handler, start, end, accum, splitRange = false) {
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
getStackContext(startPos, rangeLabels) {
|
|
263
|
-
return this.client.getStackContext(startPos, rangeLabels);
|
|
262
|
+
this.client.walkSegments(handler, start, end, accum, splitRange);
|
|
264
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* @returns The most recent sequence number which has been acked by the server and processed by this
|
|
266
|
+
* SharedSegmentSequence.
|
|
267
|
+
*/
|
|
265
268
|
getCurrentSeq() {
|
|
266
269
|
return this.client.getCurrentSeq();
|
|
267
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Inserts a segment directly before a `ReferencePosition`.
|
|
273
|
+
* @param refPos - The reference position to insert the segment at
|
|
274
|
+
* @param segment - The segment to insert
|
|
275
|
+
*/
|
|
268
276
|
insertAtReferencePosition(pos, segment) {
|
|
269
|
-
|
|
270
|
-
if (insertOp) {
|
|
271
|
-
this.submitSequenceMessage(insertOp);
|
|
272
|
-
}
|
|
277
|
+
this.guardReentrancy(() => this.client.insertAtReferencePositionLocal(pos, segment));
|
|
273
278
|
}
|
|
274
279
|
/**
|
|
275
|
-
*
|
|
276
|
-
*
|
|
280
|
+
* Inserts a segment
|
|
281
|
+
* @param start - The position to insert the segment at
|
|
282
|
+
* @param spec - The segment to inserts spec
|
|
277
283
|
*/
|
|
278
|
-
|
|
279
|
-
|
|
284
|
+
insertFromSpec(pos, spec) {
|
|
285
|
+
const segment = this.segmentFromSpec(spec);
|
|
286
|
+
this.guardReentrancy(() => this.client.insertSegmentLocal(pos, segment));
|
|
280
287
|
}
|
|
288
|
+
/**
|
|
289
|
+
* Retrieves the interval collection keyed on `label`. If no such interval collection exists,
|
|
290
|
+
* creates one.
|
|
291
|
+
*/
|
|
281
292
|
getIntervalCollection(label) {
|
|
282
293
|
return this.intervalCollections.get(label);
|
|
283
294
|
}
|
|
284
295
|
/**
|
|
285
|
-
* @returns
|
|
286
|
-
*
|
|
296
|
+
* @returns An iterable object that enumerates the IntervalCollection labels.
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
*
|
|
300
|
+
* ```typescript
|
|
287
301
|
* const iter = this.getIntervalCollectionKeys();
|
|
288
302
|
* for (key of iter)
|
|
289
303
|
* const collection = this.getIntervalCollection(key);
|
|
290
304
|
* ...
|
|
291
|
-
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
292
307
|
getIntervalCollectionLabels() {
|
|
293
308
|
return this.intervalCollections.keys();
|
|
294
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}
|
|
312
|
+
*/
|
|
295
313
|
summarizeCore(serializer, telemetryContext) {
|
|
296
314
|
const builder = new runtime_utils_1.SummaryTreeBuilder();
|
|
297
315
|
// conditionally write the interval collection blob
|
|
@@ -328,19 +346,24 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
328
346
|
const insert = this.client.insertSegmentLocal(insertIndex, segment);
|
|
329
347
|
if (insert) {
|
|
330
348
|
if (start < end) {
|
|
331
|
-
|
|
332
|
-
this.submitSequenceMessage((0, merge_tree_1.createGroupOp)(insert, remove));
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
this.submitSequenceMessage(insert);
|
|
349
|
+
this.client.removeRangeLocal(start, end);
|
|
336
350
|
}
|
|
337
351
|
}
|
|
338
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.onConnect}
|
|
355
|
+
*/
|
|
339
356
|
onConnect() {
|
|
340
357
|
// Update merge tree collaboration information with new client ID and then resend pending ops
|
|
341
358
|
this.client.startOrUpdateCollaboration(this.runtime.clientId);
|
|
342
359
|
}
|
|
360
|
+
/**
|
|
361
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}
|
|
362
|
+
*/
|
|
343
363
|
onDisconnect() { }
|
|
364
|
+
/**
|
|
365
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}
|
|
366
|
+
*/
|
|
344
367
|
reSubmitCore(content, localOpMetadata) {
|
|
345
368
|
if (!this.intervalCollections.tryResubmitMessage(content, localOpMetadata)) {
|
|
346
369
|
this.submitSequenceMessage(this.client.regeneratePendingOp(content, localOpMetadata));
|
|
@@ -350,10 +373,9 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
350
373
|
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}
|
|
351
374
|
*/
|
|
352
375
|
async loadCore(storage) {
|
|
353
|
-
var _a;
|
|
354
376
|
if (await storage.contains(snapshotFileName)) {
|
|
355
377
|
const blob = await storage.readBlob(snapshotFileName);
|
|
356
|
-
const header = (0,
|
|
378
|
+
const header = (0, client_utils_1.bufferToString)(blob, "utf8");
|
|
357
379
|
this.intervalCollections.populate(header);
|
|
358
380
|
}
|
|
359
381
|
try {
|
|
@@ -367,10 +389,11 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
367
389
|
.then((msgs) => {
|
|
368
390
|
msgs.forEach((m) => {
|
|
369
391
|
const collabWindow = this.client.getCollabWindow();
|
|
370
|
-
if (m.minimumSequenceNumber < collabWindow.minSeq
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
392
|
+
if (m.minimumSequenceNumber < collabWindow.minSeq ||
|
|
393
|
+
m.referenceSequenceNumber < collabWindow.minSeq ||
|
|
394
|
+
m.sequenceNumber <= collabWindow.minSeq ||
|
|
395
|
+
// sequenceNumber could be the same if messages are part of a grouped batch
|
|
396
|
+
m.sequenceNumber < collabWindow.currentSeq) {
|
|
374
397
|
throw new Error(`Invalid catchup operations in snapshot: ${JSON.stringify({
|
|
375
398
|
op: {
|
|
376
399
|
seq: m.sequenceNumber,
|
|
@@ -390,7 +413,7 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
390
413
|
.catch((error) => {
|
|
391
414
|
this.loadFinished(error);
|
|
392
415
|
});
|
|
393
|
-
if (
|
|
416
|
+
if (this.dataStoreRuntime.options?.sequenceInitializeFromHeaderOnly !== true) {
|
|
394
417
|
// if we not doing partial load, await the catch up ops,
|
|
395
418
|
// and the finalization of the load
|
|
396
419
|
await loadCatchUpOps;
|
|
@@ -400,29 +423,37 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
400
423
|
this.loadFinished(error);
|
|
401
424
|
}
|
|
402
425
|
}
|
|
426
|
+
/**
|
|
427
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}
|
|
428
|
+
*/
|
|
403
429
|
processCore(message, local, localOpMetadata) {
|
|
404
430
|
// if loading isn't complete, we need to cache all
|
|
405
431
|
// incoming ops to be applied after loading is complete
|
|
406
432
|
if (this.deferIncomingOps) {
|
|
407
|
-
(0,
|
|
433
|
+
(0, core_utils_1.assert)(!local, 0x072 /* "Unexpected local op when loading not finished" */);
|
|
408
434
|
this.loadedDeferredIncomingOps.push(message);
|
|
409
435
|
}
|
|
410
436
|
else {
|
|
411
|
-
(0,
|
|
437
|
+
(0, core_utils_1.assert)(message.type === protocol_definitions_1.MessageType.Operation, 0x073 /* "Sequence message not operation" */);
|
|
412
438
|
const handled = this.intervalCollections.tryProcessMessage(message.contents, local, message, localOpMetadata);
|
|
413
439
|
if (!handled) {
|
|
414
440
|
this.processMergeTreeMsg(message, local);
|
|
415
441
|
}
|
|
416
442
|
}
|
|
417
443
|
}
|
|
444
|
+
/**
|
|
445
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.didAttach}
|
|
446
|
+
*/
|
|
418
447
|
didAttach() {
|
|
419
|
-
var _a;
|
|
420
448
|
// If we are not local, and we've attached we need to start generating and sending ops
|
|
421
449
|
// so start collaboration and provide a default client id incase we are not connected
|
|
422
450
|
if (this.isAttached()) {
|
|
423
|
-
this.client.startOrUpdateCollaboration(
|
|
451
|
+
this.client.startOrUpdateCollaboration(this.runtime.clientId ?? "attached");
|
|
424
452
|
}
|
|
425
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.initializeLocalCore}
|
|
456
|
+
*/
|
|
426
457
|
initializeLocalCore() {
|
|
427
458
|
super.initializeLocalCore();
|
|
428
459
|
this.loadFinished();
|
|
@@ -431,18 +462,19 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
431
462
|
* {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
|
|
432
463
|
*/
|
|
433
464
|
applyStashedOp(content) {
|
|
434
|
-
return this.client.applyStashedOp(content);
|
|
465
|
+
return this.client.applyStashedOp((0, shared_object_base_1.parseHandles)(content, this.serializer));
|
|
435
466
|
}
|
|
436
467
|
summarizeMergeTree(serializer) {
|
|
437
468
|
// Are we fully loaded? If not, things will go south
|
|
438
|
-
(0,
|
|
469
|
+
(0, core_utils_1.assert)(this.loadedDeferred.isCompleted, 0x074 /* "Snapshot called when not fully loaded" */);
|
|
439
470
|
const minSeq = this.runtime.deltaManager.minimumSequenceNumber;
|
|
440
471
|
this.processMinSequenceNumberChanged(minSeq);
|
|
441
|
-
this.messagesSinceMSNChange.forEach((m) => {
|
|
472
|
+
this.messagesSinceMSNChange.forEach((m) => {
|
|
473
|
+
m.minimumSequenceNumber = minSeq;
|
|
474
|
+
});
|
|
442
475
|
return this.client.summarize(this.runtime, this.handle, serializer, this.messagesSinceMSNChange);
|
|
443
476
|
}
|
|
444
477
|
processMergeTreeMsg(rawMessage, local) {
|
|
445
|
-
var _a, _b;
|
|
446
478
|
const message = (0, shared_object_base_1.parseHandles)(rawMessage, this.serializer);
|
|
447
479
|
const ops = [];
|
|
448
480
|
function transformOps(event) {
|
|
@@ -450,23 +482,28 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
450
482
|
}
|
|
451
483
|
const needsTransformation = message.referenceSequenceNumber !== message.sequenceNumber - 1;
|
|
452
484
|
let stashMessage = message;
|
|
453
|
-
if (
|
|
485
|
+
if (this.runtime.options?.newMergeTreeSnapshotFormat !== true) {
|
|
454
486
|
if (needsTransformation) {
|
|
455
487
|
this.on("sequenceDelta", transformOps);
|
|
456
488
|
}
|
|
457
489
|
}
|
|
458
490
|
this.client.applyMsg(message, local);
|
|
459
|
-
if (
|
|
491
|
+
if (this.runtime.options?.newMergeTreeSnapshotFormat !== true) {
|
|
460
492
|
if (needsTransformation) {
|
|
461
493
|
this.removeListener("sequenceDelta", transformOps);
|
|
462
494
|
// shallow clone the message as we only overwrite top level properties,
|
|
463
495
|
// like referenceSequenceNumber and content only
|
|
464
|
-
stashMessage =
|
|
496
|
+
stashMessage = {
|
|
497
|
+
...message,
|
|
498
|
+
referenceSequenceNumber: stashMessage.sequenceNumber - 1,
|
|
499
|
+
// eslint-disable-next-line import/no-deprecated
|
|
500
|
+
contents: ops.length !== 1 ? (0, merge_tree_1.createGroupOp)(...ops) : ops[0],
|
|
501
|
+
};
|
|
465
502
|
}
|
|
466
503
|
this.messagesSinceMSNChange.push(stashMessage);
|
|
467
504
|
// Do GC every once in a while...
|
|
468
|
-
if (this.messagesSinceMSNChange.length > 20
|
|
469
|
-
|
|
505
|
+
if (this.messagesSinceMSNChange.length > 20 &&
|
|
506
|
+
this.messagesSinceMSNChange[20].sequenceNumber < message.minimumSequenceNumber) {
|
|
470
507
|
this.processMinSequenceNumberChanged(message.minimumSequenceNumber);
|
|
471
508
|
}
|
|
472
509
|
}
|
|
@@ -516,7 +553,7 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
516
553
|
if (!intervalCollection.attached) {
|
|
517
554
|
intervalCollection.attachGraph(this.client, key);
|
|
518
555
|
}
|
|
519
|
-
(0,
|
|
556
|
+
(0, core_utils_1.assert)(previousValue === undefined, 0x2c1 /* "Creating an interval collection that already exists?" */);
|
|
520
557
|
this.emit("createIntervalCollection", key, local, this);
|
|
521
558
|
});
|
|
522
559
|
// Initialize existing SharedIntervalCollections
|
|
@@ -527,4 +564,37 @@ class SharedSegmentSequence extends shared_object_base_1.SharedObject {
|
|
|
527
564
|
}
|
|
528
565
|
}
|
|
529
566
|
exports.SharedSegmentSequence = SharedSegmentSequence;
|
|
530
|
-
|
|
567
|
+
function createReentrancyDetector(onReentrancy) {
|
|
568
|
+
let depth = 0;
|
|
569
|
+
function detectReentrancy(callback) {
|
|
570
|
+
if (depth > 0) {
|
|
571
|
+
onReentrancy(depth);
|
|
572
|
+
}
|
|
573
|
+
depth++;
|
|
574
|
+
try {
|
|
575
|
+
return callback();
|
|
576
|
+
}
|
|
577
|
+
finally {
|
|
578
|
+
depth--;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
return detectReentrancy;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Apps which generate reentrant behavior may do so at a high frequency.
|
|
585
|
+
* Logging even per-SharedSegmentSequence instance might be too noisy, and having a few logs from a session
|
|
586
|
+
* is likely enough.
|
|
587
|
+
*/
|
|
588
|
+
let totalReentrancyLogs = 3;
|
|
589
|
+
/**
|
|
590
|
+
* Resets the reentrancy log counter. Test-only API.
|
|
591
|
+
*/
|
|
592
|
+
function resetReentrancyLogCounter() {
|
|
593
|
+
totalReentrancyLogs = 3;
|
|
594
|
+
}
|
|
595
|
+
exports.resetReentrancyLogCounter = resetReentrancyLogCounter;
|
|
596
|
+
const reentrancyErrorMessage = "Reentrancy detected in sequence local ops";
|
|
597
|
+
const ensureNoReentrancy = createReentrancyDetector(() => {
|
|
598
|
+
throw new telemetry_utils_1.LoggingError(reentrancyErrorMessage);
|
|
599
|
+
});
|
|
600
|
+
//# sourceMappingURL=sequence.cjs.map
|