@fluidframework/container-loader 2.0.0-dev-rc.3.0.0.254674 → 2.0.0-dev-rc.4.0.0.261659

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 (151) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/api-report/container-loader.api.md +7 -3
  3. package/dist/audience.d.ts +6 -4
  4. package/dist/audience.d.ts.map +1 -1
  5. package/dist/audience.js +18 -3
  6. package/dist/audience.js.map +1 -1
  7. package/dist/connectionManager.d.ts +6 -2
  8. package/dist/connectionManager.d.ts.map +1 -1
  9. package/dist/connectionManager.js +40 -16
  10. package/dist/connectionManager.js.map +1 -1
  11. package/dist/connectionStateHandler.d.ts +29 -8
  12. package/dist/connectionStateHandler.d.ts.map +1 -1
  13. package/dist/connectionStateHandler.js +49 -36
  14. package/dist/connectionStateHandler.js.map +1 -1
  15. package/dist/container.d.ts +6 -10
  16. package/dist/container.d.ts.map +1 -1
  17. package/dist/container.js +126 -113
  18. package/dist/container.js.map +1 -1
  19. package/dist/containerContext.d.ts +1 -1
  20. package/dist/containerContext.d.ts.map +1 -1
  21. package/dist/containerContext.js.map +1 -1
  22. package/dist/containerStorageAdapter.d.ts +12 -3
  23. package/dist/containerStorageAdapter.d.ts.map +1 -1
  24. package/dist/containerStorageAdapter.js +42 -4
  25. package/dist/containerStorageAdapter.js.map +1 -1
  26. package/dist/debugLogger.d.ts +1 -2
  27. package/dist/debugLogger.d.ts.map +1 -1
  28. package/dist/debugLogger.js.map +1 -1
  29. package/dist/deltaManager.d.ts +3 -4
  30. package/dist/deltaManager.d.ts.map +1 -1
  31. package/dist/deltaManager.js +8 -3
  32. package/dist/deltaManager.js.map +1 -1
  33. package/dist/error.d.ts +1 -2
  34. package/dist/error.d.ts.map +1 -1
  35. package/dist/error.js.map +1 -1
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +3 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/{alpha.d.ts → legacy.d.ts} +5 -2
  41. package/dist/loadPaused.d.ts +35 -0
  42. package/dist/loadPaused.d.ts.map +1 -0
  43. package/dist/loadPaused.js +115 -0
  44. package/dist/loadPaused.js.map +1 -0
  45. package/dist/loader.d.ts +1 -1
  46. package/dist/loader.d.ts.map +1 -1
  47. package/dist/loader.js +0 -13
  48. package/dist/loader.js.map +1 -1
  49. package/dist/packageVersion.d.ts +1 -1
  50. package/dist/packageVersion.js +1 -1
  51. package/dist/packageVersion.js.map +1 -1
  52. package/dist/protocol.d.ts.map +1 -1
  53. package/dist/protocol.js +3 -0
  54. package/dist/protocol.js.map +1 -1
  55. package/dist/public.d.ts +2 -1
  56. package/dist/retriableDocumentStorageService.d.ts +1 -1
  57. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  58. package/dist/retriableDocumentStorageService.js.map +1 -1
  59. package/dist/serializedStateManager.d.ts +23 -5
  60. package/dist/serializedStateManager.d.ts.map +1 -1
  61. package/dist/serializedStateManager.js +72 -22
  62. package/dist/serializedStateManager.js.map +1 -1
  63. package/dist/utils.d.ts +2 -2
  64. package/dist/utils.d.ts.map +1 -1
  65. package/dist/utils.js +2 -3
  66. package/dist/utils.js.map +1 -1
  67. package/{dist/beta.d.ts → internal.d.ts} +2 -4
  68. package/{lib/beta.d.ts → legacy.d.ts} +2 -4
  69. package/lib/audience.d.ts +6 -4
  70. package/lib/audience.d.ts.map +1 -1
  71. package/lib/audience.js +19 -4
  72. package/lib/audience.js.map +1 -1
  73. package/lib/connectionManager.d.ts +6 -2
  74. package/lib/connectionManager.d.ts.map +1 -1
  75. package/lib/connectionManager.js +41 -17
  76. package/lib/connectionManager.js.map +1 -1
  77. package/lib/connectionStateHandler.d.ts +29 -8
  78. package/lib/connectionStateHandler.d.ts.map +1 -1
  79. package/lib/connectionStateHandler.js +49 -36
  80. package/lib/connectionStateHandler.js.map +1 -1
  81. package/lib/container.d.ts +6 -10
  82. package/lib/container.d.ts.map +1 -1
  83. package/lib/container.js +126 -113
  84. package/lib/container.js.map +1 -1
  85. package/lib/containerContext.d.ts +1 -1
  86. package/lib/containerContext.d.ts.map +1 -1
  87. package/lib/containerContext.js.map +1 -1
  88. package/lib/containerStorageAdapter.d.ts +12 -3
  89. package/lib/containerStorageAdapter.d.ts.map +1 -1
  90. package/lib/containerStorageAdapter.js +42 -4
  91. package/lib/containerStorageAdapter.js.map +1 -1
  92. package/lib/debugLogger.d.ts +1 -2
  93. package/lib/debugLogger.d.ts.map +1 -1
  94. package/lib/debugLogger.js.map +1 -1
  95. package/lib/deltaManager.d.ts +3 -4
  96. package/lib/deltaManager.d.ts.map +1 -1
  97. package/lib/deltaManager.js +9 -4
  98. package/lib/deltaManager.js.map +1 -1
  99. package/lib/error.d.ts +1 -2
  100. package/lib/error.d.ts.map +1 -1
  101. package/lib/error.js.map +1 -1
  102. package/lib/index.d.ts +1 -0
  103. package/lib/index.d.ts.map +1 -1
  104. package/lib/index.js +1 -0
  105. package/lib/index.js.map +1 -1
  106. package/lib/{alpha.d.ts → legacy.d.ts} +5 -2
  107. package/lib/loadPaused.d.ts +35 -0
  108. package/lib/loadPaused.d.ts.map +1 -0
  109. package/lib/loadPaused.js +111 -0
  110. package/lib/loadPaused.js.map +1 -0
  111. package/lib/loader.d.ts +1 -1
  112. package/lib/loader.d.ts.map +1 -1
  113. package/lib/loader.js +1 -14
  114. package/lib/loader.js.map +1 -1
  115. package/lib/packageVersion.d.ts +1 -1
  116. package/lib/packageVersion.js +1 -1
  117. package/lib/packageVersion.js.map +1 -1
  118. package/lib/protocol.d.ts.map +1 -1
  119. package/lib/protocol.js +3 -0
  120. package/lib/protocol.js.map +1 -1
  121. package/lib/public.d.ts +2 -1
  122. package/lib/retriableDocumentStorageService.d.ts +1 -1
  123. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  124. package/lib/retriableDocumentStorageService.js +1 -1
  125. package/lib/retriableDocumentStorageService.js.map +1 -1
  126. package/lib/serializedStateManager.d.ts +23 -5
  127. package/lib/serializedStateManager.d.ts.map +1 -1
  128. package/lib/serializedStateManager.js +66 -16
  129. package/lib/serializedStateManager.js.map +1 -1
  130. package/lib/utils.d.ts +2 -2
  131. package/lib/utils.d.ts.map +1 -1
  132. package/lib/utils.js +2 -3
  133. package/lib/utils.js.map +1 -1
  134. package/package.json +29 -27
  135. package/src/audience.ts +30 -9
  136. package/src/connectionManager.ts +50 -21
  137. package/src/connectionStateHandler.ts +76 -43
  138. package/src/container.ts +150 -153
  139. package/src/containerContext.ts +1 -1
  140. package/src/containerStorageAdapter.ts +59 -7
  141. package/src/debugLogger.ts +1 -1
  142. package/src/deltaManager.ts +13 -6
  143. package/src/error.ts +1 -1
  144. package/src/index.ts +1 -0
  145. package/src/loadPaused.ts +140 -0
  146. package/src/loader.ts +1 -21
  147. package/src/packageVersion.ts +1 -1
  148. package/src/protocol.ts +4 -0
  149. package/src/retriableDocumentStorageService.ts +5 -2
  150. package/src/serializedStateManager.ts +107 -31
  151. package/src/utils.ts +3 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @fluidframework/container-loader
2
2
 
3
+ ## 2.0.0-rc.3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - container-definitions: IContainerContext.getSpecifiedCodeDetails() removed [97d68aa06b](https://github.com/microsoft/FluidFramework/commit/97d68aa06bd5c022ecb026655814aea222a062ae)
8
+
9
+ IContainerContext.getSpecifiedCodeDetails() was deprecated in 0.42 and has now been removed.
10
+
11
+ - Packages now use package.json "exports" and require modern module resolution [97d68aa06b](https://github.com/microsoft/FluidFramework/commit/97d68aa06bd5c022ecb026655814aea222a062ae)
12
+
13
+ Fluid Framework packages have been updated to use the [package.json "exports"
14
+ field](https://nodejs.org/docs/latest-v18.x/api/packages.html#exports) to define explicit entry points for both
15
+ TypeScript types and implementation code.
16
+
17
+ This means that using Fluid Framework packages require the following TypeScript settings in tsconfig.json:
18
+
19
+ - `"moduleResolution": "Node16"` with `"module": "Node16"`
20
+ - `"moduleResolution": "Bundler"` with `"module": "ESNext"`
21
+
22
+ We recommend using Node16/Node16 unless absolutely necessary. That will produce transpiled JavaScript that is suitable
23
+ for use with modern versions of Node.js _and_ Bundlers.
24
+ [See the TypeScript documentation](https://www.typescriptlang.org/tsconfig#moduleResolution) for more information
25
+ regarding the module and moduleResolution options.
26
+
27
+ **Node10 moduleResolution is not supported; it does not support Fluid Framework's API structuring pattern that is used
28
+ to distinguish stable APIs from those that are in development.**
29
+
30
+ ### Minor Changes
31
+
32
+ - driver-definitions: update submitSignal content type to string [97d68aa06b](https://github.com/microsoft/FluidFramework/commit/97d68aa06bd5c022ecb026655814aea222a062ae)
33
+
34
+ Change IDocumentDeltaConnection.submitSignal's content argument type to string which represents actual/known use.
35
+
3
36
  ## 2.0.0-rc.2.0.0
4
37
 
5
38
  ### Minor Changes
@@ -15,6 +15,7 @@ import { IDocumentStorageService } from '@fluidframework/driver-definitions/inte
15
15
  import { IFluidCodeDetails } from '@fluidframework/container-definitions/internal';
16
16
  import { IFluidModule } from '@fluidframework/container-definitions/internal';
17
17
  import { IHostLoader } from '@fluidframework/container-definitions/internal';
18
+ import { ILoader } from '@fluidframework/container-definitions/internal';
18
19
  import { ILoaderOptions as ILoaderOptions_2 } from '@fluidframework/container-definitions/internal';
19
20
  import { ILocationRedirectionError } from '@fluidframework/driver-definitions/internal';
20
21
  import { IProtocolHandler as IProtocolHandler_2 } from '@fluidframework/protocol-base';
@@ -23,7 +24,7 @@ import { IQuorumSnapshot } from '@fluidframework/protocol-base';
23
24
  import { IRequest } from '@fluidframework/core-interfaces';
24
25
  import { ISignalMessage } from '@fluidframework/protocol-definitions';
25
26
  import { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';
26
- import { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils';
27
+ import { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils/internal';
27
28
  import { IUrlResolver } from '@fluidframework/driver-definitions/internal';
28
29
 
29
30
  // @public
@@ -88,7 +89,7 @@ export interface ILoaderServices {
88
89
  readonly urlResolver: IUrlResolver;
89
90
  }
90
91
 
91
- // @internal
92
+ // @alpha
92
93
  export interface IParsedUrl {
93
94
  id: string;
94
95
  path: string;
@@ -107,6 +108,9 @@ export interface IProtocolHandler extends IProtocolHandler_2 {
107
108
  // @internal
108
109
  export function isLocationRedirectionError(error: any): error is ILocationRedirectionError;
109
110
 
111
+ // @internal
112
+ export function loadContainerPaused(loader: ILoader, request: IRequest, loadToSequenceNumber?: number, signal?: AbortSignal): Promise<IContainer>;
113
+
110
114
  // @alpha
111
115
  export class Loader implements IHostLoader {
112
116
  constructor(loaderProps: ILoaderProps);
@@ -132,7 +136,7 @@ export type ProtocolHandlerBuilder = (attributes: IDocumentAttributes, snapshot:
132
136
  // @alpha
133
137
  export function resolveWithLocationRedirectionHandling<T>(api: (request: IRequest) => Promise<T>, request: IRequest, urlResolver: IUrlResolver, logger?: ITelemetryBaseLogger): Promise<T>;
134
138
 
135
- // @internal
139
+ // @alpha
136
140
  export function tryParseCompatibleResolvedUrl(url: string): IParsedUrl | undefined;
137
141
 
138
142
  // @alpha
@@ -2,16 +2,18 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { EventEmitter } from "@fluid-internal/client-utils";
6
- import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
5
+ import { TypedEventEmitter } from "@fluid-internal/client-utils";
6
+ import { IAudienceEvents, IAudienceOwner, ISelf } from "@fluidframework/container-definitions/internal";
7
7
  import { IClient } from "@fluidframework/protocol-definitions";
8
8
  /**
9
9
  * Audience represents all clients connected to the op stream.
10
10
  */
11
- export declare class Audience extends EventEmitter implements IAudienceOwner {
11
+ export declare class Audience extends TypedEventEmitter<IAudienceEvents> implements IAudienceOwner {
12
12
  private readonly members;
13
+ private _currentClientId;
13
14
  constructor();
14
- on(event: "addMember" | "removeMember", listener: (clientId: string, client: IClient) => void): this;
15
+ getSelf(): ISelf | undefined;
16
+ setCurrentClientId(clientId: string): void;
15
17
  /**
16
18
  * Adds a new client to the audience
17
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"audience.d.ts","sourceRoot":"","sources":["../src/audience.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAEhF,OAAO,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAE/D;;GAEG;AACH,qBAAa,QAAS,SAAQ,YAAa,YAAW,cAAc;IACnE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;;IAQ/C,EAAE,CACR,KAAK,EAAE,WAAW,GAAG,cAAc,EACnC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GACnD,IAAI;IAKP;;OAEG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAenD;;;OAGG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAW9C;;;;;OAKG;IACI,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAIzC;;;;;OAKG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;CAGvD"}
1
+ {"version":3,"file":"audience.d.ts","sourceRoot":"","sources":["../src/audience.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EACN,eAAe,EACf,cAAc,EACd,KAAK,EACL,MAAM,gDAAgD,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAE/D;;GAEG;AACH,qBAAa,QAAS,SAAQ,iBAAiB,CAAC,eAAe,CAAE,YAAW,cAAc;IACzF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,gBAAgB,CAAqB;;IAQtC,OAAO,IAAI,KAAK,GAAG,SAAS;IAS5B,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAejD;;OAEG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAenD;;;OAGG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAW9C;;;;;OAKG;IACI,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAIzC;;;;;OAKG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;CAGvD"}
package/dist/audience.js CHANGED
@@ -10,15 +10,30 @@ const internal_1 = require("@fluidframework/core-utils/internal");
10
10
  /**
11
11
  * Audience represents all clients connected to the op stream.
12
12
  */
13
- class Audience extends client_utils_1.EventEmitter {
13
+ class Audience extends client_utils_1.TypedEventEmitter {
14
14
  constructor() {
15
15
  super();
16
16
  this.members = new Map();
17
17
  // We are expecting this class to have many listeners, so we suppress noisy "MaxListenersExceededWarning" logging.
18
18
  super.setMaxListeners(0);
19
19
  }
20
- on(event, listener) {
21
- return super.on(event, listener);
20
+ getSelf() {
21
+ return this._currentClientId === undefined
22
+ ? undefined
23
+ : {
24
+ clientId: this._currentClientId,
25
+ client: this.getMember(this._currentClientId),
26
+ };
27
+ }
28
+ setCurrentClientId(clientId) {
29
+ if (this._currentClientId !== clientId) {
30
+ const oldId = this._currentClientId;
31
+ this._currentClientId = clientId;
32
+ // this.getMember(clientId) could resolve to undefined in these two cases:
33
+ // 1) Feature gates controlling ConnectionStateHandler() behavior are off
34
+ // 2) we are loading from stashed state and audience is empty, but we remember and set prior clientId
35
+ this.emit("selfChanged", oldId === undefined ? undefined : ({ clientId: oldId }), { clientId, client: this.getMember(clientId) });
36
+ }
22
37
  }
23
38
  /**
24
39
  * Adds a new client to the audience
@@ -1 +1 @@
1
- {"version":3,"file":"audience.js","sourceRoot":"","sources":["../src/audience.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAA4D;AAE5D,kEAA6D;AAG7D;;GAEG;AACH,MAAa,QAAS,SAAQ,2BAAY;IAGzC;QACC,KAAK,EAAE,CAAC;QAHQ,YAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;QAIrD,kHAAkH;QAClH,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAMM,EAAE,CAAC,KAAa,EAAE,QAAkC;QAC1D,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,QAAgB,EAAE,OAAgB;QAClD,mGAAmG;QACnG,+FAA+F;QAC/F,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAA,iBAAM,EACL,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAClD,KAAK,CAAC,wDAAwD,CAC9D,CAAC;SACF;aAAM;YACN,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;SAC1C;IACF,CAAC;IAED;;;OAGG;IACI,YAAY,CAAC,QAAgB;QACnC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,aAAa,KAAK,SAAS,EAAE;YAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;SACZ;aAAM;YACN,OAAO,KAAK,CAAC;SACb;IACF,CAAC;IAED;;;;;OAKG;IACI,UAAU;QAChB,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACI,SAAS,CAAC,QAAgB;QAChC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;CACD;AArED,4BAqEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"@fluid-internal/client-utils\";\nimport { IAudienceOwner } from \"@fluidframework/container-definitions/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { IClient } from \"@fluidframework/protocol-definitions\";\n\n/**\n * Audience represents all clients connected to the op stream.\n */\nexport class Audience extends EventEmitter implements IAudienceOwner {\n\tprivate readonly members = new Map<string, IClient>();\n\n\tconstructor() {\n\t\tsuper();\n\t\t// We are expecting this class to have many listeners, so we suppress noisy \"MaxListenersExceededWarning\" logging.\n\t\tsuper.setMaxListeners(0);\n\t}\n\n\tpublic on(\n\t\tevent: \"addMember\" | \"removeMember\",\n\t\tlistener: (clientId: string, client: IClient) => void,\n\t): this;\n\tpublic on(event: string, listener: (...args: any[]) => void): this {\n\t\treturn super.on(event, listener);\n\t}\n\n\t/**\n\t * Adds a new client to the audience\n\t */\n\tpublic addMember(clientId: string, details: IClient) {\n\t\t// Given that signal delivery is unreliable process, we might observe same client being added twice\n\t\t// In such case we should see exactly same payload (IClient), and should not raise event twice!\n\t\tif (this.members.has(clientId)) {\n\t\t\tconst client = this.members.get(clientId);\n\t\t\tassert(\n\t\t\t\tJSON.stringify(client) === JSON.stringify(details),\n\t\t\t\t0x4b2 /* new client has different payload from existing one */,\n\t\t\t);\n\t\t} else {\n\t\t\tthis.members.set(clientId, details);\n\t\t\tthis.emit(\"addMember\", clientId, details);\n\t\t}\n\t}\n\n\t/**\n\t * Removes a client from the audience. Only emits an event if a client is actually removed\n\t * @returns if a client was removed from the audience\n\t */\n\tpublic removeMember(clientId: string): boolean {\n\t\tconst removedClient = this.members.get(clientId);\n\t\tif (removedClient !== undefined) {\n\t\t\tthis.members.delete(clientId);\n\t\t\tthis.emit(\"removeMember\", clientId, removedClient);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves all the members in the audience.\n\t *\n\t * @remarks When the container is disconnected, this will keep returning the audience as it was last seen before the\n\t * container disconnected.\n\t */\n\tpublic getMembers(): Map<string, IClient> {\n\t\treturn new Map(this.members);\n\t}\n\n\t/**\n\t * Retrieves a specific member of the audience.\n\t *\n\t * @remarks When the container is disconnected, this will keep returning members from the audience as it was last seen\n\t * before the container disconnected.\n\t */\n\tpublic getMember(clientId: string): IClient | undefined {\n\t\treturn this.members.get(clientId);\n\t}\n}\n"]}
1
+ {"version":3,"file":"audience.js","sourceRoot":"","sources":["../src/audience.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAMjE,kEAA6D;AAG7D;;GAEG;AACH,MAAa,QAAS,SAAQ,gCAAkC;IAI/D;QACC,KAAK,EAAE,CAAC;QAJQ,YAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;QAKrD,kHAAkH;QAClH,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAEM,OAAO;QACb,OAAO,IAAI,CAAC,gBAAgB,KAAK,SAAS;YACzC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC;gBACA,QAAQ,EAAE,IAAI,CAAC,gBAAgB;gBAC/B,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC;aAC5C,CAAC;IACN,CAAC;IAEM,kBAAkB,CAAC,QAAgB;QACzC,IAAI,IAAI,CAAC,gBAAgB,KAAK,QAAQ,EAAE;YACvC,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC;YACjC,0EAA0E;YAC1E,yEAAyE;YACzE,qGAAqG;YACrG,IAAI,CAAC,IAAI,CACR,aAAa,EACb,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAkB,CAAC,EACvE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAkB,CAC9D,CAAC;SACF;IACF,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,QAAgB,EAAE,OAAgB;QAClD,mGAAmG;QACnG,+FAA+F;QAC/F,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAA,iBAAM,EACL,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAClD,KAAK,CAAC,wDAAwD,CAC9D,CAAC;SACF;aAAM;YACN,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;SAC1C;IACF,CAAC;IAED;;;OAGG;IACI,YAAY,CAAC,QAAgB;QACnC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,aAAa,KAAK,SAAS,EAAE;YAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;SACZ;aAAM;YACN,OAAO,KAAK,CAAC;SACb;IACF,CAAC;IAED;;;;;OAKG;IACI,UAAU;QAChB,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACI,SAAS,CAAC,QAAgB;QAChC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;CACD;AAtFD,4BAsFC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport {\n\tIAudienceEvents,\n\tIAudienceOwner,\n\tISelf,\n} from \"@fluidframework/container-definitions/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { IClient } from \"@fluidframework/protocol-definitions\";\n\n/**\n * Audience represents all clients connected to the op stream.\n */\nexport class Audience extends TypedEventEmitter<IAudienceEvents> implements IAudienceOwner {\n\tprivate readonly members = new Map<string, IClient>();\n\tprivate _currentClientId: string | undefined;\n\n\tconstructor() {\n\t\tsuper();\n\t\t// We are expecting this class to have many listeners, so we suppress noisy \"MaxListenersExceededWarning\" logging.\n\t\tsuper.setMaxListeners(0);\n\t}\n\n\tpublic getSelf(): ISelf | undefined {\n\t\treturn this._currentClientId === undefined\n\t\t\t? undefined\n\t\t\t: {\n\t\t\t\t\tclientId: this._currentClientId,\n\t\t\t\t\tclient: this.getMember(this._currentClientId),\n\t\t\t };\n\t}\n\n\tpublic setCurrentClientId(clientId: string): void {\n\t\tif (this._currentClientId !== clientId) {\n\t\t\tconst oldId = this._currentClientId;\n\t\t\tthis._currentClientId = clientId;\n\t\t\t// this.getMember(clientId) could resolve to undefined in these two cases:\n\t\t\t// 1) Feature gates controlling ConnectionStateHandler() behavior are off\n\t\t\t// 2) we are loading from stashed state and audience is empty, but we remember and set prior clientId\n\t\t\tthis.emit(\n\t\t\t\t\"selfChanged\",\n\t\t\t\toldId === undefined ? undefined : ({ clientId: oldId } satisfies ISelf),\n\t\t\t\t{ clientId, client: this.getMember(clientId) } satisfies ISelf,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a new client to the audience\n\t */\n\tpublic addMember(clientId: string, details: IClient) {\n\t\t// Given that signal delivery is unreliable process, we might observe same client being added twice\n\t\t// In such case we should see exactly same payload (IClient), and should not raise event twice!\n\t\tif (this.members.has(clientId)) {\n\t\t\tconst client = this.members.get(clientId);\n\t\t\tassert(\n\t\t\t\tJSON.stringify(client) === JSON.stringify(details),\n\t\t\t\t0x4b2 /* new client has different payload from existing one */,\n\t\t\t);\n\t\t} else {\n\t\t\tthis.members.set(clientId, details);\n\t\t\tthis.emit(\"addMember\", clientId, details);\n\t\t}\n\t}\n\n\t/**\n\t * Removes a client from the audience. Only emits an event if a client is actually removed\n\t * @returns if a client was removed from the audience\n\t */\n\tpublic removeMember(clientId: string): boolean {\n\t\tconst removedClient = this.members.get(clientId);\n\t\tif (removedClient !== undefined) {\n\t\t\tthis.members.delete(clientId);\n\t\t\tthis.emit(\"removeMember\", clientId, removedClient);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves all the members in the audience.\n\t *\n\t * @remarks When the container is disconnected, this will keep returning the audience as it was last seen before the\n\t * container disconnected.\n\t */\n\tpublic getMembers(): Map<string, IClient> {\n\t\treturn new Map(this.members);\n\t}\n\n\t/**\n\t * Retrieves a specific member of the audience.\n\t *\n\t * @remarks When the container is disconnected, this will keep returning members from the audience as it was last seen\n\t * before the container disconnected.\n\t */\n\tpublic getMember(clientId: string): IClient | undefined {\n\t\treturn this.members.get(clientId);\n\t}\n}\n"]}
@@ -6,8 +6,8 @@ import { ICriticalContainerError, IDeltaQueue, ReadOnlyInfo } from "@fluidframew
6
6
  import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
7
7
  import { IDocumentService } from "@fluidframework/driver-definitions/internal";
8
8
  import { ConnectionMode, IClient, IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
9
- import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
10
- import { IConnectionManager, IConnectionManagerFactoryArgs, IConnectionStateChangeReason, ReconnectMode } from "./contracts.js";
9
+ import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
10
+ import { IConnectionDetailsInternal, IConnectionManager, IConnectionManagerFactoryArgs, IConnectionStateChangeReason, ReconnectMode } from "./contracts.js";
11
11
  /**
12
12
  * Implementation of IConnectionManager, used by Container class
13
13
  * Implements constant connectivity to relay service, by reconnecting in case of lost connection or error.
@@ -28,6 +28,8 @@ export declare class ConnectionManager implements IConnectionManager {
28
28
  */
29
29
  private pendingConnection;
30
30
  private connection;
31
+ /** Details about connection. undefined if there is no active connection. */
32
+ private _connectionDetails?;
31
33
  /** file ACL - whether user has only read-only access to a file */
32
34
  private _readonlyPermissions;
33
35
  /** tracks host requiring read-only mode. */
@@ -57,6 +59,8 @@ export declare class ConnectionManager implements IConnectionManager {
57
59
  get connectionMode(): ConnectionMode;
58
60
  get connected(): boolean;
59
61
  get clientId(): string | undefined;
62
+ /** Details about connection. undefined if there is no active connection. */
63
+ get connectionDetails(): IConnectionDetailsInternal | undefined;
60
64
  /**
61
65
  * Automatic reconnecting enabled or disabled.
62
66
  * If set to Never, then reconnecting will never be allowed.
@@ -1 +1 @@
1
- {"version":3,"file":"connectionManager.d.ts","sourceRoot":"","sources":["../src/connectionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connectionManager.d.ts","sourceRoot":"","sources":["../src/connectionManager.ts"],"names":[],"mappings":"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"}
@@ -125,6 +125,10 @@ class ConnectionManager {
125
125
  get clientId() {
126
126
  return this.connection?.clientId;
127
127
  }
128
+ /** Details about connection. undefined if there is no active connection. */
129
+ get connectionDetails() {
130
+ return this._connectionDetails;
131
+ }
128
132
  /**
129
133
  * Automatic reconnecting enabled or disabled.
130
134
  * If set to Never, then reconnecting will never be allowed.
@@ -371,17 +375,7 @@ class ConnectionManager {
371
375
  }
372
376
  async connectCore(reason, connectionMode) {
373
377
  (0, internal_1.assert)(!this._disposed, 0x26a /* "not closed" */);
374
- if (this.connection !== undefined) {
375
- return; // Connection attempt already completed successfully
376
- }
377
- let pendingConnectionMode;
378
- if (this.pendingConnection !== undefined) {
379
- pendingConnectionMode = this.pendingConnection.connectionMode;
380
- this.cancelConnection(reason); // Throw out in-progress connection attempt in favor of new attempt
381
- (0, internal_1.assert)(this.pendingConnection === undefined, 0x344 /* this.pendingConnection should be undefined */);
382
- }
383
- // If there is no specified ConnectionMode, try the previous mode, if there is no previous mode use default
384
- let requestedMode = connectionMode ?? pendingConnectionMode ?? this.defaultReconnectionMode;
378
+ let requestedMode = connectionMode ?? this.defaultReconnectionMode;
385
379
  // if we have any non-acked ops from last connection, reconnect as "write".
386
380
  // without that we would connect in view-only mode, which will result in immediate
387
381
  // firing of "connected" event from Container and switch of current clientId (as tracked
@@ -390,8 +384,30 @@ class ConnectionManager {
390
384
  if (this.shouldJoinWrite()) {
391
385
  requestedMode = "write";
392
386
  }
387
+ if (this.connection !== undefined || this.pendingConnection !== undefined) {
388
+ // Connection attempt already completed successfully or is in progress
389
+ // In general, there should be no issues if the modes do not match:
390
+ // If at some point it was Ok to connect as "read" (i.e. there were no pending ops we had to track),
391
+ // then it should be Ok to use "read" connection even if for some reason request came in to connect as "write"
392
+ // (though that should never happen)
393
+ // The opposite should be fine as well: we may have had idle "write" connection, and request to reconnect came in,
394
+ // using default "read" mode.
395
+ // That all said, let's understand better where such mismatches are coming from.
396
+ const mode = this.connection?.mode ?? this.pendingConnection?.connectionMode;
397
+ if (mode !== requestedMode) {
398
+ this.logger.sendTelemetryEvent({
399
+ eventName: "ConnectionModeMismatch",
400
+ connected: this.connection !== undefined,
401
+ mode,
402
+ requestedMode,
403
+ stack: (0, internal_3.generateStack)(),
404
+ });
405
+ }
406
+ return;
407
+ }
393
408
  const docService = this.serviceProvider();
394
409
  (0, internal_1.assert)(docService !== undefined, 0x2a7 /* "Container is not attached" */);
410
+ this.props.establishConnectionHandler(reason);
395
411
  let connection;
396
412
  if (docService.policies?.storageOnly === true) {
397
413
  connection = new NoDeltaStream();
@@ -411,7 +427,6 @@ class ConnectionManager {
411
427
  },
412
428
  connectionMode: requestedMode,
413
429
  };
414
- this.props.establishConnectionHandler(reason);
415
430
  // This loop will keep trying to connect until successful, with a delay between each iteration.
416
431
  while (connection === undefined) {
417
432
  if (this._disposed) {
@@ -481,6 +496,11 @@ class ConnectionManager {
481
496
  duration: (0, internal_3.formatTick)(client_utils_1.performance.now() - connectStartTime),
482
497
  }, origError);
483
498
  lastError = origError;
499
+ // We will not perform retries if the container disconnected and the ReconnectMode is set to Disabled or Never
500
+ // so break out of the re-connecting while-loop after first attempt
501
+ if (this.reconnectMode !== contracts_js_1.ReconnectMode.Enabled) {
502
+ return;
503
+ }
484
504
  const waitStartTime = client_utils_1.performance.now();
485
505
  const retryDelayFromError = (0, internal_2.getRetryDelayFromError)(origError);
486
506
  // If the error told us to wait or browser signals us that we are offline, then calculate the time we
@@ -569,6 +589,7 @@ class ConnectionManager {
569
589
  const connection = this.connection;
570
590
  // Avoid any re-entrancy - clear object reference
571
591
  this.connection = undefined;
592
+ this._connectionDetails = undefined;
572
593
  // Remove listeners first so we don't try to retrigger this flow accidentally through reconnectOnError
573
594
  connection.off("op", this.opHandler);
574
595
  connection.off("signal", this.signalHandler);
@@ -591,7 +612,10 @@ class ConnectionManager {
591
612
  (0, internal_1.assert)(this.pendingConnection !== undefined, 0x345 /* this.pendingConnection is undefined when trying to cancel */);
592
613
  this.pendingConnection.abort();
593
614
  this.pendingConnection = undefined;
594
- this.logger.sendTelemetryEvent({ eventName: "ConnectionCancelReceived" });
615
+ this.logger.sendTelemetryEvent({
616
+ eventName: "ConnectionCancelReceived",
617
+ reason: reason.text,
618
+ });
595
619
  this.props.cancelConnectionHandler({
596
620
  text: `Cancel Pending Connection due to ${reason.text}`,
597
621
  error: reason.error,
@@ -670,9 +694,9 @@ class ConnectionManager {
670
694
  }
671
695
  }
672
696
  this.props.incomingOpHandler(initialMessages, this.connectFirstConnection ? "InitialOps" : "ReconnectOps");
673
- const details = ConnectionManager.detailsFromConnection(connection, reason);
674
- details.checkpointSequenceNumber = checkpointSequenceNumber;
675
- this.props.connectHandler(details);
697
+ this._connectionDetails = ConnectionManager.detailsFromConnection(connection, reason);
698
+ this._connectionDetails.checkpointSequenceNumber = checkpointSequenceNumber;
699
+ this.props.connectHandler(this._connectionDetails);
676
700
  this.connectFirstConnection = false;
677
701
  // Synthesize clear & join signals out of initialClients state.
678
702
  // This allows us to have single way to process signals, and makes it simpler to initialize