@fluidframework/replay-driver 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.
- package/CHANGELOG.md +34 -4
- package/README.md +49 -46
- package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
- package/api-extractor/api-extractor-report.json +5 -0
- package/dist/replayDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/replayDocumentDeltaConnection.js +24 -19
- package/dist/replayDocumentDeltaConnection.js.map +1 -1
- package/dist/replayDocumentService.js +2 -0
- package/dist/replayDocumentService.js.map +1 -1
- package/dist/replayDocumentServiceFactory.d.ts +7 -1
- package/dist/replayDocumentServiceFactory.d.ts.map +1 -1
- package/dist/replayDocumentServiceFactory.js +11 -0
- package/dist/replayDocumentServiceFactory.js.map +1 -1
- package/dist/storageImplementations.js +13 -4
- package/dist/storageImplementations.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/replayDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/replayDocumentDeltaConnection.js +24 -19
- package/lib/replayDocumentDeltaConnection.js.map +1 -1
- package/lib/replayDocumentService.js +2 -0
- package/lib/replayDocumentService.js.map +1 -1
- package/lib/replayDocumentServiceFactory.d.ts +7 -1
- package/lib/replayDocumentServiceFactory.d.ts.map +1 -1
- package/lib/replayDocumentServiceFactory.js +11 -0
- package/lib/replayDocumentServiceFactory.js.map +1 -1
- package/lib/storageImplementations.js +13 -4
- package/lib/storageImplementations.js.map +1 -1
- package/package.json +28 -32
- package/src/replayDocumentServiceFactory.ts +14 -1
- package/tsconfig.json +1 -1
- package/internal.d.ts +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,42 @@
|
|
|
1
1
|
# @fluidframework/replay-driver
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 3.0.0
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Minor Changes
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
@@ -10,15 +10,15 @@ to mimic the web socket connection.
|
|
|
10
10
|
|
|
11
11
|
## Using Fluid Framework libraries
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
library consumers should always prefer `^`.
|
|
13
|
+
For a dependency on a Fluid Framework library's public APIs, we recommend a `^` (caret) version range.
|
|
14
|
+
For example, use `^1.3.4`.
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
For a dependency on an unstable API, such as a `beta` API, we recommend a more restrictive version range.
|
|
17
|
+
For example, use a `~` version range.
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Run this command to install the package:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
npm i @fluidframework/replay-driver
|
|
@@ -26,7 +26,7 @@ npm i @fluidframework/replay-driver
|
|
|
26
26
|
|
|
27
27
|
## API Documentation
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Read the **@fluidframework/replay-driver** API documentation at <https://fluidframework.com/docs/apis/replay-driver>.
|
|
30
30
|
|
|
31
31
|
<!-- prettier-ignore-end -->
|
|
32
32
|
|
|
@@ -39,62 +39,69 @@ API documentation for **@fluidframework/replay-driver** is available at <https:/
|
|
|
39
39
|
|
|
40
40
|
## Minimum Client Requirements
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
These requirements
|
|
44
|
-
|
|
42
|
+
Fluid Framework client libraries support the platforms in this document.
|
|
43
|
+
These requirements are intentionally restrictive.
|
|
44
|
+
Within a major version series, we can relax these requirements, but we cannot make them stricter.
|
|
45
|
+
For a Long Term Support (LTS) version, we might need to support these platforms for several years.
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
If
|
|
48
|
-
|
|
47
|
+
Other configurations can work, but Fluid Framework does not support them.
|
|
48
|
+
If an unsupported configuration stops working, we do not classify this as a bug.
|
|
49
|
+
To request support for a configuration that is not listed, file an issue.
|
|
50
|
+
The product team will evaluate your request.
|
|
51
|
+
In the issue, specify the current status of the configuration:
|
|
52
|
+
|
|
53
|
+
- The configuration works but needs official support.
|
|
54
|
+
- The configuration does not work and requires changes.
|
|
49
55
|
|
|
50
56
|
### Supported Runtimes
|
|
51
57
|
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
58
|
+
- Fluid Framework supports Node.js versions 22 and 24 while they receive [upstream support](https://nodejs.org/en/about/previous-releases).
|
|
59
|
+
- Fluid Framework will stop support for version 22 [when upstream support ends on 2027-04-30](https://github.com/nodejs/release#release-schedule).
|
|
60
|
+
- Fluid Framework does not support Node.js with the `--no-experimental-fetch` flag.
|
|
61
|
+
- Fluid Framework supports modern browsers that support the ES2022 standard library.
|
|
55
62
|
|
|
56
63
|
### Supported Tools
|
|
57
64
|
|
|
58
|
-
- TypeScript
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
- [
|
|
62
|
-
-
|
|
63
|
-
|
|
65
|
+
- [TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0):
|
|
66
|
+
- Fluid Framework supports all [`strict`](https://www.typescriptlang.org/tsconfig) options.
|
|
67
|
+
- Set the build targets (`lib`, `target`) to `ES2022` or later.
|
|
68
|
+
- Enable [`strictNullChecks`](https://www.typescriptlang.org/tsconfig).
|
|
69
|
+
- 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).
|
|
70
|
+
- Fluid Framework does not fully support `exactOptionalPropertyTypes`.
|
|
71
|
+
If you enable this option, do not use `in`, `Reflect.has`, `Object.hasOwn`, or `Object.prototype.hasOwnProperty` to narrow members of Fluid Framework types.
|
|
72
|
+
These methods can incorrectly exclude `undefined` from the possible values.
|
|
64
73
|
- [webpack](https://webpack.js.org/) 5
|
|
65
|
-
- We
|
|
66
|
-
Other bundlers
|
|
74
|
+
- We do not require a specific bundler.
|
|
75
|
+
Other bundlers that handle ES Modules can work, but we actively test only webpack.
|
|
67
76
|
|
|
68
77
|
### Module Resolution
|
|
69
78
|
|
|
70
|
-
[`Node16`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution)
|
|
71
|
-
|
|
79
|
+
In TypeScript `compilerOptions`, use [`Node16`, `Node20`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution) module resolution.
|
|
80
|
+
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).
|
|
81
|
+
|
|
82
|
+
Do not use `Node10` module resolution.
|
|
72
83
|
|
|
73
84
|
### Module Formats
|
|
74
85
|
|
|
75
86
|
- ES Modules:
|
|
76
|
-
ES Modules
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
This is done to accommodate some workflows without good ES Module support.
|
|
80
|
-
If you have a workflow you would like included in this list, file an issue.
|
|
81
|
-
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.
|
|
82
|
-
|
|
83
|
-
- 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))
|
|
87
|
+
Use ES Modules to consume Fluid Framework client packages, including in Node.js.
|
|
88
|
+
- CommonJS:
|
|
89
|
+
Fluid Framework does not officially support CommonJS in version 3.0 or later.
|
|
84
90
|
|
|
85
91
|
## Contribution Guidelines
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
You can [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid Framework in these ways:
|
|
88
94
|
|
|
89
|
-
-
|
|
90
|
-
- [Submit
|
|
91
|
-
- Review
|
|
95
|
+
- Answer questions in [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
|
|
96
|
+
- [Submit bug reports](https://github.com/microsoft/FluidFramework/issues) and help verify fixes.
|
|
97
|
+
- Review [source code changes](https://github.com/microsoft/FluidFramework/pulls).
|
|
92
98
|
- [Contribute bug fixes](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md).
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
For detailed instructions, read the [repo documentation](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Home.md).
|
|
95
101
|
|
|
96
|
-
This project
|
|
97
|
-
For more information
|
|
102
|
+
This project follows the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
|
103
|
+
For more information, read the [Code of Conduct frequently asked questions](https://opensource.microsoft.com/codeofconduct/faq/).
|
|
104
|
+
For questions or comments, contact [opencode@microsoft.com](mailto:opencode@microsoft.com).
|
|
98
105
|
|
|
99
106
|
This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
|
|
100
107
|
Use of these trademarks or logos must follow Microsoft’s [Trademark & Brand Guidelines](https://www.microsoft.com/trademarks).
|
|
@@ -102,13 +109,9 @@ Use of Microsoft trademarks or logos in modified versions of this project must n
|
|
|
102
109
|
|
|
103
110
|
## Help
|
|
104
111
|
|
|
105
|
-
|
|
106
|
-
Check out [fluidframework.com](https://fluidframework.com/docs/).
|
|
107
|
-
|
|
108
|
-
Still not finding what you're looking for?
|
|
109
|
-
Please [file an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
|
|
112
|
+
Read the [Fluid Framework documentation](https://fluidframework.com/docs/) for information about Fluid Framework concepts and APIs.
|
|
110
113
|
|
|
111
|
-
|
|
114
|
+
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).
|
|
112
115
|
|
|
113
116
|
## Trademark
|
|
114
117
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
-
"extends": "
|
|
3
|
+
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-model.esm.json"
|
|
4
4
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
+
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-report-base.esm.json",
|
|
4
|
+
"mainEntryPointFilePath": "<projectFolder>/lib/public.d.ts"
|
|
5
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replayDocumentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/replayDocumentDeltaConnection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EACX,oBAAoB,EACpB,UAAU,EACV,wBAAwB,EACxB,8BAA8B,EAC9B,4BAA4B,EAC5B,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,qBAAa,sBAAuB,SAAQ,gBAAgB;aAgB1C,UAAU,EAAE,MAAM;aAClB,QAAQ,EAAE,MAAM;aAChB,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"replayDocumentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/replayDocumentDeltaConnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,13 @@ const internal_2 = require("@fluidframework/driver-definitions/internal");
|
|
|
11
11
|
const replayController_js_1 = require("./replayController.js");
|
|
12
12
|
const ReplayDocumentId = "documentId";
|
|
13
13
|
class ReplayControllerStatic extends replayController_js_1.ReplayController {
|
|
14
|
+
replayFrom;
|
|
15
|
+
replayTo;
|
|
16
|
+
unitIsTime;
|
|
17
|
+
static DelayInterval = 50;
|
|
18
|
+
static ReplayResolution = 15;
|
|
19
|
+
firstTimeStamp;
|
|
20
|
+
replayCurrent = 0;
|
|
14
21
|
// Simulated delay interval for emitting the ops
|
|
15
22
|
/**
|
|
16
23
|
* Helper class
|
|
@@ -24,7 +31,6 @@ class ReplayControllerStatic extends replayController_js_1.ReplayController {
|
|
|
24
31
|
this.replayFrom = replayFrom;
|
|
25
32
|
this.replayTo = replayTo;
|
|
26
33
|
this.unitIsTime = unitIsTime;
|
|
27
|
-
this.replayCurrent = 0;
|
|
28
34
|
if (unitIsTime !== true) {
|
|
29
35
|
// There is no code in here to start with snapshot, thus we have to start with op #0.
|
|
30
36
|
this.replayTo = 0;
|
|
@@ -143,9 +149,8 @@ class ReplayControllerStatic extends replayController_js_1.ReplayController {
|
|
|
143
149
|
}
|
|
144
150
|
}
|
|
145
151
|
exports.ReplayControllerStatic = ReplayControllerStatic;
|
|
146
|
-
ReplayControllerStatic.DelayInterval = 50;
|
|
147
|
-
ReplayControllerStatic.ReplayResolution = 15;
|
|
148
152
|
class ReplayDocumentDeltaConnection extends client_utils_1.TypedEventEmitter {
|
|
153
|
+
details;
|
|
149
154
|
/**
|
|
150
155
|
* Creates a new delta connection and mimics the delta connection to replay ops on it.
|
|
151
156
|
* @param documentService - The document service to be used to get underlying endpoints.
|
|
@@ -172,6 +177,20 @@ class ReplayDocumentDeltaConnection extends client_utils_1.TypedEventEmitter {
|
|
|
172
177
|
deltaConnection.fetchAndEmitOps(documentStorageService, controller);
|
|
173
178
|
return deltaConnection;
|
|
174
179
|
}
|
|
180
|
+
static replayProtocolVersion = "^0.1.0";
|
|
181
|
+
// Since the replay service never actually sends messages the size below is arbitrary
|
|
182
|
+
static ReplayMaxMessageSize = 16 * 1024;
|
|
183
|
+
static claims = {
|
|
184
|
+
documentId: ReplayDocumentId,
|
|
185
|
+
scopes: [internal_2.ScopeType.DocRead],
|
|
186
|
+
tenantId: "",
|
|
187
|
+
user: {
|
|
188
|
+
id: "",
|
|
189
|
+
},
|
|
190
|
+
iat: Math.round(Date.now() / 1000),
|
|
191
|
+
exp: Math.round(Date.now() / 1000) + 60 * 60, // 1 hour expiration
|
|
192
|
+
ver: "1.0",
|
|
193
|
+
};
|
|
175
194
|
get clientId() {
|
|
176
195
|
return this.details.clientId;
|
|
177
196
|
}
|
|
@@ -199,11 +218,10 @@ class ReplayDocumentDeltaConnection extends client_utils_1.TypedEventEmitter {
|
|
|
199
218
|
get serviceConfiguration() {
|
|
200
219
|
return this.details.serviceConfiguration;
|
|
201
220
|
}
|
|
221
|
+
maxMessageSize = ReplayDocumentDeltaConnection.ReplayMaxMessageSize;
|
|
202
222
|
constructor(details) {
|
|
203
223
|
super();
|
|
204
224
|
this.details = details;
|
|
205
|
-
this.maxMessageSize = ReplayDocumentDeltaConnection.ReplayMaxMessageSize;
|
|
206
|
-
this._disposed = false;
|
|
207
225
|
}
|
|
208
226
|
submit(documentMessage) {
|
|
209
227
|
// ReplayDocumentDeltaConnection.submit() can't be called - client never sees its own join on,
|
|
@@ -212,6 +230,7 @@ class ReplayDocumentDeltaConnection extends client_utils_1.TypedEventEmitter {
|
|
|
212
230
|
}
|
|
213
231
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
214
232
|
async submitSignal(message) { }
|
|
233
|
+
_disposed = false;
|
|
215
234
|
get disposed() {
|
|
216
235
|
return this._disposed;
|
|
217
236
|
}
|
|
@@ -251,18 +270,4 @@ class ReplayDocumentDeltaConnection extends client_utils_1.TypedEventEmitter {
|
|
|
251
270
|
}
|
|
252
271
|
}
|
|
253
272
|
exports.ReplayDocumentDeltaConnection = ReplayDocumentDeltaConnection;
|
|
254
|
-
ReplayDocumentDeltaConnection.replayProtocolVersion = "^0.1.0";
|
|
255
|
-
// Since the replay service never actually sends messages the size below is arbitrary
|
|
256
|
-
ReplayDocumentDeltaConnection.ReplayMaxMessageSize = 16 * 1024;
|
|
257
|
-
ReplayDocumentDeltaConnection.claims = {
|
|
258
|
-
documentId: ReplayDocumentId,
|
|
259
|
-
scopes: [internal_2.ScopeType.DocRead],
|
|
260
|
-
tenantId: "",
|
|
261
|
-
user: {
|
|
262
|
-
id: "",
|
|
263
|
-
},
|
|
264
|
-
iat: Math.round(Date.now() / 1000),
|
|
265
|
-
exp: Math.round(Date.now() / 1000) + 60 * 60, // 1 hour expiration
|
|
266
|
-
ver: "1.0",
|
|
267
|
-
};
|
|
268
273
|
//# sourceMappingURL=replayDocumentDeltaConnection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replayDocumentDeltaConnection.js","sourceRoot":"","sources":["../src/replayDocumentDeltaConnection.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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { delay } from \"@fluidframework/core-utils/internal\";\nimport type { ConnectionMode } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIClientConfiguration,\n\tIConnected,\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaConnectionEvents,\n\tIDocumentDeltaStorageService,\n\tIDocumentMessage,\n\tIDocumentService,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tISnapshotTree,\n\tITokenClaims,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { ScopeType } from \"@fluidframework/driver-definitions/internal\";\n\nimport { ReplayController } from \"./replayController.js\";\n\nconst ReplayDocumentId = \"documentId\";\n\nexport class ReplayControllerStatic extends ReplayController {\n\tprivate static readonly DelayInterval = 50;\n\tprivate static readonly ReplayResolution = 15;\n\n\tprivate firstTimeStamp: number | undefined;\n\tprivate replayCurrent = 0;\n\t// Simulated delay interval for emitting the ops\n\n\t/**\n\t * Helper class\n\t *\n\t * @param replayFrom - First op to be played on socket.\n\t * @param replayTo - Last op number to be played on socket.\n\t * @param unitIsTime - True is user want to play ops that are within a replay resolution window.\n\t */\n\tpublic constructor(\n\t\tpublic readonly replayFrom: number,\n\t\tpublic readonly replayTo: number,\n\t\tpublic readonly unitIsTime?: boolean,\n\t) {\n\t\tsuper();\n\t\tif (unitIsTime !== true) {\n\t\t\t// There is no code in here to start with snapshot, thus we have to start with op #0.\n\t\t\tthis.replayTo = 0;\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\treturn true;\n\t}\n\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\treturn [];\n\t}\n\n\tpublic async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n\t\treturn version ? Promise.reject(new Error(\"Invalid operation\")) : null;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tthrow new Error(\"Invalid operation\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\tif (!(this.unitIsTime !== true && this.replayTo >= 0)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.replayTo;\n\t}\n\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (this.replayTo >= 0) {\n\t\t\tif (this.unitIsTime === true) {\n\t\t\t\treturn (\n\t\t\t\t\tlastTimeStamp !== undefined &&\n\t\t\t\t\tthis.firstTimeStamp !== undefined &&\n\t\t\t\t\tlastTimeStamp - this.firstTimeStamp >= this.replayTo\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn currentOp >= this.replayTo;\n\t\t}\n\t\treturn lastTimeStamp === undefined; // No more ops\n\t}\n\n\tpublic skipToIndex(fetchedOps: ISequencedDocumentMessage[]): number {\n\t\tif (this.replayFrom <= 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (this.unitIsTime === true) {\n\t\t\tfor (const [i, { timestamp }] of fetchedOps.entries()) {\n\t\t\t\tif (timestamp !== undefined) {\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 (this.firstTimeStamp === undefined) {\n\t\t\t\t\t\tthis.firstTimeStamp = timestamp;\n\t\t\t\t\t}\n\t\t\t\t\tif (timestamp - this.firstTimeStamp >= this.replayFrom) {\n\t\t\t\t\t\treturn i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.replayFrom > this.replayCurrent) {\n\t\t\treturn this.replayFrom - this.replayCurrent;\n\t\t}\n\t\treturn 0;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet current = this.skipToIndex(fetchedOps);\n\n\t\treturn new Promise((resolve) => {\n\t\t\tconst replayNextOps = (): void => {\n\t\t\t\t// Emit the ops from replay to the end every \"deltainterval\" milliseconds\n\t\t\t\t// to simulate the socket stream\n\t\t\t\tconst currentOp = fetchedOps[current];\n\t\t\t\tconst playbackOps = [currentOp];\n\t\t\t\tlet nextInterval = ReplayControllerStatic.DelayInterval;\n\t\t\t\tcurrent += 1;\n\n\t\t\t\tif (this.unitIsTime === true) {\n\t\t\t\t\tconst currentTimeStamp = currentOp.timestamp;\n\t\t\t\t\tif (currentTimeStamp !== undefined) {\n\t\t\t\t\t\t// Emit more ops that is in the ReplayResolution window\n\n\t\t\t\t\t\twhile (current < fetchedOps.length) {\n\t\t\t\t\t\t\tconst op = fetchedOps[current];\n\t\t\t\t\t\t\tif (op.timestamp === undefined) {\n\t\t\t\t\t\t\t\t// Missing timestamp, just delay the standard amount of time\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst timeDiff = op.timestamp - currentTimeStamp;\n\t\t\t\t\t\t\tif (timeDiff >= ReplayControllerStatic.ReplayResolution) {\n\t\t\t\t\t\t\t\t// Time exceeded the resolution window, break out the loop\n\t\t\t\t\t\t\t\t// and delay for the time difference.\n\t\t\t\t\t\t\t\tnextInterval = timeDiff;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (timeDiff < 0) {\n\t\t\t\t\t\t\t\t// Time have regressed, just delay the standard amount of time\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// The op is within the ReplayResolution emit it now\n\t\t\t\t\t\t\tplaybackOps.push(op);\n\t\t\t\t\t\t\tcurrent += 1;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.firstTimeStamp !== undefined &&\n\t\t\t\t\t\t\tthis.replayTo >= 0 &&\n\t\t\t\t\t\t\tcurrentTimeStamp + nextInterval - this.firstTimeStamp > this.replayTo\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnextInterval = -1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tscheduleNext(nextInterval);\n\t\t\t\temitter(playbackOps);\n\t\t\t};\n\t\t\tconst scheduleNext = (nextInterval: number): void => {\n\t\t\t\tif (nextInterval >= 0 && current < fetchedOps.length) {\n\t\t\t\t\tsetTimeout(replayNextOps, nextInterval);\n\t\t\t\t} else {\n\t\t\t\t\tthis.replayCurrent += current;\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\t\t\tscheduleNext(ReplayControllerStatic.DelayInterval);\n\t\t});\n\t}\n}\n\nexport class ReplayDocumentDeltaConnection\n\textends TypedEventEmitter<IDocumentDeltaConnectionEvents>\n\timplements IDocumentDeltaConnection, IDisposable\n{\n\t/**\n\t * Creates a new delta connection and mimics the delta connection to replay ops on it.\n\t * @param documentService - The document service to be used to get underlying endpoints.\n\t */\n\tpublic static create(\n\t\tdocumentStorageService: IDocumentDeltaStorageService,\n\t\tcontroller: ReplayController,\n\t): IDocumentDeltaConnection {\n\t\tconst connection: IConnected = {\n\t\t\tclaims: ReplayDocumentDeltaConnection.claims,\n\t\t\tclientId: \"PseudoClientId\",\n\t\t\texisting: true,\n\t\t\tinitialMessages: [],\n\t\t\tinitialSignals: [],\n\t\t\tinitialClients: [],\n\t\t\tmaxMessageSize: ReplayDocumentDeltaConnection.ReplayMaxMessageSize,\n\t\t\tmode: \"read\",\n\t\t\tserviceConfiguration: {\n\t\t\t\tblockSize: 64436,\n\t\t\t\tmaxMessageSize: ReplayDocumentDeltaConnection.ReplayMaxMessageSize,\n\t\t\t},\n\t\t\tsupportedVersions: [ReplayDocumentDeltaConnection.replayProtocolVersion],\n\t\t\tversion: ReplayDocumentDeltaConnection.replayProtocolVersion,\n\t\t};\n\t\tconst deltaConnection = new ReplayDocumentDeltaConnection(connection);\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tdeltaConnection.fetchAndEmitOps(documentStorageService, controller);\n\n\t\treturn deltaConnection;\n\t}\n\n\tprivate static readonly replayProtocolVersion = \"^0.1.0\";\n\t// Since the replay service never actually sends messages the size below is arbitrary\n\tprivate static readonly ReplayMaxMessageSize = 16 * 1024;\n\n\tprivate static readonly claims: ITokenClaims = {\n\t\tdocumentId: ReplayDocumentId,\n\t\tscopes: [ScopeType.DocRead],\n\t\ttenantId: \"\",\n\t\tuser: {\n\t\t\tid: \"\",\n\t\t},\n\t\tiat: Math.round(Date.now() / 1000),\n\t\texp: Math.round(Date.now() / 1000) + 60 * 60, // 1 hour expiration\n\t\tver: \"1.0\",\n\t};\n\n\tpublic get clientId(): string {\n\t\treturn this.details.clientId;\n\t}\n\n\tpublic get mode(): ConnectionMode {\n\t\treturn this.details.mode;\n\t}\n\n\tpublic get claims(): ITokenClaims {\n\t\treturn this.details.claims;\n\t}\n\n\tpublic get existing(): boolean {\n\t\treturn this.details.existing;\n\t}\n\n\tpublic get version(): string {\n\t\treturn this.details.version;\n\t}\n\n\tpublic get initialMessages(): ISequencedDocumentMessage[] {\n\t\treturn this.details.initialMessages;\n\t}\n\n\tpublic get initialSignals(): ISignalMessage[] {\n\t\treturn this.details.initialSignals;\n\t}\n\n\tpublic get initialClients(): ISignalClient[] {\n\t\treturn this.details.initialClients;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration {\n\t\treturn this.details.serviceConfiguration;\n\t}\n\n\tpublic readonly maxMessageSize = ReplayDocumentDeltaConnection.ReplayMaxMessageSize;\n\n\tconstructor(public details: IConnected) {\n\t\tsuper();\n\t}\n\n\tpublic submit(documentMessage: IDocumentMessage[]): void {\n\t\t// ReplayDocumentDeltaConnection.submit() can't be called - client never sees its own join on,\n\t\t// and thus can never move to sending ops.\n\t\tthrow new Error(\"ReplayDocumentDeltaConnection.submit() can't be called\");\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async submitSignal(message: unknown): Promise<void> {}\n\n\tprivate _disposed = false;\n\tpublic get disposed(): boolean {\n\t\treturn this._disposed;\n\t}\n\tpublic dispose(): void {\n\t\tthis._disposed = true;\n\t}\n\n\t/**\n\t * This gets the specified ops from the delta storage endpoint and replays them in the replayer.\n\t */\n\tprivate async fetchAndEmitOps(\n\t\tdocumentStorageService: IDocumentDeltaStorageService,\n\t\tcontroller: ReplayController,\n\t): Promise<void> {\n\t\tlet done;\n\t\tlet replayPromiseChain = Promise.resolve();\n\n\t\tlet currentOp = await controller.getStartingOpSequence();\n\n\t\tdo {\n\t\t\tconst fetchTo = controller.fetchTo(currentOp);\n\n\t\t\tconst abortController = new AbortController();\n\t\t\tconst stream = documentStorageService.fetchMessages(\n\t\t\t\tcurrentOp + 1,\n\t\t\t\tfetchTo,\n\t\t\t\tabortController.signal,\n\t\t\t);\n\t\t\tdo {\n\t\t\t\tconst result = await stream.read();\n\n\t\t\t\tif (result.done) {\n\t\t\t\t\t// No more ops. But, they can show up later, either because document was just created,\n\t\t\t\t\t// or because another client keeps submitting new ops.\n\t\t\t\t\tdone = controller.isDoneFetch(currentOp, undefined);\n\t\t\t\t\tif (!done) {\n\t\t\t\t\t\tawait delay(2000);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treplayPromiseChain = replayPromiseChain.then(async () =>\n\t\t\t\t\tcontroller.replay((ops) => this.emit(\"op\", ReplayDocumentId, ops), messages),\n\t\t\t\t);\n\n\t\t\t\tconst messages = result.value;\n\t\t\t\tcurrentOp += messages.length;\n\t\t\t\tdone = controller.isDoneFetch(currentOp, messages[messages.length - 1].timestamp);\n\t\t\t} while (!done);\n\n\t\t\tabortController.abort();\n\t\t} while (!done);\n\t\treturn replayPromiseChain;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"replayDocumentDeltaConnection.js","sourceRoot":"","sources":["../src/replayDocumentDeltaConnection.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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { delay } from \"@fluidframework/core-utils/internal\";\nimport type { ConnectionMode } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIClientConfiguration,\n\tIConnected,\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaConnectionEvents,\n\tIDocumentDeltaStorageService,\n\tIDocumentMessage,\n\tIDocumentService,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tISnapshotTree,\n\tITokenClaims,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { ScopeType } from \"@fluidframework/driver-definitions/internal\";\n\nimport { ReplayController } from \"./replayController.js\";\n\nconst ReplayDocumentId = \"documentId\";\n\nexport class ReplayControllerStatic extends ReplayController {\n\tprivate static readonly DelayInterval = 50;\n\tprivate static readonly ReplayResolution = 15;\n\n\tprivate firstTimeStamp: number | undefined;\n\tprivate replayCurrent = 0;\n\t// Simulated delay interval for emitting the ops\n\n\t/**\n\t * Helper class\n\t *\n\t * @param replayFrom - First op to be played on socket.\n\t * @param replayTo - Last op number to be played on socket.\n\t * @param unitIsTime - True is user want to play ops that are within a replay resolution window.\n\t */\n\tpublic constructor(\n\t\tpublic readonly replayFrom: number,\n\t\tpublic readonly replayTo: number,\n\t\tpublic readonly unitIsTime?: boolean,\n\t) {\n\t\tsuper();\n\t\tif (unitIsTime !== true) {\n\t\t\t// There is no code in here to start with snapshot, thus we have to start with op #0.\n\t\t\tthis.replayTo = 0;\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\treturn true;\n\t}\n\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\treturn [];\n\t}\n\n\tpublic async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n\t\treturn version ? Promise.reject(new Error(\"Invalid operation\")) : null;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tthrow new Error(\"Invalid operation\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\tif (!(this.unitIsTime !== true && this.replayTo >= 0)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.replayTo;\n\t}\n\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (this.replayTo >= 0) {\n\t\t\tif (this.unitIsTime === true) {\n\t\t\t\treturn (\n\t\t\t\t\tlastTimeStamp !== undefined &&\n\t\t\t\t\tthis.firstTimeStamp !== undefined &&\n\t\t\t\t\tlastTimeStamp - this.firstTimeStamp >= this.replayTo\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn currentOp >= this.replayTo;\n\t\t}\n\t\treturn lastTimeStamp === undefined; // No more ops\n\t}\n\n\tpublic skipToIndex(fetchedOps: ISequencedDocumentMessage[]): number {\n\t\tif (this.replayFrom <= 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (this.unitIsTime === true) {\n\t\t\tfor (const [i, { timestamp }] of fetchedOps.entries()) {\n\t\t\t\tif (timestamp !== undefined) {\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 (this.firstTimeStamp === undefined) {\n\t\t\t\t\t\tthis.firstTimeStamp = timestamp;\n\t\t\t\t\t}\n\t\t\t\t\tif (timestamp - this.firstTimeStamp >= this.replayFrom) {\n\t\t\t\t\t\treturn i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.replayFrom > this.replayCurrent) {\n\t\t\treturn this.replayFrom - this.replayCurrent;\n\t\t}\n\t\treturn 0;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet current = this.skipToIndex(fetchedOps);\n\n\t\treturn new Promise((resolve) => {\n\t\t\tconst replayNextOps = (): void => {\n\t\t\t\t// Emit the ops from replay to the end every \"deltainterval\" milliseconds\n\t\t\t\t// to simulate the socket stream\n\t\t\t\tconst currentOp = fetchedOps[current];\n\t\t\t\tconst playbackOps = [currentOp];\n\t\t\t\tlet nextInterval = ReplayControllerStatic.DelayInterval;\n\t\t\t\tcurrent += 1;\n\n\t\t\t\tif (this.unitIsTime === true) {\n\t\t\t\t\tconst currentTimeStamp = currentOp.timestamp;\n\t\t\t\t\tif (currentTimeStamp !== undefined) {\n\t\t\t\t\t\t// Emit more ops that is in the ReplayResolution window\n\n\t\t\t\t\t\twhile (current < fetchedOps.length) {\n\t\t\t\t\t\t\tconst op = fetchedOps[current];\n\t\t\t\t\t\t\tif (op.timestamp === undefined) {\n\t\t\t\t\t\t\t\t// Missing timestamp, just delay the standard amount of time\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst timeDiff = op.timestamp - currentTimeStamp;\n\t\t\t\t\t\t\tif (timeDiff >= ReplayControllerStatic.ReplayResolution) {\n\t\t\t\t\t\t\t\t// Time exceeded the resolution window, break out the loop\n\t\t\t\t\t\t\t\t// and delay for the time difference.\n\t\t\t\t\t\t\t\tnextInterval = timeDiff;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (timeDiff < 0) {\n\t\t\t\t\t\t\t\t// Time have regressed, just delay the standard amount of time\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// The op is within the ReplayResolution emit it now\n\t\t\t\t\t\t\tplaybackOps.push(op);\n\t\t\t\t\t\t\tcurrent += 1;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.firstTimeStamp !== undefined &&\n\t\t\t\t\t\t\tthis.replayTo >= 0 &&\n\t\t\t\t\t\t\tcurrentTimeStamp + nextInterval - this.firstTimeStamp > this.replayTo\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnextInterval = -1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tscheduleNext(nextInterval);\n\t\t\t\temitter(playbackOps);\n\t\t\t};\n\t\t\tconst scheduleNext = (nextInterval: number): void => {\n\t\t\t\tif (nextInterval >= 0 && current < fetchedOps.length) {\n\t\t\t\t\tsetTimeout(replayNextOps, nextInterval);\n\t\t\t\t} else {\n\t\t\t\t\tthis.replayCurrent += current;\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\t\t\tscheduleNext(ReplayControllerStatic.DelayInterval);\n\t\t});\n\t}\n}\n\nexport class ReplayDocumentDeltaConnection\n\textends TypedEventEmitter<IDocumentDeltaConnectionEvents>\n\timplements IDocumentDeltaConnection, IDisposable\n{\n\t/**\n\t * Creates a new delta connection and mimics the delta connection to replay ops on it.\n\t * @param documentService - The document service to be used to get underlying endpoints.\n\t */\n\tpublic static create(\n\t\tdocumentStorageService: IDocumentDeltaStorageService,\n\t\tcontroller: ReplayController,\n\t): IDocumentDeltaConnection {\n\t\tconst connection: IConnected = {\n\t\t\tclaims: ReplayDocumentDeltaConnection.claims,\n\t\t\tclientId: \"PseudoClientId\",\n\t\t\texisting: true,\n\t\t\tinitialMessages: [],\n\t\t\tinitialSignals: [],\n\t\t\tinitialClients: [],\n\t\t\tmaxMessageSize: ReplayDocumentDeltaConnection.ReplayMaxMessageSize,\n\t\t\tmode: \"read\",\n\t\t\tserviceConfiguration: {\n\t\t\t\tblockSize: 64436,\n\t\t\t\tmaxMessageSize: ReplayDocumentDeltaConnection.ReplayMaxMessageSize,\n\t\t\t},\n\t\t\tsupportedVersions: [ReplayDocumentDeltaConnection.replayProtocolVersion],\n\t\t\tversion: ReplayDocumentDeltaConnection.replayProtocolVersion,\n\t\t};\n\t\tconst deltaConnection = new ReplayDocumentDeltaConnection(connection);\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tdeltaConnection.fetchAndEmitOps(documentStorageService, controller);\n\n\t\treturn deltaConnection;\n\t}\n\n\tprivate static readonly replayProtocolVersion = \"^0.1.0\";\n\t// Since the replay service never actually sends messages the size below is arbitrary\n\tprivate static readonly ReplayMaxMessageSize = 16 * 1024;\n\n\tprivate static readonly claims: ITokenClaims = {\n\t\tdocumentId: ReplayDocumentId,\n\t\tscopes: [ScopeType.DocRead],\n\t\ttenantId: \"\",\n\t\tuser: {\n\t\t\tid: \"\",\n\t\t},\n\t\tiat: Math.round(Date.now() / 1000),\n\t\texp: Math.round(Date.now() / 1000) + 60 * 60, // 1 hour expiration\n\t\tver: \"1.0\",\n\t};\n\n\tpublic get clientId(): string {\n\t\treturn this.details.clientId;\n\t}\n\n\tpublic get mode(): ConnectionMode {\n\t\treturn this.details.mode;\n\t}\n\n\tpublic get claims(): ITokenClaims {\n\t\treturn this.details.claims;\n\t}\n\n\tpublic get existing(): boolean {\n\t\treturn this.details.existing;\n\t}\n\n\tpublic get version(): string {\n\t\treturn this.details.version;\n\t}\n\n\tpublic get initialMessages(): ISequencedDocumentMessage[] {\n\t\treturn this.details.initialMessages;\n\t}\n\n\tpublic get initialSignals(): ISignalMessage[] {\n\t\treturn this.details.initialSignals;\n\t}\n\n\tpublic get initialClients(): ISignalClient[] {\n\t\treturn this.details.initialClients;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration {\n\t\treturn this.details.serviceConfiguration;\n\t}\n\n\tpublic readonly maxMessageSize = ReplayDocumentDeltaConnection.ReplayMaxMessageSize;\n\n\tconstructor(public details: IConnected) {\n\t\tsuper();\n\t}\n\n\tpublic submit(documentMessage: IDocumentMessage[]): void {\n\t\t// ReplayDocumentDeltaConnection.submit() can't be called - client never sees its own join on,\n\t\t// and thus can never move to sending ops.\n\t\tthrow new Error(\"ReplayDocumentDeltaConnection.submit() can't be called\");\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async submitSignal(message: unknown): Promise<void> {}\n\n\tprivate _disposed = false;\n\tpublic get disposed(): boolean {\n\t\treturn this._disposed;\n\t}\n\tpublic dispose(): void {\n\t\tthis._disposed = true;\n\t}\n\n\t/**\n\t * This gets the specified ops from the delta storage endpoint and replays them in the replayer.\n\t */\n\tprivate async fetchAndEmitOps(\n\t\tdocumentStorageService: IDocumentDeltaStorageService,\n\t\tcontroller: ReplayController,\n\t): Promise<void> {\n\t\tlet done;\n\t\tlet replayPromiseChain = Promise.resolve();\n\n\t\tlet currentOp = await controller.getStartingOpSequence();\n\n\t\tdo {\n\t\t\tconst fetchTo = controller.fetchTo(currentOp);\n\n\t\t\tconst abortController = new AbortController();\n\t\t\tconst stream = documentStorageService.fetchMessages(\n\t\t\t\tcurrentOp + 1,\n\t\t\t\tfetchTo,\n\t\t\t\tabortController.signal,\n\t\t\t);\n\t\t\tdo {\n\t\t\t\tconst result = await stream.read();\n\n\t\t\t\tif (result.done) {\n\t\t\t\t\t// No more ops. But, they can show up later, either because document was just created,\n\t\t\t\t\t// or because another client keeps submitting new ops.\n\t\t\t\t\tdone = controller.isDoneFetch(currentOp, undefined);\n\t\t\t\t\tif (!done) {\n\t\t\t\t\t\tawait delay(2000);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treplayPromiseChain = replayPromiseChain.then(async () =>\n\t\t\t\t\tcontroller.replay((ops) => this.emit(\"op\", ReplayDocumentId, ops), messages),\n\t\t\t\t);\n\n\t\t\t\tconst messages = result.value;\n\t\t\t\tcurrentOp += messages.length;\n\t\t\t\tdone = controller.isDoneFetch(currentOp, messages[messages.length - 1].timestamp);\n\t\t\t} while (!done);\n\n\t\t\tabortController.abort();\n\t\t} while (!done);\n\t\treturn replayPromiseChain;\n\t}\n}\n"]}
|
|
@@ -15,6 +15,8 @@ const replayDocumentDeltaConnection_js_1 = require("./replayDocumentDeltaConnect
|
|
|
15
15
|
* @internal
|
|
16
16
|
*/
|
|
17
17
|
class ReplayDocumentService extends client_utils_1.TypedEventEmitter {
|
|
18
|
+
controller;
|
|
19
|
+
deltaStorage;
|
|
18
20
|
static async create(documentService, controller) {
|
|
19
21
|
const useController = await controller.initStorage(documentService);
|
|
20
22
|
if (!useController) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replayDocumentService.js","sourceRoot":"","sources":["../src/replayDocumentService.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAWjE,+EAAyE;AAEzE,yFAAmF;AAEnF;;;;;GAKG;AACH,MAAa,qBACZ,SAAQ,gCAAyC;
|
|
1
|
+
{"version":3,"file":"replayDocumentService.js","sourceRoot":"","sources":["../src/replayDocumentService.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAWjE,+EAAyE;AAEzE,yFAAmF;AAEnF;;;;;GAKG;AACH,MAAa,qBACZ,SAAQ,gCAAyC;IAoB/B;IACA;IAlBX,MAAM,CAAC,KAAK,CAAC,MAAM,CACzB,eAAiC,EACjC,UAA4B;QAE5B,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,EAAE,CAAC;YACpB,OAAO,eAAe,CAAC;QACxB,CAAC;QAED,MAAM,eAAe,GAAG,gEAA6B,CAAC,MAAM,CAC3D,MAAM,eAAe,CAAC,qBAAqB,EAAE,EAC7C,UAAU,CACV,CAAC;QACF,OAAO,IAAI,qBAAqB,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAC/D,CAAC;IAED,YACkB,UAAmC,EACnC,YAAsC;QAEvD,KAAK,EAAE,CAAC;QAHS,eAAU,GAAV,UAAU,CAAyB;QACnC,iBAAY,GAAZ,YAAY,CAA0B;IAGxD,CAAC;IAEM,OAAO,KAAU,CAAC;IAEzB,8EAA8E;IAC9E,IAAW,WAAW;QACrB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACpC,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,gBAAgB;QAC5B,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,qBAAqB;QACjC,OAAO,IAAI,sDAAwB,EAAE,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,oBAAoB,CAAC,MAAe;QAChD,OAAO,IAAI,CAAC,YAAY,CAAC;IAC1B,CAAC;CACD;AA3DD,sDA2DC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IClient } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIDocumentServiceEvents,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentDeltaConnection,\n\tIResolvedUrl,\n\tIDocumentDeltaStorageService,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { EmptyDeltaStorageService } from \"./emptyDeltaStorageService.js\";\nimport type { ReplayController } from \"./replayController.js\";\nimport { ReplayDocumentDeltaConnection } from \"./replayDocumentDeltaConnection.js\";\n\n/**\n * The Replay document service dummies out the snapshot and the delta storage.\n * Delta connection simulates the socket by fetching the ops from delta storage\n * and emitting them with a pre determined delay\n * @internal\n */\nexport class ReplayDocumentService\n\textends TypedEventEmitter<IDocumentServiceEvents>\n\timplements IDocumentService\n{\n\tpublic static async create(\n\t\tdocumentService: IDocumentService,\n\t\tcontroller: ReplayController,\n\t): Promise<IDocumentService> {\n\t\tconst useController = await controller.initStorage(documentService);\n\t\tif (!useController) {\n\t\t\treturn documentService;\n\t\t}\n\n\t\tconst deltaConnection = ReplayDocumentDeltaConnection.create(\n\t\t\tawait documentService.connectToDeltaStorage(),\n\t\t\tcontroller,\n\t\t);\n\t\treturn new ReplayDocumentService(controller, deltaConnection);\n\t}\n\n\tconstructor(\n\t\tprivate readonly controller: IDocumentStorageService,\n\t\tprivate readonly deltaStorage: IDocumentDeltaConnection,\n\t) {\n\t\tsuper();\n\t}\n\n\tpublic dispose(): void {}\n\n\t// TODO: Issue-2109 Implement detach container api or put appropriate comment.\n\tpublic get resolvedUrl(): IResolvedUrl {\n\t\tthrow new Error(\"Not implemented\");\n\t}\n\n\t/**\n\t * Connects to a storage endpoint for snapshot service and blobs.\n\t * @returns returns the dummy document storage service for replay driver.\n\t */\n\tpublic async connectToStorage(): Promise<IDocumentStorageService> {\n\t\treturn this.controller;\n\t}\n\n\t/**\n\t * Connects to a delta storage endpoint for getting ops between a range.\n\t * @returns returns the dummy document delta storage service for replay driver.\n\t */\n\tpublic async connectToDeltaStorage(): Promise<IDocumentDeltaStorageService> {\n\t\treturn new EmptyDeltaStorageService();\n\t}\n\n\t/**\n\t * Connects to a delta storage endpoint of provided documentService to get ops and then replaying\n\t * them so as to mimic a delta stream endpoint.\n\t * @param client - Client that connects to socket.\n\t * @returns returns the delta stream service which replay ops from --from to --to arguments.\n\t */\n\tpublic async connectToDeltaStream(client: IClient): Promise<IDocumentDeltaConnection> {\n\t\treturn this.deltaStorage;\n\t}\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import type { ILayerCompatDetails } from "@fluid-internal/client-utils";
|
|
5
|
+
import type { ILayerCompatDetails, ILayerCompatSupportRequirements } from "@fluid-internal/client-utils";
|
|
6
6
|
import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
7
7
|
import type { ISummaryTree } from "@fluidframework/driver-definitions";
|
|
8
8
|
import type { IDocumentService, IDocumentServiceFactory, IResolvedUrl } from "@fluidframework/driver-definitions/internal";
|
|
@@ -19,6 +19,12 @@ export declare class ReplayDocumentServiceFactory implements IDocumentServiceFac
|
|
|
19
19
|
* for validating Loader-Driver compatibility.
|
|
20
20
|
*/
|
|
21
21
|
get ILayerCompatDetails(): ILayerCompatDetails | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* The requirements that the Loader layer must meet to be compatible with this Driver. This is exposed to
|
|
24
|
+
* the Loader layer so that it can validate Loader / Driver compatibility on this Driver's behalf (the Driver has
|
|
25
|
+
* no reference to the Loader to validate it directly).
|
|
26
|
+
*/
|
|
27
|
+
get ILayerCompatSupportRequirements(): ILayerCompatSupportRequirements | undefined;
|
|
22
28
|
constructor(documentServiceFactory: IDocumentServiceFactory, controller: ReplayController);
|
|
23
29
|
/**
|
|
24
30
|
* Creates a replay document service which uses the document service of provided
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replayDocumentServiceFactory.d.ts","sourceRoot":"","sources":["../src/replayDocumentServiceFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"replayDocumentServiceFactory.d.ts","sourceRoot":"","sources":["../src/replayDocumentServiceFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,mBAAmB,EACnB,+BAA+B,EAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAe,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,KAAK,EACX,gBAAgB,EAChB,uBAAuB,EACvB,YAAY,EACZ,MAAM,6CAA6C,CAAC;AAGrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAI9D;;GAEG;AACH,qBAAa,4BAA6B,YAAW,uBAAuB;IAgC1E,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU;WAhCd,MAAM,CACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,sBAAsB,EAAE,uBAAuB,GAC7C,4BAA4B;IAO/B;;;OAGG;IACH,IAAW,mBAAmB,IAAI,mBAAmB,GAAG,SAAS,CAGhE;IAED;;;;OAIG;IACH,IAAW,+BAA+B,IAAI,+BAA+B,GAAG,SAAS,CAGxF;gBAGiB,sBAAsB,EAAE,uBAAuB,EAC/C,UAAU,EAAE,gBAAgB;IAG9C;;;;;OAKG;IACU,qBAAqB,CACjC,WAAW,EAAE,YAAY,EACzB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IAmBf,eAAe,CAC3B,gBAAgB,EAAE,YAAY,EAC9B,WAAW,EAAE,YAAY,EACzB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,gBAAgB,CAAC;CAG5B"}
|
|
@@ -12,6 +12,8 @@ const replayDocumentService_js_1 = require("./replayDocumentService.js");
|
|
|
12
12
|
* @internal
|
|
13
13
|
*/
|
|
14
14
|
class ReplayDocumentServiceFactory {
|
|
15
|
+
documentServiceFactory;
|
|
16
|
+
controller;
|
|
15
17
|
static create(from, to, documentServiceFactory) {
|
|
16
18
|
return new ReplayDocumentServiceFactory(documentServiceFactory, new replayDocumentDeltaConnection_js_1.ReplayControllerStatic(from, to));
|
|
17
19
|
}
|
|
@@ -23,6 +25,15 @@ class ReplayDocumentServiceFactory {
|
|
|
23
25
|
return this.documentServiceFactory
|
|
24
26
|
.ILayerCompatDetails;
|
|
25
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* The requirements that the Loader layer must meet to be compatible with this Driver. This is exposed to
|
|
30
|
+
* the Loader layer so that it can validate Loader / Driver compatibility on this Driver's behalf (the Driver has
|
|
31
|
+
* no reference to the Loader to validate it directly).
|
|
32
|
+
*/
|
|
33
|
+
get ILayerCompatSupportRequirements() {
|
|
34
|
+
return this.documentServiceFactory
|
|
35
|
+
.ILayerCompatSupportRequirements;
|
|
36
|
+
}
|
|
26
37
|
constructor(documentServiceFactory, controller) {
|
|
27
38
|
this.documentServiceFactory = documentServiceFactory;
|
|
28
39
|
this.controller = controller;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replayDocumentServiceFactory.js","sourceRoot":"","sources":["../src/replayDocumentServiceFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"replayDocumentServiceFactory.js","sourceRoot":"","sources":["../src/replayDocumentServiceFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAaH,uEAA6E;AAG7E,yFAA4E;AAC5E,yEAAmE;AAEnE;;GAEG;AACH,MAAa,4BAA4B;IAgCtB;IACA;IAhCX,MAAM,CAAC,MAAM,CACnB,IAAY,EACZ,EAAU,EACV,sBAA+C;QAE/C,OAAO,IAAI,4BAA4B,CACtC,sBAAsB,EACtB,IAAI,yDAAsB,CAAC,IAAI,EAAE,EAAE,CAAC,CACpC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,IAAW,mBAAmB;QAC7B,OAAQ,IAAI,CAAC,sBAA2D;aACtE,mBAAmB,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,IAAW,+BAA+B;QACzC,OAAQ,IAAI,CAAC,sBAAuE;aAClF,+BAA+B,CAAC;IACnC,CAAC;IAED,YACkB,sBAA+C,EAC/C,UAA4B;QAD5B,2BAAsB,GAAtB,sBAAsB,CAAyB;QAC/C,eAAU,GAAV,UAAU,CAAkB;IAC3C,CAAC;IAEJ;;;;;OAKG;IACI,KAAK,CAAC,qBAAqB,CACjC,WAAyB,EACzB,MAA6B,EAC7B,kBAA4B;QAE5B,iEAAiE;QACjE,wGAAwG;QACxG,MAAM,YAAY,GAAG,IAAA,4BAAiB,EAAC;YACtC,MAAM;YACN,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;SACvC,CAAC,CAAC;QAEH,OAAO,gDAAqB,CAAC,MAAM,CAClC,MAAM,IAAI,CAAC,sBAAsB,CAAC,qBAAqB,CACtD,WAAW,EACX,YAAY,EACZ,kBAAkB,CAClB,EACD,IAAI,CAAC,UAAU,CACf,CAAC;IACH,CAAC;IAED,8EAA8E;IACvE,KAAK,CAAC,eAAe,CAC3B,gBAA8B,EAC9B,WAAyB,EACzB,MAA6B,EAC7B,kBAA4B;QAE5B,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACpC,CAAC;CACD;AAzED,oEAyEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tILayerCompatDetails,\n\tILayerCompatSupportRequirements,\n} from \"@fluid-internal/client-utils\";\nimport type { FluidObject, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIDocumentService,\n\tIDocumentServiceFactory,\n\tIResolvedUrl,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { ReplayController } from \"./replayController.js\";\nimport { ReplayControllerStatic } from \"./replayDocumentDeltaConnection.js\";\nimport { ReplayDocumentService } from \"./replayDocumentService.js\";\n\n/**\n * @internal\n */\nexport class ReplayDocumentServiceFactory implements IDocumentServiceFactory {\n\tpublic static create(\n\t\tfrom: number,\n\t\tto: number,\n\t\tdocumentServiceFactory: IDocumentServiceFactory,\n\t): ReplayDocumentServiceFactory {\n\t\treturn new ReplayDocumentServiceFactory(\n\t\t\tdocumentServiceFactory,\n\t\t\tnew ReplayControllerStatic(from, to),\n\t\t);\n\t}\n\n\t/**\n\t * The compatibility details of the base Driver layer that is exposed to the Loader layer\n\t * for validating Loader-Driver compatibility.\n\t */\n\tpublic get ILayerCompatDetails(): ILayerCompatDetails | undefined {\n\t\treturn (this.documentServiceFactory as FluidObject<ILayerCompatDetails>)\n\t\t\t.ILayerCompatDetails;\n\t}\n\n\t/**\n\t * The requirements that the Loader layer must meet to be compatible with this Driver. This is exposed to\n\t * the Loader layer so that it can validate Loader / Driver compatibility on this Driver's behalf (the Driver has\n\t * no reference to the Loader to validate it directly).\n\t */\n\tpublic get ILayerCompatSupportRequirements(): ILayerCompatSupportRequirements | undefined {\n\t\treturn (this.documentServiceFactory as FluidObject<ILayerCompatSupportRequirements>)\n\t\t\t.ILayerCompatSupportRequirements;\n\t}\n\n\tpublic constructor(\n\t\tprivate readonly documentServiceFactory: IDocumentServiceFactory,\n\t\tprivate readonly controller: ReplayController,\n\t) {}\n\n\t/**\n\t * Creates a replay document service which uses the document service of provided\n\t * documentServiceFactory for connecting to delta stream endpoint.\n\t * @param resolvedUrl - URL to be used for connecting to endpoints.\n\t * @returns returns the requested document service\n\t */\n\tpublic async createDocumentService(\n\t\tresolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\t// Always include isReplay: true on events for the Replay Driver.\n\t\t// It's used in testing/debugging scenarios, so we want to be able to filter these events out sometimes.\n\t\tconst replayLogger = createChildLogger({\n\t\t\tlogger,\n\t\t\tproperties: { all: { isReplay: true } },\n\t\t});\n\n\t\treturn ReplayDocumentService.create(\n\t\t\tawait this.documentServiceFactory.createDocumentService(\n\t\t\t\tresolvedUrl,\n\t\t\t\treplayLogger,\n\t\t\t\tclientIsSummarizer,\n\t\t\t),\n\t\t\tthis.controller,\n\t\t);\n\t}\n\n\t// TODO: Issue-2109 Implement detach container api or put appropriate comment.\n\tpublic async createContainer(\n\t\tcreateNewSummary: ISummaryTree,\n\t\tresolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\tthrow new Error(\"Not implemented\");\n\t}\n}\n"]}
|
|
@@ -14,10 +14,15 @@ const replayController_js_1 = require("./replayController.js");
|
|
|
14
14
|
* @internal
|
|
15
15
|
*/
|
|
16
16
|
class FileSnapshotReader extends replayController_js_1.ReadDocumentStorageServiceBase {
|
|
17
|
+
// IVersion.treeId used to communicate between getVersions() & getSnapshotTree() calls to indicate IVersion is ours.
|
|
18
|
+
static FileStorageVersionTreeId = "FileStorageTreeId";
|
|
19
|
+
docId;
|
|
20
|
+
docTree;
|
|
21
|
+
blobs;
|
|
22
|
+
commits = {};
|
|
23
|
+
trees = {};
|
|
17
24
|
constructor(json) {
|
|
18
25
|
super();
|
|
19
|
-
this.commits = {};
|
|
20
|
-
this.trees = {};
|
|
21
26
|
this.commits = json.commits;
|
|
22
27
|
this.blobs = new Map();
|
|
23
28
|
this.docTree = (0, internal_2.buildSnapshotTree)(json.tree.entries, this.blobs);
|
|
@@ -61,12 +66,13 @@ class FileSnapshotReader extends replayController_js_1.ReadDocumentStorageServic
|
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
exports.FileSnapshotReader = FileSnapshotReader;
|
|
64
|
-
// IVersion.treeId used to communicate between getVersions() & getSnapshotTree() calls to indicate IVersion is ours.
|
|
65
|
-
FileSnapshotReader.FileStorageVersionTreeId = "FileStorageTreeId";
|
|
66
69
|
/**
|
|
67
70
|
* @internal
|
|
68
71
|
*/
|
|
69
72
|
class SnapshotStorage extends replayController_js_1.ReadDocumentStorageServiceBase {
|
|
73
|
+
storage;
|
|
74
|
+
docTree;
|
|
75
|
+
docId;
|
|
70
76
|
constructor(storage, docTree) {
|
|
71
77
|
super();
|
|
72
78
|
this.storage = storage;
|
|
@@ -94,6 +100,8 @@ class SnapshotStorage extends replayController_js_1.ReadDocumentStorageServiceBa
|
|
|
94
100
|
}
|
|
95
101
|
exports.SnapshotStorage = SnapshotStorage;
|
|
96
102
|
class StaticStorageDocumentService extends client_utils_1.TypedEventEmitter {
|
|
103
|
+
resolvedUrl;
|
|
104
|
+
storage;
|
|
97
105
|
constructor(resolvedUrl, storage) {
|
|
98
106
|
super();
|
|
99
107
|
this.resolvedUrl = resolvedUrl;
|
|
@@ -116,6 +124,7 @@ exports.StaticStorageDocumentService = StaticStorageDocumentService;
|
|
|
116
124
|
* @internal
|
|
117
125
|
*/
|
|
118
126
|
class StaticStorageDocumentServiceFactory {
|
|
127
|
+
storage;
|
|
119
128
|
constructor(storage) {
|
|
120
129
|
this.storage = storage;
|
|
121
130
|
}
|