@fluidframework/container-loader 2.100.0 → 2.101.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/api-report/container-loader.legacy.alpha.api.md +13 -1
  3. package/dist/captureReferencedContents.d.ts +154 -0
  4. package/dist/captureReferencedContents.d.ts.map +1 -0
  5. package/dist/captureReferencedContents.js +349 -0
  6. package/dist/captureReferencedContents.js.map +1 -0
  7. package/dist/connectionManager.d.ts.map +1 -1
  8. package/dist/connectionManager.js +25 -7
  9. package/dist/connectionManager.js.map +1 -1
  10. package/dist/connectionStateHandler.d.ts.map +1 -1
  11. package/dist/connectionStateHandler.js +3 -1
  12. package/dist/connectionStateHandler.js.map +1 -1
  13. package/dist/container.d.ts.map +1 -1
  14. package/dist/container.js +6 -1
  15. package/dist/container.js.map +1 -1
  16. package/dist/containerStorageAdapter.d.ts +19 -1
  17. package/dist/containerStorageAdapter.d.ts.map +1 -1
  18. package/dist/containerStorageAdapter.js.map +1 -1
  19. package/dist/createAndLoadContainerUtils.d.ts +95 -0
  20. package/dist/createAndLoadContainerUtils.d.ts.map +1 -1
  21. package/dist/createAndLoadContainerUtils.js +137 -11
  22. package/dist/createAndLoadContainerUtils.js.map +1 -1
  23. package/dist/frozenServices.d.ts +113 -30
  24. package/dist/frozenServices.d.ts.map +1 -1
  25. package/dist/frozenServices.js +236 -58
  26. package/dist/frozenServices.js.map +1 -1
  27. package/dist/index.d.ts +2 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +5 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/legacyAlpha.d.ts +2 -0
  32. package/dist/loaderLayerCompatState.d.ts +1 -1
  33. package/dist/packageVersion.d.ts +1 -1
  34. package/dist/packageVersion.js +1 -1
  35. package/dist/packageVersion.js.map +1 -1
  36. package/dist/pendingLocalStateStore.d.ts.map +1 -1
  37. package/dist/pendingLocalStateStore.js +9 -3
  38. package/dist/pendingLocalStateStore.js.map +1 -1
  39. package/dist/serializedStateManager.d.ts +16 -1
  40. package/dist/serializedStateManager.d.ts.map +1 -1
  41. package/dist/serializedStateManager.js +11 -1
  42. package/dist/serializedStateManager.js.map +1 -1
  43. package/lib/captureReferencedContents.d.ts +154 -0
  44. package/lib/captureReferencedContents.d.ts.map +1 -0
  45. package/lib/captureReferencedContents.js +338 -0
  46. package/lib/captureReferencedContents.js.map +1 -0
  47. package/lib/connectionManager.d.ts.map +1 -1
  48. package/lib/connectionManager.js +26 -8
  49. package/lib/connectionManager.js.map +1 -1
  50. package/lib/connectionStateHandler.d.ts.map +1 -1
  51. package/lib/connectionStateHandler.js +3 -1
  52. package/lib/connectionStateHandler.js.map +1 -1
  53. package/lib/container.d.ts.map +1 -1
  54. package/lib/container.js +6 -1
  55. package/lib/container.js.map +1 -1
  56. package/lib/containerStorageAdapter.d.ts +19 -1
  57. package/lib/containerStorageAdapter.d.ts.map +1 -1
  58. package/lib/containerStorageAdapter.js.map +1 -1
  59. package/lib/createAndLoadContainerUtils.d.ts +95 -0
  60. package/lib/createAndLoadContainerUtils.d.ts.map +1 -1
  61. package/lib/createAndLoadContainerUtils.js +128 -3
  62. package/lib/createAndLoadContainerUtils.js.map +1 -1
  63. package/lib/frozenServices.d.ts +113 -30
  64. package/lib/frozenServices.d.ts.map +1 -1
  65. package/lib/frozenServices.js +233 -57
  66. package/lib/frozenServices.js.map +1 -1
  67. package/lib/index.d.ts +2 -1
  68. package/lib/index.d.ts.map +1 -1
  69. package/lib/index.js +2 -1
  70. package/lib/index.js.map +1 -1
  71. package/lib/legacyAlpha.d.ts +2 -0
  72. package/lib/loaderLayerCompatState.d.ts +1 -1
  73. package/lib/packageVersion.d.ts +1 -1
  74. package/lib/packageVersion.js +1 -1
  75. package/lib/packageVersion.js.map +1 -1
  76. package/lib/pendingLocalStateStore.d.ts.map +1 -1
  77. package/lib/pendingLocalStateStore.js +9 -3
  78. package/lib/pendingLocalStateStore.js.map +1 -1
  79. package/lib/serializedStateManager.d.ts +16 -1
  80. package/lib/serializedStateManager.d.ts.map +1 -1
  81. package/lib/serializedStateManager.js +11 -1
  82. package/lib/serializedStateManager.js.map +1 -1
  83. package/package.json +11 -11
  84. package/src/captureReferencedContents.ts +446 -0
  85. package/src/connectionManager.ts +30 -8
  86. package/src/connectionStateHandler.ts +14 -9
  87. package/src/container.ts +6 -0
  88. package/src/containerStorageAdapter.ts +20 -1
  89. package/src/createAndLoadContainerUtils.ts +229 -2
  90. package/src/frozenServices.ts +285 -64
  91. package/src/index.ts +7 -0
  92. package/src/packageVersion.ts +1 -1
  93. package/src/pendingLocalStateStore.ts +8 -1
  94. package/src/serializedStateManager.ts +28 -1
@@ -10,12 +10,30 @@ import type { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/intern
10
10
  import type { MemoryDetachedBlobStorage } from "./memoryBlobStorage.js";
11
11
  import type { ISerializedStateManagerDocumentStorageService, SerializedSnapshotInfo } from "./serializedStateManager.js";
12
12
  /**
13
- * Stringified blobs from a summary/snapshot tree.
13
+ * Stringified blobs from a summary/snapshot tree, keyed by blob id.
14
+ * Values are **UTF-8-encoded** — this is the right encoding for JSON or
15
+ * other text the runtime authors and consumes through this map. For
16
+ * arbitrary binary payloads (e.g. attachment blob contents), use
17
+ * {@link IBase64BlobContents} instead; a UTF-8 round-trip silently
18
+ * corrupts non-UTF-8 byte sequences with replacement characters.
14
19
  * @internal
15
20
  */
16
21
  export interface ISerializableBlobContents {
17
22
  [id: string]: string;
18
23
  }
24
+ /**
25
+ * Stringified blobs inlined in a summary/snapshot tree, keyed by blob id.
26
+ * Values are **base64-encoded** raw bytes. Used for attachment-blob
27
+ * payloads, which may carry arbitrary binary data (images, encrypted
28
+ * blobs, etc.). Mirrors the encoding used by the runtime's own
29
+ * pending-blob serializer in `BlobManager`. Structurally identical to
30
+ * {@link ISerializableBlobContents}; the two types exist to keep the
31
+ * encoding contract visible at every call site.
32
+ * @internal
33
+ */
34
+ export interface IBase64BlobContents {
35
+ [id: string]: string;
36
+ }
19
37
  /**
20
38
  * This class wraps the actual storage and make sure no wrong apis are called according to
21
39
  * container attach state.
@@ -1 +1 @@
1
- {"version":3,"file":"containerStorageAdapter.d.ts","sourceRoot":"","sources":["../src/containerStorageAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"containerStorageAdapter.d.ts","sourceRoot":"","sources":["../src/containerStorageAdapter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"containerStorageAdapter.js","sourceRoot":"","sources":["../src/containerStorageAdapter.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 { bufferToString } from \"@fluid-internal/client-utils\";\nimport type {\n\tISnapshotTreeWithBlobContents,\n\tIContainerStorageService,\n} from \"@fluidframework/container-definitions/internal\";\nimport type { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport type {\n\tFetchSource,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentStorageServicePolicies,\n\tISnapshot,\n\tISnapshotFetchOptions,\n\tISummaryContext,\n\tICreateBlobResponse,\n\tISnapshotTree,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { isInstanceOfISnapshot, UsageError } from \"@fluidframework/driver-utils/internal\";\nimport type { ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { MemoryDetachedBlobStorage } from \"./memoryBlobStorage.js\";\nimport { ProtocolTreeStorageService } from \"./protocolTreeDocumentStorageService.js\";\nimport { RetriableDocumentStorageService } from \"./retriableDocumentStorageService.js\";\nimport type {\n\tISerializedStateManagerDocumentStorageService,\n\tSerializedSnapshotInfo,\n} from \"./serializedStateManager.js\";\nimport { convertSnapshotInfoToSnapshot } from \"./utils.js\";\n\n/**\n * Stringified blobs from a summary/snapshot tree.\n * @internal\n */\nexport interface ISerializableBlobContents {\n\t[id: string]: string;\n}\n\n/**\n * This class wraps the actual storage and make sure no wrong apis are called according to\n * container attach state.\n */\nexport class ContainerStorageAdapter\n\timplements\n\t\tISerializedStateManagerDocumentStorageService,\n\t\tIContainerStorageService,\n\t\tIDisposable\n{\n\tprivate _storageService: IDocumentStorageService & Partial<IDisposable>;\n\n\tprivate _summarizeProtocolTree: boolean | undefined;\n\t/**\n\t * Whether the adapter will enforce sending combined summary trees.\n\t */\n\tpublic get summarizeProtocolTree(): boolean {\n\t\treturn this._summarizeProtocolTree === true;\n\t}\n\n\tprivate _loadedGroupIdSnapshots: Record<string, ISnapshot> = {};\n\t/**\n\t * Any loading group id (virtualized) snapshot download from storage will be stored here.\n\t */\n\tpublic get loadedGroupIdSnapshots(): Record<string, ISnapshot> {\n\t\treturn this._loadedGroupIdSnapshots;\n\t}\n\n\t/**\n\t * ArrayBufferLikes containing blobs from a snapshot\n\t */\n\tprivate readonly blobContents: { [id: string]: ArrayBufferLike } = {};\n\n\t/**\n\t * An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then\n\t * after connecting to a real service augments it with retry and combined summary tree enforcement.\n\t * @param detachedBlobStorage - The detached blob storage to use up until we connect to a real service\n\t * @param logger - Telemetry logger\n\t * @param loadingGroupIdSnapshotsFromPendingState - in offline mode, any loading group snapshots we've downloaded from the service that were stored in the pending state\n\t * @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to\n\t * upload, and fix it up with a protocol tree if needed\n\t * @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's \"summarizeProtocolTree\" before this value.\n\t */\n\tpublic constructor(\n\t\tdetachedBlobStorage: MemoryDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate loadingGroupIdSnapshotsFromPendingState:\n\t\t\t| Record<string, SerializedSnapshotInfo>\n\t\t\t| undefined,\n\t\tprivate readonly addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree,\n\t\tprivate readonly enableSummarizeProtocolTree: boolean | undefined,\n\t) {\n\t\tthis._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);\n\t}\n\n\tdisposed: boolean = false;\n\tdispose(error?: Error): void {\n\t\tthis._storageService?.dispose?.(error);\n\t\tthis.disposed = true;\n\t}\n\n\tpublic connectToService(service: IDocumentService, maxRetries?: number): void {\n\t\tif (!(this._storageService instanceof BlobOnlyStorage)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst storageServiceP = service.connectToStorage();\n\t\tconst retriableStorage = (this._storageService = new RetriableDocumentStorageService(\n\t\t\tstorageServiceP,\n\t\t\tthis.logger,\n\t\t\tmaxRetries,\n\t\t));\n\n\t\t// A storage service wrapper which intercept calls to uploadSummaryWithContext and ensure they include\n\t\t// the protocol summary, provided single-commit summary is enabled.\n\t\tthis._storageService = new ProtocolTreeStorageService(\n\t\t\tretriableStorage,\n\t\t\t(...props) => {\n\t\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"summarizeProtocolTreeEnabled\" });\n\t\t\t\treturn this.addProtocolSummaryIfMissing(...props);\n\t\t\t},\n\t\t\t// A callback to ensure we fetch the most updated value of service.policies.summarizeProtocolTree, which could be set\n\t\t\t// based on the response received from the service after connection is established.\n\t\t\t() => {\n\t\t\t\t// Determine whether or not container should upload the protocol summary along with the summary.\n\t\t\t\t// This is determined based on what value is set for serve policy's summariProtocolTree value or the enableSummarizeProtocolTree\n\t\t\t\t// retrievd from the loader options or monitoring context config.\n\t\t\t\tconst shouldSummarizeProtocolTree =\n\t\t\t\t\tservice.policies?.summarizeProtocolTree ?? this.enableSummarizeProtocolTree ?? false;\n\n\t\t\t\tif (this._summarizeProtocolTree !== shouldSummarizeProtocolTree) {\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"isSummarizeProtocolTreeEnabled\",\n\t\t\t\t\t\tdetails: { value: shouldSummarizeProtocolTree },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis._summarizeProtocolTree = shouldSummarizeProtocolTree;\n\t\t\t\treturn this._summarizeProtocolTree;\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic cacheSnapshotBlobs(snapshotBlobs: Map<string, ArrayBuffer>): void {\n\t\tfor (const [id, value] of snapshotBlobs.entries()) {\n\t\t\tthis.blobContents[id] ??= value;\n\t\t}\n\t}\n\n\tpublic clearPendingState(): void {\n\t\tthis.loadingGroupIdSnapshotsFromPendingState = undefined;\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\t// back-compat 0.40 containerRuntime requests policies even in detached container if storage is present\n\t\t// and storage is always present in >=0.41.\n\t\ttry {\n\t\t\treturn this._storageService.policies;\n\t\t} catch {\n\t\t\t// No-op\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tpublic get maximumCacheDurationMs(): IDocumentStorageServicePolicies[\"maximumCacheDurationMs\"] {\n\t\treturn this.policies?.maximumCacheDurationMs;\n\t}\n\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion,\n\t\tscenarioName?: string,\n\t\t// API called below uses null\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): Promise<ISnapshotTree | null> {\n\t\treturn this._storageService.getSnapshotTree(version, scenarioName);\n\t}\n\n\tpublic async getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot> {\n\t\tlet snapshot: ISnapshot;\n\t\tif (\n\t\t\tthis.loadingGroupIdSnapshotsFromPendingState !== undefined &&\n\t\t\tsnapshotFetchOptions?.loadingGroupIds !== undefined\n\t\t) {\n\t\t\tconst localSnapshot =\n\t\t\t\tthis.loadingGroupIdSnapshotsFromPendingState[snapshotFetchOptions.loadingGroupIds[0]];\n\t\t\tassert(localSnapshot !== undefined, 0x970 /* Local snapshot must be present */);\n\t\t\tsnapshot = convertSnapshotInfoToSnapshot(localSnapshot);\n\t\t} else {\n\t\t\tif (this._storageService.getSnapshot === undefined) {\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"getSnapshot api should exist in internal storage in ContainerStorageAdapter\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tsnapshot = await this._storageService.getSnapshot(snapshotFetchOptions);\n\t\t}\n\n\t\t// Track the latest snapshot for each loading group id\n\t\tconst loadingGroupIds = snapshotFetchOptions?.loadingGroupIds;\n\t\tassert(\n\t\t\tsnapshot.sequenceNumber !== undefined,\n\t\t\t0x971 /* Snapshot must have sequence number */,\n\t\t);\n\t\tif (loadingGroupIds !== undefined) {\n\t\t\tfor (const loadingGroupId of loadingGroupIds) {\n\t\t\t\t// Do we actually want to update the stored snapshot?\n\t\t\t\t// What if the incoming snapshot is way newer than the stored snapshot?\n\t\t\t\t// We only want to update the stored snapshot if the incoming snapshot is newer (stored sequence number < incoming sequence number)\n\t\t\t\tconst storedSeqNum =\n\t\t\t\t\tthis._loadedGroupIdSnapshots[loadingGroupId]?.sequenceNumber ?? -1;\n\t\t\t\tif (storedSeqNum < snapshot.sequenceNumber) {\n\t\t\t\t\tthis._loadedGroupIdSnapshots[loadingGroupId] = snapshot;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn snapshot;\n\t}\n\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\tconst maybeBlob = this.blobContents[id];\n\t\tif (maybeBlob !== undefined) {\n\t\t\treturn maybeBlob;\n\t\t}\n\t\treturn this._storageService.readBlob(id);\n\t}\n\n\tpublic async getVersions(\n\t\t// API used below uses null\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string,\n\t\tfetchSource?: FetchSource,\n\t): Promise<IVersion[]> {\n\t\treturn this._storageService.getVersions(versionId, count, scenarioName, fetchSource);\n\t}\n\n\tpublic async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\treturn this._storageService.uploadSummaryWithContext(summary, context);\n\t}\n\n\tpublic async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this._storageService.createBlob(file);\n\t}\n}\n\n/**\n * Storage which only supports createBlob() and readBlob(). This is used with IDetachedBlobStorage to support\n * blobs in detached containers.\n */\nclass BlobOnlyStorage implements IDocumentStorageService {\n\tconstructor(\n\t\tprivate readonly detachedStorage: MemoryDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {}\n\n\tpublic async createBlob(content: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this.verifyStorage().createBlob(content);\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\treturn this.verifyStorage().readBlob(blobId);\n\t}\n\n\tprivate verifyStorage(): MemoryDetachedBlobStorage {\n\t\tif (this.detachedStorage === undefined) {\n\t\t\tthrow new UsageError(\"Real storage calls not allowed in Unattached container\");\n\t\t}\n\t\treturn this.detachedStorage;\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\treturn this.notCalled();\n\t}\n\n\t/* eslint-disable @typescript-eslint/unbound-method */\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;\n\tpublic getSnapshot: () => Promise<ISnapshot> = this.notCalled;\n\tpublic getVersions: () => Promise<IVersion[]> = this.notCalled;\n\tpublic write: () => Promise<IVersion> = this.notCalled;\n\tpublic uploadSummaryWithContext: () => Promise<string> = this.notCalled;\n\tpublic downloadSummary: () => Promise<ISummaryTree> = this.notCalled;\n\t/* eslint-enable @typescript-eslint/unbound-method */\n\n\tprivate notCalled(): never {\n\t\tthis.verifyStorage();\n\t\ttry {\n\t\t\t// some browsers may not populate stack unless exception is thrown\n\t\t\tthrow new Error(\"BlobOnlyStorage not implemented method used\");\n\t\t} catch (error) {\n\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"BlobOnlyStorageWrongCall\" }, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\n// runtime will write a tree to the summary containing \"attachment\" type entries\n// which reference attachment blobs by ID, along with a blob containing the blob redirect table.\n// However, some drivers do not support the \"attachment\" type and will convert them to \"blob\" type\n// entries. We want to avoid saving these to reduce the size of stashed change blobs, but we\n// need to make sure the blob redirect table is saved.\nconst blobsTreeName = \".blobs\";\nconst redirectTableBlobName = \".redirectTable\";\n\n/**\n * Get blob contents of a snapshot tree from storage (or, ideally, cache)\n */\nexport async function getBlobContentsFromTree(\n\tsnapshot: ISnapshot | ISnapshotTree,\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n): Promise<ISerializableBlobContents> {\n\tconst blobs = {};\n\tif (isInstanceOfISnapshot(snapshot)) {\n\t\tconst blobContents = snapshot.blobContents;\n\t\tfor (const [id, content] of blobContents.entries()) {\n\t\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\t\tblobs[id] = bufferToString(content, \"utf8\");\n\t\t}\n\t} else {\n\t\tawait getBlobContentsFromTreeCore(snapshot, blobs, storage);\n\t}\n\treturn blobs;\n}\n\nasync function getBlobContentsFromTreeCore(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n\troot = true,\n): Promise<unknown[]> {\n\tconst treePs: Promise<unknown>[] = [];\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (root && key === blobsTreeName) {\n\t\t\ttreePs.push(getBlobManagerTreeFromTree(subTree, blobs, storage));\n\t\t} else {\n\t\t\ttreePs.push(getBlobContentsFromTreeCore(subTree, blobs, storage, false));\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = await storage.readBlob(id);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n\treturn Promise.all(treePs);\n}\n\n// save redirect table from .blobs tree but nothing else\nasync function getBlobManagerTreeFromTree(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n): Promise<void> {\n\tconst id = tree.blobs[redirectTableBlobName];\n\tassert(id !== undefined, 0x9ce /* id is undefined in getBlobManagerTreeFromTree */);\n\tconst blob = await storage.readBlob(id);\n\t// ArrayBufferLike will not survive JSON.stringify()\n\tblobs[id] = bufferToString(blob, \"utf8\");\n}\n\n/**\n * Extract blob contents from a snapshot tree with blob contents\n */\nexport function getBlobContentsFromTreeWithBlobContents(\n\tsnapshot: ISnapshotTreeWithBlobContents,\n): ISerializableBlobContents {\n\tconst blobs = {};\n\tgetBlobContentsFromTreeWithBlobContentsCore(snapshot, blobs);\n\treturn blobs;\n}\n\nfunction getBlobContentsFromTreeWithBlobContentsCore(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n\troot = true,\n): void {\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (root && key === blobsTreeName) {\n\t\t\tgetBlobManagerTreeFromTreeWithBlobContents(subTree, blobs);\n\t\t} else {\n\t\t\tgetBlobContentsFromTreeWithBlobContentsCore(subTree, blobs, false);\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = tree.blobsContents?.[id];\n\t\tassert(blob !== undefined, 0x2ec /* \"Blob must be present in blobsContents\" */);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n}\n\n// save redirect table from .blobs tree but nothing else\nfunction getBlobManagerTreeFromTreeWithBlobContents(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n): void {\n\tconst id = tree.blobs[redirectTableBlobName];\n\tassert(\n\t\tid !== undefined,\n\t\t0x9cf /* id is undefined in getBlobManagerTreeFromTreeWithBlobContents */,\n\t);\n\tconst blob = tree.blobsContents?.[id];\n\tassert(blob !== undefined, 0x70f /* Blob must be present in blobsContents */);\n\t// ArrayBufferLike will not survive JSON.stringify()\n\tblobs[id] = bufferToString(blob, \"utf8\");\n}\n"]}
1
+ {"version":3,"file":"containerStorageAdapter.js","sourceRoot":"","sources":["../src/containerStorageAdapter.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 { bufferToString } from \"@fluid-internal/client-utils\";\nimport type {\n\tISnapshotTreeWithBlobContents,\n\tIContainerStorageService,\n} from \"@fluidframework/container-definitions/internal\";\nimport type { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport type {\n\tFetchSource,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentStorageServicePolicies,\n\tISnapshot,\n\tISnapshotFetchOptions,\n\tISummaryContext,\n\tICreateBlobResponse,\n\tISnapshotTree,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { isInstanceOfISnapshot, UsageError } from \"@fluidframework/driver-utils/internal\";\nimport type { ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { MemoryDetachedBlobStorage } from \"./memoryBlobStorage.js\";\nimport { ProtocolTreeStorageService } from \"./protocolTreeDocumentStorageService.js\";\nimport { RetriableDocumentStorageService } from \"./retriableDocumentStorageService.js\";\nimport type {\n\tISerializedStateManagerDocumentStorageService,\n\tSerializedSnapshotInfo,\n} from \"./serializedStateManager.js\";\nimport { convertSnapshotInfoToSnapshot } from \"./utils.js\";\n\n/**\n * Stringified blobs from a summary/snapshot tree, keyed by blob id.\n * Values are **UTF-8-encoded** — this is the right encoding for JSON or\n * other text the runtime authors and consumes through this map. For\n * arbitrary binary payloads (e.g. attachment blob contents), use\n * {@link IBase64BlobContents} instead; a UTF-8 round-trip silently\n * corrupts non-UTF-8 byte sequences with replacement characters.\n * @internal\n */\nexport interface ISerializableBlobContents {\n\t[id: string]: string;\n}\n\n/**\n * Stringified blobs inlined in a summary/snapshot tree, keyed by blob id.\n * Values are **base64-encoded** raw bytes. Used for attachment-blob\n * payloads, which may carry arbitrary binary data (images, encrypted\n * blobs, etc.). Mirrors the encoding used by the runtime's own\n * pending-blob serializer in `BlobManager`. Structurally identical to\n * {@link ISerializableBlobContents}; the two types exist to keep the\n * encoding contract visible at every call site.\n * @internal\n */\nexport interface IBase64BlobContents {\n\t[id: string]: string;\n}\n\n/**\n * This class wraps the actual storage and make sure no wrong apis are called according to\n * container attach state.\n */\nexport class ContainerStorageAdapter\n\timplements\n\t\tISerializedStateManagerDocumentStorageService,\n\t\tIContainerStorageService,\n\t\tIDisposable\n{\n\tprivate _storageService: IDocumentStorageService & Partial<IDisposable>;\n\n\tprivate _summarizeProtocolTree: boolean | undefined;\n\t/**\n\t * Whether the adapter will enforce sending combined summary trees.\n\t */\n\tpublic get summarizeProtocolTree(): boolean {\n\t\treturn this._summarizeProtocolTree === true;\n\t}\n\n\tprivate _loadedGroupIdSnapshots: Record<string, ISnapshot> = {};\n\t/**\n\t * Any loading group id (virtualized) snapshot download from storage will be stored here.\n\t */\n\tpublic get loadedGroupIdSnapshots(): Record<string, ISnapshot> {\n\t\treturn this._loadedGroupIdSnapshots;\n\t}\n\n\t/**\n\t * ArrayBufferLikes containing blobs from a snapshot\n\t */\n\tprivate readonly blobContents: { [id: string]: ArrayBufferLike } = {};\n\n\t/**\n\t * An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then\n\t * after connecting to a real service augments it with retry and combined summary tree enforcement.\n\t * @param detachedBlobStorage - The detached blob storage to use up until we connect to a real service\n\t * @param logger - Telemetry logger\n\t * @param loadingGroupIdSnapshotsFromPendingState - in offline mode, any loading group snapshots we've downloaded from the service that were stored in the pending state\n\t * @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to\n\t * upload, and fix it up with a protocol tree if needed\n\t * @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's \"summarizeProtocolTree\" before this value.\n\t */\n\tpublic constructor(\n\t\tdetachedBlobStorage: MemoryDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate loadingGroupIdSnapshotsFromPendingState:\n\t\t\t| Record<string, SerializedSnapshotInfo>\n\t\t\t| undefined,\n\t\tprivate readonly addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree,\n\t\tprivate readonly enableSummarizeProtocolTree: boolean | undefined,\n\t) {\n\t\tthis._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);\n\t}\n\n\tdisposed: boolean = false;\n\tdispose(error?: Error): void {\n\t\tthis._storageService?.dispose?.(error);\n\t\tthis.disposed = true;\n\t}\n\n\tpublic connectToService(service: IDocumentService, maxRetries?: number): void {\n\t\tif (!(this._storageService instanceof BlobOnlyStorage)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst storageServiceP = service.connectToStorage();\n\t\tconst retriableStorage = (this._storageService = new RetriableDocumentStorageService(\n\t\t\tstorageServiceP,\n\t\t\tthis.logger,\n\t\t\tmaxRetries,\n\t\t));\n\n\t\t// A storage service wrapper which intercept calls to uploadSummaryWithContext and ensure they include\n\t\t// the protocol summary, provided single-commit summary is enabled.\n\t\tthis._storageService = new ProtocolTreeStorageService(\n\t\t\tretriableStorage,\n\t\t\t(...props) => {\n\t\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"summarizeProtocolTreeEnabled\" });\n\t\t\t\treturn this.addProtocolSummaryIfMissing(...props);\n\t\t\t},\n\t\t\t// A callback to ensure we fetch the most updated value of service.policies.summarizeProtocolTree, which could be set\n\t\t\t// based on the response received from the service after connection is established.\n\t\t\t() => {\n\t\t\t\t// Determine whether or not container should upload the protocol summary along with the summary.\n\t\t\t\t// This is determined based on what value is set for serve policy's summariProtocolTree value or the enableSummarizeProtocolTree\n\t\t\t\t// retrievd from the loader options or monitoring context config.\n\t\t\t\tconst shouldSummarizeProtocolTree =\n\t\t\t\t\tservice.policies?.summarizeProtocolTree ?? this.enableSummarizeProtocolTree ?? false;\n\n\t\t\t\tif (this._summarizeProtocolTree !== shouldSummarizeProtocolTree) {\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"isSummarizeProtocolTreeEnabled\",\n\t\t\t\t\t\tdetails: { value: shouldSummarizeProtocolTree },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis._summarizeProtocolTree = shouldSummarizeProtocolTree;\n\t\t\t\treturn this._summarizeProtocolTree;\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic cacheSnapshotBlobs(snapshotBlobs: Map<string, ArrayBuffer>): void {\n\t\tfor (const [id, value] of snapshotBlobs.entries()) {\n\t\t\tthis.blobContents[id] ??= value;\n\t\t}\n\t}\n\n\tpublic clearPendingState(): void {\n\t\tthis.loadingGroupIdSnapshotsFromPendingState = undefined;\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\t// back-compat 0.40 containerRuntime requests policies even in detached container if storage is present\n\t\t// and storage is always present in >=0.41.\n\t\ttry {\n\t\t\treturn this._storageService.policies;\n\t\t} catch {\n\t\t\t// No-op\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tpublic get maximumCacheDurationMs(): IDocumentStorageServicePolicies[\"maximumCacheDurationMs\"] {\n\t\treturn this.policies?.maximumCacheDurationMs;\n\t}\n\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion,\n\t\tscenarioName?: string,\n\t\t// API called below uses null\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): Promise<ISnapshotTree | null> {\n\t\treturn this._storageService.getSnapshotTree(version, scenarioName);\n\t}\n\n\tpublic async getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot> {\n\t\tlet snapshot: ISnapshot;\n\t\tif (\n\t\t\tthis.loadingGroupIdSnapshotsFromPendingState !== undefined &&\n\t\t\tsnapshotFetchOptions?.loadingGroupIds !== undefined\n\t\t) {\n\t\t\tconst localSnapshot =\n\t\t\t\tthis.loadingGroupIdSnapshotsFromPendingState[snapshotFetchOptions.loadingGroupIds[0]];\n\t\t\tassert(localSnapshot !== undefined, 0x970 /* Local snapshot must be present */);\n\t\t\tsnapshot = convertSnapshotInfoToSnapshot(localSnapshot);\n\t\t} else {\n\t\t\tif (this._storageService.getSnapshot === undefined) {\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"getSnapshot api should exist in internal storage in ContainerStorageAdapter\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tsnapshot = await this._storageService.getSnapshot(snapshotFetchOptions);\n\t\t}\n\n\t\t// Track the latest snapshot for each loading group id\n\t\tconst loadingGroupIds = snapshotFetchOptions?.loadingGroupIds;\n\t\tassert(\n\t\t\tsnapshot.sequenceNumber !== undefined,\n\t\t\t0x971 /* Snapshot must have sequence number */,\n\t\t);\n\t\tif (loadingGroupIds !== undefined) {\n\t\t\tfor (const loadingGroupId of loadingGroupIds) {\n\t\t\t\t// Do we actually want to update the stored snapshot?\n\t\t\t\t// What if the incoming snapshot is way newer than the stored snapshot?\n\t\t\t\t// We only want to update the stored snapshot if the incoming snapshot is newer (stored sequence number < incoming sequence number)\n\t\t\t\tconst storedSeqNum =\n\t\t\t\t\tthis._loadedGroupIdSnapshots[loadingGroupId]?.sequenceNumber ?? -1;\n\t\t\t\tif (storedSeqNum < snapshot.sequenceNumber) {\n\t\t\t\t\tthis._loadedGroupIdSnapshots[loadingGroupId] = snapshot;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn snapshot;\n\t}\n\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\tconst maybeBlob = this.blobContents[id];\n\t\tif (maybeBlob !== undefined) {\n\t\t\treturn maybeBlob;\n\t\t}\n\t\treturn this._storageService.readBlob(id);\n\t}\n\n\tpublic async getVersions(\n\t\t// API used below uses null\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string,\n\t\tfetchSource?: FetchSource,\n\t): Promise<IVersion[]> {\n\t\treturn this._storageService.getVersions(versionId, count, scenarioName, fetchSource);\n\t}\n\n\tpublic async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\treturn this._storageService.uploadSummaryWithContext(summary, context);\n\t}\n\n\tpublic async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this._storageService.createBlob(file);\n\t}\n}\n\n/**\n * Storage which only supports createBlob() and readBlob(). This is used with IDetachedBlobStorage to support\n * blobs in detached containers.\n */\nclass BlobOnlyStorage implements IDocumentStorageService {\n\tconstructor(\n\t\tprivate readonly detachedStorage: MemoryDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {}\n\n\tpublic async createBlob(content: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this.verifyStorage().createBlob(content);\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\treturn this.verifyStorage().readBlob(blobId);\n\t}\n\n\tprivate verifyStorage(): MemoryDetachedBlobStorage {\n\t\tif (this.detachedStorage === undefined) {\n\t\t\tthrow new UsageError(\"Real storage calls not allowed in Unattached container\");\n\t\t}\n\t\treturn this.detachedStorage;\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\treturn this.notCalled();\n\t}\n\n\t/* eslint-disable @typescript-eslint/unbound-method */\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;\n\tpublic getSnapshot: () => Promise<ISnapshot> = this.notCalled;\n\tpublic getVersions: () => Promise<IVersion[]> = this.notCalled;\n\tpublic write: () => Promise<IVersion> = this.notCalled;\n\tpublic uploadSummaryWithContext: () => Promise<string> = this.notCalled;\n\tpublic downloadSummary: () => Promise<ISummaryTree> = this.notCalled;\n\t/* eslint-enable @typescript-eslint/unbound-method */\n\n\tprivate notCalled(): never {\n\t\tthis.verifyStorage();\n\t\ttry {\n\t\t\t// some browsers may not populate stack unless exception is thrown\n\t\t\tthrow new Error(\"BlobOnlyStorage not implemented method used\");\n\t\t} catch (error) {\n\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"BlobOnlyStorageWrongCall\" }, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\n// runtime will write a tree to the summary containing \"attachment\" type entries\n// which reference attachment blobs by ID, along with a blob containing the blob redirect table.\n// However, some drivers do not support the \"attachment\" type and will convert them to \"blob\" type\n// entries. We want to avoid saving these to reduce the size of stashed change blobs, but we\n// need to make sure the blob redirect table is saved.\nconst blobsTreeName = \".blobs\";\nconst redirectTableBlobName = \".redirectTable\";\n\n/**\n * Get blob contents of a snapshot tree from storage (or, ideally, cache)\n */\nexport async function getBlobContentsFromTree(\n\tsnapshot: ISnapshot | ISnapshotTree,\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n): Promise<ISerializableBlobContents> {\n\tconst blobs = {};\n\tif (isInstanceOfISnapshot(snapshot)) {\n\t\tconst blobContents = snapshot.blobContents;\n\t\tfor (const [id, content] of blobContents.entries()) {\n\t\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\t\tblobs[id] = bufferToString(content, \"utf8\");\n\t\t}\n\t} else {\n\t\tawait getBlobContentsFromTreeCore(snapshot, blobs, storage);\n\t}\n\treturn blobs;\n}\n\nasync function getBlobContentsFromTreeCore(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n\troot = true,\n): Promise<unknown[]> {\n\tconst treePs: Promise<unknown>[] = [];\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (root && key === blobsTreeName) {\n\t\t\ttreePs.push(getBlobManagerTreeFromTree(subTree, blobs, storage));\n\t\t} else {\n\t\t\ttreePs.push(getBlobContentsFromTreeCore(subTree, blobs, storage, false));\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = await storage.readBlob(id);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n\treturn Promise.all(treePs);\n}\n\n// save redirect table from .blobs tree but nothing else\nasync function getBlobManagerTreeFromTree(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n): Promise<void> {\n\tconst id = tree.blobs[redirectTableBlobName];\n\tassert(id !== undefined, 0x9ce /* id is undefined in getBlobManagerTreeFromTree */);\n\tconst blob = await storage.readBlob(id);\n\t// ArrayBufferLike will not survive JSON.stringify()\n\tblobs[id] = bufferToString(blob, \"utf8\");\n}\n\n/**\n * Extract blob contents from a snapshot tree with blob contents\n */\nexport function getBlobContentsFromTreeWithBlobContents(\n\tsnapshot: ISnapshotTreeWithBlobContents,\n): ISerializableBlobContents {\n\tconst blobs = {};\n\tgetBlobContentsFromTreeWithBlobContentsCore(snapshot, blobs);\n\treturn blobs;\n}\n\nfunction getBlobContentsFromTreeWithBlobContentsCore(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n\troot = true,\n): void {\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (root && key === blobsTreeName) {\n\t\t\tgetBlobManagerTreeFromTreeWithBlobContents(subTree, blobs);\n\t\t} else {\n\t\t\tgetBlobContentsFromTreeWithBlobContentsCore(subTree, blobs, false);\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = tree.blobsContents?.[id];\n\t\tassert(blob !== undefined, 0x2ec /* \"Blob must be present in blobsContents\" */);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n}\n\n// save redirect table from .blobs tree but nothing else\nfunction getBlobManagerTreeFromTreeWithBlobContents(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n): void {\n\tconst id = tree.blobs[redirectTableBlobName];\n\tassert(\n\t\tid !== undefined,\n\t\t0x9cf /* id is undefined in getBlobManagerTreeFromTreeWithBlobContents */,\n\t);\n\tconst blob = tree.blobsContents?.[id];\n\tassert(blob !== undefined, 0x70f /* Blob must be present in blobsContents */);\n\t// ArrayBufferLike will not survive JSON.stringify()\n\tblobs[id] = bufferToString(blob, \"utf8\");\n}\n"]}
@@ -130,6 +130,33 @@ export interface ILoadFrozenContainerFromPendingStateProps extends ILoadExisting
130
130
  * Pending local state to be applied to the container.
131
131
  */
132
132
  readonly pendingLocalState: string;
133
+ /**
134
+ * Controls whether the frozen container is surfaced as read-only.
135
+ *
136
+ * Defaults to `true`. When `true`, the container reports `readOnlyInfo.readonly === true`
137
+ * with `storageOnly === true`, matching the historical behavior of frozen loads.
138
+ *
139
+ * When `false`, the container loads as writable so the runtime will accept DDS submissions.
140
+ * The connection itself stays `Connected`: the connection manager recognizes the synthetic
141
+ * frozen delta stream and drops outbound messages at the network layer, so no read→write
142
+ * reconnect is attempted. Local DDS state continues to update via optimistic apply, and
143
+ * submitted ops accumulate in the runtime's pending-state manager. Use this when callers
144
+ * want to accrue and capture pending state without publishing it.
145
+ *
146
+ * @remarks
147
+ * The flag uses negative polarity (`readOnly`) rather than a positive opt-in (`writable`)
148
+ * to align with `IContainer.readOnlyInfo.readonly`, which is the established surface for
149
+ * read/write state on a loaded container. A future positive-polarity option can layer on
150
+ * top of this without breaking callers, but flipping the polarity now would split readers
151
+ * between two conventions for the same concept.
152
+ *
153
+ * Subsystem behavior is unchanged from the read-only frozen path regardless of `readOnly`:
154
+ * storage operations still throw (only `readBlob` is supported); summarizer / id-compressor
155
+ * never fire because no acks arrive; the quorum is whatever was captured in pending state
156
+ * and gains no members during the writable-frozen lifetime. The only behavioral delta is
157
+ * that the runtime accepts DDS submissions and accumulates them in `pendingStateManager`.
158
+ */
159
+ readonly readOnly?: boolean;
133
160
  }
134
161
  /**
135
162
  * Loads a frozen container from pending local state.
@@ -137,6 +164,74 @@ export interface ILoadFrozenContainerFromPendingStateProps extends ILoadExisting
137
164
  * @legacy @alpha
138
165
  */
139
166
  export declare function loadFrozenContainerFromPendingState(props: ILoadFrozenContainerFromPendingStateProps): Promise<IContainer>;
167
+ /**
168
+ * Properties for {@link captureFullContainerState}.
169
+ * @legacy @alpha
170
+ */
171
+ export interface ICaptureFullContainerStateProps {
172
+ /**
173
+ * The url resolver used to resolve the request into a Fluid resolved url.
174
+ */
175
+ readonly urlResolver: IUrlResolver;
176
+ /**
177
+ * The document service factory used to construct the driver services
178
+ * against which the state is captured.
179
+ */
180
+ readonly documentServiceFactory: IDocumentServiceFactory;
181
+ /**
182
+ * The request identifying the container whose state is to be captured.
183
+ */
184
+ readonly request: IRequest;
185
+ /**
186
+ * Optional logger for driver-side telemetry.
187
+ */
188
+ readonly logger?: ITelemetryBaseLogger | undefined;
189
+ }
190
+ /**
191
+ * Captures the current state of an attached container using only driver-level
192
+ * services, without instantiating a runtime or loading a full container. The
193
+ * returned string is a serialized pending container state in the same wire
194
+ * format produced by a live container's pending-state serialization, and can
195
+ * be handed to {@link loadExistingContainer} as `pendingLocalState`.
196
+ *
197
+ * The output is a self-contained view of the container's referenced graph:
198
+ * the latest snapshot, inlined contents of every blob reachable through
199
+ * referenced subtrees, inlined contents of every referenced attachment blob
200
+ * keyed by storage id, and all ops with sequence numbers after the base
201
+ * snapshot's sequence number (as read from its attributes blob).
202
+ *
203
+ * Reachability respects GC. Snapshot subtrees flagged `unreferenced: true`
204
+ * are skipped (their contents are not inlined). Attachment blobs that GC has
205
+ * marked unreferenced, tombstoned, or deleted are skipped. When the snapshot
206
+ * has no GC tree (GC disabled or pre-GC document), no filtering is applied.
207
+ *
208
+ * Blob reads on load hit the `ContainerStorageAdapter` cache populated from
209
+ * the captured `snapshotBlobs` map, so a frozen loader can serve the full
210
+ * referenced graph without a live storage service.
211
+ *
212
+ * `pendingRuntimeState` is `undefined` — no runtime is instantiated — so the
213
+ * output cannot carry DDS-level in-flight changes. It is intended for state
214
+ * relay, inspection, and durable-state snapshot use cases.
215
+ *
216
+ * Containers that declare loading groups are not yet supported: the function
217
+ * throws `UsageError` if any referenced subtree carries a `groupId`. Group
218
+ * snapshots would need a separate prefetch + serialization path; until there
219
+ * is a known consumer and end-to-end coverage, the capture refuses rather
220
+ * than silently producing pending state that omits group data.
221
+ *
222
+ * Note: if a new snapshot lands between the snapshot fetch and the ops fetch,
223
+ * the returned state may not reflect the very latest snapshot, but remains
224
+ * internally consistent: ops are anchored to the snapshot that was captured.
225
+ *
226
+ * No `mixinMonitoringContext` / `configProvider` is wired here, deliberately
227
+ * diverging from the sibling entry points in this file. The function reads
228
+ * no feature flags and instantiates no runtime, so there is nothing for a
229
+ * monitoring context to gate or attribute. If a future change introduces
230
+ * config-gated behavior or runtime-attributed telemetry, add the wiring
231
+ * back together with that change.
232
+ * @legacy @alpha
233
+ */
234
+ export declare function captureFullContainerState({ urlResolver, documentServiceFactory, request, logger, }: ICaptureFullContainerStateProps): Promise<string>;
140
235
  /**
141
236
  * Loads a summarizer container with the required headers, triggers an on-demand summary, and then closes it.
142
237
  * Returns success/failure and an optional error for host-side handling.
@@ -1 +1 @@
1
- {"version":3,"file":"createAndLoadContainerUtils.d.ts","sourceRoot":"","sources":["../src/createAndLoadContainerUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createAndLoadContainerUtils.d.ts","sourceRoot":"","sources":["../src/createAndLoadContainerUtils.ts"],"names":[],"mappings":"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"}
@@ -3,13 +3,16 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { LoaderHeader } from "@fluidframework/container-definitions/internal";
6
- import { DriverHeader } from "@fluidframework/driver-definitions/internal";
7
- import { GenericError, normalizeError, createChildMonitoringContext, mixinMonitoringContext, sessionStorageConfigProvider, PerformanceEvent, isFluidError, } from "@fluidframework/telemetry-utils/internal";
6
+ import { DriverHeader, FetchSource } from "@fluidframework/driver-definitions/internal";
7
+ import { getSnapshotTree } from "@fluidframework/driver-utils/internal";
8
+ import { GenericError, UsageError, normalizeError, createChildMonitoringContext, mixinMonitoringContext, sessionStorageConfigProvider, PerformanceEvent, isFluidError, } from "@fluidframework/telemetry-utils/internal";
8
9
  import { v4 as uuid } from "uuid";
10
+ import { captureReferencedAttachmentBlobs, extractBlobAttachReferences, inlineAttachmentBlobsByReference, parseGcSnapshotData, readReferencedSnapshotBlobs, snapshotHasLoadingGroups, unreferencedAttachmentBlobLocalIds, } from "./captureReferencedContents.js";
9
11
  import { DebugLogger } from "./debugLogger.js";
10
12
  import { createFrozenDocumentServiceFactory } from "./frozenServices.js";
11
13
  import { Loader } from "./loader.js";
12
14
  import { pkgVersion } from "./packageVersion.js";
15
+ import { getDocumentAttributes } from "./utils.js";
13
16
  /**
14
17
  * Creates a new container using the specified code details but in an unattached state. While unattached, all
15
18
  * updates will only be local until the user explicitly attaches the container to a service provider.
@@ -53,9 +56,131 @@ export async function loadExistingContainer(loadExistingContainerProps) {
53
56
  export async function loadFrozenContainerFromPendingState(props) {
54
57
  return loadExistingContainer({
55
58
  ...props,
56
- documentServiceFactory: createFrozenDocumentServiceFactory(props.documentServiceFactory),
59
+ documentServiceFactory: createFrozenDocumentServiceFactory(props.documentServiceFactory, props.readOnly),
57
60
  });
58
61
  }
62
+ /**
63
+ * Captures the current state of an attached container using only driver-level
64
+ * services, without instantiating a runtime or loading a full container. The
65
+ * returned string is a serialized pending container state in the same wire
66
+ * format produced by a live container's pending-state serialization, and can
67
+ * be handed to {@link loadExistingContainer} as `pendingLocalState`.
68
+ *
69
+ * The output is a self-contained view of the container's referenced graph:
70
+ * the latest snapshot, inlined contents of every blob reachable through
71
+ * referenced subtrees, inlined contents of every referenced attachment blob
72
+ * keyed by storage id, and all ops with sequence numbers after the base
73
+ * snapshot's sequence number (as read from its attributes blob).
74
+ *
75
+ * Reachability respects GC. Snapshot subtrees flagged `unreferenced: true`
76
+ * are skipped (their contents are not inlined). Attachment blobs that GC has
77
+ * marked unreferenced, tombstoned, or deleted are skipped. When the snapshot
78
+ * has no GC tree (GC disabled or pre-GC document), no filtering is applied.
79
+ *
80
+ * Blob reads on load hit the `ContainerStorageAdapter` cache populated from
81
+ * the captured `snapshotBlobs` map, so a frozen loader can serve the full
82
+ * referenced graph without a live storage service.
83
+ *
84
+ * `pendingRuntimeState` is `undefined` — no runtime is instantiated — so the
85
+ * output cannot carry DDS-level in-flight changes. It is intended for state
86
+ * relay, inspection, and durable-state snapshot use cases.
87
+ *
88
+ * Containers that declare loading groups are not yet supported: the function
89
+ * throws `UsageError` if any referenced subtree carries a `groupId`. Group
90
+ * snapshots would need a separate prefetch + serialization path; until there
91
+ * is a known consumer and end-to-end coverage, the capture refuses rather
92
+ * than silently producing pending state that omits group data.
93
+ *
94
+ * Note: if a new snapshot lands between the snapshot fetch and the ops fetch,
95
+ * the returned state may not reflect the very latest snapshot, but remains
96
+ * internally consistent: ops are anchored to the snapshot that was captured.
97
+ *
98
+ * No `mixinMonitoringContext` / `configProvider` is wired here, deliberately
99
+ * diverging from the sibling entry points in this file. The function reads
100
+ * no feature flags and instantiates no runtime, so there is nothing for a
101
+ * monitoring context to gate or attribute. If a future change introduces
102
+ * config-gated behavior or runtime-attributed telemetry, add the wiring
103
+ * back together with that change.
104
+ * @legacy @alpha
105
+ */
106
+ export async function captureFullContainerState({ urlResolver, documentServiceFactory, request, logger, }) {
107
+ const resolvedUrl = await urlResolver.resolve(request);
108
+ if (resolvedUrl === undefined) {
109
+ throw new UsageError("Failed to resolve request to a Fluid URL");
110
+ }
111
+ const documentService = await documentServiceFactory.createDocumentService(resolvedUrl, logger);
112
+ try {
113
+ const storage = await documentService.connectToStorage();
114
+ const versions = await storage.getVersions(
115
+ // `null` signals "latest"
116
+ // eslint-disable-next-line unicorn/no-null
117
+ null, 1, "captureFullContainerState", FetchSource.noCache);
118
+ const version = versions[0];
119
+ const snapshot = storage.getSnapshot === undefined
120
+ ? ((await storage.getSnapshotTree(version, "captureFullContainerState")) ?? undefined)
121
+ : await storage.getSnapshot({
122
+ cacheSnapshot: false,
123
+ versionId: version?.id,
124
+ scenarioName: "captureFullContainerState",
125
+ });
126
+ if (snapshot === undefined) {
127
+ throw new GenericError("Failed to fetch snapshot for captureFullContainerState");
128
+ }
129
+ const baseSnapshot = getSnapshotTree(snapshot);
130
+ if (snapshotHasLoadingGroups(baseSnapshot)) {
131
+ throw new UsageError("captureFullContainerState does not yet support containers with loading groups");
132
+ }
133
+ const attributes = await getDocumentAttributes(storage, baseSnapshot);
134
+ const gcData = await parseGcSnapshotData(baseSnapshot, storage);
135
+ // Structural snapshot blobs (JSON/text the runtime authored) are
136
+ // UTF-8-encoded; attachment blobs may carry arbitrary binary bytes
137
+ // and are base64-encoded. Keep them on separate fields of the
138
+ // pending state so the load side can apply the matching decoder
139
+ // without ambiguity. See IPendingContainerState.attachmentBlobContents.
140
+ const [snapshotBlobs, attachmentBlobContents] = await Promise.all([
141
+ readReferencedSnapshotBlobs(snapshot, storage), // utf8 encoded
142
+ captureReferencedAttachmentBlobs(baseSnapshot, storage, gcData), // base64 encoded
143
+ ]);
144
+ const deltaStorage = await documentService.connectToDeltaStorage();
145
+ const opsStream = deltaStorage.fetchMessages(attributes.sequenceNumber + 1, undefined, undefined, false, "captureFullContainerState");
146
+ const savedOps = [];
147
+ const postSnapshotBlobReferences = [];
148
+ let opsResult = await opsStream.read();
149
+ while (!opsResult.done) {
150
+ for (const op of opsResult.value) {
151
+ savedOps.push(op);
152
+ // Blobs uploaded after the base snapshot are not in its
153
+ // `.blobs` redirect table, so `captureReferencedAttachmentBlobs`
154
+ // did not see them. The wire-format BlobAttach op carries
155
+ // `(localId, storageId)` in its metadata; collect those here so
156
+ // we can backfill the bytes before sealing the artifact.
157
+ const refs = extractBlobAttachReferences(op);
158
+ if (refs.length > 0) {
159
+ postSnapshotBlobReferences.push(...refs);
160
+ }
161
+ }
162
+ opsResult = await opsStream.read();
163
+ }
164
+ if (postSnapshotBlobReferences.length > 0) {
165
+ const added = await inlineAttachmentBlobsByReference(postSnapshotBlobReferences, storage, unreferencedAttachmentBlobLocalIds(gcData), attachmentBlobContents);
166
+ Object.assign(attachmentBlobContents, added);
167
+ }
168
+ const pendingState = {
169
+ attached: true,
170
+ baseSnapshot,
171
+ snapshotBlobs,
172
+ attachmentBlobContents: Object.keys(attachmentBlobContents).length === 0 ? undefined : attachmentBlobContents,
173
+ loadedGroupIdSnapshots: undefined,
174
+ pendingRuntimeState: undefined,
175
+ savedOps,
176
+ url: resolvedUrl.url,
177
+ };
178
+ return JSON.stringify(pendingState);
179
+ }
180
+ finally {
181
+ documentService.dispose();
182
+ }
183
+ }
59
184
  /**
60
185
  * Loads a summarizer container with the required headers, triggers an on-demand summary, and then closes it.
61
186
  * Returns success/failure and an optional error for host-side handling.
@@ -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 { IClientDetails } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIDocumentServiceFactory,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { DriverHeader } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tGenericError,\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 { 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 {\n\tLoadSummarizerSummaryResult,\n\tOnDemandSummaryResults,\n\tSummarizeOnDemandResults,\n} from \"./summarizerResultTypes.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 * Properties necessary for creating and loading a container.\n * @legacy @beta\n */\nexport interface ICreateAndLoadContainerProps {\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\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 * Props used to load a container.\n * @legacy @beta\n */\nexport interface ILoadExistingContainerProps extends ICreateAndLoadContainerProps {\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 extends ICreateAndLoadContainerProps {\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 extends ICreateAndLoadContainerProps {\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 * @legacy @alpha\n */\nexport interface ILoadFrozenContainerFromPendingStateProps\n\textends ILoadExistingContainerProps {\n\t/**\n\t * Pending local state to be applied to the container.\n\t */\n\treadonly pendingLocalState: string;\n}\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\treturn loadExistingContainer({\n\t\t...props,\n\t\tdocumentServiceFactory: createFrozenDocumentServiceFactory(props.documentServiceFactory),\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":"AAAA;;;GAGG;AAQH,OAAO,EAAE,YAAY,EAAE,MAAM,gDAAgD,CAAC;AAe9E,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EACN,YAAY,EACZ,UAAU,EACV,cAAc,EACd,4BAA4B,EAC5B,sBAAsB,EACtB,4BAA4B,EAC5B,gBAAgB,EAChB,YAAY,GACZ,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EACN,gCAAgC,EAChC,2BAA2B,EAC3B,gCAAgC,EAChC,mBAAmB,EACnB,2BAA2B,EAC3B,wBAAwB,EACxB,kCAAkC,GAElC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,kCAAkC,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAQjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA+HnD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,4BAA2D;IAE3D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,4BAA4B,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC,uBAAuB,CAAC,4BAA4B,CAAC,WAAW,EAAE;QAC/E,YAAY,EAAE,4BAA4B,CAAC,cAAc;QACzD,qBAAqB,EAAE,4BAA4B,CAAC,qBAAqB;KACzE,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC/C,+BAAiE;IAEjE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,+BAA+B,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC,sCAAsC,CACnD,+BAA+B,CAAC,eAAe,EAC/C;QACC,YAAY,EAAE,+BAA+B,CAAC,cAAc;QAC5D,qBAAqB,EAAE,+BAA+B,CAAC,qBAAqB;KAC5E,CACD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,0BAAuD;IAEvD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,0BAA0B,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC,OAAO,CACpB,0BAA0B,CAAC,OAAO,EAClC,0BAA0B,CAAC,iBAAiB,CAC5C,CAAC;AACH,CAAC;AA0CD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mCAAmC,CACxD,KAAgD;IAEhD,OAAO,qBAAqB,CAAC;QAC5B,GAAG,KAAK;QACR,sBAAsB,EAAE,kCAAkC,CACzD,KAAK,CAAC,sBAAsB,EAC5B,KAAK,CAAC,QAAQ,CACd;KACD,CAAC,CAAC;AACJ,CAAC;AA0BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,EAC/C,WAAW,EACX,sBAAsB,EACtB,OAAO,EACP,MAAM,GAC2B;IACjC,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,UAAU,CAAC,0CAA0C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,sBAAsB,CAAC,qBAAqB,CACzE,WAAW,EACX,MAAM,CACN,CAAC;IACF,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,gBAAgB,EAAE,CAAC;QAEzD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW;QACzC,0BAA0B;QAC1B,2CAA2C;QAC3C,IAAI,EACJ,CAAC,EACD,2BAA2B,EAC3B,WAAW,CAAC,OAAO,CACnB,CAAC;QACF,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,QAAQ,GACb,OAAO,CAAC,WAAW,KAAK,SAAS;YAChC,CAAC,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC,IAAI,SAAS,CAAC;YACtF,CAAC,CAAC,MAAM,OAAO,CAAC,WAAW,CAAC;gBAC1B,aAAa,EAAE,KAAK;gBACpB,SAAS,EAAE,OAAO,EAAE,EAAE;gBACtB,YAAY,EAAE,2BAA2B;aACzC,CAAC,CAAC;QACN,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,YAAY,CAAC,wDAAwD,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,wBAAwB,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,UAAU,CACnB,+EAA+E,CAC/E,CAAC;QACH,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAChE,iEAAiE;QACjE,mEAAmE;QACnE,8DAA8D;QAC9D,gEAAgE;QAChE,wEAAwE;QACxE,MAAM,CAAC,aAAa,EAAE,sBAAsB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjE,2BAA2B,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,eAAe;YAC/D,gCAAgC,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,iBAAiB;SAClF,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,qBAAqB,EAAE,CAAC;QACnE,MAAM,SAAS,GAAG,YAAY,CAAC,aAAa,CAC3C,UAAU,CAAC,cAAc,GAAG,CAAC,EAC7B,SAAS,EACT,SAAS,EACT,KAAK,EACL,2BAA2B,CAC3B,CAAC;QACF,MAAM,QAAQ,GAAgC,EAAE,CAAC;QACjD,MAAM,0BAA0B,GAA2B,EAAE,CAAC;QAC9D,IAAI,SAAS,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACvC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YACxB,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;gBAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAClB,wDAAwD;gBACxD,iEAAiE;gBACjE,0DAA0D;gBAC1D,gEAAgE;gBAChE,yDAAyD;gBACzD,MAAM,IAAI,GAAG,2BAA2B,CAAC,EAAE,CAAC,CAAC;gBAC7C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACrB,0BAA0B,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;gBAC1C,CAAC;YACF,CAAC;YACD,SAAS,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACpC,CAAC;QAED,IAAI,0BAA0B,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,MAAM,gCAAgC,CACnD,0BAA0B,EAC1B,OAAO,EACP,kCAAkC,CAAC,MAAM,CAAC,EAC1C,sBAAsB,CACtB,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,YAAY,GAA2B;YAC5C,QAAQ,EAAE,IAAI;YACd,YAAY;YACZ,aAAa;YACb,sBAAsB,EACrB,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB;YACtF,sBAAsB,EAAE,SAAS;YACjC,mBAAmB,EAAE,SAAS;YAC9B,QAAQ;YACR,GAAG,EAAE,WAAW,CAAC,GAAG;SACpB,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,CAAC;YAAS,CAAC;QACV,eAAe,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qCAAqC,CAC1D,4BAA2D;IAE3D,IAAI,MAAM,GAAG,MAAM,6CAA6C,CAC/D,4BAA4B,CAC5B,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB;;;;WAIG;QACH,MAAM,GAAG,MAAM,6CAA6C,CAAC,4BAA4B,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,KAAK,UAAU,6CAA6C,CAC3D,4BAA2D;IAE3D,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,4BAA4B,CAAC;IAC1F,MAAM,cAAc,GAAG;QACtB,QAAQ,EAAE,IAAI,EAAE;QAChB,aAAa,EAAE,UAAU;KACzB,CAAC;IAEF,MAAM,KAAK,GAAG,sBAAsB,CACnC,WAAW,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,EAAE;QACvD,GAAG,EAAE,cAAc;KACnB,CAAC,EACF,4BAA4B,CAAC,KAAK,EAClC,cAAc,CACd,CAAC;IACF,MAAM,EAAE,GAAG,4BAA4B,CAAC;QACvC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,SAAS,EAAE,oBAAoB;KAC/B,CAAC,CAAC;IACH,OAAO,gBAAgB,CAAC,cAAc,CACrC,EAAE,CAAC,MAAM,EACT,EAAE,SAAS,EAAE,2BAA2B,EAAE,EAC1C,KAAK,EAAE,KAAK,EAAE,EAAE;QACf,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC;QAC5C,MAAM,OAAO,GAAG;YACf,GAAG,eAAe;YAClB,OAAO,EAAE;gBACR,GAAG,WAAW;gBACd,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK;gBAC3B,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE;oBAC7B,YAAY,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;oBACpC,IAAI,EAAE,YAAY;iBAClB;gBACD,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE,IAAI;gBACtC,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,KAAK;aAC/B;SACD,CAAC;QAEF,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC;YAC7C,GAAG,4BAA4B;YAC/B,OAAO;SACP,CAAC,CAAC;QAEH,IAAI,gBAA8D,CAAC;QACnE,IAAI,oBAAsE,CAAC;QAC3E,IAAI,CAAC;YACJ,IAAI,SAAS,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;gBAC3C,MAAM,IAAI,YAAY,CAAC,wCAAwC,CAAC,CAAC;YAClE,CAAC;YACD,MAAM,WAAW,GAAG,CAAC,MAAM,SAAS,CAAC,aAAa,EAAE,CAAgC,CAAC;YACrF,MAAM,UAAU,GAAG,WAAW,EAAE,WAAW,CAAC;YAC5C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,IAAI,YAAY,CAAC,sCAAsC,CAAC,CAAC;YAChE,CAAC;YACD,4CAA4C;YAC5C,8BAA8B;YAC9B,MAAM,YAAY,GACjB,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,oCAAoC,CAAC,KAAK,IAAI,CAAC;YAErE,MAAM,gBAAgB,GACrB,UAAU,CAAC,iBAAiB,CAAC;gBAC5B,MAAM,EAAE,kBAAkB;gBAC1B,cAAc,EAAE,IAAI;gBACpB,QAAQ,EAAE,YAAY;aACtB,CAAC,CAAC;YACJ,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC5D,gBAAgB,CAAC,gBAAgB;gBACjC,gBAAgB,CAAC,oBAAoB;aACrC,CAAC,CAAC;YAEH,MAAM,cAAc,GAA2B;gBAC9C,gBAAgB,EAAE,gBAAgB,CAAC,OAAO;gBAC1C,WAAW,EAAE,gBAAgB,CAAC,OAAO;oBACpC,CAAC,CAAC;wBACA,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK;wBAClC,MAAM,EAAE,oBAAoB,CAAC,OAAO;4BACnC,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM;4BACvD,CAAC,CAAC,SAAS;qBACZ;oBACF,CAAC,CAAC,EAAE;gBACL,oBAAoB,EAAE,oBAAoB,CAAC,OAAO;aAClD,CAAC;YAEF,IAAI,gBAAgB,CAAC,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,CAAC;gBAC9D,KAAK,CAAC,GAAG,CAAC;oBACT,OAAO,EAAE,IAAI;oBACb,gBAAgB,EAAE,IAAI;oBACtB,oBAAoB,EAAE,IAAI;iBAC1B,CAAC,CAAC;gBACH,OAAO;oBACN,OAAO,EAAE,IAAI;oBACb,cAAc;iBACd,CAAC;YACH,CAAC;YAED,MAAM,YAAY,GACjB,gBAAgB,CAAC,OAAO,KAAK,KAAK;gBACjC,CAAC,CAAC,gBAAgB,CAAC,KAAK;gBACxB,CAAC,CAAC,oBAAoB,CAAC,OAAO,KAAK,KAAK;oBACvC,CAAC,CAAC,oBAAoB,CAAC,KAAK;oBAC5B,CAAC,CAAC,IAAI,YAAY,CAAC,0BAA0B,CAAC,CAAC;YAElD,KAAK,CAAC,GAAG,CAAC;gBACT,OAAO,EAAE,KAAK;gBACd,gBAAgB,EAAE,gBAAgB,CAAC,OAAO;gBAC1C,oBAAoB,EAAE,oBAAoB,CAAC,OAAO;aAClD,CAAC,CAAC;YACH,OAAO;gBACN,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,YAAY;aACnB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;YACxC,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YACxE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QAC/C,CAAC;gBAAS,CAAC;YACV,SAAS,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC;IACF,CAAC,EACD,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAC7C,CAAC;AACH,CAAC","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 { IClientDetails } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIDocumentServiceFactory,\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 { getDocumentAttributes } 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 * Properties necessary for creating and loading a container.\n * @legacy @beta\n */\nexport interface ICreateAndLoadContainerProps {\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\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 * Props used to load a container.\n * @legacy @beta\n */\nexport interface ILoadExistingContainerProps extends ICreateAndLoadContainerProps {\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 extends ICreateAndLoadContainerProps {\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 extends ICreateAndLoadContainerProps {\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 * @legacy @alpha\n */\nexport interface ILoadFrozenContainerFromPendingStateProps\n\textends ILoadExistingContainerProps {\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}\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\treturn loadExistingContainer({\n\t\t...props,\n\t\tdocumentServiceFactory: createFrozenDocumentServiceFactory(\n\t\t\tprops.documentServiceFactory,\n\t\t\tprops.readOnly,\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\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"]}