@fluidframework/container-loader 2.0.0-internal.5.0.1 → 2.0.0-internal.5.1.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 (86) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +21 -0
  3. package/dist/connectionManager.d.ts.map +1 -1
  4. package/dist/connectionManager.js +32 -13
  5. package/dist/connectionManager.js.map +1 -1
  6. package/dist/connectionStateHandler.d.ts +11 -0
  7. package/dist/connectionStateHandler.d.ts.map +1 -1
  8. package/dist/connectionStateHandler.js +24 -1
  9. package/dist/connectionStateHandler.js.map +1 -1
  10. package/dist/container.d.ts +15 -11
  11. package/dist/container.d.ts.map +1 -1
  12. package/dist/container.js +44 -55
  13. package/dist/container.js.map +1 -1
  14. package/dist/containerStorageAdapter.d.ts.map +1 -1
  15. package/dist/containerStorageAdapter.js +6 -15
  16. package/dist/containerStorageAdapter.js.map +1 -1
  17. package/dist/contracts.d.ts +8 -0
  18. package/dist/contracts.d.ts.map +1 -1
  19. package/dist/contracts.js.map +1 -1
  20. package/dist/deltaManager.d.ts +18 -7
  21. package/dist/deltaManager.d.ts.map +1 -1
  22. package/dist/deltaManager.js +42 -30
  23. package/dist/deltaManager.js.map +1 -1
  24. package/dist/deltaQueue.d.ts +2 -3
  25. package/dist/deltaQueue.d.ts.map +1 -1
  26. package/dist/deltaQueue.js +2 -3
  27. package/dist/deltaQueue.js.map +1 -1
  28. package/dist/loader.d.ts +0 -2
  29. package/dist/loader.d.ts.map +1 -1
  30. package/dist/loader.js +24 -32
  31. package/dist/loader.js.map +1 -1
  32. package/dist/packageVersion.d.ts +1 -1
  33. package/dist/packageVersion.js +1 -1
  34. package/dist/packageVersion.js.map +1 -1
  35. package/dist/tsdoc-metadata.json +11 -0
  36. package/dist/utils.d.ts +2 -0
  37. package/dist/utils.d.ts.map +1 -1
  38. package/dist/utils.js +8 -1
  39. package/dist/utils.js.map +1 -1
  40. package/lib/connectionManager.d.ts.map +1 -1
  41. package/lib/connectionManager.js +32 -13
  42. package/lib/connectionManager.js.map +1 -1
  43. package/lib/connectionStateHandler.d.ts +11 -0
  44. package/lib/connectionStateHandler.d.ts.map +1 -1
  45. package/lib/connectionStateHandler.js +24 -1
  46. package/lib/connectionStateHandler.js.map +1 -1
  47. package/lib/container.d.ts +15 -11
  48. package/lib/container.d.ts.map +1 -1
  49. package/lib/container.js +44 -55
  50. package/lib/container.js.map +1 -1
  51. package/lib/containerStorageAdapter.d.ts.map +1 -1
  52. package/lib/containerStorageAdapter.js +6 -15
  53. package/lib/containerStorageAdapter.js.map +1 -1
  54. package/lib/contracts.d.ts +8 -0
  55. package/lib/contracts.d.ts.map +1 -1
  56. package/lib/contracts.js.map +1 -1
  57. package/lib/deltaManager.d.ts +18 -7
  58. package/lib/deltaManager.d.ts.map +1 -1
  59. package/lib/deltaManager.js +44 -32
  60. package/lib/deltaManager.js.map +1 -1
  61. package/lib/deltaQueue.d.ts +2 -3
  62. package/lib/deltaQueue.d.ts.map +1 -1
  63. package/lib/deltaQueue.js +2 -3
  64. package/lib/deltaQueue.js.map +1 -1
  65. package/lib/loader.d.ts +0 -2
  66. package/lib/loader.d.ts.map +1 -1
  67. package/lib/loader.js +24 -32
  68. package/lib/loader.js.map +1 -1
  69. package/lib/packageVersion.d.ts +1 -1
  70. package/lib/packageVersion.js +1 -1
  71. package/lib/packageVersion.js.map +1 -1
  72. package/lib/utils.d.ts +2 -0
  73. package/lib/utils.d.ts.map +1 -1
  74. package/lib/utils.js +7 -1
  75. package/lib/utils.js.map +1 -1
  76. package/package.json +17 -36
  77. package/src/connectionManager.ts +33 -15
  78. package/src/connectionStateHandler.ts +45 -1
  79. package/src/container.ts +87 -75
  80. package/src/containerStorageAdapter.ts +4 -16
  81. package/src/contracts.ts +10 -0
  82. package/src/deltaManager.ts +52 -33
  83. package/src/deltaQueue.ts +2 -3
  84. package/src/loader.ts +33 -40
  85. package/src/packageVersion.ts +1 -1
  86. package/src/utils.ts +15 -1
package/lib/loader.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.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 { v4 as uuid } from \"uuid\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/common-definitions\";\nimport {\n\tITelemetryLoggerExt,\n\tChildLogger,\n\tDebugLogger,\n\tIConfigProviderBase,\n\tloggerToMonitoringContext,\n\tmixinMonitoringContext,\n\tMonitoringContext,\n\tPerformanceEvent,\n\tsessionStorageConfigProvider,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tFluidObject,\n\tIFluidRouter,\n\tIRequest,\n\tIRequestHeader,\n\tIResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\tIContainer,\n\tIFluidModule,\n\tIHostLoader,\n\tILoader,\n\tILoaderOptions as ILoaderOptions1,\n\tLoaderHeader,\n\tIProvideFluidCodeDetailsComparer,\n\tIFluidCodeDetails,\n} from \"@fluidframework/container-definitions\";\nimport {\n\tIDocumentServiceFactory,\n\tIDocumentStorageService,\n\tIResolvedUrl,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { Container, IPendingContainerState } from \"./container\";\nimport { IParsedUrl, parseUrl } from \"./utils\";\nimport { pkgVersion } from \"./packageVersion\";\nimport { ProtocolHandlerBuilder } from \"./protocol\";\n\nfunction canUseCache(request: IRequest): boolean {\n\tif (request.headers === undefined) {\n\t\treturn true;\n\t}\n\n\treturn request.headers[LoaderHeader.cache] !== false;\n}\n\nfunction ensureResolvedUrlDefined(\n\tresolved: IResolvedUrl | undefined,\n): asserts resolved is IResolvedUrl {\n\tif (resolved === undefined) {\n\t\tthrow new Error(`Object is not a IResolveUrl.`);\n\t}\n}\n/**\n * @internal\n */\nexport class RelativeLoader implements ILoader {\n\tconstructor(\n\t\tprivate readonly container: Container,\n\t\tprivate readonly loader: ILoader | undefined,\n\t) {}\n\n\tpublic get IFluidRouter(): IFluidRouter {\n\t\treturn this;\n\t}\n\n\tpublic async resolve(request: IRequest): Promise<IContainer> {\n\t\tif (request.url.startsWith(\"/\")) {\n\t\t\tif (canUseCache(request)) {\n\t\t\t\treturn this.container;\n\t\t\t} else {\n\t\t\t\tensureResolvedUrlDefined(this.container.resolvedUrl);\n\t\t\t\tconst container = await Container.clone(\n\t\t\t\t\tthis.container,\n\t\t\t\t\t{\n\t\t\t\t\t\tresolvedUrl: { ...this.container.resolvedUrl },\n\t\t\t\t\t\tversion: request.headers?.[LoaderHeader.version] ?? undefined,\n\t\t\t\t\t\tloadMode: request.headers?.[LoaderHeader.loadMode],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcanReconnect: request.headers?.[LoaderHeader.reconnect],\n\t\t\t\t\t\tclientDetailsOverride: request.headers?.[LoaderHeader.clientDetails],\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn container;\n\t\t\t}\n\t\t}\n\n\t\tif (this.loader === undefined) {\n\t\t\tthrow new Error(\"Cannot resolve external containers\");\n\t\t}\n\t\treturn this.loader.resolve(request);\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\tif (request.url.startsWith(\"/\")) {\n\t\t\tconst container = await this.resolve(request);\n\t\t\treturn container.request(request);\n\t\t}\n\n\t\tif (this.loader === undefined) {\n\t\t\treturn {\n\t\t\t\tstatus: 404,\n\t\t\t\tvalue: \"Cannot request external containers\",\n\t\t\t\tmimeType: \"plain/text\",\n\t\t\t};\n\t\t}\n\t\treturn this.loader.request(request);\n\t}\n}\n\nexport interface ILoaderOptions extends ILoaderOptions1 {\n\tsummarizeProtocolTree?: boolean;\n}\n\n/**\n * @deprecated IFluidModuleWithDetails interface is moved to\n * {@link @fluidframework/container-definitions#IFluidModuleWithDetails}\n * to have all the code loading modules in one package. #8193\n * Encapsulates a module entry point with corresponding code details.\n */\nexport interface IFluidModuleWithDetails {\n\t/** Fluid code module that implements the runtime factory needed to instantiate the container runtime. */\n\tmodule: IFluidModule;\n\t/**\n\t * Code details associated with the module. Represents a document schema this module supports.\n\t * If the code loader implements the {@link @fluidframework/core-interfaces#IFluidCodeDetailsComparer} interface,\n\t * it'll be called to determine whether the module code details satisfy the new code proposal in the quorum.\n\t */\n\tdetails: IFluidCodeDetails;\n}\n\n/**\n * @deprecated ICodeDetailsLoader interface is moved to {@link @fluidframework/container-definition#ICodeDetailsLoader}\n * to have code loading modules in one package. #8193\n * Fluid code loader resolves a code module matching the document schema, i.e. code details, such as\n * a package name and package version range.\n */\nexport interface ICodeDetailsLoader extends Partial<IProvideFluidCodeDetailsComparer> {\n\t/**\n\t * Load the code module (package) that is capable to interact with the document.\n\t *\n\t * @param source - Code proposal that articulates the current schema the document is written in.\n\t * @returns - Code module entry point along with the code details associated with it.\n\t */\n\tload(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails>;\n}\n\n/**\n * Services and properties necessary for creating a loader\n */\nexport interface ILoaderProps {\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 used by various layers\n\t * to control features\n\t */\n\treadonly options?: ILoaderOptions;\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;\n\n\t/**\n\t * The logger that all telemetry should be pushed to.\n\t */\n\treadonly logger?: ITelemetryBaseLogger;\n\n\t/**\n\t * Blobs storage for detached containers.\n\t */\n\treadonly detachedBlobStorage?: IDetachedBlobStorage;\n\n\t/**\n\t * The configuration provider which may be used to control features.\n\t */\n\treadonly configProvider?: IConfigProviderBase;\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;\n}\n\n/**\n * Services and properties used by and exposed by the loader\n */\nexport interface ILoaderServices {\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 used by various layers\n\t * to control features\n\t */\n\treadonly options: ILoaderOptions;\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;\n\n\t/**\n\t * The logger downstream consumers should construct their loggers from\n\t */\n\treadonly subLogger: ITelemetryLoggerExt;\n\n\t/**\n\t * Blobs storage for detached containers.\n\t */\n\treadonly detachedBlobStorage?: IDetachedBlobStorage;\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;\n}\n\n/**\n * Subset of IDocumentStorageService which only supports createBlob() and readBlob(). This is used to support\n * blobs in detached containers.\n */\nexport type IDetachedBlobStorage = Pick<IDocumentStorageService, \"createBlob\" | \"readBlob\"> & {\n\tsize: number;\n\t/**\n\t * Return an array of all blob IDs present in storage\n\t */\n\tgetBlobIds(): string[];\n};\n\n/**\n * With an already-resolved container, we can request a component directly, without loading the container again\n * @param container - a resolved container\n * @returns component on the container\n */\nexport async function requestResolvedObjectFromContainer(\n\tcontainer: IContainer,\n\theaders?: IRequestHeader,\n): Promise<IResponse> {\n\tensureResolvedUrlDefined(container.resolvedUrl);\n\tconst parsedUrl = parseUrl(container.resolvedUrl.url);\n\n\tif (parsedUrl === undefined) {\n\t\tthrow new Error(`Invalid URL ${container.resolvedUrl.url}`);\n\t}\n\n\tconst entryPoint: FluidObject<IFluidRouter> | undefined = await container.getEntryPoint?.();\n\tconst router = entryPoint?.IFluidRouter ?? container.IFluidRouter;\n\n\treturn router.request({\n\t\turl: `${parsedUrl.path}${parsedUrl.query}`,\n\t\theaders,\n\t});\n}\n\n/**\n * Manages Fluid resource loading\n */\nexport class Loader implements IHostLoader {\n\tprivate readonly containers = new Map<string, Promise<Container>>();\n\tpublic readonly services: ILoaderServices;\n\tprivate readonly mc: MonitoringContext;\n\n\tconstructor(loaderProps: ILoaderProps) {\n\t\tconst scope: FluidObject<ILoader> = { ...loaderProps.scope };\n\t\tif (loaderProps.options?.provideScopeLoader !== false) {\n\t\t\tscope.ILoader = this;\n\t\t}\n\t\tconst telemetryProps = {\n\t\t\tloaderId: uuid(),\n\t\t\tloaderVersion: pkgVersion,\n\t\t};\n\n\t\tconst subMc = mixinMonitoringContext(\n\t\t\tDebugLogger.mixinDebugLogger(\"fluid:telemetry\", loaderProps.logger, {\n\t\t\t\tall: telemetryProps,\n\t\t\t}),\n\t\t\tsessionStorageConfigProvider.value,\n\t\t\tloaderProps.configProvider,\n\t\t);\n\n\t\tthis.services = {\n\t\t\t...loaderProps,\n\t\t\tscope,\n\t\t\tsubLogger: subMc.logger,\n\t\t\toptions: loaderProps.options ?? {},\n\t\t};\n\t\tthis.mc = loggerToMonitoringContext(ChildLogger.create(this.services.subLogger, \"Loader\"));\n\t}\n\n\tpublic get IFluidRouter(): IFluidRouter {\n\t\treturn this;\n\t}\n\n\tpublic async createDetachedContainer(codeDetails: IFluidCodeDetails): Promise<IContainer> {\n\t\tconst container = await Container.createDetached(this.services, codeDetails);\n\n\t\tif (this.cachingEnabled) {\n\t\t\tcontainer.once(\"attached\", () => {\n\t\t\t\tensureResolvedUrlDefined(container.resolvedUrl);\n\t\t\t\tconst parsedUrl = parseUrl(container.resolvedUrl.url);\n\t\t\t\tif (parsedUrl !== undefined) {\n\t\t\t\t\tthis.addToContainerCache(parsedUrl.id, Promise.resolve(container));\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn container;\n\t}\n\n\tpublic async rehydrateDetachedContainerFromSnapshot(snapshot: string): Promise<IContainer> {\n\t\treturn Container.rehydrateDetachedFromSnapshot(this.services, snapshot);\n\t}\n\n\tpublic async resolve(request: IRequest, pendingLocalState?: string): Promise<IContainer> {\n\t\tconst eventName = pendingLocalState === undefined ? \"Resolve\" : \"ResolveWithPendingState\";\n\t\treturn PerformanceEvent.timedExecAsync(this.mc.logger, { eventName }, async () => {\n\t\t\tconst resolved = await this.resolveCore(\n\t\t\t\trequest,\n\t\t\t\tpendingLocalState !== undefined ? JSON.parse(pendingLocalState) : undefined,\n\t\t\t);\n\t\t\treturn resolved.container;\n\t\t});\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\tthis.mc.logger,\n\t\t\t{ eventName: \"Request\" },\n\t\t\tasync () => {\n\t\t\t\tconst resolved = await this.resolveCore(request);\n\t\t\t\treturn resolved.container.request({\n\t\t\t\t\t...request,\n\t\t\t\t\turl: `${resolved.parsed.path}${resolved.parsed.query}`,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate getKeyForContainerCache(request: IRequest, parsedUrl: IParsedUrl): string {\n\t\tconst key =\n\t\t\trequest.headers?.[LoaderHeader.version] !== undefined\n\t\t\t\t? `${parsedUrl.id}@${request.headers[LoaderHeader.version]}`\n\t\t\t\t: parsedUrl.id;\n\t\treturn key;\n\t}\n\n\tprivate addToContainerCache(key: string, containerP: Promise<Container>) {\n\t\tthis.containers.set(key, containerP);\n\t\tcontainerP\n\t\t\t.then((container) => {\n\t\t\t\t// If the container is closed or becomes closed after we resolve it, remove it from the cache.\n\t\t\t\tif (container.closed) {\n\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t} else {\n\t\t\t\t\tcontainer.once(\"closed\", () => {\n\t\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {});\n\t}\n\n\tprivate async resolveCore(\n\t\trequest: IRequest,\n\t\tpendingLocalState?: IPendingContainerState,\n\t): Promise<{ container: Container; parsed: IParsedUrl }> {\n\t\tconst resolvedAsFluid = await this.services.urlResolver.resolve(request);\n\t\tensureResolvedUrlDefined(resolvedAsFluid);\n\n\t\t// Parse URL into data stores\n\t\tconst parsed = parseUrl(resolvedAsFluid.url);\n\t\tif (parsed === undefined) {\n\t\t\tthrow new Error(`Invalid URL ${resolvedAsFluid.url}`);\n\t\t}\n\n\t\tif (pendingLocalState !== undefined) {\n\t\t\tconst parsedPendingUrl = parseUrl(pendingLocalState.url);\n\t\t\tif (\n\t\t\t\tparsedPendingUrl?.id !== parsed.id ||\n\t\t\t\tparsedPendingUrl?.path.replace(/\\/$/, \"\") !== parsed.path.replace(/\\/$/, \"\")\n\t\t\t) {\n\t\t\t\tconst message = `URL ${resolvedAsFluid.url} does not match pending state URL ${pendingLocalState.url}`;\n\t\t\t\tthrow new Error(message);\n\t\t\t}\n\t\t}\n\n\t\tconst { canCache, fromSequenceNumber } = this.parseHeader(parsed, request);\n\t\tconst shouldCache = pendingLocalState !== undefined ? false : canCache;\n\n\t\tlet container: Container;\n\t\tif (shouldCache) {\n\t\t\tconst key = this.getKeyForContainerCache(request, parsed);\n\t\t\tconst maybeContainer = await this.containers.get(key);\n\t\t\tif (maybeContainer !== undefined) {\n\t\t\t\tcontainer = maybeContainer;\n\t\t\t} else {\n\t\t\t\tconst containerP = this.loadContainer(request, resolvedAsFluid);\n\t\t\t\tthis.addToContainerCache(key, containerP);\n\t\t\t\tcontainer = await containerP;\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer = await this.loadContainer(request, resolvedAsFluid, pendingLocalState);\n\t\t}\n\n\t\tif (container.deltaManager.lastSequenceNumber <= fromSequenceNumber) {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tfunction opHandler(message: ISequencedDocumentMessage) {\n\t\t\t\t\tif (message.sequenceNumber > fromSequenceNumber) {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t\tcontainer.removeListener(\"op\", opHandler);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontainer.on(\"op\", opHandler);\n\t\t\t});\n\t\t}\n\n\t\treturn { container, parsed };\n\t}\n\n\tprivate get cachingEnabled() {\n\t\treturn this.services.options.cache !== false;\n\t}\n\n\tprivate canCacheForRequest(headers: IRequestHeader): boolean {\n\t\treturn this.cachingEnabled && headers[LoaderHeader.cache] !== false;\n\t}\n\n\tprivate parseHeader(parsed: IParsedUrl, request: IRequest) {\n\t\tlet fromSequenceNumber = -1;\n\n\t\trequest.headers = request.headers ?? {};\n\n\t\tconst headerSeqNum = request.headers[LoaderHeader.sequenceNumber];\n\t\tif (headerSeqNum !== undefined) {\n\t\t\tfromSequenceNumber = headerSeqNum;\n\t\t}\n\n\t\t// If set in both query string and headers, use query string\n\t\trequest.headers[LoaderHeader.version] =\n\t\t\tparsed.version ?? request.headers[LoaderHeader.version];\n\n\t\tconst canCache = this.canCacheForRequest(request.headers);\n\n\t\treturn {\n\t\t\tcanCache,\n\t\t\tfromSequenceNumber,\n\t\t};\n\t}\n\n\tprivate async loadContainer(\n\t\trequest: IRequest,\n\t\tresolvedUrl: IResolvedUrl,\n\t\tpendingLocalState?: IPendingContainerState,\n\t): Promise<Container> {\n\t\treturn Container.load(\n\t\t\t{\n\t\t\t\tresolvedUrl,\n\t\t\t\tversion: request.headers?.[LoaderHeader.version] ?? undefined,\n\t\t\t\tloadMode: request.headers?.[LoaderHeader.loadMode],\n\t\t\t\tpendingLocalState,\n\t\t\t},\n\t\t\t{\n\t\t\t\tcanReconnect: request.headers?.[LoaderHeader.reconnect],\n\t\t\t\tclientDetailsOverride: request.headers?.[LoaderHeader.clientDetails],\n\t\t\t\t...this.services,\n\t\t\t},\n\t\t);\n\t}\n}\n"]}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EAEN,WAAW,EACX,WAAW,EAEX,yBAAyB,EACzB,sBAAsB,EAEtB,gBAAgB,EAChB,4BAA4B,GAC5B,MAAM,iCAAiC,CAAC;AAQzC,OAAO,EAMN,YAAY,GAGZ,MAAM,uCAAuC,CAAC;AAQ/C,OAAO,EAAE,SAAS,EAA0B,MAAM,aAAa,CAAC;AAChE,OAAO,EAAc,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,SAAS,WAAW,CAAC,OAAiB;IACrC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE;QAClC,OAAO,IAAI,CAAC;KACZ;IAED,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AACtD,CAAC;AAED,SAAS,wBAAwB,CAChC,QAAkC;IAElC,IAAI,QAAQ,KAAK,SAAS,EAAE;QAC3B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;KAChD;AACF,CAAC;AACD;;GAEG;AACH,MAAM,OAAO,cAAc;IAC1B,YACkB,SAAoB,EACpB,MAA2B;QAD3B,cAAS,GAAT,SAAS,CAAW;QACpB,WAAM,GAAN,MAAM,CAAqB;IAC1C,CAAC;IAEJ,IAAW,YAAY;QACtB,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB;;QACrC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YAChC,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE;gBACzB,OAAO,IAAI,CAAC,SAAS,CAAC;aACtB;iBAAM;gBACN,wBAAwB,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;gBACrD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAC3C;oBACC,WAAW,oBAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAE;oBAC9C,OAAO,EAAE,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,OAAO,CAAC,mCAAI,SAAS;oBAC7D,QAAQ,EAAE,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,QAAQ,CAAC;iBAClD,EACD;oBACC,YAAY,EAAE,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,SAAS,CAAC;oBACvD,qBAAqB,EAAE,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,aAAa,CAAC;iBACpE,CACD,CAAC;gBACF,OAAO,SAAS,CAAC;aACjB;SACD;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;YAC9B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACtD;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB;QACrC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YAChC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC9C,OAAO,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAClC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;YAC9B,OAAO;gBACN,MAAM,EAAE,GAAG;gBACX,KAAK,EAAE,oCAAoC;gBAC3C,QAAQ,EAAE,YAAY;aACtB,CAAC;SACF;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;CACD;AA8JD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACvD,SAAqB,EACrB,OAAwB;;IAExB,wBAAwB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAEtD,IAAI,SAAS,KAAK,SAAS,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,eAAe,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC;KAC5D;IAED,MAAM,UAAU,GAA0C,MAAM,CAAA,MAAA,SAAS,CAAC,aAAa,+CAAvB,SAAS,CAAkB,CAAA,CAAC;IAC5F,MAAM,MAAM,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,YAAY,mCAAI,SAAS,CAAC,YAAY,CAAC;IAElE,OAAO,MAAM,CAAC,OAAO,CAAC;QACrB,GAAG,EAAE,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE;QAC1C,OAAO;KACP,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,MAAM;IAKlB,YAAY,WAAyB;QAJpB,eAAU,GAAG,IAAI,GAAG,EAA8B,CAAC;QAKnE,MAAM,EACL,WAAW,EACX,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,KAAK,EACL,MAAM,EACN,mBAAmB,EACnB,cAAc,EACd,sBAAsB,GACtB,GAAG,WAAW,CAAC;QAEhB,MAAM,cAAc,GAAG;YACtB,QAAQ,EAAE,IAAI,EAAE;YAChB,aAAa,EAAE,UAAU;SACzB,CAAC;QAEF,MAAM,KAAK,GAAG,sBAAsB,CACnC,WAAW,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,EAAE;YACvD,GAAG,EAAE,cAAc;SACnB,CAAC,EACF,4BAA4B,CAAC,KAAK,EAClC,cAAc,CACd,CAAC;QAEF,IAAI,CAAC,QAAQ,GAAG;YACf,WAAW;YACX,sBAAsB;YACtB,UAAU;YACV,OAAO,EAAE,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE;YACtB,KAAK,EACJ,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,kBAAkB,MAAK,KAAK,CAAC,CAAC,iCAAM,KAAK,KAAE,OAAO,EAAE,IAAI,IAAG,CAAC,mBAAM,KAAK,CAAE;YACnF,mBAAmB;YACnB,sBAAsB;YACtB,SAAS,EAAE,KAAK,CAAC,MAAM;SACvB,CAAC;QACF,IAAI,CAAC,EAAE,GAAG,yBAAyB,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,IAAW,YAAY;QACtB,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,KAAK,CAAC,uBAAuB,CAAC,WAA8B;QAClE,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE7E,IAAI,IAAI,CAAC,cAAc,EAAE;YACxB,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE;gBAC/B,wBAAwB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;gBAChD,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACtD,IAAI,SAAS,KAAK,SAAS,EAAE;oBAC5B,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;iBACnE;YACF,CAAC,CAAC,CAAC;SACH;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,sCAAsC,CAAC,QAAgB;QACnE,OAAO,SAAS,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzE,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB,EAAE,iBAA0B;QACjE,MAAM,SAAS,GAAG,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB,CAAC;QAC1F,OAAO,gBAAgB,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,IAAI,EAAE;YAChF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CACtC,OAAO,EACP,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAC3E,CAAC;YACF,OAAO,QAAQ,CAAC,SAAS,CAAC;QAC3B,CAAC,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB;QACrC,OAAO,gBAAgB,CAAC,cAAc,CACrC,IAAI,CAAC,EAAE,CAAC,MAAM,EACd,EAAE,SAAS,EAAE,SAAS,EAAE,EACxB,KAAK,IAAI,EAAE;YACV,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACjD,OAAO,QAAQ,CAAC,SAAS,CAAC,OAAO,iCAC7B,OAAO,KACV,GAAG,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IACrD,CAAC;QACJ,CAAC,CACD,CAAC;IACH,CAAC;IAEO,uBAAuB,CAAC,OAAiB,EAAE,SAAqB;;QACvE,MAAM,GAAG,GACR,CAAA,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,OAAO,CAAC,MAAK,SAAS;YACpD,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;YAC5D,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;QACjB,OAAO,GAAG,CAAC;IACZ,CAAC;IAEO,mBAAmB,CAAC,GAAW,EAAE,UAA8B;QACtE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACrC,UAAU;aACR,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;YACnB,8FAA8F;YAC9F,IAAI,SAAS,CAAC,MAAM,EAAE;gBACrB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;aAC5B;iBAAM;gBACN,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;oBAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC7B,CAAC,CAAC,CAAC;aACH;QACF,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,GAAE,CAAC,CAAC,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,WAAW,CACxB,OAAiB,EACjB,iBAA0C;;QAE1C,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACzE,wBAAwB,CAAC,eAAe,CAAC,CAAC;QAE1C,6BAA6B;QAC7B,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,MAAM,KAAK,SAAS,EAAE;YACzB,MAAM,IAAI,KAAK,CAAC,eAAe,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC;SACtD;QAED,IAAI,iBAAiB,KAAK,SAAS,EAAE;YACpC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;YACzD,IACC,CAAA,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,EAAE,MAAK,MAAM,CAAC,EAAE;gBAClC,CAAA,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,MAAK,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAC3E;gBACD,MAAM,OAAO,GAAG,OAAO,eAAe,CAAC,GAAG,qCAAqC,iBAAiB,CAAC,GAAG,EAAE,CAAC;gBACvG,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;aACzB;SACD;QAED,MAAA,OAAO,CAAC,OAAO,oCAAf,OAAO,CAAC,OAAO,GAAK,EAAE,EAAC;QACvB,qIAAqI;QACrI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC;YACpC,MAAA,MAAM,CAAC,OAAO,mCAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACzD,MAAM,QAAQ,GACb,IAAI,CAAC,cAAc;YACnB,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,KAAK;YAC7C,iBAAiB,KAAK,SAAS,CAAC;QACjC,MAAM,kBAAkB,GAAG,MAAA,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,mCAAI,CAAC,CAAC,CAAC;QAE9E,IAAI,SAAoB,CAAC;QACzB,IAAI,QAAQ,EAAE;YACb,MAAM,GAAG,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1D,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtD,IAAI,cAAc,KAAK,SAAS,EAAE;gBACjC,SAAS,GAAG,cAAc,CAAC;aAC3B;iBAAM;gBACN,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBAChE,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;gBAC1C,SAAS,GAAG,MAAM,UAAU,CAAC;aAC7B;SACD;aAAM;YACN,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;SAClF;QAED,IAAI,SAAS,CAAC,YAAY,CAAC,kBAAkB,IAAI,kBAAkB,EAAE;YACpE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,SAAS,SAAS,CAAC,OAAkC;oBACpD,IAAI,OAAO,CAAC,cAAc,GAAG,kBAAkB,EAAE;wBAChD,OAAO,EAAE,CAAC;wBACV,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;qBAC1C;gBACF,CAAC;gBAED,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;SACH;QAED,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED,IAAY,cAAc;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,aAAa,CAC1B,OAAiB,EACjB,WAAyB,EACzB,iBAA0C;;QAE1C,OAAO,SAAS,CAAC,IAAI,CACpB;YACC,WAAW;YACX,OAAO,EAAE,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,OAAO,CAAC,mCAAI,SAAS;YAC7D,QAAQ,EAAE,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,QAAQ,CAAC;YAClD,iBAAiB;SACjB,kBAEA,YAAY,EAAE,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,SAAS,CAAC,EACvD,qBAAqB,EAAE,MAAA,OAAO,CAAC,OAAO,0CAAG,YAAY,CAAC,aAAa,CAAC,IACjE,IAAI,CAAC,QAAQ,EAEjB,CAAC;IACH,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/common-definitions\";\nimport {\n\tITelemetryLoggerExt,\n\tChildLogger,\n\tDebugLogger,\n\tIConfigProviderBase,\n\tloggerToMonitoringContext,\n\tmixinMonitoringContext,\n\tMonitoringContext,\n\tPerformanceEvent,\n\tsessionStorageConfigProvider,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tFluidObject,\n\tIFluidRouter,\n\tIRequest,\n\tIRequestHeader,\n\tIResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\tIContainer,\n\tIFluidModule,\n\tIHostLoader,\n\tILoader,\n\tILoaderOptions as ILoaderOptions1,\n\tLoaderHeader,\n\tIProvideFluidCodeDetailsComparer,\n\tIFluidCodeDetails,\n} from \"@fluidframework/container-definitions\";\nimport {\n\tIDocumentServiceFactory,\n\tIDocumentStorageService,\n\tIResolvedUrl,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { Container, IPendingContainerState } from \"./container\";\nimport { IParsedUrl, parseUrl } from \"./utils\";\nimport { pkgVersion } from \"./packageVersion\";\nimport { ProtocolHandlerBuilder } from \"./protocol\";\n\nfunction canUseCache(request: IRequest): boolean {\n\tif (request.headers === undefined) {\n\t\treturn true;\n\t}\n\n\treturn request.headers[LoaderHeader.cache] !== false;\n}\n\nfunction ensureResolvedUrlDefined(\n\tresolved: IResolvedUrl | undefined,\n): asserts resolved is IResolvedUrl {\n\tif (resolved === undefined) {\n\t\tthrow new Error(`Object is not a IResolveUrl.`);\n\t}\n}\n/**\n * @internal\n */\nexport class RelativeLoader implements ILoader {\n\tconstructor(\n\t\tprivate readonly container: Container,\n\t\tprivate readonly loader: ILoader | undefined,\n\t) {}\n\n\tpublic get IFluidRouter(): IFluidRouter {\n\t\treturn this;\n\t}\n\n\tpublic async resolve(request: IRequest): Promise<IContainer> {\n\t\tif (request.url.startsWith(\"/\")) {\n\t\t\tif (canUseCache(request)) {\n\t\t\t\treturn this.container;\n\t\t\t} else {\n\t\t\t\tensureResolvedUrlDefined(this.container.resolvedUrl);\n\t\t\t\tconst container = await this.container.clone(\n\t\t\t\t\t{\n\t\t\t\t\t\tresolvedUrl: { ...this.container.resolvedUrl },\n\t\t\t\t\t\tversion: request.headers?.[LoaderHeader.version] ?? undefined,\n\t\t\t\t\t\tloadMode: request.headers?.[LoaderHeader.loadMode],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcanReconnect: request.headers?.[LoaderHeader.reconnect],\n\t\t\t\t\t\tclientDetailsOverride: request.headers?.[LoaderHeader.clientDetails],\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn container;\n\t\t\t}\n\t\t}\n\n\t\tif (this.loader === undefined) {\n\t\t\tthrow new Error(\"Cannot resolve external containers\");\n\t\t}\n\t\treturn this.loader.resolve(request);\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\tif (request.url.startsWith(\"/\")) {\n\t\t\tconst container = await this.resolve(request);\n\t\t\treturn container.request(request);\n\t\t}\n\n\t\tif (this.loader === undefined) {\n\t\t\treturn {\n\t\t\t\tstatus: 404,\n\t\t\t\tvalue: \"Cannot request external containers\",\n\t\t\t\tmimeType: \"plain/text\",\n\t\t\t};\n\t\t}\n\t\treturn this.loader.request(request);\n\t}\n}\n\nexport interface ILoaderOptions extends ILoaderOptions1 {\n\tsummarizeProtocolTree?: boolean;\n}\n\n/**\n * @deprecated IFluidModuleWithDetails interface is moved to\n * {@link @fluidframework/container-definitions#IFluidModuleWithDetails}\n * to have all the code loading modules in one package. #8193\n * Encapsulates a module entry point with corresponding code details.\n */\nexport interface IFluidModuleWithDetails {\n\t/** Fluid code module that implements the runtime factory needed to instantiate the container runtime. */\n\tmodule: IFluidModule;\n\t/**\n\t * Code details associated with the module. Represents a document schema this module supports.\n\t * If the code loader implements the {@link @fluidframework/core-interfaces#IFluidCodeDetailsComparer} interface,\n\t * it'll be called to determine whether the module code details satisfy the new code proposal in the quorum.\n\t */\n\tdetails: IFluidCodeDetails;\n}\n\n/**\n * @deprecated ICodeDetailsLoader interface is moved to {@link @fluidframework/container-definition#ICodeDetailsLoader}\n * to have code loading modules in one package. #8193\n * Fluid code loader resolves a code module matching the document schema, i.e. code details, such as\n * a package name and package version range.\n */\nexport interface ICodeDetailsLoader extends Partial<IProvideFluidCodeDetailsComparer> {\n\t/**\n\t * Load the code module (package) that is capable to interact with the document.\n\t *\n\t * @param source - Code proposal that articulates the current schema the document is written in.\n\t * @returns - Code module entry point along with the code details associated with it.\n\t */\n\tload(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails>;\n}\n\n/**\n * Services and properties necessary for creating a loader\n */\nexport interface ILoaderProps {\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 used by various layers\n\t * to control features\n\t */\n\treadonly options?: ILoaderOptions;\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;\n\n\t/**\n\t * The logger that all telemetry should be pushed to.\n\t */\n\treadonly logger?: ITelemetryBaseLogger;\n\n\t/**\n\t * Blobs storage for detached containers.\n\t */\n\treadonly detachedBlobStorage?: IDetachedBlobStorage;\n\n\t/**\n\t * The configuration provider which may be used to control features.\n\t */\n\treadonly configProvider?: IConfigProviderBase;\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;\n}\n\n/**\n * Services and properties used by and exposed by the loader\n */\nexport interface ILoaderServices {\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 used by various layers\n\t * to control features\n\t */\n\treadonly options: ILoaderOptions;\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;\n\n\t/**\n\t * The logger downstream consumers should construct their loggers from\n\t */\n\treadonly subLogger: ITelemetryLoggerExt;\n\n\t/**\n\t * Blobs storage for detached containers.\n\t */\n\treadonly detachedBlobStorage?: IDetachedBlobStorage;\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;\n}\n\n/**\n * Subset of IDocumentStorageService which only supports createBlob() and readBlob(). This is used to support\n * blobs in detached containers.\n */\nexport type IDetachedBlobStorage = Pick<IDocumentStorageService, \"createBlob\" | \"readBlob\"> & {\n\tsize: number;\n\t/**\n\t * Return an array of all blob IDs present in storage\n\t */\n\tgetBlobIds(): string[];\n};\n\n/**\n * With an already-resolved container, we can request a component directly, without loading the container again\n * @param container - a resolved container\n * @returns component on the container\n */\nexport async function requestResolvedObjectFromContainer(\n\tcontainer: IContainer,\n\theaders?: IRequestHeader,\n): Promise<IResponse> {\n\tensureResolvedUrlDefined(container.resolvedUrl);\n\tconst parsedUrl = parseUrl(container.resolvedUrl.url);\n\n\tif (parsedUrl === undefined) {\n\t\tthrow new Error(`Invalid URL ${container.resolvedUrl.url}`);\n\t}\n\n\tconst entryPoint: FluidObject<IFluidRouter> | undefined = await container.getEntryPoint?.();\n\tconst router = entryPoint?.IFluidRouter ?? container.IFluidRouter;\n\n\treturn router.request({\n\t\turl: `${parsedUrl.path}${parsedUrl.query}`,\n\t\theaders,\n\t});\n}\n\n/**\n * Manages Fluid resource loading\n */\nexport class Loader implements IHostLoader {\n\tprivate readonly containers = new Map<string, Promise<Container>>();\n\tpublic readonly services: ILoaderServices;\n\tprivate readonly mc: MonitoringContext;\n\n\tconstructor(loaderProps: ILoaderProps) {\n\t\tconst {\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory,\n\t\t\tcodeLoader,\n\t\t\toptions,\n\t\t\tscope,\n\t\t\tlogger,\n\t\t\tdetachedBlobStorage,\n\t\t\tconfigProvider,\n\t\t\tprotocolHandlerBuilder,\n\t\t} = loaderProps;\n\n\t\tconst telemetryProps = {\n\t\t\tloaderId: uuid(),\n\t\t\tloaderVersion: pkgVersion,\n\t\t};\n\n\t\tconst subMc = mixinMonitoringContext(\n\t\t\tDebugLogger.mixinDebugLogger(\"fluid:telemetry\", logger, {\n\t\t\t\tall: telemetryProps,\n\t\t\t}),\n\t\t\tsessionStorageConfigProvider.value,\n\t\t\tconfigProvider,\n\t\t);\n\n\t\tthis.services = {\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory,\n\t\t\tcodeLoader,\n\t\t\toptions: options ?? {},\n\t\t\tscope:\n\t\t\t\toptions?.provideScopeLoader !== false ? { ...scope, ILoader: this } : { ...scope },\n\t\t\tdetachedBlobStorage,\n\t\t\tprotocolHandlerBuilder,\n\t\t\tsubLogger: subMc.logger,\n\t\t};\n\t\tthis.mc = loggerToMonitoringContext(ChildLogger.create(this.services.subLogger, \"Loader\"));\n\t}\n\n\tpublic get IFluidRouter(): IFluidRouter {\n\t\treturn this;\n\t}\n\n\tpublic async createDetachedContainer(codeDetails: IFluidCodeDetails): Promise<IContainer> {\n\t\tconst container = await Container.createDetached(this.services, codeDetails);\n\n\t\tif (this.cachingEnabled) {\n\t\t\tcontainer.once(\"attached\", () => {\n\t\t\t\tensureResolvedUrlDefined(container.resolvedUrl);\n\t\t\t\tconst parsedUrl = parseUrl(container.resolvedUrl.url);\n\t\t\t\tif (parsedUrl !== undefined) {\n\t\t\t\t\tthis.addToContainerCache(parsedUrl.id, Promise.resolve(container));\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn container;\n\t}\n\n\tpublic async rehydrateDetachedContainerFromSnapshot(snapshot: string): Promise<IContainer> {\n\t\treturn Container.rehydrateDetachedFromSnapshot(this.services, snapshot);\n\t}\n\n\tpublic async resolve(request: IRequest, pendingLocalState?: string): Promise<IContainer> {\n\t\tconst eventName = pendingLocalState === undefined ? \"Resolve\" : \"ResolveWithPendingState\";\n\t\treturn PerformanceEvent.timedExecAsync(this.mc.logger, { eventName }, async () => {\n\t\t\tconst resolved = await this.resolveCore(\n\t\t\t\trequest,\n\t\t\t\tpendingLocalState !== undefined ? JSON.parse(pendingLocalState) : undefined,\n\t\t\t);\n\t\t\treturn resolved.container;\n\t\t});\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\tthis.mc.logger,\n\t\t\t{ eventName: \"Request\" },\n\t\t\tasync () => {\n\t\t\t\tconst resolved = await this.resolveCore(request);\n\t\t\t\treturn resolved.container.request({\n\t\t\t\t\t...request,\n\t\t\t\t\turl: `${resolved.parsed.path}${resolved.parsed.query}`,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate getKeyForContainerCache(request: IRequest, parsedUrl: IParsedUrl): string {\n\t\tconst key =\n\t\t\trequest.headers?.[LoaderHeader.version] !== undefined\n\t\t\t\t? `${parsedUrl.id}@${request.headers[LoaderHeader.version]}`\n\t\t\t\t: parsedUrl.id;\n\t\treturn key;\n\t}\n\n\tprivate addToContainerCache(key: string, containerP: Promise<Container>) {\n\t\tthis.containers.set(key, containerP);\n\t\tcontainerP\n\t\t\t.then((container) => {\n\t\t\t\t// If the container is closed or becomes closed after we resolve it, remove it from the cache.\n\t\t\t\tif (container.closed) {\n\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t} else {\n\t\t\t\t\tcontainer.once(\"closed\", () => {\n\t\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {});\n\t}\n\n\tprivate async resolveCore(\n\t\trequest: IRequest,\n\t\tpendingLocalState?: IPendingContainerState,\n\t): Promise<{ container: Container; parsed: IParsedUrl }> {\n\t\tconst resolvedAsFluid = await this.services.urlResolver.resolve(request);\n\t\tensureResolvedUrlDefined(resolvedAsFluid);\n\n\t\t// Parse URL into data stores\n\t\tconst parsed = parseUrl(resolvedAsFluid.url);\n\t\tif (parsed === undefined) {\n\t\t\tthrow new Error(`Invalid URL ${resolvedAsFluid.url}`);\n\t\t}\n\n\t\tif (pendingLocalState !== undefined) {\n\t\t\tconst parsedPendingUrl = parseUrl(pendingLocalState.url);\n\t\t\tif (\n\t\t\t\tparsedPendingUrl?.id !== parsed.id ||\n\t\t\t\tparsedPendingUrl?.path.replace(/\\/$/, \"\") !== parsed.path.replace(/\\/$/, \"\")\n\t\t\t) {\n\t\t\t\tconst message = `URL ${resolvedAsFluid.url} does not match pending state URL ${pendingLocalState.url}`;\n\t\t\t\tthrow new Error(message);\n\t\t\t}\n\t\t}\n\n\t\trequest.headers ??= {};\n\t\t// If set in both query string and headers, use query string. Also write the value from the query string into the header either way.\n\t\trequest.headers[LoaderHeader.version] =\n\t\t\tparsed.version ?? request.headers[LoaderHeader.version];\n\t\tconst canCache =\n\t\t\tthis.cachingEnabled &&\n\t\t\trequest.headers[LoaderHeader.cache] !== false &&\n\t\t\tpendingLocalState === undefined;\n\t\tconst fromSequenceNumber = request.headers[LoaderHeader.sequenceNumber] ?? -1;\n\n\t\tlet container: Container;\n\t\tif (canCache) {\n\t\t\tconst key = this.getKeyForContainerCache(request, parsed);\n\t\t\tconst maybeContainer = await this.containers.get(key);\n\t\t\tif (maybeContainer !== undefined) {\n\t\t\t\tcontainer = maybeContainer;\n\t\t\t} else {\n\t\t\t\tconst containerP = this.loadContainer(request, resolvedAsFluid);\n\t\t\t\tthis.addToContainerCache(key, containerP);\n\t\t\t\tcontainer = await containerP;\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer = await this.loadContainer(request, resolvedAsFluid, pendingLocalState);\n\t\t}\n\n\t\tif (container.deltaManager.lastSequenceNumber <= fromSequenceNumber) {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tfunction opHandler(message: ISequencedDocumentMessage) {\n\t\t\t\t\tif (message.sequenceNumber > fromSequenceNumber) {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t\tcontainer.removeListener(\"op\", opHandler);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontainer.on(\"op\", opHandler);\n\t\t\t});\n\t\t}\n\n\t\treturn { container, parsed };\n\t}\n\n\tprivate get cachingEnabled() {\n\t\treturn this.services.options.cache !== false;\n\t}\n\n\tprivate async loadContainer(\n\t\trequest: IRequest,\n\t\tresolvedUrl: IResolvedUrl,\n\t\tpendingLocalState?: IPendingContainerState,\n\t): Promise<Container> {\n\t\treturn Container.load(\n\t\t\t{\n\t\t\t\tresolvedUrl,\n\t\t\t\tversion: request.headers?.[LoaderHeader.version] ?? undefined,\n\t\t\t\tloadMode: request.headers?.[LoaderHeader.loadMode],\n\t\t\t\tpendingLocalState,\n\t\t\t},\n\t\t\t{\n\t\t\t\tcanReconnect: request.headers?.[LoaderHeader.reconnect],\n\t\t\t\tclientDetailsOverride: request.headers?.[LoaderHeader.clientDetails],\n\t\t\t\t...this.services,\n\t\t\t},\n\t\t);\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/container-loader";
8
- export declare const pkgVersion = "2.0.0-internal.5.0.1";
8
+ export declare const pkgVersion = "2.0.0-internal.5.1.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/container-loader";
8
- export const pkgVersion = "2.0.0-internal.5.0.1";
8
+ export const pkgVersion = "2.0.0-internal.5.1.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,kCAAkC,CAAC;AAC1D,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-loader\";\nexport const pkgVersion = \"2.0.0-internal.5.0.1\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,kCAAkC,CAAC;AAC1D,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-loader\";\nexport const pkgVersion = \"2.0.0-internal.5.1.0\";\n"]}
package/lib/utils.d.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ISummaryTree, ISnapshotTree } from "@fluidframework/protocol-definitions";
6
+ import { DeltaStreamConnectionForbiddenError } from "@fluidframework/driver-utils";
6
7
  export interface ISnapshotTreeWithBlobContents extends ISnapshotTree {
7
8
  blobsContents: {
8
9
  [path: string]: ArrayBufferLike;
@@ -31,4 +32,5 @@ export declare function parseUrl(url: string): IParsedUrl | undefined;
31
32
  export declare function convertProtocolAndAppSummaryToSnapshotTree(protocolSummaryTree: ISummaryTree, appSummaryTree: ISummaryTree): ISnapshotTreeWithBlobContents;
32
33
  export declare const getSnapshotTreeFromSerializedContainer: (detachedContainerSnapshot: ISummaryTree) => ISnapshotTreeWithBlobContents;
33
34
  export declare function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree;
35
+ export declare function isDeltaStreamConnectionForbiddenError(error: any): error is DeltaStreamConnectionForbiddenError;
34
36
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,sCAAsC,CAAC;AAMhG,MAAM,WAAW,6BAA8B,SAAQ,aAAa;IACnE,aAAa,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;KAAE,CAAC;IACnD,KAAK,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,6BAA6B,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAW5D;AA0DD;;;;GAIG;AACH,wBAAgB,0CAA0C,CACzD,mBAAmB,EAAE,YAAY,EACjC,cAAc,EAAE,YAAY,GAC1B,6BAA6B,CAW/B;AAID,eAAO,MAAM,sCAAsC,8BACvB,YAAY,KACrC,6BAYF,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAE9E"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,sCAAsC,CAAC;AAEhG,OAAO,EACN,mCAAmC,EAEnC,MAAM,8BAA8B,CAAC;AAKtC,MAAM,WAAW,6BAA8B,SAAQ,aAAa;IACnE,aAAa,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;KAAE,CAAC;IACnD,KAAK,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,6BAA6B,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAW5D;AA0DD;;;;GAIG;AACH,wBAAgB,0CAA0C,CACzD,mBAAmB,EAAE,YAAY,EACjC,cAAc,EAAE,YAAY,GAC1B,6BAA6B,CAW/B;AAID,eAAO,MAAM,sCAAsC,8BACvB,YAAY,KACrC,6BAYF,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAE9E;AAED,wBAAgB,qCAAqC,CACpD,KAAK,EAAE,GAAG,GACR,KAAK,IAAI,mCAAmC,CAM9C"}
package/lib/utils.js CHANGED
@@ -7,7 +7,8 @@ import { v4 as uuid } from "uuid";
7
7
  import { assert, stringToBuffer, Uint8ArrayToArrayBuffer, unreachableCase, } from "@fluidframework/common-utils";
8
8
  import { SummaryType } from "@fluidframework/protocol-definitions";
9
9
  import { LoggingError } from "@fluidframework/telemetry-utils";
10
- import { isCombinedAppAndProtocolSummary } from "@fluidframework/driver-utils";
10
+ import { isCombinedAppAndProtocolSummary, } from "@fluidframework/driver-utils";
11
+ import { DriverErrorType } from "@fluidframework/driver-definitions";
11
12
  export function parseUrl(url) {
12
13
  var _a;
13
14
  const parsed = parse(url, true);
@@ -97,4 +98,9 @@ export const getSnapshotTreeFromSerializedContainer = (detachedContainerSnapshot
97
98
  export function getProtocolSnapshotTree(snapshot) {
98
99
  return ".protocol" in snapshot.trees ? snapshot.trees[".protocol"] : snapshot;
99
100
  }
101
+ export function isDeltaStreamConnectionForbiddenError(error) {
102
+ return (typeof error === "object" &&
103
+ error !== null &&
104
+ (error === null || error === void 0 ? void 0 : error.errorType) === DriverErrorType.deltaStreamConnectionForbidden);
105
+ }
100
106
  //# sourceMappingURL=utils.js.map
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 { parse } from \"url\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n\tassert,\n\tstringToBuffer,\n\tUint8ArrayToArrayBuffer,\n\tunreachableCase,\n} from \"@fluidframework/common-utils\";\nimport { ISummaryTree, ISnapshotTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { LoggingError } from \"@fluidframework/telemetry-utils\";\nimport { isCombinedAppAndProtocolSummary } from \"@fluidframework/driver-utils\";\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\nexport interface IParsedUrl {\n\tid: string;\n\tpath: string;\n\tquery: string;\n\t/**\n\t * Null means do not use snapshots, undefined means load latest snapshot\n\t * otherwise it's version ID passed to IDocumentStorageService.getVersions() to figure out what snapshot to use.\n\t * If needed, can add undefined which is treated by Container.load() as load latest snapshot.\n\t */\n\tversion: string | null | undefined;\n}\n\nexport function parseUrl(url: string): IParsedUrl | undefined {\n\tconst parsed = parse(url, true);\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? { id: match[1], path: match[2], query, version: parsed.query.version as string }\n\t\t: undefined;\n}\n\n/**\n * Converts summary tree (for upload) to snapshot tree (for download).\n * Summary tree blobs contain contents, but snapshot tree blobs normally\n * contain IDs pointing to storage. This will create 2 blob entries in the\n * snapshot tree for each blob in the summary tree. One will be the regular\n * path pointing to a uniquely generated ID. Then there will be another\n * entry with the path as that uniquely generated ID, and value as the\n * blob contents as a base-64 string.\n * @param summary - summary to convert\n */\nfunction convertSummaryToSnapshotWithEmbeddedBlobContents(\n\tsummary: ISummaryTree,\n): ISnapshotTreeWithBlobContents {\n\tconst treeNode: ISnapshotTreeWithBlobContents = {\n\t\tblobs: {},\n\t\tblobsContents: {},\n\t\ttrees: {},\n\t\tid: uuid(),\n\t\tunreferenced: summary.unreferenced,\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\ttreeNode.trees[key] =\n\t\t\t\t\tconvertSummaryToSnapshotWithEmbeddedBlobContents(summaryObject);\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\tcase SummaryType.Blob: {\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tconst contentBuffer =\n\t\t\t\t\ttypeof summaryObject.content === \"string\"\n\t\t\t\t\t\t? stringToBuffer(summaryObject.content, \"utf8\")\n\t\t\t\t\t\t: Uint8ArrayToArrayBuffer(summaryObject.content);\n\t\t\t\ttreeNode.blobsContents[blobId] = contentBuffer;\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\tbreak;\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn treeNode;\n}\n\n/**\n * Combine and convert protocol and app summary tree to format which is readable by container while rehydrating.\n * @param protocolSummaryTree - Protocol Summary Tree\n * @param appSummaryTree - App Summary Tree\n */\nexport function convertProtocolAndAppSummaryToSnapshotTree(\n\tprotocolSummaryTree: ISummaryTree,\n\tappSummaryTree: ISummaryTree,\n): ISnapshotTreeWithBlobContents {\n\t// Shallow copy is fine, since we are doing a deep clone below.\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 =\n\t\tconvertSummaryToSnapshotWithEmbeddedBlobContents(combinedSummary);\n\treturn snapshotTreeWithBlobContents;\n}\n\n// This function converts the snapshot taken in detached container(by serialize api) to snapshotTree with which\n// a detached container can be rehydrated.\nexport const getSnapshotTreeFromSerializedContainer = (\n\tdetachedContainerSnapshot: ISummaryTree,\n): ISnapshotTreeWithBlobContents => {\n\tassert(\n\t\tisCombinedAppAndProtocolSummary(detachedContainerSnapshot),\n\t\t0x1e0 /* \"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 = convertProtocolAndAppSummaryToSnapshotTree(\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"]}
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 { parse } from \"url\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n\tassert,\n\tstringToBuffer,\n\tUint8ArrayToArrayBuffer,\n\tunreachableCase,\n} from \"@fluidframework/common-utils\";\nimport { ISummaryTree, ISnapshotTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { LoggingError } from \"@fluidframework/telemetry-utils\";\nimport {\n\tDeltaStreamConnectionForbiddenError,\n\tisCombinedAppAndProtocolSummary,\n} from \"@fluidframework/driver-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\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\nexport interface IParsedUrl {\n\tid: string;\n\tpath: string;\n\tquery: string;\n\t/**\n\t * Null means do not use snapshots, undefined means load latest snapshot\n\t * otherwise it's version ID passed to IDocumentStorageService.getVersions() to figure out what snapshot to use.\n\t * If needed, can add undefined which is treated by Container.load() as load latest snapshot.\n\t */\n\tversion: string | null | undefined;\n}\n\nexport function parseUrl(url: string): IParsedUrl | undefined {\n\tconst parsed = parse(url, true);\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? { id: match[1], path: match[2], query, version: parsed.query.version as string }\n\t\t: undefined;\n}\n\n/**\n * Converts summary tree (for upload) to snapshot tree (for download).\n * Summary tree blobs contain contents, but snapshot tree blobs normally\n * contain IDs pointing to storage. This will create 2 blob entries in the\n * snapshot tree for each blob in the summary tree. One will be the regular\n * path pointing to a uniquely generated ID. Then there will be another\n * entry with the path as that uniquely generated ID, and value as the\n * blob contents as a base-64 string.\n * @param summary - summary to convert\n */\nfunction convertSummaryToSnapshotWithEmbeddedBlobContents(\n\tsummary: ISummaryTree,\n): ISnapshotTreeWithBlobContents {\n\tconst treeNode: ISnapshotTreeWithBlobContents = {\n\t\tblobs: {},\n\t\tblobsContents: {},\n\t\ttrees: {},\n\t\tid: uuid(),\n\t\tunreferenced: summary.unreferenced,\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\ttreeNode.trees[key] =\n\t\t\t\t\tconvertSummaryToSnapshotWithEmbeddedBlobContents(summaryObject);\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\tcase SummaryType.Blob: {\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tconst contentBuffer =\n\t\t\t\t\ttypeof summaryObject.content === \"string\"\n\t\t\t\t\t\t? stringToBuffer(summaryObject.content, \"utf8\")\n\t\t\t\t\t\t: Uint8ArrayToArrayBuffer(summaryObject.content);\n\t\t\t\ttreeNode.blobsContents[blobId] = contentBuffer;\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\tbreak;\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn treeNode;\n}\n\n/**\n * Combine and convert protocol and app summary tree to format which is readable by container while rehydrating.\n * @param protocolSummaryTree - Protocol Summary Tree\n * @param appSummaryTree - App Summary Tree\n */\nexport function convertProtocolAndAppSummaryToSnapshotTree(\n\tprotocolSummaryTree: ISummaryTree,\n\tappSummaryTree: ISummaryTree,\n): ISnapshotTreeWithBlobContents {\n\t// Shallow copy is fine, since we are doing a deep clone below.\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 =\n\t\tconvertSummaryToSnapshotWithEmbeddedBlobContents(combinedSummary);\n\treturn snapshotTreeWithBlobContents;\n}\n\n// This function converts the snapshot taken in detached container(by serialize api) to snapshotTree with which\n// a detached container can be rehydrated.\nexport const getSnapshotTreeFromSerializedContainer = (\n\tdetachedContainerSnapshot: ISummaryTree,\n): ISnapshotTreeWithBlobContents => {\n\tassert(\n\t\tisCombinedAppAndProtocolSummary(detachedContainerSnapshot),\n\t\t0x1e0 /* \"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 = convertProtocolAndAppSummaryToSnapshotTree(\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 function isDeltaStreamConnectionForbiddenError(\n\terror: any,\n): error is DeltaStreamConnectionForbiddenError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\terror?.errorType === DriverErrorType.deltaStreamConnectionForbidden\n\t);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-loader",
3
- "version": "2.0.0-internal.5.0.1",
3
+ "version": "2.0.0-internal.5.1.0",
4
4
  "description": "Fluid container loader",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -37,14 +37,14 @@
37
37
  "dependencies": {
38
38
  "@fluidframework/common-definitions": "^0.20.1",
39
39
  "@fluidframework/common-utils": "^1.1.1",
40
- "@fluidframework/container-definitions": ">=2.0.0-internal.5.0.1 <2.0.0-internal.5.1.0",
41
- "@fluidframework/container-utils": ">=2.0.0-internal.5.0.1 <2.0.0-internal.5.1.0",
42
- "@fluidframework/core-interfaces": ">=2.0.0-internal.5.0.1 <2.0.0-internal.5.1.0",
43
- "@fluidframework/driver-definitions": ">=2.0.0-internal.5.0.1 <2.0.0-internal.5.1.0",
44
- "@fluidframework/driver-utils": ">=2.0.0-internal.5.0.1 <2.0.0-internal.5.1.0",
40
+ "@fluidframework/container-definitions": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
41
+ "@fluidframework/container-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
42
+ "@fluidframework/core-interfaces": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
43
+ "@fluidframework/driver-definitions": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
44
+ "@fluidframework/driver-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
45
45
  "@fluidframework/protocol-base": "^0.1039.1000",
46
46
  "@fluidframework/protocol-definitions": "^1.1.0",
47
- "@fluidframework/telemetry-utils": ">=2.0.0-internal.5.0.1 <2.0.0-internal.5.1.0",
47
+ "@fluidframework/telemetry-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
48
48
  "abort-controller": "^3.0.0",
49
49
  "double-ended-queue": "^2.1.0-0",
50
50
  "events": "^3.1.0",
@@ -53,13 +53,13 @@
53
53
  "uuid": "^8.3.1"
54
54
  },
55
55
  "devDependencies": {
56
- "@fluid-internal/test-loader-utils": ">=2.0.0-internal.5.0.1 <2.0.0-internal.5.1.0",
57
- "@fluid-tools/build-cli": "^0.18.2",
58
- "@fluidframework/build-common": "^1.1.0",
59
- "@fluidframework/build-tools": "^0.18.2",
60
- "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.4.1.0",
56
+ "@fluid-internal/test-loader-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
57
+ "@fluid-tools/build-cli": "^0.19.0",
58
+ "@fluidframework/build-common": "^1.2.0",
59
+ "@fluidframework/build-tools": "^0.19.0",
60
+ "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.5.0.0",
61
61
  "@fluidframework/eslint-config-fluid": "^2.0.0",
62
- "@fluidframework/mocha-test-setup": ">=2.0.0-internal.5.0.1 <2.0.0-internal.5.1.0",
62
+ "@fluidframework/mocha-test-setup": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
63
63
  "@microsoft/api-extractor": "^7.34.4",
64
64
  "@types/double-ended-queue": "^2.1.0",
65
65
  "@types/events": "^3.0.0",
@@ -82,33 +82,14 @@
82
82
  "typescript": "~4.5.5"
83
83
  },
84
84
  "typeValidation": {
85
- "broken": {
86
- "RemovedInterfaceDeclaration_IContainerConfig": {
87
- "forwardCompat": false,
88
- "backCompat": false
89
- },
90
- "RemovedInterfaceDeclaration_IContainerLoadOptions": {
91
- "forwardCompat": false,
92
- "backCompat": false
93
- },
94
- "RemovedInterfaceDeclaration_IPendingContainerState": {
95
- "forwardCompat": false,
96
- "backCompat": false
97
- },
98
- "RemovedInterfaceDeclaration_ISerializableBlobContents": {
99
- "forwardCompat": false,
100
- "backCompat": false
101
- }
102
- }
85
+ "broken": {}
103
86
  },
104
87
  "scripts": {
105
- "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
106
- "build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
107
- "build:compile": "concurrently npm:build:commonjs npm:build:esnext",
88
+ "build": "fluid-build . --task build",
89
+ "build:commonjs": "fluid-build . --task commonjs",
90
+ "build:compile": "fluid-build . --task compile",
108
91
  "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
109
92
  "build:esnext": "tsc --project ./tsconfig.esnext.json",
110
- "build:full": "npm run build",
111
- "build:full:compile": "npm run build:compile",
112
93
  "build:genver": "gen-version",
113
94
  "build:test": "tsc --project ./src/test/tsconfig.json",
114
95
  "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
@@ -14,7 +14,6 @@ import {
14
14
  } from "@fluidframework/container-definitions";
15
15
  import { GenericError, UsageError } from "@fluidframework/container-utils";
16
16
  import {
17
- DriverErrorType,
18
17
  IAnyDriverError,
19
18
  IDocumentService,
20
19
  IDocumentDeltaConnection,
@@ -52,6 +51,7 @@ import {
52
51
  import { ReconnectMode, IConnectionManager, IConnectionManagerFactoryArgs } from "./contracts";
53
52
  import { DeltaQueue } from "./deltaQueue";
54
53
  import { SignalType } from "./protocol";
54
+ import { isDeltaStreamConnectionForbiddenError } from "./utils";
55
55
 
56
56
  const MaxReconnectDelayInMs = 8000;
57
57
  const InitialReconnectDelayInMs = 1000;
@@ -106,6 +106,9 @@ class NoDeltaStream
106
106
  blockSize: 0,
107
107
  };
108
108
  checkpointSequenceNumber?: number | undefined = undefined;
109
+ constructor(public readonly storageOnlyReason?: string) {
110
+ super();
111
+ }
109
112
  submit(messages: IDocumentMessage[]): void {
110
113
  this.emit(
111
114
  "nack",
@@ -134,6 +137,10 @@ class NoDeltaStream
134
137
  }
135
138
  }
136
139
 
140
+ function isNoDeltaStreamConnection(connection: any): connection is NoDeltaStream {
141
+ return connection instanceof NoDeltaStream;
142
+ }
143
+
137
144
  const waitForOnline = async (): Promise<void> => {
138
145
  // Only wait if we have a strong signal that we're offline - otherwise assume we're online.
139
146
  if (globalThis.navigator?.onLine === false && globalThis.addEventListener !== undefined) {
@@ -309,14 +316,19 @@ export class ConnectionManager implements IConnectionManager {
309
316
  }
310
317
 
311
318
  public get readOnlyInfo(): ReadOnlyInfo {
312
- const storageOnly =
313
- this.connection !== undefined && this.connection instanceof NoDeltaStream;
319
+ let storageOnly: boolean = false;
320
+ let storageOnlyReason: string | undefined;
321
+ if (isNoDeltaStreamConnection(this.connection)) {
322
+ storageOnly = true;
323
+ storageOnlyReason = this.connection.storageOnlyReason;
324
+ }
314
325
  if (storageOnly || this._forceReadonly || this._readonlyPermissions === true) {
315
326
  return {
316
327
  readonly: true,
317
328
  forced: this._forceReadonly,
318
329
  permissions: this._readonlyPermissions,
319
330
  storageOnly,
331
+ storageOnlyReason,
320
332
  };
321
333
  }
322
334
 
@@ -373,8 +385,6 @@ export class ConnectionManager implements IConnectionManager {
373
385
  }
374
386
  this._disposed = true;
375
387
 
376
- this.pendingConnection = undefined;
377
-
378
388
  // Ensure that things like triggerConnect() will short circuit
379
389
  this._reconnectMode = ReconnectMode.Never;
380
390
 
@@ -489,7 +499,7 @@ export class ConnectionManager implements IConnectionManager {
489
499
  let pendingConnectionMode;
490
500
  if (this.pendingConnection !== undefined) {
491
501
  pendingConnectionMode = this.pendingConnection.connectionMode;
492
- this.cancelConnection(); // Throw out in-progress connection attempt in favor of new attempt
502
+ this.cancelConnection(reason); // Throw out in-progress connection attempt in favor of new attempt
493
503
  assert(
494
504
  this.pendingConnection === undefined,
495
505
  0x344 /* this.pendingConnection should be undefined */,
@@ -533,6 +543,7 @@ export class ConnectionManager implements IConnectionManager {
533
543
  connectionMode: requestedMode,
534
544
  };
535
545
 
546
+ this.props.establishConnectionHandler(reason);
536
547
  // This loop will keep trying to connect until successful, with a delay between each iteration.
537
548
  while (connection === undefined) {
538
549
  if (this._disposed) {
@@ -562,12 +573,8 @@ export class ConnectionManager implements IConnectionManager {
562
573
  connection = undefined;
563
574
  }
564
575
  } catch (origError: any) {
565
- if (
566
- typeof origError === "object" &&
567
- origError !== null &&
568
- origError?.errorType === DriverErrorType.deltaStreamConnectionForbidden
569
- ) {
570
- connection = new NoDeltaStream();
576
+ if (isDeltaStreamConnectionForbiddenError(origError)) {
577
+ connection = new NoDeltaStream(origError.storageOnlyReason);
571
578
  requestedMode = "read";
572
579
  break;
573
580
  }
@@ -593,6 +600,7 @@ export class ConnectionManager implements IConnectionManager {
593
600
 
594
601
  lastError = origError;
595
602
 
603
+ const waitStartTime = performance.now();
596
604
  const retryDelayFromError = getRetryDelayFromError(origError);
597
605
  if (retryDelayFromError !== undefined) {
598
606
  // If the error told us to wait, then we wait.
@@ -613,6 +621,14 @@ export class ConnectionManager implements IConnectionManager {
613
621
  // NOTE: This isn't strictly true for drivers that don't require network (e.g. local driver). Really this logic
614
622
  // should probably live in the driver.
615
623
  await waitForOnline();
624
+ this.logger.sendPerformanceEvent({
625
+ eventName: "WaitBetweenConnectionAttempts",
626
+ duration: performance.now() - waitStartTime,
627
+ details: JSON.stringify({
628
+ retryDelayFromError,
629
+ delayMs,
630
+ }),
631
+ });
616
632
  }
617
633
  }
618
634
 
@@ -674,7 +690,7 @@ export class ConnectionManager implements IConnectionManager {
674
690
 
675
691
  if (this.connection === undefined) {
676
692
  if (this.pendingConnection !== undefined) {
677
- this.cancelConnection();
693
+ this.cancelConnection(reason);
678
694
  return true;
679
695
  }
680
696
  return false;
@@ -712,7 +728,7 @@ export class ConnectionManager implements IConnectionManager {
712
728
  /**
713
729
  * Cancel in-progress connection attempt.
714
730
  */
715
- private cancelConnection() {
731
+ private cancelConnection(reason: string) {
716
732
  assert(
717
733
  this.pendingConnection !== undefined,
718
734
  0x345 /* this.pendingConnection is undefined when trying to cancel */,
@@ -720,6 +736,7 @@ export class ConnectionManager implements IConnectionManager {
720
736
  this.pendingConnection.abort();
721
737
  this.pendingConnection = undefined;
722
738
  this.logger.sendTelemetryEvent({ eventName: "ConnectionCancelReceived" });
739
+ this.props.cancelConnectionHandler(`Cancel Pending Connection due to ${reason}`);
723
740
  }
724
741
 
725
742
  /**
@@ -941,7 +958,7 @@ export class ConnectionManager implements IConnectionManager {
941
958
 
942
959
  this.triggerConnect(
943
960
  error !== undefined
944
- ? "Reconnect on Error"
961
+ ? "Reconnecting due to Error"
945
962
  : `Reconnecting due to: ${disconnectMessage}`,
946
963
  requestedMode,
947
964
  );
@@ -960,6 +977,7 @@ export class ConnectionManager implements IConnectionManager {
960
977
  forcedReadonly: this.readOnlyInfo.forced,
961
978
  readonlyPermissions: this.readOnlyInfo.permissions,
962
979
  storageOnly: this.readOnlyInfo.storageOnly,
980
+ storageOnlyReason: this.readOnlyInfo.storageOnlyReason,
963
981
  });
964
982
  this.props.closeHandler(error);
965
983
  return undefined;
@@ -59,6 +59,13 @@ export interface IConnectionStateHandler {
59
59
  initProtocol(protocol: IProtocolHandler): void;
60
60
  receivedConnectEvent(details: IConnectionDetailsInternal): void;
61
61
  receivedDisconnectEvent(reason: string, error?: IAnyDriverError): void;
62
+ establishingConnection(reason: string): void;
63
+ /**
64
+ * Switches state to disconnected when we are still establishing connection during container.load(),
65
+ * container connect() or reconnect and the container gets closed or disposed or disconnect happens.
66
+ * @param reason - reason for cancelling the connection.
67
+ */
68
+ cancelEstablishingConnection(reason: string): void;
62
69
  }
63
70
 
64
71
  export function createConnectionStateHandler(
@@ -144,6 +151,14 @@ class ConnectionStateHandlerPassThrough
144
151
  return this.pimpl.receivedDisconnectEvent(reason, error);
145
152
  }
146
153
 
154
+ public establishingConnection(reason: string) {
155
+ return this.pimpl.establishingConnection(reason);
156
+ }
157
+
158
+ public cancelEstablishingConnection(reason: string) {
159
+ return this.pimpl.cancelEstablishingConnection(reason);
160
+ }
161
+
147
162
  public receivedConnectEvent(details: IConnectionDetailsInternal) {
148
163
  return this.pimpl.receivedConnectEvent(details);
149
164
  }
@@ -230,9 +245,17 @@ class ConnectionStateCatchup extends ConnectionStateHandlerPassThrough {
230
245
  this.catchUpMonitor?.dispose();
231
246
  this.catchUpMonitor = undefined;
232
247
  break;
233
- case ConnectionState.CatchingUp:
248
+ // ConnectionState.EstablishingConnection state would be set when we start establishing connection
249
+ // during container.connect() or reconnect because of an error.
250
+ case ConnectionState.EstablishingConnection:
234
251
  assert(
235
252
  this._connectionState === ConnectionState.Disconnected,
253
+ 0x6d2 /* connectivity transition to establishing connection */,
254
+ );
255
+ break;
256
+ case ConnectionState.CatchingUp:
257
+ assert(
258
+ this._connectionState === ConnectionState.EstablishingConnection,
236
259
  0x3e3 /* connectivity transitions */,
237
260
  );
238
261
  break;
@@ -471,6 +494,27 @@ class ConnectionStateHandler implements IConnectionStateHandler {
471
494
  this.setConnectionState(ConnectionState.Disconnected, reason, error);
472
495
  }
473
496
 
497
+ public cancelEstablishingConnection(reason: string) {
498
+ assert(
499
+ this._connectionState === ConnectionState.EstablishingConnection,
500
+ 0x6d3 /* Connection state should be EstablishingConnection */,
501
+ );
502
+ assert(this.connection === undefined, 0x6d4 /* No connetion should be present */);
503
+ const oldState = this._connectionState;
504
+ this._connectionState = ConnectionState.Disconnected;
505
+ this.handler.connectionStateChanged(ConnectionState.Disconnected, oldState, reason);
506
+ }
507
+
508
+ public establishingConnection(reason: string) {
509
+ const oldState = this._connectionState;
510
+ this._connectionState = ConnectionState.EstablishingConnection;
511
+ this.handler.connectionStateChanged(
512
+ ConnectionState.EstablishingConnection,
513
+ oldState,
514
+ `Establishing Connection due to ${reason}`,
515
+ );
516
+ }
517
+
474
518
  private shouldWaitForJoinSignal() {
475
519
  assert(
476
520
  this.connection !== undefined,