@fluidframework/container-loader 2.0.0-dev.5.3.2.178189 → 2.0.0-dev.6.4.0.191457

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 (173) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/README.md +10 -6
  3. package/dist/audience.d.ts +1 -0
  4. package/dist/audience.d.ts.map +1 -1
  5. package/dist/audience.js +5 -3
  6. package/dist/audience.js.map +1 -1
  7. package/dist/catchUpMonitor.js +2 -2
  8. package/dist/catchUpMonitor.js.map +1 -1
  9. package/dist/connectionManager.d.ts +5 -5
  10. package/dist/connectionManager.d.ts.map +1 -1
  11. package/dist/connectionManager.js +97 -93
  12. package/dist/connectionManager.js.map +1 -1
  13. package/dist/connectionStateHandler.d.ts +15 -14
  14. package/dist/connectionStateHandler.d.ts.map +1 -1
  15. package/dist/connectionStateHandler.js +50 -52
  16. package/dist/connectionStateHandler.js.map +1 -1
  17. package/dist/container.d.ts +20 -9
  18. package/dist/container.d.ts.map +1 -1
  19. package/dist/container.js +327 -277
  20. package/dist/container.js.map +1 -1
  21. package/dist/containerContext.d.ts +2 -7
  22. package/dist/containerContext.d.ts.map +1 -1
  23. package/dist/containerContext.js +2 -14
  24. package/dist/containerContext.js.map +1 -1
  25. package/dist/containerStorageAdapter.d.ts.map +1 -1
  26. package/dist/containerStorageAdapter.js +12 -13
  27. package/dist/containerStorageAdapter.js.map +1 -1
  28. package/dist/contracts.d.ts +21 -8
  29. package/dist/contracts.d.ts.map +1 -1
  30. package/dist/contracts.js +3 -3
  31. package/dist/contracts.js.map +1 -1
  32. package/dist/debugLogger.d.ts +30 -0
  33. package/dist/debugLogger.d.ts.map +1 -0
  34. package/dist/debugLogger.js +95 -0
  35. package/dist/debugLogger.js.map +1 -0
  36. package/dist/deltaManager.d.ts +21 -10
  37. package/dist/deltaManager.d.ts.map +1 -1
  38. package/dist/deltaManager.js +114 -66
  39. package/dist/deltaManager.js.map +1 -1
  40. package/dist/deltaQueue.d.ts +1 -1
  41. package/dist/deltaQueue.d.ts.map +1 -1
  42. package/dist/deltaQueue.js +10 -10
  43. package/dist/deltaQueue.js.map +1 -1
  44. package/dist/disposal.d.ts +2 -2
  45. package/dist/disposal.d.ts.map +1 -1
  46. package/dist/disposal.js +1 -1
  47. package/dist/disposal.js.map +1 -1
  48. package/dist/error.d.ts +23 -0
  49. package/dist/error.d.ts.map +1 -0
  50. package/dist/error.js +32 -0
  51. package/dist/error.js.map +1 -0
  52. package/dist/loader.d.ts +22 -3
  53. package/dist/loader.d.ts.map +1 -1
  54. package/dist/loader.js +82 -51
  55. package/dist/loader.js.map +1 -1
  56. package/dist/noopHeuristic.d.ts +2 -2
  57. package/dist/noopHeuristic.d.ts.map +1 -1
  58. package/dist/noopHeuristic.js +6 -5
  59. package/dist/noopHeuristic.js.map +1 -1
  60. package/dist/packageVersion.d.ts +1 -1
  61. package/dist/packageVersion.js +1 -1
  62. package/dist/packageVersion.js.map +1 -1
  63. package/dist/protocol.d.ts +4 -2
  64. package/dist/protocol.d.ts.map +1 -1
  65. package/dist/protocol.js +25 -4
  66. package/dist/protocol.js.map +1 -1
  67. package/dist/quorum.d.ts +4 -1
  68. package/dist/quorum.d.ts.map +1 -1
  69. package/dist/quorum.js +1 -13
  70. package/dist/quorum.js.map +1 -1
  71. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  72. package/dist/retriableDocumentStorageService.js +4 -4
  73. package/dist/retriableDocumentStorageService.js.map +1 -1
  74. package/dist/utils.d.ts +8 -1
  75. package/dist/utils.d.ts.map +1 -1
  76. package/dist/utils.js +30 -11
  77. package/dist/utils.js.map +1 -1
  78. package/lib/audience.d.ts +1 -0
  79. package/lib/audience.d.ts.map +1 -1
  80. package/lib/audience.js +4 -2
  81. package/lib/audience.js.map +1 -1
  82. package/lib/catchUpMonitor.js +1 -1
  83. package/lib/catchUpMonitor.js.map +1 -1
  84. package/lib/connectionManager.d.ts +5 -5
  85. package/lib/connectionManager.d.ts.map +1 -1
  86. package/lib/connectionManager.js +74 -67
  87. package/lib/connectionManager.js.map +1 -1
  88. package/lib/connectionStateHandler.d.ts +15 -14
  89. package/lib/connectionStateHandler.d.ts.map +1 -1
  90. package/lib/connectionStateHandler.js +27 -29
  91. package/lib/connectionStateHandler.js.map +1 -1
  92. package/lib/container.d.ts +20 -9
  93. package/lib/container.d.ts.map +1 -1
  94. package/lib/container.js +288 -238
  95. package/lib/container.js.map +1 -1
  96. package/lib/containerContext.d.ts +2 -7
  97. package/lib/containerContext.d.ts.map +1 -1
  98. package/lib/containerContext.js +2 -14
  99. package/lib/containerContext.js.map +1 -1
  100. package/lib/containerStorageAdapter.d.ts.map +1 -1
  101. package/lib/containerStorageAdapter.js +5 -6
  102. package/lib/containerStorageAdapter.js.map +1 -1
  103. package/lib/contracts.d.ts +21 -8
  104. package/lib/contracts.d.ts.map +1 -1
  105. package/lib/contracts.js +3 -3
  106. package/lib/contracts.js.map +1 -1
  107. package/lib/debugLogger.d.ts +30 -0
  108. package/lib/debugLogger.d.ts.map +1 -0
  109. package/lib/debugLogger.js +91 -0
  110. package/lib/debugLogger.js.map +1 -0
  111. package/lib/deltaManager.d.ts +21 -10
  112. package/lib/deltaManager.d.ts.map +1 -1
  113. package/lib/deltaManager.js +88 -37
  114. package/lib/deltaManager.js.map +1 -1
  115. package/lib/deltaQueue.d.ts +1 -1
  116. package/lib/deltaQueue.d.ts.map +1 -1
  117. package/lib/deltaQueue.js +3 -3
  118. package/lib/deltaQueue.js.map +1 -1
  119. package/lib/disposal.d.ts +2 -2
  120. package/lib/disposal.d.ts.map +1 -1
  121. package/lib/disposal.js +1 -1
  122. package/lib/disposal.js.map +1 -1
  123. package/lib/error.d.ts +23 -0
  124. package/lib/error.d.ts.map +1 -0
  125. package/lib/error.js +28 -0
  126. package/lib/error.js.map +1 -0
  127. package/lib/loader.d.ts +22 -3
  128. package/lib/loader.d.ts.map +1 -1
  129. package/lib/loader.js +82 -51
  130. package/lib/loader.js.map +1 -1
  131. package/lib/noopHeuristic.d.ts +2 -2
  132. package/lib/noopHeuristic.d.ts.map +1 -1
  133. package/lib/noopHeuristic.js +2 -1
  134. package/lib/noopHeuristic.js.map +1 -1
  135. package/lib/packageVersion.d.ts +1 -1
  136. package/lib/packageVersion.js +1 -1
  137. package/lib/packageVersion.js.map +1 -1
  138. package/lib/protocol.d.ts +4 -2
  139. package/lib/protocol.d.ts.map +1 -1
  140. package/lib/protocol.js +25 -4
  141. package/lib/protocol.js.map +1 -1
  142. package/lib/quorum.d.ts +4 -1
  143. package/lib/quorum.d.ts.map +1 -1
  144. package/lib/quorum.js +0 -11
  145. package/lib/quorum.js.map +1 -1
  146. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  147. package/lib/retriableDocumentStorageService.js +2 -2
  148. package/lib/retriableDocumentStorageService.js.map +1 -1
  149. package/lib/utils.d.ts +8 -1
  150. package/lib/utils.d.ts.map +1 -1
  151. package/lib/utils.js +25 -7
  152. package/lib/utils.js.map +1 -1
  153. package/package.json +26 -32
  154. package/src/audience.ts +7 -1
  155. package/src/catchUpMonitor.ts +1 -1
  156. package/src/connectionManager.ts +75 -51
  157. package/src/connectionStateHandler.ts +31 -38
  158. package/src/container.ts +335 -240
  159. package/src/containerContext.ts +0 -16
  160. package/src/containerStorageAdapter.ts +2 -1
  161. package/src/contracts.ts +27 -11
  162. package/src/debugLogger.ts +113 -0
  163. package/src/deltaManager.ts +84 -34
  164. package/src/deltaQueue.ts +2 -1
  165. package/src/disposal.ts +2 -2
  166. package/src/error.ts +44 -0
  167. package/src/loader.ts +83 -35
  168. package/src/noopHeuristic.ts +3 -2
  169. package/src/packageVersion.ts +1 -1
  170. package/src/protocol.ts +33 -2
  171. package/src/quorum.ts +0 -10
  172. package/src/retriableDocumentStorageService.ts +2 -4
  173. package/src/utils.ts +33 -8
@@ -3,14 +3,10 @@
3
3
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
4
  * Licensed under the MIT License.
5
5
  */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
6
  Object.defineProperty(exports, "__esModule", { value: true });
10
7
  exports.ConnectionManager = void 0;
11
- const abort_controller_1 = __importDefault(require("abort-controller"));
12
- const common_utils_1 = require("@fluidframework/common-utils");
13
- const container_utils_1 = require("@fluidframework/container-utils");
8
+ const core_utils_1 = require("@fluidframework/core-utils");
9
+ const client_utils_1 = require("@fluid-internal/client-utils");
14
10
  const driver_utils_1 = require("@fluidframework/driver-utils");
15
11
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
16
12
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
@@ -18,7 +14,6 @@ const contracts_1 = require("./contracts");
18
14
  const deltaQueue_1 = require("./deltaQueue");
19
15
  const protocol_1 = require("./protocol");
20
16
  const utils_1 = require("./utils");
21
- const MaxReconnectDelayInMs = 8000;
22
17
  const InitialReconnectDelayInMs = 1000;
23
18
  const DefaultChunkSize = 16 * 1024;
24
19
  const fatalConnectErrorProp = { fatalConnectError: true };
@@ -40,7 +35,7 @@ const clientNoDeltaStream = {
40
35
  scopes: [],
41
36
  };
42
37
  const clientIdNoDeltaStream = "storage-only client";
43
- class NoDeltaStream extends common_utils_1.TypedEventEmitter {
38
+ class NoDeltaStream extends client_utils_1.TypedEventEmitter {
44
39
  constructor(storageOnlyReason) {
45
40
  super();
46
41
  this.storageOnlyReason = storageOnlyReason;
@@ -89,9 +84,8 @@ function isNoDeltaStreamConnection(connection) {
89
84
  return connection instanceof NoDeltaStream;
90
85
  }
91
86
  const waitForOnline = async () => {
92
- var _a;
93
87
  // Only wait if we have a strong signal that we're offline - otherwise assume we're online.
94
- 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) {
95
89
  return new Promise((resolve) => {
96
90
  const resolveAndRemoveListener = () => {
97
91
  resolve();
@@ -175,15 +169,13 @@ class ConnectionManager {
175
169
  * The current connection mode, initially read.
176
170
  */
177
171
  get connectionMode() {
178
- var _a, _b;
179
- 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";
180
173
  }
181
174
  get connected() {
182
175
  return this.connection !== undefined;
183
176
  }
184
177
  get clientId() {
185
- var _a;
186
- return (_a = this.connection) === null || _a === void 0 ? void 0 : _a.clientId;
178
+ return this.connection?.clientId;
187
179
  }
188
180
  /**
189
181
  * Automatic reconnecting enabled or disabled.
@@ -193,8 +185,7 @@ class ConnectionManager {
193
185
  return this._reconnectMode;
194
186
  }
195
187
  get maxMessageSize() {
196
- var _a, _b, _c;
197
- 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;
198
189
  }
199
190
  get version() {
200
191
  if (this.connection === undefined) {
@@ -203,12 +194,10 @@ class ConnectionManager {
203
194
  return this.connection.version;
204
195
  }
205
196
  get serviceConfiguration() {
206
- var _a;
207
- return (_a = this.connection) === null || _a === void 0 ? void 0 : _a.serviceConfiguration;
197
+ return this.connection?.serviceConfiguration;
208
198
  }
209
199
  get scopes() {
210
- var _a;
211
- return (_a = this.connection) === null || _a === void 0 ? void 0 : _a.claims.scopes;
200
+ return this.connection?.claims.scopes;
212
201
  }
213
202
  get outbound() {
214
203
  return this._outbound;
@@ -220,9 +209,11 @@ class ConnectionManager {
220
209
  get connectionProps() {
221
210
  return this.connection !== undefined
222
211
  ? this._connectionProps
223
- : Object.assign(Object.assign({}, this._connectionProps), {
212
+ : {
213
+ ...this._connectionProps,
224
214
  // Report how many ops this client sent in last disconnected session
225
- sentOps: this.clientSequenceNumber });
215
+ sentOps: this.clientSequenceNumber,
216
+ };
226
217
  }
227
218
  shouldJoinWrite() {
228
219
  // We don't have to wait for ack for topmost NoOps. So subtract those.
@@ -292,26 +283,30 @@ class ConnectionManager {
292
283
  // Ensure that things like triggerConnect() will short circuit
293
284
  this._reconnectMode = contracts_1.ReconnectMode.Never;
294
285
  this._outbound.clear();
295
- const disconnectReason = "Closing DeltaManager";
286
+ const disconnectReason = {
287
+ text: "Closing DeltaManager",
288
+ error,
289
+ };
290
+ const oldReadonlyValue = this.readonly;
296
291
  // This raises "disconnect" event if we have active connection.
297
292
  this.disconnectFromDeltaStream(disconnectReason);
298
293
  if (switchToReadonly) {
299
294
  // Notify everyone we are in read-only state.
300
295
  // Useful for data stores in case we hit some critical error,
301
296
  // to switch to a mode where user edits are not accepted
302
- this.set_readonlyPermissions(true);
297
+ this.set_readonlyPermissions(true, oldReadonlyValue);
303
298
  }
304
299
  }
305
300
  /**
306
301
  * Enables or disables automatic reconnecting.
307
302
  * Will throw an error if reconnectMode set to Never.
308
303
  */
309
- setAutoReconnect(mode) {
310
- (0, common_utils_1.assert)(mode !== contracts_1.ReconnectMode.Never && this._reconnectMode !== contracts_1.ReconnectMode.Never, 0x278 /* "API is not supported for non-connecting or closed container" */);
304
+ setAutoReconnect(mode, reason) {
305
+ (0, core_utils_1.assert)(mode !== contracts_1.ReconnectMode.Never && this._reconnectMode !== contracts_1.ReconnectMode.Never, 0x278 /* "API is not supported for non-connecting or closed container" */);
311
306
  this._reconnectMode = mode;
312
307
  if (mode !== contracts_1.ReconnectMode.Enabled) {
313
308
  // immediately disconnect - do not rely on service eventually dropping connection.
314
- this.disconnectFromDeltaStream("setAutoReconnect");
309
+ this.disconnectFromDeltaStream(reason);
315
310
  }
316
311
  }
317
312
  /**
@@ -342,7 +337,7 @@ class ConnectionManager {
342
337
  this._forceReadonly = readonly;
343
338
  if (oldValue !== this.readonly) {
344
339
  if (this._reconnectMode === contracts_1.ReconnectMode.Never) {
345
- throw new container_utils_1.UsageError("API is not supported for non-connecting or closed container");
340
+ throw new telemetry_utils_1.UsageError("API is not supported for non-connecting or closed container");
346
341
  }
347
342
  let reconnect = false;
348
343
  if (this.readonly === true) {
@@ -354,31 +349,29 @@ class ConnectionManager {
354
349
  // host logic error.
355
350
  this.logger.sendErrorEvent({ eventName: "ForceReadonlyPendingChanged" });
356
351
  }
357
- reconnect = this.disconnectFromDeltaStream("Force readonly");
352
+ reconnect = this.disconnectFromDeltaStream({ text: "Force readonly" });
358
353
  }
359
354
  this.props.readonlyChangeHandler(this.readonly);
360
355
  if (reconnect) {
361
356
  // reconnect if we disconnected from before.
362
- this.triggerConnect("Force Readonly", "read");
357
+ this.triggerConnect({ text: "Force Readonly" }, "read");
363
358
  }
364
359
  }
365
360
  }
366
- set_readonlyPermissions(readonly) {
367
- const oldValue = this.readonly;
368
- this._readonlyPermissions = readonly;
369
- if (oldValue !== this.readonly) {
361
+ set_readonlyPermissions(newReadonlyValue, oldReadonlyValue) {
362
+ this._readonlyPermissions = newReadonlyValue;
363
+ if (oldReadonlyValue !== this.readonly) {
370
364
  this.props.readonlyChangeHandler(this.readonly);
371
365
  }
372
366
  }
373
367
  connect(reason, connectionMode) {
374
- this.connectCore(reason, connectionMode).catch((error) => {
375
- const normalizedError = (0, telemetry_utils_1.normalizeError)(error, { props: fatalConnectErrorProp });
368
+ this.connectCore(reason, connectionMode).catch((e) => {
369
+ const normalizedError = (0, telemetry_utils_1.normalizeError)(e, { props: fatalConnectErrorProp });
376
370
  this.props.closeHandler(normalizedError);
377
371
  });
378
372
  }
379
373
  async connectCore(reason, connectionMode) {
380
- var _a, _b, _c;
381
- (0, common_utils_1.assert)(!this._disposed, 0x26a /* "not closed" */);
374
+ (0, core_utils_1.assert)(!this._disposed, 0x26a /* "not closed" */);
382
375
  if (this.connection !== undefined) {
383
376
  return; // Connection attempt already completed successfully
384
377
  }
@@ -386,10 +379,10 @@ class ConnectionManager {
386
379
  if (this.pendingConnection !== undefined) {
387
380
  pendingConnectionMode = this.pendingConnection.connectionMode;
388
381
  this.cancelConnection(reason); // Throw out in-progress connection attempt in favor of new attempt
389
- (0, common_utils_1.assert)(this.pendingConnection === undefined, 0x344 /* this.pendingConnection should be undefined */);
382
+ (0, core_utils_1.assert)(this.pendingConnection === undefined, 0x344 /* this.pendingConnection should be undefined */);
390
383
  }
391
384
  // If there is no specified ConnectionMode, try the previous mode, if there is no previous mode use default
392
- let requestedMode = (_a = connectionMode !== null && connectionMode !== void 0 ? connectionMode : pendingConnectionMode) !== null && _a !== void 0 ? _a : this.defaultReconnectionMode;
385
+ let requestedMode = connectionMode ?? pendingConnectionMode ?? this.defaultReconnectionMode;
393
386
  // if we have any non-acked ops from last connection, reconnect as "write".
394
387
  // without that we would connect in view-only mode, which will result in immediate
395
388
  // firing of "connected" event from Container and switch of current clientId (as tracked
@@ -399,19 +392,19 @@ class ConnectionManager {
399
392
  requestedMode = "write";
400
393
  }
401
394
  const docService = this.serviceProvider();
402
- (0, common_utils_1.assert)(docService !== undefined, 0x2a7 /* "Container is not attached" */);
395
+ (0, core_utils_1.assert)(docService !== undefined, 0x2a7 /* "Container is not attached" */);
403
396
  let connection;
404
- if (((_b = docService.policies) === null || _b === void 0 ? void 0 : _b.storageOnly) === true) {
397
+ if (docService.policies?.storageOnly === true) {
405
398
  connection = new NoDeltaStream();
406
399
  this.setupNewSuccessfulConnection(connection, "read", reason);
407
- (0, common_utils_1.assert)(this.pendingConnection === undefined, 0x2b3 /* "logic error" */);
400
+ (0, core_utils_1.assert)(this.pendingConnection === undefined, 0x2b3 /* "logic error" */);
408
401
  return;
409
402
  }
410
403
  let delayMs = InitialReconnectDelayInMs;
411
404
  let connectRepeatCount = 0;
412
- const connectStartTime = common_utils_1.performance.now();
405
+ const connectStartTime = client_utils_1.performance.now();
413
406
  let lastError;
414
- const abortController = new abort_controller_1.default();
407
+ const abortController = new AbortController();
415
408
  const abortSignal = abortController.signal;
416
409
  this.pendingConnection = {
417
410
  abort: () => {
@@ -429,7 +422,7 @@ class ConnectionManager {
429
422
  this.logger.sendTelemetryEvent({
430
423
  eventName: "ConnectionAttemptCancelled",
431
424
  attempts: connectRepeatCount,
432
- duration: telemetry_utils_1.TelemetryLogger.formatTick(common_utils_1.performance.now() - connectStartTime),
425
+ duration: (0, telemetry_utils_1.formatTick)(client_utils_1.performance.now() - connectStartTime),
433
426
  connectionEstablished: false,
434
427
  });
435
428
  return;
@@ -437,7 +430,10 @@ class ConnectionManager {
437
430
  connectRepeatCount++;
438
431
  try {
439
432
  this.client.mode = requestedMode;
440
- connection = await docService.connectToDeltaStream(Object.assign(Object.assign({}, this.client), { mode: requestedMode }));
433
+ connection = await docService.connectToDeltaStream({
434
+ ...this.client,
435
+ mode: requestedMode,
436
+ });
441
437
  if (connection.disposed) {
442
438
  // Nobody observed this connection, so drop it on the floor and retry.
443
439
  this.logger.sendTelemetryEvent({ eventName: "ReceivedClosedConnection" });
@@ -461,10 +457,10 @@ class ConnectionManager {
461
457
  attempts: connectRepeatCount,
462
458
  delay: delayMs,
463
459
  eventName: "DeltaConnectionFailureToConnect",
464
- duration: telemetry_utils_1.TelemetryLogger.formatTick(common_utils_1.performance.now() - connectStartTime),
460
+ duration: (0, telemetry_utils_1.formatTick)(client_utils_1.performance.now() - connectStartTime),
465
461
  }, origError);
466
462
  lastError = origError;
467
- const waitStartTime = common_utils_1.performance.now();
463
+ const waitStartTime = client_utils_1.performance.now();
468
464
  const retryDelayFromError = (0, driver_utils_1.getRetryDelayFromError)(origError);
469
465
  if (retryDelayFromError !== undefined) {
470
466
  // If the error told us to wait, then we wait.
@@ -473,12 +469,12 @@ class ConnectionManager {
473
469
  setTimeout(resolve, retryDelayFromError);
474
470
  });
475
471
  }
476
- else if (((_c = globalThis.navigator) === null || _c === void 0 ? void 0 : _c.onLine) !== false) {
472
+ else if (globalThis.navigator?.onLine !== false) {
477
473
  // If the error didn't tell us to wait, let's still wait a little bit before retrying.
478
474
  // We skip this delay if we're confident we're offline, because we probably just need to wait to come back online.
479
475
  await new Promise((resolve) => {
480
476
  setTimeout(resolve, delayMs);
481
- delayMs = Math.min(delayMs * 2, MaxReconnectDelayInMs);
477
+ delayMs = Math.min(delayMs * 2, (0, driver_utils_1.calculateMaxWaitTime)(origError));
482
478
  });
483
479
  }
484
480
  // If we believe we're offline, we assume there's no point in trying until we at least think we're online.
@@ -487,7 +483,7 @@ class ConnectionManager {
487
483
  await waitForOnline();
488
484
  this.logger.sendPerformanceEvent({
489
485
  eventName: "WaitBetweenConnectionAttempts",
490
- duration: common_utils_1.performance.now() - waitStartTime,
486
+ duration: client_utils_1.performance.now() - waitStartTime,
491
487
  details: JSON.stringify({
492
488
  retryDelayFromError,
493
489
  delayMs,
@@ -500,7 +496,7 @@ class ConnectionManager {
500
496
  (0, driver_utils_1.logNetworkFailure)(this.logger, {
501
497
  eventName: "MultipleDeltaConnectionFailures",
502
498
  attempts: connectRepeatCount,
503
- duration: telemetry_utils_1.TelemetryLogger.formatTick(common_utils_1.performance.now() - connectStartTime),
499
+ duration: (0, telemetry_utils_1.formatTick)(client_utils_1.performance.now() - connectStartTime),
504
500
  }, lastError);
505
501
  }
506
502
  // Check for abort signal after while loop as well
@@ -509,7 +505,7 @@ class ConnectionManager {
509
505
  this.logger.sendTelemetryEvent({
510
506
  eventName: "ConnectionAttemptCancelled",
511
507
  attempts: connectRepeatCount,
512
- duration: telemetry_utils_1.TelemetryLogger.formatTick(common_utils_1.performance.now() - connectStartTime),
508
+ duration: (0, telemetry_utils_1.formatTick)(client_utils_1.performance.now() - connectStartTime),
513
509
  connectionEstablished: true,
514
510
  });
515
511
  return;
@@ -539,7 +535,7 @@ class ConnectionManager {
539
535
  * @param error - Error causing the disconnect if any.
540
536
  * @returns A boolean that indicates if there was an existing connection (or pending connection) to disconnect
541
537
  */
542
- disconnectFromDeltaStream(reason, error) {
538
+ disconnectFromDeltaStream(reason) {
543
539
  this.pendingReconnect = false;
544
540
  if (this.connection === undefined) {
545
541
  if (this.pendingConnection !== undefined) {
@@ -548,7 +544,7 @@ class ConnectionManager {
548
544
  }
549
545
  return false;
550
546
  }
551
- (0, common_utils_1.assert)(this.pendingConnection === undefined, 0x27b /* "reentrancy may result in incorrect behavior" */);
547
+ (0, core_utils_1.assert)(this.pendingConnection === undefined, 0x27b /* "reentrancy may result in incorrect behavior" */);
552
548
  const connection = this.connection;
553
549
  // Avoid any re-entrancy - clear object reference
554
550
  this.connection = undefined;
@@ -563,7 +559,7 @@ class ConnectionManager {
563
559
  this._outbound.pause();
564
560
  this._outbound.clear();
565
561
  connection.dispose();
566
- this.props.disconnectHandler(reason, error);
562
+ this.props.disconnectHandler(reason);
567
563
  this._connectionVerboseProps = {};
568
564
  return true;
569
565
  }
@@ -571,11 +567,14 @@ class ConnectionManager {
571
567
  * Cancel in-progress connection attempt.
572
568
  */
573
569
  cancelConnection(reason) {
574
- (0, common_utils_1.assert)(this.pendingConnection !== undefined, 0x345 /* this.pendingConnection is undefined when trying to cancel */);
570
+ (0, core_utils_1.assert)(this.pendingConnection !== undefined, 0x345 /* this.pendingConnection is undefined when trying to cancel */);
575
571
  this.pendingConnection.abort();
576
572
  this.pendingConnection = undefined;
577
573
  this.logger.sendTelemetryEvent({ eventName: "ConnectionCancelReceived" });
578
- this.props.cancelConnectionHandler(`Cancel Pending Connection due to ${reason}`);
574
+ this.props.cancelConnectionHandler({
575
+ text: `Cancel Pending Connection due to ${reason.text}`,
576
+ error: reason.error,
577
+ });
579
578
  }
580
579
  /**
581
580
  * Once we've successfully gotten a connection, we need to set up state, attach event listeners, and process
@@ -583,11 +582,11 @@ class ConnectionManager {
583
582
  * @param connection - The newly established connection
584
583
  */
585
584
  setupNewSuccessfulConnection(connection, requestedMode, reason) {
586
- var _a;
587
585
  // Old connection should have been cleaned up before establishing a new one
588
- (0, common_utils_1.assert)(this.connection === undefined, 0x0e6 /* "old connection exists on new connection setup" */);
589
- (0, common_utils_1.assert)(!connection.disposed, 0x28a /* "can't be disposed - Callers need to ensure that!" */);
586
+ (0, core_utils_1.assert)(this.connection === undefined, 0x0e6 /* "old connection exists on new connection setup" */);
587
+ (0, core_utils_1.assert)(!connection.disposed, 0x28a /* "can't be disposed - Callers need to ensure that!" */);
590
588
  this.pendingConnection = undefined;
589
+ const oldReadonlyValue = this.readonly;
591
590
  this.connection = connection;
592
591
  // Does information in scopes & mode matches?
593
592
  // If we asked for "write" and got "read", then file is read-only
@@ -602,12 +601,12 @@ class ConnectionManager {
602
601
  }
603
602
  // This connection mode validation logic is moving to the driver layer in 0.44. These two asserts can be
604
603
  // removed after those packages have released and become ubiquitous.
605
- (0, common_utils_1.assert)(requestedMode === "read" || readonly === (this.connectionMode === "read"), 0x0e7 /* "claims/connectionMode mismatch" */);
606
- (0, common_utils_1.assert)(!readonly || this.connectionMode === "read", 0x0e8 /* "readonly perf with write connection" */);
607
- this.set_readonlyPermissions(readonly);
604
+ (0, core_utils_1.assert)(requestedMode === "read" || readonly === (this.connectionMode === "read"), 0x0e7 /* "claims/connectionMode mismatch" */);
605
+ (0, core_utils_1.assert)(!readonly || this.connectionMode === "read", 0x0e8 /* "readonly perf with write connection" */);
606
+ this.set_readonlyPermissions(readonly, oldReadonlyValue);
608
607
  if (this._disposed) {
609
608
  // Raise proper events, Log telemetry event and close connection.
610
- this.disconnectFromDeltaStream("ConnectionManager already closed");
609
+ this.disconnectFromDeltaStream({ text: "ConnectionManager already closed" });
611
610
  return;
612
611
  }
613
612
  this._outbound.resume();
@@ -664,7 +663,7 @@ class ConnectionManager {
664
663
  }),
665
664
  };
666
665
  this.props.signalHandler(clearSignal);
667
- for (const priorClient of (_a = connection.initialClients) !== null && _a !== void 0 ? _a : []) {
666
+ for (const priorClient of connection.initialClients ?? []) {
668
667
  const joinSignal = {
669
668
  clientId: null,
670
669
  content: JSON.stringify({
@@ -692,7 +691,7 @@ class ConnectionManager {
692
691
  * @returns A promise that resolves when the connection is reestablished or we stop trying
693
692
  */
694
693
  reconnectOnError(requestedMode, error) {
695
- this.reconnect(requestedMode, error.message, error).catch(this.props.closeHandler);
694
+ this.reconnect(requestedMode, { text: error.message, error }).catch(this.props.closeHandler);
696
695
  }
697
696
  /**
698
697
  * Disconnect the current connection and reconnect.
@@ -701,20 +700,20 @@ class ConnectionManager {
701
700
  * @param error - Error reconnect information including whether or not to reconnect
702
701
  * @returns A promise that resolves when the connection is reestablished or we stop trying
703
702
  */
704
- async reconnect(requestedMode, disconnectMessage, error) {
703
+ async reconnect(requestedMode, reason) {
705
704
  // We quite often get protocol errors before / after observing nack/disconnect
706
705
  // we do not want to run through same sequence twice.
707
706
  // If we're already disconnected/disconnecting it's not appropriate to call this again.
708
- (0, common_utils_1.assert)(this.connection !== undefined, 0x0eb /* "Missing connection for reconnect" */);
709
- this.disconnectFromDeltaStream(disconnectMessage, error);
707
+ (0, core_utils_1.assert)(this.connection !== undefined, 0x0eb /* "Missing connection for reconnect" */);
708
+ this.disconnectFromDeltaStream(reason);
710
709
  // We will always trigger reconnect, even if canRetry is false.
711
710
  // Any truly fatal error state will result in container close upon attempted reconnect,
712
711
  // which is a preferable to closing abruptly when a live connection fails.
713
- if (error !== undefined && !error.canRetry) {
712
+ if (reason.error?.canRetry === false) {
714
713
  this.logger.sendTelemetryEvent({
715
714
  eventName: "reconnectingDespiteFatalError",
716
715
  reconnectMode: this.reconnectMode,
717
- }, error);
716
+ }, reason.error);
718
717
  }
719
718
  if (this.reconnectMode === contracts_1.ReconnectMode.Never) {
720
719
  // Do not raise container error if we are closing just because we lost connection.
@@ -727,9 +726,9 @@ class ConnectionManager {
727
726
  return;
728
727
  }
729
728
  // If the error tells us to wait before retrying, then do so.
730
- const delayMs = (0, driver_utils_1.getRetryDelayFromError)(error);
731
- if (error !== undefined && delayMs !== undefined) {
732
- this.props.reconnectionDelayHandler(delayMs, error);
729
+ const delayMs = (0, driver_utils_1.getRetryDelayFromError)(reason.error);
730
+ if (reason.error !== undefined && delayMs !== undefined) {
731
+ this.props.reconnectionDelayHandler(delayMs, reason.error);
733
732
  await new Promise((resolve) => {
734
733
  setTimeout(resolve, delayMs);
735
734
  });
@@ -738,15 +737,17 @@ class ConnectionManager {
738
737
  // NOTE: This isn't strictly true for drivers that don't require network (e.g. local driver). Really this logic
739
738
  // should probably live in the driver.
740
739
  await waitForOnline();
741
- this.triggerConnect(error !== undefined
742
- ? "Reconnecting due to Error"
743
- : `Reconnecting due to: ${disconnectMessage}`, requestedMode);
740
+ this.triggerConnect({
741
+ text: reason.error !== undefined
742
+ ? "Reconnecting due to Error"
743
+ : `Reconnecting due to: ${reason.text}`,
744
+ error: reason.error,
745
+ }, requestedMode);
744
746
  }
745
747
  prepareMessageToSend(message) {
746
- var _a, _b;
747
748
  if (this.readonly === true) {
748
- (0, common_utils_1.assert)(this.readOnlyInfo.readonly === true, 0x1f0 /* "Unexpected mismatch in readonly" */);
749
- const error = new container_utils_1.GenericError("deltaManagerReadonlySubmit", undefined /* error */, {
749
+ (0, core_utils_1.assert)(this.readOnlyInfo.readonly === true, 0x1f0 /* "Unexpected mismatch in readonly" */);
750
+ const error = new telemetry_utils_1.GenericError("deltaManagerReadonlySubmit", undefined /* error */, {
750
751
  readonly: this.readOnlyInfo.readonly,
751
752
  forcedReadonly: this.readOnlyInfo.forced,
752
753
  readonlyPermissions: this.readOnlyInfo.permissions,
@@ -759,9 +760,9 @@ class ConnectionManager {
759
760
  // reset clientSequenceNumber if we are using new clientId.
760
761
  // we keep info about old connection as long as possible to be able to account for all non-acked ops
761
762
  // that we pick up on next connection.
762
- (0, common_utils_1.assert)(!!this.connection, 0x0e4 /* "Lost old connection!" */);
763
- if (this.lastSubmittedClientId !== ((_a = this.connection) === null || _a === void 0 ? void 0 : _a.clientId)) {
764
- this.lastSubmittedClientId = (_b = this.connection) === null || _b === void 0 ? void 0 : _b.clientId;
763
+ (0, core_utils_1.assert)(!!this.connection, 0x0e4 /* "Lost old connection!" */);
764
+ if (this.lastSubmittedClientId !== this.connection?.clientId) {
765
+ this.lastSubmittedClientId = this.connection?.clientId;
765
766
  this.clientSequenceNumber = 0;
766
767
  this.clientSequenceNumberObserved = 0;
767
768
  }
@@ -771,7 +772,10 @@ class ConnectionManager {
771
772
  else {
772
773
  this.localOpsToIgnore = 0;
773
774
  }
774
- return Object.assign(Object.assign({}, message), { clientSequenceNumber: ++this.clientSequenceNumber });
775
+ return {
776
+ ...message,
777
+ clientSequenceNumber: ++this.clientSequenceNumber,
778
+ };
775
779
  }
776
780
  submitSignal(content) {
777
781
  if (this.connection !== undefined) {
@@ -782,7 +786,7 @@ class ConnectionManager {
782
786
  }
783
787
  }
784
788
  sendMessages(messages) {
785
- (0, common_utils_1.assert)(this.connected, 0x2b4 /* "not connected on sending ops!" */);
789
+ (0, core_utils_1.assert)(this.connected, 0x2b4 /* "not connected on sending ops!" */);
786
790
  // If connection is "read" or implicit "read" (got leave op for "write" connection),
787
791
  // then op can't make it through - we will get a nack if op is sent.
788
792
  // We can short-circuit this process.
@@ -797,24 +801,24 @@ class ConnectionManager {
797
801
  if (this.pendingReconnect) {
798
802
  // still valid?
799
803
  await this.reconnect("write", // connectionMode
800
- "Switch to write");
804
+ { text: "Switch to write" });
801
805
  }
802
806
  })
803
807
  .catch(() => { });
804
808
  }
805
809
  return;
806
810
  }
807
- (0, common_utils_1.assert)(!this.pendingReconnect, 0x2b5 /* "logic error" */);
811
+ (0, core_utils_1.assert)(!this.pendingReconnect, 0x2b5 /* "logic error" */);
808
812
  this._outbound.push(messages);
809
813
  }
810
814
  beforeProcessingIncomingOp(message) {
811
815
  // if we have connection, and message is local, then we better treat is as local!
812
- (0, common_utils_1.assert)(this.clientId !== message.clientId || this.lastSubmittedClientId === message.clientId, 0x0ee /* "Not accounting local messages correctly" */);
816
+ (0, core_utils_1.assert)(this.clientId !== message.clientId || this.lastSubmittedClientId === message.clientId, 0x0ee /* "Not accounting local messages correctly" */);
813
817
  if (this.lastSubmittedClientId !== undefined &&
814
818
  this.lastSubmittedClientId === message.clientId) {
815
819
  const clientSequenceNumber = message.clientSequenceNumber;
816
- (0, common_utils_1.assert)(this.clientSequenceNumberObserved < clientSequenceNumber, 0x0ef /* "client seq# not growing" */);
817
- (0, common_utils_1.assert)(clientSequenceNumber <= this.clientSequenceNumber, 0x0f0 /* "Incoming local client seq# > generated by this client" */);
820
+ (0, core_utils_1.assert)(this.clientSequenceNumberObserved < clientSequenceNumber, 0x0ef /* "client seq# not growing" */);
821
+ (0, core_utils_1.assert)(clientSequenceNumber <= this.clientSequenceNumber, 0x0f0 /* "Incoming local client seq# > generated by this client" */);
818
822
  this.clientSequenceNumberObserved = clientSequenceNumber;
819
823
  }
820
824
  if (message.type === protocol_definitions_1.MessageType.ClientLeave) {
@@ -830,7 +834,7 @@ class ConnectionManager {
830
834
  // Clients need to be able to transition to "read" state after some time of inactivity!
831
835
  // Note - this may close container!
832
836
  this.reconnect("read", // connectionMode
833
- "Switch to read").catch((error) => {
837
+ { text: "Switch to read" }).catch((error) => {
834
838
  this.logger.sendErrorEvent({ eventName: "SwitchToReadConnection" }, error);
835
839
  });
836
840
  }