@fluidframework/sequence 2.30.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +506 -495
- package/api-report/sequence.legacy.alpha.api.md +67 -5
- package/dist/IntervalCollectionValues.d.ts +3 -51
- package/dist/IntervalCollectionValues.d.ts.map +1 -1
- package/dist/IntervalCollectionValues.js +6 -49
- package/dist/IntervalCollectionValues.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -8
- package/dist/index.js.map +1 -1
- package/dist/intervalCollection.d.ts +292 -63
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +111 -193
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervalCollectionMap.d.ts +11 -32
- package/dist/intervalCollectionMap.d.ts.map +1 -1
- package/dist/intervalCollectionMap.js +37 -90
- package/dist/intervalCollectionMap.js.map +1 -1
- package/dist/intervalCollectionMapInterfaces.d.ts +10 -83
- package/dist/intervalCollectionMapInterfaces.d.ts.map +1 -1
- package/dist/intervalCollectionMapInterfaces.js.map +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.d.ts +10 -11
- package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
- package/dist/intervalIndex/endpointInRangeIndex.js +4 -5
- package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
- package/dist/intervalIndex/endpointIndex.d.ts +12 -13
- package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
- package/dist/intervalIndex/endpointIndex.js +4 -5
- package/dist/intervalIndex/endpointIndex.js.map +1 -1
- package/dist/intervalIndex/idIntervalIndex.d.ts +6 -12
- package/dist/intervalIndex/idIntervalIndex.d.ts.map +1 -1
- package/dist/intervalIndex/idIntervalIndex.js +0 -3
- package/dist/intervalIndex/idIntervalIndex.js.map +1 -1
- package/dist/intervalIndex/index.d.ts +2 -2
- package/dist/intervalIndex/index.d.ts.map +1 -1
- package/dist/intervalIndex/index.js.map +1 -1
- package/dist/intervalIndex/intervalIndex.d.ts +28 -1
- package/dist/intervalIndex/intervalIndex.d.ts.map +1 -1
- package/dist/intervalIndex/intervalIndex.js.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +30 -13
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.js +4 -5
- package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -1
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js +1 -1
- package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -1
- package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +2 -2
- package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -1
- package/dist/intervalIndex/sequenceIntervalIndexes.js.map +1 -1
- package/dist/intervalIndex/startpointInRangeIndex.d.ts +10 -11
- package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
- package/dist/intervalIndex/startpointInRangeIndex.js +4 -5
- package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
- package/dist/intervals/index.d.ts +2 -3
- package/dist/intervals/index.d.ts.map +1 -1
- package/dist/intervals/index.js +1 -6
- package/dist/intervals/index.js.map +1 -1
- package/dist/intervals/intervalUtils.d.ts +3 -25
- package/dist/intervals/intervalUtils.d.ts.map +1 -1
- package/dist/intervals/intervalUtils.js.map +1 -1
- package/dist/intervals/sequenceInterval.d.ts +3 -8
- package/dist/intervals/sequenceInterval.d.ts.map +1 -1
- package/dist/intervals/sequenceInterval.js +1 -9
- package/dist/intervals/sequenceInterval.js.map +1 -1
- package/dist/legacy.d.ts +4 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/sequence.d.ts +4 -6
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +3 -5
- package/dist/sequence.js.map +1 -1
- package/dist/sharedIntervalCollection.d.ts +2 -63
- package/dist/sharedIntervalCollection.d.ts.map +1 -1
- package/dist/sharedIntervalCollection.js +0 -113
- package/dist/sharedIntervalCollection.js.map +1 -1
- package/dist/sharedString.d.ts.map +1 -1
- package/dist/sharedString.js +6 -6
- package/dist/sharedString.js.map +1 -1
- package/lib/IntervalCollectionValues.d.ts +3 -51
- package/lib/IntervalCollectionValues.d.ts.map +1 -1
- package/lib/IntervalCollectionValues.js +5 -47
- package/lib/IntervalCollectionValues.js.map +1 -1
- package/lib/index.d.ts +4 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -3
- package/lib/index.js.map +1 -1
- package/lib/intervalCollection.d.ts +292 -63
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +113 -191
- package/lib/intervalCollection.js.map +1 -1
- package/lib/intervalCollectionMap.d.ts +11 -32
- package/lib/intervalCollectionMap.d.ts.map +1 -1
- package/lib/intervalCollectionMap.js +39 -92
- package/lib/intervalCollectionMap.js.map +1 -1
- package/lib/intervalCollectionMapInterfaces.d.ts +10 -83
- package/lib/intervalCollectionMapInterfaces.d.ts.map +1 -1
- package/lib/intervalCollectionMapInterfaces.js.map +1 -1
- package/lib/intervalIndex/endpointInRangeIndex.d.ts +10 -11
- package/lib/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
- package/lib/intervalIndex/endpointInRangeIndex.js +5 -6
- package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -1
- package/lib/intervalIndex/endpointIndex.d.ts +12 -13
- package/lib/intervalIndex/endpointIndex.d.ts.map +1 -1
- package/lib/intervalIndex/endpointIndex.js +5 -6
- package/lib/intervalIndex/endpointIndex.js.map +1 -1
- package/lib/intervalIndex/idIntervalIndex.d.ts +6 -12
- package/lib/intervalIndex/idIntervalIndex.d.ts.map +1 -1
- package/lib/intervalIndex/idIntervalIndex.js +0 -3
- package/lib/intervalIndex/idIntervalIndex.js.map +1 -1
- package/lib/intervalIndex/index.d.ts +2 -2
- package/lib/intervalIndex/index.d.ts.map +1 -1
- package/lib/intervalIndex/index.js.map +1 -1
- package/lib/intervalIndex/intervalIndex.d.ts +28 -1
- package/lib/intervalIndex/intervalIndex.d.ts.map +1 -1
- package/lib/intervalIndex/intervalIndex.js.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +30 -13
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.js +5 -6
- package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -1
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js +2 -2
- package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -1
- package/lib/intervalIndex/sequenceIntervalIndexes.d.ts +2 -2
- package/lib/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -1
- package/lib/intervalIndex/sequenceIntervalIndexes.js.map +1 -1
- package/lib/intervalIndex/startpointInRangeIndex.d.ts +10 -11
- package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
- package/lib/intervalIndex/startpointInRangeIndex.js +5 -6
- package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -1
- package/lib/intervals/index.d.ts +2 -3
- package/lib/intervals/index.d.ts.map +1 -1
- package/lib/intervals/index.js +1 -2
- package/lib/intervals/index.js.map +1 -1
- package/lib/intervals/intervalUtils.d.ts +3 -25
- package/lib/intervals/intervalUtils.d.ts.map +1 -1
- package/lib/intervals/intervalUtils.js.map +1 -1
- package/lib/intervals/sequenceInterval.d.ts +3 -8
- package/lib/intervals/sequenceInterval.d.ts.map +1 -1
- package/lib/intervals/sequenceInterval.js +0 -8
- package/lib/intervals/sequenceInterval.js.map +1 -1
- package/lib/legacy.d.ts +4 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/sequence.d.ts +4 -6
- package/lib/sequence.d.ts.map +1 -1
- package/lib/sequence.js +3 -5
- package/lib/sequence.js.map +1 -1
- package/lib/sharedIntervalCollection.d.ts +2 -63
- package/lib/sharedIntervalCollection.d.ts.map +1 -1
- package/lib/sharedIntervalCollection.js +1 -110
- package/lib/sharedIntervalCollection.js.map +1 -1
- package/lib/sharedString.d.ts.map +1 -1
- package/lib/sharedString.js +6 -6
- package/lib/sharedString.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +19 -22
- package/src/IntervalCollectionValues.ts +10 -93
- package/src/index.ts +6 -17
- package/src/intervalCollection.ts +524 -343
- package/src/intervalCollectionMap.ts +72 -140
- package/src/intervalCollectionMapInterfaces.ts +13 -104
- package/src/intervalIndex/endpointInRangeIndex.ts +17 -29
- package/src/intervalIndex/endpointIndex.ts +19 -31
- package/src/intervalIndex/idIntervalIndex.ts +15 -25
- package/src/intervalIndex/index.ts +2 -1
- package/src/intervalIndex/intervalIndex.ts +30 -1
- package/src/intervalIndex/overlappingIntervalsIndex.ts +50 -27
- package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +2 -3
- package/src/intervalIndex/sequenceIntervalIndexes.ts +2 -2
- package/src/intervalIndex/startpointInRangeIndex.ts +17 -29
- package/src/intervals/index.ts +0 -3
- package/src/intervals/intervalUtils.ts +3 -38
- package/src/intervals/sequenceInterval.ts +2 -12
- package/src/packageVersion.ts +1 -1
- package/src/sequence.ts +8 -20
- package/src/sharedIntervalCollection.ts +5 -183
- package/src/sharedString.ts +6 -24
- package/dist/intervals/interval.d.ts +0 -76
- package/dist/intervals/interval.d.ts.map +0 -1
- package/dist/intervals/interval.js +0 -167
- package/dist/intervals/interval.js.map +0 -1
- package/lib/intervals/interval.d.ts +0 -76
- package/lib/intervals/interval.d.ts.map +0 -1
- package/lib/intervals/interval.js +0 -162
- package/lib/intervals/interval.js.map +0 -1
- package/prettier.config.cjs +0 -8
- package/src/intervals/interval.ts +0 -226
|
@@ -5,36 +5,27 @@
|
|
|
5
5
|
|
|
6
6
|
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
7
7
|
import { IFluidHandle } from "@fluidframework/core-interfaces";
|
|
8
|
+
import type { IEvent, IEventProvider } from "@fluidframework/core-interfaces";
|
|
8
9
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
9
10
|
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
10
11
|
import { ValueType, IFluidSerializer } from "@fluidframework/shared-object-base/internal";
|
|
11
12
|
|
|
13
|
+
import { makeSerializable } from "./IntervalCollectionValues.js";
|
|
12
14
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "./IntervalCollectionValues.js";
|
|
16
|
-
import {
|
|
17
|
-
type IntervalCollection,
|
|
15
|
+
IntervalCollection,
|
|
16
|
+
opsMap,
|
|
18
17
|
reservedIntervalIdKey,
|
|
19
18
|
toOptionalSequencePlace,
|
|
20
19
|
toSequencePlace,
|
|
20
|
+
type ISerializedIntervalCollectionV1,
|
|
21
|
+
type ISerializedIntervalCollectionV2,
|
|
21
22
|
} from "./intervalCollection.js";
|
|
22
23
|
import {
|
|
23
|
-
IIntervalCollectionType,
|
|
24
24
|
IIntervalCollectionTypeOperationValue,
|
|
25
25
|
IMapMessageLocalMetadata,
|
|
26
26
|
ISerializableIntervalCollection,
|
|
27
|
-
ISharedDefaultMapEvents,
|
|
28
|
-
IValueChanged,
|
|
29
|
-
// eslint-disable-next-line import/no-deprecated
|
|
30
|
-
IValueOpEmitter,
|
|
31
27
|
SequenceOptions,
|
|
32
28
|
} from "./intervalCollectionMapInterfaces.js";
|
|
33
|
-
import {
|
|
34
|
-
type ISerializableInterval,
|
|
35
|
-
IntervalDeltaOpType,
|
|
36
|
-
SerializedIntervalDelta,
|
|
37
|
-
} from "./intervals/index.js";
|
|
38
29
|
|
|
39
30
|
function isMapOperation(op: unknown): op is IMapOperation {
|
|
40
31
|
return typeof op === "object" && op !== null && "type" in op && op.type === "act";
|
|
@@ -67,6 +58,10 @@ export interface IMapDataObjectSerializable {
|
|
|
67
58
|
[key: string]: ISerializableIntervalCollection;
|
|
68
59
|
}
|
|
69
60
|
|
|
61
|
+
export interface IntervalCollectionMapEvents extends IEvent {
|
|
62
|
+
(event: "createIntervalCollection", listener: (key: string, local: boolean) => void): void;
|
|
63
|
+
}
|
|
64
|
+
|
|
70
65
|
/**
|
|
71
66
|
* A DefaultMap is a map-like distributed data structure, supporting operations on values stored by
|
|
72
67
|
* string key locations.
|
|
@@ -74,7 +69,7 @@ export interface IMapDataObjectSerializable {
|
|
|
74
69
|
* Creation of values is implicit on access (either via `get` or a remote op application referring to
|
|
75
70
|
* a collection that wasn't previously known)
|
|
76
71
|
*/
|
|
77
|
-
export class IntervalCollectionMap
|
|
72
|
+
export class IntervalCollectionMap {
|
|
78
73
|
/**
|
|
79
74
|
* The number of key/value pairs stored in the map.
|
|
80
75
|
*/
|
|
@@ -82,45 +77,15 @@ export class IntervalCollectionMap<T extends ISerializableInterval> {
|
|
|
82
77
|
return this.data.size;
|
|
83
78
|
}
|
|
84
79
|
|
|
85
|
-
/**
|
|
86
|
-
* Mapping of op types to message handlers.
|
|
87
|
-
*/
|
|
88
|
-
private readonly messageHandler = {
|
|
89
|
-
process: (
|
|
90
|
-
op: IMapOperation,
|
|
91
|
-
local: boolean,
|
|
92
|
-
message: ISequencedDocumentMessage,
|
|
93
|
-
localOpMetadata: IMapMessageLocalMetadata,
|
|
94
|
-
) => {
|
|
95
|
-
const localValue = this.data.get(op.key) ?? this.createCore(op.key, local);
|
|
96
|
-
const handler = localValue.getOpHandler(op.value.opName);
|
|
97
|
-
const previousValue = localValue.value;
|
|
98
|
-
const translatedValue = op.value.value as any;
|
|
99
|
-
handler.process(previousValue, translatedValue, local, message, localOpMetadata);
|
|
100
|
-
const event: IValueChanged = { key: op.key, previousValue };
|
|
101
|
-
this.eventEmitter.emit("valueChanged", event, local, message, this.eventEmitter);
|
|
102
|
-
},
|
|
103
|
-
submit: (op: IMapOperation, localOpMetadata: IMapMessageLocalMetadata) => {
|
|
104
|
-
this.submitMessage(op, localOpMetadata);
|
|
105
|
-
},
|
|
106
|
-
resubmit: (op: IMapOperation, localOpMetadata: IMapMessageLocalMetadata) => {
|
|
107
|
-
const localValue = this.data.get(op.key);
|
|
108
|
-
|
|
109
|
-
assert(localValue !== undefined, 0x3f8 /* Local value expected on resubmission */);
|
|
110
|
-
|
|
111
|
-
const handler = localValue.getOpHandler(op.value.opName);
|
|
112
|
-
const rebased = handler.rebase(localValue.value, op.value, localOpMetadata);
|
|
113
|
-
if (rebased !== undefined) {
|
|
114
|
-
const { rebasedOp, rebasedLocalOpMetadata } = rebased;
|
|
115
|
-
this.submitMessage({ ...op, value: rebasedOp }, rebasedLocalOpMetadata);
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
|
|
120
80
|
/**
|
|
121
81
|
* The in-memory data the map is storing.
|
|
122
82
|
*/
|
|
123
|
-
private readonly data = new Map<string,
|
|
83
|
+
private readonly data = new Map<string, IntervalCollection>();
|
|
84
|
+
|
|
85
|
+
private readonly eventEmitter = new TypedEventEmitter<IntervalCollectionMapEvents>();
|
|
86
|
+
public get events(): IEventProvider<IntervalCollectionMapEvents> {
|
|
87
|
+
return this.eventEmitter;
|
|
88
|
+
}
|
|
124
89
|
|
|
125
90
|
/**
|
|
126
91
|
* Create a new default map.
|
|
@@ -137,9 +102,7 @@ export class IntervalCollectionMap<T extends ISerializableInterval> {
|
|
|
137
102
|
op: IMapOperation,
|
|
138
103
|
localOpMetadata: IMapMessageLocalMetadata,
|
|
139
104
|
) => void,
|
|
140
|
-
private readonly type: IIntervalCollectionType<T>,
|
|
141
105
|
private readonly options?: Partial<SequenceOptions>,
|
|
142
|
-
public readonly eventEmitter = new TypedEventEmitter<ISharedDefaultMapEvents>(),
|
|
143
106
|
) {}
|
|
144
107
|
|
|
145
108
|
/**
|
|
@@ -161,7 +124,7 @@ export class IntervalCollectionMap<T extends ISerializableInterval> {
|
|
|
161
124
|
const nextVal = localValuesIterator.next();
|
|
162
125
|
return nextVal.done
|
|
163
126
|
? { value: undefined, done: true }
|
|
164
|
-
: { value: nextVal.value
|
|
127
|
+
: { value: nextVal.value, done: false }; // Unpack the stored value
|
|
165
128
|
},
|
|
166
129
|
[Symbol.iterator]() {
|
|
167
130
|
return this;
|
|
@@ -172,22 +135,23 @@ export class IntervalCollectionMap<T extends ISerializableInterval> {
|
|
|
172
135
|
/**
|
|
173
136
|
* {@inheritDoc ISharedMap.get}
|
|
174
137
|
*/
|
|
175
|
-
public get(key: string): IntervalCollection
|
|
138
|
+
public get(key: string): IntervalCollection {
|
|
176
139
|
const localValue = this.data.get(key) ?? this.createCore(key, true);
|
|
177
140
|
|
|
178
|
-
return localValue
|
|
141
|
+
return localValue;
|
|
179
142
|
}
|
|
180
143
|
|
|
181
|
-
public
|
|
144
|
+
public serialize(serializer: IFluidSerializer): string {
|
|
182
145
|
const serializableMapData: IMapDataObjectSerializable = {};
|
|
183
146
|
this.data.forEach((localValue, key) => {
|
|
184
|
-
serializableMapData[key] = makeSerializable(
|
|
147
|
+
serializableMapData[key] = makeSerializable(
|
|
148
|
+
localValue,
|
|
149
|
+
serializer,
|
|
150
|
+
this.handle,
|
|
151
|
+
this.options?.intervalSerializationFormat ?? "2",
|
|
152
|
+
);
|
|
185
153
|
});
|
|
186
|
-
return serializableMapData;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
public serialize(serializer: IFluidSerializer): string {
|
|
190
|
-
return JSON.stringify(this.getSerializableStorage(serializer));
|
|
154
|
+
return JSON.stringify(serializableMapData);
|
|
191
155
|
}
|
|
192
156
|
|
|
193
157
|
/**
|
|
@@ -214,12 +178,13 @@ export class IntervalCollectionMap<T extends ISerializableInterval> {
|
|
|
214
178
|
// collection. See https://github.com/microsoft/FluidFramework/issues/10557 for more context.
|
|
215
179
|
const normalizedKey = key.startsWith("intervalCollections/") ? key.substring(20) : key;
|
|
216
180
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
181
|
+
assert(
|
|
182
|
+
serializable.type !== ValueType[ValueType.Plain] &&
|
|
183
|
+
serializable.type !== ValueType[ValueType.Shared],
|
|
184
|
+
0x2e1 /* "Support for plain value types removed." */,
|
|
185
|
+
);
|
|
221
186
|
|
|
222
|
-
this.
|
|
187
|
+
this.createCore(normalizedKey, false, serializable.value);
|
|
223
188
|
}
|
|
224
189
|
}
|
|
225
190
|
|
|
@@ -233,7 +198,16 @@ export class IntervalCollectionMap<T extends ISerializableInterval> {
|
|
|
233
198
|
*/
|
|
234
199
|
public tryResubmitMessage(op: unknown, localOpMetadata: IMapMessageLocalMetadata): boolean {
|
|
235
200
|
if (isMapOperation(op)) {
|
|
236
|
-
this.
|
|
201
|
+
const localValue = this.data.get(op.key);
|
|
202
|
+
|
|
203
|
+
assert(localValue !== undefined, 0x3f8 /* Local value expected on resubmission */);
|
|
204
|
+
|
|
205
|
+
const handler = opsMap[op.value.opName];
|
|
206
|
+
const rebased = handler.rebase(localValue, op.value, localOpMetadata);
|
|
207
|
+
if (rebased !== undefined) {
|
|
208
|
+
const { rebasedOp, rebasedLocalOpMetadata } = rebased;
|
|
209
|
+
this.submitMessage({ ...op, value: rebasedOp }, rebasedLocalOpMetadata);
|
|
210
|
+
}
|
|
237
211
|
return true;
|
|
238
212
|
}
|
|
239
213
|
return false;
|
|
@@ -299,8 +273,13 @@ export class IntervalCollectionMap<T extends ISerializableInterval> {
|
|
|
299
273
|
localOpMetadata: unknown,
|
|
300
274
|
): boolean {
|
|
301
275
|
if (isMapOperation(op)) {
|
|
302
|
-
this.
|
|
303
|
-
|
|
276
|
+
const localValue = this.data.get(op.key) ?? this.createCore(op.key, local);
|
|
277
|
+
const handler = opsMap[op.value.opName];
|
|
278
|
+
const previousValue = localValue;
|
|
279
|
+
const translatedValue = op.value.value as any;
|
|
280
|
+
handler.process(
|
|
281
|
+
previousValue,
|
|
282
|
+
translatedValue,
|
|
304
283
|
local,
|
|
305
284
|
message,
|
|
306
285
|
localOpMetadata as IMapMessageLocalMetadata,
|
|
@@ -314,77 +293,30 @@ export class IntervalCollectionMap<T extends ISerializableInterval> {
|
|
|
314
293
|
* Initializes a default ValueType at the provided key.
|
|
315
294
|
* Should be used when a map operation incurs creation.
|
|
316
295
|
* @param key - The key being initialized
|
|
317
|
-
* @param local - Whether the message originated from the local client
|
|
318
296
|
*/
|
|
319
|
-
private createCore(
|
|
320
|
-
const localValue = new IntervalCollectionTypeLocalValue(
|
|
321
|
-
this.type.factory.load(this.makeMapValueOpEmitter(key), undefined, this.options),
|
|
322
|
-
this.type,
|
|
323
|
-
);
|
|
324
|
-
const previousValue = this.data.get(key);
|
|
325
|
-
this.data.set(key, localValue);
|
|
326
|
-
const event: IValueChanged = { key, previousValue };
|
|
327
|
-
this.eventEmitter.emit("create", event, local, this.eventEmitter);
|
|
328
|
-
return localValue;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* The remote ISerializableValue we're receiving (either as a result of a load or an incoming set op) will
|
|
333
|
-
* have the information we need to create a real object, but will not be the real object yet. For example,
|
|
334
|
-
* we might know it's a map and the map's ID but not have the actual map or its data yet. makeLocal's
|
|
335
|
-
* job is to convert that information into a real object for local usage.
|
|
336
|
-
* @param key - The key that the caller intends to store the local value into (used for ops later). But
|
|
337
|
-
* doesn't actually store the local value into that key. So better not lie!
|
|
338
|
-
* @param serializable - The remote information that we can convert into a real object
|
|
339
|
-
* @returns The local value that was produced
|
|
340
|
-
*/
|
|
341
|
-
private makeLocal(
|
|
297
|
+
private createCore(
|
|
342
298
|
key: string,
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
299
|
+
local: boolean,
|
|
300
|
+
serializedIntervals?: ISerializedIntervalCollectionV1 | ISerializedIntervalCollectionV2,
|
|
301
|
+
): IntervalCollection {
|
|
302
|
+
const localValue = new IntervalCollection(
|
|
303
|
+
(op, md) => {
|
|
304
|
+
{
|
|
305
|
+
this.submitMessage(
|
|
306
|
+
{
|
|
307
|
+
key,
|
|
308
|
+
type: "act",
|
|
309
|
+
value: op,
|
|
310
|
+
},
|
|
311
|
+
md,
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
serializedIntervals ?? [],
|
|
354
316
|
this.options,
|
|
355
317
|
);
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Create an emitter for a value type to emit ops from the given key.
|
|
361
|
-
* @param key - The key of the map that the value type will be stored on
|
|
362
|
-
* @returns A value op emitter for the given key
|
|
363
|
-
*/
|
|
364
|
-
// eslint-disable-next-line import/no-deprecated
|
|
365
|
-
private makeMapValueOpEmitter(key: string): IValueOpEmitter {
|
|
366
|
-
// eslint-disable-next-line import/no-deprecated
|
|
367
|
-
const emit: IValueOpEmitter["emit"] = (
|
|
368
|
-
opName: IntervalDeltaOpType,
|
|
369
|
-
previousValue: unknown,
|
|
370
|
-
params: SerializedIntervalDelta,
|
|
371
|
-
localOpMetadata: IMapMessageLocalMetadata,
|
|
372
|
-
): void => {
|
|
373
|
-
const op: IMapOperation = {
|
|
374
|
-
key,
|
|
375
|
-
type: "act",
|
|
376
|
-
value: {
|
|
377
|
-
opName,
|
|
378
|
-
value: params,
|
|
379
|
-
},
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
this.submitMessage(op, localOpMetadata);
|
|
383
|
-
|
|
384
|
-
const event: IValueChanged = { key, previousValue };
|
|
385
|
-
this.eventEmitter.emit("valueChanged", event, true, null, this.eventEmitter);
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
return { emit };
|
|
318
|
+
this.data.set(key, localValue);
|
|
319
|
+
this.eventEmitter.emit("createIntervalCollection", key, local, this.eventEmitter);
|
|
320
|
+
return localValue;
|
|
389
321
|
}
|
|
390
322
|
}
|
|
@@ -3,58 +3,20 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IEventThisPlaceHolder } from "@fluidframework/core-interfaces";
|
|
7
6
|
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
8
7
|
import type { IMergeTreeOptions } from "@fluidframework/merge-tree/internal";
|
|
9
|
-
import { ISharedObjectEvents } from "@fluidframework/shared-object-base/internal";
|
|
10
8
|
|
|
11
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
IntervalCollection,
|
|
11
|
+
ISerializedIntervalCollectionV1,
|
|
12
|
+
ISerializedIntervalCollectionV2,
|
|
13
|
+
} from "./intervalCollection.js";
|
|
12
14
|
import {
|
|
13
|
-
type ISerializableInterval,
|
|
14
15
|
ISerializedInterval,
|
|
15
16
|
IntervalDeltaOpType,
|
|
16
|
-
IntervalOpType,
|
|
17
17
|
SerializedIntervalDelta,
|
|
18
18
|
} from "./intervals/index.js";
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
* Type of "valueChanged" event parameter.
|
|
22
|
-
*/
|
|
23
|
-
export interface IValueChanged {
|
|
24
|
-
/**
|
|
25
|
-
* The key storing the value that changed.
|
|
26
|
-
*/
|
|
27
|
-
key: string;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* The value that was stored at the key prior to the change.
|
|
31
|
-
*/
|
|
32
|
-
previousValue: any;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Value types are given an IValueOpEmitter to emit their ops through the container type that holds them.
|
|
37
|
-
* @internal
|
|
38
|
-
*/
|
|
39
|
-
export interface IValueOpEmitter {
|
|
40
|
-
/**
|
|
41
|
-
* Called by the value type to emit a value type operation through the container type holding it.
|
|
42
|
-
* @param opName - Name of the emitted operation
|
|
43
|
-
* @param previousValue - JSONable previous value as defined by the value type @deprecated unused
|
|
44
|
-
* @param params - JSONable params for the operation as defined by the value type
|
|
45
|
-
* @param localOpMetadata - JSONable local metadata which should be submitted with the op
|
|
46
|
-
*/
|
|
47
|
-
emit(
|
|
48
|
-
opName: IntervalOpType,
|
|
49
|
-
previousValue: undefined,
|
|
50
|
-
params: SerializedIntervalDelta,
|
|
51
|
-
localOpMetadata: IMapMessageLocalMetadata,
|
|
52
|
-
): void;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @internal
|
|
57
|
-
*/
|
|
58
20
|
export interface IMapMessageLocalMetadata {
|
|
59
21
|
localSeq: number;
|
|
60
22
|
}
|
|
@@ -85,42 +47,18 @@ export interface SequenceOptions
|
|
|
85
47
|
* The default value is false.
|
|
86
48
|
*/
|
|
87
49
|
intervalStickinessEnabled: boolean;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* A value factory is used to serialize/deserialize value types to a map
|
|
92
|
-
* @legacy
|
|
93
|
-
* @alpha
|
|
94
|
-
*/
|
|
95
|
-
export interface IIntervalCollectionFactory<T extends ISerializableInterval> {
|
|
96
|
-
/**
|
|
97
|
-
* Create a new value type. Used both in creation of new value types, as well as in loading existing ones
|
|
98
|
-
* from remote.
|
|
99
|
-
* @param emitter - Emitter object that the created value type will use to emit operations
|
|
100
|
-
* @param raw - Initialization parameters as defined by the value type
|
|
101
|
-
* @returns The new value type
|
|
102
|
-
*/
|
|
103
|
-
load(
|
|
104
|
-
emitter: IValueOpEmitter,
|
|
105
|
-
raw: any,
|
|
106
|
-
options?: Partial<SequenceOptions>,
|
|
107
|
-
): IntervalCollection<T>;
|
|
108
50
|
|
|
109
51
|
/**
|
|
110
|
-
*
|
|
111
|
-
* loadable using the load method of its factory.
|
|
112
|
-
* @param value - The value type to serialize
|
|
113
|
-
* @returns The JSONable form of the value type
|
|
52
|
+
* This is for testing, and allows us to output intervals in the older formats.
|
|
114
53
|
*/
|
|
115
|
-
|
|
54
|
+
intervalSerializationFormat: "1" | "2";
|
|
116
55
|
}
|
|
117
56
|
|
|
118
57
|
/**
|
|
119
58
|
* Defines an operation that a value type is able to handle.
|
|
120
|
-
*
|
|
121
|
-
* @alpha
|
|
59
|
+
*
|
|
122
60
|
*/
|
|
123
|
-
export interface IIntervalCollectionOperation
|
|
61
|
+
export interface IIntervalCollectionOperation {
|
|
124
62
|
/**
|
|
125
63
|
* Performs the actual processing on the incoming operation.
|
|
126
64
|
* @param value - The current value stored at the given key, which should be the value type
|
|
@@ -130,7 +68,7 @@ export interface IIntervalCollectionOperation<T extends ISerializableInterval> {
|
|
|
130
68
|
* @param localOpMetadata - any local metadata submitted by `IValueOpEmitter.emit`.
|
|
131
69
|
*/
|
|
132
70
|
process(
|
|
133
|
-
value: IntervalCollection
|
|
71
|
+
value: IntervalCollection,
|
|
134
72
|
params: ISerializedInterval,
|
|
135
73
|
local: boolean,
|
|
136
74
|
message: ISequencedDocumentMessage | undefined,
|
|
@@ -146,7 +84,7 @@ export interface IIntervalCollectionOperation<T extends ISerializableInterval> {
|
|
|
146
84
|
* @returns A rebased version of the op and any local metadata that should be submitted with it.
|
|
147
85
|
*/
|
|
148
86
|
rebase(
|
|
149
|
-
value: IntervalCollection
|
|
87
|
+
value: IntervalCollection,
|
|
150
88
|
op: IIntervalCollectionTypeOperationValue,
|
|
151
89
|
localOpMetadata: IMapMessageLocalMetadata,
|
|
152
90
|
):
|
|
@@ -157,33 +95,6 @@ export interface IIntervalCollectionOperation<T extends ISerializableInterval> {
|
|
|
157
95
|
| undefined;
|
|
158
96
|
}
|
|
159
97
|
|
|
160
|
-
/**
|
|
161
|
-
* Defines a value type that can be registered on a container type.
|
|
162
|
-
*/
|
|
163
|
-
export interface IIntervalCollectionType<T extends ISerializableInterval> {
|
|
164
|
-
/**
|
|
165
|
-
* Name of the value type.
|
|
166
|
-
*/
|
|
167
|
-
name: string;
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Factory method used to convert to/from a JSON form of the type.
|
|
171
|
-
*/
|
|
172
|
-
factory: IIntervalCollectionFactory<T>;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Operations that can be applied to the value type.
|
|
176
|
-
*/
|
|
177
|
-
ops: Map<IntervalOpType, IIntervalCollectionOperation<T>>;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export interface ISharedDefaultMapEvents extends ISharedObjectEvents {
|
|
181
|
-
(
|
|
182
|
-
event: "valueChanged" | "create",
|
|
183
|
-
listener: (changed: IValueChanged, local: boolean, target: IEventThisPlaceHolder) => void,
|
|
184
|
-
): void;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
98
|
/**
|
|
188
99
|
* The _ready-for-serialization_ format of values contained in DDS contents. This allows us to use
|
|
189
100
|
* ISerializableValue.type to understand whether they're storing a Plain JS object, a SharedObject, or a value type.
|
|
@@ -199,12 +110,12 @@ export interface ISerializableIntervalCollection {
|
|
|
199
110
|
/**
|
|
200
111
|
* A type annotation to help indicate how the value serializes.
|
|
201
112
|
*/
|
|
202
|
-
type:
|
|
113
|
+
type: "sharedStringIntervalCollection";
|
|
203
114
|
|
|
204
115
|
/**
|
|
205
116
|
* The JSONable representation of the value.
|
|
206
117
|
*/
|
|
207
|
-
value:
|
|
118
|
+
value: ISerializedIntervalCollectionV1 | ISerializedIntervalCollectionV2;
|
|
208
119
|
}
|
|
209
120
|
|
|
210
121
|
export interface ISerializedIntervalCollection {
|
|
@@ -226,8 +137,6 @@ export interface ISerializedIntervalCollection {
|
|
|
226
137
|
* value is whatever params the ValueType needs to complete that operation. Similar to ISerializableValue, it is
|
|
227
138
|
* serializable via JSON.stringify/parse but differs in that it has no equivalency with an in-memory value - rather
|
|
228
139
|
* it just describes an operation to be applied to an already-in-memory value.
|
|
229
|
-
* @legacy
|
|
230
|
-
* @alpha
|
|
231
140
|
*/
|
|
232
141
|
export interface IIntervalCollectionTypeOperationValue {
|
|
233
142
|
/**
|
|
@@ -7,16 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
import { Client, PropertyAction, RedBlackTree } from "@fluidframework/merge-tree/internal";
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
IIntervalHelpers,
|
|
12
|
-
ISerializableInterval,
|
|
13
|
-
IntervalType,
|
|
14
|
-
SequenceInterval,
|
|
15
|
-
sequenceIntervalHelpers,
|
|
16
|
-
} from "../intervals/index.js";
|
|
10
|
+
import { IntervalType, SequenceInterval, createSequenceInterval } from "../intervals/index.js";
|
|
17
11
|
import { ISharedString } from "../sharedString.js";
|
|
18
12
|
|
|
19
|
-
import {
|
|
13
|
+
import { type SequenceIntervalIndex } from "./intervalIndex.js";
|
|
20
14
|
import {
|
|
21
15
|
HasComparisonOverride,
|
|
22
16
|
compareOverrideables,
|
|
@@ -29,25 +23,19 @@ import {
|
|
|
29
23
|
* Provide additional APIs to support efficiently querying a collection of intervals whose endpoints fall within a specified range.
|
|
30
24
|
* @internal
|
|
31
25
|
*/
|
|
32
|
-
export interface IEndpointInRangeIndex
|
|
33
|
-
extends IntervalIndex<TInterval> {
|
|
26
|
+
export interface IEndpointInRangeIndex extends SequenceIntervalIndex {
|
|
34
27
|
/**
|
|
35
28
|
* @returns an array of all intervals contained in this collection whose endpoints locate in the range [start, end] (includes both ends)
|
|
36
29
|
*/
|
|
37
|
-
findIntervalsWithEndpointInRange(start: number, end: number):
|
|
30
|
+
findIntervalsWithEndpointInRange(start: number, end: number): SequenceInterval[];
|
|
38
31
|
}
|
|
39
32
|
|
|
40
|
-
export class EndpointInRangeIndex
|
|
41
|
-
implements IEndpointInRangeIndex<TInterval>
|
|
42
|
-
{
|
|
33
|
+
export class EndpointInRangeIndex implements IEndpointInRangeIndex {
|
|
43
34
|
private readonly intervalTree;
|
|
44
35
|
|
|
45
|
-
constructor(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
) {
|
|
49
|
-
this.intervalTree = new RedBlackTree<TInterval, TInterval>(
|
|
50
|
-
(a: TInterval, b: TInterval) => {
|
|
36
|
+
constructor(private readonly client: Client) {
|
|
37
|
+
this.intervalTree = new RedBlackTree<SequenceInterval, SequenceInterval>(
|
|
38
|
+
(a: SequenceInterval, b: SequenceInterval) => {
|
|
51
39
|
const compareEndsResult = a.compareEnd(b);
|
|
52
40
|
if (compareEndsResult !== 0) {
|
|
53
41
|
return compareEndsResult;
|
|
@@ -71,25 +59,25 @@ export class EndpointInRangeIndex<TInterval extends ISerializableInterval>
|
|
|
71
59
|
);
|
|
72
60
|
}
|
|
73
61
|
|
|
74
|
-
public add(interval:
|
|
62
|
+
public add(interval: SequenceInterval): void {
|
|
75
63
|
this.intervalTree.put(interval, interval);
|
|
76
64
|
}
|
|
77
65
|
|
|
78
|
-
public remove(interval:
|
|
66
|
+
public remove(interval: SequenceInterval): void {
|
|
79
67
|
this.intervalTree.remove(interval);
|
|
80
68
|
}
|
|
81
69
|
|
|
82
|
-
public findIntervalsWithEndpointInRange(start: number, end: number):
|
|
70
|
+
public findIntervalsWithEndpointInRange(start: number, end: number): SequenceInterval[] {
|
|
83
71
|
if (start <= 0 || start > end || this.intervalTree.isEmpty()) {
|
|
84
72
|
return [];
|
|
85
73
|
}
|
|
86
|
-
const results:
|
|
87
|
-
const action: PropertyAction<
|
|
74
|
+
const results: SequenceInterval[] = [];
|
|
75
|
+
const action: PropertyAction<SequenceInterval, SequenceInterval> = (node) => {
|
|
88
76
|
results.push(node.data);
|
|
89
77
|
return true;
|
|
90
78
|
};
|
|
91
79
|
|
|
92
|
-
const transientStartInterval =
|
|
80
|
+
const transientStartInterval = createSequenceInterval(
|
|
93
81
|
"transient",
|
|
94
82
|
start,
|
|
95
83
|
start,
|
|
@@ -97,7 +85,7 @@ export class EndpointInRangeIndex<TInterval extends ISerializableInterval>
|
|
|
97
85
|
IntervalType.Transient,
|
|
98
86
|
);
|
|
99
87
|
|
|
100
|
-
const transientEndInterval =
|
|
88
|
+
const transientEndInterval = createSequenceInterval(
|
|
101
89
|
"transient",
|
|
102
90
|
end,
|
|
103
91
|
end,
|
|
@@ -119,7 +107,7 @@ export class EndpointInRangeIndex<TInterval extends ISerializableInterval>
|
|
|
119
107
|
*/
|
|
120
108
|
export function createEndpointInRangeIndex(
|
|
121
109
|
sharedString: ISharedString,
|
|
122
|
-
): IEndpointInRangeIndex
|
|
110
|
+
): IEndpointInRangeIndex {
|
|
123
111
|
const client = (sharedString as unknown as { client: Client }).client;
|
|
124
|
-
return new EndpointInRangeIndex
|
|
112
|
+
return new EndpointInRangeIndex(client);
|
|
125
113
|
}
|