@fluidframework/container-loader 2.117.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/CHANGELOG.md +76 -2
  2. package/README.md +53 -50
  3. package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
  4. package/api-report/container-loader.legacy.alpha.api.md +4 -3
  5. package/dist/attachment.d.ts.map +1 -1
  6. package/dist/audience.js +3 -2
  7. package/dist/audience.js.map +1 -1
  8. package/dist/captureReferencedContents.js +9 -9
  9. package/dist/captureReferencedContents.js.map +1 -1
  10. package/dist/catchUpMonitor.js +11 -8
  11. package/dist/catchUpMonitor.js.map +1 -1
  12. package/dist/connectionManager.d.ts.map +1 -1
  13. package/dist/connectionManager.js +86 -51
  14. package/dist/connectionManager.js.map +1 -1
  15. package/dist/connectionStateHandler.js +40 -14
  16. package/dist/connectionStateHandler.js.map +1 -1
  17. package/dist/container.d.ts +1 -1
  18. package/dist/container.d.ts.map +1 -1
  19. package/dist/container.js +193 -143
  20. package/dist/container.js.map +1 -1
  21. package/dist/containerContext.js +48 -11
  22. package/dist/containerContext.js.map +1 -1
  23. package/dist/containerStorageAdapter.js +25 -17
  24. package/dist/containerStorageAdapter.js.map +1 -1
  25. package/dist/contracts.d.ts.map +1 -1
  26. package/dist/createAndLoadContainerUtils.d.ts +34 -13
  27. package/dist/createAndLoadContainerUtils.d.ts.map +1 -1
  28. package/dist/createAndLoadContainerUtils.js +97 -37
  29. package/dist/createAndLoadContainerUtils.js.map +1 -1
  30. package/dist/debugLogger.d.ts +7 -22
  31. package/dist/debugLogger.d.ts.map +1 -1
  32. package/dist/debugLogger.js +34 -34
  33. package/dist/debugLogger.js.map +1 -1
  34. package/dist/deltaManager.d.ts +16 -4
  35. package/dist/deltaManager.d.ts.map +1 -1
  36. package/dist/deltaManager.js +75 -49
  37. package/dist/deltaManager.js.map +1 -1
  38. package/dist/deltaManagerFactory.d.ts +23 -0
  39. package/dist/deltaManagerFactory.d.ts.map +1 -0
  40. package/dist/deltaManagerFactory.js +17 -0
  41. package/dist/deltaManagerFactory.js.map +1 -0
  42. package/dist/deltaQueue.js +14 -7
  43. package/dist/deltaQueue.js.map +1 -1
  44. package/dist/disposal.js +1 -2
  45. package/dist/disposal.js.map +1 -1
  46. package/dist/error.js +5 -4
  47. package/dist/error.js.map +1 -1
  48. package/dist/frozenServices.d.ts +2 -2
  49. package/dist/frozenServices.d.ts.map +1 -1
  50. package/dist/frozenServices.js +52 -34
  51. package/dist/frozenServices.js.map +1 -1
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +2 -1
  55. package/dist/index.js.map +1 -1
  56. package/dist/loadContainerToSequenceNumber.d.ts +6 -5
  57. package/dist/loadContainerToSequenceNumber.d.ts.map +1 -1
  58. package/dist/loadContainerToSequenceNumber.js +5 -6
  59. package/dist/loadContainerToSequenceNumber.js.map +1 -1
  60. package/dist/loadPaused.js +1 -2
  61. package/dist/loadPaused.js.map +1 -1
  62. package/dist/loader.js +5 -1
  63. package/dist/loader.js.map +1 -1
  64. package/dist/loaderLayerCompatState.d.ts +25 -1
  65. package/dist/loaderLayerCompatState.d.ts.map +1 -1
  66. package/dist/loaderLayerCompatState.js +79 -11
  67. package/dist/loaderLayerCompatState.js.map +1 -1
  68. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +2 -3
  69. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  70. package/dist/memoryBlobStorage.js +2 -3
  71. package/dist/memoryBlobStorage.js.map +1 -1
  72. package/dist/noopHeuristic.js +3 -1
  73. package/dist/noopHeuristic.js.map +1 -1
  74. package/dist/packageVersion.d.ts +1 -1
  75. package/dist/packageVersion.d.ts.map +1 -1
  76. package/dist/packageVersion.js +1 -1
  77. package/dist/packageVersion.js.map +1 -1
  78. package/dist/pendingLocalStateStore.d.ts +4 -3
  79. package/dist/pendingLocalStateStore.d.ts.map +1 -1
  80. package/dist/pendingLocalStateStore.js +26 -37
  81. package/dist/pendingLocalStateStore.js.map +1 -1
  82. package/dist/pointInTimeServices.js +4 -2
  83. package/dist/pointInTimeServices.js.map +1 -1
  84. package/dist/protocol/protocol.js +3 -0
  85. package/dist/protocol/protocol.js.map +1 -1
  86. package/dist/protocol/quorum.js +26 -5
  87. package/dist/protocol/quorum.js.map +1 -1
  88. package/dist/protocol.js +5 -3
  89. package/dist/protocol.js.map +1 -1
  90. package/dist/protocolTreeDocumentStorageService.js +10 -0
  91. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  92. package/dist/quorum.js +1 -2
  93. package/dist/quorum.js.map +1 -1
  94. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  95. package/dist/retriableDocumentStorageService.js +5 -1
  96. package/dist/retriableDocumentStorageService.js.map +1 -1
  97. package/dist/serializedStateManager.d.ts +6 -0
  98. package/dist/serializedStateManager.d.ts.map +1 -1
  99. package/dist/serializedStateManager.js +19 -24
  100. package/dist/serializedStateManager.js.map +1 -1
  101. package/dist/snapshotRefresher.js +31 -36
  102. package/dist/snapshotRefresher.js.map +1 -1
  103. package/dist/utils.d.ts +1 -1
  104. package/dist/utils.d.ts.map +1 -1
  105. package/dist/utils.js +13 -13
  106. package/dist/utils.js.map +1 -1
  107. package/lib/attachment.d.ts.map +1 -1
  108. package/lib/audience.js +3 -2
  109. package/lib/audience.js.map +1 -1
  110. package/lib/catchUpMonitor.js +11 -8
  111. package/lib/catchUpMonitor.js.map +1 -1
  112. package/lib/connectionManager.d.ts.map +1 -1
  113. package/lib/connectionManager.js +86 -51
  114. package/lib/connectionManager.js.map +1 -1
  115. package/lib/connectionStateHandler.js +37 -11
  116. package/lib/connectionStateHandler.js.map +1 -1
  117. package/lib/container.d.ts +1 -1
  118. package/lib/container.d.ts.map +1 -1
  119. package/lib/container.js +191 -141
  120. package/lib/container.js.map +1 -1
  121. package/lib/containerContext.js +48 -11
  122. package/lib/containerContext.js.map +1 -1
  123. package/lib/containerStorageAdapter.js +22 -14
  124. package/lib/containerStorageAdapter.js.map +1 -1
  125. package/lib/contracts.d.ts.map +1 -1
  126. package/lib/createAndLoadContainerUtils.d.ts +34 -13
  127. package/lib/createAndLoadContainerUtils.d.ts.map +1 -1
  128. package/lib/createAndLoadContainerUtils.js +93 -32
  129. package/lib/createAndLoadContainerUtils.js.map +1 -1
  130. package/lib/debugLogger.d.ts +7 -22
  131. package/lib/debugLogger.d.ts.map +1 -1
  132. package/lib/debugLogger.js +34 -33
  133. package/lib/debugLogger.js.map +1 -1
  134. package/lib/deltaManager.d.ts +16 -4
  135. package/lib/deltaManager.d.ts.map +1 -1
  136. package/lib/deltaManager.js +75 -49
  137. package/lib/deltaManager.js.map +1 -1
  138. package/lib/deltaManagerFactory.d.ts +23 -0
  139. package/lib/deltaManagerFactory.d.ts.map +1 -0
  140. package/lib/deltaManagerFactory.js +14 -0
  141. package/lib/deltaManagerFactory.js.map +1 -0
  142. package/lib/deltaQueue.js +14 -7
  143. package/lib/deltaQueue.js.map +1 -1
  144. package/lib/error.js +5 -4
  145. package/lib/error.js.map +1 -1
  146. package/lib/frozenServices.d.ts +2 -2
  147. package/lib/frozenServices.d.ts.map +1 -1
  148. package/lib/frozenServices.js +48 -30
  149. package/lib/frozenServices.js.map +1 -1
  150. package/lib/index.d.ts +1 -1
  151. package/lib/index.d.ts.map +1 -1
  152. package/lib/index.js +1 -1
  153. package/lib/index.js.map +1 -1
  154. package/lib/legacy.d.ts +1 -1
  155. package/lib/legacyAlpha.d.ts +1 -1
  156. package/lib/loadContainerToSequenceNumber.d.ts +6 -5
  157. package/lib/loadContainerToSequenceNumber.d.ts.map +1 -1
  158. package/lib/loadContainerToSequenceNumber.js +4 -4
  159. package/lib/loadContainerToSequenceNumber.js.map +1 -1
  160. package/lib/loader.js +6 -2
  161. package/lib/loader.js.map +1 -1
  162. package/lib/loaderLayerCompatState.d.ts +25 -1
  163. package/lib/loaderLayerCompatState.d.ts.map +1 -1
  164. package/lib/loaderLayerCompatState.js +76 -9
  165. package/lib/loaderLayerCompatState.js.map +1 -1
  166. package/lib/noopHeuristic.js +3 -1
  167. package/lib/noopHeuristic.js.map +1 -1
  168. package/lib/packageVersion.d.ts +1 -1
  169. package/lib/packageVersion.d.ts.map +1 -1
  170. package/lib/packageVersion.js +1 -1
  171. package/lib/packageVersion.js.map +1 -1
  172. package/lib/pendingLocalStateStore.d.ts +4 -3
  173. package/lib/pendingLocalStateStore.d.ts.map +1 -1
  174. package/lib/pendingLocalStateStore.js +26 -37
  175. package/lib/pendingLocalStateStore.js.map +1 -1
  176. package/lib/pointInTimeServices.js +2 -0
  177. package/lib/pointInTimeServices.js.map +1 -1
  178. package/lib/protocol/protocol.js +3 -0
  179. package/lib/protocol/protocol.js.map +1 -1
  180. package/lib/protocol/quorum.js +26 -5
  181. package/lib/protocol/quorum.js.map +1 -1
  182. package/lib/protocol.js +2 -0
  183. package/lib/protocol.js.map +1 -1
  184. package/lib/protocolTreeDocumentStorageService.js +10 -0
  185. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  186. package/lib/public.d.ts +1 -1
  187. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  188. package/lib/retriableDocumentStorageService.js +5 -1
  189. package/lib/retriableDocumentStorageService.js.map +1 -1
  190. package/lib/serializedStateManager.d.ts +6 -0
  191. package/lib/serializedStateManager.d.ts.map +1 -1
  192. package/lib/serializedStateManager.js +15 -20
  193. package/lib/serializedStateManager.js.map +1 -1
  194. package/lib/snapshotRefresher.js +31 -36
  195. package/lib/snapshotRefresher.js.map +1 -1
  196. package/lib/utils.d.ts +1 -1
  197. package/lib/utils.d.ts.map +1 -1
  198. package/lib/utils.js +3 -3
  199. package/lib/utils.js.map +1 -1
  200. package/package.json +44 -106
  201. package/src/container.ts +35 -22
  202. package/src/createAndLoadContainerUtils.ts +131 -46
  203. package/src/debugLogger.ts +39 -40
  204. package/src/deltaManager.ts +18 -5
  205. package/src/deltaManagerFactory.ts +53 -0
  206. package/src/frozenServices.ts +6 -7
  207. package/src/index.ts +1 -0
  208. package/src/loadContainerToSequenceNumber.ts +7 -6
  209. package/src/loader.ts +2 -2
  210. package/src/loaderLayerCompatState.ts +85 -20
  211. package/src/packageVersion.ts +1 -1
  212. package/src/pendingLocalStateStore.ts +7 -3
  213. package/src/pointInTime/DEV.md +47 -4
  214. package/src/serializedStateManager.ts +6 -0
  215. package/src/utils.ts +3 -3
  216. package/tsconfig.json +1 -1
  217. package/internal.d.ts +0 -11
  218. package/legacy/alpha.d.ts +0 -11
  219. package/legacy.d.ts +0 -11
  220. /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
  221. /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
package/dist/container.js CHANGED
@@ -4,7 +4,9 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.asLegacyAlpha = exports.Container = exports.waitContainerToCatchUp = void 0;
7
+ exports.Container = void 0;
8
+ exports.waitContainerToCatchUp = waitContainerToCatchUp;
9
+ exports.asLegacyAlpha = asLegacyAlpha;
8
10
  /* eslint-disable unicorn/consistent-function-scoping, @typescript-eslint/prefer-nullish-coalescing, @typescript-eslint/prefer-optional-chain */
9
11
  const client_utils_1 = require("@fluid-internal/client-utils");
10
12
  const container_definitions_1 = require("@fluidframework/container-definitions");
@@ -18,13 +20,12 @@ const internal_5 = require("@fluidframework/telemetry-utils/internal");
18
20
  const uuid_1 = require("uuid");
19
21
  const attachment_js_1 = require("./attachment.js");
20
22
  const audience_js_1 = require("./audience.js");
21
- const connectionManager_js_1 = require("./connectionManager.js");
22
23
  const connectionState_js_1 = require("./connectionState.js");
23
24
  const connectionStateHandler_js_1 = require("./connectionStateHandler.js");
24
25
  const containerContext_js_1 = require("./containerContext.js");
25
26
  const containerStorageAdapter_js_1 = require("./containerStorageAdapter.js");
26
27
  const contracts_js_1 = require("./contracts.js");
27
- const deltaManager_js_1 = require("./deltaManager.js");
28
+ const deltaManagerFactory_js_1 = require("./deltaManagerFactory.js");
28
29
  const loader_js_1 = require("./loader.js");
29
30
  const loaderLayerCompatState_js_1 = require("./loaderLayerCompatState.js");
30
31
  const memoryBlobStorage_js_1 = require("./memoryBlobStorage.js");
@@ -112,7 +113,6 @@ async function waitContainerToCatchUp(container) {
112
113
  }
113
114
  });
114
115
  }
115
- exports.waitContainerToCatchUp = waitContainerToCatchUp;
116
116
  const getCodeProposal = (quorum) => quorum.get("code") ?? quorum.get("code2");
117
117
  const summarizerClientType = "summarizer";
118
118
  class Container extends internal_5.EventEmitterWithErrorHandling {
@@ -181,6 +181,41 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
181
181
  return container;
182
182
  }, { start: true, end: true, cancel: "generic" });
183
183
  }
184
+ // Tells if container can reconnect on losing fist connection
185
+ // If false, container gets closed on loss of connection.
186
+ _canReconnect;
187
+ clientDetailsOverride;
188
+ urlResolver;
189
+ serviceFactory;
190
+ codeLoader;
191
+ options;
192
+ scope;
193
+ subLogger;
194
+ detachedBlobStorage;
195
+ protocolHandlerBuilder;
196
+ signalAudience = new audience_js_1.Audience();
197
+ client;
198
+ mc;
199
+ /**
200
+ * Used by the RelativeLoader to spawn a new Container for the same document. Used to create the summarizing client.
201
+ */
202
+ clone;
203
+ /**
204
+ * Lifecycle state of the container, used mainly to prevent re-entrancy and telemetry
205
+ *
206
+ * States are allowed to progress to further states:
207
+ * "loading" - "loaded" - "closing" - "disposing" - "closed" - "disposed"
208
+ *
209
+ * For example, moving from "closed" to "disposing" is not allowed since it is an earlier state.
210
+ *
211
+ * loading: Container has been created, but is not yet in normal/loaded state
212
+ * loaded: Container is in normal/loaded state
213
+ * closing: Container has started closing process (for re-entrancy prevention)
214
+ * disposing: Container has started disposing process (for re-entrancy prevention)
215
+ * closed: Container has closed
216
+ * disposed: Container has been disposed
217
+ */
218
+ _lifecycleState = "loading";
184
219
  setLoaded() {
185
220
  // It's conceivable the container could be closed when this is called
186
221
  // Only transition states if currently loading
@@ -227,18 +262,48 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
227
262
  get disposed() {
228
263
  return this._lifecycleState === "disposing" || this._lifecycleState === "disposed";
229
264
  }
265
+ storageAdapter;
266
+ _deltaManager;
267
+ service;
268
+ fetchOps = async (from, to, abortSignal) => {
269
+ const deltaStorage = await this.service?.connectToDeltaStorage();
270
+ if (deltaStorage === undefined) {
271
+ throw new Error("Cannot fetch ops: delta storage is unavailable");
272
+ }
273
+ return deltaStorage.fetchMessages(from, to, abortSignal);
274
+ };
275
+ _runtime;
230
276
  get runtime() {
231
277
  if (this._runtime === undefined) {
232
278
  throw new Error("Attempted to access runtime before it was defined");
233
279
  }
234
280
  return this._runtime;
235
281
  }
282
+ _protocolHandler;
236
283
  get protocolHandler() {
237
284
  if (this._protocolHandler === undefined) {
238
285
  throw new Error("Attempted to access protocolHandler before it was defined");
239
286
  }
240
287
  return this._protocolHandler;
241
288
  }
289
+ /**
290
+ * During initialization we pause the inbound queues. We track this state to ensure we only call resume once
291
+ */
292
+ inboundQueuePausedFromInit = true;
293
+ connectionCount = 0;
294
+ connectionTransitionTimes = [];
295
+ _loadedFromVersion;
296
+ _dirtyContainer = false;
297
+ attachmentData = { state: container_definitions_1.AttachState.Detached };
298
+ serializedStateManager;
299
+ _containerId;
300
+ lastVisible;
301
+ visibilityEventHandler;
302
+ connectionStateHandler;
303
+ clientsWhoShouldHaveLeft = new Set();
304
+ _containerMetadata = {};
305
+ setAutoReconnectTime = (0, client_utils_1.performanceNow)();
306
+ noopHeuristic;
242
307
  get connectionMode() {
243
308
  return this._deltaManager.connectionManager.connectionMode;
244
309
  }
@@ -314,6 +379,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
314
379
  getSpecifiedCodeDetails() {
315
380
  return this.getCodeDetailsFromQuorum();
316
381
  }
382
+ _loadedCodeDetails;
317
383
  /**
318
384
  * Get the code details that were used to load the container.
319
385
  * @returns The code details that were used to load the container if it is loaded, undefined if it is not yet
@@ -322,6 +388,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
322
388
  getLoadedCodeDetails() {
323
389
  return this._loadedCodeDetails;
324
390
  }
391
+ _loadedModule;
325
392
  /**
326
393
  * Retrieves the audience associated with the document
327
394
  */
@@ -360,6 +427,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
360
427
  this._lifecycleEvents.once("disposed", disposedHandler);
361
428
  });
362
429
  }
430
+ _lifecycleEvents = new client_utils_1.TypedEventEmitter();
363
431
  constructor(createProps, loadProps) {
364
432
  super((name, error) => {
365
433
  this.mc.logger.sendErrorEvent({
@@ -368,144 +436,22 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
368
436
  }, error);
369
437
  this.close((0, internal_5.normalizeError)(error));
370
438
  });
371
- this.signalAudience = new audience_js_1.Audience();
372
- /**
373
- * Lifecycle state of the container, used mainly to prevent re-entrancy and telemetry
374
- *
375
- * States are allowed to progress to further states:
376
- * "loading" - "loaded" - "closing" - "disposing" - "closed" - "disposed"
377
- *
378
- * For example, moving from "closed" to "disposing" is not allowed since it is an earlier state.
379
- *
380
- * loading: Container has been created, but is not yet in normal/loaded state
381
- * loaded: Container is in normal/loaded state
382
- * closing: Container has started closing process (for re-entrancy prevention)
383
- * disposing: Container has started disposing process (for re-entrancy prevention)
384
- * closed: Container has closed
385
- * disposed: Container has been disposed
386
- */
387
- this._lifecycleState = "loading";
388
- this.fetchOps = async (from, to, abortSignal) => {
389
- const deltaStorage = await this.service?.connectToDeltaStorage();
390
- if (deltaStorage === undefined) {
391
- throw new Error("Cannot fetch ops: delta storage is unavailable");
392
- }
393
- return deltaStorage.fetchMessages(from, to, abortSignal);
394
- };
395
- /**
396
- * During initialization we pause the inbound queues. We track this state to ensure we only call resume once
397
- */
398
- this.inboundQueuePausedFromInit = true;
399
- this.connectionCount = 0;
400
- this.connectionTransitionTimes = [];
401
- this._dirtyContainer = false;
402
- this.attachmentData = { state: container_definitions_1.AttachState.Detached };
403
- this.clientsWhoShouldHaveLeft = new Set();
404
- this._containerMetadata = {};
405
- this.setAutoReconnectTime = (0, client_utils_1.performanceNow)();
406
- this._lifecycleEvents = new client_utils_1.TypedEventEmitter();
407
- this.verifyClosedAfterCalls = 0;
408
- this._disposed = false;
409
- this.attach = (0, utils_js_1.runSingle)(async (request, attachProps) => {
410
- await internal_5.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Attach" }, async () => {
411
- if (this._lifecycleState !== "loaded" ||
412
- this.attachmentData.state === container_definitions_1.AttachState.Attached) {
413
- // pre-0.58 error message: containerNotValidForAttach
414
- throw new internal_5.UsageError(`The Container is not in a valid state for attach [${this._lifecycleState}] and [${this.attachState}]`);
415
- }
416
- const normalizeErrorAndClose = (error) => {
417
- const newError = (0, internal_5.normalizeError)(error);
418
- this.close(newError);
419
- // add resolved URL on error object so that host has the ability to find this document and delete it
420
- newError.addTelemetryProperties({
421
- resolvedUrl: this.service?.resolvedUrl?.url,
422
- });
423
- return newError;
424
- };
425
- const setAttachmentData = (attachmentData) => {
426
- const previousState = this.attachmentData.state;
427
- this.attachmentData = attachmentData;
428
- const state = this.attachmentData.state;
429
- if (state !== previousState && state !== container_definitions_1.AttachState.Detached) {
430
- try {
431
- this.runtime.setAttachState(state);
432
- this.emit(state.toLocaleLowerCase());
433
- }
434
- catch (error) {
435
- throw normalizeErrorAndClose(error);
436
- }
437
- }
438
- };
439
- const createAttachmentSummary = (redirectTable) => {
440
- try {
441
- (0, internal_2.assert)(this._deltaManager.inbound.length === 0, 0x0d6 /* "Inbound queue should be empty when attaching" */);
442
- return (0, utils_js_1.combineAppAndProtocolSummary)(this.runtime.createSummary(redirectTable), this.captureProtocolSummary());
443
- }
444
- catch (error) {
445
- throw normalizeErrorAndClose(error);
446
- }
447
- };
448
- const createOrGetStorageService = async (summary) => {
449
- // Actually go and create the resolved document
450
- if (this.service === undefined) {
451
- const createNewResolvedUrl = await this.urlResolver.resolve(request);
452
- (0, internal_2.assert)(this.client.details.type !== summarizerClientType &&
453
- createNewResolvedUrl !== undefined, 0x2c4 /* "client should not be summarizer before container is created" */);
454
- this.service = await this.createDocumentService(createNewResolvedUrl, {
455
- mode: "attach",
456
- summary,
457
- });
458
- }
459
- this.storageAdapter.connectToService(this.service);
460
- return this.storageAdapter;
461
- };
462
- let attachP = (0, attachment_js_1.runRetriableAttachProcess)({
463
- initialAttachmentData: this.attachmentData,
464
- detachedBlobStorage: this.detachedBlobStorage,
465
- setAttachmentData,
466
- createAttachmentSummary,
467
- createOrGetStorageService,
468
- });
469
- // only enable the new behavior if the config is set
470
- if (this.mc.config.getBoolean("Fluid.Container.DisableCloseOnAttachFailure") !== true) {
471
- attachP = attachP.catch((error) => {
472
- throw normalizeErrorAndClose(error);
473
- });
474
- }
475
- // If offline load is enabled, attachP will return the attach summary (in Snapshot format) so we can initialize SerializedStateManager
476
- const snapshotWithBlobs = await attachP;
477
- this.serializedStateManager.setInitialSnapshot(snapshotWithBlobs);
478
- if (!this.closed) {
479
- this.detachedBlobStorage?.dispose?.();
480
- this.handleDeltaConnectionArg(attachProps?.deltaConnection, {
481
- fetchOpsFromStorage: false,
482
- reason: { text: "createDetached" },
483
- });
484
- }
485
- }, { start: true, end: true, cancel: "generic" });
486
- });
487
- this.getAbsoluteUrl = async (relativeUrl) => {
488
- if (this.resolvedUrl === undefined) {
489
- return undefined;
490
- }
491
- return this.urlResolver.getAbsoluteUrl(this.resolvedUrl, relativeUrl, (0, contracts_js_1.getPackageName)(this._loadedCodeDetails));
492
- };
493
- this.metadataUpdateHandler = (metadata) => {
494
- this._containerMetadata = { ...this._containerMetadata, ...metadata };
495
- this.emit("metadataUpdate", metadata);
496
- };
497
- this.updateDirtyContainerState = (dirty) => {
498
- if (this._dirtyContainer === dirty) {
499
- return;
500
- }
501
- this._dirtyContainer = dirty;
502
- this.emit(dirty ? dirtyContainerEvent : savedContainerEvent);
503
- };
504
439
  const { canReconnect, clientDetailsOverride, urlResolver, documentServiceFactory, codeLoader, options, scope, subLogger, protocolHandlerBuilder, } = createProps;
505
- // Validate that the Driver is compatible with this Loader.
506
- const maybeDriverCompatDetails = documentServiceFactory;
507
- (0, loaderLayerCompatState_js_1.validateDriverCompatibility)(maybeDriverCompatDetails.ILayerCompatDetails, (error) => { } /* disposeFn */, // There is nothing to dispose here, so just ignore the error.
508
- (0, internal_5.createChildMonitoringContext)({ logger: subLogger, namespace: "Container" }));
440
+ const maybeDriverCompat = documentServiceFactory;
441
+ const driverCompatMonitoringContext = (0, internal_5.createChildMonitoringContext)({
442
+ logger: subLogger,
443
+ namespace: "Container",
444
+ });
445
+ // Validate that the Driver is compatible with this Loader. This is the standard direction: the Loader holds
446
+ // a reference to the Driver and validates it.
447
+ (0, loaderLayerCompatState_js_1.validateDriverCompatibility)(maybeDriverCompat.ILayerCompatDetails, (error) => { } /* disposeFn */, // There is nothing to dispose here, so just ignore the error.
448
+ driverCompatMonitoringContext);
449
+ // Validate that this Loader is compatible with the Driver. This is the reverse, non-standard direction: a
450
+ // layer normally validates the layer it holds a reference to, but the Driver has no reference to the Loader
451
+ // and so cannot validate it itself. The Driver instead publishes the requirements it has for the Loader (via
452
+ // ILayerCompatSupportRequirements), and the Loader validates itself against them here, on the Driver's behalf.
453
+ (0, loaderLayerCompatState_js_1.validateLoaderCompatibilityWithDriver)(maybeDriverCompat.ILayerCompatDetails, maybeDriverCompat.ILayerCompatSupportRequirements, (error) => { } /* disposeFn */, // There is nothing to dispose here, so just ignore the error.
454
+ driverCompatMonitoringContext);
509
455
  this.connectionTransitionTimes[connectionState_js_1.ConnectionState.Disconnected] = (0, client_utils_1.performanceNow)();
510
456
  const pendingLocalState = loadProps?.pendingLocalState;
511
457
  this._canReconnect = canReconnect ?? true;
@@ -686,6 +632,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
686
632
  // "closing" will lose that info (can also solve by tracking extra state).
687
633
  this.verifyClosedAfter(() => this._deltaManager.close(error));
688
634
  }
635
+ verifyClosedAfterCalls = 0;
689
636
  verifyClosedAfter(callback) {
690
637
  this.verifyClosedAfterCalls++;
691
638
  try {
@@ -740,6 +687,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
740
687
  }
741
688
  }
742
689
  }
690
+ _disposed = false;
743
691
  disposeCore(error) {
744
692
  (0, internal_2.assert)(!this._disposed, 0x54c /* Container already disposed */);
745
693
  this._disposed = true;
@@ -826,6 +774,84 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
826
774
  };
827
775
  return JSON.stringify(detachedContainerState);
828
776
  }
777
+ attach = (0, utils_js_1.runSingle)(async (request, attachProps) => {
778
+ await internal_5.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Attach" }, async () => {
779
+ if (this._lifecycleState !== "loaded" ||
780
+ this.attachmentData.state === container_definitions_1.AttachState.Attached) {
781
+ // pre-0.58 error message: containerNotValidForAttach
782
+ throw new internal_5.UsageError(`The Container is not in a valid state for attach [${this._lifecycleState}] and [${this.attachState}]`);
783
+ }
784
+ const normalizeErrorAndClose = (error) => {
785
+ const newError = (0, internal_5.normalizeError)(error);
786
+ this.close(newError);
787
+ // add resolved URL on error object so that host has the ability to find this document and delete it
788
+ newError.addTelemetryProperties({
789
+ resolvedUrl: this.service?.resolvedUrl?.url,
790
+ });
791
+ return newError;
792
+ };
793
+ const setAttachmentData = (attachmentData) => {
794
+ const previousState = this.attachmentData.state;
795
+ this.attachmentData = attachmentData;
796
+ const state = this.attachmentData.state;
797
+ if (state !== previousState && state !== container_definitions_1.AttachState.Detached) {
798
+ try {
799
+ this.runtime.setAttachState(state);
800
+ this.emit(state.toLocaleLowerCase());
801
+ }
802
+ catch (error) {
803
+ throw normalizeErrorAndClose(error);
804
+ }
805
+ }
806
+ };
807
+ const createAttachmentSummary = (redirectTable) => {
808
+ try {
809
+ (0, internal_2.assert)(this._deltaManager.inbound.length === 0, 0x0d6 /* "Inbound queue should be empty when attaching" */);
810
+ return (0, utils_js_1.combineAppAndProtocolSummary)(this.runtime.createSummary(redirectTable), this.captureProtocolSummary());
811
+ }
812
+ catch (error) {
813
+ throw normalizeErrorAndClose(error);
814
+ }
815
+ };
816
+ const createOrGetStorageService = async (summary) => {
817
+ // Actually go and create the resolved document
818
+ if (this.service === undefined) {
819
+ const createNewResolvedUrl = await this.urlResolver.resolve(request);
820
+ (0, internal_2.assert)(this.client.details.type !== summarizerClientType &&
821
+ createNewResolvedUrl !== undefined, 0x2c4 /* "client should not be summarizer before container is created" */);
822
+ this.service = await this.createDocumentService(createNewResolvedUrl, {
823
+ mode: "attach",
824
+ summary,
825
+ });
826
+ }
827
+ this.storageAdapter.connectToService(this.service);
828
+ return this.storageAdapter;
829
+ };
830
+ let attachP = (0, attachment_js_1.runRetriableAttachProcess)({
831
+ initialAttachmentData: this.attachmentData,
832
+ detachedBlobStorage: this.detachedBlobStorage,
833
+ setAttachmentData,
834
+ createAttachmentSummary,
835
+ createOrGetStorageService,
836
+ });
837
+ // only enable the new behavior if the config is set
838
+ if (this.mc.config.getBoolean("Fluid.Container.DisableCloseOnAttachFailure") !== true) {
839
+ attachP = attachP.catch((error) => {
840
+ throw normalizeErrorAndClose(error);
841
+ });
842
+ }
843
+ // If offline load is enabled, attachP will return the attach summary (in Snapshot format) so we can initialize SerializedStateManager
844
+ const snapshotWithBlobs = await attachP;
845
+ this.serializedStateManager.setInitialSnapshot(snapshotWithBlobs);
846
+ if (!this.closed) {
847
+ this.detachedBlobStorage?.dispose?.();
848
+ this.handleDeltaConnectionArg(attachProps?.deltaConnection, {
849
+ fetchOpsFromStorage: false,
850
+ reason: { text: "createDetached" },
851
+ });
852
+ }
853
+ }, { start: true, end: true, cancel: "generic" });
854
+ });
829
855
  setAutoReconnectInternal(mode, reason) {
830
856
  const currentMode = this._deltaManager.connectionManager.reconnectMode;
831
857
  if (currentMode === mode) {
@@ -898,6 +924,12 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
898
924
  // Ensure connection to web socket
899
925
  this.connectToDeltaStream(args);
900
926
  }
927
+ getAbsoluteUrl = async (relativeUrl) => {
928
+ if (this.resolvedUrl === undefined) {
929
+ return undefined;
930
+ }
931
+ return this.urlResolver.getAbsoluteUrl(this.resolvedUrl, relativeUrl, (0, contracts_js_1.getPackageName)(this._loadedCodeDetails));
932
+ };
901
933
  async proposeCodeDetails(codeDetails) {
902
934
  if (!(0, internal_1.isFluidCodeDetails)(codeDetails)) {
903
935
  throw new Error("Provided codeDetails are not IFluidCodeDetails");
@@ -966,6 +998,10 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
966
998
  }
967
999
  this._deltaManager.connect(args);
968
1000
  }
1001
+ metadataUpdateHandler = (metadata) => {
1002
+ this._containerMetadata = { ...this._containerMetadata, ...metadata };
1003
+ this.emit("metadataUpdate", metadata);
1004
+ };
969
1005
  /**
970
1006
  * Creates a document service during container attachment or loading.
971
1007
  * @param resolvedUrl - The resolved URL of the container.
@@ -1287,7 +1323,15 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1287
1323
  createDeltaManager() {
1288
1324
  const serviceProvider = () => this.service;
1289
1325
  const disableLoadConnectionRetries = this.mc.config.getBoolean("Fluid.Container.DisableLoadConnectionRetries") === true;
1290
- const deltaManager = new deltaManager_js_1.DeltaManager(serviceProvider, (0, internal_5.createChildLogger)({ logger: this.subLogger, namespace: "DeltaManager" }), () => this.activeConnection(), (props) => new connectionManager_js_1.ConnectionManager(serviceProvider, () => this.isDirty, this.client, this._canReconnect, (0, internal_5.createChildLogger)({ logger: this.subLogger, namespace: "ConnectionManager" }), props, disableLoadConnectionRetries ? 1 : undefined /* maxInitialConnectionAttempts */));
1326
+ const deltaManager = (0, deltaManagerFactory_js_1.createDeltaManager)({
1327
+ serviceProvider,
1328
+ logger: this.subLogger,
1329
+ active: () => this.activeConnection(),
1330
+ containerDirty: () => this.isDirty,
1331
+ client: this.client,
1332
+ reconnectAllowed: this._canReconnect,
1333
+ maxInitialConnectionAttempts: disableLoadConnectionRetries ? 1 : undefined,
1334
+ });
1291
1335
  // Disable inbound queues as Container is not ready to accept any ops until we are fully loaded!
1292
1336
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
1293
1337
  deltaManager.inbound.pause();
@@ -1611,6 +1655,13 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1611
1655
  throw error;
1612
1656
  }
1613
1657
  }
1658
+ updateDirtyContainerState = (dirty) => {
1659
+ if (this._dirtyContainer === dirty) {
1660
+ return;
1661
+ }
1662
+ this._dirtyContainer = dirty;
1663
+ this.emit(dirty ? dirtyContainerEvent : savedContainerEvent);
1664
+ };
1614
1665
  /**
1615
1666
  * Send the connected status to the runtime.
1616
1667
  * @param readonly - Is the container in readonly mode?
@@ -1728,5 +1779,4 @@ exports.Container = Container;
1728
1779
  function asLegacyAlpha(base) {
1729
1780
  return base;
1730
1781
  }
1731
- exports.asLegacyAlpha = asLegacyAlpha;
1732
1782
  //# sourceMappingURL=container.js.map