@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
@@ -4,7 +4,12 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.loadSummarizerContainerAndMakeSummary = exports.captureFullContainerState = exports.loadFrozenContainerFromPendingState = exports.loadExistingContainer = exports.rehydrateDetachedContainer = exports.createDetachedContainer = void 0;
7
+ exports.createDetachedContainer = createDetachedContainer;
8
+ exports.rehydrateDetachedContainer = rehydrateDetachedContainer;
9
+ exports.loadExistingContainer = loadExistingContainer;
10
+ exports.loadFrozenContainerFromPendingState = loadFrozenContainerFromPendingState;
11
+ exports.captureFullContainerState = captureFullContainerState;
12
+ exports.loadSummarizerContainerAndMakeSummary = loadSummarizerContainerAndMakeSummary;
8
13
  const internal_1 = require("@fluidframework/container-definitions/internal");
9
14
  const internal_2 = require("@fluidframework/core-utils/internal");
10
15
  const internal_3 = require("@fluidframework/driver-definitions/internal");
@@ -12,7 +17,9 @@ const internal_4 = require("@fluidframework/driver-utils/internal");
12
17
  const internal_5 = require("@fluidframework/telemetry-utils/internal");
13
18
  const uuid_1 = require("uuid");
14
19
  const captureReferencedContents_js_1 = require("./captureReferencedContents.js");
20
+ const catchUpMonitor_js_1 = require("./catchUpMonitor.js");
15
21
  const debugLogger_js_1 = require("./debugLogger.js");
22
+ const deltaManagerFactory_js_1 = require("./deltaManagerFactory.js");
16
23
  const frozenServices_js_1 = require("./frozenServices.js");
17
24
  const loader_js_1 = require("./loader.js");
18
25
  const packageVersion_js_1 = require("./packageVersion.js");
@@ -30,7 +37,6 @@ async function createDetachedContainer(createDetachedContainerProps) {
30
37
  clientDetailsOverride: createDetachedContainerProps.clientDetailsOverride,
31
38
  });
32
39
  }
33
- exports.createDetachedContainer = createDetachedContainer;
34
40
  /**
35
41
  * Creates a new container using the specified snapshot but in an unattached state. While unattached, all
36
42
  * updates will only be local until the user explicitly attaches the container to a service provider.
@@ -44,7 +50,6 @@ async function rehydrateDetachedContainer(rehydrateDetachedContainerProps) {
44
50
  clientDetailsOverride: rehydrateDetachedContainerProps.clientDetailsOverride,
45
51
  });
46
52
  }
47
- exports.rehydrateDetachedContainer = rehydrateDetachedContainer;
48
53
  /**
49
54
  * Loads a container with an existing snapshot from the service.
50
55
  * @param loadExistingContainerProps - Services and properties necessary for loading an existing container.
@@ -54,7 +59,6 @@ async function loadExistingContainer(loadExistingContainerProps) {
54
59
  const loader = new loader_js_1.Loader(loadExistingContainerProps);
55
60
  return loader.resolve(loadExistingContainerProps.request, loadExistingContainerProps.pendingLocalState);
56
61
  }
57
- exports.loadExistingContainer = loadExistingContainer;
58
62
  const driverPropKeys = ["request", "urlResolver", "documentServiceFactory"];
59
63
  // Recognizable opaque placeholder used as `request.url` for the offline form of
60
64
  // `loadFrozenContainerFromPendingState`. The synthesized `IUrlResolver` ignores
@@ -80,6 +84,9 @@ async function loadFrozenContainerFromPendingState(props) {
80
84
  // returns a resolved URL whose `url` equals `pendingLocalState.url`, so the
81
85
  // identity guard in `Loader.resolveCore` is trivially satisfied.
82
86
  const pending = (0, utils_js_1.getAttachedContainerStateFromSerializedContainer)(pendingLocalState);
87
+ if (pending.blobContentsMode === "reference") {
88
+ throw new internal_5.UsageError(`${fnName}: pending state does not contain inlined snapshot blob contents. Reference-only state captured by ${captureFullContainerState.name} requires online driver wiring.`);
89
+ }
83
90
  const parsed = (0, utils_js_1.tryParseCompatibleResolvedUrl)(pending.url);
84
91
  if (parsed === undefined) {
85
92
  throw new internal_5.UsageError(`${fnName}: pending state URL is not in a parseable form (${pending.url})`);
@@ -137,7 +144,6 @@ async function loadFrozenContainerFromPendingState(props) {
137
144
  documentServiceFactory: (0, frozenServices_js_1.createFrozenDocumentServiceFactory)(onlineProps.documentServiceFactory, readOnly),
138
145
  });
139
146
  }
140
- exports.loadFrozenContainerFromPendingState = loadFrozenContainerFromPendingState;
141
147
  /**
142
148
  * Captures the current state of an attached container using only driver-level
143
149
  * services, without instantiating a runtime or loading a full container. The
@@ -145,11 +151,19 @@ exports.loadFrozenContainerFromPendingState = loadFrozenContainerFromPendingStat
145
151
  * format produced by a live container's pending-state serialization, and can
146
152
  * be handed to {@link loadExistingContainer} as `pendingLocalState`.
147
153
  *
148
- * The output is a self-contained view of the container's referenced graph:
149
- * the latest snapshot, inlined contents of every blob reachable through
154
+ * By default, the output is a self-contained view of the container's referenced
155
+ * graph: the latest snapshot, inlined contents of every blob reachable through
150
156
  * referenced subtrees, inlined contents of every referenced attachment blob
151
157
  * keyed by storage id, and all ops with sequence numbers after the base
152
- * snapshot's sequence number (as read from its attributes blob).
158
+ * snapshot's sequence number through the point observed when the delta stream
159
+ * connects. The same DeltaManager catch-up path used by container loading
160
+ * combines delta-storage and delta-stream ops, so recently sequenced ops do
161
+ * not need to have reached durable delta storage before capture.
162
+ *
163
+ * When `blobCaptureMode` is `"reference"`, the snapshot tree retains the blob
164
+ * IDs needed to load the container, but structural and attachment payloads are
165
+ * omitted. Reference-only state requires live storage during load and cannot be
166
+ * used with the fully offline form of {@link loadFrozenContainerFromPendingState}.
153
167
  *
154
168
  * Reachability respects GC. Snapshot subtrees flagged `unreferenced: true`
155
169
  * are skipped (their contents are not inlined). Attachment blobs that GC has
@@ -170,7 +184,8 @@ exports.loadFrozenContainerFromPendingState = loadFrozenContainerFromPendingStat
170
184
  * is a known consumer and end-to-end coverage, the capture refuses rather
171
185
  * than silently producing pending state that omits group data.
172
186
  *
173
- * Note: if a new snapshot lands between the snapshot fetch and the ops fetch,
187
+ * @privateRemarks
188
+ * Note: if a new snapshot lands between the snapshot fetch and delta catch-up,
174
189
  * the returned state may not reflect the very latest snapshot, but remains
175
190
  * internally consistent: ops are anchored to the snapshot that was captured.
176
191
  *
@@ -182,22 +197,54 @@ exports.loadFrozenContainerFromPendingState = loadFrozenContainerFromPendingStat
182
197
  * back together with that change.
183
198
  * @legacy @alpha
184
199
  */
185
- async function captureFullContainerState({ urlResolver, documentServiceFactory, request, logger, }) {
200
+ async function captureFullContainerState({ urlResolver, documentServiceFactory, request, logger, blobCaptureMode = "inline", }) {
186
201
  const resolvedUrl = await urlResolver.resolve(request);
187
202
  if (resolvedUrl === undefined) {
188
203
  throw new internal_5.UsageError("Failed to resolve request to a Fluid URL");
189
204
  }
190
- // Validate the resolver's URL shape at capture time. The captured pending
191
- // state is rehydrated later (possibly in a different process) via the
192
- // offline form of `loadFrozenContainerFromPendingState`, which requires
193
- // `tryParseCompatibleResolvedUrl` to succeed on `pendingLocalState.url`.
194
- // Failing fast here turns "your captured artifact silently isn't
195
- // rehydratable" into a same-call error a partner can act on, instead of
196
- // surfacing as a `UsageError` at offline-load time in a different process.
197
- if ((0, utils_js_1.tryParseCompatibleResolvedUrl)(resolvedUrl.url) === undefined) {
205
+ // Inline state supports the offline form of `loadFrozenContainerFromPendingState`,
206
+ // which requires `tryParseCompatibleResolvedUrl` to succeed on `pendingLocalState.url`.
207
+ // Reference-only state always uses the caller's live resolver, so it has no such constraint.
208
+ if (blobCaptureMode === "inline" &&
209
+ (0, utils_js_1.tryParseCompatibleResolvedUrl)(resolvedUrl.url) === undefined) {
198
210
  throw new internal_5.UsageError(`${captureFullContainerState.name}: resolved URL is not in the shape required by tryParseCompatibleResolvedUrl (protocol://<string>/<tenantId>/<docId>?<querystring>); captured state would not rehydrate offline (${resolvedUrl.url})`);
199
211
  }
200
212
  const documentService = await documentServiceFactory.createDocumentService(resolvedUrl, logger);
213
+ const captureLogger = (0, internal_5.createChildLogger)({ logger, namespace: "captureFullContainerState" });
214
+ const client = {
215
+ details: { capabilities: { interactive: true } },
216
+ mode: "read",
217
+ permission: [],
218
+ scopes: [],
219
+ user: { id: "" },
220
+ };
221
+ const deltaManager = (0, deltaManagerFactory_js_1.createDeltaManager)({
222
+ serviceProvider: () => documentService,
223
+ logger: captureLogger,
224
+ active: () => false,
225
+ containerDirty: () => false,
226
+ client,
227
+ reconnectAllowed: true,
228
+ });
229
+ const connectedP = new Promise((resolve) => {
230
+ deltaManager.once("connect", () => resolve());
231
+ });
232
+ const closedP = new Promise((_resolve, reject) => {
233
+ deltaManager.once("closed", (error) => {
234
+ reject(error === undefined
235
+ ? new internal_5.GenericError("DeltaManager closed while capturing container state")
236
+ : (0, internal_5.normalizeError)(error));
237
+ });
238
+ });
239
+ deltaManager.connect({
240
+ reason: { text: "captureFullContainerState" },
241
+ mode: "read",
242
+ // Ops will be fetched from storage using the later "attachOpHandler" call. Attempting to fetch here is a no-op anyway as
243
+ // no op handler is yet attached.
244
+ // Fetching the snapshot first such that an op handler could be attached using its sequence number information may simplify
245
+ // the code, but doing it this way allows parallelization of snapshot fetch and establishing a connection.
246
+ fetchOpsFromStorage: false,
247
+ });
201
248
  try {
202
249
  const storage = await documentService.connectToStorage();
203
250
  const versions = await storage.getVersions(
@@ -220,35 +267,39 @@ async function captureFullContainerState({ urlResolver, documentServiceFactory,
220
267
  throw new internal_5.UsageError("captureFullContainerState does not yet support containers with loading groups");
221
268
  }
222
269
  const attributes = await (0, utils_js_1.getDocumentAttributes)(storage, baseSnapshot);
223
- const gcData = await (0, captureReferencedContents_js_1.parseGcSnapshotData)(baseSnapshot, storage);
270
+ let gcData;
271
+ let snapshotBlobs = {};
272
+ let attachmentBlobContents = {};
224
273
  // Structural snapshot blobs (JSON/text the runtime authored) are
225
274
  // UTF-8-encoded; attachment blobs may carry arbitrary binary bytes
226
275
  // and are base64-encoded. Keep them on separate fields of the
227
276
  // pending state so the load side can apply the matching decoder
228
277
  // without ambiguity. See IPendingContainerState.attachmentBlobContents.
229
- const [snapshotBlobs, attachmentBlobContents] = await Promise.all([
230
- (0, captureReferencedContents_js_1.readReferencedSnapshotBlobs)(snapshot, storage), // utf8 encoded
231
- (0, captureReferencedContents_js_1.captureReferencedAttachmentBlobs)(baseSnapshot, storage, gcData), // base64 encoded
232
- ]);
233
- const deltaStorage = await documentService.connectToDeltaStorage();
234
- const opsStream = deltaStorage.fetchMessages(attributes.sequenceNumber + 1, undefined, undefined, false, "captureFullContainerState");
278
+ if (blobCaptureMode === "inline") {
279
+ gcData = await (0, captureReferencedContents_js_1.parseGcSnapshotData)(baseSnapshot, storage);
280
+ [snapshotBlobs, attachmentBlobContents] = await Promise.all([
281
+ (0, captureReferencedContents_js_1.readReferencedSnapshotBlobs)(snapshot, storage), // utf8 encoded
282
+ (0, captureReferencedContents_js_1.captureReferencedAttachmentBlobs)(baseSnapshot, storage, gcData), // base64 encoded
283
+ ]);
284
+ }
235
285
  const savedOps = [];
286
+ const attachP = deltaManager.attachOpHandler(attributes.minimumSequenceNumber, attributes.sequenceNumber, {
287
+ process: (message) => savedOps.push(message),
288
+ processSignal: () => { },
289
+ }, "all");
290
+ await Promise.race([Promise.all([connectedP, attachP]), closedP]);
291
+ await Promise.race([waitForCatchUp(deltaManager), closedP]);
292
+ deltaManager.dispose();
236
293
  const postSnapshotBlobReferences = [];
237
- let opsResult = await opsStream.read();
238
- while (!opsResult.done) {
239
- for (const op of opsResult.value) {
240
- savedOps.push(op);
294
+ if (blobCaptureMode === "inline") {
295
+ for (const op of savedOps) {
241
296
  // Blobs uploaded after the base snapshot are not in its
242
297
  // `.blobs` redirect table, so `captureReferencedAttachmentBlobs`
243
298
  // did not see them. The wire-format BlobAttach op carries
244
299
  // `(localId, storageId)` in its metadata; collect those here so
245
300
  // we can backfill the bytes before sealing the artifact.
246
- const refs = (0, captureReferencedContents_js_1.extractBlobAttachReferences)(op);
247
- if (refs.length > 0) {
248
- postSnapshotBlobReferences.push(...refs);
249
- }
301
+ postSnapshotBlobReferences.push(...(0, captureReferencedContents_js_1.extractBlobAttachReferences)(op));
250
302
  }
251
- opsResult = await opsStream.read();
252
303
  }
253
304
  if (postSnapshotBlobReferences.length > 0) {
254
305
  const added = await (0, captureReferencedContents_js_1.inlineAttachmentBlobsByReference)(postSnapshotBlobReferences, storage, (0, captureReferencedContents_js_1.unreferencedAttachmentBlobLocalIds)(gcData), attachmentBlobContents);
@@ -258,6 +309,7 @@ async function captureFullContainerState({ urlResolver, documentServiceFactory,
258
309
  attached: true,
259
310
  baseSnapshot,
260
311
  snapshotBlobs,
312
+ blobContentsMode: blobCaptureMode === "reference" ? "reference" : undefined,
261
313
  attachmentBlobContents: Object.keys(attachmentBlobContents).length === 0 ? undefined : attachmentBlobContents,
262
314
  loadedGroupIdSnapshots: undefined,
263
315
  pendingRuntimeState: undefined,
@@ -267,10 +319,19 @@ async function captureFullContainerState({ urlResolver, documentServiceFactory,
267
319
  return JSON.stringify(pendingState);
268
320
  }
269
321
  finally {
322
+ deltaManager.dispose();
270
323
  documentService.dispose();
271
324
  }
272
325
  }
273
- exports.captureFullContainerState = captureFullContainerState;
326
+ async function waitForCatchUp(deltaManager) {
327
+ await new Promise((resolve) => {
328
+ const monitor = new catchUpMonitor_js_1.CatchUpMonitor(deltaManager, () => {
329
+ monitor.dispose();
330
+ resolve();
331
+ });
332
+ monitor.start();
333
+ });
334
+ }
274
335
  /**
275
336
  * Loads a summarizer container with the required headers, triggers an on-demand summary, and then closes it.
276
337
  * Returns success/failure and an optional error for host-side handling.
@@ -289,14 +350,13 @@ async function loadSummarizerContainerAndMakeSummary(loadSummarizerContainerProp
289
350
  }
290
351
  return result;
291
352
  }
292
- exports.loadSummarizerContainerAndMakeSummary = loadSummarizerContainerAndMakeSummary;
293
353
  async function loadSummarizerContainerAndMakeSummaryInternal(loadSummarizerContainerProps) {
294
354
  const { logger, configProvider, request: originalRequest } = loadSummarizerContainerProps;
295
355
  const telemetryProps = {
296
356
  loaderId: (0, uuid_1.v4)(),
297
357
  loaderVersion: packageVersion_js_1.pkgVersion,
298
358
  };
299
- const subMc = (0, internal_5.mixinMonitoringContext)(debugLogger_js_1.DebugLogger.mixinDebugLogger("fluid:telemetry", logger, {
359
+ const subMc = (0, internal_5.mixinMonitoringContext)((0, debugLogger_js_1.mixinDebugLogger)("fluid:telemetry", logger, {
300
360
  all: telemetryProps,
301
361
  }), internal_5.sessionStorageConfigProvider.value, configProvider);
302
362
  const mc = (0, internal_5.createChildMonitoringContext)({
@@ -1 +1 @@
1
- {"version":3,"file":"createAndLoadContainerUtils.js","sourceRoot":"","sources":["../src/createAndLoadContainerUtils.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 type {\n\tIContainer,\n\tICodeDetailsLoader,\n\tIFluidCodeDetails,\n\tIContainerPolicies,\n} from \"@fluidframework/container-definitions/internal\";\nimport { LoaderHeader } from \"@fluidframework/container-definitions/internal\";\nimport type {\n\tFluidObject,\n\tIConfigProviderBase,\n\tIRequest,\n\tITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport type { AllOrNone } from \"@fluidframework/core-interfaces/internal\";\nimport { validateAllOrNone } from \"@fluidframework/core-utils/internal\";\nimport type { IClientDetails } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIDocumentServiceFactory,\n\tIResolvedUrl,\n\tISequencedDocumentMessage,\n\tISnapshot,\n\tISnapshotTree,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { DriverHeader, FetchSource } from \"@fluidframework/driver-definitions/internal\";\nimport { getSnapshotTree } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tGenericError,\n\tUsageError,\n\tnormalizeError,\n\tcreateChildMonitoringContext,\n\tmixinMonitoringContext,\n\tsessionStorageConfigProvider,\n\tPerformanceEvent,\n\tisFluidError,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport {\n\tcaptureReferencedAttachmentBlobs,\n\textractBlobAttachReferences,\n\tinlineAttachmentBlobsByReference,\n\tparseGcSnapshotData,\n\treadReferencedSnapshotBlobs,\n\tsnapshotHasLoadingGroups,\n\tunreferencedAttachmentBlobLocalIds,\n\ttype IBlobAttachReference,\n} from \"./captureReferencedContents.js\";\nimport { DebugLogger } from \"./debugLogger.js\";\nimport { createFrozenDocumentServiceFactory } from \"./frozenServices.js\";\nimport { Loader } from \"./loader.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\nimport type { ProtocolHandlerBuilder } from \"./protocol.js\";\nimport type { IPendingContainerState } from \"./serializedStateManager.js\";\nimport type {\n\tLoadSummarizerSummaryResult,\n\tOnDemandSummaryResults,\n\tSummarizeOnDemandResults,\n} from \"./summarizerResultTypes.js\";\nimport {\n\tgetAttachedContainerStateFromSerializedContainer,\n\tgetDocumentAttributes,\n\ttryParseCompatibleResolvedUrl,\n} from \"./utils.js\";\n\ninterface OnDemandSummarizeResultsPromises {\n\treadonly summarySubmitted: Promise<SummarizeOnDemandResults[\"summarySubmitted\"]>;\n\treadonly summaryOpBroadcasted: Promise<SummarizeOnDemandResults[\"summaryOpBroadcasted\"]>;\n}\n\ninterface OnDemandSummarizeOptions {\n\treadonly reason?: string;\n\treadonly retryOnFailure?: boolean;\n\treadonly fullTree?: boolean;\n}\n\ninterface SummarizerLike {\n\treadonly ISummarizer?: SummarizerLike;\n\tsummarizeOnDemand(options: OnDemandSummarizeOptions): OnDemandSummarizeResultsPromises;\n}\n\n/**\n * Host-level container loader properties — the code loader plus all the\n * optional policy / observability fields that aren't tied to driver wiring.\n *\n * @remarks\n * Extracted as a reusable building block so other props types (create,\n * rehydrate, load, frozen-load) can compose it without duplicating the\n * optional-fields surface.\n *\n * @legacy @beta\n */\nexport interface IContainerHostProps {\n\t/**\n\t * The code loader handles loading the necessary code\n\t * for running a container once it is loaded.\n\t */\n\treadonly codeLoader: ICodeDetailsLoader;\n\n\t/**\n\t * A property bag of options/policies used by various layers\n\t * to control features\n\t */\n\treadonly options?: IContainerPolicies | undefined;\n\n\t/**\n\t * Scope is provided to all container and is a set of shared\n\t * services for container's to integrate with their host environment.\n\t */\n\treadonly scope?: FluidObject | undefined;\n\n\t/**\n\t * The logger that all telemetry should be pushed to.\n\t */\n\treadonly logger?: ITelemetryBaseLogger | undefined;\n\n\t/**\n\t * The configuration provider which may be used to control features.\n\t */\n\treadonly configProvider?: IConfigProviderBase | undefined;\n\n\t/**\n\t * Optional property for allowing the container to use a custom\n\t * protocol implementation for handling the quorum and/or the audience.\n\t */\n\treadonly protocolHandlerBuilder?: ProtocolHandlerBuilder | undefined;\n\n\t/**\n\t * Disables the Container from reconnecting if false, allows reconnect otherwise.\n\t */\n\treadonly allowReconnect?: boolean | undefined;\n\n\t/**\n\t * Client details provided in the override will be merged over the default client.\n\t */\n\treadonly clientDetailsOverride?: IClientDetails | undefined;\n}\n\n/**\n * The driver-services pair — `urlResolver` plus `documentServiceFactory` —\n * required to wire a container to a real driver at create or load time.\n *\n * @remarks\n * Extracted as a reusable building block so the `request` field can be\n * added on top for load-time props (see {@link IContainerLoadDriverProps})\n * while create-time props that don't carry a request can compose just this\n * pair.\n *\n * @legacy @beta\n */\nexport interface IContainerDriverServices {\n\t/**\n\t * The url resolver used by the loader for resolving external urls\n\t * into Fluid urls such that the container specified by the\n\t * external url can be loaded.\n\t */\n\treadonly urlResolver: IUrlResolver;\n\t/**\n\t * The document service factory take the Fluid url provided\n\t * by the resolved url and constructs all the necessary services\n\t * for communication with the container's server.\n\t */\n\treadonly documentServiceFactory: IDocumentServiceFactory;\n}\n\n/**\n * The load-time driver wiring trio — `request`, `urlResolver`, and\n * `documentServiceFactory` together.\n *\n * @remarks\n * Reused as the all-or-nothing group for entry points (e.g. the frozen-load\n * entry point) that accept either a full driver wiring (online form) or none\n * of it (offline form). See `AllOrNone` in `@fluidframework/core-interfaces`.\n *\n * @legacy @beta\n */\nexport interface IContainerLoadDriverProps extends IContainerDriverServices {\n\t/**\n\t * The request to resolve the container.\n\t */\n\treadonly request: IRequest;\n}\n\n/**\n * Properties necessary for creating and loading a container.\n *\n * @deprecated\n * Use the composable building blocks instead: extend\n * {@link IContainerHostProps} for the code-loader / policy / observability\n * surface and {@link IContainerDriverServices} for the\n * `urlResolver` / `documentServiceFactory` pair, or compose them inline as\n * `IContainerHostProps & IContainerDriverServices`. This interface is kept\n * as an alias for back-compat and will be removed in a future release.\n *\n * @legacy @beta\n */\nexport interface ICreateAndLoadContainerProps\n\textends IContainerHostProps,\n\t\tIContainerDriverServices {}\n\n/**\n * Props used to load a container.\n * @legacy @beta\n */\nexport interface ILoadExistingContainerProps\n\textends IContainerHostProps,\n\t\tIContainerDriverServices {\n\t/**\n\t * The request to resolve the container.\n\t */\n\treadonly request: IRequest;\n\n\t/**\n\t * Pending local state to be applied to the container.\n\t */\n\treadonly pendingLocalState?: string | undefined;\n}\n\n/**\n * Props used to load summarizer container.\n * @legacy @alpha\n */\nexport type ILoadSummarizerContainerProps = Omit<\n\tILoadExistingContainerProps,\n\t\"pendingLocalState\"\n>;\n\n/**\n * Props used to create a detached container.\n * @legacy @beta\n */\nexport interface ICreateDetachedContainerProps\n\textends IContainerHostProps,\n\t\tIContainerDriverServices {\n\t/**\n\t * The code details for the container to be created.\n\t */\n\treadonly codeDetails: IFluidCodeDetails;\n}\n\n/**\n * Props used to rehydrate a detached container.\n * @legacy @beta\n */\nexport interface IRehydrateDetachedContainerProps\n\textends IContainerHostProps,\n\t\tIContainerDriverServices {\n\t/**\n\t * The serialized state returned by calling serialize on another container\n\t */\n\treadonly serializedState: string;\n}\n\n/**\n * Creates a new container using the specified code details but in an unattached state. While unattached, all\n * updates will only be local until the user explicitly attaches the container to a service provider.\n * @param createDetachedContainerProps - Services and properties necessary for creating detached container.\n * @legacy @beta\n */\nexport async function createDetachedContainer(\n\tcreateDetachedContainerProps: ICreateDetachedContainerProps,\n): Promise<IContainer> {\n\tconst loader = new Loader(createDetachedContainerProps);\n\treturn loader.createDetachedContainer(createDetachedContainerProps.codeDetails, {\n\t\tcanReconnect: createDetachedContainerProps.allowReconnect,\n\t\tclientDetailsOverride: createDetachedContainerProps.clientDetailsOverride,\n\t});\n}\n\n/**\n * Creates a new container using the specified snapshot but in an unattached state. While unattached, all\n * updates will only be local until the user explicitly attaches the container to a service provider.\n * @param rehydrateDetachedContainerProps - Services and properties necessary for rehydrating detached container from a previously serialized container's state.\n * @legacy @beta\n */\nexport async function rehydrateDetachedContainer(\n\trehydrateDetachedContainerProps: IRehydrateDetachedContainerProps,\n): Promise<IContainer> {\n\tconst loader = new Loader(rehydrateDetachedContainerProps);\n\treturn loader.rehydrateDetachedContainerFromSnapshot(\n\t\trehydrateDetachedContainerProps.serializedState,\n\t\t{\n\t\t\tcanReconnect: rehydrateDetachedContainerProps.allowReconnect,\n\t\t\tclientDetailsOverride: rehydrateDetachedContainerProps.clientDetailsOverride,\n\t\t},\n\t);\n}\n\n/**\n * Loads a container with an existing snapshot from the service.\n * @param loadExistingContainerProps - Services and properties necessary for loading an existing container.\n * @legacy @beta\n */\nexport async function loadExistingContainer(\n\tloadExistingContainerProps: ILoadExistingContainerProps,\n): Promise<IContainer> {\n\tconst loader = new Loader(loadExistingContainerProps);\n\treturn loader.resolve(\n\t\tloadExistingContainerProps.request,\n\t\tloadExistingContainerProps.pendingLocalState,\n\t);\n}\n\n/**\n * Properties required to load a frozen container from pending state.\n *\n * @remarks\n * Two forms are supported and selected by the presence of the driver-wiring\n * fields. **Online** form supplies `request`, `urlResolver`, and\n * `documentServiceFactory`; the supplied factory is wrapped in a frozen\n * factory and the resolver is used to re-resolve the request URL just as with\n * {@link loadExistingContainer}. **Offline** form omits all three driver\n * fields; the captured URL stored in `pendingLocalState` is used to\n * synthesize a resolved URL, no real driver is contacted, and\n * `IContainer.getAbsoluteUrl` throws on the returned container because the\n * resolver's external URL format is unknown without a real `IUrlResolver`.\n *\n * **Offline form precondition.** With no driver wiring there is no live\n * storage to read attachment blobs from, so any blob the runtime dereferences\n * during load must already be inlined into `pendingLocalState`. The pending\n * state must therefore be produced by {@link captureFullContainerState}\n * (which inlines all referenced attachment blobs) rather than\n * `IContainer.getPendingLocalState` / `getRequiredPendingLocalState` (which\n * do not). If the runtime needs an attachment blob that is not inlined, the\n * load fails with `UsageError` from the synthesized storage service.\n *\n * **URL shape requirement.** In the offline form the captured\n * `pendingLocalState.url` is the only URL available; it is parsed in place of\n * a real `IUrlResolver.resolve()` call, so it must satisfy\n * {@link tryParseCompatibleResolvedUrl}'s contract — a resolved URL of shape\n * `protocol://<string>/.../..?<querystring>`. This is the format that\n * Fluid-shipped drivers emit; drivers that emit a non-standard resolved-URL\n * shape will surface as a `UsageError` at load time. The online form has no\n * such constraint because the supplied resolver controls URL parsing.\n *\n * The offline form supports `readOnly: false` for the same capture-and-relay\n * use case as the online form: local DDS submissions accrue in the runtime's\n * pending-state manager and can be captured via `getPendingLocalState` for\n * a later online replay. Nothing is published from an offline container.\n *\n * Mixing the two forms (some driver fields supplied, others omitted) is a\n * compile-time error courtesy of the `AllOrNone` modifier from\n * `@fluidframework/core-interfaces`.\n * @legacy @alpha\n */\nexport type ILoadFrozenContainerFromPendingStateProps = IContainerHostProps & {\n\t/**\n\t * Pending local state to be applied to the container.\n\t */\n\treadonly pendingLocalState: string;\n\n\t/**\n\t * Controls whether the frozen container is surfaced as read-only.\n\t *\n\t * Defaults to `true`. When `true`, the container reports `readOnlyInfo.readonly === true`\n\t * with `storageOnly === true`, matching the historical behavior of frozen loads.\n\t *\n\t * When `false`, the container loads as writable so the runtime will accept DDS submissions.\n\t * The connection itself stays `Connected`: the connection manager recognizes the synthetic\n\t * frozen delta stream and drops outbound messages at the network layer, so no read→write\n\t * reconnect is attempted. Local DDS state continues to update via optimistic apply, and\n\t * submitted ops accumulate in the runtime's pending-state manager. Use this when callers\n\t * want to accrue and capture pending state without publishing it.\n\t *\n\t * @remarks\n\t * The flag uses negative polarity (`readOnly`) rather than a positive opt-in (`writable`)\n\t * to align with `IContainer.readOnlyInfo.readonly`, which is the established surface for\n\t * read/write state on a loaded container. A future positive-polarity option can layer on\n\t * top of this without breaking callers, but flipping the polarity now would split readers\n\t * between two conventions for the same concept.\n\t *\n\t * Subsystem behavior is unchanged from the read-only frozen path regardless of `readOnly`:\n\t * storage operations still throw (only `readBlob` is supported); summarizer / id-compressor\n\t * never fire because no acks arrive; the quorum is whatever was captured in pending state\n\t * and gains no members during the writable-frozen lifetime. The only behavioral delta is\n\t * that the runtime accepts DDS submissions and accumulates them in `pendingStateManager`.\n\t */\n\treadonly readOnly?: boolean;\n} & AllOrNone<IContainerLoadDriverProps>;\n\nconst driverPropKeys = [\"request\", \"urlResolver\", \"documentServiceFactory\"] as const;\n\n// Recognizable opaque placeholder used as `request.url` for the offline form of\n// `loadFrozenContainerFromPendingState`. The synthesized `IUrlResolver` ignores\n// its argument and returns a `IResolvedUrl` derived from `pendingLocalState.url`,\n// so this string is never interpreted as a real URL by any downstream stage; it\n// only needs to be a fixed sentinel that won't collide with real request URLs.\nconst offlineFrozenRequestPlaceholderUrl =\n\t\"frozen-load-from-pending-state://offline-placeholder\";\n\n/**\n * Loads a frozen container from pending local state.\n * @param props - Properties required to load a frozen container from pending state.\n * @legacy @alpha\n */\nexport async function loadFrozenContainerFromPendingState(\n\tprops: ILoadFrozenContainerFromPendingStateProps,\n): Promise<IContainer> {\n\tconst fnName = loadFrozenContainerFromPendingState.name;\n\tconst { readOnly, pendingLocalState } = props;\n\n\tconst driverWiring = validateAllOrNone<IContainerLoadDriverProps>(props, driverPropKeys);\n\n\tif (driverWiring === \"mixed\") {\n\t\tthrow new UsageError(\n\t\t\t`${fnName}: ${driverPropKeys.join(\", \")} must all be provided or all omitted`,\n\t\t);\n\t}\n\n\tif (driverWiring === \"none\") {\n\t\t// Offline: synthesize the driver wiring from the URL captured in pending state.\n\t\t// The container's load pipeline is reused unchanged — the synthesized resolver\n\t\t// returns a resolved URL whose `url` equals `pendingLocalState.url`, so the\n\t\t// identity guard in `Loader.resolveCore` is trivially satisfied.\n\t\tconst pending = getAttachedContainerStateFromSerializedContainer(pendingLocalState);\n\t\tconst parsed = tryParseCompatibleResolvedUrl(pending.url);\n\t\tif (parsed === undefined) {\n\t\t\tthrow new UsageError(\n\t\t\t\t`${fnName}: pending state URL is not in a parseable form (${pending.url})`,\n\t\t\t);\n\t\t}\n\t\t// `tryParseCompatibleResolvedUrl` returns `parsed.id` as the first two\n\t\t// path segments joined by `/` (i.e. `tenantId/docId`). Production\n\t\t// resolvers populate `IResolvedUrl.id` with the single doc-id segment\n\t\t// (see `localResolver.ts`, `insecureUrlResolver.ts`,\n\t\t// `routerlicious-urlResolver/urlResolver.ts`, `odspDriverUrlResolver.ts`),\n\t\t// so downstream consumers reading `IContainer.resolvedUrl.id` for\n\t\t// telemetry / cache keys expect the single-segment shape. Take the\n\t\t// trailing segment so offline-loaded containers match that contract.\n\t\tconst parsedIdSegments = parsed.id.split(\"/\");\n\t\tconst synthesizedId = parsedIdSegments[parsedIdSegments.length - 1] ?? parsed.id;\n\t\tconst synthesizedResolvedUrl: IResolvedUrl = {\n\t\t\ttype: \"fluid\",\n\t\t\tid: synthesizedId,\n\t\t\turl: pending.url,\n\t\t\t// `tokens` and `endpoints` are empty because no real driver is contacted; the\n\t\t\t// frozen factory never reads them. A future offline mode that needs them would\n\t\t\t// require carrying them in the pending-state format.\n\t\t\ttokens: {},\n\t\t\tendpoints: {},\n\t\t};\n\t\tconst synthesizedUrlResolver: IUrlResolver = {\n\t\t\t// The argument is ignored: in offline mode the only URL in the system is the\n\t\t\t// one captured in pending state. Any request is mapped to the same resolved URL.\n\t\t\tresolve: async () => synthesizedResolvedUrl,\n\t\t\t// External (request-form) URLs cannot be reconstructed from the captured\n\t\t\t// resolved URL alone, so we cannot honor `getAbsoluteUrl`. Surface the misuse\n\t\t\t// loudly rather than fabricate a string in the wrong format.\n\t\t\tgetAbsoluteUrl: async () => {\n\t\t\t\tthrow new UsageError(`${fnName}: getAbsoluteUrl requires ${driverPropKeys.join(\"/\")}`);\n\t\t\t},\n\t\t};\n\t\treturn loadExistingContainer({\n\t\t\t...props,\n\t\t\t// `request.url` is unused: `synthesizedUrlResolver.resolve()` returns\n\t\t\t// `synthesizedResolvedUrl` regardless of input, and the identity\n\t\t\t// guard in `Loader.resolveCore` compares the resolver's output URL\n\t\t\t// against `pendingLocalState.url` — both equal `pending.url` here.\n\t\t\t// Using a recognizable opaque placeholder instead of the resolved-form\n\t\t\t// URL avoids implying that any downstream stage interprets it as a\n\t\t\t// request-form URL.\n\t\t\trequest: { url: offlineFrozenRequestPlaceholderUrl, headers: {} },\n\t\t\turlResolver: synthesizedUrlResolver,\n\t\t\tdocumentServiceFactory: createFrozenDocumentServiceFactory(undefined, readOnly),\n\t\t});\n\t}\n\n\t// Online: wrap the caller-supplied factory so the live driver only serves blob reads.\n\t// `driverWiring === \"all\"` narrows `props` to the form that carries the driver fields.\n\tconst onlineProps = props as ILoadFrozenContainerFromPendingStateProps &\n\t\tIContainerLoadDriverProps;\n\treturn loadExistingContainer({\n\t\t...onlineProps,\n\t\tdocumentServiceFactory: createFrozenDocumentServiceFactory(\n\t\t\tonlineProps.documentServiceFactory,\n\t\t\treadOnly,\n\t\t),\n\t});\n}\n\n/**\n * Properties for {@link captureFullContainerState}.\n * @legacy @alpha\n */\nexport interface ICaptureFullContainerStateProps {\n\t/**\n\t * The url resolver used to resolve the request into a Fluid resolved url.\n\t */\n\treadonly urlResolver: IUrlResolver;\n\t/**\n\t * The document service factory used to construct the driver services\n\t * against which the state is captured.\n\t */\n\treadonly documentServiceFactory: IDocumentServiceFactory;\n\t/**\n\t * The request identifying the container whose state is to be captured.\n\t */\n\treadonly request: IRequest;\n\t/**\n\t * Optional logger for driver-side telemetry.\n\t */\n\treadonly logger?: ITelemetryBaseLogger | undefined;\n}\n\n/**\n * Captures the current state of an attached container using only driver-level\n * services, without instantiating a runtime or loading a full container. The\n * returned string is a serialized pending container state in the same wire\n * format produced by a live container's pending-state serialization, and can\n * be handed to {@link loadExistingContainer} as `pendingLocalState`.\n *\n * The output is a self-contained view of the container's referenced graph:\n * the latest snapshot, inlined contents of every blob reachable through\n * referenced subtrees, inlined contents of every referenced attachment blob\n * keyed by storage id, and all ops with sequence numbers after the base\n * snapshot's sequence number (as read from its attributes blob).\n *\n * Reachability respects GC. Snapshot subtrees flagged `unreferenced: true`\n * are skipped (their contents are not inlined). Attachment blobs that GC has\n * marked unreferenced, tombstoned, or deleted are skipped. When the snapshot\n * has no GC tree (GC disabled or pre-GC document), no filtering is applied.\n *\n * Blob reads on load hit the `ContainerStorageAdapter` cache populated from\n * the captured `snapshotBlobs` map, so a frozen loader can serve the full\n * referenced graph without a live storage service.\n *\n * `pendingRuntimeState` is `undefined` — no runtime is instantiated — so the\n * output cannot carry DDS-level in-flight changes. It is intended for state\n * relay, inspection, and durable-state snapshot use cases.\n *\n * Containers that declare loading groups are not yet supported: the function\n * throws `UsageError` if any referenced subtree carries a `groupId`. Group\n * snapshots would need a separate prefetch + serialization path; until there\n * is a known consumer and end-to-end coverage, the capture refuses rather\n * than silently producing pending state that omits group data.\n *\n * Note: if a new snapshot lands between the snapshot fetch and the ops fetch,\n * the returned state may not reflect the very latest snapshot, but remains\n * internally consistent: ops are anchored to the snapshot that was captured.\n *\n * No `mixinMonitoringContext` / `configProvider` is wired here, deliberately\n * diverging from the sibling entry points in this file. The function reads\n * no feature flags and instantiates no runtime, so there is nothing for a\n * monitoring context to gate or attribute. If a future change introduces\n * config-gated behavior or runtime-attributed telemetry, add the wiring\n * back together with that change.\n * @legacy @alpha\n */\nexport async function captureFullContainerState({\n\turlResolver,\n\tdocumentServiceFactory,\n\trequest,\n\tlogger,\n}: ICaptureFullContainerStateProps): Promise<string> {\n\tconst resolvedUrl = await urlResolver.resolve(request);\n\tif (resolvedUrl === undefined) {\n\t\tthrow new UsageError(\"Failed to resolve request to a Fluid URL\");\n\t}\n\n\t// Validate the resolver's URL shape at capture time. The captured pending\n\t// state is rehydrated later (possibly in a different process) via the\n\t// offline form of `loadFrozenContainerFromPendingState`, which requires\n\t// `tryParseCompatibleResolvedUrl` to succeed on `pendingLocalState.url`.\n\t// Failing fast here turns \"your captured artifact silently isn't\n\t// rehydratable\" into a same-call error a partner can act on, instead of\n\t// surfacing as a `UsageError` at offline-load time in a different process.\n\tif (tryParseCompatibleResolvedUrl(resolvedUrl.url) === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`${captureFullContainerState.name}: resolved URL is not in the shape required by tryParseCompatibleResolvedUrl (protocol://<string>/<tenantId>/<docId>?<querystring>); captured state would not rehydrate offline (${resolvedUrl.url})`,\n\t\t);\n\t}\n\n\tconst documentService = await documentServiceFactory.createDocumentService(\n\t\tresolvedUrl,\n\t\tlogger,\n\t);\n\ttry {\n\t\tconst storage = await documentService.connectToStorage();\n\n\t\tconst versions = await storage.getVersions(\n\t\t\t// `null` signals \"latest\"\n\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\tnull,\n\t\t\t1,\n\t\t\t\"captureFullContainerState\",\n\t\t\tFetchSource.noCache,\n\t\t);\n\t\tconst version = versions[0];\n\t\tconst snapshot: ISnapshot | ISnapshotTree | undefined =\n\t\t\tstorage.getSnapshot === undefined\n\t\t\t\t? ((await storage.getSnapshotTree(version, \"captureFullContainerState\")) ?? undefined)\n\t\t\t\t: await storage.getSnapshot({\n\t\t\t\t\t\tcacheSnapshot: false,\n\t\t\t\t\t\tversionId: version?.id,\n\t\t\t\t\t\tscenarioName: \"captureFullContainerState\",\n\t\t\t\t\t});\n\t\tif (snapshot === undefined) {\n\t\t\tthrow new GenericError(\"Failed to fetch snapshot for captureFullContainerState\");\n\t\t}\n\n\t\tconst baseSnapshot = getSnapshotTree(snapshot);\n\t\tif (snapshotHasLoadingGroups(baseSnapshot)) {\n\t\t\tthrow new UsageError(\n\t\t\t\t\"captureFullContainerState does not yet support containers with loading groups\",\n\t\t\t);\n\t\t}\n\t\tconst attributes = await getDocumentAttributes(storage, baseSnapshot);\n\t\tconst gcData = await parseGcSnapshotData(baseSnapshot, storage);\n\t\t// Structural snapshot blobs (JSON/text the runtime authored) are\n\t\t// UTF-8-encoded; attachment blobs may carry arbitrary binary bytes\n\t\t// and are base64-encoded. Keep them on separate fields of the\n\t\t// pending state so the load side can apply the matching decoder\n\t\t// without ambiguity. See IPendingContainerState.attachmentBlobContents.\n\t\tconst [snapshotBlobs, attachmentBlobContents] = await Promise.all([\n\t\t\treadReferencedSnapshotBlobs(snapshot, storage), // utf8 encoded\n\t\t\tcaptureReferencedAttachmentBlobs(baseSnapshot, storage, gcData), // base64 encoded\n\t\t]);\n\n\t\tconst deltaStorage = await documentService.connectToDeltaStorage();\n\t\tconst opsStream = deltaStorage.fetchMessages(\n\t\t\tattributes.sequenceNumber + 1,\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tfalse,\n\t\t\t\"captureFullContainerState\",\n\t\t);\n\t\tconst savedOps: ISequencedDocumentMessage[] = [];\n\t\tconst postSnapshotBlobReferences: IBlobAttachReference[] = [];\n\t\tlet opsResult = await opsStream.read();\n\t\twhile (!opsResult.done) {\n\t\t\tfor (const op of opsResult.value) {\n\t\t\t\tsavedOps.push(op);\n\t\t\t\t// Blobs uploaded after the base snapshot are not in its\n\t\t\t\t// `.blobs` redirect table, so `captureReferencedAttachmentBlobs`\n\t\t\t\t// did not see them. The wire-format BlobAttach op carries\n\t\t\t\t// `(localId, storageId)` in its metadata; collect those here so\n\t\t\t\t// we can backfill the bytes before sealing the artifact.\n\t\t\t\tconst refs = extractBlobAttachReferences(op);\n\t\t\t\tif (refs.length > 0) {\n\t\t\t\t\tpostSnapshotBlobReferences.push(...refs);\n\t\t\t\t}\n\t\t\t}\n\t\t\topsResult = await opsStream.read();\n\t\t}\n\n\t\tif (postSnapshotBlobReferences.length > 0) {\n\t\t\tconst added = await inlineAttachmentBlobsByReference(\n\t\t\t\tpostSnapshotBlobReferences,\n\t\t\t\tstorage,\n\t\t\t\tunreferencedAttachmentBlobLocalIds(gcData),\n\t\t\t\tattachmentBlobContents,\n\t\t\t);\n\t\t\tObject.assign(attachmentBlobContents, added);\n\t\t}\n\n\t\tconst pendingState: IPendingContainerState = {\n\t\t\tattached: true,\n\t\t\tbaseSnapshot,\n\t\t\tsnapshotBlobs,\n\t\t\tattachmentBlobContents:\n\t\t\t\tObject.keys(attachmentBlobContents).length === 0 ? undefined : attachmentBlobContents,\n\t\t\tloadedGroupIdSnapshots: undefined,\n\t\t\tpendingRuntimeState: undefined,\n\t\t\tsavedOps,\n\t\t\turl: resolvedUrl.url,\n\t\t};\n\t\treturn JSON.stringify(pendingState);\n\t} finally {\n\t\tdocumentService.dispose();\n\t}\n}\n\n/**\n * Loads a summarizer container with the required headers, triggers an on-demand summary, and then closes it.\n * Returns success/failure and an optional error for host-side handling.\n *\n * @legacy @alpha\n */\nexport async function loadSummarizerContainerAndMakeSummary(\n\tloadSummarizerContainerProps: ILoadSummarizerContainerProps,\n): Promise<LoadSummarizerSummaryResult> {\n\tlet result = await loadSummarizerContainerAndMakeSummaryInternal(\n\t\tloadSummarizerContainerProps,\n\t);\n\tif (!result.success) {\n\t\t/**\n\t\t * We retry once as there is potential for a race condition when loading a snapshot.\n\t\t * If the newest snapshot is not ready when creating the container but becomes available upon catching up, the container\n\t\t * will be closed so it can load from the new snapshot.\n\t\t */\n\t\tresult = await loadSummarizerContainerAndMakeSummaryInternal(loadSummarizerContainerProps);\n\t}\n\treturn result;\n}\n\nasync function loadSummarizerContainerAndMakeSummaryInternal(\n\tloadSummarizerContainerProps: ILoadSummarizerContainerProps,\n): Promise<LoadSummarizerSummaryResult> {\n\tconst { logger, configProvider, request: originalRequest } = loadSummarizerContainerProps;\n\tconst telemetryProps = {\n\t\tloaderId: uuid(),\n\t\tloaderVersion: pkgVersion,\n\t};\n\n\tconst subMc = mixinMonitoringContext(\n\t\tDebugLogger.mixinDebugLogger(\"fluid:telemetry\", logger, {\n\t\t\tall: telemetryProps,\n\t\t}),\n\t\tsessionStorageConfigProvider.value,\n\t\tconfigProvider,\n\t);\n\tconst mc = createChildMonitoringContext({\n\t\tlogger: subMc.logger,\n\t\tnamespace: \"SummarizerOnDemand\",\n\t});\n\treturn PerformanceEvent.timedExecAsync(\n\t\tmc.logger,\n\t\t{ eventName: \"SummarizerOnDemandSummary\" },\n\t\tasync (event) => {\n\t\t\tconst baseHeaders = originalRequest.headers;\n\t\t\tconst request = {\n\t\t\t\t...originalRequest,\n\t\t\t\theaders: {\n\t\t\t\t\t...baseHeaders,\n\t\t\t\t\t[LoaderHeader.cache]: false,\n\t\t\t\t\t[LoaderHeader.clientDetails]: {\n\t\t\t\t\t\tcapabilities: { interactive: false },\n\t\t\t\t\t\ttype: \"summarizer\",\n\t\t\t\t\t},\n\t\t\t\t\t[DriverHeader.summarizingClient]: true,\n\t\t\t\t\t[LoaderHeader.reconnect]: false,\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst container = await loadExistingContainer({\n\t\t\t\t...loadSummarizerContainerProps,\n\t\t\t\trequest,\n\t\t\t});\n\n\t\t\tlet summarySubmitted: SummarizeOnDemandResults[\"summarySubmitted\"];\n\t\t\tlet summaryOpBroadcasted: SummarizeOnDemandResults[\"summaryOpBroadcasted\"];\n\t\t\ttry {\n\t\t\t\tif (container.getEntryPoint === undefined) {\n\t\t\t\t\tthrow new GenericError(\"container.getEntryPoint() is undefined\");\n\t\t\t\t}\n\t\t\t\tconst fluidObject = (await container.getEntryPoint()) as FluidObject<SummarizerLike>;\n\t\t\t\tconst summarizer = fluidObject?.ISummarizer;\n\t\t\t\tif (summarizer === undefined) {\n\t\t\t\t\tthrow new GenericError(\"Summarizer entry point not available\");\n\t\t\t\t}\n\t\t\t\t// Host controlled feature gate for fullTree\n\t\t\t\t// Default value will be false\n\t\t\t\tconst fullTreeGate =\n\t\t\t\t\tmc.config.getBoolean(\"Fluid.Summarizer.FullTree.OnDemand\") === true;\n\n\t\t\t\tconst summarizeResults: OnDemandSummarizeResultsPromises =\n\t\t\t\t\tsummarizer.summarizeOnDemand({\n\t\t\t\t\t\treason: \"summaryOnRequest\",\n\t\t\t\t\t\tretryOnFailure: true,\n\t\t\t\t\t\tfullTree: fullTreeGate,\n\t\t\t\t\t});\n\t\t\t\t[summarySubmitted, summaryOpBroadcasted] = await Promise.all([\n\t\t\t\t\tsummarizeResults.summarySubmitted,\n\t\t\t\t\tsummarizeResults.summaryOpBroadcasted,\n\t\t\t\t]);\n\n\t\t\t\tconst summaryResults: OnDemandSummaryResults = {\n\t\t\t\t\tsummarySubmitted: summarySubmitted.success,\n\t\t\t\t\tsummaryInfo: summarySubmitted.success\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tstage: summarySubmitted.data.stage,\n\t\t\t\t\t\t\t\thandle: summaryOpBroadcasted.success\n\t\t\t\t\t\t\t\t\t? summaryOpBroadcasted.data.summarizeOp.contents.handle\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {},\n\t\t\t\t\tsummaryOpBroadcasted: summaryOpBroadcasted.success,\n\t\t\t\t};\n\n\t\t\t\tif (summarySubmitted.success && summaryOpBroadcasted.success) {\n\t\t\t\t\tevent.end({\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tsummarySubmitted: true,\n\t\t\t\t\t\tsummaryOpBroadcasted: true,\n\t\t\t\t\t});\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tsummaryResults,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst failureError =\n\t\t\t\t\tsummarySubmitted.success === false\n\t\t\t\t\t\t? summarySubmitted.error\n\t\t\t\t\t\t: summaryOpBroadcasted.success === false\n\t\t\t\t\t\t\t? summaryOpBroadcasted.error\n\t\t\t\t\t\t\t: new GenericError(\"On demand summary failed\");\n\n\t\t\t\tevent.end({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tsummarySubmitted: summarySubmitted.success,\n\t\t\t\t\tsummaryOpBroadcasted: summaryOpBroadcasted.success,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: failureError,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tevent.cancel({ success: false }, error);\n\t\t\t\tconst caughtError = isFluidError(error) ? error : normalizeError(error);\n\t\t\t\treturn { success: false, error: caughtError };\n\t\t\t} finally {\n\t\t\t\tcontainer.dispose();\n\t\t\t}\n\t\t},\n\t\t{ start: true, end: true, cancel: \"generic\" },\n\t);\n}\n"]}
1
+ {"version":3,"file":"createAndLoadContainerUtils.js","sourceRoot":"","sources":["../src/createAndLoadContainerUtils.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 type {\n\tIContainer,\n\tICodeDetailsLoader,\n\tIFluidCodeDetails,\n\tIContainerPolicies,\n} from \"@fluidframework/container-definitions/internal\";\nimport { LoaderHeader } from \"@fluidframework/container-definitions/internal\";\nimport type {\n\tFluidObject,\n\tIConfigProviderBase,\n\tIRequest,\n\tITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport type { AllOrNone } from \"@fluidframework/core-interfaces/internal\";\nimport { validateAllOrNone } from \"@fluidframework/core-utils/internal\";\nimport type { IClient, IClientDetails } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIDocumentServiceFactory,\n\tIResolvedUrl,\n\tISequencedDocumentMessage,\n\tISnapshot,\n\tISnapshotTree,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { DriverHeader, FetchSource } from \"@fluidframework/driver-definitions/internal\";\nimport { getSnapshotTree } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tGenericError,\n\tUsageError,\n\tcreateChildLogger,\n\tnormalizeError,\n\tcreateChildMonitoringContext,\n\tmixinMonitoringContext,\n\tsessionStorageConfigProvider,\n\tPerformanceEvent,\n\tisFluidError,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport {\n\tcaptureReferencedAttachmentBlobs,\n\textractBlobAttachReferences,\n\tinlineAttachmentBlobsByReference,\n\tparseGcSnapshotData,\n\treadReferencedSnapshotBlobs,\n\tsnapshotHasLoadingGroups,\n\tunreferencedAttachmentBlobLocalIds,\n\ttype IBlobAttachReference,\n\ttype IGcSnapshotData,\n} from \"./captureReferencedContents.js\";\nimport { CatchUpMonitor } from \"./catchUpMonitor.js\";\nimport { mixinDebugLogger } from \"./debugLogger.js\";\nimport { createDeltaManager } from \"./deltaManagerFactory.js\";\nimport { createFrozenDocumentServiceFactory } from \"./frozenServices.js\";\nimport { Loader } from \"./loader.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\nimport type { ProtocolHandlerBuilder } from \"./protocol.js\";\nimport type { IPendingContainerState } from \"./serializedStateManager.js\";\nimport type {\n\tLoadSummarizerSummaryResult,\n\tOnDemandSummaryResults,\n\tSummarizeOnDemandResults,\n} from \"./summarizerResultTypes.js\";\nimport {\n\tgetAttachedContainerStateFromSerializedContainer,\n\tgetDocumentAttributes,\n\ttryParseCompatibleResolvedUrl,\n} from \"./utils.js\";\n\ninterface OnDemandSummarizeResultsPromises {\n\treadonly summarySubmitted: Promise<SummarizeOnDemandResults[\"summarySubmitted\"]>;\n\treadonly summaryOpBroadcasted: Promise<SummarizeOnDemandResults[\"summaryOpBroadcasted\"]>;\n}\n\ninterface OnDemandSummarizeOptions {\n\treadonly reason?: string;\n\treadonly retryOnFailure?: boolean;\n\treadonly fullTree?: boolean;\n}\n\ninterface SummarizerLike {\n\treadonly ISummarizer?: SummarizerLike;\n\tsummarizeOnDemand(options: OnDemandSummarizeOptions): OnDemandSummarizeResultsPromises;\n}\n\n/**\n * Host-level container loader properties — the code loader plus all the\n * optional policy / observability fields that aren't tied to driver wiring.\n *\n * @remarks\n * Extracted as a reusable building block so other props types (create,\n * rehydrate, load, frozen-load) can compose it without duplicating the\n * optional-fields surface.\n *\n * @legacy @beta\n */\nexport interface IContainerHostProps {\n\t/**\n\t * The code loader handles loading the necessary code\n\t * for running a container once it is loaded.\n\t */\n\treadonly codeLoader: ICodeDetailsLoader;\n\n\t/**\n\t * A property bag of options/policies used by various layers\n\t * to control features\n\t */\n\treadonly options?: IContainerPolicies | undefined;\n\n\t/**\n\t * Scope is provided to all container and is a set of shared\n\t * services for container's to integrate with their host environment.\n\t */\n\treadonly scope?: FluidObject | undefined;\n\n\t/**\n\t * The logger that all telemetry should be pushed to.\n\t */\n\treadonly logger?: ITelemetryBaseLogger | undefined;\n\n\t/**\n\t * The configuration provider which may be used to control features.\n\t */\n\treadonly configProvider?: IConfigProviderBase | undefined;\n\n\t/**\n\t * Optional property for allowing the container to use a custom\n\t * protocol implementation for handling the quorum and/or the audience.\n\t */\n\treadonly protocolHandlerBuilder?: ProtocolHandlerBuilder | undefined;\n\n\t/**\n\t * Disables the Container from reconnecting if false, allows reconnect otherwise.\n\t */\n\treadonly allowReconnect?: boolean | undefined;\n\n\t/**\n\t * Client details provided in the override will be merged over the default client.\n\t */\n\treadonly clientDetailsOverride?: IClientDetails | undefined;\n}\n\n/**\n * The driver-services pair — `urlResolver` plus `documentServiceFactory` —\n * required to wire a container to a real driver at create or load time.\n *\n * @remarks\n * Extracted as a reusable building block so the `request` field can be\n * added on top for load-time props (see {@link IContainerLoadDriverProps})\n * while create-time props that don't carry a request can compose just this\n * pair.\n *\n * @legacy @beta\n */\nexport interface IContainerDriverServices {\n\t/**\n\t * The url resolver used by the loader for resolving external urls\n\t * into Fluid urls such that the container specified by the\n\t * external url can be loaded.\n\t */\n\treadonly urlResolver: IUrlResolver;\n\t/**\n\t * The document service factory take the Fluid url provided\n\t * by the resolved url and constructs all the necessary services\n\t * for communication with the container's server.\n\t */\n\treadonly documentServiceFactory: IDocumentServiceFactory;\n}\n\n/**\n * The load-time driver wiring trio — `request`, `urlResolver`, and\n * `documentServiceFactory` together.\n *\n * @remarks\n * Reused as the all-or-nothing group for entry points (e.g. the frozen-load\n * entry point) that accept either a full driver wiring (online form) or none\n * of it (offline form). See `AllOrNone` in `@fluidframework/core-interfaces`.\n *\n * @legacy @beta\n */\nexport interface IContainerLoadDriverProps extends IContainerDriverServices {\n\t/**\n\t * The request to resolve the container.\n\t */\n\treadonly request: IRequest;\n}\n\n/**\n * Properties necessary for creating and loading a container.\n *\n * @deprecated\n * Use the composable building blocks instead: extend\n * {@link IContainerHostProps} for the code-loader / policy / observability\n * surface and {@link IContainerDriverServices} for the\n * `urlResolver` / `documentServiceFactory` pair, or compose them inline as\n * `IContainerHostProps & IContainerDriverServices`. This interface is kept\n * as an alias for back-compat and will be removed in a future release.\n *\n * @legacy @beta\n */\nexport interface ICreateAndLoadContainerProps\n\textends IContainerHostProps,\n\t\tIContainerDriverServices {}\n\n/**\n * Props used to load a container.\n * @legacy @beta\n */\nexport interface ILoadExistingContainerProps\n\textends IContainerHostProps,\n\t\tIContainerDriverServices {\n\t/**\n\t * The request to resolve the container.\n\t */\n\treadonly request: IRequest;\n\n\t/**\n\t * Pending local state to be applied to the container.\n\t */\n\treadonly pendingLocalState?: string | undefined;\n}\n\n/**\n * Props used to load summarizer container.\n * @legacy @alpha\n */\nexport type ILoadSummarizerContainerProps = Omit<\n\tILoadExistingContainerProps,\n\t\"pendingLocalState\"\n>;\n\n/**\n * Props used to create a detached container.\n * @legacy @beta\n */\nexport interface ICreateDetachedContainerProps\n\textends IContainerHostProps,\n\t\tIContainerDriverServices {\n\t/**\n\t * The code details for the container to be created.\n\t */\n\treadonly codeDetails: IFluidCodeDetails;\n}\n\n/**\n * Props used to rehydrate a detached container.\n * @legacy @beta\n */\nexport interface IRehydrateDetachedContainerProps\n\textends IContainerHostProps,\n\t\tIContainerDriverServices {\n\t/**\n\t * The serialized state returned by calling serialize on another container\n\t */\n\treadonly serializedState: string;\n}\n\n/**\n * Creates a new container using the specified code details but in an unattached state. While unattached, all\n * updates will only be local until the user explicitly attaches the container to a service provider.\n * @param createDetachedContainerProps - Services and properties necessary for creating detached container.\n * @legacy @beta\n */\nexport async function createDetachedContainer(\n\tcreateDetachedContainerProps: ICreateDetachedContainerProps,\n): Promise<IContainer> {\n\tconst loader = new Loader(createDetachedContainerProps);\n\treturn loader.createDetachedContainer(createDetachedContainerProps.codeDetails, {\n\t\tcanReconnect: createDetachedContainerProps.allowReconnect,\n\t\tclientDetailsOverride: createDetachedContainerProps.clientDetailsOverride,\n\t});\n}\n\n/**\n * Creates a new container using the specified snapshot but in an unattached state. While unattached, all\n * updates will only be local until the user explicitly attaches the container to a service provider.\n * @param rehydrateDetachedContainerProps - Services and properties necessary for rehydrating detached container from a previously serialized container's state.\n * @legacy @beta\n */\nexport async function rehydrateDetachedContainer(\n\trehydrateDetachedContainerProps: IRehydrateDetachedContainerProps,\n): Promise<IContainer> {\n\tconst loader = new Loader(rehydrateDetachedContainerProps);\n\treturn loader.rehydrateDetachedContainerFromSnapshot(\n\t\trehydrateDetachedContainerProps.serializedState,\n\t\t{\n\t\t\tcanReconnect: rehydrateDetachedContainerProps.allowReconnect,\n\t\t\tclientDetailsOverride: rehydrateDetachedContainerProps.clientDetailsOverride,\n\t\t},\n\t);\n}\n\n/**\n * Loads a container with an existing snapshot from the service.\n * @param loadExistingContainerProps - Services and properties necessary for loading an existing container.\n * @legacy @beta\n */\nexport async function loadExistingContainer(\n\tloadExistingContainerProps: ILoadExistingContainerProps,\n): Promise<IContainer> {\n\tconst loader = new Loader(loadExistingContainerProps);\n\treturn loader.resolve(\n\t\tloadExistingContainerProps.request,\n\t\tloadExistingContainerProps.pendingLocalState,\n\t);\n}\n\n/**\n * Properties required to load a frozen container from pending state.\n *\n * @remarks\n * Two forms are supported and selected by the presence of the driver-wiring\n * fields. **Online** form supplies `request`, `urlResolver`, and\n * `documentServiceFactory`; the supplied factory is wrapped in a frozen\n * factory and the resolver is used to re-resolve the request URL just as with\n * {@link loadExistingContainer}. **Offline** form omits all three driver\n * fields; the captured URL stored in `pendingLocalState` is used to\n * synthesize a resolved URL, no real driver is contacted, and\n * `IContainer.getAbsoluteUrl` throws on the returned container because the\n * resolver's external URL format is unknown without a real `IUrlResolver`.\n *\n * **Offline form precondition.** With no driver wiring there is no live\n * storage to read blobs from, so every structural and attachment blob the\n * runtime dereferences during load must already be inlined into\n * `pendingLocalState`. The pending state must therefore be produced by\n * {@link captureFullContainerState} with its default `\"inline\"` blob capture\n * mode rather than its `\"reference\"` mode or\n * `IContainer.getPendingLocalState` / `getRequiredPendingLocalState`. Missing\n * blob payloads fail the load with `UsageError`.\n *\n * **URL shape requirement.** In the offline form the captured\n * `pendingLocalState.url` is the only URL available; it is parsed in place of\n * a real `IUrlResolver.resolve()` call, so it must satisfy\n * {@link tryParseCompatibleResolvedUrl}'s contract — a resolved URL of shape\n * `protocol://{host}/.../..?{queryString}`. This is the format that\n * Fluid-shipped drivers emit; drivers that emit a non-standard resolved-URL\n * shape will surface as a `UsageError` at load time. The online form has no\n * such constraint because the supplied resolver controls URL parsing.\n *\n * The offline form supports `readOnly: false` for the same capture-and-relay\n * use case as the online form: local DDS submissions accrue in the runtime's\n * pending-state manager and can be captured via `getPendingLocalState` for\n * a later online replay. Nothing is published from an offline container.\n *\n * Mixing the two forms (some driver fields supplied, others omitted) is a\n * compile-time error courtesy of the `AllOrNone` modifier from\n * `@fluidframework/core-interfaces`.\n * @legacy @alpha\n */\nexport type ILoadFrozenContainerFromPendingStateProps = IContainerHostProps & {\n\t/**\n\t * Pending local state to be applied to the container.\n\t */\n\treadonly pendingLocalState: string;\n\n\t/**\n\t * Controls whether the frozen container is surfaced as read-only.\n\t *\n\t * Defaults to `true`. When `true`, the container reports `readOnlyInfo.readonly === true`\n\t * with `storageOnly === true`, matching the historical behavior of frozen loads.\n\t *\n\t * When `false`, the container loads as writable so the runtime will accept DDS submissions.\n\t * The connection itself stays `Connected`: the connection manager recognizes the synthetic\n\t * frozen delta stream and drops outbound messages at the network layer, so no read→write\n\t * reconnect is attempted. Local DDS state continues to update via optimistic apply, and\n\t * submitted ops accumulate in the runtime's pending-state manager. Use this when callers\n\t * want to accrue and capture pending state without publishing it.\n\t *\n\t * @remarks\n\t * The flag uses negative polarity (`readOnly`) rather than a positive opt-in (`writable`)\n\t * to align with `IContainer.readOnlyInfo.readonly`, which is the established surface for\n\t * read/write state on a loaded container. A future positive-polarity option can layer on\n\t * top of this without breaking callers, but flipping the polarity now would split readers\n\t * between two conventions for the same concept.\n\t *\n\t * Subsystem behavior is unchanged from the read-only frozen path regardless of `readOnly`:\n\t * storage operations still throw (only `readBlob` is supported); summarizer / id-compressor\n\t * never fire because no acks arrive; the quorum is whatever was captured in pending state\n\t * and gains no members during the writable-frozen lifetime. The only behavioral delta is\n\t * that the runtime accepts DDS submissions and accumulates them in `pendingStateManager`.\n\t */\n\treadonly readOnly?: boolean;\n} & AllOrNone<IContainerLoadDriverProps>;\n\nconst driverPropKeys = [\"request\", \"urlResolver\", \"documentServiceFactory\"] as const;\n\n// Recognizable opaque placeholder used as `request.url` for the offline form of\n// `loadFrozenContainerFromPendingState`. The synthesized `IUrlResolver` ignores\n// its argument and returns a `IResolvedUrl` derived from `pendingLocalState.url`,\n// so this string is never interpreted as a real URL by any downstream stage; it\n// only needs to be a fixed sentinel that won't collide with real request URLs.\nconst offlineFrozenRequestPlaceholderUrl =\n\t\"frozen-load-from-pending-state://offline-placeholder\";\n\n/**\n * Loads a frozen container from pending local state.\n * @param props - Properties required to load a frozen container from pending state.\n * @legacy @alpha\n */\nexport async function loadFrozenContainerFromPendingState(\n\tprops: ILoadFrozenContainerFromPendingStateProps,\n): Promise<IContainer> {\n\tconst fnName = loadFrozenContainerFromPendingState.name;\n\tconst { readOnly, pendingLocalState } = props;\n\n\tconst driverWiring = validateAllOrNone<IContainerLoadDriverProps>(props, driverPropKeys);\n\n\tif (driverWiring === \"mixed\") {\n\t\tthrow new UsageError(\n\t\t\t`${fnName}: ${driverPropKeys.join(\", \")} must all be provided or all omitted`,\n\t\t);\n\t}\n\n\tif (driverWiring === \"none\") {\n\t\t// Offline: synthesize the driver wiring from the URL captured in pending state.\n\t\t// The container's load pipeline is reused unchanged — the synthesized resolver\n\t\t// returns a resolved URL whose `url` equals `pendingLocalState.url`, so the\n\t\t// identity guard in `Loader.resolveCore` is trivially satisfied.\n\t\tconst pending = getAttachedContainerStateFromSerializedContainer(pendingLocalState);\n\t\tif (pending.blobContentsMode === \"reference\") {\n\t\t\tthrow new UsageError(\n\t\t\t\t`${fnName}: pending state does not contain inlined snapshot blob contents. Reference-only state captured by ${captureFullContainerState.name} requires online driver wiring.`,\n\t\t\t);\n\t\t}\n\t\tconst parsed = tryParseCompatibleResolvedUrl(pending.url);\n\t\tif (parsed === undefined) {\n\t\t\tthrow new UsageError(\n\t\t\t\t`${fnName}: pending state URL is not in a parseable form (${pending.url})`,\n\t\t\t);\n\t\t}\n\t\t// `tryParseCompatibleResolvedUrl` returns `parsed.id` as the first two\n\t\t// path segments joined by `/` (i.e. `tenantId/docId`). Production\n\t\t// resolvers populate `IResolvedUrl.id` with the single doc-id segment\n\t\t// (see `localResolver.ts`, `insecureUrlResolver.ts`,\n\t\t// `routerlicious-urlResolver/urlResolver.ts`, `odspDriverUrlResolver.ts`),\n\t\t// so downstream consumers reading `IContainer.resolvedUrl.id` for\n\t\t// telemetry / cache keys expect the single-segment shape. Take the\n\t\t// trailing segment so offline-loaded containers match that contract.\n\t\tconst parsedIdSegments = parsed.id.split(\"/\");\n\t\tconst synthesizedId = parsedIdSegments[parsedIdSegments.length - 1] ?? parsed.id;\n\t\tconst synthesizedResolvedUrl: IResolvedUrl = {\n\t\t\ttype: \"fluid\",\n\t\t\tid: synthesizedId,\n\t\t\turl: pending.url,\n\t\t\t// `tokens` and `endpoints` are empty because no real driver is contacted; the\n\t\t\t// frozen factory never reads them. A future offline mode that needs them would\n\t\t\t// require carrying them in the pending-state format.\n\t\t\ttokens: {},\n\t\t\tendpoints: {},\n\t\t};\n\t\tconst synthesizedUrlResolver: IUrlResolver = {\n\t\t\t// The argument is ignored: in offline mode the only URL in the system is the\n\t\t\t// one captured in pending state. Any request is mapped to the same resolved URL.\n\t\t\tresolve: async () => synthesizedResolvedUrl,\n\t\t\t// External (request-form) URLs cannot be reconstructed from the captured\n\t\t\t// resolved URL alone, so we cannot honor `getAbsoluteUrl`. Surface the misuse\n\t\t\t// loudly rather than fabricate a string in the wrong format.\n\t\t\tgetAbsoluteUrl: async () => {\n\t\t\t\tthrow new UsageError(`${fnName}: getAbsoluteUrl requires ${driverPropKeys.join(\"/\")}`);\n\t\t\t},\n\t\t};\n\t\treturn loadExistingContainer({\n\t\t\t...props,\n\t\t\t// `request.url` is unused: `synthesizedUrlResolver.resolve()` returns\n\t\t\t// `synthesizedResolvedUrl` regardless of input, and the identity\n\t\t\t// guard in `Loader.resolveCore` compares the resolver's output URL\n\t\t\t// against `pendingLocalState.url` — both equal `pending.url` here.\n\t\t\t// Using a recognizable opaque placeholder instead of the resolved-form\n\t\t\t// URL avoids implying that any downstream stage interprets it as a\n\t\t\t// request-form URL.\n\t\t\trequest: { url: offlineFrozenRequestPlaceholderUrl, headers: {} },\n\t\t\turlResolver: synthesizedUrlResolver,\n\t\t\tdocumentServiceFactory: createFrozenDocumentServiceFactory(undefined, readOnly),\n\t\t});\n\t}\n\n\t// Online: wrap the caller-supplied factory so the live driver only serves blob reads.\n\t// `driverWiring === \"all\"` narrows `props` to the form that carries the driver fields.\n\tconst onlineProps = props as ILoadFrozenContainerFromPendingStateProps &\n\t\tIContainerLoadDriverProps;\n\treturn loadExistingContainer({\n\t\t...onlineProps,\n\t\tdocumentServiceFactory: createFrozenDocumentServiceFactory(\n\t\t\tonlineProps.documentServiceFactory,\n\t\t\treadOnly,\n\t\t),\n\t});\n}\n\n/**\n * Properties for {@link captureFullContainerState}.\n * @legacy @alpha\n */\nexport interface ICaptureFullContainerStateProps {\n\t/**\n\t * The url resolver used to resolve the request into a Fluid resolved url.\n\t */\n\treadonly urlResolver: IUrlResolver;\n\t/**\n\t * The document service factory used to construct the driver services\n\t * against which the state is captured.\n\t */\n\treadonly documentServiceFactory: IDocumentServiceFactory;\n\t/**\n\t * The request identifying the container whose state is to be captured.\n\t */\n\treadonly request: IRequest;\n\t/**\n\t * Optional logger for driver-side telemetry.\n\t */\n\treadonly logger?: ITelemetryBaseLogger | undefined;\n\t/**\n\t * Controls whether blob payloads are included in the captured state.\n\t *\n\t * `\"inline\"` (the default) includes blob contents, producing self-contained\n\t * state that supports fully offline loading with {@link loadFrozenContainerFromPendingState}.\n\t *\n\t * `\"reference\"` preserves blob IDs in the snapshot tree but omits their\n\t * payloads. This reduces the captured state size, but loading requires live\n\t * storage through {@link loadExistingContainer} or the online form of\n\t * {@link loadFrozenContainerFromPendingState}.\n\t */\n\treadonly blobCaptureMode?: \"inline\" | \"reference\" | undefined;\n}\n\n/**\n * Captures the current state of an attached container using only driver-level\n * services, without instantiating a runtime or loading a full container. The\n * returned string is a serialized pending container state in the same wire\n * format produced by a live container's pending-state serialization, and can\n * be handed to {@link loadExistingContainer} as `pendingLocalState`.\n *\n * By default, the output is a self-contained view of the container's referenced\n * graph: the latest snapshot, inlined contents of every blob reachable through\n * referenced subtrees, inlined contents of every referenced attachment blob\n * keyed by storage id, and all ops with sequence numbers after the base\n * snapshot's sequence number through the point observed when the delta stream\n * connects. The same DeltaManager catch-up path used by container loading\n * combines delta-storage and delta-stream ops, so recently sequenced ops do\n * not need to have reached durable delta storage before capture.\n *\n * When `blobCaptureMode` is `\"reference\"`, the snapshot tree retains the blob\n * IDs needed to load the container, but structural and attachment payloads are\n * omitted. Reference-only state requires live storage during load and cannot be\n * used with the fully offline form of {@link loadFrozenContainerFromPendingState}.\n *\n * Reachability respects GC. Snapshot subtrees flagged `unreferenced: true`\n * are skipped (their contents are not inlined). Attachment blobs that GC has\n * marked unreferenced, tombstoned, or deleted are skipped. When the snapshot\n * has no GC tree (GC disabled or pre-GC document), no filtering is applied.\n *\n * Blob reads on load hit the `ContainerStorageAdapter` cache populated from\n * the captured `snapshotBlobs` map, so a frozen loader can serve the full\n * referenced graph without a live storage service.\n *\n * `pendingRuntimeState` is `undefined` — no runtime is instantiated — so the\n * output cannot carry DDS-level in-flight changes. It is intended for state\n * relay, inspection, and durable-state snapshot use cases.\n *\n * Containers that declare loading groups are not yet supported: the function\n * throws `UsageError` if any referenced subtree carries a `groupId`. Group\n * snapshots would need a separate prefetch + serialization path; until there\n * is a known consumer and end-to-end coverage, the capture refuses rather\n * than silently producing pending state that omits group data.\n *\n * @privateRemarks\n * Note: if a new snapshot lands between the snapshot fetch and delta catch-up,\n * the returned state may not reflect the very latest snapshot, but remains\n * internally consistent: ops are anchored to the snapshot that was captured.\n *\n * No `mixinMonitoringContext` / `configProvider` is wired here, deliberately\n * diverging from the sibling entry points in this file. The function reads\n * no feature flags and instantiates no runtime, so there is nothing for a\n * monitoring context to gate or attribute. If a future change introduces\n * config-gated behavior or runtime-attributed telemetry, add the wiring\n * back together with that change.\n * @legacy @alpha\n */\nexport async function captureFullContainerState({\n\turlResolver,\n\tdocumentServiceFactory,\n\trequest,\n\tlogger,\n\tblobCaptureMode = \"inline\",\n}: ICaptureFullContainerStateProps): Promise<string> {\n\tconst resolvedUrl = await urlResolver.resolve(request);\n\tif (resolvedUrl === undefined) {\n\t\tthrow new UsageError(\"Failed to resolve request to a Fluid URL\");\n\t}\n\n\t// Inline state supports the offline form of `loadFrozenContainerFromPendingState`,\n\t// which requires `tryParseCompatibleResolvedUrl` to succeed on `pendingLocalState.url`.\n\t// Reference-only state always uses the caller's live resolver, so it has no such constraint.\n\tif (\n\t\tblobCaptureMode === \"inline\" &&\n\t\ttryParseCompatibleResolvedUrl(resolvedUrl.url) === undefined\n\t) {\n\t\tthrow new UsageError(\n\t\t\t`${captureFullContainerState.name}: resolved URL is not in the shape required by tryParseCompatibleResolvedUrl (protocol://<string>/<tenantId>/<docId>?<querystring>); captured state would not rehydrate offline (${resolvedUrl.url})`,\n\t\t);\n\t}\n\n\tconst documentService = await documentServiceFactory.createDocumentService(\n\t\tresolvedUrl,\n\t\tlogger,\n\t);\n\tconst captureLogger = createChildLogger({ logger, namespace: \"captureFullContainerState\" });\n\tconst client: IClient = {\n\t\tdetails: { capabilities: { interactive: true } },\n\t\tmode: \"read\",\n\t\tpermission: [],\n\t\tscopes: [],\n\t\tuser: { id: \"\" },\n\t};\n\tconst deltaManager = createDeltaManager({\n\t\tserviceProvider: () => documentService,\n\t\tlogger: captureLogger,\n\t\tactive: () => false,\n\t\tcontainerDirty: () => false,\n\t\tclient,\n\t\treconnectAllowed: true,\n\t});\n\tconst connectedP = new Promise<void>((resolve) => {\n\t\tdeltaManager.once(\"connect\", () => resolve());\n\t});\n\tconst closedP = new Promise<never>((_resolve, reject) => {\n\t\tdeltaManager.once(\"closed\", (error) => {\n\t\t\treject(\n\t\t\t\terror === undefined\n\t\t\t\t\t? new GenericError(\"DeltaManager closed while capturing container state\")\n\t\t\t\t\t: normalizeError(error),\n\t\t\t);\n\t\t});\n\t});\n\tdeltaManager.connect({\n\t\treason: { text: \"captureFullContainerState\" },\n\t\tmode: \"read\",\n\t\t// Ops will be fetched from storage using the later \"attachOpHandler\" call. Attempting to fetch here is a no-op anyway as\n\t\t// no op handler is yet attached.\n\t\t// Fetching the snapshot first such that an op handler could be attached using its sequence number information may simplify\n\t\t// the code, but doing it this way allows parallelization of snapshot fetch and establishing a connection.\n\t\tfetchOpsFromStorage: false,\n\t});\n\ttry {\n\t\tconst storage = await documentService.connectToStorage();\n\n\t\tconst versions = await storage.getVersions(\n\t\t\t// `null` signals \"latest\"\n\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\tnull,\n\t\t\t1,\n\t\t\t\"captureFullContainerState\",\n\t\t\tFetchSource.noCache,\n\t\t);\n\t\tconst version = versions[0];\n\t\tconst snapshot: ISnapshot | ISnapshotTree | undefined =\n\t\t\tstorage.getSnapshot === undefined\n\t\t\t\t? ((await storage.getSnapshotTree(version, \"captureFullContainerState\")) ?? undefined)\n\t\t\t\t: await storage.getSnapshot({\n\t\t\t\t\t\tcacheSnapshot: false,\n\t\t\t\t\t\tversionId: version?.id,\n\t\t\t\t\t\tscenarioName: \"captureFullContainerState\",\n\t\t\t\t\t});\n\t\tif (snapshot === undefined) {\n\t\t\tthrow new GenericError(\"Failed to fetch snapshot for captureFullContainerState\");\n\t\t}\n\n\t\tconst baseSnapshot = getSnapshotTree(snapshot);\n\t\tif (snapshotHasLoadingGroups(baseSnapshot)) {\n\t\t\tthrow new UsageError(\n\t\t\t\t\"captureFullContainerState does not yet support containers with loading groups\",\n\t\t\t);\n\t\t}\n\t\tconst attributes = await getDocumentAttributes(storage, baseSnapshot);\n\t\tlet gcData: IGcSnapshotData | undefined;\n\t\tlet snapshotBlobs = {};\n\t\tlet attachmentBlobContents = {};\n\t\t// Structural snapshot blobs (JSON/text the runtime authored) are\n\t\t// UTF-8-encoded; attachment blobs may carry arbitrary binary bytes\n\t\t// and are base64-encoded. Keep them on separate fields of the\n\t\t// pending state so the load side can apply the matching decoder\n\t\t// without ambiguity. See IPendingContainerState.attachmentBlobContents.\n\t\tif (blobCaptureMode === \"inline\") {\n\t\t\tgcData = await parseGcSnapshotData(baseSnapshot, storage);\n\t\t\t[snapshotBlobs, attachmentBlobContents] = await Promise.all([\n\t\t\t\treadReferencedSnapshotBlobs(snapshot, storage), // utf8 encoded\n\t\t\t\tcaptureReferencedAttachmentBlobs(baseSnapshot, storage, gcData), // base64 encoded\n\t\t\t]);\n\t\t}\n\n\t\tconst savedOps: ISequencedDocumentMessage[] = [];\n\t\tconst attachP = deltaManager.attachOpHandler(\n\t\t\tattributes.minimumSequenceNumber,\n\t\t\tattributes.sequenceNumber,\n\t\t\t{\n\t\t\t\tprocess: (message) => savedOps.push(message),\n\t\t\t\tprocessSignal: () => {},\n\t\t\t},\n\t\t\t\"all\",\n\t\t);\n\t\tawait Promise.race([Promise.all([connectedP, attachP]), closedP]);\n\t\tawait Promise.race([waitForCatchUp(deltaManager), closedP]);\n\t\tdeltaManager.dispose();\n\n\t\tconst postSnapshotBlobReferences: IBlobAttachReference[] = [];\n\t\tif (blobCaptureMode === \"inline\") {\n\t\t\tfor (const op of savedOps) {\n\t\t\t\t// Blobs uploaded after the base snapshot are not in its\n\t\t\t\t// `.blobs` redirect table, so `captureReferencedAttachmentBlobs`\n\t\t\t\t// did not see them. The wire-format BlobAttach op carries\n\t\t\t\t// `(localId, storageId)` in its metadata; collect those here so\n\t\t\t\t// we can backfill the bytes before sealing the artifact.\n\t\t\t\tpostSnapshotBlobReferences.push(...extractBlobAttachReferences(op));\n\t\t\t}\n\t\t}\n\n\t\tif (postSnapshotBlobReferences.length > 0) {\n\t\t\tconst added = await inlineAttachmentBlobsByReference(\n\t\t\t\tpostSnapshotBlobReferences,\n\t\t\t\tstorage,\n\t\t\t\tunreferencedAttachmentBlobLocalIds(gcData),\n\t\t\t\tattachmentBlobContents,\n\t\t\t);\n\t\t\tObject.assign(attachmentBlobContents, added);\n\t\t}\n\n\t\tconst pendingState: IPendingContainerState = {\n\t\t\tattached: true,\n\t\t\tbaseSnapshot,\n\t\t\tsnapshotBlobs,\n\t\t\tblobContentsMode: blobCaptureMode === \"reference\" ? \"reference\" : undefined,\n\t\t\tattachmentBlobContents:\n\t\t\t\tObject.keys(attachmentBlobContents).length === 0 ? undefined : attachmentBlobContents,\n\t\t\tloadedGroupIdSnapshots: undefined,\n\t\t\tpendingRuntimeState: undefined,\n\t\t\tsavedOps,\n\t\t\turl: resolvedUrl.url,\n\t\t};\n\t\treturn JSON.stringify(pendingState);\n\t} finally {\n\t\tdeltaManager.dispose();\n\t\tdocumentService.dispose();\n\t}\n}\n\nasync function waitForCatchUp(\n\tdeltaManager: ReturnType<typeof createDeltaManager>,\n): Promise<void> {\n\tawait new Promise<void>((resolve) => {\n\t\tconst monitor = new CatchUpMonitor(deltaManager, () => {\n\t\t\tmonitor.dispose();\n\t\t\tresolve();\n\t\t});\n\t\tmonitor.start();\n\t});\n}\n\n/**\n * Loads a summarizer container with the required headers, triggers an on-demand summary, and then closes it.\n * Returns success/failure and an optional error for host-side handling.\n *\n * @legacy @alpha\n */\nexport async function loadSummarizerContainerAndMakeSummary(\n\tloadSummarizerContainerProps: ILoadSummarizerContainerProps,\n): Promise<LoadSummarizerSummaryResult> {\n\tlet result = await loadSummarizerContainerAndMakeSummaryInternal(\n\t\tloadSummarizerContainerProps,\n\t);\n\tif (!result.success) {\n\t\t/**\n\t\t * We retry once as there is potential for a race condition when loading a snapshot.\n\t\t * If the newest snapshot is not ready when creating the container but becomes available upon catching up, the container\n\t\t * will be closed so it can load from the new snapshot.\n\t\t */\n\t\tresult = await loadSummarizerContainerAndMakeSummaryInternal(loadSummarizerContainerProps);\n\t}\n\treturn result;\n}\n\nasync function loadSummarizerContainerAndMakeSummaryInternal(\n\tloadSummarizerContainerProps: ILoadSummarizerContainerProps,\n): Promise<LoadSummarizerSummaryResult> {\n\tconst { logger, configProvider, request: originalRequest } = loadSummarizerContainerProps;\n\tconst telemetryProps = {\n\t\tloaderId: uuid(),\n\t\tloaderVersion: pkgVersion,\n\t};\n\n\tconst subMc = mixinMonitoringContext(\n\t\tmixinDebugLogger(\"fluid:telemetry\", logger, {\n\t\t\tall: telemetryProps,\n\t\t}),\n\t\tsessionStorageConfigProvider.value,\n\t\tconfigProvider,\n\t);\n\tconst mc = createChildMonitoringContext({\n\t\tlogger: subMc.logger,\n\t\tnamespace: \"SummarizerOnDemand\",\n\t});\n\treturn PerformanceEvent.timedExecAsync(\n\t\tmc.logger,\n\t\t{ eventName: \"SummarizerOnDemandSummary\" },\n\t\tasync (event) => {\n\t\t\tconst baseHeaders = originalRequest.headers;\n\t\t\tconst request = {\n\t\t\t\t...originalRequest,\n\t\t\t\theaders: {\n\t\t\t\t\t...baseHeaders,\n\t\t\t\t\t[LoaderHeader.cache]: false,\n\t\t\t\t\t[LoaderHeader.clientDetails]: {\n\t\t\t\t\t\tcapabilities: { interactive: false },\n\t\t\t\t\t\ttype: \"summarizer\",\n\t\t\t\t\t},\n\t\t\t\t\t[DriverHeader.summarizingClient]: true,\n\t\t\t\t\t[LoaderHeader.reconnect]: false,\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst container = await loadExistingContainer({\n\t\t\t\t...loadSummarizerContainerProps,\n\t\t\t\trequest,\n\t\t\t});\n\n\t\t\tlet summarySubmitted: SummarizeOnDemandResults[\"summarySubmitted\"];\n\t\t\tlet summaryOpBroadcasted: SummarizeOnDemandResults[\"summaryOpBroadcasted\"];\n\t\t\ttry {\n\t\t\t\tif (container.getEntryPoint === undefined) {\n\t\t\t\t\tthrow new GenericError(\"container.getEntryPoint() is undefined\");\n\t\t\t\t}\n\t\t\t\tconst fluidObject = (await container.getEntryPoint()) as FluidObject<SummarizerLike>;\n\t\t\t\tconst summarizer = fluidObject?.ISummarizer;\n\t\t\t\tif (summarizer === undefined) {\n\t\t\t\t\tthrow new GenericError(\"Summarizer entry point not available\");\n\t\t\t\t}\n\t\t\t\t// Host controlled feature gate for fullTree\n\t\t\t\t// Default value will be false\n\t\t\t\tconst fullTreeGate =\n\t\t\t\t\tmc.config.getBoolean(\"Fluid.Summarizer.FullTree.OnDemand\") === true;\n\n\t\t\t\tconst summarizeResults: OnDemandSummarizeResultsPromises =\n\t\t\t\t\tsummarizer.summarizeOnDemand({\n\t\t\t\t\t\treason: \"summaryOnRequest\",\n\t\t\t\t\t\tretryOnFailure: true,\n\t\t\t\t\t\tfullTree: fullTreeGate,\n\t\t\t\t\t});\n\t\t\t\t[summarySubmitted, summaryOpBroadcasted] = await Promise.all([\n\t\t\t\t\tsummarizeResults.summarySubmitted,\n\t\t\t\t\tsummarizeResults.summaryOpBroadcasted,\n\t\t\t\t]);\n\n\t\t\t\tconst summaryResults: OnDemandSummaryResults = {\n\t\t\t\t\tsummarySubmitted: summarySubmitted.success,\n\t\t\t\t\tsummaryInfo: summarySubmitted.success\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tstage: summarySubmitted.data.stage,\n\t\t\t\t\t\t\t\thandle: summaryOpBroadcasted.success\n\t\t\t\t\t\t\t\t\t? summaryOpBroadcasted.data.summarizeOp.contents.handle\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {},\n\t\t\t\t\tsummaryOpBroadcasted: summaryOpBroadcasted.success,\n\t\t\t\t};\n\n\t\t\t\tif (summarySubmitted.success && summaryOpBroadcasted.success) {\n\t\t\t\t\tevent.end({\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tsummarySubmitted: true,\n\t\t\t\t\t\tsummaryOpBroadcasted: true,\n\t\t\t\t\t});\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tsummaryResults,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst failureError =\n\t\t\t\t\tsummarySubmitted.success === false\n\t\t\t\t\t\t? summarySubmitted.error\n\t\t\t\t\t\t: summaryOpBroadcasted.success === false\n\t\t\t\t\t\t\t? summaryOpBroadcasted.error\n\t\t\t\t\t\t\t: new GenericError(\"On demand summary failed\");\n\n\t\t\t\tevent.end({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tsummarySubmitted: summarySubmitted.success,\n\t\t\t\t\tsummaryOpBroadcasted: summaryOpBroadcasted.success,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: failureError,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tevent.cancel({ success: false }, error);\n\t\t\t\tconst caughtError = isFluidError(error) ? error : normalizeError(error);\n\t\t\t\treturn { success: false, error: caughtError };\n\t\t\t} finally {\n\t\t\t\tcontainer.dispose();\n\t\t\t}\n\t\t},\n\t\t{ start: true, end: true, cancel: \"generic\" },\n\t);\n}\n"]}
@@ -2,29 +2,14 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import type { ITelemetryBaseEvent, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
5
+ import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
6
6
  import { type ITelemetryLoggerPropertyBags, type TelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
7
7
  /**
8
- * Implementation of debug logger
8
+ * Mix in debug logger with another logger.
9
+ * Returned logger will output events to both newly created debug logger, as well as base logger
10
+ * @param namespace - Telemetry event name prefix to add to all events
11
+ * @param baseLogger - Base logger to output events (in addition to debug logger being created). Can be undefined.
12
+ * @param properties - Base properties to add to all events
9
13
  */
10
- export declare class DebugLogger implements ITelemetryBaseLogger {
11
- private readonly debug;
12
- private readonly debugErr;
13
- /**
14
- * Mix in debug logger with another logger.
15
- * Returned logger will output events to both newly created debug logger, as well as base logger
16
- * @param namespace - Telemetry event name prefix to add to all events
17
- * @param properties - Base properties to add to all events
18
- * @param propertyGetters - Getters to add additional properties to all events
19
- * @param baseLogger - Base logger to output events (in addition to debug logger being created). Can be undefined.
20
- */
21
- static mixinDebugLogger(namespace: string, baseLogger?: ITelemetryBaseLogger, properties?: ITelemetryLoggerPropertyBags): TelemetryLoggerExt;
22
- private constructor();
23
- /**
24
- * Send an event to debug loggers
25
- *
26
- * @param event - the event to send
27
- */
28
- send(event: ITelemetryBaseEvent): void;
29
- }
14
+ export declare function mixinDebugLogger(namespace: string, baseLogger?: ITelemetryBaseLogger, properties?: ITelemetryLoggerPropertyBags): TelemetryLoggerExt;
30
15
  //# sourceMappingURL=debugLogger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"debugLogger.d.ts","sourceRoot":"","sources":["../src/debugLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACX,mBAAmB,EACnB,oBAAoB,EAEpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAIN,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EACvB,MAAM,0CAA0C,CAAC;AAOlD;;GAEG;AACH,qBAAa,WAAY,YAAW,oBAAoB;IAwCtD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAxC1B;;;;;;;OAOG;WACW,gBAAgB,CAC7B,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,oBAAoB,EACjC,UAAU,CAAC,EAAE,4BAA4B,GACvC,kBAAkB;IA0BrB,OAAO;IAKP;;;;OAIG;IACI,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;CA4C7C"}
1
+ {"version":3,"file":"debugLogger.d.ts","sourceRoot":"","sources":["../src/debugLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAEX,oBAAoB,EAEpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAIN,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EACvB,MAAM,0CAA0C,CAAC;AAmElD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC/B,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,oBAAoB,EACjC,UAAU,CAAC,EAAE,4BAA4B,GACvC,kBAAkB,CAwBpB"}
@@ -7,7 +7,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
7
7
  return (mod && mod.__esModule) ? mod : { "default": mod };
8
8
  };
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.DebugLogger = void 0;
10
+ exports.mixinDebugLogger = mixinDebugLogger;
11
11
  const client_utils_1 = require("@fluid-internal/client-utils");
12
12
  const internal_1 = require("@fluidframework/telemetry-utils/internal");
13
13
  // This import style is necessary to ensure the emitted JS code works in both CJS and ESM.
@@ -17,38 +17,8 @@ const { debug: registerDebug } = debug_1.default;
17
17
  * Implementation of debug logger
18
18
  */
19
19
  class DebugLogger {
20
- /**
21
- * Mix in debug logger with another logger.
22
- * Returned logger will output events to both newly created debug logger, as well as base logger
23
- * @param namespace - Telemetry event name prefix to add to all events
24
- * @param properties - Base properties to add to all events
25
- * @param propertyGetters - Getters to add additional properties to all events
26
- * @param baseLogger - Base logger to output events (in addition to debug logger being created). Can be undefined.
27
- */
28
- static mixinDebugLogger(namespace, baseLogger, properties) {
29
- // Setup base logger upfront, such that host can disable it (if needed)
30
- const debug = registerDebug(namespace);
31
- // Create one for errors that is always enabled
32
- // It can be silenced by replacing console.error if the debug namespace is not enabled.
33
- const debugErr = registerDebug(namespace);
34
- debugErr.log = function (...args) {
35
- if (debug.enabled === true) {
36
- // if the namespace is enabled, just use the default logger
37
- registerDebug.log(...args);
38
- }
39
- else {
40
- // other wise, use the console logger (which could be replaced and silenced)
41
- console.error(...args);
42
- }
43
- };
44
- debugErr.enabled = true;
45
- return (0, internal_1.createMultiSinkLogger)({
46
- namespace,
47
- loggers: [baseLogger, new DebugLogger(debug, debugErr)],
48
- properties,
49
- tryInheritProperties: true,
50
- });
51
- }
20
+ debug;
21
+ debugErr;
52
22
  constructor(debug, debugErr) {
53
23
  this.debug = debug;
54
24
  this.debugErr = debugErr;
@@ -97,5 +67,35 @@ class DebugLogger {
97
67
  logger(`${name} ${payload} ${tick} ${stack}`);
98
68
  }
99
69
  }
100
- exports.DebugLogger = DebugLogger;
70
+ /**
71
+ * Mix in debug logger with another logger.
72
+ * Returned logger will output events to both newly created debug logger, as well as base logger
73
+ * @param namespace - Telemetry event name prefix to add to all events
74
+ * @param baseLogger - Base logger to output events (in addition to debug logger being created). Can be undefined.
75
+ * @param properties - Base properties to add to all events
76
+ */
77
+ function mixinDebugLogger(namespace, baseLogger, properties) {
78
+ // Setup base logger upfront, such that host can disable it (if needed)
79
+ const debug = registerDebug(namespace);
80
+ // Create one for errors that is always enabled
81
+ // It can be silenced by replacing console.error if the debug namespace is not enabled.
82
+ const debugErr = registerDebug(namespace);
83
+ debugErr.log = function (...args) {
84
+ if (debug.enabled === true) {
85
+ // if the namespace is enabled, just use the default logger
86
+ registerDebug.log(...args);
87
+ }
88
+ else {
89
+ // other wise, use the console logger (which could be replaced and silenced)
90
+ console.error(...args);
91
+ }
92
+ };
93
+ debugErr.enabled = true;
94
+ return (0, internal_1.createMultiSinkLogger)({
95
+ namespace,
96
+ loggers: [baseLogger, new DebugLogger(debug, debugErr)],
97
+ properties,
98
+ tryInheritProperties: true,
99
+ });
100
+ }
101
101
  //# sourceMappingURL=debugLogger.js.map