@fluidframework/container-loader 2.0.0-internal.5.4.0 → 2.0.0-internal.6.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 (100) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/connectionManager.d.ts +1 -1
  3. package/dist/connectionManager.d.ts.map +1 -1
  4. package/dist/connectionManager.js +24 -25
  5. package/dist/connectionManager.js.map +1 -1
  6. package/dist/connectionStateHandler.d.ts +2 -1
  7. package/dist/connectionStateHandler.d.ts.map +1 -1
  8. package/dist/connectionStateHandler.js +9 -16
  9. package/dist/connectionStateHandler.js.map +1 -1
  10. package/dist/container.d.ts +10 -5
  11. package/dist/container.d.ts.map +1 -1
  12. package/dist/container.js +160 -99
  13. package/dist/container.js.map +1 -1
  14. package/dist/containerContext.d.ts +2 -12
  15. package/dist/containerContext.d.ts.map +1 -1
  16. package/dist/containerContext.js +1 -20
  17. package/dist/containerContext.js.map +1 -1
  18. package/dist/containerStorageAdapter.js +3 -5
  19. package/dist/containerStorageAdapter.js.map +1 -1
  20. package/dist/contracts.d.ts +11 -2
  21. package/dist/contracts.d.ts.map +1 -1
  22. package/dist/contracts.js +3 -3
  23. package/dist/contracts.js.map +1 -1
  24. package/dist/debugLogger.js +2 -3
  25. package/dist/debugLogger.js.map +1 -1
  26. package/dist/deltaManager.d.ts +16 -3
  27. package/dist/deltaManager.d.ts.map +1 -1
  28. package/dist/deltaManager.js +62 -24
  29. package/dist/deltaManager.js.map +1 -1
  30. package/dist/deltaQueue.js +1 -2
  31. package/dist/deltaQueue.js.map +1 -1
  32. package/dist/loader.d.ts +12 -0
  33. package/dist/loader.d.ts.map +1 -1
  34. package/dist/loader.js +57 -42
  35. package/dist/loader.js.map +1 -1
  36. package/dist/packageVersion.d.ts +1 -1
  37. package/dist/packageVersion.js +1 -1
  38. package/dist/packageVersion.js.map +1 -1
  39. package/dist/protocol.d.ts.map +1 -1
  40. package/dist/protocol.js +2 -3
  41. package/dist/protocol.js.map +1 -1
  42. package/dist/utils.d.ts +8 -1
  43. package/dist/utils.d.ts.map +1 -1
  44. package/dist/utils.js +24 -6
  45. package/dist/utils.js.map +1 -1
  46. package/lib/connectionManager.d.ts +1 -1
  47. package/lib/connectionManager.d.ts.map +1 -1
  48. package/lib/connectionManager.js +25 -26
  49. package/lib/connectionManager.js.map +1 -1
  50. package/lib/connectionStateHandler.d.ts +2 -1
  51. package/lib/connectionStateHandler.d.ts.map +1 -1
  52. package/lib/connectionStateHandler.js +9 -16
  53. package/lib/connectionStateHandler.js.map +1 -1
  54. package/lib/container.d.ts +10 -5
  55. package/lib/container.d.ts.map +1 -1
  56. package/lib/container.js +159 -98
  57. package/lib/container.js.map +1 -1
  58. package/lib/containerContext.d.ts +2 -12
  59. package/lib/containerContext.d.ts.map +1 -1
  60. package/lib/containerContext.js +1 -20
  61. package/lib/containerContext.js.map +1 -1
  62. package/lib/containerStorageAdapter.js +3 -5
  63. package/lib/containerStorageAdapter.js.map +1 -1
  64. package/lib/contracts.d.ts +11 -2
  65. package/lib/contracts.d.ts.map +1 -1
  66. package/lib/contracts.js +3 -3
  67. package/lib/contracts.js.map +1 -1
  68. package/lib/debugLogger.js +2 -3
  69. package/lib/debugLogger.js.map +1 -1
  70. package/lib/deltaManager.d.ts +16 -3
  71. package/lib/deltaManager.d.ts.map +1 -1
  72. package/lib/deltaManager.js +62 -24
  73. package/lib/deltaManager.js.map +1 -1
  74. package/lib/deltaQueue.js +1 -2
  75. package/lib/deltaQueue.js.map +1 -1
  76. package/lib/loader.d.ts +12 -0
  77. package/lib/loader.d.ts.map +1 -1
  78. package/lib/loader.js +57 -42
  79. package/lib/loader.js.map +1 -1
  80. package/lib/packageVersion.d.ts +1 -1
  81. package/lib/packageVersion.js +1 -1
  82. package/lib/packageVersion.js.map +1 -1
  83. package/lib/protocol.d.ts.map +1 -1
  84. package/lib/protocol.js +2 -3
  85. package/lib/protocol.js.map +1 -1
  86. package/lib/utils.d.ts +8 -1
  87. package/lib/utils.d.ts.map +1 -1
  88. package/lib/utils.js +22 -5
  89. package/lib/utils.js.map +1 -1
  90. package/package.json +11 -11
  91. package/src/connectionManager.ts +7 -3
  92. package/src/connectionStateHandler.ts +3 -2
  93. package/src/container.ts +113 -28
  94. package/src/containerContext.ts +0 -24
  95. package/src/contracts.ts +16 -5
  96. package/src/deltaManager.ts +22 -5
  97. package/src/loader.ts +37 -23
  98. package/src/packageVersion.ts +1 -1
  99. package/src/protocol.ts +0 -1
  100. package/src/utils.ts +29 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,86 @@
1
1
  # @fluidframework/container-loader
2
2
 
3
+ ## 2.0.0-internal.6.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Removed IContainerContext.existing [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
8
+
9
+ The recommended means of checking for existing changed to the instantiateRuntime param in 2021, and the IContainerContext.existing member was formally deprecated in 2.0.0-internal.2.0.0. This member is now removed.
10
+
11
+ - Remove closeAndGetPendingLocalState from IContainer [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
12
+
13
+ This change removes the deprecated and experimental method closeAndGetPendingLocalState from IContainer. It continues to
14
+ exist on IContainerExperimental.
15
+
16
+ IContainerExperimental is an interface that is easily casted to, which enables partners to access experimental features for testing and evaluation.
17
+ Moving the experimental method off IContainer will reduce exposure and churn on that production interface as we iterate
18
+ on and finalize our experimental features.
19
+
20
+ Experimental features should not be used in production environments.
21
+
22
+ - Loader container caching off by default [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
23
+
24
+ Loader container caching will now be off by default and the ability to control it is deprecated. Loader caching is deprecated and will be removed in a future release, as well as all caching functionality of containers. Please try not to rely on caching and inform us if you cannot do so.
25
+
26
+ If you run into trouble with this behavior, please report it ASAP to the FluidFramework team and use the following options (available in this release only) to unblock you:
27
+
28
+ - set `ILoaderProps.options.cache` to `true` when constructing a `Loader` object (see the `ILoaderOptions` interface)
29
+ - set `[LoaderHeader.cache]` header to `true` when requesting a container
30
+
31
+ - getPendingLocalState and closeAndGetPendingLocalState are now async [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
32
+
33
+ getPendingLocalState and closeAndGetPendingLocalState are now async to allow uploading blobs to attach to a DDS (in closing scenario). There is a new parameter in those methods at the container/runtime layer "notifyImminentClosure" which is true only when closing and ensures uploading blobs fast resolve and get attached. Once we apply stashed ops to new container, blob will try to reupload and we will know where to place its references.
34
+
35
+ - Upgraded typescript transpilation target to ES2020 [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
36
+
37
+ Upgraded typescript transpilation target to ES2020. This is done in order to decrease the bundle sizes of Fluid Framework packages. This has provided size improvements across the board for ex. Loader, Driver, Runtime etc. Reduced bundle sizes helps to load lesser code in apps and hence also helps to improve the perf.If any app wants to target any older versions of browsers with which this target version is not compatible, then they can use packages like babel to transpile to a older target.
38
+
39
+ - `Loader.resolve()` throws if `LoaderHeader.sequenceNumber` and `IContainerLoadMode.opsBeforeReturn` do not match [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
40
+
41
+ Calling `Loader.resolve()` will now throw an error if `LoaderHeader.sequenceNumber` is defined but `IContainerLoadMode.opsBeforeReturn` is not set to "sequenceNumber". Vice versa, `Loader.resolve()` will also throw an error if `IContainerLoadMode.opsBeforeReturn` is set to "sequenceNumber" but `LoaderHeader.sequenceNumber` is not defined.
42
+
43
+ - IDeltaManager members disposed and dispose() removed [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
44
+
45
+ IDeltaManager members disposed and dispose() were deprecated in 2.0.0-internal.5.3.0 and have now been removed.
46
+
47
+ - Request APIs deprecated on ILoader [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
48
+
49
+ The `request` API (associated with the `IFluidRouter` interface) has been deprecated on `ILoader` and `Loader`.
50
+ Please migrate all usage to using the `IContainer.request(...)` method if using a dynamic request URL, or to the `IContainer.getEntryPoint()` method if trying to obtain the application-specified root object.
51
+
52
+ **Note:** The `IContainer.request(...)` method will be deprecated in an upcoming release, so do not rely on this method for a long-term solution (the APIs around `entryPoint` and `getEntryPoint()` will become required and available for usage in its place).
53
+
54
+ After calling `ILoader.resolve(...)`, call the `request(...)` method on the returned `IContainer` with a corresponding request URL. For converting a request URL from `Loader` to `Container`, use the `IUrlResolver` passed into the `Loader`'s constructor.
55
+ The following is an example of what this change may look like:
56
+
57
+ ```
58
+ // OLD
59
+ const request: IRequest;
60
+ const urlResolver = new YourUrlResolver();
61
+ const loader = new Loader({ urlResolver, ... });
62
+
63
+ await loader.resolve(request);
64
+ const response = loader.request(request);
65
+ ```
66
+
67
+ ```
68
+ // NEW
69
+ const request: IRequest;
70
+ const urlResolver = new YourUrlResolver();
71
+ const loader = new Loader({ urlResolver, ... });
72
+
73
+ const container = await loader.resolve(request);
74
+ const resolvedUrl: IRequest = urlResolver.resolve(request);
75
+
76
+ // Parse the `resolvedUrl.url` property as necessary before passing to `container.request(...)`
77
+ // For an example, see the `Loader.resolveCore(...)` method
78
+ const parsedResolvedUrl = // implement parse logic here
79
+ const response = container.request(parsedResolvedUrl);
80
+ ```
81
+
82
+ Status on removal of the request pattern is tracked in [Removing-IFluidRouter.md](https://github.com/microsoft/FluidFramework/blob/main/packages/common/core-interfaces/Removing-IFluidRouter.md)
83
+
3
84
  ## 2.0.0-internal.5.4.0
4
85
 
5
86
  Dependency updates only.
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ITelemetryProperties } from "@fluidframework/core-interfaces";
6
- import { IDeltaQueue, ReadOnlyInfo, ICriticalContainerError } from "@fluidframework/container-definitions";
6
+ import { ICriticalContainerError, IDeltaQueue, ReadOnlyInfo } from "@fluidframework/container-definitions";
7
7
  import { IDocumentService } from "@fluidframework/driver-definitions";
8
8
  import { ConnectionMode, IClient, IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
9
9
  import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
@@ -1 +1 @@
1
- {"version":3,"file":"connectionManager.d.ts","sourceRoot":"","sources":["../src/connectionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connectionManager.d.ts","sourceRoot":"","sources":["../src/connectionManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAe,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEpF,OAAO,EACN,uBAAuB,EACvB,WAAW,EACX,YAAY,EACZ,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAEN,gBAAgB,EAGhB,MAAM,oCAAoC,CAAC;AAU5C,OAAO,EACN,cAAc,EACd,OAAO,EACP,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAGhB,yBAAyB,EAOzB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAA8B,MAAM,iCAAiC,CAAC;AAClG,OAAO,EACN,aAAa,EACb,kBAAkB,EAClB,6BAA6B,EAE7B,MAAM,aAAa,CAAC;AAwHrB;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAoL1D,OAAO,CAAC,QAAQ,CAAC,eAAe;aAChB,cAAc,EAAE,MAAM,OAAO;IAC7C,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAxLvB,qEAAqE;IACrE,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAiB;IAEzD;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,UAAU,CAAuC;IAEzD,kEAAkE;IAClE,OAAO,CAAC,oBAAoB,CAAsB;IAElD,4CAA4C;IAC5C,OAAO,CAAC,cAAc,CAAS;IAE/B;;OAEG;IACH,OAAO,CAAC,cAAc,CAAgB;IAEtC,2EAA2E;IAC3E,OAAO,CAAC,gBAAgB,CAAS;IAEjC,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,4BAA4B,CAAK;IACzC,sFAAsF;IACtF,OAAO,CAAC,gBAAgB,CAAK;IAE7B,yDAAyD;IACzD,OAAO,CAAC,qBAAqB,CAAqB;IAElD,OAAO,CAAC,sBAAsB,CAAQ;IAEtC,OAAO,CAAC,uBAAuB,CAAuC;IAEtE,OAAO,CAAC,gBAAgB,CAA4B;IAEpD,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAE3D,IAAW,sBAAsB,oCAEhC;IAED,SAAgB,aAAa,EAAE,cAAc,CAAC;IAE9C;;OAEG;IACH,IAAW,cAAc,IAAI,cAAc,CAE1C;IAED,IAAW,SAAS,YAEnB;IAED,IAAW,QAAQ,uBAElB;IACD;;;OAGG;IACH,IAAW,aAAa,IAAI,aAAa,CAExC;IAED,IAAW,cAAc,IAAI,MAAM,CAElC;IAED,IAAW,OAAO,IAAI,MAAM,CAK3B;IAED,IAAW,oBAAoB,IAAI,oBAAoB,GAAG,SAAS,CAElE;IAED,IAAW,MAAM,IAAI,MAAM,EAAE,GAAG,SAAS,CAExC;IAED,IAAW,QAAQ,IAAI,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAErD;IAED;;;OAGG;IACH,IAAW,eAAe,IAAI,oBAAoB,CAQjD;IAEM,eAAe,IAAI,OAAO;IAmBjC;;;;;;;;OAQG;IACH,OAAO,KAAK,QAAQ,GAEnB;IAED,IAAW,YAAY,IAAI,YAAY,CAkBtC;IAED,OAAO,CAAC,MAAM,CAAC,qBAAqB;gBAmBlB,eAAe,EAAE,MAAM,gBAAgB,GAAG,SAAS,EACpD,cAAc,EAAE,MAAM,OAAO,EACrC,MAAM,EAAE,OAAO,EACvB,gBAAgB,EAAE,OAAO,EACR,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,6BAA6B;IAoB/C,OAAO,CAAC,KAAK,CAAC,EAAE,uBAAuB,EAAE,gBAAgB,GAAE,OAAc;IAwBhF;;;OAGG;IACI,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAclD;;;;;;;;;;;;;;;;OAgBG;IACI,aAAa,CAAC,QAAQ,EAAE,OAAO;IAoCtC,OAAO,CAAC,uBAAuB;IAQxB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,cAAc;YAOhD,WAAW;IA2KzB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IActB;;;;;OAKG;IACH,OAAO,CAAC,yBAAyB;IAwCjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;OAIG;IACH,OAAO,CAAC,4BAA4B;IA+IpC;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;;;;;OAMG;YACW,SAAS;IA2DhB,oBAAoB,CAC1B,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,GACrD,gBAAgB,GAAG,SAAS;IAuCxB,YAAY,CAAC,OAAO,EAAE,GAAG;IAQzB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE;IA+BzC,0BAA0B,CAAC,OAAO,EAAE,yBAAyB;IAgDpE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAGxB;IAGF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAkB1B;IAGF,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAIxC;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAE3B;CACF"}
@@ -84,9 +84,8 @@ function isNoDeltaStreamConnection(connection) {
84
84
  return connection instanceof NoDeltaStream;
85
85
  }
86
86
  const waitForOnline = async () => {
87
- var _a;
88
87
  // Only wait if we have a strong signal that we're offline - otherwise assume we're online.
89
- if (((_a = globalThis.navigator) === null || _a === void 0 ? void 0 : _a.onLine) === false && globalThis.addEventListener !== undefined) {
88
+ if (globalThis.navigator?.onLine === false && globalThis.addEventListener !== undefined) {
90
89
  return new Promise((resolve) => {
91
90
  const resolveAndRemoveListener = () => {
92
91
  resolve();
@@ -170,15 +169,13 @@ class ConnectionManager {
170
169
  * The current connection mode, initially read.
171
170
  */
172
171
  get connectionMode() {
173
- var _a, _b;
174
- return (_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : "read";
172
+ return this.connection?.mode ?? "read";
175
173
  }
176
174
  get connected() {
177
175
  return this.connection !== undefined;
178
176
  }
179
177
  get clientId() {
180
- var _a;
181
- return (_a = this.connection) === null || _a === void 0 ? void 0 : _a.clientId;
178
+ return this.connection?.clientId;
182
179
  }
183
180
  /**
184
181
  * Automatic reconnecting enabled or disabled.
@@ -188,8 +185,7 @@ class ConnectionManager {
188
185
  return this._reconnectMode;
189
186
  }
190
187
  get maxMessageSize() {
191
- var _a, _b, _c;
192
- return (_c = (_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.serviceConfiguration) === null || _b === void 0 ? void 0 : _b.maxMessageSize) !== null && _c !== void 0 ? _c : DefaultChunkSize;
188
+ return this.connection?.serviceConfiguration?.maxMessageSize ?? DefaultChunkSize;
193
189
  }
194
190
  get version() {
195
191
  if (this.connection === undefined) {
@@ -198,12 +194,10 @@ class ConnectionManager {
198
194
  return this.connection.version;
199
195
  }
200
196
  get serviceConfiguration() {
201
- var _a;
202
- return (_a = this.connection) === null || _a === void 0 ? void 0 : _a.serviceConfiguration;
197
+ return this.connection?.serviceConfiguration;
203
198
  }
204
199
  get scopes() {
205
- var _a;
206
- return (_a = this.connection) === null || _a === void 0 ? void 0 : _a.claims.scopes;
200
+ return this.connection?.claims.scopes;
207
201
  }
208
202
  get outbound() {
209
203
  return this._outbound;
@@ -215,9 +209,11 @@ class ConnectionManager {
215
209
  get connectionProps() {
216
210
  return this.connection !== undefined
217
211
  ? this._connectionProps
218
- : Object.assign(Object.assign({}, this._connectionProps), {
212
+ : {
213
+ ...this._connectionProps,
219
214
  // Report how many ops this client sent in last disconnected session
220
- sentOps: this.clientSequenceNumber });
215
+ sentOps: this.clientSequenceNumber,
216
+ };
221
217
  }
222
218
  shouldJoinWrite() {
223
219
  // We don't have to wait for ack for topmost NoOps. So subtract those.
@@ -372,7 +368,6 @@ class ConnectionManager {
372
368
  });
373
369
  }
374
370
  async connectCore(reason, connectionMode) {
375
- var _a, _b, _c;
376
371
  (0, common_utils_1.assert)(!this._disposed, 0x26a /* "not closed" */);
377
372
  if (this.connection !== undefined) {
378
373
  return; // Connection attempt already completed successfully
@@ -384,7 +379,7 @@ class ConnectionManager {
384
379
  (0, common_utils_1.assert)(this.pendingConnection === undefined, 0x344 /* this.pendingConnection should be undefined */);
385
380
  }
386
381
  // If there is no specified ConnectionMode, try the previous mode, if there is no previous mode use default
387
- let requestedMode = (_a = connectionMode !== null && connectionMode !== void 0 ? connectionMode : pendingConnectionMode) !== null && _a !== void 0 ? _a : this.defaultReconnectionMode;
382
+ let requestedMode = connectionMode ?? pendingConnectionMode ?? this.defaultReconnectionMode;
388
383
  // if we have any non-acked ops from last connection, reconnect as "write".
389
384
  // without that we would connect in view-only mode, which will result in immediate
390
385
  // firing of "connected" event from Container and switch of current clientId (as tracked
@@ -396,7 +391,7 @@ class ConnectionManager {
396
391
  const docService = this.serviceProvider();
397
392
  (0, common_utils_1.assert)(docService !== undefined, 0x2a7 /* "Container is not attached" */);
398
393
  let connection;
399
- if (((_b = docService.policies) === null || _b === void 0 ? void 0 : _b.storageOnly) === true) {
394
+ if (docService.policies?.storageOnly === true) {
400
395
  connection = new NoDeltaStream();
401
396
  this.setupNewSuccessfulConnection(connection, "read", reason);
402
397
  (0, common_utils_1.assert)(this.pendingConnection === undefined, 0x2b3 /* "logic error" */);
@@ -432,7 +427,10 @@ class ConnectionManager {
432
427
  connectRepeatCount++;
433
428
  try {
434
429
  this.client.mode = requestedMode;
435
- connection = await docService.connectToDeltaStream(Object.assign(Object.assign({}, this.client), { mode: requestedMode }));
430
+ connection = await docService.connectToDeltaStream({
431
+ ...this.client,
432
+ mode: requestedMode,
433
+ });
436
434
  if (connection.disposed) {
437
435
  // Nobody observed this connection, so drop it on the floor and retry.
438
436
  this.logger.sendTelemetryEvent({ eventName: "ReceivedClosedConnection" });
@@ -468,7 +466,7 @@ class ConnectionManager {
468
466
  setTimeout(resolve, retryDelayFromError);
469
467
  });
470
468
  }
471
- else if (((_c = globalThis.navigator) === null || _c === void 0 ? void 0 : _c.onLine) !== false) {
469
+ else if (globalThis.navigator?.onLine !== false) {
472
470
  // If the error didn't tell us to wait, let's still wait a little bit before retrying.
473
471
  // We skip this delay if we're confident we're offline, because we probably just need to wait to come back online.
474
472
  await new Promise((resolve) => {
@@ -578,7 +576,6 @@ class ConnectionManager {
578
576
  * @param connection - The newly established connection
579
577
  */
580
578
  setupNewSuccessfulConnection(connection, requestedMode, reason) {
581
- var _a;
582
579
  // Old connection should have been cleaned up before establishing a new one
583
580
  (0, common_utils_1.assert)(this.connection === undefined, 0x0e6 /* "old connection exists on new connection setup" */);
584
581
  (0, common_utils_1.assert)(!connection.disposed, 0x28a /* "can't be disposed - Callers need to ensure that!" */);
@@ -659,7 +656,7 @@ class ConnectionManager {
659
656
  }),
660
657
  };
661
658
  this.props.signalHandler(clearSignal);
662
- for (const priorClient of (_a = connection.initialClients) !== null && _a !== void 0 ? _a : []) {
659
+ for (const priorClient of connection.initialClients ?? []) {
663
660
  const joinSignal = {
664
661
  clientId: null,
665
662
  content: JSON.stringify({
@@ -738,7 +735,6 @@ class ConnectionManager {
738
735
  : `Reconnecting due to: ${disconnectMessage}`, requestedMode);
739
736
  }
740
737
  prepareMessageToSend(message) {
741
- var _a, _b;
742
738
  if (this.readonly === true) {
743
739
  (0, common_utils_1.assert)(this.readOnlyInfo.readonly === true, 0x1f0 /* "Unexpected mismatch in readonly" */);
744
740
  const error = new container_utils_1.GenericError("deltaManagerReadonlySubmit", undefined /* error */, {
@@ -755,8 +751,8 @@ class ConnectionManager {
755
751
  // we keep info about old connection as long as possible to be able to account for all non-acked ops
756
752
  // that we pick up on next connection.
757
753
  (0, common_utils_1.assert)(!!this.connection, 0x0e4 /* "Lost old connection!" */);
758
- if (this.lastSubmittedClientId !== ((_a = this.connection) === null || _a === void 0 ? void 0 : _a.clientId)) {
759
- this.lastSubmittedClientId = (_b = this.connection) === null || _b === void 0 ? void 0 : _b.clientId;
754
+ if (this.lastSubmittedClientId !== this.connection?.clientId) {
755
+ this.lastSubmittedClientId = this.connection?.clientId;
760
756
  this.clientSequenceNumber = 0;
761
757
  this.clientSequenceNumberObserved = 0;
762
758
  }
@@ -766,7 +762,10 @@ class ConnectionManager {
766
762
  else {
767
763
  this.localOpsToIgnore = 0;
768
764
  }
769
- return Object.assign(Object.assign({}, message), { clientSequenceNumber: ++this.clientSequenceNumber });
765
+ return {
766
+ ...message,
767
+ clientSequenceNumber: ++this.clientSequenceNumber,
768
+ };
770
769
  }
771
770
  submitSignal(content) {
772
771
  if (this.connection !== undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"connectionManager.js","sourceRoot":"","sources":["../src/connectionManager.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 { IDisposable, ITelemetryProperties } from \"@fluidframework/core-interfaces\";\nimport { assert, performance, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n\tIDeltaQueue,\n\tReadOnlyInfo,\n\tIConnectionDetailsInternal,\n\tICriticalContainerError,\n} from \"@fluidframework/container-definitions\";\nimport { GenericError, UsageError } from \"@fluidframework/container-utils\";\nimport {\n\tIAnyDriverError,\n\tIDocumentService,\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport {\n\tcanRetryOnError,\n\tcreateWriteError,\n\tcreateGenericNetworkError,\n\tgetRetryDelayFromError,\n\tlogNetworkFailure,\n\tisRuntimeMessage,\n\tcalculateMaxWaitTime,\n} from \"@fluidframework/driver-utils\";\nimport {\n\tConnectionMode,\n\tIClient,\n\tIClientConfiguration,\n\tIClientDetails,\n\tIDocumentMessage,\n\tINack,\n\tINackContent,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tITokenClaims,\n\tMessageType,\n\tScopeType,\n\tISequencedDocumentSystemMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLoggerExt, formatTick, normalizeError } from \"@fluidframework/telemetry-utils\";\nimport { ReconnectMode, IConnectionManager, IConnectionManagerFactoryArgs } from \"./contracts\";\nimport { DeltaQueue } from \"./deltaQueue\";\nimport { SignalType } from \"./protocol\";\nimport { isDeltaStreamConnectionForbiddenError } from \"./utils\";\n\nconst InitialReconnectDelayInMs = 1000;\nconst DefaultChunkSize = 16 * 1024;\n\nconst fatalConnectErrorProp = { fatalConnectError: true };\n\nfunction getNackReconnectInfo(nackContent: INackContent) {\n\tconst message = `Nack (${nackContent.type}): ${nackContent.message}`;\n\tconst canRetry = nackContent.code !== 403;\n\tconst retryAfterMs =\n\t\tnackContent.retryAfter !== undefined ? nackContent.retryAfter * 1000 : undefined;\n\treturn createGenericNetworkError(\n\t\tmessage,\n\t\t{ canRetry, retryAfterMs },\n\t\t{ statusCode: nackContent.code, driverVersion: undefined },\n\t);\n}\n\n/**\n * Implementation of IDocumentDeltaConnection that does not support submitting\n * or receiving ops. Used in storage-only mode.\n */\nconst clientNoDeltaStream: IClient = {\n\tmode: \"read\",\n\tdetails: { capabilities: { interactive: true } },\n\tpermission: [],\n\tuser: { id: \"storage-only client\" }, // we need some \"fake\" ID here.\n\tscopes: [],\n};\nconst clientIdNoDeltaStream: string = \"storage-only client\";\n\nclass NoDeltaStream\n\textends TypedEventEmitter<IDocumentDeltaConnectionEvents>\n\timplements IDocumentDeltaConnection, IDisposable\n{\n\tclientId = clientIdNoDeltaStream;\n\tclaims: ITokenClaims = {\n\t\tscopes: [ScopeType.DocRead],\n\t} as any;\n\tmode: ConnectionMode = \"read\";\n\texisting: boolean = true;\n\tmaxMessageSize: number = 0;\n\tversion: string = \"\";\n\tinitialMessages: ISequencedDocumentMessage[] = [];\n\tinitialSignals: ISignalMessage[] = [];\n\tinitialClients: ISignalClient[] = [\n\t\t{ client: clientNoDeltaStream, clientId: clientIdNoDeltaStream },\n\t];\n\tserviceConfiguration: IClientConfiguration = {\n\t\tmaxMessageSize: 0,\n\t\tblockSize: 0,\n\t};\n\tcheckpointSequenceNumber?: number | undefined = undefined;\n\tconstructor(public readonly storageOnlyReason?: string) {\n\t\tsuper();\n\t}\n\tsubmit(messages: IDocumentMessage[]): void {\n\t\tthis.emit(\n\t\t\t\"nack\",\n\t\t\tthis.clientId,\n\t\t\tmessages.map((operation) => {\n\t\t\t\treturn {\n\t\t\t\t\toperation,\n\t\t\t\t\tcontent: { message: \"Cannot submit with storage-only connection\", code: 403 },\n\t\t\t\t};\n\t\t\t}),\n\t\t);\n\t}\n\tsubmitSignal(message: any): void {\n\t\tthis.emit(\"nack\", this.clientId, {\n\t\t\toperation: message,\n\t\t\tcontent: { message: \"Cannot submit signal with storage-only connection\", code: 403 },\n\t\t});\n\t}\n\n\tprivate _disposed = false;\n\tpublic get disposed() {\n\t\treturn this._disposed;\n\t}\n\tpublic dispose() {\n\t\tthis._disposed = true;\n\t}\n}\n\nfunction isNoDeltaStreamConnection(connection: any): connection is NoDeltaStream {\n\treturn connection instanceof NoDeltaStream;\n}\n\nconst waitForOnline = async (): Promise<void> => {\n\t// Only wait if we have a strong signal that we're offline - otherwise assume we're online.\n\tif (globalThis.navigator?.onLine === false && globalThis.addEventListener !== undefined) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst resolveAndRemoveListener = () => {\n\t\t\t\tresolve();\n\t\t\t\tglobalThis.removeEventListener(\"online\", resolveAndRemoveListener);\n\t\t\t};\n\t\t\tglobalThis.addEventListener(\"online\", resolveAndRemoveListener);\n\t\t});\n\t}\n};\n\n/**\n * Interface to track the current in-progress connection attempt.\n */\ninterface IPendingConnection {\n\t/**\n\t * Used to cancel an in-progress connection attempt.\n\t */\n\tabort(): void;\n\n\t/**\n\t * Desired ConnectionMode of this in-progress connection attempt.\n\t */\n\tconnectionMode: ConnectionMode;\n}\n\n/**\n * Implementation of IConnectionManager, used by Container class\n * Implements constant connectivity to relay service, by reconnecting in case of lost connection or error.\n * Exposes various controls to influence this process, including manual reconnects, forced read-only mode, etc.\n */\nexport class ConnectionManager implements IConnectionManager {\n\t/** Connection mode used when reconnecting on error or disconnect. */\n\tprivate readonly defaultReconnectionMode: ConnectionMode;\n\n\t/**\n\t * Tracks the current in-progress connection attempt. Undefined if there is none.\n\t * Note: Once the connection attempt fires and the code becomes asynchronous, its possible that a new connection\n\t * attempt was fired and this.pendingConnection was overwritten to reflect the new attempt.\n\t */\n\tprivate pendingConnection: IPendingConnection | undefined;\n\tprivate connection: IDocumentDeltaConnection | undefined;\n\n\t/** file ACL - whether user has only read-only access to a file */\n\tprivate _readonlyPermissions: boolean | undefined;\n\n\t/** tracks host requiring read-only mode. */\n\tprivate _forceReadonly = false;\n\n\t/**\n\t * Controls whether the DeltaManager will automatically reconnect to the delta stream after receiving a disconnect.\n\t */\n\tprivate _reconnectMode: ReconnectMode;\n\n\t/** True if there is pending (async) reconnection from \"read\" to \"write\" */\n\tprivate pendingReconnect = false;\n\n\tprivate clientSequenceNumber = 0;\n\tprivate clientSequenceNumberObserved = 0;\n\t/** Counts the number of non-runtime ops sent by the client which may not be acked. */\n\tprivate localOpsToIgnore = 0;\n\n\t/** track clientId used last time when we sent any ops */\n\tprivate lastSubmittedClientId: string | undefined;\n\n\tprivate connectFirstConnection = true;\n\n\tprivate _connectionVerboseProps: Record<string, string | number> = {};\n\n\tprivate _connectionProps: ITelemetryProperties = {};\n\n\tprivate _disposed = false;\n\n\tprivate readonly _outbound: DeltaQueue<IDocumentMessage[]>;\n\n\tpublic get connectionVerboseProps() {\n\t\treturn this._connectionVerboseProps;\n\t}\n\n\tpublic readonly clientDetails: IClientDetails;\n\n\t/**\n\t * The current connection mode, initially read.\n\t */\n\tpublic get connectionMode(): ConnectionMode {\n\t\treturn this.connection?.mode ?? \"read\";\n\t}\n\n\tpublic get connected() {\n\t\treturn this.connection !== undefined;\n\t}\n\n\tpublic get clientId() {\n\t\treturn this.connection?.clientId;\n\t}\n\t/**\n\t * Automatic reconnecting enabled or disabled.\n\t * If set to Never, then reconnecting will never be allowed.\n\t */\n\tpublic get reconnectMode(): ReconnectMode {\n\t\treturn this._reconnectMode;\n\t}\n\n\tpublic get maxMessageSize(): number {\n\t\treturn this.connection?.serviceConfiguration?.maxMessageSize ?? DefaultChunkSize;\n\t}\n\n\tpublic get version(): string {\n\t\tif (this.connection === undefined) {\n\t\t\tthrow new Error(\"Cannot check version without a connection\");\n\t\t}\n\t\treturn this.connection.version;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration | undefined {\n\t\treturn this.connection?.serviceConfiguration;\n\t}\n\n\tpublic get scopes(): string[] | undefined {\n\t\treturn this.connection?.claims.scopes;\n\t}\n\n\tpublic get outbound(): IDeltaQueue<IDocumentMessage[]> {\n\t\treturn this._outbound;\n\t}\n\n\t/**\n\t * Returns set of props that can be logged in telemetry that provide some insights / statistics\n\t * about current or last connection (if there is no connection at the moment)\n\t */\n\tpublic get connectionProps(): ITelemetryProperties {\n\t\treturn this.connection !== undefined\n\t\t\t? this._connectionProps\n\t\t\t: {\n\t\t\t\t\t...this._connectionProps,\n\t\t\t\t\t// Report how many ops this client sent in last disconnected session\n\t\t\t\t\tsentOps: this.clientSequenceNumber,\n\t\t\t };\n\t}\n\n\tpublic shouldJoinWrite(): boolean {\n\t\t// We don't have to wait for ack for topmost NoOps. So subtract those.\n\t\tconst outstandingOps =\n\t\t\tthis.clientSequenceNumberObserved < this.clientSequenceNumber - this.localOpsToIgnore;\n\n\t\t// Previous behavior was to force write mode here only when there are outstanding ops (besides\n\t\t// no-ops). The dirty signal from runtime should provide the same behavior, but also support\n\t\t// stashed ops that weren't submitted to container layer yet. For safety, we want to retain the\n\t\t// same behavior whenever dirty is false.\n\t\tconst isDirty = this.containerDirty();\n\t\tif (outstandingOps !== isDirty) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"DesiredConnectionModeMismatch\",\n\t\t\t\tdetails: JSON.stringify({ outstandingOps, isDirty }),\n\t\t\t});\n\t\t}\n\t\treturn outstandingOps || isDirty;\n\t}\n\n\t/**\n\t * Tells if container is in read-only mode.\n\t * Data stores should listen for \"readonly\" notifications and disallow user\n\t * making changes to data stores.\n\t * Readonly state can be because of no storage write permission,\n\t * or due to host forcing readonly mode for container.\n\t * It is undefined if we have not yet established websocket connection\n\t * and do not know if user has write access to a file.\n\t */\n\tprivate get readonly(): boolean | undefined {\n\t\treturn this.readOnlyInfo.readonly;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\tlet storageOnly: boolean = false;\n\t\tlet storageOnlyReason: string | undefined;\n\t\tif (isNoDeltaStreamConnection(this.connection)) {\n\t\t\tstorageOnly = true;\n\t\t\tstorageOnlyReason = this.connection.storageOnlyReason;\n\t\t}\n\t\tif (storageOnly || this._forceReadonly || this._readonlyPermissions === true) {\n\t\t\treturn {\n\t\t\t\treadonly: true,\n\t\t\t\tforced: this._forceReadonly,\n\t\t\t\tpermissions: this._readonlyPermissions,\n\t\t\t\tstorageOnly,\n\t\t\t\tstorageOnlyReason,\n\t\t\t};\n\t\t}\n\n\t\treturn { readonly: this._readonlyPermissions };\n\t}\n\n\tprivate static detailsFromConnection(\n\t\tconnection: IDocumentDeltaConnection,\n\t\treason: string,\n\t): IConnectionDetailsInternal {\n\t\treturn {\n\t\t\tclaims: connection.claims,\n\t\t\tclientId: connection.clientId,\n\t\t\tcheckpointSequenceNumber: connection.checkpointSequenceNumber,\n\t\t\tget initialClients() {\n\t\t\t\treturn connection.initialClients;\n\t\t\t},\n\t\t\tmode: connection.mode,\n\t\t\tserviceConfiguration: connection.serviceConfiguration,\n\t\t\tversion: connection.version,\n\t\t\treason,\n\t\t};\n\t}\n\n\tconstructor(\n\t\tprivate readonly serviceProvider: () => IDocumentService | undefined,\n\t\tpublic readonly containerDirty: () => boolean,\n\t\tprivate client: IClient,\n\t\treconnectAllowed: boolean,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate readonly props: IConnectionManagerFactoryArgs,\n\t) {\n\t\tthis.clientDetails = this.client.details;\n\t\tthis.defaultReconnectionMode = this.client.mode;\n\t\tthis._reconnectMode = reconnectAllowed ? ReconnectMode.Enabled : ReconnectMode.Never;\n\n\t\t// Outbound message queue. The outbound queue is represented as a queue of an array of ops. Ops contained\n\t\t// within an array *must* fit within the maxMessageSize and are guaranteed to be ordered sequentially.\n\t\tthis._outbound = new DeltaQueue<IDocumentMessage[]>((messages) => {\n\t\t\tif (this.connection === undefined) {\n\t\t\t\tthrow new Error(\"Attempted to submit an outbound message without connection\");\n\t\t\t}\n\t\t\tthis.connection.submit(messages);\n\t\t});\n\n\t\tthis._outbound.on(\"error\", (error) => {\n\t\t\tthis.props.closeHandler(normalizeError(error));\n\t\t});\n\t}\n\n\tpublic dispose(error?: ICriticalContainerError, switchToReadonly: boolean = true) {\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis._disposed = true;\n\n\t\t// Ensure that things like triggerConnect() will short circuit\n\t\tthis._reconnectMode = ReconnectMode.Never;\n\n\t\tthis._outbound.clear();\n\n\t\tconst disconnectReason = \"Closing DeltaManager\";\n\n\t\t// This raises \"disconnect\" event if we have active connection.\n\t\tthis.disconnectFromDeltaStream(disconnectReason);\n\n\t\tif (switchToReadonly) {\n\t\t\t// Notify everyone we are in read-only state.\n\t\t\t// Useful for data stores in case we hit some critical error,\n\t\t\t// to switch to a mode where user edits are not accepted\n\t\t\tthis.set_readonlyPermissions(true);\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables automatic reconnecting.\n\t * Will throw an error if reconnectMode set to Never.\n\t */\n\tpublic setAutoReconnect(mode: ReconnectMode): void {\n\t\tassert(\n\t\t\tmode !== ReconnectMode.Never && this._reconnectMode !== ReconnectMode.Never,\n\t\t\t0x278 /* \"API is not supported for non-connecting or closed container\" */,\n\t\t);\n\n\t\tthis._reconnectMode = mode;\n\n\t\tif (mode !== ReconnectMode.Enabled) {\n\t\t\t// immediately disconnect - do not rely on service eventually dropping connection.\n\t\t\tthis.disconnectFromDeltaStream(\"setAutoReconnect\");\n\t\t}\n\t}\n\n\t/**\n\t * Sends signal to runtime (and data stores) to be read-only.\n\t * Hosts may have read only views, indicating to data stores that no edits are allowed.\n\t * This is independent from this._readonlyPermissions (permissions) and this.connectionMode\n\t * (server can return \"write\" mode even when asked for \"read\")\n\t * Leveraging same \"readonly\" event as runtime & data stores should behave the same in such case\n\t * as in read-only permissions.\n\t * But this.active can be used by some DDSes to figure out if ops can be sent\n\t * (for example, read-only view still participates in code proposals / upgrades decisions)\n\t *\n\t * Forcing Readonly does not prevent DDS from generating ops. It is up to user code to honour\n\t * the readonly flag. If ops are generated, they will accumulate locally and not be sent. If\n\t * there are pending in the outbound queue, it will stop sending until force readonly is\n\t * cleared.\n\t *\n\t * @param readonly - set or clear force readonly.\n\t */\n\tpublic forceReadonly(readonly: boolean) {\n\t\tif (readonly !== this._forceReadonly) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"ForceReadOnly\",\n\t\t\t\tvalue: readonly,\n\t\t\t});\n\t\t}\n\t\tconst oldValue = this.readonly;\n\t\tthis._forceReadonly = readonly;\n\n\t\tif (oldValue !== this.readonly) {\n\t\t\tif (this._reconnectMode === ReconnectMode.Never) {\n\t\t\t\tthrow new UsageError(\"API is not supported for non-connecting or closed container\");\n\t\t\t}\n\t\t\tlet reconnect = false;\n\t\t\tif (this.readonly === true) {\n\t\t\t\t// If we switch to readonly while connected, we should disconnect first\n\t\t\t\t// See comment in the \"readonly\" event handler to deltaManager set up by\n\t\t\t\t// the ContainerRuntime constructor\n\n\t\t\t\tif (this.shouldJoinWrite()) {\n\t\t\t\t\t// If we have pending changes, then we will never send them - it smells like\n\t\t\t\t\t// host logic error.\n\t\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"ForceReadonlyPendingChanged\" });\n\t\t\t\t}\n\n\t\t\t\treconnect = this.disconnectFromDeltaStream(\"Force readonly\");\n\t\t\t}\n\t\t\tthis.props.readonlyChangeHandler(this.readonly);\n\t\t\tif (reconnect) {\n\t\t\t\t// reconnect if we disconnected from before.\n\t\t\t\tthis.triggerConnect(\"Force Readonly\", \"read\");\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate set_readonlyPermissions(readonly: boolean) {\n\t\tconst oldValue = this.readonly;\n\t\tthis._readonlyPermissions = readonly;\n\t\tif (oldValue !== this.readonly) {\n\t\t\tthis.props.readonlyChangeHandler(this.readonly);\n\t\t}\n\t}\n\n\tpublic connect(reason: string, connectionMode?: ConnectionMode) {\n\t\tthis.connectCore(reason, connectionMode).catch((error) => {\n\t\t\tconst normalizedError = normalizeError(error, { props: fatalConnectErrorProp });\n\t\t\tthis.props.closeHandler(normalizedError);\n\t\t});\n\t}\n\n\tprivate async connectCore(reason: string, connectionMode?: ConnectionMode): Promise<void> {\n\t\tassert(!this._disposed, 0x26a /* \"not closed\" */);\n\n\t\tif (this.connection !== undefined) {\n\t\t\treturn; // Connection attempt already completed successfully\n\t\t}\n\n\t\tlet pendingConnectionMode;\n\t\tif (this.pendingConnection !== undefined) {\n\t\t\tpendingConnectionMode = this.pendingConnection.connectionMode;\n\t\t\tthis.cancelConnection(reason); // Throw out in-progress connection attempt in favor of new attempt\n\t\t\tassert(\n\t\t\t\tthis.pendingConnection === undefined,\n\t\t\t\t0x344 /* this.pendingConnection should be undefined */,\n\t\t\t);\n\t\t}\n\t\t// If there is no specified ConnectionMode, try the previous mode, if there is no previous mode use default\n\t\tlet requestedMode = connectionMode ?? pendingConnectionMode ?? this.defaultReconnectionMode;\n\n\t\t// if we have any non-acked ops from last connection, reconnect as \"write\".\n\t\t// without that we would connect in view-only mode, which will result in immediate\n\t\t// firing of \"connected\" event from Container and switch of current clientId (as tracked\n\t\t// by all DDSes). This will make it impossible to figure out if ops actually made it through,\n\t\t// so DDSes will immediately resubmit all pending ops, and some of them will be duplicates, corrupting document\n\t\tif (this.shouldJoinWrite()) {\n\t\t\trequestedMode = \"write\";\n\t\t}\n\n\t\tconst docService = this.serviceProvider();\n\t\tassert(docService !== undefined, 0x2a7 /* \"Container is not attached\" */);\n\n\t\tlet connection: IDocumentDeltaConnection | undefined;\n\n\t\tif (docService.policies?.storageOnly === true) {\n\t\t\tconnection = new NoDeltaStream();\n\t\t\tthis.setupNewSuccessfulConnection(connection, \"read\", reason);\n\t\t\tassert(this.pendingConnection === undefined, 0x2b3 /* \"logic error\" */);\n\t\t\treturn;\n\t\t}\n\n\t\tlet delayMs = InitialReconnectDelayInMs;\n\t\tlet connectRepeatCount = 0;\n\t\tconst connectStartTime = performance.now();\n\t\tlet lastError: any;\n\n\t\tconst abortController = new AbortController();\n\t\tconst abortSignal = abortController.signal;\n\t\tthis.pendingConnection = {\n\t\t\tabort: () => {\n\t\t\t\tabortController.abort();\n\t\t\t},\n\t\t\tconnectionMode: requestedMode,\n\t\t};\n\n\t\tthis.props.establishConnectionHandler(reason);\n\t\t// This loop will keep trying to connect until successful, with a delay between each iteration.\n\t\twhile (connection === undefined) {\n\t\t\tif (this._disposed) {\n\t\t\t\tthrow new Error(\"Attempting to connect a closed DeltaManager\");\n\t\t\t}\n\t\t\tif (abortSignal.aborted === true) {\n\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"ConnectionAttemptCancelled\",\n\t\t\t\t\tattempts: connectRepeatCount,\n\t\t\t\t\tduration: formatTick(performance.now() - connectStartTime),\n\t\t\t\t\tconnectionEstablished: false,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconnectRepeatCount++;\n\n\t\t\ttry {\n\t\t\t\tthis.client.mode = requestedMode;\n\t\t\t\tconnection = await docService.connectToDeltaStream({\n\t\t\t\t\t...this.client,\n\t\t\t\t\tmode: requestedMode,\n\t\t\t\t});\n\n\t\t\t\tif (connection.disposed) {\n\t\t\t\t\t// Nobody observed this connection, so drop it on the floor and retry.\n\t\t\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"ReceivedClosedConnection\" });\n\t\t\t\t\tconnection = undefined;\n\t\t\t\t}\n\t\t\t} catch (origError: any) {\n\t\t\t\tif (isDeltaStreamConnectionForbiddenError(origError)) {\n\t\t\t\t\tconnection = new NoDeltaStream(origError.storageOnlyReason);\n\t\t\t\t\trequestedMode = \"read\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Socket.io error when we connect to wrong socket, or hit some multiplexing bug\n\t\t\t\tif (!canRetryOnError(origError)) {\n\t\t\t\t\tconst error = normalizeError(origError, { props: fatalConnectErrorProp });\n\t\t\t\t\tthis.props.closeHandler(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\t// Since the error is retryable this will not log to the error table\n\t\t\t\tlogNetworkFailure(\n\t\t\t\t\tthis.logger,\n\t\t\t\t\t{\n\t\t\t\t\t\tattempts: connectRepeatCount,\n\t\t\t\t\t\tdelay: delayMs, // milliseconds\n\t\t\t\t\t\teventName: \"DeltaConnectionFailureToConnect\",\n\t\t\t\t\t\tduration: formatTick(performance.now() - connectStartTime),\n\t\t\t\t\t},\n\t\t\t\t\torigError,\n\t\t\t\t);\n\n\t\t\t\tlastError = origError;\n\n\t\t\t\tconst waitStartTime = performance.now();\n\t\t\t\tconst retryDelayFromError = getRetryDelayFromError(origError);\n\t\t\t\tif (retryDelayFromError !== undefined) {\n\t\t\t\t\t// If the error told us to wait, then we wait.\n\t\t\t\t\tthis.props.reconnectionDelayHandler(retryDelayFromError, origError);\n\t\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\t\tsetTimeout(resolve, retryDelayFromError);\n\t\t\t\t\t});\n\t\t\t\t} else if (globalThis.navigator?.onLine !== false) {\n\t\t\t\t\t// If the error didn't tell us to wait, let's still wait a little bit before retrying.\n\t\t\t\t\t// We skip this delay if we're confident we're offline, because we probably just need to wait to come back online.\n\t\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\t\tsetTimeout(resolve, delayMs);\n\t\t\t\t\t\tdelayMs = Math.min(delayMs * 2, calculateMaxWaitTime(origError));\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// If we believe we're offline, we assume there's no point in trying until we at least think we're online.\n\t\t\t\t// NOTE: This isn't strictly true for drivers that don't require network (e.g. local driver). Really this logic\n\t\t\t\t// should probably live in the driver.\n\t\t\t\tawait waitForOnline();\n\t\t\t\tthis.logger.sendPerformanceEvent({\n\t\t\t\t\teventName: \"WaitBetweenConnectionAttempts\",\n\t\t\t\t\tduration: performance.now() - waitStartTime,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\tretryDelayFromError,\n\t\t\t\t\t\tdelayMs,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// If we retried more than once, log an event about how long it took (this will not log to error table)\n\t\tif (connectRepeatCount > 1) {\n\t\t\tlogNetworkFailure(\n\t\t\t\tthis.logger,\n\t\t\t\t{\n\t\t\t\t\teventName: \"MultipleDeltaConnectionFailures\",\n\t\t\t\t\tattempts: connectRepeatCount,\n\t\t\t\t\tduration: formatTick(performance.now() - connectStartTime),\n\t\t\t\t},\n\t\t\t\tlastError,\n\t\t\t);\n\t\t}\n\n\t\t// Check for abort signal after while loop as well\n\t\tif (abortSignal.aborted === true) {\n\t\t\tconnection.dispose();\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"ConnectionAttemptCancelled\",\n\t\t\t\tattempts: connectRepeatCount,\n\t\t\t\tduration: formatTick(performance.now() - connectStartTime),\n\t\t\t\tconnectionEstablished: true,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setupNewSuccessfulConnection(connection, requestedMode, reason);\n\t}\n\n\t/**\n\t * Start the connection. Any error should result in container being closed.\n\t * And report the error if it escapes for any reason.\n\t * @param args - The connection arguments\n\t */\n\tprivate triggerConnect(reason: string, connectionMode: ConnectionMode) {\n\t\t// reconnect() includes async awaits, and that causes potential race conditions\n\t\t// where we might already have a connection. If it were to happen, it's possible that we will connect\n\t\t// with different mode to `connectionMode`. Glancing through the caller chains, it looks like code should be\n\t\t// fine (if needed, reconnect flow will get triggered again). Places where new mode matters should encode it\n\t\t// directly in connectCore - see this.shouldJoinWrite() test as an example.\n\t\t// assert(this.connection === undefined, 0x239 /* \"called only in disconnected state\" */);\n\n\t\tif (this.reconnectMode !== ReconnectMode.Enabled) {\n\t\t\treturn;\n\t\t}\n\t\tthis.connect(reason, connectionMode);\n\t}\n\n\t/**\n\t * Disconnect the current connection.\n\t * @param reason - Text description of disconnect reason to emit with disconnect event\n\t * @param error - Error causing the disconnect if any.\n\t * @returns A boolean that indicates if there was an existing connection (or pending connection) to disconnect\n\t */\n\tprivate disconnectFromDeltaStream(reason: string, error?: IAnyDriverError): boolean {\n\t\tthis.pendingReconnect = false;\n\n\t\tif (this.connection === undefined) {\n\t\t\tif (this.pendingConnection !== undefined) {\n\t\t\t\tthis.cancelConnection(reason);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tassert(\n\t\t\tthis.pendingConnection === undefined,\n\t\t\t0x27b /* \"reentrancy may result in incorrect behavior\" */,\n\t\t);\n\n\t\tconst connection = this.connection;\n\t\t// Avoid any re-entrancy - clear object reference\n\t\tthis.connection = undefined;\n\n\t\t// Remove listeners first so we don't try to retrigger this flow accidentally through reconnectOnError\n\t\tconnection.off(\"op\", this.opHandler);\n\t\tconnection.off(\"signal\", this.props.signalHandler);\n\t\tconnection.off(\"nack\", this.nackHandler);\n\t\tconnection.off(\"disconnect\", this.disconnectHandlerInternal);\n\t\tconnection.off(\"error\", this.errorHandler);\n\t\tconnection.off(\"pong\", this.props.pongHandler);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tthis._outbound.pause();\n\t\tthis._outbound.clear();\n\t\tconnection.dispose();\n\n\t\tthis.props.disconnectHandler(reason, error);\n\n\t\tthis._connectionVerboseProps = {};\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Cancel in-progress connection attempt.\n\t */\n\tprivate cancelConnection(reason: string) {\n\t\tassert(\n\t\t\tthis.pendingConnection !== undefined,\n\t\t\t0x345 /* this.pendingConnection is undefined when trying to cancel */,\n\t\t);\n\t\tthis.pendingConnection.abort();\n\t\tthis.pendingConnection = undefined;\n\t\tthis.logger.sendTelemetryEvent({ eventName: \"ConnectionCancelReceived\" });\n\t\tthis.props.cancelConnectionHandler(`Cancel Pending Connection due to ${reason}`);\n\t}\n\n\t/**\n\t * Once we've successfully gotten a connection, we need to set up state, attach event listeners, and process\n\t * initial messages.\n\t * @param connection - The newly established connection\n\t */\n\tprivate setupNewSuccessfulConnection(\n\t\tconnection: IDocumentDeltaConnection,\n\t\trequestedMode: ConnectionMode,\n\t\treason: string,\n\t) {\n\t\t// Old connection should have been cleaned up before establishing a new one\n\t\tassert(\n\t\t\tthis.connection === undefined,\n\t\t\t0x0e6 /* \"old connection exists on new connection setup\" */,\n\t\t);\n\t\tassert(\n\t\t\t!connection.disposed,\n\t\t\t0x28a /* \"can't be disposed - Callers need to ensure that!\" */,\n\t\t);\n\n\t\tthis.pendingConnection = undefined;\n\n\t\tthis.connection = connection;\n\n\t\t// Does information in scopes & mode matches?\n\t\t// If we asked for \"write\" and got \"read\", then file is read-only\n\t\t// But if we ask read, server can still give us write.\n\t\tconst readonly = !connection.claims.scopes.includes(ScopeType.DocWrite);\n\n\t\tif (connection.mode !== requestedMode) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"ConnectionModeMismatch\",\n\t\t\t\trequestedMode,\n\t\t\t\tmode: connection.mode,\n\t\t\t});\n\t\t}\n\t\t// This connection mode validation logic is moving to the driver layer in 0.44. These two asserts can be\n\t\t// removed after those packages have released and become ubiquitous.\n\t\tassert(\n\t\t\trequestedMode === \"read\" || readonly === (this.connectionMode === \"read\"),\n\t\t\t0x0e7 /* \"claims/connectionMode mismatch\" */,\n\t\t);\n\t\tassert(\n\t\t\t!readonly || this.connectionMode === \"read\",\n\t\t\t0x0e8 /* \"readonly perf with write connection\" */,\n\t\t);\n\n\t\tthis.set_readonlyPermissions(readonly);\n\n\t\tif (this._disposed) {\n\t\t\t// Raise proper events, Log telemetry event and close connection.\n\t\t\tthis.disconnectFromDeltaStream(\"ConnectionManager already closed\");\n\t\t\treturn;\n\t\t}\n\n\t\tthis._outbound.resume();\n\n\t\tconnection.on(\"op\", this.opHandler);\n\t\tconnection.on(\"signal\", this.props.signalHandler);\n\t\tconnection.on(\"nack\", this.nackHandler);\n\t\tconnection.on(\"disconnect\", this.disconnectHandlerInternal);\n\t\tconnection.on(\"error\", this.errorHandler);\n\t\tconnection.on(\"pong\", this.props.pongHandler);\n\n\t\t// Initial messages are always sorted. However, due to early op handler installed by drivers and appending those\n\t\t// ops to initialMessages, resulting set is no longer sorted, which would result in client hitting storage to\n\t\t// fill in gap. We will recover by cancelling this request once we process remaining ops, but it's a waste that\n\t\t// we could avoid\n\t\tconst initialMessages = connection.initialMessages.sort(\n\t\t\t(a, b) => a.sequenceNumber - b.sequenceNumber,\n\t\t);\n\n\t\t// Some storages may provide checkpointSequenceNumber to identify how far client is behind.\n\t\tlet checkpointSequenceNumber = connection.checkpointSequenceNumber;\n\n\t\tthis._connectionVerboseProps = {\n\t\t\tclientId: connection.clientId,\n\t\t\tmode: connection.mode,\n\t\t};\n\n\t\t// reset connection props\n\t\tthis._connectionProps = {};\n\n\t\tif (connection.relayServiceAgent !== undefined) {\n\t\t\tthis._connectionVerboseProps.relayServiceAgent = connection.relayServiceAgent;\n\t\t\tthis._connectionProps.relayServiceAgent = connection.relayServiceAgent;\n\t\t}\n\t\tthis._connectionProps.socketDocumentId = connection.claims.documentId;\n\t\tthis._connectionProps.connectionMode = connection.mode;\n\n\t\tlet last = -1;\n\t\tif (initialMessages.length !== 0) {\n\t\t\tthis._connectionVerboseProps.connectionInitialOpsFrom =\n\t\t\t\tinitialMessages[0].sequenceNumber;\n\t\t\tlast = initialMessages[initialMessages.length - 1].sequenceNumber;\n\t\t\tthis._connectionVerboseProps.connectionInitialOpsTo = last + 1;\n\t\t\t// Update knowledge of how far we are behind, before raising \"connect\" event\n\t\t\t// This is duplication of what incomingOpHandler() does, but we have to raise event before we get there,\n\t\t\t// so duplicating update logic here as well.\n\t\t\tif (checkpointSequenceNumber === undefined || checkpointSequenceNumber < last) {\n\t\t\t\tcheckpointSequenceNumber = last;\n\t\t\t}\n\t\t}\n\n\t\tthis.props.incomingOpHandler(\n\t\t\tinitialMessages,\n\t\t\tthis.connectFirstConnection ? \"InitialOps\" : \"ReconnectOps\",\n\t\t);\n\n\t\tconst details = ConnectionManager.detailsFromConnection(connection, reason);\n\t\tdetails.checkpointSequenceNumber = checkpointSequenceNumber;\n\t\tthis.props.connectHandler(details);\n\n\t\tthis.connectFirstConnection = false;\n\n\t\t// Synthesize clear & join signals out of initialClients state.\n\t\t// This allows us to have single way to process signals, and makes it simpler to initialize\n\t\t// protocol in Container.\n\t\tconst clearSignal: ISignalMessage = {\n\t\t\tclientId: null, // system message\n\t\t\tcontent: JSON.stringify({\n\t\t\t\ttype: SignalType.Clear,\n\t\t\t}),\n\t\t};\n\t\tthis.props.signalHandler(clearSignal);\n\n\t\tfor (const priorClient of connection.initialClients ?? []) {\n\t\t\tconst joinSignal: ISignalMessage = {\n\t\t\t\tclientId: null, // system signal\n\t\t\t\tcontent: JSON.stringify({\n\t\t\t\t\ttype: SignalType.ClientJoin,\n\t\t\t\t\tcontent: priorClient, // ISignalClient\n\t\t\t\t}),\n\t\t\t};\n\t\t\tthis.props.signalHandler(joinSignal);\n\t\t}\n\n\t\t// Unfortunately, there is no defined order between initialSignals (including join & leave signals)\n\t\t// and connection.initialClients. In practice, connection.initialSignals quite often contains join signal\n\t\t// for \"self\" and connection.initialClients does not contain \"self\", so we have to process them after\n\t\t// \"clear\" signal above.\n\t\tif (connection.initialSignals !== undefined) {\n\t\t\tfor (const signal of connection.initialSignals) {\n\t\t\t\tthis.props.signalHandler(signal);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Disconnect the current connection and reconnect. Closes the container if it fails.\n\t * @param connection - The connection that wants to reconnect - no-op if it's different from this.connection\n\t * @param requestedMode - Read or write\n\t * @param error - Error reconnect information including whether or not to reconnect\n\t * @returns A promise that resolves when the connection is reestablished or we stop trying\n\t */\n\tprivate reconnectOnError(requestedMode: ConnectionMode, error: IAnyDriverError) {\n\t\tthis.reconnect(requestedMode, error.message, error).catch(this.props.closeHandler);\n\t}\n\n\t/**\n\t * Disconnect the current connection and reconnect.\n\t * @param connection - The connection that wants to reconnect - no-op if it's different from this.connection\n\t * @param requestedMode - Read or write\n\t * @param error - Error reconnect information including whether or not to reconnect\n\t * @returns A promise that resolves when the connection is reestablished or we stop trying\n\t */\n\tprivate async reconnect(\n\t\trequestedMode: ConnectionMode,\n\t\tdisconnectMessage: string,\n\t\terror?: IAnyDriverError,\n\t) {\n\t\t// We quite often get protocol errors before / after observing nack/disconnect\n\t\t// we do not want to run through same sequence twice.\n\t\t// If we're already disconnected/disconnecting it's not appropriate to call this again.\n\t\tassert(this.connection !== undefined, 0x0eb /* \"Missing connection for reconnect\" */);\n\n\t\tthis.disconnectFromDeltaStream(disconnectMessage, error);\n\n\t\t// We will always trigger reconnect, even if canRetry is false.\n\t\t// Any truly fatal error state will result in container close upon attempted reconnect,\n\t\t// which is a preferable to closing abruptly when a live connection fails.\n\t\tif (error !== undefined && !error.canRetry) {\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"reconnectingDespiteFatalError\",\n\t\t\t\t\treconnectMode: this.reconnectMode,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\n\t\tif (this.reconnectMode === ReconnectMode.Never) {\n\t\t\t// Do not raise container error if we are closing just because we lost connection.\n\t\t\t// Those errors (like IdleDisconnect) would show up in telemetry dashboards and\n\t\t\t// are very misleading, as first initial reaction - some logic is broken.\n\t\t\tthis.props.closeHandler();\n\t\t}\n\n\t\t// If closed then we can't reconnect\n\t\tif (this._disposed || this.reconnectMode !== ReconnectMode.Enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the error tells us to wait before retrying, then do so.\n\t\tconst delayMs = getRetryDelayFromError(error);\n\t\tif (error !== undefined && delayMs !== undefined) {\n\t\t\tthis.props.reconnectionDelayHandler(delayMs, error);\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tsetTimeout(resolve, delayMs);\n\t\t\t});\n\t\t}\n\n\t\t// If we believe we're offline, we assume there's no point in trying again until we at least think we're online.\n\t\t// NOTE: This isn't strictly true for drivers that don't require network (e.g. local driver). Really this logic\n\t\t// should probably live in the driver.\n\t\tawait waitForOnline();\n\n\t\tthis.triggerConnect(\n\t\t\terror !== undefined\n\t\t\t\t? \"Reconnecting due to Error\"\n\t\t\t\t: `Reconnecting due to: ${disconnectMessage}`,\n\t\t\trequestedMode,\n\t\t);\n\t}\n\n\tpublic prepareMessageToSend(\n\t\tmessage: Omit<IDocumentMessage, \"clientSequenceNumber\">,\n\t): IDocumentMessage | undefined {\n\t\tif (this.readonly === true) {\n\t\t\tassert(\n\t\t\t\tthis.readOnlyInfo.readonly === true,\n\t\t\t\t0x1f0 /* \"Unexpected mismatch in readonly\" */,\n\t\t\t);\n\t\t\tconst error = new GenericError(\"deltaManagerReadonlySubmit\", undefined /* error */, {\n\t\t\t\treadonly: this.readOnlyInfo.readonly,\n\t\t\t\tforcedReadonly: this.readOnlyInfo.forced,\n\t\t\t\treadonlyPermissions: this.readOnlyInfo.permissions,\n\t\t\t\tstorageOnly: this.readOnlyInfo.storageOnly,\n\t\t\t\tstorageOnlyReason: this.readOnlyInfo.storageOnlyReason,\n\t\t\t});\n\t\t\tthis.props.closeHandler(error);\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// reset clientSequenceNumber if we are using new clientId.\n\t\t// we keep info about old connection as long as possible to be able to account for all non-acked ops\n\t\t// that we pick up on next connection.\n\t\tassert(!!this.connection, 0x0e4 /* \"Lost old connection!\" */);\n\t\tif (this.lastSubmittedClientId !== this.connection?.clientId) {\n\t\t\tthis.lastSubmittedClientId = this.connection?.clientId;\n\t\t\tthis.clientSequenceNumber = 0;\n\t\t\tthis.clientSequenceNumberObserved = 0;\n\t\t}\n\n\t\tif (!isRuntimeMessage(message)) {\n\t\t\tthis.localOpsToIgnore++;\n\t\t} else {\n\t\t\tthis.localOpsToIgnore = 0;\n\t\t}\n\n\t\treturn {\n\t\t\t...message,\n\t\t\tclientSequenceNumber: ++this.clientSequenceNumber,\n\t\t};\n\t}\n\n\tpublic submitSignal(content: any) {\n\t\tif (this.connection !== undefined) {\n\t\t\tthis.connection.submitSignal(content);\n\t\t} else {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"submitSignalDisconnected\" });\n\t\t}\n\t}\n\n\tpublic sendMessages(messages: IDocumentMessage[]) {\n\t\tassert(this.connected, 0x2b4 /* \"not connected on sending ops!\" */);\n\t\t// If connection is \"read\" or implicit \"read\" (got leave op for \"write\" connection),\n\t\t// then op can't make it through - we will get a nack if op is sent.\n\t\t// We can short-circuit this process.\n\t\t// Note that we also want nacks to be rare and be treated as catastrophic failures.\n\t\t// Be careful with reentrancy though - disconnected event should not be be raised in the\n\t\t// middle of the current workflow, but rather on clean stack!\n\t\tif (this.connectionMode === \"read\") {\n\t\t\tif (!this.pendingReconnect) {\n\t\t\t\tthis.pendingReconnect = true;\n\t\t\t\tPromise.resolve()\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\tif (this.pendingReconnect) {\n\t\t\t\t\t\t\t// still valid?\n\t\t\t\t\t\t\tawait this.reconnect(\n\t\t\t\t\t\t\t\t\"write\", // connectionMode\n\t\t\t\t\t\t\t\t\"Switch to write\", // message\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tassert(!this.pendingReconnect, 0x2b5 /* \"logic error\" */);\n\n\t\tthis._outbound.push(messages);\n\t}\n\n\tpublic beforeProcessingIncomingOp(message: ISequencedDocumentMessage) {\n\t\t// if we have connection, and message is local, then we better treat is as local!\n\t\tassert(\n\t\t\tthis.clientId !== message.clientId || this.lastSubmittedClientId === message.clientId,\n\t\t\t0x0ee /* \"Not accounting local messages correctly\" */,\n\t\t);\n\n\t\tif (\n\t\t\tthis.lastSubmittedClientId !== undefined &&\n\t\t\tthis.lastSubmittedClientId === message.clientId\n\t\t) {\n\t\t\tconst clientSequenceNumber = message.clientSequenceNumber;\n\n\t\t\tassert(\n\t\t\t\tthis.clientSequenceNumberObserved < clientSequenceNumber,\n\t\t\t\t0x0ef /* \"client seq# not growing\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tclientSequenceNumber <= this.clientSequenceNumber,\n\t\t\t\t0x0f0 /* \"Incoming local client seq# > generated by this client\" */,\n\t\t\t);\n\n\t\t\tthis.clientSequenceNumberObserved = clientSequenceNumber;\n\t\t}\n\n\t\tif (message.type === MessageType.ClientLeave) {\n\t\t\tconst systemLeaveMessage = message as ISequencedDocumentSystemMessage;\n\t\t\tconst clientId = JSON.parse(systemLeaveMessage.data) as string;\n\t\t\tif (clientId === this.clientId) {\n\t\t\t\t// We have been kicked out from quorum\n\t\t\t\tthis.logger.sendPerformanceEvent({ eventName: \"ReadConnectionTransition\" });\n\n\t\t\t\t// Please see #8483 for more details on why maintaining connection further as is would not work.\n\t\t\t\t// Short story - connection properties are immutable, and many processes (consensus DDSes, summarizer)\n\t\t\t\t// assume that connection stays \"write\" connection until disconnect, and act accordingly, which may\n\t\t\t\t// not work well with de-facto \"read\" connection we are in after receiving own leave op on timeout.\n\t\t\t\t// Clients need to be able to transition to \"read\" state after some time of inactivity!\n\t\t\t\t// Note - this may close container!\n\t\t\t\tthis.reconnect(\n\t\t\t\t\t\"read\", // connectionMode\n\t\t\t\t\t\"Switch to read\", // message\n\t\t\t\t).catch((error) => {\n\t\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"SwitchToReadConnection\" }, error);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate readonly opHandler = (documentId: string, messagesArg: ISequencedDocumentMessage[]) => {\n\t\tconst messages = Array.isArray(messagesArg) ? messagesArg : [messagesArg];\n\t\tthis.props.incomingOpHandler(messages, \"opHandler\");\n\t};\n\n\t// Always connect in write mode after getting nacked.\n\tprivate readonly nackHandler = (documentId: string, messages: INack[]) => {\n\t\tconst message = messages[0];\n\t\tif (this._readonlyPermissions === true) {\n\t\t\tthis.props.closeHandler(\n\t\t\t\tcreateWriteError(\"writeOnReadOnlyDocument\", { driverVersion: undefined }),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reconnectInfo = getNackReconnectInfo(message.content);\n\n\t\t// If the nack indicates we cannot retry, then close the container outright\n\t\tif (!reconnectInfo.canRetry) {\n\t\t\tthis.props.closeHandler(reconnectInfo);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.reconnectOnError(\"write\", reconnectInfo);\n\t};\n\n\t// Connection mode is always read on disconnect/error unless the system mode was write.\n\tprivate readonly disconnectHandlerInternal = (disconnectReason: IAnyDriverError) => {\n\t\t// Note: we might get multiple disconnect calls on same socket, as early disconnect notification\n\t\t// (\"server_disconnect\", ODSP-specific) is mapped to \"disconnect\"\n\t\tthis.reconnectOnError(this.defaultReconnectionMode, disconnectReason);\n\t};\n\n\tprivate readonly errorHandler = (error: IAnyDriverError) => {\n\t\tthis.reconnectOnError(this.defaultReconnectionMode, error);\n\t};\n}\n"]}
1
+ {"version":3,"file":"connectionManager.js","sourceRoot":"","sources":["../src/connectionManager.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 { IDisposable, ITelemetryProperties } from \"@fluidframework/core-interfaces\";\nimport { assert, performance, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n\tICriticalContainerError,\n\tIDeltaQueue,\n\tReadOnlyInfo,\n} from \"@fluidframework/container-definitions\";\nimport { GenericError, UsageError } from \"@fluidframework/container-utils\";\nimport {\n\tIAnyDriverError,\n\tIDocumentService,\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport {\n\tcanRetryOnError,\n\tcreateWriteError,\n\tcreateGenericNetworkError,\n\tgetRetryDelayFromError,\n\tlogNetworkFailure,\n\tisRuntimeMessage,\n\tcalculateMaxWaitTime,\n} from \"@fluidframework/driver-utils\";\nimport {\n\tConnectionMode,\n\tIClient,\n\tIClientConfiguration,\n\tIClientDetails,\n\tIDocumentMessage,\n\tINack,\n\tINackContent,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tITokenClaims,\n\tMessageType,\n\tScopeType,\n\tISequencedDocumentSystemMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLoggerExt, formatTick, normalizeError } from \"@fluidframework/telemetry-utils\";\nimport {\n\tReconnectMode,\n\tIConnectionManager,\n\tIConnectionManagerFactoryArgs,\n\tIConnectionDetailsInternal,\n} from \"./contracts\";\nimport { DeltaQueue } from \"./deltaQueue\";\nimport { SignalType } from \"./protocol\";\nimport { isDeltaStreamConnectionForbiddenError } from \"./utils\";\n\nconst InitialReconnectDelayInMs = 1000;\nconst DefaultChunkSize = 16 * 1024;\n\nconst fatalConnectErrorProp = { fatalConnectError: true };\n\nfunction getNackReconnectInfo(nackContent: INackContent) {\n\tconst message = `Nack (${nackContent.type}): ${nackContent.message}`;\n\tconst canRetry = nackContent.code !== 403;\n\tconst retryAfterMs =\n\t\tnackContent.retryAfter !== undefined ? nackContent.retryAfter * 1000 : undefined;\n\treturn createGenericNetworkError(\n\t\tmessage,\n\t\t{ canRetry, retryAfterMs },\n\t\t{ statusCode: nackContent.code, driverVersion: undefined },\n\t);\n}\n\n/**\n * Implementation of IDocumentDeltaConnection that does not support submitting\n * or receiving ops. Used in storage-only mode.\n */\nconst clientNoDeltaStream: IClient = {\n\tmode: \"read\",\n\tdetails: { capabilities: { interactive: true } },\n\tpermission: [],\n\tuser: { id: \"storage-only client\" }, // we need some \"fake\" ID here.\n\tscopes: [],\n};\nconst clientIdNoDeltaStream: string = \"storage-only client\";\n\nclass NoDeltaStream\n\textends TypedEventEmitter<IDocumentDeltaConnectionEvents>\n\timplements IDocumentDeltaConnection, IDisposable\n{\n\tclientId = clientIdNoDeltaStream;\n\tclaims: ITokenClaims = {\n\t\tscopes: [ScopeType.DocRead],\n\t} as any;\n\tmode: ConnectionMode = \"read\";\n\texisting: boolean = true;\n\tmaxMessageSize: number = 0;\n\tversion: string = \"\";\n\tinitialMessages: ISequencedDocumentMessage[] = [];\n\tinitialSignals: ISignalMessage[] = [];\n\tinitialClients: ISignalClient[] = [\n\t\t{ client: clientNoDeltaStream, clientId: clientIdNoDeltaStream },\n\t];\n\tserviceConfiguration: IClientConfiguration = {\n\t\tmaxMessageSize: 0,\n\t\tblockSize: 0,\n\t};\n\tcheckpointSequenceNumber?: number | undefined = undefined;\n\tconstructor(public readonly storageOnlyReason?: string) {\n\t\tsuper();\n\t}\n\tsubmit(messages: IDocumentMessage[]): void {\n\t\tthis.emit(\n\t\t\t\"nack\",\n\t\t\tthis.clientId,\n\t\t\tmessages.map((operation) => {\n\t\t\t\treturn {\n\t\t\t\t\toperation,\n\t\t\t\t\tcontent: { message: \"Cannot submit with storage-only connection\", code: 403 },\n\t\t\t\t};\n\t\t\t}),\n\t\t);\n\t}\n\tsubmitSignal(message: any): void {\n\t\tthis.emit(\"nack\", this.clientId, {\n\t\t\toperation: message,\n\t\t\tcontent: { message: \"Cannot submit signal with storage-only connection\", code: 403 },\n\t\t});\n\t}\n\n\tprivate _disposed = false;\n\tpublic get disposed() {\n\t\treturn this._disposed;\n\t}\n\tpublic dispose() {\n\t\tthis._disposed = true;\n\t}\n}\n\nfunction isNoDeltaStreamConnection(connection: any): connection is NoDeltaStream {\n\treturn connection instanceof NoDeltaStream;\n}\n\nconst waitForOnline = async (): Promise<void> => {\n\t// Only wait if we have a strong signal that we're offline - otherwise assume we're online.\n\tif (globalThis.navigator?.onLine === false && globalThis.addEventListener !== undefined) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst resolveAndRemoveListener = () => {\n\t\t\t\tresolve();\n\t\t\t\tglobalThis.removeEventListener(\"online\", resolveAndRemoveListener);\n\t\t\t};\n\t\t\tglobalThis.addEventListener(\"online\", resolveAndRemoveListener);\n\t\t});\n\t}\n};\n\n/**\n * Interface to track the current in-progress connection attempt.\n */\ninterface IPendingConnection {\n\t/**\n\t * Used to cancel an in-progress connection attempt.\n\t */\n\tabort(): void;\n\n\t/**\n\t * Desired ConnectionMode of this in-progress connection attempt.\n\t */\n\tconnectionMode: ConnectionMode;\n}\n\n/**\n * Implementation of IConnectionManager, used by Container class\n * Implements constant connectivity to relay service, by reconnecting in case of lost connection or error.\n * Exposes various controls to influence this process, including manual reconnects, forced read-only mode, etc.\n */\nexport class ConnectionManager implements IConnectionManager {\n\t/** Connection mode used when reconnecting on error or disconnect. */\n\tprivate readonly defaultReconnectionMode: ConnectionMode;\n\n\t/**\n\t * Tracks the current in-progress connection attempt. Undefined if there is none.\n\t * Note: Once the connection attempt fires and the code becomes asynchronous, its possible that a new connection\n\t * attempt was fired and this.pendingConnection was overwritten to reflect the new attempt.\n\t */\n\tprivate pendingConnection: IPendingConnection | undefined;\n\tprivate connection: IDocumentDeltaConnection | undefined;\n\n\t/** file ACL - whether user has only read-only access to a file */\n\tprivate _readonlyPermissions: boolean | undefined;\n\n\t/** tracks host requiring read-only mode. */\n\tprivate _forceReadonly = false;\n\n\t/**\n\t * Controls whether the DeltaManager will automatically reconnect to the delta stream after receiving a disconnect.\n\t */\n\tprivate _reconnectMode: ReconnectMode;\n\n\t/** True if there is pending (async) reconnection from \"read\" to \"write\" */\n\tprivate pendingReconnect = false;\n\n\tprivate clientSequenceNumber = 0;\n\tprivate clientSequenceNumberObserved = 0;\n\t/** Counts the number of non-runtime ops sent by the client which may not be acked. */\n\tprivate localOpsToIgnore = 0;\n\n\t/** track clientId used last time when we sent any ops */\n\tprivate lastSubmittedClientId: string | undefined;\n\n\tprivate connectFirstConnection = true;\n\n\tprivate _connectionVerboseProps: Record<string, string | number> = {};\n\n\tprivate _connectionProps: ITelemetryProperties = {};\n\n\tprivate _disposed = false;\n\n\tprivate readonly _outbound: DeltaQueue<IDocumentMessage[]>;\n\n\tpublic get connectionVerboseProps() {\n\t\treturn this._connectionVerboseProps;\n\t}\n\n\tpublic readonly clientDetails: IClientDetails;\n\n\t/**\n\t * The current connection mode, initially read.\n\t */\n\tpublic get connectionMode(): ConnectionMode {\n\t\treturn this.connection?.mode ?? \"read\";\n\t}\n\n\tpublic get connected() {\n\t\treturn this.connection !== undefined;\n\t}\n\n\tpublic get clientId() {\n\t\treturn this.connection?.clientId;\n\t}\n\t/**\n\t * Automatic reconnecting enabled or disabled.\n\t * If set to Never, then reconnecting will never be allowed.\n\t */\n\tpublic get reconnectMode(): ReconnectMode {\n\t\treturn this._reconnectMode;\n\t}\n\n\tpublic get maxMessageSize(): number {\n\t\treturn this.connection?.serviceConfiguration?.maxMessageSize ?? DefaultChunkSize;\n\t}\n\n\tpublic get version(): string {\n\t\tif (this.connection === undefined) {\n\t\t\tthrow new Error(\"Cannot check version without a connection\");\n\t\t}\n\t\treturn this.connection.version;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration | undefined {\n\t\treturn this.connection?.serviceConfiguration;\n\t}\n\n\tpublic get scopes(): string[] | undefined {\n\t\treturn this.connection?.claims.scopes;\n\t}\n\n\tpublic get outbound(): IDeltaQueue<IDocumentMessage[]> {\n\t\treturn this._outbound;\n\t}\n\n\t/**\n\t * Returns set of props that can be logged in telemetry that provide some insights / statistics\n\t * about current or last connection (if there is no connection at the moment)\n\t */\n\tpublic get connectionProps(): ITelemetryProperties {\n\t\treturn this.connection !== undefined\n\t\t\t? this._connectionProps\n\t\t\t: {\n\t\t\t\t\t...this._connectionProps,\n\t\t\t\t\t// Report how many ops this client sent in last disconnected session\n\t\t\t\t\tsentOps: this.clientSequenceNumber,\n\t\t\t };\n\t}\n\n\tpublic shouldJoinWrite(): boolean {\n\t\t// We don't have to wait for ack for topmost NoOps. So subtract those.\n\t\tconst outstandingOps =\n\t\t\tthis.clientSequenceNumberObserved < this.clientSequenceNumber - this.localOpsToIgnore;\n\n\t\t// Previous behavior was to force write mode here only when there are outstanding ops (besides\n\t\t// no-ops). The dirty signal from runtime should provide the same behavior, but also support\n\t\t// stashed ops that weren't submitted to container layer yet. For safety, we want to retain the\n\t\t// same behavior whenever dirty is false.\n\t\tconst isDirty = this.containerDirty();\n\t\tif (outstandingOps !== isDirty) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"DesiredConnectionModeMismatch\",\n\t\t\t\tdetails: JSON.stringify({ outstandingOps, isDirty }),\n\t\t\t});\n\t\t}\n\t\treturn outstandingOps || isDirty;\n\t}\n\n\t/**\n\t * Tells if container is in read-only mode.\n\t * Data stores should listen for \"readonly\" notifications and disallow user\n\t * making changes to data stores.\n\t * Readonly state can be because of no storage write permission,\n\t * or due to host forcing readonly mode for container.\n\t * It is undefined if we have not yet established websocket connection\n\t * and do not know if user has write access to a file.\n\t */\n\tprivate get readonly(): boolean | undefined {\n\t\treturn this.readOnlyInfo.readonly;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\tlet storageOnly: boolean = false;\n\t\tlet storageOnlyReason: string | undefined;\n\t\tif (isNoDeltaStreamConnection(this.connection)) {\n\t\t\tstorageOnly = true;\n\t\t\tstorageOnlyReason = this.connection.storageOnlyReason;\n\t\t}\n\t\tif (storageOnly || this._forceReadonly || this._readonlyPermissions === true) {\n\t\t\treturn {\n\t\t\t\treadonly: true,\n\t\t\t\tforced: this._forceReadonly,\n\t\t\t\tpermissions: this._readonlyPermissions,\n\t\t\t\tstorageOnly,\n\t\t\t\tstorageOnlyReason,\n\t\t\t};\n\t\t}\n\n\t\treturn { readonly: this._readonlyPermissions };\n\t}\n\n\tprivate static detailsFromConnection(\n\t\tconnection: IDocumentDeltaConnection,\n\t\treason: string,\n\t): IConnectionDetailsInternal {\n\t\treturn {\n\t\t\tclaims: connection.claims,\n\t\t\tclientId: connection.clientId,\n\t\t\tcheckpointSequenceNumber: connection.checkpointSequenceNumber,\n\t\t\tget initialClients() {\n\t\t\t\treturn connection.initialClients;\n\t\t\t},\n\t\t\tmode: connection.mode,\n\t\t\tserviceConfiguration: connection.serviceConfiguration,\n\t\t\tversion: connection.version,\n\t\t\treason,\n\t\t};\n\t}\n\n\tconstructor(\n\t\tprivate readonly serviceProvider: () => IDocumentService | undefined,\n\t\tpublic readonly containerDirty: () => boolean,\n\t\tprivate client: IClient,\n\t\treconnectAllowed: boolean,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate readonly props: IConnectionManagerFactoryArgs,\n\t) {\n\t\tthis.clientDetails = this.client.details;\n\t\tthis.defaultReconnectionMode = this.client.mode;\n\t\tthis._reconnectMode = reconnectAllowed ? ReconnectMode.Enabled : ReconnectMode.Never;\n\n\t\t// Outbound message queue. The outbound queue is represented as a queue of an array of ops. Ops contained\n\t\t// within an array *must* fit within the maxMessageSize and are guaranteed to be ordered sequentially.\n\t\tthis._outbound = new DeltaQueue<IDocumentMessage[]>((messages) => {\n\t\t\tif (this.connection === undefined) {\n\t\t\t\tthrow new Error(\"Attempted to submit an outbound message without connection\");\n\t\t\t}\n\t\t\tthis.connection.submit(messages);\n\t\t});\n\n\t\tthis._outbound.on(\"error\", (error) => {\n\t\t\tthis.props.closeHandler(normalizeError(error));\n\t\t});\n\t}\n\n\tpublic dispose(error?: ICriticalContainerError, switchToReadonly: boolean = true) {\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis._disposed = true;\n\n\t\t// Ensure that things like triggerConnect() will short circuit\n\t\tthis._reconnectMode = ReconnectMode.Never;\n\n\t\tthis._outbound.clear();\n\n\t\tconst disconnectReason = \"Closing DeltaManager\";\n\n\t\t// This raises \"disconnect\" event if we have active connection.\n\t\tthis.disconnectFromDeltaStream(disconnectReason);\n\n\t\tif (switchToReadonly) {\n\t\t\t// Notify everyone we are in read-only state.\n\t\t\t// Useful for data stores in case we hit some critical error,\n\t\t\t// to switch to a mode where user edits are not accepted\n\t\t\tthis.set_readonlyPermissions(true);\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables automatic reconnecting.\n\t * Will throw an error if reconnectMode set to Never.\n\t */\n\tpublic setAutoReconnect(mode: ReconnectMode): void {\n\t\tassert(\n\t\t\tmode !== ReconnectMode.Never && this._reconnectMode !== ReconnectMode.Never,\n\t\t\t0x278 /* \"API is not supported for non-connecting or closed container\" */,\n\t\t);\n\n\t\tthis._reconnectMode = mode;\n\n\t\tif (mode !== ReconnectMode.Enabled) {\n\t\t\t// immediately disconnect - do not rely on service eventually dropping connection.\n\t\t\tthis.disconnectFromDeltaStream(\"setAutoReconnect\");\n\t\t}\n\t}\n\n\t/**\n\t * Sends signal to runtime (and data stores) to be read-only.\n\t * Hosts may have read only views, indicating to data stores that no edits are allowed.\n\t * This is independent from this._readonlyPermissions (permissions) and this.connectionMode\n\t * (server can return \"write\" mode even when asked for \"read\")\n\t * Leveraging same \"readonly\" event as runtime & data stores should behave the same in such case\n\t * as in read-only permissions.\n\t * But this.active can be used by some DDSes to figure out if ops can be sent\n\t * (for example, read-only view still participates in code proposals / upgrades decisions)\n\t *\n\t * Forcing Readonly does not prevent DDS from generating ops. It is up to user code to honour\n\t * the readonly flag. If ops are generated, they will accumulate locally and not be sent. If\n\t * there are pending in the outbound queue, it will stop sending until force readonly is\n\t * cleared.\n\t *\n\t * @param readonly - set or clear force readonly.\n\t */\n\tpublic forceReadonly(readonly: boolean) {\n\t\tif (readonly !== this._forceReadonly) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"ForceReadOnly\",\n\t\t\t\tvalue: readonly,\n\t\t\t});\n\t\t}\n\t\tconst oldValue = this.readonly;\n\t\tthis._forceReadonly = readonly;\n\n\t\tif (oldValue !== this.readonly) {\n\t\t\tif (this._reconnectMode === ReconnectMode.Never) {\n\t\t\t\tthrow new UsageError(\"API is not supported for non-connecting or closed container\");\n\t\t\t}\n\t\t\tlet reconnect = false;\n\t\t\tif (this.readonly === true) {\n\t\t\t\t// If we switch to readonly while connected, we should disconnect first\n\t\t\t\t// See comment in the \"readonly\" event handler to deltaManager set up by\n\t\t\t\t// the ContainerRuntime constructor\n\n\t\t\t\tif (this.shouldJoinWrite()) {\n\t\t\t\t\t// If we have pending changes, then we will never send them - it smells like\n\t\t\t\t\t// host logic error.\n\t\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"ForceReadonlyPendingChanged\" });\n\t\t\t\t}\n\n\t\t\t\treconnect = this.disconnectFromDeltaStream(\"Force readonly\");\n\t\t\t}\n\t\t\tthis.props.readonlyChangeHandler(this.readonly);\n\t\t\tif (reconnect) {\n\t\t\t\t// reconnect if we disconnected from before.\n\t\t\t\tthis.triggerConnect(\"Force Readonly\", \"read\");\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate set_readonlyPermissions(readonly: boolean) {\n\t\tconst oldValue = this.readonly;\n\t\tthis._readonlyPermissions = readonly;\n\t\tif (oldValue !== this.readonly) {\n\t\t\tthis.props.readonlyChangeHandler(this.readonly);\n\t\t}\n\t}\n\n\tpublic connect(reason: string, connectionMode?: ConnectionMode) {\n\t\tthis.connectCore(reason, connectionMode).catch((error) => {\n\t\t\tconst normalizedError = normalizeError(error, { props: fatalConnectErrorProp });\n\t\t\tthis.props.closeHandler(normalizedError);\n\t\t});\n\t}\n\n\tprivate async connectCore(reason: string, connectionMode?: ConnectionMode): Promise<void> {\n\t\tassert(!this._disposed, 0x26a /* \"not closed\" */);\n\n\t\tif (this.connection !== undefined) {\n\t\t\treturn; // Connection attempt already completed successfully\n\t\t}\n\n\t\tlet pendingConnectionMode;\n\t\tif (this.pendingConnection !== undefined) {\n\t\t\tpendingConnectionMode = this.pendingConnection.connectionMode;\n\t\t\tthis.cancelConnection(reason); // Throw out in-progress connection attempt in favor of new attempt\n\t\t\tassert(\n\t\t\t\tthis.pendingConnection === undefined,\n\t\t\t\t0x344 /* this.pendingConnection should be undefined */,\n\t\t\t);\n\t\t}\n\t\t// If there is no specified ConnectionMode, try the previous mode, if there is no previous mode use default\n\t\tlet requestedMode = connectionMode ?? pendingConnectionMode ?? this.defaultReconnectionMode;\n\n\t\t// if we have any non-acked ops from last connection, reconnect as \"write\".\n\t\t// without that we would connect in view-only mode, which will result in immediate\n\t\t// firing of \"connected\" event from Container and switch of current clientId (as tracked\n\t\t// by all DDSes). This will make it impossible to figure out if ops actually made it through,\n\t\t// so DDSes will immediately resubmit all pending ops, and some of them will be duplicates, corrupting document\n\t\tif (this.shouldJoinWrite()) {\n\t\t\trequestedMode = \"write\";\n\t\t}\n\n\t\tconst docService = this.serviceProvider();\n\t\tassert(docService !== undefined, 0x2a7 /* \"Container is not attached\" */);\n\n\t\tlet connection: IDocumentDeltaConnection | undefined;\n\n\t\tif (docService.policies?.storageOnly === true) {\n\t\t\tconnection = new NoDeltaStream();\n\t\t\tthis.setupNewSuccessfulConnection(connection, \"read\", reason);\n\t\t\tassert(this.pendingConnection === undefined, 0x2b3 /* \"logic error\" */);\n\t\t\treturn;\n\t\t}\n\n\t\tlet delayMs = InitialReconnectDelayInMs;\n\t\tlet connectRepeatCount = 0;\n\t\tconst connectStartTime = performance.now();\n\t\tlet lastError: any;\n\n\t\tconst abortController = new AbortController();\n\t\tconst abortSignal = abortController.signal;\n\t\tthis.pendingConnection = {\n\t\t\tabort: () => {\n\t\t\t\tabortController.abort();\n\t\t\t},\n\t\t\tconnectionMode: requestedMode,\n\t\t};\n\n\t\tthis.props.establishConnectionHandler(reason);\n\t\t// This loop will keep trying to connect until successful, with a delay between each iteration.\n\t\twhile (connection === undefined) {\n\t\t\tif (this._disposed) {\n\t\t\t\tthrow new Error(\"Attempting to connect a closed DeltaManager\");\n\t\t\t}\n\t\t\tif (abortSignal.aborted === true) {\n\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"ConnectionAttemptCancelled\",\n\t\t\t\t\tattempts: connectRepeatCount,\n\t\t\t\t\tduration: formatTick(performance.now() - connectStartTime),\n\t\t\t\t\tconnectionEstablished: false,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconnectRepeatCount++;\n\n\t\t\ttry {\n\t\t\t\tthis.client.mode = requestedMode;\n\t\t\t\tconnection = await docService.connectToDeltaStream({\n\t\t\t\t\t...this.client,\n\t\t\t\t\tmode: requestedMode,\n\t\t\t\t});\n\n\t\t\t\tif (connection.disposed) {\n\t\t\t\t\t// Nobody observed this connection, so drop it on the floor and retry.\n\t\t\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"ReceivedClosedConnection\" });\n\t\t\t\t\tconnection = undefined;\n\t\t\t\t}\n\t\t\t} catch (origError: any) {\n\t\t\t\tif (isDeltaStreamConnectionForbiddenError(origError)) {\n\t\t\t\t\tconnection = new NoDeltaStream(origError.storageOnlyReason);\n\t\t\t\t\trequestedMode = \"read\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Socket.io error when we connect to wrong socket, or hit some multiplexing bug\n\t\t\t\tif (!canRetryOnError(origError)) {\n\t\t\t\t\tconst error = normalizeError(origError, { props: fatalConnectErrorProp });\n\t\t\t\t\tthis.props.closeHandler(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\t// Since the error is retryable this will not log to the error table\n\t\t\t\tlogNetworkFailure(\n\t\t\t\t\tthis.logger,\n\t\t\t\t\t{\n\t\t\t\t\t\tattempts: connectRepeatCount,\n\t\t\t\t\t\tdelay: delayMs, // milliseconds\n\t\t\t\t\t\teventName: \"DeltaConnectionFailureToConnect\",\n\t\t\t\t\t\tduration: formatTick(performance.now() - connectStartTime),\n\t\t\t\t\t},\n\t\t\t\t\torigError,\n\t\t\t\t);\n\n\t\t\t\tlastError = origError;\n\n\t\t\t\tconst waitStartTime = performance.now();\n\t\t\t\tconst retryDelayFromError = getRetryDelayFromError(origError);\n\t\t\t\tif (retryDelayFromError !== undefined) {\n\t\t\t\t\t// If the error told us to wait, then we wait.\n\t\t\t\t\tthis.props.reconnectionDelayHandler(retryDelayFromError, origError);\n\t\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\t\tsetTimeout(resolve, retryDelayFromError);\n\t\t\t\t\t});\n\t\t\t\t} else if (globalThis.navigator?.onLine !== false) {\n\t\t\t\t\t// If the error didn't tell us to wait, let's still wait a little bit before retrying.\n\t\t\t\t\t// We skip this delay if we're confident we're offline, because we probably just need to wait to come back online.\n\t\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\t\tsetTimeout(resolve, delayMs);\n\t\t\t\t\t\tdelayMs = Math.min(delayMs * 2, calculateMaxWaitTime(origError));\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// If we believe we're offline, we assume there's no point in trying until we at least think we're online.\n\t\t\t\t// NOTE: This isn't strictly true for drivers that don't require network (e.g. local driver). Really this logic\n\t\t\t\t// should probably live in the driver.\n\t\t\t\tawait waitForOnline();\n\t\t\t\tthis.logger.sendPerformanceEvent({\n\t\t\t\t\teventName: \"WaitBetweenConnectionAttempts\",\n\t\t\t\t\tduration: performance.now() - waitStartTime,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\tretryDelayFromError,\n\t\t\t\t\t\tdelayMs,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// If we retried more than once, log an event about how long it took (this will not log to error table)\n\t\tif (connectRepeatCount > 1) {\n\t\t\tlogNetworkFailure(\n\t\t\t\tthis.logger,\n\t\t\t\t{\n\t\t\t\t\teventName: \"MultipleDeltaConnectionFailures\",\n\t\t\t\t\tattempts: connectRepeatCount,\n\t\t\t\t\tduration: formatTick(performance.now() - connectStartTime),\n\t\t\t\t},\n\t\t\t\tlastError,\n\t\t\t);\n\t\t}\n\n\t\t// Check for abort signal after while loop as well\n\t\tif (abortSignal.aborted === true) {\n\t\t\tconnection.dispose();\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"ConnectionAttemptCancelled\",\n\t\t\t\tattempts: connectRepeatCount,\n\t\t\t\tduration: formatTick(performance.now() - connectStartTime),\n\t\t\t\tconnectionEstablished: true,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setupNewSuccessfulConnection(connection, requestedMode, reason);\n\t}\n\n\t/**\n\t * Start the connection. Any error should result in container being closed.\n\t * And report the error if it escapes for any reason.\n\t * @param args - The connection arguments\n\t */\n\tprivate triggerConnect(reason: string, connectionMode: ConnectionMode) {\n\t\t// reconnect() includes async awaits, and that causes potential race conditions\n\t\t// where we might already have a connection. If it were to happen, it's possible that we will connect\n\t\t// with different mode to `connectionMode`. Glancing through the caller chains, it looks like code should be\n\t\t// fine (if needed, reconnect flow will get triggered again). Places where new mode matters should encode it\n\t\t// directly in connectCore - see this.shouldJoinWrite() test as an example.\n\t\t// assert(this.connection === undefined, 0x239 /* \"called only in disconnected state\" */);\n\n\t\tif (this.reconnectMode !== ReconnectMode.Enabled) {\n\t\t\treturn;\n\t\t}\n\t\tthis.connect(reason, connectionMode);\n\t}\n\n\t/**\n\t * Disconnect the current connection.\n\t * @param reason - Text description of disconnect reason to emit with disconnect event\n\t * @param error - Error causing the disconnect if any.\n\t * @returns A boolean that indicates if there was an existing connection (or pending connection) to disconnect\n\t */\n\tprivate disconnectFromDeltaStream(reason: string, error?: IAnyDriverError): boolean {\n\t\tthis.pendingReconnect = false;\n\n\t\tif (this.connection === undefined) {\n\t\t\tif (this.pendingConnection !== undefined) {\n\t\t\t\tthis.cancelConnection(reason);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tassert(\n\t\t\tthis.pendingConnection === undefined,\n\t\t\t0x27b /* \"reentrancy may result in incorrect behavior\" */,\n\t\t);\n\n\t\tconst connection = this.connection;\n\t\t// Avoid any re-entrancy - clear object reference\n\t\tthis.connection = undefined;\n\n\t\t// Remove listeners first so we don't try to retrigger this flow accidentally through reconnectOnError\n\t\tconnection.off(\"op\", this.opHandler);\n\t\tconnection.off(\"signal\", this.props.signalHandler);\n\t\tconnection.off(\"nack\", this.nackHandler);\n\t\tconnection.off(\"disconnect\", this.disconnectHandlerInternal);\n\t\tconnection.off(\"error\", this.errorHandler);\n\t\tconnection.off(\"pong\", this.props.pongHandler);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tthis._outbound.pause();\n\t\tthis._outbound.clear();\n\t\tconnection.dispose();\n\n\t\tthis.props.disconnectHandler(reason, error);\n\n\t\tthis._connectionVerboseProps = {};\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Cancel in-progress connection attempt.\n\t */\n\tprivate cancelConnection(reason: string) {\n\t\tassert(\n\t\t\tthis.pendingConnection !== undefined,\n\t\t\t0x345 /* this.pendingConnection is undefined when trying to cancel */,\n\t\t);\n\t\tthis.pendingConnection.abort();\n\t\tthis.pendingConnection = undefined;\n\t\tthis.logger.sendTelemetryEvent({ eventName: \"ConnectionCancelReceived\" });\n\t\tthis.props.cancelConnectionHandler(`Cancel Pending Connection due to ${reason}`);\n\t}\n\n\t/**\n\t * Once we've successfully gotten a connection, we need to set up state, attach event listeners, and process\n\t * initial messages.\n\t * @param connection - The newly established connection\n\t */\n\tprivate setupNewSuccessfulConnection(\n\t\tconnection: IDocumentDeltaConnection,\n\t\trequestedMode: ConnectionMode,\n\t\treason: string,\n\t) {\n\t\t// Old connection should have been cleaned up before establishing a new one\n\t\tassert(\n\t\t\tthis.connection === undefined,\n\t\t\t0x0e6 /* \"old connection exists on new connection setup\" */,\n\t\t);\n\t\tassert(\n\t\t\t!connection.disposed,\n\t\t\t0x28a /* \"can't be disposed - Callers need to ensure that!\" */,\n\t\t);\n\n\t\tthis.pendingConnection = undefined;\n\n\t\tthis.connection = connection;\n\n\t\t// Does information in scopes & mode matches?\n\t\t// If we asked for \"write\" and got \"read\", then file is read-only\n\t\t// But if we ask read, server can still give us write.\n\t\tconst readonly = !connection.claims.scopes.includes(ScopeType.DocWrite);\n\n\t\tif (connection.mode !== requestedMode) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"ConnectionModeMismatch\",\n\t\t\t\trequestedMode,\n\t\t\t\tmode: connection.mode,\n\t\t\t});\n\t\t}\n\t\t// This connection mode validation logic is moving to the driver layer in 0.44. These two asserts can be\n\t\t// removed after those packages have released and become ubiquitous.\n\t\tassert(\n\t\t\trequestedMode === \"read\" || readonly === (this.connectionMode === \"read\"),\n\t\t\t0x0e7 /* \"claims/connectionMode mismatch\" */,\n\t\t);\n\t\tassert(\n\t\t\t!readonly || this.connectionMode === \"read\",\n\t\t\t0x0e8 /* \"readonly perf with write connection\" */,\n\t\t);\n\n\t\tthis.set_readonlyPermissions(readonly);\n\n\t\tif (this._disposed) {\n\t\t\t// Raise proper events, Log telemetry event and close connection.\n\t\t\tthis.disconnectFromDeltaStream(\"ConnectionManager already closed\");\n\t\t\treturn;\n\t\t}\n\n\t\tthis._outbound.resume();\n\n\t\tconnection.on(\"op\", this.opHandler);\n\t\tconnection.on(\"signal\", this.props.signalHandler);\n\t\tconnection.on(\"nack\", this.nackHandler);\n\t\tconnection.on(\"disconnect\", this.disconnectHandlerInternal);\n\t\tconnection.on(\"error\", this.errorHandler);\n\t\tconnection.on(\"pong\", this.props.pongHandler);\n\n\t\t// Initial messages are always sorted. However, due to early op handler installed by drivers and appending those\n\t\t// ops to initialMessages, resulting set is no longer sorted, which would result in client hitting storage to\n\t\t// fill in gap. We will recover by cancelling this request once we process remaining ops, but it's a waste that\n\t\t// we could avoid\n\t\tconst initialMessages = connection.initialMessages.sort(\n\t\t\t(a, b) => a.sequenceNumber - b.sequenceNumber,\n\t\t);\n\n\t\t// Some storages may provide checkpointSequenceNumber to identify how far client is behind.\n\t\tlet checkpointSequenceNumber = connection.checkpointSequenceNumber;\n\n\t\tthis._connectionVerboseProps = {\n\t\t\tclientId: connection.clientId,\n\t\t\tmode: connection.mode,\n\t\t};\n\n\t\t// reset connection props\n\t\tthis._connectionProps = {};\n\n\t\tif (connection.relayServiceAgent !== undefined) {\n\t\t\tthis._connectionVerboseProps.relayServiceAgent = connection.relayServiceAgent;\n\t\t\tthis._connectionProps.relayServiceAgent = connection.relayServiceAgent;\n\t\t}\n\t\tthis._connectionProps.socketDocumentId = connection.claims.documentId;\n\t\tthis._connectionProps.connectionMode = connection.mode;\n\n\t\tlet last = -1;\n\t\tif (initialMessages.length !== 0) {\n\t\t\tthis._connectionVerboseProps.connectionInitialOpsFrom =\n\t\t\t\tinitialMessages[0].sequenceNumber;\n\t\t\tlast = initialMessages[initialMessages.length - 1].sequenceNumber;\n\t\t\tthis._connectionVerboseProps.connectionInitialOpsTo = last + 1;\n\t\t\t// Update knowledge of how far we are behind, before raising \"connect\" event\n\t\t\t// This is duplication of what incomingOpHandler() does, but we have to raise event before we get there,\n\t\t\t// so duplicating update logic here as well.\n\t\t\tif (checkpointSequenceNumber === undefined || checkpointSequenceNumber < last) {\n\t\t\t\tcheckpointSequenceNumber = last;\n\t\t\t}\n\t\t}\n\n\t\tthis.props.incomingOpHandler(\n\t\t\tinitialMessages,\n\t\t\tthis.connectFirstConnection ? \"InitialOps\" : \"ReconnectOps\",\n\t\t);\n\n\t\tconst details = ConnectionManager.detailsFromConnection(connection, reason);\n\t\tdetails.checkpointSequenceNumber = checkpointSequenceNumber;\n\t\tthis.props.connectHandler(details);\n\n\t\tthis.connectFirstConnection = false;\n\n\t\t// Synthesize clear & join signals out of initialClients state.\n\t\t// This allows us to have single way to process signals, and makes it simpler to initialize\n\t\t// protocol in Container.\n\t\tconst clearSignal: ISignalMessage = {\n\t\t\tclientId: null, // system message\n\t\t\tcontent: JSON.stringify({\n\t\t\t\ttype: SignalType.Clear,\n\t\t\t}),\n\t\t};\n\t\tthis.props.signalHandler(clearSignal);\n\n\t\tfor (const priorClient of connection.initialClients ?? []) {\n\t\t\tconst joinSignal: ISignalMessage = {\n\t\t\t\tclientId: null, // system signal\n\t\t\t\tcontent: JSON.stringify({\n\t\t\t\t\ttype: SignalType.ClientJoin,\n\t\t\t\t\tcontent: priorClient, // ISignalClient\n\t\t\t\t}),\n\t\t\t};\n\t\t\tthis.props.signalHandler(joinSignal);\n\t\t}\n\n\t\t// Unfortunately, there is no defined order between initialSignals (including join & leave signals)\n\t\t// and connection.initialClients. In practice, connection.initialSignals quite often contains join signal\n\t\t// for \"self\" and connection.initialClients does not contain \"self\", so we have to process them after\n\t\t// \"clear\" signal above.\n\t\tif (connection.initialSignals !== undefined) {\n\t\t\tfor (const signal of connection.initialSignals) {\n\t\t\t\tthis.props.signalHandler(signal);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Disconnect the current connection and reconnect. Closes the container if it fails.\n\t * @param connection - The connection that wants to reconnect - no-op if it's different from this.connection\n\t * @param requestedMode - Read or write\n\t * @param error - Error reconnect information including whether or not to reconnect\n\t * @returns A promise that resolves when the connection is reestablished or we stop trying\n\t */\n\tprivate reconnectOnError(requestedMode: ConnectionMode, error: IAnyDriverError) {\n\t\tthis.reconnect(requestedMode, error.message, error).catch(this.props.closeHandler);\n\t}\n\n\t/**\n\t * Disconnect the current connection and reconnect.\n\t * @param connection - The connection that wants to reconnect - no-op if it's different from this.connection\n\t * @param requestedMode - Read or write\n\t * @param error - Error reconnect information including whether or not to reconnect\n\t * @returns A promise that resolves when the connection is reestablished or we stop trying\n\t */\n\tprivate async reconnect(\n\t\trequestedMode: ConnectionMode,\n\t\tdisconnectMessage: string,\n\t\terror?: IAnyDriverError,\n\t) {\n\t\t// We quite often get protocol errors before / after observing nack/disconnect\n\t\t// we do not want to run through same sequence twice.\n\t\t// If we're already disconnected/disconnecting it's not appropriate to call this again.\n\t\tassert(this.connection !== undefined, 0x0eb /* \"Missing connection for reconnect\" */);\n\n\t\tthis.disconnectFromDeltaStream(disconnectMessage, error);\n\n\t\t// We will always trigger reconnect, even if canRetry is false.\n\t\t// Any truly fatal error state will result in container close upon attempted reconnect,\n\t\t// which is a preferable to closing abruptly when a live connection fails.\n\t\tif (error !== undefined && !error.canRetry) {\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"reconnectingDespiteFatalError\",\n\t\t\t\t\treconnectMode: this.reconnectMode,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\n\t\tif (this.reconnectMode === ReconnectMode.Never) {\n\t\t\t// Do not raise container error if we are closing just because we lost connection.\n\t\t\t// Those errors (like IdleDisconnect) would show up in telemetry dashboards and\n\t\t\t// are very misleading, as first initial reaction - some logic is broken.\n\t\t\tthis.props.closeHandler();\n\t\t}\n\n\t\t// If closed then we can't reconnect\n\t\tif (this._disposed || this.reconnectMode !== ReconnectMode.Enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the error tells us to wait before retrying, then do so.\n\t\tconst delayMs = getRetryDelayFromError(error);\n\t\tif (error !== undefined && delayMs !== undefined) {\n\t\t\tthis.props.reconnectionDelayHandler(delayMs, error);\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tsetTimeout(resolve, delayMs);\n\t\t\t});\n\t\t}\n\n\t\t// If we believe we're offline, we assume there's no point in trying again until we at least think we're online.\n\t\t// NOTE: This isn't strictly true for drivers that don't require network (e.g. local driver). Really this logic\n\t\t// should probably live in the driver.\n\t\tawait waitForOnline();\n\n\t\tthis.triggerConnect(\n\t\t\terror !== undefined\n\t\t\t\t? \"Reconnecting due to Error\"\n\t\t\t\t: `Reconnecting due to: ${disconnectMessage}`,\n\t\t\trequestedMode,\n\t\t);\n\t}\n\n\tpublic prepareMessageToSend(\n\t\tmessage: Omit<IDocumentMessage, \"clientSequenceNumber\">,\n\t): IDocumentMessage | undefined {\n\t\tif (this.readonly === true) {\n\t\t\tassert(\n\t\t\t\tthis.readOnlyInfo.readonly === true,\n\t\t\t\t0x1f0 /* \"Unexpected mismatch in readonly\" */,\n\t\t\t);\n\t\t\tconst error = new GenericError(\"deltaManagerReadonlySubmit\", undefined /* error */, {\n\t\t\t\treadonly: this.readOnlyInfo.readonly,\n\t\t\t\tforcedReadonly: this.readOnlyInfo.forced,\n\t\t\t\treadonlyPermissions: this.readOnlyInfo.permissions,\n\t\t\t\tstorageOnly: this.readOnlyInfo.storageOnly,\n\t\t\t\tstorageOnlyReason: this.readOnlyInfo.storageOnlyReason,\n\t\t\t});\n\t\t\tthis.props.closeHandler(error);\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// reset clientSequenceNumber if we are using new clientId.\n\t\t// we keep info about old connection as long as possible to be able to account for all non-acked ops\n\t\t// that we pick up on next connection.\n\t\tassert(!!this.connection, 0x0e4 /* \"Lost old connection!\" */);\n\t\tif (this.lastSubmittedClientId !== this.connection?.clientId) {\n\t\t\tthis.lastSubmittedClientId = this.connection?.clientId;\n\t\t\tthis.clientSequenceNumber = 0;\n\t\t\tthis.clientSequenceNumberObserved = 0;\n\t\t}\n\n\t\tif (!isRuntimeMessage(message)) {\n\t\t\tthis.localOpsToIgnore++;\n\t\t} else {\n\t\t\tthis.localOpsToIgnore = 0;\n\t\t}\n\n\t\treturn {\n\t\t\t...message,\n\t\t\tclientSequenceNumber: ++this.clientSequenceNumber,\n\t\t};\n\t}\n\n\tpublic submitSignal(content: any) {\n\t\tif (this.connection !== undefined) {\n\t\t\tthis.connection.submitSignal(content);\n\t\t} else {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"submitSignalDisconnected\" });\n\t\t}\n\t}\n\n\tpublic sendMessages(messages: IDocumentMessage[]) {\n\t\tassert(this.connected, 0x2b4 /* \"not connected on sending ops!\" */);\n\t\t// If connection is \"read\" or implicit \"read\" (got leave op for \"write\" connection),\n\t\t// then op can't make it through - we will get a nack if op is sent.\n\t\t// We can short-circuit this process.\n\t\t// Note that we also want nacks to be rare and be treated as catastrophic failures.\n\t\t// Be careful with reentrancy though - disconnected event should not be be raised in the\n\t\t// middle of the current workflow, but rather on clean stack!\n\t\tif (this.connectionMode === \"read\") {\n\t\t\tif (!this.pendingReconnect) {\n\t\t\t\tthis.pendingReconnect = true;\n\t\t\t\tPromise.resolve()\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\tif (this.pendingReconnect) {\n\t\t\t\t\t\t\t// still valid?\n\t\t\t\t\t\t\tawait this.reconnect(\n\t\t\t\t\t\t\t\t\"write\", // connectionMode\n\t\t\t\t\t\t\t\t\"Switch to write\", // message\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tassert(!this.pendingReconnect, 0x2b5 /* \"logic error\" */);\n\n\t\tthis._outbound.push(messages);\n\t}\n\n\tpublic beforeProcessingIncomingOp(message: ISequencedDocumentMessage) {\n\t\t// if we have connection, and message is local, then we better treat is as local!\n\t\tassert(\n\t\t\tthis.clientId !== message.clientId || this.lastSubmittedClientId === message.clientId,\n\t\t\t0x0ee /* \"Not accounting local messages correctly\" */,\n\t\t);\n\n\t\tif (\n\t\t\tthis.lastSubmittedClientId !== undefined &&\n\t\t\tthis.lastSubmittedClientId === message.clientId\n\t\t) {\n\t\t\tconst clientSequenceNumber = message.clientSequenceNumber;\n\n\t\t\tassert(\n\t\t\t\tthis.clientSequenceNumberObserved < clientSequenceNumber,\n\t\t\t\t0x0ef /* \"client seq# not growing\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tclientSequenceNumber <= this.clientSequenceNumber,\n\t\t\t\t0x0f0 /* \"Incoming local client seq# > generated by this client\" */,\n\t\t\t);\n\n\t\t\tthis.clientSequenceNumberObserved = clientSequenceNumber;\n\t\t}\n\n\t\tif (message.type === MessageType.ClientLeave) {\n\t\t\tconst systemLeaveMessage = message as ISequencedDocumentSystemMessage;\n\t\t\tconst clientId = JSON.parse(systemLeaveMessage.data) as string;\n\t\t\tif (clientId === this.clientId) {\n\t\t\t\t// We have been kicked out from quorum\n\t\t\t\tthis.logger.sendPerformanceEvent({ eventName: \"ReadConnectionTransition\" });\n\n\t\t\t\t// Please see #8483 for more details on why maintaining connection further as is would not work.\n\t\t\t\t// Short story - connection properties are immutable, and many processes (consensus DDSes, summarizer)\n\t\t\t\t// assume that connection stays \"write\" connection until disconnect, and act accordingly, which may\n\t\t\t\t// not work well with de-facto \"read\" connection we are in after receiving own leave op on timeout.\n\t\t\t\t// Clients need to be able to transition to \"read\" state after some time of inactivity!\n\t\t\t\t// Note - this may close container!\n\t\t\t\tthis.reconnect(\n\t\t\t\t\t\"read\", // connectionMode\n\t\t\t\t\t\"Switch to read\", // message\n\t\t\t\t).catch((error) => {\n\t\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"SwitchToReadConnection\" }, error);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate readonly opHandler = (documentId: string, messagesArg: ISequencedDocumentMessage[]) => {\n\t\tconst messages = Array.isArray(messagesArg) ? messagesArg : [messagesArg];\n\t\tthis.props.incomingOpHandler(messages, \"opHandler\");\n\t};\n\n\t// Always connect in write mode after getting nacked.\n\tprivate readonly nackHandler = (documentId: string, messages: INack[]) => {\n\t\tconst message = messages[0];\n\t\tif (this._readonlyPermissions === true) {\n\t\t\tthis.props.closeHandler(\n\t\t\t\tcreateWriteError(\"writeOnReadOnlyDocument\", { driverVersion: undefined }),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reconnectInfo = getNackReconnectInfo(message.content);\n\n\t\t// If the nack indicates we cannot retry, then close the container outright\n\t\tif (!reconnectInfo.canRetry) {\n\t\t\tthis.props.closeHandler(reconnectInfo);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.reconnectOnError(\"write\", reconnectInfo);\n\t};\n\n\t// Connection mode is always read on disconnect/error unless the system mode was write.\n\tprivate readonly disconnectHandlerInternal = (disconnectReason: IAnyDriverError) => {\n\t\t// Note: we might get multiple disconnect calls on same socket, as early disconnect notification\n\t\t// (\"server_disconnect\", ODSP-specific) is mapped to \"disconnect\"\n\t\tthis.reconnectOnError(this.defaultReconnectionMode, disconnectReason);\n\t};\n\n\tprivate readonly errorHandler = (error: IAnyDriverError) => {\n\t\tthis.reconnectOnError(this.defaultReconnectionMode, error);\n\t};\n}\n"]}
@@ -3,11 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ITelemetryProperties, TelemetryEventCategory } from "@fluidframework/core-interfaces";
6
- import { IConnectionDetailsInternal, IDeltaManager } from "@fluidframework/container-definitions";
6
+ import { IDeltaManager } from "@fluidframework/container-definitions";
7
7
  import { IAnyDriverError } from "@fluidframework/driver-definitions";
8
8
  import { ISequencedClient, IClient } from "@fluidframework/protocol-definitions";
9
9
  import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
10
10
  import { ConnectionState } from "./connectionState";
11
+ import { IConnectionDetailsInternal } from "./contracts";
11
12
  import { IProtocolHandler } from "./protocol";
12
13
  /** Constructor parameter type for passing in dependencies needed by the ConnectionStateHandler */
13
14
  export interface IConnectionStateHandlerInputs {