@fluidframework/container-loader 2.11.0 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/api-report/container-loader.legacy.alpha.api.md +39 -0
  3. package/dist/container.d.ts.map +1 -1
  4. package/dist/container.js.map +1 -1
  5. package/dist/containerStorageAdapter.js.map +1 -1
  6. package/dist/createAndLoadContainerUtils.d.ts +125 -0
  7. package/dist/createAndLoadContainerUtils.d.ts.map +1 -0
  8. package/dist/createAndLoadContainerUtils.js +50 -0
  9. package/dist/createAndLoadContainerUtils.js.map +1 -0
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +5 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/legacy.d.ts +7 -0
  15. package/dist/loadPaused.d.ts +4 -3
  16. package/dist/loadPaused.d.ts.map +1 -1
  17. package/dist/loadPaused.js +12 -8
  18. package/dist/loadPaused.js.map +1 -1
  19. package/dist/packageVersion.d.ts +1 -1
  20. package/dist/packageVersion.js +1 -1
  21. package/dist/packageVersion.js.map +1 -1
  22. package/dist/utils.d.ts.map +1 -1
  23. package/dist/utils.js +1 -3
  24. package/dist/utils.js.map +1 -1
  25. package/lib/container.d.ts.map +1 -1
  26. package/lib/container.js.map +1 -1
  27. package/lib/containerStorageAdapter.js.map +1 -1
  28. package/lib/createAndLoadContainerUtils.d.ts +125 -0
  29. package/lib/createAndLoadContainerUtils.d.ts.map +1 -0
  30. package/lib/createAndLoadContainerUtils.js +44 -0
  31. package/lib/createAndLoadContainerUtils.js.map +1 -0
  32. package/lib/index.d.ts +1 -0
  33. package/lib/index.d.ts.map +1 -1
  34. package/lib/index.js +1 -0
  35. package/lib/index.js.map +1 -1
  36. package/lib/legacy.d.ts +7 -0
  37. package/lib/loadPaused.d.ts +4 -3
  38. package/lib/loadPaused.d.ts.map +1 -1
  39. package/lib/loadPaused.js +12 -8
  40. package/lib/loadPaused.js.map +1 -1
  41. package/lib/packageVersion.d.ts +1 -1
  42. package/lib/packageVersion.js +1 -1
  43. package/lib/packageVersion.js.map +1 -1
  44. package/lib/utils.d.ts.map +1 -1
  45. package/lib/utils.js +1 -3
  46. package/lib/utils.js.map +1 -1
  47. package/package.json +14 -14
  48. package/src/container.ts +2 -2
  49. package/src/containerStorageAdapter.ts +3 -3
  50. package/src/createAndLoadContainerUtils.ts +182 -0
  51. package/src/index.ts +9 -0
  52. package/src/loadPaused.ts +14 -9
  53. package/src/packageVersion.ts +1 -1
  54. package/src/utils.ts +1 -4
package/lib/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.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 {\n\tUint8ArrayToString,\n\tbufferToString,\n\tstringToBuffer,\n} from \"@fluid-internal/client-utils\";\nimport { assert, compareArrays, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { ISummaryTree, SummaryType } from \"@fluidframework/driver-definitions\";\nimport {\n\tDriverErrorTypes,\n\tIDocumentAttributes,\n\tISnapshotTree,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tIDocumentStorageService,\n\ttype ISnapshot,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tCombinedAppAndProtocolSummary,\n\tDeltaStreamConnectionForbiddenError,\n\tisCombinedAppAndProtocolSummary,\n\treadAndParse,\n} from \"@fluidframework/driver-utils/internal\";\nimport {\n\tLoggingError,\n\tUsageError,\n\ttype IFluidErrorBase,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { ISerializableBlobContents } from \"./containerStorageAdapter.js\";\nimport type {\n\tIPendingContainerState,\n\tIPendingDetachedContainerState,\n\tISnapshotInfo,\n\tSnapshotWithBlobs,\n} from \"./serializedStateManager.js\";\n\n// This is used when we rehydrate a container from the snapshot. Here we put the blob contents\n// in separate property: blobContents.\nexport interface ISnapshotTreeWithBlobContents extends ISnapshotTree {\n\tblobsContents: { [path: string]: ArrayBufferLike };\n\ttrees: { [path: string]: ISnapshotTreeWithBlobContents };\n}\n\n/**\n * Interface to represent the parsed parts of IResolvedUrl.url to help\n * in getting info about different parts of the url.\n * May not be compatible or relevant for any Url Resolver\n * @legacy\n * @alpha\n */\nexport interface IParsedUrl {\n\t/**\n\t * It is combination of tenantid/docId part of the url.\n\t */\n\tid: string;\n\t/**\n\t * It is the deep link path in the url.\n\t */\n\tpath: string;\n\t/**\n\t * Query string part of the url.\n\t */\n\tquery: string;\n\t/**\n\t * Undefined means load latest snapshot, otherwise it's version ID passed to IDocumentStorageService.getVersions()\n\t * to figure out what snapshot to use.\n\t */\n\tversion: string | undefined;\n}\n\n/**\n * Utility api to parse the IResolvedUrl.url into specific parts like querystring, path to get\n * deep link info etc.\n * Warning - This function may not be compatible with any Url Resolver's resolved url. It works\n * with urls of type: protocol://<string>/.../..?<querystring>\n * @param url - This is the IResolvedUrl.url part of the resolved url.\n * @returns The IParsedUrl representing the input URL, or undefined if the format was not supported\n * @legacy\n * @alpha\n */\nexport function tryParseCompatibleResolvedUrl(url: string): IParsedUrl | undefined {\n\tconst parsed = new URL(url);\n\tif (typeof parsed.pathname !== \"string\") {\n\t\tthrow new LoggingError(\"Failed to parse pathname\");\n\t}\n\tconst query = parsed.search ?? \"\";\n\tconst regex = /^\\/([^/]*\\/[^/]*)(\\/?.*)$/;\n\tconst match = regex.exec(parsed.pathname);\n\treturn match?.length === 3\n\t\t? {\n\t\t\t\tid: match[1],\n\t\t\t\tpath: match[2],\n\t\t\t\tquery,\n\t\t\t\t// URLSearchParams returns null if the param is not provided.\n\t\t\t\tversion: parsed.searchParams.get(\"version\") ?? undefined,\n\t\t\t}\n\t\t: undefined;\n}\n\n/**\n * Combine the app summary and protocol summary in 1 tree.\n * @param appSummary - Summary of the app.\n * @param protocolSummary - Summary of the protocol.\n * @internal\n */\nexport function combineAppAndProtocolSummary(\n\tappSummary: ISummaryTree,\n\tprotocolSummary: ISummaryTree,\n): CombinedAppAndProtocolSummary {\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(appSummary),\n\t\t0x5a8 /* app summary is already a combined tree! */,\n\t);\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(protocolSummary),\n\t\t0x5a9 /* protocol summary is already a combined tree! */,\n\t);\n\tconst createNewSummary: CombinedAppAndProtocolSummary = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\t\".protocol\": protocolSummary,\n\t\t\t\".app\": appSummary,\n\t\t},\n\t};\n\treturn createNewSummary;\n}\n\n/**\n * Converts a summary to snapshot tree and separate its blob contents\n * to align detached container format with IPendingContainerState\n * @param summary - ISummaryTree\n */\nfunction convertSummaryToSnapshotAndBlobs(summary: ISummaryTree): SnapshotWithBlobs {\n\tlet blobContents: ISerializableBlobContents = {};\n\tconst treeNode: ISnapshotTree = {\n\t\tblobs: {},\n\t\ttrees: {},\n\t\tid: uuid(),\n\t\tunreferenced: summary.unreferenced,\n\t\tgroupId: summary.groupId,\n\t};\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\tconst summaryObject = summary.tree[key];\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\tconst innerSnapshot = convertSummaryToSnapshotAndBlobs(summaryObject);\n\t\t\t\ttreeNode.trees[key] = innerSnapshot.baseSnapshot;\n\t\t\t\tblobContents = { ...blobContents, ...innerSnapshot.snapshotBlobs };\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Attachment: {\n\t\t\t\ttreeNode.blobs[key] = summaryObject.id;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tconst contentString: string =\n\t\t\t\t\tsummaryObject.content instanceof Uint8Array\n\t\t\t\t\t\t? Uint8ArrayToString(summaryObject.content)\n\t\t\t\t\t\t: summaryObject.content;\n\t\t\t\tblobContents[blobId] = contentString;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle: {\n\t\t\t\tthrow new LoggingError(\n\t\t\t\t\t\"No handles should be there in summary in detached container!!\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t\tunreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n\t\t\t}\n\t\t}\n\t}\n\tconst pendingSnapshot = { baseSnapshot: treeNode, snapshotBlobs: blobContents };\n\treturn pendingSnapshot;\n}\n\n/**\n * Converts a snapshot to snapshotInfo with its blob contents\n * to align detached container format with IPendingContainerState\n *\n * Note, this assumes the ISnapshot sequence number is defined. Otherwise an assert will be thrown\n * @param snapshot - ISnapshot\n */\nexport function convertSnapshotToSnapshotInfo(snapshot: ISnapshot): ISnapshotInfo {\n\tassert(\n\t\tsnapshot.sequenceNumber !== undefined,\n\t\t0x93a /* Snapshot sequence number is missing */,\n\t);\n\tconst snapshotBlobs: ISerializableBlobContents = {};\n\tfor (const [blobId, arrayBufferLike] of snapshot.blobContents.entries()) {\n\t\tsnapshotBlobs[blobId] = bufferToString(arrayBufferLike, \"utf8\");\n\t}\n\treturn {\n\t\tbaseSnapshot: snapshot.snapshotTree,\n\t\tsnapshotBlobs,\n\t\tsnapshotSequenceNumber: snapshot.sequenceNumber,\n\t};\n}\n\n/**\n * Converts a snapshot to snapshotInfo with its blob contents\n * to align detached container format with IPendingContainerState\n *\n * Note, this assumes the ISnapshot sequence number is defined. Otherwise an assert will be thrown\n * @param snapshot - ISnapshot\n */\nexport function convertSnapshotInfoToSnapshot(\n\tsnapshotInfo: ISnapshotInfo,\n\tsnapshotSequenceNumber: number,\n): ISnapshot {\n\tconst blobContents = new Map<string, ArrayBufferLike>();\n\tfor (const [blobId, serializedContent] of Object.entries(snapshotInfo.snapshotBlobs)) {\n\t\tblobContents.set(blobId, stringToBuffer(serializedContent, \"utf8\"));\n\t}\n\treturn {\n\t\tsnapshotTree: snapshotInfo.baseSnapshot,\n\t\tblobContents,\n\t\tops: [],\n\t\tsequenceNumber: snapshotSequenceNumber,\n\t\tlatestSequenceNumber: undefined,\n\t\tsnapshotFormatV: 1,\n\t};\n}\n\n/**\n * Converts summary parts into a SnapshotTree and its blob contents.\n * @param protocolSummaryTree - Protocol Summary Tree\n * @param appSummaryTree - App Summary Tree\n */\nfunction convertProtocolAndAppSummaryToSnapshotAndBlobs(\n\tprotocolSummaryTree: ISummaryTree,\n\tappSummaryTree: ISummaryTree,\n): SnapshotWithBlobs {\n\tconst combinedSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: { ...appSummaryTree.tree },\n\t};\n\n\tcombinedSummary.tree[\".protocol\"] = protocolSummaryTree;\n\tconst snapshotTreeWithBlobContents = convertSummaryToSnapshotAndBlobs(combinedSummary);\n\treturn snapshotTreeWithBlobContents;\n}\n\nexport const getSnapshotTreeAndBlobsFromSerializedContainer = (\n\tdetachedContainerSnapshot: ISummaryTree,\n): SnapshotWithBlobs => {\n\tassert(\n\t\tisCombinedAppAndProtocolSummary(detachedContainerSnapshot),\n\t\t0x8e6 /* Protocol and App summary trees should be present */,\n\t);\n\tconst protocolSummaryTree = detachedContainerSnapshot.tree[\".protocol\"];\n\tconst appSummaryTree = detachedContainerSnapshot.tree[\".app\"];\n\tconst snapshotTreeWithBlobContents = convertProtocolAndAppSummaryToSnapshotAndBlobs(\n\t\tprotocolSummaryTree,\n\t\tappSummaryTree,\n\t);\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree {\n\treturn \".protocol\" in snapshot.trees ? snapshot.trees[\".protocol\"] : snapshot;\n}\n\nexport const combineSnapshotTreeAndSnapshotBlobs = (\n\tbaseSnapshot: ISnapshotTree,\n\tsnapshotBlobs: ISerializableBlobContents,\n): ISnapshotTreeWithBlobContents => {\n\tconst blobsContents: { [path: string]: ArrayBufferLike } = {};\n\n\t// Process blobs in the current level\n\tfor (const [, id] of Object.entries(baseSnapshot.blobs)) {\n\t\tif (snapshotBlobs[id]) {\n\t\t\tblobsContents[id] = stringToBuffer(snapshotBlobs[id], \"utf8\");\n\t\t}\n\t}\n\n\t// Recursively process trees in the current level\n\tconst trees: { [path: string]: ISnapshotTreeWithBlobContents } = {};\n\tfor (const [path, tree] of Object.entries(baseSnapshot.trees)) {\n\t\ttrees[path] = combineSnapshotTreeAndSnapshotBlobs(tree, snapshotBlobs);\n\t}\n\n\t// Create a new snapshot tree with blob contents and processed trees\n\tconst snapshotTreeWithBlobContents: ISnapshotTreeWithBlobContents = {\n\t\t...baseSnapshot,\n\t\tblobsContents,\n\t\ttrees,\n\t};\n\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function isDeltaStreamConnectionForbiddenError(\n\terror: unknown,\n): error is DeltaStreamConnectionForbiddenError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error as Partial<IFluidErrorBase>)?.errorType ===\n\t\t\tDriverErrorTypes.deltaStreamConnectionForbidden\n\t);\n}\n\n/**\n * Validates format in parsed string get from detached container\n * serialization using IPendingDetachedContainerState format.\n */\nfunction isPendingDetachedContainerState(\n\tdetachedContainerState: IPendingDetachedContainerState,\n): detachedContainerState is IPendingDetachedContainerState {\n\tif (\n\t\tdetachedContainerState?.attached === undefined ||\n\t\tdetachedContainerState?.baseSnapshot === undefined ||\n\t\tdetachedContainerState?.snapshotBlobs === undefined ||\n\t\tdetachedContainerState?.hasAttachmentBlobs === undefined\n\t) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Parses the given string into {@link IPendingDetachedContainerState} format,\n * with validation (if invalid, throws a UsageError).\n * This is the inverse of the JSON.stringify call in {@link Container.serialize}\n */\nexport function getDetachedContainerStateFromSerializedContainer(\n\tserializedContainer: string,\n): IPendingDetachedContainerState {\n\tconst hasBlobsSummaryTree = \".hasAttachmentBlobs\";\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\tconst parsedContainerState = JSON.parse(serializedContainer);\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\tif (isPendingDetachedContainerState(parsedContainerState)) {\n\t\treturn parsedContainerState;\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t} else if (isCombinedAppAndProtocolSummary(parsedContainerState)) {\n\t\tconst { baseSnapshot, snapshotBlobs } =\n\t\t\tgetSnapshotTreeAndBlobsFromSerializedContainer(parsedContainerState);\n\t\tconst detachedContainerState: IPendingDetachedContainerState = {\n\t\t\tattached: false,\n\t\t\tbaseSnapshot,\n\t\t\tsnapshotBlobs,\n\t\t\thasAttachmentBlobs: parsedContainerState.tree[hasBlobsSummaryTree] !== undefined,\n\t\t};\n\t\treturn detachedContainerState;\n\t} else {\n\t\tthrow new UsageError(\"Cannot rehydrate detached container. Incorrect format\");\n\t}\n}\n\n/**\n * Blindly parses the given string into {@link IPendingContainerState} format.\n * This is the inverse of the JSON.stringify call in {@link SerializedStateManager.getPendingLocalState}\n */\nexport function getAttachedContainerStateFromSerializedContainer(\n\tserializedContainer: string | undefined,\n): IPendingContainerState | undefined {\n\treturn serializedContainer === undefined\n\t\t? undefined\n\t\t: (JSON.parse(serializedContainer) as IPendingContainerState);\n}\n\n/**\n * Ensures only a single instance of the provided async function is running.\n * If there are multiple calls they will all get the same promise to wait on.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const runSingle = <A extends any[], R>(\n\tfunc: (...args: A) => Promise<R>,\n): ((...args: A) => Promise<R>) => {\n\tlet running:\n\t\t| {\n\t\t\t\targs: A;\n\t\t\t\tresult: Promise<R>;\n\t\t }\n\t\t| undefined;\n\t// don't mark this function async, so we return the same promise,\n\t// rather than one that is wrapped due to async\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\treturn (...args: A): Promise<R> => {\n\t\tif (running !== undefined) {\n\t\t\tif (!compareArrays(running.args, args)) {\n\t\t\t\treturn Promise.reject(\n\t\t\t\t\tnew UsageError(\"Subsequent calls cannot use different arguments.\"),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn running.result;\n\t\t}\n\t\trunning = { args, result: func(...args).finally(() => (running = undefined)) };\n\t\treturn running.result;\n\t};\n};\n\nexport async function getDocumentAttributes(\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n\ttree: ISnapshotTree | undefined,\n): Promise<IDocumentAttributes> {\n\tif (tree === undefined) {\n\t\treturn {\n\t\t\tminimumSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t};\n\t}\n\n\t// Backward compatibility: old docs would have \".attributes\" instead of \"attributes\"\n\tconst attributesHash =\n\t\t\".protocol\" in tree.trees\n\t\t\t? tree.trees[\".protocol\"].blobs.attributes\n\t\t\t: tree.blobs[\".attributes\"];\n\n\tconst attributes = await readAndParse<IDocumentAttributes>(storage, attributesHash);\n\n\treturn attributes;\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.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 {\n\tUint8ArrayToString,\n\tbufferToString,\n\tstringToBuffer,\n} from \"@fluid-internal/client-utils\";\nimport { assert, compareArrays, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { ISummaryTree, SummaryType } from \"@fluidframework/driver-definitions\";\nimport {\n\tDriverErrorTypes,\n\tIDocumentAttributes,\n\tISnapshotTree,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tIDocumentStorageService,\n\ttype ISnapshot,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tCombinedAppAndProtocolSummary,\n\tDeltaStreamConnectionForbiddenError,\n\tisCombinedAppAndProtocolSummary,\n\treadAndParse,\n} from \"@fluidframework/driver-utils/internal\";\nimport {\n\tLoggingError,\n\tUsageError,\n\ttype IFluidErrorBase,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { ISerializableBlobContents } from \"./containerStorageAdapter.js\";\nimport type {\n\tIPendingContainerState,\n\tIPendingDetachedContainerState,\n\tISnapshotInfo,\n\tSnapshotWithBlobs,\n} from \"./serializedStateManager.js\";\n\n// This is used when we rehydrate a container from the snapshot. Here we put the blob contents\n// in separate property: blobContents.\nexport interface ISnapshotTreeWithBlobContents extends ISnapshotTree {\n\tblobsContents: { [path: string]: ArrayBufferLike };\n\ttrees: { [path: string]: ISnapshotTreeWithBlobContents };\n}\n\n/**\n * Interface to represent the parsed parts of IResolvedUrl.url to help\n * in getting info about different parts of the url.\n * May not be compatible or relevant for any Url Resolver\n * @legacy\n * @alpha\n */\nexport interface IParsedUrl {\n\t/**\n\t * It is combination of tenantid/docId part of the url.\n\t */\n\tid: string;\n\t/**\n\t * It is the deep link path in the url.\n\t */\n\tpath: string;\n\t/**\n\t * Query string part of the url.\n\t */\n\tquery: string;\n\t/**\n\t * Undefined means load latest snapshot, otherwise it's version ID passed to IDocumentStorageService.getVersions()\n\t * to figure out what snapshot to use.\n\t */\n\tversion: string | undefined;\n}\n\n/**\n * Utility api to parse the IResolvedUrl.url into specific parts like querystring, path to get\n * deep link info etc.\n * Warning - This function may not be compatible with any Url Resolver's resolved url. It works\n * with urls of type: protocol://<string>/.../..?<querystring>\n * @param url - This is the IResolvedUrl.url part of the resolved url.\n * @returns The IParsedUrl representing the input URL, or undefined if the format was not supported\n * @legacy\n * @alpha\n */\nexport function tryParseCompatibleResolvedUrl(url: string): IParsedUrl | undefined {\n\tconst parsed = new URL(url);\n\tif (typeof parsed.pathname !== \"string\") {\n\t\tthrow new LoggingError(\"Failed to parse pathname\");\n\t}\n\tconst query = parsed.search ?? \"\";\n\tconst regex = /^\\/([^/]*\\/[^/]*)(\\/?.*)$/;\n\tconst match = regex.exec(parsed.pathname);\n\treturn match?.length === 3\n\t\t? {\n\t\t\t\tid: match[1],\n\t\t\t\tpath: match[2],\n\t\t\t\tquery,\n\t\t\t\t// URLSearchParams returns null if the param is not provided.\n\t\t\t\tversion: parsed.searchParams.get(\"version\") ?? undefined,\n\t\t\t}\n\t\t: undefined;\n}\n\n/**\n * Combine the app summary and protocol summary in 1 tree.\n * @param appSummary - Summary of the app.\n * @param protocolSummary - Summary of the protocol.\n * @internal\n */\nexport function combineAppAndProtocolSummary(\n\tappSummary: ISummaryTree,\n\tprotocolSummary: ISummaryTree,\n): CombinedAppAndProtocolSummary {\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(appSummary),\n\t\t0x5a8 /* app summary is already a combined tree! */,\n\t);\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(protocolSummary),\n\t\t0x5a9 /* protocol summary is already a combined tree! */,\n\t);\n\tconst createNewSummary: CombinedAppAndProtocolSummary = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\t\".protocol\": protocolSummary,\n\t\t\t\".app\": appSummary,\n\t\t},\n\t};\n\treturn createNewSummary;\n}\n\n/**\n * Converts a summary to snapshot tree and separate its blob contents\n * to align detached container format with IPendingContainerState\n * @param summary - ISummaryTree\n */\nfunction convertSummaryToSnapshotAndBlobs(summary: ISummaryTree): SnapshotWithBlobs {\n\tlet blobContents: ISerializableBlobContents = {};\n\tconst treeNode: ISnapshotTree = {\n\t\tblobs: {},\n\t\ttrees: {},\n\t\tid: uuid(),\n\t\tunreferenced: summary.unreferenced,\n\t\tgroupId: summary.groupId,\n\t};\n\tfor (const [key, summaryObject] of Object.entries(summary.tree)) {\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\tconst innerSnapshot = convertSummaryToSnapshotAndBlobs(summaryObject);\n\t\t\t\ttreeNode.trees[key] = innerSnapshot.baseSnapshot;\n\t\t\t\tblobContents = { ...blobContents, ...innerSnapshot.snapshotBlobs };\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Attachment: {\n\t\t\t\ttreeNode.blobs[key] = summaryObject.id;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tconst contentString: string =\n\t\t\t\t\tsummaryObject.content instanceof Uint8Array\n\t\t\t\t\t\t? Uint8ArrayToString(summaryObject.content)\n\t\t\t\t\t\t: summaryObject.content;\n\t\t\t\tblobContents[blobId] = contentString;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle: {\n\t\t\t\tthrow new LoggingError(\n\t\t\t\t\t\"No handles should be there in summary in detached container!!\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t\tunreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n\t\t\t}\n\t\t}\n\t}\n\tconst pendingSnapshot = { baseSnapshot: treeNode, snapshotBlobs: blobContents };\n\treturn pendingSnapshot;\n}\n\n/**\n * Converts a snapshot to snapshotInfo with its blob contents\n * to align detached container format with IPendingContainerState\n *\n * Note, this assumes the ISnapshot sequence number is defined. Otherwise an assert will be thrown\n * @param snapshot - ISnapshot\n */\nexport function convertSnapshotToSnapshotInfo(snapshot: ISnapshot): ISnapshotInfo {\n\tassert(\n\t\tsnapshot.sequenceNumber !== undefined,\n\t\t0x93a /* Snapshot sequence number is missing */,\n\t);\n\tconst snapshotBlobs: ISerializableBlobContents = {};\n\tfor (const [blobId, arrayBufferLike] of snapshot.blobContents.entries()) {\n\t\tsnapshotBlobs[blobId] = bufferToString(arrayBufferLike, \"utf8\");\n\t}\n\treturn {\n\t\tbaseSnapshot: snapshot.snapshotTree,\n\t\tsnapshotBlobs,\n\t\tsnapshotSequenceNumber: snapshot.sequenceNumber,\n\t};\n}\n\n/**\n * Converts a snapshot to snapshotInfo with its blob contents\n * to align detached container format with IPendingContainerState\n *\n * Note, this assumes the ISnapshot sequence number is defined. Otherwise an assert will be thrown\n * @param snapshot - ISnapshot\n */\nexport function convertSnapshotInfoToSnapshot(\n\tsnapshotInfo: ISnapshotInfo,\n\tsnapshotSequenceNumber: number,\n): ISnapshot {\n\tconst blobContents = new Map<string, ArrayBufferLike>();\n\tfor (const [blobId, serializedContent] of Object.entries(snapshotInfo.snapshotBlobs)) {\n\t\tblobContents.set(blobId, stringToBuffer(serializedContent, \"utf8\"));\n\t}\n\treturn {\n\t\tsnapshotTree: snapshotInfo.baseSnapshot,\n\t\tblobContents,\n\t\tops: [],\n\t\tsequenceNumber: snapshotSequenceNumber,\n\t\tlatestSequenceNumber: undefined,\n\t\tsnapshotFormatV: 1,\n\t};\n}\n\n/**\n * Converts summary parts into a SnapshotTree and its blob contents.\n * @param protocolSummaryTree - Protocol Summary Tree\n * @param appSummaryTree - App Summary Tree\n */\nfunction convertProtocolAndAppSummaryToSnapshotAndBlobs(\n\tprotocolSummaryTree: ISummaryTree,\n\tappSummaryTree: ISummaryTree,\n): SnapshotWithBlobs {\n\tconst combinedSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: { ...appSummaryTree.tree },\n\t};\n\n\tcombinedSummary.tree[\".protocol\"] = protocolSummaryTree;\n\tconst snapshotTreeWithBlobContents = convertSummaryToSnapshotAndBlobs(combinedSummary);\n\treturn snapshotTreeWithBlobContents;\n}\n\nexport const getSnapshotTreeAndBlobsFromSerializedContainer = (\n\tdetachedContainerSnapshot: ISummaryTree,\n): SnapshotWithBlobs => {\n\tassert(\n\t\tisCombinedAppAndProtocolSummary(detachedContainerSnapshot),\n\t\t0x8e6 /* Protocol and App summary trees should be present */,\n\t);\n\tconst protocolSummaryTree = detachedContainerSnapshot.tree[\".protocol\"];\n\tconst appSummaryTree = detachedContainerSnapshot.tree[\".app\"];\n\tconst snapshotTreeWithBlobContents = convertProtocolAndAppSummaryToSnapshotAndBlobs(\n\t\tprotocolSummaryTree,\n\t\tappSummaryTree,\n\t);\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree {\n\treturn \".protocol\" in snapshot.trees ? snapshot.trees[\".protocol\"] : snapshot;\n}\n\nexport const combineSnapshotTreeAndSnapshotBlobs = (\n\tbaseSnapshot: ISnapshotTree,\n\tsnapshotBlobs: ISerializableBlobContents,\n): ISnapshotTreeWithBlobContents => {\n\tconst blobsContents: { [path: string]: ArrayBufferLike } = {};\n\n\t// Process blobs in the current level\n\tfor (const [, id] of Object.entries(baseSnapshot.blobs)) {\n\t\tif (snapshotBlobs[id]) {\n\t\t\tblobsContents[id] = stringToBuffer(snapshotBlobs[id], \"utf8\");\n\t\t}\n\t}\n\n\t// Recursively process trees in the current level\n\tconst trees: { [path: string]: ISnapshotTreeWithBlobContents } = {};\n\tfor (const [path, tree] of Object.entries(baseSnapshot.trees)) {\n\t\ttrees[path] = combineSnapshotTreeAndSnapshotBlobs(tree, snapshotBlobs);\n\t}\n\n\t// Create a new snapshot tree with blob contents and processed trees\n\tconst snapshotTreeWithBlobContents: ISnapshotTreeWithBlobContents = {\n\t\t...baseSnapshot,\n\t\tblobsContents,\n\t\ttrees,\n\t};\n\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function isDeltaStreamConnectionForbiddenError(\n\terror: unknown,\n): error is DeltaStreamConnectionForbiddenError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error as Partial<IFluidErrorBase>)?.errorType ===\n\t\t\tDriverErrorTypes.deltaStreamConnectionForbidden\n\t);\n}\n\n/**\n * Validates format in parsed string get from detached container\n * serialization using IPendingDetachedContainerState format.\n */\nfunction isPendingDetachedContainerState(\n\tdetachedContainerState: IPendingDetachedContainerState,\n): detachedContainerState is IPendingDetachedContainerState {\n\tif (\n\t\tdetachedContainerState?.attached === undefined ||\n\t\tdetachedContainerState?.baseSnapshot === undefined ||\n\t\tdetachedContainerState?.snapshotBlobs === undefined ||\n\t\tdetachedContainerState?.hasAttachmentBlobs === undefined\n\t) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Parses the given string into {@link IPendingDetachedContainerState} format,\n * with validation (if invalid, throws a UsageError).\n * This is the inverse of the JSON.stringify call in {@link Container.serialize}\n */\nexport function getDetachedContainerStateFromSerializedContainer(\n\tserializedContainer: string,\n): IPendingDetachedContainerState {\n\tconst hasBlobsSummaryTree = \".hasAttachmentBlobs\";\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\tconst parsedContainerState = JSON.parse(serializedContainer);\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\tif (isPendingDetachedContainerState(parsedContainerState)) {\n\t\treturn parsedContainerState;\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t} else if (isCombinedAppAndProtocolSummary(parsedContainerState)) {\n\t\tconst { baseSnapshot, snapshotBlobs } =\n\t\t\tgetSnapshotTreeAndBlobsFromSerializedContainer(parsedContainerState);\n\t\tconst detachedContainerState: IPendingDetachedContainerState = {\n\t\t\tattached: false,\n\t\t\tbaseSnapshot,\n\t\t\tsnapshotBlobs,\n\t\t\thasAttachmentBlobs: parsedContainerState.tree[hasBlobsSummaryTree] !== undefined,\n\t\t};\n\t\treturn detachedContainerState;\n\t} else {\n\t\tthrow new UsageError(\"Cannot rehydrate detached container. Incorrect format\");\n\t}\n}\n\n/**\n * Blindly parses the given string into {@link IPendingContainerState} format.\n * This is the inverse of the JSON.stringify call in {@link SerializedStateManager.getPendingLocalState}\n */\nexport function getAttachedContainerStateFromSerializedContainer(\n\tserializedContainer: string | undefined,\n): IPendingContainerState | undefined {\n\treturn serializedContainer === undefined\n\t\t? undefined\n\t\t: (JSON.parse(serializedContainer) as IPendingContainerState);\n}\n\n/**\n * Ensures only a single instance of the provided async function is running.\n * If there are multiple calls they will all get the same promise to wait on.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const runSingle = <A extends any[], R>(\n\tfunc: (...args: A) => Promise<R>,\n): ((...args: A) => Promise<R>) => {\n\tlet running:\n\t\t| {\n\t\t\t\targs: A;\n\t\t\t\tresult: Promise<R>;\n\t\t }\n\t\t| undefined;\n\t// don't mark this function async, so we return the same promise,\n\t// rather than one that is wrapped due to async\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\treturn (...args: A): Promise<R> => {\n\t\tif (running !== undefined) {\n\t\t\tif (!compareArrays(running.args, args)) {\n\t\t\t\treturn Promise.reject(\n\t\t\t\t\tnew UsageError(\"Subsequent calls cannot use different arguments.\"),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn running.result;\n\t\t}\n\t\trunning = { args, result: func(...args).finally(() => (running = undefined)) };\n\t\treturn running.result;\n\t};\n};\n\nexport async function getDocumentAttributes(\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n\ttree: ISnapshotTree | undefined,\n): Promise<IDocumentAttributes> {\n\tif (tree === undefined) {\n\t\treturn {\n\t\t\tminimumSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t};\n\t}\n\n\t// Backward compatibility: old docs would have \".attributes\" instead of \"attributes\"\n\tconst attributesHash =\n\t\t\".protocol\" in tree.trees\n\t\t\t? tree.trees[\".protocol\"].blobs.attributes\n\t\t\t: tree.blobs[\".attributes\"];\n\n\tconst attributes = await readAndParse<IDocumentAttributes>(storage, attributesHash);\n\n\treturn attributes;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-loader",
3
- "version": "2.11.0",
3
+ "version": "2.13.0",
4
4
  "description": "Fluid container loader",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -119,13 +119,13 @@
119
119
  "temp-directory": "nyc/.nyc_output"
120
120
  },
121
121
  "dependencies": {
122
- "@fluid-internal/client-utils": "~2.11.0",
123
- "@fluidframework/container-definitions": "~2.11.0",
124
- "@fluidframework/core-interfaces": "~2.11.0",
125
- "@fluidframework/core-utils": "~2.11.0",
126
- "@fluidframework/driver-definitions": "~2.11.0",
127
- "@fluidframework/driver-utils": "~2.11.0",
128
- "@fluidframework/telemetry-utils": "~2.11.0",
122
+ "@fluid-internal/client-utils": "~2.13.0",
123
+ "@fluidframework/container-definitions": "~2.13.0",
124
+ "@fluidframework/core-interfaces": "~2.13.0",
125
+ "@fluidframework/core-utils": "~2.13.0",
126
+ "@fluidframework/driver-definitions": "~2.13.0",
127
+ "@fluidframework/driver-utils": "~2.13.0",
128
+ "@fluidframework/telemetry-utils": "~2.13.0",
129
129
  "@types/events_pkg": "npm:@types/events@^3.0.0",
130
130
  "@ungap/structured-clone": "^1.2.0",
131
131
  "debug": "^4.3.4",
@@ -134,20 +134,20 @@
134
134
  "uuid": "^9.0.0"
135
135
  },
136
136
  "devDependencies": {
137
- "@arethetypeswrong/cli": "^0.16.4",
137
+ "@arethetypeswrong/cli": "^0.17.1",
138
138
  "@biomejs/biome": "~1.9.3",
139
- "@fluid-internal/client-utils": "~2.11.0",
140
- "@fluid-internal/mocha-test-setup": "~2.11.0",
141
- "@fluid-private/test-loader-utils": "~2.11.0",
139
+ "@fluid-internal/client-utils": "~2.13.0",
140
+ "@fluid-internal/mocha-test-setup": "~2.13.0",
141
+ "@fluid-private/test-loader-utils": "~2.13.0",
142
142
  "@fluid-tools/build-cli": "^0.51.0",
143
143
  "@fluidframework/build-common": "^2.0.3",
144
144
  "@fluidframework/build-tools": "^0.51.0",
145
- "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.10.0",
145
+ "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.12.0",
146
146
  "@fluidframework/eslint-config-fluid": "^5.6.0",
147
147
  "@microsoft/api-extractor": "7.47.8",
148
148
  "@types/debug": "^4.1.5",
149
149
  "@types/double-ended-queue": "^2.1.0",
150
- "@types/mocha": "^9.1.1",
150
+ "@types/mocha": "^10.0.10",
151
151
  "@types/node": "^18.19.0",
152
152
  "@types/sinon": "^17.0.3",
153
153
  "@types/ungap__structured-clone": "^1.2.0",
package/src/container.ts CHANGED
@@ -22,13 +22,13 @@ import {
22
22
  IFluidCodeDetailsComparer,
23
23
  IFluidModuleWithDetails,
24
24
  IGetPendingLocalStateProps,
25
- IHostLoader,
26
25
  IProvideFluidCodeDetailsComparer,
27
26
  IProvideRuntimeFactory,
28
27
  IRuntime,
29
28
  isFluidCodeDetails,
30
29
  IDeltaManager,
31
30
  ReadOnlyInfo,
31
+ type ILoader,
32
32
  } from "@fluidframework/container-definitions/internal";
33
33
  import {
34
34
  FluidObject,
@@ -2403,7 +2403,7 @@ export class Container
2403
2403
 
2404
2404
  // The relative loader will proxy requests to '/' to the loader itself assuming no non-cache flags
2405
2405
  // are set. Global requests will still go directly to the loader
2406
- const maybeLoader: FluidObject<IHostLoader> = this.scope;
2406
+ const maybeLoader: FluidObject<ILoader> = this.scope;
2407
2407
  const loader = new RelativeLoader(this, maybeLoader.ILoader);
2408
2408
 
2409
2409
  const loadCodeResult = await PerformanceEvent.timedExecAsync(
@@ -214,7 +214,7 @@ export class ContainerStorageAdapter
214
214
  }
215
215
 
216
216
  public async readBlob(id: string): Promise<ArrayBufferLike> {
217
- const maybeBlob = this.blobContents[id];
217
+ const maybeBlob: string | ArrayBufferLike | undefined = this.blobContents[id];
218
218
  if (maybeBlob !== undefined) {
219
219
  if (typeof maybeBlob === "string") {
220
220
  const blob = stringToBuffer(maybeBlob, "utf8");
@@ -361,7 +361,7 @@ async function getBlobManagerTreeFromTree(
361
361
  blobs: ISerializableBlobContents,
362
362
  storage: Pick<IDocumentStorageService, "readBlob">,
363
363
  ): Promise<void> {
364
- const id = tree.blobs[redirectTableBlobName];
364
+ const id: string | undefined = tree.blobs[redirectTableBlobName];
365
365
  assert(id !== undefined, 0x9ce /* id is undefined in getBlobManagerTreeFromTree */);
366
366
  const blob = await storage.readBlob(id);
367
367
  // ArrayBufferLike will not survive JSON.stringify()
@@ -404,7 +404,7 @@ function getBlobManagerTreeFromTreeWithBlobContents(
404
404
  tree: ISnapshotTreeWithBlobContents,
405
405
  blobs: ISerializableBlobContents,
406
406
  ): void {
407
- const id = tree.blobs[redirectTableBlobName];
407
+ const id: string | undefined = tree.blobs[redirectTableBlobName];
408
408
  assert(
409
409
  id !== undefined,
410
410
  0x9cf /* id is undefined in getBlobManagerTreeFromTreeWithBlobContents */,
@@ -0,0 +1,182 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ IContainer,
8
+ ICodeDetailsLoader,
9
+ IFluidCodeDetails,
10
+ type IContainerPolicies,
11
+ } from "@fluidframework/container-definitions/internal";
12
+ import {
13
+ FluidObject,
14
+ IConfigProviderBase,
15
+ IRequest,
16
+ ITelemetryBaseLogger,
17
+ } from "@fluidframework/core-interfaces";
18
+ import { IClientDetails } from "@fluidframework/driver-definitions";
19
+ import {
20
+ IDocumentServiceFactory,
21
+ IUrlResolver,
22
+ } from "@fluidframework/driver-definitions/internal";
23
+
24
+ import { Loader } from "./loader.js";
25
+ import { ProtocolHandlerBuilder } from "./protocol.js";
26
+
27
+ /**
28
+ * Properties necessary for creating and loading a container.
29
+ * @legacy
30
+ * @alpha
31
+ */
32
+ export interface ICreateAndLoadContainerProps {
33
+ /**
34
+ * The url resolver used by the loader for resolving external urls
35
+ * into Fluid urls such that the container specified by the
36
+ * external url can be loaded.
37
+ */
38
+ readonly urlResolver: IUrlResolver;
39
+ /**
40
+ * The document service factory take the Fluid url provided
41
+ * by the resolved url and constructs all the necessary services
42
+ * for communication with the container's server.
43
+ */
44
+ readonly documentServiceFactory: IDocumentServiceFactory;
45
+ /**
46
+ * The code loader handles loading the necessary code
47
+ * for running a container once it is loaded.
48
+ */
49
+ readonly codeLoader: ICodeDetailsLoader;
50
+
51
+ /**
52
+ * A property bag of options/policies used by various layers
53
+ * to control features
54
+ */
55
+ readonly options?: IContainerPolicies | undefined;
56
+
57
+ /**
58
+ * Scope is provided to all container and is a set of shared
59
+ * services for container's to integrate with their host environment.
60
+ */
61
+ readonly scope?: FluidObject | undefined;
62
+
63
+ /**
64
+ * The logger that all telemetry should be pushed to.
65
+ */
66
+ readonly logger?: ITelemetryBaseLogger | undefined;
67
+
68
+ /**
69
+ * The configuration provider which may be used to control features.
70
+ */
71
+ readonly configProvider?: IConfigProviderBase | undefined;
72
+
73
+ /**
74
+ * Optional property for allowing the container to use a custom
75
+ * protocol implementation for handling the quorum and/or the audience.
76
+ */
77
+ readonly protocolHandlerBuilder?: ProtocolHandlerBuilder | undefined;
78
+
79
+ /**
80
+ * Disables the Container from reconnecting if false, allows reconnect otherwise.
81
+ */
82
+ readonly allowReconnect?: boolean | undefined;
83
+
84
+ /**
85
+ * Client details provided in the override will be merged over the default client.
86
+ */
87
+ readonly clientDetailsOverride?: IClientDetails | undefined;
88
+ }
89
+
90
+ /**
91
+ * Props used to load a container.
92
+ * @legacy
93
+ * @alpha
94
+ */
95
+ export interface ILoadExistingContainerProps extends ICreateAndLoadContainerProps {
96
+ /**
97
+ * The request to resolve the container.
98
+ */
99
+ readonly request: IRequest;
100
+
101
+ /**
102
+ * Pending local state to be applied to the container.
103
+ */
104
+ readonly pendingLocalState?: string | undefined;
105
+ }
106
+
107
+ /**
108
+ * Props used to create a detached container.
109
+ * @legacy
110
+ * @alpha
111
+ */
112
+ export interface ICreateDetachedContainerProps extends ICreateAndLoadContainerProps {
113
+ /**
114
+ * The code details for the container to be created.
115
+ */
116
+ readonly codeDetails: IFluidCodeDetails;
117
+ }
118
+
119
+ /**
120
+ * Props used to rehydrate a detached container.
121
+ * @legacy
122
+ * @alpha
123
+ */
124
+ export interface IRehydrateDetachedContainerProps extends ICreateAndLoadContainerProps {
125
+ /**
126
+ * The serialized state returned by calling serialize on another container
127
+ */
128
+ readonly serializedState: string;
129
+ }
130
+
131
+ /**
132
+ * Creates a new container using the specified code details but in an unattached state. While unattached, all
133
+ * updates will only be local until the user explicitly attaches the container to a service provider.
134
+ * @param createDetachedContainerProps - Services and properties necessary for creating detached container.
135
+ * @legacy
136
+ * @alpha
137
+ */
138
+ export async function createDetachedContainer(
139
+ createDetachedContainerProps: ICreateDetachedContainerProps,
140
+ ): Promise<IContainer> {
141
+ const loader = new Loader(createDetachedContainerProps);
142
+ return loader.createDetachedContainer(createDetachedContainerProps.codeDetails, {
143
+ canReconnect: createDetachedContainerProps.allowReconnect,
144
+ clientDetailsOverride: createDetachedContainerProps.clientDetailsOverride,
145
+ });
146
+ }
147
+
148
+ /**
149
+ * Creates a new container using the specified snapshot but in an unattached state. While unattached, all
150
+ * updates will only be local until the user explicitly attaches the container to a service provider.
151
+ * @param rehydrateDetachedContainerProps - Services and properties necessary for rehydrating detached container from a previously serialized container's state.
152
+ * @legacy
153
+ * @alpha
154
+ */
155
+ export async function rehydrateDetachedContainer(
156
+ rehydrateDetachedContainerProps: IRehydrateDetachedContainerProps,
157
+ ): Promise<IContainer> {
158
+ const loader = new Loader(rehydrateDetachedContainerProps);
159
+ return loader.rehydrateDetachedContainerFromSnapshot(
160
+ rehydrateDetachedContainerProps.serializedState,
161
+ {
162
+ canReconnect: rehydrateDetachedContainerProps.allowReconnect,
163
+ clientDetailsOverride: rehydrateDetachedContainerProps.clientDetailsOverride,
164
+ },
165
+ );
166
+ }
167
+
168
+ /**
169
+ * Loads a container with an existing snapshot from the service.
170
+ * @param loadExistingContainerProps - Services and properties necessary for loading an existing container.
171
+ * @legacy
172
+ * @alpha
173
+ */
174
+ export async function loadExistingContainer(
175
+ loadExistingContainerProps: ILoadExistingContainerProps,
176
+ ): Promise<IContainer> {
177
+ const loader = new Loader(loadExistingContainerProps);
178
+ return loader.resolve(
179
+ loadExistingContainerProps.request,
180
+ loadExistingContainerProps.pendingLocalState,
181
+ );
182
+ }
package/src/index.ts CHANGED
@@ -5,6 +5,15 @@
5
5
 
6
6
  export { ConnectionState } from "./connectionState.js";
7
7
  export { IContainerExperimental, waitContainerToCatchUp } from "./container.js";
8
+ export {
9
+ createDetachedContainer,
10
+ loadExistingContainer,
11
+ rehydrateDetachedContainer,
12
+ ICreateAndLoadContainerProps,
13
+ ICreateDetachedContainerProps,
14
+ ILoadExistingContainerProps,
15
+ IRehydrateDetachedContainerProps,
16
+ } from "./createAndLoadContainerUtils.js";
8
17
  export {
9
18
  ICodeDetailsLoader,
10
19
  IDetachedBlobStorage,
package/src/loadPaused.ts CHANGED
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import {
7
- ILoader,
8
7
  isIDeltaManagerFull,
9
8
  LoaderHeader,
10
9
  type IContainer,
@@ -14,6 +13,9 @@ import type { IErrorBase } from "@fluidframework/core-interfaces";
14
13
  import { assert } from "@fluidframework/core-utils/internal";
15
14
  import { GenericError } from "@fluidframework/telemetry-utils/internal";
16
15
 
16
+ import { loadExistingContainer } from "./createAndLoadContainerUtils.js";
17
+ import { type ILoaderProps } from "./loader.js";
18
+
17
19
  /* eslint-disable jsdoc/check-indentation */
18
20
 
19
21
  /**
@@ -35,7 +37,7 @@ import { GenericError } from "@fluidframework/telemetry-utils/internal";
35
37
  * network connectivity issues / ability to cancel (IContainer.disconnect) or close container (IContainer.close)
36
38
  * This flow needs to fetch ops (potentially connecting to delta connection), and any retriable errors on this path result in infinite retry.
37
39
  * If you need to cancel that process, consider supplying AbortSignal parameter.
38
- * @param loader - loader instance to use to load container
40
+ * @param loaderProps - The loader props to use to load the container.
39
41
  * @param request - request identifying container instance / load parameters. LoaderHeader.loadMode headers are ignored (see above)
40
42
  * @param loadToSequenceNumber - optional sequence number. If provided, ops are processed up to this sequence number.
41
43
  * @param signal - optional abort signal that can be used to cancel waiting for the ops.
@@ -44,17 +46,20 @@ import { GenericError } from "@fluidframework/telemetry-utils/internal";
44
46
  * @internal
45
47
  */
46
48
  export async function loadContainerPaused(
47
- loader: ILoader,
49
+ loaderProps: ILoaderProps,
48
50
  request: IRequest,
49
51
  loadToSequenceNumber?: number,
50
52
  signal?: AbortSignal,
51
53
  ): Promise<IContainer> {
52
- const container = await loader.resolve({
53
- url: request.url,
54
- headers: {
55
- ...request.headers,
56
- // ensure we do not process any ops, such that we can examine container before ops starts to flow.
57
- [LoaderHeader.loadMode]: { opsBeforeReturn: undefined, deltaConnection: "none" },
54
+ const container = await loadExistingContainer({
55
+ ...loaderProps,
56
+ request: {
57
+ url: request.url,
58
+ headers: {
59
+ ...request.headers,
60
+ // ensure we do not process any ops, such that we can examine container before ops starts to flow.
61
+ [LoaderHeader.loadMode]: { opsBeforeReturn: undefined, deltaConnection: "none" },
62
+ },
58
63
  },
59
64
  });
60
65
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-loader";
9
- export const pkgVersion = "2.11.0";
9
+ export const pkgVersion = "2.13.0";
package/src/utils.ts CHANGED
@@ -145,10 +145,7 @@ function convertSummaryToSnapshotAndBlobs(summary: ISummaryTree): SnapshotWithBl
145
145
  unreferenced: summary.unreferenced,
146
146
  groupId: summary.groupId,
147
147
  };
148
- const keys = Object.keys(summary.tree);
149
- for (const key of keys) {
150
- const summaryObject = summary.tree[key];
151
-
148
+ for (const [key, summaryObject] of Object.entries(summary.tree)) {
152
149
  switch (summaryObject.type) {
153
150
  case SummaryType.Tree: {
154
151
  const innerSnapshot = convertSummaryToSnapshotAndBlobs(summaryObject);