@fluidframework/matrix 2.41.0-338186 → 2.41.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 +4 -0
- package/dist/matrix.d.ts +1 -3
- package/dist/matrix.d.ts.map +1 -1
- package/dist/matrix.js +61 -47
- package/dist/matrix.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/lib/matrix.d.ts +1 -3
- package/lib/matrix.d.ts.map +1 -1
- package/lib/matrix.js +61 -47
- package/lib/matrix.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/package.json +18 -18
- package/src/matrix.ts +88 -55
- package/src/packageVersion.ts +1 -1
package/lib/packageVersion.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,wBAAwB,CAAC;AAChD,MAAM,CAAC,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,wBAAwB,CAAC;AAChD,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/matrix\";\nexport const pkgVersion = \"2.41.0\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/matrix",
|
|
3
|
-
"version": "2.41.0
|
|
3
|
+
"version": "2.41.0",
|
|
4
4
|
"description": "Distributed matrix",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -81,17 +81,17 @@
|
|
|
81
81
|
"temp-directory": "nyc/.nyc_output"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@fluid-internal/client-utils": "2.41.0
|
|
85
|
-
"@fluidframework/core-interfaces": "2.41.0
|
|
86
|
-
"@fluidframework/core-utils": "2.41.0
|
|
87
|
-
"@fluidframework/datastore-definitions": "2.41.0
|
|
88
|
-
"@fluidframework/driver-definitions": "2.41.0
|
|
89
|
-
"@fluidframework/driver-utils": "2.41.0
|
|
90
|
-
"@fluidframework/merge-tree": "2.41.0
|
|
91
|
-
"@fluidframework/runtime-definitions": "2.41.0
|
|
92
|
-
"@fluidframework/runtime-utils": "2.41.0
|
|
93
|
-
"@fluidframework/shared-object-base": "2.41.0
|
|
94
|
-
"@fluidframework/telemetry-utils": "2.41.0
|
|
84
|
+
"@fluid-internal/client-utils": "~2.41.0",
|
|
85
|
+
"@fluidframework/core-interfaces": "~2.41.0",
|
|
86
|
+
"@fluidframework/core-utils": "~2.41.0",
|
|
87
|
+
"@fluidframework/datastore-definitions": "~2.41.0",
|
|
88
|
+
"@fluidframework/driver-definitions": "~2.41.0",
|
|
89
|
+
"@fluidframework/driver-utils": "~2.41.0",
|
|
90
|
+
"@fluidframework/merge-tree": "~2.41.0",
|
|
91
|
+
"@fluidframework/runtime-definitions": "~2.41.0",
|
|
92
|
+
"@fluidframework/runtime-utils": "~2.41.0",
|
|
93
|
+
"@fluidframework/shared-object-base": "~2.41.0",
|
|
94
|
+
"@fluidframework/telemetry-utils": "~2.41.0",
|
|
95
95
|
"@tiny-calc/nano": "0.0.0-alpha.5",
|
|
96
96
|
"double-ended-queue": "^2.1.0-0",
|
|
97
97
|
"tslib": "^1.10.0"
|
|
@@ -99,17 +99,17 @@
|
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
101
101
|
"@biomejs/biome": "~1.9.3",
|
|
102
|
-
"@fluid-internal/mocha-test-setup": "2.41.0
|
|
103
|
-
"@fluid-private/stochastic-test-utils": "2.41.0
|
|
104
|
-
"@fluid-private/test-dds-utils": "2.41.0
|
|
102
|
+
"@fluid-internal/mocha-test-setup": "~2.41.0",
|
|
103
|
+
"@fluid-private/stochastic-test-utils": "~2.41.0",
|
|
104
|
+
"@fluid-private/test-dds-utils": "~2.41.0",
|
|
105
105
|
"@fluid-tools/benchmark": "^0.51.0",
|
|
106
106
|
"@fluid-tools/build-cli": "^0.55.0",
|
|
107
107
|
"@fluidframework/build-common": "^2.0.3",
|
|
108
108
|
"@fluidframework/build-tools": "^0.55.0",
|
|
109
|
-
"@fluidframework/container-definitions": "2.41.0
|
|
110
|
-
"@fluidframework/eslint-config-fluid": "^5.7.
|
|
109
|
+
"@fluidframework/container-definitions": "~2.41.0",
|
|
110
|
+
"@fluidframework/eslint-config-fluid": "^5.7.4",
|
|
111
111
|
"@fluidframework/matrix-previous": "npm:@fluidframework/matrix@2.40.0",
|
|
112
|
-
"@fluidframework/test-runtime-utils": "2.41.0
|
|
112
|
+
"@fluidframework/test-runtime-utils": "~2.41.0",
|
|
113
113
|
"@microsoft/api-extractor": "7.52.8",
|
|
114
114
|
"@tiny-calc/micro": "0.0.0-alpha.5",
|
|
115
115
|
"@types/double-ended-queue": "^2.1.0",
|
package/src/matrix.ts
CHANGED
|
@@ -204,6 +204,15 @@ export interface ISharedMatrix<T = any>
|
|
|
204
204
|
switchSetCellPolicy(): void;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
type FirstWriterWinsPolicy =
|
|
208
|
+
| { state: "off" }
|
|
209
|
+
| { state: "local" }
|
|
210
|
+
| {
|
|
211
|
+
state: "on";
|
|
212
|
+
switchOpSeqNumber: number;
|
|
213
|
+
cellLastWriteTracker: SparseArray2D<CellLastWriteTrackerItem>;
|
|
214
|
+
};
|
|
215
|
+
|
|
207
216
|
/**
|
|
208
217
|
* A SharedMatrix holds a rectangular 2D array of values. Supported operations
|
|
209
218
|
* include setting values and inserting/removing rows and columns.
|
|
@@ -244,10 +253,10 @@ export class SharedMatrix<T = any>
|
|
|
244
253
|
|
|
245
254
|
private cells = new SparseArray2D<MatrixItem<T>>(); // Stores cell values.
|
|
246
255
|
private readonly pending = new SparseArray2D<number>(); // Tracks pending writes.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
256
|
+
|
|
257
|
+
private fwwPolicy: FirstWriterWinsPolicy = {
|
|
258
|
+
state: "off",
|
|
259
|
+
};
|
|
251
260
|
|
|
252
261
|
// Used to track if there is any reentrancy in setCell code.
|
|
253
262
|
private reentrantCount: number = 0;
|
|
@@ -267,7 +276,6 @@ export class SharedMatrix<T = any>
|
|
|
267
276
|
) {
|
|
268
277
|
super(id, runtime, attributes, "fluid_matrix_");
|
|
269
278
|
|
|
270
|
-
this.setCellLwwToFwwPolicySwitchOpSeqNumber = -1;
|
|
271
279
|
this.rows = new PermutationVector(
|
|
272
280
|
SnapshotPath.rows,
|
|
273
281
|
this.logger,
|
|
@@ -333,7 +341,7 @@ export class SharedMatrix<T = any>
|
|
|
333
341
|
}
|
|
334
342
|
|
|
335
343
|
public isSetCellConflictResolutionPolicyFWW(): boolean {
|
|
336
|
-
return this.
|
|
344
|
+
return this.fwwPolicy.state !== "off";
|
|
337
345
|
}
|
|
338
346
|
|
|
339
347
|
public getCell(row: number, col: number): MatrixItem<T> {
|
|
@@ -470,8 +478,7 @@ export class SharedMatrix<T = any>
|
|
|
470
478
|
row,
|
|
471
479
|
col,
|
|
472
480
|
value,
|
|
473
|
-
fwwMode:
|
|
474
|
-
this.userSwitchedSetCellPolicy || this.setCellLwwToFwwPolicySwitchOpSeqNumber > -1,
|
|
481
|
+
fwwMode: this.fwwPolicy.state !== "off",
|
|
475
482
|
};
|
|
476
483
|
|
|
477
484
|
const rowsRef = this.createOpMetadataLocalRef(this.rows, row, localSeq);
|
|
@@ -668,15 +675,29 @@ export class SharedMatrix<T = any>
|
|
|
668
675
|
SnapshotPath.cols,
|
|
669
676
|
this.cols.summarize(this.runtime, this.handle, serializer),
|
|
670
677
|
);
|
|
671
|
-
const artifactsToSummarize
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
];
|
|
678
|
+
const artifactsToSummarize: (
|
|
679
|
+
| undefined
|
|
680
|
+
| number
|
|
681
|
+
| ReturnType<SparseArray2D<MatrixItem<T> | number>["snapshot"]>
|
|
682
|
+
)[] = [this.cells.snapshot(), this.pending.snapshot()];
|
|
676
683
|
|
|
677
684
|
// Only need to store it in the snapshot if we have switched the policy already.
|
|
678
|
-
if (this.
|
|
679
|
-
artifactsToSummarize.push(
|
|
685
|
+
if (this.fwwPolicy.state === "on") {
|
|
686
|
+
artifactsToSummarize.push(
|
|
687
|
+
this.fwwPolicy.switchOpSeqNumber,
|
|
688
|
+
this.fwwPolicy.cellLastWriteTracker.snapshot(),
|
|
689
|
+
);
|
|
690
|
+
} else {
|
|
691
|
+
// back-compat: used -1 for disabled
|
|
692
|
+
artifactsToSummarize.push(
|
|
693
|
+
-1,
|
|
694
|
+
/*
|
|
695
|
+
* we should set undefined in place of cellLastWriteTracker to ensure the number of array entries is consistent.
|
|
696
|
+
* Doing that currently breaks snapshot tests. Its is probably fine, but if new elements are ever added, we need
|
|
697
|
+
* ensure undefined is also set.
|
|
698
|
+
*/
|
|
699
|
+
// undefined
|
|
700
|
+
);
|
|
680
701
|
}
|
|
681
702
|
builder.addBlob(
|
|
682
703
|
SnapshotPath.cells,
|
|
@@ -786,19 +807,15 @@ export class SharedMatrix<T = any>
|
|
|
786
807
|
this.rows.removeLocalReferencePosition(rowsRef);
|
|
787
808
|
this.cols.removeLocalReferencePosition(colsRef);
|
|
788
809
|
if (row !== undefined && col !== undefined && row >= 0 && col >= 0) {
|
|
789
|
-
const lastCellModificationDetails = this.cellLastWriteTracker.getCell(
|
|
790
|
-
rowHandle,
|
|
791
|
-
colHandle,
|
|
792
|
-
);
|
|
793
810
|
// If the mode is LWW, then send the op.
|
|
794
811
|
// Otherwise if the current mode is FWW and if we generated this op, after seeing the
|
|
795
812
|
// last set op, or it is the first set op for the cell, then regenerate the op,
|
|
796
813
|
// otherwise raise conflict. We want to check the current mode here and not that
|
|
797
814
|
// whether op was made in FWW or not.
|
|
798
815
|
if (
|
|
799
|
-
this.
|
|
800
|
-
|
|
801
|
-
|
|
816
|
+
this.fwwPolicy.state !== "on" ||
|
|
817
|
+
referenceSeqNumber >=
|
|
818
|
+
(this.fwwPolicy.cellLastWriteTracker.getCell(rowHandle, colHandle)?.seqNum ?? 0)
|
|
802
819
|
) {
|
|
803
820
|
this.sendSetCellOp(row, col, setOp.value, rowHandle, colHandle, localSeq);
|
|
804
821
|
} else if (this.pending.getCell(rowHandle, colHandle) !== undefined) {
|
|
@@ -854,11 +871,21 @@ export class SharedMatrix<T = any>
|
|
|
854
871
|
];
|
|
855
872
|
|
|
856
873
|
this.cells = SparseArray2D.load(cellData);
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
874
|
+
// back-compat: used -1 for disabled, also may not exist
|
|
875
|
+
const switchOpSeqNumber =
|
|
876
|
+
setCellLwwToFwwPolicySwitchOpSeqNumber === -1
|
|
877
|
+
? undefined
|
|
878
|
+
: (setCellLwwToFwwPolicySwitchOpSeqNumber ?? undefined);
|
|
879
|
+
this.fwwPolicy =
|
|
880
|
+
switchOpSeqNumber === undefined
|
|
881
|
+
? {
|
|
882
|
+
state: "off",
|
|
883
|
+
}
|
|
884
|
+
: {
|
|
885
|
+
state: "on",
|
|
886
|
+
switchOpSeqNumber,
|
|
887
|
+
cellLastWriteTracker: SparseArray2D.load(cellLastWriteTracker),
|
|
888
|
+
};
|
|
862
889
|
} catch (error) {
|
|
863
890
|
this.logger.sendErrorEvent({ eventName: "MatrixLoadFailed" }, error);
|
|
864
891
|
}
|
|
@@ -874,11 +901,11 @@ export class SharedMatrix<T = any>
|
|
|
874
901
|
message: ISequencedDocumentMessage,
|
|
875
902
|
): boolean {
|
|
876
903
|
assert(
|
|
877
|
-
this.
|
|
904
|
+
this.fwwPolicy.state === "on",
|
|
878
905
|
0x85f /* should be in Fww mode when calling this method */,
|
|
879
906
|
);
|
|
880
907
|
assert(message.clientId !== null, 0x860 /* clientId should not be null */);
|
|
881
|
-
const lastCellModificationDetails = this.cellLastWriteTracker.getCell(
|
|
908
|
+
const lastCellModificationDetails = this.fwwPolicy.cellLastWriteTracker.getCell(
|
|
882
909
|
rowHandle,
|
|
883
910
|
colHandle,
|
|
884
911
|
);
|
|
@@ -927,11 +954,13 @@ export class SharedMatrix<T = any>
|
|
|
927
954
|
);
|
|
928
955
|
|
|
929
956
|
const { row, col, value, fwwMode } = contents;
|
|
930
|
-
const isPreviousSetCellPolicyModeFWW =
|
|
931
|
-
this.setCellLwwToFwwPolicySwitchOpSeqNumber > -1;
|
|
932
957
|
// If this is the first op notifying us of the policy change, then set the policy change seq number.
|
|
933
|
-
if (
|
|
934
|
-
this.
|
|
958
|
+
if (fwwMode === true && this.fwwPolicy.state !== "on") {
|
|
959
|
+
this.fwwPolicy = {
|
|
960
|
+
state: "on",
|
|
961
|
+
switchOpSeqNumber: msg.sequenceNumber,
|
|
962
|
+
cellLastWriteTracker: new SparseArray2D(),
|
|
963
|
+
};
|
|
935
964
|
}
|
|
936
965
|
|
|
937
966
|
assert(msg.clientId !== null, 0x861 /* clientId should not be null!! */);
|
|
@@ -945,11 +974,10 @@ export class SharedMatrix<T = any>
|
|
|
945
974
|
// If policy is switched and cell should be modified too based on policy, then update the tracker.
|
|
946
975
|
// If policy is not switched, then also update the tracker in case it is the latest.
|
|
947
976
|
if (
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
(this.setCellLwwToFwwPolicySwitchOpSeqNumber === -1 && isLatestPendingOp)
|
|
977
|
+
this.fwwPolicy.state === "on" &&
|
|
978
|
+
this.shouldSetCellBasedOnFWW(rowHandle, colHandle, msg)
|
|
951
979
|
) {
|
|
952
|
-
this.cellLastWriteTracker.setCell(rowHandle, colHandle, {
|
|
980
|
+
this.fwwPolicy.cellLastWriteTracker.setCell(rowHandle, colHandle, {
|
|
953
981
|
seqNum: msg.sequenceNumber,
|
|
954
982
|
clientId: msg.clientId,
|
|
955
983
|
});
|
|
@@ -971,17 +999,14 @@ export class SharedMatrix<T = any>
|
|
|
971
999
|
isHandleValid(rowHandle) && isHandleValid(colHandle),
|
|
972
1000
|
0x022 /* "SharedMatrix row and/or col handles are invalid!" */,
|
|
973
1001
|
);
|
|
974
|
-
if (this.
|
|
1002
|
+
if (this.fwwPolicy.state === "on") {
|
|
975
1003
|
// If someone tried to Overwrite the cell value or first write on this cell or
|
|
976
1004
|
// same client tried to modify the cell or if the previous mode was LWW, then we need to still
|
|
977
1005
|
// overwrite the cell and raise conflict if we have pending changes as our change is going to be lost.
|
|
978
|
-
if (
|
|
979
|
-
!isPreviousSetCellPolicyModeFWW ||
|
|
980
|
-
this.shouldSetCellBasedOnFWW(rowHandle, colHandle, msg)
|
|
981
|
-
) {
|
|
1006
|
+
if (this.shouldSetCellBasedOnFWW(rowHandle, colHandle, msg)) {
|
|
982
1007
|
const previousValue = this.cells.getCell(rowHandle, colHandle);
|
|
983
1008
|
this.cells.setCell(rowHandle, colHandle, value);
|
|
984
|
-
this.cellLastWriteTracker.setCell(rowHandle, colHandle, {
|
|
1009
|
+
this.fwwPolicy.cellLastWriteTracker.setCell(rowHandle, colHandle, {
|
|
985
1010
|
seqNum: msg.sequenceNumber,
|
|
986
1011
|
clientId: msg.clientId,
|
|
987
1012
|
});
|
|
@@ -1006,10 +1031,6 @@ export class SharedMatrix<T = any>
|
|
|
1006
1031
|
// If there is a pending (unACKed) local write to the same cell, skip the current op
|
|
1007
1032
|
// since it "happened before" the pending write.
|
|
1008
1033
|
this.cells.setCell(rowHandle, colHandle, value);
|
|
1009
|
-
this.cellLastWriteTracker.setCell(rowHandle, colHandle, {
|
|
1010
|
-
seqNum: msg.sequenceNumber,
|
|
1011
|
-
clientId: msg.clientId,
|
|
1012
|
-
});
|
|
1013
1034
|
for (const consumer of this.consumers.values()) {
|
|
1014
1035
|
consumer.cellsChanged(adjustedRow, adjustedCol, 1, 1, this);
|
|
1015
1036
|
}
|
|
@@ -1051,7 +1072,12 @@ export class SharedMatrix<T = any>
|
|
|
1051
1072
|
for (const rowHandle of rowHandles) {
|
|
1052
1073
|
this.cells.clearRows(/* rowStart: */ rowHandle, /* rowCount: */ 1);
|
|
1053
1074
|
this.pending.clearRows(/* rowStart: */ rowHandle, /* rowCount: */ 1);
|
|
1054
|
-
this.
|
|
1075
|
+
if (this.fwwPolicy.state === "on") {
|
|
1076
|
+
this.fwwPolicy.cellLastWriteTracker?.clearRows(
|
|
1077
|
+
/* rowStart: */ rowHandle,
|
|
1078
|
+
/* rowCount: */ 1,
|
|
1079
|
+
);
|
|
1080
|
+
}
|
|
1055
1081
|
}
|
|
1056
1082
|
};
|
|
1057
1083
|
|
|
@@ -1059,17 +1085,24 @@ export class SharedMatrix<T = any>
|
|
|
1059
1085
|
for (const colHandle of colHandles) {
|
|
1060
1086
|
this.cells.clearCols(/* colStart: */ colHandle, /* colCount: */ 1);
|
|
1061
1087
|
this.pending.clearCols(/* colStart: */ colHandle, /* colCount: */ 1);
|
|
1062
|
-
this.
|
|
1088
|
+
if (this.fwwPolicy.state === "on") {
|
|
1089
|
+
this.fwwPolicy.cellLastWriteTracker?.clearCols(
|
|
1090
|
+
/* colStart: */ colHandle,
|
|
1091
|
+
/* colCount: */ 1,
|
|
1092
|
+
);
|
|
1093
|
+
}
|
|
1063
1094
|
}
|
|
1064
1095
|
};
|
|
1065
1096
|
|
|
1066
1097
|
public switchSetCellPolicy(): void {
|
|
1067
|
-
if (this.
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1098
|
+
if (this.fwwPolicy.state === "off") {
|
|
1099
|
+
this.fwwPolicy = this.isAttached()
|
|
1100
|
+
? { state: "local" }
|
|
1101
|
+
: {
|
|
1102
|
+
state: "on",
|
|
1103
|
+
switchOpSeqNumber: 0,
|
|
1104
|
+
cellLastWriteTracker: new SparseArray2D(),
|
|
1105
|
+
};
|
|
1073
1106
|
}
|
|
1074
1107
|
}
|
|
1075
1108
|
|
package/src/packageVersion.ts
CHANGED