@fluidframework/container-loader 0.54.2 → 0.56.0-49831

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 (77) hide show
  1. package/.eslintrc.js +1 -1
  2. package/dist/connectionStateHandler.d.ts +1 -0
  3. package/dist/connectionStateHandler.d.ts.map +1 -1
  4. package/dist/connectionStateHandler.js +11 -2
  5. package/dist/connectionStateHandler.js.map +1 -1
  6. package/dist/container.d.ts +6 -12
  7. package/dist/container.d.ts.map +1 -1
  8. package/dist/container.js +50 -58
  9. package/dist/container.js.map +1 -1
  10. package/dist/containerContext.d.ts +11 -3
  11. package/dist/containerContext.d.ts.map +1 -1
  12. package/dist/containerContext.js +12 -6
  13. package/dist/containerContext.js.map +1 -1
  14. package/dist/containerStorageAdapter.d.ts +1 -1
  15. package/dist/containerStorageAdapter.d.ts.map +1 -1
  16. package/dist/containerStorageAdapter.js.map +1 -1
  17. package/dist/deltaManager.d.ts +0 -11
  18. package/dist/deltaManager.d.ts.map +1 -1
  19. package/dist/deltaManager.js +0 -13
  20. package/dist/deltaManager.js.map +1 -1
  21. package/dist/deltaManagerProxy.d.ts +0 -1
  22. package/dist/deltaManagerProxy.d.ts.map +1 -1
  23. package/dist/deltaManagerProxy.js +0 -3
  24. package/dist/deltaManagerProxy.js.map +1 -1
  25. package/dist/loader.d.ts +3 -3
  26. package/dist/loader.d.ts.map +1 -1
  27. package/dist/loader.js.map +1 -1
  28. package/dist/packageVersion.d.ts +1 -1
  29. package/dist/packageVersion.d.ts.map +1 -1
  30. package/dist/packageVersion.js +1 -1
  31. package/dist/packageVersion.js.map +1 -1
  32. package/dist/retriableDocumentStorageService.d.ts +1 -1
  33. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  34. package/dist/retriableDocumentStorageService.js.map +1 -1
  35. package/lib/connectionStateHandler.d.ts +1 -0
  36. package/lib/connectionStateHandler.d.ts.map +1 -1
  37. package/lib/connectionStateHandler.js +11 -2
  38. package/lib/connectionStateHandler.js.map +1 -1
  39. package/lib/container.d.ts +6 -12
  40. package/lib/container.d.ts.map +1 -1
  41. package/lib/container.js +52 -60
  42. package/lib/container.js.map +1 -1
  43. package/lib/containerContext.d.ts +11 -3
  44. package/lib/containerContext.d.ts.map +1 -1
  45. package/lib/containerContext.js +12 -6
  46. package/lib/containerContext.js.map +1 -1
  47. package/lib/containerStorageAdapter.d.ts +1 -1
  48. package/lib/containerStorageAdapter.d.ts.map +1 -1
  49. package/lib/containerStorageAdapter.js.map +1 -1
  50. package/lib/deltaManager.d.ts +0 -11
  51. package/lib/deltaManager.d.ts.map +1 -1
  52. package/lib/deltaManager.js +0 -13
  53. package/lib/deltaManager.js.map +1 -1
  54. package/lib/deltaManagerProxy.d.ts +0 -1
  55. package/lib/deltaManagerProxy.d.ts.map +1 -1
  56. package/lib/deltaManagerProxy.js +0 -3
  57. package/lib/deltaManagerProxy.js.map +1 -1
  58. package/lib/loader.d.ts +3 -3
  59. package/lib/loader.d.ts.map +1 -1
  60. package/lib/loader.js.map +1 -1
  61. package/lib/packageVersion.d.ts +1 -1
  62. package/lib/packageVersion.d.ts.map +1 -1
  63. package/lib/packageVersion.js +1 -1
  64. package/lib/packageVersion.js.map +1 -1
  65. package/lib/retriableDocumentStorageService.d.ts +1 -1
  66. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  67. package/lib/retriableDocumentStorageService.js.map +1 -1
  68. package/package.json +19 -18
  69. package/src/connectionStateHandler.ts +13 -3
  70. package/src/container.ts +71 -69
  71. package/src/containerContext.ts +18 -9
  72. package/src/containerStorageAdapter.ts +1 -1
  73. package/src/deltaManager.ts +0 -14
  74. package/src/deltaManagerProxy.ts +0 -4
  75. package/src/loader.ts +3 -3
  76. package/src/packageVersion.ts +1 -1
  77. package/src/retriableDocumentStorageService.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"retriableDocumentStorageService.d.ts","sourceRoot":"","sources":["../src/retriableDocumentStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACH,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EAClB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,KAAK,EACL,QAAQ,EACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGnF,qBAAa,+BAAgC,YAAW,uBAAuB,EAAE,WAAW;IAGpF,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAH3B,OAAO,CAAC,SAAS,CAAS;gBAEL,sBAAsB,EAAE,uBAAuB,EAC/C,MAAM,EAAE,gBAAgB;IAI7C,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAEjE;IACD,IAAW,QAAQ,YAA6B;IACzC,OAAO;IAId,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAOlE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAO9C,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOlE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOtF,wBAAwB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB1F,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAO9D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,OAAO,CAAC,oBAAoB;YAOd,YAAY;CAU7B"}
1
+ {"version":3,"file":"retriableDocumentStorageService.d.ts","sourceRoot":"","sources":["../src/retriableDocumentStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACH,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EAClB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,KAAK,EACL,QAAQ,EACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGnF,qBAAa,+BAAgC,YAAW,uBAAuB,EAAE,WAAW;IAGpF,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAH3B,OAAO,CAAC,SAAS,CAAS;gBAEL,sBAAsB,EAAE,uBAAuB,EAC/C,MAAM,EAAE,gBAAgB;IAI7C,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAEjE;IACD,IAAW,QAAQ,YAA6B;IACzC,OAAO;IAId,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAOlE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAO9C,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOzE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOtF,wBAAwB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB1F,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAO9D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,OAAO,CAAC,oBAAoB;YAOd,YAAY;CAU7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"retriableDocumentStorageService.js","sourceRoot":"","sources":["../src/retriableDocumentStorageService.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 { assert } from \"@fluidframework/common-utils\";\nimport { GenericError } from \"@fluidframework/container-utils\";\nimport {\n IDocumentStorageService,\n IDocumentStorageServicePolicies,\n ISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport {\n ICreateBlobResponse,\n ISnapshotTree,\n ISummaryHandle,\n ISummaryTree,\n ITree,\n IVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { runWithRetry } from \"@fluidframework/driver-utils\";\n\nexport class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {\n private _disposed = false;\n constructor(\n private readonly internalStorageService: IDocumentStorageService,\n private readonly logger: ITelemetryLogger,\n ) {\n }\n\n public get policies(): IDocumentStorageServicePolicies | undefined {\n return this.internalStorageService.policies;\n }\n public get disposed() { return this._disposed; }\n public dispose() {\n this._disposed = true;\n }\n\n public get repositoryUrl(): string {\n return this.internalStorageService.repositoryUrl;\n }\n\n public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n return this.runWithRetry(\n async () => this.internalStorageService.getSnapshotTree(version),\n \"storage_getSnapshotTree\",\n );\n }\n\n public async readBlob(id: string): Promise<ArrayBufferLike> {\n return this.runWithRetry(\n async () => this.internalStorageService.readBlob(id),\n \"storage_readBlob\",\n );\n }\n\n public async getVersions(versionId: string, count: number): Promise<IVersion[]> {\n return this.runWithRetry(\n async () => this.internalStorageService.getVersions(versionId, count),\n \"storage_getVersions\",\n );\n }\n\n public async write(tree: ITree, parents: string[], message: string, ref: string): Promise<IVersion> {\n return this.runWithRetry(\n async () => this.internalStorageService.write(tree, parents, message, ref),\n \"storage_write\",\n );\n }\n\n public async uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string> {\n // Not using retry loop here. Couple reasons:\n // 1. If client lost connectivity, then retry loop will result in uploading stale summary\n // by stale summarizer after connectivity comes back. It will cause failures for this client and for\n // real (new) summarizer. This problem in particular should be solved in future by supplying abort handle\n // on all APIs and caller (ContainerRuntime.submitSummary) aborting call on loss of connectivity\n // 2. Similar, if we get 429 with retryAfter = 10 minutes, it's likely not the right call to retry summary\n // upload in 10 minutes - it's better to keep processing ops and retry later. Though caller needs to take\n // retryAfter into account!\n // But retry loop is required for creation flow (Container.attach)\n assert((context.referenceSequenceNumber === 0) === (context.ackHandle === undefined),\n 0x251 /* \"creation summary has to have seq=0 && handle === undefined\" */);\n if (context.referenceSequenceNumber !== 0) {\n return this.internalStorageService.uploadSummaryWithContext(summary, context);\n }\n\n // Creation flow with attachment blobs - need to do retries!\n return this.runWithRetry(\n async () => this.internalStorageService.uploadSummaryWithContext(summary, context),\n \"storage_uploadSummaryWithContext\",\n );\n }\n\n public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n return this.runWithRetry(\n async () => this.internalStorageService.downloadSummary(handle),\n \"storage_downloadSummary\",\n );\n }\n\n public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n return this.runWithRetry(\n async () => this.internalStorageService.createBlob(file),\n \"storage_createBlob\",\n );\n }\n\n private checkStorageDisposed() {\n if (this._disposed) {\n throw new GenericError(\"storageServiceDisposedCannotRetry\", { canRetry: false });\n }\n return undefined;\n }\n\n private async runWithRetry<T>(api: () => Promise<T>, callName: string): Promise<T> {\n return runWithRetry(\n api,\n callName,\n this.logger,\n {\n retry: () => this.checkStorageDisposed(),\n },\n );\n }\n}\n"]}
1
+ {"version":3,"file":"retriableDocumentStorageService.js","sourceRoot":"","sources":["../src/retriableDocumentStorageService.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 { assert } from \"@fluidframework/common-utils\";\nimport { GenericError } from \"@fluidframework/container-utils\";\nimport {\n IDocumentStorageService,\n IDocumentStorageServicePolicies,\n ISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport {\n ICreateBlobResponse,\n ISnapshotTree,\n ISummaryHandle,\n ISummaryTree,\n ITree,\n IVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { runWithRetry } from \"@fluidframework/driver-utils\";\n\nexport class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {\n private _disposed = false;\n constructor(\n private readonly internalStorageService: IDocumentStorageService,\n private readonly logger: ITelemetryLogger,\n ) {\n }\n\n public get policies(): IDocumentStorageServicePolicies | undefined {\n return this.internalStorageService.policies;\n }\n public get disposed() { return this._disposed; }\n public dispose() {\n this._disposed = true;\n }\n\n public get repositoryUrl(): string {\n return this.internalStorageService.repositoryUrl;\n }\n\n public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n return this.runWithRetry(\n async () => this.internalStorageService.getSnapshotTree(version),\n \"storage_getSnapshotTree\",\n );\n }\n\n public async readBlob(id: string): Promise<ArrayBufferLike> {\n return this.runWithRetry(\n async () => this.internalStorageService.readBlob(id),\n \"storage_readBlob\",\n );\n }\n\n public async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n return this.runWithRetry(\n async () => this.internalStorageService.getVersions(versionId, count),\n \"storage_getVersions\",\n );\n }\n\n public async write(tree: ITree, parents: string[], message: string, ref: string): Promise<IVersion> {\n return this.runWithRetry(\n async () => this.internalStorageService.write(tree, parents, message, ref),\n \"storage_write\",\n );\n }\n\n public async uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string> {\n // Not using retry loop here. Couple reasons:\n // 1. If client lost connectivity, then retry loop will result in uploading stale summary\n // by stale summarizer after connectivity comes back. It will cause failures for this client and for\n // real (new) summarizer. This problem in particular should be solved in future by supplying abort handle\n // on all APIs and caller (ContainerRuntime.submitSummary) aborting call on loss of connectivity\n // 2. Similar, if we get 429 with retryAfter = 10 minutes, it's likely not the right call to retry summary\n // upload in 10 minutes - it's better to keep processing ops and retry later. Though caller needs to take\n // retryAfter into account!\n // But retry loop is required for creation flow (Container.attach)\n assert((context.referenceSequenceNumber === 0) === (context.ackHandle === undefined),\n 0x251 /* \"creation summary has to have seq=0 && handle === undefined\" */);\n if (context.referenceSequenceNumber !== 0) {\n return this.internalStorageService.uploadSummaryWithContext(summary, context);\n }\n\n // Creation flow with attachment blobs - need to do retries!\n return this.runWithRetry(\n async () => this.internalStorageService.uploadSummaryWithContext(summary, context),\n \"storage_uploadSummaryWithContext\",\n );\n }\n\n public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n return this.runWithRetry(\n async () => this.internalStorageService.downloadSummary(handle),\n \"storage_downloadSummary\",\n );\n }\n\n public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n return this.runWithRetry(\n async () => this.internalStorageService.createBlob(file),\n \"storage_createBlob\",\n );\n }\n\n private checkStorageDisposed() {\n if (this._disposed) {\n throw new GenericError(\"storageServiceDisposedCannotRetry\", { canRetry: false });\n }\n return undefined;\n }\n\n private async runWithRetry<T>(api: () => Promise<T>, callName: string): Promise<T> {\n return runWithRetry(\n api,\n callName,\n this.logger,\n {\n retry: () => this.checkStorageDisposed(),\n },\n );\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-loader",
3
- "version": "0.54.2",
3
+ "version": "0.56.0-49831",
4
4
  "description": "Fluid container loader",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": "https://github.com/microsoft/FluidFramework",
@@ -23,7 +23,7 @@
23
23
  "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
24
24
  "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
25
25
  "eslint": "eslint --format stylish src",
26
- "eslint:fix": "eslint --format stylish src --fix",
26
+ "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
27
27
  "lint": "npm run eslint",
28
28
  "lint:fix": "npm run eslint:fix",
29
29
  "test": "npm run test:mocha",
@@ -58,14 +58,14 @@
58
58
  "dependencies": {
59
59
  "@fluidframework/common-definitions": "^0.20.1",
60
60
  "@fluidframework/common-utils": "^0.32.1",
61
- "@fluidframework/container-definitions": "^0.44.0",
62
- "@fluidframework/container-utils": "^0.54.2",
63
- "@fluidframework/core-interfaces": "^0.41.0",
64
- "@fluidframework/driver-definitions": "^0.43.0",
65
- "@fluidframework/driver-utils": "^0.54.2",
61
+ "@fluidframework/container-definitions": "^0.45.0-0",
62
+ "@fluidframework/container-utils": "0.56.0-49831",
63
+ "@fluidframework/core-interfaces": "^0.42.0-0",
64
+ "@fluidframework/driver-definitions": "^0.44.0-0",
65
+ "@fluidframework/driver-utils": "0.56.0-49831",
66
66
  "@fluidframework/protocol-base": "^0.1034.0",
67
67
  "@fluidframework/protocol-definitions": "^0.1026.0",
68
- "@fluidframework/telemetry-utils": "^0.54.2",
68
+ "@fluidframework/telemetry-utils": "0.56.0-49831",
69
69
  "abort-controller": "^3.0.0",
70
70
  "double-ended-queue": "^2.1.0-0",
71
71
  "lodash": "^4.17.21",
@@ -73,27 +73,28 @@
73
73
  },
74
74
  "devDependencies": {
75
75
  "@fluidframework/build-common": "^0.23.0",
76
- "@fluidframework/eslint-config-fluid": "^0.24.0",
77
- "@fluidframework/mocha-test-setup": "^0.54.2",
78
- "@fluidframework/test-loader-utils": "^0.54.2",
76
+ "@fluidframework/eslint-config-fluid": "^0.25.0",
77
+ "@fluidframework/mocha-test-setup": "0.56.0-49831",
78
+ "@fluidframework/test-loader-utils": "0.56.0-49831",
79
79
  "@microsoft/api-extractor": "^7.16.1",
80
+ "@rushstack/eslint-config": "^2.5.1",
80
81
  "@types/double-ended-queue": "^2.1.0",
81
82
  "@types/lodash": "^4.14.118",
82
83
  "@types/mocha": "^8.2.2",
83
84
  "@types/node": "^14.18.0",
84
85
  "@types/sinon": "^7.0.13",
85
- "@typescript-eslint/eslint-plugin": "~4.14.0",
86
- "@typescript-eslint/parser": "~4.14.0",
86
+ "@typescript-eslint/eslint-plugin": "~5.9.0",
87
+ "@typescript-eslint/parser": "~5.9.0",
87
88
  "concurrently": "^6.2.0",
88
89
  "copyfiles": "^2.1.0",
89
90
  "cross-env": "^7.0.2",
90
- "eslint": "~7.18.0",
91
+ "eslint": "~8.6.0",
92
+ "eslint-plugin-editorconfig": "~3.2.0",
91
93
  "eslint-plugin-eslint-comments": "~3.2.0",
92
- "eslint-plugin-import": "~2.22.1",
94
+ "eslint-plugin-import": "~2.25.4",
93
95
  "eslint-plugin-no-null": "~1.0.2",
94
- "eslint-plugin-prefer-arrow": "~1.2.2",
95
- "eslint-plugin-react": "~7.22.0",
96
- "eslint-plugin-unicorn": "~26.0.1",
96
+ "eslint-plugin-react": "~7.28.0",
97
+ "eslint-plugin-unicorn": "~40.0.0",
97
98
  "mocha": "^8.4.0",
98
99
  "nyc": "^15.0.0",
99
100
  "rimraf": "^2.6.2",
@@ -57,8 +57,9 @@ export class ConnectionStateHandler {
57
57
  private readonly logger: ITelemetryLogger,
58
58
  ) {
59
59
  this.prevClientLeftTimer = new Timer(
60
- // Default is 90 sec for which we are going to wait for its own "leave" message.
61
- this.handler.maxClientLeaveWaitTime ?? 90000,
60
+ // Default is 5 min for which we are going to wait for its own "leave" message. This is same as
61
+ // the max time on server after which leave op is sent.
62
+ this.handler.maxClientLeaveWaitTime ?? 300000,
62
63
  () => {
63
64
  assert(!this.connected,
64
65
  0x2ac /* "Connected when timeout waiting for leave from previous session fired!" */);
@@ -96,6 +97,15 @@ export class ConnectionStateHandler {
96
97
  this.prevClientLeftTimer.clear();
97
98
  }
98
99
 
100
+ public containerSaved() {
101
+ // If we were waiting for moving to Connected state, then only apply for state change. Since the container
102
+ // is now saved and we don't have any ops to roundtrip, we can clear the timer and apply for connected state.
103
+ if (this.prevClientLeftTimer.hasTimer) {
104
+ this.prevClientLeftTimer.clear();
105
+ this.applyForConnectedState("containerSaved");
106
+ }
107
+ }
108
+
99
109
  public receivedAddMemberEvent(clientId: string) {
100
110
  // This is the only one that requires the pending client ID
101
111
  if (clientId === this.pendingClientId) {
@@ -118,7 +128,7 @@ export class ConnectionStateHandler {
118
128
  }
119
129
  }
120
130
 
121
- private applyForConnectedState(source: "removeMemberEvent" | "addMemberEvent" | "timeout") {
131
+ private applyForConnectedState(source: "removeMemberEvent" | "addMemberEvent" | "timeout" | "containerSaved") {
122
132
  const protocolHandler = this.handler.protocolHandler();
123
133
  assert(protocolHandler !== undefined, 0x236 /* "In all cases it should be already installed" */);
124
134
  // Move to connected state only if we are in Connecting state, we have seen our join op
package/src/container.ts CHANGED
@@ -8,7 +8,6 @@ import merge from "lodash/merge";
8
8
  import { v4 as uuid } from "uuid";
9
9
  import {
10
10
  IDisposable,
11
- ITelemetryLogger,
12
11
  } from "@fluidframework/common-definitions";
13
12
  import { assert, performance, unreachableCase } from "@fluidframework/common-utils";
14
13
  import {
@@ -65,24 +64,24 @@ import {
65
64
  ICommittedProposal,
66
65
  IDocumentAttributes,
67
66
  IDocumentMessage,
67
+ IPendingProposal,
68
68
  IProcessMessageResult,
69
- IQuorum,
69
+ IQuorumClients,
70
+ IQuorumProposals,
70
71
  ISequencedClient,
71
72
  ISequencedDocumentMessage,
72
73
  ISequencedProposal,
73
74
  ISignalClient,
74
75
  ISignalMessage,
75
76
  ISnapshotTree,
77
+ ISummaryContent,
78
+ ISummaryTree,
76
79
  ITree,
77
80
  ITreeEntry,
78
81
  IVersion,
79
82
  MessageType,
80
- TreeEntry,
81
- ISummaryTree,
82
- IPendingProposal,
83
83
  SummaryType,
84
- ISummaryContent,
85
- IQuorumProposals,
84
+ TreeEntry,
86
85
  } from "@fluidframework/protocol-definitions";
87
86
  import {
88
87
  ChildLogger,
@@ -93,6 +92,8 @@ import {
93
92
  connectedEventName,
94
93
  disconnectedEventName,
95
94
  normalizeError,
95
+ MonitoringContext,
96
+ loggerToMonitoringContext,
96
97
  } from "@fluidframework/telemetry-utils";
97
98
  import { Audience } from "./audience";
98
99
  import { ContainerContext } from "./containerContext";
@@ -248,9 +249,9 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
248
249
  });
249
250
 
250
251
  return PerformanceEvent.timedExecAsync(
251
- container.logger,
252
+ container.mc.logger,
252
253
  { eventName: "Load" },
253
- async (event) => new Promise<Container>((res, rej) => {
254
+ async (event) => new Promise<Container>((resolve, reject) => {
254
255
  container._lifecycleState = "loading";
255
256
  const version = loadOptions.version;
256
257
 
@@ -262,7 +263,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
262
263
  const mode: IContainerLoadMode = loadOptions.loadMode ?? defaultMode;
263
264
 
264
265
  const onClosed = (err?: ICriticalContainerError) => {
265
- rej(err ?? new GenericError("containerClosedWithoutErrorDuringLoad"));
266
+ reject(err ?? new GenericError("containerClosedWithoutErrorDuringLoad"));
266
267
  };
267
268
  container.on("closed", onClosed);
268
269
 
@@ -272,7 +273,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
272
273
  })
273
274
  .then((props) => {
274
275
  event.end({ ...props, ...loadOptions.loadMode });
275
- res(container);
276
+ resolve(container);
276
277
  },
277
278
  (error) => {
278
279
  const err = normalizeError(error);
@@ -299,7 +300,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
299
300
  {});
300
301
 
301
302
  return PerformanceEvent.timedExecAsync(
302
- container.logger,
303
+ container.mc.logger,
303
304
  { eventName: "CreateDetached" },
304
305
  async (_event) => {
305
306
  container._lifecycleState = "loading";
@@ -321,7 +322,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
321
322
  loader,
322
323
  {});
323
324
  return PerformanceEvent.timedExecAsync(
324
- container.logger,
325
+ container.mc.logger,
325
326
  { eventName: "RehydrateDetachedFromSnapshot" },
326
327
  async (_event) => {
327
328
  const deserializedSummary = JSON.parse(snapshot) as ISummaryTree;
@@ -338,7 +339,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
338
339
  // If false, container gets closed on loss of connection.
339
340
  private readonly _canReconnect: boolean = true;
340
341
 
341
- private readonly logger: ITelemetryLogger;
342
+ private readonly mc: MonitoringContext;
342
343
 
343
344
  private _lifecycleState: "created" | "loading" | "loaded" | "closing" | "closed" = "created";
344
345
 
@@ -368,7 +369,6 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
368
369
  return this._storage;
369
370
  }
370
371
 
371
- // Active chaincode and associated runtime
372
372
  private _storageService: IDocumentStorageService & IDisposable | undefined;
373
373
  private get storageService(): IDocumentStorageService {
374
374
  if (this._storageService === undefined) {
@@ -408,6 +408,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
408
408
  private _dirtyContainer = false;
409
409
 
410
410
  private lastVisible: number | undefined;
411
+ private readonly visibilityEventHandler: (() => void) | undefined;
411
412
  private readonly connectionStateHandler: ConnectionStateHandler;
412
413
 
413
414
  private setAutoReconnectTime = performance.now();
@@ -442,10 +443,6 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
442
443
  this._deltaManager.connectionManager.forceReadonly(readonly);
443
444
  }
444
445
 
445
- public get id(): string {
446
- return this._resolvedUrl?.id ?? "";
447
- }
448
-
449
446
  public get deltaManager(): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {
450
447
  return this._deltaManager;
451
448
  }
@@ -486,16 +483,6 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
486
483
  return this._deltaManager.clientDetails;
487
484
  }
488
485
 
489
- /**
490
- * The current code details for the container's runtime
491
- * @deprecated use getSpecifiedCodeDetails for the code details currently specified for this container, or
492
- * getLoadedCodeDetails for the code details that the container's context was loaded with.
493
- * To be removed after getSpecifiedCodeDetails and getLoadedCodeDetails become ubiquitous.
494
- */
495
- public get codeDetails(): IFluidCodeDetails | undefined {
496
- return this._context?.codeDetails ?? this.getCodeDetailsFromQuorum();
497
- }
498
-
499
486
  /**
500
487
  * Get the code details that are currently specified for the container.
501
488
  * @returns The current code details if any are specified, undefined if none are specified.
@@ -531,7 +518,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
531
518
 
532
519
  private get serviceFactory() {return this.loader.services.documentServiceFactory;}
533
520
  private get urlResolver() {return this.loader.services.urlResolver;}
534
- public get options(): ILoaderOptions { return this.loader.services.options; }
521
+ public readonly options: ILoaderOptions;
535
522
  private get scope() { return this.loader.services.scope;}
536
523
  private get codeLoader() { return this.loader.services.codeLoader;}
537
524
 
@@ -540,7 +527,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
540
527
  config: IContainerConfig,
541
528
  ) {
542
529
  super((name, error) => {
543
- this.logger.sendErrorEvent(
530
+ this.mc.logger.sendErrorEvent(
544
531
  {
545
532
  eventName: "ContainerEventHandlerException",
546
533
  name: typeof name === "string" ? name : undefined,
@@ -569,12 +556,12 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
569
556
  all: {
570
557
  clientType, // Differentiating summarizer container from main container
571
558
  containerId: uuid(),
572
- docId: () => this.id,
559
+ docId: () => this._resolvedUrl?.id ?? undefined,
573
560
  containerAttachState: () => this._attachState,
574
561
  containerLifecycleState: () => this._lifecycleState,
575
562
  containerConnectionState: () => ConnectionState[this.connectionState],
576
563
  },
577
- // we need to be judicious with our logging here to avoid generting too much data
564
+ // we need to be judicious with our logging here to avoid generating too much data
578
565
  // all data logged here should be broadly applicable, and not specific to a
579
566
  // specific error or class of errors
580
567
  error: {
@@ -587,14 +574,22 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
587
574
  dmLastMsqSeqNumber: () => this.deltaManager?.lastMessage?.sequenceNumber,
588
575
  dmLastMsqSeqTimestamp: () => this.deltaManager?.lastMessage?.timestamp,
589
576
  dmLastMsqSeqClientId: () => this.deltaManager?.lastMessage?.clientId,
590
- connectionState: () => ConnectionState[this.connectionState],
591
577
  connectionStateDuration:
592
578
  () => performance.now() - this.connectionTransitionTimes[this.connectionState],
593
579
  },
594
580
  });
595
581
 
596
582
  // Prefix all events in this file with container-loader
597
- this.logger = ChildLogger.create(this.subLogger, "Container");
583
+ this.mc = loggerToMonitoringContext(ChildLogger.create(this.subLogger, "Container"));
584
+
585
+ const summarizeProtocolTree =
586
+ this.mc.config.getBoolean("Fluid.Container.summarizeProtocolTree")
587
+ ?? this.loader.services.options.summarizeProtocolTree;
588
+
589
+ this.options = {
590
+ ... this.loader.services.options,
591
+ summarizeProtocolTree,
592
+ };
598
593
 
599
594
  this.connectionStateHandler = new ConnectionStateHandler(
600
595
  {
@@ -617,17 +612,21 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
617
612
  }
618
613
  },
619
614
  },
620
- this.logger,
615
+ this.mc.logger,
621
616
  );
622
617
 
618
+ this.on(savedContainerEvent, () => {
619
+ this.connectionStateHandler.containerSaved();
620
+ });
621
+
623
622
  this._deltaManager = this.createDeltaManager();
624
623
  this._storage = new ContainerStorageAdapter(
625
624
  () => {
626
625
  if (this.attachState !== AttachState.Attached) {
627
626
  if (this.loader.services.detachedBlobStorage !== undefined) {
628
- return new BlobOnlyStorage(this.loader.services.detachedBlobStorage, this.logger);
627
+ return new BlobOnlyStorage(this.loader.services.detachedBlobStorage, this.mc.logger);
629
628
  }
630
- this.logger.sendErrorEvent({
629
+ this.mc.logger.sendErrorEvent({
631
630
  eventName: "NoRealStorageInDetachedContainer",
632
631
  });
633
632
  throw new Error("Real storage calls not allowed in Unattached container");
@@ -643,14 +642,15 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
643
642
  // keep track of last time page was visible for telemetry
644
643
  if (isDomAvailable) {
645
644
  this.lastVisible = document.hidden ? performance.now() : undefined;
646
- document.addEventListener("visibilitychange", () => {
645
+ this.visibilityEventHandler = () => {
647
646
  if (document.hidden) {
648
647
  this.lastVisible = performance.now();
649
648
  } else {
650
649
  // settimeout so this will hopefully fire after disconnect event if being hidden caused it
651
650
  setTimeout(() => this.lastVisible = undefined, 0);
652
651
  }
653
- });
652
+ };
653
+ document.addEventListener("visibilitychange", this.visibilityEventHandler);
654
654
  }
655
655
 
656
656
  // We observed that most users of platform do not check Container.connected event on load, causing bugs.
@@ -684,7 +684,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
684
684
  default:
685
685
  }
686
686
  }).catch((error) => {
687
- this.logger.sendErrorEvent({ eventName: "RaiseConnectedEventError" }, error);
687
+ this.mc.logger.sendErrorEvent({ eventName: "RaiseConnectedEventError" }, error);
688
688
  });
689
689
  });
690
690
  }
@@ -692,7 +692,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
692
692
  /**
693
693
  * Retrieves the quorum associated with the document
694
694
  */
695
- public getQuorum(): IQuorum {
695
+ public getQuorum(): IQuorumClients {
696
696
  return this.protocolHandler.quorum;
697
697
  }
698
698
 
@@ -724,10 +724,10 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
724
724
  // Driver need to ensure all caches are cleared on critical errors
725
725
  this.service?.dispose(error);
726
726
  } catch (exception) {
727
- this.logger.sendErrorEvent({ eventName: "ContainerCloseException"}, exception);
727
+ this.mc.logger.sendErrorEvent({ eventName: "ContainerCloseException"}, exception);
728
728
  }
729
729
 
730
- this.logger.sendTelemetryEvent(
730
+ this.mc.logger.sendTelemetryEvent(
731
731
  {
732
732
  eventName: "ContainerClose",
733
733
  category: error === undefined ? "generic" : "error",
@@ -738,6 +738,9 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
738
738
  this.emit("closed", error);
739
739
 
740
740
  this.removeAllListeners();
741
+ if (this.visibilityEventHandler !== undefined) {
742
+ document.removeEventListener("visibilitychange", this.visibilityEventHandler);
743
+ }
741
744
  } finally {
742
745
  this._lifecycleState = "closed";
743
746
  }
@@ -779,7 +782,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
779
782
  }
780
783
 
781
784
  public async attach(request: IRequest): Promise<void> {
782
- await PerformanceEvent.timedExecAsync(this.logger, { eventName: "Attach" }, async () => {
785
+ await PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Attach" }, async () => {
783
786
  if (this._lifecycleState !== "loaded") {
784
787
  throw new UsageError(`containerNotValidForAttach [${this._lifecycleState}]`);
785
788
  }
@@ -824,7 +827,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
824
827
  this.subLogger,
825
828
  ),
826
829
  "containerAttach",
827
- this.logger,
830
+ this.mc.logger,
828
831
  {}, // progress
829
832
  );
830
833
  }
@@ -890,7 +893,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
890
893
 
891
894
  public async request(path: IRequest): Promise<IResponse> {
892
895
  return PerformanceEvent.timedExecAsync(
893
- this.logger,
896
+ this.mc.logger,
894
897
  { eventName: "Request" },
895
898
  async () => this.context.request(path),
896
899
  { end: true, cancel: "error" },
@@ -900,7 +903,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
900
903
  public async snapshot(tagMessage: string, fullTree: boolean = false): Promise<void> {
901
904
  // Only snapshot once a code quorum has been established
902
905
  if (!this.protocolHandler.quorum.has("code") && !this.protocolHandler.quorum.has("code2")) {
903
- this.logger.sendTelemetryEvent({ eventName: "SkipSnapshot" });
906
+ this.mc.logger.sendTelemetryEvent({ eventName: "SkipSnapshot" });
904
907
  return;
905
908
  }
906
909
 
@@ -909,7 +912,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
909
912
  await this.deltaManager.inbound.pause();
910
913
  await this.snapshotCore(tagMessage, fullTree);
911
914
  } catch (ex) {
912
- this.logger.sendErrorEvent({ eventName: "SnapshotExceptionError" }, ex);
915
+ this.mc.logger.sendErrorEvent({ eventName: "SnapshotExceptionError" }, ex);
913
916
  throw ex;
914
917
  } finally {
915
918
  this.deltaManager.inbound.resume();
@@ -931,7 +934,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
931
934
  const duration = now - this.setAutoReconnectTime;
932
935
  this.setAutoReconnectTime = now;
933
936
 
934
- this.logger.sendTelemetryEvent({
937
+ this.mc.logger.sendTelemetryEvent({
935
938
  eventName: reconnect ? "AutoReconnectEnabled" : "AutoReconnectDisabled",
936
939
  connectionMode: this.connectionMode,
937
940
  connectionState: ConnectionState[this.connectionState],
@@ -977,6 +980,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
977
980
  }
978
981
 
979
982
  /**
983
+ * @deprecated 0.56, will be removed in next release from IContainerContext
980
984
  * Raise non-critical error to host. Calling this API will not close container.
981
985
  * For critical errors, please call Container.close(error).
982
986
  * @param error - an error to raise
@@ -1007,15 +1011,15 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1007
1011
  }
1008
1012
 
1009
1013
  if (this.codeLoader.IFluidCodeDetailsComparer) {
1010
- const comparision = await this.codeLoader.IFluidCodeDetailsComparer.compare(
1014
+ const comparison = await this.codeLoader.IFluidCodeDetailsComparer.compare(
1011
1015
  codeDetails,
1012
1016
  this.getCodeDetailsFromQuorum());
1013
- if (comparision !== undefined && comparision <= 0) {
1017
+ if (comparison !== undefined && comparison <= 0) {
1014
1018
  throw new Error("Proposed code details should be greater than the current");
1015
1019
  }
1016
1020
  }
1017
1021
 
1018
- return this.getQuorum().propose("code", codeDetails)
1022
+ return this.protocolHandler.quorum.propose("code", codeDetails)
1019
1023
  .then(()=>true)
1020
1024
  .catch(()=>false);
1021
1025
  }
@@ -1052,7 +1056,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1052
1056
  const message = `Commit @${deltaDetails} ${tagMessage}`;
1053
1057
 
1054
1058
  // Pull in the prior version and snapshot tree to store against
1055
- const lastVersion = await this.getVersion(this.id);
1059
+ const lastVersion = await this.getVersion(null);
1056
1060
 
1057
1061
  const parents = lastVersion !== undefined ? [lastVersion.id] : [];
1058
1062
 
@@ -1094,7 +1098,6 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1094
1098
 
1095
1099
  // Save attributes for the document
1096
1100
  const documentAttributes = {
1097
- branch: this.id,
1098
1101
  minimumSequenceNumber: this._deltaManager.minimumSequenceNumber,
1099
1102
  sequenceNumber: this._deltaManager.lastSequenceNumber,
1100
1103
  term: this._deltaManager.referenceTerm,
@@ -1117,7 +1120,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1117
1120
  return root;
1118
1121
  }
1119
1122
 
1120
- private async getVersion(version: string): Promise<IVersion | undefined> {
1123
+ private async getVersion(version: string | null): Promise<IVersion | undefined> {
1121
1124
  const versions = await this.storageService.getVersions(version, 1);
1122
1125
  return versions[0];
1123
1126
  }
@@ -1341,9 +1344,10 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1341
1344
  const storageService = await this.service.connectToStorage();
1342
1345
 
1343
1346
  this._storageService =
1344
- new RetriableDocumentStorageService(storageService, this.logger);
1347
+ new RetriableDocumentStorageService(storageService, this.mc.logger);
1345
1348
 
1346
1349
  if(this.options.summarizeProtocolTree === true) {
1350
+ this.mc.logger.sendTelemetryEvent({eventName:"summarizeProtocolTreeEnabled"});
1347
1351
  this._storageService =
1348
1352
  new ProtocolTreeStorageService(this._storageService, ()=>this.captureProtocolSummary());
1349
1353
  }
@@ -1449,7 +1453,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1449
1453
  (sequenceNumber, key, value) => {
1450
1454
  if (key === "code" || key === "code2") {
1451
1455
  if (!isFluidCodeDetails(value)) {
1452
- this.logger.sendErrorEvent({
1456
+ this.mc.logger.sendErrorEvent({
1453
1457
  eventName: "CodeProposalNotIFluidCodeDetails",
1454
1458
  });
1455
1459
  }
@@ -1646,7 +1650,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1646
1650
  }
1647
1651
  }
1648
1652
 
1649
- this.logger.sendPerformanceEvent({
1653
+ this.mc.logger.sendPerformanceEvent({
1650
1654
  eventName: `ConnectionStateChange_${ConnectionState[value]}`,
1651
1655
  from: ConnectionState[oldState],
1652
1656
  duration,
@@ -1684,10 +1688,10 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1684
1688
  }
1685
1689
  assert(this.protocolHandler !== undefined, 0x0dc /* "Protocol handler should be set here" */);
1686
1690
  this.protocolHandler.quorum.setConnectionState(state, this.clientId);
1687
- raiseConnectedEvent(this.logger, this, state, this.clientId);
1691
+ raiseConnectedEvent(this.mc.logger, this, state, this.clientId);
1688
1692
 
1689
1693
  if (logOpsOnReconnect) {
1690
- this.logger.sendTelemetryEvent(
1694
+ this.mc.logger.sendTelemetryEvent(
1691
1695
  { eventName: "OpsSentOnReconnect", count: this.messageCountAfterDisconnection });
1692
1696
  }
1693
1697
  }
@@ -1722,7 +1726,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1722
1726
 
1723
1727
  private submitMessage(type: MessageType, contents: any, batch?: boolean, metadata?: any): number {
1724
1728
  if (this.connectionState !== ConnectionState.Connected) {
1725
- this.logger.sendErrorEvent({ eventName: "SubmitMessageWithNoConnection", type });
1729
+ this.mc.logger.sendErrorEvent({ eventName: "SubmitMessageWithNoConnection", type });
1726
1730
  return -1;
1727
1731
  }
1728
1732
 
@@ -1796,17 +1800,17 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1796
1800
  private async fetchSnapshotTree(specifiedVersion: string | undefined):
1797
1801
  Promise<{snapshot?: ISnapshotTree; versionId?: string}>
1798
1802
  {
1799
- const version = await this.getVersion(specifiedVersion ?? this.id);
1803
+ const version = await this.getVersion(specifiedVersion ?? null);
1800
1804
 
1801
1805
  if (version === undefined && specifiedVersion !== undefined) {
1802
1806
  // We should have a defined version to load from if specified version requested
1803
- this.logger.sendErrorEvent({ eventName: "NoVersionFoundWhenSpecified", id: specifiedVersion });
1807
+ this.mc.logger.sendErrorEvent({ eventName: "NoVersionFoundWhenSpecified", id: specifiedVersion });
1804
1808
  }
1805
1809
  this._loadedFromVersion = version;
1806
1810
  const snapshot = await this.storageService.getSnapshotTree(version) ?? undefined;
1807
1811
 
1808
1812
  if (snapshot === undefined && version !== undefined) {
1809
- this.logger.sendErrorEvent({ eventName: "getSnapshotTreeFailed", id: version.id });
1813
+ this.mc.logger.sendErrorEvent({ eventName: "getSnapshotTreeFailed", id: version.id });
1810
1814
  }
1811
1815
  return { snapshot, versionId: version?.id };
1812
1816
  }
@@ -1838,7 +1842,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1838
1842
  assert(this._context?.disposed !== false, 0x0dd /* "Existing context not disposed" */);
1839
1843
  // If this assert fires, our state tracking is likely not synchronized between COntainer & runtime.
1840
1844
  if (this._dirtyContainer) {
1841
- this.logger.sendErrorEvent({ eventName: "DirtyContainerReloadContainer" });
1845
+ this.mc.logger.sendErrorEvent({ eventName: "DirtyContainerReloadContainer" });
1842
1846
  }
1843
1847
 
1844
1848
  // The relative loader will proxy requests to '/' to the loader itself assuming no non-cache flags
@@ -1869,9 +1873,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1869
1873
  this.emit("contextChanged", codeDetails);
1870
1874
  }
1871
1875
 
1872
- // Please avoid calling it directly.
1873
- // raiseContainerWarning() is the right flow for most cases
1874
1876
  private logContainerError(warning: ContainerWarning) {
1875
- this.logger.sendErrorEvent({ eventName: "ContainerWarning" }, warning);
1877
+ this.mc.logger.sendErrorEvent({ eventName: "ContainerWarning" }, warning);
1876
1878
  }
1877
1879
  }