@fluidframework/container-loader 2.0.0-dev.2.2.0.111723 → 2.0.0-dev.2.3.0.115467

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 (60) hide show
  1. package/dist/audience.d.ts.map +1 -1
  2. package/dist/audience.js +6 -1
  3. package/dist/audience.js.map +1 -1
  4. package/dist/collabWindowTracker.js +5 -4
  5. package/dist/collabWindowTracker.js.map +1 -1
  6. package/dist/connectionManager.d.ts.map +1 -1
  7. package/dist/connectionManager.js +3 -0
  8. package/dist/connectionManager.js.map +1 -1
  9. package/dist/connectionStateHandler.js +4 -4
  10. package/dist/connectionStateHandler.js.map +1 -1
  11. package/dist/container.d.ts +8 -0
  12. package/dist/container.d.ts.map +1 -1
  13. package/dist/container.js +4 -3
  14. package/dist/container.js.map +1 -1
  15. package/dist/containerContext.d.ts.map +1 -1
  16. package/dist/containerContext.js +5 -1
  17. package/dist/containerContext.js.map +1 -1
  18. package/dist/contracts.d.ts +8 -0
  19. package/dist/contracts.d.ts.map +1 -1
  20. package/dist/contracts.js.map +1 -1
  21. package/dist/deltaManager.js +2 -2
  22. package/dist/deltaManager.js.map +1 -1
  23. package/dist/packageVersion.d.ts +1 -1
  24. package/dist/packageVersion.js +1 -1
  25. package/dist/packageVersion.js.map +1 -1
  26. package/lib/audience.d.ts.map +1 -1
  27. package/lib/audience.js +6 -1
  28. package/lib/audience.js.map +1 -1
  29. package/lib/collabWindowTracker.js +5 -4
  30. package/lib/collabWindowTracker.js.map +1 -1
  31. package/lib/connectionManager.d.ts.map +1 -1
  32. package/lib/connectionManager.js +3 -0
  33. package/lib/connectionManager.js.map +1 -1
  34. package/lib/connectionStateHandler.js +4 -4
  35. package/lib/connectionStateHandler.js.map +1 -1
  36. package/lib/container.d.ts +8 -0
  37. package/lib/container.d.ts.map +1 -1
  38. package/lib/container.js +3 -3
  39. package/lib/container.js.map +1 -1
  40. package/lib/containerContext.d.ts.map +1 -1
  41. package/lib/containerContext.js +5 -1
  42. package/lib/containerContext.js.map +1 -1
  43. package/lib/contracts.d.ts +8 -0
  44. package/lib/contracts.d.ts.map +1 -1
  45. package/lib/contracts.js.map +1 -1
  46. package/lib/deltaManager.js +2 -2
  47. package/lib/deltaManager.js.map +1 -1
  48. package/lib/packageVersion.d.ts +1 -1
  49. package/lib/packageVersion.js +1 -1
  50. package/lib/packageVersion.js.map +1 -1
  51. package/package.json +15 -15
  52. package/src/audience.ts +6 -1
  53. package/src/collabWindowTracker.ts +5 -5
  54. package/src/connectionManager.ts +4 -1
  55. package/src/connectionStateHandler.ts +4 -4
  56. package/src/container.ts +3 -3
  57. package/src/containerContext.ts +8 -2
  58. package/src/contracts.ts +8 -0
  59. package/src/deltaManager.ts +2 -2
  60. package/src/packageVersion.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-loader",
3
- "version": "2.0.0-dev.2.2.0.111723",
3
+ "version": "2.0.0-dev.2.3.0.115467",
4
4
  "description": "Fluid container loader",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -65,14 +65,14 @@
65
65
  "dependencies": {
66
66
  "@fluidframework/common-definitions": "^0.20.1",
67
67
  "@fluidframework/common-utils": "^1.0.0",
68
- "@fluidframework/container-definitions": ">=2.0.0-dev.2.2.0.111723 <2.0.0-dev.3.0.0",
69
- "@fluidframework/container-utils": ">=2.0.0-dev.2.2.0.111723 <2.0.0-dev.3.0.0",
70
- "@fluidframework/core-interfaces": ">=2.0.0-dev.2.2.0.111723 <2.0.0-dev.3.0.0",
71
- "@fluidframework/driver-definitions": ">=2.0.0-dev.2.2.0.111723 <2.0.0-dev.3.0.0",
72
- "@fluidframework/driver-utils": ">=2.0.0-dev.2.2.0.111723 <2.0.0-dev.3.0.0",
68
+ "@fluidframework/container-definitions": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0",
69
+ "@fluidframework/container-utils": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0",
70
+ "@fluidframework/core-interfaces": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0",
71
+ "@fluidframework/driver-definitions": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0",
72
+ "@fluidframework/driver-utils": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0",
73
73
  "@fluidframework/protocol-base": "^0.1038.2000",
74
74
  "@fluidframework/protocol-definitions": "^1.1.0",
75
- "@fluidframework/telemetry-utils": ">=2.0.0-dev.2.2.0.111723 <2.0.0-dev.3.0.0",
75
+ "@fluidframework/telemetry-utils": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0",
76
76
  "abort-controller": "^3.0.0",
77
77
  "double-ended-queue": "^2.1.0-0",
78
78
  "lodash": "^4.17.21",
@@ -80,13 +80,13 @@
80
80
  "uuid": "^8.3.1"
81
81
  },
82
82
  "devDependencies": {
83
- "@fluid-tools/build-cli": "^0.6.0-109663",
83
+ "@fluid-tools/build-cli": "^0.7.0",
84
84
  "@fluidframework/build-common": "^1.1.0",
85
- "@fluidframework/build-tools": "^0.6.0-109663",
86
- "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.2.1.0",
85
+ "@fluidframework/build-tools": "^0.7.0",
86
+ "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.2.2.0",
87
87
  "@fluidframework/eslint-config-fluid": "^1.2.0",
88
- "@fluidframework/mocha-test-setup": ">=2.0.0-dev.2.2.0.111723 <2.0.0-dev.3.0.0",
89
- "@fluidframework/test-loader-utils": ">=2.0.0-dev.2.2.0.111723 <2.0.0-dev.3.0.0",
88
+ "@fluidframework/mocha-test-setup": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0",
89
+ "@fluidframework/test-loader-utils": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0",
90
90
  "@microsoft/api-extractor": "^7.22.2",
91
91
  "@rushstack/eslint-config": "^2.5.1",
92
92
  "@types/double-ended-queue": "^2.1.0",
@@ -106,9 +106,9 @@
106
106
  "typescript": "~4.5.5"
107
107
  },
108
108
  "typeValidation": {
109
- "version": "2.0.0-internal.2.2.0",
110
- "baselineRange": ">=2.0.0-internal.2.1.0 <2.0.0-internal.2.2.0",
111
- "baselineVersion": "2.0.0-internal.2.1.0",
109
+ "version": "2.0.0-internal.2.3.0",
110
+ "baselineRange": ">=2.0.0-internal.2.2.0 <2.0.0-internal.2.3.0",
111
+ "baselineVersion": "2.0.0-internal.2.2.0",
112
112
  "broken": {}
113
113
  }
114
114
  }
package/src/audience.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { EventEmitter } from "events";
6
+ import { assert } from "@fluidframework/common-utils";
6
7
  import { IAudienceOwner } from "@fluidframework/container-definitions";
7
8
  import { IClient } from "@fluidframework/protocol-definitions";
8
9
 
@@ -23,7 +24,11 @@ export class Audience extends EventEmitter implements IAudienceOwner {
23
24
  public addMember(clientId: string, details: IClient) {
24
25
  // Given that signal delivery is unreliable process, we might observe same client being added twice
25
26
  // In such case we should see exactly same payload (IClient), and should not raise event twice!
26
- if (!this.members.has(clientId)) {
27
+ if (this.members.has(clientId)) {
28
+ const client = this.members.get(clientId);
29
+ assert(JSON.stringify(client) === JSON.stringify(details), 0x4b2 /* new client has different payload from existing one */);
30
+ }
31
+ else {
27
32
  this.members.set(clientId, details);
28
33
  this.emit("addMember", clientId, details);
29
34
  }
@@ -73,11 +73,11 @@ export class CollabWindowTracker {
73
73
  // Ensure we only send noop after a batch of many ops is processed
74
74
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
75
75
  Promise.resolve().then(() => {
76
- assert(this.opsCountSinceNoop >= this.NoopCountFrequency,
77
- 0x3ae /* not enough ops were sent to reach the noop frequency */);
78
- this.submitNoop(false /* immediate */);
79
- // reset count now that all ops are processed
80
- this.opsCountSinceNoop = 0;
76
+ if (this.opsCountSinceNoop >= this.NoopCountFrequency) {
77
+ this.submitNoop(false /* immediate */);
78
+ // reset count now that all ops are processed
79
+ this.opsCountSinceNoop = 0;
80
+ }
81
81
  return;
82
82
  });
83
83
  }
@@ -267,7 +267,7 @@ export class ConnectionManager implements IConnectionManager {
267
267
  * It is undefined if we have not yet established websocket connection
268
268
  * and do not know if user has write access to a file.
269
269
  */
270
- private get readonly() {
270
+ private get readonly(): boolean | undefined {
271
271
  if (this._forceReadonly) {
272
272
  return true;
273
273
  }
@@ -665,6 +665,9 @@ export class ConnectionManager implements IConnectionManager {
665
665
  // But if we ask read, server can still give us write.
666
666
  const readonly = !connection.claims.scopes.includes(ScopeType.DocWrite);
667
667
 
668
+ if (connection.mode !== requestedMode) {
669
+ this.logger.sendTelemetryEvent({ eventName: "ConnectionModeMismatch", requestedMode, mode: connection.mode });
670
+ }
668
671
  // This connection mode validation logic is moving to the driver layer in 0.44. These two asserts can be
669
672
  // removed after those packages have released and become ubiquitous.
670
673
  assert(requestedMode === "read" || readonly === (this.connectionMode === "read"),
@@ -288,7 +288,7 @@ class ConnectionStateHandler implements IConnectionStateHandler {
288
288
 
289
289
  private startJoinOpTimer() {
290
290
  assert(!this.joinOpTimer.hasTimer, 0x234 /* "has joinOpTimer" */);
291
- assert(this.connection !== undefined, "have connection");
291
+ assert(this.connection !== undefined, 0x4b3 /* have connection */);
292
292
  this.joinOpTimer.start(
293
293
  this.connection.mode === "write" ? JoinOpTimeoutMs : JoinSignalTimeoutMs,
294
294
  );
@@ -388,7 +388,7 @@ class ConnectionStateHandler implements IConnectionStateHandler {
388
388
  }
389
389
 
390
390
  private shouldWaitForJoinSignal() {
391
- assert(this.connection !== undefined, "all callers call here with active connection");
391
+ assert(this.connection !== undefined, 0x4b4 /* all callers call here with active connection */);
392
392
  return this.connection.mode === "write" || this.readClientsWaitForJoinSignal;
393
393
  }
394
394
 
@@ -525,12 +525,12 @@ class ConnectionStateHandler implements IConnectionStateHandler {
525
525
 
526
526
  this.membership?.on("addMember", (clientId, details) => {
527
527
  assert((details as IClient).mode === "read" || protocol.quorum.getMember(clientId) !== undefined,
528
- "Audience is subset of quorum");
528
+ 0x4b5 /* Audience is subset of quorum */);
529
529
  this.receivedAddMemberEvent(clientId);
530
530
  });
531
531
 
532
532
  this.membership?.on("removeMember", (clientId) => {
533
- assert(protocol.quorum.getMember(clientId) === undefined, "Audience is subset of quorum");
533
+ assert(protocol.quorum.getMember(clientId) === undefined, 0x4b6 /* Audience is subset of quorum */);
534
534
  this.receivedRemoveMemberEvent(clientId);
535
535
  });
536
536
 
package/src/container.ts CHANGED
@@ -241,14 +241,14 @@ const getCodeProposal =
241
241
  * @param eventName - event name
242
242
  * @param action - functor to call and measure
243
243
  */
244
- async function ReportIfTooLong(
244
+ export async function ReportIfTooLong(
245
245
  logger: ITelemetryLogger,
246
246
  eventName: string,
247
247
  action: () => Promise<ITelemetryProperties>,
248
248
  ) {
249
249
  const event = PerformanceEvent.start(logger, { eventName });
250
250
  const props = await action();
251
- if (event.duration > 1000) {
251
+ if (event.duration > 200) {
252
252
  event.end(props);
253
253
  }
254
254
  }
@@ -1525,7 +1525,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1525
1525
  deltaManager.inboundSignal.pause();
1526
1526
 
1527
1527
  deltaManager.on("connect", (details: IConnectionDetails, _opsBehind?: number) => {
1528
- assert(this.connectionMode === details.mode, "mismatch");
1528
+ assert(this.connectionMode === details.mode, 0x4b7 /* mismatch */);
1529
1529
  this.connectionStateHandler.receivedConnectEvent(
1530
1530
  details,
1531
1531
  );
@@ -46,7 +46,7 @@ import {
46
46
  ISummaryContent,
47
47
  } from "@fluidframework/protocol-definitions";
48
48
  import { PerformanceEvent } from "@fluidframework/telemetry-utils";
49
- import { Container } from "./container";
49
+ import { Container, ReportIfTooLong } from "./container";
50
50
 
51
51
  const PackageNotFactoryError = "Code package does not implement IRuntimeFactory";
52
52
 
@@ -324,7 +324,13 @@ export class ContainerContext implements IContainerContext {
324
324
 
325
325
  private async instantiateRuntime(existing: boolean) {
326
326
  const runtimeFactory = await this.getRuntimeFactory();
327
- this._runtime = await runtimeFactory.instantiateRuntime(this, existing);
327
+ await ReportIfTooLong(
328
+ this.taggedLogger,
329
+ "instantiateRuntime",
330
+ async () => {
331
+ this._runtime = await runtimeFactory.instantiateRuntime(this, existing);
332
+ return {};
333
+ });
328
334
  }
329
335
 
330
336
  private attachListener() {
package/src/contracts.ts CHANGED
@@ -148,15 +148,23 @@ export interface IConnectionManagerFactoryArgs {
148
148
 
149
149
  /**
150
150
  * Called whenever ping/pong messages are roundtripped on connection.
151
+ *
152
+ * @deprecated No replacement API intended.
151
153
  */
152
154
  readonly pongHandler: (latency: number) => void;
153
155
 
154
156
  /**
155
157
  * Called whenever connection type changes from writable to read-only or vice versa.
158
+ *
159
+ * @remarks
160
+ *
156
161
  * Connection can be read-only if user has no edit permissions, or if container forced
157
162
  * connection to be read-only.
158
163
  * This should not be confused with "read" / "write"connection mode which is internal
159
164
  * optimization.
165
+ *
166
+ * @param readonly - Whether or not the container is now read-only.
167
+ * `undefined` indicates that user permissions are not yet known.
160
168
  */
161
169
  readonly readonlyChangeHandler: (readonly?: boolean) => void;
162
170
  }
@@ -118,8 +118,8 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
118
118
  // There are three numbers we track
119
119
  // * lastQueuedSequenceNumber is the last queued sequence number. If there are gaps in seq numbers, then this number
120
120
  // is not updated until we cover that gap, so it increases each time by 1.
121
- // * lastObservedSeqNumber is an estimation of last known sequence number for container in storage. It's initially
122
- // populated at web socket connection time (if storage provides that info) and is updated once ops shows up.
121
+ // * lastObservedSeqNumber is an estimation of last known sequence number for container in storage. It's initially
122
+ // populated at web socket connection time (if storage provides that info) and is updated once ops shows up.
123
123
  // It's never less than lastQueuedSequenceNumber
124
124
  // * lastProcessedSequenceNumber - last processed sequence number
125
125
  private lastQueuedSequenceNumber: number = 0;
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-loader";
9
- export const pkgVersion = "2.0.0-dev.2.2.0.111723";
9
+ export const pkgVersion = "2.0.0-dev.2.3.0.115467";