@fluidframework/cell 2.0.0-internal.2.2.1 → 2.0.0-internal.2.3.1
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 +5 -1
- package/README.md +95 -1
- package/dist/cell.d.ts +30 -69
- package/dist/cell.d.ts.map +1 -1
- package/dist/cell.js +34 -69
- package/dist/cell.js.map +1 -1
- package/dist/cellFactory.d.ts +18 -1
- package/dist/cellFactory.d.ts.map +1 -1
- package/dist/cellFactory.js +18 -1
- package/dist/cellFactory.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +70 -3
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/cell.d.ts +30 -69
- package/lib/cell.d.ts.map +1 -1
- package/lib/cell.js +34 -69
- package/lib/cell.js.map +1 -1
- package/lib/cellFactory.d.ts +18 -1
- package/lib/cellFactory.d.ts.map +1 -1
- package/lib/cellFactory.js +18 -1
- package/lib/cellFactory.js.map +1 -1
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -1
- package/lib/interfaces.d.ts +70 -3
- package/lib/interfaces.d.ts.map +1 -1
- package/lib/interfaces.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/package.json +13 -13
- package/src/cell.ts +54 -87
- package/src/cellFactory.ts +20 -3
- package/src/index.ts +6 -0
- package/src/interfaces.ts +77 -4
- package/src/packageVersion.ts +1 -1
package/.eslintrc.js
CHANGED
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
module.exports = {
|
|
7
7
|
"extends": [
|
|
8
|
-
require.resolve("@fluidframework/eslint-config-fluid"), "prettier"
|
|
8
|
+
require.resolve("@fluidframework/eslint-config-fluid/strict"), "prettier"
|
|
9
9
|
],
|
|
10
10
|
"parserOptions": {
|
|
11
11
|
"project": ["./tsconfig.json", "./src/test/tsconfig.json"]
|
|
12
12
|
},
|
|
13
|
+
"rules": {
|
|
14
|
+
// TODO: consider re-enabling once we have addressed how this rule conflicts with our error codes.
|
|
15
|
+
"unicorn/numeric-separators-style": "off",
|
|
16
|
+
}
|
|
13
17
|
}
|
package/README.md
CHANGED
|
@@ -1,3 +1,97 @@
|
|
|
1
1
|
# @fluidframework/cell
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The `SharedCell` Distributed Data Structure (DDS) stores a single, shared value that can be edited or deleted.
|
|
4
|
+
|
|
5
|
+
<!-- AUTO-GENERATED-CONTENT:START (README_INSTALLATION_SECTION:includeHeading=TRUE) -->
|
|
6
|
+
|
|
7
|
+
<!-- prettier-ignore-start -->
|
|
8
|
+
|
|
9
|
+
<!-- This section is automatically generated. To update it, make the appropriate changes to docs/md-magic.config.js or the embedded content, then run 'npm run build:md-magic' in the docs folder. -->
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
To get started, install the package by running the following command:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm i @fluidframework/cell
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
<!-- prettier-ignore-end -->
|
|
20
|
+
|
|
21
|
+
<!-- AUTO-GENERATED-CONTENT:END -->
|
|
22
|
+
|
|
23
|
+
<!-- AUTO-GENERATED-CONTENT:START (README_API_DOCS_SECTION:includeHeading=TRUE) -->
|
|
24
|
+
|
|
25
|
+
<!-- prettier-ignore-start -->
|
|
26
|
+
|
|
27
|
+
<!-- This section is automatically generated. To update it, make the appropriate changes to docs/md-magic.config.js or the embedded content, then run 'npm run build:md-magic' in the docs folder. -->
|
|
28
|
+
|
|
29
|
+
## API Documentation
|
|
30
|
+
|
|
31
|
+
API documentation for **@fluidframework/cell** is available at <https://fluidframework.com/docs/apis/cell>.
|
|
32
|
+
|
|
33
|
+
<!-- prettier-ignore-end -->
|
|
34
|
+
|
|
35
|
+
<!-- AUTO-GENERATED-CONTENT:END -->
|
|
36
|
+
|
|
37
|
+
<!-- AUTO-GENERATED-CONTENT:START (README_CONTRIBUTION_GUIDELINES_SECTION:includeHeading=TRUE) -->
|
|
38
|
+
|
|
39
|
+
<!-- prettier-ignore-start -->
|
|
40
|
+
|
|
41
|
+
<!-- This section is automatically generated. To update it, make the appropriate changes to docs/md-magic.config.js or the embedded content, then run 'npm run build:md-magic' in the docs folder. -->
|
|
42
|
+
|
|
43
|
+
## Contribution Guidelines
|
|
44
|
+
|
|
45
|
+
There are many ways to [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid.
|
|
46
|
+
|
|
47
|
+
- Participate in Q&A in our [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
|
|
48
|
+
- [Submit bugs](https://github.com/microsoft/FluidFramework/issues) and help us verify fixes as they are checked in.
|
|
49
|
+
- Review the [source code changes](https://github.com/microsoft/FluidFramework/pulls).
|
|
50
|
+
- [Contribute bug fixes](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md).
|
|
51
|
+
|
|
52
|
+
Detailed instructions for working in the repo can be found in the [Wiki](https://github.com/microsoft/FluidFramework/wiki).
|
|
53
|
+
|
|
54
|
+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
|
55
|
+
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
|
56
|
+
|
|
57
|
+
This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
|
|
58
|
+
Use of these trademarks or logos must follow Microsoft’s [Trademark & Brand Guidelines](https://www.microsoft.com/trademarks).
|
|
59
|
+
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
|
|
60
|
+
|
|
61
|
+
<!-- prettier-ignore-end -->
|
|
62
|
+
|
|
63
|
+
<!-- AUTO-GENERATED-CONTENT:END -->
|
|
64
|
+
|
|
65
|
+
<!-- AUTO-GENERATED-CONTENT:START (README_HELP_SECTION:includeHeading=TRUE) -->
|
|
66
|
+
|
|
67
|
+
<!-- prettier-ignore-start -->
|
|
68
|
+
|
|
69
|
+
<!-- This section is automatically generated. To update it, make the appropriate changes to docs/md-magic.config.js or the embedded content, then run 'npm run build:md-magic' in the docs folder. -->
|
|
70
|
+
|
|
71
|
+
## Help
|
|
72
|
+
|
|
73
|
+
Not finding what you're looking for in this README?
|
|
74
|
+
Check out our [GitHub Wiki](https://github.com/microsoft/FluidFramework/wiki) or [fluidframework.com](https://fluidframework.com/docs/).
|
|
75
|
+
|
|
76
|
+
Still not finding what you're looking for? Please [file an issue](https://github.com/microsoft/FluidFramework/wiki/Submitting-Bugs-and-Feature-Requests).
|
|
77
|
+
Thank you!
|
|
78
|
+
|
|
79
|
+
<!-- prettier-ignore-end -->
|
|
80
|
+
|
|
81
|
+
<!-- AUTO-GENERATED-CONTENT:END -->
|
|
82
|
+
|
|
83
|
+
<!-- AUTO-GENERATED-CONTENT:START (README_TRADEMARK_SECTION:includeHeading=TRUE) -->
|
|
84
|
+
|
|
85
|
+
<!-- prettier-ignore-start -->
|
|
86
|
+
|
|
87
|
+
<!-- This section is automatically generated. To update it, make the appropriate changes to docs/md-magic.config.js or the embedded content, then run 'npm run build:md-magic' in the docs folder. -->
|
|
88
|
+
|
|
89
|
+
## Trademark
|
|
90
|
+
|
|
91
|
+
This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
|
|
92
|
+
Use of these trademarks or logos must follow Microsoft's [Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
|
|
93
|
+
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
|
|
94
|
+
|
|
95
|
+
<!-- prettier-ignore-end -->
|
|
96
|
+
|
|
97
|
+
<!-- AUTO-GENERATED-CONTENT:END -->
|
package/dist/cell.d.ts
CHANGED
|
@@ -8,65 +8,22 @@ import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
|
|
|
8
8
|
import { IFluidSerializer, SharedObject } from "@fluidframework/shared-object-base";
|
|
9
9
|
import { ISharedCell, ISharedCellEvents } from "./interfaces";
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @remarks
|
|
14
|
-
* ### Creation
|
|
15
|
-
*
|
|
16
|
-
* To create a `SharedCell`, call the static create method:
|
|
17
|
-
*
|
|
18
|
-
* ```typescript
|
|
19
|
-
* const myCell = SharedCell.create(this.runtime, id);
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* ### Usage
|
|
23
|
-
*
|
|
24
|
-
* The value stored in the cell can be set with the `.set()` method and retrieved with the `.get()` method:
|
|
25
|
-
*
|
|
26
|
-
* ```typescript
|
|
27
|
-
* myCell.set(3);
|
|
28
|
-
* console.log(myCell.get()); // 3
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* The value must only be plain JS objects or `SharedObject` handles (e.g. to another DDS or Fluid object).
|
|
32
|
-
* In collaborative scenarios, the value is settled with a policy of _last write wins_.
|
|
33
|
-
*
|
|
34
|
-
* The `.delete()` method will delete the stored value from the cell:
|
|
35
|
-
*
|
|
36
|
-
* ```typescript
|
|
37
|
-
* myCell.delete();
|
|
38
|
-
* console.log(myCell.get()); // undefined
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* The `.empty()` method will check if the value is undefined.
|
|
42
|
-
*
|
|
43
|
-
* ```typescript
|
|
44
|
-
* if (myCell.empty()) {
|
|
45
|
-
* // myCell.get() will return undefined
|
|
46
|
-
* } else {
|
|
47
|
-
* // myCell.get() will return a non-undefined value
|
|
48
|
-
* }
|
|
49
|
-
* ```
|
|
50
|
-
*
|
|
51
|
-
* ### Eventing
|
|
52
|
-
*
|
|
53
|
-
* `SharedCell` is an `EventEmitter`, and will emit events when other clients make modifications. You should
|
|
54
|
-
* register for these events and respond appropriately as the data is modified. `valueChanged` will be emitted
|
|
55
|
-
* in response to a `set`, and `delete` will be emitted in response to a `delete`.
|
|
11
|
+
* {@inheritDoc ISharedCell}
|
|
56
12
|
*/
|
|
57
13
|
export declare class SharedCell<T = any> extends SharedObject<ISharedCellEvents<T>> implements ISharedCell<T> {
|
|
58
14
|
/**
|
|
59
|
-
* Create a new
|
|
15
|
+
* Create a new `SharedCell`.
|
|
60
16
|
*
|
|
61
|
-
* @param runtime - data store runtime
|
|
62
|
-
* @param id -
|
|
63
|
-
*
|
|
17
|
+
* @param runtime - The data store runtime to which the `SharedCell` belongs.
|
|
18
|
+
* @param id - Unique identifier for the `SharedCell`.
|
|
19
|
+
*
|
|
20
|
+
* @returns The newly create `SharedCell`. Note that it will not yet be attached.
|
|
64
21
|
*/
|
|
65
|
-
static create(runtime: IFluidDataStoreRuntime, id?: string): SharedCell
|
|
22
|
+
static create(runtime: IFluidDataStoreRuntime, id?: string): SharedCell;
|
|
66
23
|
/**
|
|
67
|
-
*
|
|
24
|
+
* Gets the factory for the `SharedCell` to register with the data store.
|
|
68
25
|
*
|
|
69
|
-
* @returns
|
|
26
|
+
* @returns A factory that creates and loads `SharedCell`s.
|
|
70
27
|
*/
|
|
71
28
|
static getFactory(): IChannelFactory;
|
|
72
29
|
/**
|
|
@@ -85,11 +42,11 @@ export declare class SharedCell<T = any> extends SharedObject<ISharedCellEvents<
|
|
|
85
42
|
private messageIdObserved;
|
|
86
43
|
private readonly pendingMessageIds;
|
|
87
44
|
/**
|
|
88
|
-
* Constructs a new
|
|
89
|
-
* be provided
|
|
45
|
+
* Constructs a new `SharedCell`.
|
|
46
|
+
* If the object is non-local an id and service interfaces will be provided.
|
|
90
47
|
*
|
|
91
|
-
* @param runtime - data store runtime the
|
|
92
|
-
* @param id -
|
|
48
|
+
* @param runtime - The data store runtime to which the `SharedCell` belongs.
|
|
49
|
+
* @param id - Unique identifier for the `SharedCell`.
|
|
93
50
|
*/
|
|
94
51
|
constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes);
|
|
95
52
|
/**
|
|
@@ -109,9 +66,9 @@ export declare class SharedCell<T = any> extends SharedObject<ISharedCellEvents<
|
|
|
109
66
|
*/
|
|
110
67
|
empty(): boolean;
|
|
111
68
|
/**
|
|
112
|
-
*
|
|
69
|
+
* Creates a summary for the Cell.
|
|
113
70
|
*
|
|
114
|
-
* @returns
|
|
71
|
+
* @returns The summary of the current state of the Cell.
|
|
115
72
|
*/
|
|
116
73
|
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
|
|
117
74
|
/**
|
|
@@ -119,25 +76,26 @@ export declare class SharedCell<T = any> extends SharedObject<ISharedCellEvents<
|
|
|
119
76
|
*/
|
|
120
77
|
protected loadCore(storage: IChannelStorageService): Promise<void>;
|
|
121
78
|
/**
|
|
122
|
-
* Initialize a local instance of cell
|
|
79
|
+
* Initialize a local instance of cell.
|
|
123
80
|
*/
|
|
124
81
|
protected initializeLocalCore(): void;
|
|
125
82
|
/**
|
|
126
|
-
* Call back on disconnect
|
|
83
|
+
* Call back on disconnect.
|
|
127
84
|
*/
|
|
128
85
|
protected onDisconnect(): void;
|
|
129
86
|
/**
|
|
130
|
-
* Apply inner op
|
|
87
|
+
* Apply inner op.
|
|
88
|
+
*
|
|
131
89
|
* @param content - ICellOperation content
|
|
132
90
|
*/
|
|
133
91
|
private applyInnerOp;
|
|
134
92
|
/**
|
|
135
|
-
* Process a cell operation
|
|
93
|
+
* Process a cell operation (op).
|
|
136
94
|
*
|
|
137
|
-
* @param message -
|
|
138
|
-
* @param local -
|
|
95
|
+
* @param message - The message to prepare.
|
|
96
|
+
* @param local - Whether or not the message was sent by the local client.
|
|
139
97
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
140
|
-
* For messages from a remote client, this will be undefined
|
|
98
|
+
* For messages from a remote client, this will be `undefined`.
|
|
141
99
|
*/
|
|
142
100
|
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
|
|
143
101
|
private setCore;
|
|
@@ -146,19 +104,22 @@ export declare class SharedCell<T = any> extends SharedObject<ISharedCellEvents<
|
|
|
146
104
|
private createLocalOpMetadata;
|
|
147
105
|
/**
|
|
148
106
|
* {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
|
|
107
|
+
*
|
|
149
108
|
* @internal
|
|
150
109
|
*/
|
|
151
110
|
protected applyStashedOp(content: unknown): unknown;
|
|
152
111
|
/**
|
|
153
|
-
* Rollback a local op
|
|
154
|
-
*
|
|
112
|
+
* Rollback a local op.
|
|
113
|
+
*
|
|
114
|
+
* @param content - The operation to rollback.
|
|
155
115
|
* @param localOpMetadata - The local metadata associated with the op.
|
|
156
116
|
*/
|
|
157
117
|
protected rollback(content: any, localOpMetadata: unknown): void;
|
|
158
118
|
/**
|
|
159
119
|
* Submit a cell message to remote clients.
|
|
160
|
-
*
|
|
161
|
-
* @param
|
|
120
|
+
*
|
|
121
|
+
* @param op - The cell message.
|
|
122
|
+
* @param previousValue - The value of the cell before this op.
|
|
162
123
|
*/
|
|
163
124
|
private submitCellMessage;
|
|
164
125
|
}
|
package/dist/cell.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell.d.ts","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,YAAY,EACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE5E,OAAO,EAA2B,gBAAgB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAE7G,OAAO,EACH,WAAW,EACX,iBAAiB,EAEpB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"cell.d.ts","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,YAAY,EACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE5E,OAAO,EAA2B,gBAAgB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAE7G,OAAO,EACH,WAAW,EACX,iBAAiB,EAEpB,MAAM,cAAc,CAAC;AAyBtB;;GAEG;AAGH,qBAAa,UAAU,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,YAAY,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;IACjG;;;;;;;OAOG;WACW,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU;IAI9E;;;;OAIG;WACW,UAAU,IAAI,eAAe;IAI3C;;OAEG;IACH,OAAO,CAAC,IAAI,CAA8B;IAE1C;;;OAGG;IACH,OAAO,CAAC,SAAS,CAAc;IAE/B;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAc;IAEvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgB;IAElD;;;;;;OAMG;gBACgB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,kBAAkB;IAI9F;;OAEG;IACI,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS;IAIzC;;OAEG;IACI,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAqBxC;;OAEG;IACI,MAAM,IAAI,IAAI;IAerB;;OAEG;IACI,KAAK,IAAI,OAAO;IAIvB;;;;OAIG;IACH,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,qBAAqB;IAK5E;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxE;;OAEG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAIrC;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAE9B;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAapB;;;;;;;OAOG;IACH,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAwBzG,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,qBAAqB;IAS7B;;;;OAIG;IACH,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAMnD;;;;;OAKG;IAGH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAmB/D;;;;;MAKE;IACH,OAAO,CAAC,iBAAiB;CAI5B"}
|
package/dist/cell.js
CHANGED
|
@@ -12,59 +12,17 @@ const shared_object_base_1 = require("@fluidframework/shared-object-base");
|
|
|
12
12
|
const cellFactory_1 = require("./cellFactory");
|
|
13
13
|
const snapshotFileName = "header";
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @remarks
|
|
18
|
-
* ### Creation
|
|
19
|
-
*
|
|
20
|
-
* To create a `SharedCell`, call the static create method:
|
|
21
|
-
*
|
|
22
|
-
* ```typescript
|
|
23
|
-
* const myCell = SharedCell.create(this.runtime, id);
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* ### Usage
|
|
27
|
-
*
|
|
28
|
-
* The value stored in the cell can be set with the `.set()` method and retrieved with the `.get()` method:
|
|
29
|
-
*
|
|
30
|
-
* ```typescript
|
|
31
|
-
* myCell.set(3);
|
|
32
|
-
* console.log(myCell.get()); // 3
|
|
33
|
-
* ```
|
|
34
|
-
*
|
|
35
|
-
* The value must only be plain JS objects or `SharedObject` handles (e.g. to another DDS or Fluid object).
|
|
36
|
-
* In collaborative scenarios, the value is settled with a policy of _last write wins_.
|
|
37
|
-
*
|
|
38
|
-
* The `.delete()` method will delete the stored value from the cell:
|
|
39
|
-
*
|
|
40
|
-
* ```typescript
|
|
41
|
-
* myCell.delete();
|
|
42
|
-
* console.log(myCell.get()); // undefined
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* The `.empty()` method will check if the value is undefined.
|
|
46
|
-
*
|
|
47
|
-
* ```typescript
|
|
48
|
-
* if (myCell.empty()) {
|
|
49
|
-
* // myCell.get() will return undefined
|
|
50
|
-
* } else {
|
|
51
|
-
* // myCell.get() will return a non-undefined value
|
|
52
|
-
* }
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* ### Eventing
|
|
56
|
-
*
|
|
57
|
-
* `SharedCell` is an `EventEmitter`, and will emit events when other clients make modifications. You should
|
|
58
|
-
* register for these events and respond appropriately as the data is modified. `valueChanged` will be emitted
|
|
59
|
-
* in response to a `set`, and `delete` will be emitted in response to a `delete`.
|
|
15
|
+
* {@inheritDoc ISharedCell}
|
|
60
16
|
*/
|
|
17
|
+
// TODO: use `unknown` instead (breaking change).
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
19
|
class SharedCell extends shared_object_base_1.SharedObject {
|
|
62
20
|
/**
|
|
63
|
-
* Constructs a new
|
|
64
|
-
* be provided
|
|
21
|
+
* Constructs a new `SharedCell`.
|
|
22
|
+
* If the object is non-local an id and service interfaces will be provided.
|
|
65
23
|
*
|
|
66
|
-
* @param runtime - data store runtime the
|
|
67
|
-
* @param id -
|
|
24
|
+
* @param runtime - The data store runtime to which the `SharedCell` belongs.
|
|
25
|
+
* @param id - Unique identifier for the `SharedCell`.
|
|
68
26
|
*/
|
|
69
27
|
constructor(id, runtime, attributes) {
|
|
70
28
|
super(id, runtime, attributes, "fluid_cell_");
|
|
@@ -81,19 +39,20 @@ class SharedCell extends shared_object_base_1.SharedObject {
|
|
|
81
39
|
this.pendingMessageIds = [];
|
|
82
40
|
}
|
|
83
41
|
/**
|
|
84
|
-
* Create a new
|
|
42
|
+
* Create a new `SharedCell`.
|
|
85
43
|
*
|
|
86
|
-
* @param runtime - data store runtime
|
|
87
|
-
* @param id -
|
|
88
|
-
*
|
|
44
|
+
* @param runtime - The data store runtime to which the `SharedCell` belongs.
|
|
45
|
+
* @param id - Unique identifier for the `SharedCell`.
|
|
46
|
+
*
|
|
47
|
+
* @returns The newly create `SharedCell`. Note that it will not yet be attached.
|
|
89
48
|
*/
|
|
90
49
|
static create(runtime, id) {
|
|
91
50
|
return runtime.createChannel(id, cellFactory_1.CellFactory.Type);
|
|
92
51
|
}
|
|
93
52
|
/**
|
|
94
|
-
*
|
|
53
|
+
* Gets the factory for the `SharedCell` to register with the data store.
|
|
95
54
|
*
|
|
96
|
-
* @returns
|
|
55
|
+
* @returns A factory that creates and loads `SharedCell`s.
|
|
97
56
|
*/
|
|
98
57
|
static getFactory() {
|
|
99
58
|
return new cellFactory_1.CellFactory();
|
|
@@ -146,9 +105,9 @@ class SharedCell extends shared_object_base_1.SharedObject {
|
|
|
146
105
|
return this.data === undefined;
|
|
147
106
|
}
|
|
148
107
|
/**
|
|
149
|
-
*
|
|
108
|
+
* Creates a summary for the Cell.
|
|
150
109
|
*
|
|
151
|
-
* @returns
|
|
110
|
+
* @returns The summary of the current state of the Cell.
|
|
152
111
|
*/
|
|
153
112
|
summarizeCore(serializer) {
|
|
154
113
|
const content = { value: this.data };
|
|
@@ -162,17 +121,18 @@ class SharedCell extends shared_object_base_1.SharedObject {
|
|
|
162
121
|
this.data = this.decode(content);
|
|
163
122
|
}
|
|
164
123
|
/**
|
|
165
|
-
* Initialize a local instance of cell
|
|
124
|
+
* Initialize a local instance of cell.
|
|
166
125
|
*/
|
|
167
126
|
initializeLocalCore() {
|
|
168
127
|
this.data = undefined;
|
|
169
128
|
}
|
|
170
129
|
/**
|
|
171
|
-
* Call back on disconnect
|
|
130
|
+
* Call back on disconnect.
|
|
172
131
|
*/
|
|
173
132
|
onDisconnect() { }
|
|
174
133
|
/**
|
|
175
|
-
* Apply inner op
|
|
134
|
+
* Apply inner op.
|
|
135
|
+
*
|
|
176
136
|
* @param content - ICellOperation content
|
|
177
137
|
*/
|
|
178
138
|
applyInnerOp(content) {
|
|
@@ -186,12 +146,12 @@ class SharedCell extends shared_object_base_1.SharedObject {
|
|
|
186
146
|
}
|
|
187
147
|
}
|
|
188
148
|
/**
|
|
189
|
-
* Process a cell operation
|
|
149
|
+
* Process a cell operation (op).
|
|
190
150
|
*
|
|
191
|
-
* @param message -
|
|
192
|
-
* @param local -
|
|
151
|
+
* @param message - The message to prepare.
|
|
152
|
+
* @param local - Whether or not the message was sent by the local client.
|
|
193
153
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
194
|
-
* For messages from a remote client, this will be undefined
|
|
154
|
+
* For messages from a remote client, this will be `undefined`.
|
|
195
155
|
*/
|
|
196
156
|
processCore(message, local, localOpMetadata) {
|
|
197
157
|
const cellOpMetadata = localOpMetadata;
|
|
@@ -227,7 +187,6 @@ class SharedCell extends shared_object_base_1.SharedObject {
|
|
|
227
187
|
}
|
|
228
188
|
decode(cellValue) {
|
|
229
189
|
const value = cellValue.value;
|
|
230
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
231
190
|
return this.serializer.decode(value);
|
|
232
191
|
}
|
|
233
192
|
createLocalOpMetadata(op, previousValue) {
|
|
@@ -240,6 +199,7 @@ class SharedCell extends shared_object_base_1.SharedObject {
|
|
|
240
199
|
}
|
|
241
200
|
/**
|
|
242
201
|
* {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
|
|
202
|
+
*
|
|
243
203
|
* @internal
|
|
244
204
|
*/
|
|
245
205
|
applyStashedOp(content) {
|
|
@@ -248,12 +208,16 @@ class SharedCell extends shared_object_base_1.SharedObject {
|
|
|
248
208
|
return this.createLocalOpMetadata(cellContent, previousValue);
|
|
249
209
|
}
|
|
250
210
|
/**
|
|
251
|
-
* Rollback a local op
|
|
252
|
-
*
|
|
211
|
+
* Rollback a local op.
|
|
212
|
+
*
|
|
213
|
+
* @param content - The operation to rollback.
|
|
253
214
|
* @param localOpMetadata - The local metadata associated with the op.
|
|
254
215
|
*/
|
|
216
|
+
// TODO: use `unknown` instead (breaking change).
|
|
217
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
255
218
|
rollback(content, localOpMetadata) {
|
|
256
219
|
const cellOpMetadata = localOpMetadata;
|
|
220
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
257
221
|
if (content.type === "setCell" || content.type === "deleteCell") {
|
|
258
222
|
if (cellOpMetadata.previousValue === undefined) {
|
|
259
223
|
this.deleteCore();
|
|
@@ -272,8 +236,9 @@ class SharedCell extends shared_object_base_1.SharedObject {
|
|
|
272
236
|
}
|
|
273
237
|
/**
|
|
274
238
|
* Submit a cell message to remote clients.
|
|
275
|
-
*
|
|
276
|
-
* @param
|
|
239
|
+
*
|
|
240
|
+
* @param op - The cell message.
|
|
241
|
+
* @param previousValue - The value of the cell before this op.
|
|
277
242
|
*/
|
|
278
243
|
submitCellMessage(op, previousValue) {
|
|
279
244
|
const localMetadata = this.createLocalOpMetadata(op, previousValue);
|
package/dist/cell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell.js","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AACtD,+EAA8F;AAS9F,+DAA4D;AAC5D,2EAA6G;AAC7G,+CAA4C;AA0B5C,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAa,UAAoB,SAAQ,iCAAkC;IAwCvE;;;;;;OAMG;IACH,YAAY,EAAU,EAAE,OAA+B,EAAE,UAA8B;QACnF,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QAtBlD;;;WAGG;QACK,cAAS,GAAW,CAAC,CAAC,CAAC;QAE/B;;;WAGG;QACK,sBAAiB,GAAW,CAAC,CAAC,CAAC;QAEtB,sBAAiB,GAAa,EAAE,CAAC;IAWlD,CAAC;IA/CD;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CAAC,OAA+B,EAAE,EAAW;QAC7D,OAAO,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,yBAAW,CAAC,IAAI,CAAe,CAAC;IACrE,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,UAAU;QACpB,OAAO,IAAI,yBAAW,EAAE,CAAC;IAC7B,CAAC;IA+BD;;OAEG;IACI,GAAG;QACN,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,KAAsB;QAC7B,mCAAmC;QACnC,MAAM,cAAc,GAAe;YAC/B,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;SACpD,CAAC;QAEF,yBAAyB;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAE1C,+CAA+C;QAC/C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACpB,OAAO;SACV;QAED,MAAM,EAAE,GAAsB;YAC1B,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,cAAc;SACxB,CAAC;QACF,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACI,MAAM;QACT,4BAA4B;QAC5B,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAExC,+CAA+C;QAC/C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACpB,OAAO;SACV;QAED,MAAM,EAAE,GAAyB;YAC7B,IAAI,EAAE,YAAY;SACrB,CAAC;QACF,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACI,KAAK;QACR,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACO,aAAa,CAAC,UAA4B;QAChD,MAAM,OAAO,GAAe,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACjD,OAAO,IAAA,4CAAuB,EAAC,gBAAgB,EAAE,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACjG,CAAC;IAED;;OAEG;IACO,KAAK,CAAC,QAAQ,CAAC,OAA+B;QACpD,MAAM,OAAO,GAAG,MAAM,IAAA,2BAAY,EAAa,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAE1E,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACO,mBAAmB;QACzB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IAC1B,CAAC;IAED;;OAEG;IACO,YAAY,KAAK,CAAC;IAE5B;;;OAGG;IACK,YAAY,CAAC,OAAuB;QACxC,QAAQ,OAAO,CAAC,IAAI,EAAE;YAClB,KAAK,SAAS;gBACV,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAEpD,KAAK,YAAY;gBACb,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;YAE7B;gBACI,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;SAC5C;IACL,CAAC;IAED;;;;;;;OAOG;IACO,WAAW,CAAC,OAAkC,EAAE,KAAc,EAAE,eAAwB;QAC9F,MAAM,cAAc,GAAG,eAAuC,CAAC;QAC/D,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,iBAAiB,EAAE;YAC3C,sGAAsG;YACtG,IAAI,KAAK,EAAE;gBACP,MAAM,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,CAAC;gBAC1D,IAAA,qBAAM,EAAC,iBAAiB,KAAK,SAAS,IAAI,iBAAiB,IAAI,IAAI,CAAC,SAAS,EACzE,KAAK,CAAC,+DAA+D,CAAC,CAAC;gBAC3E,IAAA,qBAAM,EAAC,IAAI,CAAC,iBAAiB,KAAK,SAAS;oBACvC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,gBAAgB,EAC7D,KAAK,CAAC,yCAAyC,CAAC,CAAC;gBACrD,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;gBAC/B,2CAA2C;gBAC3C,IAAI,CAAC,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,CAAC;aAC5D;YACD,OAAO;SACV;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,kCAAW,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE;YAClD,MAAM,EAAE,GAAG,OAAO,CAAC,QAA0B,CAAC;YAC9C,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SACzB;IACL,CAAC;IAEO,OAAO,CAAC,KAAsB;QAClC,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACjC,OAAO,kBAAkB,CAAC;IAC9B,CAAC;IAEO,UAAU;QACd,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpB,OAAO,kBAAkB,CAAC;IAC9B,CAAC;IAEO,MAAM,CAAC,SAAqB;QAChC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,+DAA+D;QAC/D,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAEO,qBAAqB,CAAC,EAAkB,EAAE,aAA+B;QAC7E,MAAM,gBAAgB,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC;QAC1C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC9C,MAAM,aAAa,GAAyB;YACxC,gBAAgB,EAAE,aAAa;SAClC,CAAC;QACF,OAAO,aAAa,CAAC;IACzB,CAAC;IAED;;;OAGG;IACO,cAAc,CAAC,OAAgB;QACrC,MAAM,WAAW,GAAG,OAAyB,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACO,QAAQ,CAAC,OAAY,EAAE,eAAwB;QACrD,MAAM,cAAc,GAAG,eAAuC,CAAC;QAC/D,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;YAC7D,IAAI,cAAc,CAAC,aAAa,KAAK,SAAS,EAAE;gBAC5C,IAAI,CAAC,UAAU,EAAE,CAAC;aACrB;iBAAM;gBACH,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;aAC9C;YAED,MAAM,oBAAoB,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC;YAC1D,IAAI,oBAAoB,KAAK,cAAc,CAAC,gBAAgB,EAAE;gBAC1D,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;aAC9D;SACJ;aAAM;YACH,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;SAClD;IACL,CAAC;IAEA;;;;MAIE;IACK,iBAAiB,CAAC,EAAkB,EAAE,aAAmB;QAC7D,MAAM,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACpE,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IAC/C,CAAC;CACJ;AAlQD,gCAkQC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelStorageService,\n IChannelFactory,\n Serializable,\n} from \"@fluidframework/datastore-definitions\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { createSingleBlobSummary, IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base\";\nimport { CellFactory } from \"./cellFactory\";\nimport {\n ISharedCell,\n ISharedCellEvents,\n ICellLocalOpMetadata,\n} from \"./interfaces\";\n\n/**\n * Description of a cell delta operation\n */\ntype ICellOperation = ISetCellOperation | IDeleteCellOperation;\n\ninterface ISetCellOperation {\n type: \"setCell\";\n value: ICellValue;\n}\n\ninterface IDeleteCellOperation {\n type: \"deleteCell\";\n}\n\ninterface ICellValue {\n // The actual value contained in the cell which needs to be wrapped to handle undefined\n value: any;\n}\n\nconst snapshotFileName = \"header\";\n\n/**\n * The SharedCell distributed data structure can be used to store a single serializable value.\n *\n * @remarks\n * ### Creation\n *\n * To create a `SharedCell`, call the static create method:\n *\n * ```typescript\n * const myCell = SharedCell.create(this.runtime, id);\n * ```\n *\n * ### Usage\n *\n * The value stored in the cell can be set with the `.set()` method and retrieved with the `.get()` method:\n *\n * ```typescript\n * myCell.set(3);\n * console.log(myCell.get()); // 3\n * ```\n *\n * The value must only be plain JS objects or `SharedObject` handles (e.g. to another DDS or Fluid object).\n * In collaborative scenarios, the value is settled with a policy of _last write wins_.\n *\n * The `.delete()` method will delete the stored value from the cell:\n *\n * ```typescript\n * myCell.delete();\n * console.log(myCell.get()); // undefined\n * ```\n *\n * The `.empty()` method will check if the value is undefined.\n *\n * ```typescript\n * if (myCell.empty()) {\n * // myCell.get() will return undefined\n * } else {\n * // myCell.get() will return a non-undefined value\n * }\n * ```\n *\n * ### Eventing\n *\n * `SharedCell` is an `EventEmitter`, and will emit events when other clients make modifications. You should\n * register for these events and respond appropriately as the data is modified. `valueChanged` will be emitted\n * in response to a `set`, and `delete` will be emitted in response to a `delete`.\n */\nexport class SharedCell<T = any> extends SharedObject<ISharedCellEvents<T>>\n implements ISharedCell<T> {\n /**\n * Create a new shared cell\n *\n * @param runtime - data store runtime the new shared map belongs to\n * @param id - optional name of the shared map\n * @returns newly create shared map (but not attached yet)\n */\n public static create(runtime: IFluidDataStoreRuntime, id?: string) {\n return runtime.createChannel(id, CellFactory.Type) as SharedCell;\n }\n\n /**\n * Get a factory for SharedCell to register with the data store.\n *\n * @returns a factory that creates and load SharedCell\n */\n public static getFactory(): IChannelFactory {\n return new CellFactory();\n }\n /**\n * The data held by this cell.\n */\n private data: Serializable<T> | undefined;\n\n /**\n * This is used to assign a unique id to outgoing messages. It is used to track messages until\n * they are ack'd.\n */\n private messageId: number = -1;\n\n /**\n * This keeps track of the messageId of messages that have been ack'd. It is updated every time\n * we a message is ack'd with it's messageId.\n */\n private messageIdObserved: number = -1;\n\n private readonly pendingMessageIds: number[] = [];\n\n /**\n * Constructs a new shared cell. If the object is non-local an id and service interfaces will\n * be provided\n *\n * @param runtime - data store runtime the shared map belongs to\n * @param id - optional name of the shared map\n */\n constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes) {\n super(id, runtime, attributes, \"fluid_cell_\");\n }\n\n /**\n * {@inheritDoc ISharedCell.get}\n */\n public get(): Serializable<T> | undefined {\n return this.data;\n }\n\n /**\n * {@inheritDoc ISharedCell.set}\n */\n public set(value: Serializable<T>) {\n // Serialize the value if required.\n const operationValue: ICellValue = {\n value: this.serializer.encode(value, this.handle),\n };\n\n // Set the value locally.\n const previousValue = this.setCore(value);\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return;\n }\n\n const op: ISetCellOperation = {\n type: \"setCell\",\n value: operationValue,\n };\n this.submitCellMessage(op, previousValue);\n }\n\n /**\n * {@inheritDoc ISharedCell.delete}\n */\n public delete() {\n // Delete the value locally.\n const previousValue = this.deleteCore();\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return;\n }\n\n const op: IDeleteCellOperation = {\n type: \"deleteCell\",\n };\n this.submitCellMessage(op, previousValue);\n }\n\n /**\n * {@inheritDoc ISharedCell.empty}\n */\n public empty() {\n return this.data === undefined;\n }\n\n /**\n * Create a summary for the cell\n *\n * @returns the summary of the current state of the cell\n */\n protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n const content: ICellValue = { value: this.data };\n return createSingleBlobSummary(snapshotFileName, serializer.stringify(content, this.handle));\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n */\n protected async loadCore(storage: IChannelStorageService): Promise<void> {\n const content = await readAndParse<ICellValue>(storage, snapshotFileName);\n\n this.data = this.decode(content);\n }\n\n /**\n * Initialize a local instance of cell\n */\n protected initializeLocalCore() {\n this.data = undefined;\n }\n\n /**\n * Call back on disconnect\n */\n protected onDisconnect() { }\n\n /**\n * Apply inner op\n * @param content - ICellOperation content\n */\n private applyInnerOp(content: ICellOperation) {\n switch (content.type) {\n case \"setCell\":\n return this.setCore(this.decode(content.value));\n\n case \"deleteCell\":\n return this.deleteCore();\n\n default:\n throw new Error(\"Unknown operation\");\n }\n }\n\n /**\n * Process a cell operation\n *\n * @param message - the message to prepare\n * @param local - whether the message was sent by the local client\n * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n * For messages from a remote client, this will be undefined.\n */\n protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown) {\n const cellOpMetadata = localOpMetadata as ICellLocalOpMetadata;\n if (this.messageId !== this.messageIdObserved) {\n // We are waiting for an ACK on our change to this cell - we will ignore all messages until we get it.\n if (local) {\n const messageIdReceived = cellOpMetadata.pendingMessageId;\n assert(messageIdReceived !== undefined && messageIdReceived <= this.messageId,\n 0x00c /* \"messageId is incorrect from from the local client's ACK\" */);\n assert(this.pendingMessageIds !== undefined &&\n this.pendingMessageIds[0] === cellOpMetadata.pendingMessageId,\n 0x471 /* Unexpected pending message received */);\n this.pendingMessageIds.shift();\n // We got an ACK. Update messageIdObserved.\n this.messageIdObserved = cellOpMetadata.pendingMessageId;\n }\n return;\n }\n\n if (message.type === MessageType.Operation && !local) {\n const op = message.contents as ICellOperation;\n this.applyInnerOp(op);\n }\n }\n\n private setCore(value: Serializable<T>): Serializable<T> | undefined {\n const previousLocalValue = this.get();\n this.data = value;\n this.emit(\"valueChanged\", value);\n return previousLocalValue;\n }\n\n private deleteCore(): Serializable<T> | undefined {\n const previousLocalValue = this.get();\n this.data = undefined;\n this.emit(\"delete\");\n return previousLocalValue;\n }\n\n private decode(cellValue: ICellValue) {\n const value = cellValue.value;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return this.serializer.decode(value);\n }\n\n private createLocalOpMetadata(op: ICellOperation, previousValue?: Serializable<T>): ICellLocalOpMetadata {\n const pendingMessageId = ++this.messageId;\n this.pendingMessageIds.push(pendingMessageId);\n const localMetadata: ICellLocalOpMetadata = {\n pendingMessageId, previousValue,\n };\n return localMetadata;\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}\n * @internal\n */\n protected applyStashedOp(content: unknown): unknown {\n const cellContent = content as ICellOperation;\n const previousValue = this.applyInnerOp(cellContent);\n return this.createLocalOpMetadata(cellContent, previousValue);\n }\n\n /**\n * Rollback a local op\n * @param content - The operation to rollback\n * @param localOpMetadata - The local metadata associated with the op.\n */\n protected rollback(content: any, localOpMetadata: unknown) {\n const cellOpMetadata = localOpMetadata as ICellLocalOpMetadata;\n if (content.type === \"setCell\" || content.type === \"deleteCell\") {\n if (cellOpMetadata.previousValue === undefined) {\n this.deleteCore();\n } else {\n this.setCore(cellOpMetadata.previousValue);\n }\n\n const lastPendingMessageId = this.pendingMessageIds.pop();\n if (lastPendingMessageId !== cellOpMetadata.pendingMessageId) {\n throw new Error(\"Rollback op does not match last pending\");\n }\n } else {\n throw new Error(\"Unsupported op for rollback\");\n }\n }\n\n /**\n * Submit a cell message to remote clients.\n * @param op - The cell message\n * @param previousValue - The value of the cell before this op\n */\n private submitCellMessage(op: ICellOperation, previousValue?: any): void {\n const localMetadata = this.createLocalOpMetadata(op, previousValue);\n this.submitLocalMessage(op, localMetadata);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cell.js","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AACtD,+EAA8F;AAS9F,+DAA4D;AAC5D,2EAA6G;AAC7G,+CAA4C;AA4B5C,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAElC;;GAEG;AACH,iDAAiD;AACjD,8DAA8D;AAC9D,MAAa,UAAoB,SAAQ,iCAAkC;IAyCvE;;;;;;OAMG;IACH,YAAmB,EAAU,EAAE,OAA+B,EAAE,UAA8B;QAC1F,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QAtBlD;;;WAGG;QACK,cAAS,GAAW,CAAC,CAAC,CAAC;QAE/B;;;WAGG;QACK,sBAAiB,GAAW,CAAC,CAAC,CAAC;QAEtB,sBAAiB,GAAa,EAAE,CAAC;IAWlD,CAAC;IAjDD;;;;;;;OAOG;IACI,MAAM,CAAC,MAAM,CAAC,OAA+B,EAAE,EAAW;QAC7D,OAAO,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,yBAAW,CAAC,IAAI,CAAe,CAAC;IACrE,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,UAAU;QACpB,OAAO,IAAI,yBAAW,EAAE,CAAC;IAC7B,CAAC;IAgCD;;OAEG;IACI,GAAG;QACN,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,KAAsB;QAC7B,mCAAmC;QACnC,MAAM,cAAc,GAAe;YAC/B,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;SACpD,CAAC;QAEF,yBAAyB;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAE1C,+CAA+C;QAC/C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACpB,OAAO;SACV;QAED,MAAM,EAAE,GAAsB;YAC1B,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,cAAc;SACxB,CAAC;QACF,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACI,MAAM;QACT,4BAA4B;QAC5B,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAExC,+CAA+C;QAC/C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACpB,OAAO;SACV;QAED,MAAM,EAAE,GAAyB;YAC7B,IAAI,EAAE,YAAY;SACrB,CAAC;QACF,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACI,KAAK;QACR,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACO,aAAa,CAAC,UAA4B;QAChD,MAAM,OAAO,GAAe,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACjD,OAAO,IAAA,4CAAuB,EAAC,gBAAgB,EAAE,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACjG,CAAC;IAED;;OAEG;IACO,KAAK,CAAC,QAAQ,CAAC,OAA+B;QACpD,MAAM,OAAO,GAAG,MAAM,IAAA,2BAAY,EAAa,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAE1E,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACO,mBAAmB;QACzB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IAC1B,CAAC;IAED;;OAEG;IACO,YAAY,KAAW,CAAC;IAElC;;;;OAIG;IACK,YAAY,CAAC,OAAuB;QACxC,QAAQ,OAAO,CAAC,IAAI,EAAE;YAClB,KAAK,SAAS;gBACV,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAEpD,KAAK,YAAY;gBACb,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;YAE7B;gBACI,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;SAC5C;IACL,CAAC;IAED;;;;;;;OAOG;IACO,WAAW,CAAC,OAAkC,EAAE,KAAc,EAAE,eAAwB;QAC9F,MAAM,cAAc,GAAG,eAAuC,CAAC;QAC/D,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,iBAAiB,EAAE;YAC3C,sGAAsG;YACtG,IAAI,KAAK,EAAE;gBACP,MAAM,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,CAAC;gBAC1D,IAAA,qBAAM,EAAC,iBAAiB,KAAK,SAAS,IAAI,iBAAiB,IAAI,IAAI,CAAC,SAAS,EACzE,KAAK,CAAC,+DAA+D,CAAC,CAAC;gBAC3E,IAAA,qBAAM,EAAC,IAAI,CAAC,iBAAiB,KAAK,SAAS;oBACvC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,gBAAgB,EAC7D,KAAK,CAAC,yCAAyC,CAAC,CAAC;gBACrD,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;gBAC/B,2CAA2C;gBAC3C,IAAI,CAAC,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,CAAC;aAC5D;YACD,OAAO;SACV;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,kCAAW,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE;YAClD,MAAM,EAAE,GAAG,OAAO,CAAC,QAA0B,CAAC;YAC9C,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SACzB;IACL,CAAC;IAEO,OAAO,CAAC,KAAsB;QAClC,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACjC,OAAO,kBAAkB,CAAC;IAC9B,CAAC;IAEO,UAAU;QACd,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpB,OAAO,kBAAkB,CAAC;IAC9B,CAAC;IAEO,MAAM,CAAC,SAAqB;QAChC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAoB,CAAE;IAC7D,CAAC;IAEO,qBAAqB,CAAC,EAAkB,EAAE,aAA+B;QAC7E,MAAM,gBAAgB,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC;QAC1C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC9C,MAAM,aAAa,GAAyB;YACxC,gBAAgB,EAAE,aAAa;SAClC,CAAC;QACF,OAAO,aAAa,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACO,cAAc,CAAC,OAAgB;QACrC,MAAM,WAAW,GAAG,OAAyB,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAClE,CAAC;IAED;;;;;OAKG;IACH,iDAAiD;IACjD,iHAAiH;IACvG,QAAQ,CAAC,OAAY,EAAE,eAAwB;QACrD,MAAM,cAAc,GAAG,eAAuC,CAAC;QAC/D,sEAAsE;QACtE,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;YAC7D,IAAI,cAAc,CAAC,aAAa,KAAK,SAAS,EAAE;gBAC5C,IAAI,CAAC,UAAU,EAAE,CAAC;aACrB;iBAAM;gBACH,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,aAAgC,CAAC,CAAC;aACjE;YAED,MAAM,oBAAoB,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC;YAC1D,IAAI,oBAAoB,KAAK,cAAc,CAAC,gBAAgB,EAAE;gBAC1D,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;aAC9D;SACJ;aAAM;YACH,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;SAClD;IACL,CAAC;IAEA;;;;;MAKE;IACK,iBAAiB,CAAC,EAAkB,EAAE,aAA+B;QACzE,MAAM,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACpE,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IAC/C,CAAC;CACJ;AAzQD,gCAyQC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelStorageService,\n IChannelFactory,\n Serializable,\n} from \"@fluidframework/datastore-definitions\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { createSingleBlobSummary, IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base\";\nimport { CellFactory } from \"./cellFactory\";\nimport {\n ISharedCell,\n ISharedCellEvents,\n ICellLocalOpMetadata,\n} from \"./interfaces\";\n\n/**\n * Description of a cell delta operation\n */\ntype ICellOperation = ISetCellOperation | IDeleteCellOperation;\n\ninterface ISetCellOperation {\n type: \"setCell\";\n value: ICellValue;\n}\n\ninterface IDeleteCellOperation {\n type: \"deleteCell\";\n}\n\ninterface ICellValue {\n /**\n * The actual value contained in the `Cell`, which needs to be wrapped to handle `undefined`.\n */\n value: unknown;\n}\n\nconst snapshotFileName = \"header\";\n\n/**\n * {@inheritDoc ISharedCell}\n */\n// TODO: use `unknown` instead (breaking change).\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class SharedCell<T = any> extends SharedObject<ISharedCellEvents<T>> implements ISharedCell<T> {\n /**\n * Create a new `SharedCell`.\n *\n * @param runtime - The data store runtime to which the `SharedCell` belongs.\n * @param id - Unique identifier for the `SharedCell`.\n *\n * @returns The newly create `SharedCell`. Note that it will not yet be attached.\n */\n public static create(runtime: IFluidDataStoreRuntime, id?: string): SharedCell {\n return runtime.createChannel(id, CellFactory.Type) as SharedCell;\n }\n\n /**\n * Gets the factory for the `SharedCell` to register with the data store.\n *\n * @returns A factory that creates and loads `SharedCell`s.\n */\n public static getFactory(): IChannelFactory {\n return new CellFactory();\n }\n\n /**\n * The data held by this cell.\n */\n private data: Serializable<T> | undefined;\n\n /**\n * This is used to assign a unique id to outgoing messages. It is used to track messages until\n * they are ack'd.\n */\n private messageId: number = -1;\n\n /**\n * This keeps track of the messageId of messages that have been ack'd. It is updated every time\n * we a message is ack'd with it's messageId.\n */\n private messageIdObserved: number = -1;\n\n private readonly pendingMessageIds: number[] = [];\n\n /**\n * Constructs a new `SharedCell`.\n * If the object is non-local an id and service interfaces will be provided.\n *\n * @param runtime - The data store runtime to which the `SharedCell` belongs.\n * @param id - Unique identifier for the `SharedCell`.\n */\n public constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes) {\n super(id, runtime, attributes, \"fluid_cell_\");\n }\n\n /**\n * {@inheritDoc ISharedCell.get}\n */\n public get(): Serializable<T> | undefined {\n return this.data;\n }\n\n /**\n * {@inheritDoc ISharedCell.set}\n */\n public set(value: Serializable<T>): void {\n // Serialize the value if required.\n const operationValue: ICellValue = {\n value: this.serializer.encode(value, this.handle),\n };\n\n // Set the value locally.\n const previousValue = this.setCore(value);\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return;\n }\n\n const op: ISetCellOperation = {\n type: \"setCell\",\n value: operationValue,\n };\n this.submitCellMessage(op, previousValue);\n }\n\n /**\n * {@inheritDoc ISharedCell.delete}\n */\n public delete(): void {\n // Delete the value locally.\n const previousValue = this.deleteCore();\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return;\n }\n\n const op: IDeleteCellOperation = {\n type: \"deleteCell\",\n };\n this.submitCellMessage(op, previousValue);\n }\n\n /**\n * {@inheritDoc ISharedCell.empty}\n */\n public empty(): boolean {\n return this.data === undefined;\n }\n\n /**\n * Creates a summary for the Cell.\n *\n * @returns The summary of the current state of the Cell.\n */\n protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n const content: ICellValue = { value: this.data };\n return createSingleBlobSummary(snapshotFileName, serializer.stringify(content, this.handle));\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n */\n protected async loadCore(storage: IChannelStorageService): Promise<void> {\n const content = await readAndParse<ICellValue>(storage, snapshotFileName);\n\n this.data = this.decode(content);\n }\n\n /**\n * Initialize a local instance of cell.\n */\n protected initializeLocalCore(): void {\n this.data = undefined;\n }\n\n /**\n * Call back on disconnect.\n */\n protected onDisconnect(): void { }\n\n /**\n * Apply inner op.\n *\n * @param content - ICellOperation content\n */\n private applyInnerOp(content: ICellOperation): Serializable<T> | undefined {\n switch (content.type) {\n case \"setCell\":\n return this.setCore(this.decode(content.value));\n\n case \"deleteCell\":\n return this.deleteCore();\n\n default:\n throw new Error(\"Unknown operation\");\n }\n }\n\n /**\n * Process a cell operation (op).\n *\n * @param message - The message to prepare.\n * @param local - Whether or not the message was sent by the local client.\n * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n * For messages from a remote client, this will be `undefined`.\n */\n protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n const cellOpMetadata = localOpMetadata as ICellLocalOpMetadata;\n if (this.messageId !== this.messageIdObserved) {\n // We are waiting for an ACK on our change to this cell - we will ignore all messages until we get it.\n if (local) {\n const messageIdReceived = cellOpMetadata.pendingMessageId;\n assert(messageIdReceived !== undefined && messageIdReceived <= this.messageId,\n 0x00c /* \"messageId is incorrect from from the local client's ACK\" */);\n assert(this.pendingMessageIds !== undefined &&\n this.pendingMessageIds[0] === cellOpMetadata.pendingMessageId,\n 0x471 /* Unexpected pending message received */);\n this.pendingMessageIds.shift();\n // We got an ACK. Update messageIdObserved.\n this.messageIdObserved = cellOpMetadata.pendingMessageId;\n }\n return;\n }\n\n if (message.type === MessageType.Operation && !local) {\n const op = message.contents as ICellOperation;\n this.applyInnerOp(op);\n }\n }\n\n private setCore(value: Serializable<T>): Serializable<T> | undefined {\n const previousLocalValue = this.get();\n this.data = value;\n this.emit(\"valueChanged\", value);\n return previousLocalValue;\n }\n\n private deleteCore(): Serializable<T> | undefined {\n const previousLocalValue = this.get();\n this.data = undefined;\n this.emit(\"delete\");\n return previousLocalValue;\n }\n\n private decode(cellValue: ICellValue): Serializable<T> {\n const value = cellValue.value;\n return this.serializer.decode(value) as Serializable<T> ;\n }\n\n private createLocalOpMetadata(op: ICellOperation, previousValue?: Serializable<T>): ICellLocalOpMetadata {\n const pendingMessageId = ++this.messageId;\n this.pendingMessageIds.push(pendingMessageId);\n const localMetadata: ICellLocalOpMetadata = {\n pendingMessageId, previousValue,\n };\n return localMetadata;\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}\n *\n * @internal\n */\n protected applyStashedOp(content: unknown): unknown {\n const cellContent = content as ICellOperation;\n const previousValue = this.applyInnerOp(cellContent);\n return this.createLocalOpMetadata(cellContent, previousValue);\n }\n\n /**\n * Rollback a local op.\n *\n * @param content - The operation to rollback.\n * @param localOpMetadata - The local metadata associated with the op.\n */\n // TODO: use `unknown` instead (breaking change).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n protected rollback(content: any, localOpMetadata: unknown): void {\n const cellOpMetadata = localOpMetadata as ICellLocalOpMetadata;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (content.type === \"setCell\" || content.type === \"deleteCell\") {\n if (cellOpMetadata.previousValue === undefined) {\n this.deleteCore();\n } else {\n this.setCore(cellOpMetadata.previousValue as Serializable<T>);\n }\n\n const lastPendingMessageId = this.pendingMessageIds.pop();\n if (lastPendingMessageId !== cellOpMetadata.pendingMessageId) {\n throw new Error(\"Rollback op does not match last pending\");\n }\n } else {\n throw new Error(\"Unsupported op for rollback\");\n }\n }\n\n /**\n * Submit a cell message to remote clients.\n *\n * @param op - The cell message.\n * @param previousValue - The value of the cell before this op.\n */\n private submitCellMessage(op: ICellOperation, previousValue?: Serializable<T>): void {\n const localMetadata = this.createLocalOpMetadata(op, previousValue);\n this.submitLocalMessage(op, localMetadata);\n }\n}\n"]}
|
package/dist/cellFactory.d.ts
CHANGED
|
@@ -5,17 +5,34 @@
|
|
|
5
5
|
import { IChannelAttributes, IFluidDataStoreRuntime, IChannelServices, IChannelFactory } from "@fluidframework/datastore-definitions";
|
|
6
6
|
import { ISharedCell } from "./interfaces";
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* {@link @fluidframework/datastore-definitions#IChannelFactory} for {@link ISharedCell}.
|
|
9
|
+
*
|
|
10
|
+
* @sealed
|
|
9
11
|
*/
|
|
10
12
|
export declare class CellFactory implements IChannelFactory {
|
|
13
|
+
/**
|
|
14
|
+
* {@inheritDoc CellFactory."type"}
|
|
15
|
+
*/
|
|
11
16
|
static readonly Type = "https://graph.microsoft.com/types/cell";
|
|
17
|
+
/**
|
|
18
|
+
* {@inheritDoc CellFactory.attributes}
|
|
19
|
+
*/
|
|
12
20
|
static readonly Attributes: IChannelAttributes;
|
|
21
|
+
/**
|
|
22
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
|
|
23
|
+
*/
|
|
13
24
|
get type(): string;
|
|
25
|
+
/**
|
|
26
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}
|
|
27
|
+
*/
|
|
14
28
|
get attributes(): IChannelAttributes;
|
|
15
29
|
/**
|
|
16
30
|
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}
|
|
17
31
|
*/
|
|
18
32
|
load(runtime: IFluidDataStoreRuntime, id: string, services: IChannelServices, attributes: IChannelAttributes): Promise<ISharedCell>;
|
|
33
|
+
/**
|
|
34
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}
|
|
35
|
+
*/
|
|
19
36
|
create(document: IFluidDataStoreRuntime, id: string): ISharedCell;
|
|
20
37
|
}
|
|
21
38
|
//# sourceMappingURL=cellFactory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cellFactory.d.ts","sourceRoot":"","sources":["../src/cellFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EAClB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C
|
|
1
|
+
{"version":3,"file":"cellFactory.d.ts","sourceRoot":"","sources":["../src/cellFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EAClB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C;;;;GAIG;AACH,qBAAa,WAAY,YAAW,eAAe;IAC/C;;OAEG;IACH,gBAAuB,IAAI,4CAA4C;IAEvE;;OAEG;IACH,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,kBAAkB,CAE1C;IAED;;OAEG;IACU,IAAI,CACb,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC;IAMzD;;OAEG;IACI,MAAM,CAAC,QAAQ,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW;CAK3E"}
|
package/dist/cellFactory.js
CHANGED
|
@@ -8,12 +8,20 @@ exports.CellFactory = void 0;
|
|
|
8
8
|
const cell_1 = require("./cell");
|
|
9
9
|
const packageVersion_1 = require("./packageVersion");
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* {@link @fluidframework/datastore-definitions#IChannelFactory} for {@link ISharedCell}.
|
|
12
|
+
*
|
|
13
|
+
* @sealed
|
|
12
14
|
*/
|
|
13
15
|
class CellFactory {
|
|
16
|
+
/**
|
|
17
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
|
|
18
|
+
*/
|
|
14
19
|
get type() {
|
|
15
20
|
return CellFactory.Type;
|
|
16
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}
|
|
24
|
+
*/
|
|
17
25
|
get attributes() {
|
|
18
26
|
return CellFactory.Attributes;
|
|
19
27
|
}
|
|
@@ -25,6 +33,9 @@ class CellFactory {
|
|
|
25
33
|
await cell.load(services);
|
|
26
34
|
return cell;
|
|
27
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}
|
|
38
|
+
*/
|
|
28
39
|
create(document, id) {
|
|
29
40
|
const cell = new cell_1.SharedCell(id, document, this.attributes);
|
|
30
41
|
cell.initializeLocal();
|
|
@@ -32,7 +43,13 @@ class CellFactory {
|
|
|
32
43
|
}
|
|
33
44
|
}
|
|
34
45
|
exports.CellFactory = CellFactory;
|
|
46
|
+
/**
|
|
47
|
+
* {@inheritDoc CellFactory."type"}
|
|
48
|
+
*/
|
|
35
49
|
CellFactory.Type = "https://graph.microsoft.com/types/cell";
|
|
50
|
+
/**
|
|
51
|
+
* {@inheritDoc CellFactory.attributes}
|
|
52
|
+
*/
|
|
36
53
|
CellFactory.Attributes = {
|
|
37
54
|
type: CellFactory.Type,
|
|
38
55
|
snapshotFormatVersion: "0.1",
|