@fluidframework/sequence 0.59.4001 → 1.1.0-75972
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 +1 -1
- package/README.md +18 -6
- package/dist/defaultMap.d.ts +2 -6
- package/dist/defaultMap.d.ts.map +1 -1
- package/dist/defaultMap.js +27 -37
- package/dist/defaultMap.js.map +1 -1
- package/dist/defaultMapInterfaces.d.ts +24 -3
- package/dist/defaultMapInterfaces.d.ts.map +1 -1
- package/dist/defaultMapInterfaces.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/intervalCollection.d.ts +93 -8
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +434 -178
- package/dist/intervalCollection.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/sequence.d.ts +6 -7
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +17 -21
- package/dist/sequence.js.map +1 -1
- package/dist/sharedIntervalCollection.d.ts.map +1 -1
- package/dist/sharedIntervalCollection.js +2 -2
- package/dist/sharedIntervalCollection.js.map +1 -1
- package/dist/sharedSequence.js.map +1 -1
- package/dist/sparsematrix.js +2 -2
- package/dist/sparsematrix.js.map +1 -1
- package/lib/defaultMap.d.ts +2 -6
- package/lib/defaultMap.d.ts.map +1 -1
- package/lib/defaultMap.js +27 -37
- package/lib/defaultMap.js.map +1 -1
- package/lib/defaultMapInterfaces.d.ts +24 -3
- package/lib/defaultMapInterfaces.d.ts.map +1 -1
- package/lib/defaultMapInterfaces.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/intervalCollection.d.ts +93 -8
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +435 -179
- package/lib/intervalCollection.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/sequence.d.ts +6 -7
- package/lib/sequence.d.ts.map +1 -1
- package/lib/sequence.js +18 -22
- package/lib/sequence.js.map +1 -1
- package/lib/sharedIntervalCollection.d.ts.map +1 -1
- package/lib/sharedIntervalCollection.js +2 -2
- package/lib/sharedIntervalCollection.js.map +1 -1
- package/lib/sharedSequence.js.map +1 -1
- package/lib/sparsematrix.js +2 -2
- package/lib/sparsematrix.js.map +1 -1
- package/package.json +23 -45
- package/src/defaultMap.ts +39 -41
- package/src/defaultMapInterfaces.ts +28 -3
- package/src/index.ts +3 -0
- package/src/intervalCollection.ts +575 -211
- package/src/packageVersion.ts +1 -1
- package/src/sequence.ts +36 -38
- package/src/sharedIntervalCollection.ts +4 -3
- package/src/sharedSequence.ts +1 -1
- package/src/sparsematrix.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/sequence",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0-75972",
|
|
4
4
|
"description": "Distributed sequence",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -64,51 +64,39 @@
|
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
66
66
|
"@fluidframework/common-utils": "^0.32.1",
|
|
67
|
-
"@fluidframework/
|
|
68
|
-
"@fluidframework/
|
|
69
|
-
"@fluidframework/
|
|
67
|
+
"@fluidframework/container-utils": "1.1.0-75972",
|
|
68
|
+
"@fluidframework/core-interfaces": "1.1.0-75972",
|
|
69
|
+
"@fluidframework/datastore-definitions": "1.1.0-75972",
|
|
70
|
+
"@fluidframework/merge-tree": "1.1.0-75972",
|
|
70
71
|
"@fluidframework/protocol-definitions": "^0.1028.2000",
|
|
71
|
-
"@fluidframework/runtime-definitions": "
|
|
72
|
-
"@fluidframework/runtime-utils": "
|
|
73
|
-
"@fluidframework/shared-object-base": "
|
|
74
|
-
"@fluidframework/telemetry-utils": "
|
|
72
|
+
"@fluidframework/runtime-definitions": "1.1.0-75972",
|
|
73
|
+
"@fluidframework/runtime-utils": "1.1.0-75972",
|
|
74
|
+
"@fluidframework/shared-object-base": "1.1.0-75972",
|
|
75
|
+
"@fluidframework/telemetry-utils": "1.1.0-75972",
|
|
75
76
|
"uuid": "^8.3.1"
|
|
76
77
|
},
|
|
77
78
|
"devDependencies": {
|
|
78
|
-
"@fluid-internal/stochastic-test-utils": "
|
|
79
|
-
"@fluid-internal/test-dds-utils": "
|
|
80
|
-
"@fluidframework/build-common": "^0.
|
|
81
|
-
"@fluidframework/build-tools": "^0.2.
|
|
79
|
+
"@fluid-internal/stochastic-test-utils": "1.1.0-75972",
|
|
80
|
+
"@fluid-internal/test-dds-utils": "1.1.0-75972",
|
|
81
|
+
"@fluidframework/build-common": "^0.24.0-0",
|
|
82
|
+
"@fluidframework/build-tools": "^0.2.71273",
|
|
82
83
|
"@fluidframework/eslint-config-fluid": "^0.28.2000",
|
|
83
|
-
"@fluidframework/gitresources": "^0.1036.
|
|
84
|
-
"@fluidframework/mocha-test-setup": "
|
|
85
|
-
"@fluidframework/sequence-previous": "npm:@fluidframework/sequence
|
|
86
|
-
"@fluidframework/server-services-client": "^0.1036.
|
|
87
|
-
"@fluidframework/test-runtime-utils": "
|
|
84
|
+
"@fluidframework/gitresources": "^0.1036.5000-0",
|
|
85
|
+
"@fluidframework/mocha-test-setup": "1.1.0-75972",
|
|
86
|
+
"@fluidframework/sequence-previous": "npm:@fluidframework/sequence@^1.0.0",
|
|
87
|
+
"@fluidframework/server-services-client": "^0.1036.5000-0",
|
|
88
|
+
"@fluidframework/test-runtime-utils": "1.1.0-75972",
|
|
88
89
|
"@microsoft/api-extractor": "^7.22.2",
|
|
89
90
|
"@rushstack/eslint-config": "^2.5.1",
|
|
90
91
|
"@types/diff": "^3.5.1",
|
|
91
92
|
"@types/mocha": "^9.1.1",
|
|
92
93
|
"@types/node": "^14.18.0",
|
|
93
94
|
"@types/random-js": "^1.0.31",
|
|
94
|
-
"@typescript-eslint/eslint-plugin": "~5.9.0",
|
|
95
|
-
"@typescript-eslint/parser": "~5.9.0",
|
|
96
95
|
"concurrently": "^6.2.0",
|
|
97
96
|
"copyfiles": "^2.1.0",
|
|
98
97
|
"cross-env": "^7.0.2",
|
|
99
98
|
"diff": "^3.5.0",
|
|
100
99
|
"eslint": "~8.6.0",
|
|
101
|
-
"eslint-plugin-editorconfig": "~3.2.0",
|
|
102
|
-
"eslint-plugin-eslint-comments": "~3.2.0",
|
|
103
|
-
"eslint-plugin-import": "~2.25.4",
|
|
104
|
-
"eslint-plugin-jest": "~26.1.3",
|
|
105
|
-
"eslint-plugin-jsdoc": "~39.3.0",
|
|
106
|
-
"eslint-plugin-mocha": "~10.0.3",
|
|
107
|
-
"eslint-plugin-promise": "~6.0.0",
|
|
108
|
-
"eslint-plugin-react": "~7.28.0",
|
|
109
|
-
"eslint-plugin-tsdoc": "~0.2.14",
|
|
110
|
-
"eslint-plugin-unicorn": "~40.0.0",
|
|
111
|
-
"eslint-plugin-unused-imports": "~2.0.0",
|
|
112
100
|
"mocha": "^10.0.0",
|
|
113
101
|
"nyc": "^15.0.0",
|
|
114
102
|
"random-js": "^1.0.8",
|
|
@@ -117,23 +105,13 @@
|
|
|
117
105
|
"typescript-formatter": "7.1.0"
|
|
118
106
|
},
|
|
119
107
|
"typeValidation": {
|
|
120
|
-
"version": "
|
|
108
|
+
"version": "1.1.0",
|
|
121
109
|
"broken": {
|
|
122
|
-
"
|
|
123
|
-
"forwardCompat": false
|
|
124
|
-
"backCompat": false
|
|
110
|
+
"ClassDeclaration_IntervalCollection": {
|
|
111
|
+
"forwardCompat": false
|
|
125
112
|
},
|
|
126
|
-
"
|
|
127
|
-
"forwardCompat": false
|
|
128
|
-
"backCompat": false
|
|
129
|
-
},
|
|
130
|
-
"ClassDeclaration_SequenceEvent": {
|
|
131
|
-
"forwardCompat": false,
|
|
132
|
-
"backCompat": false
|
|
133
|
-
},
|
|
134
|
-
"ClassDeclaration_SequenceMaintenanceEvent": {
|
|
135
|
-
"forwardCompat": false,
|
|
136
|
-
"backCompat": false
|
|
113
|
+
"ClassDeclaration_SequenceInterval": {
|
|
114
|
+
"forwardCompat": false
|
|
137
115
|
}
|
|
138
116
|
}
|
|
139
117
|
}
|
package/src/defaultMap.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
IValueType,
|
|
25
25
|
IValueTypeOperationValue,
|
|
26
26
|
ISharedDefaultMapEvents,
|
|
27
|
+
IMapMessageLocalMetadata,
|
|
27
28
|
} from "./defaultMapInterfaces";
|
|
28
29
|
|
|
29
30
|
/**
|
|
@@ -49,13 +50,11 @@ interface IMapMessageHandler {
|
|
|
49
50
|
* Communicate the operation to remote clients.
|
|
50
51
|
* @param op - The map operation to submit
|
|
51
52
|
*/
|
|
52
|
-
submit(op: IMapOperation): void;
|
|
53
|
+
submit(op: IMapOperation, localOpMetadata: IMapMessageLocalMetadata): void;
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
}
|
|
55
|
+
resubmit(op: IMapOperation, localOpMetadata: IMapMessageLocalMetadata): void;
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
lastProcessedSeq: number;
|
|
57
|
+
getStashedOpLocalMetadata(op: IMapOperation): unknown;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
/**
|
|
@@ -121,8 +120,6 @@ export class DefaultMap<T> {
|
|
|
121
120
|
*/
|
|
122
121
|
private readonly data = new Map<string, ValueTypeLocalValue<T>>();
|
|
123
122
|
|
|
124
|
-
private lastProcessedSeq: number = -1;
|
|
125
|
-
|
|
126
123
|
/**
|
|
127
124
|
* Create a new default map.
|
|
128
125
|
* @param serializer - The serializer to serialize / parse handles
|
|
@@ -158,12 +155,9 @@ export class DefaultMap<T> {
|
|
|
158
155
|
const iterator = {
|
|
159
156
|
next(): IteratorResult<[string, any]> {
|
|
160
157
|
const nextVal = localEntriesIterator.next();
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// Unpack the stored value
|
|
165
|
-
return { value: [nextVal.value[0], nextVal.value[1].value], done: false };
|
|
166
|
-
}
|
|
158
|
+
return nextVal.done
|
|
159
|
+
? { value: undefined, done: true }
|
|
160
|
+
: { value: [nextVal.value[0], nextVal.value[1].value], done: false }; // Unpack the stored value
|
|
167
161
|
},
|
|
168
162
|
[Symbol.iterator]() {
|
|
169
163
|
return this;
|
|
@@ -181,12 +175,9 @@ export class DefaultMap<T> {
|
|
|
181
175
|
const iterator = {
|
|
182
176
|
next(): IteratorResult<any> {
|
|
183
177
|
const nextVal = localValuesIterator.next();
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// Unpack the stored value
|
|
188
|
-
return { value: nextVal.value.value, done: false };
|
|
189
|
-
}
|
|
178
|
+
return nextVal.done
|
|
179
|
+
? { value: undefined, done: true }
|
|
180
|
+
: { value: nextVal.value.value, done: false }; // Unpack the stored value
|
|
190
181
|
},
|
|
191
182
|
[Symbol.iterator]() {
|
|
192
183
|
return this;
|
|
@@ -217,10 +208,8 @@ export class DefaultMap<T> {
|
|
|
217
208
|
* {@inheritDoc ISharedMap.get}
|
|
218
209
|
*/
|
|
219
210
|
public get(key: string): T {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
localValue = this.createCore(key, true);
|
|
223
|
-
}
|
|
211
|
+
const localValue = this.data.get(key) ?? this.createCore(key, true);
|
|
212
|
+
|
|
224
213
|
return localValue.value;
|
|
225
214
|
}
|
|
226
215
|
|
|
@@ -271,8 +260,14 @@ export class DefaultMap<T> {
|
|
|
271
260
|
continue;
|
|
272
261
|
}
|
|
273
262
|
|
|
263
|
+
// Back-compat: Sequence previously arbitrarily prefixed all interval collection keys with
|
|
264
|
+
// "intervalCollections/". This would burden users trying to iterate the collection and
|
|
265
|
+
// access its value, as well as those trying to match a create message to its underlying
|
|
266
|
+
// collection. See https://github.com/microsoft/FluidFramework/issues/10557 for more context.
|
|
267
|
+
const normalizedKey = key.startsWith("intervalCollections/") ? key.substring(20) : key;
|
|
268
|
+
|
|
274
269
|
const localValue = {
|
|
275
|
-
key,
|
|
270
|
+
key: normalizedKey,
|
|
276
271
|
value: this.makeLocal(key, serializable),
|
|
277
272
|
};
|
|
278
273
|
|
|
@@ -292,17 +287,11 @@ export class DefaultMap<T> {
|
|
|
292
287
|
* also sent if we are asked to resubmit the message.
|
|
293
288
|
* @returns True if the operation was submitted, false otherwise.
|
|
294
289
|
*/
|
|
295
|
-
public
|
|
290
|
+
public tryResubmitMessage(op: any, localOpMetadata: IMapMessageLocalMetadata): boolean {
|
|
296
291
|
const type: string = op.type;
|
|
297
292
|
const handler = this.messageHandlers.get(type);
|
|
298
293
|
if (handler !== undefined) {
|
|
299
|
-
|
|
300
|
-
// we don't know how to rebase these operations, so if any other op has come in
|
|
301
|
-
// we will fail.
|
|
302
|
-
if (this.lastProcessedSeq !== mapLocalMetadata?.lastProcessedSeq) {
|
|
303
|
-
throw new Error("SharedInterval does not support reconnect in presence of external changes");
|
|
304
|
-
}
|
|
305
|
-
handler.submit(op as IMapOperation);
|
|
294
|
+
handler.resubmit(op as IMapOperation, localOpMetadata);
|
|
306
295
|
return true;
|
|
307
296
|
}
|
|
308
297
|
return false;
|
|
@@ -331,9 +320,6 @@ export class DefaultMap<T> {
|
|
|
331
320
|
message: ISequencedDocumentMessage | undefined,
|
|
332
321
|
localOpMetadata: unknown,
|
|
333
322
|
): boolean {
|
|
334
|
-
// track the seq of every incoming message, so we can detect if any
|
|
335
|
-
// changes happened during a resubmit
|
|
336
|
-
this.lastProcessedSeq = message.sequenceNumber;
|
|
337
323
|
const handler = this.messageHandlers.get(op.type);
|
|
338
324
|
if (handler !== undefined) {
|
|
339
325
|
handler.process(op, local, message, localOpMetadata as IMapMessageLocalMetadata);
|
|
@@ -402,14 +388,26 @@ export class DefaultMap<T> {
|
|
|
402
388
|
const translatedValue = parseHandles(
|
|
403
389
|
op.value.value,
|
|
404
390
|
this.serializer);
|
|
405
|
-
handler.process(previousValue, translatedValue, local, message);
|
|
391
|
+
handler.process(previousValue, translatedValue, local, message, localOpMetadata);
|
|
406
392
|
const event: IValueChanged = { key: op.key, previousValue };
|
|
407
393
|
this.eventEmitter.emit("valueChanged", event, local, message, this.eventEmitter);
|
|
408
394
|
},
|
|
409
|
-
submit: (op: IMapValueTypeOperation) => {
|
|
395
|
+
submit: (op: IMapValueTypeOperation, localOpMetadata: IMapMessageLocalMetadata) => {
|
|
410
396
|
this.submitMessage(
|
|
411
397
|
op,
|
|
412
|
-
|
|
398
|
+
localOpMetadata,
|
|
399
|
+
);
|
|
400
|
+
},
|
|
401
|
+
resubmit: (op: IMapValueTypeOperation, localOpMetadata: IMapMessageLocalMetadata) => {
|
|
402
|
+
const localValue = this.data.get(op.key);
|
|
403
|
+
const handler = localValue.getOpHandler(op.value.opName);
|
|
404
|
+
const {
|
|
405
|
+
rebasedOp,
|
|
406
|
+
rebasedLocalOpMetadata,
|
|
407
|
+
} = handler.rebase(localValue.value, op.value, localOpMetadata);
|
|
408
|
+
this.submitMessage(
|
|
409
|
+
{ ...op, value: rebasedOp },
|
|
410
|
+
rebasedLocalOpMetadata,
|
|
413
411
|
);
|
|
414
412
|
},
|
|
415
413
|
getStashedOpLocalMetadata: (op: IMapValueTypeOperation) => {
|
|
@@ -427,7 +425,7 @@ export class DefaultMap<T> {
|
|
|
427
425
|
* @returns A value op emitter for the given key
|
|
428
426
|
*/
|
|
429
427
|
private makeMapValueOpEmitter(key: string): IValueOpEmitter {
|
|
430
|
-
const emit = (opName: string, previousValue: any, params: any) => {
|
|
428
|
+
const emit = (opName: string, previousValue: any, params: any, localOpMetadata: IMapMessageLocalMetadata) => {
|
|
431
429
|
const translatedParams = makeHandlesSerializable(
|
|
432
430
|
params,
|
|
433
431
|
this.serializer,
|
|
@@ -441,8 +439,8 @@ export class DefaultMap<T> {
|
|
|
441
439
|
value: translatedParams,
|
|
442
440
|
},
|
|
443
441
|
};
|
|
444
|
-
|
|
445
|
-
this.submitMessage(op,
|
|
442
|
+
|
|
443
|
+
this.submitMessage(op, localOpMetadata);
|
|
446
444
|
|
|
447
445
|
const event: IValueChanged = { key, previousValue };
|
|
448
446
|
this.eventEmitter.emit("valueChanged", event, true, null, this.eventEmitter);
|
|
@@ -24,6 +24,7 @@ export interface IValueChanged {
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Value types are given an IValueOpEmitter to emit their ops through the container type that holds them.
|
|
27
|
+
* @internal
|
|
27
28
|
*/
|
|
28
29
|
export interface IValueOpEmitter {
|
|
29
30
|
/**
|
|
@@ -31,9 +32,17 @@ export interface IValueOpEmitter {
|
|
|
31
32
|
* @param opName - Name of the emitted operation
|
|
32
33
|
* @param previousValue - JSONable previous value as defined by the value type
|
|
33
34
|
* @param params - JSONable params for the operation as defined by the value type
|
|
34
|
-
* @
|
|
35
|
+
* @param localOpMetadata - JSONable local metadata which should be submitted with the op
|
|
36
|
+
* @internal
|
|
35
37
|
*/
|
|
36
|
-
emit(opName: string, previousValue: any, params: any): void;
|
|
38
|
+
emit(opName: string, previousValue: any, params: any, localOpMetadata: IMapMessageLocalMetadata): void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export interface IMapMessageLocalMetadata {
|
|
45
|
+
localSeq: number;
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
/**
|
|
@@ -72,14 +81,30 @@ export interface IValueOperation<T> {
|
|
|
72
81
|
* @param params - The params on the incoming operation
|
|
73
82
|
* @param local - Whether the operation originated from this client
|
|
74
83
|
* @param message - The operation itself
|
|
84
|
+
* @param localOpMetadata - any local metadata submitted by `IValueOpEmitter.emit`.
|
|
75
85
|
* @alpha
|
|
76
86
|
*/
|
|
77
87
|
process(
|
|
78
88
|
value: T,
|
|
79
89
|
params: any,
|
|
80
90
|
local: boolean,
|
|
81
|
-
message: ISequencedDocumentMessage | undefined
|
|
91
|
+
message: ISequencedDocumentMessage | undefined,
|
|
92
|
+
localOpMetadata: IMapMessageLocalMetadata | undefined
|
|
82
93
|
);
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Rebases an `op` on `value` from its original perspective (ref/local seq) to the current
|
|
97
|
+
* perspective. Should be invoked on reconnection.
|
|
98
|
+
* @param value - The current value stored at the given key, which should be the value type.
|
|
99
|
+
* @param op - The op to be rebased.
|
|
100
|
+
* @param localOpMetadata - Any local metadata that was originally submitted with the op.
|
|
101
|
+
* @returns A rebased version of the op and any local metadata that should be submitted with it.
|
|
102
|
+
*/
|
|
103
|
+
rebase(
|
|
104
|
+
value: T,
|
|
105
|
+
op: IValueTypeOperationValue,
|
|
106
|
+
localOpMetadata: IMapMessageLocalMetadata
|
|
107
|
+
): { rebasedOp: IValueTypeOperationValue; rebasedLocalOpMetadata: IMapMessageLocalMetadata; };
|
|
83
108
|
}
|
|
84
109
|
|
|
85
110
|
/**
|
package/src/index.ts
CHANGED
|
@@ -14,8 +14,11 @@ export {
|
|
|
14
14
|
ISerializableInterval,
|
|
15
15
|
ISerializedInterval,
|
|
16
16
|
SequenceInterval,
|
|
17
|
+
ISerializedIntervalCollectionV2,
|
|
18
|
+
CompressedSerializedInterval,
|
|
17
19
|
} from "./intervalCollection";
|
|
18
20
|
export {
|
|
21
|
+
IMapMessageLocalMetadata,
|
|
19
22
|
IValueOpEmitter,
|
|
20
23
|
} from "./defaultMapInterfaces";
|
|
21
24
|
export * from "./sharedString";
|