@fluidframework/register-collection 2.118.0 → 3.0.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +34 -4
  2. package/README.md +53 -50
  3. package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
  4. package/dist/consensusRegisterCollection.d.ts +1 -1
  5. package/dist/consensusRegisterCollection.js +4 -4
  6. package/dist/consensusRegisterCollection.js.map +1 -1
  7. package/dist/consensusRegisterCollectionFactory.d.ts +1 -1
  8. package/dist/consensusRegisterCollectionFactory.d.ts.map +1 -1
  9. package/dist/consensusRegisterCollectionFactory.js +9 -9
  10. package/dist/consensusRegisterCollectionFactory.js.map +1 -1
  11. package/dist/interfaces.d.ts +1 -1
  12. package/dist/interfaces.js.map +1 -1
  13. package/dist/packageVersion.d.ts +1 -1
  14. package/dist/packageVersion.d.ts.map +1 -1
  15. package/dist/packageVersion.js +1 -1
  16. package/dist/packageVersion.js.map +1 -1
  17. package/lib/consensusRegisterCollection.d.ts +1 -1
  18. package/lib/consensusRegisterCollection.js +4 -4
  19. package/lib/consensusRegisterCollection.js.map +1 -1
  20. package/lib/consensusRegisterCollectionFactory.js +9 -9
  21. package/lib/consensusRegisterCollectionFactory.js.map +1 -1
  22. package/lib/interfaces.d.ts +1 -1
  23. package/lib/interfaces.js.map +1 -1
  24. package/lib/legacy.d.ts +1 -1
  25. package/lib/packageVersion.d.ts +1 -1
  26. package/lib/packageVersion.d.ts.map +1 -1
  27. package/lib/packageVersion.js +1 -1
  28. package/lib/packageVersion.js.map +1 -1
  29. package/lib/public.d.ts +1 -1
  30. package/package.json +36 -56
  31. package/src/consensusRegisterCollection.ts +1 -1
  32. package/src/interfaces.ts +1 -1
  33. package/src/packageVersion.ts +1 -1
  34. package/tsconfig.json +1 -1
  35. package/internal.d.ts +0 -11
  36. package/legacy.d.ts +0 -11
  37. /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
  38. /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,12 +1,42 @@
1
1
  # @fluidframework/register-collection
2
2
 
3
- ## 2.118.0
3
+ ## 3.0.0
4
4
 
5
- Dependency updates only.
5
+ ### Minor Changes
6
6
 
7
- ## 2.117.0
7
+ - Removal of direct CommonJS support ([#28124](https://github.com/microsoft/FluidFramework/pull/28124)) [0f84e3b8878](https://github.com/microsoft/FluidFramework/commit/0f84e3b8878a5e75b2253976d98fd963bbd9db88)
8
8
 
9
- Dependency updates only.
9
+ Direct `require()` import is no longer directly supported.
10
+ Package is transpiled as ECMAScript Module.
11
+
12
+ See [Removal of direct CommonJS support in v3.0](https://github.com/microsoft/FluidFramework/issues/27444) for more information.
13
+
14
+ - Require modern TypeScript module resolution ([#27970](https://github.com/microsoft/FluidFramework/pull/27970)) [325e2016ca9](https://github.com/microsoft/FluidFramework/commit/325e2016ca9978d4a1f7552c97ba34feac9df41f)
15
+
16
+ Fluid Framework Client packages no longer include type declaration compatibility entrypoints for TypeScript's legacy Node10 resolution mode (`"moduleResolution": "node"` or `"node10"`).
17
+ Applications upgrading to Fluid Framework 3.0 must use one of the following supported configurations:
18
+ - `"module": "Node16"` with `"moduleResolution": "Node16"`
19
+ - `"module": "NodeNext"` with `"moduleResolution": "NodeNext"`
20
+ - `"module": "ESNext"` with `"moduleResolution": "Bundler"`
21
+
22
+ Existing public package entrypoints exposed through `package.json` exports, including `/alpha`, `/beta`, and `/legacy`, remain available under supported module resolution modes.
23
+
24
+ See [Removal of Node10 resolutions in v3.0](https://github.com/microsoft/FluidFramework/issues/27457) for more information.
25
+
26
+ - Client packages now target ES2022 ([#27846](https://github.com/microsoft/FluidFramework/pull/27846)) [91c78541bdd](https://github.com/microsoft/FluidFramework/commit/91c78541bddcbca5d6c5f357b023eeaee617d885)
27
+
28
+ The TypeScript compilation `target` and `lib` for the Fluid Framework client packages have been raised from ES2021/ES2020 to **ES2022**.
29
+ The published JavaScript now uses ES2022 language features (with correspondingly less down-leveling), so consuming these packages requires a runtime that supports ES2022.
30
+ All actively supported Node.js versions and evergreen browsers already meet this requirement.
31
+
32
+ Note that Fluid Framework has not officially supported targets older than ES2022 since before 2.0: this is documented in [ClientRequirements.md](https://github.com/microsoft/FluidFramework/blob/main/ClientRequirements.md) as well as the README for every client package.
33
+
34
+ It is possible this change could impact users of less up to date JavaScript runtimes.
35
+ Impacted users can use a tool like [babel](https://babeljs.io/) to transpile out unsupported language features.
36
+
37
+ - Build with TypeScript 6 ([#28052](https://github.com/microsoft/FluidFramework/pull/28052)) [7ab015c49de](https://github.com/microsoft/FluidFramework/commit/7ab015c49deec84833cdfe1fb5e1606b901f6e81)
38
+
39
+ FluidFramework Client SDK is now built using TypeScript 6. Consumers should build with TypeScript v6 or v7 or compatible tooling.
10
40
 
11
41
  ## 2.116.0
12
42
 
package/README.md CHANGED
@@ -9,15 +9,15 @@ A consensus register collection is a distributed data structure (DDS), which hol
9
9
 
10
10
  ## Using Fluid Framework libraries
11
11
 
12
- When taking a dependency on a Fluid Framework library's public APIs, we recommend using a `^` (caret) version range, such as `^1.3.4`.
13
- While Fluid Framework libraries may use different ranges with interdependencies between other Fluid Framework libraries,
14
- library consumers should always prefer `^`.
12
+ For a dependency on a Fluid Framework library's public APIs, we recommend a `^` (caret) version range.
13
+ For example, use `^1.3.4`.
15
14
 
16
- If using any of Fluid Framework's unstable APIs (for example, its `beta` APIs), we recommend using a more constrained version range, such as `~`.
15
+ For a dependency on an unstable API, such as a `beta` API, we recommend a more restrictive version range.
16
+ For example, use a `~` version range.
17
17
 
18
18
  ## Installation
19
19
 
20
- To get started, install the package by running the following command:
20
+ Run this command to install the package:
21
21
 
22
22
  ```bash
23
23
  npm i @fluidframework/register-collection
@@ -25,16 +25,16 @@ npm i @fluidframework/register-collection
25
25
 
26
26
  ## Importing from this package
27
27
 
28
- This package leverages [package.json exports](https://nodejs.org/api/packages.html#exports) to separate its APIs by support level.
29
- For more information on the related support guarantees, see [API Support Levels](https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels).
28
+ This package uses [package.json exports](https://nodejs.org/api/packages.html#exports) to separate APIs by support level.
29
+ For information about the support guarantees, read [API Support Levels](https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels).
30
30
 
31
- To access the `public` ([SemVer](https://semver.org/)) APIs, import via `@fluidframework/register-collection` like normal.
31
+ Import the `public` APIs from `@fluidframework/register-collection`.
32
32
 
33
- To access the `legacy` APIs, import via `@fluidframework/register-collection/legacy`.
33
+ Import the `legacy` APIs from `@fluidframework/register-collection/legacy`.
34
34
 
35
35
  ## API Documentation
36
36
 
37
- API documentation for **@fluidframework/register-collection** is available at <https://fluidframework.com/docs/apis/register-collection>.
37
+ Read the **@fluidframework/register-collection** API documentation at <https://fluidframework.com/docs/apis/register-collection>.
38
38
 
39
39
  <!-- prettier-ignore-end -->
40
40
 
@@ -63,62 +63,69 @@ Below are the policies that the DDS implements:
63
63
 
64
64
  ## Minimum Client Requirements
65
65
 
66
- These are the platform requirements for the current version of Fluid Framework Client Packages.
67
- These requirements err on the side of being too strict since within a major version they can be relaxed over time, but not made stricter.
68
- For Long Term Support (LTS) versions this can require supporting these platforms for several years.
66
+ Fluid Framework client libraries support the platforms in this document.
67
+ These requirements are intentionally restrictive.
68
+ Within a major version series, we can relax these requirements, but we cannot make them stricter.
69
+ For a Long Term Support (LTS) version, we might need to support these platforms for several years.
69
70
 
70
- It is likely that other configurations will work, but they are not supported: if they stop working, we do not consider that a bug.
71
- If you would benefit from support for something not listed here, file an issue and the product team will evaluate your request.
72
- When making such a request please include if the configuration already works (and thus the request is just that it becomes officially supported), or if changes are required to get it working.
71
+ Other configurations can work, but Fluid Framework does not support them.
72
+ If an unsupported configuration stops working, we do not classify this as a bug.
73
+ To request support for a configuration that is not listed, file an issue.
74
+ The product team will evaluate your request.
75
+ In the issue, specify the current status of the configuration:
76
+
77
+ - The configuration works but needs official support.
78
+ - The configuration does not work and requires changes.
73
79
 
74
80
  ### Supported Runtimes
75
81
 
76
- - NodeJs ^22.22.2 except that we will drop support for it [when NodeJs 22 loses its upstream support on 2027-04-30](https://github.com/nodejs/release#release-schedule), and will support a newer LTS version of NodeJS at least 1 year before 22 is end-of-life.
77
- - Running Fluid in a Node.js environment with the `--no-experimental-fetch` flag is not supported.
78
- - Modern browsers supporting the es2022 standard library: in response to asks we can add explicit support for using babel to polyfill to target specific standards or runtimes (meaning we can avoid/remove use of things that don't polyfill robustly, but otherwise target modern standards).
82
+ - Fluid Framework supports Node.js versions 22 and 24 while they receive [upstream support](https://nodejs.org/en/about/previous-releases).
83
+ - Fluid Framework will stop support for version 22 [when upstream support ends on 2027-04-30](https://github.com/nodejs/release#release-schedule).
84
+ - Fluid Framework does not support Node.js with the `--no-experimental-fetch` flag.
85
+ - Fluid Framework supports modern browsers that support the ES2022 standard library.
79
86
 
80
87
  ### Supported Tools
81
88
 
82
- - TypeScript 5.4:
83
- - All [`strict`](https://www.typescriptlang.org/tsconfig) options are supported.
84
- - [`strictNullChecks`](https://www.typescriptlang.org/tsconfig) is required.
85
- - [Configuration options deprecated in 5.0](https://github.com/microsoft/TypeScript/issues/51909) are not supported.
86
- - `exactOptionalPropertyTypes` is currently not fully supported.
87
- If used, narrowing members of Fluid Framework types types using `in`, `Reflect.has`, `Object.hasOwn` or `Object.prototype.hasOwnProperty` should be avoided as they may incorrectly exclude `undefined` from the possible values in some cases.
89
+ - [TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0):
90
+ - Fluid Framework supports all [`strict`](https://www.typescriptlang.org/tsconfig) options.
91
+ - Set the build targets (`lib`, `target`) to `ES2022` or later.
92
+ - Enable [`strictNullChecks`](https://www.typescriptlang.org/tsconfig).
93
+ - Fluid Framework does not support [configuration options deprecated in TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0#breaking-changes-and-deprecations-in-typescript-6-0).
94
+ - Fluid Framework does not fully support `exactOptionalPropertyTypes`.
95
+ If you enable this option, do not use `in`, `Reflect.has`, `Object.hasOwn`, or `Object.prototype.hasOwnProperty` to narrow members of Fluid Framework types.
96
+ These methods can incorrectly exclude `undefined` from the possible values.
88
97
  - [webpack](https://webpack.js.org/) 5
89
- - We are not intending to be prescriptive about what bundler to use.
90
- Other bundlers which can handle ES Modules should work, but webpack is the only one we actively test.
98
+ - We do not require a specific bundler.
99
+ Other bundlers that handle ES Modules can work, but we actively test only webpack.
91
100
 
92
101
  ### Module Resolution
93
102
 
94
- [`Node16`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution) resolution should be used with TypeScript compilerOptions to follow the [Node.js v12+ ESM Resolution and Loading algorithm](https://nodejs.github.io/nodejs.dev/en/api/v20/esm/#resolution-and-loading-algorithm).
95
- Node10 resolution is not supported as it does not support Fluid Framework's API structuring pattern that is used to distinguish stable APIs from those that are in development.
103
+ In TypeScript `compilerOptions`, use [`Node16`, `Node20`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution) module resolution.
104
+ These settings follow the [Node.js v12+ ESM Resolution and Loading algorithm](https://nodejs.github.io/nodejs.dev/en/api/v20/esm/#resolution-and-loading-algorithm).
105
+
106
+ Do not use `Node10` module resolution.
96
107
 
97
108
  ### Module Formats
98
109
 
99
110
  - ES Modules:
100
- ES Modules are the preferred way to consume our client packages (including in NodeJs) and consuming our client packages from ES Modules is fully supported.
101
- - CommonJs:
102
- Consuming our client packages as CommonJs is supported only in NodeJS and only for the cases listed below.
103
- This is done to accommodate some workflows without good ES Module support.
104
- If you have a workflow you would like included in this list, file an issue.
105
- Once this list of workflows motivating CommonJS support is empty, we may drop support for CommonJS one year after notice of the change is posted here.
106
-
107
- - Testing with Jest (which lacks [stable ESM support](https://jestjs.io/docs/ecmascript-modules) due to [unstable APIs in NodeJs](https://github.com/nodejs/node/issues/37648))
111
+ Use ES Modules to consume Fluid Framework client packages, including in Node.js.
112
+ - CommonJS:
113
+ Fluid Framework does not officially support CommonJS in version 3.0 or later.
108
114
 
109
115
  ## Contribution Guidelines
110
116
 
111
- There are many ways to [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid.
117
+ You can [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid Framework in these ways:
112
118
 
113
- - Participate in Q&A in our [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
114
- - [Submit bugs](https://github.com/microsoft/FluidFramework/issues) and help us verify fixes as they are checked in.
115
- - Review the [source code changes](https://github.com/microsoft/FluidFramework/pulls).
119
+ - Answer questions in [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
120
+ - [Submit bug reports](https://github.com/microsoft/FluidFramework/issues) and help verify fixes.
121
+ - Review [source code changes](https://github.com/microsoft/FluidFramework/pulls).
116
122
  - [Contribute bug fixes](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md).
117
123
 
118
- Detailed instructions for working in the repo can be found in the [Wiki](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Home.md).
124
+ For detailed instructions, read the [repo documentation](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Home.md).
119
125
 
120
- This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
121
- 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.
126
+ This project follows the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
127
+ For more information, read the [Code of Conduct frequently asked questions](https://opensource.microsoft.com/codeofconduct/faq/).
128
+ For questions or comments, contact [opencode@microsoft.com](mailto:opencode@microsoft.com).
122
129
 
123
130
  This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
124
131
  Use of these trademarks or logos must follow Microsoft’s [Trademark & Brand Guidelines](https://www.microsoft.com/trademarks).
@@ -126,13 +133,9 @@ Use of Microsoft trademarks or logos in modified versions of this project must n
126
133
 
127
134
  ## Help
128
135
 
129
- Not finding what you're looking for in this README?
130
- Check out [fluidframework.com](https://fluidframework.com/docs/).
131
-
132
- Still not finding what you're looking for?
133
- Please [file an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
136
+ Read the [Fluid Framework documentation](https://fluidframework.com/docs/) for information about Fluid Framework concepts and APIs.
134
137
 
135
- Thank you!
138
+ To request information that the documentation does not contain, [create an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
136
139
 
137
140
  ## Trademark
138
141
 
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
3
- "extends": "../../../common/build/build-common/api-extractor-model.esm.json"
3
+ "extends": "<projectFolder>/../../../common/build/build-common/api-extractor-model.esm.json"
4
4
  }
@@ -26,7 +26,7 @@ export declare class ConsensusRegisterCollection<T> extends SharedObject<IConsen
26
26
  * Creates a new register or writes a new value.
27
27
  * Returns a promise that will resolve when the write is acked.
28
28
  *
29
- * @returns Promise<true> if write was non-concurrent
29
+ * @returns A promise resolving to `true` if the write was non-concurrent
30
30
  */
31
31
  write(key: string, value: T): Promise<boolean>;
32
32
  /**
@@ -26,21 +26,21 @@ const snapshotFileName = "header";
26
26
  * @legacy @beta
27
27
  */
28
28
  class ConsensusRegisterCollection extends internal_3.SharedObject {
29
+ data = new Map();
30
+ internalEvents = (0, client_utils_1.createEmitter)();
31
+ nextPendingMessageId = 0;
29
32
  /**
30
33
  * Constructs a new consensus register collection. If the object is non-local an id and service interfaces will
31
34
  * be provided
32
35
  */
33
36
  constructor(id, runtime, attributes) {
34
37
  super(id, runtime, attributes, "fluid_consensusRegisterCollection_");
35
- this.data = new Map();
36
- this.internalEvents = (0, client_utils_1.createEmitter)();
37
- this.nextPendingMessageId = 0;
38
38
  }
39
39
  /**
40
40
  * Creates a new register or writes a new value.
41
41
  * Returns a promise that will resolve when the write is acked.
42
42
  *
43
- * @returns Promise<true> if write was non-concurrent
43
+ * @returns A promise resolving to `true` if the write was non-concurrent
44
44
  */
45
45
  async write(key, value) {
46
46
  if (this.runtime.disposed) {
@@ -1 +1 @@
1
- {"version":3,"file":"consensusRegisterCollection.js","sourceRoot":"","sources":["../src/consensusRegisterCollection.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\nimport { bufferToString, createEmitter } from \"@fluid-internal/client-utils\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport {\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\n\nimport type {\n\tIConsensusRegisterCollection,\n\tIConsensusRegisterCollectionEvents,\n} from \"./interfaces.js\";\nimport { ReadPolicy } from \"./interfaces.js\";\n\ninterface ILocalData<T> {\n\t// Atomic version\n\tatomic: ILocalRegister<T>;\n\n\t// All concurrent versions awaiting consensus\n\tversions: ILocalRegister<T>[];\n}\n\ninterface ILocalRegister<T> {\n\t// Register value, wrapped for backwards compatibility with < 0.17\n\tvalue: {\n\t\ttype: \"Plain\";\n\t\tvalue: T;\n\t};\n\n\t// The sequence number when last consensus was reached\n\tsequenceNumber: number;\n}\n\nconst newLocalRegister = <T>(sequenceNumber: number, value: T): ILocalRegister<T> => ({\n\tsequenceNumber,\n\tvalue: {\n\t\ttype: \"Plain\",\n\t\tvalue,\n\t},\n});\n\n/**\n * An operation for consensus register collection\n *\n * The value stored in this op is serialized as a string and must be deserialized\n */\ninterface IRegisterOperationSerialized {\n\tkey: string;\n\ttype: \"write\";\n\tserializedValue: string;\n\n\t// Message can be delivered with delay - resubmitted on reconnect.\n\t// As such, refSeq needs to reference seq # at the time op was created,\n\t// not when op was actually sent over wire (ISequencedDocumentMessage.referenceSequenceNumber),\n\t// as client can ingest ops in between.\n\trefSeq: number | undefined;\n}\n\n/**\n * IRegisterOperation format in versions \\< 0.17 and \\>=2.0.0-rc.2.0.0\n *\n * The value stored in this op is _not_ serialized and is stored literally as `T`\n */\ninterface IRegisterOperationPlain<T> {\n\tkey: string;\n\ttype: \"write\";\n\n\tvalue: {\n\t\ttype: \"Plain\";\n\t\tvalue: T;\n\t};\n\n\t// back-compat: for clients prior to 2.0.0-rc.2.0.0, we must also pass in\n\t// the serialized value for them to parse handles correctly. we do not have\n\t// to pay the cost of deserializing this value in newer clients\n\tserializedValue: string;\n\n\t// back-compat: files at rest written with runtime <= 0.13 do not have refSeq\n\trefSeq: number | undefined;\n}\n\n/** Incoming ops could match any of these types */\ntype IIncomingRegisterOperation<T> = IRegisterOperationSerialized | IRegisterOperationPlain<T>;\n\n/** Distinguish between incoming op formats so we know which type it is */\nconst incomingOpMatchesPlainFormat = <T>(op): op is IRegisterOperationPlain<T> =>\n\t\"value\" in op;\n\nconst snapshotFileName = \"header\";\n\ninterface IConsensusRegisterCollectionInternalEvents {\n\t/**\n\t * Emitted when a pending message is rolled back.\n\t * @param rollbackMessageId - A unique identifying number for the pending message.\n\t */\n\tpendingMessageRollback: (rollbackMessageId: number) => void;\n\n\t/**\n\t * Emitted when a pending message is acknowledged.\n\t * @param ackMessageId - A unique identifying number for the pending message.\n\t * @param isWinner - Whether the message won the FWW race to modify the value.\n\t */\n\tpendingMessageAck: (ackMessageId: number, isWinner: boolean) => void;\n}\n\n/**\n * {@inheritDoc IConsensusRegisterCollection}\n * @deprecated Use {@link IConsensusRegisterCollection} for typing and {@link ConsensusRegisterCollectionFactory} to create instances. This implementation class will be removed in a future release.\n * @legacy @beta\n */\nexport class ConsensusRegisterCollection<T>\n\textends SharedObject<IConsensusRegisterCollectionEvents>\n\timplements IConsensusRegisterCollection<T>\n{\n\tprivate readonly data = new Map<string, ILocalData<T>>();\n\tprivate readonly internalEvents =\n\t\tcreateEmitter<IConsensusRegisterCollectionInternalEvents>();\n\n\tprivate nextPendingMessageId: number = 0;\n\n\t/**\n\t * Constructs a new consensus register collection. If the object is non-local an id and service interfaces will\n\t * be provided\n\t */\n\tpublic constructor(\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(id, runtime, attributes, \"fluid_consensusRegisterCollection_\");\n\t}\n\n\t/**\n\t * Creates a new register or writes a new value.\n\t * Returns a promise that will resolve when the write is acked.\n\t *\n\t * @returns Promise<true> if write was non-concurrent\n\t */\n\tpublic async write(key: string, value: T): Promise<boolean> {\n\t\tif (this.runtime.disposed) {\n\t\t\t// Return false if disposed to signify that we did not write.\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!this.isAttached()) {\n\t\t\tthis.processInboundWrite(key, value, 0, 0, true);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst message: IRegisterOperationPlain<T> = {\n\t\t\tkey,\n\t\t\ttype: \"write\",\n\t\t\tserializedValue: this.stringify(value, this.serializer),\n\t\t\tvalue: {\n\t\t\t\ttype: \"Plain\",\n\t\t\t\tvalue,\n\t\t\t},\n\t\t\trefSeq: this.deltaManager.lastSequenceNumber,\n\t\t};\n\n\t\tconst pendingMessageId = this.nextPendingMessageId++;\n\n\t\t// There are three ways the write promise can resolve:\n\t\t// 1. The write is acked\n\t\t// 2. The write is rolled back\n\t\t// 3. The runtime is disposed\n\t\t// The boolean value returned by the promise is true if the attempted write was ack'd and won, false otherwise.\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tconst handleAck = (ackMessageId: number, isWinner: boolean): void => {\n\t\t\t\tif (ackMessageId === pendingMessageId) {\n\t\t\t\t\tresolve(isWinner);\n\t\t\t\t\tremoveListeners();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleRollback = (rollbackMessageId: number): void => {\n\t\t\t\tif (rollbackMessageId === pendingMessageId) {\n\t\t\t\t\t// If we rolled back the pending message, resolve the promise with false.\n\t\t\t\t\tresolve(false);\n\t\t\t\t\tremoveListeners();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleDisposed = (): void => {\n\t\t\t\tresolve(false);\n\t\t\t\tremoveListeners();\n\t\t\t};\n\n\t\t\tconst removeListeners = (): void => {\n\t\t\t\tthis.internalEvents.off(\"pendingMessageAck\", handleAck);\n\t\t\t\tthis.internalEvents.off(\"pendingMessageRollback\", handleRollback);\n\t\t\t\tthis.runtime.off(\"dispose\", handleDisposed);\n\t\t\t};\n\n\t\t\tthis.internalEvents.on(\"pendingMessageAck\", handleAck);\n\t\t\tthis.internalEvents.on(\"pendingMessageRollback\", handleRollback);\n\t\t\tthis.runtime.on(\"dispose\", handleDisposed);\n\n\t\t\tthis.submitLocalMessage(message, pendingMessageId);\n\t\t});\n\t}\n\n\t/**\n\t * Returns the most recent local value of a register.\n\t * @param key - The key to read\n\t * @param readPolicy - The ReadPolicy to apply. Defaults to Atomic.\n\t */\n\tpublic read(key: string, readPolicy: ReadPolicy = ReadPolicy.Atomic): T | undefined {\n\t\tif (readPolicy === ReadPolicy.Atomic) {\n\t\t\treturn this.readAtomic(key);\n\t\t}\n\n\t\tconst versions = this.readVersions(key);\n\n\t\tif (versions !== undefined) {\n\t\t\t// We don't support deletion. So there should be at least one value.\n\t\t\tassert(versions.length > 0, 0x06c /* \"Value should be undefined or non-empty\" */);\n\n\t\t\treturn versions[versions.length - 1];\n\t\t}\n\t}\n\n\tpublic readVersions(key: string): T[] | undefined {\n\t\tconst data = this.data.get(key);\n\t\treturn data?.versions.map((element: ILocalRegister<T>) => element.value.value);\n\t}\n\n\tpublic keys(): string[] {\n\t\treturn [...this.data.keys()];\n\t}\n\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\tconst dataObj: { [key: string]: ILocalData<T> } = {};\n\t\tfor (const [k, v] of this.data.entries()) {\n\t\t\tdataObj[k] = v;\n\t\t}\n\n\t\treturn createSingleBlobSummary(snapshotFileName, this.stringify(dataObj, serializer));\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst blob = await storage.readBlob(snapshotFileName);\n\t\tconst header = bufferToString(blob, \"utf8\");\n\t\tconst dataObj = this.parse(header, this.serializer);\n\n\t\tfor (const key of Object.keys(dataObj)) {\n\t\t\tassert(\n\t\t\t\tdataObj[key].atomic?.value.type !== \"Shared\",\n\t\t\t\t0x06d /* \"SharedObjects contained in ConsensusRegisterCollection can no longer be deserialized as of 0.17\" */,\n\t\t\t);\n\n\t\t\tthis.data.set(key, dataObj[key]);\n\t\t}\n\t}\n\n\tprotected onDisconnect(): void {}\n\n\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\tif (messageEnvelope.type === MessageType.Operation) {\n\t\t\tconst op = messageContent.contents as IIncomingRegisterOperation<T>;\n\t\t\tswitch (op.type) {\n\t\t\t\tcase \"write\": {\n\t\t\t\t\t// backward compatibility: File at rest written with runtime <= 0.13 do not have refSeq\n\t\t\t\t\t// when the refSeq property didn't exist\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\t\t\t\tif (op.refSeq === undefined) {\n\t\t\t\t\t\top.refSeq = messageEnvelope.referenceSequenceNumber;\n\t\t\t\t\t}\n\t\t\t\t\t// Message can be delivered with delay - e.g. resubmitted on reconnect.\n\t\t\t\t\t// Use the refSeq from when the op was created, not when it was transmitted\n\t\t\t\t\tconst refSeqWhenCreated = op.refSeq;\n\t\t\t\t\tassert(\n\t\t\t\t\t\trefSeqWhenCreated <= messageEnvelope.referenceSequenceNumber,\n\t\t\t\t\t\t0x06e /* \"Message's reference sequence number < op's reference sequence number!\" */,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst value = incomingOpMatchesPlainFormat<T>(op)\n\t\t\t\t\t\t? op.value.value\n\t\t\t\t\t\t: (this.parse(op.serializedValue, this.serializer) as T);\n\t\t\t\t\tconst isWinner = this.processInboundWrite(\n\t\t\t\t\t\top.key,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\trefSeqWhenCreated,\n\t\t\t\t\t\tmessageEnvelope.sequenceNumber,\n\t\t\t\t\t\tlocal,\n\t\t\t\t\t);\n\t\t\t\t\tif (local) {\n\t\t\t\t\t\t// Resolve the pending promise for this operation now that we have received an ack for it.\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\ttypeof messageContent.localOpMetadata === \"number\",\n\t\t\t\t\t\t\t0xc0e /* Expect localOpMetadata to be a number */,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.internalEvents.emit(\n\t\t\t\t\t\t\t\"pendingMessageAck\",\n\t\t\t\t\t\t\tmessageContent.localOpMetadata,\n\t\t\t\t\t\t\tisWinner,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tunreachableCase(op.type);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate readAtomic(key: string): T | undefined {\n\t\tconst data = this.data.get(key);\n\t\treturn data?.atomic.value.value;\n\t}\n\n\t/**\n\t * Process an inbound write op\n\t * @param key - Key that was written to\n\t * @param value - Incoming value\n\t * @param refSeq - RefSeq at the time of write on the remote client\n\t * @param sequenceNumber - Sequence Number of this write op\n\t * @param local - Did this write originate on this client\n\t */\n\tprivate processInboundWrite(\n\t\tkey: string,\n\t\tvalue: T,\n\t\trefSeq: number,\n\t\tsequenceNumber: number,\n\t\tlocal: boolean,\n\t): boolean {\n\t\tlet data = this.data.get(key);\n\t\t// Atomic update if it's a new register or the write was not concurrent,\n\t\t// meaning our state was known to the remote client at the time of write\n\t\tconst isWinner = data === undefined || refSeq >= data.atomic.sequenceNumber;\n\t\tif (isWinner) {\n\t\t\tconst atomicUpdate = newLocalRegister<T>(sequenceNumber, value);\n\t\t\tif (data === undefined) {\n\t\t\t\tdata = {\n\t\t\t\t\tatomic: atomicUpdate,\n\t\t\t\t\tversions: [], // we'll update versions next, leave it empty for now\n\t\t\t\t};\n\t\t\t\tthis.data.set(key, data);\n\t\t\t} else {\n\t\t\t\tdata.atomic = atomicUpdate;\n\t\t\t}\n\t\t} else {\n\t\t\tassert(!!data, 0x06f /* \"data missing for non-atomic inbound update!\" */);\n\t\t}\n\n\t\t// Remove versions that were known to the remote client at the time of write\n\t\twhile (data.versions.length > 0 && refSeq >= data.versions[0].sequenceNumber) {\n\t\t\tdata.versions.shift();\n\t\t}\n\n\t\tconst versionUpdate = newLocalRegister<T>(sequenceNumber, value);\n\n\t\t// Asserts for data integrity\n\t\tif (!this.isAttached()) {\n\t\t\tassert(\n\t\t\t\trefSeq === 0 && sequenceNumber === 0,\n\t\t\t\t0x070 /* \"sequence numbers are expected to be 0 when unattached\" */,\n\t\t\t);\n\t\t} else if (data.versions.length > 0) {\n\t\t\tassert(\n\t\t\t\t// seqNum should always be increasing, except for the case of grouped batches (seqNum will be the same)\n\t\t\t\tsequenceNumber >= data.versions[data.versions.length - 1].sequenceNumber,\n\t\t\t\t0x071 /* \"Versions should naturally be ordered by sequenceNumber\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Push the new element.\n\t\tdata.versions.push(versionUpdate);\n\n\t\t// Raise events at the end, to avoid reentrancy issues\n\t\tif (isWinner) {\n\t\t\tthis.emit(\"atomicChanged\", key, value, local);\n\t\t}\n\t\tthis.emit(\"versionChanged\", key, value, local);\n\n\t\treturn isWinner;\n\t}\n\n\tprivate stringify(value: any, serializer: IFluidSerializer): string {\n\t\treturn serializer.stringify(value, this.handle);\n\t}\n\n\tprivate parse(content: string, serializer: IFluidSerializer): any {\n\t\treturn serializer.parse(content);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}\n\t * @sealed\n\t */\n\tprotected rollback(content: unknown, localOpMetadata: unknown): void {\n\t\t// We don't need to do anything to roll back CRC, it's safe to just drop\n\t\t// the op on the floor since we don't modify the DDS until the ack.\n\t\t// We emit an internal event so we know to resolve the pending promise.\n\t\tassert(\n\t\t\ttypeof localOpMetadata === \"number\",\n\t\t\t0xc0f /* Expect localOpMetadata to be a number */,\n\t\t);\n\t\tthis.internalEvents.emit(\"pendingMessageRollback\", localOpMetadata);\n\t}\n\n\tprotected applyStashedOp(content: unknown): void {\n\t\tconst op = content as IIncomingRegisterOperation<T>;\n\t\tassert(op.type === \"write\", 0xccc /* Only write ops should be stashed */);\n\t\t// Submit the original op (preserving its refSeq) so we can match the ACK\n\t\t// when it arrives during remote op processing.\n\t\tconst pendingMessageId = this.nextPendingMessageId++;\n\t\tthis.submitLocalMessage(op, pendingMessageId);\n\t}\n}\n"]}
1
+ {"version":3,"file":"consensusRegisterCollection.js","sourceRoot":"","sources":["../src/consensusRegisterCollection.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\nimport { bufferToString, createEmitter } from \"@fluid-internal/client-utils\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport {\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\n\nimport type {\n\tIConsensusRegisterCollection,\n\tIConsensusRegisterCollectionEvents,\n} from \"./interfaces.js\";\nimport { ReadPolicy } from \"./interfaces.js\";\n\ninterface ILocalData<T> {\n\t// Atomic version\n\tatomic: ILocalRegister<T>;\n\n\t// All concurrent versions awaiting consensus\n\tversions: ILocalRegister<T>[];\n}\n\ninterface ILocalRegister<T> {\n\t// Register value, wrapped for backwards compatibility with < 0.17\n\tvalue: {\n\t\ttype: \"Plain\";\n\t\tvalue: T;\n\t};\n\n\t// The sequence number when last consensus was reached\n\tsequenceNumber: number;\n}\n\nconst newLocalRegister = <T>(sequenceNumber: number, value: T): ILocalRegister<T> => ({\n\tsequenceNumber,\n\tvalue: {\n\t\ttype: \"Plain\",\n\t\tvalue,\n\t},\n});\n\n/**\n * An operation for consensus register collection\n *\n * The value stored in this op is serialized as a string and must be deserialized\n */\ninterface IRegisterOperationSerialized {\n\tkey: string;\n\ttype: \"write\";\n\tserializedValue: string;\n\n\t// Message can be delivered with delay - resubmitted on reconnect.\n\t// As such, refSeq needs to reference seq # at the time op was created,\n\t// not when op was actually sent over wire (ISequencedDocumentMessage.referenceSequenceNumber),\n\t// as client can ingest ops in between.\n\trefSeq: number | undefined;\n}\n\n/**\n * IRegisterOperation format in versions \\< 0.17 and \\>=2.0.0-rc.2.0.0\n *\n * The value stored in this op is _not_ serialized and is stored literally as `T`\n */\ninterface IRegisterOperationPlain<T> {\n\tkey: string;\n\ttype: \"write\";\n\n\tvalue: {\n\t\ttype: \"Plain\";\n\t\tvalue: T;\n\t};\n\n\t// back-compat: for clients prior to 2.0.0-rc.2.0.0, we must also pass in\n\t// the serialized value for them to parse handles correctly. we do not have\n\t// to pay the cost of deserializing this value in newer clients\n\tserializedValue: string;\n\n\t// back-compat: files at rest written with runtime <= 0.13 do not have refSeq\n\trefSeq: number | undefined;\n}\n\n/** Incoming ops could match any of these types */\ntype IIncomingRegisterOperation<T> = IRegisterOperationSerialized | IRegisterOperationPlain<T>;\n\n/** Distinguish between incoming op formats so we know which type it is */\nconst incomingOpMatchesPlainFormat = <T>(op): op is IRegisterOperationPlain<T> =>\n\t\"value\" in op;\n\nconst snapshotFileName = \"header\";\n\ninterface IConsensusRegisterCollectionInternalEvents {\n\t/**\n\t * Emitted when a pending message is rolled back.\n\t * @param rollbackMessageId - A unique identifying number for the pending message.\n\t */\n\tpendingMessageRollback: (rollbackMessageId: number) => void;\n\n\t/**\n\t * Emitted when a pending message is acknowledged.\n\t * @param ackMessageId - A unique identifying number for the pending message.\n\t * @param isWinner - Whether the message won the FWW race to modify the value.\n\t */\n\tpendingMessageAck: (ackMessageId: number, isWinner: boolean) => void;\n}\n\n/**\n * {@inheritDoc IConsensusRegisterCollection}\n * @deprecated Use {@link IConsensusRegisterCollection} for typing and {@link ConsensusRegisterCollectionFactory} to create instances. This implementation class will be removed in a future release.\n * @legacy @beta\n */\nexport class ConsensusRegisterCollection<T>\n\textends SharedObject<IConsensusRegisterCollectionEvents>\n\timplements IConsensusRegisterCollection<T>\n{\n\tprivate readonly data = new Map<string, ILocalData<T>>();\n\tprivate readonly internalEvents =\n\t\tcreateEmitter<IConsensusRegisterCollectionInternalEvents>();\n\n\tprivate nextPendingMessageId: number = 0;\n\n\t/**\n\t * Constructs a new consensus register collection. If the object is non-local an id and service interfaces will\n\t * be provided\n\t */\n\tpublic constructor(\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(id, runtime, attributes, \"fluid_consensusRegisterCollection_\");\n\t}\n\n\t/**\n\t * Creates a new register or writes a new value.\n\t * Returns a promise that will resolve when the write is acked.\n\t *\n\t * @returns A promise resolving to `true` if the write was non-concurrent\n\t */\n\tpublic async write(key: string, value: T): Promise<boolean> {\n\t\tif (this.runtime.disposed) {\n\t\t\t// Return false if disposed to signify that we did not write.\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!this.isAttached()) {\n\t\t\tthis.processInboundWrite(key, value, 0, 0, true);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst message: IRegisterOperationPlain<T> = {\n\t\t\tkey,\n\t\t\ttype: \"write\",\n\t\t\tserializedValue: this.stringify(value, this.serializer),\n\t\t\tvalue: {\n\t\t\t\ttype: \"Plain\",\n\t\t\t\tvalue,\n\t\t\t},\n\t\t\trefSeq: this.deltaManager.lastSequenceNumber,\n\t\t};\n\n\t\tconst pendingMessageId = this.nextPendingMessageId++;\n\n\t\t// There are three ways the write promise can resolve:\n\t\t// 1. The write is acked\n\t\t// 2. The write is rolled back\n\t\t// 3. The runtime is disposed\n\t\t// The boolean value returned by the promise is true if the attempted write was ack'd and won, false otherwise.\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tconst handleAck = (ackMessageId: number, isWinner: boolean): void => {\n\t\t\t\tif (ackMessageId === pendingMessageId) {\n\t\t\t\t\tresolve(isWinner);\n\t\t\t\t\tremoveListeners();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleRollback = (rollbackMessageId: number): void => {\n\t\t\t\tif (rollbackMessageId === pendingMessageId) {\n\t\t\t\t\t// If we rolled back the pending message, resolve the promise with false.\n\t\t\t\t\tresolve(false);\n\t\t\t\t\tremoveListeners();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleDisposed = (): void => {\n\t\t\t\tresolve(false);\n\t\t\t\tremoveListeners();\n\t\t\t};\n\n\t\t\tconst removeListeners = (): void => {\n\t\t\t\tthis.internalEvents.off(\"pendingMessageAck\", handleAck);\n\t\t\t\tthis.internalEvents.off(\"pendingMessageRollback\", handleRollback);\n\t\t\t\tthis.runtime.off(\"dispose\", handleDisposed);\n\t\t\t};\n\n\t\t\tthis.internalEvents.on(\"pendingMessageAck\", handleAck);\n\t\t\tthis.internalEvents.on(\"pendingMessageRollback\", handleRollback);\n\t\t\tthis.runtime.on(\"dispose\", handleDisposed);\n\n\t\t\tthis.submitLocalMessage(message, pendingMessageId);\n\t\t});\n\t}\n\n\t/**\n\t * Returns the most recent local value of a register.\n\t * @param key - The key to read\n\t * @param readPolicy - The ReadPolicy to apply. Defaults to Atomic.\n\t */\n\tpublic read(key: string, readPolicy: ReadPolicy = ReadPolicy.Atomic): T | undefined {\n\t\tif (readPolicy === ReadPolicy.Atomic) {\n\t\t\treturn this.readAtomic(key);\n\t\t}\n\n\t\tconst versions = this.readVersions(key);\n\n\t\tif (versions !== undefined) {\n\t\t\t// We don't support deletion. So there should be at least one value.\n\t\t\tassert(versions.length > 0, 0x06c /* \"Value should be undefined or non-empty\" */);\n\n\t\t\treturn versions[versions.length - 1];\n\t\t}\n\t}\n\n\tpublic readVersions(key: string): T[] | undefined {\n\t\tconst data = this.data.get(key);\n\t\treturn data?.versions.map((element: ILocalRegister<T>) => element.value.value);\n\t}\n\n\tpublic keys(): string[] {\n\t\treturn [...this.data.keys()];\n\t}\n\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\tconst dataObj: { [key: string]: ILocalData<T> } = {};\n\t\tfor (const [k, v] of this.data.entries()) {\n\t\t\tdataObj[k] = v;\n\t\t}\n\n\t\treturn createSingleBlobSummary(snapshotFileName, this.stringify(dataObj, serializer));\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst blob = await storage.readBlob(snapshotFileName);\n\t\tconst header = bufferToString(blob, \"utf8\");\n\t\tconst dataObj = this.parse(header, this.serializer);\n\n\t\tfor (const key of Object.keys(dataObj)) {\n\t\t\tassert(\n\t\t\t\tdataObj[key].atomic?.value.type !== \"Shared\",\n\t\t\t\t0x06d /* \"SharedObjects contained in ConsensusRegisterCollection can no longer be deserialized as of 0.17\" */,\n\t\t\t);\n\n\t\t\tthis.data.set(key, dataObj[key]);\n\t\t}\n\t}\n\n\tprotected onDisconnect(): void {}\n\n\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\tif (messageEnvelope.type === MessageType.Operation) {\n\t\t\tconst op = messageContent.contents as IIncomingRegisterOperation<T>;\n\t\t\tswitch (op.type) {\n\t\t\t\tcase \"write\": {\n\t\t\t\t\t// backward compatibility: File at rest written with runtime <= 0.13 do not have refSeq\n\t\t\t\t\t// when the refSeq property didn't exist\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\t\t\t\tif (op.refSeq === undefined) {\n\t\t\t\t\t\top.refSeq = messageEnvelope.referenceSequenceNumber;\n\t\t\t\t\t}\n\t\t\t\t\t// Message can be delivered with delay - e.g. resubmitted on reconnect.\n\t\t\t\t\t// Use the refSeq from when the op was created, not when it was transmitted\n\t\t\t\t\tconst refSeqWhenCreated = op.refSeq;\n\t\t\t\t\tassert(\n\t\t\t\t\t\trefSeqWhenCreated <= messageEnvelope.referenceSequenceNumber,\n\t\t\t\t\t\t0x06e /* \"Message's reference sequence number < op's reference sequence number!\" */,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst value = incomingOpMatchesPlainFormat<T>(op)\n\t\t\t\t\t\t? op.value.value\n\t\t\t\t\t\t: (this.parse(op.serializedValue, this.serializer) as T);\n\t\t\t\t\tconst isWinner = this.processInboundWrite(\n\t\t\t\t\t\top.key,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\trefSeqWhenCreated,\n\t\t\t\t\t\tmessageEnvelope.sequenceNumber,\n\t\t\t\t\t\tlocal,\n\t\t\t\t\t);\n\t\t\t\t\tif (local) {\n\t\t\t\t\t\t// Resolve the pending promise for this operation now that we have received an ack for it.\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\ttypeof messageContent.localOpMetadata === \"number\",\n\t\t\t\t\t\t\t0xc0e /* Expect localOpMetadata to be a number */,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.internalEvents.emit(\n\t\t\t\t\t\t\t\"pendingMessageAck\",\n\t\t\t\t\t\t\tmessageContent.localOpMetadata,\n\t\t\t\t\t\t\tisWinner,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tunreachableCase(op.type);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate readAtomic(key: string): T | undefined {\n\t\tconst data = this.data.get(key);\n\t\treturn data?.atomic.value.value;\n\t}\n\n\t/**\n\t * Process an inbound write op\n\t * @param key - Key that was written to\n\t * @param value - Incoming value\n\t * @param refSeq - RefSeq at the time of write on the remote client\n\t * @param sequenceNumber - Sequence Number of this write op\n\t * @param local - Did this write originate on this client\n\t */\n\tprivate processInboundWrite(\n\t\tkey: string,\n\t\tvalue: T,\n\t\trefSeq: number,\n\t\tsequenceNumber: number,\n\t\tlocal: boolean,\n\t): boolean {\n\t\tlet data = this.data.get(key);\n\t\t// Atomic update if it's a new register or the write was not concurrent,\n\t\t// meaning our state was known to the remote client at the time of write\n\t\tconst isWinner = data === undefined || refSeq >= data.atomic.sequenceNumber;\n\t\tif (isWinner) {\n\t\t\tconst atomicUpdate = newLocalRegister<T>(sequenceNumber, value);\n\t\t\tif (data === undefined) {\n\t\t\t\tdata = {\n\t\t\t\t\tatomic: atomicUpdate,\n\t\t\t\t\tversions: [], // we'll update versions next, leave it empty for now\n\t\t\t\t};\n\t\t\t\tthis.data.set(key, data);\n\t\t\t} else {\n\t\t\t\tdata.atomic = atomicUpdate;\n\t\t\t}\n\t\t} else {\n\t\t\tassert(!!data, 0x06f /* \"data missing for non-atomic inbound update!\" */);\n\t\t}\n\n\t\t// Remove versions that were known to the remote client at the time of write\n\t\twhile (data.versions.length > 0 && refSeq >= data.versions[0].sequenceNumber) {\n\t\t\tdata.versions.shift();\n\t\t}\n\n\t\tconst versionUpdate = newLocalRegister<T>(sequenceNumber, value);\n\n\t\t// Asserts for data integrity\n\t\tif (!this.isAttached()) {\n\t\t\tassert(\n\t\t\t\trefSeq === 0 && sequenceNumber === 0,\n\t\t\t\t0x070 /* \"sequence numbers are expected to be 0 when unattached\" */,\n\t\t\t);\n\t\t} else if (data.versions.length > 0) {\n\t\t\tassert(\n\t\t\t\t// seqNum should always be increasing, except for the case of grouped batches (seqNum will be the same)\n\t\t\t\tsequenceNumber >= data.versions[data.versions.length - 1].sequenceNumber,\n\t\t\t\t0x071 /* \"Versions should naturally be ordered by sequenceNumber\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Push the new element.\n\t\tdata.versions.push(versionUpdate);\n\n\t\t// Raise events at the end, to avoid reentrancy issues\n\t\tif (isWinner) {\n\t\t\tthis.emit(\"atomicChanged\", key, value, local);\n\t\t}\n\t\tthis.emit(\"versionChanged\", key, value, local);\n\n\t\treturn isWinner;\n\t}\n\n\tprivate stringify(value: any, serializer: IFluidSerializer): string {\n\t\treturn serializer.stringify(value, this.handle);\n\t}\n\n\tprivate parse(content: string, serializer: IFluidSerializer): any {\n\t\treturn serializer.parse(content);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}\n\t * @sealed\n\t */\n\tprotected rollback(content: unknown, localOpMetadata: unknown): void {\n\t\t// We don't need to do anything to roll back CRC, it's safe to just drop\n\t\t// the op on the floor since we don't modify the DDS until the ack.\n\t\t// We emit an internal event so we know to resolve the pending promise.\n\t\tassert(\n\t\t\ttypeof localOpMetadata === \"number\",\n\t\t\t0xc0f /* Expect localOpMetadata to be a number */,\n\t\t);\n\t\tthis.internalEvents.emit(\"pendingMessageRollback\", localOpMetadata);\n\t}\n\n\tprotected applyStashedOp(content: unknown): void {\n\t\tconst op = content as IIncomingRegisterOperation<T>;\n\t\tassert(op.type === \"write\", 0xccc /* Only write ops should be stashed */);\n\t\t// Submit the original op (preserving its refSeq) so we can match the ACK\n\t\t// when it arrives during remote op processing.\n\t\tconst pendingMessageId = this.nextPendingMessageId++;\n\t\tthis.submitLocalMessage(op, pendingMessageId);\n\t}\n}\n"]}
@@ -23,7 +23,7 @@ export declare class ConsensusRegisterCollectionFactory implements IChannelFacto
23
23
  * {@inheritDoc IConsensusRegisterCollection}
24
24
  * @legacy @beta
25
25
  */
26
- export declare const ConsensusRegisterCollection: import("@fluidframework/shared-object-base/internal").ISharedObjectKind<IConsensusRegisterCollection<any>> & import("@fluidframework/shared-object-base/internal").SharedObjectKind<IConsensusRegisterCollection<any>>;
26
+ export declare const ConsensusRegisterCollection: import("@fluidframework/shared-object-base", { with: { "resolution-mode": "import" } }).ISharedObjectKind<IConsensusRegisterCollection<any>> & import("@fluidframework/shared-object-base", { with: { "resolution-mode": "import" } }).SharedObjectKind<IConsensusRegisterCollection<any>>;
27
27
  /**
28
28
  * Compatibility alias for {@link IConsensusRegisterCollection}.
29
29
  * @legacy @beta
@@ -1 +1 @@
1
- {"version":3,"file":"consensusRegisterCollectionFactory.d.ts","sourceRoot":"","sources":["../src/consensusRegisterCollectionFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AAKxD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAGpE;;;GAGG;AACH,qBAAa,kCACZ,YAAW,eAAe,CAAC,4BAA4B,CAAC;IAKxD,OAAc,IAAI,SAAqE;IAEvF,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAW,UAAU,IAAI,kBAAkB,CAE1C;IAED;;OAEG;IACU,IAAI,CAChB,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAC5B,OAAO,CAAC,4BAA4B,CAAC;IAOjC,MAAM,CAAC,QAAQ,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,4BAA4B;CAUzF;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,wNAEvC,CAAC;AACF;;;GAGG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,IAAI,4BAA4B,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"consensusRegisterCollectionFactory.d.ts","sourceRoot":"","sources":["../src/consensusRegisterCollectionFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AAKxD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAGpE;;;GAGG;AACH,qBAAa,kCACZ,YAAW,eAAe,CAAC,4BAA4B,CAAC;IAKxD,OAAc,IAAI,SAAqE;IAEvF,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAW,UAAU,IAAI,kBAAkB,CAE1C;IAED;;OAEG;IACU,IAAI,CAChB,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAC5B,OAAO,CAAC,4BAA4B,CAAC;IAOjC,MAAM,CAAC,QAAQ,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,4BAA4B;CAUzF;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,4RAEvC,CAAC;AACF;;;GAGG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,IAAI,4BAA4B,CAAC,CAAC,CAAC,CAAC"}
@@ -14,6 +14,15 @@ const packageVersion_js_1 = require("./packageVersion.js");
14
14
  * @legacy @beta
15
15
  */
16
16
  class ConsensusRegisterCollectionFactory {
17
+ // New type string, to be activated once the migration has been fully shipped dark and is safe to flip.
18
+ // See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.
19
+ // public static Type = "consensus-register-collection";
20
+ static Type = "https://graph.microsoft.com/types/consensus-register-collection";
21
+ static Attributes = {
22
+ type: ConsensusRegisterCollectionFactory.Type,
23
+ snapshotFormatVersion: "0.1",
24
+ packageVersion: packageVersion_js_1.pkgVersion,
25
+ };
17
26
  get type() {
18
27
  return ConsensusRegisterCollectionFactory.Type;
19
28
  }
@@ -37,15 +46,6 @@ class ConsensusRegisterCollectionFactory {
37
46
  }
38
47
  }
39
48
  exports.ConsensusRegisterCollectionFactory = ConsensusRegisterCollectionFactory;
40
- // New type string, to be activated once the migration has been fully shipped dark and is safe to flip.
41
- // See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.
42
- // public static Type = "consensus-register-collection";
43
- ConsensusRegisterCollectionFactory.Type = "https://graph.microsoft.com/types/consensus-register-collection";
44
- ConsensusRegisterCollectionFactory.Attributes = {
45
- type: ConsensusRegisterCollectionFactory.Type,
46
- snapshotFormatVersion: "0.1",
47
- packageVersion: packageVersion_js_1.pkgVersion,
48
- };
49
49
  /**
50
50
  * {@inheritDoc IConsensusRegisterCollection}
51
51
  * @legacy @beta
@@ -1 +1 @@
1
- {"version":3,"file":"consensusRegisterCollectionFactory.js","sourceRoot":"","sources":["../src/consensusRegisterCollectionFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAQH,0EAAqF;AAErF,mGAAmG;AACnG,qFAAmH;AAEnH,2DAAiD;AAEjD;;;GAGG;AACH,MAAa,kCAAkC;IAc9C,IAAW,IAAI;QACd,OAAO,kCAAkC,CAAC,IAAI,CAAC;IAChD,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,kCAAkC,CAAC,UAAU,CAAC;IACtD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,wFAAwF;QACxF,MAAM,UAAU,GAAG,IAAI,4DAAgC,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QACjF,MAAM,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,OAAO,UAAU,CAAC;IACnB,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACzD,wFAAwF;QACxF,MAAM,UAAU,GAAG,IAAI,4DAAgC,CACtD,EAAE,EACF,QAAQ,EACR,kCAAkC,CAAC,UAAU,CAC7C,CAAC;QACF,UAAU,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC;IACnB,CAAC;;AA9CF,gFA+CC;AA5CA,uGAAuG;AACvG,qFAAqF;AACrF,wDAAwD;AAC1C,uCAAI,GAAG,iEAAiE,CAAC;AAEhE,6CAAU,GAAuB;IACvD,IAAI,EAAE,kCAAkC,CAAC,IAAI;IAC7C,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,8BAAU;CAC1B,CAAC;AAqCH;;;GAGG;AACU,QAAA,2BAA2B,GAAG,IAAA,iCAAsB,EAChE,kCAAkC,CAClC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIChannelServices,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\n// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class in factory\nimport { ConsensusRegisterCollection as ConsensusRegisterCollectionClass } from \"./consensusRegisterCollection.js\";\nimport type { IConsensusRegisterCollection } from \"./interfaces.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * The factory that defines the consensus queue.\n * @legacy @beta\n */\nexport class ConsensusRegisterCollectionFactory\n\timplements IChannelFactory<IConsensusRegisterCollection>\n{\n\t// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.\n\t// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.\n\t// public static Type = \"consensus-register-collection\";\n\tpublic static Type = \"https://graph.microsoft.com/types/consensus-register-collection\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: ConsensusRegisterCollectionFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type(): string {\n\t\treturn ConsensusRegisterCollectionFactory.Type;\n\t}\n\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn ConsensusRegisterCollectionFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<IConsensusRegisterCollection> {\n\t\t// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class\n\t\tconst collection = new ConsensusRegisterCollectionClass(id, runtime, attributes);\n\t\tawait collection.load(services);\n\t\treturn collection;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): IConsensusRegisterCollection {\n\t\t// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class\n\t\tconst collection = new ConsensusRegisterCollectionClass(\n\t\t\tid,\n\t\t\tdocument,\n\t\t\tConsensusRegisterCollectionFactory.Attributes,\n\t\t);\n\t\tcollection.initializeLocal();\n\t\treturn collection;\n\t}\n}\n\n/**\n * {@inheritDoc IConsensusRegisterCollection}\n * @legacy @beta\n */\nexport const ConsensusRegisterCollection = createSharedObjectKind(\n\tConsensusRegisterCollectionFactory,\n);\n/**\n * Compatibility alias for {@link IConsensusRegisterCollection}.\n * @legacy @beta\n */\nexport type ConsensusRegisterCollection<T> = IConsensusRegisterCollection<T>;\n"]}
1
+ {"version":3,"file":"consensusRegisterCollectionFactory.js","sourceRoot":"","sources":["../src/consensusRegisterCollectionFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAQH,0EAAqF;AAErF,mGAAmG;AACnG,qFAAmH;AAEnH,2DAAiD;AAEjD;;;GAGG;AACH,MAAa,kCAAkC;IAG9C,uGAAuG;IACvG,qFAAqF;IACrF,wDAAwD;IACjD,MAAM,CAAC,IAAI,GAAG,iEAAiE,CAAC;IAEhF,MAAM,CAAU,UAAU,GAAuB;QACvD,IAAI,EAAE,kCAAkC,CAAC,IAAI;QAC7C,qBAAqB,EAAE,KAAK;QAC5B,cAAc,EAAE,8BAAU;KAC1B,CAAC;IAEF,IAAW,IAAI;QACd,OAAO,kCAAkC,CAAC,IAAI,CAAC;IAChD,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,kCAAkC,CAAC,UAAU,CAAC;IACtD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,wFAAwF;QACxF,MAAM,UAAU,GAAG,IAAI,4DAAgC,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QACjF,MAAM,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,OAAO,UAAU,CAAC;IACnB,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACzD,wFAAwF;QACxF,MAAM,UAAU,GAAG,IAAI,4DAAgC,CACtD,EAAE,EACF,QAAQ,EACR,kCAAkC,CAAC,UAAU,CAC7C,CAAC;QACF,UAAU,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC;IACnB,CAAC;;AA9CF,gFA+CC;AAED;;;GAGG;AACU,QAAA,2BAA2B,GAAG,IAAA,iCAAsB,EAChE,kCAAkC,CAClC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIChannelServices,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\n// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class in factory\nimport { ConsensusRegisterCollection as ConsensusRegisterCollectionClass } from \"./consensusRegisterCollection.js\";\nimport type { IConsensusRegisterCollection } from \"./interfaces.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * The factory that defines the consensus queue.\n * @legacy @beta\n */\nexport class ConsensusRegisterCollectionFactory\n\timplements IChannelFactory<IConsensusRegisterCollection>\n{\n\t// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.\n\t// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.\n\t// public static Type = \"consensus-register-collection\";\n\tpublic static Type = \"https://graph.microsoft.com/types/consensus-register-collection\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: ConsensusRegisterCollectionFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type(): string {\n\t\treturn ConsensusRegisterCollectionFactory.Type;\n\t}\n\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn ConsensusRegisterCollectionFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<IConsensusRegisterCollection> {\n\t\t// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class\n\t\tconst collection = new ConsensusRegisterCollectionClass(id, runtime, attributes);\n\t\tawait collection.load(services);\n\t\treturn collection;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): IConsensusRegisterCollection {\n\t\t// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class\n\t\tconst collection = new ConsensusRegisterCollectionClass(\n\t\t\tid,\n\t\t\tdocument,\n\t\t\tConsensusRegisterCollectionFactory.Attributes,\n\t\t);\n\t\tcollection.initializeLocal();\n\t\treturn collection;\n\t}\n}\n\n/**\n * {@inheritDoc IConsensusRegisterCollection}\n * @legacy @beta\n */\nexport const ConsensusRegisterCollection = createSharedObjectKind(\n\tConsensusRegisterCollectionFactory,\n);\n/**\n * Compatibility alias for {@link IConsensusRegisterCollection}.\n * @legacy @beta\n */\nexport type ConsensusRegisterCollection<T> = IConsensusRegisterCollection<T>;\n"]}
@@ -43,7 +43,7 @@ export interface IConsensusRegisterCollection<T = any> extends ISharedObject<ICo
43
43
  * Attempts to write a register with a value. Returns a promise to indicate the roundtrip completion.
44
44
  * For a non existent register, it will attempt to create a new register with the specified value.
45
45
  *
46
- * @returns Promise<true> if write was non-concurrent
46
+ * @returns A promise resolving to `true` if the write was non-concurrent
47
47
  */
48
48
  write(key: string, value: T): Promise<boolean>;
49
49
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA0EH;;;GAGG;AACH,IAAY,UAMX;AAND,WAAY,UAAU;IACrB,mFAAmF;IACnF,+CAAM,CAAA;IAEN,2DAA2D;IAC3D,yCAAG,CAAA;AACJ,CAAC,EANW,UAAU,0BAAV,UAAU,QAMrB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IChannelFactory } from \"@fluidframework/datastore-definitions/internal\";\nimport type {\n\tISharedObject,\n\tISharedObjectEvents,\n} from \"@fluidframework/shared-object-base/internal\";\n\n/**\n * Consensus Register Collection channel factory interface\n *\n * Extends the base IChannelFactory to return a more definite type of IConsensusRegisterCollection\n * Use for the runtime to create and load distributed data structure by type name of each channel.\n * @legacy @beta\n * @deprecated Use `IChannelFactory<IConsensusRegisterCollection>`.\n */\nexport type IConsensusRegisterCollectionFactory =\n\tIChannelFactory<IConsensusRegisterCollection>;\n\n/**\n * Events emitted by {@link IConsensusRegisterCollection}.\n * @legacy @beta\n */\nexport interface IConsensusRegisterCollectionEvents extends ISharedObjectEvents {\n\t(\n\t\tevent: \"atomicChanged\" | \"versionChanged\",\n\t\tlistener: (key: string, value: any, local: boolean) => void,\n\t);\n}\n\n/**\n * A distributed data structure that holds a set of registers with update\n * versions. On concurrent updates, a register internally stores all possible versions of a value by using reference\n * sequence number of the incoming update.\n *\n * Using all the stored versions, we can then distinguish amongst different read policies. Below are the policies\n * we support:\n *\n * Atomic: Atomicity requires a linearizable register. A linearizable register behaves as if there is only a single\n * copy of the data, and that every operation appears to take effect atomically at one point in time. This definition\n * implies that operations are executed in an well-defined order. On a concurrent update, we perform a compare-and-set\n * operation, where we compare a register sequence number with the incoming reference sequence number.\n * The earliest operation overwriting prior sequence numbers wins since every client reaches to an agreement on\n * the value. So we can safely return the first value.\n *\n * LWW: The last write to a key always wins.\n * @legacy @beta\n */\nexport interface IConsensusRegisterCollection<T = any>\n\textends ISharedObject<IConsensusRegisterCollectionEvents> {\n\t/**\n\t * Attempts to write a register with a value. Returns a promise to indicate the roundtrip completion.\n\t * For a non existent register, it will attempt to create a new register with the specified value.\n\t *\n\t * @returns Promise<true> if write was non-concurrent\n\t */\n\twrite(key: string, value: T): Promise<boolean>;\n\n\t/**\n\t * Retrieves the agreed upon value for the register based on policy. Returns undefined if not present.\n\t */\n\tread(key: string, policy?: ReadPolicy): T | undefined;\n\n\t/**\n\t * Retrives all concurrent versions. Undefined if not present.\n\t */\n\treadVersions(key: string): T[] | undefined;\n\n\t/**\n\t * Returns the keys.\n\t */\n\tkeys(): string[];\n}\n\n/**\n * Read policies used when reading the map value.\n * @legacy @beta\n */\nexport enum ReadPolicy {\n\t// On a concurrent update, returns the first agreed upon value amongst all clients.\n\tAtomic,\n\n\t// Last writer wins. Simply returns the last written value.\n\tLWW,\n}\n"]}
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA0EH;;;GAGG;AACH,IAAY,UAMX;AAND,WAAY,UAAU;IACrB,mFAAmF;IACnF,+CAAM,CAAA;IAEN,2DAA2D;IAC3D,yCAAG,CAAA;AACJ,CAAC,EANW,UAAU,0BAAV,UAAU,QAMrB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IChannelFactory } from \"@fluidframework/datastore-definitions/internal\";\nimport type {\n\tISharedObject,\n\tISharedObjectEvents,\n} from \"@fluidframework/shared-object-base/internal\";\n\n/**\n * Consensus Register Collection channel factory interface\n *\n * Extends the base IChannelFactory to return a more definite type of IConsensusRegisterCollection\n * Use for the runtime to create and load distributed data structure by type name of each channel.\n * @legacy @beta\n * @deprecated Use `IChannelFactory<IConsensusRegisterCollection>`.\n */\nexport type IConsensusRegisterCollectionFactory =\n\tIChannelFactory<IConsensusRegisterCollection>;\n\n/**\n * Events emitted by {@link IConsensusRegisterCollection}.\n * @legacy @beta\n */\nexport interface IConsensusRegisterCollectionEvents extends ISharedObjectEvents {\n\t(\n\t\tevent: \"atomicChanged\" | \"versionChanged\",\n\t\tlistener: (key: string, value: any, local: boolean) => void,\n\t);\n}\n\n/**\n * A distributed data structure that holds a set of registers with update\n * versions. On concurrent updates, a register internally stores all possible versions of a value by using reference\n * sequence number of the incoming update.\n *\n * Using all the stored versions, we can then distinguish amongst different read policies. Below are the policies\n * we support:\n *\n * Atomic: Atomicity requires a linearizable register. A linearizable register behaves as if there is only a single\n * copy of the data, and that every operation appears to take effect atomically at one point in time. This definition\n * implies that operations are executed in an well-defined order. On a concurrent update, we perform a compare-and-set\n * operation, where we compare a register sequence number with the incoming reference sequence number.\n * The earliest operation overwriting prior sequence numbers wins since every client reaches to an agreement on\n * the value. So we can safely return the first value.\n *\n * LWW: The last write to a key always wins.\n * @legacy @beta\n */\nexport interface IConsensusRegisterCollection<T = any>\n\textends ISharedObject<IConsensusRegisterCollectionEvents> {\n\t/**\n\t * Attempts to write a register with a value. Returns a promise to indicate the roundtrip completion.\n\t * For a non existent register, it will attempt to create a new register with the specified value.\n\t *\n\t * @returns A promise resolving to `true` if the write was non-concurrent\n\t */\n\twrite(key: string, value: T): Promise<boolean>;\n\n\t/**\n\t * Retrieves the agreed upon value for the register based on policy. Returns undefined if not present.\n\t */\n\tread(key: string, policy?: ReadPolicy): T | undefined;\n\n\t/**\n\t * Retrives all concurrent versions. Undefined if not present.\n\t */\n\treadVersions(key: string): T[] | undefined;\n\n\t/**\n\t * Returns the keys.\n\t */\n\tkeys(): string[];\n}\n\n/**\n * Read policies used when reading the map value.\n * @legacy @beta\n */\nexport enum ReadPolicy {\n\t// On a concurrent update, returns the first agreed upon value amongst all clients.\n\tAtomic,\n\n\t// Last writer wins. Simply returns the last written value.\n\tLWW,\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/register-collection";
8
- export declare const pkgVersion = "2.118.0";
8
+ export declare const pkgVersion = "3.0.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wCAAwC,CAAC;AAC7D,eAAO,MAAM,UAAU,YAAY,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wCAAwC,CAAC;AAC7D,eAAO,MAAM,UAAU,UAAU,CAAC"}
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/register-collection";
11
- exports.pkgVersion = "2.118.0";
11
+ exports.pkgVersion = "3.0.0";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,qCAAqC,CAAC;AAChD,QAAA,UAAU,GAAG,SAAS,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/register-collection\";\nexport const pkgVersion = \"2.118.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,qCAAqC,CAAC;AAChD,QAAA,UAAU,GAAG,OAAO,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/register-collection\";\nexport const pkgVersion = \"3.0.0\";\n"]}
@@ -26,7 +26,7 @@ export declare class ConsensusRegisterCollection<T> extends SharedObject<IConsen
26
26
  * Creates a new register or writes a new value.
27
27
  * Returns a promise that will resolve when the write is acked.
28
28
  *
29
- * @returns Promise<true> if write was non-concurrent
29
+ * @returns A promise resolving to `true` if the write was non-concurrent
30
30
  */
31
31
  write(key: string, value: T): Promise<boolean>;
32
32
  /**
@@ -23,21 +23,21 @@ const snapshotFileName = "header";
23
23
  * @legacy @beta
24
24
  */
25
25
  export class ConsensusRegisterCollection extends SharedObject {
26
+ data = new Map();
27
+ internalEvents = createEmitter();
28
+ nextPendingMessageId = 0;
26
29
  /**
27
30
  * Constructs a new consensus register collection. If the object is non-local an id and service interfaces will
28
31
  * be provided
29
32
  */
30
33
  constructor(id, runtime, attributes) {
31
34
  super(id, runtime, attributes, "fluid_consensusRegisterCollection_");
32
- this.data = new Map();
33
- this.internalEvents = createEmitter();
34
- this.nextPendingMessageId = 0;
35
35
  }
36
36
  /**
37
37
  * Creates a new register or writes a new value.
38
38
  * Returns a promise that will resolve when the write is acked.
39
39
  *
40
- * @returns Promise<true> if write was non-concurrent
40
+ * @returns A promise resolving to `true` if the write was non-concurrent
41
41
  */
42
42
  async write(key, value) {
43
43
  if (this.runtime.disposed) {
@@ -1 +1 @@
1
- {"version":3,"file":"consensusRegisterCollection.js","sourceRoot":"","sources":["../src/consensusRegisterCollection.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\nimport { bufferToString, createEmitter } from \"@fluid-internal/client-utils\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport {\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\n\nimport type {\n\tIConsensusRegisterCollection,\n\tIConsensusRegisterCollectionEvents,\n} from \"./interfaces.js\";\nimport { ReadPolicy } from \"./interfaces.js\";\n\ninterface ILocalData<T> {\n\t// Atomic version\n\tatomic: ILocalRegister<T>;\n\n\t// All concurrent versions awaiting consensus\n\tversions: ILocalRegister<T>[];\n}\n\ninterface ILocalRegister<T> {\n\t// Register value, wrapped for backwards compatibility with < 0.17\n\tvalue: {\n\t\ttype: \"Plain\";\n\t\tvalue: T;\n\t};\n\n\t// The sequence number when last consensus was reached\n\tsequenceNumber: number;\n}\n\nconst newLocalRegister = <T>(sequenceNumber: number, value: T): ILocalRegister<T> => ({\n\tsequenceNumber,\n\tvalue: {\n\t\ttype: \"Plain\",\n\t\tvalue,\n\t},\n});\n\n/**\n * An operation for consensus register collection\n *\n * The value stored in this op is serialized as a string and must be deserialized\n */\ninterface IRegisterOperationSerialized {\n\tkey: string;\n\ttype: \"write\";\n\tserializedValue: string;\n\n\t// Message can be delivered with delay - resubmitted on reconnect.\n\t// As such, refSeq needs to reference seq # at the time op was created,\n\t// not when op was actually sent over wire (ISequencedDocumentMessage.referenceSequenceNumber),\n\t// as client can ingest ops in between.\n\trefSeq: number | undefined;\n}\n\n/**\n * IRegisterOperation format in versions \\< 0.17 and \\>=2.0.0-rc.2.0.0\n *\n * The value stored in this op is _not_ serialized and is stored literally as `T`\n */\ninterface IRegisterOperationPlain<T> {\n\tkey: string;\n\ttype: \"write\";\n\n\tvalue: {\n\t\ttype: \"Plain\";\n\t\tvalue: T;\n\t};\n\n\t// back-compat: for clients prior to 2.0.0-rc.2.0.0, we must also pass in\n\t// the serialized value for them to parse handles correctly. we do not have\n\t// to pay the cost of deserializing this value in newer clients\n\tserializedValue: string;\n\n\t// back-compat: files at rest written with runtime <= 0.13 do not have refSeq\n\trefSeq: number | undefined;\n}\n\n/** Incoming ops could match any of these types */\ntype IIncomingRegisterOperation<T> = IRegisterOperationSerialized | IRegisterOperationPlain<T>;\n\n/** Distinguish between incoming op formats so we know which type it is */\nconst incomingOpMatchesPlainFormat = <T>(op): op is IRegisterOperationPlain<T> =>\n\t\"value\" in op;\n\nconst snapshotFileName = \"header\";\n\ninterface IConsensusRegisterCollectionInternalEvents {\n\t/**\n\t * Emitted when a pending message is rolled back.\n\t * @param rollbackMessageId - A unique identifying number for the pending message.\n\t */\n\tpendingMessageRollback: (rollbackMessageId: number) => void;\n\n\t/**\n\t * Emitted when a pending message is acknowledged.\n\t * @param ackMessageId - A unique identifying number for the pending message.\n\t * @param isWinner - Whether the message won the FWW race to modify the value.\n\t */\n\tpendingMessageAck: (ackMessageId: number, isWinner: boolean) => void;\n}\n\n/**\n * {@inheritDoc IConsensusRegisterCollection}\n * @deprecated Use {@link IConsensusRegisterCollection} for typing and {@link ConsensusRegisterCollectionFactory} to create instances. This implementation class will be removed in a future release.\n * @legacy @beta\n */\nexport class ConsensusRegisterCollection<T>\n\textends SharedObject<IConsensusRegisterCollectionEvents>\n\timplements IConsensusRegisterCollection<T>\n{\n\tprivate readonly data = new Map<string, ILocalData<T>>();\n\tprivate readonly internalEvents =\n\t\tcreateEmitter<IConsensusRegisterCollectionInternalEvents>();\n\n\tprivate nextPendingMessageId: number = 0;\n\n\t/**\n\t * Constructs a new consensus register collection. If the object is non-local an id and service interfaces will\n\t * be provided\n\t */\n\tpublic constructor(\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(id, runtime, attributes, \"fluid_consensusRegisterCollection_\");\n\t}\n\n\t/**\n\t * Creates a new register or writes a new value.\n\t * Returns a promise that will resolve when the write is acked.\n\t *\n\t * @returns Promise<true> if write was non-concurrent\n\t */\n\tpublic async write(key: string, value: T): Promise<boolean> {\n\t\tif (this.runtime.disposed) {\n\t\t\t// Return false if disposed to signify that we did not write.\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!this.isAttached()) {\n\t\t\tthis.processInboundWrite(key, value, 0, 0, true);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst message: IRegisterOperationPlain<T> = {\n\t\t\tkey,\n\t\t\ttype: \"write\",\n\t\t\tserializedValue: this.stringify(value, this.serializer),\n\t\t\tvalue: {\n\t\t\t\ttype: \"Plain\",\n\t\t\t\tvalue,\n\t\t\t},\n\t\t\trefSeq: this.deltaManager.lastSequenceNumber,\n\t\t};\n\n\t\tconst pendingMessageId = this.nextPendingMessageId++;\n\n\t\t// There are three ways the write promise can resolve:\n\t\t// 1. The write is acked\n\t\t// 2. The write is rolled back\n\t\t// 3. The runtime is disposed\n\t\t// The boolean value returned by the promise is true if the attempted write was ack'd and won, false otherwise.\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tconst handleAck = (ackMessageId: number, isWinner: boolean): void => {\n\t\t\t\tif (ackMessageId === pendingMessageId) {\n\t\t\t\t\tresolve(isWinner);\n\t\t\t\t\tremoveListeners();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleRollback = (rollbackMessageId: number): void => {\n\t\t\t\tif (rollbackMessageId === pendingMessageId) {\n\t\t\t\t\t// If we rolled back the pending message, resolve the promise with false.\n\t\t\t\t\tresolve(false);\n\t\t\t\t\tremoveListeners();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleDisposed = (): void => {\n\t\t\t\tresolve(false);\n\t\t\t\tremoveListeners();\n\t\t\t};\n\n\t\t\tconst removeListeners = (): void => {\n\t\t\t\tthis.internalEvents.off(\"pendingMessageAck\", handleAck);\n\t\t\t\tthis.internalEvents.off(\"pendingMessageRollback\", handleRollback);\n\t\t\t\tthis.runtime.off(\"dispose\", handleDisposed);\n\t\t\t};\n\n\t\t\tthis.internalEvents.on(\"pendingMessageAck\", handleAck);\n\t\t\tthis.internalEvents.on(\"pendingMessageRollback\", handleRollback);\n\t\t\tthis.runtime.on(\"dispose\", handleDisposed);\n\n\t\t\tthis.submitLocalMessage(message, pendingMessageId);\n\t\t});\n\t}\n\n\t/**\n\t * Returns the most recent local value of a register.\n\t * @param key - The key to read\n\t * @param readPolicy - The ReadPolicy to apply. Defaults to Atomic.\n\t */\n\tpublic read(key: string, readPolicy: ReadPolicy = ReadPolicy.Atomic): T | undefined {\n\t\tif (readPolicy === ReadPolicy.Atomic) {\n\t\t\treturn this.readAtomic(key);\n\t\t}\n\n\t\tconst versions = this.readVersions(key);\n\n\t\tif (versions !== undefined) {\n\t\t\t// We don't support deletion. So there should be at least one value.\n\t\t\tassert(versions.length > 0, 0x06c /* \"Value should be undefined or non-empty\" */);\n\n\t\t\treturn versions[versions.length - 1];\n\t\t}\n\t}\n\n\tpublic readVersions(key: string): T[] | undefined {\n\t\tconst data = this.data.get(key);\n\t\treturn data?.versions.map((element: ILocalRegister<T>) => element.value.value);\n\t}\n\n\tpublic keys(): string[] {\n\t\treturn [...this.data.keys()];\n\t}\n\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\tconst dataObj: { [key: string]: ILocalData<T> } = {};\n\t\tfor (const [k, v] of this.data.entries()) {\n\t\t\tdataObj[k] = v;\n\t\t}\n\n\t\treturn createSingleBlobSummary(snapshotFileName, this.stringify(dataObj, serializer));\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst blob = await storage.readBlob(snapshotFileName);\n\t\tconst header = bufferToString(blob, \"utf8\");\n\t\tconst dataObj = this.parse(header, this.serializer);\n\n\t\tfor (const key of Object.keys(dataObj)) {\n\t\t\tassert(\n\t\t\t\tdataObj[key].atomic?.value.type !== \"Shared\",\n\t\t\t\t0x06d /* \"SharedObjects contained in ConsensusRegisterCollection can no longer be deserialized as of 0.17\" */,\n\t\t\t);\n\n\t\t\tthis.data.set(key, dataObj[key]);\n\t\t}\n\t}\n\n\tprotected onDisconnect(): void {}\n\n\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\tif (messageEnvelope.type === MessageType.Operation) {\n\t\t\tconst op = messageContent.contents as IIncomingRegisterOperation<T>;\n\t\t\tswitch (op.type) {\n\t\t\t\tcase \"write\": {\n\t\t\t\t\t// backward compatibility: File at rest written with runtime <= 0.13 do not have refSeq\n\t\t\t\t\t// when the refSeq property didn't exist\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\t\t\t\tif (op.refSeq === undefined) {\n\t\t\t\t\t\top.refSeq = messageEnvelope.referenceSequenceNumber;\n\t\t\t\t\t}\n\t\t\t\t\t// Message can be delivered with delay - e.g. resubmitted on reconnect.\n\t\t\t\t\t// Use the refSeq from when the op was created, not when it was transmitted\n\t\t\t\t\tconst refSeqWhenCreated = op.refSeq;\n\t\t\t\t\tassert(\n\t\t\t\t\t\trefSeqWhenCreated <= messageEnvelope.referenceSequenceNumber,\n\t\t\t\t\t\t0x06e /* \"Message's reference sequence number < op's reference sequence number!\" */,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst value = incomingOpMatchesPlainFormat<T>(op)\n\t\t\t\t\t\t? op.value.value\n\t\t\t\t\t\t: (this.parse(op.serializedValue, this.serializer) as T);\n\t\t\t\t\tconst isWinner = this.processInboundWrite(\n\t\t\t\t\t\top.key,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\trefSeqWhenCreated,\n\t\t\t\t\t\tmessageEnvelope.sequenceNumber,\n\t\t\t\t\t\tlocal,\n\t\t\t\t\t);\n\t\t\t\t\tif (local) {\n\t\t\t\t\t\t// Resolve the pending promise for this operation now that we have received an ack for it.\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\ttypeof messageContent.localOpMetadata === \"number\",\n\t\t\t\t\t\t\t0xc0e /* Expect localOpMetadata to be a number */,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.internalEvents.emit(\n\t\t\t\t\t\t\t\"pendingMessageAck\",\n\t\t\t\t\t\t\tmessageContent.localOpMetadata,\n\t\t\t\t\t\t\tisWinner,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tunreachableCase(op.type);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate readAtomic(key: string): T | undefined {\n\t\tconst data = this.data.get(key);\n\t\treturn data?.atomic.value.value;\n\t}\n\n\t/**\n\t * Process an inbound write op\n\t * @param key - Key that was written to\n\t * @param value - Incoming value\n\t * @param refSeq - RefSeq at the time of write on the remote client\n\t * @param sequenceNumber - Sequence Number of this write op\n\t * @param local - Did this write originate on this client\n\t */\n\tprivate processInboundWrite(\n\t\tkey: string,\n\t\tvalue: T,\n\t\trefSeq: number,\n\t\tsequenceNumber: number,\n\t\tlocal: boolean,\n\t): boolean {\n\t\tlet data = this.data.get(key);\n\t\t// Atomic update if it's a new register or the write was not concurrent,\n\t\t// meaning our state was known to the remote client at the time of write\n\t\tconst isWinner = data === undefined || refSeq >= data.atomic.sequenceNumber;\n\t\tif (isWinner) {\n\t\t\tconst atomicUpdate = newLocalRegister<T>(sequenceNumber, value);\n\t\t\tif (data === undefined) {\n\t\t\t\tdata = {\n\t\t\t\t\tatomic: atomicUpdate,\n\t\t\t\t\tversions: [], // we'll update versions next, leave it empty for now\n\t\t\t\t};\n\t\t\t\tthis.data.set(key, data);\n\t\t\t} else {\n\t\t\t\tdata.atomic = atomicUpdate;\n\t\t\t}\n\t\t} else {\n\t\t\tassert(!!data, 0x06f /* \"data missing for non-atomic inbound update!\" */);\n\t\t}\n\n\t\t// Remove versions that were known to the remote client at the time of write\n\t\twhile (data.versions.length > 0 && refSeq >= data.versions[0].sequenceNumber) {\n\t\t\tdata.versions.shift();\n\t\t}\n\n\t\tconst versionUpdate = newLocalRegister<T>(sequenceNumber, value);\n\n\t\t// Asserts for data integrity\n\t\tif (!this.isAttached()) {\n\t\t\tassert(\n\t\t\t\trefSeq === 0 && sequenceNumber === 0,\n\t\t\t\t0x070 /* \"sequence numbers are expected to be 0 when unattached\" */,\n\t\t\t);\n\t\t} else if (data.versions.length > 0) {\n\t\t\tassert(\n\t\t\t\t// seqNum should always be increasing, except for the case of grouped batches (seqNum will be the same)\n\t\t\t\tsequenceNumber >= data.versions[data.versions.length - 1].sequenceNumber,\n\t\t\t\t0x071 /* \"Versions should naturally be ordered by sequenceNumber\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Push the new element.\n\t\tdata.versions.push(versionUpdate);\n\n\t\t// Raise events at the end, to avoid reentrancy issues\n\t\tif (isWinner) {\n\t\t\tthis.emit(\"atomicChanged\", key, value, local);\n\t\t}\n\t\tthis.emit(\"versionChanged\", key, value, local);\n\n\t\treturn isWinner;\n\t}\n\n\tprivate stringify(value: any, serializer: IFluidSerializer): string {\n\t\treturn serializer.stringify(value, this.handle);\n\t}\n\n\tprivate parse(content: string, serializer: IFluidSerializer): any {\n\t\treturn serializer.parse(content);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}\n\t * @sealed\n\t */\n\tprotected rollback(content: unknown, localOpMetadata: unknown): void {\n\t\t// We don't need to do anything to roll back CRC, it's safe to just drop\n\t\t// the op on the floor since we don't modify the DDS until the ack.\n\t\t// We emit an internal event so we know to resolve the pending promise.\n\t\tassert(\n\t\t\ttypeof localOpMetadata === \"number\",\n\t\t\t0xc0f /* Expect localOpMetadata to be a number */,\n\t\t);\n\t\tthis.internalEvents.emit(\"pendingMessageRollback\", localOpMetadata);\n\t}\n\n\tprotected applyStashedOp(content: unknown): void {\n\t\tconst op = content as IIncomingRegisterOperation<T>;\n\t\tassert(op.type === \"write\", 0xccc /* Only write ops should be stashed */);\n\t\t// Submit the original op (preserving its refSeq) so we can match the ACK\n\t\t// when it arrives during remote op processing.\n\t\tconst pendingMessageId = this.nextPendingMessageId++;\n\t\tthis.submitLocalMessage(op, pendingMessageId);\n\t}\n}\n"]}
1
+ {"version":3,"file":"consensusRegisterCollection.js","sourceRoot":"","sources":["../src/consensusRegisterCollection.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\nimport { bufferToString, createEmitter } from \"@fluid-internal/client-utils\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport {\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\n\nimport type {\n\tIConsensusRegisterCollection,\n\tIConsensusRegisterCollectionEvents,\n} from \"./interfaces.js\";\nimport { ReadPolicy } from \"./interfaces.js\";\n\ninterface ILocalData<T> {\n\t// Atomic version\n\tatomic: ILocalRegister<T>;\n\n\t// All concurrent versions awaiting consensus\n\tversions: ILocalRegister<T>[];\n}\n\ninterface ILocalRegister<T> {\n\t// Register value, wrapped for backwards compatibility with < 0.17\n\tvalue: {\n\t\ttype: \"Plain\";\n\t\tvalue: T;\n\t};\n\n\t// The sequence number when last consensus was reached\n\tsequenceNumber: number;\n}\n\nconst newLocalRegister = <T>(sequenceNumber: number, value: T): ILocalRegister<T> => ({\n\tsequenceNumber,\n\tvalue: {\n\t\ttype: \"Plain\",\n\t\tvalue,\n\t},\n});\n\n/**\n * An operation for consensus register collection\n *\n * The value stored in this op is serialized as a string and must be deserialized\n */\ninterface IRegisterOperationSerialized {\n\tkey: string;\n\ttype: \"write\";\n\tserializedValue: string;\n\n\t// Message can be delivered with delay - resubmitted on reconnect.\n\t// As such, refSeq needs to reference seq # at the time op was created,\n\t// not when op was actually sent over wire (ISequencedDocumentMessage.referenceSequenceNumber),\n\t// as client can ingest ops in between.\n\trefSeq: number | undefined;\n}\n\n/**\n * IRegisterOperation format in versions \\< 0.17 and \\>=2.0.0-rc.2.0.0\n *\n * The value stored in this op is _not_ serialized and is stored literally as `T`\n */\ninterface IRegisterOperationPlain<T> {\n\tkey: string;\n\ttype: \"write\";\n\n\tvalue: {\n\t\ttype: \"Plain\";\n\t\tvalue: T;\n\t};\n\n\t// back-compat: for clients prior to 2.0.0-rc.2.0.0, we must also pass in\n\t// the serialized value for them to parse handles correctly. we do not have\n\t// to pay the cost of deserializing this value in newer clients\n\tserializedValue: string;\n\n\t// back-compat: files at rest written with runtime <= 0.13 do not have refSeq\n\trefSeq: number | undefined;\n}\n\n/** Incoming ops could match any of these types */\ntype IIncomingRegisterOperation<T> = IRegisterOperationSerialized | IRegisterOperationPlain<T>;\n\n/** Distinguish between incoming op formats so we know which type it is */\nconst incomingOpMatchesPlainFormat = <T>(op): op is IRegisterOperationPlain<T> =>\n\t\"value\" in op;\n\nconst snapshotFileName = \"header\";\n\ninterface IConsensusRegisterCollectionInternalEvents {\n\t/**\n\t * Emitted when a pending message is rolled back.\n\t * @param rollbackMessageId - A unique identifying number for the pending message.\n\t */\n\tpendingMessageRollback: (rollbackMessageId: number) => void;\n\n\t/**\n\t * Emitted when a pending message is acknowledged.\n\t * @param ackMessageId - A unique identifying number for the pending message.\n\t * @param isWinner - Whether the message won the FWW race to modify the value.\n\t */\n\tpendingMessageAck: (ackMessageId: number, isWinner: boolean) => void;\n}\n\n/**\n * {@inheritDoc IConsensusRegisterCollection}\n * @deprecated Use {@link IConsensusRegisterCollection} for typing and {@link ConsensusRegisterCollectionFactory} to create instances. This implementation class will be removed in a future release.\n * @legacy @beta\n */\nexport class ConsensusRegisterCollection<T>\n\textends SharedObject<IConsensusRegisterCollectionEvents>\n\timplements IConsensusRegisterCollection<T>\n{\n\tprivate readonly data = new Map<string, ILocalData<T>>();\n\tprivate readonly internalEvents =\n\t\tcreateEmitter<IConsensusRegisterCollectionInternalEvents>();\n\n\tprivate nextPendingMessageId: number = 0;\n\n\t/**\n\t * Constructs a new consensus register collection. If the object is non-local an id and service interfaces will\n\t * be provided\n\t */\n\tpublic constructor(\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(id, runtime, attributes, \"fluid_consensusRegisterCollection_\");\n\t}\n\n\t/**\n\t * Creates a new register or writes a new value.\n\t * Returns a promise that will resolve when the write is acked.\n\t *\n\t * @returns A promise resolving to `true` if the write was non-concurrent\n\t */\n\tpublic async write(key: string, value: T): Promise<boolean> {\n\t\tif (this.runtime.disposed) {\n\t\t\t// Return false if disposed to signify that we did not write.\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!this.isAttached()) {\n\t\t\tthis.processInboundWrite(key, value, 0, 0, true);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst message: IRegisterOperationPlain<T> = {\n\t\t\tkey,\n\t\t\ttype: \"write\",\n\t\t\tserializedValue: this.stringify(value, this.serializer),\n\t\t\tvalue: {\n\t\t\t\ttype: \"Plain\",\n\t\t\t\tvalue,\n\t\t\t},\n\t\t\trefSeq: this.deltaManager.lastSequenceNumber,\n\t\t};\n\n\t\tconst pendingMessageId = this.nextPendingMessageId++;\n\n\t\t// There are three ways the write promise can resolve:\n\t\t// 1. The write is acked\n\t\t// 2. The write is rolled back\n\t\t// 3. The runtime is disposed\n\t\t// The boolean value returned by the promise is true if the attempted write was ack'd and won, false otherwise.\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tconst handleAck = (ackMessageId: number, isWinner: boolean): void => {\n\t\t\t\tif (ackMessageId === pendingMessageId) {\n\t\t\t\t\tresolve(isWinner);\n\t\t\t\t\tremoveListeners();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleRollback = (rollbackMessageId: number): void => {\n\t\t\t\tif (rollbackMessageId === pendingMessageId) {\n\t\t\t\t\t// If we rolled back the pending message, resolve the promise with false.\n\t\t\t\t\tresolve(false);\n\t\t\t\t\tremoveListeners();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleDisposed = (): void => {\n\t\t\t\tresolve(false);\n\t\t\t\tremoveListeners();\n\t\t\t};\n\n\t\t\tconst removeListeners = (): void => {\n\t\t\t\tthis.internalEvents.off(\"pendingMessageAck\", handleAck);\n\t\t\t\tthis.internalEvents.off(\"pendingMessageRollback\", handleRollback);\n\t\t\t\tthis.runtime.off(\"dispose\", handleDisposed);\n\t\t\t};\n\n\t\t\tthis.internalEvents.on(\"pendingMessageAck\", handleAck);\n\t\t\tthis.internalEvents.on(\"pendingMessageRollback\", handleRollback);\n\t\t\tthis.runtime.on(\"dispose\", handleDisposed);\n\n\t\t\tthis.submitLocalMessage(message, pendingMessageId);\n\t\t});\n\t}\n\n\t/**\n\t * Returns the most recent local value of a register.\n\t * @param key - The key to read\n\t * @param readPolicy - The ReadPolicy to apply. Defaults to Atomic.\n\t */\n\tpublic read(key: string, readPolicy: ReadPolicy = ReadPolicy.Atomic): T | undefined {\n\t\tif (readPolicy === ReadPolicy.Atomic) {\n\t\t\treturn this.readAtomic(key);\n\t\t}\n\n\t\tconst versions = this.readVersions(key);\n\n\t\tif (versions !== undefined) {\n\t\t\t// We don't support deletion. So there should be at least one value.\n\t\t\tassert(versions.length > 0, 0x06c /* \"Value should be undefined or non-empty\" */);\n\n\t\t\treturn versions[versions.length - 1];\n\t\t}\n\t}\n\n\tpublic readVersions(key: string): T[] | undefined {\n\t\tconst data = this.data.get(key);\n\t\treturn data?.versions.map((element: ILocalRegister<T>) => element.value.value);\n\t}\n\n\tpublic keys(): string[] {\n\t\treturn [...this.data.keys()];\n\t}\n\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\tconst dataObj: { [key: string]: ILocalData<T> } = {};\n\t\tfor (const [k, v] of this.data.entries()) {\n\t\t\tdataObj[k] = v;\n\t\t}\n\n\t\treturn createSingleBlobSummary(snapshotFileName, this.stringify(dataObj, serializer));\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst blob = await storage.readBlob(snapshotFileName);\n\t\tconst header = bufferToString(blob, \"utf8\");\n\t\tconst dataObj = this.parse(header, this.serializer);\n\n\t\tfor (const key of Object.keys(dataObj)) {\n\t\t\tassert(\n\t\t\t\tdataObj[key].atomic?.value.type !== \"Shared\",\n\t\t\t\t0x06d /* \"SharedObjects contained in ConsensusRegisterCollection can no longer be deserialized as of 0.17\" */,\n\t\t\t);\n\n\t\t\tthis.data.set(key, dataObj[key]);\n\t\t}\n\t}\n\n\tprotected onDisconnect(): void {}\n\n\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\tif (messageEnvelope.type === MessageType.Operation) {\n\t\t\tconst op = messageContent.contents as IIncomingRegisterOperation<T>;\n\t\t\tswitch (op.type) {\n\t\t\t\tcase \"write\": {\n\t\t\t\t\t// backward compatibility: File at rest written with runtime <= 0.13 do not have refSeq\n\t\t\t\t\t// when the refSeq property didn't exist\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\t\t\t\tif (op.refSeq === undefined) {\n\t\t\t\t\t\top.refSeq = messageEnvelope.referenceSequenceNumber;\n\t\t\t\t\t}\n\t\t\t\t\t// Message can be delivered with delay - e.g. resubmitted on reconnect.\n\t\t\t\t\t// Use the refSeq from when the op was created, not when it was transmitted\n\t\t\t\t\tconst refSeqWhenCreated = op.refSeq;\n\t\t\t\t\tassert(\n\t\t\t\t\t\trefSeqWhenCreated <= messageEnvelope.referenceSequenceNumber,\n\t\t\t\t\t\t0x06e /* \"Message's reference sequence number < op's reference sequence number!\" */,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst value = incomingOpMatchesPlainFormat<T>(op)\n\t\t\t\t\t\t? op.value.value\n\t\t\t\t\t\t: (this.parse(op.serializedValue, this.serializer) as T);\n\t\t\t\t\tconst isWinner = this.processInboundWrite(\n\t\t\t\t\t\top.key,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\trefSeqWhenCreated,\n\t\t\t\t\t\tmessageEnvelope.sequenceNumber,\n\t\t\t\t\t\tlocal,\n\t\t\t\t\t);\n\t\t\t\t\tif (local) {\n\t\t\t\t\t\t// Resolve the pending promise for this operation now that we have received an ack for it.\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\ttypeof messageContent.localOpMetadata === \"number\",\n\t\t\t\t\t\t\t0xc0e /* Expect localOpMetadata to be a number */,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.internalEvents.emit(\n\t\t\t\t\t\t\t\"pendingMessageAck\",\n\t\t\t\t\t\t\tmessageContent.localOpMetadata,\n\t\t\t\t\t\t\tisWinner,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tunreachableCase(op.type);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate readAtomic(key: string): T | undefined {\n\t\tconst data = this.data.get(key);\n\t\treturn data?.atomic.value.value;\n\t}\n\n\t/**\n\t * Process an inbound write op\n\t * @param key - Key that was written to\n\t * @param value - Incoming value\n\t * @param refSeq - RefSeq at the time of write on the remote client\n\t * @param sequenceNumber - Sequence Number of this write op\n\t * @param local - Did this write originate on this client\n\t */\n\tprivate processInboundWrite(\n\t\tkey: string,\n\t\tvalue: T,\n\t\trefSeq: number,\n\t\tsequenceNumber: number,\n\t\tlocal: boolean,\n\t): boolean {\n\t\tlet data = this.data.get(key);\n\t\t// Atomic update if it's a new register or the write was not concurrent,\n\t\t// meaning our state was known to the remote client at the time of write\n\t\tconst isWinner = data === undefined || refSeq >= data.atomic.sequenceNumber;\n\t\tif (isWinner) {\n\t\t\tconst atomicUpdate = newLocalRegister<T>(sequenceNumber, value);\n\t\t\tif (data === undefined) {\n\t\t\t\tdata = {\n\t\t\t\t\tatomic: atomicUpdate,\n\t\t\t\t\tversions: [], // we'll update versions next, leave it empty for now\n\t\t\t\t};\n\t\t\t\tthis.data.set(key, data);\n\t\t\t} else {\n\t\t\t\tdata.atomic = atomicUpdate;\n\t\t\t}\n\t\t} else {\n\t\t\tassert(!!data, 0x06f /* \"data missing for non-atomic inbound update!\" */);\n\t\t}\n\n\t\t// Remove versions that were known to the remote client at the time of write\n\t\twhile (data.versions.length > 0 && refSeq >= data.versions[0].sequenceNumber) {\n\t\t\tdata.versions.shift();\n\t\t}\n\n\t\tconst versionUpdate = newLocalRegister<T>(sequenceNumber, value);\n\n\t\t// Asserts for data integrity\n\t\tif (!this.isAttached()) {\n\t\t\tassert(\n\t\t\t\trefSeq === 0 && sequenceNumber === 0,\n\t\t\t\t0x070 /* \"sequence numbers are expected to be 0 when unattached\" */,\n\t\t\t);\n\t\t} else if (data.versions.length > 0) {\n\t\t\tassert(\n\t\t\t\t// seqNum should always be increasing, except for the case of grouped batches (seqNum will be the same)\n\t\t\t\tsequenceNumber >= data.versions[data.versions.length - 1].sequenceNumber,\n\t\t\t\t0x071 /* \"Versions should naturally be ordered by sequenceNumber\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Push the new element.\n\t\tdata.versions.push(versionUpdate);\n\n\t\t// Raise events at the end, to avoid reentrancy issues\n\t\tif (isWinner) {\n\t\t\tthis.emit(\"atomicChanged\", key, value, local);\n\t\t}\n\t\tthis.emit(\"versionChanged\", key, value, local);\n\n\t\treturn isWinner;\n\t}\n\n\tprivate stringify(value: any, serializer: IFluidSerializer): string {\n\t\treturn serializer.stringify(value, this.handle);\n\t}\n\n\tprivate parse(content: string, serializer: IFluidSerializer): any {\n\t\treturn serializer.parse(content);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}\n\t * @sealed\n\t */\n\tprotected rollback(content: unknown, localOpMetadata: unknown): void {\n\t\t// We don't need to do anything to roll back CRC, it's safe to just drop\n\t\t// the op on the floor since we don't modify the DDS until the ack.\n\t\t// We emit an internal event so we know to resolve the pending promise.\n\t\tassert(\n\t\t\ttypeof localOpMetadata === \"number\",\n\t\t\t0xc0f /* Expect localOpMetadata to be a number */,\n\t\t);\n\t\tthis.internalEvents.emit(\"pendingMessageRollback\", localOpMetadata);\n\t}\n\n\tprotected applyStashedOp(content: unknown): void {\n\t\tconst op = content as IIncomingRegisterOperation<T>;\n\t\tassert(op.type === \"write\", 0xccc /* Only write ops should be stashed */);\n\t\t// Submit the original op (preserving its refSeq) so we can match the ACK\n\t\t// when it arrives during remote op processing.\n\t\tconst pendingMessageId = this.nextPendingMessageId++;\n\t\tthis.submitLocalMessage(op, pendingMessageId);\n\t}\n}\n"]}
@@ -11,6 +11,15 @@ import { pkgVersion } from "./packageVersion.js";
11
11
  * @legacy @beta
12
12
  */
13
13
  export class ConsensusRegisterCollectionFactory {
14
+ // New type string, to be activated once the migration has been fully shipped dark and is safe to flip.
15
+ // See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.
16
+ // public static Type = "consensus-register-collection";
17
+ static Type = "https://graph.microsoft.com/types/consensus-register-collection";
18
+ static Attributes = {
19
+ type: ConsensusRegisterCollectionFactory.Type,
20
+ snapshotFormatVersion: "0.1",
21
+ packageVersion: pkgVersion,
22
+ };
14
23
  get type() {
15
24
  return ConsensusRegisterCollectionFactory.Type;
16
25
  }
@@ -33,15 +42,6 @@ export class ConsensusRegisterCollectionFactory {
33
42
  return collection;
34
43
  }
35
44
  }
36
- // New type string, to be activated once the migration has been fully shipped dark and is safe to flip.
37
- // See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.
38
- // public static Type = "consensus-register-collection";
39
- ConsensusRegisterCollectionFactory.Type = "https://graph.microsoft.com/types/consensus-register-collection";
40
- ConsensusRegisterCollectionFactory.Attributes = {
41
- type: ConsensusRegisterCollectionFactory.Type,
42
- snapshotFormatVersion: "0.1",
43
- packageVersion: pkgVersion,
44
- };
45
45
  /**
46
46
  * {@inheritDoc IConsensusRegisterCollection}
47
47
  * @legacy @beta
@@ -1 +1 @@
1
- {"version":3,"file":"consensusRegisterCollectionFactory.js","sourceRoot":"","sources":["../src/consensusRegisterCollectionFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,mGAAmG;AACnG,OAAO,EAAE,2BAA2B,IAAI,gCAAgC,EAAE,MAAM,kCAAkC,CAAC;AAEnH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;GAGG;AACH,MAAM,OAAO,kCAAkC;IAc9C,IAAW,IAAI;QACd,OAAO,kCAAkC,CAAC,IAAI,CAAC;IAChD,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,kCAAkC,CAAC,UAAU,CAAC;IACtD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,wFAAwF;QACxF,MAAM,UAAU,GAAG,IAAI,gCAAgC,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QACjF,MAAM,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,OAAO,UAAU,CAAC;IACnB,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACzD,wFAAwF;QACxF,MAAM,UAAU,GAAG,IAAI,gCAAgC,CACtD,EAAE,EACF,QAAQ,EACR,kCAAkC,CAAC,UAAU,CAC7C,CAAC;QACF,UAAU,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC;IACnB,CAAC;;AA3CD,uGAAuG;AACvG,qFAAqF;AACrF,wDAAwD;AAC1C,uCAAI,GAAG,iEAAiE,CAAC;AAEhE,6CAAU,GAAuB;IACvD,IAAI,EAAE,kCAAkC,CAAC,IAAI;IAC7C,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,UAAU;CAC1B,CAAC;AAqCH;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAAsB,CAChE,kCAAkC,CAClC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIChannelServices,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\n// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class in factory\nimport { ConsensusRegisterCollection as ConsensusRegisterCollectionClass } from \"./consensusRegisterCollection.js\";\nimport type { IConsensusRegisterCollection } from \"./interfaces.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * The factory that defines the consensus queue.\n * @legacy @beta\n */\nexport class ConsensusRegisterCollectionFactory\n\timplements IChannelFactory<IConsensusRegisterCollection>\n{\n\t// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.\n\t// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.\n\t// public static Type = \"consensus-register-collection\";\n\tpublic static Type = \"https://graph.microsoft.com/types/consensus-register-collection\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: ConsensusRegisterCollectionFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type(): string {\n\t\treturn ConsensusRegisterCollectionFactory.Type;\n\t}\n\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn ConsensusRegisterCollectionFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<IConsensusRegisterCollection> {\n\t\t// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class\n\t\tconst collection = new ConsensusRegisterCollectionClass(id, runtime, attributes);\n\t\tawait collection.load(services);\n\t\treturn collection;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): IConsensusRegisterCollection {\n\t\t// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class\n\t\tconst collection = new ConsensusRegisterCollectionClass(\n\t\t\tid,\n\t\t\tdocument,\n\t\t\tConsensusRegisterCollectionFactory.Attributes,\n\t\t);\n\t\tcollection.initializeLocal();\n\t\treturn collection;\n\t}\n}\n\n/**\n * {@inheritDoc IConsensusRegisterCollection}\n * @legacy @beta\n */\nexport const ConsensusRegisterCollection = createSharedObjectKind(\n\tConsensusRegisterCollectionFactory,\n);\n/**\n * Compatibility alias for {@link IConsensusRegisterCollection}.\n * @legacy @beta\n */\nexport type ConsensusRegisterCollection<T> = IConsensusRegisterCollection<T>;\n"]}
1
+ {"version":3,"file":"consensusRegisterCollectionFactory.js","sourceRoot":"","sources":["../src/consensusRegisterCollectionFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,mGAAmG;AACnG,OAAO,EAAE,2BAA2B,IAAI,gCAAgC,EAAE,MAAM,kCAAkC,CAAC;AAEnH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;GAGG;AACH,MAAM,OAAO,kCAAkC;IAG9C,uGAAuG;IACvG,qFAAqF;IACrF,wDAAwD;IACjD,MAAM,CAAC,IAAI,GAAG,iEAAiE,CAAC;IAEhF,MAAM,CAAU,UAAU,GAAuB;QACvD,IAAI,EAAE,kCAAkC,CAAC,IAAI;QAC7C,qBAAqB,EAAE,KAAK;QAC5B,cAAc,EAAE,UAAU;KAC1B,CAAC;IAEF,IAAW,IAAI;QACd,OAAO,kCAAkC,CAAC,IAAI,CAAC;IAChD,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,kCAAkC,CAAC,UAAU,CAAC;IACtD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,wFAAwF;QACxF,MAAM,UAAU,GAAG,IAAI,gCAAgC,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QACjF,MAAM,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,OAAO,UAAU,CAAC;IACnB,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACzD,wFAAwF;QACxF,MAAM,UAAU,GAAG,IAAI,gCAAgC,CACtD,EAAE,EACF,QAAQ,EACR,kCAAkC,CAAC,UAAU,CAC7C,CAAC;QACF,UAAU,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC;IACnB,CAAC;;AAGF;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAAsB,CAChE,kCAAkC,CAClC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIChannelServices,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\n// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class in factory\nimport { ConsensusRegisterCollection as ConsensusRegisterCollectionClass } from \"./consensusRegisterCollection.js\";\nimport type { IConsensusRegisterCollection } from \"./interfaces.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * The factory that defines the consensus queue.\n * @legacy @beta\n */\nexport class ConsensusRegisterCollectionFactory\n\timplements IChannelFactory<IConsensusRegisterCollection>\n{\n\t// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.\n\t// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.\n\t// public static Type = \"consensus-register-collection\";\n\tpublic static Type = \"https://graph.microsoft.com/types/consensus-register-collection\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: ConsensusRegisterCollectionFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type(): string {\n\t\treturn ConsensusRegisterCollectionFactory.Type;\n\t}\n\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn ConsensusRegisterCollectionFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<IConsensusRegisterCollection> {\n\t\t// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class\n\t\tconst collection = new ConsensusRegisterCollectionClass(id, runtime, attributes);\n\t\tawait collection.load(services);\n\t\treturn collection;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): IConsensusRegisterCollection {\n\t\t// eslint-disable-next-line import-x/no-deprecated -- Internal usage of deprecated class\n\t\tconst collection = new ConsensusRegisterCollectionClass(\n\t\t\tid,\n\t\t\tdocument,\n\t\t\tConsensusRegisterCollectionFactory.Attributes,\n\t\t);\n\t\tcollection.initializeLocal();\n\t\treturn collection;\n\t}\n}\n\n/**\n * {@inheritDoc IConsensusRegisterCollection}\n * @legacy @beta\n */\nexport const ConsensusRegisterCollection = createSharedObjectKind(\n\tConsensusRegisterCollectionFactory,\n);\n/**\n * Compatibility alias for {@link IConsensusRegisterCollection}.\n * @legacy @beta\n */\nexport type ConsensusRegisterCollection<T> = IConsensusRegisterCollection<T>;\n"]}
@@ -43,7 +43,7 @@ export interface IConsensusRegisterCollection<T = any> extends ISharedObject<ICo
43
43
  * Attempts to write a register with a value. Returns a promise to indicate the roundtrip completion.
44
44
  * For a non existent register, it will attempt to create a new register with the specified value.
45
45
  *
46
- * @returns Promise<true> if write was non-concurrent
46
+ * @returns A promise resolving to `true` if the write was non-concurrent
47
47
  */
48
48
  write(key: string, value: T): Promise<boolean>;
49
49
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0EH;;;GAGG;AACH,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACrB,mFAAmF;IACnF,+CAAM,CAAA;IAEN,2DAA2D;IAC3D,yCAAG,CAAA;AACJ,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IChannelFactory } from \"@fluidframework/datastore-definitions/internal\";\nimport type {\n\tISharedObject,\n\tISharedObjectEvents,\n} from \"@fluidframework/shared-object-base/internal\";\n\n/**\n * Consensus Register Collection channel factory interface\n *\n * Extends the base IChannelFactory to return a more definite type of IConsensusRegisterCollection\n * Use for the runtime to create and load distributed data structure by type name of each channel.\n * @legacy @beta\n * @deprecated Use `IChannelFactory<IConsensusRegisterCollection>`.\n */\nexport type IConsensusRegisterCollectionFactory =\n\tIChannelFactory<IConsensusRegisterCollection>;\n\n/**\n * Events emitted by {@link IConsensusRegisterCollection}.\n * @legacy @beta\n */\nexport interface IConsensusRegisterCollectionEvents extends ISharedObjectEvents {\n\t(\n\t\tevent: \"atomicChanged\" | \"versionChanged\",\n\t\tlistener: (key: string, value: any, local: boolean) => void,\n\t);\n}\n\n/**\n * A distributed data structure that holds a set of registers with update\n * versions. On concurrent updates, a register internally stores all possible versions of a value by using reference\n * sequence number of the incoming update.\n *\n * Using all the stored versions, we can then distinguish amongst different read policies. Below are the policies\n * we support:\n *\n * Atomic: Atomicity requires a linearizable register. A linearizable register behaves as if there is only a single\n * copy of the data, and that every operation appears to take effect atomically at one point in time. This definition\n * implies that operations are executed in an well-defined order. On a concurrent update, we perform a compare-and-set\n * operation, where we compare a register sequence number with the incoming reference sequence number.\n * The earliest operation overwriting prior sequence numbers wins since every client reaches to an agreement on\n * the value. So we can safely return the first value.\n *\n * LWW: The last write to a key always wins.\n * @legacy @beta\n */\nexport interface IConsensusRegisterCollection<T = any>\n\textends ISharedObject<IConsensusRegisterCollectionEvents> {\n\t/**\n\t * Attempts to write a register with a value. Returns a promise to indicate the roundtrip completion.\n\t * For a non existent register, it will attempt to create a new register with the specified value.\n\t *\n\t * @returns Promise<true> if write was non-concurrent\n\t */\n\twrite(key: string, value: T): Promise<boolean>;\n\n\t/**\n\t * Retrieves the agreed upon value for the register based on policy. Returns undefined if not present.\n\t */\n\tread(key: string, policy?: ReadPolicy): T | undefined;\n\n\t/**\n\t * Retrives all concurrent versions. Undefined if not present.\n\t */\n\treadVersions(key: string): T[] | undefined;\n\n\t/**\n\t * Returns the keys.\n\t */\n\tkeys(): string[];\n}\n\n/**\n * Read policies used when reading the map value.\n * @legacy @beta\n */\nexport enum ReadPolicy {\n\t// On a concurrent update, returns the first agreed upon value amongst all clients.\n\tAtomic,\n\n\t// Last writer wins. Simply returns the last written value.\n\tLWW,\n}\n"]}
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0EH;;;GAGG;AACH,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACrB,mFAAmF;IACnF,+CAAM,CAAA;IAEN,2DAA2D;IAC3D,yCAAG,CAAA;AACJ,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IChannelFactory } from \"@fluidframework/datastore-definitions/internal\";\nimport type {\n\tISharedObject,\n\tISharedObjectEvents,\n} from \"@fluidframework/shared-object-base/internal\";\n\n/**\n * Consensus Register Collection channel factory interface\n *\n * Extends the base IChannelFactory to return a more definite type of IConsensusRegisterCollection\n * Use for the runtime to create and load distributed data structure by type name of each channel.\n * @legacy @beta\n * @deprecated Use `IChannelFactory<IConsensusRegisterCollection>`.\n */\nexport type IConsensusRegisterCollectionFactory =\n\tIChannelFactory<IConsensusRegisterCollection>;\n\n/**\n * Events emitted by {@link IConsensusRegisterCollection}.\n * @legacy @beta\n */\nexport interface IConsensusRegisterCollectionEvents extends ISharedObjectEvents {\n\t(\n\t\tevent: \"atomicChanged\" | \"versionChanged\",\n\t\tlistener: (key: string, value: any, local: boolean) => void,\n\t);\n}\n\n/**\n * A distributed data structure that holds a set of registers with update\n * versions. On concurrent updates, a register internally stores all possible versions of a value by using reference\n * sequence number of the incoming update.\n *\n * Using all the stored versions, we can then distinguish amongst different read policies. Below are the policies\n * we support:\n *\n * Atomic: Atomicity requires a linearizable register. A linearizable register behaves as if there is only a single\n * copy of the data, and that every operation appears to take effect atomically at one point in time. This definition\n * implies that operations are executed in an well-defined order. On a concurrent update, we perform a compare-and-set\n * operation, where we compare a register sequence number with the incoming reference sequence number.\n * The earliest operation overwriting prior sequence numbers wins since every client reaches to an agreement on\n * the value. So we can safely return the first value.\n *\n * LWW: The last write to a key always wins.\n * @legacy @beta\n */\nexport interface IConsensusRegisterCollection<T = any>\n\textends ISharedObject<IConsensusRegisterCollectionEvents> {\n\t/**\n\t * Attempts to write a register with a value. Returns a promise to indicate the roundtrip completion.\n\t * For a non existent register, it will attempt to create a new register with the specified value.\n\t *\n\t * @returns A promise resolving to `true` if the write was non-concurrent\n\t */\n\twrite(key: string, value: T): Promise<boolean>;\n\n\t/**\n\t * Retrieves the agreed upon value for the register based on policy. Returns undefined if not present.\n\t */\n\tread(key: string, policy?: ReadPolicy): T | undefined;\n\n\t/**\n\t * Retrives all concurrent versions. Undefined if not present.\n\t */\n\treadVersions(key: string): T[] | undefined;\n\n\t/**\n\t * Returns the keys.\n\t */\n\tkeys(): string[];\n}\n\n/**\n * Read policies used when reading the map value.\n * @legacy @beta\n */\nexport enum ReadPolicy {\n\t// On a concurrent update, returns the first agreed upon value amongst all clients.\n\tAtomic,\n\n\t// Last writer wins. Simply returns the last written value.\n\tLWW,\n}\n"]}
package/lib/legacy.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  /*
7
7
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
8
+ * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  export {
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/register-collection";
8
- export declare const pkgVersion = "2.118.0";
8
+ export declare const pkgVersion = "3.0.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wCAAwC,CAAC;AAC7D,eAAO,MAAM,UAAU,YAAY,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wCAAwC,CAAC;AAC7D,eAAO,MAAM,UAAU,UAAU,CAAC"}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/register-collection";
8
- export const pkgVersion = "2.118.0";
8
+ export const pkgVersion = "3.0.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,qCAAqC,CAAC;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/register-collection\";\nexport const pkgVersion = \"2.118.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,qCAAqC,CAAC;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/register-collection\";\nexport const pkgVersion = \"3.0.0\";\n"]}
package/lib/public.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  /*
7
7
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
8
+ * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  export {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/register-collection",
3
- "version": "2.118.0",
3
+ "version": "3.0.0",
4
4
  "description": "Consensus Register",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -14,50 +14,30 @@
14
14
  "type": "module",
15
15
  "exports": {
16
16
  ".": {
17
- "import": {
18
- "types": "./lib/public.d.ts",
19
- "default": "./lib/index.js"
20
- },
21
- "require": {
22
- "types": "./dist/public.d.ts",
23
- "default": "./dist/index.js"
17
+ "types": "./lib/public.d.ts",
18
+ "default": "./lib/index.js",
19
+ "internal-entrypoint-generation": {
20
+ "types": "./dist/public.d.ts"
24
21
  }
25
22
  },
26
23
  "./legacy": {
27
- "import": {
28
- "types": "./lib/legacy.d.ts",
29
- "default": "./lib/index.js"
30
- },
31
- "require": {
32
- "types": "./dist/legacy.d.ts",
33
- "default": "./dist/index.js"
24
+ "types": "./lib/legacy.d.ts",
25
+ "default": "./lib/index.js",
26
+ "internal-entrypoint-generation": {
27
+ "types": "./dist/legacy.d.ts"
34
28
  }
35
29
  },
36
30
  "./internal": {
37
- "import": {
38
- "types": "./lib/index.d.ts",
39
- "default": "./lib/index.js"
40
- },
41
- "require": {
42
- "types": "./dist/index.d.ts",
43
- "default": "./dist/index.js"
44
- }
31
+ "types": "./lib/index.d.ts",
32
+ "default": "./lib/index.js"
45
33
  },
46
34
  "./internal/test": {
47
35
  "allow-ff-test-exports": {
48
- "import": {
49
- "types": "./lib/test/index.d.ts",
50
- "default": "./lib/test/index.js"
51
- },
52
- "require": {
53
- "types": "./dist/test/index.d.ts",
54
- "default": "./dist/test/index.js"
55
- }
36
+ "types": "./lib/test/index.d.ts",
37
+ "default": "./lib/test/index.js"
56
38
  }
57
39
  }
58
40
  },
59
- "main": "lib/index.js",
60
- "types": "lib/public.d.ts",
61
41
  "c8": {
62
42
  "all": true,
63
43
  "cache-dir": "nyc/.cache",
@@ -81,27 +61,27 @@
81
61
  "temp-directory": "nyc/.nyc_output"
82
62
  },
83
63
  "dependencies": {
84
- "@fluid-internal/client-utils": "~2.118.0",
85
- "@fluidframework/core-interfaces": "~2.118.0",
86
- "@fluidframework/core-utils": "~2.118.0",
87
- "@fluidframework/datastore-definitions": "~2.118.0",
88
- "@fluidframework/driver-definitions": "~2.118.0",
89
- "@fluidframework/driver-utils": "~2.118.0",
90
- "@fluidframework/runtime-definitions": "~2.118.0",
91
- "@fluidframework/shared-object-base": "~2.118.0"
64
+ "@fluid-internal/client-utils": "~3.0.0",
65
+ "@fluidframework/core-interfaces": "~3.0.0",
66
+ "@fluidframework/core-utils": "~3.0.0",
67
+ "@fluidframework/datastore-definitions": "~3.0.0",
68
+ "@fluidframework/driver-definitions": "~3.0.0",
69
+ "@fluidframework/driver-utils": "~3.0.0",
70
+ "@fluidframework/runtime-definitions": "~3.0.0",
71
+ "@fluidframework/shared-object-base": "~3.0.0"
92
72
  },
93
73
  "devDependencies": {
94
74
  "@arethetypeswrong/cli": "^0.18.5",
95
75
  "@biomejs/biome": "~2.4.5",
96
- "@fluid-internal/mocha-test-setup": "~2.118.0",
97
- "@fluid-private/stochastic-test-utils": "~2.118.0",
98
- "@fluid-private/test-dds-utils": "~2.118.0",
76
+ "@fluid-internal/mocha-test-setup": "~3.0.0",
77
+ "@fluid-private/stochastic-test-utils": "~3.0.0",
78
+ "@fluid-private/test-dds-utils": "~3.0.0",
99
79
  "@fluid-tools/build-cli": "^0.67.0",
100
80
  "@fluidframework/build-common": "^2.0.3",
101
81
  "@fluidframework/build-tools": "^0.67.0",
102
82
  "@fluidframework/eslint-config-fluid": "^14.0.0",
103
83
  "@fluidframework/register-collection-previous": "npm:@fluidframework/register-collection@2.116.0",
104
- "@fluidframework/test-runtime-utils": "~2.118.0",
84
+ "@fluidframework/test-runtime-utils": "~3.0.0",
105
85
  "@microsoft/api-extractor": "7.58.1",
106
86
  "@types/mocha": "^10.0.10",
107
87
  "@types/node": "~22.19.17",
@@ -114,7 +94,7 @@
114
94
  "mocha": "^11.7.5",
115
95
  "mocha-multi-reporters": "^1.5.1",
116
96
  "rimraf": "^6.1.3",
117
- "typescript": "~5.4.5"
97
+ "typescript": "~6.0.3"
118
98
  },
119
99
  "typeValidation": {
120
100
  "broken": {},
@@ -123,20 +103,21 @@
123
103
  "scripts": {
124
104
  "build": "fluid-build . --task build",
125
105
  "build:api-reports": "concurrently \"npm:build:api-reports:*\"",
126
- "build:api-reports:current": "api-extractor run --local --config api-extractor/api-extractor.current.json",
127
- "build:api-reports:legacy": "api-extractor run --local --config api-extractor/api-extractor.legacy.json",
106
+ "build:api-reports:current": "api-extractor run --local --config api-extractor/api-extractor-report.current.json",
107
+ "build:api-reports:legacy": "api-extractor run --local --config api-extractor/api-extractor-report.legacy.json",
108
+ "build:cjs": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
128
109
  "build:commonjs": "fluid-build . --task commonjs",
129
110
  "build:compile": "fluid-build . --task compile",
130
- "build:docs": "api-extractor run --local",
111
+ "build:docs": "api-extractor run --local --config api-extractor/api-extractor-model.json",
131
112
  "build:entrypoints": "fluid-build . --task build:entrypoints",
132
113
  "build:entrypoints:cjs": "flub generate entrypoints --resolutionConditions require --outFileLegacyBeta legacy --outDir ./dist",
133
- "build:entrypoints:esm": "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat",
134
- "build:esnext": "tsc --project ./tsconfig.json",
114
+ "build:entrypoints:esm": "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib",
115
+ "build:esm": "tsc --project ./tsconfig.json",
135
116
  "build:genver": "gen-version",
136
117
  "build:test": "concurrently npm:build:test:esm npm:build:test:cjs",
137
118
  "build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
138
119
  "build:test:esm": "tsc --project ./src/test/tsconfig.json",
139
- "check:are-the-types-wrong": "attw --pack . --exclude-entrypoints ./internal/test",
120
+ "check:are-the-types-wrong": "attw --pack . --profile esm-only --exclude-entrypoints ./internal/test",
140
121
  "check:biome": "biome check .",
141
122
  "check:exports": "concurrently \"npm:check:exports:*\"",
142
123
  "check:exports:bundle-release-tags": "api-extractor run --config api-extractor/api-extractor-lint-bundle.json",
@@ -146,9 +127,9 @@
146
127
  "check:exports:esm:public": "api-extractor run --config api-extractor/api-extractor-lint-public.esm.json",
147
128
  "check:format": "npm run check:biome",
148
129
  "ci:build:api-reports": "concurrently \"npm:ci:build:api-reports:*\"",
149
- "ci:build:api-reports:current": "api-extractor run --config api-extractor/api-extractor.current.json",
150
- "ci:build:api-reports:legacy": "api-extractor run --config api-extractor/api-extractor.legacy.json",
151
- "ci:build:docs": "api-extractor run",
130
+ "ci:build:api-reports:current": "api-extractor run --config api-extractor/api-extractor-report.current.json",
131
+ "ci:build:api-reports:legacy": "api-extractor run --config api-extractor/api-extractor-report.legacy.json",
132
+ "ci:build:docs": "api-extractor run --config api-extractor/api-extractor-model.json",
152
133
  "clean": "rimraf --glob dist lib {alpha,beta,internal,legacy}.d.ts \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
153
134
  "eslint": "eslint --quiet --format stylish src",
154
135
  "eslint:fix": "eslint --quiet --format stylish src --fix --fix-type problem,suggestion,layout",
@@ -162,7 +143,6 @@
162
143
  "test:mocha:cjs": "cross-env FLUID_TEST_MODULE_SYSTEM=CJS mocha",
163
144
  "test:mocha:esm": "mocha",
164
145
  "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
165
- "tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
166
146
  "typetests:gen": "flub generate typetests --dir . -v"
167
147
  }
168
148
  }
@@ -151,7 +151,7 @@ export class ConsensusRegisterCollection<T>
151
151
  * Creates a new register or writes a new value.
152
152
  * Returns a promise that will resolve when the write is acked.
153
153
  *
154
- * @returns Promise<true> if write was non-concurrent
154
+ * @returns A promise resolving to `true` if the write was non-concurrent
155
155
  */
156
156
  public async write(key: string, value: T): Promise<boolean> {
157
157
  if (this.runtime.disposed) {
package/src/interfaces.ts CHANGED
@@ -55,7 +55,7 @@ export interface IConsensusRegisterCollection<T = any>
55
55
  * Attempts to write a register with a value. Returns a promise to indicate the roundtrip completion.
56
56
  * For a non existent register, it will attempt to create a new register with the specified value.
57
57
  *
58
- * @returns Promise<true> if write was non-concurrent
58
+ * @returns A promise resolving to `true` if the write was non-concurrent
59
59
  */
60
60
  write(key: string, value: T): Promise<boolean>;
61
61
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/register-collection";
9
- export const pkgVersion = "2.118.0";
9
+ export const pkgVersion = "3.0.0";
package/tsconfig.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "../../../common/build/build-common/tsconfig.node16.json",
2
+ "extends": "../../../common/build/build-common/tsconfig.node20.json",
3
3
  "include": ["src/**/*"],
4
4
  "exclude": ["src/test/**/*"],
5
5
  "compilerOptions": {
package/internal.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- /*
7
- * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
- */
10
-
11
- export * from "./lib/index.js";
package/legacy.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- /*
7
- * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
- */
10
-
11
- export * from "./lib/legacy.js";