@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.
- package/dist/audience.d.ts.map +1 -1
- package/dist/audience.js +6 -1
- package/dist/audience.js.map +1 -1
- package/dist/collabWindowTracker.js +5 -4
- package/dist/collabWindowTracker.js.map +1 -1
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +3 -0
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.js +4 -4
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +8 -0
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +4 -3
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +5 -1
- package/dist/containerContext.js.map +1 -1
- package/dist/contracts.d.ts +8 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deltaManager.js +2 -2
- package/dist/deltaManager.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/audience.d.ts.map +1 -1
- package/lib/audience.js +6 -1
- package/lib/audience.js.map +1 -1
- package/lib/collabWindowTracker.js +5 -4
- package/lib/collabWindowTracker.js.map +1 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +3 -0
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.js +4 -4
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +8 -0
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +3 -3
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +5 -1
- package/lib/containerContext.js.map +1 -1
- package/lib/contracts.d.ts +8 -0
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/deltaManager.js +2 -2
- package/lib/deltaManager.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/package.json +15 -15
- package/src/audience.ts +6 -1
- package/src/collabWindowTracker.ts +5 -5
- package/src/connectionManager.ts +4 -1
- package/src/connectionStateHandler.ts +4 -4
- package/src/container.ts +3 -3
- package/src/containerContext.ts +8 -2
- package/src/contracts.ts +8 -0
- package/src/deltaManager.ts +2 -2
- 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.
|
|
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.
|
|
69
|
-
"@fluidframework/container-utils": ">=2.0.0-dev.2.
|
|
70
|
-
"@fluidframework/core-interfaces": ">=2.0.0-dev.2.
|
|
71
|
-
"@fluidframework/driver-definitions": ">=2.0.0-dev.2.
|
|
72
|
-
"@fluidframework/driver-utils": ">=2.0.0-dev.2.
|
|
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.
|
|
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.
|
|
83
|
+
"@fluid-tools/build-cli": "^0.7.0",
|
|
84
84
|
"@fluidframework/build-common": "^1.1.0",
|
|
85
|
-
"@fluidframework/build-tools": "^0.
|
|
86
|
-
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.2.
|
|
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.
|
|
89
|
-
"@fluidframework/test-loader-utils": ">=2.0.0-dev.2.
|
|
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.
|
|
110
|
-
"baselineRange": ">=2.0.0-internal.2.
|
|
111
|
-
"baselineVersion": "2.0.0-internal.2.
|
|
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 (
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
}
|
package/src/connectionManager.ts
CHANGED
|
@@ -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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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 >
|
|
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,
|
|
1528
|
+
assert(this.connectionMode === details.mode, 0x4b7 /* mismatch */);
|
|
1529
1529
|
this.connectionStateHandler.receivedConnectEvent(
|
|
1530
1530
|
details,
|
|
1531
1531
|
);
|
package/src/containerContext.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
}
|
package/src/deltaManager.ts
CHANGED
|
@@ -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
|
|
122
|
-
// populated at web socket connection time (if storage provides that info) and is
|
|
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;
|
package/src/packageVersion.ts
CHANGED