@fluidframework/container-loader 2.0.0-dev.1.3.0.96595 → 2.0.0-dev.1.4.5.105745
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 +4 -0
- package/dist/audience.d.ts.map +1 -1
- package/dist/audience.js +11 -6
- package/dist/audience.js.map +1 -1
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +4 -30
- package/dist/connectionManager.js.map +1 -1
- package/dist/container.d.ts +1 -0
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +17 -2
- package/dist/container.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/protocol.d.ts +3 -8
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +8 -34
- package/dist/protocol.js.map +1 -1
- package/lib/audience.d.ts +4 -0
- package/lib/audience.d.ts.map +1 -1
- package/lib/audience.js +11 -6
- package/lib/audience.js.map +1 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +4 -30
- package/lib/connectionManager.js.map +1 -1
- package/lib/container.d.ts +1 -0
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +17 -2
- package/lib/container.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/protocol.d.ts +3 -8
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +7 -33
- package/lib/protocol.js.map +1 -1
- package/package.json +10 -10
- package/src/audience.ts +12 -6
- package/src/connectionManager.ts +6 -33
- package/src/container.ts +19 -0
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +8 -31
package/lib/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/container-loader";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-dev.1.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-dev.1.4.5.105745";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,qCAAqC,CAAC;AAC1D,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,qCAAqC,CAAC;AAC1D,eAAO,MAAM,UAAU,2BAA2B,CAAC"}
|
package/lib/packageVersion.js
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export const pkgName = "@fluidframework/container-loader";
|
|
8
|
-
export const pkgVersion = "2.0.0-dev.1.
|
|
8
|
+
export const pkgVersion = "2.0.0-dev.1.4.5.105745";
|
|
9
9
|
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,kCAAkC,CAAC;AAC1D,MAAM,CAAC,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,kCAAkC,CAAC;AAC1D,MAAM,CAAC,MAAM,UAAU,GAAG,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-loader\";\nexport const pkgVersion = \"2.0.0-dev.1.4.5.105745\";\n"]}
|
package/lib/protocol.d.ts
CHANGED
|
@@ -4,23 +4,18 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { IAudienceOwner } from "@fluidframework/container-definitions";
|
|
6
6
|
import { IProtocolHandler as IBaseProtocolHandler, IQuorumSnapshot, ProtocolOpHandler } from "@fluidframework/protocol-base";
|
|
7
|
-
import { IDocumentAttributes, IProcessMessageResult, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/protocol-definitions";
|
|
8
|
-
export declare enum SignalType {
|
|
9
|
-
ClientJoin = "join",
|
|
10
|
-
ClientLeave = "leave",
|
|
11
|
-
Clear = "clear"
|
|
12
|
-
}
|
|
7
|
+
import { IDocumentAttributes, IProcessMessageResult, ISequencedDocumentMessage, ISignalClient, ISignalMessage } from "@fluidframework/protocol-definitions";
|
|
13
8
|
/**
|
|
14
9
|
* Function to be used for creating a protocol handler.
|
|
15
10
|
*/
|
|
16
|
-
export declare type ProtocolHandlerBuilder = (attributes: IDocumentAttributes, snapshot: IQuorumSnapshot, sendProposal: (key: string, value: any) => number) => IProtocolHandler;
|
|
11
|
+
export declare type ProtocolHandlerBuilder = (attributes: IDocumentAttributes, snapshot: IQuorumSnapshot, sendProposal: (key: string, value: any) => number, initialClients: ISignalClient[]) => IProtocolHandler;
|
|
17
12
|
export interface IProtocolHandler extends IBaseProtocolHandler {
|
|
18
13
|
readonly audience: IAudienceOwner;
|
|
19
14
|
processSignal(message: ISignalMessage): any;
|
|
20
15
|
}
|
|
21
16
|
export declare class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {
|
|
22
17
|
readonly audience: IAudienceOwner;
|
|
23
|
-
constructor(attributes: IDocumentAttributes, quorumSnapshot: IQuorumSnapshot, sendProposal: (key: string, value: any) => number, audience: IAudienceOwner);
|
|
18
|
+
constructor(attributes: IDocumentAttributes, quorumSnapshot: IQuorumSnapshot, sendProposal: (key: string, value: any) => number, initialClients: ISignalClient[], audience: IAudienceOwner);
|
|
24
19
|
processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult;
|
|
25
20
|
processSignal(message: ISignalMessage): void;
|
|
26
21
|
}
|
package/lib/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAEH,gBAAgB,IAAI,oBAAoB,EACxC,eAAe,EACf,iBAAiB,EACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACH,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAEH,gBAAgB,IAAI,oBAAoB,EACxC,eAAe,EACf,iBAAiB,EACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACH,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,aAAa,EACb,cAAc,EAEjB,MAAM,sCAAsC,CAAC;AAG9C;;GAEG;AACH,oBAAY,sBAAsB,GAAG,CACjC,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,EACjD,cAAc,EAAE,aAAa,EAAE,KAC9B,gBAAgB,CAAC;AAEtB,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC1D,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,aAAa,CAAC,OAAO,EAAE,cAAc,OAAE;CAC1C;AAED,qBAAa,eAAgB,SAAQ,iBAAkB,YAAW,gBAAgB;IAM1E,QAAQ,CAAC,QAAQ,EAAE,cAAc;gBAJjC,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,EACjD,cAAc,EAAE,aAAa,EAAE,EACtB,QAAQ,EAAE,cAAc;IAiB9B,cAAc,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,GAAG,qBAAqB;IAoBzF,aAAa,CAAC,OAAO,EAAE,cAAc;CAgB/C"}
|
package/lib/protocol.js
CHANGED
|
@@ -5,22 +5,12 @@
|
|
|
5
5
|
import { ProtocolOpHandler, } from "@fluidframework/protocol-base";
|
|
6
6
|
import { MessageType, } from "@fluidframework/protocol-definitions";
|
|
7
7
|
import { canBeCoalescedByService } from "@fluidframework/driver-utils";
|
|
8
|
-
// ADO: #1986: Start using enum from protocol-base.
|
|
9
|
-
export var SignalType;
|
|
10
|
-
(function (SignalType) {
|
|
11
|
-
SignalType["ClientJoin"] = "join";
|
|
12
|
-
SignalType["ClientLeave"] = "leave";
|
|
13
|
-
SignalType["Clear"] = "clear";
|
|
14
|
-
})(SignalType || (SignalType = {}));
|
|
15
8
|
export class ProtocolHandler extends ProtocolOpHandler {
|
|
16
|
-
constructor(attributes, quorumSnapshot, sendProposal, audience) {
|
|
9
|
+
constructor(attributes, quorumSnapshot, sendProposal, initialClients, audience) {
|
|
17
10
|
super(attributes.minimumSequenceNumber, attributes.sequenceNumber, attributes.term, quorumSnapshot.members, quorumSnapshot.proposals, quorumSnapshot.values, sendProposal);
|
|
18
11
|
this.audience = audience;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.quorum.on("removeMember", (clientId) => audience.removeMember(clientId));
|
|
22
|
-
for (const [clientId, details] of this.quorum.getMembers()) {
|
|
23
|
-
this.audience.addMember(clientId, details.client);
|
|
12
|
+
for (const initialClient of initialClients) {
|
|
13
|
+
this.audience.addMember(initialClient.clientId, initialClient.client);
|
|
24
14
|
}
|
|
25
15
|
}
|
|
26
16
|
processMessage(message, local) {
|
|
@@ -40,32 +30,16 @@ export class ProtocolHandler extends ProtocolOpHandler {
|
|
|
40
30
|
return super.processMessage(message, local);
|
|
41
31
|
}
|
|
42
32
|
processSignal(message) {
|
|
43
|
-
var _a;
|
|
44
33
|
const innerContent = message.content;
|
|
45
34
|
switch (innerContent.type) {
|
|
46
|
-
case
|
|
47
|
-
const members = this.audience.getMembers();
|
|
48
|
-
for (const [clientId, client] of members) {
|
|
49
|
-
if (client.mode === "read") {
|
|
50
|
-
this.audience.removeMember(clientId);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
case SignalType.ClientJoin: {
|
|
35
|
+
case MessageType.ClientJoin: {
|
|
56
36
|
const newClient = innerContent.content;
|
|
57
|
-
|
|
58
|
-
if (newClient.client.mode === "read") {
|
|
59
|
-
this.audience.addMember(newClient.clientId, newClient.client);
|
|
60
|
-
}
|
|
37
|
+
this.audience.addMember(newClient.clientId, newClient.client);
|
|
61
38
|
break;
|
|
62
39
|
}
|
|
63
|
-
case
|
|
40
|
+
case MessageType.ClientLeave: {
|
|
64
41
|
const leftClientId = innerContent.content;
|
|
65
|
-
|
|
66
|
-
if (((_a = this.audience.getMember(leftClientId)) === null || _a === void 0 ? void 0 : _a.mode) === "read") {
|
|
67
|
-
this.audience.removeMember(leftClientId);
|
|
68
|
-
}
|
|
42
|
+
this.audience.removeMember(leftClientId);
|
|
69
43
|
break;
|
|
70
44
|
}
|
|
71
45
|
default: break;
|
package/lib/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAIH,iBAAiB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAMH,WAAW,GACd,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAIH,iBAAiB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAMH,WAAW,GACd,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAiBvE,MAAM,OAAO,eAAgB,SAAQ,iBAAiB;IAClD,YACI,UAA+B,EAC/B,cAA+B,EAC/B,YAAiD,EACjD,cAA+B,EACtB,QAAwB;QAEjC,KAAK,CACD,UAAU,CAAC,qBAAqB,EAChC,UAAU,CAAC,cAAc,EACzB,UAAU,CAAC,IAAI,EACf,cAAc,CAAC,OAAO,EACtB,cAAc,CAAC,SAAS,EACxB,cAAc,CAAC,MAAM,EACrB,YAAY,CACf,CAAC;QAVO,aAAQ,GAAR,QAAQ,CAAgB;QAYjC,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE;YACxC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;SACzE;IACL,CAAC;IAEM,cAAc,CAAC,OAAkC,EAAE,KAAc;QACpE,MAAM,MAAM,GAAsC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAE1F,gFAAgF;QAChF,qFAAqF;QACrF,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE;YAC1B,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,UAAU,EAAE;gBACjE,2DAA2D;gBAC3D,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;aAC3E;YAED,IAAI,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,cAAc,MAAK,IAAI,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE;gBACtE,wDAAwD;gBACxD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;aACzE;SACJ;QAED,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;IAEM,aAAa,CAAC,OAAuB;QACxC,MAAM,YAAY,GAAG,OAAO,CAAC,OAA0C,CAAC;QACxE,QAAQ,YAAY,CAAC,IAAI,EAAE;YACvB,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC;gBACzB,MAAM,SAAS,GAAG,YAAY,CAAC,OAAwB,CAAC;gBACxD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;gBAC9D,MAAM;aACT;YACD,KAAK,WAAW,CAAC,WAAW,CAAC,CAAC;gBAC1B,MAAM,YAAY,GAAG,YAAY,CAAC,OAAiB,CAAC;gBACpD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;gBACzC,MAAM;aACT;YACD,OAAO,CAAC,CAAC,MAAM;SAClB;IACL,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IAudienceOwner } from \"@fluidframework/container-definitions\";\nimport {\n ILocalSequencedClient,\n IProtocolHandler as IBaseProtocolHandler,\n IQuorumSnapshot,\n ProtocolOpHandler,\n} from \"@fluidframework/protocol-base\";\nimport {\n IDocumentAttributes,\n IProcessMessageResult,\n ISequencedDocumentMessage,\n ISignalClient,\n ISignalMessage,\n MessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils\";\n\n/**\n * Function to be used for creating a protocol handler.\n */\nexport type ProtocolHandlerBuilder = (\n attributes: IDocumentAttributes,\n snapshot: IQuorumSnapshot,\n sendProposal: (key: string, value: any) => number,\n initialClients: ISignalClient[],\n) => IProtocolHandler;\n\nexport interface IProtocolHandler extends IBaseProtocolHandler {\n readonly audience: IAudienceOwner;\n processSignal(message: ISignalMessage);\n}\n\nexport class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {\n constructor(\n attributes: IDocumentAttributes,\n quorumSnapshot: IQuorumSnapshot,\n sendProposal: (key: string, value: any) => number,\n initialClients: ISignalClient[],\n readonly audience: IAudienceOwner,\n ) {\n super(\n attributes.minimumSequenceNumber,\n attributes.sequenceNumber,\n attributes.term,\n quorumSnapshot.members,\n quorumSnapshot.proposals,\n quorumSnapshot.values,\n sendProposal,\n );\n\n for (const initialClient of initialClients) {\n this.audience.addMember(initialClient.clientId, initialClient.client);\n }\n }\n\n public processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult {\n const client: ILocalSequencedClient | undefined = this.quorum.getMember(message.clientId);\n\n // Check and report if we're getting messages from a clientId that we previously\n // flagged as shouldHaveLeft, or from a client that's not in the quorum but should be\n if (message.clientId != null) {\n if (client === undefined && message.type !== MessageType.ClientJoin) {\n // pre-0.58 error message: messageClientIdMissingFromQuorum\n throw new Error(\"Remote message's clientId is missing from the quorum\");\n }\n\n if (client?.shouldHaveLeft === true && !canBeCoalescedByService(message)) {\n // pre-0.58 error message: messageClientIdShouldHaveLeft\n throw new Error(\"Remote message's clientId already should have left\");\n }\n }\n\n return super.processMessage(message, local);\n }\n\n public processSignal(message: ISignalMessage) {\n const innerContent = message.content as { content: any; type: string; };\n switch (innerContent.type) {\n case MessageType.ClientJoin: {\n const newClient = innerContent.content as ISignalClient;\n this.audience.addMember(newClient.clientId, newClient.client);\n break;\n }\n case MessageType.ClientLeave: {\n const leftClientId = innerContent.content as string;\n this.audience.removeMember(leftClientId);\n break;\n }\n default: break;\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-loader",
|
|
3
|
-
"version": "2.0.0-dev.1.
|
|
3
|
+
"version": "2.0.0-dev.1.4.5.105745",
|
|
4
4
|
"description": "Fluid container loader",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -63,14 +63,14 @@
|
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
65
65
|
"@fluidframework/common-utils": "^1.0.0",
|
|
66
|
-
"@fluidframework/container-definitions": "2.0.0-dev.1.
|
|
67
|
-
"@fluidframework/container-utils": "2.0.0-dev.1.
|
|
68
|
-
"@fluidframework/core-interfaces": "2.0.0-dev.1.
|
|
69
|
-
"@fluidframework/driver-definitions": "2.0.0-dev.1.
|
|
70
|
-
"@fluidframework/driver-utils": "2.0.0-dev.1.
|
|
66
|
+
"@fluidframework/container-definitions": "2.0.0-dev.1.4.5.105745",
|
|
67
|
+
"@fluidframework/container-utils": "2.0.0-dev.1.4.5.105745",
|
|
68
|
+
"@fluidframework/core-interfaces": "2.0.0-dev.1.4.5.105745",
|
|
69
|
+
"@fluidframework/driver-definitions": "2.0.0-dev.1.4.5.105745",
|
|
70
|
+
"@fluidframework/driver-utils": "2.0.0-dev.1.4.5.105745",
|
|
71
71
|
"@fluidframework/protocol-base": "^0.1037.2001",
|
|
72
72
|
"@fluidframework/protocol-definitions": "^1.0.0",
|
|
73
|
-
"@fluidframework/telemetry-utils": "2.0.0-dev.1.
|
|
73
|
+
"@fluidframework/telemetry-utils": "2.0.0-dev.1.4.5.105745",
|
|
74
74
|
"abort-controller": "^3.0.0",
|
|
75
75
|
"double-ended-queue": "^2.1.0-0",
|
|
76
76
|
"lodash": "^4.17.21",
|
|
@@ -79,11 +79,11 @@
|
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@fluidframework/build-common": "^1.0.0",
|
|
82
|
-
"@fluidframework/build-tools": "^0.4.
|
|
82
|
+
"@fluidframework/build-tools": "^0.4.4000",
|
|
83
83
|
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@^1.0.0",
|
|
84
84
|
"@fluidframework/eslint-config-fluid": "^1.0.0",
|
|
85
|
-
"@fluidframework/mocha-test-setup": "2.0.0-dev.1.
|
|
86
|
-
"@fluidframework/test-loader-utils": "2.0.0-dev.1.
|
|
85
|
+
"@fluidframework/mocha-test-setup": "2.0.0-dev.1.4.5.105745",
|
|
86
|
+
"@fluidframework/test-loader-utils": "2.0.0-dev.1.4.5.105745",
|
|
87
87
|
"@microsoft/api-extractor": "^7.22.2",
|
|
88
88
|
"@rushstack/eslint-config": "^2.5.1",
|
|
89
89
|
"@types/double-ended-queue": "^2.1.0",
|
package/src/audience.ts
CHANGED
|
@@ -21,12 +21,8 @@ export class Audience extends EventEmitter implements IAudienceOwner {
|
|
|
21
21
|
* Adds a new client to the audience
|
|
22
22
|
*/
|
|
23
23
|
public addMember(clientId: string, details: IClient) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (!this.members.has(clientId)) {
|
|
27
|
-
this.members.set(clientId, details);
|
|
28
|
-
this.emit("addMember", clientId, details);
|
|
29
|
-
}
|
|
24
|
+
this.members.set(clientId, details);
|
|
25
|
+
this.emit("addMember", clientId, details);
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
/**
|
|
@@ -57,4 +53,14 @@ export class Audience extends EventEmitter implements IAudienceOwner {
|
|
|
57
53
|
public getMember(clientId: string): IClient | undefined {
|
|
58
54
|
return this.members.get(clientId);
|
|
59
55
|
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Clears the audience
|
|
59
|
+
*/
|
|
60
|
+
public clear(): void {
|
|
61
|
+
const clientIds = this.members.keys();
|
|
62
|
+
for (const clientId of clientIds) {
|
|
63
|
+
this.removeMember(clientId);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
60
66
|
}
|
package/src/connectionManager.ts
CHANGED
|
@@ -59,7 +59,6 @@ import {
|
|
|
59
59
|
IConnectionManagerFactoryArgs,
|
|
60
60
|
} from "./contracts";
|
|
61
61
|
import { DeltaQueue } from "./deltaQueue";
|
|
62
|
-
import { SignalType } from "./protocol";
|
|
63
62
|
|
|
64
63
|
const MaxReconnectDelayInMs = 8000;
|
|
65
64
|
const InitialReconnectDelayInMs = 1000;
|
|
@@ -714,43 +713,17 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
714
713
|
initialMessages,
|
|
715
714
|
this.connectFirstConnection ? "InitialOps" : "ReconnectOps");
|
|
716
715
|
|
|
717
|
-
const details = ConnectionManager.detailsFromConnection(connection);
|
|
718
|
-
details.checkpointSequenceNumber = checkpointSequenceNumber;
|
|
719
|
-
this.props.connectHandler(details);
|
|
720
|
-
|
|
721
|
-
this.connectFirstConnection = false;
|
|
722
|
-
|
|
723
|
-
// Synthesize clear & join signals out of initialClients state.
|
|
724
|
-
// This allows us to have single way to process signals, and makes it simpler to initialize
|
|
725
|
-
// protocol in Container.
|
|
726
|
-
const clearSignal: ISignalMessage = {
|
|
727
|
-
clientId: null, // system message
|
|
728
|
-
content: JSON.stringify({
|
|
729
|
-
type: SignalType.Clear,
|
|
730
|
-
}),
|
|
731
|
-
};
|
|
732
|
-
this.props.signalHandler(clearSignal);
|
|
733
|
-
|
|
734
|
-
for (const priorClient of connection.initialClients ?? []) {
|
|
735
|
-
const joinSignal: ISignalMessage = {
|
|
736
|
-
clientId: null, // system signal
|
|
737
|
-
content: JSON.stringify({
|
|
738
|
-
type: SignalType.ClientJoin,
|
|
739
|
-
content: priorClient, // ISignalClient
|
|
740
|
-
}),
|
|
741
|
-
};
|
|
742
|
-
this.props.signalHandler(joinSignal);
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
// Unfortunately, there is no defined order between initialSignals (including join & leave signals)
|
|
746
|
-
// and connection.initialClients. In practice, connection.initialSignals quite often contains join signal
|
|
747
|
-
// for "self" and connection.initialClients does not contain "self", so we have to process them after
|
|
748
|
-
// "clear" signal above.
|
|
749
716
|
if (connection.initialSignals !== undefined) {
|
|
750
717
|
for (const signal of connection.initialSignals) {
|
|
751
718
|
this.props.signalHandler(signal);
|
|
752
719
|
}
|
|
753
720
|
}
|
|
721
|
+
|
|
722
|
+
const details = ConnectionManager.detailsFromConnection(connection);
|
|
723
|
+
details.checkpointSequenceNumber = checkpointSequenceNumber;
|
|
724
|
+
this.props.connectHandler(details);
|
|
725
|
+
|
|
726
|
+
this.connectFirstConnection = false;
|
|
754
727
|
}
|
|
755
728
|
|
|
756
729
|
/**
|
package/src/container.ts
CHANGED
|
@@ -64,6 +64,7 @@ import {
|
|
|
64
64
|
ISequencedClient,
|
|
65
65
|
ISequencedDocumentMessage,
|
|
66
66
|
ISequencedProposal,
|
|
67
|
+
ISignalClient,
|
|
67
68
|
ISignalMessage,
|
|
68
69
|
ISnapshotTree,
|
|
69
70
|
ISummaryContent,
|
|
@@ -411,6 +412,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
|
|
|
411
412
|
private readonly clientDetailsOverride: IClientDetails | undefined;
|
|
412
413
|
private readonly _deltaManager: DeltaManager<ConnectionManager>;
|
|
413
414
|
private service: IDocumentService | undefined;
|
|
415
|
+
private _initialClients: ISignalClient[] | undefined;
|
|
414
416
|
|
|
415
417
|
private _context: ContainerContext | undefined;
|
|
416
418
|
private get context() {
|
|
@@ -1381,8 +1383,11 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
|
|
|
1381
1383
|
attributes,
|
|
1382
1384
|
quorumSnapshot,
|
|
1383
1385
|
(key, value) => this.submitMessage(MessageType.Propose, JSON.stringify({ key, value })),
|
|
1386
|
+
this._initialClients ?? [],
|
|
1384
1387
|
);
|
|
1385
1388
|
|
|
1389
|
+
this._initialClients = undefined;
|
|
1390
|
+
|
|
1386
1391
|
const protocolLogger = ChildLogger.create(this.subLogger, "ProtocolHandler");
|
|
1387
1392
|
|
|
1388
1393
|
protocol.quorum.on("error", (error) => {
|
|
@@ -1507,6 +1512,20 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
|
|
|
1507
1512
|
deltaManager.inboundSignal.pause();
|
|
1508
1513
|
|
|
1509
1514
|
deltaManager.on("connect", (details: IConnectionDetails, _opsBehind?: number) => {
|
|
1515
|
+
if (this._protocolHandler === undefined) {
|
|
1516
|
+
// Store the initial clients so that they can be submitted to the
|
|
1517
|
+
// protocol handler when it is created.
|
|
1518
|
+
this._initialClients = details.initialClients;
|
|
1519
|
+
} else {
|
|
1520
|
+
// When reconnecting, the protocol handler is already created,
|
|
1521
|
+
// so we can update the audience right now.
|
|
1522
|
+
this._protocolHandler.audience.clear();
|
|
1523
|
+
|
|
1524
|
+
for (const priorClient of details.initialClients ?? []) {
|
|
1525
|
+
this._protocolHandler.audience.addMember(priorClient.clientId, priorClient.client);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1510
1529
|
this.connectionStateHandler.receivedConnectEvent(
|
|
1511
1530
|
this.connectionMode,
|
|
1512
1531
|
details,
|
package/src/packageVersion.ts
CHANGED
package/src/protocol.ts
CHANGED
|
@@ -20,13 +20,6 @@ import {
|
|
|
20
20
|
} from "@fluidframework/protocol-definitions";
|
|
21
21
|
import { canBeCoalescedByService } from "@fluidframework/driver-utils";
|
|
22
22
|
|
|
23
|
-
// ADO: #1986: Start using enum from protocol-base.
|
|
24
|
-
export enum SignalType {
|
|
25
|
-
ClientJoin = "join", // same value as MessageType.ClientJoin,
|
|
26
|
-
ClientLeave = "leave", // same value as MessageType.ClientLeave,
|
|
27
|
-
Clear = "clear", // used only by client for synthetic signals
|
|
28
|
-
}
|
|
29
|
-
|
|
30
23
|
/**
|
|
31
24
|
* Function to be used for creating a protocol handler.
|
|
32
25
|
*/
|
|
@@ -34,6 +27,7 @@ export type ProtocolHandlerBuilder = (
|
|
|
34
27
|
attributes: IDocumentAttributes,
|
|
35
28
|
snapshot: IQuorumSnapshot,
|
|
36
29
|
sendProposal: (key: string, value: any) => number,
|
|
30
|
+
initialClients: ISignalClient[],
|
|
37
31
|
) => IProtocolHandler;
|
|
38
32
|
|
|
39
33
|
export interface IProtocolHandler extends IBaseProtocolHandler {
|
|
@@ -46,6 +40,7 @@ export class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandl
|
|
|
46
40
|
attributes: IDocumentAttributes,
|
|
47
41
|
quorumSnapshot: IQuorumSnapshot,
|
|
48
42
|
sendProposal: (key: string, value: any) => number,
|
|
43
|
+
initialClients: ISignalClient[],
|
|
49
44
|
readonly audience: IAudienceOwner,
|
|
50
45
|
) {
|
|
51
46
|
super(
|
|
@@ -58,11 +53,8 @@ export class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandl
|
|
|
58
53
|
sendProposal,
|
|
59
54
|
);
|
|
60
55
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.quorum.on("removeMember", (clientId) => audience.removeMember(clientId));
|
|
64
|
-
for (const [clientId, details] of this.quorum.getMembers()) {
|
|
65
|
-
this.audience.addMember(clientId, details.client);
|
|
56
|
+
for (const initialClient of initialClients) {
|
|
57
|
+
this.audience.addMember(initialClient.clientId, initialClient.client);
|
|
66
58
|
}
|
|
67
59
|
}
|
|
68
60
|
|
|
@@ -89,29 +81,14 @@ export class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandl
|
|
|
89
81
|
public processSignal(message: ISignalMessage) {
|
|
90
82
|
const innerContent = message.content as { content: any; type: string; };
|
|
91
83
|
switch (innerContent.type) {
|
|
92
|
-
case
|
|
93
|
-
const members = this.audience.getMembers();
|
|
94
|
-
for (const [clientId, client] of members) {
|
|
95
|
-
if (client.mode === "read") {
|
|
96
|
-
this.audience.removeMember(clientId);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
case SignalType.ClientJoin: {
|
|
84
|
+
case MessageType.ClientJoin: {
|
|
102
85
|
const newClient = innerContent.content as ISignalClient;
|
|
103
|
-
|
|
104
|
-
if (newClient.client.mode === "read") {
|
|
105
|
-
this.audience.addMember(newClient.clientId, newClient.client);
|
|
106
|
-
}
|
|
86
|
+
this.audience.addMember(newClient.clientId, newClient.client);
|
|
107
87
|
break;
|
|
108
88
|
}
|
|
109
|
-
case
|
|
89
|
+
case MessageType.ClientLeave: {
|
|
110
90
|
const leftClientId = innerContent.content as string;
|
|
111
|
-
|
|
112
|
-
if (this.audience.getMember(leftClientId)?.mode === "read") {
|
|
113
|
-
this.audience.removeMember(leftClientId);
|
|
114
|
-
}
|
|
91
|
+
this.audience.removeMember(leftClientId);
|
|
115
92
|
break;
|
|
116
93
|
}
|
|
117
94
|
default: break;
|