@fluidframework/container-loader 2.0.0-rc.2.0.2 → 2.0.0-rc.3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/api-report/container-loader.api.md +13 -13
  3. package/dist/attachment.d.ts +6 -9
  4. package/dist/attachment.d.ts.map +1 -1
  5. package/dist/attachment.js +5 -5
  6. package/dist/attachment.js.map +1 -1
  7. package/dist/audience.d.ts +1 -1
  8. package/dist/audience.d.ts.map +1 -1
  9. package/dist/audience.js +4 -4
  10. package/dist/audience.js.map +1 -1
  11. package/dist/catchUpMonitor.d.ts +1 -1
  12. package/dist/catchUpMonitor.d.ts.map +1 -1
  13. package/dist/catchUpMonitor.js +2 -2
  14. package/dist/catchUpMonitor.js.map +1 -1
  15. package/dist/connectionManager.d.ts +4 -4
  16. package/dist/connectionManager.d.ts.map +1 -1
  17. package/dist/connectionManager.js +48 -43
  18. package/dist/connectionManager.js.map +1 -1
  19. package/dist/connectionStateHandler.d.ts +3 -3
  20. package/dist/connectionStateHandler.d.ts.map +1 -1
  21. package/dist/connectionStateHandler.js +27 -27
  22. package/dist/connectionStateHandler.js.map +1 -1
  23. package/dist/container.d.ts +9 -46
  24. package/dist/container.d.ts.map +1 -1
  25. package/dist/container.js +105 -116
  26. package/dist/container.js.map +1 -1
  27. package/dist/containerContext.d.ts +19 -7
  28. package/dist/containerContext.d.ts.map +1 -1
  29. package/dist/containerContext.js +7 -2
  30. package/dist/containerContext.js.map +1 -1
  31. package/dist/containerStorageAdapter.d.ts +3 -3
  32. package/dist/containerStorageAdapter.d.ts.map +1 -1
  33. package/dist/containerStorageAdapter.js +6 -6
  34. package/dist/containerStorageAdapter.js.map +1 -1
  35. package/dist/contracts.d.ts +4 -3
  36. package/dist/contracts.d.ts.map +1 -1
  37. package/dist/contracts.js +2 -2
  38. package/dist/contracts.js.map +1 -1
  39. package/dist/debugLogger.d.ts +2 -1
  40. package/dist/debugLogger.d.ts.map +1 -1
  41. package/dist/debugLogger.js +4 -4
  42. package/dist/debugLogger.js.map +1 -1
  43. package/dist/deltaManager.d.ts +11 -7
  44. package/dist/deltaManager.d.ts.map +1 -1
  45. package/dist/deltaManager.js +53 -50
  46. package/dist/deltaManager.js.map +1 -1
  47. package/dist/deltaQueue.d.ts +1 -1
  48. package/dist/deltaQueue.d.ts.map +1 -1
  49. package/dist/deltaQueue.js +5 -5
  50. package/dist/deltaQueue.js.map +1 -1
  51. package/dist/error.d.ts +3 -2
  52. package/dist/error.d.ts.map +1 -1
  53. package/dist/error.js +5 -5
  54. package/dist/error.js.map +1 -1
  55. package/dist/legacy.d.ts +29 -0
  56. package/dist/loader.d.ts +4 -4
  57. package/dist/loader.d.ts.map +1 -1
  58. package/dist/loader.js +23 -23
  59. package/dist/loader.js.map +1 -1
  60. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -2
  61. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  62. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +2 -2
  63. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  64. package/dist/noopHeuristic.d.ts +1 -1
  65. package/dist/noopHeuristic.d.ts.map +1 -1
  66. package/dist/noopHeuristic.js +6 -6
  67. package/dist/noopHeuristic.js.map +1 -1
  68. package/dist/packageVersion.d.ts +1 -1
  69. package/dist/packageVersion.js +1 -1
  70. package/dist/packageVersion.js.map +1 -1
  71. package/dist/protocol.d.ts +1 -1
  72. package/dist/protocol.d.ts.map +1 -1
  73. package/dist/protocol.js +2 -2
  74. package/dist/protocol.js.map +1 -1
  75. package/dist/protocolTreeDocumentStorageService.d.ts +4 -4
  76. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  77. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  78. package/dist/public.d.ts +14 -0
  79. package/dist/quorum.d.ts +1 -1
  80. package/dist/quorum.d.ts.map +1 -1
  81. package/dist/quorum.js +4 -0
  82. package/dist/quorum.js.map +1 -1
  83. package/dist/retriableDocumentStorageService.d.ts +2 -2
  84. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  85. package/dist/retriableDocumentStorageService.js +7 -7
  86. package/dist/retriableDocumentStorageService.js.map +1 -1
  87. package/dist/serializedStateManager.d.ts +86 -16
  88. package/dist/serializedStateManager.d.ts.map +1 -1
  89. package/dist/serializedStateManager.js +182 -82
  90. package/dist/serializedStateManager.js.map +1 -1
  91. package/dist/utils.d.ts +24 -9
  92. package/dist/utils.d.ts.map +1 -1
  93. package/dist/utils.js +82 -25
  94. package/dist/utils.js.map +1 -1
  95. package/internal.d.ts +11 -0
  96. package/legacy.d.ts +11 -0
  97. package/lib/attachment.d.ts +6 -9
  98. package/lib/attachment.d.ts.map +1 -1
  99. package/lib/attachment.js +1 -1
  100. package/lib/attachment.js.map +1 -1
  101. package/lib/audience.d.ts +1 -1
  102. package/lib/audience.d.ts.map +1 -1
  103. package/lib/audience.js +1 -1
  104. package/lib/audience.js.map +1 -1
  105. package/lib/catchUpMonitor.d.ts +1 -1
  106. package/lib/catchUpMonitor.d.ts.map +1 -1
  107. package/lib/catchUpMonitor.js +1 -1
  108. package/lib/catchUpMonitor.js.map +1 -1
  109. package/lib/connectionManager.d.ts +4 -4
  110. package/lib/connectionManager.d.ts.map +1 -1
  111. package/lib/connectionManager.js +11 -6
  112. package/lib/connectionManager.js.map +1 -1
  113. package/lib/connectionStateHandler.d.ts +3 -3
  114. package/lib/connectionStateHandler.d.ts.map +1 -1
  115. package/lib/connectionStateHandler.js +2 -2
  116. package/lib/connectionStateHandler.js.map +1 -1
  117. package/lib/container.d.ts +9 -46
  118. package/lib/container.d.ts.map +1 -1
  119. package/lib/container.js +37 -48
  120. package/lib/container.js.map +1 -1
  121. package/lib/containerContext.d.ts +19 -7
  122. package/lib/containerContext.d.ts.map +1 -1
  123. package/lib/containerContext.js +7 -2
  124. package/lib/containerContext.js.map +1 -1
  125. package/lib/containerStorageAdapter.d.ts +3 -3
  126. package/lib/containerStorageAdapter.d.ts.map +1 -1
  127. package/lib/containerStorageAdapter.js +2 -2
  128. package/lib/containerStorageAdapter.js.map +1 -1
  129. package/lib/contracts.d.ts +4 -3
  130. package/lib/contracts.d.ts.map +1 -1
  131. package/lib/contracts.js +1 -1
  132. package/lib/contracts.js.map +1 -1
  133. package/lib/debugLogger.d.ts +2 -1
  134. package/lib/debugLogger.d.ts.map +1 -1
  135. package/lib/debugLogger.js +1 -1
  136. package/lib/debugLogger.js.map +1 -1
  137. package/lib/deltaManager.d.ts +11 -7
  138. package/lib/deltaManager.d.ts.map +1 -1
  139. package/lib/deltaManager.js +13 -10
  140. package/lib/deltaManager.js.map +1 -1
  141. package/lib/deltaQueue.d.ts +1 -1
  142. package/lib/deltaQueue.d.ts.map +1 -1
  143. package/lib/deltaQueue.js +2 -2
  144. package/lib/deltaQueue.js.map +1 -1
  145. package/lib/error.d.ts +3 -2
  146. package/lib/error.d.ts.map +1 -1
  147. package/lib/error.js +2 -2
  148. package/lib/error.js.map +1 -1
  149. package/lib/legacy.d.ts +29 -0
  150. package/lib/loader.d.ts +4 -4
  151. package/lib/loader.d.ts.map +1 -1
  152. package/lib/loader.js +4 -4
  153. package/lib/loader.js.map +1 -1
  154. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -2
  155. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  156. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +2 -2
  157. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  158. package/lib/noopHeuristic.d.ts +1 -1
  159. package/lib/noopHeuristic.d.ts.map +1 -1
  160. package/lib/noopHeuristic.js +2 -2
  161. package/lib/noopHeuristic.js.map +1 -1
  162. package/lib/packageVersion.d.ts +1 -1
  163. package/lib/packageVersion.js +1 -1
  164. package/lib/packageVersion.js.map +1 -1
  165. package/lib/protocol.d.ts +1 -1
  166. package/lib/protocol.d.ts.map +1 -1
  167. package/lib/protocol.js +1 -1
  168. package/lib/protocol.js.map +1 -1
  169. package/lib/protocolTreeDocumentStorageService.d.ts +4 -4
  170. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
  171. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  172. package/lib/public.d.ts +14 -0
  173. package/lib/quorum.d.ts +1 -1
  174. package/lib/quorum.d.ts.map +1 -1
  175. package/lib/quorum.js +4 -0
  176. package/lib/quorum.js.map +1 -1
  177. package/lib/retriableDocumentStorageService.d.ts +2 -2
  178. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  179. package/lib/retriableDocumentStorageService.js +3 -3
  180. package/lib/retriableDocumentStorageService.js.map +1 -1
  181. package/lib/serializedStateManager.d.ts +86 -16
  182. package/lib/serializedStateManager.d.ts.map +1 -1
  183. package/lib/serializedStateManager.js +174 -77
  184. package/lib/serializedStateManager.js.map +1 -1
  185. package/lib/utils.d.ts +24 -9
  186. package/lib/utils.d.ts.map +1 -1
  187. package/lib/utils.js +69 -15
  188. package/lib/utils.js.map +1 -1
  189. package/package.json +37 -58
  190. package/src/attachment.ts +10 -8
  191. package/src/audience.ts +3 -2
  192. package/src/catchUpMonitor.ts +2 -2
  193. package/src/connectionManager.ts +27 -20
  194. package/src/connectionStateHandler.ts +7 -7
  195. package/src/container.ts +90 -143
  196. package/src/containerContext.ts +22 -12
  197. package/src/containerStorageAdapter.ts +7 -6
  198. package/src/contracts.ts +4 -5
  199. package/src/debugLogger.ts +3 -4
  200. package/src/deltaManager.ts +40 -30
  201. package/src/deltaQueue.ts +2 -2
  202. package/src/error.ts +5 -4
  203. package/src/loader.ts +25 -23
  204. package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +4 -4
  205. package/src/noopHeuristic.ts +3 -3
  206. package/src/packageVersion.ts +1 -1
  207. package/src/protocol.ts +2 -2
  208. package/src/protocolTreeDocumentStorageService.ts +4 -1
  209. package/src/quorum.ts +2 -1
  210. package/src/retriableDocumentStorageService.ts +6 -5
  211. package/src/serializedStateManager.ts +299 -111
  212. package/src/utils.ts +103 -24
  213. package/api-extractor-cjs.json +0 -8
  214. package/dist/container-loader-alpha.d.ts +0 -275
  215. package/dist/container-loader-beta.d.ts +0 -101
  216. package/dist/container-loader-public.d.ts +0 -101
  217. package/dist/container-loader-untrimmed.d.ts +0 -331
  218. package/lib/container-loader-alpha.d.ts +0 -275
  219. package/lib/container-loader-beta.d.ts +0 -101
  220. package/lib/container-loader-public.d.ts +0 -101
  221. package/lib/container-loader-untrimmed.d.ts +0 -331
  222. package/lib/test/attachment.spec.js +0 -380
  223. package/lib/test/attachment.spec.js.map +0 -1
  224. package/lib/test/catchUpMonitor.spec.js +0 -88
  225. package/lib/test/catchUpMonitor.spec.js.map +0 -1
  226. package/lib/test/connectionManager.spec.js +0 -201
  227. package/lib/test/connectionManager.spec.js.map +0 -1
  228. package/lib/test/connectionStateHandler.spec.js +0 -555
  229. package/lib/test/connectionStateHandler.spec.js.map +0 -1
  230. package/lib/test/container.spec.js +0 -64
  231. package/lib/test/container.spec.js.map +0 -1
  232. package/lib/test/deltaManager.spec.js +0 -405
  233. package/lib/test/deltaManager.spec.js.map +0 -1
  234. package/lib/test/loader.spec.js +0 -212
  235. package/lib/test/loader.spec.js.map +0 -1
  236. package/lib/test/locationRedirectionTests.spec.js +0 -44
  237. package/lib/test/locationRedirectionTests.spec.js.map +0 -1
  238. package/lib/test/serializedStateManager.spec.js +0 -148
  239. package/lib/test/serializedStateManager.spec.js.map +0 -1
  240. package/lib/test/snapshotConversionTest.spec.js +0 -79
  241. package/lib/test/snapshotConversionTest.spec.js.map +0 -1
  242. package/lib/test/types/validateContainerLoaderPrevious.generated.js +0 -38
  243. package/lib/test/types/validateContainerLoaderPrevious.generated.js.map +0 -1
  244. package/lib/test/utils.spec.js +0 -31
  245. package/lib/test/utils.spec.js.map +0 -1
  246. /package/{dist → lib}/tsdoc-metadata.json +0 -0
@@ -1,201 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "assert";
6
- import { MockDocumentDeltaConnection, MockDocumentService } from "@fluid-private/test-loader-utils";
7
- import { Deferred } from "@fluidframework/core-utils";
8
- import { DriverErrorTypes, } from "@fluidframework/driver-definitions";
9
- import { NonRetryableError, RetryableError } from "@fluidframework/driver-utils";
10
- import { NackErrorType } from "@fluidframework/protocol-definitions";
11
- import { MockLogger } from "@fluidframework/telemetry-utils";
12
- import { ConnectionManager } from "../connectionManager.js";
13
- import { pkgVersion } from "../packageVersion.js";
14
- describe("connectionManager", () => {
15
- let nextClientId = 0;
16
- let _mockDeltaConnection;
17
- let mockDocumentService;
18
- const client = {
19
- details: { capabilities: { interactive: true } },
20
- mode: "write",
21
- };
22
- let closed = false;
23
- let connectionCount = 0;
24
- let connectionDeferred = new Deferred();
25
- let disconnectCount = 0;
26
- const props = {
27
- closeHandler: (_error) => {
28
- closed = true;
29
- },
30
- connectHandler: () => {
31
- ++connectionCount;
32
- assert(_mockDeltaConnection !== undefined, "When connectHandler is invoked, _mockDeltaConnection should have been set");
33
- connectionDeferred.resolve(_mockDeltaConnection);
34
- connectionDeferred = new Deferred();
35
- },
36
- disconnectHandler: () => {
37
- ++disconnectCount;
38
- },
39
- incomingOpHandler: () => { },
40
- pongHandler: () => { },
41
- readonlyChangeHandler: () => { },
42
- reconnectionDelayHandler: () => { },
43
- signalHandler: () => { },
44
- establishConnectionHandler: () => { },
45
- cancelConnectionHandler: () => { },
46
- };
47
- const mockLogger = new MockLogger();
48
- async function waitForConnection() {
49
- return connectionDeferred.promise;
50
- }
51
- beforeEach(() => {
52
- nextClientId = 0;
53
- _mockDeltaConnection = undefined;
54
- closed = false;
55
- connectionCount = 0;
56
- connectionDeferred = new Deferred();
57
- disconnectCount = 0;
58
- mockDocumentService = new MockDocumentService(undefined /* deltaStorageFactory */, () => {
59
- _mockDeltaConnection = new MockDocumentDeltaConnection(`mock_client_${nextClientId++}`);
60
- return _mockDeltaConnection;
61
- });
62
- });
63
- function createConnectionManager() {
64
- return new ConnectionManager(() => mockDocumentService, () => false, client, true /* reconnectAllowed */, mockLogger.toTelemetryLogger(), props);
65
- }
66
- it("reconnectOnError - exceptions invoke closeHandler", async () => {
67
- // Arrange
68
- const connectionManager = createConnectionManager();
69
- connectionManager.connect({ text: "test:reconnectOnError" });
70
- const connection = await waitForConnection();
71
- // Monkey patch connection to be undefined to trigger assert in reconnectOnError
72
- connectionManager.connection = undefined;
73
- // Act
74
- connection.emitError({
75
- errorType: DriverErrorTypes.genericError,
76
- message: "whatever",
77
- canRetry: true,
78
- });
79
- await Promise.resolve(); // So we get the promise rejection that calls closeHandler
80
- // Assert
81
- assert(closed, "ConnectionManager should close if reconnect throws an error, e.g. hits an assert");
82
- });
83
- it("reconnectOnError - error, disconnect, and nack handling", async () => {
84
- // Arrange
85
- const connectionManager = createConnectionManager();
86
- connectionManager.connect({ text: "test:reconnectOnError" });
87
- let connection = await waitForConnection();
88
- // Act I - retryableError
89
- const error = new RetryableError("Retryable error", DriverErrorTypes.genericError, { driverVersion: pkgVersion });
90
- let oldConnection = connection;
91
- connection.emitError(error);
92
- connection = await waitForConnection();
93
- // Assert I
94
- assert(oldConnection.disposed, "Old connection should be disposed after emitting an error");
95
- assert.equal(connection.clientId, "mock_client_1", "New connection should have expected id");
96
- assert(!closed, "Don't expect closeHandler to be called when connection emits an error");
97
- assert.equal(disconnectCount, 1, "Expected 1 disconnect from emitting an error");
98
- assert.equal(connectionCount, 2, "Expected 2 connections after the first emitted an error");
99
- // Act II - nonretryable disconnect
100
- const disconnectReason = new NonRetryableError("Fatal disconnect reason", DriverErrorTypes.genericError, { driverVersion: pkgVersion });
101
- oldConnection = connection;
102
- connection.emitDisconnect(disconnectReason);
103
- connection = await waitForConnection();
104
- // Assert II
105
- assert(oldConnection.disposed, "Old connection should be disposed after emitting disconnect");
106
- assert.equal(connection.clientId, "mock_client_2", "New connection should have expected id");
107
- mockLogger.assertMatchAny([
108
- {
109
- eventName: "reconnectingDespiteFatalError",
110
- reconnectMode: "Enabled",
111
- error: "Fatal disconnect reason",
112
- canRetry: false,
113
- },
114
- ]);
115
- assert(!closed, "Don't expect closeHandler to be called even when connection emits a non-retryable disconnect");
116
- assert.equal(disconnectCount, 2, "Expected 2 disconnects from emitting an error and disconnect");
117
- assert.equal(connectionCount, 3, "Expected 3 connections after the two disconnects");
118
- // Act III - nonretryable nack
119
- const nack = {
120
- content: { code: 403, type: NackErrorType.BadRequestError, message: "fatalNack" },
121
- };
122
- oldConnection = connection;
123
- connection.emitNack("docId", [nack]);
124
- // Assert III
125
- assert(closed, "closeHandler should be called in response to 403 nack");
126
- assert(!oldConnection.disposed, "connection shouldn't be disposed since mock closeHandler doesn't do it - don't expect it here after fatal nack");
127
- assert(!mockLogger.matchEvents([{ eventName: "reconnectingDespiteFatalError" }]), "Should not see reconnectingDespiteFatalError event after fatal nack");
128
- });
129
- it("reconnectOnError - nack retryAfter", async () => {
130
- const connectionManager = createConnectionManager();
131
- connectionManager.connect({ text: "test:reconnectOnError" });
132
- let connection = await waitForConnection();
133
- const nack = {
134
- content: {
135
- code: 429,
136
- type: NackErrorType.ThrottlingError,
137
- message: "throttled",
138
- retryAfter: 0.5, // 500 ms
139
- },
140
- };
141
- connection.emitNack("docId", [nack]);
142
- assert(!closed, "Don't expect closeHandler to be called with retryable Nack");
143
- assert(connection.disposed, "Expect connection to be disconnected");
144
- assert.strictEqual(disconnectCount, 1, "Expect 1 disconnect from emitting a Nack");
145
- // Async test we aren't connected within 300 ms
146
- let checkedTimeout = false;
147
- setTimeout(() => {
148
- assert.strictEqual(connectionCount, 1, "Expect there to still not be a connection yet");
149
- checkedTimeout = true;
150
- }, 300);
151
- connection = await waitForConnection();
152
- assert.strictEqual(connectionCount, 2, "Expect there to be a connection after waiting");
153
- assert(checkedTimeout, "Expected to have checked 300ms timeout");
154
- });
155
- describe("readonly", () => {
156
- it("default is undefined", () => {
157
- const connectionManager = createConnectionManager();
158
- assert.deepStrictEqual(connectionManager.readOnlyInfo, { readonly: undefined });
159
- });
160
- it("force readonly", () => {
161
- const connectionManager = createConnectionManager();
162
- connectionManager.forceReadonly(false);
163
- assert.deepStrictEqual(connectionManager.readOnlyInfo, { readonly: undefined });
164
- connectionManager.forceReadonly(true);
165
- assert.deepStrictEqual(connectionManager.readOnlyInfo, {
166
- readonly: true,
167
- forced: true,
168
- permissions: undefined,
169
- storageOnly: false,
170
- storageOnlyReason: undefined,
171
- });
172
- });
173
- it("readonly permissions", () => {
174
- const connectionManager = createConnectionManager();
175
- connectionManager.set_readonlyPermissions(false);
176
- assert.deepStrictEqual(connectionManager.readOnlyInfo, { readonly: false });
177
- connectionManager.set_readonlyPermissions(true);
178
- assert.deepStrictEqual(connectionManager.readOnlyInfo, {
179
- readonly: true,
180
- forced: false,
181
- permissions: true,
182
- storageOnly: false,
183
- storageOnlyReason: undefined,
184
- });
185
- });
186
- it("storage only", () => {
187
- const connectionManager = createConnectionManager();
188
- mockDocumentService.policies = { storageOnly: true };
189
- assert.deepStrictEqual(connectionManager.readOnlyInfo, { readonly: undefined });
190
- connectionManager.connect({ text: "test" });
191
- assert.deepStrictEqual(connectionManager.readOnlyInfo, {
192
- readonly: true,
193
- forced: false,
194
- permissions: true,
195
- storageOnly: true,
196
- storageOnlyReason: undefined,
197
- });
198
- });
199
- });
200
- });
201
- //# sourceMappingURL=connectionManager.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connectionManager.spec.js","sourceRoot":"","sources":["../../src/test/connectionManager.spec.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 { strict as assert } from \"assert\";\nimport { MockDocumentDeltaConnection, MockDocumentService } from \"@fluid-private/test-loader-utils\";\nimport { Deferred } from \"@fluidframework/core-utils\";\nimport {\n\tDriverErrorTypes,\n\tIAnyDriverError,\n\tIDocumentService,\n} from \"@fluidframework/driver-definitions\";\nimport { NonRetryableError, RetryableError } from \"@fluidframework/driver-utils\";\nimport { IClient, INack, NackErrorType } from \"@fluidframework/protocol-definitions\";\nimport { MockLogger } from \"@fluidframework/telemetry-utils\";\nimport { ConnectionManager } from \"../connectionManager.js\";\nimport { IConnectionManagerFactoryArgs } from \"../contracts.js\";\nimport { pkgVersion } from \"../packageVersion.js\";\n\ndescribe(\"connectionManager\", () => {\n\tlet nextClientId = 0;\n\tlet _mockDeltaConnection: MockDocumentDeltaConnection | undefined;\n\tlet mockDocumentService: IDocumentService;\n\tconst client: Partial<IClient> = {\n\t\tdetails: { capabilities: { interactive: true } },\n\t\tmode: \"write\",\n\t};\n\tlet closed = false;\n\tlet connectionCount = 0;\n\tlet connectionDeferred = new Deferred<MockDocumentDeltaConnection>();\n\tlet disconnectCount = 0;\n\tconst props: IConnectionManagerFactoryArgs = {\n\t\tcloseHandler: (_error) => {\n\t\t\tclosed = true;\n\t\t},\n\t\tconnectHandler: () => {\n\t\t\t++connectionCount;\n\t\t\tassert(\n\t\t\t\t_mockDeltaConnection !== undefined,\n\t\t\t\t\"When connectHandler is invoked, _mockDeltaConnection should have been set\",\n\t\t\t);\n\t\t\tconnectionDeferred.resolve(_mockDeltaConnection);\n\t\t\tconnectionDeferred = new Deferred();\n\t\t},\n\t\tdisconnectHandler: () => {\n\t\t\t++disconnectCount;\n\t\t},\n\t\tincomingOpHandler: () => {},\n\t\tpongHandler: () => {},\n\t\treadonlyChangeHandler: () => {},\n\t\treconnectionDelayHandler: () => {},\n\t\tsignalHandler: () => {},\n\t\testablishConnectionHandler: () => {},\n\t\tcancelConnectionHandler: () => {},\n\t};\n\n\tconst mockLogger = new MockLogger();\n\tasync function waitForConnection() {\n\t\treturn connectionDeferred.promise;\n\t}\n\tbeforeEach(() => {\n\t\tnextClientId = 0;\n\t\t_mockDeltaConnection = undefined;\n\t\tclosed = false;\n\t\tconnectionCount = 0;\n\t\tconnectionDeferred = new Deferred<MockDocumentDeltaConnection>();\n\t\tdisconnectCount = 0;\n\t\tmockDocumentService = new MockDocumentService(undefined /* deltaStorageFactory */, () => {\n\t\t\t_mockDeltaConnection = new MockDocumentDeltaConnection(`mock_client_${nextClientId++}`);\n\t\t\treturn _mockDeltaConnection;\n\t\t});\n\t});\n\n\tfunction createConnectionManager(): ConnectionManager {\n\t\treturn new ConnectionManager(\n\t\t\t() => mockDocumentService,\n\t\t\t() => false,\n\t\t\tclient as IClient,\n\t\t\ttrue /* reconnectAllowed */,\n\t\t\tmockLogger.toTelemetryLogger(),\n\t\t\tprops,\n\t\t);\n\t}\n\n\tit(\"reconnectOnError - exceptions invoke closeHandler\", async () => {\n\t\t// Arrange\n\t\tconst connectionManager = createConnectionManager();\n\t\tconnectionManager.connect({ text: \"test:reconnectOnError\" });\n\t\tconst connection = await waitForConnection();\n\n\t\t// Monkey patch connection to be undefined to trigger assert in reconnectOnError\n\t\t(connectionManager as any).connection = undefined;\n\n\t\t// Act\n\t\tconnection.emitError({\n\t\t\terrorType: DriverErrorTypes.genericError,\n\t\t\tmessage: \"whatever\",\n\t\t\tcanRetry: true,\n\t\t});\n\t\tawait Promise.resolve(); // So we get the promise rejection that calls closeHandler\n\n\t\t// Assert\n\t\tassert(\n\t\t\tclosed,\n\t\t\t\"ConnectionManager should close if reconnect throws an error, e.g. hits an assert\",\n\t\t);\n\t});\n\n\tit(\"reconnectOnError - error, disconnect, and nack handling\", async () => {\n\t\t// Arrange\n\t\tconst connectionManager = createConnectionManager();\n\t\tconnectionManager.connect({ text: \"test:reconnectOnError\" });\n\t\tlet connection = await waitForConnection();\n\n\t\t// Act I - retryableError\n\t\tconst error: IAnyDriverError = new RetryableError(\n\t\t\t\"Retryable error\",\n\t\t\tDriverErrorTypes.genericError,\n\t\t\t{ driverVersion: pkgVersion },\n\t\t);\n\t\tlet oldConnection = connection;\n\t\tconnection.emitError(error);\n\t\tconnection = await waitForConnection();\n\n\t\t// Assert I\n\t\tassert(oldConnection.disposed, \"Old connection should be disposed after emitting an error\");\n\t\tassert.equal(\n\t\t\tconnection.clientId,\n\t\t\t\"mock_client_1\",\n\t\t\t\"New connection should have expected id\",\n\t\t);\n\t\tassert(!closed, \"Don't expect closeHandler to be called when connection emits an error\");\n\t\tassert.equal(disconnectCount, 1, \"Expected 1 disconnect from emitting an error\");\n\t\tassert.equal(connectionCount, 2, \"Expected 2 connections after the first emitted an error\");\n\n\t\t// Act II - nonretryable disconnect\n\t\tconst disconnectReason: IAnyDriverError = new NonRetryableError(\n\t\t\t\"Fatal disconnect reason\",\n\t\t\tDriverErrorTypes.genericError,\n\t\t\t{ driverVersion: pkgVersion },\n\t\t);\n\t\toldConnection = connection;\n\t\tconnection.emitDisconnect(disconnectReason);\n\t\tconnection = await waitForConnection();\n\n\t\t// Assert II\n\t\tassert(\n\t\t\toldConnection.disposed,\n\t\t\t\"Old connection should be disposed after emitting disconnect\",\n\t\t);\n\t\tassert.equal(\n\t\t\tconnection.clientId,\n\t\t\t\"mock_client_2\",\n\t\t\t\"New connection should have expected id\",\n\t\t);\n\t\tmockLogger.assertMatchAny([\n\t\t\t{\n\t\t\t\teventName: \"reconnectingDespiteFatalError\",\n\t\t\t\treconnectMode: \"Enabled\",\n\t\t\t\terror: \"Fatal disconnect reason\",\n\t\t\t\tcanRetry: false,\n\t\t\t},\n\t\t]);\n\t\tassert(\n\t\t\t!closed,\n\t\t\t\"Don't expect closeHandler to be called even when connection emits a non-retryable disconnect\",\n\t\t);\n\t\tassert.equal(\n\t\t\tdisconnectCount,\n\t\t\t2,\n\t\t\t\"Expected 2 disconnects from emitting an error and disconnect\",\n\t\t);\n\t\tassert.equal(connectionCount, 3, \"Expected 3 connections after the two disconnects\");\n\n\t\t// Act III - nonretryable nack\n\t\tconst nack: Partial<INack> = {\n\t\t\tcontent: { code: 403, type: NackErrorType.BadRequestError, message: \"fatalNack\" },\n\t\t};\n\t\toldConnection = connection;\n\t\tconnection.emitNack(\"docId\", [nack]);\n\n\t\t// Assert III\n\t\tassert(closed, \"closeHandler should be called in response to 403 nack\");\n\t\tassert(\n\t\t\t!oldConnection.disposed,\n\t\t\t\"connection shouldn't be disposed since mock closeHandler doesn't do it - don't expect it here after fatal nack\",\n\t\t);\n\t\tassert(\n\t\t\t!mockLogger.matchEvents([{ eventName: \"reconnectingDespiteFatalError\" }]),\n\t\t\t\"Should not see reconnectingDespiteFatalError event after fatal nack\",\n\t\t);\n\t});\n\n\tit(\"reconnectOnError - nack retryAfter\", async () => {\n\t\tconst connectionManager = createConnectionManager();\n\t\tconnectionManager.connect({ text: \"test:reconnectOnError\" });\n\t\tlet connection = await waitForConnection();\n\n\t\tconst nack: Partial<INack> = {\n\t\t\tcontent: {\n\t\t\t\tcode: 429,\n\t\t\t\ttype: NackErrorType.ThrottlingError,\n\t\t\t\tmessage: \"throttled\",\n\t\t\t\tretryAfter: 0.5, // 500 ms\n\t\t\t},\n\t\t};\n\t\tconnection.emitNack(\"docId\", [nack]);\n\n\t\tassert(!closed, \"Don't expect closeHandler to be called with retryable Nack\");\n\t\tassert(connection.disposed, \"Expect connection to be disconnected\");\n\t\tassert.strictEqual(disconnectCount, 1, \"Expect 1 disconnect from emitting a Nack\");\n\n\t\t// Async test we aren't connected within 300 ms\n\t\tlet checkedTimeout = false;\n\t\tsetTimeout(() => {\n\t\t\tassert.strictEqual(connectionCount, 1, \"Expect there to still not be a connection yet\");\n\t\t\tcheckedTimeout = true;\n\t\t}, 300);\n\n\t\tconnection = await waitForConnection();\n\t\tassert.strictEqual(connectionCount, 2, \"Expect there to be a connection after waiting\");\n\t\tassert(checkedTimeout, \"Expected to have checked 300ms timeout\");\n\t});\n\n\tdescribe(\"readonly\", () => {\n\t\tit(\"default is undefined\", () => {\n\t\t\tconst connectionManager = createConnectionManager();\n\t\t\tassert.deepStrictEqual(connectionManager.readOnlyInfo, { readonly: undefined });\n\t\t});\n\n\t\tit(\"force readonly\", () => {\n\t\t\tconst connectionManager = createConnectionManager();\n\n\t\t\tconnectionManager.forceReadonly(false);\n\t\t\tassert.deepStrictEqual(connectionManager.readOnlyInfo, { readonly: undefined });\n\n\t\t\tconnectionManager.forceReadonly(true);\n\t\t\tassert.deepStrictEqual(connectionManager.readOnlyInfo, {\n\t\t\t\treadonly: true,\n\t\t\t\tforced: true,\n\t\t\t\tpermissions: undefined,\n\t\t\t\tstorageOnly: false,\n\t\t\t\tstorageOnlyReason: undefined,\n\t\t\t});\n\t\t});\n\n\t\tit(\"readonly permissions\", () => {\n\t\t\tconst connectionManager = createConnectionManager();\n\n\t\t\t(connectionManager as any).set_readonlyPermissions(false);\n\t\t\tassert.deepStrictEqual(connectionManager.readOnlyInfo, { readonly: false });\n\n\t\t\t(connectionManager as any).set_readonlyPermissions(true);\n\t\t\tassert.deepStrictEqual(connectionManager.readOnlyInfo, {\n\t\t\t\treadonly: true,\n\t\t\t\tforced: false,\n\t\t\t\tpermissions: true,\n\t\t\t\tstorageOnly: false,\n\t\t\t\tstorageOnlyReason: undefined,\n\t\t\t});\n\t\t});\n\n\t\tit(\"storage only\", () => {\n\t\t\tconst connectionManager = createConnectionManager();\n\t\t\tmockDocumentService.policies = { storageOnly: true };\n\n\t\t\tassert.deepStrictEqual(connectionManager.readOnlyInfo, { readonly: undefined });\n\n\t\t\tconnectionManager.connect({ text: \"test\" });\n\t\t\tassert.deepStrictEqual(connectionManager.readOnlyInfo, {\n\t\t\t\treadonly: true,\n\t\t\t\tforced: false,\n\t\t\t\tpermissions: true, // storageOnly also implies client does not have write permissions\n\t\t\t\tstorageOnly: true,\n\t\t\t\tstorageOnlyReason: undefined,\n\t\t\t});\n\t\t});\n\t});\n});\n"]}