@fluidframework/matrix 2.0.0-internal.7.2.2 → 2.0.0-internal.7.4.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 +8 -0
- package/README.md +39 -0
- package/api-extractor-lint.json +13 -0
- package/api-extractor.json +3 -7
- package/api-report/matrix.api.md +19 -9
- package/dist/{handlecache.js → handlecache.cjs} +3 -3
- package/dist/handlecache.cjs.map +1 -0
- package/dist/{handletable.js → handletable.cjs} +1 -1
- package/dist/handletable.cjs.map +1 -0
- package/dist/{index.js → index.cjs} +3 -3
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/matrix-alpha.d.ts +214 -0
- package/dist/matrix-beta.d.ts +61 -0
- package/dist/matrix-public.d.ts +61 -0
- package/dist/matrix-untrimmed.d.ts +214 -0
- package/dist/{matrix.js → matrix.cjs} +185 -55
- package/dist/matrix.cjs.map +1 -0
- package/dist/matrix.d.ts +67 -8
- package/dist/matrix.d.ts.map +1 -1
- package/dist/{ops.js → ops.cjs} +2 -1
- package/dist/ops.cjs.map +1 -0
- package/dist/ops.d.ts +5 -1
- package/dist/ops.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/{permutationvector.js → permutationvector.cjs} +5 -4
- package/dist/permutationvector.cjs.map +1 -0
- package/dist/permutationvector.d.ts.map +1 -1
- package/dist/{range.js → range.cjs} +1 -1
- package/dist/range.cjs.map +1 -0
- package/dist/{runtime.js → runtime.cjs} +7 -3
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.ts +4 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/{serialization.js → serialization.cjs} +1 -1
- package/dist/serialization.cjs.map +1 -0
- package/dist/{sparsearray2d.js → sparsearray2d.cjs} +1 -1
- package/dist/sparsearray2d.cjs.map +1 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/{types.js → types.cjs} +1 -1
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/{undoprovider.js → undoprovider.cjs} +2 -2
- package/dist/undoprovider.cjs.map +1 -0
- package/lib/handlecache.d.ts +2 -2
- package/lib/handlecache.d.ts.map +1 -1
- package/lib/{handlecache.js → handlecache.mjs} +3 -4
- package/lib/handlecache.mjs.map +1 -0
- package/lib/{handletable.js → handletable.mjs} +1 -1
- package/lib/handletable.mjs.map +1 -0
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.mjs +7 -0
- package/lib/index.mjs.map +1 -0
- package/lib/matrix-alpha.d.ts +214 -0
- package/lib/matrix-beta.d.ts +61 -0
- package/lib/matrix-public.d.ts +61 -0
- package/lib/matrix-untrimmed.d.ts +214 -0
- package/lib/matrix.d.ts +69 -10
- package/lib/matrix.d.ts.map +1 -1
- package/lib/{matrix.js → matrix.mjs} +184 -55
- package/lib/matrix.mjs.map +1 -0
- package/lib/ops.d.ts +5 -1
- package/lib/ops.d.ts.map +1 -1
- package/lib/{ops.js → ops.mjs} +2 -1
- package/lib/ops.mjs.map +1 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
- package/lib/packageVersion.mjs.map +1 -0
- package/lib/permutationvector.d.ts +3 -3
- package/lib/permutationvector.d.ts.map +1 -1
- package/lib/{permutationvector.js → permutationvector.mjs} +4 -4
- package/lib/permutationvector.mjs.map +1 -0
- package/lib/{range.js → range.mjs} +1 -1
- package/lib/range.mjs.map +1 -0
- package/lib/runtime.d.ts +4 -0
- package/lib/runtime.d.ts.map +1 -1
- package/lib/{runtime.js → runtime.mjs} +7 -3
- package/lib/runtime.mjs.map +1 -0
- package/lib/serialization.d.ts.map +1 -1
- package/lib/{serialization.js → serialization.mjs} +1 -1
- package/lib/serialization.mjs.map +1 -0
- package/lib/sparsearray2d.d.ts.map +1 -1
- package/lib/{sparsearray2d.js → sparsearray2d.mjs} +1 -1
- package/lib/sparsearray2d.mjs.map +1 -0
- package/lib/types.d.ts +6 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/{types.js → types.mjs} +1 -1
- package/lib/types.mjs.map +1 -0
- package/lib/undoprovider.d.ts +4 -4
- package/lib/undoprovider.d.ts.map +1 -1
- package/lib/{undoprovider.js → undoprovider.mjs} +2 -2
- package/lib/undoprovider.mjs.map +1 -0
- package/matrix.test-files.tar +0 -0
- package/package.json +59 -35
- package/src/index.ts +1 -1
- package/src/matrix.ts +284 -59
- package/src/ops.ts +5 -0
- package/src/packageVersion.ts +1 -1
- package/src/permutationvector.ts +2 -0
- package/src/runtime.ts +4 -0
- package/src/types.ts +6 -0
- package/tsc-multi.test.json +4 -0
- package/tsconfig.json +6 -4
- package/dist/handlecache.js.map +0 -1
- package/dist/handletable.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/matrix.js.map +0 -1
- package/dist/ops.js.map +0 -1
- package/dist/packageVersion.js.map +0 -1
- package/dist/permutationvector.js.map +0 -1
- package/dist/range.js.map +0 -1
- package/dist/runtime.js.map +0 -1
- package/dist/serialization.js.map +0 -1
- package/dist/sparsearray2d.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/undoprovider.js.map +0 -1
- package/lib/handlecache.js.map +0 -1
- package/lib/handletable.js.map +0 -1
- package/lib/index.js +0 -7
- package/lib/index.js.map +0 -1
- package/lib/matrix.js.map +0 -1
- package/lib/ops.js.map +0 -1
- package/lib/packageVersion.js.map +0 -1
- package/lib/permutationvector.js.map +0 -1
- package/lib/range.js.map +0 -1
- package/lib/runtime.js.map +0 -1
- package/lib/serialization.js.map +0 -1
- package/lib/sparsearray2d.js.map +0 -1
- package/lib/types.js.map +0 -1
- package/lib/undoprovider.js.map +0 -1
- package/tsconfig.esnext.json +0 -7
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -119,3 +119,42 @@ return undefined; // Empty region
|
|
|
119
119
|
A benefit of storing the cell data in [Z-order](https://en.wikipedia.org/wiki/Z-order_curve) is that both row-major and
|
|
120
120
|
col-major traversal benefit from prefetching and cache coherence. Reading/writing to the physical storage along either
|
|
121
121
|
axis is typically within an order of magnitude compared to sequentially accessing a cache hot native JavaScript array.
|
|
122
|
+
|
|
123
|
+
### Switching From Last Write Win(LWW) to First Write Win(FWW) mode
|
|
124
|
+
|
|
125
|
+
Shared Matrix allows to make to make one way switch from LWW to FWW. This is introduced in order to handle conflict
|
|
126
|
+
when multiple clients at once initialize a cell. Using FWW, will help clients to receive a `conflict` event in case
|
|
127
|
+
their change was rejected. They can resolve conflict with the new information that they received in the event.
|
|
128
|
+
This event is only emitted when the SetCell Resolution Policy is First Write Win(FWW). This is emitted when two clients
|
|
129
|
+
race and send changes without observing each other changes, the changes that gets sequenced last would be rejected, and
|
|
130
|
+
only client who's changes rejected would be notified via this event, with expectation that it will merge its changes
|
|
131
|
+
back by accounting new information (state from winner of the race).
|
|
132
|
+
|
|
133
|
+
Some cases which documents how the Set op changes are applied or rejected during LWW -> FWW switch as some clients will
|
|
134
|
+
be in FWW mode and some will in LWW mode. When app calls `switchSetCellPolicy` the policy is changed to FWW mode
|
|
135
|
+
immediately and then later communicated to other clients via next SetOp which is made on the matrix.
|
|
136
|
+
|
|
137
|
+
**Case 1:** When all clients have switched to FWW mode, then any race between 2 Set Op, will result in a `conflict` event
|
|
138
|
+
at the loser client until it receives its own latest Set op. For example, client has sent op for cell C1. It receives remote
|
|
139
|
+
ops R1 and R2 for cell C1. It will first raise `conflict` event when it receives R1 and then another `conflict` event when
|
|
140
|
+
it receives R2. This will keep happening until it receives its own op, so that its changes are not lost due to conflict.
|
|
141
|
+
|
|
142
|
+
**Case 2:** Client switches policy to FWW locally. No SetOp is made yet. This client has no pending changes yet. On receiving
|
|
143
|
+
remote Set ops, this client will apply them all.
|
|
144
|
+
|
|
145
|
+
**Case 3:** Client switches policy to FWW locally. This client has pending changes for cell C1. On
|
|
146
|
+
receiving remote LWW Set op for C1, this client will reject it as its own op will finally be applied. So the first FWW
|
|
147
|
+
SetOp is still treated as LWW op in a way. Now lets say it has received a remote FWW op for C1 instead of a LWW op, then
|
|
148
|
+
the remote op would have been applied causing client's policy to shift to FWW with that op. It will also raise a conflict
|
|
149
|
+
event locally as its Op for cell c1 will be rejected by other clients as it is a loser op.
|
|
150
|
+
|
|
151
|
+
**Case 4:** In FWW mode, when there is no conflict, clients will still be able to overwrite cells. We track the sequence
|
|
152
|
+
number for each cell when it was last edited and also track the clientId which made that change. If the receive a Op for
|
|
153
|
+
cell C1, and its ref Sequence number is >= to sequence number at which it was last edited, then the cell would be
|
|
154
|
+
overwritten. Otherwise, if the same client made the changes, then the op will still be applied as the client knew about
|
|
155
|
+
the previous edit.
|
|
156
|
+
|
|
157
|
+
**Case 5: Reconnection:** When a client makes an op in LWW mode in disconnected state for cell C1, then when it comes online
|
|
158
|
+
later on, and catches up it sees a FWW op for C1, it will raise a `conflict` event for C1 and will not send it own op.
|
|
159
|
+
It can receive many ops for C1 during catchup and will raise `conflict` event for each of those in case they are winner
|
|
160
|
+
ops for C1.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
+
"extends": "../../../common/build/build-common/api-extractor-lint.json",
|
|
4
|
+
"messages": {
|
|
5
|
+
"extractorMessageReporting": {
|
|
6
|
+
// TODO: remove once base config has this enabled as an error
|
|
7
|
+
"ae-incompatible-release-tags": {
|
|
8
|
+
"logLevel": "error",
|
|
9
|
+
"addToApiReportFile": false
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
package/api-extractor.json
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
-
"extends": "
|
|
4
|
-
|
|
5
|
-
// TODO: Fix violations and remove these rule overrides
|
|
3
|
+
"extends": "../../../common/build/build-common/api-extractor-base.json",
|
|
6
4
|
"messages": {
|
|
7
5
|
"extractorMessageReporting": {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
},
|
|
11
|
-
"ae-forgotten-export": {
|
|
6
|
+
// TODO: Add missing documentation and remove this rule override
|
|
7
|
+
"ae-undocumented": {
|
|
12
8
|
"logLevel": "none"
|
|
13
9
|
}
|
|
14
10
|
}
|
package/api-report/matrix.api.md
CHANGED
|
@@ -9,6 +9,7 @@ import { IChannelAttributes } from '@fluidframework/datastore-definitions';
|
|
|
9
9
|
import { IChannelFactory } from '@fluidframework/datastore-definitions';
|
|
10
10
|
import { IChannelServices } from '@fluidframework/datastore-definitions';
|
|
11
11
|
import { IChannelStorageService } from '@fluidframework/datastore-definitions';
|
|
12
|
+
import { IEventThisPlaceHolder } from '@fluidframework/core-interfaces';
|
|
12
13
|
import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
|
|
13
14
|
import { IFluidSerializer } from '@fluidframework/shared-object-base';
|
|
14
15
|
import { IJSONSegment } from '@fluidframework/merge-tree';
|
|
@@ -17,12 +18,13 @@ import { IMatrixProducer } from '@tiny-calc/nano';
|
|
|
17
18
|
import { IMatrixReader } from '@tiny-calc/nano';
|
|
18
19
|
import { IMatrixWriter } from '@tiny-calc/nano';
|
|
19
20
|
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
|
|
21
|
+
import { ISharedObjectEvents } from '@fluidframework/shared-object-base';
|
|
20
22
|
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
|
|
21
23
|
import { Serializable } from '@fluidframework/datastore-definitions';
|
|
22
24
|
import { SharedObject } from '@fluidframework/shared-object-base';
|
|
23
25
|
import { SummarySerializer } from '@fluidframework/shared-object-base';
|
|
24
26
|
|
|
25
|
-
// @
|
|
27
|
+
// @alpha (undocumented)
|
|
26
28
|
export interface IRevertible {
|
|
27
29
|
// (undocumented)
|
|
28
30
|
discard(): any;
|
|
@@ -30,18 +32,23 @@ export interface IRevertible {
|
|
|
30
32
|
revert(): any;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
// @
|
|
35
|
+
// @alpha
|
|
36
|
+
export interface ISharedMatrixEvents<T> extends ISharedObjectEvents {
|
|
37
|
+
(event: "conflict", listener: (row: number, col: number, currentValue: MatrixItem<T>, conflictingValue: MatrixItem<T>, target: IEventThisPlaceHolder) => void): any;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// @alpha (undocumented)
|
|
34
41
|
export interface IUndoConsumer {
|
|
35
42
|
// (undocumented)
|
|
36
43
|
pushToCurrentOperation(revertible: IRevertible): any;
|
|
37
44
|
}
|
|
38
45
|
|
|
39
|
-
// @
|
|
46
|
+
// @alpha
|
|
40
47
|
export type MatrixItem<T> = Serializable<Exclude<T, null>> | undefined;
|
|
41
48
|
|
|
42
|
-
// @
|
|
43
|
-
export class SharedMatrix<T = any> extends SharedObject implements IMatrixProducer<MatrixItem<T>>, IMatrixReader<MatrixItem<T>>, IMatrixWriter<MatrixItem<T>> {
|
|
44
|
-
constructor(runtime: IFluidDataStoreRuntime, id: string, attributes: IChannelAttributes);
|
|
49
|
+
// @alpha
|
|
50
|
+
export class SharedMatrix<T = any> extends SharedObject<ISharedMatrixEvents<T>> implements IMatrixProducer<MatrixItem<T>>, IMatrixReader<MatrixItem<T>>, IMatrixWriter<MatrixItem<T>> {
|
|
51
|
+
constructor(runtime: IFluidDataStoreRuntime, id: string, attributes: IChannelAttributes, _isSetCellConflictResolutionPolicyFWW?: boolean);
|
|
45
52
|
// (undocumented)
|
|
46
53
|
protected applyStashedOp(content: any): unknown;
|
|
47
54
|
// (undocumented)
|
|
@@ -63,6 +70,8 @@ export class SharedMatrix<T = any> extends SharedObject implements IMatrixProduc
|
|
|
63
70
|
// (undocumented)
|
|
64
71
|
insertRows(rowStart: number, count: number): void;
|
|
65
72
|
// (undocumented)
|
|
73
|
+
isSetCellConflictResolutionPolicyFWW(): boolean;
|
|
74
|
+
// (undocumented)
|
|
66
75
|
protected loadCore(storage: IChannelStorageService): Promise<void>;
|
|
67
76
|
// (undocumented)
|
|
68
77
|
get matrixProducer(): IMatrixProducer<MatrixItem<T>>;
|
|
@@ -92,15 +101,16 @@ export class SharedMatrix<T = any> extends SharedObject implements IMatrixProduc
|
|
|
92
101
|
protected submitLocalMessage(message: any, localOpMetadata?: any): void;
|
|
93
102
|
// (undocumented)
|
|
94
103
|
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
|
|
104
|
+
switchSetCellPolicy(): void;
|
|
95
105
|
// (undocumented)
|
|
96
106
|
toString(): string;
|
|
97
|
-
//
|
|
107
|
+
// (undocumented)
|
|
98
108
|
_undoRemoveCols(colStart: number, spec: IJSONSegment): void;
|
|
99
|
-
//
|
|
109
|
+
// (undocumented)
|
|
100
110
|
_undoRemoveRows(rowStart: number, spec: IJSONSegment): void;
|
|
101
111
|
}
|
|
102
112
|
|
|
103
|
-
// @
|
|
113
|
+
// @alpha
|
|
104
114
|
export class SharedMatrixFactory implements IChannelFactory {
|
|
105
115
|
// (undocumented)
|
|
106
116
|
static readonly Attributes: IChannelAttributes;
|
|
@@ -7,8 +7,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.HandleCache = void 0;
|
|
8
8
|
/* eslint-disable no-bitwise */
|
|
9
9
|
const core_utils_1 = require("@fluidframework/core-utils");
|
|
10
|
-
const handletable_1 = require("./handletable");
|
|
11
|
-
const range_1 = require("./range");
|
|
10
|
+
const handletable_1 = require("./handletable.cjs");
|
|
11
|
+
const range_1 = require("./range.cjs");
|
|
12
12
|
/**
|
|
13
13
|
* Used by PermutationVector to cache position -\> handle lookups.
|
|
14
14
|
*
|
|
@@ -108,4 +108,4 @@ class HandleCache {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
exports.HandleCache = HandleCache;
|
|
111
|
-
//# sourceMappingURL=handlecache.
|
|
111
|
+
//# sourceMappingURL=handlecache.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlecache.cjs","sourceRoot":"","sources":["../src/handlecache.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable no-bitwise */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IVectorConsumer } from \"@tiny-calc/nano\";\nimport { Handle, isHandleValid } from \"./handletable\";\nimport { PermutationVector, PermutationSegment } from \"./permutationvector\";\nimport { ensureRange } from \"./range\";\n\n/**\n * Used by PermutationVector to cache position -\\> handle lookups.\n *\n * Perf: Possibly, this should eventually be inlined into PermutationVector itself, but\n * so far there's no measurable perf penalty for being a separate object (node 12 x64)\n */\nexport class HandleCache implements IVectorConsumer<Handle> {\n\tprivate handles: Handle[] = [];\n\tprivate start = 0;\n\n\tconstructor(public readonly vector: PermutationVector) {}\n\n\t/**\n\t * Returns the index of the given position in the 'handles' array as a Uint32.\n\t * (If the position is not in the array, returns an integer greater than 'handles.length').\n\t */\n\tprivate getIndex(position: number) {\n\t\treturn (position - this.start) >>> 0;\n\t}\n\n\t/**\n\t * Returns the handle currently assigned to the given 'position' (if any). Check\n\t * the result with 'isValidHandle(..)' to see if a handle has been allocated for\n\t * the given position.\n\t *\n\t * Throws a 'RangeError' if the provided 'position' is out-of-bounds wrt. the\n\t * PermutationVector's length.\n\t */\n\tpublic getHandle(position: number) {\n\t\tconst index = this.getIndex(position);\n\n\t\t// Perf: To encourage inlining, handling of the 'cacheMiss(..)' case has been extracted\n\t\t// to a separate method.\n\n\t\t// Perf: A cache hit implies that 'position' was in bounds. Therefore, we can defer\n\t\t// checking that 'position' is in bounds until 'cacheMiss(..)'. This yields an\n\t\t// ~40% speedup when the position is in the cache (node v12 x64).\n\n\t\treturn index < this.handles.length ? this.handles[index] : this.cacheMiss(position);\n\t}\n\n\t/** Update the cache when a handle has been allocated for a given position. */\n\tpublic addHandle(position: number, handle: Handle) {\n\t\tassert(isHandleValid(handle), 0x017 /* \"Trying to add invalid handle!\" */);\n\n\t\tconst index = this.getIndex(position);\n\t\tif (index < this.handles.length) {\n\t\t\tassert(\n\t\t\t\t!isHandleValid(this.handles[index]),\n\t\t\t\t0x018 /* \"Trying to insert handle into position with already valid handle!\" */,\n\t\t\t);\n\t\t\tthis.handles[index] = handle;\n\t\t}\n\t}\n\n\t/** Used by 'CacheMiss()' to retrieve handles for a range of positions. */\n\tprivate getHandles(start: number, end: number) {\n\t\t// TODO: This can be accelerated substantially using 'walkSegments()'. The only catch\n\t\t// is that\n\n\t\tconst handles: Handle[] = [];\n\t\tconst { vector } = this;\n\n\t\tfor (let pos = start; pos < end; pos++) {\n\t\t\tconst { segment, offset } = vector.getContainingSegment(pos);\n\t\t\tconst asPerm = segment as PermutationSegment;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\thandles.push(asPerm.start + offset!);\n\t\t}\n\n\t\treturn handles;\n\t}\n\n\tprivate cacheMiss(position: number) {\n\t\t// Coercing 'position' to an Uint32 allows us to handle a negative 'position' value\n\t\t// with the same logic that handles 'position' >= length.\n\t\tconst _position = position >>> 0;\n\n\t\t// TODO: To bound memory usage, there should be a limit on the maximum size of\n\t\t// handle[].\n\n\t\t// TODO: To reduce MergeTree lookups, this code should opportunistically grow\n\t\t// the cache to the next MergeTree segment boundary (within the limits of\n\t\t// the handle cache).\n\n\t\tif (_position < this.start) {\n\t\t\tthis.handles = this.getHandles(_position, this.start).concat(this.handles);\n\t\t\tthis.start = _position;\n\t\t\treturn this.handles[0];\n\t\t} else {\n\t\t\tensureRange(_position, this.vector.getLength());\n\n\t\t\tthis.handles = this.handles.concat(\n\t\t\t\tthis.getHandles(this.start + this.handles.length, _position + 1),\n\t\t\t);\n\t\t\treturn this.handles[this.handles.length - 1];\n\t\t}\n\t}\n\n\t// #region IVectorConsumer\n\n\titemsChanged(start: number, removedCount: number, insertedCount: number): void {\n\t\t// If positions were inserted/removed, our current policy is to trim the array\n\t\t// at the beginning of the invalidate range and lazily repopulate the handles\n\t\t// on demand.\n\t\t//\n\t\t// Some alternatives to consider that preserve the previously cached handles\n\t\t// that are still valid:\n\t\t//\n\t\t// * Eagerly populate the 'handles[]' with the newly insert values (currently guaranteed\n\t\t// to be Handle.unallocated, so we don't even need to look them up.)\n\t\t//\n\t\t// * Use a sentinel value or other mechanism to allow \"holes\" in the cache.\n\n\t\tconst index = this.getIndex(start);\n\t\tif (index < this.handles.length) {\n\t\t\tthis.handles.length = index;\n\t\t}\n\t}\n\n\t// #endregion IVectorConsumer\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handletable.cjs","sourceRoot":"","sources":["../src/handletable.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAkBI,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,wBAAgB,CAAC;AAA3D,QAAA,aAAa,iBAA8C;AAExE;;GAEG;AACH,MAAa,WAAW;IACvB,4FAA4F;IAC5F,2FAA2F;IAC3F,sFAAsF;IACtF,YAAoC,UAA0B,CAAC,CAAC,CAAC;QAA7B,YAAO,GAAP,OAAO,CAAsB;IAAG,CAAC;IAE9D,KAAK;QACX,qFAAqF;QACrF,uFAAuF;QACvF,oBAAoB;QACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACI,QAAQ;QACd,wCAAwC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAEvB,mFAAmF;QACnF,uFAAuF;QACvF,qFAAqF;QACrF,sFAAsF;QACtF,6DAA6D;QAC7D,IAAI,CAAC,IAAI,GAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAY,IAAI,IAAI,GAAG,CAAC,CAAC;QAEvD,mFAAmF;QACnF,sFAAsF;QACtF,qBAAqB;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAc,CAAC;QAEjC,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,KAAa;QAChC,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;YAC/B,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;SAC7B;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,IAAI,CAAC,MAAc;QACzB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;IACpB,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,MAAc;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAM,CAAC;IAClC,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,MAAc,EAAE,KAAQ;QAClC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,wFAAwF;IACxF,uBAAuB;IACvB,IAAY,IAAI;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAW,CAAC;IAClC,CAAC;IACD,IAAY,IAAI,CAAC,MAAc;QAC9B,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAC1B,CAAC;IAEM,iBAAiB;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAEM,MAAM,CAAC,IAAI,CAAI,IAAoB;QACzC,OAAO,IAAI,WAAW,CAAI,IAAI,CAAC,CAAC;IACjC,CAAC;CACD;AApFD,kCAoFC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport const enum Handle {\n\t/**\n\t * Sentinel representing the absence of a valid handle.\n\t */\n\tnone = 0,\n\n\t/** Minimum valid handle. */\n\tvalid = 1,\n\n\t/**\n\t * Sentinel representing an unallocated Handle. Used by PermutationVector\n\t * to delay allocate handles when previously empty row/cols become populated.\n\t */\n\tunallocated = -0x80000000,\n}\n\nexport const isHandleValid = (handle: Handle) => handle >= Handle.valid;\n\n/**\n * A handle table provides a fast mapping from an integer `handle` to a value `T`.\n */\nexport class HandleTable<T> {\n\t// Note: the first slot of the 'handles' array is reserved to store the pointer to the first\n\t// free handle. We initialize this slot with a pointer to slot '1', which will cause\n\t// us to delay allocate the following slot in the array on the first allocation.\n\tpublic constructor(private readonly handles: (Handle | T)[] = [1]) {}\n\n\tpublic clear() {\n\t\t// Restore the HandleTable's initial state by deleting all items in the handles array\n\t\t// and then re-inserting the value '1' in the 0th slot. (See comment at `handles` decl\n\t\t// for explanation.)\n\t\tthis.handles.splice(0, this.handles.length, 1);\n\t}\n\n\t/**\n\t * Allocates and returns the next available handle. Note that freed handles are recycled.\n\t */\n\tpublic allocate(): Handle {\n\t\t// Get the handle to the next free slot.\n\t\tconst free = this.next;\n\n\t\t// Update 'next' to point to the new head of the free list. We use the contents of\n\t\t// recycled slots to store the free list. The contents of the handles[free] will point\n\t\t// to the next available slot. If there are no free slots (i.e., 'handles' is full),\n\t\t// the slot will point to 'handles.length'. In this case, the handles array will grow\n\t\t// and we update 'next' to point to the new end of the array.\n\t\tthis.next = (this.handles[free] as Handle) ?? free + 1;\n\n\t\t// Out of paranoia, overwrite the contents of the newly allocated free slot with an\n\t\t// invalid handle value. This may help catch/diagnose bugs in the event the free list\n\t\t// becomes corrupted.\n\t\tthis.handles[free] = Handle.none;\n\n\t\treturn free;\n\t}\n\n\t/**\n\t * Allocates and returns the next available `count` handles.\n\t */\n\tpublic allocateMany(count: Handle) {\n\t\tconst handles = new Uint32Array(count);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\thandles[i] = this.allocate();\n\t\t}\n\t\treturn handles;\n\t}\n\n\t/**\n\t * Returns the given handle to the free list.\n\t */\n\tpublic free(handle: Handle) {\n\t\tthis.handles[handle] = this.next;\n\t\tthis.next = handle;\n\t}\n\n\t/**\n\t * Get the value `T` associated with the given handle, if any.\n\t */\n\tpublic get(handle: Handle): T {\n\t\treturn this.handles[handle] as T;\n\t}\n\n\t/**\n\t * Set the value `T` associated with the given handle.\n\t */\n\tpublic set(handle: Handle, value: T) {\n\t\tthis.handles[handle] = value;\n\t}\n\n\t// Private helpers to get/set the head of the free list, which is stored in the 0th slot\n\t// of the handle array.\n\tprivate get next() {\n\t\treturn this.handles[0] as Handle;\n\t}\n\tprivate set next(handle: Handle) {\n\t\tthis.handles[0] = handle;\n\t}\n\n\tpublic getSummaryContent() {\n\t\treturn this.handles;\n\t}\n\n\tpublic static load<T>(data: (Handle | T)[]) {\n\t\treturn new HandleTable<T>(data);\n\t}\n}\n"]}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.SharedMatrixFactory = exports.SharedMatrix = void 0;
|
|
8
|
-
var matrix_1 = require("./matrix");
|
|
8
|
+
var matrix_1 = require("./matrix.cjs");
|
|
9
9
|
Object.defineProperty(exports, "SharedMatrix", { enumerable: true, get: function () { return matrix_1.SharedMatrix; } });
|
|
10
|
-
var runtime_1 = require("./runtime");
|
|
10
|
+
var runtime_1 = require("./runtime.cjs");
|
|
11
11
|
Object.defineProperty(exports, "SharedMatrixFactory", { enumerable: true, get: function () { return runtime_1.SharedMatrixFactory; } });
|
|
12
|
-
//# sourceMappingURL=index.
|
|
12
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,uCAAyE;AAA3C,sGAAA,YAAY,OAAA;AAC1C,yCAAgD;AAAvC,8GAAA,mBAAmB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { ISharedMatrixEvents, SharedMatrix, MatrixItem } from \"./matrix\";\nexport { SharedMatrixFactory } from \"./runtime\";\n\n// TODO: We temporarily duplicate these contracts from 'framework/undo-redo' to unblock development\n// of SharedMatrix undo while we decide on the correct layering for undo.\nexport { IUndoConsumer, IRevertible } from \"./types\";\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
export { SharedMatrix, MatrixItem } from "./matrix";
|
|
5
|
+
export { ISharedMatrixEvents, SharedMatrix, MatrixItem } from "./matrix";
|
|
6
6
|
export { SharedMatrixFactory } from "./runtime";
|
|
7
7
|
export { IUndoConsumer, IRevertible } from "./types";
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAIhD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { IChannel } from '@fluidframework/datastore-definitions';
|
|
2
|
+
import { IChannelAttributes } from '@fluidframework/datastore-definitions';
|
|
3
|
+
import { IChannelFactory } from '@fluidframework/datastore-definitions';
|
|
4
|
+
import { IChannelServices } from '@fluidframework/datastore-definitions';
|
|
5
|
+
import { IChannelStorageService } from '@fluidframework/datastore-definitions';
|
|
6
|
+
import { IEventThisPlaceHolder } from '@fluidframework/core-interfaces';
|
|
7
|
+
import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
|
|
8
|
+
import { IFluidSerializer } from '@fluidframework/shared-object-base';
|
|
9
|
+
import { IJSONSegment } from '@fluidframework/merge-tree';
|
|
10
|
+
import { IMatrixConsumer } from '@tiny-calc/nano';
|
|
11
|
+
import { IMatrixProducer } from '@tiny-calc/nano';
|
|
12
|
+
import { IMatrixReader } from '@tiny-calc/nano';
|
|
13
|
+
import { IMatrixWriter } from '@tiny-calc/nano';
|
|
14
|
+
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
|
|
15
|
+
import { ISharedObjectEvents } from '@fluidframework/shared-object-base';
|
|
16
|
+
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
|
|
17
|
+
import { Serializable } from '@fluidframework/datastore-definitions';
|
|
18
|
+
import { SharedObject } from '@fluidframework/shared-object-base';
|
|
19
|
+
import { SummarySerializer } from '@fluidframework/shared-object-base';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @alpha
|
|
23
|
+
*/
|
|
24
|
+
export declare interface IRevertible {
|
|
25
|
+
revert(): any;
|
|
26
|
+
discard(): any;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Events emitted by Shared Matrix.
|
|
31
|
+
* @alpha
|
|
32
|
+
*/
|
|
33
|
+
export declare interface ISharedMatrixEvents<T> extends ISharedObjectEvents {
|
|
34
|
+
/**
|
|
35
|
+
* This event is only emitted when the SetCell Resolution Policy is First Write Win(FWW).
|
|
36
|
+
* This is emitted when two clients race and send changes without observing each other changes,
|
|
37
|
+
* the changes that gets sequenced last would be rejected, and only client who's changes rejected
|
|
38
|
+
* would be notified via this event, with expectation that it will merge its changes back by
|
|
39
|
+
* accounting new information (state from winner of the race).
|
|
40
|
+
*
|
|
41
|
+
* @remarks Listener parameters:
|
|
42
|
+
*
|
|
43
|
+
* - `row` - Row number at which conflict happened.
|
|
44
|
+
*
|
|
45
|
+
* - `col` - Col number at which conflict happened.
|
|
46
|
+
*
|
|
47
|
+
* - `currentValue` - The current value of the cell.
|
|
48
|
+
*
|
|
49
|
+
* - `conflictingValue` - The value that this client tried to set in the cell and got ignored due to conflict.
|
|
50
|
+
*
|
|
51
|
+
* - `target` - The {@link SharedMatrix} itself.
|
|
52
|
+
*/
|
|
53
|
+
(event: "conflict", listener: (row: number, col: number, currentValue: MatrixItem<T>, conflictingValue: MatrixItem<T>, target: IEventThisPlaceHolder) => void): any;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @alpha
|
|
58
|
+
*/
|
|
59
|
+
export declare interface IUndoConsumer {
|
|
60
|
+
pushToCurrentOperation(revertible: IRevertible): any;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A matrix cell value may be undefined (indicating an empty cell) or any serializable type,
|
|
65
|
+
* excluding null. (However, nulls may be embedded inside objects and arrays.)
|
|
66
|
+
* @alpha
|
|
67
|
+
*/
|
|
68
|
+
export declare type MatrixItem<T> = Serializable<Exclude<T, null>> | undefined;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A SharedMatrix holds a rectangular 2D array of values. Supported operations
|
|
72
|
+
* include setting values and inserting/removing rows and columns.
|
|
73
|
+
*
|
|
74
|
+
* Matrix values may be any Fluid serializable type, which is the set of JSON
|
|
75
|
+
* serializable types extended to include IFluidHandles.
|
|
76
|
+
*
|
|
77
|
+
* Fluid's SharedMatrix implementation works equally well for dense and sparse
|
|
78
|
+
* matrix data and physically stores data in Z-order to leverage CPU caches and
|
|
79
|
+
* prefetching when reading in either row or column major order. (See README.md
|
|
80
|
+
* for more details.)
|
|
81
|
+
* @alpha
|
|
82
|
+
*/
|
|
83
|
+
export declare class SharedMatrix<T = any> extends SharedObject<ISharedMatrixEvents<T>> implements IMatrixProducer<MatrixItem<T>>, IMatrixReader<MatrixItem<T>>, IMatrixWriter<MatrixItem<T>> {
|
|
84
|
+
id: string;
|
|
85
|
+
private readonly consumers;
|
|
86
|
+
static getFactory(): SharedMatrixFactory;
|
|
87
|
+
private readonly rows;
|
|
88
|
+
private readonly cols;
|
|
89
|
+
private cells;
|
|
90
|
+
private readonly pending;
|
|
91
|
+
private cellLastWriteTracker;
|
|
92
|
+
private setCellLwwToFwwPolicySwitchOpSeqNumber;
|
|
93
|
+
private userSwitchedSetCellPolicy;
|
|
94
|
+
private reentrantCount;
|
|
95
|
+
/**
|
|
96
|
+
* Constructor for the Shared Matrix
|
|
97
|
+
* @param runtime - DataStore runtime.
|
|
98
|
+
* @param id - id of the dds
|
|
99
|
+
* @param attributes - channel attributes
|
|
100
|
+
* @param _isSetCellConflictResolutionPolicyFWW - Conflict resolution for Matrix set op is First Writer Win in case of
|
|
101
|
+
* race condition. Client can still overwrite values in case of no race.
|
|
102
|
+
*/
|
|
103
|
+
constructor(runtime: IFluidDataStoreRuntime, id: string, attributes: IChannelAttributes, _isSetCellConflictResolutionPolicyFWW?: boolean);
|
|
104
|
+
private undo?;
|
|
105
|
+
/**
|
|
106
|
+
* Subscribes the given IUndoConsumer to the matrix.
|
|
107
|
+
*/
|
|
108
|
+
openUndo(consumer: IUndoConsumer): void;
|
|
109
|
+
private get rowHandles();
|
|
110
|
+
private get colHandles();
|
|
111
|
+
/**
|
|
112
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}
|
|
113
|
+
*/
|
|
114
|
+
static create<T>(runtime: IFluidDataStoreRuntime, id?: string): SharedMatrix<T>;
|
|
115
|
+
openMatrix(consumer: IMatrixConsumer<MatrixItem<T>>): IMatrixReader<MatrixItem<T>>;
|
|
116
|
+
closeMatrix(consumer: IMatrixConsumer<MatrixItem<T>>): void;
|
|
117
|
+
get rowCount(): number;
|
|
118
|
+
get colCount(): number;
|
|
119
|
+
isSetCellConflictResolutionPolicyFWW(): boolean;
|
|
120
|
+
getCell(row: number, col: number): MatrixItem<T>;
|
|
121
|
+
get matrixProducer(): IMatrixProducer<MatrixItem<T>>;
|
|
122
|
+
setCell(row: number, col: number, value: MatrixItem<T>): void;
|
|
123
|
+
setCells(rowStart: number, colStart: number, colCount: number, values: readonly MatrixItem<T>[]): void;
|
|
124
|
+
private setCellCore;
|
|
125
|
+
private sendSetCellOp;
|
|
126
|
+
/**
|
|
127
|
+
* This makes sure that the code inside the callback is not reentrant. We need to do that because we raise notifications
|
|
128
|
+
* to the consumers telling about these changes and they can try to change the matrix while listening to those notifications
|
|
129
|
+
* which can make the shared matrix to be in bad state. For example, we are raising notification for a setCell changes and
|
|
130
|
+
* a consumer tries to delete that row/col on receiving that notification which can lead to this matrix trying to setCell in
|
|
131
|
+
* a deleted row/col.
|
|
132
|
+
* @param callback - code that needs to protected against reentrancy.
|
|
133
|
+
*/
|
|
134
|
+
private protectAgainstReentrancy;
|
|
135
|
+
private submitVectorMessage;
|
|
136
|
+
private submitColMessage;
|
|
137
|
+
insertCols(colStart: number, count: number): void;
|
|
138
|
+
removeCols(colStart: number, count: number): void;
|
|
139
|
+
private submitRowMessage;
|
|
140
|
+
insertRows(rowStart: number, count: number): void;
|
|
141
|
+
removeRows(rowStart: number, count: number): void;
|
|
142
|
+
/***/ _undoRemoveRows(rowStart: number, spec: IJSONSegment): void;
|
|
143
|
+
/***/ _undoRemoveCols(colStart: number, spec: IJSONSegment): void;
|
|
144
|
+
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
|
|
145
|
+
/**
|
|
146
|
+
* Runs serializer on the GC data for this SharedMatrix.
|
|
147
|
+
* All the IFluidHandle's stored in the cells represent routes to other objects.
|
|
148
|
+
*/
|
|
149
|
+
protected processGCDataCore(serializer: SummarySerializer): void;
|
|
150
|
+
/**
|
|
151
|
+
* Advances the 'localSeq' counter for the cell data operation currently being queued.
|
|
152
|
+
*
|
|
153
|
+
* Do not use with 'submitColMessage()/submitRowMessage()' as these helpers + the MergeTree will
|
|
154
|
+
* automatically advance 'localSeq'.
|
|
155
|
+
*/
|
|
156
|
+
private nextLocalSeq;
|
|
157
|
+
protected submitLocalMessage(message: any, localOpMetadata?: any): void;
|
|
158
|
+
protected didAttach(): void;
|
|
159
|
+
protected onConnect(): void;
|
|
160
|
+
private rebasePosition;
|
|
161
|
+
protected reSubmitCore(content: any, localOpMetadata: unknown): void;
|
|
162
|
+
protected onDisconnect(): void;
|
|
163
|
+
/**
|
|
164
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}
|
|
165
|
+
*/
|
|
166
|
+
protected loadCore(storage: IChannelStorageService): Promise<void>;
|
|
167
|
+
/**
|
|
168
|
+
* Tells whether the setCell op should be applied or not based on First Write Win policy. It assumes
|
|
169
|
+
* we are in FWW mode.
|
|
170
|
+
*/
|
|
171
|
+
private shouldSetCellBasedOnFWW;
|
|
172
|
+
protected processCore(rawMessage: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
|
|
173
|
+
private readonly onRowDelta;
|
|
174
|
+
private readonly onColDelta;
|
|
175
|
+
private readonly onRowHandlesRecycled;
|
|
176
|
+
private readonly onColHandlesRecycled;
|
|
177
|
+
/**
|
|
178
|
+
* Api to switch Set Op policy from Last Writer Win to First Writer Win. It only switches from LWW to FWW
|
|
179
|
+
* and not from FWW to LWW. The next SetOp which is sent will communicate this policy to other clients.
|
|
180
|
+
*/
|
|
181
|
+
switchSetCellPolicy(): void;
|
|
182
|
+
/**
|
|
183
|
+
* Returns true if the latest pending write to the cell indicated by the given row/col handles
|
|
184
|
+
* matches the given 'localSeq'.
|
|
185
|
+
*
|
|
186
|
+
* A return value of `true` indicates that there are no later local operations queued that will
|
|
187
|
+
* clobber the write op at the given 'localSeq'. This includes later ops that overwrite the cell
|
|
188
|
+
* with a different value as well as row/col removals that might recycled the given row/col handles.
|
|
189
|
+
*/
|
|
190
|
+
private isLatestPendingWrite;
|
|
191
|
+
toString(): string;
|
|
192
|
+
/**
|
|
193
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
|
|
194
|
+
*/
|
|
195
|
+
protected applyStashedOp(content: any): unknown;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* {@link @fluidframework/datastore-definitions#IChannelFactory} for {@link SharedMatrix}.
|
|
200
|
+
* @alpha
|
|
201
|
+
*/
|
|
202
|
+
export declare class SharedMatrixFactory implements IChannelFactory {
|
|
203
|
+
static Type: string;
|
|
204
|
+
static readonly Attributes: IChannelAttributes;
|
|
205
|
+
get type(): string;
|
|
206
|
+
get attributes(): IChannelAttributes;
|
|
207
|
+
/**
|
|
208
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}
|
|
209
|
+
*/
|
|
210
|
+
load(runtime: IFluidDataStoreRuntime, id: string, services: IChannelServices, attributes: IChannelAttributes): Promise<IChannel>;
|
|
211
|
+
create(document: IFluidDataStoreRuntime, id: string): IChannel;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export { }
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { IChannel } from '@fluidframework/datastore-definitions';
|
|
2
|
+
import { IChannelAttributes } from '@fluidframework/datastore-definitions';
|
|
3
|
+
import { IChannelFactory } from '@fluidframework/datastore-definitions';
|
|
4
|
+
import { IChannelServices } from '@fluidframework/datastore-definitions';
|
|
5
|
+
import { IChannelStorageService } from '@fluidframework/datastore-definitions';
|
|
6
|
+
import { IEventThisPlaceHolder } from '@fluidframework/core-interfaces';
|
|
7
|
+
import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
|
|
8
|
+
import { IFluidSerializer } from '@fluidframework/shared-object-base';
|
|
9
|
+
import { IJSONSegment } from '@fluidframework/merge-tree';
|
|
10
|
+
import { IMatrixConsumer } from '@tiny-calc/nano';
|
|
11
|
+
import { IMatrixProducer } from '@tiny-calc/nano';
|
|
12
|
+
import { IMatrixReader } from '@tiny-calc/nano';
|
|
13
|
+
import { IMatrixWriter } from '@tiny-calc/nano';
|
|
14
|
+
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
|
|
15
|
+
import { ISharedObjectEvents } from '@fluidframework/shared-object-base';
|
|
16
|
+
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
|
|
17
|
+
import { Serializable } from '@fluidframework/datastore-definitions';
|
|
18
|
+
import { SharedObject } from '@fluidframework/shared-object-base';
|
|
19
|
+
import { SummarySerializer } from '@fluidframework/shared-object-base';
|
|
20
|
+
|
|
21
|
+
/* Excluded from this release type: IChannel */
|
|
22
|
+
|
|
23
|
+
/* Excluded from this release type: IChannelAttributes */
|
|
24
|
+
|
|
25
|
+
/* Excluded from this release type: IChannelFactory */
|
|
26
|
+
|
|
27
|
+
/* Excluded from this release type: IChannelServices */
|
|
28
|
+
|
|
29
|
+
/* Excluded from this release type: IChannelStorageService */
|
|
30
|
+
|
|
31
|
+
/* Excluded from this release type: IEventThisPlaceHolder */
|
|
32
|
+
|
|
33
|
+
/* Excluded from this release type: IFluidDataStoreRuntime */
|
|
34
|
+
|
|
35
|
+
/* Excluded from this release type: IFluidSerializer */
|
|
36
|
+
|
|
37
|
+
/* Excluded from this release type: IJSONSegment */
|
|
38
|
+
|
|
39
|
+
/* Excluded from this release type: IRevertible */
|
|
40
|
+
|
|
41
|
+
/* Excluded from this release type: ISharedMatrixEvents */
|
|
42
|
+
|
|
43
|
+
/* Excluded from this release type: ISharedObjectEvents */
|
|
44
|
+
|
|
45
|
+
/* Excluded from this release type: ISummaryTreeWithStats */
|
|
46
|
+
|
|
47
|
+
/* Excluded from this release type: IUndoConsumer */
|
|
48
|
+
|
|
49
|
+
/* Excluded from this release type: MatrixItem */
|
|
50
|
+
|
|
51
|
+
/* Excluded from this release type: Serializable */
|
|
52
|
+
|
|
53
|
+
/* Excluded from this release type: SharedMatrix */
|
|
54
|
+
|
|
55
|
+
/* Excluded from this release type: SharedMatrixFactory */
|
|
56
|
+
|
|
57
|
+
/* Excluded from this release type: SharedObject */
|
|
58
|
+
|
|
59
|
+
/* Excluded from this release type: SummarySerializer */
|
|
60
|
+
|
|
61
|
+
export { }
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { IChannel } from '@fluidframework/datastore-definitions';
|
|
2
|
+
import { IChannelAttributes } from '@fluidframework/datastore-definitions';
|
|
3
|
+
import { IChannelFactory } from '@fluidframework/datastore-definitions';
|
|
4
|
+
import { IChannelServices } from '@fluidframework/datastore-definitions';
|
|
5
|
+
import { IChannelStorageService } from '@fluidframework/datastore-definitions';
|
|
6
|
+
import { IEventThisPlaceHolder } from '@fluidframework/core-interfaces';
|
|
7
|
+
import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
|
|
8
|
+
import { IFluidSerializer } from '@fluidframework/shared-object-base';
|
|
9
|
+
import { IJSONSegment } from '@fluidframework/merge-tree';
|
|
10
|
+
import { IMatrixConsumer } from '@tiny-calc/nano';
|
|
11
|
+
import { IMatrixProducer } from '@tiny-calc/nano';
|
|
12
|
+
import { IMatrixReader } from '@tiny-calc/nano';
|
|
13
|
+
import { IMatrixWriter } from '@tiny-calc/nano';
|
|
14
|
+
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
|
|
15
|
+
import { ISharedObjectEvents } from '@fluidframework/shared-object-base';
|
|
16
|
+
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
|
|
17
|
+
import { Serializable } from '@fluidframework/datastore-definitions';
|
|
18
|
+
import { SharedObject } from '@fluidframework/shared-object-base';
|
|
19
|
+
import { SummarySerializer } from '@fluidframework/shared-object-base';
|
|
20
|
+
|
|
21
|
+
/* Excluded from this release type: IChannel */
|
|
22
|
+
|
|
23
|
+
/* Excluded from this release type: IChannelAttributes */
|
|
24
|
+
|
|
25
|
+
/* Excluded from this release type: IChannelFactory */
|
|
26
|
+
|
|
27
|
+
/* Excluded from this release type: IChannelServices */
|
|
28
|
+
|
|
29
|
+
/* Excluded from this release type: IChannelStorageService */
|
|
30
|
+
|
|
31
|
+
/* Excluded from this release type: IEventThisPlaceHolder */
|
|
32
|
+
|
|
33
|
+
/* Excluded from this release type: IFluidDataStoreRuntime */
|
|
34
|
+
|
|
35
|
+
/* Excluded from this release type: IFluidSerializer */
|
|
36
|
+
|
|
37
|
+
/* Excluded from this release type: IJSONSegment */
|
|
38
|
+
|
|
39
|
+
/* Excluded from this release type: IRevertible */
|
|
40
|
+
|
|
41
|
+
/* Excluded from this release type: ISharedMatrixEvents */
|
|
42
|
+
|
|
43
|
+
/* Excluded from this release type: ISharedObjectEvents */
|
|
44
|
+
|
|
45
|
+
/* Excluded from this release type: ISummaryTreeWithStats */
|
|
46
|
+
|
|
47
|
+
/* Excluded from this release type: IUndoConsumer */
|
|
48
|
+
|
|
49
|
+
/* Excluded from this release type: MatrixItem */
|
|
50
|
+
|
|
51
|
+
/* Excluded from this release type: Serializable */
|
|
52
|
+
|
|
53
|
+
/* Excluded from this release type: SharedMatrix */
|
|
54
|
+
|
|
55
|
+
/* Excluded from this release type: SharedMatrixFactory */
|
|
56
|
+
|
|
57
|
+
/* Excluded from this release type: SharedObject */
|
|
58
|
+
|
|
59
|
+
/* Excluded from this release type: SummarySerializer */
|
|
60
|
+
|
|
61
|
+
export { }
|